2012/9/5 Roland Mainz <roland.ma...@nrubsig.org>: > 2012/9/5 David Korn <d...@research.att.com>: > [CC:ing ast-developers@research.att.com so that the patch gets archived] >> cc: g...@research.att.com olga.kryzhanov...@gmail.com >> Subject: Re: New syntax for paths relative to directory fds >> (~{dirfd}/foo/bar.txt) ... >>> [Mostly Olga's idea (who is away and can't post anyway here since the >>> AT&T spam filters have a grudge against her native name... ;-( )] >>> >>> Woud the following syntax for paths relative to a directory fd "dirfd" >>> be possible without violating POSIX (right now the only way to archive >>> this is to use /dev/fd/${dirfd}/ ... which works OK but may not be >>> suiteable for a new version of the POSIX standard since POSIX does not >>> mandate any absolute paths): >>> >>> ~{dirfd}/foo/bar/txt >>> >>> (where "dirfd" is a directory fd and "foo/bar/txt" is a path relative >>> to this fd) >>> >>> Example usage: >>> -- snip -- >>> # print contents of /etc/profile and /etc/ksh.kshrc >>> redirect {dirfd}<"/etc" >>> cat <~{dirfd}/profile >>> cat <~{dirfd}/ksh.kshrc >>> -- snip -- >>> >> >> That could be done. The code is in sh/macro.c sh_tilde_expand2(). > [snip] > > Attached (as "astksh_tilde_fd001.diff.txt") is a prototype patch. > Technically it works without problems... but I'm not happy with the > |static| variable |devfdname| (short: Ugly |static| variable... which > means: Global variable (with function-local scope). Not thread-safe). > > Question: Is it _valid_ to allocate space from |shp->stk| and return > the string as return value of |sh_tilde()| ? Who or what is going to > deallocate the memory chunk ?
Short answer from David: -- snip -- Anything on shp->stk will get deleted when the command that it is expanding completes. -- snip -- Attached (as "astksh_tilde_fd002.diff.txt") is a revised patch (without function-static variables) per David&co.'s (code review) feedback... ---- Bye, Roland -- __ . . __ (o.\ \/ /.o) roland.ma...@nrubsig.org \__\/\/__/ MPEG specialist, C&&JAVA&&Sun&&Unix programmer /O /==\ O\ TEL +49 641 3992797 (;O/ \/ \O;)
diff -r -u build_i386_64bit_debug/src/cmd/ksh93/sh/macro.c build_fdsyntax/src/cmd/ksh93/sh/macro.c --- src/cmd/ksh93/sh/macro.c 2012-08-30 22:33:50.000000000 +0200 +++ src/cmd/ksh93/sh/macro.c 2012-09-05 22:47:26.194147930 +0200 @@ -2679,6 +2679,86 @@ cp = nv_getval(sh_scoped(shp,OLDPWDNOD)); return(cp); } + if(c=='{') + { +#define PROCFDBUFSIZE (20+(28*2)+1) /* sized to fit /proc format string and two |long| */ + const char *s1; + char *s2; + char *fdnamebuf, + *procfdname; + size_t len; + int fd; + + s1=&string[1]; + + s2=strchr(s1, '}'); + if (!s2) + return(NIL(char*)); + + len=s2-s1; + + fdnamebuf=stkalloc(shp->stk, (len+2)+PROCFDBUFSIZE); + if (!fdnamebuf) + return(NIL(char*)); + procfdname=fdnamebuf+len+2; + + memcpy(fdnamebuf, s1, len); + fdnamebuf[len]='\0'; + + /* + * |fdnamebuf| may now contain either a variable name + * or a fd number (we assume that variable names + * cannot start with a digit). + * Note that we allow hexadecimal fd numbers, too. + */ + if (isdigit(fdnamebuf[0])) + { + /* + * We explicitly convert from string to integer and + * back to ensure that noone can do any stunts to + * bypass security + */ + errno=0; + fd=strtol(fdnamebuf, (char **)NULL, 10); + if(errno!=0) + return(NIL(char*)); + } + else + { + Namval_t *np; + np = nv_open(fdnamebuf, shp->var_tree, NV_VARNAME|NV_NOFAIL|NV_NOADD); + if (!np) + return(NIL(char*)); + fd = (int)nv_getnum(np); + nv_close(np); + } + + if (fd < 0) + return(NIL(char*)); + + /* + * We use /proc/$PID/fd/ because this path is valid + * across process boundaries and can be passed to + * other processes... + * + * Notes: + * - the format string does not end with a '/', + * we did this to allow that ~{fd} can be used for + * plain files, too. + * - we can't cache the test whether /proc is mounted + * since the currently running script may call + * "umount" itself + */ + if (access("/proc/self/fd", X_OK) == 0) + { + snprintf(procfdname, PROCFDBUFSIZE, "/proc/%ld/fd/%d", (long)getpid(), fd); + } + else + { + snprintf(procfdname, PROCFDBUFSIZE, "/dev/fd/%d", fd); + } + return (procfdname); + } #if _WINIX if(fcgetc(c)=='/') { diff -r -u build_i386_64bit_debug/src/cmd/ksh93/tests/io.sh build_fdsyntax/src/cmd/ksh93/tests/io.sh --- src/cmd/ksh93/tests/io.sh 2012-07-10 20:26:14.000000000 +0200 +++ src/cmd/ksh93/tests/io.sh 2012-09-05 22:39:10.320811117 +0200 @@ -496,4 +496,7 @@ n=$( exec {n}< /dev/null; print -r -- $n) [[ -r /dev/fd/$n ]] && err_exit "file descriptor n=$n left open after subshell" +[[ "$( { redirect {fd}<'/etc' ; cd ~{fd} ; /bin/pwd ; true ; } 2>&1)" == '/etc' ]] || \ + err_exit 'I/O fd tilde expansion not working.' + exit $((Errors<125?Errors:125))
_______________________________________________ ast-developers mailing list ast-developers@research.att.com https://mailman.research.att.com/mailman/listinfo/ast-developers