LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   /.../ in directory path (https://www.linuxquestions.org/questions/programming-9/in-directory-path-943950/)

Sergei Steshenko 05-08-2012 04:50 PM

/.../ in directory path
 
Building 'libproxy' and running 'make install' (Makefiles are generated by 'cmake') I've noticed lines like this:

Code:

-- Installing: /mnt/sdb8/sergei/AFSWD_debug/20120424/libproxy-0.4.7/.../../lib/site_perl/5.14.2/i686-linux-thread-multi/Net/Libproxy.pm
- pay attention to "/.../".

/bin/sh accepts such paths, for example:

Code:

sergei@amdam2:~/junk> cd /mnt/sdb8/sergei/AFSWD_debug/20120424/libproxy-0.4.7/.../../lib/site_perl/5.14.2/i686-linux-thread-multi/Net/
sergei@amdam2:/mnt/sdb8/sergei/AFSWD_debug/20120424/libproxy-0.4.7/lib/site_perl/5.14.2/i686-linux-thread-multi/Net> pwd
/mnt/sdb8/sergei/AFSWD_debug/20120424/libproxy-0.4.7/lib/site_perl/5.14.2/i686-linux-thread-multi/Net

From the above it looks like

Code:

/.../../
is equivalent to

Code:

/
.

Could someone please enlighten me where and and what to read on "/.../" - I don't remember seeing it before.

Kustom42 05-08-2012 04:59 PM

That does not work for me and I have never seen or heard of it during my red hat admin days. I tried several test shell scripts and none worked.

Sergei Steshenko 05-08-2012 05:02 PM

Quote:

Originally Posted by Kustom42 (Post 4673772)
That does not work for me and I have never seen or heard of it during my red hat admin days. I tried several test shell scripts and none worked.

FWIW, I am seeing this on my SUSE-11.1 box.

Sergei Steshenko 05-08-2012 05:19 PM

Well, RTFMing (man 1p cd) I see:

Code:

      8. The curpath value shall then be converted to canonical form as follows, considering each component from beginning to end, in sequence:
...
          b. For each dot-dot component, if there is a preceding component and it is neither root nor dot-dot, the preceding component, all slashes separating  the  pre-
              ceding component from dot-dot, dot-dot and all slashes separating dot-dot from the following component shall be deleted.

- does it explain the behavior I observe ?

Kustom42 05-08-2012 05:38 PM

I do not see that text in my bash builtins man page. Where did you locate that information?

Kustom42 05-08-2012 05:40 PM

I missed your suse response. That would probably indicate a difference between the two families of Linux. Your excerpt does make sense; if it is from the man page for cd on your system then I would say there is your answer.

Nominal Animal 05-08-2012 09:55 PM

I think /mnt/sdb8/sergei/AFSWD_debug/20120424/libproxy-0.4.7/.../ must exist for that to work. Unless SuSE applies some very unsafe patches to its path resolution code.

In particular, cd /foo/.../../bar/ does not work on any of my systems (Debian and RHEL variants, no SuSE), when /foo/bar/ exists but /foo/.../ does not. (The cd(1) man page does have the same dot-dot handling description.)

Sergei Steshenko 05-09-2012 03:00 AM

Quote:

Originally Posted by Nominal Animal (Post 4673894)
I think /mnt/sdb8/sergei/AFSWD_debug/20120424/libproxy-0.4.7/.../ must exist for that to work. Unless SuSE applies some very unsafe patches to its path resolution code.

In particular, cd /foo/.../../bar/ does not work on any of my systems (Debian and RHEL variants, no SuSE), when /foo/bar/ exists but /foo/.../ does not. (The cd(1) man page does have the same dot-dot handling description.)

It apparently exists and shows up as a regular directory:


Code:

sergei@amdam2:~/junk> cd /mnt/sdb8/sergei/AFSWD_debug/20120424/libproxy-0.4.7/.../
sergei@amdam2:/mnt/sdb8/sergei/AFSWD_debug/20120424/libproxy-0.4.7/...> pwd
/mnt/sdb8/sergei/AFSWD_debug/20120424/libproxy-0.4.7/...
sergei@amdam2:/mnt/sdb8/sergei/AFSWD_debug/20120424/libproxy-0.4.7/...> ls
sergei@amdam2:/mnt/sdb8/sergei/AFSWD_debug/20120424/libproxy-0.4.7/...> ls -A
sergei@amdam2:/mnt/sdb8/sergei/AFSWD_debug/20120424/libproxy-0.4.7/...> cd
sergei@amdam2:~> cd /mnt/sdb8/sergei/AFSWD_debug/20120424/libproxy-0.4.7/.../
sergei@amdam2:/mnt/sdb8/sergei/AFSWD_debug/20120424/libproxy-0.4.7/...> pwd
/mnt/sdb8/sergei/AFSWD_debug/20120424/libproxy-0.4.7/...
sergei@amdam2:/mnt/sdb8/sergei/AFSWD_debug/20120424/libproxy-0.4.7/...> ls -a
.  ..
sergei@amdam2:/mnt/sdb8/sergei/AFSWD_debug/20120424/libproxy-0.4.7/...> cd ..
sergei@amdam2:/mnt/sdb8/sergei/AFSWD_debug/20120424/libproxy-0.4.7> ls -F
___ALREADY_BUILT___.libproxy-0.4.7  bin/  binsh/  include/  lib/  libproxy-0.4.7.dirs_with_so_or_a_files.prl  libproxy-0.4.7.PATH.txt  libproxy.py  share/
sergei@amdam2:/mnt/sdb8/sergei/AFSWD_debug/20120424/libproxy-0.4.7> ls -Fa
./  ../  .../  ___ALREADY_BUILT___.libproxy-0.4.7  bin/  binsh/  include/  lib/  libproxy-0.4.7.dirs_with_so_or_a_files.prl  libproxy-0.4.7.PATH.txt  libproxy.py  share/
sergei@amdam2:/mnt/sdb8/sergei/AFSWD_debug/20120424/libproxy-0.4.7>

.

Maybe it is created as a temporary hidden directory by 'make install', and later on files are moved from there to their final destinations ?

I yet to have to parse the quoted manpage piece.

Nominal Animal 05-09-2012 04:57 AM

Quote:

Originally Posted by Sergei Steshenko (Post 4674039)
Maybe it is created as a temporary hidden directory by 'make install', and later on files are moved from there to their final destinations ?

I think you are spot on. Usually, the temporary install directory is something like .libs , or .$builddir . Since this package is configured via cmake .. (I think), perhaps the temporary install directory name is constructed by prepending a dot to the parameter to configuring cmake, yielding ... simply by accident?!

Quote:

Originally Posted by Sergei Steshenko (Post 4674039)
I yet to have to parse the quoted manpage piece.

In any case, the quoted passage is incorrect in practice.

Path resolution does not simply apply s|/\+\([^/]+\)/\+\.\./\+|/|g (repeatedly) to the path to remove /../ components, because that would be a security risk.

In most cases, a path is assumed to be valid component-wise. That is, you should be able to trim a component off the end of the path, and end up in an existing, accessible directory, if the full path was accessible. If you allow nonexistent path components, that no longer applies.

The same rule applies when a component exists, but is inaccessible. Consider path /foo/bar/../baz/ where /foo/baz/ exists and is accessible, and /foo/bar/ also exists but is inaccessible. Because paths should be valid component-wise in practice, the original path should NOT be accessible.

I suspect this behaviour is implicitly standardized in POSIX; perhaps there is a passage that states that all components in a path must be accessible for the complete path to be accessible?

Unfortunately I'm too lazy to check. :p I first became aware of this almost a decade ago, when I was researching why Apache does so many directory lookups. (Partly due to this, partly due to .htaccess files and <Directory> directives.)

AnanthaP 05-10-2012 06:14 AM

AFAIR it was an old novell netware feature.

Nominal Animal 05-10-2012 06:40 AM

@AnanthaP: You mean old Novell Netware accepted paths like foo\bar\..\baz as long as foo\baz existed even if foo\bar did not?

As it turns out, POSIX.1-2008 (IEEE Std 1003.1™-2008) realpath() function (which applications are supposed to but not required to use to canonicalize a path before doing any manipulations to it), does specify the explicit behaviour that I described earlier -- that foo/bar/../baz is accessible only if both foo/bar and foo/baz exist and are accessible:
Quote:

The realpath() function shall fail if: Read or search permission was denied for a component of file_name [, or a] component of the path prefix is not a directory
In Linux, the kernel applies the same rule to all path resolution.

ta0kira 05-10-2012 11:11 AM

".." is a hard link to the parent directory, except in "/", which has ".." as a hard link to ".". While this might only be "simulated", processing the text of the pathname won't always be accurate. Suppose you had "/home/you/dir" -> "/". If you only went by the text, cd ~/dir/../home wouldn't work unless there was a "/home/you/home". Processing the text would also result in different behavior within C programs since presumably there isn't a kernel option to treat "..." specially. Also, I really wonder why there's a manpage for cd and why it could be different on another distro, since as far as I know cd can only work as a built-in (short of some procfs magic that I don't know about.) The manpage I have for cd is for a tcl built-in.
Kevin Barry

Nominal Animal 05-10-2012 11:39 AM

Quote:

Originally Posted by ta0kira (Post 4675208)
".." is a hard link to the parent directory, except in "/", which has ".." as a hard link to ".". While this might only be "simulated", processing the text of the pathname won't always be accurate.

If you process each component separately, building upon the path component by component, it will be logically correct.

Quote:

Originally Posted by ta0kira (Post 4675208)
Suppose you had "/home/you/dir" -> "/". If you only went by the text, cd ~/dir/../home wouldn't work unless there was a "/home/you/home".

I don't understand that statement. POSIX.1-2008 realpath() and the Linux kernel path resolution handles that just fine by the text. ~/dir/../home is expanded by the shell to /home/you/dir/../home (~ is not special to the kernel nor realpath()), which is resolved in five steps:
  1. /home
  2. /home/you
  3. /home/you/dir
    At this point, the resolved location is at / for both realpath() and the Linux kernel.
  4. /home/you/dir/..
    The parent directory always exists, even at root. The resolved location stays at root for both realpath() and the Linux kernel.
  5. /home/you/dir/../home
    Since the resolved location has a subdirectory home (as resolved already in the first step), this resolves to the exact same location as the first step.

I cannot find any contradiction between this behaviour and the POSIX.1-2008 text I quoted!

Quote:

Originally Posted by ta0kira (Post 4675208)
Processing the text would also result in different behavior within C programs since presumably there isn't a kernel option to treat "..." specially.

What? Like I said, every path component must exist and be accessible, for the path to exist and be accessible. This applies to both the Linux kernel, and POSIX.1-2008 realpath() function. (I have not bothered to check whether this is required by POSIX.1-2008 for all filesystems.)

Quote:

Originally Posted by ta0kira (Post 4675208)
Also, I really wonder why there's a manpage for cd and why it could be different on another distro, since as far as I know cd can only work as a built-in (short of some procfs magic that I don't know about.) The manpage I have for cd is for a tcl built-in.

Because the cd utility is in the POSIX standard. Regardless of how it is implemented, its functionality should be the same for users. This functionality is what the man page describes. (And as such, it is part of the POSIX man pages.)

ta0kira 05-10-2012 01:46 PM

(nevermind)

Nominal Animal 05-10-2012 03:10 PM

Quote:

Originally Posted by ta0kira (Post 4675307)
(nevermind)

I'm genuinely puzzled. If I offended you or anyone else, I apologize; it was not my intention. I only wanted to clarify the issues.


All times are GMT -5. The time now is 07:07 PM.