Index: stable/8/usr.bin/at =================================================================== --- stable/8/usr.bin/at (revision 252030) +++ stable/8/usr.bin/at (working copy) Property changes on: stable/8/usr.bin/at ___________________________________________________________________ Added: svn:mergeinfo Merged /stable/9/usr.bin/at:r237100,241364 Merged /user/luigi/ipfw3-r8/usr.bin/at:r204833-205419 Merged /head/usr.bin/at:r196879,198020,198480,198483,198897,199747,199799,199821-199822,200068,200171,200182,200275,200295,200359,201217,201225,203376,203384,203711,204195,205992,207842,207844,208320,212770,213738,213814,216591,223132,223152,223947,224271,224641,226396,227006,227755,228857,230555,234206,234772,236338,236346,236365,238514,240605,249406 Merged /vendor/resolver/dist/usr.bin/at:r1540-186085 Index: stable/8/usr.bin/at/at.c =================================================================== --- stable/8/usr.bin/at/at.c (revision 252030) +++ stable/8/usr.bin/at/at.c (working copy) @@ -533,6 +533,10 @@ /* 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 @@ char queue; long jobno; + nofJobs = argc - optind; + nofDone = 0; + PRIV_START if (chdir(ATJOB_DIR) != 0) @@ -555,9 +562,20 @@ 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 @@ errx(EXIT_FAILURE, "internal error, process_jobs = %d", what); } + + /* All arguments have been processed + */ + if (++nofDone == nofJobs) + goto end; } } } +end: closedir(spool); } /* delete_jobs */