Terminating the program gracefully in C - c

I have sort of a homework and it asks me to end the program gracefully without explicit termination such as calling exit() or killing the threads.
However I cannot think of any other methods than return 0, so what are the methods to end a program gracefully?

Killing the threads is absolutely not a graceful way to terminate a program. I think what your instructor means is that all your parent threads should wait on their child threads before terminating themselves.
Ideally, an explicit call pthread_exit from the main thread would ensure that all it's children continue running even after it exits. Refer to this link. But, the safest way to wait on your child threads before exiting is to use pthread_join.
Nevertheless, exit(0) is the graceful return for a process as such.

I think you are missing to tell us that you have a multi-threaded program. I suppose that the the idea of gracefully terminating the program is meant to terminate all your threads by setting a flag or something like that. And then only to terminate your main after all your threads have provably ended. The way you actually then terminate your main is of lesser importance.

exit(0) generally indicates that process (your program) terminated gracefully. In case of error it would exit(-1) or some other error code.

See my comment.
main will by default return 0 in the lack of a return 0; statement.
See §5.1.2.2.3¶1 of the C99 standard.
If the return type of the main function is a type compatible with int, a return from the
initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument; reaching the } that terminates the
main function returns a value of 0. If the return type is not compatible with int, the
termination status returned to the host environment is unspecified.
So, the following terminates gracefully although implicitly, distinguished from an explicit exit or return in main.
main() { }

They may be referring to how you handle errors in lower-level routines. Rather than doing something like
printf("ERROR: couldn't initialize the claveman\n");
exit(1);
You would return from that routine (possibly printing the error message at that level or waiting to do it at a higher level like main()).
return CLAVEMAN_INITIALIZE_ERROR;
All your routines would return zero for success or non-zero error codes, up until the code in main was able to return either EXIT_SUCCESS or an error code indicating the failure.

No idea what they could mean with gracefully but my first idea was just a return 0.
Or exit(0)

Related

exit() function in C — what happens if we do not write this?

I have seen many posts regarding this question. Many say that exit(EXIT_SUCCESS) should be called for successful termination, and exit(EXIT_FAILURE) for unsuccessful termination.
What I want to ask is: What if we do not call the exit() function and instead what if we write return 0 or return -1? What difference does it make?
What happens if successful termination does not happen? What are its effects?
It is told that if we call exit() functions the program becomes portable --
"portable" in the sense what? How can one function make the entire code portable?
It is told that the execution returns to the parent what happens if the execution does not return to the parent?
My questions may seem to be silly but I need answers for all of these to get rid of my ambiguity between return and exit.
Return returns a value from a function. Exit will exit your program. When called within the main function, they are essentially the same. In fact, most standard libc _start functions call main and then call exit on the result of main anyway.
Nothing, directly. The caller (usually your shell) will get the return value, and be able to know from that whether your program succeeded or not.
I don't know about this. I don't know what you mean here. exit is a standard function, and you may use it if you wish, or you can decide not to. Personally, I prefer to return from main only, and only return error status from other functions, to let the caller decide what to do with it. It's usually bad form to write an API that kills the program on anything but an unrecoverable error that the program can't manage.
If execution didn't return to the parent (which is either a shell or some other program), it would just hang forever. Your OS makes sure that this doesn't happen in most ordinary cases.

thread at exit cleanup

