Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: PATCH: chown and chgrp in files module
- X-seq: zsh-workers 8983
- From: James Kirkpatrick <jimkirk@xxxxxxxx>
- To: zefram@xxxxxxxx
- Subject: Re: PATCH: chown and chgrp in files module
- Date: Thu, 09 Dec 1999 10:20:53 -0700 (MST)
- Cc: zsh-workers@xxxxxxxxxxxxxx
- In-reply-to: <199912091602.QAA02007@xxxxxxxxxxxxxxxxxxxx>
- Mailing-list: contact zsh-workers-help@xxxxxxxxxxxxxx; run by ezmlm
I'm not sure I understand. chown and chgrp are now builtins? I need to
object to this. We use, for example, the GNU shell utilities, and rely on
certain of the options and syntaxes available. Will the zsh builtins
attempt to emulate all options from everybody's chown and chgrp? Are they
POSIX compliant?
This does not seem to be the sort of thing that should be built in to a
shell, any more than rm, ls, find, or a C compiler :-)
Jim
On Thu, 9 Dec 1999 zefram@xxxxxxxx wrote:
> I got a request for chown/chgrp as shell builtins, so here they are.
> It's pretty simple; most of the code change is actually just factoring
> out the recursion code from rm, so that it can be shared with chown.
> As a bonus, chown gets rm's -s option.
>
> I'm not 100% happy about the error handling in the recursion code.
> It seems to me that if the current directory is lost, the error message
> and return code should not be suppressed by rm's -f option. But I've
> left it as it is, because I don't immediately see how to separate out
> that case from the other errors handled by that code.
>
> -zefram
>
> diff -cr ../zsh-/Doc/Zsh/mod_files.yo ./Doc/Zsh/mod_files.yo
> *** ../zsh-/Doc/Zsh/mod_files.yo Sun Nov 28 17:42:27 1999
> --- ./Doc/Zsh/mod_files.yo Thu Dec 9 12:33:23 1999
> ***************
> *** 4,9 ****
> --- 4,46 ----
> The tt(files) module makes some standard commands available as builtins:
>
> startitem()
> + findex(chgrp)
> + item(tt(chgrp) [ tt(-Rs) ] var(group) var(filename) ...)(
> + Changes group of files specified. This is equivalent to tt(chown) with
> + a var(user-spec) argument of `tt(:)var(group)'.
> + )
> + findex(chown)
> + item(tt(chown) [ tt(-Rs) ] var(user-spec) var(filename) ...)(
> + Changes ownership and group of files specified.
> +
> + The var(user-spec) can be in four forms:
> +
> + startsitem()
> + sitem(var(user))(change owner to var(user); do not change group)
> + sitem(var(user)tt(:))(change owner to var(user); change group to var(user)'s primary group)
> + sitem(var(user)tt(:)var(group))(change owner to var(user); change group to var(group))
> + sitem(tt(:)var(group))(do not change owner; change group to var(group))
> + endsitem()
> +
> + In each case, the `tt(:)' may instead be a `tt(.)'.
> + Each of var(user) and var(group) may be either a username (or group name, as
> + appropriate) or a decimal user ID (group ID). Interpretation as a name
> + takes precedence, if there is an all-numeric username (or group name).
> +
> + The tt(-R) option causes tt(chown) to recursively descend into directories,
> + changing the ownership of all files in the directory after
> + changing the ownership of the directory itself.
> +
> + The tt(-s) option is a zsh extension to tt(chown) functionality. It enables
> + paranoid behaviour, intended to avoid security problems involving
> + a tt(chown) being tricked into affecting files other than the ones
> + intended. It will refuse to follow symbolic links, so that (for example)
> + ``tt(chown luser /tmp/foo/passwd)'' can't accidentally chown tt(/etc/passwd)
> + if tt(/tmp/foo) happens to be a link to tt(/etc). It will also check
> + where it is after leaving directories, so that a recursive chown of
> + a deep directory tree can't end up recursively chowning tt(/usr) as
> + a result of directories being moved up the tree.
> + )
> findex(ln)
> xitem(tt(ln) [ tt(-dfis) ] var(filename) var(dest))
> item(tt(ln) [ tt(-dfis) ] var(filename) ... var(dir))(
> diff -cr ../zsh-/Src/Modules/files.c ./Src/Modules/files.c
> *** ../zsh-/Src/Modules/files.c Sun Nov 28 17:42:28 1999
> --- ./Src/Modules/files.c Thu Dec 9 15:43:52 1999
> ***************
> *** 30,35 ****
> --- 30,36 ----
> #include "files.mdh"
>
> typedef int (*MoveFunc) _((char const *, char const *));
> + typedef int (*RecurseFunc) _((char *, char *, struct stat const *, void *));
>
> #ifndef STDC_HEADERS
> extern int link _((const char *, const char *));
> ***************
> *** 37,42 ****
> --- 38,45 ----
> extern int rename _((const char *, const char *));
> #endif
>
> + struct recursivecmd;
> +
> #include "files.pro"
>
> /**/
> ***************
> *** 312,331 ****
> return 0;
> }
>
> ! /* rm builtin */
>
> /**/
> static int
> ! bin_rm(char *nam, char **args, char *ops, int func)
> {
> int err = 0, len;
> char *rp, *s;
> struct dirsav ds;
>
> ds.ino = ds.dev = 0;
> ds.dirname = NULL;
> ds.dirfd = ds.level = -1;
> ! if (ops['r'] || ops['s']) {
> if ((ds.dirfd = open(".", O_RDONLY|O_NOCTTY)) < 0 &&
> zgetdir(&ds) && *ds.dirname != '/')
> ds.dirfd = open("..", O_RDONLY|O_NOCTTY);
> --- 315,356 ----
> return 0;
> }
>
> ! /* general recursion */
> !
> ! struct recursivecmd {
> ! char *nam;
> ! int opt_noerr;
> ! int opt_recurse;
> ! int opt_safe;
> ! RecurseFunc dirpre_func;
> ! RecurseFunc dirpost_func;
> ! RecurseFunc leaf_func;
> ! void *magic;
> ! };
>
> /**/
> static int
> ! recursivecmd(char *nam, int opt_noerr, int opt_recurse, int opt_safe,
> ! char **args, RecurseFunc dirpre_func, RecurseFunc dirpost_func,
> ! RecurseFunc leaf_func, void *magic)
> {
> int err = 0, len;
> char *rp, *s;
> struct dirsav ds;
> + struct recursivecmd reccmd;
>
> + reccmd.nam = nam;
> + reccmd.opt_noerr = opt_noerr;
> + reccmd.opt_recurse = opt_recurse;
> + reccmd.opt_safe = opt_safe;
> + reccmd.dirpre_func = dirpre_func;
> + reccmd.dirpost_func = dirpost_func;
> + reccmd.leaf_func = leaf_func;
> + reccmd.magic = magic;
> ds.ino = ds.dev = 0;
> ds.dirname = NULL;
> ds.dirfd = ds.level = -1;
> ! if (opt_recurse || opt_safe) {
> if ((ds.dirfd = open(".", O_RDONLY|O_NOCTTY)) < 0 &&
> zgetdir(&ds) && *ds.dirname != '/')
> ds.dirfd = open("..", O_RDONLY|O_NOCTTY);
> ***************
> *** 333,339 ****
> for(; !errflag && !(err & 2) && *args; args++) {
> rp = ztrdup(*args);
> unmetafy(rp, &len);
> ! if (ops['s']) {
> s = strrchr(rp, '/');
> if (s && !s[1]) {
> while (*s == '/' && s > rp)
> --- 358,364 ----
> for(; !errflag && !(err & 2) && *args; args++) {
> rp = ztrdup(*args);
> unmetafy(rp, &len);
> ! if (opt_safe) {
> s = strrchr(rp, '/');
> if (s && !s[1]) {
> while (*s == '/' && s > rp)
> ***************
> *** 353,368 ****
> d.ino = d.dev = 0;
> d.dirname = NULL;
> d.dirfd = d.level = -1;
> ! err |= dorm(nam, *args, s + 1, ops, &d, 0);
> zsfree(d.dirname);
> if (restoredir(&ds))
> err |= 2;
> ! } else
> zwarnnam(nam, "%s: %e", *args, errno);
> } else
> ! err |= dorm(nam, *args, rp, ops, &ds, 0);
> } else
> ! err |= dorm(nam, *args, rp, ops, &ds, 1);
> zfree(rp, len + 1);
> }
> if ((err & 2) && ds.dirfd >= 0 && restoredir(&ds) && zchdir(pwd)) {
> --- 378,393 ----
> d.ino = d.dev = 0;
> d.dirname = NULL;
> d.dirfd = d.level = -1;
> ! err |= recursivecmd_doone(&reccmd, *args, s + 1, &d, 0);
> zsfree(d.dirname);
> if (restoredir(&ds))
> err |= 2;
> ! } else if(!opt_noerr)
> zwarnnam(nam, "%s: %e", *args, errno);
> } else
> ! err |= recursivecmd_doone(&reccmd, *args, rp, &ds, 0);
> } else
> ! err |= recursivecmd_doone(&reccmd, *args, rp, &ds, 1);
> zfree(rp, len + 1);
> }
> if ((err & 2) && ds.dirfd >= 0 && restoredir(&ds) && zchdir(pwd)) {
> ***************
> *** 373,448 ****
> if (ds.dirfd >= 0)
> close(ds.dirfd);
> zsfree(ds.dirname);
> ! return ops['f'] ? 0 : !!err;
> }
>
> /**/
> static int
> ! dorm(char *nam, char *arg, char *rp, char *ops, struct dirsav *ds, int first)
> {
> ! struct stat st;
>
> ! if((!ops['d'] || !ops['f']) && !lstat(rp, &st)) {
> ! if(!ops['d'] && S_ISDIR(st.st_mode)) {
> ! if(ops['r'])
> ! return dormr(nam, arg, rp, ops, ds, first);
> ! if(!ops['f'])
> ! zwarnnam(nam, "%s: %e", arg, EISDIR);
> ! return 1;
> ! }
> ! if(!ops['f'] && ops['i']) {
> ! nicezputs(nam, stderr);
> ! fputs(": remove `", stderr);
> ! nicezputs(arg, stderr);
> ! fputs("'? ", stderr);
> ! fflush(stderr);
> ! if(!ask())
> ! return 0;
> ! } else if(!ops['f'] &&
> ! !S_ISLNK(st.st_mode) &&
> ! access(rp, W_OK)) {
> ! nicezputs(nam, stderr);
> ! fputs(": remove `", stderr);
> ! nicezputs(arg, stderr);
> ! fprintf(stderr, "', overriding mode %04o? ",
> ! mode_to_octal(st.st_mode));
> ! fflush(stderr);
> ! if(!ask())
> ! return 0;
> ! }
> }
> ! if(!unlink(rp))
> ! return 0;
> ! if(!ops['f'])
> ! zwarnnam(nam, "%s: %e", arg, errno);
> ! return 1;
> }
>
> /**/
> static int
> ! dormr(char *nam, char *arg, char *rp, char *ops, struct dirsav *ds, int first)
> {
> char *fn;
> DIR *d;
> ! int err;
> struct dirsav dsav;
> char *files = NULL;
> int fileslen = 0;
>
> err = -lchdir(rp, ds, !first);
> if (err) {
> ! if (!ops['f'])
> ! zwarnnam(nam, "%s: %e", arg, errno);
> return err;
> }
>
> dsav.ino = dsav.dev = 0;
> dsav.dirname = NULL;
> dsav.dirfd = dsav.level = -1;
> d = opendir(".");
> if(!d) {
> ! if(!ops['f'])
> ! zwarnnam(nam, "%s: %e", arg, errno);
> err = 1;
> } else {
> int arglen = strlen(arg) + 1;
> --- 398,452 ----
> if (ds.dirfd >= 0)
> close(ds.dirfd);
> zsfree(ds.dirname);
> ! return !!err;
> }
>
> /**/
> static int
> ! recursivecmd_doone(struct recursivecmd const *reccmd,
> ! char *arg, char *rp, struct dirsav *ds, int first)
> {
> ! struct stat st, *sp = NULL;
>
> ! if(reccmd->opt_recurse && !lstat(rp, &st)) {
> ! if(S_ISDIR(st.st_mode))
> ! return recursivecmd_dorec(reccmd, arg, rp, &st, ds, first);
> ! sp = &st;
> }
> ! return reccmd->leaf_func(arg, rp, sp, reccmd->magic);
> }
>
> /**/
> static int
> ! recursivecmd_dorec(struct recursivecmd const *reccmd,
> ! char *arg, char *rp, struct stat const *sp, struct dirsav *ds, int first)
> {
> char *fn;
> DIR *d;
> ! int err, err1;
> struct dirsav dsav;
> char *files = NULL;
> int fileslen = 0;
>
> + err1 = reccmd->dirpre_func(arg, rp, sp, reccmd->magic);
> + if(err1 & 2)
> + return 2;
> +
> err = -lchdir(rp, ds, !first);
> if (err) {
> ! if(!reccmd->opt_noerr)
> ! zwarnnam(reccmd->nam, "%s: %e", arg, errno);
> return err;
> }
> + err = err1;
>
> dsav.ino = dsav.dev = 0;
> dsav.dirname = NULL;
> dsav.dirfd = dsav.level = -1;
> d = opendir(".");
> if(!d) {
> ! if(!reccmd->opt_noerr)
> ! zwarnnam(reccmd->nam, "%s: %e", arg, errno);
> err = 1;
> } else {
> int arglen = strlen(arg) + 1;
> ***************
> *** 462,468 ****
> narg[arglen-1] = '/';
> strcpy(narg + arglen, fn);
> unmetafy(fn, NULL);
> ! err |= dorm(nam, narg, fn, ops, &dsav, 0);
> fn += l;
> }
> hrealloc(files, fileslen, 0);
> --- 466,472 ----
> narg[arglen-1] = '/';
> strcpy(narg + arglen, fn);
> unmetafy(fn, NULL);
> ! err |= recursivecmd_doone(reccmd, narg, fn, &dsav, 0);
> fn += l;
> }
> hrealloc(files, fileslen, 0);
> ***************
> *** 471,495 ****
> if (err & 2)
> return 2;
> if (restoredir(ds)) {
> ! if(!ops['f'])
> ! zwarnnam(nam, "failed to return to previous directory: %e",
> NULL, errno);
> return 2;
> }
> ! if(!ops['f'] && ops['i']) {
> ! nicezputs(nam, stderr);
> fputs(": remove `", stderr);
> nicezputs(arg, stderr);
> fputs("'? ", stderr);
> fflush(stderr);
> if(!ask())
> ! return err;
> }
> ! if(!rmdir(rp))
> ! return err;
> ! if(!ops['f'])
> ! zwarnnam(nam, "%s: %e", arg, errno);
> ! return 1;
> }
>
> /* module paraphernalia */
> --- 475,693 ----
> if (err & 2)
> return 2;
> if (restoredir(ds)) {
> ! if(!reccmd->opt_noerr)
> ! zwarnnam(reccmd->nam, "failed to return to previous directory: %e",
> NULL, errno);
> return 2;
> }
> ! return err | reccmd->dirpost_func(arg, rp, sp, reccmd->magic);
> ! }
> !
> ! /**/
> ! static int
> ! recurse_donothing(char *arg, char *rp, struct stat const *sp, void *magic)
> ! {
> ! return 0;
> ! }
> !
> ! /* rm builtin */
> !
> ! struct rmmagic {
> ! char *nam;
> ! int opt_force;
> ! int opt_interact;
> ! int opt_unlinkdir;
> ! };
> !
> ! /**/
> ! static int
> ! rm_leaf(char *arg, char *rp, struct stat const *sp, void *magic)
> ! {
> ! struct rmmagic *rmm = magic;
> ! struct stat st;
> !
> ! if(!rmm->opt_unlinkdir || !rmm->opt_force) {
> ! if(!sp) {
> ! if(!lstat(rp, &st))
> ! sp = &st;
> ! }
> ! if(sp) {
> ! if(!rmm->opt_unlinkdir && S_ISDIR(sp->st_mode)) {
> ! if(rmm->opt_force)
> ! return 0;
> ! zwarnnam(rmm->nam, "%s: %e", arg, EISDIR);
> ! return 1;
> ! }
> ! if(rmm->opt_interact) {
> ! nicezputs(rmm->nam, stderr);
> ! fputs(": remove `", stderr);
> ! nicezputs(arg, stderr);
> ! fputs("'? ", stderr);
> ! fflush(stderr);
> ! if(!ask())
> ! return 0;
> ! } else if(!rmm->opt_force &&
> ! !S_ISLNK(sp->st_mode) &&
> ! access(rp, W_OK)) {
> ! nicezputs(rmm->nam, stderr);
> ! fputs(": remove `", stderr);
> ! nicezputs(arg, stderr);
> ! fprintf(stderr, "', overriding mode %04o? ",
> ! mode_to_octal(sp->st_mode));
> ! fflush(stderr);
> ! if(!ask())
> ! return 0;
> ! }
> ! }
> ! }
> ! if(unlink(rp) && !rmm->opt_force) {
> ! zwarnnam(rmm->nam, "%s: %e", arg, errno);
> ! return 1;
> ! }
> ! return 0;
> ! }
> !
> ! /**/
> ! static int
> ! rm_dirpost(char *arg, char *rp, struct stat const *sp, void *magic)
> ! {
> ! struct rmmagic *rmm = magic;
> !
> ! if(rmm->opt_interact) {
> ! nicezputs(rmm->nam, stderr);
> fputs(": remove `", stderr);
> nicezputs(arg, stderr);
> fputs("'? ", stderr);
> fflush(stderr);
> if(!ask())
> ! return 0;
> }
> ! if(rmdir(rp) && !rmm->opt_force) {
> ! zwarnnam(rmm->nam, "%s: %e", arg, errno);
> ! return 1;
> ! }
> ! return 0;
> ! }
> !
> ! /**/
> ! static int
> ! bin_rm(char *nam, char **args, char *ops, int func)
> ! {
> ! struct rmmagic rmm;
> ! int err;
> !
> ! rmm.nam = nam;
> ! rmm.opt_force = ops['f'];
> ! rmm.opt_interact = ops['i'] && !ops['f'];
> ! rmm.opt_unlinkdir = ops['d'];
> ! err = recursivecmd(nam, ops['f'], ops['r'] && !ops['d'], ops['s'],
> ! args, recurse_donothing, rm_dirpost, rm_leaf, &rmm);
> ! return ops['f'] ? 0 : err;
> ! }
> !
> ! /* chown builtin */
> !
> ! struct chownmagic {
> ! char *nam;
> ! uid_t uid;
> ! gid_t gid;
> ! };
> !
> ! /**/
> ! static int
> ! chown_dochown(char *arg, char *rp, struct stat const *sp, void *magic)
> ! {
> ! struct chownmagic *chm = magic;
> !
> ! if(lchown(rp, chm->uid, chm->gid)) {
> ! zwarnnam(chm->nam, "%s: %e", arg, errno);
> ! return 1;
> ! }
> ! return 0;
> ! }
> !
> ! /**/
> ! static unsigned long getnumeric(char *p, int *errp)
> ! {
> ! unsigned long ret;
> !
> ! if(*p < '0' || *p > '9') {
> ! *errp = 1;
> ! return 0;
> ! }
> ! ret = strtoul(p, &p, 10);
> ! *errp = !!*p;
> ! return ret;
> ! }
> !
> ! enum { BIN_CHOWN, BIN_CHGRP };
> !
> ! /**/
> ! static int
> ! bin_chown(char *nam, char **args, char *ops, int func)
> ! {
> ! struct chownmagic chm;
> ! char *uspec = ztrdup(*args), *p = uspec;
> !
> ! chm.nam = nam;
> ! if(func == BIN_CHGRP) {
> ! chm.uid = -1;
> ! goto dogroup;
> ! }
> ! if(*p == ':' || *p == '.') {
> ! chm.uid = -1;
> ! p++;
> ! goto dogroup;
> ! } else {
> ! struct passwd *pwd;
> ! char *end = strchr(p, ':');
> ! if(!end)
> ! end = strchr(p, '.');
> ! if(end)
> ! *end = 0;
> ! pwd = getpwnam(p);
> ! if(pwd)
> ! chm.uid = pwd->pw_uid;
> ! else {
> ! int err;
> ! chm.uid = getnumeric(p, &err);
> ! if(err) {
> ! zwarnnam(nam, "%s: no such user", p, 0);
> ! free(uspec);
> ! return 1;
> ! }
> ! }
> ! if(end) {
> ! p = end+1;
> ! if(!*p) {
> ! if(!pwd && !(pwd = getpwuid(chm.uid))) {
> ! zwarnnam(nam, "%s: no such user", uspec, 0);
> ! free(uspec);
> ! return 1;
> ! }
> ! chm.gid = pwd->pw_gid;
> ! } else {
> ! struct group *grp;
> ! dogroup:
> ! grp = getgrnam(p);
> ! if(grp)
> ! chm.gid = grp->gr_gid;
> ! else {
> ! int err;
> ! chm.gid = getnumeric(p, &err);
> ! if(err) {
> ! zwarnnam(nam, "%s: no such group", p, 0);
> ! free(uspec);
> ! return 1;
> ! }
> ! }
> ! }
> ! } else
> ! chm.gid = -1;
> ! }
> ! free(uspec);
> ! return recursivecmd(nam, 0, ops['R'], ops['s'],
> ! args + 1, chown_dochown, recurse_donothing, chown_dochown, &chm);
> }
>
> /* module paraphernalia */
> ***************
> *** 501,512 ****
> #endif
>
> static struct builtin bintab[] = {
> ! BUILTIN("ln", 0, bin_ln, 1, -1, BIN_LN, LN_OPTS, NULL),
> ! BUILTIN("mkdir", 0, bin_mkdir, 1, -1, 0, "pm", NULL),
> ! BUILTIN("mv", 0, bin_ln, 2, -1, BIN_MV, "fi", NULL),
> ! BUILTIN("rm", 0, bin_rm, 1, -1, 0, "dfirs", NULL),
> ! BUILTIN("rmdir", 0, bin_rmdir, 1, -1, 0, NULL, NULL),
> ! BUILTIN("sync", 0, bin_sync, 0, 0, 0, NULL, NULL),
> };
>
> /**/
> --- 699,712 ----
> #endif
>
> static struct builtin bintab[] = {
> ! BUILTIN("chgrp", 0, bin_chown, 2, -1, BIN_CHGRP, "Rs", NULL),
> ! BUILTIN("chown", 0, bin_chown, 2, -1, BIN_CHOWN, "Rs", NULL),
> ! BUILTIN("ln", 0, bin_ln, 1, -1, BIN_LN, LN_OPTS, NULL),
> ! BUILTIN("mkdir", 0, bin_mkdir, 1, -1, 0, "pm", NULL),
> ! BUILTIN("mv", 0, bin_ln, 2, -1, BIN_MV, "fi", NULL),
> ! BUILTIN("rm", 0, bin_rm, 1, -1, 0, "dfirs", NULL),
> ! BUILTIN("rmdir", 0, bin_rmdir, 1, -1, 0, NULL, NULL),
> ! BUILTIN("sync", 0, bin_sync, 0, 0, 0, NULL, NULL),
> };
>
> /**/
> diff -cr ../zsh-/Src/Modules/files.mdd ./Src/Modules/files.mdd
> *** ../zsh-/Src/Modules/files.mdd Sun Nov 28 17:42:28 1999
> --- ./Src/Modules/files.mdd Thu Dec 9 12:33:44 1999
> ***************
> *** 1,3 ****
> ! autobins="ln mkdir mv rm rmdir sync"
>
> objects="files.o"
> --- 1,3 ----
> ! autobins="chgrp chown ln mkdir mv rm rmdir sync"
>
> objects="files.o"
> diff -cr ../zsh-/Src/system.h ./Src/system.h
> *** ../zsh-/Src/system.h Sun Nov 28 17:42:28 1999
> --- ./Src/system.h Thu Dec 9 15:19:03 1999
> ***************
> *** 583,588 ****
> --- 583,592 ----
> # define R_OK 4
> #endif
>
> + #ifndef HAVE_LCHOWN
> + # define lchown chown
> + #endif
> +
> #ifndef HAVE_MEMCPY
> # define memcpy memmove
> #endif
> diff -cr ../zsh-/configure.in ./configure.in
> *** ../zsh-/configure.in Wed Dec 8 19:58:26 1999
> --- ./configure.in Thu Dec 9 15:18:05 1999
> ***************
> *** 784,790 ****
> dnl need to integrate this function
> dnl AC_FUNC_STRFTIME
>
> ! AC_CHECK_FUNCS(memcpy memmove \
> strftime waitpid select poll tcsetpgrp tcgetattr strstr lstat \
> getlogin setpgid gettimeofday gethostname mkfifo wait3 difftime \
> sigblock sigsetmask sigrelse sighold killpg sigaction getrlimit \
> --- 784,790 ----
> dnl need to integrate this function
> dnl AC_FUNC_STRFTIME
>
> ! AC_CHECK_FUNCS(lchown memcpy memmove \
> strftime waitpid select poll tcsetpgrp tcgetattr strstr lstat \
> getlogin setpgid gettimeofday gethostname mkfifo wait3 difftime \
> sigblock sigsetmask sigrelse sighold killpg sigaction getrlimit \
> END
>
Messages sorted by:
Reverse Date,
Date,
Thread,
Author