110d31b957a35d4ac084be33b0f136568039c9c14Nick Pelly/*
210d31b957a35d4ac084be33b0f136568039c9c14Nick Pelly** Copyright 2009 The Android Open Source Project
310d31b957a35d4ac084be33b0f136568039c9c14Nick Pelly**
410d31b957a35d4ac084be33b0f136568039c9c14Nick Pelly** Licensed under the Apache License, Version 2.0 (the "License");
510d31b957a35d4ac084be33b0f136568039c9c14Nick Pelly** you may not use this file except in compliance with the License.
610d31b957a35d4ac084be33b0f136568039c9c14Nick Pelly** You may obtain a copy of the License at
710d31b957a35d4ac084be33b0f136568039c9c14Nick Pelly**
810d31b957a35d4ac084be33b0f136568039c9c14Nick Pelly**     http://www.apache.org/licenses/LICENSE-2.0
910d31b957a35d4ac084be33b0f136568039c9c14Nick Pelly**
1010d31b957a35d4ac084be33b0f136568039c9c14Nick Pelly** Unless required by applicable law or agreed to in writing, software
1110d31b957a35d4ac084be33b0f136568039c9c14Nick Pelly** distributed under the License is distributed on an "AS IS" BASIS,
1210d31b957a35d4ac084be33b0f136568039c9c14Nick Pelly** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1310d31b957a35d4ac084be33b0f136568039c9c14Nick Pelly** See the License for the specific language governing permissions and
1410d31b957a35d4ac084be33b0f136568039c9c14Nick Pelly** limitations under the License.
1510d31b957a35d4ac084be33b0f136568039c9c14Nick Pelly*/
1610d31b957a35d4ac084be33b0f136568039c9c14Nick Pelly
179baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly/** testing behavior of shutdown() */
1847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
1947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly#include <stdlib.h>
2047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly#include <stdio.h>
2147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly#include <errno.h>
2247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly#include <sys/uio.h>
2347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly#include <unistd.h>
2447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
2547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly#include <pthread.h>
2647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly#include <stdio.h>
2747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly#include <stdlib.h>
2847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly#include <errno.h>
2947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly#include <unistd.h>
3047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly#include <sys/socket.h>
3147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly#include <sys/ioctl.h>
3247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly#include <sys/poll.h>
3347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly#include <sys/un.h>
3447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly#include <netinet/in.h>
3547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
3647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly#include <bluetooth/bluetooth.h>
3747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly#include <bluetooth/rfcomm.h>
3847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly#include <bluetooth/sco.h>
3947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly#include <bluetooth/l2cap.h>
4047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
4147653588a022190d4b3e20194ef643dfb7b90632Nick Pellyenum sock_type {
4247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    UNIX = 0,
4347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    RFCOMM,
4447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    SCO,
4547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    L2CAP,
4647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    TCP,
4747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly};
4847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
499baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystruct thread_args {
509baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int fd;
519baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int type;
529baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int delay;
539baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly};
5447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
559baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystruct sockaddr_un  local_addr_un  = {AF_UNIX, "/tmp/foo"};
569baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystruct sockaddr_rc  local_addr_rc  = {AF_BLUETOOTH, *BDADDR_ANY, 4};
579baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystruct sockaddr_sco local_addr_sco = {AF_BLUETOOTH, *BDADDR_LOCAL};
589baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystruct sockaddr_l2  local_addr_l2  = {AF_BLUETOOTH, htobs(0x1001), *BDADDR_ANY, 0};
599baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystruct sockaddr_in  local_addr_in  = {AF_INET, 9999, {0}, {0}};
609baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
619baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystruct sockaddr_un  remote_addr_un  ;
629baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystruct sockaddr_rc  remote_addr_rc  ;
639baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystruct sockaddr_sco remote_addr_sco ;
649baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystruct sockaddr_l2  remote_addr_l2  ;
659baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystruct sockaddr_in  remote_addr_in  ;
6647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
6747653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int _socket(int type) {
6847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int ret;
6947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int family = -1;
7047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int typ = -1;
7147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int protocol = -1;
7247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
7347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    switch (type) {
7447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    case UNIX:
7547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        family = PF_UNIX;
7647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        typ = SOCK_STREAM;
7747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        protocol = 0;
7847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        break;
7947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    case RFCOMM:
8047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        family = PF_BLUETOOTH;
8147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        typ = SOCK_STREAM;
8247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        protocol = BTPROTO_RFCOMM;
8347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        break;
8447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    case SCO:
8547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        family = PF_BLUETOOTH;
8647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        typ = SOCK_SEQPACKET;
8747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        protocol = BTPROTO_SCO;
8847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        break;
8947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    case L2CAP:
9047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        family = PF_BLUETOOTH;
9147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        typ = SOCK_SEQPACKET;
9247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        protocol = BTPROTO_L2CAP;
9347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        break;
9447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    case TCP:
9547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        family = PF_INET;
9647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        typ = SOCK_STREAM;
9747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        protocol = 0;
9847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        break;
9947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    }
10047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
10147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: socket()\n", gettid());
10247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    ret = socket(family, typ, protocol);
10347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: socket() = %d\n", gettid(), ret);
10447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
10547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
10647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return ret;
10747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
10847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
10947653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int _close(int fd) {
11047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int ret;
11147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
11247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: close(%d)\n", gettid(), fd);
11347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    ret = close(fd);
11447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: close(%d) = %d\n", gettid(), fd, ret);
11547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
11647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
11747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return ret;
11847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
11947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
1209baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic int _bind(int fd, int type) {
1219baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int len = 0;
12247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int ret;
1239baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    struct sockaddr *addr = NULL;
12447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
1259baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    switch (type) {
1269baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    case UNIX:
1279baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        unlink(local_addr_un.sun_path);
1289baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        addr = (struct sockaddr *) &local_addr_un;
1299baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        len = sizeof(local_addr_un);
1309baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        break;
1319baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    case RFCOMM:
1329baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        addr = (struct sockaddr *) &local_addr_rc;
1339baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        len = sizeof(local_addr_rc);
1349baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        break;
1359baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    case SCO:
1369baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        addr = (struct sockaddr *) &local_addr_sco;
1379baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        len = sizeof(local_addr_sco);
1389baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        break;
1399baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    case L2CAP:
1409baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        addr = (struct sockaddr *) &local_addr_l2;
1419baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        len = sizeof(local_addr_l2);
1429baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        break;
1439baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    case TCP:
1449baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        addr = (struct sockaddr *) &local_addr_in;
1459baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        len = sizeof(local_addr_in);
1469baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        break;
1479baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    }
1489baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
1499baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: bind(%d)\n", gettid(), fd);
1509baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    ret = bind(fd, addr, len);
1519baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: bind(%d) = %d\n", gettid(), fd, ret);
15247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
15347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
15447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return ret;
15547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
15647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
1579baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic int _listen(int fd, int type) {
15847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int ret;
15947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
1609baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: listen(%d)\n", gettid(), fd);
1619baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    ret = listen(fd, 1);
1629baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: listen(%d) = %d\n", gettid(), fd, ret);
16347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
1649baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
1659baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return ret;
1669baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
1679baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
1689baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic int _accept(int fd, int type) {
1699baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int ret;
1709baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int len;
1719baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    struct sockaddr *addr = NULL;
1729baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
1739baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    switch (type) {
1749baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    case UNIX:
1759baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        addr = (struct sockaddr *) &remote_addr_un;
1769baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        len = sizeof(remote_addr_un);
1779baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        break;
1789baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    case RFCOMM:
1799baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        addr = (struct sockaddr *) &remote_addr_rc;
1809baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        len = sizeof(remote_addr_rc);
1819baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        break;
1829baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    case SCO:
1839baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        addr = (struct sockaddr *) &remote_addr_sco;
1849baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        len = sizeof(remote_addr_sco);
1859baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        break;
1869baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    case L2CAP:
1879baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        addr = (struct sockaddr *) &remote_addr_l2;
1889baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        len = sizeof(remote_addr_l2);
1899baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        break;
1909baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    case TCP:
1919baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        addr = (struct sockaddr *) &remote_addr_in;
1929baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        len = sizeof(remote_addr_in);
1939baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        break;
1949baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    }
1959baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
1969baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: accept(%d)\n", gettid(), fd);
1979baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    ret = accept(fd, addr, &len);
1989baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: accept(%d) = %d\n", gettid(), fd, ret);
1999baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
2009baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    else {
2019baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        printf("\tlen = %d\n", len);
20247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    }
2039baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
20447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return ret;
20547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
20647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
2079baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic int _shutdown(int fd, int how) {
2089baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int ret;
2099baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
2109baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: shutdown(%d)\n", gettid(), fd);
2119baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    ret = shutdown(fd, how);
2129baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("%d: shutdown(%d) = %d\n", gettid(), fd, ret);
2139baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
2149baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
2159baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return ret;
2169baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly}
2179baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
2189baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic void thread_accept(struct thread_args *args) {
21947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: START\n", gettid());
2209baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    sleep(args->delay);
2219baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    _accept(args->fd, args->type);
22247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: END\n", gettid());
22347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
22447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
2259baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystatic int do_accept_shutdown(int type) {
22647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int fd;
2279baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pthread_t thread;
2289baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    struct thread_args args = {-1, type, 0};
22947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
23047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    fd = _socket(type);
2319baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (fd < 0) goto error;
2329baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
2339baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (_bind(fd, type) < 0) goto error;
23447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
2359baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (_listen(fd, type) < 0) goto error;
23647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
2379baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    args.fd = fd;
2389baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pthread_create(&thread, NULL, (void *)thread_accept, (void *)&args);
23947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
2409baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    sleep(2);
2419baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    _shutdown(fd, SHUT_RDWR);
24247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
2439baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    pthread_join(thread, NULL);
24447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
24547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _close(fd);
24647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
24747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return 0;
2489baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
2499baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellyerror:
2509baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    return -1;
25147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
25247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
25347653588a022190d4b3e20194ef643dfb7b90632Nick Pellystruct {
25447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    char *name;
2559baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    int (*ptr)(int);
2569baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly} action_table[]  = {
2579baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    {"accept_shutdown", do_accept_shutdown},
2589baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    {NULL, NULL},
2599baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly};
2609baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly
2619baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pellystruct {
2629baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    char *name;
26347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    enum sock_type type;
26447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly} type_table[]  = {
26547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    {"unix", UNIX},
26647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    {"rfcomm", RFCOMM},
26747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    {"sco", SCO},
26847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    {"l2cap", L2CAP},
26947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    {"tcp", TCP},
27047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    {NULL, -1},
27147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly};
27247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
27347653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic void usage() {
27447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int i;
27547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
2769baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("sock_shutdown_test TYPE ACTION\n");
27747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("\nTYPE:\n");
27847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    for (i = 0; type_table[i].name; i++) {
27947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        printf("\t%s\n", type_table[i].name);
28047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    }
2819baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    printf("\nACTION:\n");
2829baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    for (i = 0; action_table[i].name; i++) {
2839baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        printf("\t%s\n", action_table[i].name);
2849baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    }
28547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
28647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
28747653588a022190d4b3e20194ef643dfb7b90632Nick Pellyint main(int argc, char **argv) {
28847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int i;
28947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int type = -1;
29047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
2919baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (argc != 3) {
29247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        usage();
29347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        return -1;
29447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    }
29547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    for (i = 0; type_table[i].name; i++) {
29647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        if (!strcmp(argv[1], type_table[i].name)) {
29747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly            type = type_table[i].type;
2989baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly            break;
2999baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        }
3009baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    }
3019baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    if (type == -1) {
3029baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        usage();
3039baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        return -1;
3049baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    }
3059baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly    for (i = 0; action_table[i].name; i++) {
3069baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly        if (!strcmp(argv[2], action_table[i].name)) {
3079baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly            printf("TYPE = %s ACTION = %s\n", type_table[type].name,
3089baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly                    action_table[i].name);
3099baad993d9788e544c3a30fcc5dae23fe8b1d074Nick Pelly            return (*action_table[i].ptr)(type);
31047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        }
31147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    }
31247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    usage();
31347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return -1;
31447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
315