PageRenderTime 75ms CodeModel.GetById 63ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 0ms

/contrib/cvs/lib/savecwd.c

https://bitbucket.org/freebsd/freebsd-head/
C | 142 lines | 110 code | 19 blank | 13 comment | 16 complexity | e49beb123c7e63f582443ff38281c028 MD5 | raw file
  1#ifdef HAVE_CONFIG_H
  2# include "config.h"
  3#endif
  4
  5#include <stdio.h>
  6
  7#ifdef STDC_HEADERS
  8# include <stdlib.h>
  9#endif
 10
 11#ifdef HAVE_UNISTD_H
 12# include <unistd.h>
 13#endif
 14
 15#ifdef HAVE_FCNTL_H
 16# include <sys/types.h>
 17# include <fcntl.h>
 18#else
 19# include <sys/file.h>
 20#endif
 21
 22#ifdef HAVE_DIRECT_H
 23# include <direct.h>
 24#endif
 25
 26#ifdef HAVE_IO_H
 27# include <io.h>
 28#endif
 29
 30#include <errno.h>
 31# ifndef errno
 32extern int errno;
 33#endif
 34
 35#include "savecwd.h"
 36#include "error.h"
 37
 38char *xgetwd __PROTO((void));
 39
 40/* Record the location of the current working directory in CWD so that
 41   the program may change to other directories and later use restore_cwd
 42   to return to the recorded location.  This function may allocate
 43   space using malloc (via xgetwd) or leave a file descriptor open;
 44   use free_cwd to perform the necessary free or close.  Upon failure,
 45   no memory is allocated, any locally opened file descriptors are
 46   closed;  return non-zero -- in that case, free_cwd need not be
 47   called, but doing so is ok.  Otherwise, return zero.  */
 48
 49int
 50save_cwd (cwd)
 51     struct saved_cwd *cwd;
 52{
 53  static int have_working_fchdir = 1;
 54
 55  cwd->desc = -1;
 56  cwd->name = NULL;
 57
 58  if (have_working_fchdir)
 59    {
 60#ifdef HAVE_FCHDIR
 61      cwd->desc = open (".", O_RDONLY);
 62      if (cwd->desc < 0)
 63	{
 64	  error (0, errno, "cannot open current directory");
 65	  return 1;
 66	}
 67
 68# if __sun__ || sun
 69      /* On SunOS 4, fchdir returns EINVAL if accounting is enabled,
 70	 so we have to fall back to chdir.  */
 71      if (fchdir (cwd->desc))
 72	{
 73	  if (errno == EINVAL)
 74	    {
 75	      close (cwd->desc);
 76	      cwd->desc = -1;
 77	      have_working_fchdir = 0;
 78	    }
 79	  else
 80	    {
 81	      error (0, errno, "current directory");
 82	      close (cwd->desc);
 83	      cwd->desc = -1;
 84	      return 1;
 85	    }
 86	}
 87# endif /* __sun__ || sun */
 88#else
 89#define fchdir(x) (abort (), 0)
 90      have_working_fchdir = 0;
 91#endif
 92    }
 93
 94  if (!have_working_fchdir)
 95    {
 96      cwd->name = xgetwd ();
 97      if (cwd->name == NULL)
 98	{
 99	  error (0, errno, "cannot get current directory");
100	  return 1;
101	}
102    }
103  return 0;
104}
105
106/* Change to recorded location, CWD, in directory hierarchy.
107   If "saved working directory", NULL))
108   */
109
110int
111restore_cwd (cwd, dest)
112     const struct saved_cwd *cwd;
113     const char *dest;
114{
115  int fail = 0;
116  if (cwd->desc >= 0)
117    {
118      if (fchdir (cwd->desc))
119	{
120	  error (0, errno, "cannot return to %s",
121		 (dest ? dest : "saved working directory"));
122	  fail = 1;
123	}
124    }
125  else if (chdir (cwd->name) < 0)
126    {
127      error (0, errno, "%s", cwd->name);
128      fail = 1;
129    }
130  return fail;
131}
132
133void
134free_cwd (cwd)
135     struct saved_cwd *cwd;
136{
137  if (cwd->desc >= 0)
138    close (cwd->desc);
139  if (cwd->name)
140    free (cwd->name);
141}
142