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