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