sock_shutdown_test.c revision 47653588a022190d4b3e20194ef643dfb7b90632
147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly/*
247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly** Copyright 2009 The Android Open Source Project
347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly**
447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly** Licensed under the Apache License, Version 2.0 (the "License");
547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly** you may not use this file except in compliance with the License.
647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly** You may obtain a copy of the License at
747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly**
847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly**     http://www.apache.org/licenses/LICENSE-2.0
947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly**
1047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly** Unless required by applicable law or agreed to in writing, software
1147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly** distributed under the License is distributed on an "AS IS" BASIS,
1247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly** See the License for the specific language governing permissions and
1447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly** limitations under the License.
1547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly*/
1647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
1747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly/** socket testing  */
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    SOCKETPAIR,
4847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly};
4947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
5047653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic void print_events(int events) {
5147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (events & POLLIN) printf("POLLIN ");
5247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (events & POLLPRI) printf("POLLPRI ");
5347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (events & POLLOUT) printf("POLLOUT ");
5447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (events & POLLERR) printf("POLLERR ");
5547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (events & POLLHUP) printf("POLLHUP ");
5647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (events & POLLNVAL) printf("POLLNVAL ");
5747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("\n");
5847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
5947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
6047653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic void print_fds(struct pollfd *ufds, nfds_t nfds) {
6147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    unsigned int i;
6247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    for (i=0; i<nfds; i++)
6347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        printf("%d ", ufds[i].fd);
6447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
6547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
6647653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int _socket(int type) {
6747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int ret;
6847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int family = -1;
6947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int typ = -1;
7047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int protocol = -1;
7147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
7247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    switch (type) {
7347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    case UNIX:
7447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        family = PF_UNIX;
7547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        typ = SOCK_STREAM;
7647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        protocol = 0;
7747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        break;
7847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    case RFCOMM:
7947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        family = PF_BLUETOOTH;
8047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        typ = SOCK_STREAM;
8147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        protocol = BTPROTO_RFCOMM;
8247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        break;
8347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    case SCO:
8447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        family = PF_BLUETOOTH;
8547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        typ = SOCK_SEQPACKET;
8647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        protocol = BTPROTO_SCO;
8747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        break;
8847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    case L2CAP:
8947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        family = PF_BLUETOOTH;
9047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        typ = SOCK_SEQPACKET;
9147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        protocol = BTPROTO_L2CAP;
9247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        break;
9347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    case TCP:
9447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        family = PF_INET;
9547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        typ = SOCK_STREAM;
9647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        protocol = 0;
9747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        break;
9847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    case SOCKETPAIR:
9947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        {
10047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly            int fd[2];
10147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly            printf("%d: socketpair()\n", gettid());
10247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly            ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
10347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly            printf("%d: socketpair() = %d\n", gettid(), ret);
10447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly            if (ret) {
10547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly                printf("\terr %d (%s)\n", errno, strerror(errno));
10647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly                return -1;
10747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly            }
10847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly            return fd[0];
10947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        }
11047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    }
11147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
11247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: socket()\n", gettid());
11347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    ret = socket(family, typ, protocol);
11447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: socket() = %d\n", gettid(), ret);
11547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
11647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
11747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return ret;
11847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
11947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
12047653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int _close(int fd) {
12147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int ret;
12247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
12347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: close(%d)\n", gettid(), fd);
12447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    ret = close(fd);
12547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: close(%d) = %d\n", gettid(), fd, ret);
12647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
12747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
12847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return ret;
12947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
13047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
13147653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int _shutdown(int fd) {
13247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int ret;
13347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
13447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: shutdown(%d)\n", gettid(), fd);
13547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    ret = shutdown(fd, SHUT_RDWR);
13647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: shutdown(%d) = %d\n", gettid(), fd, ret);
13747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
13847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
13947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return ret;
14047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
14147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
14247653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int _poll(struct pollfd *ufds, nfds_t nfds, int timeout) {
14347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int ret;
14447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    unsigned int i;
14547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
14647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: poll(", gettid());
14747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    print_fds(ufds, nfds);
14847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf(")\n");
14947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    ret = poll(ufds, nfds, timeout);
15047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: poll() = %d\n", gettid(), ret);
15147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
15247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (ret > 0) {
15347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        for (i=0; i<nfds; i++) {
15447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly            if (ufds[i].revents) {
15547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly                printf("\tfd %d ", ufds[i].fd); print_events(ufds[i].revents);
15647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly            }
15747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        }
15847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    }
15947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return ret;
16047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
16147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
16247653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic void thread_poll(int fd) {
16347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    struct pollfd pfd;
16447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: START\n", gettid());
16547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pfd.fd = fd;
16647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pfd.events = 0;
16747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _poll(&pfd, 1, -1);
16847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: END\n", gettid());
16947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
17047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
17147653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int do_poll_shutdown(int type) {
17247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    const int MAX_T = 2;
17347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int fd;
17447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_t t[MAX_T];
17547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int i;
17647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
17747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    fd = _socket(type);
17847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
17947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    for (i=0; i<MAX_T; i++)
18047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        pthread_create(&t[i], NULL, (void *)thread_poll, (void *)fd);
18147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
18247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    sleep(1);
18347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
18447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _shutdown(fd);
18547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
18647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    for (i=0; i<MAX_T; i++)
18747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        pthread_join(t[i], NULL);
18847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
18947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _close(fd);
19047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
19147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return 0;
19247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
19347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
19447653588a022190d4b3e20194ef643dfb7b90632Nick Pellystruct {
19547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    char *name;
19647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    enum sock_type type;
19747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly} type_table[]  = {
19847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    {"unix", UNIX},
19947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    {"rfcomm", RFCOMM},
20047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    {"sco", SCO},
20147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    {"l2cap", L2CAP},
20247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    {"tcp", TCP},
20347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    {"socketpair", SOCKETPAIR},
20447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    {NULL, -1},
20547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly};
20647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
20747653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic void usage() {
20847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int i;
20947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
21047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("sock_shutdown_test TYPE\n");
21147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("\nTYPE:\n");
21247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    for (i = 0; type_table[i].name; i++) {
21347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        printf("\t%s\n", type_table[i].name);
21447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    }
21547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
21647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
21747653588a022190d4b3e20194ef643dfb7b90632Nick Pellyint main(int argc, char **argv) {
21847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int i;
21947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int type = -1;
22047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
22147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (argc != 2) {
22247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        usage();
22347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        return -1;
22447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    }
22547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    for (i = 0; type_table[i].name; i++) {
22647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        if (!strcmp(argv[1], type_table[i].name)) {
22747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly            type = type_table[i].type;
22847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly            printf("TYPE = %s\n", type_table[type].name);
22947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly            return do_poll_shutdown(type);
23047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        }
23147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    }
23247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    usage();
23347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return -1;
23447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
235