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 */
35 #define _(msgid) gettext (msgid)
37 /* Replacement for Solaris' openat function.
38 <http://www.google.com/search?q=openat+site:docs.sun.com>
39 Simulate it by doing save_cwd/fchdir/open/restore_cwd.
40 If either the save_cwd or the restore_cwd fails (relatively unlikely,
41 and usually indicative of a problem that deserves close attention),
42 then give a diagnostic and exit nonzero.
43 Otherwise, upon failure, set errno and return -1, as openat does.
44 Upon successful completion, return a file descriptor. */
46 rpl_openat (int fd, char const *file, int flags, ...)
48 struct saved_cwd saved_cwd;
56 va_start (arg, flags);
58 /* Assume that mode_t is passed compatibly with mode_t's type
59 after argument promotion. */
60 mode = va_arg (arg, mode_t);
65 if (fd == AT_FDCWD || *file == '/')
66 return open (file, flags, mode);
68 if (save_cwd (&saved_cwd) != 0)
69 error (exit_failure, errno,
70 _("openat: unable to record current working directory"));
75 free_cwd (&saved_cwd);
80 new_fd = open (file, flags, mode);
83 if (restore_cwd (&saved_cwd) != 0)
84 error (exit_failure, errno,
85 _("openat: unable to restore working directory"));
87 free_cwd (&saved_cwd);
93 /* Replacement for Solaris' function by the same name.
94 <http://www.google.com/search?q=fdopendir+site:docs.sun.com>
95 Simulate it by doing save_cwd/fchdir/opendir(".")/restore_cwd.
96 If either the save_cwd or the restore_cwd fails (relatively unlikely,
97 and usually indicative of a problem that deserves close attention),
98 then give a diagnostic and exit nonzero.
99 Otherwise, this function works just like Solaris' fdopendir. */
103 struct saved_cwd saved_cwd;
108 return opendir (".");
110 if (save_cwd (&saved_cwd) != 0)
111 error (exit_failure, errno,
112 _("fdopendir: unable to record current working directory"));
114 if (fchdir (fd) != 0)
117 free_cwd (&saved_cwd);
125 if (restore_cwd (&saved_cwd) != 0)
126 error (exit_failure, errno,
127 _("fdopendir: unable to restore working directory"));
129 free_cwd (&saved_cwd);
135 /* Replacement for Solaris' function by the same name.
136 <http://www.google.com/search?q=fstatat+site:docs.sun.com>
137 Simulate it by doing save_cwd/fchdir/(stat|lstat)/restore_cwd.
138 If either the save_cwd or the restore_cwd fails (relatively unlikely,
139 and usually indicative of a problem that deserves close attention),
140 then give a diagnostic and exit nonzero.
141 Otherwise, this function works just like Solaris' fstatat. */
143 fstatat (int fd, char const *file, struct stat *st, int flag)
145 struct saved_cwd saved_cwd;
150 return (flag == AT_SYMLINK_NOFOLLOW
154 if (save_cwd (&saved_cwd) != 0)
155 error (exit_failure, errno,
156 _("fstatat: unable to record current working directory"));
158 if (fchdir (fd) != 0)
161 free_cwd (&saved_cwd);
166 err = (flag == AT_SYMLINK_NOFOLLOW
171 if (restore_cwd (&saved_cwd) != 0)
172 error (exit_failure, errno,
173 _("fstatat: unable to restore working directory"));
175 free_cwd (&saved_cwd);