exit(3)

๐Ÿ’– exit(3) โ€” the manual page, but make it make sense ๐Ÿ’–

okay bestie, welcome to exit(3) from the Library Functions Manual. yes that's the whole title. we're doing process termination today and we're doing it cutely. ๐ŸŽ€


โœจ NAME โœจ

exit โ€” cause normal process termination

like. the vibe check that ends the whole program. periodt. ๐Ÿ’…


๐Ÿ“š LIBRARY ๐Ÿ“š

Standard C library (libc, -lc) ๐Ÿซถ


๐ŸŒธ SYNOPSIS ๐ŸŒธ

#include <stdlib.h>

[[noreturn]] void exit(int status);

so you include <stdlib.h>, and you call it with an int status. that's it. that's the whole summoning ritual. โœจ


๐Ÿฆ‹ DESCRIPTION ๐Ÿฆ‹

okay so exit() causes normal process termination, and the least significant byte of status (aka status & 0xFF) gets handed back to the parent process โ€” check out wait(2) for the receiving end of that. ๐Ÿ’Œ

Every function you registered with atexit(3) and on_exit(3) gets called, in reverse order of registration. yes, reverse. last one in, first one out, it's giving stack energy fr fr.

and here's the spicy part โ€” it is literally possible for one of those functions to call atexit(3) or on_exit(3) and register yet another function to run during exit processing, and that new registration gets added to the front of the list of functions still waiting to be called. chaotic? yes. legal? also yes. ๐Ÿ˜ญ

but if one of those functions doesn't return (like, it calls _exit(3), or it just kills itself with a signal), then none of the remaining functions get called, and further exit processing โ€” especially the flushing of stdio(3) streams โ€” is abandoned. gone. not happening. ๐Ÿ’€

oh and if a function was registered multiple times with atexit(3) or on_exit(3), it gets called as many times as it was registered. equal treatment. no favoritism. ๐Ÿ‘‘

All open stdio(3) streams get flushed and closed. Files created by tmpfile(3) get removed. clean up after yourself queen. ๐Ÿงน

The C standard specifies two constants โ€” <mint>EXIT_SUCCESS</mint> and <mint>EXIT_FAILURE</mint> โ€” and you can pass those to exit() to say "successful termination" or "unsuccessful termination" respectively. use them. they're iconic. ๐ŸŒˆ


๐Ÿ’ซ RETURN VALUE ๐Ÿ’ซ

The exit() function does not return.

not "returns 0". not "returns NULL". it does not return. no return value era. she's gone. ๐Ÿฆ‹โœจ


๐Ÿ”ฅ ATTRIBUTES ๐Ÿ”ฅ

for an explanation of the terms used in this section, go see attributes(7) bestie.

  • Interface: exit()
  • Attribute: Thread safety
  • Value: MT-Unsafe race:exit

so basically: the exit() function uses a global variable that is not protected, which means it is not thread-safe. heads up if you're in your multithreaded girlboss era. ๐Ÿ’…


โญ STANDARDS โญ

C11, POSIX.1-2008. certified. โœจ


๐ŸŽ€ HISTORY ๐ŸŽ€

C89, POSIX.1-2001, SVr4, 4.3BSD. she's been around. she's got lore. ๐Ÿ‘‘


๐Ÿ’œ NOTES ๐Ÿ’œ

okay important stuff, pay attention:

The behavior is undefined if one of the functions registered using atexit(3) and on_exit(3) calls either exit() or longjmp(3). undefined. like, technically anything can happen. do not do this. ๐Ÿ™ˆ

Also note that a call to execve(2) removes registrations created using atexit(3) and on_exit(3). bye registrations. โœŒ๏ธ

The use of EXIT_SUCCESS and EXIT_FAILURE is slightly more portable (to non-UNIX environments) than using 0 and some nonzero value like 1 or -1. In particular, VMS uses a different convention. so like, if you wanna be a global traveler with your code, use the constants. ๐ŸŒ

BSD has attempted to standardize exit codes (and some C libraries, such as the GNU C library, have adopted that too) โ€” see the file <sysexits.h>. ๐Ÿ“„

After exit(), the exit status must be transmitted to the parent process. There are three cases:

  1. If the parent has set SA_NOCLDWAIT, or has set the SIGCHLD handler to SIG_IGN, the status is discarded and the child dies immediately.
  2. If the parent was waiting on the child, it is notified of the exit status and the child dies immediately.
  3. Otherwise, the child becomes a "zombie" process: most of the process resources are recycled, but a slot containing minimal information about the child process (termination status, resource usage statistics) is retained in the process table. This allows the parent to subsequently use waitpid(2) (or similar) to learn the termination status of the child; at that point the zombie process slot is released. ๐ŸงŸ

If the implementation supports the SIGCHLD signal, this signal is sent to the parent. If the parent has set SA_NOCLDWAIT, it is undefined whether a SIGCHLD signal is sent.

๐ŸŒŠ Signals sent to other processes ๐ŸŒŠ

If the exiting process is a session leader and its controlling terminal is the controlling terminal of the session, then every process in the foreground process group of this controlling terminal gets a SIGHUP signal, and the terminal is disassociated from this session โ€” which lets it be acquired by a new controlling process. handing off the aux cord, basically. ๐ŸŽง

If the exit of the process causes a process group to become orphaned, and if any member of the newly orphaned process group is stopped, then a SIGHUP signal followed by a SIGCONT signal will be sent to each process in this process group. See setpgid(2) for an explanation of orphaned process groups. ๐Ÿซถ

Except in the above cases โ€” where the signalled processes may be children of the terminating process โ€” termination of a process does not in general cause a signal to be sent to children of that process. However, a process can use the prctl(2) PR_SET_PDEATHSIG operation to arrange that it receives a signal if its parent terminates. so if you wanna know when mom leaves, there's a way. ๐Ÿ˜ญ


๐Ÿ‘€ SEE ALSO ๐Ÿ‘€

get_robust_list(2), exit(2), setpgid(2), wait(2), _exit(3), atexit(3), on_exit(3), tmpfile(3)

go read them. do it. iykyk. ๐Ÿ“šโœจ


and that's the whole page bestie!! ๐ŸŽ€๐Ÿ’–

this whole thing is from Linux man-pages 6.20, dated 2026-06-05 โ€” that's the exit(3) page, and honestly? she ate. ๐Ÿ’…๐Ÿฆ‹โœจ

๐Ÿ“ฆ where this page comes from
  • arch rolling: man-pages 6.20-1 ยท BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
  • nixpkgs unstable: man-pages 6.20
  • ๐Ÿ“œ the page's license: Linux-man-pages-copyleft
  • ๐Ÿ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms