[pacman-dev] [PATCH] Set SIGPIPE handler to SIG_IGN when downloading

Dan McGee dan at archlinux.org
Fri Oct 31 20:42:56 EDT 2008


We don't want a failed write to kill our whole program when we are
downloading things, so set the SIGPIPE handler to ignore when downloading
and restore any previous signal handler when we complete the download.

Signed-off-by: Dan McGee <dan at archlinux.org>
---
 lib/libalpm/dload.c |   12 ++++++++++++
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c
index e4a8a0b..f197d06 100644
--- a/lib/libalpm/dload.c
+++ b/lib/libalpm/dload.c
@@ -24,6 +24,7 @@
 #include <errno.h>
 #include <string.h>
 #include <unistd.h>
+#include <signal.h>
 #include <limits.h>
 /* the following two are needed on BSD for libfetch */
 #if defined(HAVE_SYS_SYSLIMITS_H)
@@ -115,6 +116,7 @@ static int download_internal(const char *url, const char *localpath,
 	size_t dl_thisfile = 0;
 	char *tempfile, *destfile, *filename;
 	int ret = 0;
+	struct sigaction new_action, old_action;
 	struct url *fileurl = url_for_string(url);
 
 	if(!fileurl) {
@@ -148,6 +150,13 @@ static int download_internal(const char *url, const char *localpath,
 	/* 10s timeout - TODO make a config option */
 	fetchTimeout = 10000;
 
+	/* ignore any SIGPIPE signals- these may occur if our FTP socket dies or
+	 * something along those lines. Store the old signal handler first. */
+	new_action.sa_handler = SIG_IGN;
+	sigemptyset(&new_action.sa_mask);
+	sigaction(SIGPIPE, NULL, &old_action);
+	sigaction(SIGPIPE, &new_action, NULL);
+
 	dlf = fetchXGet(fileurl, &ust, (handle->nopassiveftp ? "" : "p"));
 
 	if(fetchLastErrCode != 0 || dlf == NULL) {
@@ -238,6 +247,9 @@ static int download_internal(const char *url, const char *localpath,
 	ret = 0;
 
 cleanup:
+	/* restore any existing SIGPIPE signal handler */
+	sigaction(SIGPIPE, &old_action, NULL);
+
 	FREE(tempfile);
 	FREE(destfile);
 	if(localf != NULL) {
-- 
1.6.0.3




More information about the pacman-dev mailing list