1hdr,sys	poll,socket,netinet/in
2lib	select,poll,socket
3lib	htons,htonl sys/types.h sys/socket.h netinet/in.h
4lib	getaddrinfo sys/types.h sys/socket.h netdb.h
5typ	fd_set sys/socket.h sys/select.h
6tst	pipe_socketpair note{ use socketpair() for peekable pipe() }end execute{
7	#include <ast.h>
8	#include <signal.h>
9	#include <sys/types.h>
10	#include <sys/socket.h>
11	#ifndef SHUT_RD
12	#define SHUT_RD		0
13	#endif
14	#ifndef SHUT_WR
15	#define SHUT_WR		1
16	#endif
17	static void handler(sig)
18	int	sig;
19	{
20		_exit(0);
21	}
22	int main()
23	{
24		int		n;
25		int		pfd[2];
26		int		sfd[2];
27		char		buf[256];
28		pid_t		pid;
29		static char	msg[] = "hello world\n";
30		close(0);
31		if (pipe(pfd) < 0 ||
32		    socketpair(AF_UNIX, SOCK_STREAM, 0, sfd) < 0 ||
33		    shutdown(sfd[1], SHUT_RD) < 0 ||
34		    shutdown(sfd[0], SHUT_WR) < 0)
35			return(1);
36		if ((pid = fork()) < 0)
37			return(1);
38		if (pid)
39		{
40			close(pfd[1]);
41			close(sfd[1]);
42			wait(&n);
43			if (sfpkrd(pfd[0], buf, sizeof(buf), '\n', -1, 1) >= 0 ||
44			    sfpkrd(sfd[0], buf, sizeof(buf), '\n', -1, 1) < 0)
45				return(1);
46		}
47		else
48		{
49			close(pfd[0]);
50			close(sfd[0]);
51			write(pfd[1], msg, sizeof(msg) - 1);
52			write(sfd[1], msg, sizeof(msg) - 1);
53			return(0);
54		}
55		close(pfd[0]);
56		close(sfd[0]);
57		signal(SIGPIPE, handler);
58		if (socketpair(AF_UNIX, SOCK_STREAM, 0, sfd) < 0 ||
59		    shutdown(sfd[1], SHUT_RD) < 0 ||
60		    shutdown(sfd[0], SHUT_WR) < 0)
61			return(1);
62		close(sfd[0]);
63		write(sfd[1], msg, sizeof(msg) - 1);
64		return(1);
65	}
66}end
67tst	socketpair_devfd note{ /dev/fd/N handles socketpair() }end execute{
68	#include <ast.h>
69	#include <fs3d.h>
70	#include <sys/types.h>
71	#include <sys/socket.h>
72	int main()
73	{
74		int		devfd;
75		int		n;
76		int		sfd[2];
77		fs3d(FS3D_OFF);
78		close(0);
79		open("/dev/null", O_RDONLY);
80		if ((n = open("/dev/fd/0", O_RDONLY)) < 0)
81			return(1);
82		close(n);
83		if (socketpair(AF_UNIX, SOCK_STREAM, 0, sfd) < 0 ||
84		    shutdown(sfd[0], 1) < 0 ||
85		    shutdown(sfd[1], 0) < 0)
86			return(1);
87		close(0);
88		dup(sfd[0]);
89		close(sfd[0]);
90		if ((n = open("/dev/fd/0", O_RDONLY)) < 0)
91			return(1);
92		return(0);
93	}
94}end
95tst	socketpair_shutdown_mode note{ fchmod() after socketpair() shutdown() }end execute{
96	#include <ast.h>
97	#include <sys/types.h>
98	#include <sys/stat.h>
99	#include <sys/socket.h>
100	int main()
101	{
102		int		sfd[2];
103		struct stat	st0;
104		struct stat	st1;
105		if (socketpair(AF_UNIX, SOCK_STREAM, 0, sfd) < 0 ||
106		    shutdown(sfd[0], 1) < 0 ||
107		    shutdown(sfd[1], 0) < 0)
108			return(1);
109		if (fstat(sfd[0], &st0) < 0 || fstat(sfd[1], &st1) < 0)
110			return(1);
111		if ((st0.st_mode & (S_IRUSR|S_IWUSR)) == S_IRUSR &&
112		    (st1.st_mode & (S_IRUSR|S_IWUSR)) == S_IWUSR)
113			return(1);
114		if (fchmod(sfd[0], S_IRUSR) < 0 ||
115		    fstat(sfd[0], &st0) < 0 ||
116		    (st0.st_mode & (S_IRUSR|S_IWUSR)) != S_IRUSR)
117			return(1);
118		if (fchmod(sfd[1], S_IWUSR) < 0 ||
119		    fstat(sfd[1], &st1) < 0 ||
120		    (st1.st_mode & (S_IRUSR|S_IWUSR)) != S_IWUSR)
121			return(1);
122		return(0);
123	}
124}end
125cat{
126	#pragma prototyped
127	#ifdef _lib_poll
128	#   define poll _SYS_poll
129	#else
130	#   undef _hdr_poll
131	#   undef _sys_poll
132	#endif /* _lib_poll */
133	#ifdef _hdr_poll
134	#    include    <poll.h>
135	#else
136	#   ifdef _sys_poll
137	#	include    <sys/poll.h>
138	#   endif /* _sys_poll */
139	#endif /* _hdr_poll */
140	#ifdef _lib_poll
141	#   undef poll
142	    extern int poll(struct pollfd*,unsigned long,int);
143	#endif /* _lib_poll */
144	#ifdef _lib_select
145	#   ifndef FD_ZERO
146	#	define FD_ZERO(x)	(*(x)=0)
147	#   endif /* FD_ZERO */
148	#   ifndef FD_SET
149	#	define FD_SET(n,x)	(*(x)|=(1L<<(n)))
150	#   endif /* FD_SET */
151	#   ifndef _typ_fd_set
152		typedef long fd_set;
153	#   endif /*_typ_fd_set */
154	#endif /* _lib_select */
155}end
156