1 /* save-cwd.c -- Save and restore current working directory.
3 Copyright (C) 1995, 1997, 1998 Free Software Foundation, Inc.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software Foundation,
17 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19 /* Written by Jim Meyering <meyering@na-net.ornl.gov>. */
26 /* Record the location of the current working directory in CWD so that
27 the program may change to other directories and later use restore_cwd
28 to return to the recorded location. This function may allocate
29 space using malloc (via xgetcwd) or leave a file descriptor open;
30 use free_cwd to perform the necessary free or close. Upon failure,
31 no memory is allocated, any locally opened file descriptors are
32 closed; return non-zero -- in that case, free_cwd need not be
33 called, but doing so is ok. Otherwise, return zero. */
36 save_cwd(struct saved_cwd *cwd)
38 static int have_working_fchdir = 1;
43 if (have_working_fchdir) {
45 cwd->desc = open(".", O_RDONLY);
47 Emsg1(M_ERROR, 0, "Cannot open current directory: %s\n", strerror(errno));
52 /* On SunOS 4, fchdir returns EINVAL if accounting is enabled,
53 so we have to fall back to chdir. */
54 if (fchdir(cwd->desc)) {
55 if (errno == EINVAL) {
58 have_working_fchdir = 0;
60 Emsg1(M_ERROR, 0, "Current directory: %s\n", strerror(errno));
66 # endif /* __sun__ || sun */
68 # define fchdir(x) (abort (), 0)
69 have_working_fchdir = 0;
73 if (!have_working_fchdir) {
74 POOLMEM *buf = get_pool_memory(PM_FNAME);
75 cwd->name = (POOLMEM *)getcwd(buf, sizeof_pool_memory(buf));
76 if (cwd->name == NULL) {
77 Emsg1(M_ERROR, 0, "Cannot get current directory: %s\n", strerror(errno));
78 free_pool_memory(buf);
85 /* Change to recorded location, CWD, in directory hierarchy.
86 If "saved working directory", NULL))
90 restore_cwd(const struct saved_cwd *cwd, const char *dest, const char *from)
94 if (fchdir(cwd->desc)) {
95 Emsg4(M_ERROR, 0, "Cannot return to %s%s%s: %s\n",
96 (dest ? dest : "saved working directory"),
97 (from ? " from " : ""),
98 (from ? from : ""), strerror(errno));
101 } else if (chdir(cwd->name) < 0) {
102 Emsg2(M_ERROR, 0, "%s: %s\n", cwd->name, strerror(errno));
109 free_cwd(struct saved_cwd *cwd)
111 if (cwd->desc >= 0) {
115 free_pool_memory(cwd->name);