1 /* provide a replacement openat function
2 Copyright (C) 2004, 2005 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
18 /* written by Jim Meyering */
37 #define _(msgid) gettext (msgid)
39 /* Replacement for Solaris' openat function.
40 <http://www.google.com/search?q=openat+site:docs.sun.com>
41 Simulate it by doing save_cwd/fchdir/open/restore_cwd.
42 If either the save_cwd or the restore_cwd fails (relatively unlikely,
43 and usually indicative of a problem that deserves close attention),
44 then give a diagnostic and exit nonzero.
45 Otherwise, upon failure, set errno and return -1, as openat does.
46 Upon successful completion, return a file descriptor. */
48 rpl_openat (int fd
, char const *file
, int flags
, ...)
50 struct saved_cwd saved_cwd
;
58 va_start (arg
, flags
);
60 /* Assume that mode_t is passed compatibly with mode_t's type
61 after argument promotion. */
62 mode
= va_arg (arg
, mode_t
);
67 if (fd
== AT_FDCWD
|| *file
== '/')
68 return open (file
, flags
, mode
);
70 if (save_cwd (&saved_cwd
) != 0)
71 error (exit_failure
, errno
,
72 _("openat: unable to record current working directory"));
77 free_cwd (&saved_cwd
);
82 new_fd
= open (file
, flags
, mode
);
85 if (restore_cwd (&saved_cwd
) != 0)
86 error (exit_failure
, errno
,
87 _("openat: unable to restore working directory"));
89 free_cwd (&saved_cwd
);
95 /* Replacement for Solaris' function by the same name.
96 <http://www.google.com/search?q=fdopendir+site:docs.sun.com>
97 Simulate it by doing save_cwd/fchdir/opendir(".")/restore_cwd.
98 If either the save_cwd or the restore_cwd fails (relatively unlikely,
99 and usually indicative of a problem that deserves close attention),
100 then give a diagnostic and exit nonzero.
101 Otherwise, this function works just like Solaris' fdopendir. */
105 struct saved_cwd saved_cwd
;
110 return opendir (".");
112 if (save_cwd (&saved_cwd
) != 0)
113 error (exit_failure
, errno
,
114 _("fdopendir: unable to record current working directory"));
116 if (fchdir (fd
) != 0)
119 free_cwd (&saved_cwd
);
127 if (restore_cwd (&saved_cwd
) != 0)
128 error (exit_failure
, errno
,
129 _("fdopendir: unable to restore working directory"));
131 free_cwd (&saved_cwd
);
137 /* Replacement for Solaris' function by the same name.
138 <http://www.google.com/search?q=fstatat+site:docs.sun.com>
139 Simulate it by doing save_cwd/fchdir/(stat|lstat)/restore_cwd.
140 If either the save_cwd or the restore_cwd fails (relatively unlikely,
141 and usually indicative of a problem that deserves close attention),
142 then give a diagnostic and exit nonzero.
143 Otherwise, this function works just like Solaris' fstatat. */
145 fstatat (int fd
, char const *file
, struct stat
*st
, int flag
)
147 struct saved_cwd saved_cwd
;
152 return (flag
== AT_SYMLINK_NOFOLLOW
156 if (save_cwd (&saved_cwd
) != 0)
157 error (exit_failure
, errno
,
158 _("fstatat: unable to record current working directory"));
160 if (fchdir (fd
) != 0)
163 free_cwd (&saved_cwd
);
168 err
= (flag
== AT_SYMLINK_NOFOLLOW
173 if (restore_cwd (&saved_cwd
) != 0)
174 error (exit_failure
, errno
,
175 _("fstatat: unable to restore working directory"));
177 free_cwd (&saved_cwd
);