chdir(2)

๐Ÿ’ซ chdir, fchdir โ€” changing where you live (your working directory, bestie)

okay so real talk: this is chdir(2), the system calls manual page, and it's genuinely one of the most useful lil pages in the whole book. If you've ever wanted your program to move to a different directory instead of just yapping about paths, this is the one. Let's get into it ๐Ÿ’…


โœจ LIBRARY โœจ

Standard C library, aka libc, link it with -lc. The classics ๐ŸŽ€


๐ŸŒธ SYNOPSIS ๐ŸŒธ

#include <unistd.h>

int chdir(const char *path);
int fchdir(int fd);

๐Ÿฆ‹ Feature Test Macro Requirements for glibc ๐Ÿฆ‹

(genuinely just go read feature_test_macros(7) if you wanna know the whole lore)

For fchdir():

_XOPEN_SOURCE >= 500
    || /* Since glibc 2.12: */ _POSIX_C_SOURCE >= 200809L
    || /* glibc up to and including 2.19: */ _BSD_SOURCE

yes bestie the comments are literally in the macro, that's not me being cute, that's just how it's written ๐Ÿ˜ญ


๐Ÿ’– DESCRIPTION ๐Ÿ’–

chdir() changes the current working directory of the process that's calling it, and it sends it to whatever directory you named in <italic>path*. It's giving "we live here now." ๐Ÿก

fchdir() is literally identical to chdir(). The only difference โ€” the one difference, no cap โ€” is that instead of a path you hand it an open file descriptor. Same energy, different entrance ๐Ÿšช


๐Ÿ”ฅ RETURN VALUE ๐Ÿ”ฅ

  • Slay (success): returns zero โœจ
  • Not slay (error): returns -1, and errno gets set to tell you exactly what went wrong ๐Ÿ‘‘

๐Ÿ’€ ERRORS ๐Ÿ’€

Heads up: depending on what filesystem you're on, other errors can pop up too. But here are the more general ones for chdir():

  • EACCES โ€” search permission was denied for one of the components of <italic>path*. (go peek at path_resolution(7) for the full saga)
  • EFAULT โ€” <italic>path* is pointing somewhere outside your accessible address space. Rude.
  • EIO โ€” an I/O error happened, it's giving haunted hardware ๐Ÿซ 
  • ELOOP โ€” wayyy too many symbolic links got encountered while resolving <italic>path*.
  • ENAMETOOLONG โ€” <italic>path* is too long. bestie. it's too long.
  • ENOENT โ€” the directory you named in <italic>path* does not exist ๐Ÿ˜ญ
  • ENOMEM โ€” insufficient kernel memory was available.
  • ENOTDIR โ€” a component of <italic>path* is not a directory.

And now the general errors for fchdir():

  • EACCES โ€” search permission was denied on the directory that's open on fd.
  • EBADF โ€” fd is not a valid file descriptor ๐Ÿ™ˆ
  • ENOTDIR โ€” fd does not refer to a directory.

๐Ÿ‘‘ STANDARDS ๐Ÿ‘‘

POSIX.1-2024. periodt.


๐ŸŒˆ HISTORY ๐ŸŒˆ

  • chdir() โ€” SVr4, POSIX.1-1988, 4.4BSD.
  • fchdir() โ€” SVr4, 4.4BSD, SUSv1, POSIX.1-2001 XSI, POSIX.1-2008.

look at her, she's been iconic since the 80s ๐Ÿ’œ


๐Ÿงš NOTES ๐Ÿงš

The current working directory is the starting point for interpreting relative pathnames โ€” you know, the ones that don't start with '/'. So like, "../somedir" means "from wherever I am right now," which is exactly why this call matters so much ๐Ÿ‘€

A child process created via fork(2) inherits its parent's current working directory. But โ€” and this is the part people forget โ€” the current working directory is left unchanged by execve(2). So it survives the exec, no notes โœจ


๐Ÿซถ SEE ALSO ๐Ÿซถ


and that's the whole page, bestie!! this one came from Linux man-pages 6.20, dated 2026-02-08, and it's the chdir(2) page ๐Ÿ’– go change some directories, you absolute icon ๐Ÿฆ‹โœจ

๐Ÿ“ฆ 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