[APUE] on Linux / Windows system, you can only set up path no more than_ MAX / MAX_ Path length path?

Time:2020-11-7

Questions raised

When dealing with the file system path, we usually open a memory area to receive the path, or splice the path and pass it to the system call. This is because the path has a maximum length limit on each system. On windows, the value is max_ Path, generally no more than 260; on Linux, this value is path_ Max, generally no more than 4096 (or through pathconf (_ PC_ PATH_ Max,…), but generally 4096), just like the following typical code:

 1 int main ()
 2 {
 3 #ifdef WIN32
 4     char buf[MAX_PATH + 1] = { 0 };
 5     if (GetModuleFileNameA(NULL, buf, MAX_PATH) == 0)
 6     {
 7         printf("get current module path failed, errno %d", GetLastError());
 8         return -1;
 9     }
10 #else
11     char buf[PATH_MAX + 1] = { 0 };
12     if (readlink("/proc/self/exe", buf, PATH_MAX) < 0)
13     {
14         printf("read exe path failed, errno %d", errno);
15         return -1;
16     }
17 #endif
18 
19     printf("current executable file path: %s\n", buf);
20     return 0; 
21 }

 

It is used to get the full path of the current executable file. Getmodulefilename and readlink system calls are called on windows and Linux respectively, and the memory area buf receiving the full path is allocated on the stack in advance. Finally, the successful path is printed to the console. On both systems, the outputs are as follows:

Windows

current executable file path: E:\code\apue.chapter\Release\path_max.exe

 Linux

current executable file path: /home/yunhai/code/apue/02.chapter/path_max

 

Other path related calls are similar. Then the question arises: is this maximum path length for programming (otherwise, memory needs to be allocated dynamically, and two calls are needed, one of which is used to obtain the final path length), or is it that the underlying file system can only support such a long path?

Problem verification

In order to clarify this problem, I specially wrote a test program:

path_max.c

1 #ifdef WIN32
  2 #  ifndef _ WIN32_ WinNT // specifies that the minimum required platform is Windows Vista.
  3 #  define _ WIN32_ WinNT 0x0600 // change this value to the appropriate value for other versions of windows.
  4 #  endif
  5 #include  
  6 #include  
  7 #else 
  8 #include 
  9 #include  
 10 #include  
 11 #include  
 12 #include  
 13 #endif 
 14 #include 
 15 #include  
 16 #include  
 17 #include 
 18 
 19 void get_random_name (char *name, int len, int level)
 20 {
 21   int i, n; 
 22   sprintf (name, "%d", level); 
 23   n = strlen (name); 
 24   for (i=n; i file_len ? dir_len : file_len) + 1); 
 54   if (name == 0)
 55     return -1; 
 56 
 57 
 58   do
 59   {
 60     get_random_name (name, dir_len, ++level); 
 61 #ifdef WIN32
 62     //ret = _mkdir (name); 
 63     //if (ret == -1)
 64     ret = CreateDirectory(name, NULL); 
 65     if (!ret)
 66     {
 67       printf ("CreateDirectory %s failed, errno = %d\n", name, GetLastError ()); 
 68       break; 
 69     }
 70 #else 
 71     ret = mkdir (name, 0777); 
 72     if (ret == -1)
 73     {
 74       printf ("mkdir %s failed, errno = %d\n", name, errno); 
 75       break; 
 76     }
 77 #endif 
 78     
 79     printf ("mkdir %s\n", name); 
 80 #ifdef WIN32
 81     //ret = _chdir (name); 
 82     //if (ret == -1)
 83     ret = SetCurrentDirectory(name); 
 84     if (!ret)
 85     {
 86       printf ("SetCurrentDirectory %s failed, errno = %d\n", name, GetLastError ()); 
 87       break; 
 88     }
 89 #else 
 90     ret = chdir (name); 
 91     if (ret == -1)
 92     {
 93       printf ("chdir %s failed, errno = %d\n", name, errno); 
 94       break; 
 95     }
 96 #endif 
 97 
 98     //printf ("change to that dir\n"); 
 99     get_random_name (name, file_len, level); 
100 #ifdef WIN32
101     fd = CreateFile (name, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, 0); 
102     if (fd == INVALID_HANDLE_VALUE)
103       printf ("open %s failed, errno = %d\n", name, GetLastError ()); 
104     else 
105     {
106       printf ("open %s OK.\n", name); 
107       CloseHandle (fd); 
108     }
109 #else 
110     int fd = open (name, O_RDWR | O_CREAT, 0644); 
111     if (fd == -1)
112       printf ("open %s failed, errno = %d\n", name, errno); 
113     else 
114     {
115       printf ("open %s OK.\n", name); 
116       close (fd); 
117     }
118 #endif 
119   } while (1); 
120 
121   free (name); 
122   return 0; 
123 }

 

This small program is very simple, each time create a directory, switch in, create a file. This goes on and on until you exit in error. The length of the directory name is fixed to 9, so that the directory separator (/ or \) is added to make it exactly 10. After that, the total length of the path is calculated according to the depth of the directory. The length of the file name is fixed to 100 to facilitate the calculation of the total length of the path. At the same time, each name will consist of 26 letters at the beginning of the directory. For example, the directory at level 10 may be as long as “10jmvrfqv”. The number 10 in front of the directory clearly identifies the directory level. Similarly, the file name is also preceded by the level number, which is also for the convenience of calculation. OK, let’s run this test program on both systems.

