svn commit: r252035 - stable/9/usr.bin/at
Pietro Cerutti
gahr at FreeBSD.org
Thu Jun 20 16:51:26 UTC 2013
Author: gahr (ports committer)
Date: Thu Jun 20 16:51:25 2013
New Revision: 252035
URL: http://svnweb.freebsd.org/changeset/base/252035
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/9/usr.bin/at/at.c
Directory Properties:
stable/9/usr.bin/at/ (props changed)
Modified: stable/9/usr.bin/at/at.c
==============================================================================
--- stable/9/usr.bin/at/at.c Thu Jun 20 16:50:05 2013 (r252034)
+++ stable/9/usr.bin/at/at.c Thu Jun 20 16:51:25 2013 (r252035)
@@ -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 */
More information about the svn-src-stable-9
mailing list