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