_exit(2)

๐Ÿ’… _exit(2) โ€” the "girl, I'm out" syscall ๐Ÿ’…

okay bestie, so this is page _exit(2) from the System Calls Manual, and honestly? it's giving "exit but make it instant." no cleanup era, no goodbye tour, just โœจgoneโœจ. let me walk you through it ๐Ÿซถ


๐ŸŒธ NAME ๐ŸŒธ

_exit, _Exit โ€” terminate the calling process

like, end it. that's the whole job. periodt ๐Ÿ’€


๐ŸŽ€ LIBRARY ๐ŸŽ€

Standard C library (libc, -lc)


โœจ SYNOPSIS โœจ

#include <unistd.h>

[[noreturn]] void _exit(int status);
#include <stdlib.h>

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

๐Ÿฆ‹ Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

_Exit():
    _ISOC99_SOURCE || _POSIX_C_SOURCE >= 200112L

so if you're trying to use _Exit() and the compiler's acting brand new, that's your vibe check right there ๐Ÿ‘‘


๐Ÿ’– DESCRIPTION ๐Ÿ’–

_exit() terminates the calling process "immediately". and yes the quotes are doing heavy lifting there, we'll get to that. anyway, here's the tea ๐Ÿต:

  • any open file descriptors belonging to the process get closed
  • any children of the process are inherited by init(1) (or by the nearest "subreaper" process as defined through the use of the prctl(2) PR_SET_CHILD_SUBREAPER operation) โ€” so your kids get adopted, no cap ๐Ÿงš
  • the process's parent is sent a SIGCHLD signal ๐Ÿ“จ

The value status & 0xFF is returned to the parent process as the process's exit status, and can be collected by the parent using one of the wait(2) family of calls. so like, mask it down to the low 8 bits and that's what mama gets in the mail ๐Ÿ’Œ

The function _Exit() is equivalent to _exit(). literally twins. same energy. ๐Ÿ‘ฏ


๐Ÿ”ฅ RETURN VALUE ๐Ÿ”ฅ

These functions do not return.

not "return null", not "return -1" โ€” they Do Not Return. you don't come back from this one, bestie ๐Ÿ’€โœจ


๐ŸŒˆ STANDARDS ๐ŸŒˆ

  • _exit() โ€” POSIX.1-2024.
  • _Exit() โ€” C11, POSIX.1-2024.

both iconic, both standards-approved ๐Ÿ‘‘


โญ HISTORY โญ

  • _exit() โ€” 4.3BSD, SVr4, POSIX.1-1988.
  • _Exit() โ€” C99, POSIX.1-2001.

she's got lore. she's got range. she's been around ๐ŸŽ€


๐Ÿ’œ NOTES ๐Ÿ’œ

okay so this is the part where it gets juicy ๐Ÿ“

For a discussion on the effects of an exit, the transmission of exit status, zombie processes, signals sent, and so on โ€” see exit(3). zombie processes!! plural!! we love a spooky queen ๐ŸงŸโ€โ™€๏ธ

The function _exit() is like exit(3), but does not call any functions registered with atexit(3) or on_exit(3). so all those cleanup handlers you carefully registered? they're not getting called. they're staying on read ๐Ÿ™ˆ

Open stdio(3) streams are not flushed. yeah. your buffered output? might just evaporate. if you needed that, you should've called exit(3), bestie ๐Ÿ˜ญ

On the other hand, _exit() does close open file descriptors, and this may cause an unknown delay, waiting for pending output to finish. so like, it's fast but not guaranteed fast, which is the most annoying kind of fast tbh ๐Ÿ’€ If the delay is undesired, it may be useful to call functions like tcflush(3) before calling _exit(). Whether any pending I/O is canceled, and which pending I/O may be canceled upon _exit(), is implementation-dependent. so it's giving "it depends" and we simply have to live with that ๐ŸŒธ

๐Ÿงš C library/kernel differences ๐Ÿงš

The text above in DESCRIPTION describes the traditional effect of _exit(), which is to terminate a process, and these are the semantics specified by POSIX.1 and implemented by the C library wrapper function. On modern systems, this means termination of all threads in the process. so: whole squad gone. bye to everyone ๐Ÿ‘‹

By contrast with the C library wrapper function, the raw Linux _exit() system call terminates only the calling thread, and actions such as reparenting child processes or sending SIGCHLD to the parent process are performed only if this is the last thread in the thread group. so the syscall is out here doing solo missions while the wrapper is running the whole group chat ๐Ÿ˜ญ the audacity

Up to glibc 2.3, the _exit() wrapper function invoked the kernel system call of the same name. Since glibc 2.3, the wrapper function invokes exit_group(2), in order to terminate all of the threads in a process. glow-up era โœจ exit_group(2) said "I'll handle the whole thread group, thanks" ๐Ÿ’…


๐Ÿฆ‹ SEE ALSO ๐Ÿฆ‹

execve(2), exit_group(2), fork(2), kill(2), wait(2), wait4(2), waitpid(2), atexit(3), exit(3), on_exit(3), termios(3)

the whole friend group honestly, go read them ๐Ÿซถ


and that's the page!! ๐Ÿ’– this lil number is from Linux man-pages 6.18, dated 2026-02-08, and it's the _exit(2) entry โ€” so next time you need to leave a process with zero drama and zero cleanup, you know exactly who to call. mwah ๐Ÿ’‹ bye bestie!! ๐ŸŒˆโœจ

๐Ÿ“ฆ where this page comes from