18e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly/*
28e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly * Copyright 2009 The Android Open Source Project
38e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly *
48e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly * Licensed under the Apache License, Version 2.0 (the "License");
58e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly * you may not use this file except in compliance with the License.
68e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly * You may obtain a copy of the License at
78e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly *
88e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly *     http://www.apache.org/licenses/LICENSE-2.0
98e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly *
108e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly * Unless required by applicable law or agreed to in writing, software
118e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly * distributed under the License is distributed on an "AS IS" BASIS,
128e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly * See the License for the specific language governing permissions and
148e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly * limitations under the License.
158e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly */
168e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
178e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly/* Helper to test linux pipe's */
188e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
198e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly#include <pthread.h>
208e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly#include <stdlib.h>
218e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly#include <stdio.h>
228e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly#include <errno.h>
238e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly#include <unistd.h>
248e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly#include <sys/poll.h>
258e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly#include <sys/socket.h>
268e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
278e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pellystatic void print_events(int events) {
288e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    if (events & POLLIN) printf("POLLIN ");
298e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    if (events & POLLPRI) printf("POLLPRI ");
308e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    if (events & POLLOUT) printf("POLLOUT ");
318e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    if (events & POLLERR) printf("POLLERR ");
328e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    if (events & POLLHUP) printf("POLLHUP ");
338e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    if (events & POLLNVAL) printf("POLLNVAL ");
348e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    printf("\n");
358e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly}
368e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
3747653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int _socketpair(int fd[2]) {
3847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int ret;
3947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: socketpair()\n", gettid());
4047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
4147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: socketpair() = %d\n", gettid(), ret);
4247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (ret) printf("\terr %d (%s)\n", errno, strerror(errno));
4347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return ret;
4447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
4547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
468e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pellystatic int _close(int fd) {
478e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    int ret;
488e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    printf("%d: close(%d)\n", gettid(), fd);
498e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    ret = close(fd);
508e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    printf("%d: close(%d) = %d\n", gettid(), fd, ret);
518e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    if (ret) printf("\terr %d (%s)\n", errno, strerror(errno));
528e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    return ret;
538e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly}
548e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
558e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pellystatic int _poll(struct pollfd *ufds, nfds_t nfds, int timeout) {
568e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    int ret;
578e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    unsigned int i;
588e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    printf("%d: poll()\n", gettid());
598e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    ret = poll(ufds, nfds, timeout);
608e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    printf("%d: poll() = %d\n", gettid(), ret);
618e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
628e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    if (ret > 0) {
638e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly        for (i=0; i<nfds; i++) {
648e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly            if (ufds[i].revents) {
658e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly                printf("\tfd %d ", ufds[i].fd); print_events(ufds[i].revents);
668e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly            }
678e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly        }
688e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    }
698e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    return ret;
708e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly}
718e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
728e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pellystatic int _write(int fd, char *buf, int len) {
738e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    int ret;
748e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
758e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    printf("%d: write(%d)\n", gettid(), fd);
768e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    ret = write(fd, buf, len);
778e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    printf("%d: write(%d) = %d\n", gettid(), fd, ret);
788e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
798e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
808e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    return ret;
818e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly}
828e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
8347653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int _read(int fd) {
8447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int ret;
8547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    char buf;
8647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
8747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: read(%d)\n", gettid(), fd);
8847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    ret = read(fd, &buf, 1);
8947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: read(%d) = %d [%d]\n", gettid(), fd, ret, (int)buf);
9047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
9147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
9247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return ret;
9347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
9447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
958e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pellystatic int _shutdown(int fd, int how) {
968e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    int ret;
978e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
988e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    printf("%d: shutdown(%d)\n", gettid(), fd);
998e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    ret = shutdown(fd, how);
1008e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    printf("%d: shutdown(%d) = %d\n", gettid(), fd, ret);
1018e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
1028e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
1038e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    return ret;
1048e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly}
1058e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pellystatic void thread_poll(void *args) {
1068e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    int fd = (int)args;
1078e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    struct pollfd pfd;
1088e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    printf("%d: START\n", gettid());
1098e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    pfd.fd = fd;
1108e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    pfd.events = 0;
1118e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    _poll(&pfd, 1, -1);
1128e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    printf("%d: END\n", gettid());
1138e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly}
1148e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
1158e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pellystatic void thread_pollin(void *args) {
1168e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    int fd = (int)args;
1178e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    struct pollfd pfd;
1188e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    printf("%d: START\n", gettid());
1198e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    pfd.fd = fd;
1208e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    pfd.events = POLLIN;
1218e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    _poll(&pfd, 1, -1);
1228e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    printf("%d: END\n", gettid());
1238e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly}
1248e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
12547653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic void thread_pollin_rand_delay(void *args) {
12647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int fd = (int)args;
12747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    struct pollfd pfd;
12847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int delay = (int)((double)random() * (10000000.0 / 2147483647.0));
12947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: START (delay = %d)\n", gettid(), delay);
13047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pfd.fd = fd;
13147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pfd.events = POLLIN;
13247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    usleep(delay);
13347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _poll(&pfd, 1, -1);
13447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: END\n", gettid());
13547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
13647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
13747653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic void thread_read(void *args) {
13847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int fd = (int)args;
13947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: START\n", gettid());
14047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _read(fd);
14147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    printf("%d: END\n", gettid());
14247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
14347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
1448e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pellystatic void thread_close(void *args) {
1458e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    int fd = (int)args;
1468e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    printf("%d: START\n", gettid());
1478e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    _close(fd);
1488e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    printf("%d: END\n", gettid());
1498e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly}
1508e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
1518e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pellystatic int do_poll_poll_close() {
1528e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    pthread_t t1;
1538e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    pthread_t t2;
1548e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    int fd[2];
1558e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
1568e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    if (pipe(fd)) return -1;
1578e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
1588e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    pthread_create(&t1, NULL, (void *)thread_poll, NULL);
1598e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    pthread_create(&t2, NULL, (void *)thread_poll, NULL);
1608e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
1618e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    sleep(1);
1628e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
1638e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    _close(fd[1]);
1648e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
1658e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    pthread_join(t1, NULL);
1668e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    pthread_join(t2, NULL);
1678e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
1688e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    return 0;
1698e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly}
1708e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
17147653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int do_socketpair_poll1_shutdown2() {
17247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int fd[2];
17347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_t t;
17447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
17547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (_socketpair(fd)) return -1;
17647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
17747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_create(&t, NULL, (void *)thread_poll, (void *)fd[1]);
17847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
17947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    sleep(1);
18047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
18147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _shutdown(fd[0], SHUT_RDWR);
18247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
18347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    sleep(1);
18447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
18547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _close(fd[0]);
18647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
18747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_join(t, NULL);
18847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
18947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return 0;
19047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
19147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
19247653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int do_socketpair_poll1_shutdown1() {
19347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int fd[2];
19447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_t t;
19547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
19647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (_socketpair(fd)) return -1;
19747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
19847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_create(&t, NULL, (void *)thread_poll, (void *)fd[0]);
19947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
20047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    sleep(1);
20147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
20247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _shutdown(fd[0], SHUT_RDWR);
20347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
20447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    sleep(1);
20547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
20647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _close(fd[0]);
20747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
20847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_join(t, NULL);
20947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
21047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return 0;
21147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
21247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
21347653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int do_socketpair_poll1_close1() {
21447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int fd[2];
21547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_t t;
21647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
21747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (_socketpair(fd)) return -1;
21847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
21947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_create(&t, NULL, (void *)thread_poll, (void *)fd[0]);
22047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
22147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    sleep(1);
22247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
22347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _close(fd[0]);
22447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
22547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_join(t, NULL);
22647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
22747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return 0;
22847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
22947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
23047653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int do_socketpair_read1_shutdown1() {
23147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int fd[2];
23247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_t t;
23347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
23447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (_socketpair(fd)) return -1;
23547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
23647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_create(&t, NULL, (void *)thread_read, (void *)fd[0]);
23747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
23847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    sleep(1);
23947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
24047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _shutdown(fd[0], SHUT_RDWR);
24147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
24247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    sleep(1);
24347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
24447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _close(fd[0]);
24547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
24647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_join(t, NULL);
24747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
24847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return 0;
24947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
25047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
2518e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pellystatic int do_pipe_pipe_pipe() {
2528e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    int fd[2];
2538e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    int i;
2548e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
2558e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    while (1) {
2568e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly        if (pipe(fd)) {
2578e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly            printf("pipe: %s\n", strerror(errno));
2588e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly            return -1;
2598e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly        }
2608e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly        printf("%d %d\n", fd[0], fd[1]);
2618e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly        close(fd[0]);
2628e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly        close(fd[1]);
2638e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    }
2648e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
2658e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    return 0;
2668e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly}
2678e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pellystatic int do_pollin_pollin_write() {
2688e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    pthread_t t1;
2698e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    pthread_t t2;
2708e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    int fd[2];
2718e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    char buf = 'a';
2728e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    int i;
2738e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
2748e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    if (pipe(fd)) return -1;
2758e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
2768e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    pthread_create(&t1, NULL, (void *)thread_pollin, (void *)fd[0]);
2778e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    pthread_create(&t2, NULL, (void *)thread_pollin, (void *)fd[0]);
2788e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
2798e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    sleep(1);
2808e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
2818e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    for (i = 0; i < 100; i++)
2828e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly        _write(fd[1], &buf, 1);
2838e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
2848e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    pthread_join(t1, NULL);
2858e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    pthread_join(t2, NULL);
2868e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
2878e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    return 0;
2888e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly}
2898e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
29047653588a022190d4b3e20194ef643dfb7b90632Nick Pellystatic int do_pollin_pollin_pollin_write_pollin_pollin_pollin() {
29147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    const int MAX_T = 10;
29247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    pthread_t t[MAX_T];
29347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int fd[2];
29447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    char buf = 'a';
29547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    int i;
29647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
29747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    if (pipe(fd)) return -1;
29847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
29947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    for (i=0; i<MAX_T; i++)
30047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        pthread_create(&t[i], NULL, (void *)thread_pollin_rand_delay, (void *)fd[0]);
30147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
30247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    sleep(5);
30347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
30447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _write(fd[1], &buf, 1);
30547653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
30647653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    for (i=0; i<MAX_T; i++)
30747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly        pthread_join(t[i], NULL);
30847653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
30947653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _close(fd[0]);
31047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    _close(fd[1]);
31147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
31247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    return 0;
31347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly}
31447653588a022190d4b3e20194ef643dfb7b90632Nick Pelly
3158e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pellystatic int do_poll_poll_shutdown() {
31607e2e433c27fb8c0bebe2b6b2f0865f3314aaecaNick Pelly#if 0
3178e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    pthread_t t1;
3188e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    pthread_t t2;
3198e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    int fd[2];
3208e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
3218e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    if (pipe(fd)) return -1;
3228e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
3238e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    pthread_create(&t1, NULL, (void *)thread_poll, (void *)fd[0]);
3248e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    pthread_create(&t2, NULL, (void *)thread_poll, (void *)fd[0]);
3258e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
3268e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    sleep(1);
3278e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
3288e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    _shutdown(fd[1], SHUT_RDWR);
3298e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
3308e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    pthread_join(t1, NULL);
3318e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    pthread_join(t2, NULL);
33207e2e433c27fb8c0bebe2b6b2f0865f3314aaecaNick Pelly#endif
3338e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
33407e2e433c27fb8c0bebe2b6b2f0865f3314aaecaNick Pelly    return -1;
3358e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly}
3368e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
3378e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pellystatic int THREADS = 100;
3388e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
3398e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pellystatic int do_close_poll_poll_poll() {
3408e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    pthread_t t[THREADS];
3418e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    int i;
3428e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    int fd[2];
3438e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
3448e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    if (pipe(fd)) return -1;
3458e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
3468e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    _close(fd[1]);
3478e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
3488e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    for (i = 0; i < THREADS; i++)
3498e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly        pthread_create(&t[i], NULL, (void *)thread_poll, (void *)fd[0]);
3508e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
3518e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    for (i = 0; i < THREADS; i++)
3528e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly        pthread_join(t[i], NULL);
3538e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
3548e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    return 0;
3558e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly}
3568e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
3578e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pellystatic int do_close_close_close() {
3588e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    pthread_t t[THREADS];
3598e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    int i;
3608e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    int fd[2];
3618e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
3628e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    if (pipe(fd)) return -1;
3638e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
3648e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    for (i = 0; i < THREADS; i++)
3658e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly        pthread_create(&t[i], NULL, (void *)thread_close, (void *)fd[i%2]);
3668e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
3678e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    return 0;
3688e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly}
3698e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
3708e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pellystatic int pipe_close_w_close_r_repeat() {
3718e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    int fd[2];
3728e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    pthread_t t;
3738e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    int i;
3748e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
3758e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    for (i = 0; i < THREADS; i++) {
3768e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly        if (pipe(fd)) return -1;
3778e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly        pthread_create(&t, NULL, (void *)thread_poll, (void *)fd[0]);
3788e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly        _close(fd[1]);
3798e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly        _close(fd[0]);
3808e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly        pthread_join(t, NULL);
3818e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    }
3828e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
3838e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    return 0;
3848e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly}
3858e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
3868e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pellystruct {
3878e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    char *name;
3888e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    int (*ptr)();
3898e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly} function_table[]  = {
39047653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    {"socketpair_poll1_shutdown2", do_socketpair_poll1_shutdown2},
39147653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    {"socketpair_poll1_shutdown1", do_socketpair_poll1_shutdown1},
39247653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    {"socketpair_poll1_close1", do_socketpair_poll1_close1},
39347653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    {"socketpair_read1_shutdown1", do_socketpair_read1_shutdown1},
3948e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    {"pipe_pipe_pipe", do_pipe_pipe_pipe},
3958e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    {"poll_poll_close", do_poll_poll_close},
3968e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    {"pollin_pollin_write", do_pollin_pollin_write},
39747653588a022190d4b3e20194ef643dfb7b90632Nick Pelly    {"pollin_pollin_pollin_write_pollin_pollin_pollin", do_pollin_pollin_pollin_write_pollin_pollin_pollin},
3988e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    {"poll_poll_shutdown", do_poll_poll_shutdown},
3998e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    {"close_poll_poll_poll", do_close_poll_poll_poll},
4008e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    {"close_close_close", do_close_close_close},
4018e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    {"pipe_close_w_close_w_repeat", pipe_close_w_close_r_repeat},
4028e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    {NULL, NULL},
4038e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly};
4048e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
4058e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pellystatic void usage() {
4068e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    int i;
4078e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
4088e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    printf("Usage:\n");
4098e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    for (i = 0; function_table[i].name; i++) {
4108e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly        printf("\tpipetest %s\n", function_table[i].name);
4118e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    }
4128e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly}
4138e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
4148e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pellyint main(int argc, char **argv) {
4158e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    int i;
4168e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly
4178e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    if (argc != 2) {
4188e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly        usage();
4198e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly        return -1;
4208e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    }
4218e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    for (i = 0; function_table[i].name; i++) {
4228e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly        if (!strcmp(argv[1], function_table[i].name)) {
4238e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly            printf("%s\n", function_table[i].name);
4248e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly            return (*function_table[i].ptr)();
4258e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly        }
4268e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    }
4278e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    usage();
4288e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly    return -1;
4298e914727cfa67d9fd7407970e3b694fe72824ee2Nick Pelly}
430