On Thu, Jun 20, 2013 at 8:30 PM, Roland Mainz <[email protected]> wrote:
> On Thu, Jun 20, 2013 at 1:13 PM, Roland Mainz <[email protected]> 
> wrote:
>> On Wed, Jun 19, 2013 at 5:49 PM, Cedric Blancher
>> <[email protected]> wrote:
>>> On 19 June 2013 16:16, David Korn <[email protected]> wrote:
>>>> cc: [email protected]
>>>> Subject: Re: [ast-developers] When will the tree reopen for normal patches?
>>>> --------
>>>>
>>>>> cd /dev/fd/$d no longer works
>>>>
>>>> What do you mean that it no longer works, I just did
>>>>         exec 9< /tmp
>>>> and was able to do
>>>>         cd /dev/fd/9/foo
>>>> to change to /tmp/foo.
>>>>
>>>
>>> /bin/ksh -c 'exec {n}</etc ; cd /dev/fd/$n/ ; true'
>>> /bin/ksh: cd: /dev/fd/11/: [Bad address]
>>>
>>> This has been reported to [email protected] several
>>> times. Search for '[Bad address]'.
>>>
>>> There were also requests for cd -f $n relative_path to allow relative
>>> paths which go above the starting point of fd, e.g. cd -f $n ../../a/b
>>> The other reason for cd -f $fd relative_path was that POSIX does not
>>> standardise absolute paths and that bash and dash developers see it as
>>> a cleaner API to openat() than using /dev/fd
>>
>> Attached (as "astksh_20130613_cd_f_dirfd_002.diff.txt") is the patch
>> to add $ cd -f $fd # ... it's more or less the same solution which was
>> proposed for bash4&&dash, too.
>
> Attached (as "astksh_20130613_cd_f_dirfd_003.diff.txt") is an updated
> patch which fixes the issue that the "pwd" builtin was unable to
> determinate the current cwd location.
>
> The fix works the same way how Sun's Solaris and other OSes with NFSv4
> XATTR support handled the issue in their Bourne shell+csh versions.
>
> Example:
> -- snip --
> $ ksh -c 'redirect {n}<"/etc" ; cd -f $n X11 ; pwd -P; pwd -L ; true'
> -- snip --
> ... will print...
> -- snip --
> /etc/X11
> .
> -- snip --
> ... "/etc/X11" is the physical location... but we use "." as the
> logical location since the logical cwd can not successfully be
> determinated... for example because the directory the descriptor $n is
> pointing to may have moved or the location wasn't know from the
> beginning (David: No... a tracking cache doesn't help if an external
> process or filesystem deamon renames the directory). We can't let
> "pwd" return an error... Sun once determinated that it breaks too many
> scripts (while using "." as logical name seems to work) ... ;-(
>
> More complex example:
> -- snip --
> $ bash -c 'rm -Rf transaction_done ;mkdir transaction1 ; exec
> {n}<"transaction1" ; n=$n ~/bin/ksh -c "mv transaction1
> transaction_done ; cd -f \$n . ; pwd -L ; pwd -P ; true"'
> .
> /home/test001/tmp/l1/transaction_done
> -- snip --
> "." is used as logical name since there is no name associated with the
> file descriptor at the time the shell obtains the fd.

... and finally... in the case David&&Glenn do not like the idea of
"." being returned as logical directory by the "pwd" builtin is a
patch (as 
"astksh_20130613_cd_f_dirfd_003_alternative1_no_logicalpwd_dot.diff.txt")
which throws an error if someone wants to access the logical
directory.

----

Bye,
Roland

-- 
  __ .  . __
 (o.\ \/ /.o) [email protected]
  \__\/\/__/  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/bltins/cd_pwd.c 
build_i386_64bit_debug_cd_f/src/cmd/ksh93/bltins/cd_pwd.c
--- build_i386_64bit_debug/src/cmd/ksh93/bltins/cd_pwd.c        2013-05-16 
16:36:14.000000000 +0200
+++ build_i386_64bit_debug_cd_f/src/cmd/ksh93/bltins/cd_pwd.c   2013-06-20 
20:46:33.378961553 +0200
@@ -19,8 +19,8 @@
 ***********************************************************************/
 #pragma prototyped
 /*
- * cd [-LP@]  [dirname]
- * cd [-LP@]  [old] [new]
+ * cd [-LP@] [-f dirfd] [dirname]
+ * cd [-LP@] [-fdirfd] [old] [new]
  * pwd [-LP]
  *
  *   David Korn
@@ -114,7 +114,7 @@
                        {
                                while(*p=='/')
                                        p++;
-                               path = *p?(const char*)p:0;
+                               path = *p?(const char*)p:e_dot;
                                dir = fd;
                        }
                }
@@ -169,14 +169,24 @@
        register Shell_t *shp = context->shp;
        int saverrno=0;
        int rval;
-       bool flag=false,xattr=false;
+       bool flag=false,xattr=false,unset_pwdnod=false;
        char *oldpwd;
+       int dirfd = shp->pwdfd;
        int newdirfd;
        Namval_t *opwdnod, *pwdnod;
        if(sh_isoption(shp,SH_RESTRICTED))
                errormsg(SH_DICT,ERROR_exit(1),e_restricted+4);
        while((rval = optget(argv,sh_optcd))) switch(rval)
        {
+#ifdef AT_FDCWD
+              case 'f':
+                       errno = 0;
+                       dirfd = strtol(opt_info.arg, (char **)NULL, 10);        
+                       if ((errno != 0) || (dirfd < 0))
+                               errormsg(SH_DICT, ERROR_system(1), "%s: invalid 
dir fd", opt_info.arg);
+                       unset_pwdnod=true;
+                       break;
+#endif
                case 'L':
                        flag = false;
                        break;
@@ -186,6 +196,7 @@
 #ifdef O_XATTR
                case '@':
                        xattr = true;
+                       unset_pwdnod=true;
                        break;
 #endif
                case ':':
@@ -307,7 +318,7 @@
                                        continue;
 #endif /* SHOPT_FS_3D */
                }
