[BACK]Return to function.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / find

Diff for /src/usr.bin/find/function.c between version 1.7 and 1.8

version 1.7, 1996/09/01 04:56:26 version 1.8, 1996/12/23 04:58:10
Line 362 
Line 362 
 }  }
   
 /*  /*
    * -execdir utility [arg ... ] ; functions --
    *
    *      True if the executed utility returns a zero value as exit status.
    *      The end of the primary expression is delimited by a semicolon.  If
    *      "{}" occurs anywhere, it gets replaced by the unqualified pathname.
    *      The current directory for the execution of utility is the same as
    *      the directory where the file lives.
    */
   int
   f_execdir(plan, entry)
           register PLAN *plan;
           FTSENT *entry;
   {
           extern int dotfd;
           register int cnt;
           pid_t pid;
           int status;
           char *file;
   
           /* XXX - if file/dir ends in '/' this will not work -- can it? */
           if ((file = strrchr(entry->fts_path, '/')))
               file++;
           else
               file = entry->fts_path;
   
           for (cnt = 0; plan->e_argv[cnt]; ++cnt)
                   if (plan->e_len[cnt])
                           brace_subst(plan->e_orig[cnt], &plan->e_argv[cnt],
                               file, plan->e_len[cnt]);
   
           /* don't mix output of command with find output */
           fflush(stdout);
           fflush(stderr);
   
           switch (pid = vfork()) {
           case -1:
                   err(1, "fork");
                   /* NOTREACHED */
           case 0:
                   execvp(plan->e_argv[0], plan->e_argv);
                   warn("%s", plan->e_argv[0]);
                   _exit(1);
           }
           pid = waitpid(pid, &status, 0);
           return (pid != -1 && WIFEXITED(status) && !WEXITSTATUS(status));
   }
   
   /*
    * c_execdir --
    *      build three parallel arrays, one with pointers to the strings passed
    *      on the command line, one with (possibly duplicated) pointers to the
    *      argv array, and one with integer values that are lengths of the
    *      strings, but also flags meaning that the string has to be massaged.
    */
   PLAN *
   c_execdir(argvp)
           char ***argvp;
   {
           PLAN *new;                      /* node returned */
           register int cnt;
           register char **argv, **ap, *p;
   
           ftsoptions &= ~FTS_NOSTAT;
           isoutput = 1;
   
           new = palloc(N_EXECDIR, f_execdir);
   
           for (ap = argv = *argvp;; ++ap) {
                   if (!*ap)
                           errx(1,
                               "-execdir: no terminating \";\"");
                   if (**ap == ';')
                           break;
           }
   
           cnt = ap - *argvp + 1;
           new->e_argv = (char **)emalloc((u_int)cnt * sizeof(char *));
           new->e_orig = (char **)emalloc((u_int)cnt * sizeof(char *));
           new->e_len = (int *)emalloc((u_int)cnt * sizeof(int));
   
           for (argv = *argvp, cnt = 0; argv < ap; ++argv, ++cnt) {
                   new->e_orig[cnt] = *argv;
                   for (p = *argv; *p; ++p)
                           if (p[0] == '{' && p[1] == '}') {
                                   new->e_argv[cnt] = emalloc((u_int)MAXPATHLEN);
                                   new->e_len[cnt] = MAXPATHLEN;
                                   break;
                           }
                   if (!*p) {
                           new->e_argv[cnt] = *argv;
                           new->e_len[cnt] = 0;
                   }
           }
           new->e_argv[cnt] = new->e_orig[cnt] = NULL;
   
           *argvp = argv + 1;
           return (new);
   }
   
   /*
  * -follow functions --   * -follow functions --
  *   *
  *      Always true, causes symbolic links to be followed on a global   *      Always true, causes symbolic links to be followed on a global

Legend:
Removed from v.1.7  
changed lines
  Added in v.1.8