Use the *at system calls instead of changing directories.

 - todd

Index: usr.bin/at/at.c
===================================================================
RCS file: /cvs/src/usr.bin/at/at.c,v
retrieving revision 1.70
diff -u -p -u -r1.70 at.c
--- usr.bin/at/at.c     9 Nov 2015 15:57:39 -0000       1.70
+++ usr.bin/at/at.c     9 Nov 2015 21:48:05 -0000
@@ -214,8 +214,8 @@ writefile(const char *cwd, time_t runtim
        act.sa_flags = 0;
        sigaction(SIGINT, &act, NULL);
 
-       if ((lockdes = open(AT_SPOOL, O_RDONLY, 0)) < 0)
-               perr("Cannot open jobs dir");
+       if ((lockdes = open(AT_SPOOL, O_RDONLY|O_DIRECTORY, 0)) < 0)
+               perr2("Cannot open ", AT_SPOOL);
 
        /*
         * Lock the jobs dir so we don't have to worry about someone
@@ -479,7 +479,7 @@ list_jobs(int argc, char **argv, int cou
        uid_t *uids;
        char queue, *ep;
        DIR *spool;
-       int i, shortformat;
+       int dfd, i, shortformat;
        size_t numjobs, maxjobs;
 
        if (argc) {
@@ -498,13 +498,11 @@ list_jobs(int argc, char **argv, int cou
 
        shortformat = strcmp(__progname, "at") == 0;
 
-       if (chdir(AT_SPOOL) != 0)
-               perr2("Cannot change to ", AT_SPOOL);
-
-       if ((spool = opendir(".")) == NULL)
+       if ((dfd = open(AT_SPOOL, O_RDONLY|O_DIRECTORY)) == -1 ||
+           (spool = fdopendir(dfd)) == NULL)
                perr2("Cannot open ", AT_SPOOL);
 
-       if (fstat(dirfd(spool), &stbuf) != 0)
+       if (fstat(dfd, &stbuf) != 0)
                perr2("Cannot stat ", AT_SPOOL);
 
        /*
@@ -520,8 +518,8 @@ list_jobs(int argc, char **argv, int cou
 
        /* Loop over every file in the directory. */
        while ((dirent = readdir(spool)) != NULL) {
-               if (stat(dirent->d_name, &stbuf) != 0)
-                       perr2("Cannot stat in ", AT_SPOOL);
+               if (fstatat(dfd, dirent->d_name, &stbuf, AT_SYMLINK_NOFOLLOW) 
!= 0)
+                       perr2("Cannot stat ", dirent->d_name);
 
                /*
                 * See it's a regular file and has its x bit turned on and
@@ -632,12 +630,10 @@ process_jobs(int argc, char **argv, int 
        FILE *fp;
        DIR *spool;
        int job_matches, jobs_len, uids_len;
-       int error, i, ch, changed;
-
-       if (chdir(AT_SPOOL) != 0)
-               perr2("Cannot change to ", AT_SPOOL);
+       int error, i, ch, changed, dfd;
 
-       if ((spool = opendir(".")) == NULL)
+       if ((dfd = open(AT_SPOOL, O_RDONLY|O_DIRECTORY)) == -1 ||
+           (spool = fdopendir(dfd)) == NULL)
                perr2("Cannot open ", AT_SPOOL);
 
        /* Convert argv into a list of jobs and uids. */
@@ -671,8 +667,8 @@ process_jobs(int argc, char **argv, int 
        /* Loop over every file in the directory */
        changed = 0;
        while ((dirent = readdir(spool)) != NULL) {
-               if (stat(dirent->d_name, &stbuf) != 0)
-                       perr2("Cannot stat in ", AT_SPOOL);
+               if (fstatat(dfd, dirent->d_name, &stbuf, AT_SYMLINK_NOFOLLOW) 
!= 0)
+                       perr2("Cannot stat ", dirent->d_name);
 
                if (stbuf.st_uid != user_uid && user_uid != 0)
                        continue;
@@ -709,7 +705,7 @@ process_jobs(int argc, char **argv, int 
                        case ATRM:
                                if (!interactive ||
                                    (interactive && rmok(runtimer))) {
-                                       if (unlink(dirent->d_name) == 0)
+                                       if (unlinkat(dfd, dirent->d_name, 0) == 
0)
                                                changed = 1;
                                        else
                                                perr(dirent->d_name);
@@ -721,9 +717,10 @@ process_jobs(int argc, char **argv, int 
                                break;
 
                        case CAT:
-                               fp = fopen(dirent->d_name, "r");
-                               if (!fp)
-                                       perr("Cannot open file");
+                               i = openat(dfd, dirent->d_name,
+                                   O_RDONLY|O_NOFOLLOW);
+                               if (i == -1 || (fp = fdopen(i, "r")) == NULL)
+                                       perr2("Cannot open ", dirent->d_name);
 
                                while ((ch = getc(fp)) != EOF)
                                        putchar(ch);
@@ -751,12 +748,8 @@ process_jobs(int argc, char **argv, int 
        free(uids);
 
        /* If we modied the spool, poke cron so it knows to reload. */
-       if (changed) {
-               if (chdir(CRONDIR) != 0)
-                       perror(CRONDIR);
-               else
-                       poke_daemon(AT_SPOOL, RELOAD_AT);
-       }
+       if (changed)
+               poke_daemon(AT_SPOOL, RELOAD_AT);
 
        return (error);
 }

Reply via email to