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