exit()

B

BartC

Can I use the return value provided to exit() for my own purposes?

(This is so that I can pick up the exit-value when I invoke the program from
another. BTW what's the best way of invoking a program under Linux so that
this value can be retrieved?)
 
J

John Gordon

In said:
Can I use the return value provided to exit() for my own purposes?

Yes. However program exit codes are fairly limited in range; I believe
you can only use values from 0 to 255.
(This is so that I can pick up the exit-value when I invoke the program from
another. BTW what's the best way of invoking a program under Linux so that
this value can be retrieved?)

From a shell, the exit status of the previous command is typically
available from the $? variable.

If you're invoking a program from another program, the invoking function
(typically something like system("command")) will usually return the exit
status. Although, in this case, the returned value may be a combination
of the program's exit command and the shell that was spawned to run it;
you may have to separate out the two values.
 
K

Keith Thompson

John Gordon said:
Yes. However program exit codes are fairly limited in range; I believe
you can only use values from 0 to 255.

That's true for Unix/Linux/POSIX systems. It may or may not be true for
other systems.

The C standard says that exit() takes an int argument. It causes the
program to terminate and return a implementation-defined status to
the environment (0 or EXIT_SUCCESS should return a status denoting
success, and EXIT_FAILURE should return a status denoting failure).
From a shell, the exit status of the previous command is typically
available from the $? variable.

That's for the Bourne shell and shells derived from it. csh and tcsh
use $status.
If you're invoking a program from another program, the invoking function
(typically something like system("command")) will usually return the exit
status. Although, in this case, the returned value may be a combination
of the program's exit command and the shell that was spawned to run it;
you may have to separate out the two values.

The documentation for the system() function for your environment will
tell you how to interpret the result returned by system(). On Unix-like
systems, if a program invoked by system() calls exit(N), system() will
return N<<8. system() returns other values if the program terminated
due to a signal.
 
A

Alain Ketterlin

BartC said:
Can I use the return value provided to exit() for my own purposes?

(This is so that I can pick up the exit-value when I invoke the program from
another. BTW what's the best way of invoking a program under Linux so that
this value can be retrieved?)

Under Linux (and POSIX), the exit value has no predefined meaning (but a
limited range, and conventions). If you control the whole chain, you're
probably invoking from a parent process with fork/exec*. Then the parent
can use wait() to retrieve the exit code (after having checked whether
the child terminated by calling exit()). If you use higher-level
interfaces to launch the program (e.g., system()), you may loose some
accuracy

-- Alain.
 
K

Keith Thompson

Alain Ketterlin said:
Under Linux (and POSIX), the exit value has no predefined meaning (but a
limited range, and conventions).

