19baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly/*
29baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly** Copyright 2009 The Android Open Source Project
39baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly**
49baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly** Licensed under the Apache License, Version 2.0 (the "License");
59baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly** you may not use this file except in compliance with the License.
69baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly** You may obtain a copy of the License at
79baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly**
89baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly**     http://www.apache.org/licenses/LICENSE-2.0
99baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly**
109baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly** Unless required by applicable law or agreed to in writing, software
119baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly** distributed under the License is distributed on an "AS IS" BASIS,
129baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly** See the License for the specific language governing permissions and
149baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly** limitations under the License.
159baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly*/
169baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
179baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly/** socket testing  */
189baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
199baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly#include <stdlib.h>
209baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly#include <stdio.h>
219baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly#include <errno.h>
229baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly#include <sys/uio.h>
239baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly#include <unistd.h>
249baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
259baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly#include <pthread.h>
269baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly#include <stdio.h>
279baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly#include <stdlib.h>
289baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly#include <errno.h>
299baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly#include <unistd.h>
309baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly#include <sys/socket.h>
319baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly#include <sys/ioctl.h>
329baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly#include <sys/poll.h>
339baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly#include <sys/un.h>
349baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly#include <netinet/in.h>
359baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
369baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly#include <bluetooth/bluetooth.h>
379baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly#include <bluetooth/rfcomm.h>
389baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly#include <bluetooth/sco.h>
399baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly#include <bluetooth/l2cap.h>
409baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
419baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly#include "cutils/abort_socket.h"
429baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
439baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellyenum sock_type {
449baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    UNIX = 0,
459baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    RFCOMM,
469baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    SCO,
479baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    L2CAP,
489baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    TCP,
499baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly};
509baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
519baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystruct thread_args {
529baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int fd;
539baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int type;
549baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int delay;
559baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly};
569baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
579baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystruct sockaddr_un  local_addr_un  = {AF_UNIX, "/data/foo"};
589baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystruct sockaddr_rc  local_addr_rc  = {AF_BLUETOOTH, *BDADDR_ANY, 4};
599baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystruct sockaddr_sco local_addr_sco = {AF_BLUETOOTH, *BDADDR_LOCAL};
609baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystruct sockaddr_l2  local_addr_l2  = {AF_BLUETOOTH, htobs(0x1001), *BDADDR_ANY, 0};
619baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystruct sockaddr_in  local_addr_in  = {AF_INET, 9999, {0}, {0}};
629baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
639baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystruct sockaddr_un  remote_addr_un  ;
649baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystruct sockaddr_rc  remote_addr_rc  ;
659baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystruct sockaddr_sco remote_addr_sco ;
669baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystruct sockaddr_l2  remote_addr_l2  ;
679baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystruct sockaddr_in  remote_addr_in  ;
689baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
699baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic void print_events(int events) {
709baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (events & POLLIN) printf("POLLIN ");
719baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (events & POLLPRI) printf("POLLPRI ");
729baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (events & POLLOUT) printf("POLLOUT ");
739baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (events & POLLERR) printf("POLLERR ");
749baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (events & POLLHUP) printf("POLLHUP ");
759baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (events & POLLNVAL) printf("POLLNVAL ");
769baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("\n");
779baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
789baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
799baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic void print_fds(struct pollfd *ufds, nfds_t nfds) {
809baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    unsigned int i;
819baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    for (i=0; i<nfds; i++)
829baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        printf("%d ", ufds[i].fd);
839baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
849baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
859baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic int _socket(int type) {
869baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int ret;
879baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int family = -1;
889baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int typ = -1;
899baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int protocol = -1;
909baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
919baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    switch (type) {
929baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    case UNIX:
939baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        family = PF_UNIX;
949baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        typ = SOCK_STREAM;
959baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        protocol = 0;
969baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        break;
979baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    case RFCOMM:
989baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        family = PF_BLUETOOTH;
999baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        typ = SOCK_STREAM;
1009baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        protocol = BTPROTO_RFCOMM;
1019baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        break;
1029baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    case SCO:
1039baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        family = PF_BLUETOOTH;
1049baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        typ = SOCK_SEQPACKET;
1059baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        protocol = BTPROTO_SCO;
1069baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        break;
1079baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    case L2CAP:
1089baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        family = PF_BLUETOOTH;
1099baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        typ = SOCK_SEQPACKET;
1109baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        protocol = BTPROTO_L2CAP;
1119baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        break;
1129baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    case TCP:
1139baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        family = PF_INET;
1149baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        typ = SOCK_STREAM;
1159baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        protocol = 0;
1169baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        break;
1179baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    }
1189baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
1199baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: socket()\n", gettid());
1209baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    ret = socket(family, typ, protocol);
1219baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: socket() = %d\n", gettid(), ret);
1229baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
1239baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
1249baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return ret;
1259baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
1269baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
1279baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic int _close(int fd, int type) {
1289baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int ret;
1299baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
1309baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: close(%d)\n", gettid(), fd);
1319baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    ret = close(fd);
1329baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: close(%d) = %d\n", gettid(), fd, ret);
1339baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
1349baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
1359baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return ret;
1369baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
1379baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
1389baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic int _bind(int fd, int type) {
1399baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int len = 0;
1409baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int ret;
1419baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    struct sockaddr *addr = NULL;
1429baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
1439baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    switch (type) {
1449baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    case UNIX:
1459baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        unlink(local_addr_un.sun_path);
1469baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        addr = (struct sockaddr *) &local_addr_un;
1479baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        len = sizeof(local_addr_un);
1489baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        break;
1499baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    case RFCOMM:
1509baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        addr = (struct sockaddr *) &local_addr_rc;
1519baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        len = sizeof(local_addr_rc);
1529baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        break;
1539baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    case SCO:
1549baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        addr = (struct sockaddr *) &local_addr_sco;
1559baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        len = sizeof(local_addr_sco);
1569baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        break;
1579baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    case L2CAP:
1589baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        addr = (struct sockaddr *) &local_addr_l2;
1599baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        len = sizeof(local_addr_l2);
1609baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        break;
1619baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    case TCP:
1629baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        addr = (struct sockaddr *) &local_addr_in;
1639baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        len = sizeof(local_addr_in);
1649baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        break;
1659baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    }
1669baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
1679baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: bind(%d)\n", gettid(), fd);
1689baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    ret = bind(fd, addr, len);
1699baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: bind(%d) = %d\n", gettid(), fd, ret);
1709baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
1719baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
1729baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return ret;
1739baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
1749baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
1759baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic int _listen(int fd, int type) {
1769baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int ret;
1779baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
1789baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: listen(%d)\n", gettid(), fd);
1799baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    ret = listen(fd, 1);
1809baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: listen(%d) = %d\n", gettid(), fd, ret);
1819baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
1829baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
1839baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return ret;
1849baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
1859baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
1869baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic int _read(int fd) {
1879baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int ret;
1889baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    char buf;
1899baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
1909baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: read(%d)\n", gettid(), fd);
1919baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    ret = read(fd, &buf, 1);
1929baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: read(%d) = %d [%d]\n", gettid(), fd, ret, (int)buf);
1939baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
1949baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
1959baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return ret;
1969baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
1979baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
1989baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
1999baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic int _accept(int fd, int type) {
2009baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int ret;
2019baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int len;
2029baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    struct sockaddr *addr = NULL;
2039baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
2049baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    switch (type) {
2059baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    case UNIX:
2069baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        addr = (struct sockaddr *) &remote_addr_un;
2079baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        len = sizeof(remote_addr_un);
2089baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        break;
2099baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    case RFCOMM:
2109baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        addr = (struct sockaddr *) &remote_addr_rc;
2119baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        len = sizeof(remote_addr_rc);
2129baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        break;
2139baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    case SCO:
2149baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        addr = (struct sockaddr *) &remote_addr_sco;
2159baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        len = sizeof(remote_addr_sco);
2169baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        break;
2179baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    case L2CAP:
2189baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        addr = (struct sockaddr *) &remote_addr_l2;
2199baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        len = sizeof(remote_addr_l2);
2209baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        break;
2219baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    case TCP:
2229baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        addr = (struct sockaddr *) &remote_addr_in;
2239baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        len = sizeof(remote_addr_in);
2249baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        break;
2259baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    }
2269baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
2279baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: accept(%d)\n", gettid(), fd);
2289baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    ret = accept(fd, addr, &len);
2299baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: accept(%d) = %d\n", gettid(), fd, ret);
2309baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
2319baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    else {
2329baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        printf("\tlen = %d\n", len);
2339baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    }
2349baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
2359baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return ret;
2369baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
2379baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
2389baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic int _connect(int fd, int type) {
2399baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int ret;
2409baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int len = 0;
2419baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    struct sockaddr *addr = NULL;
2429baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
2439baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    switch (type) {
2449baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    case UNIX:
2459baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        addr = (struct sockaddr *) &local_addr_un;
2469baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        len = sizeof(local_addr_un);
2479baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        break;
2489baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    case RFCOMM:
2499baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        addr = (struct sockaddr *) &local_addr_rc;
2509baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        len = sizeof(local_addr_rc);
2519baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        break;
2529baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    case SCO:
2539baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        addr = (struct sockaddr *) &local_addr_sco;
2549baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        len = sizeof(local_addr_sco);
2559baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        break;
2569baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    case L2CAP:
2579baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        addr = (struct sockaddr *) &local_addr_l2;
2589baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        len = sizeof(local_addr_l2);
2599baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        break;
2609baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    case TCP:
2619baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        addr = (struct sockaddr *) &local_addr_in;
2629baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        len = sizeof(local_addr_in);
2639baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        break;
2649baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    }
2659baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
2669baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: connect(%d)\n", gettid(), fd);
2679baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    ret = connect(fd, addr, len);
2689baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: connect(%d) = %d\n", gettid(), fd, ret);
2699baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
2709baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
2719baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return ret;
2729baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
2739baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
2749baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic int _write(int fd, int type) {
2759baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int ret;
2769baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    char buf = 69;
2779baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
2789baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: write(%d)\n", gettid(), fd);
2799baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    ret = write(fd, &buf, 1);
2809baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: write(%d) = %d\n", gettid(), fd, ret);
2819baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
2829baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
2839baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return ret;
2849baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
2859baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
2869baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic int _shutdown(int fd, int how) {
2879baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int ret;
2889baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
2899baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: shutdown(%d)\n", gettid(), fd);
2909baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    ret = shutdown(fd, how);
2919baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: shutdown(%d) = %d\n", gettid(), fd, ret);
2929baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
2939baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
2949baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return ret;
2959baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
2969baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
2979baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic int _poll(struct pollfd *ufds, nfds_t nfds, int timeout) {
2989baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int ret;
2999baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    unsigned int i;
3009baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
3019baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: poll(", gettid());
3029baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    print_fds(ufds, nfds);
3039baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf(")\n");
3049baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    ret = poll(ufds, nfds, timeout);
3059baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: poll() = %d\n", gettid(), ret);
3069baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
3079baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (ret > 0) {
3089baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        for (i=0; i<nfds; i++) {
3099baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly            if (ufds[i].revents) {
3109baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly                printf("\tfd %d ", ufds[i].fd); print_events(ufds[i].revents);
3119baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly            }
3129baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        }
3139baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    }
3149baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return ret;
3159baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
3169baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
3179baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic void thread_delay_close(struct thread_args *args) {
3189baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: START\n", gettid());
3199baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    sleep(args->delay);
3209baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    _close(args->fd, args->type);
3219baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: END\n", gettid());
3229baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
3239baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
3249baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic void thread_poll(void *args) {
3259baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int fd = (int)args;
3269baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    struct pollfd pfd;
3279baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: START\n", gettid());
3289baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pfd.fd = fd;
3299baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pfd.events = 0;
3309baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    _poll(&pfd, 1, -1);
3319baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: END\n", gettid());
3329baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
3339baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
3349baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic void thread_read(void *args) {
3359baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int fd = (int)args;
3369baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: START\n", gettid());
3379baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    _read(fd);
3389baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: END\n", gettid());
3399baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
3409baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
3419baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic void thread_pollin(void *args) {
3429baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int fd = (int)args;
3439baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    struct pollfd pfd;
3449baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: START\n", gettid());
3459baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pfd.fd = fd;
3469baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pfd.events = POLLIN;
3479baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    _poll(&pfd, 1, -1);
3489baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: END\n", gettid());
3499baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
3509baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
3519baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic void thread_shutdown(int fd) {
3529baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: START\n", gettid());
3539baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    sleep(4);
3549baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    _shutdown(fd, SHUT_RDWR);
3559baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: END\n", gettid());
3569baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
3579baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
3589baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic void thread_accept(struct thread_args *args) {
3599baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: START\n", gettid());
3609baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    sleep(args->delay);
3619baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    _accept(args->fd, args->type);
3629baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: END\n", gettid());
3639baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
3649baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
3659baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic void thread_connect(struct thread_args *args) {
3669baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: START\n", gettid());
3679baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    sleep(args->delay);
3689baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    _connect(args->fd, args->type);
3699baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: END\n", gettid());
3709baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
3719baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
3729baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic void thread_delay_close_write(struct thread_args *args) {
3739baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: START\n", gettid());
3749baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    sleep(args->delay);
3759baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    _close(args->fd, args->type);
3769baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    sleep(args->delay);
3779baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    _write(args->fd, args->type);
3789baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: END\n", gettid());
3799baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
3809baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
3819baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic void thread_accept_write(struct thread_args *args) {
3829baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: START\n", gettid());
3839baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    sleep(args->delay);
3849baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    _accept(args->fd, args->type);
3859baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    sleep(args->delay);
3869baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    _write(args->fd, args->type);
3879baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: END\n", gettid());
3889baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
3899baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
3909baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic void thread_delay_connect(struct thread_args *args) {
3919baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: START\n", gettid());
3929baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    sleep(args->delay);
3939baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    args->fd = _socket(args->type);
3949baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    _connect(args->fd, args->type);
3959baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: END\n", gettid());
3969baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
3979baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
3989baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic int do_accept_accept_accept(int type) {
3999baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int fd;
4009baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
4019baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    fd = _socket(type);
4029baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (fd < 0) goto error;
4039baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
4049baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (_bind(fd, type) < 0) goto error;
4059baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
4069baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (_listen(fd, type) < 0) goto error;
4079baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
4089baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    while (1) {
4099baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        _accept(fd, type);
4109baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    }
4119baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
4129baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return 0;
4139baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
4149baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellyerror:
4159baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return -1;
4169baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
4179baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
4189baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic int do_accept_and_close(int type) {
4199baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int fd;
4209baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pthread_t thread;
4219baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    struct thread_args args = {-1, type, 1};
4229baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
4239baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    fd = _socket(type);
4249baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (fd < 0) goto error;
4259baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
4269baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (_bind(fd, type) < 0) goto error;
4279baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
4289baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (_listen(fd, type) < 0) goto error;
4299baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
4309baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    args.fd = fd;
4319baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pthread_create(&thread, NULL, (void *)thread_delay_close, (void *)&args);
4329baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
4339baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    _accept(fd, type);
4349baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
4359baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pthread_join(thread, NULL);
4369baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
4379baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return 0;
4389baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
4399baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellyerror:
4409baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return -1;
4419baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
4429baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
4439baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic int do_accept_shutdown(int type) {
4449baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int fd;
4459baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pthread_t thread;
4469baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    struct thread_args args = {-1, type, 0};
4479baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
4489baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    fd = _socket(type);
4499baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (fd < 0) goto error;
4509baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
4519baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (_bind(fd, type) < 0) goto error;
4529baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
4539baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (_listen(fd, type) < 0) goto error;
4549baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
4559baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    args.fd = fd;
4569baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pthread_create(&thread, NULL, (void *)thread_accept, (void *)&args);
4579baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
4589baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    sleep(4);
4599baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    _shutdown(fd, SHUT_RDWR);
4609baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
4619baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pthread_join(thread, NULL);
4629baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
4639baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    _close(fd, type);
4649baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
4659baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return 0;
4669baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
4679baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellyerror:
4689baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return -1;
4699baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
4709baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
4719baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic int do_connect_shutdown(int type) {
4729baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int fd;
4739baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pthread_t thread;
4749baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    struct thread_args args = {-1, type, 0};
4759baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
4769baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    fd = _socket(type);
4779baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (fd < 0) goto error;
4789baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
4799baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    args.fd = fd;
4809baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pthread_create(&thread, NULL, (void *)thread_connect, (void *)&args);
4819baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
4829baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    sleep(4);
4839baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    _shutdown(fd, SHUT_RDWR);
4849baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
4859baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pthread_join(thread, NULL);
4869baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
4879baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    _close(fd, type);
4889baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
4899baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return 0;
4909baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
4919baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellyerror:
4929baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return -1;
4939baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
4949baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
4959baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly// accept in one thread. close then write in another
4969baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic int do_accept_close_write(int type) {
4979baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int fd;
4989baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pthread_t thread;
4999baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    struct thread_args args = {-1, type, 1};
5009baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5019baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    fd = _socket(type);
5029baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (fd < 0) goto error;
5039baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5049baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (_bind(fd, type) < 0) goto error;
5059baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5069baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (_listen(fd, type) < 0) goto error;
5079baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5089baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    args.fd = fd;
5099baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pthread_create(&thread, NULL, (void *)thread_delay_close_write, (void *)&args);
5109baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5119baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    _accept(fd, type);
5129baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5139baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pthread_join(thread, NULL);
5149baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5159baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return 0;
5169baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5179baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellyerror:
5189baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return -1;
5199baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
5209baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5219baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic int do_poll_poll_poll_shutdown(int type) {
5229baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    const int MAX_T = 32;
5239baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int fd;
5249baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pthread_t t[MAX_T];
5259baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int i;
5269baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5279baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    fd = _socket(type);
5289baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5299baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    for (i=0; i<MAX_T; i++)
5309baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        pthread_create(&t[i], NULL, (void *)thread_poll, (void *)fd);
5319baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5329baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    sleep(1);
5339baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5349baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    _shutdown(fd, SHUT_RDWR);
5359baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5369baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    for (i=0; i<MAX_T; i++)
5379baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        pthread_join(t[i], NULL);
5389baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5399baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    _close(fd, type);
5409baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5419baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return 0;
5429baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
5439baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5449baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic int do_poll_poll_poll_close(int type) {
5459baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    const int MAX_T = 32;
5469baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int fd;
5479baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pthread_t t[MAX_T];
5489baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int i;
5499baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5509baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    fd = _socket(type);
5519baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5529baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    for (i=0; i<MAX_T; i++)
5539baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        pthread_create(&t[i], NULL, (void *)thread_poll, (void *)fd);
5549baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5559baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    sleep(1);
5569baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5579baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    _close(fd, type);
5589baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5599baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    for (i=0; i<MAX_T; i++)
5609baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        pthread_join(t[i], NULL);
5619baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5629baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return 0;
5639baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
5649baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5659baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic int do_read_read_read_close(int type) {
5669baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    const int MAX_T = 32;
5679baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int fd;
5689baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pthread_t t[MAX_T];
5699baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int i;
5709baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5719baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    fd = _socket(type);
5729baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5739baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    for (i=0; i<MAX_T; i++)
5749baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        pthread_create(&t[i], NULL, (void *)thread_read, (void *)fd);
5759baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5769baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    sleep(1);
5779baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5789baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    _close(fd, type);
5799baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5809baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    for (i=0; i<MAX_T; i++)
5819baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        pthread_join(t[i], NULL);
5829baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5839baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return 0;
5849baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
5859baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5869baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic int do_read_read_read_shutdown(int type) {
5879baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    const int MAX_T = 32;
5889baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int fd;
5899baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pthread_t t[MAX_T];
5909baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int i;
5919baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5929baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    fd = _socket(type);
5939baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5949baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    for (i=0; i<MAX_T; i++)
5959baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        pthread_create(&t[i], NULL, (void *)thread_read, (void *)fd);
5969baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5979baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    sleep(1);
5989baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
5999baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    _shutdown(fd, SHUT_RDWR);
6009baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
6019baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    for (i=0; i<MAX_T; i++)
6029baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        pthread_join(t[i], NULL);
6039baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
6049baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    _close(fd, type);
6059baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
6069baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return 0;
6079baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
6089baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
6099baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic int do_connected_read1_shutdown1(int type) {
6109baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int fd1, fd2;
6119baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pthread_t t1;
6129baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pthread_t t2;
6139baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    struct thread_args a1 = {-1, type, 0};
6149baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    struct thread_args a2 = {-1, type, 2};
6159baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
6169baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    fd1 = _socket(type);
6179baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (fd1 < 0) goto error;
6189baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
6199baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (_bind(fd1, type) < 0) goto error;
6209baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
6219baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (_listen(fd1, type) < 0) goto error;
6229baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
6239baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    a1.fd = fd1;
6249baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pthread_create(&t1, NULL, (void *)thread_accept_write, (void *)&a1);
6259baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
6269baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    fd2 = _socket(type);
6279baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (_connect(fd2, type)) goto error;
6289baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
6299baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pthread_create(&t2, NULL, (void *)thread_shutdown, (void *)&fd2);
6309baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
6319baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    while (1) if (_read(fd2)) break;
6329baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
6339baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pthread_join(t1, NULL);
6349baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pthread_join(t2, NULL);
6359baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
6369baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return 0;
6379baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
6389baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellyerror:
6399baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return -1;
6409baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
6419baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
6429baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly// accept in one thread, connect from two different threads
6439baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic int do_accept_connect_connect(int type) {
6449baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int fd;
6459baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pthread_t t1;
6469baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pthread_t t2;
6479baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    struct thread_args a1 = {-1, type, 1};
6489baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    struct thread_args a2 = {-1, type, 2};
6499baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
6509baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    fd = _socket(type);
6519baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (fd < 0) goto error;
6529baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
6539baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (_bind(fd, type) < 0) goto error;
6549baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
6559baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (_listen(fd, type) < 0) goto error;
6569baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
6579baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pthread_create(&t1, NULL, (void *)thread_delay_connect, (void *)&a1);
6589baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pthread_create(&t2, NULL, (void *)thread_delay_connect, (void *)&a2);
6599baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
6609baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    _accept(fd, type);
6619baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
6629baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pthread_join(t1, NULL);
6639baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pthread_join(t2, NULL);
6649baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
6659baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return 0;
6669baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
6679baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellyerror:
6689baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return -1;
6699baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
6709baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
6719baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystruct {
6729baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    char *name;
6739baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int (*ptr)(int);
6749baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly} action_table[]  = {
6759baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    {"accept_accept_accept", do_accept_accept_accept},
6769baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    {"accept_and_close", do_accept_and_close},
6779baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    {"accept_shutdown", do_accept_shutdown},
6789baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    {"connect_shutdown", do_connect_shutdown},
6799baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    {"accept_close_write", do_accept_close_write},
6809baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    {"accept_connect_connect", do_accept_connect_connect},
6819baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    {"poll_poll_poll_shutdown", do_poll_poll_poll_shutdown},
6829baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    {"poll_poll_poll_close", do_poll_poll_poll_close},
6839baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    {"read_read_read_shutdown", do_read_read_read_shutdown},
6849baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    {"read_read_read_close", do_read_read_read_close},
6859baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    {"connected_read1_shutdown1", do_connected_read1_shutdown1},
6869baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    {NULL, NULL},
6879baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly};
6889baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
6899baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystruct {
6909baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    char *name;
6919baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    enum sock_type type;
6929baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly} type_table[]  = {
6939baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    {"unix", UNIX},
6949baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    {"rfcomm", RFCOMM},
6959baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    {"sco", SCO},
6969baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    {"l2cap", L2CAP},
6979baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    {"tcp", TCP},
6989baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    {NULL, -1},
6999baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly};
7009baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
7019baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic void usage() {
7029baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int i;
7039baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
7049baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("socktest TYPE ACTION\n");
7059baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("\nTYPE:\n");
7069baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    for (i = 0; type_table[i].name; i++) {
7079baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        printf("\t%s\n", type_table[i].name);
7089baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    }
7099baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("\nACTION:\n");
7109baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    for (i = 0; action_table[i].name; i++) {
7119baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        printf("\t%s\n", action_table[i].name);
7129baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    }
7139baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
7149baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
7159baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellyint main(int argc, char **argv) {
7169baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int i;
7179baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int type = -1;
7189baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
7199baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (argc != 3) {
7209baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        usage();
7219baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        return -1;
7229baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    }
7239baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    for (i = 0; type_table[i].name; i++) {
7249baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        if (!strcmp(argv[1], type_table[i].name)) {
7259baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly            type = type_table[i].type;
7269baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly            break;
7279baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        }
7289baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    }
7299baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (type == -1) {
7309baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        usage();
7319baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        return -1;
7329baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    }
7339baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    for (i = 0; action_table[i].name; i++) {
7349baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        if (!strcmp(argv[2], action_table[i].name)) {
7359baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly            printf("TYPE = %s ACTION = %s\n", type_table[type].name,
7369baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly                    action_table[i].name);
7379baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly            return (*action_table[i].ptr)(type);
7389baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        }
7399baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    }
7409baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    usage();
7419baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return -1;
7429baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
743