How to Use the exit Function in C
-
Use the
exit
Function to Terminate Process in C -
Use the
atexit
Function to Register Exit Handler in C
This article will demonstrate multiple methods of how to use the exit
function in C.
Use the exit
Function to Terminate Process in C
When the given program is running on a UNIX-based operating system, it’s called a process. The process may be a long-running daemon style program or simple command-line utility, but eventually, both of them come to the termination point at some time. Termination can be abnormal caused by some fault/delivered signal, or the process itself can terminate gracefully as the normal behavior by calling exit
library function. It takes a single integer argument that specifies the termination value that gets returned to the parent process. Note that the exit
function does not return in the calling process.
The exit
function is the standard library function that is built on top of the system call _exit
(which we’re going to discuss in the next paragraphs). Still, it conducts more operations than just leading the caller to the termination point. Namely, exit
does some cleanup routine for the program like function registered as exit handlers are invoked, standard I/O streams buffers are flushed, and only then _exit
is called. Mind that, _exit
is a UNIX-specific system call, whereas exit
is part of the standard C library and can be utilized on different platforms.
The following example demonstrates the exit
function call with the EXIT_SUCCESS
status parameter, a macro constant of value 0
conventionally denoting a successful return.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
// Execute program code here
printf("Executing the program...\n");
sleep(5);
// exit(0);
exit(EXIT_SUCCESS);
}
Output:
Executing the program...
Use the atexit
Function to Register Exit Handler in C
The atexit
function is used to register exit handlers, which are just user-implemented functions that should be called when the process is terminated using the exit
call. atexit
takes function pointer of type void (*function)(void)
as the only argument.
Note that multiple functions can be registered by multiple atexit
calls, which leads to execution of the given functions in reverse order of registration. atexit
returns a non-zero value if the call fails. Mind that registered functions may not get called if the process gets terminated abnormally by an external signal. The next example code implements two static
functions to be registered as exit handlers, and after 5 seconds of sleep, the process terminates with an exit
call.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static void atexitFunc(void) { printf("atexitFunc called\n"); }
static void atexitFunc2(void) { printf("atexitFunc2 called\n"); }
int main(int argc, char *argv[]) {
if (atexit(atexitFunc) != 0) {
perror("atexit");
exit(EXIT_FAILURE);
}
if (atexit(atexitFunc2) != 0) {
perror("atexit");
exit(EXIT_FAILURE);
}
printf("Executing the program...\n");
sleep(5);
exit(EXIT_SUCCESS);
}
Output:
Executing the program...
atexitFunc2 called
atexitFunc called
Note that atexitFunc2
gets called first and then atexitFunc
. Alternatively, this program can be terminated directly by calling the _exit
system call, which immediately terminates the process. Mind though, that it won’t call function registered with atexit
. In contrast, _exit
closes open file descriptors, which can cause an unknown delay before the process is terminated. Additionally, one can use the return
statement with the desired status value to cause similar termination behavior as the exit
function provides.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static void atexitFunc(void) { printf("atexitFunc called\n"); }
static void atexitFunc2(void) { printf("atexitFunc2 called\n"); }
int main(int argc, char *argv[]) {
if (atexit(atexitFunc) != 0) {
perror("atexit");
exit(EXIT_FAILURE);
}
if (atexit(atexitFunc2) != 0) {
perror("atexit");
exit(EXIT_FAILURE);
}
printf("Executing the program...\n");
sleep(5);
_exit(EXIT_SUCCESS);
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn Facebook