exit(0) and exit(EXIT_SUCCESS) are well defined, both by C and by
POSIX, as an indication of success. exit(EXIT_FAILURE) denotes
failure. (EXIT_FAILURE is typically 1 on POSIX systems, but the
POSIX standard doesn't require that.)
If you control the whole chain, you're
probably invoking from a parent process with fork/exec*. Then the parent
can use wait() to retrieve the exit code (after having checked whether
the child terminated by calling exit()). If you use higher-level
interfaces to launch the program (e.g., system()), you may loose some
accuracy

The value returned by system() is well defined for POSIX; it's the same
as the result returned by waitpid(). If you evaluate

system("some_command");

and some_command calls exit(42), you can reliably get the value 42 from
the result returned by system().

Some specific commands define meanings for exit statuses other than 0 or
1. For example, the grep command exits with a status of 0 on success, 1
on failure, and 2 on error. The curl command defines 88 different error
codes, but that's an extreme case.
 
N

Nobody

The value returned by system() is well defined for POSIX; it's the same as
the result returned by waitpid(). If you evaluate

system("some_command");

and some_command calls exit(42), you can reliably get the value 42 from
the result returned by system().

Note that if execve() failed to execute the shell, the result is the same
as a program which does exit(127), so you probably shouldn't use 127 as
one of your program's exit codes.

Also, note that you need to use the macros from <sys/wait.h> to extract
the actual exit status (and to determine if there is an exit status to
extract, as opposed to e.g. a signal). The value returned from waitpid(),
system() etc combines various pieces of information into a single integer.
 
N

Noob

BartC said:
Can I use the return value provided to exit() for my own purposes?

As others have pointed out, the answer is platform-dependent.
(This is so that I can pick up the exit-value when I invoke the program from
another. BTW what's the best way of invoking a program under Linux so that
this value can be retrieved?)

Try comp.unix.programmer or comp.os.linux.development.apps
 
A

Alain Ketterlin

Keith Thompson said:
exit(0) and exit(EXIT_SUCCESS) are well defined, both by C and by
POSIX, as an indication of success. exit(EXIT_FAILURE) denotes
failure. (EXIT_FAILURE is typically 1 on POSIX systems, but the
POSIX standard doesn't require that.)

See, a value of 42 has no predefined meaning.
The value returned by system() is well defined for POSIX; it's the same
as the result returned by waitpid().

This is wrong if system() returns 127.

[...]
Some specific commands define meanings for exit statuses other than 0 or
1. For example, the grep command exits with a status of 0 on success, 1
on failure, and 2 on error. The curl command defines 88 different error
codes, but that's an extreme case.

It seems obvious to me that BartC needs something like that.

-- Alain.
 
J

James Kuyper

See, a value of 42 has no predefined meaning.

But a value of 0 does. Therefore, saying that "the exit value has no
predefined meaning", without restricting that statement to a particular
range of exit values, was incorrect.
 
K

Keith Thompson

Alain Ketterlin said:
See, a value of 42 has no predefined meaning.

Certainly -- but 0 does. Your statement that "the exit value has no
predefined meaning" is mostly correct, but incomplete.

[...]
 
J

Jorgen Grahn

IME grep is an extreme case too. The vast majority of Unix tools
return 0 for success, and 1 for errors.
It seems obvious to me that BartC needs something like that.

Why is that obvious? He didn't say anything about his actual problem,
and again: designs which rely on many different exit codes are rare.

Perhaps his needs are best served by printing something to stdout and
returning 0/1.

/Jorgen
 
B

BartC

IME grep is an extreme case too. The vast majority of Unix tools
return 0 for success, and 1 for errors.


Why is that obvious? He didn't say anything about his actual problem,
and again: designs which rely on many different exit codes are rare.

Perhaps his needs are best served by printing something to stdout and
returning 0/1.

Sometimes I need to return two values (usually 1 for success, 0 for failure;
the opposite of above); sometimes three or four (an exit code from an editor
for example that may contain a request to compile the result). A range of
0..255, or even a limited subset, would be more than adequate. And better
than having to communicate via files, although this is what I have to do
with programs such as gcc for example, to figure out if something compiled
without errors.

(And on Windows there is a special function to pick up this exit code. While
a system() function exists (and is considerably simpler to use), it's return
value seems unrelated to the exit code of any program it attempts to run.)
 
K

Keith Thompson

BartC said:
Sometimes I need to return two values (usually 1 for success, 0 for failure;
the opposite of above); sometimes three or four (an exit code from an editor
for example that may contain a request to compile the result). A range of
0..255, or even a limited subset, would be more than adequate. And better
than having to communicate via files, although this is what I have to do
with programs such as gcc for example, to figure out if something compiled
without errors.

If you need two return values denoting success and failure, you should
use 0 and EXIT_FAILURE, respectively, or EXIT_SUCCESS and EXIT_FAILURE.
If you use `exit(0)` for failure and `exit(1)` for success, your program
won't interoperate with other programs on the same system. On Unix-like
systems, for example, the usual logic of

some_program || echo "It failed" 1>&2

would not work.

And gcc on Unix-like systems follows the usual convention of
exiting with a status of 0 for success, non-0 for failure.
(Makefiles routinely take advantage of that.)
(And on Windows there is a special function to pick up this exit code. While
a system() function exists (and is considerably simpler to use), it's return
value seems unrelated to the exit code of any program it attempts to run.)

Really? I just tried an experiment on Windows 7 with
MS Visual C++ 2010 Express (compiling C code, not C++).
It seems to indicate that the result returned by system()
is exactly the same as the value passed to exit() by the
called program -- which agrees with Microsoft's documentation:
http://msdn.microsoft.com/en-us/library/277bwbdz(v=vs.110).aspx

Though there is a note that says "This API cannot be used in
applications that execute in the Windows Runtime".
 
B

BartC

If you need two return values denoting success and failure, you should
use 0 and EXIT_FAILURE, respectively, or EXIT_SUCCESS and EXIT_FAILURE.

Maybe I can do that, and reverse the two after the value has been retrieved.
That's if I can use the (to me) counter-intuitive values in the first place
(I always use an actual 1 or 0).
Really? I just tried an experiment on Windows 7 with
MS Visual C++ 2010 Express (compiling C code, not C++).
It seems to indicate that the result returned by system()
is exactly the same as the value passed to exit() by the
called program -- which agrees with Microsoft's documentation:
http://msdn.microsoft.com/en-us/library/277bwbdz(v=vs.110).aspx

So it does. I must have read those docs too carefully (they mention nothing
of exit codes), together with some presumably flawed tests. Even gcc is
giving a 0 or 1 (but again, to me, back-to-front) result.

Perhaps I can make more use of system() then, since that is more portable.
 
K

Keith Thompson

BartC said:
Maybe I can do that, and reverse the two after the value has been retrieved.
That's if I can use the (to me) counter-intuitive values in the first place
(I always use an actual 1 or 0).

My advice: get used to the fact that Unix commands (and, I think,
many Windows commands as well) return a status of 0 for success,
non-0 for failure.

The reason is that there's typically only one way for a program to
succeed, and many ways for it to fail. The status result can (in an
ad hoc way) provide more information about the nature of the failure.

There's no real need to convert the 0=success, non-0=failure value to
something you find more intuitive. Just think of it as a status code,
not a Boolean. To test whether a program succeeded or failed:

if (system("...") == 0) {
/* success */
}
else {
/* failure */
}
So it does. I must have read those docs too carefully (they mention nothing
of exit codes), together with some presumably flawed tests. Even gcc is
giving a 0 or 1 (but again, to me, back-to-front) result.

Perhaps I can make more use of system() then, since that is more portable.

"More portable" meaning, in this case, that it works reasonably on
Unix-like and Windows-like systems (though the Unix return value is more
complicated). If that's portable enough for you, great. But IMHO it's
important to be aware that the C standard doesn't say much about the
meaning of the value returned by system(), or about its relationship, if
any, to the value passed to exit(). The behavior could be quite
different on other systems.
 
G

glen herrmannsfeldt

Keith Thompson said:
My advice: get used to the fact that Unix commands (and, I think,
many Windows commands as well) return a status of 0 for success,
non-0 for failure.

I first knew return codes from OS/360, where they are usually mutliples
of four, but otherwise 0 is usually success, 4 a little worse
(warning), 8 is about what is usually called error (returned by
compilers that could keep compiling, at least for syntax checking),
then 12 for fatal errors (the compiler gave up), and 16 even worse
(such as the inability to open SYSPRINT, what some might call stdout).
The reason is that there's typically only one way for a program to
succeed, and many ways for it to fail. The status result can (in an
ad hoc way) provide more information about the nature of the failure.
There's no real need to convert the 0=success, non-0=failure value to
something you find more intuitive. Just think of it as a status code,
not a Boolean. To test whether a program succeeded or failed:

But this is comp.lang.c where booleans are int.

It does confuse things like the tests in csh, where success is 0,
and apply to the && and || operators.

(Which are supposed to work like C operators.)

-- glen
 
J

James Kuyper

On 02/16/2013 05:46 PM, glen herrmannsfeldt wrote:
....
But this is comp.lang.c where booleans are int.

_Bool b = 3;

The resulting value of 'b' does not quite fit your description.
 
B

Bart van Ingen Schenau

Maybe I can do that, and reverse the two after the value has been
retrieved. That's if I can use the (to me) counter-intuitive values in
the first place (I always use an actual 1 or 0).
Would it still be counter-intuitive if you regard the result of an
application not as a boolean, but as a status code (with 0 == "success",
EXIT_FAILURE == "generic failure", other values more specific failure
codes)?
Or do you then also use 1 for success and several values of 0 to indicate
the various failures?

Bart v Ingen Schenau
 
K

Kenny McCormack

Would it still be counter-intuitive if you regard the result of an
application not as a boolean, but as a status code (with 0 == "success",
EXIT_FAILURE == "generic failure", other values more specific failure
codes)?
Or do you then also use 1 for success and several values of 0 to indicate
the various failures?

The core problem underlying all of this - is the fact that the shell treats
a return value of 0 as "TRUE" and anything else (i.e., non-zero) as FALSE.
Which is the exact opposite of what C (and most other programming languages)
do. Hence the confusion. Digging further, what underlies that is a basic
intuitive feeling that "TRUE" should be "good" and FALSE "bad", which, I
think, corresponds with most people's basic feelings about the Universe.

Interestingly enough, the first platform I ever used that used the concept
of TRUE/FALSE to indicate error/success, did so in that order - namely,
TRUE == error and FALSE == success. Counterintuitive this was, but it got
the job done nicely.

Finally, note that the Windows API mostly follows the model that 0 == failure,
1 (although this is usually documented as "non-zero") == success, because
this is what most people (unless they've come from a Unix background) expect
and are comfortable with, even though it is technically less efficient.

Since it is clear that "BartC" comes from a Windows background, it seems
reasonable to assume that that explains why he is more comfortable with the
Windows model.

--
But the Bush apologists hope that you won't remember all that. And they
also have a theory, which I've been hearing more and more - namely,
that President Obama, though not yet in office or even elected, caused the
2008 slump. You see, people were worried in advance about his future
policies, and that's what caused the economy to tank. Seriously.

(Paul Krugman - Addicted to Bush)
 
B

Ben Bacarisse

Bart van Ingen Schenau said:
Would it still be counter-intuitive if you regard the result of an
application not as a boolean, but as a status code (with 0 == "success",
EXIT_FAILURE == "generic failure", other values more specific failure
codes)?
Or do you then also use 1 for success and several values of 0 to indicate
the various failures?

It may be a bit off the wall, but this always makes me think of the
opening of Anna Karenina:

"Happy families are all alike; every unhappy family is unhappy in its
own way."

Information is only needed to record the result of an unhappy program.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top