2012/9/6 Joshuah Hurst <joshhu...@gmail.com>:
> 2012/9/5 Roland Mainz <roland.ma...@nrubsig.org>:
>> 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...
>
> Tried, tested, fell in love :)
>
> My only concern is that redirect {f}<>file never allowed plain numbers
> as f, i.e. redirect {512}<>file. IMO you should remove that, or add
> support that redirect {512}<>file works (I doubt David Korn is going
> to like that and I am not going to like it either).

Grumpf... you're the 2nd person to complain about that detail... ;-/

... attached (as "astksh_tilde_fd003.diff.txt") is an updated patch
which has the support for ~{12345} removed. I added another testcase
to cover the nested use of directory fds, too.

----

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 original/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-06 19:45:51.234025701 +0200
@@ -2679,6 +2679,69 @@
                        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| */
+               Namval_t        *np;
+               const char      *s1;
+               char            *s2;
+               char            *fdvarnamebuf,
+                               *procfdname;
+               size_t          len;
+               int             fd;
+
+               s1=&string[1];
+
+               s2=strchr(s1, '}');
+               if (!s2)
+                       return(NIL(char*));
+
+               len=s2-s1;
+
+               fdvarnamebuf=stkalloc(shp->stk, (len+2)+(PROCFDBUFSIZE+1));
+               if (!fdvarnamebuf)
+                       return(NIL(char*));
+               procfdname=fdvarnamebuf+len+2;
+
+               memcpy(fdvarnamebuf, s1, len);
+               fdvarnamebuf[len]='\0';
+
+               /* Get integer value from variable "varname" in ~{varname} */
+               np = nv_open(fdvarnamebuf, 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/$$/fd/ because this path is valid
+                * across process boundaries and can be passed to
+                * other processes. If /proc is not mounted or does
+                * not support /proc/self/fd then we fall back to
+                * /dev/fd
+                *
+                * 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 original/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-06 20:01:25.855847844 +0200
@@ -496,4 +496,12 @@
 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 for /etc.'
+
+mkdir -p 'foo/bar'
+[[ "$( { redirect {fd}<"$PWD/foo" ; cd ~{fd} ; redirect {fd2}<~{fd}/bar ; cd 
~{fd2} ; /bin/pwd ; true ; } 2>&1)" == *'foo/bar' ]] || \
+       err_exit 'Nested I/O ~{fd} tilde expansion not working for foo/bar.'
+rm -Rf 'foo'
+
 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