I have an application in which I have 1 main thread which creates 10 different threads for doing some job. At the end of application, when I try to exit, the application is not able to cleanly exit. The stack trace is not that useful, but its showing the crash in function "cancel_deliver()" My first guess is this is some underlying call made while doing the freeing up of resources used by each thread, but not entirely sure.
fyi: The callback function for each thread has a while (1) loop:
Here is the snippet
void main (...)
{
pthread_t tid;
for (int i=0; i<10; i++)
pthread_create(&tid, NULL, xyzCallback, NULL);
}
void xyzCallback(void* data)
{
while (1)
{
////
}
}
void atExit()
{
exit(1);
}
Is there any thing that I can do to free up resrouces used by my thread and cleanly exit?
For this case
If I understand your setup correctly...
One thing you could do is have a set of 'flag' variables, one for each thread (including the main thread). When the main thread is ready to end, set its flag. This flag should be continually checked within the 10 other threads. Once it becomes set, change the flag variable for that specific thread and call pthread_exit. In the main exit method, only terminate once all the flag variables are set.
Assuming your program isn't crashing due to another reason, this should enable all the threads to finish in a controlled manner.
(or use pthread_join in the main exit function, since pthread_exit returns information used by pthread_join)
In general
Use pthread_exit instead of exit(1) to cleanly exit the thread.
From the LLNL POSIX Thread Programming page:
There is a definite problem if main() finishes before the threads it spawned if you don't call pthread_exit() explicitly. All of the threads it created will terminate because main() is done and no longer exists to support the threads.
Also see the pthread_exit man page.
You need to decide whether your threads (1) need to end in a well defined way (state), or if the latter does not matter (2) take care where and when they could be cancelled (which happens implicitly when the program ends)
Referring 1: A possible way could be to implement an exit condition which will be triggered when the program shall terminate and makes the threads leave their while(1) loop. Before leaving the main loop calling pthread_join() for any pthread_t pthread it received by the calls to pthread_create(). If all threads terminate the main's join loops is left and main ends with all threads terminated already.
Referring 2: This is the more critical case, as depending on the thread functions's code it is not clear where it will be canceled, which could lead to unexpected behaviour. A thread could be cancelled at a so called cancellation point. Some system calls are treated as such.
In any case the thread function does not necessarily need to call pthread_exit() as last statement. This is only necessary if you want to have pthread_join() receive a pointer passed to pthread_exit().

What is the difference between exit(0) and exit(1) in C?

Can anyone tell me? What is the difference between exit(0) and exit(1) in C language?
What is the difference between exit(0) and exit(1) in C language?
exit(0) indicates successful program termination & it is fully portable, While
exit(1) (usually) indicates unsucessful termination. However, it's usage is non-portable.
Note that the C standard defines EXIT_SUCCESS and EXIT_FAILURE to return termination status from a C program.
0 and EXIT_SUCCESS are the values specified by the standard to indicate successful termination, however, only EXIT_FAILURE is the standard value for returning unsucessful termination. 1 is used for the same in many implementations though.
Reference:
C99 Standard: 7.20.4.3 The exit function
Para 5
Finally, control is returned to the host environment. If the value of status is zero or
EXIT_SUCCESS, an implementation-defined form of the status successful termination is
returned. If the value of status is EXIT_FAILURE , an implementation-defined form
of the status unsuccessful termination is returned. Otherwise the status returned is
implementation-defined.
exit in the C language takes an integer representing an exit status.
Exit Success
Typically, an exit status of 0 is considered a success, or an intentional exit caused by the program's successful execution.
Exit Failure
An exit status of 1 is considered a failure, and most commonly means that the program had to exit for some reason, and was not able to successfully complete everything in the normal program flow.
Here's a GNU Resource talking about Exit Status.
As #Als has stated, two constants should be used in place of 0 and 1.
EXIT_SUCCESS is defined by the standard to be zero.
EXIT_FAILURE is not restricted by the standard to be one, but many systems do implement it as one.
exit(0) indicates that the program terminated without errors. exit(1) indicates that there were an error.
You can use different values other than 1 to differentiate between different kind of errors.
The difference is the value returned to the environment is 0 in the former case and 1 in the latter case:
$ ./prog_with_exit_0
$ echo $?
0
$
and
$ ./prog_with_exit_1
$ echo $?
1
$
Also note that the macros value EXIT_SUCCESS and EXIT_FAILURE used as an argument to exit function are implementation defined but are usually set to respectively 0 and a non-zero number. (POSIX requires EXIT_SUCCESS to be 0). So usually exit(0) means a success and exit(1) a failure.
An exit function call with an argument in main function is equivalent to the statement return with the same argument.
exit is a system call used to finish a running process from which it is called. The parameter to exit is used to inform the parent process about the status of child process. So, exit(0) can be used (and often used) to indicate successful execution of a process and exit(1) to flag an error. reference link
exit(0) is equivalent to exit(EXIT_SUCCESS).
exit(1) is equivalent to exit(EXIT_FAILURE).
On failure normally any positive value get returned to exit the process, that you can find on shell by using $?.
Value more than 128 that is caused the termination by signal. So if any shell command terminated by signal the return status must be (128+signal number).
For example:
If any shell command is terminated by SIGINT then $? will give 130 ( 128+2)
(Here 2 is signal number for SIGINT, check by using kill -l )
exit function. In the C Programming Language, the exit function calls all functions registered with at exit and terminates the program.
exit(1) means program(process) terminate unsuccessfully.
File buffers are flushed, streams are closed, and temporary files are deleted
exit(0) means Program(Process) terminate successfully.
When the executable ends (exits) it returns a value to the shell that ran it. exit(0) usually indicates that all is well, whilst exit(1) indicates that something has gone amiss.
exit() should always be called with an integer value and non-zero values are used as error codes.
See also: Use of exit() function
exit(0) means Program(Process) terminate normally successfully..
exit(1) means program(process) terminate normally unsuccessfully..
If you want to observe this thing you must know signal handling and process management in Unix ...
know about sigaction, watipid()..for()...such....API...........
exit(0) behave like return 0 in main() function, exit(1) behave like return 1. The standard is, that main function return 0, if program ended successfully while non-zero value means that program was terminated with some kind of error.

