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