1. Results on windows (win10 x64)

NAME_MAX = 260, PATH_MAX = 260
mkdir 1tdobxciu
open 1gybhgvdtngozbkzvcuvpnitcpntxgtjhasljfycfowuuqmcvvitsthzdxpckttobaqtccxeabfmnvhoeknyjifabnynkrjwzhiq OK.
mkdir 2wafsehgp
open 2ssywxcafcvpuppgxjcpctjkleftvyhwpuzydlcaaxkbsgumljccmokznqpkvliklndweyegqxvmrmtcrfwzqyllezvneztvqwma OK.
mkdir 3vmkjwgrp
open 3bclyodmcwjgzmokchhkrmharodswgmpbusxozgqogaguvppohpthetfgqxrmihdjjmqsxvdzgondfsirxfmqbmgmexdnbdjyrqr OK.
mkdir 4xmvhqrfh
open 4hclzbqzoniuuolhumysibxonqutbpqgvroamdwdorhypsfkrkyskqykdukfrngtfipgjidvazgsvdfejofbjqqwpthkfxzgwubw OK.
mkdir 5rwoxiiwh
open 5sdeemddmvkhszsubkojdemrconicercdpdcmsmitbbuxowvsqbfghagpwkgmdrytzfnafoqvwsktiwdkjskfukxtxjeknctdjcm OK.
mkdir 6fnmlhdor
open 6vjrqxecbutxcospyzihwjabulwzbvbwimubvvchdxgyhqfjebjnpbbhvtwrkjlowmzbpoqkshwjbzoqysxfthztefvzwgarrdon OK.
mkdir 7sbvhcsxw
open 7ddmdylgkhghdeefydnjfsmiyxwutewbmujsppdezpoamtwodvqvkyaeswywbfnvjctofiaftmkiwapbjawuhjvuqsmefjpfgbew OK.
mkdir 8dwhpsgaj
open 8xepfibfufsaefmghnjukuddbqhyijunkazscfjxkznnylylpcaiauwyrzcfixbjfguvimzwrabcnvxomkaelrwtgnhsjxpiwmii OK.
mkdir 9wmpqcalh
open 9ldugmypucabxtjnpxqdvinxtevztnspuakrwwhebpshzsgbkedvmxbibkwyaoxctfelwjsglvdwjfjffuleijofuoinnrdcdymf OK.
mkdir 10vlwydie
open 10jihhaxrcpsviddxserikiiyrtbiwdumzdsyhkkodreimjxivkpnnxxtgpuathmqatlajmfueupwsdwjhyferopxiqggkywccvz OK.
mkdir 11awvhauw
open 11ypsctazqpuebetmzzgrzasmjmzppymtdabgcajahhwuwilzxlgvpupuksrjtmigjogjyqxhczuunlknxupfixnyxlyjsdhgwuf OK.
mkdir 12pdznsnw
open 12easlcjvcdudtktfkseedbtlbvnjhjtlchtjbbshmjbdsnpifidqjwsttalzwlyjezixtghwortsusrifigbxhpznmiigtvviym OK.
mkdir 13pvvjtcb
open 13lbpsmpbwyzzcnjlixarmvbxpqeketgycbduhzlhhakxykncmxwhmgqrwigcywiehemmhlinrhxnxbktentpvnlazrzgniwgcnf OK.
mkdir 14jrhanvs
open 14nlvfzgxyfzekthrzidzoeugldefwnxlelbntfetdnxvxkcupkpnzxhytidycrstkchdojzrsdjxclkvfgvmmsenysyyinkylsd OK.
mkdir 15yilwbim
open 15dhjbeoeybggfrjpstbyobosrmigtfhmpbajgwhjgczgklphxweefjoliwbuabyxyfsnzjzpiaxdagfbkujrqistslqkffqmilx OK.
mkdir 16owgedmp
open 16cqauvpdzsghgmzdbdxaqdclrvuyophifemvsoygwuhbtlkkmwmwxekwcxgmauagexxtyirthfgjbztmutljstjiwcbwmntkfri failed, errno = 3
mkdir 17xljxtht
open 17umkwtdbxiayekrljssfnxgvcmytthwevlmrxptivqmvwrkpqkvxoircuwadhkyidoaydlvnnafejpssqdewcymluzmrwrrkwmn failed, errno = 3
mkdir 18aywtihk
open 18ynydjmncmakzoezcupoeqfiahsunxhqvczbuapntehglrrhubpbydnnpnbpjdschmrkzkkpvgfajemsfsvofsjoclijforjkex failed, errno = 3
mkdir 19qsvtxwm
open 19qpfdrjgnxthljturhvuymuoqctsmixxrircoievqpgrnxpzufozwvpsjocdxfhjodpfzljbgegutfsquaehjoaswqhwtsqbgmh failed, errno = 3
mkdir 20vzvuovy
open 20zqqxsfnxrccsubxwevfffunrxfugkovltzidalrmppjjyrbnohxgmwnmwcseijuhzabngyfodgodnblmvhmvnmkvqfijucfqfz failed, errno = 3
mkdir 21idgwupz
open 21vlkqahypwulaaykizzvqviqztswdwikvloswluydfyqmgjcaixqqrilsrjireprfrvbgfvspulfmnuksbvsnfkdncybuhxddtw failed, errno = 3
mkdir 22plbyhbe
open 22rbekcixmxcohnvqlyhlppmgqtpsgsjwxhuwlmhnzspkbvdrnzechjbjsglzajiadiqguutgfjfkaqdtfqeevpcrsejiiotytse failed, errno = 3
mkdir 23vggwvra
open 23tlbobatwbdpaxouojluctxqyddllqedqbeotpkkxgddristpprablooxlomgvneixubhxhemtlvipqwzzfgqcxjtdltytpialw failed, errno = 3
mkdir 24dkpkfup
open 24fujnicyzpudgnsuzcqkkgihsousejefcuepnkkxdpdxbxxfryeglrmikgxxckazfokmdrgttnqxavphpoekagfbenjyuxpfntu failed, errno = 3
CreateDirectory 25aajjgcq failed, errno = 206

 

