while ((char *) fds < ((char *) cmsg + cmsg_len)) {
if (!first)
tprints(", ");
- tprintf("%d", *fds++);
+ printfd(tcp, *fds++);
first = 0;
}
tprints("}}");
net-accept-connect
+scm_rights
set_ptracer_any
sigaction
+uio
*.log
*.log.*
*.o
AM_CFLAGS = $(WARN_CFLAGS)
-check_PROGRAMS = net-accept-connect set_ptracer_any sigaction uio
+check_PROGRAMS = \
+ net-accept-connect \
+ scm_rights \
+ set_ptracer_any \
+ sigaction \
+ uio
uio_CFLAGS = $(AM_CFLAGS) -D_FILE_OFFSET_BITS=64
ptrace_setoptions.test \
strace-f.test \
qual_syscall.test \
+ scm_rights-fd.test \
sigaction.test \
stat.test \
net.test \
--- /dev/null
+#!/bin/sh
+
+# Check how SCM_RIGHTS control messages are decoded in -y mode.
+
+. "${srcdir=.}/init.sh"
+
+# strace -y is implemented using /proc/$pid/fd
+[ -d /proc/self/fd/ ] ||
+ framework_skip_ '/proc/self/fd/ is not available'
+
+check_prog grep
+check_prog rm
+
+rm -f $LOG.*
+
+./scm_rights ||
+ fail_ 'scm_rights failed'
+
+args="-tt -ff -y -xx -enetwork -o $LOG ./scm_rights"
+$STRACE $args ||
+ fail_ "$STRACE $args failed"
+
+"$srcdir"/../strace-log-merge $LOG > $LOG || {
+ cat $LOG
+ fail_ 'strace-log-merge failed'
+}
+rm -f $LOG.*
+
+grep_log()
+{
+ local syscall="$1"; shift
+ local prefix='[1-9][0-9]* +[0-9]+:[0-9]+:[0-9]+\.[0-9]+ +'
+
+ LC_ALL=C grep -E -x "$prefix$syscall$*" $LOG > /dev/null || {
+ cat $LOG
+ fail_ "$STRACE $args failed to trace \"$syscall\" properly"
+ }
+}
+
+grep_log sendmsg '\(1<socket:\[[0-9]+\]>, \{msg_name\(0\)=NULL, msg_iov\(1\)=\[\{"\\x03\\x00\\x00\\x00[^"]*", [1-9][0-9]*\}\], msg_controllen=[1-9][0-9]*, \{cmsg_len=[1-9][0-9]*, cmsg_level=SOL_SOCKET, cmsg_type=SCM_RIGHTS, \{3</dev/null>\}\}, msg_flags=0\}, 0\) += [1-9][0-9]*'
+grep_log recvmsg '\(0<socket:\[[0-9]+\]>, \{msg_name\(0\)=NULL, msg_iov\(1\)=\[\{"\\x03\\x00\\x00\\x00[^"]*", [1-9][0-9]*\}\], msg_controllen=[1-9][0-9]*, \{cmsg_len=[1-9][0-9]*, cmsg_level=SOL_SOCKET, cmsg_type=SCM_RIGHTS, \{3</dev/null>\}\}, msg_flags=0\}, 0\) += [1-9][0-9]*'
+
+exit 0
--- /dev/null
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+
+int main(void)
+{
+ union {
+ struct cmsghdr cmsghdr;
+ char buf[CMSG_SPACE(sizeof(int))];
+ } control = {};
+
+ int fd;
+ struct iovec iov = {
+ .iov_base = &fd,
+ .iov_len = sizeof(iov)
+ };
+
+ struct msghdr mh = {
+ .msg_iov = &iov,
+ .msg_iovlen = 1,
+ .msg_control = &control,
+ .msg_controllen = sizeof(control)
+ };
+
+ while ((fd = open("/dev/null", O_RDWR)) < 3)
+ assert(fd >= 0);
+ (void) close(3);
+
+ int sv[2];
+ assert(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == 0);
+
+ pid_t pid = fork();
+ assert(pid >= 0);
+
+ if (pid) {
+ assert(close(sv[0]) == 0);
+ assert(dup2(sv[1], 1) == 1);
+ assert(close(sv[1]) == 0);
+
+ assert((fd = open("/dev/null", O_RDWR)) == 3);
+
+ struct cmsghdr *cmsg = CMSG_FIRSTHDR(&mh);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN(sizeof fd);
+ memcpy(CMSG_DATA(cmsg), &fd, sizeof fd);
+ mh.msg_controllen = cmsg->cmsg_len;
+
+ assert(sendmsg(1, &mh, 0) == sizeof(iov));
+ assert(close(1) == 0);
+
+ int status;
+ assert(waitpid(pid, &status, 0) == pid);
+ assert(status == 0);
+ } else {
+ assert(close(sv[1]) == 0);
+ assert(dup2(sv[0], 0) == 0);
+ assert(close(sv[0]) == 0);
+
+ assert(recvmsg(0, &mh, 0) == sizeof(iov));
+ assert(close(0) == 0);
+ }
+
+ return 0;
+}