From owner-svn-src-all@FreeBSD.ORG Thu Jun 20 16:50:06 2013 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id 3264786F; Thu, 20 Jun 2013 16:50:06 +0000 (UTC) (envelope-from gahr@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 0904C1672; Thu, 20 Jun 2013 16:50:06 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r5KGo5Zv094217; Thu, 20 Jun 2013 16:50:05 GMT (envelope-from gahr@svn.freebsd.org) Received: (from gahr@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r5KGo5oF094216; Thu, 20 Jun 2013 16:50:05 GMT (envelope-from gahr@svn.freebsd.org) Message-Id: <201306201650.r5KGo5oF094216@svn.freebsd.org> From: Pietro Cerutti Date: Thu, 20 Jun 2013 16:50:05 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org Subject: svn commit: r252034 - stable/8/usr.bin/at X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 20 Jun 2013 16:50:06 -0000 Author: gahr (ports committer) Date: Thu Jun 20 16:50:05 2013 New Revision: 252034 URL: http://svnweb.freebsd.org/changeset/base/252034 Log: MFC: r249406 - Do not bail out if stat(2) fails with ENOENT in the spool directory. This happens if another atrm process removes a job while we're scanning through the directory. - While at it, optimize a bit the directory scanning, so that we quit looping as soon as all jobs specified in argv have been dealt with. Approved by: cognet Modified: stable/8/usr.bin/at/at.c Directory Properties: stable/8/usr.bin/at/ (props changed) Modified: stable/8/usr.bin/at/at.c ============================================================================== --- stable/8/usr.bin/at/at.c Thu Jun 20 14:30:16 2013 (r252033) +++ stable/8/usr.bin/at/at.c Thu Jun 20 16:50:05 2013 (r252034) @@ -533,6 +533,10 @@ process_jobs(int argc, char **argv, int /* Delete every argument (job - ID) given */ int i; + int rc; + int nofJobs; + int nofDone; + int statErrno; struct stat buf; DIR *spool; struct dirent *dirent; @@ -540,6 +544,9 @@ process_jobs(int argc, char **argv, int char queue; long jobno; + nofJobs = argc - optind; + nofDone = 0; + PRIV_START if (chdir(ATJOB_DIR) != 0) @@ -555,9 +562,20 @@ process_jobs(int argc, char **argv, int while((dirent = readdir(spool)) != NULL) { PRIV_START - if (stat(dirent->d_name, &buf) != 0) - perr("cannot stat in " ATJOB_DIR); + rc = stat(dirent->d_name, &buf); + statErrno = errno; PRIV_END + /* There's a race condition between readdir above and stat here: + * another atrm process could have removed the file from the spool + * directory under our nose. If this happens, stat will set errno to + * ENOENT, which we shouldn't treat as fatal. + */ + if (rc != 0) { + if (statErrno == ENOENT) + continue; + else + perr("cannot stat in " ATJOB_DIR); + } if(sscanf(dirent->d_name, "%c%5lx%8lx", &queue, &jobno, &ctm)!=3) continue; @@ -603,9 +621,15 @@ process_jobs(int argc, char **argv, int errx(EXIT_FAILURE, "internal error, process_jobs = %d", what); } + + /* All arguments have been processed + */ + if (++nofDone == nofJobs) + goto end; } } } +end: closedir(spool); } /* delete_jobs */