I ran this program in the root directory of G: \. When I ran to the 16th level directory, CreateFile failed and returned with error code 3 (error)_ PATH_ NOT_ Found: the system cannot find the specified path). For file creation failure, it is ignored here, so the program continues to run. When running to the 25th level directory, createdirectory also fails and returns with error code 206 (error)_ FILENAME_ EXCED_ Range: the file name or extension is too long). The whole program is terminated because it can no longer continue. Take a look. When you go to level 16 directory, the whole path is as follows:

 

If you want to create a file again, the total length will rise to 162 + 1 + 100 = 263 > max_ Path, so the next file creation fails. Then look at the path when you go to level 24 directory

 

The total length is 243. If you add the length of a directory, it should be 253 < max_ Path should be able to accommodate the creation of a directory. However, I tried to create a directory under this directory and got the following error:

 

If you are creating a file, you will find that after entering a certain length of file name, you will not be able to enter it

 

This length is currently 16 (including the suffix. TXT 4 characters), plus the previous directory length 243, the total length is 243 + 1 + 16 = 260, which is exactly equal to max_ PATH。 It can be seen that for windows, the max_ Path is the limitation of the underlying file system, no matter how you play, you can’t play this lever. Attempt to switch the implementation of createdirectory / SetCurrentDirectory as_ mkdir / _ Chdir, see what’s different:

line 62-65

    ret = _chdir (name); 
    if (ret == -1)
    //ret = SetCurrentDirectory(name); 
    //if (!ret)

line 81-84

    ret = _mkdir (name); 
    if (ret == -1)
    //ret = CreateDirectory(name, NULL); 
    //if (!ret)

 

Rerun the example above and get exactly the same result.

2. Results on Linux (neokylin x64)

At first, I ran on CentOS i686. I didn’t expect to come back to see it after a while. The desktop of virtual machine was reset, all shells exited, and no output was intercepted. I had no choice but to adopt another platform. In this environment of winning the bid, Kirin finished the whole race:

$ ./path_max
NAME_MAX = 255, PATH_MAX = 4096
mkdir 1rkxtumwh
open 1tovmschzmqujtonfqbqyfomyykrtwqcrezfxbmypesyygmfxpvxvjmvkwnfudhnhgsghgfwkzxkgjpfamcxwotimgniluvucpbl OK.
mkdir 2vijihgsn
open 2rkuswxpuniccqrkbliwpzzaxhkfqqzgklackzrgpclrscduqnsfnrikasrqkswuexwqwqwlshekkigaxyhkrpwrjniuieqodnea OK.
mkdir 3fanxiuju
open 3cqwzqdmivizeyjygopureytlajkkdtehlciegumddnhdxgjnxfedfaofjysmtytfbbjjyxmdmtgjbrwywdddfrkopcclbxqcabn OK.
mkdir 4yazbmsjy
open 4wawuybydgrowjqyutxmxynkypjcbelzaowwoxwsgqiczabtuaftyuezjpbmvomxekutjsnpixuhxxctxhnwdtvmiybemnbrzxmk OK.
mkdir 5sbcaywkx
open 5torqwgobzlqjlrnygrrhqdrigvletvbmjufhcvldjbnuscuavlhmqawwwhcpegeqalzfgkirnvmfaghvuojkpghlnlcsrgkurjz OK.
mkdir 6aujthffp
open 6howeinoseubrjntbgclavxzxrjraqwrzmqdudrphnsaxhtaovootlqqebheteysqoxntpccewcbevcstqimbacfbklwqjqixovs OK.
mkdir 7fzujwwnc
open 7upunhebiffpircfhmxsllpespacnxpptglgnrjxyoohgqopclhqzxuroutdtkumshufydexusgcjwtnhbdiaxaquvvnircaywgy OK.
mkdir 8cmxwffao
open 8btdlwhtygtqaplqxcszcofbsuyqzeqphmssizmjgfziwlyvpsvsjcvbwtsxzkmhwhzhinqovrztezpusmodqjepeyoejdnhkoos OK.
mkdir 9cgjxyiqe
open 9jhydvmgovlfaltguwvegjubndkmbufhdoghmupasahuoackzxohijiwmukpopwueedqbsstvzpjbrtcokkyvuujrfahwwbcdeue OK.
mkdir 10xmzunod
open 10rfytviftdcqmtxmatlewqkqujfvdsjgjqffnpkgtoyhhvwkrhqnxaftkmqphbysrdxeukmpylxigtuxckmbmuwyimopnmkgrjk OK.

