fileio: teach read_one_line_file_at() XAT_FDROOT support
This commit is contained in:
+12
-6
@@ -420,11 +420,11 @@ int read_one_line_file_at(int dir_fd, const char *filename, char **ret) {
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
int r;
|
||||
|
||||
assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
|
||||
assert(dir_fd >= 0 || IN_SET(dir_fd, AT_FDCWD, XAT_FDROOT));
|
||||
assert(filename);
|
||||
assert(ret);
|
||||
|
||||
r = fopen_unlocked_at(dir_fd, filename, "re", 0, &f);
|
||||
r = fopen_unlocked_at(dir_fd, filename, "re", /* open_flags= */ 0, &f);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -1010,13 +1010,19 @@ static int xfopenat_regular(int dir_fd, const char *path, const char *mode, int
|
||||
|
||||
/* A combination of fopen() with openat() */
|
||||
|
||||
assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
|
||||
assert(dir_fd >= 0 || IN_SET(dir_fd, AT_FDCWD, XAT_FDROOT));
|
||||
assert(mode);
|
||||
assert(ret);
|
||||
|
||||
if (dir_fd == AT_FDCWD && path && open_flags == 0)
|
||||
f = fopen(path, mode);
|
||||
else {
|
||||
else if (dir_fd == XAT_FDROOT && path && open_flags == 0) {
|
||||
_cleanup_free_ char *j = strjoin("/", path);
|
||||
if (!j)
|
||||
return -ENOMEM;
|
||||
|
||||
f = fopen(j, mode);
|
||||
} else {
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
int mode_flags;
|
||||
|
||||
@@ -1051,7 +1057,7 @@ static int xfopenat_unix_socket(int dir_fd, const char *path, const char *bind_n
|
||||
FILE *f;
|
||||
int r;
|
||||
|
||||
assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
|
||||
assert(dir_fd >= 0 || IN_SET(dir_fd, AT_FDCWD, XAT_FDROOT));
|
||||
assert(ret);
|
||||
|
||||
sk = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
|
||||
@@ -1099,7 +1105,7 @@ int xfopenat_full(
|
||||
FILE *f = NULL; /* avoid false maybe-uninitialized warning */
|
||||
int r;
|
||||
|
||||
assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
|
||||
assert(dir_fd >= 0 || IN_SET(dir_fd, AT_FDCWD, XAT_FDROOT));
|
||||
assert(mode);
|
||||
assert(ret);
|
||||
|
||||
|
||||
+14
-3
@@ -1619,13 +1619,17 @@ int connect_unix_path(int fd, int dir_fd, const char *path) {
|
||||
_cleanup_close_ int inode_fd = -EBADF;
|
||||
|
||||
assert(fd >= 0);
|
||||
assert(dir_fd == AT_FDCWD || dir_fd >= 0);
|
||||
assert(IN_SET(dir_fd, AT_FDCWD, XAT_FDROOT) || dir_fd >= 0);
|
||||
|
||||
/* Connects to the specified AF_UNIX socket in the file system. Works around the 108 byte size limit
|
||||
* in sockaddr_un, by going via O_PATH if needed. This hence works for any kind of path. */
|
||||
|
||||
if (!path)
|
||||
if (!path) {
|
||||
if (dir_fd < 0)
|
||||
return -EISDIR;
|
||||
|
||||
return connect_unix_inode(fd, dir_fd); /* If no path is specified, then dir_fd refers to the socket inode to connect to. */
|
||||
}
|
||||
|
||||
/* Refuse zero length path early, to make sure AF_UNIX stack won't mistake this for an abstract
|
||||
* namespace path, since first char is NUL */
|
||||
@@ -1640,7 +1644,14 @@ int connect_unix_path(int fd, int dir_fd, const char *path) {
|
||||
* exist. If the path is too long, we also need to take the indirect route, since we can't fit this
|
||||
* into a sockaddr_un directly. */
|
||||
|
||||
inode_fd = openat(dir_fd, path, O_PATH|O_CLOEXEC);
|
||||
if (dir_fd == XAT_FDROOT) {
|
||||
_cleanup_free_ char *j = strjoin("/", path);
|
||||
if (!j)
|
||||
return -ENOMEM;
|
||||
|
||||
inode_fd = open(j, O_PATH|O_CLOEXEC);
|
||||
} else
|
||||
inode_fd = openat(dir_fd, path, O_PATH|O_CLOEXEC);
|
||||
if (inode_fd < 0)
|
||||
return -errno;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user