chdir(2) — Linux man page
Feature Test Macro Requirements for glibc (see feature_test_macros(7)): fchdir(): _BSD_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED
|| /* Since glibc 2.12: */ _POSIX_C_SOURCE >= 200809L
Description
chdir() changes the current working directory of the calling process to the directory specified in path.
fchdir() is identical to chdir(); the only difference is that the directory is given as an open file descriptor.
Return Value
On success, zero is returned. On error, -1 is returned, and errno is set appropriately.
Errors
Depending on the file system, other errors can be returned. The more general errors for chdir() are listed below: EACCES
Search permission is denied for one of the components of path. (See also path_resolution(7).)
path points outside your accessible address space.
Too many symbolic links were encountered in resolving path. ENAMETOOLONG path is too long. ENOENT
Insufficient kernel memory was available. ENOTDIR A component of path is not a directory. The general errors for fchdir() are listed below: EACCES
Search permission was denied on the directory open on fd.
fd is not a valid file descriptor.
Conforming To
Notes
The current working directory is the starting point for interpreting relative pathnames (those not starting with ‘/’).
A child process created via fork(2) inherits its parent’s current working directory. The current working directory is left unchanged by execve(2).
chdir() to home directory
I am using the chdir() C function to allow a user to change directory. The function however, doesn’t recognize ‘~’. Do I need to do any explicit conversion, so chdir doesn’t recognize what ~ means? Because mine isn’t working. Or am I doing something wrong?
When you need to expand ~username , you’ll need to use getpwnam() instead of getpwuid() to find the home directory.
2 Answers 2
Tilde expansion is handled by the shell, not by a system call. You could use getenv() to read the environment variable HOME and then use that as the argument to chdir() .
There are system calls to get this information that may be more reliable on an individual system, but they’re not completely portable. Look, for example, at getpwuid().
Is chdir() guaranteed not to crash if the argument is NULL? If so, this would be OK; otherwise, a little error checking would be in order!
Here’s a code snippet for anyone looking to use the latter method. jonathonhill.net/2013-09-03/tilde-expansion-in-php
Note that POSIX specifies the semantics of tilde expansion:
2.6.1 Tilde Expansion
A «tilde-prefix» consists of an unquoted character at the beginning of a word, followed by all of the characters preceding the first unquoted in the word, or all the characters in the word if there is no . In an assignment (see XBD Variable Assignment ), multiple tilde-prefixes can be used: at the beginning of the word (that is, following the of the assignment), following any unquoted , or both. A tilde-prefix in an assignment is terminated by the first unquoted or . If none of the characters in the tilde-prefix are quoted, the characters in the tilde-prefix following the are treated as a possible login name from the user database. A portable login name cannot contain characters outside the set given in the description of the LOGNAME environment variable in XBD Other Environment Variables. If the login name is null (that is, the tilde-prefix contains only the tilde), the tilde-prefix is replaced by the value of the variable HOME . If HOME is unset, the results are unspecified. Otherwise, the tilde-prefix shall be replaced by a pathname of the initial working directory associated with the login name obtained using the getpwnam() function as defined in the System Interfaces volume of POSIX.1-2008. If the system does not recognize the login name, the results are undefined.
Note in particular that if my username is me , the results of cd ~ and cd ~me may not be the same! Specifically, the HOME environment variable could be set to a value different from the one returned by getpwnam() . I’ve been using this technique for (way over 25) years to set my HOME where I want it, and the few programs that don’t recognize the difference between cd ~ and cd ~me are some (of the many) banes of my life.
chdir(3) — Linux man page
This manual page is part of the POSIX Programmer’s Manual. The Linux implementation of this interface may differ (consult the corresponding Linux manual page for details of Linux behavior), or the interface may not be implemented on Linux.
Name
Synopsis
int chdir(const char *path);
Description
The chdir() function shall cause the directory named by the pathname pointed to by the path argument to become the current working directory; that is, the starting point for path searches for pathnames not beginning with ‘/’ .
Return Value
Upon successful completion, 0 shall be returned. Otherwise, -1 shall be returned, the current working directory shall remain unchanged, and errno shall be set to indicate the error.
Errors
The chdir() function shall fail if: EACCES Search permission is denied for any component of the pathname. ELOOP A loop exists in symbolic links encountered during resolution of the path argument. ENAMETOOLONG The length of the path argument exceeds or a pathname component is longer than . ENOENT A component of path does not name an existing directory or path is an empty string. ENOTDIR A component of the pathname is not a directory.
The chdir() function may fail if: ELOOP More than symbolic links were encountered during resolution of the path argument. ENAMETOOLONG As a result of encountering a symbolic link in resolution of the path argument, the length of the substituted pathname string exceeded .
The following sections are informative.
Examples
Changing the Current Working Directory
The following example makes the value pointed to by directory, /tmp, the current working directory.
#include unistd.h> . char *directory = "/tmp"; int ret; ret = chdir (directory);
Application Usage
Rationale
The chdir() function only affects the working directory of the current process.
Future Directions
See Also
getcwd(), the Base Definitions volume of IEEE Std 1003.1-2001,