117721Speter#ifdef HAVE_CONFIG_H 217721Speter# include "config.h" 317721Speter#endif 417721Speter 517721Speter#include <stdio.h> 617721Speter 717721Speter#ifdef STDC_HEADERS 817721Speter# include <stdlib.h> 917721Speter#endif 1017721Speter 1117721Speter#ifdef HAVE_UNISTD_H 1217721Speter# include <unistd.h> 1317721Speter#endif 1417721Speter 1517721Speter#ifdef HAVE_FCNTL_H 1666525Speter# include <sys/types.h> 1717721Speter# include <fcntl.h> 1817721Speter#else 1917721Speter# include <sys/file.h> 2017721Speter#endif 2117721Speter 2217721Speter#ifdef HAVE_DIRECT_H 2317721Speter# include <direct.h> 2417721Speter#endif 2517721Speter 2617721Speter#ifdef HAVE_IO_H 2717721Speter# include <io.h> 2817721Speter#endif 2917721Speter 3017721Speter#include <errno.h> 3117721Speter# ifndef errno 3217721Speterextern int errno; 3317721Speter#endif 3417721Speter 3517721Speter#include "savecwd.h" 3617721Speter#include "error.h" 3717721Speter 3817721Speterchar *xgetwd __PROTO((void)); 3917721Speter 4017721Speter/* Record the location of the current working directory in CWD so that 4117721Speter the program may change to other directories and later use restore_cwd 4217721Speter to return to the recorded location. This function may allocate 4317721Speter space using malloc (via xgetwd) or leave a file descriptor open; 4417721Speter use free_cwd to perform the necessary free or close. Upon failure, 4517721Speter no memory is allocated, any locally opened file descriptors are 4617721Speter closed; return non-zero -- in that case, free_cwd need not be 4717721Speter called, but doing so is ok. Otherwise, return zero. */ 4817721Speter 4917721Speterint 5017721Spetersave_cwd (cwd) 5117721Speter struct saved_cwd *cwd; 5217721Speter{ 5317721Speter static int have_working_fchdir = 1; 5417721Speter 5517721Speter cwd->desc = -1; 5617721Speter cwd->name = NULL; 5717721Speter 5817721Speter if (have_working_fchdir) 5917721Speter { 6017721Speter#ifdef HAVE_FCHDIR 6117721Speter cwd->desc = open (".", O_RDONLY); 6217721Speter if (cwd->desc < 0) 6317721Speter { 6417721Speter error (0, errno, "cannot open current directory"); 6517721Speter return 1; 6617721Speter } 6717721Speter 6817721Speter# if __sun__ || sun 6917721Speter /* On SunOS 4, fchdir returns EINVAL if accounting is enabled, 7017721Speter so we have to fall back to chdir. */ 7117721Speter if (fchdir (cwd->desc)) 7217721Speter { 7317721Speter if (errno == EINVAL) 7417721Speter { 7517721Speter close (cwd->desc); 7617721Speter cwd->desc = -1; 7717721Speter have_working_fchdir = 0; 7817721Speter } 7917721Speter else 8017721Speter { 8117721Speter error (0, errno, "current directory"); 8217721Speter close (cwd->desc); 8317721Speter cwd->desc = -1; 8417721Speter return 1; 8517721Speter } 8617721Speter } 8717721Speter# endif /* __sun__ || sun */ 8817721Speter#else 8917721Speter#define fchdir(x) (abort (), 0) 9017721Speter have_working_fchdir = 0; 9117721Speter#endif 9217721Speter } 9317721Speter 9417721Speter if (!have_working_fchdir) 9517721Speter { 9617721Speter cwd->name = xgetwd (); 9717721Speter if (cwd->name == NULL) 9817721Speter { 9917721Speter error (0, errno, "cannot get current directory"); 10017721Speter return 1; 10117721Speter } 10217721Speter } 10317721Speter return 0; 10417721Speter} 10517721Speter 10617721Speter/* Change to recorded location, CWD, in directory hierarchy. 10717721Speter If "saved working directory", NULL)) 10817721Speter */ 10917721Speter 11017721Speterint 11117721Speterrestore_cwd (cwd, dest) 11217721Speter const struct saved_cwd *cwd; 11317721Speter const char *dest; 11417721Speter{ 11517721Speter int fail = 0; 11617721Speter if (cwd->desc >= 0) 11717721Speter { 11817721Speter if (fchdir (cwd->desc)) 11917721Speter { 12017721Speter error (0, errno, "cannot return to %s", 12117721Speter (dest ? dest : "saved working directory")); 12217721Speter fail = 1; 12317721Speter } 12417721Speter } 12517721Speter else if (chdir (cwd->name) < 0) 12617721Speter { 12717721Speter error (0, errno, "%s", cwd->name); 12817721Speter fail = 1; 12917721Speter } 13017721Speter return fail; 13117721Speter} 13217721Speter 13317721Spetervoid 13417721Speterfree_cwd (cwd) 13517721Speter struct saved_cwd *cwd; 13617721Speter{ 13717721Speter if (cwd->desc >= 0) 13817721Speter close (cwd->desc); 13917721Speter if (cwd->name) 14017721Speter free (cwd->name); 14117721Speter} 14217721Speter 143