sysdir.inc 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  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. Procedure MkDir(s: pchar;len:sizeuint);[IOCheck, public, alias : 'FPC_SYS_MKDIR'];
  15. const
  16. { read/write search permission for everyone }
  17. MODE_MKDIR = S_IWUSR OR S_IRUSR OR
  18. S_IWGRP OR S_IRGRP OR
  19. S_IWOTH OR S_IROTH OR
  20. S_IXUSR OR S_IXGRP OR S_IXOTH;
  21. // len is not passed to the *nix functions because the unix API doesn't
  22. // use length safeguards for these functions. (probably because there
  23. // already is a length limit due to PATH_MAX)
  24. Begin
  25. If not assigned(s) or (len=0) or (InOutRes <> 0) then
  26. exit;
  27. If Fpmkdir(s, MODE_MKDIR)<0 Then
  28. Errno2Inoutres
  29. Else
  30. InOutRes:=0;
  31. End;
  32. Procedure RmDir(s: pchar;len:sizeuint);[IOCheck, public, alias : 'FPC_SYS_RMDIR'];
  33. Begin
  34. if (len=1) and (s^ = '.') then
  35. InOutRes := 16;
  36. If not assigned(s) or (len=0) or (InOutRes <> 0) then
  37. exit;
  38. If Fprmdir(s)<0 Then
  39. Errno2Inoutres
  40. Else
  41. InOutRes:=0;
  42. End;
  43. Procedure ChDir(s: pchar;len:sizeuint);[IOCheck, public, alias : 'FPC_SYS_CHDIR'];
  44. Begin
  45. If not assigned(s) or (len=0) or (InOutRes <> 0) then
  46. exit;
  47. If Fpchdir(s)<0 Then
  48. Errno2Inoutres
  49. Else
  50. InOutRes:=0;
  51. { file not exists is path not found under tp7 }
  52. if InOutRes=2 then
  53. InOutRes:=3;
  54. End;
  55. // !! for now we use getcwd, unless we are fpc_use_libc.
  56. // !! the old code is _still needed_ since the syscall sometimes doesn't work
  57. // !! on special filesystems like NFS etc.
  58. // !! In the libc versions, the alt code is already integrated in the libc code.
  59. // !! Also significantly boosted buffersize. This will make failure of the
  60. // !! dos legacy api's better visibile due to cut-off path, instead of "empty"
  61. procedure getdir(drivenr : byte;var dir : shortstring);
  62. var
  63. buf : array[0..2047] of char;
  64. cwdinfo : stat;
  65. rootinfo : stat;
  66. thedir,dummy : string[255];
  67. dirstream : pdir;
  68. d : pdirent;
  69. name : string[255];
  70. thisdir : stat;
  71. tmp : string[255];
  72. begin
  73. dir:='';
  74. if Fpgetcwd(@buf[0],sizeof(buf))<>nil then
  75. dir:=strpas(buf)
  76. {$ifndef FPC_USE_LIBC}
  77. else
  78. begin
  79. thedir:='';
  80. dummy:='';
  81. { get root directory information }
  82. tmp := '/'+#0;
  83. if Fpstat(@tmp[1],rootinfo)<0 then
  84. Exit;
  85. repeat
  86. tmp := dummy+'.'+#0;
  87. { get current directory information }
  88. if Fpstat(@tmp[1],cwdinfo)<0 then
  89. Exit;
  90. tmp:=dummy+'..'+#0;
  91. { open directory stream }
  92. { try to find the current inode number of the cwd }
  93. dirstream:=Fpopendir(@tmp[1]);
  94. if dirstream=nil then
  95. exit;
  96. repeat
  97. name:='';
  98. d:=Fpreaddir(dirstream);
  99. { no more entries to read ... }
  100. if not assigned(d) then
  101. break;
  102. tmp:=dummy+'../'+strpas(d^.d_name) + #0;
  103. if (Fpstat(@tmp[1],thisdir)=0) then
  104. begin
  105. { found the entry for this directory name }
  106. if (cwdinfo.st_dev=thisdir.st_dev) and (cwdinfo.st_ino=thisdir.st_ino) then
  107. begin
  108. { are the filenames of type '.' or '..' ? }
  109. { then do not set the name. }
  110. if (not ((d^.d_name[0]='.') and ((d^.d_name[1]=#0) or
  111. ((d^.d_name[1]='.') and (d^.d_name[2]=#0))))) then
  112. name:='/'+strpas(d^.d_name);
  113. end;
  114. end;
  115. until (name<>'');
  116. if Fpclosedir(dirstream)<0 then
  117. Exit;
  118. thedir:=name+thedir;
  119. dummy:=dummy+'../';
  120. if ((cwdinfo.st_dev=rootinfo.st_dev) and (cwdinfo.st_ino=rootinfo.st_ino)) then
  121. begin
  122. if thedir='' then
  123. dir:='/'
  124. else
  125. dir:=thedir;
  126. exit;
  127. end;
  128. until false;
  129. end;
  130. {$endif}
  131. end;