File Index
Files and directories
Sign in
FILE

scm_inq.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/net/af_unix/scm_inq.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/* Copyright 2025 Google LLC */
  3
  4#include <linux/sockios.h>
  5#include <sys/ioctl.h>
  6#include <sys/socket.h>
  7#include <sys/types.h>
  8
  9#include "kselftest_harness.h"
 10
 11#define NR_CHUNKS	100
 12#define MSG_LEN		256
 13
 14FIXTURE(scm_inq)
 15{
 16	int fd[2];
 17};
 18
 19FIXTURE_VARIANT(scm_inq)
 20{
 21	int type;
 22};
 23
 24FIXTURE_VARIANT_ADD(scm_inq, stream)
 25{
 26	.type = SOCK_STREAM,
 27};
 28
 29FIXTURE_VARIANT_ADD(scm_inq, dgram)
 30{
 31	.type = SOCK_DGRAM,
 32};
 33
 34FIXTURE_VARIANT_ADD(scm_inq, seqpacket)
 35{
 36	.type = SOCK_SEQPACKET,
 37};
 38
 39FIXTURE_SETUP(scm_inq)
 40{
 41	int err;
 42
 43	err = socketpair(AF_UNIX, variant->type | SOCK_NONBLOCK, 0, self->fd);
 44	ASSERT_EQ(0, err);
 45}
 46
 47FIXTURE_TEARDOWN(scm_inq)
 48{
 49	close(self->fd[0]);
 50	close(self->fd[1]);
 51}
 52
 53static void send_chunks(struct __test_metadata *_metadata,
 54			FIXTURE_DATA(scm_inq) *self)
 55{
 56	char buf[MSG_LEN] = {};
 57	int i, ret;
 58
 59	for (i = 0; i < NR_CHUNKS; i++) {
 60		ret = send(self->fd[0], buf, sizeof(buf), 0);
 61		ASSERT_EQ(sizeof(buf), ret);
 62	}
 63}
 64
 65static void recv_chunks(struct __test_metadata *_metadata,
 66			FIXTURE_DATA(scm_inq) *self)
 67{
 68	char cmsg_buf[CMSG_SPACE(sizeof(int))];
 69	struct msghdr msg = {};
 70	struct iovec iov = {};
 71	struct cmsghdr *cmsg;
 72	char buf[MSG_LEN];
 73	int i, ret;
 74	int inq;
 75
 76	msg.msg_iov = &iov;
 77	msg.msg_iovlen = 1;
 78	msg.msg_control = cmsg_buf;
 79	msg.msg_controllen = sizeof(cmsg_buf);
 80
 81	iov.iov_base = buf;
 82	iov.iov_len = sizeof(buf);
 83
 84	for (i = 0; i < NR_CHUNKS; i++) {
 85		memset(buf, 0, sizeof(buf));
 86		memset(cmsg_buf, 0, sizeof(cmsg_buf));
 87
 88		ret = recvmsg(self->fd[1], &msg, 0);
 89		ASSERT_EQ(MSG_LEN, ret);
 90
 91		cmsg = CMSG_FIRSTHDR(&msg);
 92		ASSERT_NE(NULL, cmsg);
 93		ASSERT_EQ(CMSG_LEN(sizeof(int)), cmsg->cmsg_len);
 94		ASSERT_EQ(SOL_SOCKET, cmsg->cmsg_level);
 95		ASSERT_EQ(SCM_INQ, cmsg->cmsg_type);
 96
 97		ret = ioctl(self->fd[1], SIOCINQ, &inq);
 98		ASSERT_EQ(0, ret);
 99		ASSERT_EQ(*(int *)CMSG_DATA(cmsg), inq);
100	}
101}
102
103TEST_F(scm_inq, basic)
104{
105	int err, inq;
106
107	err = setsockopt(self->fd[1], SOL_SOCKET, SO_INQ, &(int){1}, sizeof(int));
108	if (variant->type != SOCK_STREAM) {
109		ASSERT_EQ(-ENOPROTOOPT, -errno);
110		return;
111	}
112
113	ASSERT_EQ(0, err);
114
115	err = ioctl(self->fd[1], SIOCINQ, &inq);
116	ASSERT_EQ(0, err);
117	ASSERT_EQ(0, inq);
118
119	send_chunks(_metadata, self);
120	recv_chunks(_metadata, self);
121}
122
123TEST_HARNESS_MAIN
~/ Read-only file preview.