On a Gnu system, I can write a C macro like dies_ok() that will fork a new process, run a piece of code, after which it can write to a shared piece of memory that it didn't exit, then in the parent process I can determine if it exited or not. This is useful for tests:
dies_ok({int x = 0/0;}, "can't divide by zero");
lives_ok({int x = 3/7;}, "this is a perfectly fine statement");
dies_ok({abort();}, "abort kills the program");
Is there any way to accomplish this on MSVC where there isn't a fork function?
EDIT: Heres the implementation that works on linux with gcc: http://github.com/zorgnax/libtap/blob/master/tap.h
CreateProcess is like fork()/exec()
The BOOST library has shared memory support for msvc. You can also use the Windows atom table which is native to Windows-
see msdn for
http://msdn.microsoft.com/en-us/library/ms649053(VS.85).aspx
Q: I don't get why in unix you have to write a string to shared memory. You can simply call exit(n) from the child process where n is an index into a predefined char *p[] list of error codes or success codes. You can have an array of 255 values, excluding 0 for EXIT_SUCCESS. Or read the sysexits.h header file for another set of ideas. wait() or waitpid() will return the exit code, or determine if the process did not exit
Related
What's the general meaning of an exit code 11 in C? I've looked around and can not find a definitive answer so I thought I would ask here. It comes when i try to add an element to a vector.
You didn't find a definitive answer because there isn't one. It's up to the author of the program to decide what exit codes they wish to use. Standard C only says that exit(0) or exit(EXIT_SUCCESS) indicate that the program is successful, and that exit(EXIT_FAILURE) indicates an error of some kind. (Returning a value from main is equivalent to calling exit with that value.) Most common operating systems including Windows, Linux, OSX, etc. use 0 for success and values from 1 to 255 to indicate errors; still choosing between error codes is up to the application writer, the value 11 isn't anything special.
Under Linux and most other Unix variants, the signal number 11 indicates a segmentation fault, as remarked by Kerrek SB. A segmentation fault happens when a program makes some kind of invalid memory access, so it's a plausible consequence of accessing an array out of bounds, or an error in pointer arithmetic, or trying to access a null pointer, or other pointer-related errors. Signal 11 is not the same thing as exit code 11: when a program dies due to a signal, it's marked as having been killed by a signal, rather than having exited normally. Unix shells report signals by reporting an exit code which is the signal number plus 128, so 139 for a segmentation fault.
The other answers have missed a possible ambiguity in the phrase "exit code". I suspect what you meant by "exit code" is the status code retrieved with the wait family of syscalls, as in:
/* assume a child process has already been created */
int status;
wait(&status);
printf("exit code %d\n", status);
If you do something like that you may very will see "exit code 11" if the child process segfaults. If the child process actually called exit(11) you might see "exit code 2816" instead.
It would be better to call those things "wait code" or "wait status" instead of "exit code", to avoid confusion with the value passed to exit. A wait code contains several pieces of information packed together into a single integer. Normally, you should not look at the integer directly (like I did above in that printf). You should instead use the W* macros from <sys/wait.h> to analyze it.
Start with the WIF* macros to find out what kind of thing happened, then use that information to decide which other W* macros to use to get the details.
if(WIFEXITED(status)) {
/* The child process exited normally */
printf("Exit value %d\n", WEXITSTATUS(status));
} else if(WIFSIGNALED(status)) {
/* The child process was killed by a signal. Note the use of strsignal
to make the output human-readable. */
printf("Killed by %s\n", strsignal(WTERMSIG(status)));
} else {
/* ... you might want to handle "stopped" or "continued" events here */
}
There is no standard defined which exit codes an application has to set in certain situations. It is totally up to the programmer which exit codes represent which error or even success !
Sometimes programmers decide that any value different from zero signals an error, and sometimes this value equals the operating systems error codes.
On Windows exit code 11 might be used because of problems with a file. If you want the description of this error code (which is specific to Windows and not necessarily your application) run net helpmsg 11.
I understand that exit(1) indicated an error , for example :
if (something went wrong)
exit(EXIT_FAILURE);
But what's the purpose of using exit(EXIT_SUCCESS); ?
When handling with processes maybe ? e.g. for fork() ?
thanks
This gives the part of the system that invokes the program (usually the command shell) a way to check if the program terminated normally or not.
Edit - start -
By the way, it is possible to query the exit code of an interactive command as well through the use of the $? shell variable. For instance this failed ls command yields an exit code of value 2.
$ ls -3
ls: invalid option -- '3'
Try `ls --help' for more information.
$ echo $?
2
Edit - end -
Imagine a batch file (or shell script) that invokes a series of programs and depending on the outcome of each run may choose some action or the other. This action may consist of a simple message to the user, or the invocation of some other program or set of programs.
This is a way for a program to return a status of its run.
Also, note that zero denotes no problem, any non-zero value indicates a problem.
Programs will often use different non-zero values to pass more information back (other than just non-normal termination). So the non-zero exit value then serves as a more specific error code that can identify a particular problem. This of course depends on the meanings of the code being available (usually/hopefully in the documentation)
For instance, the ls man page has this bit of information at the bottom:
Exit status is 0 if OK, 1 if minor problems, 2 if serious trouble.
For Unix/Linux man pages, look for the section titled EXIT STATUS to get this information.
you can only exit your program from the main function by calling return. To exit the program from anywhere else, you can call exit(EXIT_SUCCESS). For example, when the user clicks an exit button.
It's a system call. There's always good information on system calls if you check the man pages:
http://linux.die.net/man/3/exit
On a Linux box, you can simply type man exit into a terminal and this information will come up.
There are two ways of 'normally' exiting a program: returning from main(), or calling exit(). Normally exit() is used, and thought of, for signalling a failure. However, if you are not in main(), you must still exit somehow. exit(0) is usually used to terminate the process when not in main().
main() is actually not a special function to the operating system, only to the runtime environment. The 'function' that actually gets loaded is normally defined as _start() (this is handled by the linker, and beyond the scope of this answer), written in assembly, which simply prepares the environment and calls main(). Upon return from main(), it also calls exit() with the return value from main().
I am trying to test whether a c program has compiled and executed correctly or not.
Say I have just print Hello World in a c program so I want to write a c program to check
that the first program has returned 0 or has returned something else.
How can i do that.
Thanks in advance.
This is usually platform-dependent and depends on how you run one program from another. If you use the C library function system, you can run the program and then read the status code from that program as follows:
int returnCode = system("./hello-world-program");
if (returnCode == 0) {
...
}
However, you're usually better off using OS-level primitives to do this. Linux uses fork and exec to handle this, and you can read the child process's exit code given the process ID number by using the wait function in conjunction with some other code. Windows has its own mechanism for doing this which, unfortunately, I'm not familiar with.
Hope this helps!
I have a small C program calling a shell script myScript.sh. I am getting the value of ret as 256. Please help me in knowing what went wrong with the system call?
int main()
{
int ret;
ret = system (myScript.sh);
ret >>= ret;
if (ret != 0)
{
printf("ret is [%d]",ret);
}
}
Working on 64 bit UNIX operating system and using ksh shell
On my system, man system says:
The system() function returns the exit status of the shell as returned by
waitpid(2), or -1 if an error occurred when invoking fork(2) or
waitpid(2). A return value of 127 means the execution of the shell
failed.
The waitpid man page describes a set of macros such as WEXITSTATUS() that extract the actual exit code from the return value.
I'm not quite sure what you're intending to do with ret >>= ret, but that can't be right.
The way that the system function usually works on *nix is that it calls fork and then the child calls one of the exec functions with /bin/sh -c and then the string you passed to system in the child, which turns the child process into an instance of the /bin/sh program which runs the command. The parent calls one of the wait functions, which waits for the /bin/sh to exit, which it does with the same exit status as the shell script, and then system also returns that value.
If you look at the man pages for the wait system call(s):
main 3 wait
You should get some information about what gets returns and some macro functions that help you make sense of it.
The WIFEXITED(stat_val) macro can be used to test if the program exited normally as opposed to with a signal. Normal exits involve calling the exit system call. If this function returns a non-zero value then you can use the WEXITSTATUS(stat_val) macro to get the value that it actually returned.
The WIFSIGNALED(stat_val) macro can be used to test if the program was terminated with a signal, and if so the WTERMSIG(stat_val) macro will return the signal number that caused the termination.
There are some other macros that can tell you if the process were stopped or continued, rather than terminated, but I don't think that they are overly helpful to you for this purpose, but you may want to look into them.
As far as what is actually happening in this case, it can be difficult to tell. If the fork call fails then system will be able to return -1 and set errno to reflect the error. If the fork did not fail then the error may have happened in the child and be more difficult to locate. It may be possible that on your platform system might do some tests before forking to insure that you have permission to execute the appropriate files and set errno to reflect that, but maybe not.
You should look into the perror function to print out error messages in the case that errno is set.
If the failure happens after fork and within the child then you either need to get the shell to tell you more about what is happening, or get the shell script to. This may be by including echo statements in the script similarly to using print statements in your C programs.
You should also look into the access function to test if you have permission to read and/or execute files.
If you are using Linux then you should be able to do:
strace -o my_program.strace -f ./my_program
or
ltrace -o my_program.ltrace -f -S ./my_program
and then examine the trace files (after the -o) to look at what the programs and kernel say to each other. ltrace looks at how the program talks to library function, while strace looks at system calls, but the -S tells ltrace to also look at system calls. The -f argument tells them both to trace children of the program as they are created.
I just noticed that you said that you were using ksh
As I mentioned system under a Posix system should use /bin/sh or a compatible shell. This doesn't mean that /bin/sh won't run /bin/ksh to run your script (or that the kernel won't use the #! line at the beginning of the script file to do this), but it could be a problem. There are ways to run shell scripts so that this line is not used to know which shell is to be used. The most notable is:
. myshell.sh
The period and space essentially tries to dump the text of the file into the current shell session rather than run it in another process (this is useful for setting up an environment). If you were to be doing:
int x = system(". myshell.sh");
Then that could be a problem.
The exit status of the command is encoded as two bytes:
The high-order byte contains the exit status.
The low-order byte contains the signal that killed it (if any).
Since 0x0100 is 256 decimal, your shell script exited with status 1. Review your shell script and ensure it exits with status 0 when it is successful.
From the Standard (emphasis is mine):
6.5.7/3
If the value of the right operand [of the >> operator] is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined.
So, when you do
ret >>= ret;
and ret < 0 or ret >= CHAR_BIT * sizeof (int) ... anything goes
The return value of the system function can be -1 on error.
If your call returned in such a negative value, the next operation ret >>= ret; (same as ret = -1 >> -1;) results in something that has no meaning: you cannot right shift by a negative number of bits.
When you try to do things with no meaning, C is allowed to do anything ... anything at all (that includes doing nothing, doing what you expect, reformatting your hard disk, transferring your bank account to mine, making demons fly out your nose, ..., ..., ...)
Make sure your script is executable and in the path, or use the full path instead.
Nothing went wrong. Did you read the documentation? See:
RETURN VALUE
The value returned is -1 on error (e.g. fork(2) failed), and the
return status of the command otherwise. This latter return status is in the format specified in wait(2).
Thus, the exit code of the command will be WEXITSTATUS(status). In case /bin/sh could not be executed,
the exit status will be that of a command that does exit(127).
Since 256 is not -1, the call did not fail.
Why do you shift the result? Just remove the line ret >>= ret, and it will work.
I am working on linux and it helped to call the script with system("sh script.sh")
How do you run an external program and pass it command line parameters using C? If you have to use operating system API, include a solution for Windows, Mac, and Linux.
It really depends on what you're trying to do, exactly, as it's:
OS dependent
Not quite clear what you're trying to do.
Nevertheless, I'll try to provide some information for you to decide.
On UNIX, fork() creates a clone of your process from the place where you called fork. Meaning, if I have the following process:
#include <unistd.h>
#include <stdio.h>
int main()
{
printf( "hi 2 u\n" );
int mypid = fork();
if( 0 == mypid )
printf( "lol child\n" );
else
printf( "lol parent\n" );
return( 0 );
}
The output will look as follows:
hi 2 u
lol child
lol parent
When you fork() the pid returned in the child is 0, and the pid returned in the parent is the child's pid. Notice that "hi2u" is only printed once... by the parent.
execve() and its family of functions are almost always used with fork(). execve() and the like overwrite the current stackframe with the name of the application you pass to it. execve() is almost always used with fork() where you fork a child process and if you're the parent you do whatever you need to keep doing and if you're the child you exec a new process. execve() is also almost always used with waitpid() -- waitpid takes a pid of a child process and, quite literally, waits until the child terminates and returns the child's exit status to you.
Using this information, you should be able to write a very basic shell; one that takes process names on the command line and runs processes you tell it to. Of course, shells do more than that, like piping input and output, but you should be able to accomplish the basics using fork(), execve() and waitpid().
NOTE: This is *nix specific! This will NOT work on Windows.
Hope this helped.
If you want to perform more complicated operations, like reading the output of the external program, you may be better served by the popen system call. For example, to programmatically access a directory listing (this is a somewhat silly example, but useful as an example), you could write something like this:
#include <stdio.h>
int main()
{
int entry = 1;
char line[200];
FILE* output = popen("/usr/bin/ls -1 /usr/man", "r");
while ( fgets(line, 199, output) )
{
printf("%5d: %s", entry++, line);
}
}
to give output like this
1: cat1
2: cat1b
3: cat1c
4: cat1f
5: cat1m
6: cat1s
...
#include <stdlib.h>
int main()
{
system("echo HAI");
return 0;
}
I want to give a big warning to not use system and 100% never use system when you write a library. It was designed 30 years ago when multithreading was unknown to the toy operating system called Unix. And it is still not useable even when almost all programs are multithreaded today.
Use popen or do a fork+execvp, all else is will give you hard to find problems with signal handling, crashs in environment handling code etc. It's pure evil and a shame that the selected and most rated answer is promoting the use of "system". It's more healthy to promote the use of Cocain on the workplace.
On UNIX, I think you basically need to fork it if you want the spawned process to run detached from your the spawing one : For instance if you don't want your spawned process to be terminate when you quit your spawning process.
Here is a page that explains all the subtle differences between Fork, System, Exec.
If you work on Win,Mac and linux, I can recommend you the Qt Framework and its QProcess object, but I don't know if that's an option for you. The great advantages is that you will be able to compile the same code on windows linux and mac :
QString program = "./yourspawnedprogram";
QProcess * spawnedProcess = new QProcess(parent);
spawnedProcess->start(program);
// or spawnedProcess->startDetached(program);
And for extra, you can even kill the child process from the mother process,
and keep in communication with it through a stream.
One solution is the system function defined in stdlib.h
int system(const char *string);
system api example
If you need to check/read/parse the output of your external command, I would suggest to use popen() instead of system().
Speaking of platform-dependent recipes, on Windows use CreateProcess, on Posix (Linux, Mac) use fork + execvp. But system() should cover your basic needs and is part of standard library.