socktest.c revision 47653588a022190d4b3e20194ef643dfb7b90632
1b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly/*
2b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly** Copyright 2009 The Android Open Source Project
3b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly**
4b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly** Licensed under the Apache License, Version 2.0 (the "License");
5b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly** you may not use this file except in compliance with the License.
6b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly** You may obtain a copy of the License at
7b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly**
8b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly**     http://www.apache.org/licenses/LICENSE-2.0
9b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly**
10b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly** Unless required by applicable law or agreed to in writing, software
11b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly** distributed under the License is distributed on an "AS IS" BASIS,
12b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly** See the License for the specific language governing permissions and
14b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly** limitations under the License.
15b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly*/
16b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
17b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly/** socket testing  */
18b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
19b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <stdlib.h>
20b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <stdio.h>
21b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <errno.h>
22b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <sys/uio.h>
23b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <unistd.h>
24b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
25b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <pthread.h>
26b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <stdio.h>
27b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <stdlib.h>
28b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <errno.h>
29b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <unistd.h>
30b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <sys/socket.h>
31b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <sys/ioctl.h>
3247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly#include <sys/poll.h>
33b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <sys/un.h>
34b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <netinet/in.h>
35b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
36b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <bluetooth/bluetooth.h>
37b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <bluetooth/rfcomm.h>
38b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <bluetooth/sco.h>
39b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <bluetooth/l2cap.h>
40b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
41b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellyenum sock_type {
42b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    UNIX = 0,
43b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    RFCOMM,
44b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    SCO,
45b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    L2CAP,
46b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    TCP,
47b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly};
48b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
49b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystruct thread_args {
50b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int fd;
51b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int type;
523f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    int delay;
53b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly};
54b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
55b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystruct sockaddr_un  local_addr_un  = {AF_UNIX, "/data/foo"};
563f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pellystruct sockaddr_rc  local_addr_rc  = {AF_BLUETOOTH, *BDADDR_ANY, 4};
573f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pellystruct sockaddr_sco local_addr_sco = {AF_BLUETOOTH, *BDADDR_LOCAL};
58b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystruct sockaddr_l2  local_addr_l2  = {AF_BLUETOOTH, htobs(0x1001), *BDADDR_ANY, 0};
59b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystruct sockaddr_in  local_addr_in  = {AF_INET, 9999, {0}, {0}};
60b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
61b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystruct sockaddr_un  remote_addr_un  ;
62b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystruct sockaddr_rc  remote_addr_rc  ;
63b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystruct sockaddr_sco remote_addr_sco ;
64b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystruct sockaddr_l2  remote_addr_l2  ;
65b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystruct sockaddr_in  remote_addr_in  ;
66b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
6747653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic void print_events(int events) {
6847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (events & POLLIN) printf("POLLIN ");
6947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (events & POLLPRI) printf("POLLPRI ");
7047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (events & POLLOUT) printf("POLLOUT ");
7147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (events & POLLERR) printf("POLLERR ");
7247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (events & POLLHUP) printf("POLLHUP ");
7347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (events & POLLNVAL) printf("POLLNVAL ");
7447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("\n");
7547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
7647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
7747653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic void print_fds(struct pollfd *ufds, nfds_t nfds) {
7847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    unsigned int i;
7947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    for (i=0; i<nfds; i++)
8047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        printf("%d ", ufds[i].fd);
8147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
8247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
83b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystatic int _socket(int type) {
84b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int ret;
85b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int family = -1;
86b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int typ = -1;
87b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int protocol = -1;
88b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
89b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    switch (type) {
90b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case UNIX:
91b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        family = PF_UNIX;
92b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        typ = SOCK_STREAM;
93b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        protocol = 0;
94b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
95b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case RFCOMM:
96b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        family = PF_BLUETOOTH;
97b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        typ = SOCK_STREAM;
98b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        protocol = BTPROTO_RFCOMM;
99b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
100b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case SCO:
101b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        family = PF_BLUETOOTH;
102b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        typ = SOCK_SEQPACKET;
103b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        protocol = BTPROTO_SCO;
104b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
105b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case L2CAP:
106b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        family = PF_BLUETOOTH;
107b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        typ = SOCK_SEQPACKET;
108b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        protocol = BTPROTO_L2CAP;
109b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
110b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case TCP:
111b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        family = PF_INET;
112b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        typ = SOCK_STREAM;
113b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        protocol = 0;
114b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
115b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    }
116b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
117b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    printf("%d: socket()\n", gettid());
118b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    ret = socket(family, typ, protocol);
119b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    printf("%d: socket() = %d\n", gettid(), ret);
120b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
121b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
122b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    return ret;
123b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly}
124b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
125b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystatic int _close(int fd, int type) {
126b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int ret;
127b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
128b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    printf("%d: close(%d)\n", gettid(), fd);
129b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    ret = close(fd);
130b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    printf("%d: close(%d) = %d\n", gettid(), fd, ret);
131b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
132b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
133b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    return ret;
134b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly}
135b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
136b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystatic int _bind(int fd, int type) {
137b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int len = 0;
138b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int ret;
139b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    struct sockaddr *addr = NULL;
140b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
141b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    switch (type) {
142b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case UNIX:
143b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        unlink(local_addr_un.sun_path);
144b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        addr = (struct sockaddr *) &local_addr_un;
145b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        len = sizeof(local_addr_un);
146b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
147b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case RFCOMM:
148b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        addr = (struct sockaddr *) &local_addr_rc;
149b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        len = sizeof(local_addr_rc);
150b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
151b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case SCO:
152b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        addr = (struct sockaddr *) &local_addr_sco;
153b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        len = sizeof(local_addr_sco);
154b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
155b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case L2CAP:
156b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        addr = (struct sockaddr *) &local_addr_l2;
157b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        len = sizeof(local_addr_l2);
158b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
159b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case TCP:
160b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        addr = (struct sockaddr *) &local_addr_in;
161b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        len = sizeof(local_addr_in);
162b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
163b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    }
164b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
165b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    printf("%d: bind(%d)\n", gettid(), fd);
166b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    ret = bind(fd, addr, len);
167b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    printf("%d: bind(%d) = %d\n", gettid(), fd, ret);
168b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
169b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
170b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    return ret;
171b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly}
172b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
173b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystatic int _listen(int fd, int type) {
174b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int ret;
175b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
176b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    printf("%d: listen(%d)\n", gettid(), fd);
177b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    ret = listen(fd, 1);
178b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    printf("%d: listen(%d) = %d\n", gettid(), fd, ret);
179b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
180b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
181b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    return ret;
182b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly}
183b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
18447653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int _read(int fd) {
18547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int ret;
18647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    char buf;
18747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
18847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: read(%d)\n", gettid(), fd);
18947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    ret = read(fd, &buf, 1);
19047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: read(%d) = %d [%d]\n", gettid(), fd, ret, (int)buf);
19147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
19247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
19347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return ret;
19447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
19547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
19647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
197b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystatic int _accept(int fd, int type) {
198b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int ret;
199b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int len;
200b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    struct sockaddr *addr = NULL;
201b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
202b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    switch (type) {
203b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case UNIX:
204b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        addr = (struct sockaddr *) &remote_addr_un;
205b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        len = sizeof(remote_addr_un);
206b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
207b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case RFCOMM:
208b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        addr = (struct sockaddr *) &remote_addr_rc;
209b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        len = sizeof(remote_addr_rc);
210b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
211b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case SCO:
212b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        addr = (struct sockaddr *) &remote_addr_sco;
213b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        len = sizeof(remote_addr_sco);
214b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
215b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case L2CAP:
216b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        addr = (struct sockaddr *) &remote_addr_l2;
217b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        len = sizeof(remote_addr_l2);
218b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
219b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case TCP:
220b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        addr = (struct sockaddr *) &remote_addr_in;
221b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        len = sizeof(remote_addr_in);
222b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
223b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    }
224b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
225b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    printf("%d: accept(%d)\n", gettid(), fd);
226b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    ret = accept(fd, addr, &len);
227b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    printf("%d: accept(%d) = %d\n", gettid(), fd, ret);
228b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
229b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    else {
230b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        printf("\tlen = %d\n", len);
231b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    }
232b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
233b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    return ret;
234b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly}
235b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
236b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystatic int _connect(int fd, int type) {
237b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int ret;
2383f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    int len = 0;
239b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    struct sockaddr *addr = NULL;
240b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
241b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    switch (type) {
242b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case UNIX:
243b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        addr = (struct sockaddr *) &local_addr_un;
244b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        len = sizeof(local_addr_un);
245b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
246b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case RFCOMM:
247b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        addr = (struct sockaddr *) &local_addr_rc;
248b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        len = sizeof(local_addr_rc);
249b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
250b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case SCO:
251b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        addr = (struct sockaddr *) &local_addr_sco;
252b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        len = sizeof(local_addr_sco);
253b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
254b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case L2CAP:
255b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        addr = (struct sockaddr *) &local_addr_l2;
256b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        len = sizeof(local_addr_l2);
257b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
258b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case TCP:
259b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        addr = (struct sockaddr *) &local_addr_in;
260b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        len = sizeof(local_addr_in);
261b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
262b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    }
263b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
264b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    printf("%d: connect(%d)\n", gettid(), fd);
265b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    ret = connect(fd, addr, len);
266b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    printf("%d: connect(%d) = %d\n", gettid(), fd, ret);
267b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
268b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
269b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    return ret;
270b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly}
271b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
272b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystatic int _write(int fd, int type) {
273b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int ret;
27447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    char buf = 69;
275b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
276b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    printf("%d: write(%d)\n", gettid(), fd);
277b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    ret = write(fd, &buf, 1);
27847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: write(%d) = %d\n", gettid(), fd, ret);
27947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
28047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
28147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return ret;
28247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
28347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
28447653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int _shutdown(int fd, int how) {
28547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int ret;
28647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
28747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: shutdown(%d)\n", gettid(), fd);
28847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    ret = shutdown(fd, how);
28947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: shutdown(%d) = %d\n", gettid(), fd, ret);
290b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
291b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
292b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    return ret;
293b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly}
294b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
29547653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int _poll(struct pollfd *ufds, nfds_t nfds, int timeout) {
29647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int ret;
29747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    unsigned int i;
29847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
29947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: poll(", gettid());
30047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    print_fds(ufds, nfds);
30147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf(")\n");
30247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    ret = poll(ufds, nfds, timeout);
30347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: poll() = %d\n", gettid(), ret);
30447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
30547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (ret > 0) {
30647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        for (i=0; i<nfds; i++) {
30747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly            if (ufds[i].revents) {
30847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly                printf("\tfd %d ", ufds[i].fd); print_events(ufds[i].revents);
30947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly            }
31047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        }
31147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    }
31247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return ret;
31347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
31447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
3153f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pellystatic void thread_delay_close(struct thread_args *args) {
316b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    printf("%d: START\n", gettid());
3173f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    sleep(args->delay);
3183f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    _close(args->fd, args->type);
319b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    printf("%d: END\n", gettid());
320b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly}
321b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
32247653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic void thread_poll(void *args) {
32347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int fd = (int)args;
32447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    struct pollfd pfd;
32547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: START\n", gettid());
32647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pfd.fd = fd;
32747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pfd.events = 0;
32847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _poll(&pfd, 1, -1);
32947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: END\n", gettid());
33047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
33147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
33247653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic void thread_read(void *args) {
33347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int fd = (int)args;
33447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: START\n", gettid());
33547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _read(fd);
33647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: END\n", gettid());
33747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
33847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
33947653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic void thread_pollin(void *args) {
34047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int fd = (int)args;
34147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    struct pollfd pfd;
34247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: START\n", gettid());
34347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pfd.fd = fd;
34447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pfd.events = POLLIN;
34547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _poll(&pfd, 1, -1);
34647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: END\n", gettid());
34747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
34847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
34947653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic void thread_shutdown(int fd) {
35047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: START\n", gettid());
35147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    sleep(4);
35247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _shutdown(fd, SHUT_RDWR);
35347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: END\n", gettid());
35447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
35547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
35647653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic void thread_accept(struct thread_args *args) {
35747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: START\n", gettid());
35847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    sleep(args->delay);
35947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _accept(args->fd, args->type);
36047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: END\n", gettid());
36147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
36247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
36347653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic void thread_connect(struct thread_args *args) {
36447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: START\n", gettid());
36547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    sleep(args->delay);
36647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _connect(args->fd, args->type);
36747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: END\n", gettid());
36847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
36947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
3703f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pellystatic void thread_delay_close_write(struct thread_args *args) {
3713f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    printf("%d: START\n", gettid());
3723f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    sleep(args->delay);
3733f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    _close(args->fd, args->type);
3743f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    sleep(args->delay);
3753f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    _write(args->fd, args->type);
3763f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    printf("%d: END\n", gettid());
3773f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly}
378b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
37947653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic void thread_accept_write(struct thread_args *args) {
38047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: START\n", gettid());
38147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    sleep(args->delay);
38247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _accept(args->fd, args->type);
38347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    sleep(args->delay);
38447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _write(args->fd, args->type);
38547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: END\n", gettid());
38647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
38747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
3883f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pellystatic void thread_delay_connect(struct thread_args *args) {
389b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    printf("%d: START\n", gettid());
3903f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    sleep(args->delay);
3913f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    args->fd = _socket(args->type);
3923f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    _connect(args->fd, args->type);
393b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    printf("%d: END\n", gettid());
394b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly}
395b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
3963f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pellystatic int do_accept_accept_accept(int type) {
3973f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    int fd;
3983f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
3993f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    fd = _socket(type);
4003f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    if (fd < 0) goto error;
4013f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
4023f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    if (_bind(fd, type) < 0) goto error;
4033f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
4043f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    if (_listen(fd, type) < 0) goto error;
4053f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
4063f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    while (1) {
4073f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly        _accept(fd, type);
4083f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    }
4093f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
4103f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    return 0;
4113f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
4123f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pellyerror:
4133f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    return -1;
4143f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly}
4153f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
416b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystatic int do_accept_and_close(int type) {
417b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int fd;
418b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    pthread_t thread;
4193f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    struct thread_args args = {-1, type, 1};
420b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
421b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    fd = _socket(type);
422b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    if (fd < 0) goto error;
423b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
424b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    if (_bind(fd, type) < 0) goto error;
425b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
426b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    if (_listen(fd, type) < 0) goto error;
427b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
4283f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    args.fd = fd;
4293f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    pthread_create(&thread, NULL, (void *)thread_delay_close, (void *)&args);
430b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
431b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    _accept(fd, type);
432b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
433b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    pthread_join(thread, NULL);
434b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
435b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    return 0;
436b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
437b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellyerror:
438b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    return -1;
439b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly}
440b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
44147653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int do_accept_shutdown(int type) {
44247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int fd;
44347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_t thread;
44447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    struct thread_args args = {-1, type, 0};
44547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
44647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    fd = _socket(type);
44747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (fd < 0) goto error;
44847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
44947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (_bind(fd, type) < 0) goto error;
45047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
45147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (_listen(fd, type) < 0) goto error;
45247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
45347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    args.fd = fd;
45447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_create(&thread, NULL, (void *)thread_accept, (void *)&args);
45547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
45647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    sleep(4);
45747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _shutdown(fd, SHUT_RDWR);
45847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
45947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_join(thread, NULL);
46047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
46147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _close(fd, type);
46247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
46347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return 0;
46447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
46547653588a022190d4b3e20194ef643dfb7b90632Nick Pellyerror:
46647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return -1;
46747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
46847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
46947653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int do_connect_shutdown(int type) {
47047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int fd;
47147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_t thread;
47247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    struct thread_args args = {-1, type, 0};
47347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
47447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    fd = _socket(type);
47547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (fd < 0) goto error;
47647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
47747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    args.fd = fd;
47847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_create(&thread, NULL, (void *)thread_connect, (void *)&args);
47947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
48047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    sleep(4);
48147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _shutdown(fd, SHUT_RDWR);
48247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
48347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_join(thread, NULL);
48447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
48547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _close(fd, type);
48647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
48747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return 0;
48847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
48947653588a022190d4b3e20194ef643dfb7b90632Nick Pellyerror:
49047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return -1;
49147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
49247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
493b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly// accept in one thread. close then write in another
494b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystatic int do_accept_close_write(int type) {
495b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int fd;
496b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    pthread_t thread;
4973f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    struct thread_args args = {-1, type, 1};
498b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
499b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    fd = _socket(type);
500b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    if (fd < 0) goto error;
501b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
502b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    if (_bind(fd, type) < 0) goto error;
503b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
504b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    if (_listen(fd, type) < 0) goto error;
505b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
5063f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    args.fd = fd;
5073f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    pthread_create(&thread, NULL, (void *)thread_delay_close_write, (void *)&args);
508b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
509b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    _accept(fd, type);
510b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
511b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    pthread_join(thread, NULL);
512b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
513b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    return 0;
514b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
515b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellyerror:
516b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    return -1;
517b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly}
518b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
51947653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int do_poll_poll_poll_shutdown(int type) {
52047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    const int MAX_T = 32;
5213f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    int fd;
52247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_t t[MAX_T];
52347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int i;
52447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
52547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    fd = _socket(type);
52647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
52747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    for (i=0; i<MAX_T; i++)
52847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        pthread_create(&t[i], NULL, (void *)thread_poll, (void *)fd);
52947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
53047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    sleep(1);
53147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
53247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _shutdown(fd, SHUT_RDWR);
53347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
53447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    for (i=0; i<MAX_T; i++)
53547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        pthread_join(t[i], NULL);
53647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
53747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _close(fd, type);
53847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
53947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return 0;
54047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
54147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
54247653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int do_poll_poll_poll_close(int type) {
54347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    const int MAX_T = 32;
54447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int fd;
54547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_t t[MAX_T];
54647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int i;
5473f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
5483f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    fd = _socket(type);
5493f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
55047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    for (i=0; i<MAX_T; i++)
55147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        pthread_create(&t[i], NULL, (void *)thread_poll, (void *)fd);
5523f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
5533f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    sleep(1);
5543f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
55547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _close(fd, type);
55647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
55747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    for (i=0; i<MAX_T; i++)
55847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        pthread_join(t[i], NULL);
55947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
56047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return 0;
56147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
56247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
56347653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int do_read_read_read_close(int type) {
56447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    const int MAX_T = 32;
56547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int fd;
56647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_t t[MAX_T];
56747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int i;
56847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
56947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    fd = _socket(type);
57047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
57147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    for (i=0; i<MAX_T; i++)
57247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        pthread_create(&t[i], NULL, (void *)thread_read, (void *)fd);
57347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
57447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    sleep(1);
57547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
57647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _close(fd, type);
57747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
57847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    for (i=0; i<MAX_T; i++)
57947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        pthread_join(t[i], NULL);
58047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
58147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return 0;
58247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
58347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
58447653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int do_read_read_read_shutdown(int type) {
58547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    const int MAX_T = 32;
58647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int fd;
58747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_t t[MAX_T];
58847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int i;
58947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
59047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    fd = _socket(type);
59147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
59247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    for (i=0; i<MAX_T; i++)
59347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        pthread_create(&t[i], NULL, (void *)thread_read, (void *)fd);
59447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
59547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    sleep(1);
59647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
59747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _shutdown(fd, SHUT_RDWR);
59847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
59947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    for (i=0; i<MAX_T; i++)
60047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        pthread_join(t[i], NULL);
60147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
60247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _close(fd, type);
60347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
60447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return 0;
60547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
60647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
60747653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int do_connected_read1_shutdown1(int type) {
60847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int fd1, fd2;
60947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_t t1;
61047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_t t2;
61147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    struct thread_args a1 = {-1, type, 0};
61247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    struct thread_args a2 = {-1, type, 2};
61347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
61447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    fd1 = _socket(type);
61547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (fd1 < 0) goto error;
61647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
61747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (_bind(fd1, type) < 0) goto error;
61847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
61947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (_listen(fd1, type) < 0) goto error;
62047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
62147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    a1.fd = fd1;
62247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_create(&t1, NULL, (void *)thread_accept_write, (void *)&a1);
62347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
62447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    fd2 = _socket(type);
62547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (_connect(fd2, type)) goto error;
62647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
62747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_create(&t2, NULL, (void *)thread_shutdown, (void *)&fd2);
62847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
62947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    while (1) if (_read(fd2)) break;
6303f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
6313f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    pthread_join(t1, NULL);
6323f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    pthread_join(t2, NULL);
63347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
6343f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    return 0;
63547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
63647653588a022190d4b3e20194ef643dfb7b90632Nick Pellyerror:
63747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return -1;
6383f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly}
6393f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
6403f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly// accept in one thread, connect from two different threads
6413f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pellystatic int do_accept_connect_connect(int type) {
6423f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    int fd;
6433f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    pthread_t t1;
6443f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    pthread_t t2;
6453f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    struct thread_args a1 = {-1, type, 1};
6463f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    struct thread_args a2 = {-1, type, 2};
6473f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
6483f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    fd = _socket(type);
6493f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    if (fd < 0) goto error;
6503f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
6513f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    if (_bind(fd, type) < 0) goto error;
6523f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
6533f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    if (_listen(fd, type) < 0) goto error;
6543f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
6553f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    pthread_create(&t1, NULL, (void *)thread_delay_connect, (void *)&a1);
6563f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    pthread_create(&t2, NULL, (void *)thread_delay_connect, (void *)&a2);
6573f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
6583f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    _accept(fd, type);
6593f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
6603f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    pthread_join(t1, NULL);
6613f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    pthread_join(t2, NULL);
6623f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
6633f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    return 0;
6643f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
6653f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pellyerror:
6663f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    return -1;
6673f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly}
6683f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
669b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystruct {
670b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    char *name;
671b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int (*ptr)(int);
672b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly} action_table[]  = {
6733f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    {"accept_accept_accept", do_accept_accept_accept},
674b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    {"accept_and_close", do_accept_and_close},
67547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    {"accept_shutdown", do_accept_shutdown},
67647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    {"connect_shutdown", do_connect_shutdown},
677b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    {"accept_close_write", do_accept_close_write},
6783f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    {"accept_connect_connect", do_accept_connect_connect},
67947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    {"poll_poll_poll_shutdown", do_poll_poll_poll_shutdown},
68047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    {"poll_poll_poll_close", do_poll_poll_poll_close},
68147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    {"read_read_read_shutdown", do_read_read_read_shutdown},
68247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    {"read_read_read_close", do_read_read_read_close},
68347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    {"connected_read1_shutdown1", do_connected_read1_shutdown1},
684b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    {NULL, NULL},
685b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly};
686b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
687b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystruct {
688b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    char *name;
689b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    enum sock_type type;
690b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly} type_table[]  = {
691b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    {"unix", UNIX},
692b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    {"rfcomm", RFCOMM},
693b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    {"sco", SCO},
694b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    {"l2cap", L2CAP},
695b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    {"tcp", TCP},
696b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    {NULL, -1},
697b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly};
698b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
699b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystatic void usage() {
700b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int i;
701b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
702b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    printf("socktest TYPE ACTION\n");
703b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    printf("\nTYPE:\n");
704b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    for (i = 0; type_table[i].name; i++) {
705b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        printf("\t%s\n", type_table[i].name);
706b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    }
707b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    printf("\nACTION:\n");
708b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    for (i = 0; action_table[i].name; i++) {
709b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        printf("\t%s\n", action_table[i].name);
710b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    }
711b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly}
712b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
713b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellyint main(int argc, char **argv) {
714b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int i;
715b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int type = -1;
716b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
717b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    if (argc != 3) {
718b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        usage();
719b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        return -1;
720b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    }
721b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    for (i = 0; type_table[i].name; i++) {
722b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        if (!strcmp(argv[1], type_table[i].name)) {
723b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly            type = type_table[i].type;
724b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly            break;
725b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        }
726b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    }
727b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    if (type == -1) {
728b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        usage();
729b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        return -1;
730b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    }
731b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    for (i = 0; action_table[i].name; i++) {
732b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        if (!strcmp(argv[2], action_table[i].name)) {
733b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly            printf("TYPE = %s ACTION = %s\n", type_table[type].name,
734b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly                    action_table[i].name);
735b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly            return (*action_table[i].ptr)(type);
736b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        }
737b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    }
738b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    usage();
739b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    return -1;
740b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly}
741