mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-06 09:17:25 +00:00
Add -execdir which will execute the exec command in the dir of the file
in question. This change and the fts changes should be merged into 2.2-stable as soon as they are vetted in -current. This should allow cleaning of files in /tmp to be reneabled. Obtained from: OpenBSD
This commit is contained in:
parent
9a91f1cc25
commit
127d7563c4
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=28914
@ -52,6 +52,7 @@ PLAN *c_ctime __P((char *));
|
|||||||
PLAN *c_delete __P((void));
|
PLAN *c_delete __P((void));
|
||||||
PLAN *c_depth __P((void));
|
PLAN *c_depth __P((void));
|
||||||
PLAN *c_exec __P((char ***, int));
|
PLAN *c_exec __P((char ***, int));
|
||||||
|
PLAN *c_execdir __P((char ***));
|
||||||
PLAN *c_follow __P((void));
|
PLAN *c_follow __P((void));
|
||||||
PLAN *c_fstype __P((char *));
|
PLAN *c_fstype __P((char *));
|
||||||
PLAN *c_group __P((char *));
|
PLAN *c_group __P((char *));
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
.\" SUCH DAMAGE.
|
.\" SUCH DAMAGE.
|
||||||
.\"
|
.\"
|
||||||
.\" @(#)find.1 8.7 (Berkeley) 5/9/95
|
.\" @(#)find.1 8.7 (Berkeley) 5/9/95
|
||||||
.\" $Id: find.1,v 1.9 1997/05/19 16:33:26 eivind Exp $
|
.\" $Id: find.1,v 1.10 1997/05/19 18:16:00 jdp Exp $
|
||||||
.\"
|
.\"
|
||||||
.Dd May 9, 1995
|
.Dd May 9, 1995
|
||||||
.Dt FIND 1
|
.Dt FIND 1
|
||||||
@ -163,6 +163,16 @@ arguments it is replaced by the pathname of the current file.
|
|||||||
will be executed from the directory from which
|
will be executed from the directory from which
|
||||||
.Nm find
|
.Nm find
|
||||||
was executed.
|
was executed.
|
||||||
|
.It Ic -execdir Ar utility Op argument ... ;
|
||||||
|
The
|
||||||
|
.Ic \&-execdir
|
||||||
|
primary is identical to the
|
||||||
|
.Ic -exec
|
||||||
|
primary with the exception that
|
||||||
|
.Ar Utility
|
||||||
|
will be executed from the directory that holds
|
||||||
|
the current file. The filename substituted for
|
||||||
|
the string ``{}'' is not qualified.
|
||||||
.It Ic -fstype Ar type
|
.It Ic -fstype Ar type
|
||||||
True if the file is contained in a file system of type
|
True if the file is contained in a file system of type
|
||||||
.Ar type .
|
.Ar type .
|
||||||
|
@ -39,9 +39,9 @@
|
|||||||
/* node type */
|
/* node type */
|
||||||
enum ntype {
|
enum ntype {
|
||||||
N_AND = 1, /* must start > 0 */
|
N_AND = 1, /* must start > 0 */
|
||||||
N_ATIME, N_CLOSEPAREN, N_CTIME, N_DEPTH, N_EXEC, N_EXPR, N_FOLLOW,
|
N_ATIME, N_CLOSEPAREN, N_CTIME, N_DEPTH, N_EXEC, N_EXECDIR, N_EXPR,
|
||||||
N_FSTYPE, N_GROUP, N_INUM, N_LINKS, N_LS, N_MTIME, N_NAME, N_NEWER,
|
N_FOLLOW, N_FSTYPE, N_GROUP, N_INUM, N_LINKS, N_LS, N_MTIME, N_NAME,
|
||||||
N_NOGROUP, N_NOT, N_NOUSER, N_OK, N_OPENPAREN, N_OR, N_PATH,
|
N_NEWER, N_NOGROUP, N_NOT, N_NOUSER, N_OK, N_OPENPAREN, N_OR, N_PATH,
|
||||||
N_PERM, N_PRINT, N_PRUNE, N_SIZE, N_TYPE, N_USER, N_XDEV,
|
N_PERM, N_PRINT, N_PRUNE, N_SIZE, N_TYPE, N_USER, N_XDEV,
|
||||||
N_PRINT0, N_DELETE
|
N_PRINT0, N_DELETE
|
||||||
};
|
};
|
||||||
@ -101,7 +101,7 @@ typedef struct _option {
|
|||||||
#define O_NONE 0x01 /* no call required */
|
#define O_NONE 0x01 /* no call required */
|
||||||
#define O_ZERO 0x02 /* pass: nothing */
|
#define O_ZERO 0x02 /* pass: nothing */
|
||||||
#define O_ARGV 0x04 /* pass: argv, increment argv */
|
#define O_ARGV 0x04 /* pass: argv, increment argv */
|
||||||
#define O_ARGVP 0x08 /* pass: *argv, N_OK || N_EXEC */
|
#define O_ARGVP 0x08 /* pass: *argv, N_OK || N_EXEC || N_EXECDIR */
|
||||||
int flags;
|
int flags;
|
||||||
} OPTION;
|
} OPTION;
|
||||||
|
|
||||||
|
@ -313,6 +313,106 @@ c_exec(argvp, isok)
|
|||||||
return (new);
|
return (new);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* -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 --
|
||||||
*
|
*
|
||||||
|
@ -63,6 +63,7 @@ static OPTION const options[] = {
|
|||||||
{ "-delete", N_DELETE, c_delete, O_ZERO },
|
{ "-delete", N_DELETE, c_delete, O_ZERO },
|
||||||
{ "-depth", N_DEPTH, c_depth, O_ZERO },
|
{ "-depth", N_DEPTH, c_depth, O_ZERO },
|
||||||
{ "-exec", N_EXEC, c_exec, O_ARGVP },
|
{ "-exec", N_EXEC, c_exec, O_ARGVP },
|
||||||
|
{ "-execdir", N_EXECDIR, c_execdir, O_ARGVP },
|
||||||
{ "-follow", N_FOLLOW, c_follow, O_ZERO },
|
{ "-follow", N_FOLLOW, c_follow, O_ZERO },
|
||||||
{ "-fstype", N_FSTYPE, c_fstype, O_ARGV },
|
{ "-fstype", N_FSTYPE, c_fstype, O_ARGV },
|
||||||
{ "-group", N_GROUP, c_group, O_ARGV },
|
{ "-group", N_GROUP, c_group, O_ARGV },
|
||||||
|
Loading…
Reference in New Issue
Block a user