……

mkdir 1341932sc
open 1341932rlcbgduqybifdacrgopzdnulnwxjtrlldpmltibrjlzolbhuqytvnpgbmgmhzzscpfniprbbearsezmuxhrnwaqkgcsfb OK.
mkdir 1341933kk
open 1341933qrzyhsckxcbpgcdcckupgufrchjjivvbnvbwndgmgjdomgroqndzjiqnrbwbwuclpejejrtrbwgndzdvoguxqmkhpikoc OK.
mkdir 1341934nz
open 1341934ttlyecrwdpcssdvqrdmovzaeqipeneggxrgbvxzzpbthgrzxwmnsnnwdylilpotohasczrdovzybqxzmjmewcdaaokngy OK.
mkdir 1341935gu
open 1341935hgmjgenwzmuaesbsbozaqccsqmfwmnttufcclrykfvnjnocqebswduovgvusjnlduqhghhspcfypuciafaxivlgdhcwqr OK.
mkdir 1341936jv
open 1341936lzerjlkaqryhndpoisltnwzqfdoxuysfzyzkklkccljqozgyrrrgpsyvvnupnpxonwbzjlblyldomjndcglszlpwyjony OK.
mkdir 1341937le
open 1341937ojfnsspftcjhouwtxderepgcqrqfsdjgmqvejmkcovlcpivonbfttnvjhmqzpahcqeibruffrrijbfxojfhcuelbqdcgd OK.
mkdir 1341938lk
open 1341938wquzhrfoiyytzerpnyyrscewvhadnmplejkncrblpaeqgxhtxhkqkoohxokkczvikgvnzxarxghderybyktkajrxybkca OK.
mkdir 1341939fl
open 1341939lnganfaecgnhmehqftjpvthvtkfvlkiyypynuarzggitnsjsluhhpqckbjgotootfogcoxduglptfylrvuaklevondeit OK.
mkdir 1341940sc
open 1341940bgiduigqotghzgssbmuozylpnqtvjlzktipnqxggrmnsshkwvekvevmtngqwtqjnaacsyiyruljpstlnzxkfuxyhfodyg OK.
mkdir 1341941ol
open 1341941gpqypywgvhpkbkxrlubqoaovfeaelprrghqvimbdwspzemqpgshwsvrabrgmixgohyjpmmuigjikxybfsibnfunjltvws OK.
mkdir 1341942dk failed, errno = 28

 

The intermediate output is more, so it is omitted and only a dozen lines of content are displayed. I run this program in / home / VMware / code / APUE / 02.chapter directory. When I run to the 1341942 level directory, MKDIR fails and returns with error code 28 (enospc: no space left on device). The total directory path length is 34 + 1341941 * 10 = 13419444, and the total path length of the deepest file is 34 + 1341941 * 10 + 100 = 13419544, which is far greater than the path_ Max (4096). At this point, I will fail to create a new file or directory in the directory where the program is running.

$ mkdir abc
MKDIR: unable to create directory 'ABC': there is no space on the device

$ touch abc
Touch: unable to create 'ABC': there is no space on the device

 

So one thing for sure is path on Linux_ Max is not the limit of the maximum path length of the underlying file system, but a constant that is easy to program. What determines the maximum length of the path? After reading the error code of enospc above, my first reaction was that the hard disk was full. However, after checking the remaining space on the disk, I rejected the possibility. The following is the DF output I recorded before and after executing the test program.

 

It can be seen that the usage ratio of the / home mount point increases sharply (8% ~ 22%), but it does not reach 100%. Therefore, the disk space is still sufficient. It is likely that the inode is exhausted (?). In any case, it is essentially a resource constraint, which allows programmers to create longer file paths on Linux, providing greater flexibility than windows. However, such a long path is not recognized by all programs. For example, where I just created the test directory, I recursively list all the files, and the output is as follows:

$ ls -R
.:
1rkxtumwh  Makefile  name_max.c  path_max    path_max.o    path_max.vcxproj
apue.o     name_max  name_max.o  path_max.c  path_max.sln

./1rkxtumwh:
1tovmschzmqujtonfqbqyfomyykrtwqcrezfxbmypesyygmfxpvxvjmvkwnfudhnhgsghgfwkzxkgjpfamcxwotimgniluvucpbl
2vijihgsn

./1rkxtumwh/2vijihgsn:
2rkuswxpuniccqrkbliwpzzaxhkfqqzgklackzrgpclrscduqnsfnrikasrqkswuexwqwqwlshekkigaxyhkrpwrjniuieqodnea
3fanxiuju

./1rkxtumwh/2vijihgsn/3fanxiuju:
3cqwzqdmivizeyjygopureytlajkkdtehlciegumddnhdxgjnxfedfaofjysmtytfbbjjyxmdmtgjbrwywdddfrkopcclbxqcabn
4yazbmsjy

