restriction PATH_MAX
births from the fact that unix (or linux, henceforth) needs to bind the size of parameters passed to the kernel. There is no limit to how deep the file hierarchy can grow, and there is always the ability to access all files, no matter how deep they are in the file system hierarchy. What is actually limited is the length of the string that you can pass or receive from the kernel representing the file name. This means that you cannot create (because you need to pass the target path) a symbolic link longer than this length, but you can easily go through the path to this limit.
When you pass the file name to the kernel, you can do this for two reasons, to name the file (or device, or socket, or fifo, or something else), to open it, etc. You do this and your file name first goes to a routine that converts this path into an inode (which actually controls the kernel). This procedure starts scanning from two possible points in the file system hierarchy. These points are the inode link of the root inode and the inode pointer of the current workflow. The choice of which index to use as the departure inode depends on the presence of the leading character /
at the beginning of the path. From this moment, the PATH_MAX
characters are processed each time, but this can lead us deep enough so that we cannot reach the root in just one step ...
Suppose you use the path to change the current directory and run chdir A/B/C/D/E/.../Z
After that, you create new directories and do the same, chdir AA/AB/AC/AD/AE/.../AZ
, then chdir BA/BB/BC/BD/...
etc ... there is nothing in the system that would prevent you from penetrating so deep into the file system (you can try it yourself, I already did and tested before). You can grow to a map that is much larger than PATH_MAX
. But this only means that you cannot get directly from the root of the file system. You can go there in steps, as far as the system allows, and depending on where you fix your root directory (using syscall chdir (2))
you may have noticed (or not) that there is no system call to get your working directory path from the root ... There are several reasons for this:
- the inode root and the working inode descriptor are two concepts from the local to the process. Two processes on the same system can have different working directories, as well as different root directories, to the extent that they can share nothing in common and in no way from one directory to reach another.
- The index path may be ambiguous. Well, this does not apply to the directory, since two hard links are not allowed to point to the same inode directory (this was possible in old organizations where directories were to be created with the
mknod(2)
system call, if you have access to some hp-ux v6 or old Unix SysV R4, you can create directories with a record ...
--- pointing to a catalog robbery or similar things, just being root and knowing how to use syscall mknod(2)
), the idea is is that when two links point to the same index, which (or both) then goes to the root, like first of them is the right path from the root to the current directory inode? - curren inode and root can be separated by a path far enough not to meet the
PATH_MAX
limit. - there may be several different file systems (and file system types) involved in root access. Thus, this is not something that can be obtained, only knowing the stored data on the disks, you should know the mount table.
For these reasons, there is no direct support in the kernel to find out the root path to the file. And also there is no way to get the path (and this is what the pwd(1)
command does) than to follow the entry ..
and go to the parent directory and look for the link there that goes to the inode number of the current directory ... and repeat this until until the parent index becomes the same as the last inode visited. Only then will you be in the root directory (your root directory, which is generally different from other process root directories)
Just try this exercise:
i=0 while [ "$i" -lt 10000 ] do mkdir dir-$i cd dir-$i i=$(expr "$i" + 1) done
and see how far you can go from the root directory in your hierarchy.
NOTE 1
Another reason that you cannot get the file path from the open descriptor is that you only have access to the inode (the path you used for open(2)
, it cannot have anything to do with the actual root path, as you can use symbolic links and in relation to the working directory or changing the root directory between an open call and the time when you want to access this path, it may not even exist, since you can have unlink(2)
d it). Information about using inode does not have a link to the inode path, since there can be several (even millions) paths to a file. In inode, you only have the number of links, which means the number of paths that actually end with this inode.