summaryrefslogtreecommitdiffstats
path: root/usr.bin/at
diff options
context:
space:
mode:
authorsjg <sjg@FreeBSD.org>2013-04-12 20:48:55 +0000
committersjg <sjg@FreeBSD.org>2013-04-12 20:48:55 +0000
commit97d8b9495668afa398ab17c8c5f7e223b5fd2e89 (patch)
tree54038c9ac32a45f8741dcc23fb9a8ffc0e15ff89 /usr.bin/at
parent5ee3bfdb338e7c80af29a67f4425c4be24c7b866 (diff)
parent086d73aef6d0ab7d21daa2076fdc8d25961f9b05 (diff)
downloadFreeBSD-src-97d8b9495668afa398ab17c8c5f7e223b5fd2e89.zip
FreeBSD-src-97d8b9495668afa398ab17c8c5f7e223b5fd2e89.tar.gz
sync from head
Diffstat (limited to 'usr.bin/at')
-rw-r--r--usr.bin/at/at.c28
-rw-r--r--usr.bin/at/privs.h2
2 files changed, 27 insertions, 3 deletions
diff --git a/usr.bin/at/at.c b/usr.bin/at/at.c
index cb2fadb..5f4500b 100644
--- a/usr.bin/at/at.c
+++ b/usr.bin/at/at.c
@@ -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 */
diff --git a/usr.bin/at/privs.h b/usr.bin/at/privs.h
index 297c252..2b0d34a 100644
--- a/usr.bin/at/privs.h
+++ b/usr.bin/at/privs.h
@@ -99,8 +99,8 @@ gid_t real_gid, effective_gid;
PRIV_START \
effective_uid = (a); \
effective_gid = (b); \
- if (setreuid((uid_t)-1, effective_uid) != 0) err(1, "setreuid failed"); \
if (setregid((gid_t)-1, effective_gid) != 0) err(1, "setregid failed"); \
+ if (setreuid((uid_t)-1, effective_uid) != 0) err(1, "setreuid failed"); \
PRIV_END \
}
#endif
OpenPOWER on IntegriCloud