summaryrefslogtreecommitdiff
path: root/lib/openat.c
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2006-08-15 19:17:30 +0000
committerJim Meyering <jim@meyering.net>2006-08-15 19:17:30 +0000
commit2ee444b5fe414a627f8600cb3989b8eed1676b9f (patch)
treeb109e89438ab841f4c23871d0ad242a9d4fcc3db /lib/openat.c
parentd8139747b188a142f388716b431e180faecd4f68 (diff)
downloadcoreutils-2ee444b5fe414a627f8600cb3989b8eed1676b9f.tar.xz
[./]
* .x-sc_require_config_h: Add lib/at-func.c. [lib/] * at-func.c: New file, with the logic of all emulated at-functions. * openat-priv.h: Include <errno.h> and define ENOSYS, in support of the EXPECTED_ERRNO macro. * openat.c (fstatat, unlinkat, fchownat): Remove function definitions. Instead, define the appropriate symbols and include "at-func.c". * mkdirat.c (mkdirat): Likewise. * fchmodat.c (fchmodat): Likewise. (ENOSYS): Remove definition. * openat.c: Don't include <errno.h>, now that "openat-priv.h" does it. Don't include "unistd--.h" -- it wasn't ever used. [m4/] * openat.m4 (gl_FUNC_OPENAT): Add at-func.c via AC_LIBSOURCES.
Diffstat (limited to 'lib/openat.c')
-rw-r--r--lib/openat.c176
1 files changed, 37 insertions, 139 deletions
diff --git a/lib/openat.c b/lib/openat.c
index 7df52ea13..ca71d658e 100644
--- a/lib/openat.c
+++ b/lib/openat.c
@@ -25,21 +25,18 @@
#include <stdarg.h>
#include <stddef.h>
-#include <errno.h>
#include "dirname.h" /* solely for definition of IS_ABSOLUTE_FILE_NAME */
#include "fcntl--.h"
#include "lstat.h"
#include "openat-priv.h"
#include "save-cwd.h"
-#include "unistd--.h"
/* Replacement for Solaris' openat function.
<http://www.google.com/search?q=openat+site:docs.sun.com>
First, try to simulate it via open ("/proc/self/fd/FD/FILE").
Failing that, simulate it by doing save_cwd/fchdir/open/restore_cwd.
- If either the save_cwd or the restore_cwd fails (relatively unlikely,
- and usually indicative of a problem that deserves close attention),
+ If either the save_cwd or the restore_cwd fails (relatively unlikely),
then give a diagnostic and exit nonzero.
Otherwise, upon failure, set errno and return -1, as openat does.
Upon successful completion, return a file descriptor. */
@@ -154,8 +151,7 @@ openat_needs_fchdir (void)
<http://www.google.com/search?q=fdopendir+site:docs.sun.com>
First, try to simulate it via opendir ("/proc/self/fd/FD"). Failing
that, simulate it by doing save_cwd/fchdir/opendir(".")/restore_cwd.
- If either the save_cwd or the restore_cwd fails (relatively unlikely,
- and usually indicative of a problem that deserves close attention),
+ If either the save_cwd or the restore_cwd fails (relatively unlikely),
then give a diagnostic and exit nonzero.
Otherwise, this function works just like Solaris' fdopendir.
@@ -211,105 +207,45 @@ fdopendir (int fd)
<http://www.google.com/search?q=fstatat+site:docs.sun.com>
First, try to simulate it via l?stat ("/proc/self/fd/FD/FILE").
Failing that, simulate it via save_cwd/fchdir/(stat|lstat)/restore_cwd.
- If either the save_cwd or the restore_cwd fails (relatively unlikely,
- and usually indicative of a problem that deserves close attention),
+ If either the save_cwd or the restore_cwd fails (relatively unlikely),
then give a diagnostic and exit nonzero.
Otherwise, this function works just like Solaris' fstatat. */
-int
-fstatat (int fd, char const *file, struct stat *st, int flag)
-{
- struct saved_cwd saved_cwd;
- int saved_errno;
- int err;
-
- if (fd == AT_FDCWD || IS_ABSOLUTE_FILE_NAME (file))
- return (flag == AT_SYMLINK_NOFOLLOW
- ? lstat (file, st)
- : stat (file, st));
-
- {
- char *proc_file;
- BUILD_PROC_NAME (proc_file, fd, file);
- err = (flag == AT_SYMLINK_NOFOLLOW
- ? lstat (proc_file, st)
- : stat (proc_file, st));
- /* If the syscall succeeds, or if it fails with an unexpected
- errno value, then return right away. Otherwise, fall through
- and resort to using save_cwd/restore_cwd. */
- if (0 <= err || ! EXPECTED_ERRNO (errno))
- return err;
- }
-
- if (save_cwd (&saved_cwd) != 0)
- openat_save_fail (errno);
- err = fchdir (fd);
- saved_errno = errno;
-
- if (! err)
- {
- err = (flag == AT_SYMLINK_NOFOLLOW
- ? lstat (file, st)
- : stat (file, st));
- saved_errno = errno;
-
- if (restore_cwd (&saved_cwd) != 0)
- openat_restore_fail (errno);
- }
-
- free_cwd (&saved_cwd);
- errno = saved_errno;
- return err;
-}
+#define AT_FUNC_NAME fstatat
+#define AT_FUNC_F1 lstat
+#define AT_FUNC_F2 stat
+#define AT_FUNC_USE_F1_COND flag == AT_SYMLINK_NOFOLLOW
+#define AT_FUNC_POST_FILE_PARAM_DECLS , struct stat *st, int flag
+#define AT_FUNC_POST_FILE_ARGS , st
+#include "at-func.c"
+#undef AT_FUNC_NAME
+#undef AT_FUNC_F1
+#undef AT_FUNC_F2
+#undef AT_FUNC_USE_F1_COND
+#undef AT_FUNC_POST_FILE_PARAM_DECLS
+#undef AT_FUNC_POST_FILE_ARGS
/* Replacement for Solaris' function by the same name.
<http://www.google.com/search?q=unlinkat+site:docs.sun.com>
First, try to simulate it via (unlink|rmdir) ("/proc/self/fd/FD/FILE").
Failing that, simulate it via save_cwd/fchdir/(unlink|rmdir)/restore_cwd.
- If either the save_cwd or the restore_cwd fails (relatively unlikely,
- and usually indicative of a problem that deserves close attention),
+ If either the save_cwd or the restore_cwd fails (relatively unlikely),
then give a diagnostic and exit nonzero.
Otherwise, this function works just like Solaris' unlinkat. */
-int
-unlinkat (int fd, char const *file, int flag)
-{
- struct saved_cwd saved_cwd;
- int saved_errno;
- int err;
- if (fd == AT_FDCWD || IS_ABSOLUTE_FILE_NAME (file))
- return (flag == AT_REMOVEDIR ? rmdir (file) : unlink (file));
-
- {
- char *proc_file;
- BUILD_PROC_NAME (proc_file, fd, file);
- err = (flag == AT_REMOVEDIR ? rmdir (proc_file) : unlink (proc_file));
- /* If the syscall succeeds, or if it fails with an unexpected
- errno value, then return right away. Otherwise, fall through
- and resort to using save_cwd/restore_cwd. */
- if (0 <= err || ! EXPECTED_ERRNO (errno))
- return err;
- }
-
- if (save_cwd (&saved_cwd) != 0)
- openat_save_fail (errno);
-
- err = fchdir (fd);
- saved_errno = errno;
-
- if (! err)
- {
- err = (flag == AT_REMOVEDIR ? rmdir (file) : unlink (file));
- saved_errno = errno;
-
- if (restore_cwd (&saved_cwd) != 0)
- openat_restore_fail (errno);
- }
-
- free_cwd (&saved_cwd);
- errno = saved_errno;
- return err;
-}
+#define AT_FUNC_NAME unlinkat
+#define AT_FUNC_F1 rmdir
+#define AT_FUNC_F2 unlink
+#define AT_FUNC_USE_F1_COND flag == AT_REMOVEDIR
+#define AT_FUNC_POST_FILE_PARAM_DECLS , int flag
+#define AT_FUNC_POST_FILE_ARGS /* empty */
+#include "at-func.c"
+#undef AT_FUNC_NAME
+#undef AT_FUNC_F1
+#undef AT_FUNC_F2
+#undef AT_FUNC_USE_F1_COND
+#undef AT_FUNC_POST_FILE_PARAM_DECLS
+#undef AT_FUNC_POST_FILE_ARGS
/* Replacement for Solaris' function by the same name.
Invoke chown or lchown on file, FILE, using OWNER and GROUP, in the
@@ -318,49 +254,11 @@ unlinkat (int fd, char const *file, int flag)
the working directory. Otherwise, resort to using save_cwd/fchdir,
then mkdir/restore_cwd. If either the save_cwd or the restore_cwd
fails, then give a diagnostic and exit nonzero. */
-int
-fchownat (int fd, char const *file, uid_t owner, gid_t group, int flag)
-{
- struct saved_cwd saved_cwd;
- int saved_errno;
- int err;
-
- if (fd == AT_FDCWD || IS_ABSOLUTE_FILE_NAME (file))
- return (flag == AT_SYMLINK_NOFOLLOW
- ? lchown (file, owner, group)
- : chown (file, owner, group));
-
- {
- char *proc_file;
- BUILD_PROC_NAME (proc_file, fd, file);
- err = (flag == AT_SYMLINK_NOFOLLOW
- ? lchown (proc_file, owner, group)
- : chown (proc_file, owner, group));
- /* If the syscall succeeds, or if it fails with an unexpected
- errno value, then return right away. Otherwise, fall through
- and resort to using save_cwd/restore_cwd. */
- if (0 <= err || ! EXPECTED_ERRNO (errno))
- return err;
- }
- if (save_cwd (&saved_cwd) != 0)
- openat_save_fail (errno);
-
- err = fchdir (fd);
- saved_errno = errno;
-
- if (! err)
- {
- err = (flag == AT_SYMLINK_NOFOLLOW
- ? lchown (file, owner, group)
- : chown (file, owner, group));
- saved_errno = errno;
-
- if (restore_cwd (&saved_cwd) != 0)
- openat_restore_fail (errno);
- }
-
- free_cwd (&saved_cwd);
- errno = saved_errno;
- return err;
-}
+#define AT_FUNC_NAME fchownat
+#define AT_FUNC_F1 lchown
+#define AT_FUNC_F2 chown
+#define AT_FUNC_USE_F1_COND flag == AT_SYMLINK_NOFOLLOW
+#define AT_FUNC_POST_FILE_PARAM_DECLS , uid_t owner, gid_t group, int flag
+#define AT_FUNC_POST_FILE_ARGS , owner, group
+#include "at-func.c"