1314001f0SRao Shoaib // SPDX-License-Identifier: GPL-2.0-or-later
2314001f0SRao Shoaib #include <stdio.h>
3314001f0SRao Shoaib #include <stdlib.h>
4314001f0SRao Shoaib #include <sys/socket.h>
5314001f0SRao Shoaib #include <arpa/inet.h>
6314001f0SRao Shoaib #include <unistd.h>
7314001f0SRao Shoaib #include <string.h>
8314001f0SRao Shoaib #include <fcntl.h>
9314001f0SRao Shoaib #include <sys/ioctl.h>
10314001f0SRao Shoaib #include <errno.h>
11314001f0SRao Shoaib #include <netinet/tcp.h>
12314001f0SRao Shoaib #include <sys/un.h>
13314001f0SRao Shoaib #include <sys/signal.h>
14314001f0SRao Shoaib #include <sys/poll.h>
15314001f0SRao Shoaib 
16314001f0SRao Shoaib static int pipefd[2];
17314001f0SRao Shoaib static int signal_recvd;
18314001f0SRao Shoaib static pid_t producer_id;
19314001f0SRao Shoaib static char sock_name[32];
20314001f0SRao Shoaib 
sig_hand(int sn,siginfo_t * si,void * p)21314001f0SRao Shoaib static void sig_hand(int sn, siginfo_t *si, void *p)
22314001f0SRao Shoaib {
23314001f0SRao Shoaib 	signal_recvd = sn;
24314001f0SRao Shoaib }
25314001f0SRao Shoaib 
set_sig_handler(int signal)26314001f0SRao Shoaib static int set_sig_handler(int signal)
27314001f0SRao Shoaib {
28314001f0SRao Shoaib 	struct sigaction sa;
29314001f0SRao Shoaib 
30314001f0SRao Shoaib 	sa.sa_sigaction = sig_hand;
31314001f0SRao Shoaib 	sigemptyset(&sa.sa_mask);
32314001f0SRao Shoaib 	sa.sa_flags = SA_SIGINFO | SA_RESTART;
33314001f0SRao Shoaib 
34314001f0SRao Shoaib 	return sigaction(signal, &sa, NULL);
35314001f0SRao Shoaib }
36314001f0SRao Shoaib 
set_filemode(int fd,int set)37314001f0SRao Shoaib static void set_filemode(int fd, int set)
38314001f0SRao Shoaib {
39314001f0SRao Shoaib 	int flags = fcntl(fd, F_GETFL, 0);
40314001f0SRao Shoaib 
41314001f0SRao Shoaib 	if (set)
42314001f0SRao Shoaib 		flags &= ~O_NONBLOCK;
43314001f0SRao Shoaib 	else
44314001f0SRao Shoaib 		flags |= O_NONBLOCK;
45314001f0SRao Shoaib 	fcntl(fd, F_SETFL, flags);
46314001f0SRao Shoaib }
47314001f0SRao Shoaib 
signal_producer(int fd)48314001f0SRao Shoaib static void signal_producer(int fd)
49314001f0SRao Shoaib {
50314001f0SRao Shoaib 	char cmd;
51314001f0SRao Shoaib 
52314001f0SRao Shoaib 	cmd = 'S';
53314001f0SRao Shoaib 	write(fd, &cmd, sizeof(cmd));
54314001f0SRao Shoaib }
55314001f0SRao Shoaib 
wait_for_signal(int fd)56314001f0SRao Shoaib static void wait_for_signal(int fd)
57314001f0SRao Shoaib {
58314001f0SRao Shoaib 	char buf[5];
59314001f0SRao Shoaib 
60314001f0SRao Shoaib 	read(fd, buf, 5);
61314001f0SRao Shoaib }
62314001f0SRao Shoaib 
die(int status)63314001f0SRao Shoaib static void die(int status)
64314001f0SRao Shoaib {
65314001f0SRao Shoaib 	fflush(NULL);
66314001f0SRao Shoaib 	unlink(sock_name);
67314001f0SRao Shoaib 	kill(producer_id, SIGTERM);
68314001f0SRao Shoaib 	exit(status);
69314001f0SRao Shoaib }
70314001f0SRao Shoaib 
is_sioctatmark(int fd)71314001f0SRao Shoaib int is_sioctatmark(int fd)
72314001f0SRao Shoaib {
73314001f0SRao Shoaib 	int ans = -1;
74314001f0SRao Shoaib 
75314001f0SRao Shoaib 	if (ioctl(fd, SIOCATMARK, &ans, sizeof(ans)) < 0) {
76314001f0SRao Shoaib #ifdef DEBUG
77314001f0SRao Shoaib 		perror("SIOCATMARK Failed");
78314001f0SRao Shoaib #endif
79314001f0SRao Shoaib 	}
80314001f0SRao Shoaib 	return ans;
81314001f0SRao Shoaib }
82314001f0SRao Shoaib 
read_oob(int fd,char * c)83314001f0SRao Shoaib void read_oob(int fd, char *c)
84314001f0SRao Shoaib {
85314001f0SRao Shoaib 
86314001f0SRao Shoaib 	*c = ' ';
87314001f0SRao Shoaib 	if (recv(fd, c, sizeof(*c), MSG_OOB) < 0) {
88314001f0SRao Shoaib #ifdef DEBUG
89314001f0SRao Shoaib 		perror("Reading MSG_OOB Failed");
90314001f0SRao Shoaib #endif
91314001f0SRao Shoaib 	}
92314001f0SRao Shoaib }
93314001f0SRao Shoaib 
read_data(int pfd,char * buf,int size)94314001f0SRao Shoaib int read_data(int pfd, char *buf, int size)
95314001f0SRao Shoaib {
96314001f0SRao Shoaib 	int len = 0;
97314001f0SRao Shoaib 
98314001f0SRao Shoaib 	memset(buf, size, '0');
99314001f0SRao Shoaib 	len = read(pfd, buf, size);
100314001f0SRao Shoaib #ifdef DEBUG
101314001f0SRao Shoaib 	if (len < 0)
102314001f0SRao Shoaib 		perror("read failed");
103314001f0SRao Shoaib #endif
104314001f0SRao Shoaib 	return len;
105314001f0SRao Shoaib }
106314001f0SRao Shoaib 
wait_for_data(int pfd,int event)107314001f0SRao Shoaib static void wait_for_data(int pfd, int event)
108314001f0SRao Shoaib {
109314001f0SRao Shoaib 	struct pollfd pfds[1];
110314001f0SRao Shoaib 
111314001f0SRao Shoaib 	pfds[0].fd = pfd;
112314001f0SRao Shoaib 	pfds[0].events = event;
113314001f0SRao Shoaib 	poll(pfds, 1, -1);
114314001f0SRao Shoaib }
115314001f0SRao Shoaib 
producer(struct sockaddr_un * consumer_addr)116314001f0SRao Shoaib void producer(struct sockaddr_un *consumer_addr)
117314001f0SRao Shoaib {
118314001f0SRao Shoaib 	int cfd;
119314001f0SRao Shoaib 	char buf[64];
120314001f0SRao Shoaib 	int i;
121314001f0SRao Shoaib 
122314001f0SRao Shoaib 	memset(buf, 'x', sizeof(buf));
123314001f0SRao Shoaib 	cfd = socket(AF_UNIX, SOCK_STREAM, 0);
124314001f0SRao Shoaib 
125314001f0SRao Shoaib 	wait_for_signal(pipefd[0]);
126314001f0SRao Shoaib 	if (connect(cfd, (struct sockaddr *)consumer_addr,
127*7d6ceeb1SMirsad Goran Todorovac 		     sizeof(*consumer_addr)) != 0) {
128314001f0SRao Shoaib 		perror("Connect failed");
129314001f0SRao Shoaib 		kill(0, SIGTERM);
130314001f0SRao Shoaib 		exit(1);
131314001f0SRao Shoaib 	}
132314001f0SRao Shoaib 
133314001f0SRao Shoaib 	for (i = 0; i < 2; i++) {
134314001f0SRao Shoaib 		/* Test 1: Test for SIGURG and OOB */
135314001f0SRao Shoaib 		wait_for_signal(pipefd[0]);
136314001f0SRao Shoaib 		memset(buf, 'x', sizeof(buf));
137314001f0SRao Shoaib 		buf[63] = '@';
138314001f0SRao Shoaib 		send(cfd, buf, sizeof(buf), MSG_OOB);
139314001f0SRao Shoaib 
140314001f0SRao Shoaib 		wait_for_signal(pipefd[0]);
141314001f0SRao Shoaib 
142314001f0SRao Shoaib 		/* Test 2: Test for OOB being overwitten */
143314001f0SRao Shoaib 		memset(buf, 'x', sizeof(buf));
144314001f0SRao Shoaib 		buf[63] = '%';
145314001f0SRao Shoaib 		send(cfd, buf, sizeof(buf), MSG_OOB);
146314001f0SRao Shoaib 
147314001f0SRao Shoaib 		memset(buf, 'x', sizeof(buf));
148314001f0SRao Shoaib 		buf[63] = '#';
149314001f0SRao Shoaib 		send(cfd, buf, sizeof(buf), MSG_OOB);
150314001f0SRao Shoaib 
151314001f0SRao Shoaib 		wait_for_signal(pipefd[0]);
152314001f0SRao Shoaib 
153314001f0SRao Shoaib 		/* Test 3: Test for SIOCATMARK */
154314001f0SRao Shoaib 		memset(buf, 'x', sizeof(buf));
155314001f0SRao Shoaib 		buf[63] = '@';
156314001f0SRao Shoaib 		send(cfd, buf, sizeof(buf), MSG_OOB);
157314001f0SRao Shoaib 
158314001f0SRao Shoaib 		memset(buf, 'x', sizeof(buf));
159314001f0SRao Shoaib 		buf[63] = '%';
160314001f0SRao Shoaib 		send(cfd, buf, sizeof(buf), MSG_OOB);
161314001f0SRao Shoaib 
162314001f0SRao Shoaib 		memset(buf, 'x', sizeof(buf));
163314001f0SRao Shoaib 		send(cfd, buf, sizeof(buf), 0);
164314001f0SRao Shoaib 
165314001f0SRao Shoaib 		wait_for_signal(pipefd[0]);
166314001f0SRao Shoaib 
167314001f0SRao Shoaib 		/* Test 4: Test for 1byte OOB msg */
168314001f0SRao Shoaib 		memset(buf, 'x', sizeof(buf));
169314001f0SRao Shoaib 		buf[0] = '@';
170314001f0SRao Shoaib 		send(cfd, buf, 1, MSG_OOB);
171314001f0SRao Shoaib 	}
172314001f0SRao Shoaib }
173314001f0SRao Shoaib 
174314001f0SRao Shoaib int
main(int argc,char ** argv)175314001f0SRao Shoaib main(int argc, char **argv)
176314001f0SRao Shoaib {
177314001f0SRao Shoaib 	int lfd, pfd;
178314001f0SRao Shoaib 	struct sockaddr_un consumer_addr, paddr;
179314001f0SRao Shoaib 	socklen_t len = sizeof(consumer_addr);
180314001f0SRao Shoaib 	char buf[1024];
181314001f0SRao Shoaib 	int on = 0;
182314001f0SRao Shoaib 	char oob;
183314001f0SRao Shoaib 	int flags;
184314001f0SRao Shoaib 	int atmark;
185314001f0SRao Shoaib 	char *tmp_file;
186314001f0SRao Shoaib 
187314001f0SRao Shoaib 	lfd = socket(AF_UNIX, SOCK_STREAM, 0);
188314001f0SRao Shoaib 	memset(&consumer_addr, 0, sizeof(consumer_addr));
189314001f0SRao Shoaib 	consumer_addr.sun_family = AF_UNIX;
190314001f0SRao Shoaib 	sprintf(sock_name, "unix_oob_%d", getpid());
191314001f0SRao Shoaib 	unlink(sock_name);
192314001f0SRao Shoaib 	strcpy(consumer_addr.sun_path, sock_name);
193314001f0SRao Shoaib 
194314001f0SRao Shoaib 	if ((bind(lfd, (struct sockaddr *)&consumer_addr,
195314001f0SRao Shoaib 		  sizeof(consumer_addr))) != 0) {
196314001f0SRao Shoaib 		perror("socket bind failed");
197314001f0SRao Shoaib 		exit(1);
198314001f0SRao Shoaib 	}
199314001f0SRao Shoaib 
200314001f0SRao Shoaib 	pipe(pipefd);
201314001f0SRao Shoaib 
202314001f0SRao Shoaib 	listen(lfd, 1);
203314001f0SRao Shoaib 
204314001f0SRao Shoaib 	producer_id = fork();
205314001f0SRao Shoaib 	if (producer_id == 0) {
206314001f0SRao Shoaib 		producer(&consumer_addr);
207314001f0SRao Shoaib 		exit(0);
208314001f0SRao Shoaib 	}
209314001f0SRao Shoaib 
210314001f0SRao Shoaib 	set_sig_handler(SIGURG);
211314001f0SRao Shoaib 	signal_producer(pipefd[1]);
212314001f0SRao Shoaib 
213314001f0SRao Shoaib 	pfd = accept(lfd, (struct sockaddr *) &paddr, &len);
214314001f0SRao Shoaib 	fcntl(pfd, F_SETOWN, getpid());
215314001f0SRao Shoaib 
216314001f0SRao Shoaib 	signal_recvd = 0;
217314001f0SRao Shoaib 	signal_producer(pipefd[1]);
218314001f0SRao Shoaib 
219314001f0SRao Shoaib 	/* Test 1:
220314001f0SRao Shoaib 	 * veriyf that SIGURG is
221d9a232d4SKuniyuki Iwashima 	 * delivered, 63 bytes are
222d9a232d4SKuniyuki Iwashima 	 * read, oob is '@', and POLLPRI works.
223314001f0SRao Shoaib 	 */
224d9a232d4SKuniyuki Iwashima 	wait_for_data(pfd, POLLPRI);
225314001f0SRao Shoaib 	read_oob(pfd, &oob);
226314001f0SRao Shoaib 	len = read_data(pfd, buf, 1024);
227314001f0SRao Shoaib 	if (!signal_recvd || len != 63 || oob != '@') {
228314001f0SRao Shoaib 		fprintf(stderr, "Test 1 failed sigurg %d len %d %c\n",
229314001f0SRao Shoaib 			 signal_recvd, len, oob);
230314001f0SRao Shoaib 			die(1);
231314001f0SRao Shoaib 	}
232314001f0SRao Shoaib 
233314001f0SRao Shoaib 	signal_recvd = 0;
234314001f0SRao Shoaib 	signal_producer(pipefd[1]);
235314001f0SRao Shoaib 
236314001f0SRao Shoaib 	/* Test 2:
237314001f0SRao Shoaib 	 * Verify that the first OOB is over written by
238314001f0SRao Shoaib 	 * the 2nd one and the first OOB is returned as
239314001f0SRao Shoaib 	 * part of the read, and sigurg is received.
240314001f0SRao Shoaib 	 */
241314001f0SRao Shoaib 	wait_for_data(pfd, POLLIN | POLLPRI);
242314001f0SRao Shoaib 	len = 0;
243314001f0SRao Shoaib 	while (len < 70)
244314001f0SRao Shoaib 		len = recv(pfd, buf, 1024, MSG_PEEK);
245314001f0SRao Shoaib 	len = read_data(pfd, buf, 1024);
246314001f0SRao Shoaib 	read_oob(pfd, &oob);
247314001f0SRao Shoaib 	if (!signal_recvd || len != 127 || oob != '#') {
248314001f0SRao Shoaib 		fprintf(stderr, "Test 2 failed, sigurg %d len %d OOB %c\n",
249314001f0SRao Shoaib 		signal_recvd, len, oob);
250314001f0SRao Shoaib 		die(1);
251314001f0SRao Shoaib 	}
252314001f0SRao Shoaib 
253314001f0SRao Shoaib 	signal_recvd = 0;
254314001f0SRao Shoaib 	signal_producer(pipefd[1]);
255314001f0SRao Shoaib 
256314001f0SRao Shoaib 	/* Test 3:
257314001f0SRao Shoaib 	 * verify that 2nd oob over writes
258314001f0SRao Shoaib 	 * the first one and read breaks at
259314001f0SRao Shoaib 	 * oob boundary returning 127 bytes
260314001f0SRao Shoaib 	 * and sigurg is received and atmark
261314001f0SRao Shoaib 	 * is set.
262314001f0SRao Shoaib 	 * oob is '%' and second read returns
263314001f0SRao Shoaib 	 * 64 bytes.
264314001f0SRao Shoaib 	 */
265314001f0SRao Shoaib 	len = 0;
266314001f0SRao Shoaib 	wait_for_data(pfd, POLLIN | POLLPRI);
267314001f0SRao Shoaib 	while (len < 150)
268314001f0SRao Shoaib 		len = recv(pfd, buf, 1024, MSG_PEEK);
269314001f0SRao Shoaib 	len = read_data(pfd, buf, 1024);
270314001f0SRao Shoaib 	atmark = is_sioctatmark(pfd);
271314001f0SRao Shoaib 	read_oob(pfd, &oob);
272314001f0SRao Shoaib 
273314001f0SRao Shoaib 	if (!signal_recvd || len != 127 || oob != '%' || atmark != 1) {
27448514a22SShuah Khan 		fprintf(stderr,
27548514a22SShuah Khan 			"Test 3 failed, sigurg %d len %d OOB %c atmark %d\n",
27648514a22SShuah Khan 			signal_recvd, len, oob, atmark);
277314001f0SRao Shoaib 		die(1);
278314001f0SRao Shoaib 	}
279314001f0SRao Shoaib 
280314001f0SRao Shoaib 	signal_recvd = 0;
281314001f0SRao Shoaib 
282314001f0SRao Shoaib 	len = read_data(pfd, buf, 1024);
283314001f0SRao Shoaib 	if (len != 64) {
284314001f0SRao Shoaib 		fprintf(stderr, "Test 3.1 failed, sigurg %d len %d OOB %c\n",
285314001f0SRao Shoaib 			signal_recvd, len, oob);
286314001f0SRao Shoaib 		die(1);
287314001f0SRao Shoaib 	}
288314001f0SRao Shoaib 
289314001f0SRao Shoaib 	signal_recvd = 0;
290314001f0SRao Shoaib 	signal_producer(pipefd[1]);
291314001f0SRao Shoaib 
292314001f0SRao Shoaib 	/* Test 4:
293314001f0SRao Shoaib 	 * verify that a single byte
294314001f0SRao Shoaib 	 * oob message is delivered.
295314001f0SRao Shoaib 	 * set non blocking mode and
296314001f0SRao Shoaib 	 * check proper error is
297314001f0SRao Shoaib 	 * returned and sigurg is
298314001f0SRao Shoaib 	 * received and correct
299314001f0SRao Shoaib 	 * oob is read.
300314001f0SRao Shoaib 	 */
301314001f0SRao Shoaib 
302314001f0SRao Shoaib 	set_filemode(pfd, 0);
303314001f0SRao Shoaib 
304314001f0SRao Shoaib 	wait_for_data(pfd, POLLIN | POLLPRI);
305314001f0SRao Shoaib 	len = read_data(pfd, buf, 1024);
306314001f0SRao Shoaib 	if ((len == -1) && (errno == 11))
307314001f0SRao Shoaib 		len = 0;
308314001f0SRao Shoaib 
309314001f0SRao Shoaib 	read_oob(pfd, &oob);
310314001f0SRao Shoaib 
311314001f0SRao Shoaib 	if (!signal_recvd || len != 0 || oob != '@') {
312314001f0SRao Shoaib 		fprintf(stderr, "Test 4 failed, sigurg %d len %d OOB %c\n",
313314001f0SRao Shoaib 			 signal_recvd, len, oob);
314314001f0SRao Shoaib 		die(1);
315314001f0SRao Shoaib 	}
316314001f0SRao Shoaib 
317314001f0SRao Shoaib 	set_filemode(pfd, 1);
318314001f0SRao Shoaib 
319314001f0SRao Shoaib 	/* Inline Testing */
320314001f0SRao Shoaib 
321314001f0SRao Shoaib 	on = 1;
322314001f0SRao Shoaib 	if (setsockopt(pfd, SOL_SOCKET, SO_OOBINLINE, &on, sizeof(on))) {
323314001f0SRao Shoaib 		perror("SO_OOBINLINE");
324314001f0SRao Shoaib 		die(1);
325314001f0SRao Shoaib 	}
326314001f0SRao Shoaib 
327314001f0SRao Shoaib 	signal_recvd = 0;
328314001f0SRao Shoaib 	signal_producer(pipefd[1]);
329314001f0SRao Shoaib 
330314001f0SRao Shoaib 	/* Test 1 -- Inline:
331314001f0SRao Shoaib 	 * Check that SIGURG is
332314001f0SRao Shoaib 	 * delivered and 63 bytes are
333314001f0SRao Shoaib 	 * read and oob is '@'
334314001f0SRao Shoaib 	 */
335314001f0SRao Shoaib 
336314001f0SRao Shoaib 	wait_for_data(pfd, POLLIN | POLLPRI);
337314001f0SRao Shoaib 	len = read_data(pfd, buf, 1024);
338314001f0SRao Shoaib 
339314001f0SRao Shoaib 	if (!signal_recvd || len != 63) {
340314001f0SRao Shoaib 		fprintf(stderr, "Test 1 Inline failed, sigurg %d len %d\n",
341314001f0SRao Shoaib 			signal_recvd, len);
342314001f0SRao Shoaib 		die(1);
343314001f0SRao Shoaib 	}
344314001f0SRao Shoaib 
345314001f0SRao Shoaib 	len = read_data(pfd, buf, 1024);
346314001f0SRao Shoaib 
347314001f0SRao Shoaib 	if (len != 1) {
348314001f0SRao Shoaib 		fprintf(stderr,
349314001f0SRao Shoaib 			 "Test 1.1 Inline failed, sigurg %d len %d oob %c\n",
350314001f0SRao Shoaib 			 signal_recvd, len, oob);
351314001f0SRao Shoaib 		die(1);
352314001f0SRao Shoaib 	}
353314001f0SRao Shoaib 
354314001f0SRao Shoaib 	signal_recvd = 0;
355314001f0SRao Shoaib 	signal_producer(pipefd[1]);
356314001f0SRao Shoaib 
357314001f0SRao Shoaib 	/* Test 2 -- Inline:
358314001f0SRao Shoaib 	 * Verify that the first OOB is over written by
359314001f0SRao Shoaib 	 * the 2nd one and read breaks correctly on
360314001f0SRao Shoaib 	 * 2nd OOB boundary with the first OOB returned as
361314001f0SRao Shoaib 	 * part of the read, and sigurg is delivered and
362314001f0SRao Shoaib 	 * siocatmark returns true.
363314001f0SRao Shoaib 	 * next read returns one byte, the oob byte
364314001f0SRao Shoaib 	 * and siocatmark returns false.
365314001f0SRao Shoaib 	 */
366314001f0SRao Shoaib 	len = 0;
367314001f0SRao Shoaib 	wait_for_data(pfd, POLLIN | POLLPRI);
368314001f0SRao Shoaib 	while (len < 70)
369314001f0SRao Shoaib 		len = recv(pfd, buf, 1024, MSG_PEEK);
370314001f0SRao Shoaib 	len = read_data(pfd, buf, 1024);
371314001f0SRao Shoaib 	atmark = is_sioctatmark(pfd);
372314001f0SRao Shoaib 	if (len != 127 || atmark != 1 || !signal_recvd) {
373314001f0SRao Shoaib 		fprintf(stderr, "Test 2 Inline failed, len %d atmark %d\n",
374314001f0SRao Shoaib 			 len, atmark);
375314001f0SRao Shoaib 		die(1);
376314001f0SRao Shoaib 	}
377314001f0SRao Shoaib 
378314001f0SRao Shoaib 	len = read_data(pfd, buf, 1024);
379314001f0SRao Shoaib 	atmark = is_sioctatmark(pfd);
380314001f0SRao Shoaib 	if (len != 1 || buf[0] != '#' || atmark == 1) {
381314001f0SRao Shoaib 		fprintf(stderr, "Test 2.1 Inline failed, len %d data %c atmark %d\n",
382314001f0SRao Shoaib 			len, buf[0], atmark);
383314001f0SRao Shoaib 		die(1);
384314001f0SRao Shoaib 	}
385314001f0SRao Shoaib 
386314001f0SRao Shoaib 	signal_recvd = 0;
387314001f0SRao Shoaib 	signal_producer(pipefd[1]);
388314001f0SRao Shoaib 
389314001f0SRao Shoaib 	/* Test 3 -- Inline:
390314001f0SRao Shoaib 	 * verify that 2nd oob over writes
391314001f0SRao Shoaib 	 * the first one and read breaks at
392314001f0SRao Shoaib 	 * oob boundary returning 127 bytes
393314001f0SRao Shoaib 	 * and sigurg is received and siocatmark
394314001f0SRao Shoaib 	 * is true after the read.
395314001f0SRao Shoaib 	 * subsequent read returns 65 bytes
396314001f0SRao Shoaib 	 * because of oob which should be '%'.
397314001f0SRao Shoaib 	 */
398314001f0SRao Shoaib 	len = 0;
399314001f0SRao Shoaib 	wait_for_data(pfd, POLLIN | POLLPRI);
400314001f0SRao Shoaib 	while (len < 126)
401314001f0SRao Shoaib 		len = recv(pfd, buf, 1024, MSG_PEEK);
402314001f0SRao Shoaib 	len = read_data(pfd, buf, 1024);
403314001f0SRao Shoaib 	atmark = is_sioctatmark(pfd);
404314001f0SRao Shoaib 	if (!signal_recvd || len != 127 || !atmark) {
405314001f0SRao Shoaib 		fprintf(stderr,
406314001f0SRao Shoaib 			 "Test 3 Inline failed, sigurg %d len %d data %c\n",
407314001f0SRao Shoaib 			 signal_recvd, len, buf[0]);
408314001f0SRao Shoaib 		die(1);
409314001f0SRao Shoaib 	}
410314001f0SRao Shoaib 
411314001f0SRao Shoaib 	len = read_data(pfd, buf, 1024);
412314001f0SRao Shoaib 	atmark = is_sioctatmark(pfd);
413314001f0SRao Shoaib 	if (len != 65 || buf[0] != '%' || atmark != 0) {
414314001f0SRao Shoaib 		fprintf(stderr,
415314001f0SRao Shoaib 			 "Test 3.1 Inline failed, len %d oob %c atmark %d\n",
416314001f0SRao Shoaib 			 len, buf[0], atmark);
417314001f0SRao Shoaib 		die(1);
418314001f0SRao Shoaib 	}
419314001f0SRao Shoaib 
420314001f0SRao Shoaib 	signal_recvd = 0;
421314001f0SRao Shoaib 	signal_producer(pipefd[1]);
422314001f0SRao Shoaib 
423314001f0SRao Shoaib 	/* Test 4 -- Inline:
424314001f0SRao Shoaib 	 * verify that a single
425314001f0SRao Shoaib 	 * byte oob message is delivered
426314001f0SRao Shoaib 	 * and read returns one byte, the oob
427314001f0SRao Shoaib 	 * byte and sigurg is received
428314001f0SRao Shoaib 	 */
429314001f0SRao Shoaib 	wait_for_data(pfd, POLLIN | POLLPRI);
430314001f0SRao Shoaib 	len = read_data(pfd, buf, 1024);
431314001f0SRao Shoaib 	if (!signal_recvd || len != 1 || buf[0] != '@') {
432314001f0SRao Shoaib 		fprintf(stderr,
433314001f0SRao Shoaib 			"Test 4 Inline failed, signal %d len %d data %c\n",
434314001f0SRao Shoaib 		signal_recvd, len, buf[0]);
435314001f0SRao Shoaib 		die(1);
436314001f0SRao Shoaib 	}
437314001f0SRao Shoaib 	die(0);
438314001f0SRao Shoaib }
439