1#ifndef HEADER_CURL_SIGPIPE_H 2#define HEADER_CURL_SIGPIPE_H 3/*************************************************************************** 4 * _ _ ____ _ 5 * Project ___| | | | _ \| | 6 * / __| | | | |_) | | 7 * | (__| |_| | _ <| |___ 8 * \___|\___/|_| \_\_____| 9 * 10 * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 11 * 12 * This software is licensed as described in the file COPYING, which 13 * you should have received as part of this distribution. The terms 14 * are also available at https://curl.se/docs/copyright.html. 15 * 16 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 * copies of the Software, and permit persons to whom the Software is 18 * furnished to do so, under the terms of the COPYING file. 19 * 20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 * KIND, either express or implied. 22 * 23 * SPDX-License-Identifier: curl 24 * 25 ***************************************************************************/ 26#include "curl_setup.h" 27 28#if defined(HAVE_SIGACTION) && \ 29 (defined(USE_OPENSSL) || defined(USE_MBEDTLS) || defined(USE_WOLFSSL)) 30#include <signal.h> 31 32struct sigpipe_ignore { 33 struct sigaction old_pipe_act; 34 bool no_signal; 35}; 36 37#define SIGPIPE_VARIABLE(x) struct sigpipe_ignore x 38 39/* 40 * sigpipe_ignore() makes sure we ignore SIGPIPE while running libcurl 41 * internals, and then sigpipe_restore() will restore the situation when we 42 * return from libcurl again. 43 */ 44static void sigpipe_ignore(struct Curl_easy *data, 45 struct sigpipe_ignore *ig) 46{ 47 /* get a local copy of no_signal because the Curl_easy might not be 48 around when we restore */ 49 ig->no_signal = data->set.no_signal; 50 if(!data->set.no_signal) { 51 struct sigaction action; 52 /* first, extract the existing situation */ 53 sigaction(SIGPIPE, NULL, &ig->old_pipe_act); 54 action = ig->old_pipe_act; 55 /* ignore this signal */ 56 action.sa_handler = SIG_IGN; 57 sigaction(SIGPIPE, &action, NULL); 58 } 59} 60 61/* 62 * sigpipe_restore() puts back the outside world's opinion of signal handler 63 * and SIGPIPE handling. It MUST only be called after a corresponding 64 * sigpipe_ignore() was used. 65 */ 66static void sigpipe_restore(struct sigpipe_ignore *ig) 67{ 68 if(!ig->no_signal) 69 /* restore the outside state */ 70 sigaction(SIGPIPE, &ig->old_pipe_act, NULL); 71} 72 73#else 74/* for systems without sigaction */ 75#define sigpipe_ignore(x,y) Curl_nop_stmt 76#define sigpipe_restore(x) Curl_nop_stmt 77#define SIGPIPE_VARIABLE(x) 78#endif 79 80#endif /* HEADER_CURL_SIGPIPE_H */ 81