home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / unixtex-6.1b-src.tgz / tar.out / contrib / unixtex / xdvik / xgetcwd.c < prev   
C/C++ Source or Header  |  1996-09-28  |  4KB  |  123 lines

  1. /* xgetcwd.c: a from-scratch version of getwd.  Based on the tcsh 5.20
  2.    source, apparently uncopyrighted.
  3.  
  4. Copyright (C) 1992, 94 Free Software Foundation, Inc.
  5.  
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2, or (at your option)
  9. any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #ifndef NOSELFILE /* for xdvik */
  21.  
  22. #include <kpathsea/config.h>
  23. #include <kpathsea/lib.h>
  24.  
  25. #ifdef HAVE_GETWD
  26. #include <kpathsea/c-pathmx.h>
  27. #else /* not HAVE_GETWD */
  28. #include <kpathsea/c-dir.h>
  29. #include <kpathsea/xopendir.h>
  30. #include <kpathsea/xstat.h>
  31.  
  32.  
  33. static void
  34. xchdir P1C(string, dirname)
  35. {
  36.   if (chdir (dirname) != 0)
  37.     FATAL_PERROR (dirname);
  38. }
  39.  
  40. #endif /* not HAVE_GETWD */
  41.  
  42.  
  43. /* Return the pathname of the current directory, or give a fatal error.  */
  44.  
  45. string
  46. xgetcwd ()
  47. {
  48.   /* If the system provides getwd, use it.  But don't use getcwd; that
  49.      forks a process on some systems, which is far more expensive than
  50.      all the stat calls we make figuring out the cwd.  */
  51. #ifdef HAVE_GETWD
  52.   string path = xmalloc (PATH_MAX + 1);
  53.   
  54.   if (getwd (path) == 0)
  55.     {
  56.       fprintf (stderr, "getwd: %s", path);
  57.       exit (1);
  58.     }
  59.   
  60.   return path;
  61. #else /* not HAVE_GETWD */
  62.   struct stat root_stat, cwd_stat;
  63.   string cwd_path = xmalloc (2); /* In case we assign "/" below.  */
  64.   
  65.   *cwd_path = 0;
  66.   
  67.   /* Find the inodes of the root and current directories.  */
  68.   root_stat = xstat ("/");
  69.   cwd_stat = xstat (".");
  70.  
  71.   /* Go up the directory hierarchy until we get to root, prepending each
  72.      directory we pass through to `cwd_path'.  */
  73.   while (!SAME_FILE_P (root_stat, cwd_stat))
  74.     {
  75.       struct dirent *e;
  76.       DIR *parent_dir;
  77.       boolean found = false;
  78.       
  79.       xchdir ("..");
  80.       parent_dir = xopendir (".");
  81.  
  82.       /* Look through the parent directory for the entry with the same
  83.          inode, so we can get its name.  */
  84.       while ((e = readdir (parent_dir)) != NULL && !found)
  85.         {
  86.           struct stat test_stat;
  87.           test_stat = xlstat (e->d_name);
  88.           
  89.           if (SAME_FILE_P (test_stat, cwd_stat))
  90.             {
  91.               /* We've found it.  Prepend the pathname.  */
  92.               string temp = cwd_path;
  93.               cwd_path = concat3 ("/", e->d_name, cwd_path);
  94.               free (temp);
  95.               
  96.               /* Set up to test the next parent.  */
  97.               cwd_stat = xstat (".");
  98.               
  99.               /* Stop reading this directory.  */
  100.               found = true;
  101.             }
  102.         }
  103.       if (!found)
  104.         FATAL2 ("No inode %d/device %d in parent directory",
  105.                 cwd_stat.st_ino, cwd_stat.st_dev);
  106.       
  107.       xclosedir (parent_dir);
  108.     }
  109.   
  110.   /* If the current directory is the root, cwd_path will be the empty
  111.      string, and we will have not gone through the loop.  */
  112.   if (*cwd_path == 0)
  113.     strcpy (cwd_path, "/");
  114.   else
  115.     /* Go back to where we were.  */
  116.     xchdir (cwd_path);
  117.  
  118.   return cwd_path;
  119. #endif /* not HAVE_GETWD */
  120. }
  121.  
  122. #endif /* not NOSELFILE */
  123.