1 | /* |
---|
2 | * Small C program to test handing arguments to programs on standard input. |
---|
3 | * This program supports multiple test modes, selected with the sole |
---|
4 | * command-line argument: |
---|
5 | * |
---|
6 | * read Read the data first and then output the data read. |
---|
7 | * write Write "Okay" first and then read the data, then exit. |
---|
8 | * exit Write "Okay" and exit without reading any data. |
---|
9 | * close Close stdin, then write "Okay" and exit. |
---|
10 | * nuls Expects "Test" with a nul after each character. |
---|
11 | * large Ensure that we read 1MB of As from stdin, then write "Okay". |
---|
12 | * delay Same as large but with delays in reading. |
---|
13 | * |
---|
14 | * Written by Russ Allbery <rra@stanford.edu> |
---|
15 | * Copyright 2009 Board of Trustees, Leland Stanford Jr. University |
---|
16 | * |
---|
17 | * See LICENSE for licensing terms. |
---|
18 | */ |
---|
19 | |
---|
20 | #include <config.h> |
---|
21 | #include <portable/system.h> |
---|
22 | |
---|
23 | #include <errno.h> |
---|
24 | #ifdef HAVE_SYS_SELECT_H |
---|
25 | # include <sys/select.h> |
---|
26 | #endif |
---|
27 | #include <sys/time.h> |
---|
28 | |
---|
29 | #include <util/util.h> |
---|
30 | |
---|
31 | int |
---|
32 | main(int argc, char *argv[]) |
---|
33 | { |
---|
34 | char *buffer, *p; |
---|
35 | ssize_t status; |
---|
36 | size_t left, i; |
---|
37 | struct timeval tv; |
---|
38 | |
---|
39 | if (argc != 3) |
---|
40 | die("expected two arguments, got %d (%s)", argc, argv[2]); |
---|
41 | buffer = xmalloc(1024 * 1024); |
---|
42 | if (strcmp(argv[2], "read") == 0) { |
---|
43 | status = read(0, buffer, 1024 * 1024); |
---|
44 | if (status <= 0) |
---|
45 | sysdie("read failed"); |
---|
46 | left = status; |
---|
47 | status = read(0, buffer + status, 1024 * 1024 - status); |
---|
48 | if (status != 0) |
---|
49 | die("didn't get EOF"); |
---|
50 | write(1, buffer, left); |
---|
51 | } else if (strcmp(argv[2], "write") == 0) { |
---|
52 | write(1, "Okay", strlen("Okay")); |
---|
53 | status = read(0, buffer, 1024 * 1024); |
---|
54 | if (status <= 0) |
---|
55 | sysdie("read failed"); |
---|
56 | status = read(0, buffer + status, 1024 * 1024 - status); |
---|
57 | if (status != 0) |
---|
58 | die("didn't get EOF"); |
---|
59 | } else if (strcmp(argv[2], "exit") == 0) { |
---|
60 | write(1, "Okay", strlen("Okay")); |
---|
61 | } else if (strcmp(argv[2], "close") == 0) { |
---|
62 | close(0); |
---|
63 | write(1, "Okay", strlen("Okay")); |
---|
64 | } else if (strcmp(argv[2], "nuls") == 0) { |
---|
65 | status = read(0, buffer, 1024 * 1024); |
---|
66 | if (status <= 0) |
---|
67 | sysdie("read failed"); |
---|
68 | left = status; |
---|
69 | status = read(0, buffer + status, 1024 * 1024 - status); |
---|
70 | if (status != 0) |
---|
71 | die("didn't get EOF"); |
---|
72 | if (left != 8 || memcmp(buffer, "T\0e\0s\0t\0", 8) != 0) |
---|
73 | die("got incorrect data"); |
---|
74 | write(1, "Okay", strlen("Okay")); |
---|
75 | } else if (strcmp(argv[2], "large") == 0) { |
---|
76 | left = 1024 * 1024; |
---|
77 | status = 1; |
---|
78 | for (p = buffer; status > 0; p += status, left -= status) { |
---|
79 | do { |
---|
80 | status = read(0, p, left); |
---|
81 | } while (status == -1 && errno == EINTR); |
---|
82 | if (status < 0) |
---|
83 | break; |
---|
84 | } |
---|
85 | if (left != 0 || status != 0) |
---|
86 | die("did not read correct amount"); |
---|
87 | for (i = 0; i < 1024 * 1024; i++) |
---|
88 | if (buffer[i] != 'A') |
---|
89 | die("invalid character in input"); |
---|
90 | write(1, "Okay", strlen("Okay")); |
---|
91 | } else if (strcmp(argv[2], "delay") == 0) { |
---|
92 | left = 1024 * 1024; |
---|
93 | status = 1; |
---|
94 | for (p = buffer; status > 0; p += status, left -= status) { |
---|
95 | do { |
---|
96 | tv.tv_sec = 0; |
---|
97 | tv.tv_usec = 50000; |
---|
98 | select(0, NULL, NULL, NULL, &tv); |
---|
99 | status = read(0, p, left); |
---|
100 | } while (status == -1 && errno == EINTR); |
---|
101 | if (status < 0) |
---|
102 | break; |
---|
103 | } |
---|
104 | if (left != 0 || status != 0) |
---|
105 | die("did not read correct amount"); |
---|
106 | for (i = 0; i < 1024 * 1024; i++) |
---|
107 | if (buffer[i] != 'A') |
---|
108 | die("invalid character in input"); |
---|
109 | write(1, "Okay", strlen("Okay")); |
---|
110 | } |
---|
111 | return 0; |
---|
112 | } |
---|