[comp.unix.questions] exit

chris@mimsy.UUCP (Chris Torek) (12/19/87)

As various people have pointed out, crt0.c (the file in which the

	exit(main(argc, argv, env))

call was found) is a system dependent way of getting C code started.
(When the operating system is asked to run a program, it jumps to
some starting location with registers and/or stack set up in some
particular way.  The code at this start location has to turn this
into a normal C stack frame and call main.  In most Unixes, this is
done by a routine in crt0.s or crt0.c.)

Nonetheless, exit(main(argc, argv, env)) is a perfectly legal thing
to write.  Here is an example with the env parameter deleted:

	int
	main(argc, argv)
		int argc;
		char **argv;
	{
		int n;

		/*
		 * Compute and print the factorial of all arguments.
		 */
		if (argc < 2)
			return (0);	/* no arguments */

		/* do the first argument */
		n = atoi(argv[1]);
		printf("%d! = %d\n", n, fac(n));

		/* do the rest of the arguments */
		exit(main(argc - 1, argv + 1));
	}

	int
	fac(n)
		int n;
	{

		if (n < 2)
			return (1);
		return (n * fac(n - 1));
	}

The *only* thing that is special about `main' is that the runtime
system somehow calls it to start the program, and that when it
returns to the runtime system (if ever), the `int' value it returns
is given back to the system as a status value.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

djones@megatest.UUCP (Dave Jones) (12/23/87)

in article <2058@bloom-beacon.MIT.EDU>, wesommer@athena.mit.edu (William Sommerfeld) says:
 
 GNU emacs has its own version of crt0.c (with probably hundreds of
  #ifdefs to account for all sorts of machine dependancies) because it
  has to be able to dump out a core image of itself containing
  pre-loaded emacs lisp, and then restart this core image later.
 



It's quite possible to dump core without hacking crt0.c, which seems to
me to be an absolute no-no. (But then, I'm the guy who hacked exit().)
Must be some other reason for the special crt0.c in gnu-emacs.

		-- djones

ok@quintus.UUCP (01/24/88)

In article <310@fig.bbn.com>, rsalz@bbn.com (Rich Salz) writes:
> Nope.  The use of && and || in csh is the opposite of that in /bin/sh.
> 	/bin/sh -c "/bin/test -d foo || mkdir foo"
> Means if the foo directory doesn't exist, make it.  That is, /bin/sh does
> the "conceptually right thing" in that it takes a||b to mean, do b if a
> failed.
> 
> The Cshell takes a||b in the mathematical sense; do b if a does an exit(0):
> 	/bin/csh -c "/bin/test -d foo || mkdir foo"
> will never make the directory, or mkdir will spit if it already exists.
> 
If you have a C-shell, do the following:
	cat >foo <<'EOF'
	#!/bin/csh
	(exit $1) && (echo true) || (echo false)
	'EOF'
	chmod +x foo
	foo 0
prints	true
	foo 1
prints	false
which indicates that the C-shell ***IS*** treating && and || the
way I said it does.  I tried Rich Salz's specific example, and
it ***DID*** make the directory.  This was under SunOS 3.2.
The C-shell manual explicitly says that "Pipelines that are separated by
&& or || form conditional sequences in which the execution of pipelines
on the right depends upon the success or failure, respectively, of the
pipeline on the left."  So it would be a very serious bug if Rich
Salz were right.

The C-shell, in addition to commands, has EXPRESSIONS, and
in expressions && and || do what he thinks.  But *ONLY* in expressions.
Unlike the Bourne shell, the C-shell doesn't have you use commands
in if and while.  You use *expressions* there.  The {command} form
converts a command to an expression, but mapping exit 0 to 1 and
exit non-zero to 0.  (It's in the manual.)

Suppose you want to create directory foo if it doesn't exist and
the current directory is writable.  Four ways:

sh :	test -d foo || ( test -w . && mkdir foo )

sh :	if test ! -d foo  && test -w . 
	    then
		mkdir foo
	    fi

csh:	test -d foo || ( test -w . && mkdir foo )

csh:	if ( ! { test -d foo } && { test -w . } ) mkdir foo
	       ^^^^^^^^^^^^^^^    ^^^^^^^^^^^^^ these are expressions!

Yes, it is confusing that the same operators are used with opposite
meanings.  Even so, it is wise to try one's examples before claiming
that they don't work...

guy@gorodish.UUCP (01/24/88)

> Nope.  The use of && and || in csh is the opposite of that in /bin/sh.

Nope.  The use of && and ||, in versions of "csh" recent enough to have the bug
that broke && and || fixed, is the same as that in "/bin/sh".  This includes
the 4.2 and 4.3 versions, and if I remember correctly it includes the 4.1
version as well.  (The bug was caused by somebody working on the C shell
forgetting that a zero exit status means true, not false, and that a non-zero
exit status means false, not true.)
	Guy Harris
	{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
	guy@sun.com