socktest.c revision 47653588a022190d4b3e20194ef643dfb7b90632
1b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly/* 2b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly** Copyright 2009 The Android Open Source Project 3b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly** 4b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly** Licensed under the Apache License, Version 2.0 (the "License"); 5b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly** you may not use this file except in compliance with the License. 6b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly** You may obtain a copy of the License at 7b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly** 8b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly** http://www.apache.org/licenses/LICENSE-2.0 9b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly** 10b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly** Unless required by applicable law or agreed to in writing, software 11b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly** distributed under the License is distributed on an "AS IS" BASIS, 12b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly** See the License for the specific language governing permissions and 14b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly** limitations under the License. 15b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly*/ 16b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 17b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly/** socket testing */ 18b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 19b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <stdlib.h> 20b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <stdio.h> 21b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <errno.h> 22b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <sys/uio.h> 23b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <unistd.h> 24b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 25b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <pthread.h> 26b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <stdio.h> 27b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <stdlib.h> 28b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <errno.h> 29b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <unistd.h> 30b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <sys/socket.h> 31b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <sys/ioctl.h> 3247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly#include <sys/poll.h> 33b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <sys/un.h> 34b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <netinet/in.h> 35b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 36b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <bluetooth/bluetooth.h> 37b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <bluetooth/rfcomm.h> 38b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <bluetooth/sco.h> 39b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly#include <bluetooth/l2cap.h> 40b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 41b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellyenum sock_type { 42b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly UNIX = 0, 43b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly RFCOMM, 44b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly SCO, 45b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly L2CAP, 46b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly TCP, 47b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly}; 48b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 49b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystruct thread_args { 50b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly int fd; 51b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly int type; 523f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly int delay; 53b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly}; 54b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 55b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystruct sockaddr_un local_addr_un = {AF_UNIX, "/data/foo"}; 563f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pellystruct sockaddr_rc local_addr_rc = {AF_BLUETOOTH, *BDADDR_ANY, 4}; 573f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pellystruct sockaddr_sco local_addr_sco = {AF_BLUETOOTH, *BDADDR_LOCAL}; 58b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystruct sockaddr_l2 local_addr_l2 = {AF_BLUETOOTH, htobs(0x1001), *BDADDR_ANY, 0}; 59b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystruct sockaddr_in local_addr_in = {AF_INET, 9999, {0}, {0}}; 60b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 61b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystruct sockaddr_un remote_addr_un ; 62b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystruct sockaddr_rc remote_addr_rc ; 63b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystruct sockaddr_sco remote_addr_sco ; 64b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystruct sockaddr_l2 remote_addr_l2 ; 65b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystruct sockaddr_in remote_addr_in ; 66b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 6747653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic void print_events(int events) { 6847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly if (events & POLLIN) printf("POLLIN "); 6947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly if (events & POLLPRI) printf("POLLPRI "); 7047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly if (events & POLLOUT) printf("POLLOUT "); 7147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly if (events & POLLERR) printf("POLLERR "); 7247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly if (events & POLLHUP) printf("POLLHUP "); 7347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly if (events & POLLNVAL) printf("POLLNVAL "); 7447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly printf("\n"); 7547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly} 7647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 7747653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic void print_fds(struct pollfd *ufds, nfds_t nfds) { 7847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly unsigned int i; 7947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly for (i=0; i<nfds; i++) 8047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly printf("%d ", ufds[i].fd); 8147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly} 8247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 83b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystatic int _socket(int type) { 84b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly int ret; 85b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly int family = -1; 86b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly int typ = -1; 87b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly int protocol = -1; 88b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 89b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly switch (type) { 90b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly case UNIX: 91b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly family = PF_UNIX; 92b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly typ = SOCK_STREAM; 93b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly protocol = 0; 94b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly break; 95b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly case RFCOMM: 96b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly family = PF_BLUETOOTH; 97b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly typ = SOCK_STREAM; 98b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly protocol = BTPROTO_RFCOMM; 99b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly break; 100b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly case SCO: 101b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly family = PF_BLUETOOTH; 102b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly typ = SOCK_SEQPACKET; 103b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly protocol = BTPROTO_SCO; 104b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly break; 105b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly case L2CAP: 106b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly family = PF_BLUETOOTH; 107b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly typ = SOCK_SEQPACKET; 108b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly protocol = BTPROTO_L2CAP; 109b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly break; 110b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly case TCP: 111b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly family = PF_INET; 112b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly typ = SOCK_STREAM; 113b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly protocol = 0; 114b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly break; 115b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly } 116b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 117b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly printf("%d: socket()\n", gettid()); 118b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly ret = socket(family, typ, protocol); 119b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly printf("%d: socket() = %d\n", gettid(), ret); 120b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno)); 121b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 122b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly return ret; 123b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly} 124b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 125b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystatic int _close(int fd, int type) { 126b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly int ret; 127b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 128b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly printf("%d: close(%d)\n", gettid(), fd); 129b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly ret = close(fd); 130b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly printf("%d: close(%d) = %d\n", gettid(), fd, ret); 131b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno)); 132b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 133b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly return ret; 134b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly} 135b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 136b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystatic int _bind(int fd, int type) { 137b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly int len = 0; 138b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly int ret; 139b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly struct sockaddr *addr = NULL; 140b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 141b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly switch (type) { 142b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly case UNIX: 143b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly unlink(local_addr_un.sun_path); 144b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly addr = (struct sockaddr *) &local_addr_un; 145b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly len = sizeof(local_addr_un); 146b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly break; 147b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly case RFCOMM: 148b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly addr = (struct sockaddr *) &local_addr_rc; 149b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly len = sizeof(local_addr_rc); 150b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly break; 151b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly case SCO: 152b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly addr = (struct sockaddr *) &local_addr_sco; 153b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly len = sizeof(local_addr_sco); 154b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly break; 155b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly case L2CAP: 156b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly addr = (struct sockaddr *) &local_addr_l2; 157b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly len = sizeof(local_addr_l2); 158b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly break; 159b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly case TCP: 160b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly addr = (struct sockaddr *) &local_addr_in; 161b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly len = sizeof(local_addr_in); 162b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly break; 163b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly } 164b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 165b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly printf("%d: bind(%d)\n", gettid(), fd); 166b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly ret = bind(fd, addr, len); 167b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly printf("%d: bind(%d) = %d\n", gettid(), fd, ret); 168b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno)); 169b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 170b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly return ret; 171b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly} 172b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 173b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystatic int _listen(int fd, int type) { 174b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly int ret; 175b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 176b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly printf("%d: listen(%d)\n", gettid(), fd); 177b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly ret = listen(fd, 1); 178b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly printf("%d: listen(%d) = %d\n", gettid(), fd, ret); 179b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno)); 180b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 181b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly return ret; 182b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly} 183b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 18447653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int _read(int fd) { 18547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly int ret; 18647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly char buf; 18747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 18847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly printf("%d: read(%d)\n", gettid(), fd); 18947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly ret = read(fd, &buf, 1); 19047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly printf("%d: read(%d) = %d [%d]\n", gettid(), fd, ret, (int)buf); 19147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno)); 19247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 19347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly return ret; 19447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly} 19547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 19647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 197b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystatic int _accept(int fd, int type) { 198b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly int ret; 199b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly int len; 200b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly struct sockaddr *addr = NULL; 201b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 202b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly switch (type) { 203b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly case UNIX: 204b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly addr = (struct sockaddr *) &remote_addr_un; 205b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly len = sizeof(remote_addr_un); 206b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly break; 207b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly case RFCOMM: 208b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly addr = (struct sockaddr *) &remote_addr_rc; 209b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly len = sizeof(remote_addr_rc); 210b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly break; 211b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly case SCO: 212b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly addr = (struct sockaddr *) &remote_addr_sco; 213b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly len = sizeof(remote_addr_sco); 214b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly break; 215b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly case L2CAP: 216b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly addr = (struct sockaddr *) &remote_addr_l2; 217b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly len = sizeof(remote_addr_l2); 218b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly break; 219b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly case TCP: 220b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly addr = (struct sockaddr *) &remote_addr_in; 221b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly len = sizeof(remote_addr_in); 222b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly break; 223b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly } 224b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 225b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly printf("%d: accept(%d)\n", gettid(), fd); 226b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly ret = accept(fd, addr, &len); 227b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly printf("%d: accept(%d) = %d\n", gettid(), fd, ret); 228b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno)); 229b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly else { 230b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly printf("\tlen = %d\n", len); 231b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly } 232b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 233b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly return ret; 234b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly} 235b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 236b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystatic int _connect(int fd, int type) { 237b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly int ret; 2383f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly int len = 0; 239b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly struct sockaddr *addr = NULL; 240b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 241b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly switch (type) { 242b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly case UNIX: 243b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly addr = (struct sockaddr *) &local_addr_un; 244b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly len = sizeof(local_addr_un); 245b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly break; 246b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly case RFCOMM: 247b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly addr = (struct sockaddr *) &local_addr_rc; 248b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly len = sizeof(local_addr_rc); 249b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly break; 250b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly case SCO: 251b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly addr = (struct sockaddr *) &local_addr_sco; 252b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly len = sizeof(local_addr_sco); 253b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly break; 254b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly case L2CAP: 255b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly addr = (struct sockaddr *) &local_addr_l2; 256b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly len = sizeof(local_addr_l2); 257b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly break; 258b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly case TCP: 259b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly addr = (struct sockaddr *) &local_addr_in; 260b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly len = sizeof(local_addr_in); 261b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly break; 262b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly } 263b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 264b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly printf("%d: connect(%d)\n", gettid(), fd); 265b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly ret = connect(fd, addr, len); 266b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly printf("%d: connect(%d) = %d\n", gettid(), fd, ret); 267b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno)); 268b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 269b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly return ret; 270b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly} 271b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 272b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystatic int _write(int fd, int type) { 273b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly int ret; 27447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly char buf = 69; 275b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 276b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly printf("%d: write(%d)\n", gettid(), fd); 277b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly ret = write(fd, &buf, 1); 27847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly printf("%d: write(%d) = %d\n", gettid(), fd, ret); 27947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno)); 28047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 28147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly return ret; 28247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly} 28347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 28447653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int _shutdown(int fd, int how) { 28547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly int ret; 28647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 28747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly printf("%d: shutdown(%d)\n", gettid(), fd); 28847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly ret = shutdown(fd, how); 28947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly printf("%d: shutdown(%d) = %d\n", gettid(), fd, ret); 290b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno)); 291b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 292b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly return ret; 293b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly} 294b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 29547653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int _poll(struct pollfd *ufds, nfds_t nfds, int timeout) { 29647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly int ret; 29747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly unsigned int i; 29847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 29947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly printf("%d: poll(", gettid()); 30047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly print_fds(ufds, nfds); 30147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly printf(")\n"); 30247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly ret = poll(ufds, nfds, timeout); 30347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly printf("%d: poll() = %d\n", gettid(), ret); 30447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno)); 30547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly if (ret > 0) { 30647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly for (i=0; i<nfds; i++) { 30747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly if (ufds[i].revents) { 30847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly printf("\tfd %d ", ufds[i].fd); print_events(ufds[i].revents); 30947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly } 31047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly } 31147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly } 31247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly return ret; 31347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly} 31447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 3153f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pellystatic void thread_delay_close(struct thread_args *args) { 316b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly printf("%d: START\n", gettid()); 3173f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly sleep(args->delay); 3183f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly _close(args->fd, args->type); 319b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly printf("%d: END\n", gettid()); 320b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly} 321b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 32247653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic void thread_poll(void *args) { 32347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly int fd = (int)args; 32447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly struct pollfd pfd; 32547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly printf("%d: START\n", gettid()); 32647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly pfd.fd = fd; 32747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly pfd.events = 0; 32847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly _poll(&pfd, 1, -1); 32947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly printf("%d: END\n", gettid()); 33047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly} 33147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 33247653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic void thread_read(void *args) { 33347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly int fd = (int)args; 33447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly printf("%d: START\n", gettid()); 33547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly _read(fd); 33647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly printf("%d: END\n", gettid()); 33747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly} 33847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 33947653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic void thread_pollin(void *args) { 34047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly int fd = (int)args; 34147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly struct pollfd pfd; 34247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly printf("%d: START\n", gettid()); 34347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly pfd.fd = fd; 34447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly pfd.events = POLLIN; 34547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly _poll(&pfd, 1, -1); 34647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly printf("%d: END\n", gettid()); 34747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly} 34847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 34947653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic void thread_shutdown(int fd) { 35047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly printf("%d: START\n", gettid()); 35147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly sleep(4); 35247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly _shutdown(fd, SHUT_RDWR); 35347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly printf("%d: END\n", gettid()); 35447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly} 35547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 35647653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic void thread_accept(struct thread_args *args) { 35747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly printf("%d: START\n", gettid()); 35847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly sleep(args->delay); 35947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly _accept(args->fd, args->type); 36047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly printf("%d: END\n", gettid()); 36147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly} 36247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 36347653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic void thread_connect(struct thread_args *args) { 36447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly printf("%d: START\n", gettid()); 36547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly sleep(args->delay); 36647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly _connect(args->fd, args->type); 36747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly printf("%d: END\n", gettid()); 36847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly} 36947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 3703f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pellystatic void thread_delay_close_write(struct thread_args *args) { 3713f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly printf("%d: START\n", gettid()); 3723f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly sleep(args->delay); 3733f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly _close(args->fd, args->type); 3743f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly sleep(args->delay); 3753f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly _write(args->fd, args->type); 3763f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly printf("%d: END\n", gettid()); 3773f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly} 378b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 37947653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic void thread_accept_write(struct thread_args *args) { 38047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly printf("%d: START\n", gettid()); 38147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly sleep(args->delay); 38247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly _accept(args->fd, args->type); 38347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly sleep(args->delay); 38447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly _write(args->fd, args->type); 38547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly printf("%d: END\n", gettid()); 38647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly} 38747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 3883f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pellystatic void thread_delay_connect(struct thread_args *args) { 389b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly printf("%d: START\n", gettid()); 3903f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly sleep(args->delay); 3913f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly args->fd = _socket(args->type); 3923f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly _connect(args->fd, args->type); 393b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly printf("%d: END\n", gettid()); 394b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly} 395b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 3963f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pellystatic int do_accept_accept_accept(int type) { 3973f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly int fd; 3983f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly 3993f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly fd = _socket(type); 4003f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly if (fd < 0) goto error; 4013f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly 4023f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly if (_bind(fd, type) < 0) goto error; 4033f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly 4043f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly if (_listen(fd, type) < 0) goto error; 4053f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly 4063f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly while (1) { 4073f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly _accept(fd, type); 4083f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly } 4093f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly 4103f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly return 0; 4113f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly 4123f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pellyerror: 4133f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly return -1; 4143f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly} 4153f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly 416b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystatic int do_accept_and_close(int type) { 417b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly int fd; 418b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly pthread_t thread; 4193f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly struct thread_args args = {-1, type, 1}; 420b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 421b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly fd = _socket(type); 422b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly if (fd < 0) goto error; 423b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 424b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly if (_bind(fd, type) < 0) goto error; 425b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 426b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly if (_listen(fd, type) < 0) goto error; 427b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 4283f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly args.fd = fd; 4293f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly pthread_create(&thread, NULL, (void *)thread_delay_close, (void *)&args); 430b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 431b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly _accept(fd, type); 432b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 433b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly pthread_join(thread, NULL); 434b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 435b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly return 0; 436b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 437b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellyerror: 438b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly return -1; 439b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly} 440b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 44147653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int do_accept_shutdown(int type) { 44247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly int fd; 44347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly pthread_t thread; 44447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly struct thread_args args = {-1, type, 0}; 44547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 44647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly fd = _socket(type); 44747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly if (fd < 0) goto error; 44847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 44947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly if (_bind(fd, type) < 0) goto error; 45047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 45147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly if (_listen(fd, type) < 0) goto error; 45247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 45347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly args.fd = fd; 45447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly pthread_create(&thread, NULL, (void *)thread_accept, (void *)&args); 45547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 45647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly sleep(4); 45747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly _shutdown(fd, SHUT_RDWR); 45847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 45947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly pthread_join(thread, NULL); 46047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 46147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly _close(fd, type); 46247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 46347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly return 0; 46447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 46547653588a022190d4b3e20194ef643dfb7b90632Nick Pellyerror: 46647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly return -1; 46747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly} 46847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 46947653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int do_connect_shutdown(int type) { 47047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly int fd; 47147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly pthread_t thread; 47247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly struct thread_args args = {-1, type, 0}; 47347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 47447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly fd = _socket(type); 47547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly if (fd < 0) goto error; 47647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 47747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly args.fd = fd; 47847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly pthread_create(&thread, NULL, (void *)thread_connect, (void *)&args); 47947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 48047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly sleep(4); 48147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly _shutdown(fd, SHUT_RDWR); 48247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 48347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly pthread_join(thread, NULL); 48447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 48547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly _close(fd, type); 48647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 48747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly return 0; 48847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 48947653588a022190d4b3e20194ef643dfb7b90632Nick Pellyerror: 49047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly return -1; 49147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly} 49247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 493b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly// accept in one thread. close then write in another 494b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystatic int do_accept_close_write(int type) { 495b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly int fd; 496b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly pthread_t thread; 4973f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly struct thread_args args = {-1, type, 1}; 498b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 499b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly fd = _socket(type); 500b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly if (fd < 0) goto error; 501b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 502b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly if (_bind(fd, type) < 0) goto error; 503b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 504b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly if (_listen(fd, type) < 0) goto error; 505b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 5063f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly args.fd = fd; 5073f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly pthread_create(&thread, NULL, (void *)thread_delay_close_write, (void *)&args); 508b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 509b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly _accept(fd, type); 510b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 511b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly pthread_join(thread, NULL); 512b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 513b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly return 0; 514b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 515b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellyerror: 516b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly return -1; 517b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly} 518b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 51947653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int do_poll_poll_poll_shutdown(int type) { 52047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly const int MAX_T = 32; 5213f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly int fd; 52247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly pthread_t t[MAX_T]; 52347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly int i; 52447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 52547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly fd = _socket(type); 52647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 52747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly for (i=0; i<MAX_T; i++) 52847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly pthread_create(&t[i], NULL, (void *)thread_poll, (void *)fd); 52947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 53047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly sleep(1); 53147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 53247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly _shutdown(fd, SHUT_RDWR); 53347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 53447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly for (i=0; i<MAX_T; i++) 53547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly pthread_join(t[i], NULL); 53647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 53747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly _close(fd, type); 53847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 53947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly return 0; 54047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly} 54147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 54247653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int do_poll_poll_poll_close(int type) { 54347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly const int MAX_T = 32; 54447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly int fd; 54547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly pthread_t t[MAX_T]; 54647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly int i; 5473f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly 5483f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly fd = _socket(type); 5493f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly 55047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly for (i=0; i<MAX_T; i++) 55147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly pthread_create(&t[i], NULL, (void *)thread_poll, (void *)fd); 5523f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly 5533f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly sleep(1); 5543f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly 55547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly _close(fd, type); 55647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 55747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly for (i=0; i<MAX_T; i++) 55847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly pthread_join(t[i], NULL); 55947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 56047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly return 0; 56147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly} 56247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 56347653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int do_read_read_read_close(int type) { 56447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly const int MAX_T = 32; 56547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly int fd; 56647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly pthread_t t[MAX_T]; 56747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly int i; 56847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 56947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly fd = _socket(type); 57047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 57147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly for (i=0; i<MAX_T; i++) 57247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly pthread_create(&t[i], NULL, (void *)thread_read, (void *)fd); 57347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 57447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly sleep(1); 57547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 57647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly _close(fd, type); 57747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 57847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly for (i=0; i<MAX_T; i++) 57947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly pthread_join(t[i], NULL); 58047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 58147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly return 0; 58247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly} 58347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 58447653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int do_read_read_read_shutdown(int type) { 58547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly const int MAX_T = 32; 58647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly int fd; 58747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly pthread_t t[MAX_T]; 58847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly int i; 58947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 59047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly fd = _socket(type); 59147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 59247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly for (i=0; i<MAX_T; i++) 59347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly pthread_create(&t[i], NULL, (void *)thread_read, (void *)fd); 59447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 59547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly sleep(1); 59647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 59747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly _shutdown(fd, SHUT_RDWR); 59847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 59947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly for (i=0; i<MAX_T; i++) 60047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly pthread_join(t[i], NULL); 60147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 60247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly _close(fd, type); 60347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 60447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly return 0; 60547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly} 60647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 60747653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int do_connected_read1_shutdown1(int type) { 60847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly int fd1, fd2; 60947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly pthread_t t1; 61047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly pthread_t t2; 61147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly struct thread_args a1 = {-1, type, 0}; 61247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly struct thread_args a2 = {-1, type, 2}; 61347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 61447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly fd1 = _socket(type); 61547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly if (fd1 < 0) goto error; 61647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 61747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly if (_bind(fd1, type) < 0) goto error; 61847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 61947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly if (_listen(fd1, type) < 0) goto error; 62047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 62147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly a1.fd = fd1; 62247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly pthread_create(&t1, NULL, (void *)thread_accept_write, (void *)&a1); 62347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 62447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly fd2 = _socket(type); 62547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly if (_connect(fd2, type)) goto error; 62647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 62747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly pthread_create(&t2, NULL, (void *)thread_shutdown, (void *)&fd2); 62847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 62947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly while (1) if (_read(fd2)) break; 6303f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly 6313f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly pthread_join(t1, NULL); 6323f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly pthread_join(t2, NULL); 63347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 6343f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly return 0; 63547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly 63647653588a022190d4b3e20194ef643dfb7b90632Nick Pellyerror: 63747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly return -1; 6383f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly} 6393f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly 6403f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly// accept in one thread, connect from two different threads 6413f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pellystatic int do_accept_connect_connect(int type) { 6423f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly int fd; 6433f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly pthread_t t1; 6443f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly pthread_t t2; 6453f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly struct thread_args a1 = {-1, type, 1}; 6463f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly struct thread_args a2 = {-1, type, 2}; 6473f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly 6483f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly fd = _socket(type); 6493f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly if (fd < 0) goto error; 6503f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly 6513f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly if (_bind(fd, type) < 0) goto error; 6523f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly 6533f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly if (_listen(fd, type) < 0) goto error; 6543f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly 6553f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly pthread_create(&t1, NULL, (void *)thread_delay_connect, (void *)&a1); 6563f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly pthread_create(&t2, NULL, (void *)thread_delay_connect, (void *)&a2); 6573f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly 6583f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly _accept(fd, type); 6593f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly 6603f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly pthread_join(t1, NULL); 6613f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly pthread_join(t2, NULL); 6623f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly 6633f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly return 0; 6643f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly 6653f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pellyerror: 6663f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly return -1; 6673f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly} 6683f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly 669b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystruct { 670b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly char *name; 671b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly int (*ptr)(int); 672b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly} action_table[] = { 6733f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly {"accept_accept_accept", do_accept_accept_accept}, 674b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly {"accept_and_close", do_accept_and_close}, 67547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly {"accept_shutdown", do_accept_shutdown}, 67647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly {"connect_shutdown", do_connect_shutdown}, 677b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly {"accept_close_write", do_accept_close_write}, 6783f61fb90d08d4848a7d7dd24180c2b95ebd60bfcNick Pelly {"accept_connect_connect", do_accept_connect_connect}, 67947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly {"poll_poll_poll_shutdown", do_poll_poll_poll_shutdown}, 68047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly {"poll_poll_poll_close", do_poll_poll_poll_close}, 68147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly {"read_read_read_shutdown", do_read_read_read_shutdown}, 68247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly {"read_read_read_close", do_read_read_read_close}, 68347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly {"connected_read1_shutdown1", do_connected_read1_shutdown1}, 684b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly {NULL, NULL}, 685b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly}; 686b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 687b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystruct { 688b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly char *name; 689b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly enum sock_type type; 690b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly} type_table[] = { 691b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly {"unix", UNIX}, 692b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly {"rfcomm", RFCOMM}, 693b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly {"sco", SCO}, 694b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly {"l2cap", L2CAP}, 695b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly {"tcp", TCP}, 696b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly {NULL, -1}, 697b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly}; 698b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 699b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellystatic void usage() { 700b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly int i; 701b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 702b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly printf("socktest TYPE ACTION\n"); 703b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly printf("\nTYPE:\n"); 704b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly for (i = 0; type_table[i].name; i++) { 705b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly printf("\t%s\n", type_table[i].name); 706b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly } 707b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly printf("\nACTION:\n"); 708b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly for (i = 0; action_table[i].name; i++) { 709b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly printf("\t%s\n", action_table[i].name); 710b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly } 711b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly} 712b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 713b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pellyint main(int argc, char **argv) { 714b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly int i; 715b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly int type = -1; 716b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly 717b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly if (argc != 3) { 718b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly usage(); 719b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly return -1; 720b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly } 721b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly for (i = 0; type_table[i].name; i++) { 722b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly if (!strcmp(argv[1], type_table[i].name)) { 723b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly type = type_table[i].type; 724b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly break; 725b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly } 726b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly } 727b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly if (type == -1) { 728b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly usage(); 729b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly return -1; 730b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly } 731b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly for (i = 0; action_table[i].name; i++) { 732b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly if (!strcmp(argv[2], action_table[i].name)) { 733b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly printf("TYPE = %s ACTION = %s\n", type_table[type].name, 734b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly action_table[i].name); 735b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly return (*action_table[i].ptr)(type); 736b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly } 737b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly } 738b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly usage(); 739b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly return -1; 740b88063b946e2c8f349e69c7db0a631088f991fc4Nick Pelly} 741