From: didg Date: Mon, 4 Jun 2007 06:57:42 +0000 (+0000) Subject: Add a timeout when reading data from afpd client in cnid_metad, from Tsiyon Sadiky... X-Git-Tag: netatalk-2-0-4-beta1~32 X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=netatalk.git;a=commitdiff_plain;h=5c1b843f93912adf3885d7d209a002af52768a42 Add a timeout when reading data from afpd client in cnid_metad, from Tsiyon Sadiky exanet --- diff --git a/etc/cnid_dbd/cnid_metad.c b/etc/cnid_dbd/cnid_metad.c index 28dd5e6b..838ab8fe 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.1.4.15.2.1 2005-09-27 10:40:41 didg Exp $ + * $Id: cnid_metad.c,v 1.1.4.15.2.2 2007-06-04 06:57:42 didg Exp $ * * Copyright (C) Joerg Lenneis 2003 * All Rights Reserved. See COPYING. @@ -92,6 +92,7 @@ static int srvfd; static int rqstfd; +volatile sig_atomic_t alarmed = 0; #define MAXSRV 128 @@ -362,11 +363,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; @@ -472,6 +478,7 @@ int main(int argc, char *argv[]) } signal(SIGPIPE, SIG_IGN); + signal(SIGALRM, catch_alarm); while (1) { rqstfd = usockfd_check(srvfd, 10000000); @@ -500,9 +507,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; @@ -523,7 +539,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; }