./1rkxtumwh/2vijihgsn/3fanxiuju/4yazbmsjy:
4wawuybydgrowjqyutxmxynkypjcbelzaowwoxwsgqiczabtuaftyuezjpbmvomxekutjsnpixuhxxctxhnwdtvmiybemnbrzxmk
5sbcaywkx

./1rkxtumwh/2vijihgsn/3fanxiuju/4yazbmsjy/5sbcaywkx:
5torqwgobzlqjlrnygrrhqdrigvletvbmjufhcvldjbnuscuavlhmqawwwhcpegeqalzfgkirnvmfaghvuojkpghlnlcsrgkurjz
6aujthffp

./1rkxtumwh/2vijihgsn/3fanxiuju/4yazbmsjy/5sbcaywkx/6aujthffp:
6howeinoseubrjntbgclavxzxrjraqwrzmqdudrphnsaxhtaovootlqqebheteysqoxntpccewcbevcstqimbacfbklwqjqixovs
7fzujwwnc

./1rkxtumwh/2vijihgsn/3fanxiuju/4yazbmsjy/5sbcaywkx/6aujthffp/7fzujwwnc:
7upunhebiffpircfhmxsllpespacnxpptglgnrjxyoohgqopclhqzxuroutdtkumshufydexusgcjwtnhbdiaxaquvvnircaywgy
8cmxwffao

./1rkxtumwh/2vijihgsn/3fanxiuju/4yazbmsjy/5sbcaywkx/6aujthffp/7fzujwwnc/8cmxwffao:
8btdlwhtygtqaplqxcszcofbsuyqzeqphmssizmjgfziwlyvpsvsjcvbwtsxzkmhwhzhinqovrztezpusmodqjepeyoejdnhkoos
9cgjxyiqe

./1rkxtumwh/2vijihgsn/3fanxiuju/4yazbmsjy/5sbcaywkx/6aujthffp/7fzujwwnc/8cmxwffao/9cgjxyiqe:
10xmzunod
9jhydvmgovlfaltguwvegjubndkmbufhdoghmupasahuoackzxohijiwmukpopwueedqbsstvzpjbrtcokkyvuujrfahwwbcdeue

./1rkxtumwh/2vijihgsn/3fanxiuju/4yazbmsjy/5sbcaywkx/6aujthffp/7fzujwwnc/8cmxwffao/9cgjxyiqe/10xmzunod:
10rfytviftdcqmtxmatlewqkqujfvdsjgjqffnpkgtoyhhvwkrhqnxaftkmqphbysrdxeukmpylxigtuxckmbmuwyimopnmkgrjk

……