Detached Threads

When we make Detached threads in main.
and supose main exits... do the detached threads keep on going on or do they also exit just like our normal Joinable threads?
It depends entirely on how the main thread exits. If it exits using exit() or returning from main(), then the entire process is exited, and every thread is terminated.
However, if it uses pthread_exit() to terminate, then the process continues running.
If this would be another thread then main, the other threads would continue. But the C99 standard says
If the return type of the main
function is a type compatible with
int, a return from the initial call to
the main function is equivalent to
calling the exit function...
(All common platforms nowadays will return an int from main, in particular this is required by POSIX.)
And the POSIX page for exit states
These functions shall terminate the
calling process...
So in summary a return from main terminates the whole program including all threads.

Does control return after "execvp()"?

if(pid == 0)
{
execvp(cmd, args);
// printf("hello"); // apparently, putting this or not does not work.
_exit(-1);
}
else
{
// parent process work
}
"execvp()" replaces the current program with the to-be-execed program (of course in the same process context). So, putting, say, any printf() calls after execvp() won't work. That is what the docs say, and I have verified it as well.
But then, why is _exit() needed..? Does it so happen that the control DOES return to statements post execvp() ?
I will be grateful for any pointers.
Thanks
The function will return if it has failed.
If one of the exec functions returns to the calling process image, an error has occurred; the return value shall be -1, and errno shall be set to indicate the error.
The _exit() allows terminating the process properly and return an exit code, even if exec fails.
The execve() syscall can fail. The classic reason for doing this would be if the file isn't there or isn't executable. execvp() wraps around execve() to add path searching and default environment handling (virtually always what you want!) and so it adds in another few failure modes, notably trying to run something with a simple name that's not on the user's path. In any case, failure is failure and there's not a lot you can do when it happens except report that it has gone wrong and Get the (now useless) child process Out Of Dodge. (The simplest error reporting method is to print an error message, perhaps with perror(), but there are others.)
The reason why you need _exit() as opposed to the more normal exit() is because you want to quit the child process but you do not want to run any registered cleanup code associated with the parent process. OK, a lot of it might be harmless, but doing things like writing goodbye messages to a socket or something would be bad, and it's often not at all obvious what has been registered with atexit(). Let the parent process worry about its resources; the child basically owns nothing other than its stack frame!
If execvp fails, _exit will be called.
execvp's man page says:
Return Value
If any of the exec() functions returns, an error will have occurred. The return value is -1, and the global variable errno will be set to indicate the error.
One thing to note, you generally don't want a process' exit status to be signed (if portability matters). While exec() is free to return -1 on failure, its returning that so you can handle that failure within the child code.
The actual _exit() status of the child should be 0 - 255, depending on what errno was raised.

Resources