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
Wrap
C/C++ Source or Header
|
1996-09-28
|
4KB
|
123 lines
/* xgetcwd.c: a from-scratch version of getwd. Based on the tcsh 5.20
source, apparently uncopyrighted.
Copyright (C) 1992, 94 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef NOSELFILE /* for xdvik */
#include <kpathsea/config.h>
#include <kpathsea/lib.h>
#ifdef HAVE_GETWD
#include <kpathsea/c-pathmx.h>
#else /* not HAVE_GETWD */
#include <kpathsea/c-dir.h>
#include <kpathsea/xopendir.h>
#include <kpathsea/xstat.h>
static void
xchdir P1C(string, dirname)
{
if (chdir (dirname) != 0)
FATAL_PERROR (dirname);
}
#endif /* not HAVE_GETWD */
/* Return the pathname of the current directory, or give a fatal error. */
string
xgetcwd ()
{
/* If the system provides getwd, use it. But don't use getcwd; that
forks a process on some systems, which is far more expensive than
all the stat calls we make figuring out the cwd. */
#ifdef HAVE_GETWD
string path = xmalloc (PATH_MAX + 1);
if (getwd (path) == 0)
{
fprintf (stderr, "getwd: %s", path);
exit (1);
}
return path;
#else /* not HAVE_GETWD */
struct stat root_stat, cwd_stat;
string cwd_path = xmalloc (2); /* In case we assign "/" below. */
*cwd_path = 0;
/* Find the inodes of the root and current directories. */
root_stat = xstat ("/");
cwd_stat = xstat (".");
/* Go up the directory hierarchy until we get to root, prepending each
directory we pass through to `cwd_path'. */
while (!SAME_FILE_P (root_stat, cwd_stat))
{
struct dirent *e;
DIR *parent_dir;
boolean found = false;
xchdir ("..");
parent_dir = xopendir (".");
/* Look through the parent directory for the entry with the same
inode, so we can get its name. */
while ((e = readdir (parent_dir)) != NULL && !found)
{
struct stat test_stat;
test_stat = xlstat (e->d_name);
if (SAME_FILE_P (test_stat, cwd_stat))
{
/* We've found it. Prepend the pathname. */
string temp = cwd_path;
cwd_path = concat3 ("/", e->d_name, cwd_path);
free (temp);
/* Set up to test the next parent. */
cwd_stat = xstat (".");
/* Stop reading this directory. */
found = true;
}
}
if (!found)
FATAL2 ("No inode %d/device %d in parent directory",
cwd_stat.st_ino, cwd_stat.st_dev);
xclosedir (parent_dir);
}
/* If the current directory is the root, cwd_path will be the empty
string, and we will have not gone through the loop. */
if (*cwd_path == 0)
strcpy (cwd_path, "/");
else
/* Go back to where we were. */
xchdir (cwd_path);
return cwd_path;
#endif /* not HAVE_GETWD */
}
#endif /* not NOSELFILE */