Advanced Programming in the UNIX® Environment

(lily) #1
ptg10805159

136 Files and Directories Chapter 4


If we compile this program, call the executablemycd,and run it, we get the following:
$pwd
/usr/lib
$mycd
chdir to /tmp succeeded
$pwd
/usr/lib
The current working directory for the shell that executed themycdprogram didn’t
change. This is a side effect of the way that the shell executes programs. Each program
is run in a separate process, so the current working directory of the shell is unaffected
by the call tochdirin the program. For this reason, thechdirfunction has to be
called directly from the shell, so thecdcommand is built into the shells.

Because the kernel must maintain knowledge of the current working directory,we
should be able to fetch its current value. Unfortunately,the kernel doesn’t maintain the
full pathname of the directory.Instead, the kernel keeps information about the
directory,such as a pointer to the directory’s v-node.
The Linux kernel can determine the full pathname. Its components aredistributed throughout
the mount table and the dcache table, and arereassembled, for example, when you read the
/proc/self/cwdsymbolic link.
What we need is a function that starts at the current working directory (dot) and
works its way up the directory hierarchy,using dot-dot to move up one level. At each
level, the function reads the directory entries until it finds the name that corresponds to
the i-node of the directory that it just came from. Repeating this procedureuntil the
root is encountered yields the entireabsolute pathname of the current working
directory.Fortunately,afunction already exists that does this work for us.
#include <unistd.h>
char *getcwd(char *buf,size_tsize);
Returns:bufif OK,NULLon error
We must pass to this function the address of a buffer,buf,and itssize(in bytes). The
buffer must be large enough to accommodate the absolute pathname plus a terminating
null byte, or else an error will be returned. (Recall the discussion of allocating space for
amaximum-sized pathname in Section 2.5.5.)
Some older implementations ofgetcwdallow the first argumentbufto beNULL.Inthis case,
the function callsmallocto allocatesizenumber of bytes dynamically.This is not part of
POSIX.1 or the Single UNIX Specification and should be avoided.

Example


The program in Figure4.24 changes to a specific directory and then callsgetcwdto
print the working directory.If we run the program, we get
$./a.out
cwd = /var/spool/uucppublic
$ls -l /usr/spool
lrwxrwxrwx 1 root 12 Jan 31 07:57 /usr/spool -> ../var/spool
Free download pdf