File: cmd-stdin.c

package info (click to toggle)
remctl 3.18-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,612 kB
  • sloc: ansic: 19,504; sh: 5,386; perl: 1,778; java: 740; makefile: 715; xml: 502; python: 430
file content (123 lines) | stat: -rw-r--r-- 4,410 bytes parent folder | download | duplicates (4)
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;
}