How to Use the exit Function in C

Jinku Hu Feb 02, 2024
  1. Use the exit Function to Terminate Process in C
  2. Use the atexit Function to Register Exit Handler in C
How to Use the exit Function 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);
Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

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

Related Article - C Process