return pidfd;
}
+int getpeerpidref(int fd, PidRef *ret) {
+ int r;
+
+ assert(fd >= 0);
+ assert(ret);
+
+ int pidfd = getpeerpidfd(fd);
+ if (pidfd < 0) {
+ if (!ERRNO_IS_NEG_NOT_SUPPORTED(pidfd))
+ return pidfd;
+
+ struct ucred ucred;
+ r = getpeercred(fd, &ucred);
+ if (r < 0)
+ return r;
+
+ return pidref_set_pid(ret, ucred.pid);
+ }
+
+ return pidref_set_pidfd_consume(ret, pidfd);
+}
+
ssize_t send_many_fds_iov_sa(
int transport_fd,
int *fds_array, size_t n_fds_array,
#include "macro.h"
#include "missing_network.h"
#include "missing_socket.h"
+#include "pidref.h"
#include "sparse-endian.h"
union sockaddr_union {
int getpeersec(int fd, char **ret);
int getpeergroups(int fd, gid_t **ret);
int getpeerpidfd(int fd);
+int getpeerpidref(int fd, PidRef *ret);
ssize_t send_many_fds_iov_sa(
int transport_fd,
assert_se(connect(fd2, &sa.sa, SOCKADDR_LEN(sa)) >= 0);
}
+TEST(getpeerpidref) {
+ _cleanup_close_pair_ int fd[2] = EBADF_PAIR;
+
+ ASSERT_OK(socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fd));
+
+ _cleanup_(pidref_done) PidRef pidref0 = PIDREF_NULL, pidref1 = PIDREF_NULL, pidref_self = PIDREF_NULL, pidref_pid1 = PIDREF_NULL;
+ ASSERT_OK(getpeerpidref(fd[0], &pidref0));
+ ASSERT_OK(getpeerpidref(fd[1], &pidref1));
+
+ ASSERT_OK(pidref_set_self(&pidref_self));
+ ASSERT_OK(pidref_set_pid(&pidref_pid1, 1));
+
+ ASSERT_TRUE(pidref_equal(&pidref0, &pidref1));
+ ASSERT_TRUE(pidref_equal(&pidref0, &pidref_self));
+ ASSERT_TRUE(pidref_equal(&pidref1, &pidref_self));
+
+ ASSERT_TRUE(!pidref_equal(&pidref_self, &pidref_pid1));
+ ASSERT_TRUE(!pidref_equal(&pidref1, &pidref_pid1));
+ ASSERT_TRUE(!pidref_equal(&pidref0, &pidref_pid1));
+}
+
DEFINE_TEST_MAIN(LOG_DEBUG);