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