From: didg Date: Wed, 4 Feb 2009 20:12:47 +0000 (+0000) Subject: Add a timeout when reading data from afpd client in cnid_metad, from Tsiyon Sadiky... X-Git-Tag: before_new_logger~14 X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=netatalk.git;a=commitdiff_plain;h=beec55e7afe7be41f64640d2329705b3005521a3 Add a timeout when reading data from afpd client in cnid_metad, from Tsiyon Sadiky exanet (merge from 2.0 branch) --- diff --git a/etc/cnid_dbd/cnid_metad.c b/etc/cnid_dbd/cnid_metad.c index 62109f48..b1b5b7a3 100644 --- a/etc/cnid_dbd/cnid_metad.c +++ b/etc/cnid_dbd/cnid_metad.c @@ -1,5 +1,5 @@ /* - * $Id: cnid_metad.c,v 1.3 2008-08-31 09:49:44 didg Exp $ + * $Id: cnid_metad.c,v 1.4 2009-02-04 20:12:47 didg Exp $ * * Copyright (C) Joerg Lenneis 2003 * All Rights Reserved. See COPYING. @@ -93,6 +93,7 @@ static int srvfd; static int rqstfd; +volatile sig_atomic_t alarmed = 0; #define MAXSRV 128 @@ -363,11 +364,16 @@ char *group; } +/* ------------------ */ +void catch_alarm(int sig) { + alarmed = 1; +} + /* ------------------ */ int main(int argc, char *argv[]) { char dbdir[MAXPATHLEN + 1]; - int len; + int len, actual_len; pid_t pid; int status; char *dbdpn = _PATH_CNID_DBD; @@ -473,6 +479,7 @@ int main(int argc, char *argv[]) } signal(SIGPIPE, SIG_IGN); + signal(SIGALRM, catch_alarm); while (1) { rqstfd = usockfd_check(srvfd, 10000000); @@ -501,9 +508,18 @@ int main(int argc, char *argv[]) } if (rqstfd <= 0) continue; + /* TODO: Check out read errors, broken pipe etc. in libatalk. Is SIGIPE ignored there? Answer: Ignored for dsi, but not for asp ... */ + alarm(5); /* to prevent read from getting stuck */ ret = read(rqstfd, &len, sizeof(int)); + alarm(0); + if (alarmed) { + alarmed = 0; + LOG(log_severe, logtype_cnid, "Read(1) bailed with alarm (timeout)"); + goto loop_end; + } + if (!ret) { /* already close */ goto loop_end; @@ -524,7 +540,16 @@ int main(int argc, char *argv[]) LOG(log_error, logtype_cnid, "wrong len parameter: %d", len); goto loop_end; } - if (read(rqstfd, dbdir, len) != len) { + + alarm(5); + actual_len = read(rqstfd, dbdir, len); + alarm(0); + if (alarmed) { + alarmed = 0; + LOG(log_severe, logtype_cnid, "Read(2) bailed with alarm (timeout)"); + goto loop_end; + } + if (actual_len != len) { LOG(log_error, logtype_cnid, "error/short read (dir): %s", strerror(errno)); goto loop_end; }