/* ** Copyright 2009 The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. */ /** socket testing */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "cutils/abort_socket.h" enum sock_type { UNIX = 0, RFCOMM, SCO, L2CAP, TCP, }; struct thread_args { int fd; int type; int delay; }; struct sockaddr_un local_addr_un = {AF_UNIX, "/data/foo"}; struct sockaddr_rc local_addr_rc = {AF_BLUETOOTH, *BDADDR_ANY, 4}; struct sockaddr_sco local_addr_sco = {AF_BLUETOOTH, *BDADDR_LOCAL}; struct sockaddr_l2 local_addr_l2 = {AF_BLUETOOTH, htobs(0x1001), *BDADDR_ANY, 0}; struct sockaddr_in local_addr_in = {AF_INET, 9999, {0}, {0}}; struct sockaddr_un remote_addr_un ; struct sockaddr_rc remote_addr_rc ; struct sockaddr_sco remote_addr_sco ; struct sockaddr_l2 remote_addr_l2 ; struct sockaddr_in remote_addr_in ; static void print_events(int events) { if (events & POLLIN) printf("POLLIN "); if (events & POLLPRI) printf("POLLPRI "); if (events & POLLOUT) printf("POLLOUT "); if (events & POLLERR) printf("POLLERR "); if (events & POLLHUP) printf("POLLHUP "); if (events & POLLNVAL) printf("POLLNVAL "); printf("\n"); } static void print_fds(struct pollfd *ufds, nfds_t nfds) { unsigned int i; for (i=0; i 0) { for (i=0; idelay); _close(args->fd, args->type); printf("%d: END\n", gettid()); } static void thread_poll(void *args) { int fd = (int)args; struct pollfd pfd; printf("%d: START\n", gettid()); pfd.fd = fd; pfd.events = 0; _poll(&pfd, 1, -1); printf("%d: END\n", gettid()); } static void thread_read(void *args) { int fd = (int)args; printf("%d: START\n", gettid()); _read(fd); printf("%d: END\n", gettid()); } static void thread_pollin(void *args) { int fd = (int)args; struct pollfd pfd; printf("%d: START\n", gettid()); pfd.fd = fd; pfd.events = POLLIN; _poll(&pfd, 1, -1); printf("%d: END\n", gettid()); } static void thread_shutdown(int fd) { printf("%d: START\n", gettid()); sleep(4); _shutdown(fd, SHUT_RDWR); printf("%d: END\n", gettid()); } static void thread_accept(struct thread_args *args) { printf("%d: START\n", gettid()); sleep(args->delay); _accept(args->fd, args->type); printf("%d: END\n", gettid()); } static void thread_connect(struct thread_args *args) { printf("%d: START\n", gettid()); sleep(args->delay); _connect(args->fd, args->type); printf("%d: END\n", gettid()); } static void thread_delay_close_write(struct thread_args *args) { printf("%d: START\n", gettid()); sleep(args->delay); _close(args->fd, args->type); sleep(args->delay); _write(args->fd, args->type); printf("%d: END\n", gettid()); } static void thread_accept_write(struct thread_args *args) { printf("%d: START\n", gettid()); sleep(args->delay); _accept(args->fd, args->type); sleep(args->delay); _write(args->fd, args->type); printf("%d: END\n", gettid()); } static void thread_delay_connect(struct thread_args *args) { printf("%d: START\n", gettid()); sleep(args->delay); args->fd = _socket(args->type); _connect(args->fd, args->type); printf("%d: END\n", gettid()); } static int do_accept_accept_accept(int type) { int fd; fd = _socket(type); if (fd < 0) goto error; if (_bind(fd, type) < 0) goto error; if (_listen(fd, type) < 0) goto error; while (1) { _accept(fd, type); } return 0; error: return -1; } static int do_accept_and_close(int type) { int fd; pthread_t thread; struct thread_args args = {-1, type, 1}; fd = _socket(type); if (fd < 0) goto error; if (_bind(fd, type) < 0) goto error; if (_listen(fd, type) < 0) goto error; args.fd = fd; pthread_create(&thread, NULL, (void *)thread_delay_close, (void *)&args); _accept(fd, type); pthread_join(thread, NULL); return 0; error: return -1; } static int do_accept_shutdown(int type) { int fd; pthread_t thread; struct thread_args args = {-1, type, 0}; fd = _socket(type); if (fd < 0) goto error; if (_bind(fd, type) < 0) goto error; if (_listen(fd, type) < 0) goto error; args.fd = fd; pthread_create(&thread, NULL, (void *)thread_accept, (void *)&args); sleep(4); _shutdown(fd, SHUT_RDWR); pthread_join(thread, NULL); _close(fd, type); return 0; error: return -1; } static int do_connect_shutdown(int type) { int fd; pthread_t thread; struct thread_args args = {-1, type, 0}; fd = _socket(type); if (fd < 0) goto error; args.fd = fd; pthread_create(&thread, NULL, (void *)thread_connect, (void *)&args); sleep(4); _shutdown(fd, SHUT_RDWR); pthread_join(thread, NULL); _close(fd, type); return 0; error: return -1; } // accept in one thread. close then write in another static int do_accept_close_write(int type) { int fd; pthread_t thread; struct thread_args args = {-1, type, 1}; fd = _socket(type); if (fd < 0) goto error; if (_bind(fd, type) < 0) goto error; if (_listen(fd, type) < 0) goto error; args.fd = fd; pthread_create(&thread, NULL, (void *)thread_delay_close_write, (void *)&args); _accept(fd, type); pthread_join(thread, NULL); return 0; error: return -1; } static int do_poll_poll_poll_shutdown(int type) { const int MAX_T = 32; int fd; pthread_t t[MAX_T]; int i; fd = _socket(type); for (i=0; i