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

Reply via email to