2
0

sysdir.inc 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Main OS dependant body of the system unit, loosely modelled
  4. after POSIX. *BSD version (Linux version is near identical)
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {*****************************************************************************
  12. Directory Handling
  13. *****************************************************************************}
  14. const
  15. { read/write search permission for everyone }
  16. MODE_MKDIR = S_IWUSR OR S_IRUSR OR
  17. S_IWGRP OR S_IRGRP OR
  18. S_IWOTH OR S_IROTH OR
  19. S_IXUSR OR S_IXGRP OR S_IXOTH;
  20. Procedure Do_MkDir(s: rawbytestring);
  21. Begin
  22. If Fpmkdir(pchar(s), MODE_MKDIR)<0 Then
  23. Errno2Inoutres
  24. End;
  25. Procedure Do_RmDir(s: rawbytestring);
  26. begin
  27. if (s='.') then
  28. begin
  29. InOutRes := 16;
  30. exit;
  31. end;
  32. If Fprmdir(pchar(S))<0 Then
  33. Errno2Inoutres
  34. End;
  35. Procedure do_ChDir(s: rawbytestring);
  36. Begin
  37. If Fpchdir(pchar(s))<0 Then
  38. Errno2Inoutres;
  39. { file not exists is path not found under tp7 }
  40. if InOutRes=2 then
  41. InOutRes:=3;
  42. End;
  43. // !! for now we use getcwd, unless we are fpc_use_libc.
  44. // !! the old code is _still needed_ since the syscall sometimes doesn't work
  45. // !! on special filesystems like NFS etc.
  46. // !! In the libc versions, the alt code is already integrated in the libc code.
  47. // !! Also significantly boosted buffersize. This will make failure of the
  48. // !! dos legacy api's better visibile due to cut-off path, instead of "empty"
  49. procedure do_getdir(drivenr : byte;var dir : rawbytestring);
  50. var
  51. buf : array[0..2047] of char;
  52. {$ifndef FPC_USE_LIBC}
  53. cwdinfo : stat;
  54. rootinfo : stat;
  55. thedir,dummy : rawbytestring;
  56. dirstream : pdir;
  57. d : pdirent;
  58. thisdir : stat;
  59. tmp : rawbytestring;
  60. {$endif FPC_USE_LIBC}
  61. begin
  62. dir:='';
  63. if Fpgetcwd(@buf[0],sizeof(buf))<>nil then
  64. begin
  65. dir:=buf;
  66. { the returned result by the OS is in the DefaultFileSystemCodePage ->
  67. no conversion }
  68. setcodepage(dir,DefaultFileSystemCodePage,false);
  69. end
  70. {$ifndef FPC_USE_LIBC}
  71. else
  72. begin
  73. dummy:='';
  74. { get root directory information }
  75. tmp := '/'+#0;
  76. if Fpstat(@tmp[1],rootinfo)<0 then
  77. Exit;
  78. repeat
  79. tmp := dummy+'.'+#0;
  80. { get current directory information }
  81. if Fpstat(@tmp[1],cwdinfo)<0 then
  82. Exit;
  83. tmp:=dummy+'..'+#0;
  84. { open directory stream }
  85. { try to find the current inode number of the cwd }
  86. dirstream:=Fpopendir(@tmp[1]);
  87. if dirstream=nil then
  88. exit;
  89. repeat
  90. thedir:='';
  91. d:=Fpreaddir(dirstream);
  92. { no more entries to read ... }
  93. if not assigned(d) then
  94. break;
  95. tmp:=dummy+'../'+d^.d_name + #0;
  96. if (Fpstat(@tmp[1],thisdir)=0) then
  97. begin
  98. { found the entry for this directory name }
  99. if (cwdinfo.st_dev=thisdir.st_dev) and (cwdinfo.st_ino=thisdir.st_ino) then
  100. begin
  101. { are the filenames of type '.' or '..' ? }
  102. { then do not set the name. }
  103. if (not ((d^.d_name[0]='.') and ((d^.d_name[1]=#0) or
  104. ((d^.d_name[1]='.') and (d^.d_name[2]=#0))))) then
  105. { d^.d_name is an array[0..x] of char -> will be assigned the
  106. ansi code page on conversion to ansistring -> also typecast
  107. '/' to ansistring rather than rawbytestring so code pages match
  108. (will be unconditionally set to DefaultFileSystemCodePage at
  109. the end without conversion) }
  110. thedir:=ansistring('/')+d^.d_name;
  111. end;
  112. end;
  113. until (thedir<>'');
  114. if Fpclosedir(dirstream)<0 then
  115. Exit;
  116. dummy:=dummy+'../';
  117. if ((cwdinfo.st_dev=rootinfo.st_dev) and (cwdinfo.st_ino=rootinfo.st_ino)) then
  118. begin
  119. if thedir='' then
  120. dir:='/'
  121. else
  122. begin
  123. dir:=thedir;
  124. { try to ensure that "dir" has a refcount of 1, so that setcodepage
  125. doesn't have to create a deep copy }
  126. thedir:='';
  127. end;
  128. { the returned result by the OS is in the DefaultFileSystemCodePage ->
  129. no conversion }
  130. setcodepage(dir,DefaultFileSystemCodePage,false);
  131. exit;
  132. end;
  133. until false;
  134. end;
  135. {$endif}
  136. end;