mirror of
https://github.com/systemd/systemd.git
synced 2025-03-08 08:58:27 +03:00
Merge pull request #23339 from poettering/sockaddr-size-limit
tree-wide: add support for connecting to AF_UNIX sockets in the file system beyond the 108ch limit
This commit is contained in:
commit
0168b91603
@ -763,8 +763,7 @@ int read_full_file_full(
|
||||
|
||||
r = xfopenat(dir_fd, filename, "re", 0, &f);
|
||||
if (r < 0) {
|
||||
_cleanup_close_ int dfd = -1, sk = -1;
|
||||
union sockaddr_union sa;
|
||||
_cleanup_close_ int sk = -1;
|
||||
|
||||
/* ENXIO is what Linux returns if we open a node that is an AF_UNIX socket */
|
||||
if (r != -ENXIO)
|
||||
@ -778,22 +777,6 @@ int read_full_file_full(
|
||||
if (offset != UINT64_MAX)
|
||||
return -ENXIO;
|
||||
|
||||
if (dir_fd == AT_FDCWD)
|
||||
r = sockaddr_un_set_path(&sa.un, filename);
|
||||
else {
|
||||
/* If we shall operate relative to some directory, then let's use O_PATH first to
|
||||
* open the socket inode, and then connect to it via /proc/self/fd/. We have to do
|
||||
* this since there's not connectat() that takes a directory fd as first arg. */
|
||||
|
||||
dfd = openat(dir_fd, filename, O_PATH|O_CLOEXEC);
|
||||
if (dfd < 0)
|
||||
return -errno;
|
||||
|
||||
r = sockaddr_un_set_path(&sa.un, FORMAT_PROC_FD_PATH(dfd));
|
||||
}
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
sk = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
|
||||
if (sk < 0)
|
||||
return -errno;
|
||||
@ -812,9 +795,11 @@ int read_full_file_full(
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (connect(sk, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0)
|
||||
return errno == ENOTSOCK ? -ENXIO : -errno; /* propagate original error if this is
|
||||
* not a socket after all */
|
||||
r = connect_unix_path(sk, dir_fd, filename);
|
||||
if (IN_SET(r, -ENOTSOCK, -EINVAL)) /* propagate original error if this is not a socket after all */
|
||||
return -ENXIO;
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (shutdown(sk, SHUT_WR) < 0)
|
||||
return -errno;
|
||||
|
@ -149,12 +149,6 @@ static int create_log_socket(int type) {
|
||||
}
|
||||
|
||||
static int log_open_syslog(void) {
|
||||
|
||||
static const union sockaddr_union sa = {
|
||||
.un.sun_family = AF_UNIX,
|
||||
.un.sun_path = "/dev/log",
|
||||
};
|
||||
|
||||
int r;
|
||||
|
||||
if (syslog_fd >= 0)
|
||||
@ -166,22 +160,21 @@ static int log_open_syslog(void) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (connect(syslog_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
|
||||
r = connect_unix_path(syslog_fd, AT_FDCWD, "/dev/log");
|
||||
if (r < 0) {
|
||||
safe_close(syslog_fd);
|
||||
|
||||
/* Some legacy syslog systems still use stream
|
||||
* sockets. They really shouldn't. But what can we
|
||||
* do... */
|
||||
/* Some legacy syslog systems still use stream sockets. They really shouldn't. But what can
|
||||
* we do... */
|
||||
syslog_fd = create_log_socket(SOCK_STREAM);
|
||||
if (syslog_fd < 0) {
|
||||
r = syslog_fd;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (connect(syslog_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
|
||||
r = -errno;
|
||||
r = connect_unix_path(syslog_fd, AT_FDCWD, "/dev/log");
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
syslog_is_stream = true;
|
||||
} else
|
||||
@ -199,12 +192,6 @@ static void log_close_journal(void) {
|
||||
}
|
||||
|
||||
static int log_open_journal(void) {
|
||||
|
||||
static const union sockaddr_union sa = {
|
||||
.un.sun_family = AF_UNIX,
|
||||
.un.sun_path = "/run/systemd/journal/socket",
|
||||
};
|
||||
|
||||
int r;
|
||||
|
||||
if (journal_fd >= 0)
|
||||
@ -216,10 +203,9 @@ static int log_open_journal(void) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (connect(journal_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
|
||||
r = -errno;
|
||||
r = connect_unix_path(journal_fd, AT_FDCWD, "/run/systemd/journal/socket");
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -1426,3 +1426,51 @@ int socket_get_mtu(int fd, int af, size_t *ret) {
|
||||
*ret = (size_t) mtu;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int connect_unix_path(int fd, int dir_fd, const char *path) {
|
||||
_cleanup_close_ int inode_fd = -1;
|
||||
union sockaddr_union sa = {
|
||||
.un.sun_family = AF_UNIX,
|
||||
};
|
||||
size_t path_len;
|
||||
socklen_t salen;
|
||||
|
||||
assert(fd >= 0);
|
||||
assert(dir_fd == AT_FDCWD || dir_fd >= 0);
|
||||
assert(path);
|
||||
|
||||
/* 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. */
|
||||
|
||||
path_len = strlen(path);
|
||||
|
||||
/* 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 */
|
||||
if (path_len <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (dir_fd == AT_FDCWD && path_len < sizeof(sa.un.sun_path)) {
|
||||
memcpy(sa.un.sun_path, path, path_len + 1);
|
||||
salen = offsetof(struct sockaddr_un, sun_path) + path_len + 1;
|
||||
} else {
|
||||
const char *proc;
|
||||
size_t proc_len;
|
||||
|
||||
/* If dir_fd is specified, then we need to go the indirect O_PATH route, because connectat()
|
||||
* does not 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 (inode_fd < 0)
|
||||
return -errno;
|
||||
|
||||
proc = FORMAT_PROC_FD_PATH(inode_fd);
|
||||
proc_len = strlen(proc);
|
||||
|
||||
assert(proc_len < sizeof(sa.un.sun_path));
|
||||
memcpy(sa.un.sun_path, proc, proc_len + 1);
|
||||
salen = offsetof(struct sockaddr_un, sun_path) + proc_len + 1;
|
||||
}
|
||||
|
||||
return RET_NERRNO(connect(fd, &sa.sa, salen));
|
||||
}
|
||||
|
@ -332,3 +332,5 @@ int socket_get_mtu(int fd, int af, size_t *ret);
|
||||
|
||||
/* an initializer for struct ucred that initialized all fields to the invalid value appropriate for each */
|
||||
#define UCRED_INVALID { .pid = 0, .uid = UID_INVALID, .gid = GID_INVALID }
|
||||
|
||||
int connect_unix_path(int fd, int dir_fd, const char *path);
|
||||
|
@ -277,8 +277,6 @@ static int connect_journal_socket(
|
||||
uid_t uid,
|
||||
gid_t gid) {
|
||||
|
||||
union sockaddr_union sa;
|
||||
socklen_t sa_len;
|
||||
uid_t olduid = UID_INVALID;
|
||||
gid_t oldgid = GID_INVALID;
|
||||
const char *j;
|
||||
@ -287,10 +285,6 @@ static int connect_journal_socket(
|
||||
j = log_namespace ?
|
||||
strjoina("/run/systemd/journal.", log_namespace, "/stdout") :
|
||||
"/run/systemd/journal/stdout";
|
||||
r = sockaddr_un_set_path(&sa.un, j);
|
||||
if (r < 0)
|
||||
return r;
|
||||
sa_len = r;
|
||||
|
||||
if (gid_is_valid(gid)) {
|
||||
oldgid = getgid();
|
||||
@ -308,10 +302,10 @@ static int connect_journal_socket(
|
||||
}
|
||||
}
|
||||
|
||||
r = RET_NERRNO(connect(fd, &sa.sa, sa_len));
|
||||
r = connect_unix_path(fd, AT_FDCWD, j);
|
||||
|
||||
/* If we fail to restore the uid or gid, things will likely
|
||||
fail later on. This should only happen if an LSM interferes. */
|
||||
/* If we fail to restore the uid or gid, things will likely fail later on. This should only happen if
|
||||
an LSM interferes. */
|
||||
|
||||
if (uid_is_valid(uid))
|
||||
(void) seteuid(olduid);
|
||||
@ -389,8 +383,6 @@ static int open_terminal_as(const char *path, int flags, int nfd) {
|
||||
}
|
||||
|
||||
static int acquire_path(const char *path, int flags, mode_t mode) {
|
||||
union sockaddr_union sa;
|
||||
socklen_t sa_len;
|
||||
_cleanup_close_ int fd = -1;
|
||||
int r;
|
||||
|
||||
@ -408,18 +400,17 @@ static int acquire_path(const char *path, int flags, mode_t mode) {
|
||||
|
||||
/* So, it appears the specified path could be an AF_UNIX socket. Let's see if we can connect to it. */
|
||||
|
||||
r = sockaddr_un_set_path(&sa.un, path);
|
||||
if (r < 0)
|
||||
return r == -EINVAL ? -ENXIO : r;
|
||||
sa_len = r;
|
||||
|
||||
fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
if (connect(fd, &sa.sa, sa_len) < 0)
|
||||
return errno == EINVAL ? -ENXIO : -errno; /* Propagate initial error if we get EINVAL, i.e. we have
|
||||
* indication that this wasn't an AF_UNIX socket after all */
|
||||
r = connect_unix_path(fd, AT_FDCWD, path);
|
||||
if (IN_SET(r, -ENOTSOCK, -EINVAL))
|
||||
/* Propagate initial error if we get ENOTSOCK or EINVAL, i.e. we have indication that this
|
||||
* wasn't an AF_UNIX socket after all */
|
||||
return -ENXIO;
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if ((flags & O_ACCMODE) == O_RDONLY)
|
||||
r = shutdown(fd, SHUT_WR);
|
||||
|
@ -1055,11 +1055,6 @@ finish:
|
||||
}
|
||||
|
||||
static int send_iovec(const struct iovec_wrapper *iovw, int input_fd) {
|
||||
|
||||
static const union sockaddr_union sa = {
|
||||
.un.sun_family = AF_UNIX,
|
||||
.un.sun_path = "/run/systemd/coredump",
|
||||
};
|
||||
_cleanup_close_ int fd = -1;
|
||||
int r;
|
||||
|
||||
@ -1070,8 +1065,9 @@ static int send_iovec(const struct iovec_wrapper *iovw, int input_fd) {
|
||||
if (fd < 0)
|
||||
return log_error_errno(errno, "Failed to create coredump socket: %m");
|
||||
|
||||
if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0)
|
||||
return log_error_errno(errno, "Failed to connect to coredump service: %m");
|
||||
r = connect_unix_path(fd, AT_FDCWD, "/run/systemd/coredump");
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to connect to coredump service: %m");
|
||||
|
||||
for (size_t i = 0; i < iovw->count; i++) {
|
||||
struct msghdr mh = {
|
||||
|
@ -226,20 +226,17 @@ static int process_progress(int fd, FILE* console) {
|
||||
}
|
||||
|
||||
static int fsck_progress_socket(void) {
|
||||
static const union sockaddr_union sa = {
|
||||
.un.sun_family = AF_UNIX,
|
||||
.un.sun_path = "/run/systemd/fsck.progress",
|
||||
};
|
||||
|
||||
_cleanup_close_ int fd = -1;
|
||||
int r;
|
||||
|
||||
fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (fd < 0)
|
||||
return log_warning_errno(errno, "socket(): %m");
|
||||
|
||||
if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0)
|
||||
return log_full_errno(IN_SET(errno, ECONNREFUSED, ENOENT) ? LOG_DEBUG : LOG_WARNING,
|
||||
errno, "Failed to connect to progress socket %s, ignoring: %m", sa.un.sun_path);
|
||||
r = connect_unix_path(fd, AT_FDCWD, "/run/systemd/fsck.progress");
|
||||
if (r < 0)
|
||||
return log_full_errno(IN_SET(r, -ECONNREFUSED, -ENOENT) ? LOG_DEBUG : LOG_WARNING,
|
||||
r, "Failed to connect to progress socket, ignoring: %m");
|
||||
|
||||
return TAKE_FD(fd);
|
||||
}
|
||||
|
@ -408,10 +408,6 @@ _public_ int sd_journal_perror(const char *message) {
|
||||
}
|
||||
|
||||
_public_ int sd_journal_stream_fd(const char *identifier, int priority, int level_prefix) {
|
||||
static const union sockaddr_union sa = {
|
||||
.un.sun_family = AF_UNIX,
|
||||
.un.sun_path = "/run/systemd/journal/stdout",
|
||||
};
|
||||
_cleanup_close_ int fd = -1;
|
||||
char *header;
|
||||
size_t l;
|
||||
@ -424,9 +420,9 @@ _public_ int sd_journal_stream_fd(const char *identifier, int priority, int leve
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
r = connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
|
||||
r = connect_unix_path(fd, AT_FDCWD, "/run/systemd/journal/stdout");
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
return r;
|
||||
|
||||
if (shutdown(fd, SHUT_RD) < 0)
|
||||
return -errno;
|
||||
|
@ -5387,12 +5387,6 @@ static int initialize_rlimits(void) {
|
||||
}
|
||||
|
||||
static int cant_be_in_netns(void) {
|
||||
union sockaddr_union sa = {
|
||||
.un = {
|
||||
.sun_family = AF_UNIX,
|
||||
.sun_path = "/run/udev/control",
|
||||
},
|
||||
};
|
||||
char udev_path[STRLEN("/proc//ns/net") + DECIMAL_STR_MAX(pid_t)];
|
||||
_cleanup_free_ char *udev_ns = NULL, *our_ns = NULL;
|
||||
_cleanup_close_ int fd = -1;
|
||||
@ -5410,13 +5404,13 @@ static int cant_be_in_netns(void) {
|
||||
if (fd < 0)
|
||||
return log_error_errno(errno, "Failed to allocate udev control socket: %m");
|
||||
|
||||
if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
|
||||
|
||||
if (errno == ENOENT || ERRNO_IS_DISCONNECT(errno))
|
||||
r = connect_unix_path(fd, AT_FDCWD, "/run/udev/control");
|
||||
if (r < 0) {
|
||||
if (r == -ENOENT || ERRNO_IS_DISCONNECT(r))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
"Sorry, but --image= requires access to the host's /run/ hierarchy, since we need access to udev.");
|
||||
|
||||
return log_error_errno(errno, "Failed to connect socket to udev control socket: %m");
|
||||
return log_error_errno(r, "Failed to connect socket to udev control socket: %m");
|
||||
}
|
||||
|
||||
r = getpeercred(fd, &ucred);
|
||||
|
@ -1,4 +1,6 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
|
||||
#include "fd-util.h"
|
||||
@ -18,17 +20,12 @@ struct nscdInvalidateRequest {
|
||||
char dbname[];
|
||||
};
|
||||
|
||||
static const union sockaddr_union nscd_sa = {
|
||||
.un.sun_family = AF_UNIX,
|
||||
.un.sun_path = "/run/nscd/socket",
|
||||
};
|
||||
|
||||
static int nscd_flush_cache_one(const char *database, usec_t end) {
|
||||
size_t req_size, has_written = 0, has_read = 0, l;
|
||||
struct nscdInvalidateRequest *req;
|
||||
_cleanup_close_ int fd = -1;
|
||||
int32_t resp;
|
||||
int events;
|
||||
int events, r;
|
||||
|
||||
assert(database);
|
||||
|
||||
@ -60,11 +57,12 @@ static int nscd_flush_cache_one(const char *database, usec_t end) {
|
||||
* nice way to connect() to a server synchronously with a time limit that would also cover dealing with the
|
||||
* backlog limit. After all SO_RCVTIMEO and SR_SNDTIMEO don't apply to connect(), and alarm() is frickin' ugly
|
||||
* and not really reasonably usable from threads-aware code.) */
|
||||
if (connect(fd, &nscd_sa.sa, SOCKADDR_UN_LEN(nscd_sa.un)) < 0) {
|
||||
if (errno == EAGAIN)
|
||||
return log_debug_errno(errno, "nscd is overloaded (backlog limit reached) and refuses to take further connections: %m");
|
||||
if (errno != EINPROGRESS)
|
||||
return log_debug_errno(errno, "Failed to connect to nscd socket: %m");
|
||||
r = connect_unix_path(fd, AT_FDCWD, "/run/nscd/socket");
|
||||
if (r < 0) {
|
||||
if (r == -EAGAIN)
|
||||
return log_debug_errno(r, "nscd is overloaded (backlog limit reached) and refuses to take further connections: %m");
|
||||
if (r != -EINPROGRESS)
|
||||
return log_debug_errno(r, "Failed to connect to nscd socket: %m");
|
||||
|
||||
/* Continue in case of EINPROGRESS, but don't bother with send() or recv() until being notified that
|
||||
* establishing the connection is complete. */
|
||||
|
@ -271,17 +271,11 @@ static int varlink_new(Varlink **ret) {
|
||||
int varlink_connect_address(Varlink **ret, const char *address) {
|
||||
_cleanup_(varlink_unrefp) Varlink *v = NULL;
|
||||
union sockaddr_union sockaddr;
|
||||
socklen_t sockaddr_len;
|
||||
int r;
|
||||
|
||||
assert_return(ret, -EINVAL);
|
||||
assert_return(address, -EINVAL);
|
||||
|
||||
r = sockaddr_un_set_path(&sockaddr.un, address);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to set socket address '%s': %m", address);
|
||||
sockaddr_len = r;
|
||||
|
||||
r = varlink_new(&v);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to create varlink object: %m");
|
||||
@ -292,9 +286,21 @@ int varlink_connect_address(Varlink **ret, const char *address) {
|
||||
|
||||
v->fd = fd_move_above_stdio(v->fd);
|
||||
|
||||
if (connect(v->fd, &sockaddr.sa, sockaddr_len) < 0) {
|
||||
if (!IN_SET(errno, EAGAIN, EINPROGRESS))
|
||||
return log_debug_errno(errno, "Failed to connect to %s: %m", address);
|
||||
r = sockaddr_un_set_path(&sockaddr.un, address);
|
||||
if (r < 0) {
|
||||
if (r != -ENAMETOOLONG)
|
||||
return log_debug_errno(r, "Failed to set socket address '%s': %m", address);
|
||||
|
||||
/* This is a file system path, and too long to fit into sockaddr_un. Let's connect via O_PATH
|
||||
* to this socket. */
|
||||
|
||||
r = connect_unix_path(v->fd, AT_FDCWD, address);
|
||||
} else
|
||||
r = RET_NERRNO(connect(v->fd, &sockaddr.sa, r));
|
||||
|
||||
if (r < 0) {
|
||||
if (!IN_SET(r, -EAGAIN, -EINPROGRESS))
|
||||
return log_debug_errno(r, "Failed to connect to %s: %m", address);
|
||||
|
||||
v->connecting = true; /* We are asynchronously connecting, i.e. the connect() is being
|
||||
* processed in the background. As long as that's the case the socket
|
||||
|
@ -881,7 +881,7 @@ TEST(read_full_file_socket) {
|
||||
_cleanup_close_ int listener = -1;
|
||||
_cleanup_free_ char *data = NULL, *clientname = NULL;
|
||||
union sockaddr_union sa;
|
||||
const char *j;
|
||||
const char *j, *jj;
|
||||
size_t size;
|
||||
pid_t pid;
|
||||
int r;
|
||||
@ -897,6 +897,11 @@ TEST(read_full_file_socket) {
|
||||
assert_se(bind(listener, &sa.sa, SOCKADDR_UN_LEN(sa.un)) >= 0);
|
||||
assert_se(listen(listener, 1) >= 0);
|
||||
|
||||
/* Make sure the socket doesn't fit into a struct sockaddr_un, but we can still access it */
|
||||
jj = strjoina(z, "/a_very_long_patha_very_long_patha_very_long_patha_very_long_patha_very_long_patha_very_long_patha_very_long_patha_very_long_path");
|
||||
assert_se(strlen(jj) > sizeof_field(struct sockaddr_un, sun_path));
|
||||
assert_se(rename(j, jj) >= 0);
|
||||
|
||||
/* Bind the *client* socket to some randomized name, to verify that this works correctly. */
|
||||
assert_se(asprintf(&clientname, "@%" PRIx64 "/test-bindname", random_u64()) >= 0);
|
||||
|
||||
@ -924,8 +929,8 @@ TEST(read_full_file_socket) {
|
||||
_exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
assert_se(read_full_file_full(AT_FDCWD, j, UINT64_MAX, SIZE_MAX, 0, NULL, &data, &size) == -ENXIO);
|
||||
assert_se(read_full_file_full(AT_FDCWD, j, UINT64_MAX, SIZE_MAX, READ_FULL_FILE_CONNECT_SOCKET, clientname, &data, &size) >= 0);
|
||||
assert_se(read_full_file_full(AT_FDCWD, jj, UINT64_MAX, SIZE_MAX, 0, NULL, &data, &size) == -ENXIO);
|
||||
assert_se(read_full_file_full(AT_FDCWD, jj, UINT64_MAX, SIZE_MAX, READ_FULL_FILE_CONNECT_SOCKET, clientname, &data, &size) >= 0);
|
||||
assert_se(size == strlen(TEST_STR));
|
||||
assert_se(streq(data, TEST_STR));
|
||||
|
||||
|
@ -942,25 +942,19 @@ static int display_services(int argc, char *argv[], void *userdata) {
|
||||
|
||||
FOREACH_DIRENT(de, d, return -errno) {
|
||||
_cleanup_free_ char *j = NULL, *no = NULL;
|
||||
union sockaddr_union sockaddr;
|
||||
socklen_t sockaddr_len;
|
||||
_cleanup_close_ int fd = -1;
|
||||
|
||||
j = path_join("/run/systemd/userdb/", de->d_name);
|
||||
if (!j)
|
||||
return log_oom();
|
||||
|
||||
r = sockaddr_un_set_path(&sockaddr.un, j);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Path %s does not fit in AF_UNIX socket address: %m", j);
|
||||
sockaddr_len = r;
|
||||
|
||||
fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
|
||||
if (fd < 0)
|
||||
return log_error_errno(errno, "Failed to allocate AF_UNIX/SOCK_STREAM socket: %m");
|
||||
|
||||
if (connect(fd, &sockaddr.sa, sockaddr_len) < 0) {
|
||||
no = strjoin("No (", errno_to_name(errno), ")");
|
||||
r = connect_unix_path(fd, dirfd(d), de->d_name);
|
||||
if (r < 0) {
|
||||
no = strjoin("No (", errno_to_name(r), ")");
|
||||
if (!no)
|
||||
return log_oom();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user