15b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes/*
25b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes * Copyright (C) 2013 The Android Open Source Project
35b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes *
45b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
55b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes * you may not use this file except in compliance with the License.
65b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes * You may obtain a copy of the License at
75b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes *
85b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
95b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes *
105b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes * Unless required by applicable law or agreed to in writing, software
115b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
125b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes * See the License for the specific language governing permissions and
145b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes * limitations under the License.
155b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes */
165b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes
175b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes#include <gtest/gtest.h>
185b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes
195b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes#include <errno.h>
20f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#include <signal.h>
215b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes#include <stdlib.h>
225b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes#include <sys/select.h>
231021c05f1bef70d78cddff41b151787b8195cac9Brian Carlstrom#include <sys/types.h>
241021c05f1bef70d78cddff41b151787b8195cac9Brian Carlstrom#include <sys/wait.h>
255b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes
265b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott HughesTEST(sys_select, fd_set_smoke) {
275b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes  fd_set fds;
285b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes  FD_ZERO(&fds);
295b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes
305b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes  for (size_t i = 0; i < 1024; ++i) {
315b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes    EXPECT_FALSE(FD_ISSET(i, &fds));
325b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes  }
335b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes
345b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes  FD_SET(0, &fds);
355b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes  EXPECT_TRUE(FD_ISSET(0, &fds));
365b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes  EXPECT_FALSE(FD_ISSET(1, &fds));
375b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes  FD_SET(1, &fds);
385b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes  EXPECT_TRUE(FD_ISSET(0, &fds));
395b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes  EXPECT_TRUE(FD_ISSET(1, &fds));
405b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes  FD_CLR(0, &fds);
415b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes  EXPECT_FALSE(FD_ISSET(0, &fds));
425b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes  EXPECT_TRUE(FD_ISSET(1, &fds));
435b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes  FD_CLR(1, &fds);
445b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes  EXPECT_FALSE(FD_ISSET(0, &fds));
455b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes  EXPECT_FALSE(FD_ISSET(1, &fds));
465b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes}
4711952073af22568bba0b661f7a9d4402c443a888Elliott Hughes
48e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris#define DELAY_MSG "1234"
49e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris
50e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferrisstatic void DelayedWrite(int* pid, int* fd) {
51e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris  int fds[2];
52e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris  ASSERT_EQ(0, pipe(fds));
53e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris
54e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris  if ((*pid = fork()) == 0) {
55e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris    close(fds[0]);
56e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris    usleep(5000);
57e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris    EXPECT_EQ(5, write(fds[1], DELAY_MSG, sizeof(DELAY_MSG)));
58e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris    close(fds[1]);
59e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris    exit(0);
60e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris  }
61e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris  ASSERT_LT(0, *pid);
62e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris  close(fds[1]);
63e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris
64e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris  *fd = fds[0];
65e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris}
66e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris
67e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferrisstatic void DelayedWriteCleanup(int pid, int fd) {
68e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris  char buf[sizeof(DELAY_MSG)];
69e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris  ASSERT_EQ(static_cast<ssize_t>(sizeof(DELAY_MSG)), read(fd, buf, sizeof(DELAY_MSG)));
70e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris  ASSERT_STREQ(DELAY_MSG, buf);
71e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris  ASSERT_EQ(pid, waitpid(pid, NULL, 0));
72e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris}
73e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris
7411952073af22568bba0b661f7a9d4402c443a888Elliott HughesTEST(sys_select, select_smoke) {
7511952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  fd_set r;
7611952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  FD_ZERO(&r);
7711952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  fd_set w;
7811952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  FD_ZERO(&w);
7911952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  fd_set e;
8011952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  FD_ZERO(&e);
8111952073af22568bba0b661f7a9d4402c443a888Elliott Hughes
8211952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  FD_SET(STDIN_FILENO, &r);
8311952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  FD_SET(STDOUT_FILENO, &w);
8411952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  FD_SET(STDERR_FILENO, &w);
8511952073af22568bba0b661f7a9d4402c443a888Elliott Hughes
8611952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  int max = STDERR_FILENO + 1;
8711952073af22568bba0b661f7a9d4402c443a888Elliott Hughes
8811952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  // Invalid max fd.
8911952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  ASSERT_EQ(-1, select(-1, &r, &w, &e, NULL));
9011952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  ASSERT_EQ(EINVAL, errno);
9111952073af22568bba0b661f7a9d4402c443a888Elliott Hughes
9211952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  ASSERT_EQ(2, select(max, &r, &w, &e, NULL));
9311952073af22568bba0b661f7a9d4402c443a888Elliott Hughes
9411952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  // Invalid timeout.
9511952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  timeval tv;
9611952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  tv.tv_sec = -1;
9711952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  tv.tv_usec = 0;
9811952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  ASSERT_EQ(-1, select(max, &r, &w, &e, &tv));
9911952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  ASSERT_EQ(EINVAL, errno);
10011952073af22568bba0b661f7a9d4402c443a888Elliott Hughes
10111952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  // Valid timeout...
10211952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  tv.tv_sec = 1;
103e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris  int pid, fd;
104e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris  DelayedWrite(&pid, &fd);
105e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris
106e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris  FD_ZERO(&r);
107e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris  FD_SET(fd, &r);
108e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris  ASSERT_EQ(1, select(fd+1, &r, NULL, NULL, &tv));
109e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris  // Both tv_sec and tv_nsec should have been updated.
110e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris  ASSERT_EQ(0, tv.tv_sec);
111e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris  ASSERT_NE(0, tv.tv_usec);
112e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris
113e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris  DelayedWriteCleanup(pid, fd);
11411952073af22568bba0b661f7a9d4402c443a888Elliott Hughes}
11511952073af22568bba0b661f7a9d4402c443a888Elliott Hughes
11611952073af22568bba0b661f7a9d4402c443a888Elliott HughesTEST(sys_select, pselect_smoke) {
11711952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  sigset_t ss;
11811952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  sigemptyset(&ss);
11911952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  sigaddset(&ss, SIGPIPE);
12011952073af22568bba0b661f7a9d4402c443a888Elliott Hughes
12111952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  fd_set r;
12211952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  FD_ZERO(&r);
12311952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  fd_set w;
12411952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  FD_ZERO(&w);
12511952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  fd_set e;
12611952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  FD_ZERO(&e);
12711952073af22568bba0b661f7a9d4402c443a888Elliott Hughes
12811952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  FD_SET(STDIN_FILENO, &r);
12911952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  FD_SET(STDOUT_FILENO, &w);
13011952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  FD_SET(STDERR_FILENO, &w);
13111952073af22568bba0b661f7a9d4402c443a888Elliott Hughes
13211952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  int max = STDERR_FILENO + 1;
13311952073af22568bba0b661f7a9d4402c443a888Elliott Hughes
13411952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  // Invalid max fd.
13511952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  ASSERT_EQ(-1, pselect(-1, &r, &w, &e, NULL, &ss));
13611952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  ASSERT_EQ(EINVAL, errno);
13711952073af22568bba0b661f7a9d4402c443a888Elliott Hughes
13811952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  ASSERT_EQ(2, pselect(max, &r, &w, &e, NULL, &ss));
13911952073af22568bba0b661f7a9d4402c443a888Elliott Hughes
14011952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  // Invalid timeout.
14111952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  timespec tv;
14211952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  tv.tv_sec = -1;
14311952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  tv.tv_nsec = 0;
14411952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  ASSERT_EQ(-1, pselect(max, &r, &w, &e, &tv, &ss));
14511952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  ASSERT_EQ(EINVAL, errno);
14611952073af22568bba0b661f7a9d4402c443a888Elliott Hughes
14711952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  // Valid timeout...
14811952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  tv.tv_sec = 1;
149e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris  int pid, fd;
150e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris  DelayedWrite(&pid, &fd);
151e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris
152e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris  FD_ZERO(&r);
153e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris  FD_SET(fd, &r);
154e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris  ASSERT_EQ(1, pselect(fd+1, &r, NULL, NULL, &tv, NULL));
155e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris  // Neither tv_sec nor tv_nsec should have been updated.
156e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris  ASSERT_EQ(1, tv.tv_sec);
157e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris  ASSERT_EQ(0, tv.tv_nsec);
158e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris
159e3bb025b3d963e4aa412ab3eee35ca2187eb0ecaChristopher Ferris  DelayedWriteCleanup(pid, fd);
16011952073af22568bba0b661f7a9d4402c443a888Elliott Hughes}
161