- 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
This commit is contained in:
gahr 2013-04-12 14:32:16 +00:00
parent b186c48188
commit fd27383897

View File

@ -531,6 +531,10 @@ process_jobs(int argc, char **argv, int what)
/* Delete every argument (job - ID) given
*/
int i;
int rc;
int nofJobs;
int nofDone;
int statErrno;
struct stat buf;
DIR *spool;
struct dirent *dirent;
@ -538,6 +542,9 @@ process_jobs(int argc, char **argv, int what)
char queue;
long jobno;
nofJobs = argc - optind;
nofDone = 0;
PRIV_START
if (chdir(ATJOB_DIR) != 0)
@ -553,9 +560,20 @@ process_jobs(int argc, char **argv, int what)
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;
@ -601,9 +619,15 @@ process_jobs(int argc, char **argv, int what)
errx(EXIT_FAILURE, "internal error, process_jobs = %d",
what);
}
/* All arguments have been processed
*/
if (++nofDone == nofJobs)
goto end;
}
}
}
end:
closedir(spool);
} /* delete_jobs */