/
timed_read.c
68 lines (54 loc) · 2.14 KB
/
timed_read.c
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
/**********************************************************************\
* Copyright (C) Michael Kerrisk, 2010. *
* *
* This program is free software. You may use, modify, and redistribute *
* it under the terms of the GNU Affero General Public License as *
* published by the Free Software Foundation, either version 3 or (at *
* your option) any later version. This program is distributed without *
* any warranty. See the file COPYING for details. *
\**********************************************************************/
/* timed_read.c
Demonstrate the use of a timer to place a timeout on a blocking system call
(read(2) in this case).
*/
#include <signal.h>
#include "tlpi_hdr.h"
#define BUF_SIZE 200
static void /* SIGALRM handler: interrupts blocked system call */
handler(int sig)
{
printf("Caught signal\n"); /* UNSAFE (see Section 21.1.2) */
}
int
main(int argc, char *argv[])
{
struct sigaction sa;
char buf[BUF_SIZE];
ssize_t numRead;
int savedErrno;
if (argc > 1 && strcmp(argv[1], "--help") == 0)
usageErr("%s [num-secs [restart-flag]]\n", argv[0]);
/* Set up handler for SIGALRM. Allow system calls to be interrupted,
unless second command-line argument was supplied. */
sa.sa_flags = (argc > 2) ? SA_RESTART : 0;
sigemptyset(&sa.sa_mask);
sa.sa_handler = handler;
if (sigaction(SIGALRM, &sa, NULL) == -1)
errExit("sigaction");
alarm((argc > 1) ? getInt(argv[1], GN_NONNEG, "num-secs") : 10);
numRead = read(STDIN_FILENO, buf, BUF_SIZE - 1);
savedErrno = errno; /* In case alarm() changes it */
alarm(0); /* Ensure timer is turned off */
errno = savedErrno;
/* Determine result of read() */
if (numRead == -1) {
if (errno == EINTR)
printf("Read timed out\n");
else
errMsg("read");
} else {
printf("Successful read (%ld bytes): %.*s",
(long) numRead, (int) numRead, buf);
}
exit(EXIT_SUCCESS);
}