/***********************************************************************1* *2* This software is part of the ast package *3* Copyright (c) 1985-2011 AT&T Intellectual Property *4* and is licensed under the *5* Eclipse Public License, Version 1.0 *6* by AT&T Intellectual Property *7* *8* A copy of the License is available at *9* http://www.eclipse.org/org/documents/epl-v10.html *10* (with md5 checksum b35adb5213ca9657e911e9befb180842) *11* *12* Information and Software Systems Research *13* AT&T Research *14* Florham Park NJ *15* *16* Glenn Fowler <[email protected]> *17* David Korn <[email protected]> *18* Phong Vo <[email protected]> *19* *20***********************************************************************/21#pragma prototyped22/*23* K. P. Vo24* G. S. Fowler25* AT&T Research26*/2728#include <ast.h>29#include <error.h>30#include <stk.h>3132#if DEBUG3334#undef PATH_MAX3536#define PATH_MAX 163738static int39vchdir(const char* path)40{41int n;4243if (strlen(path) >= PATH_MAX)44{45errno = ENAMETOOLONG;46n = -1;47}48else n = chdir(path);49return n;50}5152#define chdir(p) vchdir(p)5354#endif5556/*57* set the current directory to path58* if path is long and home!=0 then pathcd(home,0)59* is called on intermediate chdir errors60*/6162int63pathcd(const char* path, const char* home)64{65register char* p = (char*)path;66register char* s;67register int n;68int i;69int r;7071r = 0;72for (;;)73{74/*75* this should work 99% of the time76*/7778if (!chdir(p))79return r;8081/*82* chdir failed83*/8485if ((n = strlen(p)) < PATH_MAX)86return -1;87#ifdef ENAMETOOLONG88if (errno != ENAMETOOLONG)89return -1;90#endif9192/*93* path is too long -- copy so it can be modified in place94*/9596i = stktell(stkstd);97sfputr(stkstd, p, 0);98stkseek(stkstd, i);99p = stkptr(stkstd, i);100for (;;)101{102/*103* get a short prefix component104*/105106s = p + PATH_MAX;107while (--s >= p && *s != '/');108if (s <= p)109break;110111/*112* chdir to the prefix113*/114115*s++ = 0;116if (chdir(p))117break;118119/*120* do the remainder121*/122123if ((n -= s - p) < PATH_MAX)124{125if (chdir(s))126break;127return r;128}129p = s;130}131132/*133* try to recover back to home134*/135136if (!(p = (char*)home))137return -1;138home = 0;139r = -1;140}141}142143144