mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-20 17:32:09 +02:00
581 lines
13 KiB
ObjectPascal
581 lines
13 KiB
ObjectPascal
{
|
|
$Id$
|
|
This file is part of the Free Pascal run time library.
|
|
Copyright (c) 1999-2001 by Florian Klaempfl
|
|
member of the Free Pascal development team
|
|
|
|
Sysutils unit for POSIX compliant systems
|
|
|
|
See the file COPYING.FPC, included in this distribution,
|
|
for details about the copyright.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
**********************************************************************}
|
|
unit sysutils;
|
|
interface
|
|
|
|
{$MODE objfpc}
|
|
{ force ansistrings }
|
|
{$H+}
|
|
|
|
|
|
{ Include platform independent interface part }
|
|
{$i sysutilh.inc}
|
|
|
|
{ Platform dependent calls }
|
|
|
|
Procedure AddDisk(const path:string);
|
|
|
|
implementation
|
|
|
|
uses
|
|
sysconst,dos,posix;
|
|
|
|
{ Include platform independent implementation part }
|
|
{$i sysutils.inc}
|
|
|
|
|
|
|
|
{****************************************************************************
|
|
File Functions
|
|
****************************************************************************}
|
|
{$I-}
|
|
const
|
|
{ read/write permission for everyone }
|
|
MODE_OPEN = S_IWUSR OR S_IRUSR OR
|
|
S_IWGRP OR S_IRGRP OR
|
|
S_IWOTH OR S_IROTH;
|
|
|
|
|
|
Function FileOpen (Const FileName : string; Mode : Integer) : Longint;
|
|
|
|
Var Flags : cint;
|
|
FileHandle : cint;
|
|
{ lock: flock;}
|
|
BEGIN
|
|
Flags:=0;
|
|
Case (Mode and 3) of
|
|
fmOpenRead : Flags:=Flags or O_RDONLY;
|
|
fmOpenWrite : Flags:=Flags or O_WRONLY;
|
|
fmOpenReadWrite : Flags:=Flags or O_RDWR;
|
|
end;
|
|
FileHandle:=sys_Open (pchar(FileName),Flags,MODE_OPEN);
|
|
if (ErrNo=Sys_EROFS) and ((Flags and O_RDWR)<>0) then
|
|
begin
|
|
Flags:=Flags and not(O_RDWR);
|
|
FileHandle:=sys_open(pchar(FileName),Flags,MODE_OPEN);
|
|
end;
|
|
FileOpen := longint(FileHandle);
|
|
(*
|
|
{ if there was an error, then don't do anything }
|
|
if FileHandle = -1 then
|
|
exit;
|
|
{ now check if the file can actually be used }
|
|
{ by verifying the locks on the file }
|
|
lock.l_whence := SEEK_SET;
|
|
lock.l_start := 0; { from start of file }
|
|
lock.l_len := 0; { to END of file }
|
|
if sys_fcntl(FileHandle, F_GETLK, @lock)<>-1 then
|
|
begin
|
|
{ if another process has created a lock on this file }
|
|
{ exclusive lock? }
|
|
if (lock.l_type = F_WRLCK) then
|
|
begin
|
|
{ close and exit }
|
|
sys_close(FileHandle);
|
|
FileOpen := -1;
|
|
exit;
|
|
end;
|
|
{ shared lock? }
|
|
if (lock.l_type = F_RDLK) and
|
|
((Flags = O_RDWR) or Flags = O_WRONLY)) then
|
|
begin
|
|
{ close and exit }
|
|
sys_close(FileHandle);
|
|
FileOpen := -1;
|
|
exit;
|
|
end;
|
|
end;
|
|
{ now actually set the lock: }
|
|
{ only the following are simulated with sysutils : }
|
|
{ - fmShareDenywrite (get exclusive lock) }
|
|
{ - fmShareExclusive (get exclusive lock) }
|
|
if ((Mode and fmShareDenyWrite)<>0) or
|
|
((Mode and fmShareExclusive)<>0) then
|
|
begin
|
|
lock.l_whence := SEEK_SET;
|
|
lock.l_start := 0; { from stat of file }
|
|
lock.l_len := 0; { to END of file }
|
|
lock.l_type := F_WRLCK; { exclusive lock }
|
|
if sys_fcntl(FileHandle, F_SETLK, @lock)=-1 then
|
|
begin
|
|
sys_close(FileHandel);
|
|
FileOpen := -1;
|
|
exit;
|
|
end;
|
|
end;
|
|
*)
|
|
end;
|
|
|
|
|
|
Function FileCreate (Const FileName : String) : Longint;
|
|
|
|
begin
|
|
FileCreate:=sys_Open(pchar(FileName),O_RDWR or O_CREAT or O_TRUNC,MODE_OPEN);
|
|
end;
|
|
|
|
|
|
Function FileRead (Handle : Longint; Var Buffer; Count : longint) : Longint;
|
|
|
|
begin
|
|
repeat
|
|
FileRead:=sys_read(Handle,pchar(@Buffer),Count);
|
|
until ErrNo<>Sys_EINTR;
|
|
If FileRead = -1 then
|
|
FileRead := 0;
|
|
end;
|
|
|
|
|
|
Function FileWrite (Handle : Longint; const Buffer; Count : Longint) : Longint;
|
|
|
|
begin
|
|
repeat
|
|
FileWrite:=sys_write(Handle,pchar(@Buffer),Count);
|
|
until ErrNo<>Sys_EINTR;
|
|
if FileWrite = -1 then
|
|
FileWrite := 0;
|
|
end;
|
|
|
|
|
|
Function FileSeek (Handle,FOffset,Origin : Longint) : Longint;
|
|
var
|
|
whence : cint;
|
|
begin
|
|
FileSeek := -1;
|
|
case Origin of
|
|
{ from beginning of file }
|
|
0 : whence := SEEK_SET;
|
|
{ from current position }
|
|
1 : whence := SEEK_CUR;
|
|
{ from end of file }
|
|
2 : whence := SEEK_END;
|
|
else
|
|
exit;
|
|
end;
|
|
FileSeek := sys_lseek(Handle,FOffset,whence);
|
|
if errno <> 0 then
|
|
FileSeek := -1;
|
|
end;
|
|
|
|
|
|
Procedure FileClose (Handle : Longint);
|
|
|
|
begin
|
|
sys_close(Handle);
|
|
end;
|
|
|
|
Function FileTruncate (Handle,Size: Longint) : boolean;
|
|
|
|
begin
|
|
if sys_ftruncate(Handle,Size)=0 then
|
|
FileTruncate := true
|
|
else
|
|
FileTruncate := false;
|
|
end;
|
|
|
|
|
|
Function FileAge (Const FileName : String): Longint;
|
|
|
|
var F: file;
|
|
Time: longint;
|
|
begin
|
|
Assign(F,FileName);
|
|
Reset(F,1);
|
|
dos.GetFTime(F,Time);
|
|
Close(F);
|
|
FileAge := Time;
|
|
end;
|
|
|
|
|
|
Function FileExists (Const FileName : String) : Boolean;
|
|
|
|
Var Info : Stat;
|
|
|
|
begin
|
|
if sys_stat(pchar(filename),Info)<>0 then
|
|
FileExists := false
|
|
else
|
|
FileExists := true;
|
|
end;
|
|
|
|
|
|
Function UNIXToWinAttr (FN : Pchar; Const Info : Stat) : Longint;
|
|
|
|
begin
|
|
Result:=faArchive;
|
|
If S_ISDIR(Info.st_mode) then
|
|
Result:=Result or faDirectory ;
|
|
If (FN[0]='.') and (not (FN[1] in [#0,'.'])) then
|
|
Result:=Result or faHidden;
|
|
if (info.st_mode and S_IWUSR)=0 then
|
|
Result:=Result or fareadonly;
|
|
If S_ISREG(Info.st_Mode) Then
|
|
Result:=Result or faSysFile;
|
|
end;
|
|
|
|
|
|
|
|
|
|
type
|
|
PDOSSearchRec = ^SearchRec;
|
|
|
|
Function FindFirst (Const Path : String; Attr : Longint; Var Rslt : TSearchRec) : Longint;
|
|
|
|
Const
|
|
faSpecial = faHidden or faSysFile or faVolumeID or faDirectory;
|
|
var
|
|
p : pDOSSearchRec;
|
|
dosattr: word;
|
|
begin
|
|
dosattr:=0;
|
|
if Attr and faHidden <> 0 then
|
|
dosattr := dosattr or Hidden;
|
|
if Attr and faSysFile <> 0 then
|
|
dosattr := dosattr or SysFile;
|
|
if Attr and favolumeID <> 0 then
|
|
dosattr := dosattr or VolumeID;
|
|
if Attr and faDirectory <> 0 then
|
|
dosattr := dosattr or faDirectory;
|
|
New(p);
|
|
Rslt.FindHandle := THandle(p);
|
|
dos.FindFirst(path,dosattr,p^);
|
|
if DosError <> 0 then
|
|
begin
|
|
FindFirst := -1;
|
|
end
|
|
else
|
|
begin
|
|
Rslt.Name := p^.Name;
|
|
Rslt.Time := p^.Time;
|
|
Rslt.Attr := p^.Attr;
|
|
Rslt.ExcludeAttr := not p^.Attr;
|
|
Rslt.Size := p^.Size;
|
|
FindFirst := 0;
|
|
end;
|
|
end;
|
|
|
|
|
|
Function FindNext (Var Rslt : TSearchRec) : Longint;
|
|
var
|
|
p : pDOSSearchRec;
|
|
begin
|
|
p:= PDOsSearchRec(Rslt.FindHandle);
|
|
if not assigned(p) then
|
|
begin
|
|
FindNext := -1;
|
|
exit;
|
|
end;
|
|
Dos.FindNext(p^);
|
|
if DosError <> 0 then
|
|
begin
|
|
FindNext := -1;
|
|
end
|
|
else
|
|
begin
|
|
Rslt.Name := p^.Name;
|
|
Rslt.Time := p^.Time;
|
|
Rslt.Attr := p^.Attr;
|
|
Rslt.ExcludeAttr := not p^.Attr;
|
|
Rslt.Size := p^.Size;
|
|
FindNext := 0;
|
|
end;
|
|
end;
|
|
|
|
|
|
Procedure FindClose (Var F : TSearchrec);
|
|
|
|
Var
|
|
p : PDOSSearchRec;
|
|
|
|
begin
|
|
p:=PDOSSearchRec(f.FindHandle);
|
|
if not assigned(p) then
|
|
exit;
|
|
Dos.FindClose(p^);
|
|
if assigned(p) then
|
|
Dispose(p);
|
|
f.FindHandle := THandle(nil);
|
|
end;
|
|
|
|
Function FileGetDate (Handle : Longint) : Longint;
|
|
|
|
Var Info : Stat;
|
|
|
|
begin
|
|
If sys_FStat(Handle,Info)<>0 then
|
|
Result:=-1
|
|
else
|
|
Result:=Info.st_mtime;
|
|
end;
|
|
|
|
|
|
Function FileSetDate (Handle,Age : Longint) : Longint;
|
|
|
|
begin
|
|
// Impossible under unix from FileHandle !!
|
|
FileSetDate:=-1;
|
|
end;
|
|
|
|
|
|
Function FileGetAttr (Const FileName : String) : Longint;
|
|
|
|
Var Info : Stat;
|
|
|
|
begin
|
|
If sys_stat (pchar(FileName),Info)<>0 then
|
|
Result:=-1
|
|
Else
|
|
Result:=UNIXToWinAttr(Pchar(FileName),Info);
|
|
end;
|
|
|
|
|
|
Function FileSetAttr (Const Filename : String; Attr: longint) : Longint;
|
|
|
|
begin
|
|
Result:=-1;
|
|
end;
|
|
|
|
|
|
Function DeleteFile (Const FileName : String) : Boolean;
|
|
begin
|
|
if sys_unlink(pchar(FileName))=0 then
|
|
DeleteFile := true
|
|
else
|
|
DeleteFile := false;
|
|
end;
|
|
|
|
Function RenameFile (Const OldName, NewName : String) : Boolean;
|
|
|
|
begin
|
|
{ you can directly typecast and ansistring to a pchar }
|
|
if sys_rename(pchar(OldName),pchar(NewName))=0 then
|
|
RenameFile := TRUE
|
|
else
|
|
RenameFile := FALSE;
|
|
end;
|
|
|
|
|
|
|
|
|
|
{****************************************************************************
|
|
Disk Functions
|
|
****************************************************************************}
|
|
|
|
{
|
|
The Diskfree and Disksize functions need a file on the specified drive, since this
|
|
is required for the statfs system call.
|
|
These filenames are set in drivestr[0..26], and have been preset to :
|
|
0 - '.' (default drive - hence current dir is ok.)
|
|
1 - '/fd0/.' (floppy drive 1 - should be adapted to local system )
|
|
2 - '/fd1/.' (floppy drive 2 - should be adapted to local system )
|
|
3 - '/' (C: equivalent of dos is the root partition)
|
|
4..26 (can be set by you're own applications)
|
|
! Use AddDisk() to Add new drives !
|
|
They both return -1 when a failure occurs.
|
|
}
|
|
Const
|
|
FixDriveStr : array[0..3] of pchar=(
|
|
'.',
|
|
'/fd0/.',
|
|
'/fd1/.',
|
|
'/.'
|
|
);
|
|
var
|
|
Drives : byte;
|
|
DriveStr : array[4..26] of pchar;
|
|
|
|
Procedure AddDisk(const path:string);
|
|
begin
|
|
if not (DriveStr[Drives]=nil) then
|
|
FreeMem(DriveStr[Drives],StrLen(DriveStr[Drives])+1);
|
|
GetMem(DriveStr[Drives],length(Path)+1);
|
|
StrPCopy(DriveStr[Drives],path);
|
|
inc(Drives);
|
|
if Drives>26 then
|
|
Drives:=4;
|
|
end;
|
|
|
|
|
|
|
|
Function DiskFree(Drive: Byte): int64;
|
|
Begin
|
|
DiskFree := dos.diskFree(Drive);
|
|
End;
|
|
|
|
|
|
|
|
Function DiskSize(Drive: Byte): int64;
|
|
Begin
|
|
DiskSize := dos.DiskSize(Drive);
|
|
End;
|
|
|
|
|
|
|
|
|
|
Function GetCurrentDir : String;
|
|
begin
|
|
GetDir (0,Result);
|
|
end;
|
|
|
|
|
|
Function SetCurrentDir (Const NewDir : String) : Boolean;
|
|
begin
|
|
ChDir(NewDir);
|
|
result := (IOResult = 0);
|
|
end;
|
|
|
|
|
|
Function CreateDir (Const NewDir : String) : Boolean;
|
|
begin
|
|
MkDir(NewDir);
|
|
result := (IOResult = 0);
|
|
end;
|
|
|
|
|
|
Function RemoveDir (Const Dir : String) : Boolean;
|
|
begin
|
|
RmDir(Dir);
|
|
result := (IOResult = 0);
|
|
end;
|
|
|
|
|
|
Function DirectoryExists(const Directory: string): Boolean;
|
|
|
|
var
|
|
Info : Stat;
|
|
l: cint;
|
|
begin
|
|
l:=sys_Stat(pchar(Directory),Info);
|
|
if l<>0 then
|
|
Result:=S_ISDIR(info.st_mode)
|
|
else
|
|
Result := false;
|
|
end;
|
|
|
|
|
|
{****************************************************************************
|
|
Misc Functions
|
|
****************************************************************************}
|
|
|
|
procedure Beep;
|
|
begin
|
|
end;
|
|
|
|
|
|
{****************************************************************************
|
|
Locale Functions
|
|
****************************************************************************}
|
|
|
|
Procedure GetLocalTime(var SystemTime: TSystemTime);
|
|
var
|
|
dayOfWeek: word;
|
|
begin
|
|
dos.GetTime(SystemTime.Hour, SystemTime.Minute, SystemTime.Second,SystemTime.Millisecond);
|
|
dos.GetDate(SystemTime.Year, SystemTime.Month, SystemTime.Day, DayOfWeek);
|
|
end ;
|
|
|
|
|
|
Procedure InitAnsi;
|
|
Var
|
|
i : longint;
|
|
begin
|
|
{ Fill table entries 0 to 127 }
|
|
for i := 0 to 96 do
|
|
UpperCaseTable[i] := chr(i);
|
|
for i := 97 to 122 do
|
|
UpperCaseTable[i] := chr(i - 32);
|
|
for i := 123 to 191 do
|
|
UpperCaseTable[i] := chr(i);
|
|
Move (CPISO88591UCT,UpperCaseTable[192],SizeOf(CPISO88591UCT));
|
|
|
|
for i := 0 to 64 do
|
|
LowerCaseTable[i] := chr(i);
|
|
for i := 65 to 90 do
|
|
LowerCaseTable[i] := chr(i + 32);
|
|
for i := 91 to 191 do
|
|
LowerCaseTable[i] := chr(i);
|
|
Move (CPISO88591LCT,UpperCaseTable[192],SizeOf(CPISO88591UCT));
|
|
end;
|
|
|
|
|
|
Procedure InitInternational;
|
|
begin
|
|
InitAnsi;
|
|
end;
|
|
|
|
function SysErrorMessage(ErrorCode: Integer): String;
|
|
|
|
begin
|
|
{ Result:=StrError(ErrorCode);}
|
|
end;
|
|
|
|
{****************************************************************************
|
|
OS utility functions
|
|
****************************************************************************}
|
|
|
|
Function GetEnvironmentVariable(Const EnvVar : String) : String;
|
|
|
|
begin
|
|
Result:=Dos.Getenv(shortstring(EnvVar));
|
|
end;
|
|
|
|
|
|
{****************************************************************************
|
|
Initialization code
|
|
****************************************************************************}
|
|
|
|
Initialization
|
|
InitExceptions; { Initialize exceptions. OS independent }
|
|
InitInternational; { Initialize internationalization settings }
|
|
Finalization
|
|
DoneExceptions;
|
|
end.
|
|
{
|
|
$Log$
|
|
Revision 1.9 2003-11-26 20:00:19 florian
|
|
* error handling for Variants improved
|
|
|
|
Revision 1.8 2003/10/25 23:43:59 hajny
|
|
* THandle in sysutils common using System.THandle
|
|
|
|
Revision 1.7 2003/10/09 20:13:19 florian
|
|
* more type alias updates as suggested by DarekM
|
|
|
|
Revision 1.6 2003/04/01 15:57:41 peter
|
|
* made THandle platform dependent and unique type
|
|
|
|
Revision 1.5 2003/03/29 15:36:58 hajny
|
|
* DirectoryExists merged from the fixes branch
|
|
|
|
Revision 1.4 2003/03/29 15:16:26 hajny
|
|
* dummy DirectoryExists added
|
|
|
|
Revision 1.3 2002/09/07 16:01:26 peter
|
|
* old logs removed and tabs fixed
|
|
|
|
Revision 1.2 2002/08/10 13:42:36 marco
|
|
* Fixes Posix dir copied to devel branch
|
|
|
|
Revision 1.1.2.5 2002/04/28 07:28:43 carl
|
|
* some cleanup
|
|
|
|
Revision 1.1.2.4 2002/03/03 08:47:37 carl
|
|
+ FindFirst / FindNext implemented
|
|
|
|
Revision 1.1.2.3 2002/01/22 07:41:11 michael
|
|
+ Fixed FileSearch bug in Win32 and made FIleSearch platform independent
|
|
|
|
} |