From 4208951389e547545c43fc8c0daa42d0cf8b729e Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Thu, 3 Sep 2009 11:38:53 -0600 Subject: [PATCH] openat: make template easier to use * lib/at-func.c (CALL_FUNC): Allow AT_FUNC_USE_F1_COND and AT_FUNC_F2 to be undefined. (VALIDATE_FLAG): New macro; use it to reject bad flags. (AT_FUNC_USE_F1_COND): Change sense to just flag bit. * lib/fchmodat.c (AT_FUNC_USE_F1_COND): Adjust. * lib/fchownat.c (AT_FUNC_USE_F1_COND): Likewise. * lib/openat.c (AT_FUNC_USE_F1_COND) [fstatat, unlinkat]: Likewise. * lib/mkdirat.c (AT_FUNC_F2, AT_FUNC_USE_F1_COND): Delete. * lib/selinux-at.c (AT_FUNC_F2, AT_FUNC_USE_F1_COND) [getfileconat, lgetfileconat, setfileconat, lsetfileconat]: Likewise. Signed-off-by: Eric Blake --- ChangeLog | 14 ++++++++++++++ lib/at-func.c | 27 +++++++++++++++++++++------ lib/fchmodat.c | 2 +- lib/fchownat.c | 2 +- lib/mkdirat.c | 2 -- lib/openat.c | 4 ++-- lib/selinux-at.c | 16 ---------------- 7 files changed, 39 insertions(+), 28 deletions(-) diff --git a/ChangeLog b/ChangeLog index a73cad1cb..288440ec7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,19 @@ 2009-09-03 Eric Blake + openat: make template easier to use + * lib/at-func.c (CALL_FUNC): Allow AT_FUNC_USE_F1_COND and + AT_FUNC_F2 to be undefined. + (VALIDATE_FLAG): New macro; use it to reject bad flags. + (AT_FUNC_USE_F1_COND): Change sense to just flag bit. + * lib/fchmodat.c (AT_FUNC_USE_F1_COND): Adjust. + * lib/fchownat.c (AT_FUNC_USE_F1_COND): Likewise. + * lib/openat.c (AT_FUNC_USE_F1_COND) [fstatat, unlinkat]: + Likewise. + * lib/mkdirat.c (AT_FUNC_F2, AT_FUNC_USE_F1_COND): Delete. + * lib/selinux-at.c (AT_FUNC_F2, AT_FUNC_USE_F1_COND) + [getfileconat, lgetfileconat, setfileconat, lsetfileconat]: + Likewise. + openat: declare in POSIX headers * NEWS: Mention this. * modules/openat (configure.ac): Declare witnesses. diff --git a/lib/at-func.c b/lib/at-func.c index c7963fe3d..620fdafb0 100644 --- a/lib/at-func.c +++ b/lib/at-func.c @@ -1,5 +1,5 @@ /* Define an at-style functions like fstatat, unlinkat, fchownat, etc. - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006, 2009 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -16,14 +16,27 @@ /* written by Jim Meyering */ -#define CALL_FUNC(F) \ - (AT_FUNC_USE_F1_COND \ +#ifdef AT_FUNC_USE_F1_COND +# define CALL_FUNC(F) \ + (flag == AT_FUNC_USE_F1_COND \ ? AT_FUNC_F1 (F AT_FUNC_POST_FILE_ARGS) \ : AT_FUNC_F2 (F AT_FUNC_POST_FILE_ARGS)) +# define VALIDATE_FLAG(F) \ + if (flag & ~AT_FUNC_USE_F1_COND) \ + { \ + errno = EINVAL; \ + return -1; \ + } +#else +# define CALL_FUNC(F) (AT_FUNC_F1 (F AT_FUNC_POST_FILE_ARGS)) +# define VALIDATE_FLAG(F) /* empty */ +#endif -/* Call AT_FUNC_F1 or AT_FUNC_F2 (testing AT_FUNC_USE_F1_COND to - determine which) to operate on FILE, which is in the directory - open on descriptor FD. If possible, do it without changing the +/* Call AT_FUNC_F1 to operate on FILE, which is in the directory + open on descriptor FD. If AT_FUNC_USE_F1_COND is defined to a value, + AT_FUNC_POST_FILE_PARAM_DECLS must inlude a parameter named flag; + call AT_FUNC_F2 if FLAG is 0 or fail if FLAG contains more bits than + AT_FUNC_USE_F1_COND. If possible, do it without changing the working directory. Otherwise, resort to using save_cwd/fchdir, then AT_FUNC_F?/restore_cwd. If either the save_cwd or the restore_cwd fails, then give a diagnostic and exit nonzero. */ @@ -34,6 +47,8 @@ AT_FUNC_NAME (int fd, char const *file AT_FUNC_POST_FILE_PARAM_DECLS) int saved_errno; int err; + VALIDATE_FLAG (flag); + if (fd == AT_FDCWD || IS_ABSOLUTE_FILE_NAME (file)) return CALL_FUNC (file); diff --git a/lib/fchmodat.c b/lib/fchmodat.c index 23eee6459..cc2776eb1 100644 --- a/lib/fchmodat.c +++ b/lib/fchmodat.c @@ -45,7 +45,7 @@ static int lchmod (char const *f, mode_t m) { errno = ENOSYS; return -1; } #define AT_FUNC_NAME fchmodat #define AT_FUNC_F1 lchmod #define AT_FUNC_F2 chmod -#define AT_FUNC_USE_F1_COND flag == AT_SYMLINK_NOFOLLOW +#define AT_FUNC_USE_F1_COND AT_SYMLINK_NOFOLLOW #define AT_FUNC_POST_FILE_PARAM_DECLS , mode_t mode, int flag #define AT_FUNC_POST_FILE_ARGS , mode #include "at-func.c" diff --git a/lib/fchownat.c b/lib/fchownat.c index c217b5243..ba5d86baf 100644 --- a/lib/fchownat.c +++ b/lib/fchownat.c @@ -41,7 +41,7 @@ #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_USE_F1_COND 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" diff --git a/lib/mkdirat.c b/lib/mkdirat.c index d4b3317a2..33ece9ccd 100644 --- a/lib/mkdirat.c +++ b/lib/mkdirat.c @@ -34,8 +34,6 @@ #define AT_FUNC_NAME mkdirat #define AT_FUNC_F1 mkdir -#define AT_FUNC_F2 mkdir -#define AT_FUNC_USE_F1_COND 1 #define AT_FUNC_POST_FILE_PARAM_DECLS , mode_t mode #define AT_FUNC_POST_FILE_ARGS , mode #include "at-func.c" diff --git a/lib/openat.c b/lib/openat.c index 0e2c27b7b..e1471b8c0 100644 --- a/lib/openat.c +++ b/lib/openat.c @@ -169,7 +169,7 @@ openat_needs_fchdir (void) #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_USE_F1_COND 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" @@ -191,7 +191,7 @@ openat_needs_fchdir (void) #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_USE_F1_COND AT_REMOVEDIR #define AT_FUNC_POST_FILE_PARAM_DECLS , int flag #define AT_FUNC_POST_FILE_ARGS /* empty */ #include "at-func.c" diff --git a/lib/selinux-at.c b/lib/selinux-at.c index 18e6b0f40..65f938b41 100644 --- a/lib/selinux-at.c +++ b/lib/selinux-at.c @@ -33,56 +33,40 @@ #define AT_FUNC_NAME getfileconat #define AT_FUNC_F1 getfilecon -#define AT_FUNC_F2 getfilecon -#define AT_FUNC_USE_F1_COND 1 #define AT_FUNC_POST_FILE_PARAM_DECLS , security_context_t *con #define AT_FUNC_POST_FILE_ARGS , con #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 #define AT_FUNC_NAME lgetfileconat #define AT_FUNC_F1 lgetfilecon -#define AT_FUNC_F2 lgetfilecon -#define AT_FUNC_USE_F1_COND 1 #define AT_FUNC_POST_FILE_PARAM_DECLS , security_context_t *con #define AT_FUNC_POST_FILE_ARGS , con #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 #define AT_FUNC_NAME setfileconat #define AT_FUNC_F1 setfilecon -#define AT_FUNC_F2 setfilecon -#define AT_FUNC_USE_F1_COND 1 #define AT_FUNC_POST_FILE_PARAM_DECLS , security_context_t con #define AT_FUNC_POST_FILE_ARGS , con #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 #define AT_FUNC_NAME lsetfileconat #define AT_FUNC_F1 lsetfilecon -#define AT_FUNC_F2 lsetfilecon -#define AT_FUNC_USE_F1_COND 1 #define AT_FUNC_POST_FILE_PARAM_DECLS , security_context_t con #define AT_FUNC_POST_FILE_ARGS , con #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 -- 2.11.0