410dntuzt
Ls: unable to open directory. / 1rkxtumwh / 2vijihgsn / 3fanxuju / 4yazbmsjy / 5sbcaywkx / 6aujthfp / 7fzujwwnc / 8cmxwfao / 9cgjx
yiqe/10xmzunod/11ltybuja/12pddukks/13pgjmtme/14yxyuhvt/15qgddfps/16ipghtsx/17hrlvjqw/18mlwamyj/19ycqq
oum/20gdekplr/21mgkqtef/22uxjelyo/23yuogjxv/24gdyuetr/25ekyseyq/26mohxeho/27yhfufeo/28emftmwp/29detfm
nz/30ulhqorq/31lzvmcau/32vrkdiho/33pwrixvt/34ysjlzxm/35anbimen/36aazpcto/37dpzcvhb/38vbxsrwc/39urooly
a/40gabvtkg/41fswpnkc/42eyozjbb/43mbsphto/44szukcad/45lobskag/46njddwrk/47qmyaqip/48qywwpge/49jymbads
/50cevctwp/51dbrvvrg/52alaqbak/53wdxytcx/54iajcocc/55yulgnls/56xdvlohr/57rsyzzme/58avlsjct/59kzwpnmn/
60zuuyott/61cmyywqh/62fyuzvce/63djljats/64aopcwyi/65rxefdvy/66egqsclw/67jxyausw/68atlilhv/69xrxqsel/7
0isglkct/71fwkjdms/72mhygulk/73nlnwbrx/74sroynrd/75dimglds/76ulettre/77cvdbchx/78imrnssw/79uqfezsr/80
lkhipxs/81rbdpqqz/82lvyzxqt/83sgxgrxx/84tsgcvwa/85jaamdba/86zoneybo/87glbanpe/88tkzaefg/89rrwsack/90u
owxuoq/91rabkpyi/92dcnxiyz/93lacaahs/94frjwezd/95yhtpnte/96fblotmh/97mibhekj/98rzonuec/99topwrdn/100d
blgkn/101drisrx/102aqjjso/103uefcom/104yrflxq/105hyfxyh/106tlpbnl/107ndiswq/108uvgksb/109ozcwup/110qx
pxlo/111gttfdp/112nepxhw/113xwflah/114yibgjy/115dffvxj/116ukiosf/117fpvyvt/118kdreee/119ejgwiz/120lpo
qvc/121gihnlr/122umltry/123ajaaeq/124unorwj/125iuipco/126uwghec/127lzrzvo/128zytdwi/129xvkgeh/130mgfx
pr/131kekuik/132fjlbpy/133wogrgw/134eotsoo/135fquige/136smcyju/137obzwup/138fewkay/139dgizof/140gqrvp
w/141lwxiji/142gprlwz/143geyxsn/144otqwya/145ooyfvk/146ucigye/147xstuji/148ziprio/149ufrzci/150lmgpli
/151kczfla/152svbdit/153fzlyns/154yirhkv/155xbdixx/156mogbae/157goxflw/158fixfsg/159ncihug/160bnrvsj/
161ynpfeh/162cmanrm/163utjekr/164qcvzim/165ypxvkh/166ggnvdw/167nszvsr/168uyuayf/169fatffy/170znjsdj/1
71jqobhe/172syewyj/173fbdzgu/174bufnki/175qasxqn/176rigmyh/177zwoexf/178bdrxbg/179ggdmzx/180ljyrtm/18
1qbywid/182wsjhtx/183moknmr/184haaeaa/185jdpxza/186eerxfa/187kpfjiq/188wrdbbh/189uuhvct/190ofpwct/191
qnmtmy/192gqyowy/193eckugg/194oonhah/195dbjuxd/196qzbvuh/197kcqziu/198akbhoa/199hkszfc/200aqieum/201a
hkuqb/202hkikbi/203gywiex/204ibfmca/205vgczdp/206pchnch/207tfkxlo/208orztrq/209foperp/210umtatf/211rf
qqzo/212xuspzm/213bsqdet/214kbvvmg/215qsbepc/216qqqvea/217mtyasr/218eunbgv/219stppxz/220ncqzlb/221qgl
ips/222naqylv/223ymrfpk/224vavwhr/225dznual/226iuraac/227ztobic/228jynnfd/229iatquu/230vuokzi/231ykpc
bl/232wqldxe/233qeebyv/234nvspvv/235iqxfye/236nwnztb/237qjtgnn/238qyzyas/239lhcqon/240piorsv/241upvvm
j/242sjgemx/243ndojai/244whhuvw/245hmojut/246kwaiwh/247ohckmb/248ucmdrh/249eqzimi/250uymmqd/251cnglst
/252iysywl/253jridil/254nmoqzh/255ygguhk/256nwuiap/257zvtolc/258urycli/259kpiuab/260jempzc/261jyqcbe/
262sulagk/263mvljld/264ciiawa/265vjxora/266rxfgkg/267jwvpoy/268mpmgja/269xpxycf/270fjxobt/271zahncm/2
72soljdu/273jcdwrq/274wvrusy/275noyexu/276oksjfe/277wzfwvr/278tcsfue/279uhzgjs/280lfpypw/281cyjibv/28
2jwnlgu/283nnktxs/284udmuma/285xzbwnj/286jemqma/287xnedax/288dcvfle/289ddnbqe/290jheimg/291rscgbr/292
zlyhgw/293jbmjzx/294qocgsi/295mbyvyj/296ntwpkk/297jhofrm/298ibirpc/299kquens/300mbjnmo/301najyhm/302g
yerut/303blongi/304tafajx/305suvetf/306faeoiu/307dunnih/308ifvtsq/309vulqxe/310ilvtjv/311gzknfk/312ju
xeni/313bpaezt/314dcqgbb/315rqnuic/316ejhbrb/317wfzvzo/318hfndtr/319zgsznw/320dqahuh/321mdnyne/322xiu
lms/323lplrvo/324qtvodk/325tiigxk/326kljzob/327lxxopm/328qwjlms/329jwcbic/330nowwgr/331jqqbce/332qael
pn/333vyyvlr/334wvchpm/335afdbpb/336vsrvym/337ktyfii/338gasxaz/339gjjnco/340yqdxcc/341eysxtl/342ipsoc
o/343xrjucz/344aoetoq/345rtnyzv/346ptrthp/347gnxqkl/348vfpcrp/349jmoobg/350glqvzi/351vkznzy/352cmjseg
/353zgxeyh/354vfkgth/355fnhgjo/356cyouso/357hruehw/358jadbhv/359hklsla/360hwsife/361ragklc/362xydtpr/
363tjrhwj/364gpsojy/365sphazl/366fgwang/367tovqhr/368ybyzbe/369wasspn/370jjkehg/371fvmqie/372bdigtd/3
73afocqc/374agluqq/375jlrfsu/376gtbemx/377lqbrlg/378xmxxvu/379pwznpd/380gdryol/381cgzdfe/382egzxfd/38
3ciccll/384mpoifm/385ygdqiy/386ahilzb/387bhmyia/388cmfhah/389kuxsqg/390winlgk/391jnjlim/392vurqut/393
yehkub/394vkgknd/395pxnmgr/396bsnizx/397bzbbbs/398kdfjjs/399ugopik/400klxzic/401kaqhcd/402iyrruo/403d
Tncvg / 404feosyw / 405cbohnn / 406hfirse / 407tqbohz / 408udrjbo / 409yhmpsz / 410dntuzt: file name is too long

 

If there are more intermediate outputs, they are omitted. When running to the 410 level directory, LS reports an error. The total length of the upper level directory path reaches 34 + 409 * 10 = 4124, which is actually better than path_ Max is larger, but it still exits due to insufficient buffer. Try to find the file again, and the output is as follows:

$ find .
.
./name_max.o
./path_max.c
./Makefile
./name_max
./path_max
./path_max.o
./name_max.c
./1rkxtumwh
./1rkxtumwh/1tovmschzmqujtonfqbqyfomyykrtwqcrezfxbmypesyygmfxpvxvjmvkwnfudhnhgsghgfwkzxkgjpfamcxwotimgniluvucpbl
./1rkxtumwh/2vijihgsn
./1rkxtumwh/2vijihgsn/3fanxiuju
./1rkxtumwh/2vijihgsn/3fanxiuju/3cqwzqdmivizeyjygopureytlajkkdtehlciegumddnhdxgjnxfedfaofjysmtytfbbjjyxmdmtgjbrwywdddfrkopcclbxqcabn
./1rkxtumwh/2vijihgsn/3fanxiuju/4yazbmsjy
./1rkxtumwh/2vijihgsn/3fanxiuju/4yazbmsjy/5sbcaywkx
./1rkxtumwh/2vijihgsn/3fanxiuju/4yazbmsjy/5sbcaywkx/6aujthffp
./1rkxtumwh/2vijihgsn/3fanxiuju/4yazbmsjy/5sbcaywkx/6aujthffp/6howeinoseubrjntbgclavxzxrjraqwrzmqdudrphnsaxhtaovootlqqebheteysqoxntpccewcbevcstqimbacfbklwqjqixovs
./1rkxtumwh/2vijihgsn/3fanxiuju/4yazbmsjy/5sbcaywkx/6aujthffp/7fzujwwnc
./1rkxtumwh/2vijihgsn/3fanxiuju/4yazbmsjy/5sbcaywkx/6aujthffp/7fzujwwnc/7upunhebiffpircfhmxsllpespacnxpptglgnrjxyoohgqopclhqzxuroutdtkumshufydexusgcjwtnhbdiaxaquvvnircaywgy
./1rkxtumwh/2vijihgsn/3fanxiuju/4yazbmsjy/5sbcaywkx/6aujthffp/7fzujwwnc/8cmxwffao
./1rkxtumwh/2vijihgsn/3fanxiuju/4yazbmsjy/5sbcaywkx/6aujthffp/7fzujwwnc/8cmxwffao/8btdlwhtygtqaplqxcszcofbsuyqzeqphmssizmjgfziwlyvpsvsjcvbwtsxzkmhwhzhinqovrztezpusmodqjepeyoejdnhkoos
./1rkxtumwh/2vijihgsn/3fanxiuju/4yazbmsjy/5sbcaywkx/6aujthffp/7fzujwwnc/8cmxwffao/9cgjxyiqe
./1rkxtumwh/2vijihgsn/3fanxiuju/4yazbmsjy/5sbcaywkx/6aujthffp/7fzujwwnc/8cmxwffao/9cgjxyiqe/10xmzunod
./1rkxtumwh/2vijihgsn/3fanxiuju/4yazbmsjy/5sbcaywkx/6aujthffp/7fzujwwnc/8cmxwffao/9cgjxyiqe/10xmzunod/10rfytviftdcqmtxmatlewqkqujfvdsjgjqffnpkgtoyhhvwkrhqnxaftkmqphbysrdxeukmpylxigtuxckmbmuwyimopnmkgrjk

……

 

In the end, I don’t know whether it has been completed or not, because the whole virtual machine took n days and this command has not finished running (n > 10). The screenshot of find in the running process shows that:

 

I sorted the memory consumption from high to low. I can see that after n days of running the find command, the memory consumption has exceeded that of the entire graphical interface (xorg). In addition, the memory and CPU of the mate terminal associated with the find command are running at a high level. But at least find doesn’t use path_ Max can simply limit the path length, which may be realized by dynamically allocating memory. In addition, I was curious about the handle cost of this command, so I looked at the output of lsof:

