Skip to content

Commit

Permalink
Setup a specific SIGPIPE Signal handler (#2929)
Browse files Browse the repository at this point in the history
* Setup a specific SIGPIPE Signal handler due to curl bugs that ignore CURLOPT_NOSIGNAL configuration
  • Loading branch information
abraunegg authored Oct 25, 2024
1 parent 5cf8667 commit 99cd975
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 4 deletions.
24 changes: 22 additions & 2 deletions src/curlEngine.d
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import std.json;
import std.stdio;
import std.range;
import core.memory;
import core.sys.posix.signal;

// What other modules that we have created do we need to import?
import log;
Expand All @@ -20,6 +21,11 @@ import util;
// Shared pool of CurlEngine instances accessible across all threads
__gshared CurlEngine[] curlEnginePool; // __gshared is used to declare a variable that is shared across all threads

extern (C) void sigpipeHandler(int signum) {
// Custom handler to ignore SIGPIPE signals
addLogEntry("ERROR: Handling a cURL SIGPIPE signal despite CURLOPT_NOSIGNAL being set (cURL Operational Bug) ...");
}

class CurlResponse {
HTTP.Method method;
const(char)[] url;
Expand Down Expand Up @@ -238,11 +244,25 @@ class CurlEngine {
GC.minimize();
}

// Setup a specific SIGPIPE Signal handler due to curl bugs that ignore CurlOption.nosignal
void setupSIGPIPESignalHandler() {
// Setup the signal handler
sigaction_t curlAction;
curlAction.sa_handler = &sigpipeHandler; // Direct function pointer assignment
sigaction(SIGPIPE, &curlAction, null); // Broken Pipe signal from curl
}

// Initialise this curl instance
void initialise(ulong dnsTimeout, ulong connectTimeout, ulong dataTimeout, ulong operationTimeout, int maxRedirects, bool httpsDebug, string userAgent, bool httpProtocol, ulong userRateLimit, ulong protocolVersion, ulong maxIdleTime, bool keepAlive=true) {
// Setting this to false ensures that when we close the curl instance, any open sockets are closed - which we need to do when running
// multiple threads and API instances at the same time otherwise we run out of local files | sockets pretty quickly
// There are many broken curl versions being used, mainly provided by Ubuntu
// Ignore SIGPIPE to prevent the application from exiting without reason with an exit code of 141 when bad curl version generate this signal despite being told not to (CurlOption.nosignal) below
setupSIGPIPESignalHandler();

// Setting 'keepAlive' to false ensures that when we close the curl instance, any open sockets are closed - which we need to do when running
// multiple threads and API instances at the same time otherwise we run out of local files | sockets pretty quickly
this.keepAlive = keepAlive;

// Curl DNS Timeout Handling
this.dnsTimeout = dnsTimeout;

// Curl Timeout Handling
Expand Down
4 changes: 2 additions & 2 deletions src/main.d
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,7 @@ int main(string[] cliArgs) {
if (verboseLogging) {addLogEntry("Syncing changes from this selected path: " ~ singleDirectoryPath, ["verbose"]);}
}

// Handle SIGINT and SIGTERM
// Handle SIGINT, SIGTERM and SIGSEGV signals
setupSignalHandler();

// Are we doing a --sync operation? This includes doing any --single-directory operations
Expand Down Expand Up @@ -1445,7 +1445,7 @@ void checkForNoMountScenario() {
}
}

// Setup a signal handler for catching CTRL-C and others during application execution
// Setup a signal handler for catching SIGINT, SIGTERM and SIGSEGV (CTRL-C and others) during application execution
void setupSignalHandler() {
sigaction_t action;
action.sa_handler = &exitViaSignalHandler; // Direct function pointer assignment
Expand Down

0 comments on commit 99cd975

Please sign in to comment.