unlocked_stdio(3)

πŸ’– unlocked_stdio(3) β€” the nonlocking stdio besties πŸ’–

okay so. bestie. you know how <stdio.h> is like the main character of every C program ever? well this page is about its unlocked siblings β€” the ones who do the exact same job but refuse to wait their turn in line. very "i don't queue, i arrive" energy. no cap. πŸŽ€


✨ NAME ✨

getc_unlocked, getchar_unlocked, putc_unlocked, putchar_unlocked β€” the nonlocking stdio functions, aka the stdio girlies who skipped the lock entirely πŸ’…


πŸ“š LIBRARY πŸ“š

Standard C library (libc, -lc)


πŸ¦‹ SYNOPSIS πŸ¦‹

like, here's the whole friend group. every single one. no skipping, we do not gatekeep here 🫢

#include <stdio.h>

int getc_unlocked(FILE *stream);
int getchar_unlocked(void);
int putc_unlocked(int c, FILE *stream);
int putchar_unlocked(int c);

void clearerr_unlocked(FILE *stream);
int feof_unlocked(FILE *stream);
int ferror_unlocked(FILE *stream);
int fileno_unlocked(FILE *stream);
int fflush_unlocked(FILE *_Nullable stream);

int fgetc_unlocked(FILE *stream);
int fputc_unlocked(int c, FILE *stream);

size_t fread_unlocked(size_t size, size_t n;
                      void ptr[restrict size * n],
                      size_t size, size_t n,
                      FILE *restrict stream);
size_t fwrite_unlocked(size_t size, size_t n;
                      const void ptr[restrict size * n],
                      size_t size, size_t n,
                      FILE *restrict stream);

char *fgets_unlocked(int n;
                      char s[restrict n], int n, FILE *restrict stream);
int fputs_unlocked(const char *restrict s, FILE *restrict stream);

#include <wchar.h>

wint_t getwc_unlocked(FILE *stream);
wint_t getwchar_unlocked(void);
wint_t fgetwc_unlocked(FILE *stream);

wint_t fputwc_unlocked(wchar_t wc, FILE *stream);
wint_t putwc_unlocked(wchar_t wc, FILE *stream);
wint_t putwchar_unlocked(wchar_t wc);

wchar_t *fgetws_unlocked(int n;
                      wchar_t ws[restrict n], int n,
                      FILE *restrict stream);
int fputws_unlocked(const wchar_t *restrict ws,
                      FILE *restrict stream);

πŸ”‘ Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

okay this part is the "which door do i knock on" section and it is SO specific, so read carefully bestie:

getc_unlocked(), getchar_unlocked(), putc_unlocked(), putchar_unlocked():

/* glibc >= 2.24: */ _POSIX_C_SOURCE >= 199309L
    || /* glibc <= 2.23: */ _POSIX_C_SOURCE
    || /* glibc <= 2.19: */ _SVID_SOURCE || _BSD_SOURCE

clearerr_unlocked(), feof_unlocked(), ferror_unlocked(), fileno_unlocked(), fflush_unlocked(), fgetc_unlocked(), fputc_unlocked(), fread_unlocked(), fwrite_unlocked():

/* glibc >= 2.19: */ _DEFAULT_SOURCE
    || /* glibc <= 2.19: */ _SVID_SOURCE || _BSD_SOURCE

fgets_unlocked(), fputs_unlocked(), getwc_unlocked(), getwchar_unlocked(), fgetwc_unlocked(), fputwc_unlocked(), putwchar_unlocked(), fgetws_unlocked(), fputws_unlocked():

_GNU_SOURCE

🌸 DESCRIPTION 🌸

every single one of these functions behaves exactly like its counterpart without the _unlocked suffix. same vibes, same results, zero drama. the ONE difference? they do not use locking. like, they don't set locks themselves, and they don't check for locks that somebody else set either. which means… they are thread-unsafe. periodt. πŸ”₯

πŸ’€ real talk: thread-unsafe is not a cute little quirk, it's a whole situation. go read flockfile(3) if you need the locked-up version, bestie.

πŸ‘‘ ATTRIBUTES πŸ‘‘

for the whole explanation of what these words even mean, see attributes(7). here's the rundown, and yes i'm giving you every line 🧚

Thread safety: MT-Safe race:stream β€” for:

  • getc_unlocked()
  • putc_unlocked()
  • clearerr_unlocked()
  • fflush_unlocked()
  • fgetc_unlocked()
  • fputc_unlocked()
  • fread_unlocked()
  • fwrite_unlocked()
  • fgets_unlocked()
  • fputs_unlocked()
  • getwc_unlocked()
  • fgetwc_unlocked()
  • fputwc_unlocked()
  • putwc_unlocked()
  • fgetws_unlocked()
  • fputws_unlocked()

Thread safety: MT-Unsafe race:stdin β€” for:

  • getchar_unlocked()
  • getwchar_unlocked()

Thread safety: MT-Unsafe race:stdout β€” for:

  • putchar_unlocked()
  • putwchar_unlocked()

Thread safety: MT-Safe β€” for:

  • feof_unlocked()
  • ferror_unlocked()
  • fileno_unlocked()

⭐ STANDARDS ⭐

literally the receipts:

  • getc_unlocked()
  • getchar_unlocked()
  • putc_unlocked()
  • putchar_unlocked()

β†’ POSIX.1-2008. slay. πŸ‘‘

  • everything else:

β†’ None. they're just out here, unstandardized, living their truth. πŸ™ˆ


🌈 HISTORY 🌈

the origin story, bestie:

  • getc_unlocked()
  • getchar_unlocked()
  • putc_unlocked()
  • putchar_unlocked()

β†’ POSIX.1-2001. they've been iconic for a minute.


πŸŽ€ SEE ALSO πŸŽ€


and that's the whole page, you're welcome πŸ’œ this was Linux man-pages 6.20, dated 2026-02-08, and this is unlocked_stdio(3) signing off. mwah. 🫢✨

πŸ“¦ 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