2 * This Cplant(TM) source code is the property of Sandia National
5 * This Cplant(TM) source code is copyrighted by Sandia National
8 * The redistribution of this Cplant(TM) source code is subject to the
9 * terms of the GNU Lesser General Public License
10 * (see cit/LGPL or http://www.gnu.org/licenses/lgpl.html)
12 * Cplant(TM) Copyright 1998-2003 Sandia Corporation.
13 * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
14 * license for use of this work by or on behalf of the US Government.
15 * Export of this program may require a license from the United States
20 * #############################################################################
22 * # This Cplant(TM) source code is the property of Sandia National
25 * # This Cplant(TM) source code is copyrighted by Sandia National
28 * # The redistribution of this Cplant(TM) source code is subject to the
29 * # terms of the GNU Lesser General Public License
30 * # (see cit/LGPL or http://www.gnu.org/licenses/lgpl.html)
32 * # Cplant(TM) Copyright 1998-2003 Sandia Corporation.
33 * # Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
34 * # license for use of this work by or on behalf of the US Government.
35 * # Export of this program may require a license from the United States
38 * #############################################################################
42 * This library is free software; you can redistribute it and/or
43 * modify it under the terms of the GNU Lesser General Public
44 * License as published by the Free Software Foundation; either
45 * version 2.1 of the License, or (at your option) any later version.
47 * This library is distributed in the hope that it will be useful,
48 * but WITHOUT ANY WARRANTY; without even the implied warranty of
49 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
50 * Lesser General Public License for more details.
52 * You should have received a copy of the GNU Lesser General Public
53 * License along with this library; if not, write to the Free Software
54 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
56 * Questions or comments about this library should be sent to:
59 * Sandia National Laboratories, New Mexico
61 * Albuquerque, NM 87185-1110
67 #include <sys/types.h>
74 #include <sys/queue.h>
80 #include "sysio-symbols.h"
83 const char *_sysio_init_cwd = NULL;
86 struct pnode *_sysio_cwd = NULL;
89 * Change to directory specified by the given pnode.
92 _sysio_p_chdir(struct pnode *pno)
97 * Revalidate the pnode, and ensure it's an accessable directory
99 err = _sysio_p_validate(pno, NULL, NULL);
102 if (!(pno->p_base->pb_ino &&
103 S_ISDIR(pno->p_base->pb_ino->i_stbuf.st_mode)))
106 err = _sysio_permitted(pno->p_base->pb_ino, X_OK);
111 * Release old if set.
117 * Finally, change to the new.
125 SYSIO_INTERFACE_NAME(chdir)(const char *path)
129 SYSIO_INTERFACE_DISPLAY_BLOCK;
131 SYSIO_INTERFACE_ENTER;
132 err = _sysio_namei(_sysio_cwd, path, 0, NULL, &pno);
134 SYSIO_INTERFACE_RETURN(-1, err);
136 err = _sysio_p_chdir(pno);
139 SYSIO_INTERFACE_RETURN(err ? -1 : 0, err);
144 sysio_sym_weak_alias(SYSIO_INTERFACE_NAME(chdir),
145 PREPEND(__, SYSIO_INTERFACE_NAME(chdir)))
149 * Return path tracked by the path ancestor chain.
151 * If the buf pointer is NULL, a buffer large enough to hold the path
152 * is allocated from the heap.
156 _sysio_p_path(struct pnode *pno, char **buf, size_t size)
165 if (!size && buf && *buf)
169 * Walk up the tree to the root, summing the component name
170 * lengths and counting the vertices.
176 * If this is a covering path-node then the name should be
177 * the *covered* nodes name, not this one unless we are at
178 * the root of the name-space.
180 while (pno == pno->p_mount->mnt_root && pno != pno->p_parent )
181 pno = pno->p_mount->mnt_covers;
184 * Add length of this component to running sum and
185 * account for this vertex.
187 assert((len >= pno->p_base->pb_name.len &&
188 (size_t )~0 - pno->p_base->pb_name.len > len) ||
189 (size_t )~0 - len > pno->p_base->pb_name.len);
190 len += pno->p_base->pb_name.len;
194 } while (pno != pno->p_parent);
198 if (len >= size || n >= size - len)
202 * Allocate path buffer from the heap.
204 *buf = malloc(size * sizeof(char));
210 * Fill in the path buffer.
214 *cp = '\0'; /* NUL terminate */
217 * If this is a covering path-node then the name should be
218 * the *covered* nodes name, not this one unless we are at
219 * the root of the name-space.
221 while (pno == pno->p_mount->mnt_root && pno != pno->p_parent )
222 pno = pno->p_mount->mnt_covers;
225 * Add component and separator.
227 cp -= pno->p_base->pb_name.len;
228 (void )memcpy(cp, pno->p_base->pb_name.name,
229 pno->p_base->pb_name.len);
231 *--cp = PATH_SEPARATOR;
233 } while (pno != pno->p_parent);
239 SYSIO_INTERFACE_NAME(getcwd)(char *buf, size_t size)
242 SYSIO_INTERFACE_DISPLAY_BLOCK;
244 SYSIO_INTERFACE_ENTER;
250 * Can no longer defer initialization of the current working
251 * directory. Force namei to make it happen now.
253 if (_sysio_namei(NULL, ".", 0, NULL, &pno) != 0)
258 err = _sysio_p_path(_sysio_cwd, &buf, buf ? size : 0);
259 SYSIO_INTERFACE_RETURN(err ? NULL : buf, err);
264 sysio_sym_weak_alias(SYSIO_INTERFACE_NAME(getcwd),
265 PREPEND(__, SYSIO_INTERFACE_NAME(getcwd)))
268 #if defined(PATH_MAX) && !(defined(REDSTORM))
270 SYSIO_INTERFACE_NAME(getwd)(char *buf)
278 return SYSIO_INTERFACE_NAME(getcwd)(buf, PATH_MAX);