aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2022-09-17 19:47:57 +0000
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2022-09-17 19:58:30 +0000
commit7ae60af75b78f408420512c58fd5a08ca7a88bad (patch)
tree51ef7f542c448a0717e69029f1b9dd164933c7bd
parent6841aed6c4abde1aa7015348496c86cadc227a1f (diff)
downloadglibc-7ae60af75b78f408420512c58fd5a08ca7a88bad.tar.xz
glibc-7ae60af75b78f408420512c58fd5a08ca7a88bad.zip
hurd: Factorize at/non-at functions
Non-at functions can be implemented by just calling the corresponding at function with AT_FDCWD and zero at_flags. In the linkat case, the at behavior is different (O_NOLINK), so this introduces __linkat_common to pass O_NOLINK as appropriate. lstat functions can also be implemented with fstatat by adding __fstatat64_common which takes a flags parameter in addition to the at_flags parameter, In the end this factorizes chmod, chown, link, lstat64, mkdir, readlink, rename, stat64, symlink, unlink, utimes. This also makes __lstat, __lxstat64, __stat and __xstat64 directly use __fstatat64_common instead of __lstat64 or __stat64.
-rw-r--r--include/sys/stat.h2
-rw-r--r--include/time.h1
-rw-r--r--include/unistd.h4
-rw-r--r--sysdeps/mach/hurd/chmod.c10
-rw-r--r--sysdeps/mach/hurd/chown.c10
-rw-r--r--sysdeps/mach/hurd/fchmodat.c4
-rw-r--r--sysdeps/mach/hurd/fchownat.c3
-rw-r--r--sysdeps/mach/hurd/fstatat64.c12
-rw-r--r--sysdeps/mach/hurd/fstatat_common.h23
-rw-r--r--sysdeps/mach/hurd/futimesat.c3
-rw-r--r--sysdeps/mach/hurd/link.c32
-rw-r--r--sysdeps/mach/hurd/linkat.c16
-rw-r--r--sysdeps/mach/hurd/linkat_common.h23
-rw-r--r--sysdeps/mach/hurd/lstat.c6
-rw-r--r--sysdeps/mach/hurd/lstat64.c14
-rw-r--r--sysdeps/mach/hurd/lxstat64.c4
-rw-r--r--sysdeps/mach/hurd/mkdir.c14
-rw-r--r--sysdeps/mach/hurd/mkdirat.c4
-rw-r--r--sysdeps/mach/hurd/readlink.c42
-rw-r--r--sysdeps/mach/hurd/readlinkat.c3
-rw-r--r--sysdeps/mach/hurd/rename.c21
-rw-r--r--sysdeps/mach/hurd/stat.c5
-rw-r--r--sysdeps/mach/hurd/stat64.c12
-rw-r--r--sysdeps/mach/hurd/symlink.c40
-rw-r--r--sysdeps/mach/hurd/symlinkat.c4
-rw-r--r--sysdeps/mach/hurd/unlink.c15
-rw-r--r--sysdeps/mach/hurd/unlinkat.c4
-rw-r--r--sysdeps/mach/hurd/utimes.c14
-rw-r--r--sysdeps/mach/hurd/xstat64.c4
29 files changed, 123 insertions, 226 deletions
diff --git a/include/sys/stat.h b/include/sys/stat.h
index 13e777b3c7..4a29e842de 100644
--- a/include/sys/stat.h
+++ b/include/sys/stat.h
@@ -66,10 +66,12 @@ hidden_proto (__fstatat64_time64);
extern int __chmod (const char *__file, __mode_t __mode);
libc_hidden_proto (__chmod)
extern int __fchmod (int __fd, __mode_t __mode);
+extern int __fchmodat (int __fd, const char *__file, mode_t __mode, int __flag);
libc_hidden_proto (fchmodat)
extern __mode_t __umask (__mode_t __mask);
extern int __mkdir (const char *__path, __mode_t __mode);
libc_hidden_proto (__mkdir)
+extern int __mkdirat (int __fd, const char *__path, mode_t __mode);
extern int __mknodat (int fd, const char *path, mode_t mode, dev_t dev);
libc_hidden_proto (__mknodat);
diff --git a/include/time.h b/include/time.h
index a64eff54f5..20abea69d4 100644
--- a/include/time.h
+++ b/include/time.h
@@ -196,6 +196,7 @@ extern int __utimensat64_helper (int fd, const char *file,
const struct __timespec64 tsp[2], int flags);
libc_hidden_proto (__utimensat64_helper);
+extern int __futimesat (int __fd, const char *__file, const struct timeval __tvp[2]);
#if __TIMESIZE == 64
# define __futimes64 __futimes
# define __futimesat64 __futimesat
diff --git a/include/unistd.h b/include/unistd.h
index af795a37c8..4345d08d60 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -78,6 +78,7 @@ extern int __chown (const char *__file,
libc_hidden_proto (__chown)
extern int __fchown (int __fd,
__uid_t __owner, __gid_t __group);
+extern int __fchownat (int __fd, const char *__file, uid_t __owner, gid_t __group, int __flag);
extern int __lchown (const char *__file, __uid_t __owner,
__gid_t __group);
extern int __chdir (const char *__path) attribute_hidden;
@@ -148,9 +149,12 @@ libc_hidden_proto (_Fork);
extern int __isatty (int __fd) attribute_hidden;
extern int __link (const char *__from, const char *__to);
extern int __symlink (const char *__from, const char *__to);
+extern int __symlinkat (const char *__from, int __fd, const char *__to);
extern ssize_t __readlink (const char *__path, char *__buf, size_t __len)
attribute_hidden;
+extern ssize_t __readlinkat (int __fd, const char *__file_name, char *__buf, size_t __len);
extern int __unlink (const char *__name) attribute_hidden;
+extern int __unlinkat (int __fd, const char *__name, int __flag);
extern int __gethostname (char *__name, size_t __len) attribute_hidden;
extern int __revoke (const char *__file);
extern int __profil (unsigned short int *__sample_buffer, size_t __size,
diff --git a/sysdeps/mach/hurd/chmod.c b/sysdeps/mach/hurd/chmod.c
index 7b79d24990..313483193d 100644
--- a/sysdeps/mach/hurd/chmod.c
+++ b/sysdeps/mach/hurd/chmod.c
@@ -24,15 +24,7 @@
int
__chmod (const char *file, mode_t mode)
{
- error_t err;
- file_t port = __file_name_lookup (file, 0, 0);
- if (port == MACH_PORT_NULL)
- return -1;
- err = __file_chmod (port, mode);
- __mach_port_deallocate (__mach_task_self (), port);
- if (err)
- return __hurd_fail (err);
- return 0;
+ return __fchmodat (AT_FDCWD, file, mode, 0);
}
libc_hidden_def (__chmod)
diff --git a/sysdeps/mach/hurd/chown.c b/sysdeps/mach/hurd/chown.c
index 0c5565bea3..f2915211c5 100644
--- a/sysdeps/mach/hurd/chown.c
+++ b/sysdeps/mach/hurd/chown.c
@@ -24,15 +24,7 @@
int
__chown (const char *file, uid_t owner, gid_t group)
{
- error_t err;
- file_t port = __file_name_lookup (file, 0, 0);
- if (port == MACH_PORT_NULL)
- return -1;
- err = __file_chown (port, owner, group);
- __mach_port_deallocate (__mach_task_self (), port);
- if (err)
- return __hurd_fail (err);
- return 0;
+ return __fchownat (AT_FDCWD, file, owner, group, 0);
}
libc_hidden_def (__chown)
weak_alias (__chown, chown)
diff --git a/sysdeps/mach/hurd/fchmodat.c b/sysdeps/mach/hurd/fchmodat.c
index 5bdd5c4f25..44385cc07e 100644
--- a/sysdeps/mach/hurd/fchmodat.c
+++ b/sysdeps/mach/hurd/fchmodat.c
@@ -25,7 +25,7 @@
#include <hurd/fd.h>
int
-fchmodat (int fd, const char *file, mode_t mode, int flag)
+__fchmodat (int fd, const char *file, mode_t mode, int flag)
{
error_t err;
file_t port = __file_name_lookup_at (fd, flag, file, 0, 0);
@@ -37,4 +37,6 @@ fchmodat (int fd, const char *file, mode_t mode, int flag)
return __hurd_fail (err);
return 0;
}
+
+weak_alias (__fchmodat, fchmodat)
libc_hidden_def (fchmodat)
diff --git a/sysdeps/mach/hurd/fchownat.c b/sysdeps/mach/hurd/fchownat.c
index a34632c63e..580f38f057 100644
--- a/sysdeps/mach/hurd/fchownat.c
+++ b/sysdeps/mach/hurd/fchownat.c
@@ -26,7 +26,7 @@
/* Change the owner and group of FILE. */
int
-fchownat (int fd, const char *file, uid_t owner, gid_t group, int flag)
+__fchownat (int fd, const char *file, uid_t owner, gid_t group, int flag)
{
error_t err;
file_t port = __file_name_lookup_at (fd, flag, file, 0, 0);
@@ -38,3 +38,4 @@ fchownat (int fd, const char *file, uid_t owner, gid_t group, int flag)
return __hurd_fail (err);
return 0;
}
+weak_alias (__fchownat, fchownat)
diff --git a/sysdeps/mach/hurd/fstatat64.c b/sysdeps/mach/hurd/fstatat64.c
index 56c1291b77..ca60ba43c4 100644
--- a/sysdeps/mach/hurd/fstatat64.c
+++ b/sysdeps/mach/hurd/fstatat64.c
@@ -23,14 +23,16 @@
#include <hurd.h>
#include <hurd/fd.h>
+#include <fstatat_common.h>
+
/* Get information about the file descriptor FD in BUF. */
int
-__fstatat64 (int fd, const char *filename, struct stat64 *buf, int flag)
+__fstatat64_common (int fd, const char *filename, struct stat64 *buf, int at_flags, int flags)
{
error_t err;
io_t port;
- port = __file_name_lookup_at (fd, flag, filename, 0, 0);
+ port = __file_name_lookup_at (fd, at_flags, filename, flags, 0);
if (port == MACH_PORT_NULL)
return -1;
@@ -39,5 +41,11 @@ __fstatat64 (int fd, const char *filename, struct stat64 *buf, int flag)
return __hurd_fail (err);
}
+
+int
+__fstatat64 (int fd, const char *filename, struct stat64 *buf, int at_flags)
+{
+ return __fstatat64_common (fd, filename, buf, at_flags, 0);
+}
libc_hidden_def (__fstatat64)
weak_alias (__fstatat64, fstatat64)
diff --git a/sysdeps/mach/hurd/fstatat_common.h b/sysdeps/mach/hurd/fstatat_common.h
new file mode 100644
index 0000000000..dd95a70a25
--- /dev/null
+++ b/sysdeps/mach/hurd/fstatat_common.h
@@ -0,0 +1,23 @@
+/* Copyright (C) 2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _FSTATAT_COMMON_H
+#define _FSTATAT_COMMON_H 1
+
+extern int __fstatat64_common (int fd, const char *filename, struct stat64 *buf, int at_flags, int flags);
+
+#endif /* link_common.h */
diff --git a/sysdeps/mach/hurd/futimesat.c b/sysdeps/mach/hurd/futimesat.c
index 9745a3936b..0976f2dfa9 100644
--- a/sysdeps/mach/hurd/futimesat.c
+++ b/sysdeps/mach/hurd/futimesat.c
@@ -27,7 +27,7 @@
/* Change the access time of FILE relative to FD to TVP[0] and
the modification time of FILE to TVP[1]. */
int
-futimesat (int fd, const char *file, const struct timeval tvp[2])
+__futimesat (int fd, const char *file, const struct timeval tvp[2])
{
error_t err;
file_t port;
@@ -43,3 +43,4 @@ futimesat (int fd, const char *file, const struct timeval tvp[2])
return __hurd_fail (err);
return 0;
}
+weak_alias (__futimesat, futimesat)
diff --git a/sysdeps/mach/hurd/link.c b/sysdeps/mach/hurd/link.c
index 48856bdce9..2267ae0732 100644
--- a/sysdeps/mach/hurd/link.c
+++ b/sysdeps/mach/hurd/link.c
@@ -20,39 +20,13 @@
#include <unistd.h>
#include <hurd.h>
+#include <linkat_common.h>
+
/* Make a link to FROM called TO. */
int
__link (const char *from, const char *to)
{
- error_t err;
- file_t oldfile, linknode, todir;
- char *toname;
-
- oldfile = __file_name_lookup (from, 0, 0);
- if (oldfile == MACH_PORT_NULL)
- return -1;
-
- /* The file_getlinknode RPC returns the port that should be passed to
- the receiving filesystem (the one containing TODIR) in dir_link. */
-
- err = __file_getlinknode (oldfile, &linknode);
- __mach_port_deallocate (__mach_task_self (), oldfile);
- if (err)
- return __hurd_fail (err);
-
- todir = __file_name_split (to, &toname);
- if (todir != MACH_PORT_NULL)
- {
- err = __dir_link (todir, linknode, toname, 1);
- __mach_port_deallocate (__mach_task_self (), todir);
- }
- __mach_port_deallocate (__mach_task_self (), linknode);
- if (todir == MACH_PORT_NULL)
- return -1;
-
- if (err)
- return __hurd_fail (err);
- return 0;
+ return __linkat_common (AT_FDCWD, from, AT_FDCWD, to, 0, 0);
}
weak_alias (__link, link)
diff --git a/sysdeps/mach/hurd/linkat.c b/sysdeps/mach/hurd/linkat.c
index 2433614cfb..9ccef6f334 100644
--- a/sysdeps/mach/hurd/linkat.c
+++ b/sysdeps/mach/hurd/linkat.c
@@ -23,18 +23,17 @@
#include <hurd.h>
#include <hurd/fd.h>
+#include <linkat_common.h>
/* Make a link to FROM relative to FROMFD called TO relative to TOFD. */
int
-linkat (int fromfd, const char *from, int tofd, const char *to, int flags)
+__linkat_common (int fromfd, const char *from, int tofd, const char *to, int at_flags, int flags)
{
error_t err;
file_t oldfile, linknode, todir;
char *toname;
- /* POSIX says linkat doesn't follow symlinks by default, so pass
- O_NOLINK. That can be overridden by AT_SYMLINK_FOLLOW in FLAGS. */
- oldfile = __file_name_lookup_at (fromfd, flags, from, O_NOLINK, 0);
+ oldfile = __file_name_lookup_at (fromfd, at_flags, from, flags, 0);
if (oldfile == MACH_PORT_NULL)
return -1;
@@ -60,3 +59,12 @@ linkat (int fromfd, const char *from, int tofd, const char *to, int flags)
return __hurd_fail (err);
return 0;
}
+
+int
+__linkat (int fromfd, const char *from, int tofd, const char *to, int at_flags)
+{
+ /* POSIX says linkat doesn't follow symlinks by default, so pass
+ O_NOLINK. That can be overridden by AT_SYMLINK_FOLLOW in FLAGS. */
+ return __linkat_common (fromfd, from, tofd, to, at_flags, O_NOLINK);
+}
+weak_alias (__linkat, linkat)
diff --git a/sysdeps/mach/hurd/linkat_common.h b/sysdeps/mach/hurd/linkat_common.h
new file mode 100644
index 0000000000..6c98c57cbe
--- /dev/null
+++ b/sysdeps/mach/hurd/linkat_common.h
@@ -0,0 +1,23 @@
+/* Copyright (C) 2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _LINKAT_COMMON_H
+#define _LINKAT_COMMON_H 1
+
+extern int __linkat_common (int fromfd, const char *from, int tofd, const char *to, int at_flags, int flags);
+
+#endif /* link_common.h */
diff --git a/sysdeps/mach/hurd/lstat.c b/sysdeps/mach/hurd/lstat.c
index 2acfda1934..4fdc312186 100644
--- a/sysdeps/mach/hurd/lstat.c
+++ b/sysdeps/mach/hurd/lstat.c
@@ -18,6 +18,9 @@
#include <errno.h>
#include <sys/stat.h>
#include <stddef.h>
+#include <fcntl.h>
+
+#include <fstatat_common.h>
#include "statconv.c"
@@ -25,6 +28,7 @@ int
__lstat (const char *file, struct stat *buf)
{
struct stat64 buf64;
- return __lstat64 (file, &buf64) ?: stat64_conv (buf, &buf64);
+ return __fstatat64_common (AT_FDCWD, file, &buf64, 0, O_NOLINK) ?:
+ stat64_conv (buf, &buf64);
}
weak_alias (__lstat, lstat)
diff --git a/sysdeps/mach/hurd/lstat64.c b/sysdeps/mach/hurd/lstat64.c
index 55ce1552b3..d67daf9f61 100644
--- a/sysdeps/mach/hurd/lstat64.c
+++ b/sysdeps/mach/hurd/lstat64.c
@@ -21,21 +21,13 @@
#include <fcntl.h>
#include <hurd.h>
+#include <fstatat_common.h>
+
/* Get information about the file descriptor FD in BUF. */
int
__lstat64 (const char *file, struct stat64 *buf)
{
- error_t err;
- file_t port;
-
- port = __file_name_lookup (file, O_NOLINK, 0);
- if (port == MACH_PORT_NULL)
- return -1;
- err = __io_stat (port, buf);
- __mach_port_deallocate (__mach_task_self (), port);
- if (err)
- return __hurd_fail (err);
- return 0;
+ return __fstatat64_common (AT_FDCWD, file, buf, 0, O_NOLINK);
}
hidden_def (__lstat64)
weak_alias (__lstat64, lstat64)
diff --git a/sysdeps/mach/hurd/lxstat64.c b/sysdeps/mach/hurd/lxstat64.c
index 450fed0cad..7cd86ab4d7 100644
--- a/sysdeps/mach/hurd/lxstat64.c
+++ b/sysdeps/mach/hurd/lxstat64.c
@@ -22,6 +22,8 @@
#include <hurd.h>
#include <shlib-compat.h>
+#include <fstatat_common.h>
+
#if LIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_33)
/* Get information about the file descriptor FD in BUF. */
@@ -31,6 +33,6 @@ __lxstat64 (int vers, const char *file, struct stat64 *buf)
if (vers != _STAT_VER)
return __hurd_fail (EINVAL);
- return __lstat64 (file, buf);
+ return __fstatat64_common (AT_FDCWD, file, buf, 0, O_NOLINK);
}
#endif
diff --git a/sysdeps/mach/hurd/mkdir.c b/sysdeps/mach/hurd/mkdir.c
index 06a7c16945..9dbb47b77b 100644
--- a/sysdeps/mach/hurd/mkdir.c
+++ b/sysdeps/mach/hurd/mkdir.c
@@ -25,19 +25,7 @@
int
__mkdir (const char *file_name, mode_t mode)
{
- error_t err;
- const char *name;
- file_t parent;
- if (!strcmp (file_name, "/"))
- return __hurd_fail (EEXIST);
- parent = __directory_name_split (file_name, (char **) &name);
- if (parent == MACH_PORT_NULL)
- return -1;
- err = __dir_mkdir (parent, name, mode & ~_hurd_umask);
- __mach_port_deallocate (__mach_task_self (), parent);
- if (err)
- return __hurd_fail (err);
- return 0;
+ return __mkdirat (AT_FDCWD, file_name, mode);
}
libc_hidden_def (__mkdir)
diff --git a/sysdeps/mach/hurd/mkdirat.c b/sysdeps/mach/hurd/mkdirat.c
index 367b2d0052..b27da52faf 100644
--- a/sysdeps/mach/hurd/mkdirat.c
+++ b/sysdeps/mach/hurd/mkdirat.c
@@ -24,7 +24,7 @@
#include <string.h>
int
-mkdirat (int fd, const char *path, mode_t mode)
+__mkdirat (int fd, const char *path, mode_t mode)
{
err