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
259baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly#include <fcntl.h>
26b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <pthread.h>
27b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <stdio.h>
28b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <stdlib.h>
29b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <errno.h>
30b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <unistd.h>
31b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <sys/socket.h>
32b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <sys/ioctl.h>
3347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly#include <sys/poll.h>
34b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <sys/un.h>
35b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <netinet/in.h>
36b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
37b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <bluetooth/bluetooth.h>
38b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <bluetooth/rfcomm.h>
39b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <bluetooth/sco.h>
40b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <bluetooth/l2cap.h>
41b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
42b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellyenum sock_type {
43b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    UNIX = 0,
44b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    RFCOMM,
45b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    SCO,
46b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    L2CAP,
47b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    TCP,
48b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly};
49b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
50b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystruct thread_args {
51b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int fd;
52b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int type;
533f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    int delay;
54b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly};
55b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
56b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystruct sockaddr_un  local_addr_un  = {AF_UNIX, "/data/foo"};
573f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pellystruct sockaddr_rc  local_addr_rc  = {AF_BLUETOOTH, *BDADDR_ANY, 4};
583f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pellystruct sockaddr_sco local_addr_sco = {AF_BLUETOOTH, *BDADDR_LOCAL};
59b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystruct sockaddr_l2  local_addr_l2  = {AF_BLUETOOTH, htobs(0x1001), *BDADDR_ANY, 0};
60b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystruct sockaddr_in  local_addr_in  = {AF_INET, 9999, {0}, {0}};
61b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
62b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystruct sockaddr_un  remote_addr_un  ;
63b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystruct sockaddr_rc  remote_addr_rc  ;
64b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystruct sockaddr_sco remote_addr_sco ;
65b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystruct sockaddr_l2  remote_addr_l2  ;
66b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystruct sockaddr_in  remote_addr_in  ;
67b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
6847653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic void print_events(int events) {
6947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (events & POLLIN) printf("POLLIN ");
7047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (events & POLLPRI) printf("POLLPRI ");
7147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (events & POLLOUT) printf("POLLOUT ");
7247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (events & POLLERR) printf("POLLERR ");
7347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (events & POLLHUP) printf("POLLHUP ");
7447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (events & POLLNVAL) printf("POLLNVAL ");
7547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("\n");
7647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
7747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
7847653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic void print_fds(struct pollfd *ufds, nfds_t nfds) {
7947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    unsigned int i;
8047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    for (i=0; i<nfds; i++)
8147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        printf("%d ", ufds[i].fd);
8247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
8347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
84b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystatic int _socket(int type) {
85b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int ret;
86b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int family = -1;
87b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int typ = -1;
88b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int protocol = -1;
89b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
90b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    switch (type) {
91b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case UNIX:
92b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        family = PF_UNIX;
93b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        typ = SOCK_STREAM;
94b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        protocol = 0;
95b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
96b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case RFCOMM:
97b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        family = PF_BLUETOOTH;
98b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        typ = SOCK_STREAM;
99b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        protocol = BTPROTO_RFCOMM;
100b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
101b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case SCO:
102b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        family = PF_BLUETOOTH;
103b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        typ = SOCK_SEQPACKET;
104b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        protocol = BTPROTO_SCO;
105b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
106b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case L2CAP:
107b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        family = PF_BLUETOOTH;
108b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        typ = SOCK_SEQPACKET;
109b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        protocol = BTPROTO_L2CAP;
110b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
111b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case TCP:
112b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        family = PF_INET;
113b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        typ = SOCK_STREAM;
114b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        protocol = 0;
115b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
116b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    }
117b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
1189baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: socket()\n", pthread_self());
119b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    ret = socket(family, typ, protocol);
1209baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: socket() = %d\n", pthread_self(), ret);
121b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
122b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
123b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    return ret;
124b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly}
125b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
126b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystatic int _close(int fd, int type) {
127b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int ret;
128b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
1299baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: close(%d)\n", pthread_self(), fd);
130b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    ret = close(fd);
1319baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: close(%d) = %d\n", pthread_self(), fd, ret);
132b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
133b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
134b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    return ret;
135b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly}
136b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
137b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystatic int _bind(int fd, int type) {
138b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int len = 0;
139b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int ret;
140b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    struct sockaddr *addr = NULL;
141b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
142b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    switch (type) {
143b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case UNIX:
144b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        unlink(local_addr_un.sun_path);
145b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        addr = (struct sockaddr *) &local_addr_un;
146b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        len = sizeof(local_addr_un);
147b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
148b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case RFCOMM:
149b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        addr = (struct sockaddr *) &local_addr_rc;
150b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        len = sizeof(local_addr_rc);
151b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
152b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case SCO:
153b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        addr = (struct sockaddr *) &local_addr_sco;
154b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        len = sizeof(local_addr_sco);
155b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
156b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case L2CAP:
157b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        addr = (struct sockaddr *) &local_addr_l2;
158b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        len = sizeof(local_addr_l2);
159b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
160b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case TCP:
161b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        addr = (struct sockaddr *) &local_addr_in;
162b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        len = sizeof(local_addr_in);
163b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
164b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    }
165b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
1669baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: bind(%d)\n", pthread_self(), fd);
167b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    ret = bind(fd, addr, len);
1689baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: bind(%d) = %d\n", pthread_self(), fd, ret);
169b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
170b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
171b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    return ret;
172b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly}
173b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
174b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystatic int _listen(int fd, int type) {
175b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int ret;
176b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
1779baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: listen(%d)\n", pthread_self(), fd);
178b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    ret = listen(fd, 1);
1799baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: listen(%d) = %d\n", pthread_self(), fd, ret);
180b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
181b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
182b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    return ret;
183b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly}
184b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
18547653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int _read(int fd) {
18647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int ret;
18747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    char buf;
18847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
1899baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: read(%d)\n", pthread_self(), fd);
19047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    ret = read(fd, &buf, 1);
1919baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: read(%d) = %d [%d]\n", pthread_self(), fd, ret, (int)buf);
19247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
19347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
19447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return ret;
19547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
19647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
19747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
198b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystatic int _accept(int fd, int type) {
199b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int ret;
200b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int len;
201b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    struct sockaddr *addr = NULL;
202b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
203b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    switch (type) {
204b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case UNIX:
205b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        addr = (struct sockaddr *) &remote_addr_un;
206b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        len = sizeof(remote_addr_un);
207b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
208b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case RFCOMM:
209b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        addr = (struct sockaddr *) &remote_addr_rc;
210b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        len = sizeof(remote_addr_rc);
211b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
212b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case SCO:
213b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        addr = (struct sockaddr *) &remote_addr_sco;
214b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        len = sizeof(remote_addr_sco);
215b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
216b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case L2CAP:
217b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        addr = (struct sockaddr *) &remote_addr_l2;
218b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        len = sizeof(remote_addr_l2);
219b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
220b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case TCP:
221b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        addr = (struct sockaddr *) &remote_addr_in;
222b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        len = sizeof(remote_addr_in);
223b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
224b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    }
225b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
2269baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: accept(%d)\n", pthread_self(), fd);
227b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    ret = accept(fd, addr, &len);
2289baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: accept(%d) = %d\n", pthread_self(), fd, ret);
229b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
230b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    else {
231b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        printf("\tlen = %d\n", len);
232b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    }
233b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
234b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    return ret;
235b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly}
236b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
2379baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellyint get_bdaddr(const char *str, bdaddr_t *ba) {
2389baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    char *d = ((char *)ba) + 5, *endp;
2399baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int i;
2409baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    for(i = 0; i < 6; i++) {
2419baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        *d-- = strtol(str, &endp, 16);
2429baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        if (*endp != ':' && i != 5) {
2439baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly            memset(ba, 0, sizeof(bdaddr_t));
2449baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly            return -1;
2459baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        }
2469baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        str = endp + 1;
2479baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    }
2489baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return 0;
2499baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
2509baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
251b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystatic int _connect(int fd, int type) {
252b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int ret;
2533f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    int len = 0;
254b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    struct sockaddr *addr = NULL;
255b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
256b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    switch (type) {
257b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case UNIX:
258b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        addr = (struct sockaddr *) &local_addr_un;
259b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        len = sizeof(local_addr_un);
260b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
261b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case RFCOMM:
2629baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        get_bdaddr("00:11:22:33:44:55", &local_addr_rc.rc_bdaddr);
263b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        addr = (struct sockaddr *) &local_addr_rc;
264b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        len = sizeof(local_addr_rc);
265b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
266b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case SCO:
267b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        addr = (struct sockaddr *) &local_addr_sco;
268b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        len = sizeof(local_addr_sco);
269b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
270b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case L2CAP:
271b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        addr = (struct sockaddr *) &local_addr_l2;
272b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        len = sizeof(local_addr_l2);
273b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
274b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    case TCP:
275b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        addr = (struct sockaddr *) &local_addr_in;
276b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        len = sizeof(local_addr_in);
277b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        break;
278b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    }
279b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
2809baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: connect(%d)\n", pthread_self(), fd);
281b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    ret = connect(fd, addr, len);
2829baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: connect(%d) = %d\n", pthread_self(), fd, ret);
283b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
284b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
285b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    return ret;
286b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly}
287b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
288b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystatic int _write(int fd, int type) {
289b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int ret;
29047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    char buf = 69;
291b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
2929baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: write(%d)\n", pthread_self(), fd);
293b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    ret = write(fd, &buf, 1);
2949baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: write(%d) = %d\n", pthread_self(), fd, ret);
29547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
29647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
29747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return ret;
29847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
29947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
30047653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int _shutdown(int fd, int how) {
30147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int ret;
30247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
3039baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: shutdown(%d)\n", pthread_self(), fd);
30447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    ret = shutdown(fd, how);
3059baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: shutdown(%d) = %d\n", pthread_self(), fd, ret);
306b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
307b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
308b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    return ret;
309b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly}
310b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
31147653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int _poll(struct pollfd *ufds, nfds_t nfds, int timeout) {
31247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int ret;
31347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    unsigned int i;
31447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
3159baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: poll(", pthread_self());
31647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    print_fds(ufds, nfds);
31747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf(")\n");
31847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    ret = poll(ufds, nfds, timeout);
3199baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: poll() = %d\n", pthread_self(), ret);
32047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
32147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (ret > 0) {
32247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        for (i=0; i<nfds; i++) {
32347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly            if (ufds[i].revents) {
32447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly                printf("\tfd %d ", ufds[i].fd); print_events(ufds[i].revents);
32547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly            }
32647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        }
32747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    }
32847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return ret;
32947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
33047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
3313f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pellystatic void thread_delay_close(struct thread_args *args) {
3329baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: START\n", pthread_self());
3333f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    sleep(args->delay);
3343f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    _close(args->fd, args->type);
3359baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: END\n", pthread_self());
336b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly}
337b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
33847653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic void thread_poll(void *args) {
33947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int fd = (int)args;
34047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    struct pollfd pfd;
3419baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: START\n", pthread_self());
34247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pfd.fd = fd;
34347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pfd.events = 0;
34447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _poll(&pfd, 1, -1);
3459baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: END\n", pthread_self());
34647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
34747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
34847653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic void thread_read(void *args) {
34947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int fd = (int)args;
3509baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: START\n", pthread_self());
35147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _read(fd);
3529baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: END\n", pthread_self());
35347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
35447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
35547653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic void thread_pollin(void *args) {
35647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int fd = (int)args;
35747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    struct pollfd pfd;
3589baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: START\n", pthread_self());
35947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pfd.fd = fd;
36047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pfd.events = POLLIN;
36147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _poll(&pfd, 1, -1);
3629baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: END\n", pthread_self());
36347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
36447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
36547653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic void thread_shutdown(int fd) {
3669baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: START\n", pthread_self());
36747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    sleep(4);
36847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _shutdown(fd, SHUT_RDWR);
3699baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: END\n", pthread_self());
37047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
37147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
37247653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic void thread_accept(struct thread_args *args) {
3739baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: START\n", pthread_self());
37447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    sleep(args->delay);
37547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _accept(args->fd, args->type);
3769baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: END\n", pthread_self());
37747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
37847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
37947653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic void thread_connect(struct thread_args *args) {
3809baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: START\n", pthread_self());
38147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    sleep(args->delay);
38247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _connect(args->fd, args->type);
3839baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: END\n", pthread_self());
38447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
38547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
3863f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pellystatic void thread_delay_close_write(struct thread_args *args) {
3879baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: START\n", pthread_self());
3883f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    sleep(args->delay);
3893f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    _close(args->fd, args->type);
3903f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    sleep(args->delay);
3913f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    _write(args->fd, args->type);
3929baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: END\n", pthread_self());
3933f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly}
394b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
39547653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic void thread_accept_write(struct thread_args *args) {
3969baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: START\n", pthread_self());
39747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    sleep(args->delay);
39847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _accept(args->fd, args->type);
39947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    sleep(args->delay);
40047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _write(args->fd, args->type);
4019baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: END\n", pthread_self());
40247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
40347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
4043f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pellystatic void thread_delay_connect(struct thread_args *args) {
4059baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: START\n", pthread_self());
4063f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    sleep(args->delay);
4073f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    args->fd = _socket(args->type);
4083f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    _connect(args->fd, args->type);
4099baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%ld: END\n", pthread_self());
410b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly}
411b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
4123f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pellystatic int do_accept_accept_accept(int type) {
4133f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    int fd;
4143f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
4153f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    fd = _socket(type);
4163f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    if (fd < 0) goto error;
4173f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
4183f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    if (_bind(fd, type) < 0) goto error;
4193f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
4203f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    if (_listen(fd, type) < 0) goto error;
4213f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
4223f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    while (1) {
4233f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly        _accept(fd, type);
4243f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    }
4253f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
4263f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    return 0;
4273f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
4283f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pellyerror:
4293f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    return -1;
4303f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly}
4313f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
432b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystatic int do_accept_and_close(int type) {
433b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int fd;
434b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    pthread_t thread;
4353f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    struct thread_args args = {-1, type, 1};
436b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
437b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    fd = _socket(type);
438b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    if (fd < 0) goto error;
439b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
440b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    if (_bind(fd, type) < 0) goto error;
441b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
442b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    if (_listen(fd, type) < 0) goto error;
443b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
4443f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    args.fd = fd;
4453f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    pthread_create(&thread, NULL, (void *)thread_delay_close, (void *)&args);
446b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
447b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    _accept(fd, type);
448b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
449b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    pthread_join(thread, NULL);
450b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
451b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    return 0;
452b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
453b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellyerror:
454b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    return -1;
455b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly}
456b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
45747653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int do_accept_shutdown(int type) {
45847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int fd;
45947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_t thread;
46047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    struct thread_args args = {-1, type, 0};
46147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
46247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    fd = _socket(type);
46347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (fd < 0) goto error;
46447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
46547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (_bind(fd, type) < 0) goto error;
46647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
46747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (_listen(fd, type) < 0) goto error;
46847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
46947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    args.fd = fd;
47047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_create(&thread, NULL, (void *)thread_accept, (void *)&args);
47147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
47247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    sleep(4);
47347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _shutdown(fd, SHUT_RDWR);
47447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
47547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_join(thread, NULL);
47647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
47747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _close(fd, type);
47847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
47947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return 0;
48047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
48147653588a022190d4b3e20194ef643dfb7b90632Nick Pellyerror:
48247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return -1;
48347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
48447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
48547653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int do_connect_shutdown(int type) {
48647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int fd;
48747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_t thread;
48847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    struct thread_args args = {-1, type, 0};
48947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
49047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    fd = _socket(type);
49147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (fd < 0) goto error;
49247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
49347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    args.fd = fd;
49447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_create(&thread, NULL, (void *)thread_connect, (void *)&args);
49547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
49647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    sleep(4);
49747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _shutdown(fd, SHUT_RDWR);
49847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
49947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_join(thread, NULL);
50047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
50147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _close(fd, type);
50247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
50347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return 0;
50447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
50547653588a022190d4b3e20194ef643dfb7b90632Nick Pellyerror:
50647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return -1;
50747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
50847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
5099baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic int do_connectnb_shutdown(int type) {
5109baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int fd;
5119baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int flags;
5129baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pthread_t thread;
5139baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    struct thread_args args = {-1, type, 0};
5149baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5159baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5169baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    fd = _socket(type);
5179baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (fd < 0) goto error;
5189baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5199baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    flags = fcntl(fd, F_GETFL);
5209baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (flags == -1)
5219baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        return -1;
5229baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (fcntl(fd, F_SETFL, flags | O_NONBLOCK))
5239baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        return -1;
5249baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5259baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    _connect(fd, type);
5269baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5279baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    sleep(1);
5289baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    _shutdown(fd, SHUT_RDWR);
5299baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5309baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    sleep(2);
5319baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5329baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    _close(fd, type);
5339baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5349baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return 0;
5359baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5369baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellyerror:
5379baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return -1;
5389baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
5399baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5409baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic int do_connectnb_close(int type) {
5419baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int fd;
5429baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pthread_t thread;
5439baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    struct thread_args args = {-1, type, 0};
5449baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int flags;
5459baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5469baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    fd = _socket(type);
5479baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (fd < 0) goto error;
5489baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5499baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    flags = fcntl(fd, F_GETFL);
5509baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (flags == -1)
5519baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        return -1;
5529baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (fcntl(fd, F_SETFL, flags | O_NONBLOCK))
5539baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        return -1;
5549baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5559baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    _connect(fd, type);
5569baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5579baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    sleep(2);
5589baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5599baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    _close(fd, type);
5609baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5619baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return 0;
5629baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5639baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellyerror:
5649baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return -1;
5659baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
5669baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
567b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly// accept in one thread. close then write in another
568b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystatic int do_accept_close_write(int type) {
569b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int fd;
570b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    pthread_t thread;
5713f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    struct thread_args args = {-1, type, 1};
572b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
573b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    fd = _socket(type);
574b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    if (fd < 0) goto error;
575b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
576b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    if (_bind(fd, type) < 0) goto error;
577b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
578b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    if (_listen(fd, type) < 0) goto error;
579b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
5803f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    args.fd = fd;
5813f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    pthread_create(&thread, NULL, (void *)thread_delay_close_write, (void *)&args);
582b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
583b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    _accept(fd, type);
584b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
585b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    pthread_join(thread, NULL);
586b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
587b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    return 0;
588b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
589b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellyerror:
590b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    return -1;
591b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly}
592b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
59347653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int do_poll_poll_poll_shutdown(int type) {
59447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    const int MAX_T = 32;
5953f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    int fd;
59647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_t t[MAX_T];
59747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int i;
59847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
59947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    fd = _socket(type);
60047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
60147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    for (i=0; i<MAX_T; i++)
60247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        pthread_create(&t[i], NULL, (void *)thread_poll, (void *)fd);
60347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
60447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    sleep(1);
60547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
60647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _shutdown(fd, SHUT_RDWR);
60747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
60847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    for (i=0; i<MAX_T; i++)
60947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        pthread_join(t[i], NULL);
61047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
61147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _close(fd, type);
61247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
61347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return 0;
61447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
61547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
61647653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int do_poll_poll_poll_close(int type) {
61747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    const int MAX_T = 32;
61847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int fd;
61947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_t t[MAX_T];
62047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int i;
6213f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
6223f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    fd = _socket(type);
6233f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
62447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    for (i=0; i<MAX_T; i++)
62547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        pthread_create(&t[i], NULL, (void *)thread_poll, (void *)fd);
6263f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
6273f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    sleep(1);
6283f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
62947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _close(fd, type);
63047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
63147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    for (i=0; i<MAX_T; i++)
63247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        pthread_join(t[i], NULL);
63347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
63447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return 0;
63547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
63647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
63747653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int do_read_read_read_close(int type) {
63847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    const int MAX_T = 32;
63947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int fd;
64047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_t t[MAX_T];
64147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int i;
64247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
64347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    fd = _socket(type);
64447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
64547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    for (i=0; i<MAX_T; i++)
64647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        pthread_create(&t[i], NULL, (void *)thread_read, (void *)fd);
64747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
64847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    sleep(1);
64947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
65047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _close(fd, type);
65147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
65247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    for (i=0; i<MAX_T; i++)
65347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        pthread_join(t[i], NULL);
65447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
65547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return 0;
65647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
65747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
65847653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int do_read_read_read_shutdown(int type) {
65947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    const int MAX_T = 32;
66047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int fd;
66147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_t t[MAX_T];
66247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int i;
66347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
66447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    fd = _socket(type);
66547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
66647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    for (i=0; i<MAX_T; i++)
66747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        pthread_create(&t[i], NULL, (void *)thread_read, (void *)fd);
66847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
66947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    sleep(1);
67047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
67147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _shutdown(fd, SHUT_RDWR);
67247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
67347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    for (i=0; i<MAX_T; i++)
67447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        pthread_join(t[i], NULL);
67547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
67647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _close(fd, type);
67747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
67847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return 0;
67947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
68047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
68147653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int do_connected_read1_shutdown1(int type) {
68247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int fd1, fd2;
68347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_t t1;
68447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_t t2;
68547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    struct thread_args a1 = {-1, type, 0};
68647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    struct thread_args a2 = {-1, type, 2};
68747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
68847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    fd1 = _socket(type);
68947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (fd1 < 0) goto error;
69047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
69147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (_bind(fd1, type) < 0) goto error;
69247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
69347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (_listen(fd1, type) < 0) goto error;
69447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
69547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    a1.fd = fd1;
69647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_create(&t1, NULL, (void *)thread_accept_write, (void *)&a1);
69747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
69847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    fd2 = _socket(type);
69947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (_connect(fd2, type)) goto error;
70047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
70147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_create(&t2, NULL, (void *)thread_shutdown, (void *)&fd2);
70247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
70347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    while (1) if (_read(fd2)) break;
7043f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
7053f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    pthread_join(t1, NULL);
7063f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    pthread_join(t2, NULL);
70747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
7083f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    return 0;
70947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
71047653588a022190d4b3e20194ef643dfb7b90632Nick Pellyerror:
71147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return -1;
7123f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly}
7133f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
7143f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly// accept in one thread, connect from two different threads
7153f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pellystatic int do_accept_connect_connect(int type) {
7163f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    int fd;
7173f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    pthread_t t1;
7183f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    pthread_t t2;
7193f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    struct thread_args a1 = {-1, type, 1};
7203f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    struct thread_args a2 = {-1, type, 2};
7213f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
7223f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    fd = _socket(type);
7233f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    if (fd < 0) goto error;
7243f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
7253f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    if (_bind(fd, type) < 0) goto error;
7263f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
7273f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    if (_listen(fd, type) < 0) goto error;
7283f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
7293f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    pthread_create(&t1, NULL, (void *)thread_delay_connect, (void *)&a1);
7303f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    pthread_create(&t2, NULL, (void *)thread_delay_connect, (void *)&a2);
7313f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
7323f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    _accept(fd, type);
7333f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
7343f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    pthread_join(t1, NULL);
7353f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    pthread_join(t2, NULL);
7363f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
7373f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    return 0;
7383f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
7393f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pellyerror:
7403f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    return -1;
7413f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly}
7423f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly
743b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystruct {
744b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    char *name;
745b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int (*ptr)(int);
746b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly} action_table[]  = {
7473f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    {"accept_accept_accept", do_accept_accept_accept},
748b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    {"accept_and_close", do_accept_and_close},
74947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    {"accept_shutdown", do_accept_shutdown},
75047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    {"connect_shutdown", do_connect_shutdown},
7519baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    {"connectnb_shutdown", do_connectnb_shutdown},
7529baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    {"connectnb_close", do_connectnb_close},
753b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    {"accept_close_write", do_accept_close_write},
7543f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly    {"accept_connect_connect", do_accept_connect_connect},
75547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    {"poll_poll_poll_shutdown", do_poll_poll_poll_shutdown},
75647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    {"poll_poll_poll_close", do_poll_poll_poll_close},
75747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    {"read_read_read_shutdown", do_read_read_read_shutdown},
75847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    {"read_read_read_close", do_read_read_read_close},
75947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    {"connected_read1_shutdown1", do_connected_read1_shutdown1},
760b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    {NULL, NULL},
761b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly};
762b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
763b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystruct {
764b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    char *name;
765b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    enum sock_type type;
766b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly} type_table[]  = {
767b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    {"unix", UNIX},
768b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    {"rfcomm", RFCOMM},
769b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    {"sco", SCO},
770b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    {"l2cap", L2CAP},
771b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    {"tcp", TCP},
772b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    {NULL, -1},
773b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly};
774b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
775b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystatic void usage() {
776b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int i;
777b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
778b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    printf("socktest TYPE ACTION\n");
779b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    printf("\nTYPE:\n");
780b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    for (i = 0; type_table[i].name; i++) {
781b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        printf("\t%s\n", type_table[i].name);
782b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    }
783b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    printf("\nACTION:\n");
784b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    for (i = 0; action_table[i].name; i++) {
785b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        printf("\t%s\n", action_table[i].name);
786b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    }
787b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly}
788b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
789b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellyint main(int argc, char **argv) {
790b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int i;
791b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    int type = -1;
792b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly
793b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    if (argc != 3) {
794b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        usage();
795b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        return -1;
796b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    }
797b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    for (i = 0; type_table[i].name; i++) {
798b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        if (!strcmp(argv[1], type_table[i].name)) {
799b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly            type = type_table[i].type;
800b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly            break;
801b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        }
802b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    }
803b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    if (type == -1) {
804b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        usage();
805b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        return -1;
806b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    }
807b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    for (i = 0; action_table[i].name; i++) {
808b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        if (!strcmp(argv[2], action_table[i].name)) {
809b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly            printf("TYPE = %s ACTION = %s\n", type_table[type].name,
810b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly                    action_table[i].name);
811b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly            return (*action_table[i].ptr)(type);
812b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly        }
813b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    }
814b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    usage();
815b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly    return -1;
816b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly}
817