$ lsof -p `pidof find`
COMMAND    PID   USER   FD      TYPE DEVICE  SIZE/OFF    NODE NAME
find    113339 vmware  cwd       DIR    8,5      4096 2095005 /home/vmware/code/apue/02.chapter
find    113339 vmware  rtd       DIR    8,3      4096       2 /
find    113339 vmware  txt       REG    8,3    203296 1180356 /usr/bin/find
find    113339 vmware  mem       REG    8,3 106374736 1187939 /usr/lib/locale/locale-archive
find    113339 vmware  mem       REG    8,3    141880 1191334 /usr/lib64/libpthread-2.20.so
find    113339 vmware  mem       REG    8,3     19512 1190784 /usr/lib64/libdl-2.20.so
find    113339 vmware  mem       REG    8,3    447240 1191294 /usr/lib64/libpcre.so.1.2.3
find    113339 vmware  mem       REG    8,3   2082456 1190695 /usr/lib64/libc-2.20.so
find    113339 vmware  mem       REG    8,3   1167000 1191118 /usr/lib64/libm-2.20.so
find    113339 vmware  mem       REG    8,3    154784 1191415 /usr/lib64/libselinux.so.1
find    113339 vmware  mem       REG    8,3    163184 1190512 /usr/lib64/ld-2.20.so
find    113339 vmware  mem       REG    8,3     26254 1448972 /usr/lib64/gconv/gconv-modules.cache
find    113339 vmware  mem       REG    8,3     30239 3015834 /usr/share/locale/zh_CN/LC_MESSAGES/findutils.mo
find    113339 vmware    0u      CHR  136,0       0t0       3 /dev/pts/0
find    113339 vmware    1u      CHR  136,0       0t0       3 /dev/pts/0
find    113339 vmware    2u      CHR  136,0       0t0       3 /dev/pts/0
find    113339 vmware    3r      DIR    8,5      4096 2095005 /home/vmware/code/apue/02.chapter
find    113339 vmware    4r  unknown                          /proc/113339/fd/4 (readlink: File name too long)
find    113339 vmware    6r  unknown                          /proc/113339/fd/6 (readlink: File name too long)
find    113339 vmware    7r  unknown                          /proc/113339/fd/7 (readlink: File name too long)
find    113339 vmware    9r  unknown                          /proc/113339/fd/9 (readlink: File name too long)
find    113339 vmware   10r  unknown                          /proc/113339/fd/10 (readlink: File name too long)
find    113339 vmware   11r  unknown                          /proc/113339/fd/11 (readlink: File name too long)

 

Surprisingly, there are not many open file handles. According to my understanding, there should be a directory file handle opened for each level of directory traversal. But now I can’t see it because the example I created is special. There is only one subdirectory in each directory? Or does find find find take a different route without taking up a lot of handles? I don’t know for the time being. On the whole, find is better than ls, and I immediately admire this magical command. Finally, we can see another phenomenon from the above output. Because the path is too long, the readlink returns an error. It can be seen that many system APIs do not support long paths. Finally, you can use RM – RF XXX to try to clean up these directories and files:

 

As expected, RM takes up a lot of memory and CPU, but it can work (and the time is not as exaggerated as find, which is more than ten minutes), so my virtual machine can recover to the working condition before the test. Here are some of lsof’s output for RM

$ lsof -p `pidof rm`
COMMAND   PID   USER   FD      TYPE DEVICE  SIZE/OFF    NODE NAME
rm      70867 vmware  cwd       DIR    8,5      4096 2095005 /home/vmware/code/apue/02.chapter
rm      70867 vmware  rtd       DIR    8,3      4096       2 /
rm      70867 vmware  txt       REG    8,3     62872 1181241 /usr/bin/rm
rm      70867 vmware  mem       REG    8,3 106374736 1187939 /usr/lib/locale/locale-archive
rm      70867 vmware  mem       REG    8,3   2082456 1190695 /usr/lib64/libc-2.20.so
rm      70867 vmware  mem       REG    8,3    163184 1190512 /usr/lib64/ld-2.20.so
rm      70867 vmware    0u      CHR  136,0       0t0       3 /dev/pts/0
rm      70867 vmware    1u      CHR  136,0       0t0       3 /dev/pts/0
rm      70867 vmware    2u      CHR  136,0       0t0       3 /dev/pts/0
rm      70867 vmware    3u  unknown                          /proc/70867/fd/3 (readlink: File name too long)
rm      70867 vmware    4u  unknown                          /proc/70867/fd/4 (readlink: No such file or directory)
rm      70867 vmware    5u  unknown                          /proc/70867/fd/5 (readlink: File name too long)
rm      70867 vmware    6u  unknown                          /proc/70867/fd/6 (readlink: File name too long)
rm      70867 vmware    7u  unknown                          /proc/70867/fd/7 (readlink: File name too long)
rm      70867 vmware    8u  unknown                          /proc/70867/fd/8 (readlink: File name too long)

 

Like find, it doesn’t have many open file handles (otherwise the number of open file handles would have exceeded the limit). In addition, from the output of lsof, some nodes have been deleted by RM, so readlink reports an error.

conclusion

For very long file paths, different linux commands have different degrees of support, some support and some do not. Moreover, considering that the total length of the command line passed to the process is also limited, ordinary commands will not support such a long path except for some commands that support recursive directory processing. On the other hand, from the programmer’s point of view, it is also troublesome to support the large path. Firstly, the system support does not support the input and output super long paths; if it supports, the input scenario is easier to handle, and the output scenario is more troublesome. The easiest way is to define a path greater than your own_ Max is a constant and uses it to allocate memory, but there are also problems. On the one hand, daily processing wastes memory; on the other hand, if the path exceeds the value defined by yourself, there will still be receiving truncation. Moreover, programmers have no way to predict the length of the path to get, so as to allocate memory dynamically in advance.

To sum up, this maximum path limit is not that the system can not support super long paths, and as a convention between the system and the application, with this Convention, the processing of the path by the program will be simplified. Besides, we don’t have a hard demand for super long paths. Most Windows applications run well under the limit of 260 character paths, not to mention the limitation of Linux 4096.

An additional use of this test program is to exhaust the inode (?) of the partition where it is located, and observe some performance of the system under such extreme conditions. For example, when I try to capture the screen and fail, I get the following prompt box:

 

 

This program is a useful tool when you need to verify the behavior of a program in this extreme state.