1
1
/* save-cwd.c -- Save and restore current working directory.
3
Copyright (C) 1995, 1997-1998, 2003-2006, 2009-2010 Free Software
3
Copyright (C) 1995, 1997-1998, 2003-2006, 2009-2012 Free Software
6
6
This program is free software: you can redistribute it and/or modify
38
38
# define GNULIB_FCNTL_SAFER 0
41
/* On systems without the fchdir function (WOE), pretend that open
42
always returns -1 so that save_cwd resorts to using xgetcwd.
43
Since chdir_long requires fchdir, use chdir instead. */
46
# define open(File, Flags) (-1)
48
# define fchdir(Fd) (abort (), -1)
50
# define chdir_long(Dir) chdir (Dir)
53
41
/* Record the location of the current working directory in CWD so that
54
42
the program may change to other directories and later use restore_cwd
55
43
to return to the recorded location. This function may allocate
56
space using malloc (via xgetcwd) or leave a file descriptor open;
44
space using malloc (via getcwd) or leave a file descriptor open;
57
45
use free_cwd to perform the necessary free or close. Upon failure,
58
46
no memory is allocated, any locally opened file descriptors are
59
47
closed; return non-zero -- in that case, free_cwd need not be
60
48
called, but doing so is ok. Otherwise, return zero.
62
The `raison d'etre' for this interface is that the working directory
50
The _raison d'etre_ for this interface is that the working directory
63
51
is sometimes inaccessible, and getcwd is not robust or as efficient.
64
52
So, we prefer to use the open/fchdir approach, but fall back on
53
getcwd if necessary. This module works for most cases with just
54
the getcwd-lgpl module, but to be truly robust, use the getcwd module.
67
56
Some systems lack fchdir altogether: e.g., OS/2, pre-2001 Cygwin,
68
57
SCO Xenix. Also, SunOS 4 and Irix 5.3 provide the function, yet it
78
cwd->desc = open (".", O_RDONLY);
67
cwd->desc = open (".", O_SEARCH);
79
68
if (!GNULIB_FCNTL_SAFER)
80
69
cwd->desc = fd_safer (cwd->desc);
83
cwd->name = xgetcwd ();
72
cwd->name = getcwd (NULL, 0);
84
73
return cwd->name ? 0 : -1;
76
set_cloexec_flag (cwd->desc, true);