3 Prints the absolute name of the present working directory. */
10 static bool getcwd (char *cwd, size_t cwd_size);
16 if (getcwd (cwd, sizeof cwd))
28 /* Stores the inode number for FILE_NAME in *INUM.
29 Returns true if successful, false if the file could not be
32 get_inumber (const char *file_name, int *inum)
34 int fd = open (file_name);
45 /* Prepends PREFIX to the characters stored in the final *DST_LEN
46 bytes of the DST_SIZE-byte buffer that starts at DST.
47 Returns true if successful, false if adding that many
48 characters, plus a null terminator, would overflow the buffer.
49 (No null terminator is actually added or depended upon, but
50 its space is accounted for.) */
52 prepend (const char *prefix,
53 char *dst, size_t *dst_len, size_t dst_size)
55 size_t prefix_len = strlen (prefix);
56 if (prefix_len + *dst_len + 1 <= dst_size)
58 *dst_len += prefix_len;
59 memcpy ((dst + dst_size) - *dst_len, prefix, prefix_len);
66 /* Stores the current working directory, as a null-terminated
67 string, in the CWD_SIZE bytes in CWD.
68 Returns true if successful, false on error. Errors include
69 system errors, directory trees deeper than MAX_LEVEL levels,
70 and insufficient space in CWD. */
72 getcwd (char *cwd, size_t cwd_size)
77 char name[MAX_LEVEL * 3 + 1 + READDIR_MAX_LEN + 1];
82 /* Make sure there's enough space for at least "/". */
86 /* Get inumber for current directory. */
87 if (!get_inumber (".", &child_inum))
93 int parent_inum, parent_fd;
95 /* Compose "../../../..", etc., in NAME. */
96 if ((namep - name) > MAX_LEVEL * 3)
102 /* Open directory. */
103 parent_fd = open (name);
108 /* If parent and child have the same inumber,
109 then we've arrived at the root. */
110 parent_inum = inumber (parent_fd);
111 if (parent_inum == child_inum)
114 /* Find name of file in parent directory with the child's
119 if (!readdir (parent_fd, namep) || !get_inumber (name, &test_inum))
124 if (test_inum == child_inum)
129 /* Prepend "/name" to CWD. */
130 if (!prepend (namep - 1, cwd, &cwd_len, cwd_size))
134 child_inum = parent_inum;
140 /* Move the string to the beginning of CWD,
141 and null-terminate it. */
142 memmove (cwd, (cwd + cwd_size) - cwd_len, cwd_len);
147 /* Special case for the root. */
148 strlcpy (cwd, "/", cwd_size);