VM: full munmap
[minix.git] / lib / libsffs / path.c
blob8abe9b3550137eceda22bc0e62c7c8ad511a97c9
1 /* This file contains routines for creating and manipulating path strings.
3 * The entry points into this file are:
4 * make_path construct a path string for an inode
5 * push_path add a path component to the end of a path string
6 * pop_path remove the last path component from a path string
8 * Created:
9 * April 2009 (D.C. van Moolenbroek)
12 #include "inc.h"
14 /*===========================================================================*
15 * make_path *
16 *===========================================================================*/
17 int make_path(path, ino)
18 char path[PATH_MAX];
19 struct inode *ino;
21 /* Given an inode, construct the path identifying that inode.
23 char buf[PATH_MAX], *p, *prefix;
24 size_t len, plen, total;
26 p = &buf[sizeof(buf) - 1];
27 p[0] = 0;
29 dprintf(("%s: make_path: constructing path for inode %d\n",
30 sffs_name, ino->i_num));
32 /* Get the length of the prefix, skipping any leading slashes. */
33 for (prefix = sffs_params->p_prefix; prefix[0] == '/'; prefix++);
34 plen = strlen(prefix);
36 /* Construct the path right-to-left in a temporary buffer first. */
37 for (total = plen; ino != NULL && !IS_ROOT(ino); ino = ino->i_parent) {
38 len = strlen(ino->i_name);
40 total += len + 1;
41 p -= len + 1;
43 if (total >= sizeof(buf))
44 return ENAMETOOLONG;
46 p[0] = '/';
47 memcpy(p + 1, ino->i_name, len);
50 /* If any of the intermediate inodes has no parent, the final inode is no
51 * longer addressable by name.
53 if (ino == NULL)
54 return ENOENT;
56 /* Put the result in the actual buffer. We need the leading slash in the
57 * temporary buffer only when the prefix is not empty.
59 if (!prefix[0] && p[0] == '/') p++;
61 strlcpy(path, prefix, PATH_MAX);
62 strlcpy(&path[plen], p, PATH_MAX - plen);
64 dprintf(("%s: make_path: resulting path is '%s'\n", sffs_name, path));
66 return OK;
69 /*===========================================================================*
70 * push_path *
71 *===========================================================================*/
72 int push_path(path, name)
73 char path[PATH_MAX];
74 char *name;
76 /* Add a component to the end of a path.
78 size_t len, add;
80 len = strlen(path);
81 add = strlen(name);
82 if (len > 0) add++;
84 if (len + add >= PATH_MAX)
85 return ENAMETOOLONG;
87 if (len > 0) path[len++] = '/';
88 strlcpy(&path[len], name, PATH_MAX - len);
90 return OK;
93 /*===========================================================================*
94 * pop_path *
95 *===========================================================================*/
96 void pop_path(path)
97 char path[PATH_MAX];
99 /* Remove the last component from a path.
101 char *p;
103 p = strrchr(path, '/');
105 if (p == NULL) {
106 p = path;
108 /* Can't pop the root component */
109 assert(p[0] != 0);
112 p[0] = 0;