Loading...
1// SPDX-License-Identifier: GPL-2.0-only
2/* Timeout API for single-threaded programs that use blocking
3 * syscalls (read/write/send/recv/connect/accept).
4 *
5 * Copyright (C) 2017 Red Hat, Inc.
6 *
7 * Author: Stefan Hajnoczi <stefanha@redhat.com>
8 */
9
10/* Use the following pattern:
11 *
12 * timeout_begin(TIMEOUT);
13 * do {
14 * ret = accept(...);
15 * timeout_check("accept");
16 * } while (ret < 0 && ret == EINTR);
17 * timeout_end();
18 */
19
20#include <stdlib.h>
21#include <stdbool.h>
22#include <unistd.h>
23#include <stdio.h>
24#include "timeout.h"
25
26static volatile bool timeout;
27
28/* SIGALRM handler function. Do not use sleep(2), alarm(2), or
29 * setitimer(2) while using this API - they may interfere with each
30 * other.
31 */
32void sigalrm(int signo)
33{
34 timeout = true;
35}
36
37/* Start a timeout. Call timeout_check() to verify that the timeout hasn't
38 * expired. timeout_end() must be called to stop the timeout. Timeouts cannot
39 * be nested.
40 */
41void timeout_begin(unsigned int seconds)
42{
43 alarm(seconds);
44}
45
46/* Exit with an error message if the timeout has expired */
47void timeout_check(const char *operation)
48{
49 if (timeout) {
50 fprintf(stderr, "%s timed out\n", operation);
51 exit(EXIT_FAILURE);
52 }
53}
54
55/* Stop a timeout */
56void timeout_end(void)
57{
58 alarm(0);
59 timeout = false;
60}
1/* Timeout API for single-threaded programs that use blocking
2 * syscalls (read/write/send/recv/connect/accept).
3 *
4 * Copyright (C) 2017 Red Hat, Inc.
5 *
6 * Author: Stefan Hajnoczi <stefanha@redhat.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; version 2
11 * of the License.
12 */
13
14/* Use the following pattern:
15 *
16 * timeout_begin(TIMEOUT);
17 * do {
18 * ret = accept(...);
19 * timeout_check("accept");
20 * } while (ret < 0 && ret == EINTR);
21 * timeout_end();
22 */
23
24#include <stdlib.h>
25#include <stdbool.h>
26#include <unistd.h>
27#include <stdio.h>
28#include "timeout.h"
29
30static volatile bool timeout;
31
32/* SIGALRM handler function. Do not use sleep(2), alarm(2), or
33 * setitimer(2) while using this API - they may interfere with each
34 * other.
35 */
36void sigalrm(int signo)
37{
38 timeout = true;
39}
40
41/* Start a timeout. Call timeout_check() to verify that the timeout hasn't
42 * expired. timeout_end() must be called to stop the timeout. Timeouts cannot
43 * be nested.
44 */
45void timeout_begin(unsigned int seconds)
46{
47 alarm(seconds);
48}
49
50/* Exit with an error message if the timeout has expired */
51void timeout_check(const char *operation)
52{
53 if (timeout) {
54 fprintf(stderr, "%s timed out\n", operation);
55 exit(EXIT_FAILURE);
56 }
57}
58
59/* Stop a timeout */
60void timeout_end(void)
61{
62 alarm(0);
63 timeout = false;
64}