#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#ifdef STDC_HEADERS
# include <stdlib.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#else
# include <sys/file.h>
#endif
#ifdef HAVE_DIRECT_H
# include <direct.h>
#endif
#ifdef HAVE_IO_H
# include <io.h>
#endif
#include <errno.h>
# ifndef errno
extern int errno;
#endif
#include "savecwd.h"
#include "error.h"
char *xgetwd( void );
int
save_cwd (cwd)
struct saved_cwd *cwd;
{
static int have_working_fchdir = 1;
cwd->desc = -1;
cwd->name = NULL;
if (have_working_fchdir)
{
#ifdef HAVE_FCHDIR
cwd->desc = open (".", O_RDONLY);
if (cwd->desc < 0)
{
error (0, errno, "cannot open current directory");
return 1;
}
# if __sun__ || sun
if (fchdir (cwd->desc))
{
if (errno == EINVAL)
{
close (cwd->desc);
cwd->desc = -1;
have_working_fchdir = 0;
}
else
{
error (0, errno, "current directory");
close (cwd->desc);
cwd->desc = -1;
return 1;
}
}
# endif
#else
#define fchdir(x) (abort (), 0)
have_working_fchdir = 0;
#endif
}
if (!have_working_fchdir)
{
cwd->name = xgetwd ();
if (cwd->name == NULL)
{
error (0, errno, "cannot get current directory");
return 1;
}
}
return 0;
}
int
restore_cwd (cwd, dest)
const struct saved_cwd *cwd;
const char *dest;
{
int fail = 0;
if (cwd->desc >= 0)
{
if (fchdir (cwd->desc))
{
error (0, errno, "cannot return to %s",
(dest ? dest : "saved working directory"));
fail = 1;
}
}
else if (_chdir2 (cwd->name) < 0)
{
error (0, errno, "%s", cwd->name);
fail = 1;
}
return fail;
}
void
free_cwd (cwd)
struct saved_cwd *cwd;
{
if (cwd->desc >= 0)
close (cwd->desc);
if (cwd->name)
free (cwd->name);
}