timeout.c (1284B)
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}