-               rval = newdirfd = sh_diropenat(shp, shp->pwdfd,
+               rval = newdirfd = sh_diropenat(shp, dirfd,
                        path_relative(shp,stakptr(PATH_OFFSET)), xattr);
                if(newdirfd >=0)
                {
@@ -346,7 +357,7 @@
        if(rval<0 && *dir=='/' && 
*(path_relative(shp,stakptr(PATH_OFFSET)))!='/')
        {
                rval = newdirfd = sh_diropenat(shp,
-                       shp->pwdfd,
+                       dirfd,
                        dir, xattr);
                if(newdirfd >=0)
                {
@@ -403,9 +414,17 @@
        /* delete trailing '/' */
        while(--flag>0 && dir[flag]=='/')
                dir[flag] = 0;
-       nv_putval(pwdnod,dir,NV_RDONLY);
-       nv_onattr(pwdnod,NV_NOFREE|NV_EXPORT);
-       shp->pwd = pwdnod->nvalue.cp;
+       if (unset_pwdnod)
+       {
+               nv_unset(pwdnod);
+               shp->pwd = strdup(e_dot);
+       }
+       else
+       {
+               nv_putval(pwdnod,dir,NV_RDONLY);
+               nv_onattr(pwdnod,NV_NOFREE|NV_EXPORT);
+               shp->pwd = pwdnod->nvalue.cp;
+       }
        nv_scan(shp->track_tree,rehash,(void*)0,NV_TAGGED,NV_TAGGED);
        path_newdir(shp,shp->pathlist);
        path_newdir(shp,shp->cdpathlist);
@@ -416,17 +435,18 @@
 
 int    b_pwd(int argc, char *argv[],Shbltin_t *context)
 {
-       register int n, flag = 0;
-       register char *cp;
+       register int n;
+       bool pflag = false;
+       register char *cp, *freecp=NULL;
        register Shell_t *shp = context->shp;
        NOT_USED(argc);
        while((n = optget(argv,sh_optpwd))) switch(n)
        {
                case 'L':
-                       flag = 0;
+                       pflag = false;
                        break;
                case 'P':
-                       flag = 1;
+                       pflag = true;
                        break;
                case ':':
                        errormsg(SH_DICT,2, "%s", opt_info.arg);
@@ -437,22 +457,47 @@
        }
        if(error_info.errors)
                errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
-       if(*(cp = path_pwd(shp,0)) != '/')
-               errormsg(SH_DICT,ERROR_system(1), e_pwd);
-       if(flag)
+       cp = path_pwd(shp,0);
+       if(pflag)
        {
+               int mc;
+
+               /*
+                * Try the hard way to find the physical location.
+                * This may happen for NFSv4 xattr directories,
+                * Solaris samfs and some other special cases
+                * which may not have a proper logical name when
+                * "cd" was used.
+                */
+               if(*cp != '/')
+               {
+                       freecp = cp = getcwd(NULL, 0);
+                       if (!cp)
+                               errormsg(SH_DICT,ERROR_system(1), e_pwd);
+               }
+
 #if SHOPT_FS_3D
-               if(shp->gd->lim.fs3d && (flag = 
mount(e_dot,NIL(char*),FS3D_GET|FS3D_VIEW,0))>=0)
+               if(shp->gd->lim.fs3d && (mc = 
mount(e_dot,NIL(char*),FS3D_GET|FS3D_VIEW,0))>=0)
                {
-                       cp = (char*)stakseek(++flag+PATH_MAX);
-                       mount(e_dot,cp,FS3D_GET|FS3D_VIEW|FS3D_SIZE(flag),0);
+                       cp = (char*)stakseek(++mc+PATH_MAX);
+                       mount(e_dot,cp,FS3D_GET|FS3D_VIEW|FS3D_SIZE(mc),0);
                }
                else
 #endif /* SHOPT_FS_3D */
                        cp = strcpy(stakseek(strlen(cp)+PATH_MAX),cp);
                pathcanon(cp,PATH_MAX,PATH_PHYSICAL);
        }
+       else
+       {
+               if(*cp != '/')
+                       errormsg(SH_DICT,ERROR_system(1), e_pwd);
+       }
+
        sfputr(sfstdout,cp,'\n');
+
+       if (freecp)
+               free(freecp);
+
        return(0);
 }
 
diff -r -u build_i386_64bit_debug/src/cmd/ksh93/data/builtins.c 
build_i386_64bit_debug_cd_f/src/cmd/ksh93/data/builtins.c
--- build_i386_64bit_debug/src/cmd/ksh93/data/builtins.c        2013-05-30 
05:34:48.000000000 +0200
+++ build_i386_64bit_debug_cd_f/src/cmd/ksh93/data/builtins.c   2013-06-20 
12:52:28.993198173 +0200
@@ -446,7 +446,7 @@
 ;
 
 const char sh_optcd[] =
-"[-1c?\n@(#)$Id: cd (AT&T Research) 2012-07-10 $\n]"
+"[-1c?\n@(#)$Id: cd (AT&T Research) 2013-06-20 $\n]"
 USAGE_LICENSE
 "[+NAME?cd - change working directory ]"
 "[+DESCRIPTION?\bcd\b changes the current working directory of the "
@@ -482,6 +482,9 @@
        "\bPATH_RESOLVE\b.  If \bPATH_RESOLVE\b is \bphysical\b, "
        "then the behavior will be as if \b-P\b were specified.  Otherwise, "
        "the behavior will be as if  \b-L\b were specified.]"
+#ifdef AT_FDCWD
+"[f]#[dirfd?Path is relative to this directory fd.]"
+#endif
 "[L?Handle each pathname component \b..\b in a logical fashion by moving "
        "up one level by name in the present working directory.]"
 "[P?The present working directory is first converted to an absolute pathname "
Only in build_i386_64bit_debug_cd_f/src/cmd/ksh93/tests: arrays.sh
_______________________________________________
ast-developers mailing list
[email protected]
http://lists.research.att.com/mailman/listinfo/ast-developers

Reply via email to