ADLER1%BRANDEIS.BITNET@CUNYVM.CUNY.EDU (12/16/87)
I was looking through the file crt0.c in the GNU emacs source code and found the command exit(main(argc,argv,env)); which I find puzzling. I thought that one was supposed to give exit a number for an argument. What does the above command do and why would anyone want to do it that way ? ADLER1@BRANDEIS.BITNET
pardo@uw-june.UUCP (David Keppel) (12/17/87)
>why: > exit(main(argc,argv,env)) Guesses: The C compiler (or the loader, or whatever) guarantees that there is some function called "main" that is the thing you want to execute first. Main is defined as returning an int, so exit() gets an int. Therefore this code can set up whatever it needs, call main, and then exit with whatever status code main exited with. This would be like status = main(argc,argv,envp); exit(status); but doesn't use an extra variable. ;-D on (Well it _sounded_ like a good idea at the time!) Pardo
gwyn@brl-smoke.ARPA (Doug Gwyn ) (12/17/87)
In article <10875@brl-adm.ARPA> ADLER1%BRANDEIS.BITNET@CUNYVM.CUNY.EDU writes: >exit(main(argc,argv,env)); >which I find puzzling. I thought that one was supposed to give exit a >number for an argument. exit() takes an int argument; main() returns an int value. What don't you understand? By the way, the "env" parameter is nonstandard, although it doesn't matter on some architectures.
ljz@fxgrp.UUCP (Lloyd Zusman, Master Byte Software) (12/17/87)
In article <10875@brl-adm.ARPA> ADLER1%BRANDEIS.BITNET@CUNYVM.CUNY.EDU writes: >I was looking through the file crt0.c in the GNU emacs source code and >found the command > >exit(main(argc,argv,env)); > >which I find puzzling. I thought that one was supposed to give exit a >number for an argument. What does the above command do and why would >anyone want to do it that way ? This command invokes your main() routine with the proper arguments. Just like any other C function, main() returns a value. Consider the following code fragment ... int retcode; . . . retcode = main(argc, argv, env); exit(retcode); In this case, exit() is getting a number as its argument. This is equivalent to the "exit(main(argc, argv, env))" command that was mentioned above. Perhaps your confusion is due to the fact that you didn't think that main() is the same as other functions. It is. You can give it a return() statement ... main() { . . . return(99); } This is supposed to be equivalent to main() { . . . exit(99); } I say "supposed to" because I've used C compilers on the IBM PC where this doesn't work. The "exit(main(...))" construct in the crt0.c will ensure that this construct works like it should. ------------------------------------------------------------------------- Lloyd Zusman Master Byte Software Los Gatos, California Internet: fxgrp!ljz@ames.arpa "We take things well in hand." UUCP: ...!ames!fxgrp!ljz
ncbauers@ndsuvax.UUCP (Michael Bauers) (12/17/87)
In article <10875@brl-adm.ARPA> ADLER1%BRANDEIS.BITNET@CUNYVM.CUNY.EDU writes: >I was looking through the file crt0.c in the GNU emacs source code and >found the command >exit(main(argc,argv,env)); >which I find puzzling. I thought that one was supposed to give exit a >number for an argument. What does the above command do and why would >anyone want to do it that way ? Well I have never seen syntax like this...but it should just recur- sively call main. I assume you know what argc, argv, and env are. Main would be in big trouble if it did not have a normal exit statement which presumably is of the form exit(n).
mr@homxb.UUCP (mark) (12/18/87)
In article <10875@brl-adm.ARPA>, ADLER1%BRANDEIS.BITNET@CUNYVM.CUNY.EDU writes: > I was looking through the file crt0.c in the GNU emacs source code and > found the command > > exit(main(argc,argv,env)); > > which I find puzzling. I thought that one was supposed to give exit a > number for an argument. What does the above command do and why would > anyone want to do it that way ? > > ADLER1@BRANDEIS.BITNET main() returns an int which is then the argument to exit() and is then returned to the shell or whatever exec'ed the program. This brings up an interesting problem : What if you declare main to return something other than an int ? Is that allowed ? mark homxb!mr
marty1@houdi.UUCP (M.BRILLIANT) (12/18/87)
> > I was looking through the file crt0.c in the GNU emacs source code and > found the command > > exit(main(argc,argv,env)); > > which I find puzzling. I thought that one was supposed to give exit a > number for an argument. What does the above command do and why would > anyone want to do it that way ? > > ADLER1@BRANDEIS.BITNET Yeah, I second the question. What this does is execute main(...) and then give exit() the number that main returns. So main(...) must have in it some statements of the form return(3); or return(status); so that exit() will get a useful number. But the same effect would be achieved if main() had statements of the form exit(3); or exit(status);. The key question is where the exit(main(..)) was found. Since main() is the first function called, no statement is needed to invoke main(). Put it another way, since main() is invoked anyway, any statement that calls main() must call it recursively. Why would anybody do that? M. B. Brilliant Marty AT&T-BL HO 3D-520 (201)-949-1858 Holmdel, NJ 07733 ihnp4!houdi!marty1
daveb@laidbak.UUCP (Dave Burton) (12/18/87)
In article <10875@brl-adm.ARPA> ADLER1%BRANDEIS.BITNET@CUNYVM.CUNY.EDU writes: >I was looking through the file crt0.c in the GNU emacs source code and >found the command > >exit(main(argc,argv,env)); > >which I find puzzling. I thought that one was supposed to give exit a >number for an argument. What does the above command do and why would >anyone want to do it that way ? > >ADLER1@BRANDEIS.BITNET Actually, "main(...)" DOES give exit() an integer argument. Remember, any function without a type declaration in C is implicitly a function returning int. This line of code simply starts the C program at the symbol "main", passing the usual arguments to it. When main returns, an integer value is pushed on the stack for the exit(). I don't have the emacs source, so I don't know exactly what main() returns to exit(). If no explicit return is given, the value returned is undefined. If main() quits with an exit() call, I believe the exit(main()) will get the argument from the main(){ ... exit(x); }. -- --------------------"Well, it looked good when I wrote it"--------------------- Verbal: Dave Burton Net: ...!ihnp4!laidbak!daveb V-MAIL: (312) 505-9100 x325 USSnail: 1901 N. Naper Blvd. #include <disclaimer.h> Naperville, IL 60540
daveb@laidbak.UUCP (Dave Burton) (12/18/87)
In article <176@fxgrp.UUCP> fxgrp!ljz@ames.arpa (Lloyd Zusman, Master Byte Software) writes: >In article <10875@brl-adm.ARPA> ADLER1%BRANDEIS.BITNET@CUNYVM.CUNY.EDU writes: >>... >>found the command >>exit(main(argc,argv,env)); >>which I find puzzling. ... > ... > return(99); > ... >This is supposed to be equivalent to > ... > exit(99); > ... >I say "supposed to" because I've used C compilers on the IBM PC where >this doesn't work. They are NOT equivalent! At least in the UNIX environment, exit() is a function that flushes all buffers (and closes all file descriptors?), as well as handling functions registered via onexit(), finally calling _exit(), a system call that never returns. Using return instead of exit() bypasses this cleanup operation. -- --------------------"Well, it looked good when I wrote it"--------------------- Verbal: Dave Burton Net: ...!ihnp4!laidbak!daveb V-MAIL: (312) 505-9100 x325 USSnail: 1901 N. Naper Blvd. #include <disclaimer.h> Naperville, IL 60540
gp@picuxa.UUCP (Greg Pasquariello X1190) (12/18/87)
In article <1451@houdi.UUCP>, marty1@houdi.UUCP (M.BRILLIANT) writes: > > The key question is where the exit(main(..)) was found. Since main() > is the first function called, no statement is needed to invoke main(). > Put it another way, since main() is invoked anyway, any statement that > calls main() must call it recursively. Why would anybody do that? On the compilers that I have seen, main() isn't the first routine called. Rather, some startup code is included (typically called _main()) that in turn invokes main(). Therefor exit(main(argc,argv,envp)) is an efficient way (it saves a variable) to call main and return an exit status.
sbw@naucse.UUCP (Steve Wampler) (12/19/87)
In article <1451@houdi.UUCP>, marty1@houdi.UUCP (M.BRILLIANT) writes: > > > > I was looking through the file crt0.c in the GNU emacs source code and > > found the command > > > > exit(main(argc,argv,env)); > > The key question is where the exit(main(..)) was found. Since main() > is the first function called, no statement is needed to invoke main(). > Put it another way, since main() is invoked anyway, any statement that > calls main() must call it recursively. Why would anybody do that? The key is probably that the statement was found in crt0.c. On all the systems I'm familiar with, the 'main' function is not called directly by the system - instead the system invokes a 'startup' routine that opens standard files, munges the environment a bit, and then calls 'main'. I'll bet the above code was in a routine 'start' or 'Start'. Most of the languages I'm familiar with do this - I can remember rewriting the FORTRAN startup routine on a CDC 6400 to process ratfor more cleanly, patterned after an approach some friends used on a DEC-10.
wesommer@athena.mit.edu (William Sommerfeld) (12/19/87)
This really isn't a C question; it is a UNIX question. > > I was looking through the file crt0.c in the GNU emacs source code and > found the command > > exit(main(argc,argv,env)); > First misconception: exit() is a _function_ in the C library. It happens to be different from other functions in that it never returns control to its caller, but that's just a property of the implementation; there isn't anything in the C compiler which special-cases exit(), or abort(), or any of the other special functions. You don't have to pass it a constant integer. On UNIX, crt0.c happens to be the module which sets up argv, argc, and the environment and then calls main() with the appropriate arguments; it is silently included into the load image by 'cc' when you use it to link a program. Needless to say, it is highly architecture- and OS- dependant. 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. - Bill
pardo@uw-june.UUCP (David Keppel) (12/19/87)
[Why does crt0.c have "exit(main(argc,argv,argp));"? Isn't main called first?] I think that crt0.c is responsible for implementing the convention that main() is called first. crt0.c shags some environment pointers off of the stack and in some implementations may do other stuff. crt0.c is called directly by the kernel. This also means that it is the *last* thing executed before a user program terminates. (Sorry if I got this wrong, but I think that's how it goes). ;-D on (Conventions? NAHHHH... ) Pardo
jph@houxa.UUCP (J.HARKINS) (12/19/87)
In article <10875@brl-adm.ARPA>, ADLER1%BRANDEIS.BITNET@CUNYVM.CUNY.EDU writes: > > exit(main(argc,argv,env)); > > which I find puzzling. I thought that one was supposed to give exit a > number for an argument. What does the above command do and why would > anyone want to do it that way ? As the other posters have noted, main() returns an int which is what exit() needs. However, doing this also ensures that exit() will be called, even if it is never explicitely called from main(). exit() may flush buffers, close files, and perform other chores required for nice, systematic completion of a C program. How many times have you seen buffered output not get printed because a program died between the output statement and the physical flushing of its output buffer? The exit(main()) ensures that things like this should not happen. ------- Disclaimer: I hereby disclaim all my debts. ------ Jack Harkins @ AT&T Bell Labs Princeton Information (201) 949-3618 (201) 356-7573 ihnp4!houxa!jph
ljz@fxgrp.UUCP (Lloyd Zusman, Master Byte Software) (12/19/87)
In article <1451@houdi.UUCP> marty1@houdi.UUCP (M.BRILLIANT) writes: >> I was looking through the file crt0.c in the GNU emacs source code and >> found the command >> >> exit(main(argc,argv,env)); > ... >The key question is where the exit(main(..)) was found. Since main() >is the first function called, no statement is needed to invoke main(). >Put it another way, since main() is invoked anyway, any statement that >calls main() must call it recursively. Why would anybody do that? It is a de facto and possibly also de jure standard in unix for the run-time support code for a C program exist in a file called crt0.o, whose source code would, presumably, be in a file called crt0.c. By "run time support" I mean the following: the code in crt0.o is what gets executed *before* the main() routine gets called. This code will do things such as intialize certain C-library variables, open stdin, stdout, and stderr, parse command-line arguments, and possibly many other things. One of the final things it does is to invoke a function called "main" with the argc, argv, and possibly also envp arguments. This is how the system knows to start executing your program at the main() entry point. The linker knows about this crt0.o file and automatically links it in without you having to specify it. Hence, it is entirely appropriate for an the above-mentioned exit statement to appear in crt0.c. With regard to the issue of main() having a return statement, if you use the crt0.c startup module (i.e., runtime support module) described above, you can have your main() routine issue a return(N) statement and it will be treated just as if you issued an exit(N) statement (for integer values of N, of course). I'm not sure if this is standard behavior. In several C compilers on the IBM PC, there is a varied interpretation of this. I've seen the following two ways of doing this in the runtime support modules of IBM PC C compilers. (1) As above. In other words, exit(main(argc, argv, envp)); (2) Ignore main's return code main(argc, argv, envp); exit(0); The first option will behave as described above with regard to return and exit in main(). The second one requires the programmer to put an exit(N) statement into the main() routine if an non-zero exit code is desired. Any return statements in the main() routine would have their arguments ignored in the second option. A disadvantage of the first approach is that you will get an indeterminate exit code if you leave the main() routine without a return or an exit, which is a quite common occurrence. I'm sure that we could have a nice long discussion about this issue. ------------------------------------------------------------------------- Lloyd Zusman Master Byte Software Los Gatos, California Internet: fxgrp!ljz@ames.arpa "We take things well in hand." UUCP: ...!ames!fxgrp!ljz
chris@mimsy.UUCP (Chris Torek) (12/19/87)
In article <1286@laidbak.UUCP> daveb@laidbak.UUCP (Dave Burton) writes:
-They are NOT equivalent!
-At least in the UNIX environment, exit() is a function that flushes all
-buffers (and closes all file descriptors?), as well as handling functions
-registered via onexit(), finally calling _exit(), a system call that
-never returns.
-
-Using return instead of exit() bypasses this cleanup operation.
If it does, the system is broken.
exit(n) and return(n)-from-main are supposed to be equivalent. Among
those systems that get it wrong are various releases of SunOS (where
the difference was intentional, yet still wrong).
--
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690)
Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
gwyn@brl-smoke.ARPA (Doug Gwyn ) (12/19/87)
In article <1451@houdi.UUCP> marty1@houdi.UUCP (M.BRILLIANT) writes: >The key question is where the exit(main(..)) was found. He told you; it was in crt0.c, the C run-time startup module. That is the fellow who runs your main() function. I doubt that in the Gnu package it was called recursively.
gwyn@brl-smoke.ARPA (Doug Gwyn ) (12/19/87)
In article <1286@laidbak.UUCP> daveb@laidbak.UUCP (Dave Burton) writes: >Using return instead of exit() bypasses this cleanup operation. False.
gwyn@brl-smoke.ARPA (Doug Gwyn ) (12/19/87)
In article <182@fxgrp.UUCP> fxgrp!ljz@ames.arpa (Lloyd Zusman, Master Byte Software) writes: > main(argc, argv, envp); > exit(0); Such implementations do not conform to the proposed ANSI C standard.
dave@westmark.UUCP (Dave Levenson) (12/19/87)
In article <1451@houdi.UUCP>, marty1@houdi.UUCP (M.BRILLIANT) writes: > > > > I was looking through the file crt0.c in the GNU emacs source code and > > found the command > > > > exit(main(argc,argv,env)); > > ... > The key question is where the exit(main(..)) was found. Since main() > is the first function called, no statement is needed to invoke main(). > Put it another way, since main() is invoked anyway, any statement that > calls main() must call it recursively. Why would anybody do that? Why call main() ? Well, you, yourself, said that main is the first function _called_. This implies that someone calls main. The code that actually receives control from the operating system is a runtime initialization function called crt0. It establishes the runtime stack, the local copy of the environment, and the arguments, and then calls main(). In other words, main() is not the first function to be called, it is the first user-written function to be called. It is called by crt0, which is not application-specific, and generally supplied by the compiler-writer. Main may call exit() explicitly, or it may return to its caller. In the latter case, its caller calls exit, apparently, and passes the return value of main() when it does so! -- Dave Levenson Westmark, Inc. A node for news. Warren, NJ USA {rutgers | clyde | mtune | ihnp4}!westmark!dave
ljz@fxgrp.UUCP (Lloyd Zusman, Master Byte Software) (12/19/87)
In article <1286@laidbak.UUCP> daveb@laidbak.UUCP (Dave Burton) writes: >In article <176@fxgrp.UUCP> fxgrp!ljz@ames.arpa (Lloyd Zusman, Master Byte Software) writes: >>In article <10875@brl-adm.ARPA> ADLER1%BRANDEIS.BITNET@CUNYVM.CUNY.EDU writes: > ... >At least in the UNIX environment, exit() is a function that flushes all >buffers (and closes all file descriptors?), as well as handling functions >registered via onexit(), finally calling _exit(), a system call that >never returns. > >Using return instead of exit() bypasses this cleanup operation. In the GNU version of crt0.o, this is obviously not the case due to the exit(main(argc, argv, envp)); statement in the GNU crt0.c file. In this case, using the return statement to leave main() will indeed cause all the cleanup functions to take place because this results in an immediate exit() call from the crt0 module [ i.e., *not* an _exit() call ]. I have been told here that our SunOS version 3.4 system works the same way as the GNU crt0 module is written, and hence at least on our unix, return(N) and exit(N) will be the same if issued from main() [ assuming, of course that my source of information about SunOS is correct ]. But upon reflection, I have to agree that it is better to always use an exit() statement in main() instead of relying on return [ or even worse, using neither return nor exit(), as is often done ]. If even one C compiler doesn't use exit() with main() the way it is done in the GNU crt0 module, then you have unpredictable results if exit() is left out of main(). So, to be safe, always leave main() via exit(). ------------------------------------------------------------------------- Lloyd Zusman Master Byte Software Los Gatos, California Internet: fxgrp!ljz@ames.arpa "We take things well in hand." UUCP: ...!ames!fxgrp!ljz
gwyn@brl-smoke.ARPA (Doug Gwyn ) (12/19/87)
In article <1253@homxb.UUCP> mr@homxb.UUCP (mark) writes: >This brings up an interesting problem : "Interesting" must be in the mind of the beholder! > What if you declare main to return something other than an int ? Simple: if you do that, you're wrong. > Is that allowed ? How could it be? However, few compilers will warn you about this mistake.
andrew@teletron.UUCP (Andrew Scott) (12/22/87)
In article <184@fxgrp.UUCP>, ljz@fxgrp.UUCP (Lloyd Zusman, Master Byte Software) writes:
But upon reflection, I have to agree that it is better to always
use an exit() statement in main() instead of relying on return [ or
even worse, using neither return nor exit(), as is often done ].
If even one C compiler doesn't use exit() with main() the way it
is done in the GNU crt0 module, then you have unpredictable results
if exit() is left out of main().
So, to be safe, always leave main() via exit().
Is it *really* better to use exit() instead of return from main()? Are there
many compilers that don't do the same thing? The reason I ask is that it's
always annoyed me that our lint doesn't understand exit() (and similar
functions) and complains that "main() returns random value to invocation
environment" if I don't use return.
Andrew
lvc@tut.cis.ohio-state.edu (Lawrence V. Cipriani) (12/23/87)
In article <164@teletron.UUCP>, andrew@teletron.UUCP (Andrew Scott) writes: previous quotation and first two questions deleted > The reason I ask is that it's > always annoyed me that our lint doesn't understand exit() (and similar > functions) and complains that "main() returns random value to invocation > environment" if I don't use return. > > Andrew This has bothered me about lint too. I don't think it will ever be changed by AT&T (but don't quote me on that). To get lint to shut up about this use the /*NOTREACHED*/ comment after the call to exit(n); e.g. main(argc, argv) int argc; char *argv[]; { code for main exit(n); /*NOTREACHED*/ } This will work for similar functions too. I wish I didn't HAVE to do this, but thats how to get around the complaint. -- Larry Cipriani AT&T Network Systems at cbosgd!osu-cis!tut!lvc Ohio State University
djones@megatest.UUCP (Dave Jones) (12/23/87)
in article <1451@houdi.UUCP>, marty1@houdi.UUCP (M.BRILLIANT) says: > >> >> I was looking through the file crt0.c in the GNU emacs source code and >> found the command >> >> exit(main(argc,argv,env)); >> >> which I find puzzling. I thought that one was supposed to give exit a >> number for an argument. What does the above command do and why would >> anyone want to do it that way ? >> >> ADLER1@BRANDEIS.BITNET > > Yeah, I second the question. What this does is execute main(...) and > then give exit() the number that main returns. So main(...) must have > in it some statements of the form return(3); or return(status); so that > exit() will get a useful number. But the same effect would be achieved > if main() had statements of the form exit(3); or exit(status);. > > The key question is where the exit(main(..)) was found. Since main() > is the first function called, no statement is needed to invoke main(). > Put it another way, since main() is invoked anyway, any statement that > calls main() must call it recursively. Why would anybody do that? > > M. B. Brilliant Marty > AT&T-BL HO 3D-520 (201)-949-1858 > Holmdel, NJ 07733 ihnp4!houdi!marty1 Don't count on anything in GNU emacs being what it appears to be. Our GNU emacs guru ("gnuru?") was gone for a couple of weeks, and I found myself with the job of fixing a bug. I chased it down, and it seemed to indicate a new static variable. So I added one. When the new version of emacs came up, it crashed, on entry... long before it could have gotten to any reference to the new variable. I tried running it under dbx. dbx crashed. Much head-scratching later, I discovered that when you add a new static variable, you have to do some extra magic... I forget just what. Seems there is a step in the making of a new emacs that edits the a.out file. Probably for purposes of runtime garbage collection. So it is quite possible that some step in the "make" is changing the name of "main" to "foo", or "bar" to "main" or something. There is also a concept of a "recursive edit" in emacs. Maybe that's it. The bad news is that our gnuru has now gone on to different pastures of an indeterminate shade of green. I hope that was the last bug in gnuemacs. New subject: As to why main() should return something rather than just call exit(). I suspect that before stdio, there was no "exit()". Old-timers, is that true? Anyway, all that the Berkeley 4.2 exit() does is to flush all the stdio buffers, then call _exit(). Problem is, stdio is not unique in requiring some clean-up upon any exit from the program. I confess that I have on occasion used my own a.out editor to change the name of the C-library's exit() "Cexit" or whatever, then written my own exit() which does some cleanup then calls the (now) Cexit routine. Simpler than trying to police the use of exit() by a dozen or so fellow programmers. Moral: Start a company policy of not using exit(). Call Lexit() instead. Have a way of registering cleanup routines with Lexit. A possible solution: /* No, I have not tested this, so if it's buggy, it's buggy. */ static int (*cleanup)(); int (*)(); set_Lexit(new_cleanup) int (*new_cleanup)(); { int (*old_cleanup)() = cleanup; cleanup = new_cleanup; return old_cleanup; } Lexit(code) { if(cleanup) (*cleanup)(code); exit(code); } /* use.... */ static int (*next_cleanup)(); foo_cleanup(code) { /* do my cleanup then... */ (*next_cleanup)(); } bar() { next_cleanup = set_Lexit(foo_cleanup); /* do stuff ... */ }
djones@megatest.UUCP (Dave Jones) (12/23/87)
[...] > At least in the UNIX environment, exit() is a function that flushes all > buffers (and closes all file descriptors?), as well as handling functions > registered via onexit(), finally calling _exit(), a system call that > never returns. > > Using return instead of exit() bypasses this cleanup operation. > > > > > -- > --------------------"Well, it looked good when I wrote it"--------------------- > Verbal: Dave Burton Net: ...!ihnp4!laidbak!daveb Hum. "onexit"... Just what's needed. (See my previous note, where I rambled on about "Lexit()". But on my Sun-3, I find no manual-page for onexit, and nm /lib/libc.a | grep onexit returns silently. So it looks as though not ALL unixes have onexit(). By the way, I've figured out what those long canned signatures with disclaimers are for. It's to keep vn from rejecting your reply because "quoted text is longer than new text"! So... Dave Jones Megatest Corp. 880 Fox Lane San Jose, CA. 95131 (408) 437-9700 Ext 3227 UUCP: ucbvax!sun!megatest!djones ARPA: megatest!djones@riacs.ARPA
ok@quintus.UUCP (Richard A. O'Keefe) (12/24/87)
In article <174@goofy.megatest.UUCP>, djones@megatest.UUCP (Dave Jones) writes: > Hum. "onexit"... Just what's needed. (See my previous note, where I > rambled on about "Lexit()". > > But on my Sun-3, I find no manual-page for onexit, and > > nm /lib/libc.a | grep onexit > > returns silently. So it looks as though not ALL unixes have onexit(). % man exit <oh dear, it's raving on about Csh commands> % man 2 exit <tells me about _exit(), with a cross-reference to exit(3)> % man 3 exit <tells me about exit(), with a cross-reference to on_exit(3)> % man 3 on_exit SYNOPSIS int on_exit(procp, arg) void (*procp)(); caddr_t arg; NOTES This call is specific to Sun Unix and should not be used if portability is a concern. Basically, there is a stack of up to 20 termination functions, and on_exit() pushes the pair procp,arg on the stack. On exit, these pairs are popped and procp(arg) called in reverse order. The problem with this feature (and with the version in dpANS) is that it is too global. What I would like to be able to do is { FILE *f; EXIT_HANDLER *e; FCHECK(f = fopen(...)); e = push_exit_handler(fclose, f); .... pop_run_one_handler(e); ... } so that I can put cleanup actions onto a stack and REMOVE them when they have been done, but if an exit() happens in between the actions will be done. Common Lisp's "unwind-protect" is the kind of thing we're after. Some other C implementations have a similar thing called "atexit()" or "at_exit()". While onexit() or whatever doesn't quite do what I want, I can at least register my own handler manager with it, so it's ok as a primitive.
msb@sq.uucp (Mark Brader) (12/26/87)
Lloyd Zusman (ljz@fxgrp.UUCP) writes: > But upon reflection, I have to agree that it is better to always > use an exit() statement in main() instead of relying on return [ or > even worse, using neither return nor exit(), as is often done ]. > If even one C compiler doesn't use exit() with main() the way it > is done in the GNU crt0 module, then you have unpredictable results > if exit() is left out of main(). I once met a C compiler that didn't implement ++ correctly for pointers to structures. Does this mean that we should all stop using ++? I suggest that return is the better thing to use in main(). If you use exit(), you're making the assumption that this function will always be the mainline of its program; if you use return, you can wrap another mainline around it by just changing the name of the original one. Also, if this practice is followed, a call to exit() really stands out as an abnormal return path, like longjmp(). Of course, if main() is recursive, the two forms are not equivalent; but not many people write recursive mainlines, and those that do are old enough to look after themselves. Mark Brader "C takes the point of view SoftQuad Inc., Toronto that the programmer is always right" utzoo!sq!msb, msb@sq.com -- Michael DeCorte
ftw@datacube.UUCP (12/28/87)
djones@megatest.UUCP writes: > Hum. "onexit"... Just what's needed. (See my previous note, where I > rambled on about "Lexit()". > But on my Sun-3, I find no manual-page for onexit, and > nm /lib/libc.a | grep onexit > returns silently. So it looks as though not ALL unixes have onexit(). The person who mentioned onexit() could have been using a Whitesmiths compiler. Their library provides onexit(). <edited> > Dave Jones > Megatest Corp. > 880 Fox Lane > San Jose, CA. > 95131 > (408) 437-9700 Ext 3227 > UUCP: ucbvax!sun!megatest!djones > ARPA: megatest!djones@riacs.ARPA #include <disclaimer.h> Farrell T. Woods Datacube Inc. Systems / Software Group 4 Dearborn Rd. Peabody, Ma 01960 VOICE: 617-535-6644; FAX: (617) 535-5643; TWX: (710) 347-0125 INTERNET: ftw@datacube.COM UUCP: {rutgers, ihnp4, mirror}!datacube!ftw "OS/2 -- Half an operating system"
ok@quintus.UUCP (Richard A. O'Keefe) (12/31/87)
I just installed a program which came over one of the *sources* newsgroups. The accompanying README was extremely funny: it said The program should be owned by root and suid. But that's not a C joke. What is of interest here is its use of exit(). It used exit() in two ways: exit(1) /* can't find datum in file */ exit(-1) /* can't fopen file, either "r" or "w" */ Oddly enough, it did not use exit(0) at the end of main(). Given all the hoo-haa we've been having about exit() recently, I thought it might not be out of place to warn people that the value given to exit() is often truncated to 8 bits on the way out. For example, in UNIX, for which this program was intended, saying this-program some-argument if [ #? -eq -1 ] ; then ... fi will NEVER succeed, because the return value is going to be 255. The VAX-11 C manual explicitly says that the argument of exit() should be 0 or a value errno might have. The Oct86 dpANS said only that 0 arguments indicate success and non-0 arguments indicate failure in some system-dependent way. Except where you are writing code for a specific system (say you have #if cases for MVS, VMS, and UNIX) it seems like a good idea to pass only 0 or 1 to exit().
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/06/88)
In article <171@goofy.megatest.UUCP> djones@megatest.UUCP (Dave Jones) writes: >Moral: Start a company policy of not using exit(). Call Lexit() instead. >Have a way of registering cleanup routines with Lexit. A possible solution: ANSI C provides an atexit() function that helps immensely with this. However, in the interim you need to take care of this yourself. One possibility is to use my public-domain implementation of atexit() and atexit-supporting exit(), which requires that your current "exit" library entry be renamed, to "__exit" for example, but otherwise slips right into your current C library. Contact me if you need a copy. - Gwyn@BRL.MIL
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/06/88)
In article <502@cresswell.quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes: >Except where you are writing code for a specific system (say you >have #if cases for MVS, VMS, and UNIX) it seems like a good idea >to pass only 0 or 1 to exit(). VMS C would like for exit(1); to also mean "success", we were told, so the current proposed standard requires <stdlib.h> to define macros EXIT_FAILURE and EXIT_SUCCESS. Special dispensation was granted to the value 0, which also indicates success (the VMS C implementor agreed that he could make that work on his system). All other values of the exit status have implementation-defined meaning; they might contain system error codes, errno values, or some other stuff with non-portable meaning.
peter@sugar.UUCP (Peter da Silva) (01/06/88)
In article ... ok@quintus.UUCP (Richard A. O'Keefe) writes: > [exit()] > > The VAX-11 C manual explicitly says that the argument of exit() > should be 0 or a value errno might have. > > The Oct86 dpANS said only that 0 arguments indicate success and > non-0 arguments indicate failure in some system-dependent way. > > Except where you are writing code for a specific system (say you > have #if cases for MVS, VMS, and UNIX) it seems like a good idea > to pass only 0 or 1 to exit(). I like passing -1 because: It's negative (some systems use the sign bit to specify true/false). It's odd (some systems use the low bit for the same purpose). All bits are set (some systems do ANDS and ORS using & and |). If it's truncated, it's large (some systems use small values for warnings, and large ones for fatal errors). I've never had a system treat "-1" as a successful result. I have had one ignore a return code of 1. -- -- Peter da Silva `-_-' ...!hoptoad!academ!uhnix1!sugar!peter -- Disclaimer: These U aren't mere opinions... these are *values*.
brett@wjvax.UUCP (Brett Galloway) (01/07/88)
In article <6935@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes: >In article <502@cresswell.quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes: >>Except where you are writing code for a specific system (say you >>have #if cases for MVS, VMS, and UNIX) it seems like a good idea >>to pass only 0 or 1 to exit(). > >VMS C would like for exit(1); to also mean "success", we were told, >so the current proposed standard requires <stdlib.h> to define macros >EXIT_FAILURE and EXIT_SUCCESS. Special dispensation was granted to >the value 0, which also indicates success (the VMS C implementor >agreed that he could make that work on his system). All other values >of the exit status have implementation-defined meaning; they might >contain system error codes, errno values, or some other stuff with >non-portable meaning. It appears to me that requiring EXIT_FAILURE and EXIT_SUCCESS is a sop to VMS's non-traditional usage. Now I grant that it is a nice idea to define EXIT_FAILURE and EXIT_SUCCESS. I also grant that other exit values are implementation-defined. However, it is hard to conceive an implementation which has multiple exit-success values. In this context, 0 is by far the most intuitive choice for EXIT_SUCCESS. Instead of accommodating VMS's stupid choice of exit values, why not require an ANSI-conforming VMS C compiler to swap 0 and 1 in the exit() in its C library? That way, even if VMS wants to see 1 for success, it will, with C programs able to return the natural value of 0 for success. I seem to recall that VMS already defines macros for error return values. It could swap those (make 0 success). This way, currently-compiled VMS C binaries would continue to run, and newly-compiled C binaries would also work (they would get the swapped exit() *and *the new EXIT_FAILURE and EXIT_SUCCESS macros at the same time. The only time that there would be a problem would be a re-link without a re-compile. Frankly, anybody that would not re-compile across a transition to an ANSI-conformant compiler deserves what they get. This solves the problem for everybody, while leaving conformant the vast body of programs which use the natural exit(0) => success and exit(!0) => !success. It puts the burden of conformance upon VMS instead of upon the rest of the world. This is apt, since VMS caused the problem in the first place. -- ------------- Brett D. Galloway {ac6,calma,cerebus,isi,isieng,pyramid,tymix}!wjvax!brett
chris@mimsy.UUCP (Chris Torek) (01/08/88)
>>VMS C would like for exit(1); to also mean "success", we were told, In article <1179@wjvax.UUCP> brett@wjvax.UUCP (Brett Galloway) writes: >Instead of accommodating VMS's stupid choice of exit values, why not require >an ANSI-conforming VMS C compiler to swap 0 and 1 in the exit() in its C >library? This is not the right approach. The right approach is this: exit(int status) { _vms_exit(!status); } /* more complex encodings can be devised */ /* note that _vms_exit shuts down stdio in this example */ _exit(int status) { _vms_stopcold(!status); } /* just another example */ The `problem' is that VMS programmers need access to the full range of VMS status values. There are many sub-fields to a VMS status. The low bit means `success'; the next few bits define what sort of error; a few more define a sub-error or previous error or something similar; and so forth. (Incidentally, exit status 0 in VMS means `failed, no errors occurred'. It is also possible to exit with `succeeded, but fatal errors occurred'.) But VMS status values mean nothing on other operating systems! Writing exit(0x1074); /* some fancy error or another */ means nothing outside of VMS---so why not use a VMS-specific function such as _vms_exit()? -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/08/88)
In article <1179@wjvax.UUCP> brett@wjvax.UUCP (Brett Galloway) writes: >It appears to me that requiring EXIT_FAILURE and EXIT_SUCCESS is a >sop to VMS's non-traditional usage. Yes, it was, but the argument was made that the exit status is intended to pass system-specific useful information back to the environment, and I have a hard time arguing against that because UNIX does that all the time. Clearly, X3J11 is in no position to dictate what various system information must consist of, other than "generic success" and "generic failure" which are the only useful statuses for portable applications. >However, it is hard to conceive an implementation >which has multiple exit-success values. VMS does! I agree that probably all implementations, including VMS, will #define EXIT_SUCCESS 0 >Instead of accommodating VMS's stupid choice of exit values, why not require >an ANSI-conforming VMS C compiler to swap 0 and 1 in the exit() in its C >library? We tried that, but many existing VMS applications have been passing the value of 1 (disguised as SYS$SUCCESS or something like that) to exit() to indicate success. >This is apt, since VMS caused the problem in the first place. Actually, I agree with this, but since we found a solution that the VMS folk could live with, why not stick with it.
egisin@orchid.waterloo.edu (Eric Gisin) (01/09/88)
> The `problem' is that VMS programmers need access to the full range > of VMS status values. There are many sub-fields to a VMS status. VMS C programmers have always had sys$exit() to return VMS status values. There is no excuse for making exit() synonymous with sys$exit -- something like the following would have been better and Unix compatible. exit(i) { sys$exit((i==0) ? SS$_NORMAL : SS$_CFAILURE); }
john@chinet.UUCP (John Mundt) (01/10/88)
In article <1179@wjvax.UUCP> brett@wjvax.UUCP (Brett Galloway) writes: >It appears to me that requiring EXIT_FAILURE and EXIT_SUCCESS is a >sop to VMS's non-traditional usage. Now I grant that it is a nice idea to >define EXIT_FAILURE and EXIT_SUCCESS. I also grant that other exit values >are implementation-defined. However, it is hard to conceive an implementation >which has multiple exit-success values. In this context, 0 is by far the >most intuitive choice for EXIT_SUCCESS. Using a non-zero exit value for a programs that exec()s a series of sub-programs allows the sub-program to return the user's intentions back to the execing program. We use it in a menu-driven bbs program where 0 is the plain-vanilla exit value with no special action intended while other values call up various menus or denote a particular program error. John Mundt, ....ihnp4!chinet!teachad!fred Teachers' Aide, Inc. ---------------------------- My opinions reflect the thinking of the company. I *own* it!
brett@wjvax.UUCP (Brett Galloway) (01/11/88)
In article <6983@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes: >In article <1179@wjvax.UUCP> brett@wjvax.UUCP I wrote: >>However, it is hard to conceive an implementation >>which has multiple exit-success values. >VMS does! >I agree that probably all implementations, including VMS, will > #define EXIT_SUCCESS 0 I overstated. I even have applications which have multiple exit-success values. However, there was always one fundamental exit-success value. I feel that 0 is the best choice for this. >>Instead of accommodating VMS's stupid choice of exit values, why not require >>an ANSI-conforming VMS C compiler to swap 0 and 1 in the exit() in its C >>library? >We tried that, but many existing VMS applications have been passing >the value of 1 (disguised as SYS$SUCCESS or something like that) to >exit() to indicate success. Not to beat a dead horse, but that's why I suggested swapping 0 and 1 in exit() *and* simultaneously re-defining SYS$SUCCESS et al in the relevant header file(s). As I noted, this would break only unlinked binaries that were not re-compiled. I had said: - The only time that there would be a problem would be a re-link without a - re-compile. Frankly, anybody that would not re-compile across a transition - to an ANSI-conformant compiler deserves what they get. One E-mail respondent took exception to my tone (deservedly, I believe). However, I stand by my point. It is unlikely that unlinked binaries will survive across the transition to an ANSI C library. >>This is apt, since VMS caused the problem in the first place. >Actually, I agree with this, but since we found a solution that the >VMS folk could live with, why not stick with it. Of course the VMS folk could live with the ANSI C solution; it *is* effectively the VMS solution. It is a trivial matter for VMS to adapt to this solution. -- ------------- Brett D. Galloway {ac6,calma,cerebus,isi,isieng,pyramid,tymix}!wjvax!brett
tanner@ki4pv.uucp (Dr. T. Andrews) (01/11/88)
In article <6983@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes:
) [ elaborates on VMS and EXIT_SUCCESS, EXIT_FAILURE reasoning ]
) Actually, I agree with this, but since we found a solution that the
) VMS folk could live with, why not stick with it.
Great! You've found a solution that the VMS folks could live with.
Unfortunately, those few unlucky enough to not be using VMS have been
spending their lives coding progs which finish with exit(0) when they
worked. How about a slap in the face with a wet towel to them?
--
{allegra clyde!codas decvax!ucf-cs ihnp4!codas killer}!ki4pv!tanner
gwyn@brl-smoke.UUCP (01/12/88)
In article <1185@wjvax.UUCP> brett@wjvax.UUCP (Brett Galloway) writes: >... simultaneously re-defining SYS$SUCCESS et al in the relevant header file(s). I may be mistaken, but I was under the impression that the SYS$... symbols were not #defined constants, but rather were system-wide logical names, or something of the sort.
gwyn@brl-smoke.UUCP (01/12/88)
In article <7208@ki4pv.uucp> tanner@ki4pv.uucp (Dr. T. Andrews) writes:
-Great! You've found a solution that the VMS folks could live with.
-Unfortunately, those few unlucky enough to not be using VMS have been
-spending their lives coding progs which finish with exit(0) when they
-worked. How about a slap in the face with a wet towel to them?
Please pay more careful attention. exit(0); is still a valid way of
reporting success under the proposed ANSI C. I'm sure I said that.
However, exit(1); is not guaranteed to report failure on all systems.
The real need was for EXIT_FAILURE; EXIT_SUCCESS was introduced just
for symmetry and completeness.
g-rh@cca.CCA.COM (Richard Harter) (01/12/88)
In article <7208@ki4pv.uucp> tanner@ki4pv.uucp (Dr. T. Andrews) writes: > >Great! You've found a solution that the VMS folks could live with. >Unfortunately, those few unlucky enough to not be using VMS have been >spending their lives coding progs which finish with exit(0) when they >worked. How about a slap in the face with a wet towel to them? People who write exit(0) are violating the well known canons of good programming practice -- "Thou shalt not embed magic numbers in your code". In this case, 0 is a magic number -- it is a coded value and the wise (read those who learned by being burnt) use symbolic names which are defined in one place only. [I am guilty of this also, so if I am pointing fingers, I share the guilt.] Does it matter? That depends. If your only environment is one where the magic number is always 0 then there is no harm in using 0. If you are writing code which will be ported across operating systems then it matters a great deal. I do not understand the wet towel bit. If you are a Unix programmer in the habit of using exit(0) you are not impacted by the standard. Your code will work the way it always did. If you are writing portable code you will be grateful for a standard mechanism for handling returns that is not operating system dependent. -- In the fields of Hell where the grass grows high Are the graves of dreams allowed to die. Richard Harter, SMDS Inc.
hydrovax@nmtsun.nmt.edu (M. Warner Losh) (01/13/88)
In article <1185@wjvax.UUCP>, brett@wjvax.UUCP (Brett Galloway) writes: > In article <6983@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes: > >In article <1179@wjvax.UUCP> brett@wjvax.UUCP I wrote: > >>However, it is hard to conceive an implementation > >>which has multiple exit-success values. > >VMS does! > >I agree that probably all implementations, including VMS, will > > #define EXIT_SUCCESS 0 > > Of course the VMS folk could live with the ANSI C solution; it *is* > effectively the VMS solution. It is a trivial matter for VMS to adapt to > this solution. Am I missing something here, or are you saying that because VMS cause this so-called mess, that they should have to live with a UNIX like kludge, just to make you happy? When you exit(0) on VMS you get the error %NONAME-W-NOMESSAGE, No message text for message 0000000 or something similar. Remember that VMS is not really 'C' based, and much of the code is written in a whole slew of languages. Would you propose that all of that be rewritten? I think not. The more proper VMS implementation of EXIT_STATUS should be SS$_NORMAL, which is (at least in 4x) defined to be 1. Why would you expect an operating system dependent scheme such as exit(0) to work on all OS's? The whole world isn't using UNIX. -- bitnet: lush@nmt.csnet M. Warner Losh csnet: warner%hydrovax@nmtsun uucp: ...{cmcl2, ihnp4}!lanl!unmvax!nmtsun!warner%hydrovax ...{cmcl2, ihnp4}!lanl!unmvax!nmtsun!hydrovax Warning: Hydrovax is both a machine, and an account, so be careful.
dhesi@bsu-cs.UUCP (Rahul Dhesi) (01/14/88)
In article <23160@cca.CCA.COM> g-rh@CCA.CCA.COM.UUCP (Richard Harter) writes: >In this case, 0 is a magic number -- it is a coded value and the wise >(read those who learned by being burnt) use symbolic names which are >defined in one place only. But zero is not a magic number, else we'd all have to stop assuming that the range of unsigned values begins at 0 (have to use UNSIGNED_MIN instead), or assume that array indices start at 0 (have to begin arrays at ARAY_MIN), or assume that NULL is zero (could be 17 on some machines), or assume that all static variables are initialized to zero (ought to be INIT_DEFAULT, an implementation-defined constant), or assume that division by zero is illegal (division by ILL_DIVISOR, an implementation-defined constant, is illegal instead), etc. -- Rahul Dhesi UUCP: <backbones>!{iuvax,pur-ee,uunet}!bsu-cs!dhesi
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/15/88)
In article <1843@bsu-cs.UUCP> dhesi@bsu-cs.UUCP (Rahul Dhesi) writes: >In article <23160@cca.CCA.COM> g-rh@CCA.CCA.COM.UUCP (Richard Harter) writes: >>In this case, 0 is a magic number -- it is a coded value ... >But zero is not a magic number, ... What g-rh was trying to say was that the SUCCESSFUL TERMINATION STATUS INDICATOR (which traditionally has been 0 on UNIX systems) is a "magic number", and he's right.
eichin@athena.mit.edu (Mark W. Eichin) (01/16/88)
Regarding Rahul Dhesi's comments on 0 not being a magic number: 1) Assuming NULL is zero (meaning it is a zero bitstring internally) is not correct, however casting 0 to a pointer, as in: if(*p){ do_something() } where (*p) is (*p != 0) which becomes (*p != NULL) is valid. The trick is the conversion of 0 to NULL; on Multics, NULL is a pointer into segment -1 with arbitrary offset; on Primes, it is something other non-zero bitmap. This gets hashed about here every 6 months, it seems. 2) Assuming that arrays start at 0 is straight out of K&R. However, you are then stuck with using C arrays. I had a large (50Klines) application where we started out with a custom implementation of arrays, with bounds checking and operator packages and other ``neat stuff'', and we ORIGINALLY had ARRAY_MIN == 1. It kept us honest... since after the 3d rewrite (aren't educational projects fun :-) we decided to change the Array package implementation and ARRAY_MIN was suddenly 0 again. I am glad we didn't start out with 0 and convert to 1 later, that would have been BAD... but with all of the fenceposts to keep track of, we had alot of references to BASE that were explicit, so the conversion went fairly smoothly. (With a real package layer, like C++ has, we would have had NO problems, but this was vanilla C...) 3) Assuming that Division by Zero is illegal is not implementation defined, since the implementation is specified as standard mathematics. Mathematicians use a special symbol for `that which division is not defined upon': 0. Why should C programmers do otherwise? :-) In any case, the original point (that zero is not a magic number) was correct (we are *almost* in violent agreement here) but some of the excuses were not correct; point 2 above bothered me enough to respond... the point being that some things that are specified, but are changeable anyway. Zero is *specified* in some places as the correct thing, so extracting it out as a symbol can clutter and confuse. The change in meaning of 0 as a value to exit(int status) under un*x and vms$exit() is from the original spec being o/s specific. Oh well... Mark Eichin <eichin@athena.mit.edu> SIPB Member & Project Athena ``Watchmaker''
eichin@athena.mit.edu (Mark W. Eichin) (01/16/88)
Under 4.3BSD, there is a <sysexits.h> which does include a bunch of standard return values like EX_USAGE, EX_NOPERM, and others, for use as arguments to exit(); it is not complete, in fact it isn't terribly large. In any case, there is one return value EX_OK commented as /* successful termination */ with the value of 0... it is NOT documented in the comments at the top. It doesn't seem that many people use these, are they a really recent development? If it were in common use, the problem under discussion wouldn't be so severe... Mark Eichin <eichin@athena.mit.edu> SIPB Member & Project Athena ``Watchmaker''
dhesi@bsu-cs.UUCP (01/16/88)
I gave a number of example attempting to show that zero is inherently
a unique integer and therefore not a "magic number" in the usual
sense of the term.
In article <2305@bloom-beacon.MIT.EDU> eichin@athena.mit.edu (Mark W.
Eichin) gives a number of counter arguments.
I respond thus.
Zero symmetrically divides the number line. If one had to choose ONE
of the values on the number line as being unique, it would have to be
zero. It is the only value that isn't arbitrary, the only one that
doesn't have a mirror-image counterpart (of opposite sign), the only
one that can't be a legal divisor, the only one that, in short,
stands out as "different" from all the other values.
It seems to make perfect sense to me that in the non-VMS world in which
a single successful termination value, and multiple failure termination
values, are needed, zero should be the successful termination value.
Therefore the use of exit(0) for successful termination is not
arbitrary. It is intuitively correct.
--
Rahul Dhesi UUCP: <backbones>!{iuvax,pur-ee,uunet}!bsu-cs!dhesi
jay@splut.UUCP (Jay Maynard) (01/16/88)
In article <7208@ki4pv.uucp>, tanner@ki4pv.uucp (Dr. T. Andrews) writes: > In article <6983@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes: > ) [ elaborates on VMS and EXIT_SUCCESS, EXIT_FAILURE reasoning ] > ) Actually, I agree with this, but since we found a solution that the > ) VMS folk could live with, why not stick with it. > > Unfortunately, those few unlucky enough to not be using VMS have been > spending their lives coding progs which finish with exit(0) when they > worked. How about a slap in the face with a wet towel to them? for(i = 0; i < 100; i++) { repeat_after_me('All the world does not run on Unix, either.'); } I think it's only fair that those of us who complain about 'all the world is a VAX' should complain about 'all the world is Unix' as well... This is probably the best, portable solution. -- Jay Maynard, K5ZC (@WB5BBW)...>splut!< | GEnie: JAYMAYNARD CI$: 71036,1603 uucp: {uunet!nuchat,academ!uhnix1,{ihnp4,bellcore,killer}!tness1}!splut!jay Never ascribe to malice that which can adequately be explained by stupidity. The opinions herein are shared by none of my cats, much less anyone else.
mike@arizona.UUCP (01/17/88)
In article <1868@bsu-cs.UUCP>, dhesi@bsu-cs.UUCP (Rahul Dhesi) writes: > [...] > Zero symmetrically divides the number line. If one had to choose ONE > of the values on the number line as being unique, it would have to be > zero. It is the only value that isn't arbitrary, the only one that > doesn't have a mirror-image counterpart (of opposite sign), the only > one that can't be a legal divisor, the only one that, in short, > stands out as "different" from all the other values. One (1) symmetrically divides the number line. If one had to choose ONE of the values on the number line as being unique, it would have to be one. It is the only value that isn't arbitrary, it only one that is a multiplicative identity, the only number of noses on my face, the only one, in short, that stands out as "different" from all the other values. :-> -- Mike Coffin mike@arizona.edu Univ. of Ariz. Dept. of Comp. Sci. {allegra,cmcl2,ihnp4}!arizona!mike Tucson, AZ 85721 (602)621-4252
hydrovax@nmtsun.nmt.edu (M. Warner Losh) (01/17/88)
In article <1843@bsu-cs.UUCP>, dhesi@bsu-cs.UUCP (Rahul Dhesi) writes: > In article <23160@cca.CCA.COM> g-rh@CCA.CCA.COM.UUCP (Richard Harter) writes: > >In this case, 0 is a magic number -- it is a coded value and the wise > >(read those who learned by being burnt) use symbolic names which are > >defined in one place only. > > But zero is not a magic number, > Rahul Dhesi UUCP: <backbones>!{iuvax,pur-ee,uunet}!bsu-cs!dhesi Rahul, any number is magic. We associate Zero with a correct exit, ONLY BECAUSE WE HAVE BE TAUGH THIS BY UNIX. If you had ever worked wit (a real operating system :-)) VMS, then you know that an ODD number is sucess, while an even one is an error. Both systems are equally valid, since they are arbitrary abstractions. FLAME ON Your statements about valid uses of zero THAT ARE DEFINED TO BE VALID IN C (K&R version), are so amazinly BOGUS, that I'm not even going to include them in this article. THE WHOLE WORLD IS NOT UNIX, VMS, MVS, or any other operating system. Please try to remeber that there are some things in a "standard" 'C' that are part of C (like the zero indexing) and somethings that are part of the environment that 'C' lives in (the exit() stuff for one). FLAME OFF -- bitnet: lush@nmt.csnet M. Warner Losh csnet: warner%hydrovax@nmtsun uucp: ...{cmcl2, ihnp4}!lanl!unmvax!nmtsun!warner%hydrovax ...{cmcl2, ihnp4}!lanl!unmvax!nmtsun!hydrovax Warning: Hydrovax is both a machine, and an account, so be careful.
mike@arizona.edu (Mike Coffin) (01/17/88)
In article <1868@bsu-cs.UUCP>, dhesi@bsu-cs.UUCP (Rahul Dhesi) writes: > [...] > Zero symmetrically divides the number line. If one had to choose ONE > of the values on the number line as being unique, it would have to be > zero. It is the only value that isn't arbitrary, the only one that > doesn't have a mirror-image counterpart (of opposite sign), the only > one that can't be a legal divisor, the only one that, in short, > stands out as "different" from all the other values. One (1) symmetrically divides the number line. If one had to choose ONE of the values on the number line as being unique, it would have to be one. It is the only value that isn't arbitrary, it only one that is a multiplicative identity, the only number of noses on my face, the only one, in short, that stands out as "different" from all the other values. :-> -- Mike Coffin mike@arizona.edu Univ. of Ariz. Dept. of Comp. Sci. {allegra,cmcl2,ihnp4}!arizona!mike Tucson, AZ 85721 (602)621-42
g-rh@cca.CCA.COM (Richard Harter) (01/17/88)
In article <1868@bsu-cs.UUCP> dhesi@bsu-cs.UUCP (Rahul Dhesi) writes: >I gave a number of example attempting to show that zero is inherently >a unique integer and therefore not a "magic number" in the usual >sense of the term. > ... Discussion of the properties of zero deleted ... > >It seems to make perfect sense to me that in the non-VMS world in which >a single successful termination value, and multiple failure termination >values, are needed, zero should be the successful termination value. > >Therefore the use of exit(0) for successful termination is not >arbitrary. It is intuitively correct. This is perhaps my fault for assuming that everyone knows what is meant by a magic number, as in "don't use magic numbers". Let me give an example. Look at the following code: char foo[57]; .... for(i=0;i<57;i++) {...} foo[55]='\n'; foo[56]='\0'; As we all know, this kind of code is likely to create maintenance problems. If, for some reason, we want to change the size of foo, we must identify and change every occurence of 57, including the indirect ones. Experienced programmers will prefer something like this #define size 57 .... char foo[size]; .... for (i=0;i<size;i++) {...} foo[size-2]='\n'; foo[size-1]='\0'; This has two advantages. The number, 57, is explicitly referenced only once, which makes it much easier to alter. The name, size, has a specific meaning that is relevant to, and limited to, its actual usage. A magic number is a number embedded in code that has a special meaning in the context of the code. In this context 57 is a magic number. 0,1, and 2, as used, are not, because they are implied by the conventions of the language. Note that it is the usage and meaning that determines whether a number is a magic number or not. It is considered good programming practice to avoid using magic numbers. Numbers which represent encoded values are magic numbers. For example, if I write a function which returns a number returning a color, with 0=red, 1=blue, and 2=green, I will do better if my code says return red; (with read appropriately defined) than if I say return 0; In addition to the two advantages I cited above, there is a third advantage in this case. If I hard code the encoded values, the encodings have to be known in two places -- in my function and in the program(s) calling my function. Life will clearly be simpler if the encodings are in a common place shared by my function and the program(s) that call my function. This will be particularly true if my function is going to be used by several different programs which may use different encodings. My apologies for going on at length about basic principles, but it would appear that these thoughts are novel for some people. Rahul argues above that zero has various special properties, and that it is therefore the "best" choice for representing successful termination. This is irrelevant. It doesn't matter whether zero is the "best" choice or not. It would still be bad practice to return zero, even if all operating systems accepted it as meaning successful termination. As we know, some do, and some do not. I will concede that 'exit(0)' is standard practice in UNIX environments, and that there has been, heretofore, for standard for sharing encodings of the returned value with the host operating system. I also recognize that if you are only concerned with C programs running under UNIX, then it won't matter if you write exit(0). If it doesn't matter in your case, and you are not a purist about good programming practice, then the issue is moot. If, however, you are dealing with software that will have to run on a variety of machines and operating systems then it matters very much. -- In the fields of Hell where the grass grows high Are the graves of dreams allowed to die. Richard Harter, SMDS Inc.
sns@genghis.UUCP (Sam Southard) (01/18/88)
In article <1868@bsu-cs.UUCP>, dhesi@bsu-cs.UUCP (Rahul Dhesi) writes: > Zero symmetrically divides the number line. If one had to choose ONE Let me choose one. There are the same number of numbers greater than one as there are less than one, so one must symmetrically divide the number line. > of the values on the number line as being unique, it would have to be > zero. It is the only value that isn't arbitrary, the only one that > doesn't have a mirror-image counterpart (of opposite sign), the only > one that can't be a legal divisor, the only one that, in short, > stands out as "different" from all the other values. If we had to choose ONE of the values on the number line as being uniqe, it would have to be one. It is the only value that isn't arbitrary, the only one which when multiplying or dividing another number yields the same number, the only one whose mirror image is the square of 'i', the only one that, in short, stands out as "different" from all the other values. > Therefore the use of exit(0) for successful termination is not > arbitrary. It is intuitively correct. Therefore the use of exit(0) for successful termination is completely arbitrary. Obviosly, the intuitive value is exit(1). Rahul, *every* number has unique properties. Those of one and zero simply stand out more and are more significant. -- Sam Southard, Jr. {sns@genghis.caltech.edu|sns@genghis.uucp|{backbone}!cit-vax!genghis!sns}
rsalz@bbn.com (Rich Salz) (01/18/88)
>Under 4.3BSD, there is a <sysexits.h> which does include a bunch of >standard return values like EX_USAGE, EX_NOPERM, and others ... > Mark Eichin The sysexits.h file was originally written by Eric Allman as part of the original sendmail distribution (shortly after 4.1c, I think). When 4.2 was released the file made its way into /usr/include. Apparently /usr/include was already filled up, so the Berkeley folks decided to move <time.h> into <sys/time.h> as a tradeoff, thereby forcing thousands of Makefile writers to add -I/usr/include/sys to their DEFS macro. Getting back to reality, I have word from ATT that they have absolutely no claim on sendmail, and a Berkeley spokesman says that (quoting from personal e-mail) "it is redistributable as long as due credit is given to the University." With such credit given, then... HEY, YOU: Further discussion on error codes -- especially this file -- probably isn't relative to this "C" newsgroup or mailing list. /r$ /* ** SYSEXITS.H -- Exit status codes for system programs. ** ** This include file attempts to categorize possible error ** exit statuses for system programs, notably delivermail ** and the Berkeley network. ** ** Error numbers begin at EX__BASE to reduce the possibility of ** clashing with other exit statuses that random programs may ** already return. The meaning of the codes is approximately ** as follows: ** ** EX_USAGE -- The command was used incorrectly, e.g., with ** the wrong number of arguments, a bad flag, a bad ** syntax in a parameter, or whatever. ** EX_DATAERR -- The input data was incorrect in some way. ** This should only be used for user's data & not ** system files. ** EX_NOINPUT -- An input file (not a system file) did not ** exist or was not readable. This could also include ** errors like "No message" to a mailer (if it cared ** to catch it). ** EX_NOUSER -- The user specified did not exist. This might ** be used for mail addresses or remote logins. ** EX_NOHOST -- The host specified did not exist. This is used ** in mail addresses or network requests. ** EX_UNAVAILABLE -- A service is unavailable. This can occur ** if a support program or file does not exist. This ** can also be used as a catchall message when something ** you wanted to do doesn't work, but you don't know ** why. ** EX_SOFTWARE -- An internal software error has been detected. ** This should be limited to non-operating system related ** errors as possible. ** EX_OSERR -- An operating system error has been detected. ** This is intended to be used for such things as "cannot ** fork", "cannot create pipe", or the like. It includes ** things like getuid returning a user that does not ** exist in the passwd file. ** EX_OSFILE -- Some system file (e.g., /etc/passwd, /etc/utmp, ** etc.) does not exist, cannot be opened, or has some ** sort of error (e.g., syntax error). ** EX_CANTCREAT -- A (user specified) output file cannot be ** created. ** EX_IOERR -- An error occurred while doing I/O on some file. ** EX_TEMPFAIL -- temporary failure, indicating something that ** is not really an error. In sendmail, this means ** that a mailer (e.g.) could not create a connection, ** and the request should be reattempted later. ** EX_PROTOCOL -- the remote system returned something that ** was "not possible" during a protocol exchange. ** EX_NOPERM -- You did not have sufficient permission to ** perform the operation. This is not intended for ** file system problems, which should use NOINPUT or ** CANTCREAT, but rather for higher level permissions. ** For example, kre uses this to restrict who students ** can send mail to. ** ** Maintained by Eric Allman (eric@berkeley, ucbvax!eric) -- ** please mail changes to me. ** ** @(#)sysexits.h 4.2 7/31/83 */ # define EX_OK 0 /* successful termination */ # define EX__BASE 64 /* base value for error messages */ # define EX_USAGE 64 /* command line usage error */ # define EX_DATAERR 65 /* data format error */ # define EX_NOINPUT 66 /* cannot open input */ # define EX_NOUSER 67 /* addressee unknown */ # define EX_NOHOST 68 /* host name unknown */ # define EX_UNAVAILABLE 69 /* service unavailable */ # define EX_SOFTWARE 70 /* internal software error */ # define EX_OSERR 71 /* system error (e.g., can't fork) */ # define EX_OSFILE 72 /* critical OS file missing */ # define EX_CANTCREAT 73 /* can't create (user) output file */ # define EX_IOERR 74 /* input/output error */ # define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */ # define EX_PROTOCOL 76 /* remote error in protocol */ # define EX_NOPERM 77 /* permission denied */ -- For comp.sources.unix stuff, mail to sources@uunet.uu.net.
hydrovax@nmtsun.nmt.edu (M. Warner Losh) (01/18/88)
Mark Eichin write that using exit(0) is OS sepcific, when in fact it is ENVIRONMENT specific. True enough that all of the SHELLS that UN*X uses use an exit status of zero to mean success (at least all of the one's that I know of). It is the SHELL, NOT THE OPERATING SYSTEM, that is the factor here. If you were programming on VMS, where you could have the dcl shell (or more correctly (from a VMS point of view :-), command interpreter [sic on spelling]) that treats an exit status of on ODD number as success, and an EVEN (for error, I quess) number as an error. On the same machine, running the same OS, you can also have DEC/Shell, which assumes a more "unix" oriented posture. That is, it expects the "exit(0)" convention. As a side note. exit(0) in UNIX isn't quit correct. The UNIX shell, as far as I know, doesn't give a hill of beans wheather you say exit(0), exit(1000), exit (magic_number).... It is the SHELL SCRIPTS that people write that impose this "standard" upon UNIX. I could be wrong about this, but I seem to remeber reading in one of the books/manuals/mag articles about unix that this was the case. I know it's common practice, but is it required? Plesae resond only if YOU KNOW FOR SURE. -- bitnet: lush@nmt.csnet M. Warner Losh csnet: warner%hydrovax@nmtsun uucp: ...{cmcl2, ihnp4}!lanl!unmvax!nmtsun!warner%hydrovax ...{cmcl2, ihnp4}!lanl!unmvax!nmtsun!hydrovax Warning: Hydrovax is both a machine, and an account, so be careful.
hydrovax@nmtsun.nmt.edu (M. Warner Losh) (01/18/88)
In article <1868@bsu-cs.UUCP>, dhesi@bsu-cs.UUCP (Rahul Dhesi) writes: > Zero symmetrically divides the number line. If one had to choose ONE > of the values on the number line as being unique, it would have to be > zero. It is the only value that isn't arbitrary, the only one that > doesn't have a mirror-image counterpart (of opposite sign), the only > one that can't be a legal divisor, the only one that, in short, > stands out as "different" from all the other values. > Because it is, as you say, different, it is magic. That is one of the definitions of a magic number. It is different, yet arbitrary. btw, your arguement that it isn't arbitrary is BOGUS. I could easily come up with simialar arguements that one (SS$_NORMAL, the normal exit status in VMS) isn't arbitrary : If you have something, then the least whole number of it you can have is one. Therefore one isn't arbitrary. :-) * 16 The point is, that in this case, ZERO, or ANY OTHER NUMBER THAT YOU CHOSSE TO REPESENT SUCCESS IS arbitrary. Come on Rahul, you will have to do better than that if you want to convince anybody that zero isn't arbitrary. -- bitnet: lush@nmt.csnet M. Warner Losh csnet: warner%hydrovax@nmtsun uucp: ...{cmcl2, ihnp4}!lanl!unmvax!nmtsun!warner%hydrovax ...{cmcl2, ihnp4}!lanl!unmvax!nmtsun!hydrovax Warning: Hydrovax is both a machine, and an account, so be careful.
goudreau@xyzzy.UUCP (Bob Goudreau) (01/18/88)
In article <1868@bsu-cs.UUCP> dhesi@bsu-cs.UUCP (Rahul Dhesi) writes: >I gave a number of example attempting to show that zero is inherently >a unique integer and therefore not a "magic number" in the usual >sense of the term. >.... >It seems to make perfect sense to me that in the non-VMS world in which >a single successful termination value, and multiple failure termination >values, are needed, zero should be the successful termination value. > >Therefore the use of exit(0) for successful termination is not >arbitrary. It is intuitively correct. Gee that's swell, but it still doesn't address the issue of the magic number. You can stamp your feet and pout all you want at "non-intuitive" operating systems, but your code still won't port to them easily. Doug Gwyn is still correct: zero is definitely a magic number when used as the successful termination value. Your point about zero as the first index to an array is irrelevant: such behavior is part of the specification of the C language. Return statuses are OS-dependent, and are explicitly beyond the scope of X3J11.
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/18/88)
In article <304@fig.bbn.com> rsalz@bbn.com (Rich Salz) writes: >** SYSEXITS.H -- Exit status codes for system programs. Use this on UNIX systems if you wish; it is NOT suitable for use on some other operating systems.
leichter@yale.UUCP (Jerry Leichter) (01/19/88)
In article <7121@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes: >In article <304@fig.bbn.com> rsalz@bbn.com (Rich Salz) writes: >>** SYSEXITS.H -- Exit status codes for system programs. > >Use this on UNIX systems if you wish; it is NOT suitable for use on some >other operating systems. On the other hand, the NAMES and their respective meanings would make sense on any operating system. If you are willing to (a) use only macros from SYSEXITS.H in calls to exit() or as values returned by main(); and (b) go through the fairly simple exercise of creating a SYSEXITS.H with values appropriate to a particular operating system you want to port to; then your code will be very portable (at least in this one respect). Of course, if SYSEXITS.H were to become standard - either part of an ANSI C standard, or a defacto standard - then (b) becomes unnecessary, since some- one will already have done the work. ...and THAT, of course, was the whole point. (I'm sure Doug understands this, but it might have gotten missed in his very brief response.) (It should be noted, though, that the list of errors was clearly chosen with a particular kind of program - a mailer - in mind. While some of them are more generally useful ("No permission"), others are rather specialized ("Protocol error"), and there are probably other, more generally-useful errors that would have to be included to create a truely useful, general- purpose "SYSEXITS" file.) -- Jerry
malloy@crash.cts.com (Sean Malloy) (01/19/88)
In article <3475@megaron.arizona.edu> mike@arizona.edu (Mike Coffin) writes: >In article <1868@bsu-cs.UUCP>, dhesi@bsu-cs.UUCP (Rahul Dhesi) writes: >> [...] >> Zero symmetrically divides the number line. If one had to choose ONE >> [...] >> one that can't be a legal divisor, the only one that, in short, >> stands out as "different" from all the other values. >One (1) symmetrically divides the number line. If one had to choose ONE > [...] >only one, in short, that stands out as "different" from all the other >values. :-> No, zero has to be more 'different'. Zero is the number of subjects concerning the internals of C which can be discussed without accreting huge quantities of flames, stupid comments, and "I would do it this way" followups. -- Sean Malloy {hplabs!hp-sdd, akgua, sdcsvax, nosc}!crash!malloy ARPA: crash!malloy@nosc Naval Personnel Research and Development Center San Diego, CA 92152-6800 UUCP: {hplabs!hp-sdd, akgua, sdcsvax}!nprdc!malloy ARPA: malloy@nprdc
chris@mimsy.UUCP (Chris Torek) (01/19/88)
In article <1225@nmtsun.nmt.edu> hydrovax@nmtsun.nmt.edu (M. Warner Losh) writes: >... The more proper VMS implementation of EXIT_STATUS should be >SS$_NORMAL, which is (at least in 4x) defined to be 1. (I think it was inherited from RT-11. It was 1 in VMS 2.8.) >Why would you expect an operating system dependent scheme such >as exit(0) to work on all OS's? Simple. Let me phrase it this way: `Why would you expect a standard library scheme to be dependent on the O/S?' Or, `whoever said exit was a system call?' Unix, by virtue of being the first system to implement the language, is privileged: it gets to take the argument to exit() and pass it back to the calling program. Other systems might have to convert the argument to 0 => success, anything else => unspecified failure. (Actually, other systems might attempt to map the exits in <sysexits.h>.) This---a boolean success/failure indication---is as much as, or perhaps even more than, a portable standard could guarantee. Specific systems would also provide system specific versions of exit(). Indeed, Unix systems might define either _unix_exit(int status) { exit(status); } or exit(int status) { _unix_exit(status); } (symmetry means never having to say `oops' :-) ) VMS would provide exit(int status) { _vms_exit(_vms_map(status)); } while AOS/VS would provide exit(int stauts) { _aos_exit(_aos_map(status)); } Of course, this is not what the dpANS says, so the argument is rather pointless. But this is what should have been done. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
wesommer@athena.mit.edu (William E. Sommerfeld) (01/19/88)
In article <1225@nmtsun.nmt.edu> hydrovax@nmtsun.nmt.edu (M. Warner Losh) writes: >Am I missing something here, or are you saying that because VMS cause >this so-called mess, that they should have to live with a UNIX like >kludge, just to make you happy? When you exit(0) on VMS you get the error > >%NONAME-W-NOMESSAGE, No message text for message 0000000 > >or something similar. Remember that VMS is not really 'C' based, and >much of the code is written in a whole slew of languages. So what. You can use exit(), fork(), etc. from BSD UNIX FORTRAN and Pascal. > Would you propose that all of that be rewritten? If ANSI doesn't support this, it effectively means that someone will have to rewrite all the UNIX code which does this to use EXIT_SUCCESS and EXIT_FAILURE. VMS is just one machine-dependant, non-portable OS, whereas UNIX can runs on any hardware that VMS can, and then some. >The more proper >VMS implementation of EXIT_STATUS should be SS$_NORMAL, which is >(at least in 4x) defined to be 1. Why would you expect an operating >system dependent scheme such as exit(0) to work on all OS's? The whole >world isn't using UNIX. UNIX is not the only system where zero is success, and non-zero is failure; for example, Multics `system calls' and library routines return a status codes which are zero on success, and non-zero on failure. Multics is by no means C based, either... I would say that, of the systems I have seen, it is far more common to use 0->success, nonzero->failure. Besides, on most architectures (except for the VAX), it's easier to test a whole word against zero than it is to test the lower bit. Since you want multiple error values to distinguish between different cases, and also want to make testing for success as cheap as possible, this implies that 0 must be success. It would make a _lot_ of sense if VMS C were to ``go with the flow'' and change exit() so that it actually returned (code ? (code << 1) : 1), assuming that even return codes mark failure, and odd ones mark success?), or, if that wasn't feasible, (code ? SS$_FAILURE : SS$_SUCCESS) An emulation of wait() could perform the reverse transformation for the benefit of things which wanted to call out to other processes, assuming that you can emulate the UNIX fork() and wait() calls under VMS. If you wanted to write VMS-specific code, you could use the system calls directly to talk to other system functions, but then you would _NOT_ have portable code. The implementation can define additional routines (vms_exit(), or whatever) if they wanted to return "success, sort of" (is that what the other success codes mean?) instead of just a straight success or failure indication. - Bill
mwm@eris (Mike (My watch has windows) Meyer) (01/19/88)
In article <1868@bsu-cs.UUCP> dhesi@bsu-cs.UUCP (Rahul Dhesi) writes:
<I gave a number of example attempting to show that zero is inherently
<a unique integer and therefore not a "magic number" in the usual
<sense of the term.
# mount /dev/mathematicians_hat /head
Rahul, *all* numbers are unique and interesting. Even 1729. You can
even proof it, if you like. I dislike zero because there's no
primitive operate that generates a common set when applied to zero.
One and either of + or - generates a common set.
# umount /dev/mathematicians_hat
# mount /dev/programmers_hat /head
<Therefore the use of exit(0) for successful termination is not
<arbitrary. It is intuitively correct.
I don't see anything intuitive about exiting with a false value for
success. Exiting with a true value seems a lot more intuitive to me.
<mike
--
How many times do you have to fall Mike Meyer
While people stand there gawking? mwm@berkeley.edu
How many times do you have to fall ucbvax!mwm
Before you end up walking? mwm@ucbjade.BITNET
eichin@athena.mit.edu (Mark W. Eichin) (01/19/88)
This looks much too simple to me: In C: exit(ansi_status) int ansi_status; { int vms_status; switch(ansi_status) { case 0: vms_status = SS$EXIT; /* == 1 */ break; case 1: /* .... fill in other ANSI codes and there VMS equivalents .... */ default: vms_status = SS$WEIRD; /* you know what I mean... */ } vms_$exit(vms_status); /* getting out for real */ } In English: The ANSI values for arguments to exit() do NOT specify what the program must return to the operating system! They map status meanings to the >>>argument of exit()<<< which will then get shuffled off into the operating system as anything it wants... The question that should follow is "what about system() or exec()/wait(), what should they return?" Well, ANSI could probably specify that too, and any operating system that needed to do a mapping for exit() could just reverse the mapping... Thus, the arguments seem to result from the neglect of the idea that simple units specified by ANSI could have deeper implementations. Am I missing something dreadful here? [The details are fuzzy, my knowledge of the VMS problem derives solely from these postings... but this idea SEEMS sound.] Mark Eichin <eichin@athena.mit.edu> Mark Eichin <eichin@athena.mit.edu> SIPB Member & Project Athena ``Watchmaker''
dhesi@bsu-cs.UUCP (Rahul Dhesi) (01/19/88)
In article <10237@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes: >Unix, by virtue of being the first system to implement the language, >is privileged: it gets to take the argument to exit() and pass it >back to the calling program. Other systems might have to convert >the argument to 0 => success, anything else => unspecified failure. A Daniel come to judgement! -- Rahul Dhesi UUCP: <backbones>!{iuvax,pur-ee,uunet}!bsu-cs!dhesi
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/19/88)
In article <21531@yale-celray.yale.UUCP> leichter@yale-celray.UUCP (Jerry Leichter) writes: >On the other hand, the NAMES and their respective meanings would make sense >on any operating system. No! Many operating systems cannot return such a variety of termination statuses. And it would do little good to have several of them mapped into the same value. Plus, there are zillions of possible reasons for program failure, and any pre-established list cannot cover enough of them. I think we're doing quite well to get just the two, generic failure and generic success, standardized.
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/19/88)
In article <1225@nmtsun.nmt.edu> hydrovax@nmtsun.nmt.edu (M. Warner Losh) writes: >Why would you expect an operating system dependent scheme such as exit(0) >to work on all OS's? The whole world isn't using UNIX. You guys have gotten confused. X3J11, including the VMS C implementor, agreed to the following: #include <stdlib.h> /* defines EXIT_SUCCESS & EXIT_FAILURE */ exit(0); /* indicates success on all OSes */ exit(EXIT_SUCCESS); /* indicates success on all OSes */ exit(EXIT_FAILURE); /* indicates failure on all OSes */ If, as you report, VMS C does not currently map exit(0) to something sensible, that will have to be fixed before VMS C is ANSI-conforming. >%NONAME-W-NOMESSAGE, No message text for message 0000000 Certainly this is not something that is essential to preserve on VMS!
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/19/88)
In article <6597@agate.BERKELEY.EDU> mwm@eris.UUCP (Mike (My watch has windows) Meyer) writes: >Rahul, *all* numbers are unique and interesting. Even 1729. 1729 is especially interesting, or "not dull" as Ramanujan would say. However, those who haven't already heard about it wouldn't get the joke anyway. >You can even [prove] it, if you like. Let U = { n : n positive integer AND n is uninteresting }. Assume (*) that U is a non-empty set. It must have a least member, call it m. But, since m is the smallest uninteresting integer, it is quite interesting. This means it could not have been in U. But that is a contradiction. Therefore the assumption (*) must be false. Therefore there are no uninteresting positive integers. QED :-)
tanner@ki4pv.uucp (Dr. T. Andrews) (01/19/88)
In article <334@splut.UUCP>, jay@splut.UUCP writes: ) In article <7208@ki4pv.uucp>, tanner@ki4pv.uucp (Dr. T. Andrews) writes: )> [ remarks supporting exit(0) deleted ] ) for(i = 0; i < 100; i++) { ) repeat_after_me('All the world does not run on Unix, either.'); ) } He's right. Much of the world doesn't run unix. Much of the world does run C, however, and that means that somewhere out there we have people implementing C compilers in diverse environments. In fact, I had the pleasure of supporting just such a beast. In one environment where exit status didn't have the same system-defined meaning, I went and did the right thing: I implemented an exit() with the standard (in the old sense, not in the X3J11 sense) meaning. My exit(0) did the right thing; my exit(non_zero) also did the right thing. It seems reasonable that the vax implementor should also take the trouble to do the right thing. If the vax folks wish to do something strange with vms_exit status, then they and the compiler vendor are free to implemnt a VMS-specific exit routine (vms_exit(), perhaps) which supports the funny meanings like "failed, no errors" and "worked, but fatal errors". However, since this code will be VMS specific, the implementation should only affect VMS sites. The rest of the world's code, which uses things like exit(0), exit(1), and of course the ever-popular exit(n_err), should continue to be supported. Perhaps it's time for something like this: for ( i=101 ; --i ; ) repeat_after_me("standards codify existing practice\n"); -- {allegra clyde!codas decvax!ucf-cs ihnp4!codas killer}!ki4pv!tanner
ok@quintus.UUCP (Richard A. O'Keefe) (01/20/88)
In article <7133@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes: > In article <1225@nmtsun.nmt.edu> hydrovax@nmtsun.nmt.edu (M. Warner Losh) writes: > >Why would you expect an operating system dependent scheme such as exit(0) > >to work on all OS's? The whole world isn't using UNIX. > If, as you report, VMS C does not currently map exit(0) to something > sensible, that will have to be fixed before VMS C is ANSI-conforming. Everything that has been said about VMS and exit(0) so far is false. I decide that it was time to check the manual. Programming in VAX C Order Number AA-L370B-TE For VAX/VMS version 4.0 or later Compiler version VAX C version 2.0 April 1985. Section 22.1.2 exit, _exit exit([status]) _exit([status]) The optional argument status corresponds with [sic!] an errno value. ... The functions return the specified status to the parent process. ... The two functions are identical. [I do not understand how an argument can exchange letters with (correspond with) a number. No doubt they meant "correspond to". Aren't eddicayshun wunnerful?] Checking SYS$LIBRARY:ERRNO.H, I found that not only were the errno symbols (such as EPERM) the same as in UNIX, they had been given the same numbers as well. It is clear, therefore, that in the VMS implementation of C, the argument of exit() is a ***UNIX*** error number (including 0 as specifying NO error), *NOT* a VMS error code. Trying several values of N in main() { exit(N); } and main() { return N; } I found that *none* of them resulted in any message from DCL; *all* of them produced a quiet exit. {But the return code was available to DCL for inspection, and perror() does plausible things.} VAX-11 C does more optimisation than most C compilers do. For compatibility with other compilers, the preprocessor accepts but IGNORES #pragma. I wonder about the other compilers that "need" it, I really do.
dhesi@bsu-cs.UUCP (Rahul Dhesi) (01/21/88)
In article <551@cresswell.quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes: >Everything that has been said about VMS and exit(0) so far is false. ... >I found that *none* of them resulted in any message from DCL; >*all* of them produced a quiet exit. The time frame of discussion is important. DEC has recently revised its C compiler for VMS. Some things formerly missing are now present, and the old exit(0) problem ("No text for message 0000" etc.) has been fixed. -- Rahul Dhesi UUCP: <backbones>!{iuvax,pur-ee,uunet}!bsu-cs!dhesi
ok@quintus.UUCP (Richard A. O'Keefe) (01/21/88)
In article <7292@ki4pv.uucp>, tanner@ki4pv.uucp (Dr. T. Andrews) writes: > ) for(i = 0; i < 100; i++) { > ) repeat_after_me('All the world does not run on Unix, either.'); > ) } > specific, the implementation should only affect VMS sites. The rest > of the world's code, which uses things like exit(0), exit(1), and > of course the ever-popular exit(n_err), should continue to be supported. > If you are using UNIX, ***DON'T*** use exit(n_err)! Why? Because the error code is truncated to EIGHT BITS. So 256, 512, 768 errors and so on look exactly like ZERO errors. There are a couple of UNIX utilities which do things like returning the number of files they couldn't read. Which of course makes them useless in scripts unless you first check that they are given fewer than 256 files... exit(n_err) has never worked in UNIX, which is the original home of C. How can you "continue to support" something which has always been broken? Just to repeat an earlier point: exit(0) and exit(1) ***DO*** work in VMS. I think I was the one to start this exchange about exit() in C, and my original point was that exit(-1) *does not work in UNIX*. I suggested sticking to 0 and 1 because they *do* work in UNIX *and* in VMS. We're also interested in IBM MVS and VM/CMS, so here's another data point: IBM Systems Application Architecture Common Programming Interface C Reference [SC266-4353-0] For MVS, VM, and OS/2 says, on page 202, void exit(int status) set status to 0 to indicate a normal exit or to some other value to indicate an error. Control, and the value of status, is returned to the operating system. This also works in SAS Lattice C. (Apparently under OS, exit(x) where x > 4095 is truncated to exit(4095).) The bottom line is that 0 for success, 1 for failure *is* portable between UNIX, VAX/VMS, IBM-MVS, IBM-VM/CMS, and IBM-OS/2, and that exit(n) for n < 0 or n > 255 never "worked" in UNIX either.
TLIMONCE%DREW.BITNET@CUNYVM.CUNY.EDU (01/21/88)
Can someone post how ANSI proposes to handle this situation? I think I remember someone mentioning the method and it sounded very good. Can we hear the whole story? Tom Limoncelli Drew U/Box 1060/Madison NJ 07940 Bitnet: tlimonce@drew.BITNET Disclaimer: These are my views, not my employer or Drew Univesity. --------------------------------------------------------------------------
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/21/88)
In article <7292@ki4pv.uucp> tanner@ki4pv.uucp (Dr. T. Andrews) writes: >Perhaps it's time for something like this: > for ( i=101 ; --i ; ) > repeat_after_me("standards codify existing practice\n"); for ( ; ; ) repeat_after_me( "there is no single \"existing practice\"" "in this case\n" );
wen-king@cit-vlsi.Caltech.Edu (Wen-King Su) (01/22/88)
In article <555@cresswell.quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes: >In article <7292@ki4pv.uucp>, tanner@ki4pv.uucp (Dr. T. Andrews) writes: <Just to repeat an earlier point: exit(0) and exit(1) ***DO*** work in VMS. >I think I was the one to start this exchange about exit() in C, and my <original point was that exit(-1) *does not work in UNIX*. I suggested >sticking to 0 and 1 because they *do* work in UNIX *and* in VMS. This seems a little strange to me so I decided to check it out. Following is a script showing that exit(-1) DOES work in UNIX. I am running it on a SUN and I am using csh. Script started on Thu Jan 21 10:19:36 1988 % cat t.c main() { exit(-1); } % t % echo $status -1 % t & [1] 5825 % [1] Exit -1 t % ^D script done on Thu Jan 21 10:20:03 1988 I agree that it is a good idea to have 0 as the universal indicator of success, but I believe application programmers should be free to use other numbers to their own advantage and OS should provide them with the maximum flexibility. The issue of portability is something each programmer has to decide for <arrg!!>self, but it is always useful for those who had the experience to point out trouble spots and recommend solutions. /*------------------------------------------------------------------------*\ | Wen-King Su wen-king@vlsi.caltech.edu Caltech Corp of Cosmic Engineers | \*------------------------------------------------------------------------*/
hydrovax@nmtsun.nmt.edu (M. Warner Losh) (01/22/88)
In article <10237@mimsy.UUCP>, chris@mimsy.UUCP (Chris Torek) writes: > In article <1225@nmtsun.nmt.edu> I write > >... The more proper VMS implementation of EXIT_STATUS should be > >SS$_NORMAL, which is (at least in 4x) defined to be 1. > > (I think it was inherited from RT-11. It was 1 in VMS 2.8.) > > >Why would you expect an operating system dependent scheme such > >as exit(0) to work on all OS's? > > Simple. Let me phrase it this way: `Why would you expect a standard > library scheme to be dependent on the O/S?' Or, `whoever said exit > was a system call?' If I remember correctly, fopen() is system dependent (you can't say fopen ("/tmp/foo", "r"), for example, and expect it to work on all operating systems. The same sort of thing is true about exit(). > Unix, by virtue of being the first system to implement the language, > is privileged: it gets to take the argument to exit() and pass it > back to the calling program. Other systems might have to convert > the argument to 0 => success, anything else => unspecified failure. The UNIX operating system does not work this way. The shells that surround it DO. What I mean is this : UNIX doesn't give a furry rat's whatever what you use for an exit status, it mearly passes it to the shell (or to make, or whatever) who then desides what to do with that number. Even the shell doesn't care what value you give it, as long as you give it something. Most people choose to use zero, cause that's what K&R say to use. Not that I'm slamming UNIX, or anything, that's just what's goin' on behind the scenes. In VMS, the exit status is more than just any arbitrary number. Each of the numbers has a perscribed meaning. The numbers are interpeted, again by the shell (to use the UNIX terminology; command interpreter to use DEC's), as meaning success or failure. Again, these exit values are useful to the shell, or shell scripts that are running (DCL command files) IN ADDITION TO THE SHELL ITSELF. There are mechanisms to allow you to say "When a warning, or anything more sever occures, then branch to this part of my DCL program". The basic argument is this: Since UNIX had it first, should all other OS's be forced to use that convention? I think not. THIS IS AN OPERATING SYSTEM DEPENDENT ISSUE, just like file names. It should be delt with in a reasonably intelligent mannor, so that ALL PARTIES involved CAN WRITE PORTABLE CODE. Isn't that what ANSI is all about????? -- bitnet: lush@nmt.csnet M. Warner Losh csnet: warner%hydrovax@nmtsun uucp: ...{cmcl2, ihnp4}!lanl!unmvax!nmtsun!warner%hydrovax ...{cmcl2, ihnp4}!lanl!unmvax!nmtsun!hydrovax Warning: Hydrovax is both a machine, and an account, so be careful.
sarge@scheme.Berkeley.EDU (Steven Sargent) (01/22/88)
The UNIX shells absolutely enforce the 0 vs. nonzero exit status distinction. 1. The usages (Shell) if cmdlist; then stuff; else stuff; fi (csh) if ({cmd}) then stuff; else stuff; endif along with their loop analogues, make the decision based on exit status of cmd (or of the last command in cmdlist). 2. The Shell's operators && and || also work this way, i.e., in foo && bar bar is executed only if foo exits happily. 3. The Shell has a command-line option (-e) that causes a script to exit whenever a command exits nonzeroly. All this (and more, I'm sure; but csh is of less interest to me in this context) is available in the relevant manual pages. S.
ok@quintus.UUCP (Richard A. O'Keefe) (01/22/88)
In article <5262@cit-vax.Caltech.Edu>, wen-king@cit-vlsi.Caltech.Edu (Wen-King Su) writes: > In article <555@cresswell.quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes: > <original point was that exit(-1) *does not work in UNIX*. I suggested > >sticking to 0 and 1 because they *do* work in UNIX *and* in VMS. > > This seems a little strange to me so I decided to check it out. > Following is a script showing that exit(-1) DOES work in UNIX. To summarise, cat <<EOF >t.c main(argc, argv) int argc; char **argv; { exit(argc >= 2 ? atoi(argv[1]) : -1); } EOF cc -o t t.c He ran this program on a SUN, and claimed that it works. I too shall run this on a SUN. Behold! Script started on Thu Jan 21 20:09:54 1988 % csh % t ; echo $status -1 % t 254 ; echo $status -2 % exit % sh $ t ; echo $? 255 $ t -2 ; echo $? 254 $ exit % exit script done on Thu Jan 21 20:10:42 1988 To repeat my point, UNIX truncates the argument to 8 bits. The Bourne shell treats this as an unsigned char. The C shell treats this as a signed char. Note that on a SUN, according to /usr/include/sys/wait.h (the include file which describes the termination status result that is returned to a process's parent) the Bourne shell is right (the field is described as unsigned short w_Retcode:8;) and the C shell is wrong. I don't want to argue for one or the other, only to point out that they are different, so exit(-1) isn't even portable between two shells on the same machine! Wen-King Su also says: > success, but I believe application programmers should be free to use > other numbers to their own advantage and OS should provide them with > the maximum flexibility. The issue of portability is something each > programmer has to decide for <arrg!!>self, but it is always useful for > those who had the experience to point out trouble spots and recommend > solutions. Well, yes, but before using other numbers to their own advantage, application programmers should at least take the trouble to read the manuals (on a SUN, man 2 exit says explicitly that the low order 8 bits of the status are made available through wait(2), and man 2 wait points you to <sys/wait.h> where those 8 bits are explicitly declared to be UNsigned). I am grateful to Wen-King Su, because I didn't know about this design bug in the C shell before. (The manual doesn't say that status can take negative values, though there is a comment about adding 0200 which may have some faint connexion.) Are there any implementations of C in which exit(0) and exit(1) do NOT work? Presumably there are, or the ANSI committee wouldn't have added the new macros (:-), but which are they?
sns@genghis.UUCP (Sam Southard) (01/23/88)
In article <1234@nmtsun.nmt.edu>, hydrovax@nmtsun.nmt.edu (M. Warner Losh) writes: > you could have the dcl shell (or more correctly (from a VMS point of view :-), > command interpreter [sic on spelling]) that treats an exit status of > on ODD number as success, and an EVEN (for error, I quess) number as Yet another reason not to use VMS - on VMS success is odd. -- Sam Southard, Jr. {sns@genghis.caltech.edu|sns@genghis.uucp|{backbone}!cit-vax!genghis!sns}
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/23/88)
In article <1234@nmtsun.nmt.edu> hydrovax@nmtsun.nmt.edu (M. Warner Losh) writes: >As a side note. exit(0) in UNIX isn't quit correct. The UNIX shell, >as far as I know, doesn't give a hill of beans wheather you say exit(0), >exit(1000), exit (magic_number).... No, there are shell built-ins such as "test" that "know" that only a 0 termination status indicates success. Note that only the low-order 8 bits of the exit status are significant on UNIX. Therefore, adding any multiple of 256 would have no effect (but don't do this, please!). The point that the exit status is interpreted by the execution environment, which is not necessarily synonymous with the "operating system", is correct. Saying that this is a "shell" is being too specific, however. In fact, even on UNIX it's not necessarily a shell, just the parent process.
ok@quintus.UUCP (Richard A. O'Keefe) (01/23/88)
In article <1234@nmtsun.nmt.edu>, hydrovax@nmtsun.nmt.edu (M. Warner Losh) writes (with spelling unchanged): > As a side note. exit(0) in UNIX isn't quit correct. The UNIX shell, > as far as I know, doesn't give a hill of beans wheather you say exit(0), > exit(1000), exit (magic_number).... It is the SHELL SCRIPTS that people > write that impose this "standard" upon UNIX. I could be wrong about this He is. sh(1): Option: set -e is "exit immediately if a command exits with a non-zero exit status". Control structures: Cmd1 && Cmd2 executes Cmd2 iff Cmd1 returns a zero exit status, Cmd1 || Cmd2 executes Cmd2 iff Cmd1 returns a non-zero exit status. if Cmds then ... treats zero exit status as true, non-zero as false. while Cmds do ... is the same. csh(1): Option: set -e means exit if a command terminates abnormally OR exits with NONZERO. "Builtin commands that fail return exit status `1', all other builtin command set status to `0'." && and || are as in sh(1); if and while take expressions, not commands, as arguments. make(1): "make normally terminates when a command returns non-zero status, unless the -i or -k option is in effect." It is quite definitely the shells which impose the convention 0 == success == true, non-zero ==failure == false, not the scripts. Try the following in a recent Bourne shell: # "foo N" prints true or false foo() { ( exit $1 ) && ( echo true ) || ( echo false ) } # try it foo 0 # true foo 1 # false This is relevant to some C programmers because the 0/non-0 convention is the direct opposite of the C convention. This confused me for a couple of days. It is possible to program around the non-zero-exit- status-means-failure convention, but it definitely is a convention that is supported by UNIX shells (not scripts) and by DEC/Shell in VMS. Note that this convention is reflected back into C by the system(3) command: system "returns the exit status of the shell". This means that the 0==success, non-zero==failure rule is visible to C. (You *do* check the result of calls to system(), don't you?) Alas, all that the Oct86 dpANS says about the result of system() is that system(NULL) returns non-zero to indicate that there is a command interpreter system(non-NULL) is completely implementation-defined. Beware, by the way. Due to byte sex problems, even in UNIX, the result of system() may be shifted left by 8 (it is on a SUN). We still have the question: exit(0) and exit(1) make sense in UNIX, VAX/VMS, IBM-MVS, and IBM-VM. Which implementations of C do they *not* work in? Which implementations of C do *not* use 0==success for system()?
hydrovax@nmtsun.nmt.edu (M. Warner Losh) (01/23/88)
In article <551@cresswell.quintus.UUCP>, ok@quintus.UUCP (Richard A. O'Keefe) writes: > > Trying several values of N in > main() { exit(N); } > and main() { return N; } > I found that *none* of them resulted in any message from DCL; > *all* of them produced a quiet exit. {But the return code was > available to DCL for inspection, and perror() does plausible things.} I have VMS version 4.4, running C version 2.2. When I do an exit(0);, I get the message that I posted. (The No message for this message message). In the 2.2 manual, section 22.1.2, it says that the value is returned to DCL "and a message is displayed". I guess that Version 2.3 fixes this problem. -- bitnet: lush@nmt.csnet M. Warner Losh csnet: warner%hydrovax@nmtsun uucp: ...{cmcl2, ihnp4}!lanl!unmvax!nmtsun!warner%hydrovax ...{cmcl2, ihnp4}!lanl!unmvax!nmtsun!hydrovax Warning: Hydrovax is both a machine, and an account, so be careful.
guy@gorodish.Sun.COM (Guy Harris) (01/23/88)
> Beware, by the way. Due to byte sex problems, even in UNIX, the > result of system() may be shifted left by 8 (it is on a SUN). Nope. This has nothing to do with byte sex problems, and is true on all non-broken UNIX implementations (even those with a byte size other than 8 bits). On UNIX systems, "system()" calls "wait()" to wait for the shell that runs the command to terminate; the value that "wait()" stuffs into the "int" pointed to by its first argument is what "system()" returns. The exit status of the shell is always shifted left by 8 in the value returned by "wait()"; the low order 8 bits are used if the shell stops or is terminated by a signal. (Ignore the fact that in BSD systems "wait" is nominally declared as returning a "union wait". The BSD *kernel* code still returns an "int", in the same way that all other UNIX implementations do. The "union wait" was, I presume, an attempt to make it easier to pull the exit status apart. Unfortunately, since the order of bit fields in a structure is implementation-dependent, that structure is not portable! Note that the Sun version of that structure has "#ifdef"s giving one definition for little-endian VAXes and another for big-endian Sun-3s and Sun-4s.) Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com
chris@mimsy.UUCP (Chris Torek) (01/23/88)
>In article <10237@mimsy.UUCP> I claimed that (in a better world) >>Unix, by virtue of being the first system to implement the language, >>is privileged: it gets to take the argument to exit() and pass it >>back to the calling program. Other systems might have to convert >>the argument to 0 => success, anything else => unspecified failure. In article <1240@nmtsun.nmt.edu> hydrovax@nmtsun.nmt.edu (M. Warner Losh) writes: > The UNIX operating system does not work this way. The shells that >surround it DO. This is true, and entirely irrelevant. Since the shells that surround it assume that 0 => success, anything else => unspecified failure, `Unix' (whatever that is) assumes 0 => success, anything else => unspecified failure. While there are programs that do not follow this convention, they are in the minority (and, incidentally, they are being weeded out, at least in 4BSD: /etc/dump recently changed to exit(0) instead of exit(1) on success). In other words, all we have to do is take this convention and establish it as a standard across all systems (including Unix!---where it is implemented entirely outside of the kernel, but it *is* implemented), and *everything* *works*. We have gained portability and lost nothing. >The basic argument is this: Since UNIX had it first, should all other >OS's be forced to use that convention? Since portability is gained, and nothing is lost, *YES*. This is then a *language* convention, *not* an operating system convention. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
ok@quintus.UUCP (Richard A. O'Keefe) (01/23/88)
In article <39799@sun.uucp>, guy@gorodish.Sun.COM (Guy Harris) writes: > > Beware, by the way. Due to byte sex problems, even in UNIX, the > > result of system() may be shifted left by 8 (it is on a SUN). > > Nope. This has nothing to do with byte sex problems, and is true on all > non-broken UNIX implementations (even those with a byte size other than 8 > bits). > OOPS! I was misled by the SUN manual page for system(2), which suggests that the value IS e.g. 127 but 'may be displayed as "32512"'. The manual page for wait(2) is still misleading. I checked a System Vr2 manual, and it says "the <<high order 8 bits>> of status contain the low order 8 bits of the argument that the child process passed to exit()"; you have to read carefully to realise that this means the high order 8 bits of the low order 16 bits... I've been using #define WAIT_EXIT(x) (((x) >> 8) & 0377) #define WAIT_DUMP(x) ( (x) & 0200) #define WAIT_SGNO(x) ( (x) & 0177) int child; int status; ... if ((child = wait(&status)) < 0) ... for years, and just put up with 4.2BSD lint complaining about the way I use wait(). I'd forgotten what the macros do. (That's portability...)
hydrovax@nmtsun.nmt.edu (M. Warner Losh) (01/24/88)
In article <7162@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes: > In article <1234@nmtsun.nmt.edu> hydrovax@nmtsun.nmt.edu (I) write: > >As a side note. exit(0) in UNIX isn't quit correct. The UNIX shell, > >as far as I know, doesn't give a hill of beans wheather you say exit(0), > >exit(1000), exit (magic_number).... > > No, there are shell built-ins such as "test" that "know" that only a 0 > termination status indicates success. > A knee jerk reaction at best. Had I stopped to read the manuals..... > The point that the exit status is interpreted by the execution environment, > which is not necessarily synonymous with the "operating system", is correct. > Saying that this is a "shell" is being too specific, however. In fact, > even on UNIX it's not necessarily a shell, just the parent process. I know that picking nits like this can be irritating, but they should be pointed out from time to time. I just got a little carried away with the generalism. Programmers that complain about how this or that system does X should realize what part of the system is resonsible for the X behaviour. Otherwise, we might say that UNIX (or VMS) has lots of bugs in it, because some obscure utility core dumps (or produces a typical VMS error SCREEN :-). That utility is buggy, not the operating system in which it lives. -- bitnet: lush@nmt.csnet M. Warner Losh csnet: warner%hydrovax@nmtsun uucp: ...{cmcl2, ihnp4}!lanl!unmvax!nmtsun!warner%hydrovax ...{cmcl2, ihnp4}!lanl!unmvax!nmtsun!hydrovax Warning: Hydrovax is both a machine, and an account, so be careful.
rsalz@bbn.com (Rich Salz) (01/24/88)
>>I might be wrong. >You are. So are you. :-) > sh(1): ... > Control structures: Cmd1 && Cmd2 executes Cmd2 iff Cmd1 returns > a zero exit status, Cmd1 || Cmd2 executes Cmd2 iff Cmd1 returns ... > csh(1): > ... && and || are as in sh(1); ... 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. This has stopped being an comp.lang.c.ansii-bash issue, so I'm directing followups to comp.unix.questions /r$ -- For comp.sources.unix stuff, mail to sources@uunet.uu.net.
peter@sugar.UUCP (Peter da Silva) (02/03/88)
I don't understand the problem. On VMS, neither 1 nor 0 are valid exit codes. So have the exit function map 0 into SUCCESS, and 1 into FAIL. Let anything else through unchanged... Or go with VMS$EXIT(VMS_CODE);. -- -- Peter da Silva `-_-' ...!hoptoad!academ!uhnix1!sugar!peter -- Disclaimer: These U aren't mere opinions... these are *values*.
jkchan@lynx.cat.syr.edu (J. K. Chan) (03/31/91)
I must be missing learning some simple idea about the use of exit();.
Given the following program (I chopped it out from my program),
"lint" always issues a warning message as shown in the comment part
of the program. My program can run but I'm bothered by the lint
warning message. I tried to use lint in different Unix accounts but
still got the same message. The K&R book didn't say anything more than just
using exit(); directly. Please help and send email to the above address.
Thanks in advance.
Jim
/*
exit value declared inconsistently llib-lc(232) :: t.c(8)
*/
#include <stdio.h>
#include <stdlib.h>
main()
{
exit(0);
}
jim@segue.segue.com (Jim Balter) (04/01/91)
In article <1991Mar30.155011.767@rodan.acs.syr.edu> jkchan@lynx.cat.syr.edu (J. K. Chan) writes: > exit value declared inconsistently llib-lc(232) :: t.c(8) How is exit declared in stdlib.h and in llib-lc on your system? They should both be declared as returning void. I suspect that your stdlib.h doesn't declare exit at all, which would explain why the message refers to t.c(8), which would be an implicit declaration of int exit(); in the absense of a declaration in stdlib.h. When posting a question like this to the net, you really ought to provide the obvious information (what system and compiler you are using, what line 232 of llib-lc is) rather than assuming people have E.S.P. or that all systems are identical. It is also useful to treat such a specific informative message from lint as just that, rather than as a magic incantation. In any case, your usage of exit is fine. Some compilers and versions of lint will also complain that main returns no value even though it is expected to. Some will honor a comment on the declaration of exit indicating that it never returns, or (inferior) some will honor a /*NOTREACHED*/ following the call to exit, but since this is far from universal, just learn to ignore the warnings when issued in conjunction with exit. Or use return instead of exit in main; thats will avoid the warnings in this case.
jjr@rushpc (John J. Rushford Jr) (04/02/91)
In article <1991Mar30.155011.767@rodan.acs.syr.edu> jkchan@lynx.cat.syr.edu (J. K. Chan) writes: > exit value declared inconsistently llib-lc(232) :: t.c(8) In article <1991Mar31.6943@segue.segue.com> jim@segue.segue.com (Jim Balter) writes: > How is exit declared in stdlib.h and in llib-lc on your system? They should > both be declared as returning void. I suspect that your stdlib.h doesn't > declare exit at all, which would explain why the message refers to t.c(8), > which would be an implicit declaration of int exit(); in the absense of > a declaration in stdlib.h. I've always used the following and avoid the lint complaint: #include <stdio.h> void exit(); /* exit returns type void */ main() { program_stuff(); exit(1); exit(2); exit(3); exit(etc); } -- J. Rushford ----------- Westminster, Colorado.