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-2006 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)))
105 if ((err = _sysio_permitted(pno, X_OK)) != 0)
109 * Release old if set.
115 * Finally, change to the new.
123 SYSIO_INTERFACE_NAME(chdir)(const char *path)
127 SYSIO_INTERFACE_DISPLAY_BLOCK;
129 SYSIO_INTERFACE_ENTER;
130 err = _sysio_namei(_sysio_cwd, path, 0, NULL, &pno);
132 SYSIO_INTERFACE_RETURN(-1, err);
134 err = _sysio_p_chdir(pno);
137 SYSIO_INTERFACE_RETURN(err ? -1 : 0, err);
142 sysio_sym_weak_alias(SYSIO_INTERFACE_NAME(chdir),
143 PREPEND(__, SYSIO_INTERFACE_NAME(chdir)))
147 * Return path tracked by the path ancestor chain.
149 * If the buf pointer is NULL, a buffer large enough to hold the path
150 * is allocated from the heap.
154 _sysio_p_path(struct pnode *pno, char **buf, size_t size)
163 if (!size && buf && *buf)
167 * Walk up the tree to the root, summing the component name
168 * lengths and counting the vertices.
174 * If this is a covering path-node then the name should be
175 * the *covered* nodes name, not this one unless we are at
176 * the root of the name-space.
178 while (pno == pno->p_mount->mnt_root && pno != pno->p_parent )
179 pno = pno->p_mount->mnt_covers;
182 * Add length of this component to running sum and
183 * account for this vertex.
185 assert((len >= pno->p_base->pb_name.len &&
186 (size_t )~0 - pno->p_base->pb_name.len > len) ||
187 (size_t )~0 - len > pno->p_base->pb_name.len);
188 len += pno->p_base->pb_name.len;
192 } while (pno != pno->p_parent);
196 if (len >= size || n >= size - len)
200 * Allocate path buffer from the heap.
202 *buf = malloc(size * sizeof(char));
208 * Fill in the path buffer.
212 *cp = '\0'; /* NUL terminate */
215 * If this is a covering path-node then the name should be
216 * the *covered* nodes name, not this one unless we are at
217 * the root of the name-space.
219 while (pno == pno->p_mount->mnt_root && pno != pno->p_parent )
220 pno = pno->p_mount->mnt_covers;
223 * Add component and separator.
225 cp -= pno->p_base->pb_name.len;
226 (void )memcpy(cp, pno->p_base->pb_name.name,
227 pno->p_base->pb_name.len);
229 *--cp = PATH_SEPARATOR;
231 } while (pno != pno->p_parent);
237 SYSIO_INTERFACE_NAME(getcwd)(char *buf, size_t size)
240 SYSIO_INTERFACE_DISPLAY_BLOCK;
242 SYSIO_INTERFACE_ENTER;
243 #ifdef DEFER_INIT_CWD
248 * Can no longer defer initialization of the current working
249 * directory. Force namei to make it happen now.
251 if (_sysio_namei(NULL, ".", 0, NULL, &pno) != 0)
256 err = _sysio_p_path(_sysio_cwd, &buf, buf ? size : 0);
257 SYSIO_INTERFACE_RETURN(err ? NULL : buf, err);
262 sysio_sym_weak_alias(SYSIO_INTERFACE_NAME(getcwd),
263 PREPEND(__, SYSIO_INTERFACE_NAME(getcwd)))
266 #if defined(PATH_MAX) && !(defined(REDSTORM))
268 SYSIO_INTERFACE_NAME(getwd)(char *buf)
276 return SYSIO_INTERFACE_NAME(getcwd)(buf, PATH_MAX);