home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / cvs-1.8.7-src.tgz / tar.out / fsf / cvs / lib / savecwd.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  3KB  |  142 lines

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