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);
48 Emsg1(M_ERROR, 0, _("Cannot open current directory: %s\n"), be.strerror());
53 /* On SunOS 4, fchdir returns EINVAL if accounting is enabled,
54 so we have to fall back to chdir. */
55 if (fchdir(cwd->desc)) {
56 if (errno == EINVAL) {
59 have_working_fchdir = 0;
62 Emsg1(M_ERROR, 0, _("Current directory: %s\n"), be.strerror());
68 # endif /* __sun__ || sun */
70 # define fchdir(x) (abort (), 0)
71 have_working_fchdir = 0;
75 if (!have_working_fchdir) {
77 POOLMEM *buf = get_memory(MAX_PATH);
79 POOLMEM *buf = get_memory(5000);
81 cwd->name = (POOLMEM *)getcwd(buf, sizeof_pool_memory(buf));
82 if (cwd->name == NULL) {
84 Emsg1(M_ERROR, 0, _("Cannot get current directory: %s\n"), be.strerror());
85 free_pool_memory(buf);
92 /* Change to recorded location, CWD, in directory hierarchy.
93 If "saved working directory", NULL))
97 restore_cwd(const struct saved_cwd *cwd, const char *dest, const char *from)
100 if (cwd->desc >= 0) {
101 if (fchdir(cwd->desc)) {
105 Emsg3(M_ERROR, 0, _("Cannot return to %s from %s: %s\n"),
106 dest, from, be.strerror());
109 Emsg2(M_ERROR, 0, _("Cannot return to saved working directory from %s: %s\n"),
110 from, be.strerror());
115 Emsg2(M_ERROR, 0, _("Cannot return to %s: %s\n"),
116 dest, be.strerror());
119 Emsg1(M_ERROR, 0, _("Cannot return to saved working directory: %s\n"),
125 } else if (chdir(cwd->name) < 0) {
127 Emsg2(M_ERROR, 0, "%s: %s\n", cwd->name, be.strerror());
134 free_cwd(struct saved_cwd *cwd)
136 if (cwd->desc >= 0) {
140 free_pool_memory(cwd->name);