| Author | Tokens | Token Proportion | Commits | Commit Proportion |
|---|---|---|---|---|
| Kuniyuki Iwashima | 951 | 89.38% | 2 | 66.67% |
| Soichiro Ueda | 113 | 10.62% | 1 | 33.33% |
| Total | 1064 | 3 |
// SPDX-License-Identifier: GPL-2.0 /* Copyright 2025 Google LLC */ #include <stdlib.h> #include <unistd.h> #include <sys/socket.h> #include "../../kselftest_harness.h" FIXTURE(so_peek_off) { int fd[2]; /* 0: sender, 1: receiver */ }; FIXTURE_VARIANT(so_peek_off) { int type; }; FIXTURE_VARIANT_ADD(so_peek_off, stream) { .type = SOCK_STREAM, }; FIXTURE_VARIANT_ADD(so_peek_off, dgram) { .type = SOCK_DGRAM, }; FIXTURE_VARIANT_ADD(so_peek_off, seqpacket) { .type = SOCK_SEQPACKET, }; FIXTURE_SETUP(so_peek_off) { struct timeval timeout = { .tv_sec = 5, .tv_usec = 0, }; int ret; ret = socketpair(AF_UNIX, variant->type, 0, self->fd); ASSERT_EQ(0, ret); ret = setsockopt(self->fd[1], SOL_SOCKET, SO_RCVTIMEO_NEW, &timeout, sizeof(timeout)); ASSERT_EQ(0, ret); ret = setsockopt(self->fd[1], SOL_SOCKET, SO_PEEK_OFF, &(int){0}, sizeof(int)); ASSERT_EQ(0, ret); } FIXTURE_TEARDOWN(so_peek_off) { close_range(self->fd[0], self->fd[1], 0); } #define sendeq(fd, str, flags) \ do { \ int bytes, len = strlen(str); \ \ bytes = send(fd, str, len, flags); \ ASSERT_EQ(len, bytes); \ } while (0) #define recveq(fd, str, buflen, flags) \ do { \ char buf[(buflen) + 1] = {}; \ int bytes; \ \ bytes = recv(fd, buf, buflen, flags); \ ASSERT_NE(-1, bytes); \ ASSERT_STREQ(str, buf); \ } while (0) #define peekoffeq(fd, expected) \ do { \ socklen_t optlen = sizeof(int); \ int off = -1; \ int ret; \ \ ret = getsockopt(fd, SOL_SOCKET, SO_PEEK_OFF, \ &off, &optlen); \ ASSERT_EQ(0, ret); \ ASSERT_EQ((socklen_t)sizeof(off), optlen); \ ASSERT_EQ(expected, off); \ } while (0) #define async \ for (pid_t pid = (pid = fork(), \ pid < 0 ? \ __TH_LOG("Failed to start async {}"), \ _metadata->exit_code = KSFT_FAIL, \ __bail(1, _metadata), \ 0xdead : \ pid); \ !pid; exit(0)) TEST_F(so_peek_off, single_chunk) { sendeq(self->fd[0], "aaaabbbb", 0); recveq(self->fd[1], "aaaa", 4, MSG_PEEK); peekoffeq(self->fd[1], 4); recveq(self->fd[1], "bbbb", 100, MSG_PEEK); peekoffeq(self->fd[1], 8); recveq(self->fd[1], "aaaabbbb", 8, 0); peekoffeq(self->fd[1], 0); } TEST_F(so_peek_off, two_chunks) { sendeq(self->fd[0], "aaaa", 0); sendeq(self->fd[0], "bbbb", 0); recveq(self->fd[1], "aaaa", 4, MSG_PEEK); peekoffeq(self->fd[1], 4); recveq(self->fd[1], "bbbb", 100, MSG_PEEK); peekoffeq(self->fd[1], 8); recveq(self->fd[1], "aaaa", 4, 0); recveq(self->fd[1], "bbbb", 4, 0); peekoffeq(self->fd[1], 0); } TEST_F(so_peek_off, two_chunks_blocking) { async { usleep(1000); sendeq(self->fd[0], "aaaa", 0); } recveq(self->fd[1], "aaaa", 4, MSG_PEEK); peekoffeq(self->fd[1], 4); async { usleep(1000); sendeq(self->fd[0], "bbbb", 0); } /* goto again; -> goto redo; in unix_stream_read_generic(). */ recveq(self->fd[1], "bbbb", 100, MSG_PEEK); peekoffeq(self->fd[1], 8); recveq(self->fd[1], "aaaa", 4, 0); recveq(self->fd[1], "bbbb", 4, 0); peekoffeq(self->fd[1], 0); } TEST_F(so_peek_off, two_chunks_overlap) { sendeq(self->fd[0], "aaaa", 0); recveq(self->fd[1], "aa", 2, MSG_PEEK); peekoffeq(self->fd[1], 2); sendeq(self->fd[0], "bbbb", 0); if (variant->type == SOCK_STREAM) { /* SOCK_STREAM tries to fill the buffer. */ recveq(self->fd[1], "aabb", 4, MSG_PEEK); peekoffeq(self->fd[1], 6); recveq(self->fd[1], "bb", 100, MSG_PEEK); peekoffeq(self->fd[1], 8); } else { /* SOCK_DGRAM and SOCK_SEQPACKET returns at the skb boundary. */ recveq(self->fd[1], "aa", 100, MSG_PEEK); peekoffeq(self->fd[1], 4); recveq(self->fd[1], "bbbb", 100, MSG_PEEK); peekoffeq(self->fd[1], 8); } recveq(self->fd[1], "aaaa", 4, 0); recveq(self->fd[1], "bbbb", 4, 0); peekoffeq(self->fd[1], 0); } TEST_F(so_peek_off, two_chunks_overlap_blocking) { async { usleep(1000); sendeq(self->fd[0], "aaaa", 0); } recveq(self->fd[1], "aa", 2, MSG_PEEK); peekoffeq(self->fd[1], 2); async { usleep(1000); sendeq(self->fd[0], "bbbb", 0); } /* Even SOCK_STREAM does not wait if at least one byte is read. */ recveq(self->fd[1], "aa", 100, MSG_PEEK); peekoffeq(self->fd[1], 4); recveq(self->fd[1], "bbbb", 100, MSG_PEEK); peekoffeq(self->fd[1], 8); recveq(self->fd[1], "aaaa", 4, 0); recveq(self->fd[1], "bbbb", 4, 0); peekoffeq(self->fd[1], 0); } TEST_HARNESS_MAIN
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with Cregit http://github.com/cregit/cregit
Version 2.0-RC1