3 This file is part of the Free Pascal run time library
.
4 Copyright (c
) 1999-2000 by Michael Van Canneyt
and Peter Vreman
,
5 members of the Free Pascal development team
7 See the file COPYING
.FPC
, included
in this distribution
,
8 for details about the copyright
.
10 This program is distributed
in the hope that it will be useful
,
11 but WITHOUT ANY WARRANTY
; without even the implied warranty of
12 MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE
.
14 **********************************************************************}
19 {Max FileName Length
for files
}
22 {Bitmasks
for CPU Flags
}
30 {Bitmasks
for file attribute
}
47 ComStr
= String
[FileNameLen
];
48 PathStr
= String
[FileNameLen
];
49 DirStr
= String
[FileNameLen
];
50 NameStr
= String
[FileNameLen
];
51 ExtStr
= String
[FileNameLen
];
53 SearchRec
= packed Record
54 {Fill
: array
[1..21] of byte
; Fill replaced with below
}
55 SearchNum
: LongInt
; {to track which search this is
}
56 SearchPos
: LongInt
; {directory position
}
57 DirPtr
: LongInt
; {directory pointer
for reading directory
}
58 SearchType
: Byte
; {0=normal
, 1=open will close
, 2=only
1 file
}
59 SearchAttr
: Byte
; {attribute we are searching
for}
60 Fill
: Array
[1..07] of Byte
; {future use
}
62 Attr
: Byte
; {attribute of found file
}
63 Time
: LongInt
; {last modify date of found file
}
64 Size
: LongInt
; {file size of found file
}
65 Reserved
: Word
; {future use
}
66 Name
: String
[FileNameLen
]; {name of found file
}
67 SearchSpec
: String
[FileNameLen
]; {search pattern
}
68 NamePos
: Word
; {end of path
, start of name position
}
72 filerec
.inc contains the definition of the filerec
.
73 textrec
.inc contains the definition of the textrec
.
74 It is
in a separate file to make it available
in other units without
75 having to use the DOS unit
for it
.
80 Registers
= packed record
82 0 : (ax
,f1
,bx
,f2
,cx
,f3
,dx
,f4
,bp
,f5
,si
,f51
,di
,f6
,ds
,f7
,es
,f8
,flags
,fs
,gs
: word
);
83 1 : (al
,ah
,f9
,f10
,bl
,bh
,f11
,f12
,cl
,ch
,f13
,f14
,dl
,dh
: byte
);
84 2 : (eax
, ebx
, ecx
, edx
, ebp
, esi
, edi
: longint
);
87 DateTime
= packed record
100 function
weekday(y
,m
,d
: longint
) : longint
;
101 Procedure
UnixDateToDt(SecsPast
: LongInt
; Var Dt
: DateTime
);
102 Function
DTToUnixDate(DT
: DateTime
): LongInt
;
105 Function DosVersion
: Word
;
106 Procedure
GetDate(var year
, month
, mday
, wday
: word
);
107 Procedure
GetTime(var hour
, minute
, second
, sec100
: word
);
108 procedure
SetDate(year
,month
,day
: word
);
109 Procedure
SetTime(hour
,minute
,second
,sec100
: word
);
110 Procedure
UnpackTime(p
: longint
; var t
: datetime
);
111 Procedure
PackTime(var t
: datetime
; var p
: longint
);
114 Procedure
Exec(const path
: pathstr
; const comline
: comstr
);
115 Function DosExitCode
: word
;
118 Procedure
AddDisk(const path
:string);
120 Function
DiskFree(drive
: byte
) : int64
;
121 Function
DiskSize(drive
: byte
) : int64
;
123 Function
DiskFree(drive
: byte
) : longint
;
124 Function
DiskSize(drive
: byte
) : longint
;
126 Procedure
FindFirst(const path
: pathstr
; attr
: word
; var f
: searchRec
);
127 Procedure
FindNext(var f
: searchRec
);
128 Procedure
FindClose(Var f
: SearchRec
);
131 Procedure
GetFAttr(var f
; var attr
: word
);
132 Procedure
GetFTime(var f
; var time
: longint
);
133 Function
FSearch(path
: pathstr
; dirlist
: string
): pathstr
;
134 Function
FExpand(const path
: pathstr
): pathstr
;
135 Procedure
FSplit(path
: pathstr
; var dir
: dirstr
; var name
: namestr
; var ext
: extstr
);
138 Function EnvCount
: longint
;
139 Function
EnvStr(index
: integer
): string
;
140 Function
GetEnv (envvar
: string
): string
;
142 {Do Nothing Functions
, no Linux
version}
143 Procedure
Intr(intno
: byte
; var regs
: registers
);
144 Procedure
MSDos(var regs
: registers
);
145 Procedure SwapVectors
;
146 Procedure
GetIntVec(intno
: byte
; var vector
: pointer
);
147 Procedure
SetIntVec(intno
: byte
; vector
: pointer
);
148 Procedure
Keep(exitcode
: word
);
149 Procedure
SetFAttr(var f
; attr
: word
);
150 Procedure
SetFTime(var f
; time
: longint
);
151 Procedure
GetCBreak(var breakvalue
: boolean
);
152 Procedure
SetCBreak(breakvalue
: boolean
);
153 Procedure
GetVerify(var verify
: boolean
);
154 Procedure
SetVerify(verify
: boolean
);
162 {******************************************************************************
163 --- Link C Lib
if set
---
164 ******************************************************************************}
177 {******************************************************************************
178 --- Info
/ Date / Time
---
179 ******************************************************************************}
188 GTRec
= packed Record
198 Function DosVersion
:Word;
200 Buffer
: Array
[0..255] of Char
;
210 Move(info
.release
,buffer
[0],40);
211 TmpStr
:=StrPas(Buffer
);
213 TmpStr
:='FreeBSD doesn''t support UName';
216 TmpPos
:=Pos('.',TmpStr
);
219 Tmp2
:=Copy(TmpStr
,TmpPos
+1,40);
220 Delete(TmpStr
,TmpPos
,40);
222 TmpPos
:=Pos('.',Tmp2
);
224 Delete(Tmp2
,TmpPos
,40);
227 DosVersion
:=Rel
+(SubRel shl
8);
230 function
WeekDay (y
,m
,d
:longint):longint;
232 Calculates th day of the week
. returns
-1 on error
237 if (m
<1) or (m
>12) or (y
<1600) or (y
>4000) or
238 (d
<1) or (d
>30+((m
+ord(m
>7)) and 1)-ord(m
=2)) or
239 ((m
*d
=58) and (((y mod
4>0) or (y mod
100=0)) and (y mod
400>0))) then
250 WeekDay
:=(d
+2*u
+((3*(u
+1)) div
5)+v
+(v div
4)-(v div
100)+(v div
400)+1) mod
7;
256 Procedure
GetDate(Var Year
, Month
, MDay
, WDay
: Word
);
258 Linux
.GetDate(Year
,Month
,MDay
);
259 Wday
:=weekday(Year
,Month
,MDay
);
264 Procedure
SetDate(Year
, Month
, Day
: Word
);
271 Procedure
GetTime(Var Hour
, Minute
, Second
, Sec100
: Word
);
273 Linux
.GetTime(Hour
,Minute
,Second
,Sec100
);
278 Procedure
SetTime(Hour
, Minute
, Second
, Sec100
: Word
);
285 Procedure
packtime(var t
: datetime
;var p
: longint
);
287 p
:=(t
.sec shr
1)+(t
.min shl
5)+(t
.hour shl
11)+(t
.day shl
16)+(t
.month shl
21)+((t
.year-1980
) shl
25);
292 Procedure
unpacktime(p
: longint
;var t
: datetime
);
294 t
.sec
:=(p
and 31) shl
1;
295 t
.min
:=(p shr
5) and 63;
296 t
.hour
:=(p shr
11) and 31;
297 t
.day
:=(p shr
16) and 31;
298 t
.month
:=(p shr
21) and 15;
299 t
.year
:=(p shr
25)+1980;
303 Procedure
UnixDateToDt(SecsPast
: LongInt
; Var Dt
: DateTime
);
305 EpochToLocal(SecsPast
,dt
.Year
,dt
.Month
,dt
.Day
,dt
.Hour
,dt
.Min
,dt
.Sec
);
310 Function
DTToUnixDate(DT
: DateTime
): LongInt
;
312 DTToUnixDate
:=LocalToEpoch(dt
.Year
,dt
.Month
,dt
.Day
,dt
.Hour
,dt
.Min
,dt
.Sec
);
317 {******************************************************************************
319 ******************************************************************************}
322 LastDosExitCode
: word
;
324 Procedure
Exec (Const Path
: PathStr
; Const ComLine
: ComStr
);
333 {The child does the actual exec
, and then exits
}
334 Execl (Path
+' '+ComLine
);
335 {If the execve fails
, we
return an exitvalue of
127, to let it be known
}
339 if pid
=-1 then {Fork failed
}
344 {We
're in the parent, let's wait
.}
345 Waitpid (pid
,@status,0);
346 if status
=127 then {The child couldn
't execve !!}
347 DosError:=8 {We set this error, erroneously, since we cannot get to the real error}
350 LastDosExitCode:=status shr 8;
357 Function DosExitCode: Word;
359 DosExitCode:=LastDosExitCode;
363 {******************************************************************************
365 ******************************************************************************}
368 The Diskfree and Disksize functions need a file on the specified drive, since this
369 is required for the statfs system call.
370 These filenames are set in drivestr[0..26], and have been preset to :
371 0 - '.' (default drive - hence current dir is ok.)
372 1 - '/fd0/.' (floppy drive 1 - should be adapted to local system )
373 2 - '/fd1/.' (floppy drive 2 - should be adapted to local system )
374 3 - '/' (C: equivalent of dos is the root partition)
375 4..26 (can be set by you're own applications
)
376 ! Use
AddDisk() to Add new drives
!
377 They both
return -1 when a failure occurs
.
380 FixDriveStr
: array
[0..3] of pchar
=(
388 DriveStr
: array
[4..26] of pchar
;
390 Procedure
AddDisk(const path
:string);
392 if not (DriveStr
[Drives
]=nil) then
393 FreeMem(DriveStr
[Drives
],StrLen(DriveStr
[Drives
])+1);
394 GetMem(DriveStr
[Drives
],length(Path
)+1);
395 StrPCopy(DriveStr
[Drives
],path
);
405 Function
DiskFree(Drive
: Byte
): int64
;
409 if ((Drive
<4) and (not (fixdrivestr
[Drive
]=nil)) and fsstat(StrPas(fixdrivestr
[drive
]),fs
)) or
410 ((not (drivestr
[Drive
]=nil)) and fsstat(StrPas(drivestr
[drive
]),fs
)) then
411 Diskfree
:=int64(fs
.bavail
)*int64(fs
.bsize
)
418 Function
DiskSize(Drive
: Byte
): int64
;
422 if ((Drive
<4) and (not (fixdrivestr
[Drive
]=nil)) and fsstat(StrPas(fixdrivestr
[drive
]),fs
)) or
423 ((not (drivestr
[Drive
]=nil)) and fsstat(StrPas(drivestr
[drive
]),fs
)) then
424 DiskSize
:=int64(fs
.blocks
)*int64(fs
.bsize
)
431 Function
DiskFree(Drive
: Byte
): Longint
;
435 if ((Drive
<4) and (not (fixdrivestr
[Drive
]=nil)) and fsstat(StrPas(fixdrivestr
[drive
]),fs
)) or
436 ((not (drivestr
[Drive
]=nil)) and fsstat(StrPas(drivestr
[drive
]),fs
)) then
437 Diskfree
:=fs
.bavail
*fs
.bsize
444 Function
DiskSize(Drive
: Byte
): Longint
;
448 if ((Drive
<4) and (not (fixdrivestr
[Drive
]=nil)) and fsstat(StrPas(fixdrivestr
[drive
]),fs
)) or
449 ((not (drivestr
[Drive
]=nil)) and fsstat(StrPas(drivestr
[drive
]),fs
)) then
450 DiskSize
:=fs
.blocks
*fs
.bsize
458 {******************************************************************************
459 --- Findfirst FindNext
---
460 ******************************************************************************}
465 RtlFindRecType
= Record
471 RtlFindRecs
: Array
[1..RtlFindSize
] of RtlFindRecType
;
472 CurrSearchNum
: LongInt
;
475 Procedure
FindClose(Var f
: SearchRec
);
477 Closes dirptr
if it is open
482 if f
.SearchType
=0 then
486 if (RtlFindRecs
[i
].SearchNum
=f
.SearchNum
) then
489 until (i
>RtlFindSize
);
490 If i
<=RtlFindSize Then
492 RtlFindRecs
[i
].SearchNum
:=0;
494 closedir(pdir(f
.dirptr
));
501 Function
FindGetFileInfo(const s
:string;var f
:SearchRec):boolean;
507 FindGetFileInfo
:=false;
508 if not Fstat(s
,st
) then
511 info
.FMTime
:=st
.mtime
;
512 if (st
.mode
and STAT_IFMT
)=STAT_IFDIR
then
516 if (st
.mode
and STAT_IWUSR
)=0 then
517 info
.fmode
:=info
.fmode
or 1;
518 If ((Info
.FMode
and Not(f
.searchattr
))=0) Then
520 f
.Name
:=Copy(s
,f
.NamePos
+1,255);
523 UnixDateToDT(Info
.FMTime
, DT
);
525 FindGetFileInfo
:=true;
530 Function FindLastUsed
: Longint
;
532 Find unused
or least recently used dirpointer slot
in findrecs array
535 BestMatch
,i
: Longint
;
541 While (i
<= RtlFindSize
) And (Not Found
) Do
543 If (RtlFindRecs
[i
].SearchNum
= 0) Then
550 If RtlFindRecs
[i
].LastUsed
> RtlFindRecs
[BestMatch
].LastUsed Then
555 FindLastUsed
:= BestMatch
;
560 Procedure
FindNext(Var f
: SearchRec
);
562 re-opens dir
if not already
in array
and calls FindWorkProc
565 DirName
: Array
[0..256] of Char
;
574 If f
.SearchType
=0 Then
577 For i
:=1 to RtlFindSize Do
579 If RtlFindRecs
[i
].SearchNum
= f
.SearchNum Then
581 Inc(RtlFindRecs
[i
].LastUsed
);
585 If f
.NamePos
= 0 Then
593 Move(f
.SearchSpec
[1], DirName
[0], f
.NamePos
);
594 DirName
[f
.NamePos
] := #0;
596 f
.DirPtr
:= longint(opendir(@
(DirName
)));
599 ArrayPos
:=FindLastUsed
;
600 If RtlFindRecs
[ArrayPos
].SearchNum
> 0 Then
601 CloseDir(pdir(rtlfindrecs
[arraypos
].dirptr
));
602 RtlFindRecs
[ArrayPos
].SearchNum
:= f
.SearchNum
;
603 RtlFindRecs
[ArrayPos
].DirPtr
:= f
.DirPtr
;
604 if f
.searchpos
>0 then
605 seekdir(pdir(f
.dirptr
), f
.searchpos
);
609 RtlFindRecs
[ArrayPos
].LastUsed
:=0;
612 SName
:=Copy(f
.SearchSpec
,f
.NamePos
+1,255);
614 Finished
:=(f
.dirptr
=0);
615 While Not Finished Do
617 p
:=readdir(pdir(f
.dirptr
));
621 FName
:=Strpas(@p^
.name
);
626 If
FNMatch(SName
,FName
) Then
628 Found
:=FindGetFileInfo(Copy(f
.SearchSpec
,1,f
.NamePos
)+FName
,f
);
637 f
.searchpos
:=telldir(pdir(f
.dirptr
));
648 Procedure
FindFirst(Const Path
: PathStr
; Attr
: Word
; Var f
: SearchRec
);
650 opens dir
and calls FindWorkProc
659 f
.SearchSpec
:= Path
;
660 f
.SearchAttr
:= Attr
;
662 f
.NamePos
:= Length(f
.SearchSpec
);
663 while (f
.NamePos
>0) and (f
.SearchSpec
[f
.NamePos
]<>'/') do
666 if (Pos('?',Path
)=0) and (Pos('*',Path
)=0) then
668 if FindGetFileInfo(Path
,f
) then
672 if ErrNo
=Sys_ENOENT
then
685 f
.SearchNum
:=CurrSearchNum
;
692 {******************************************************************************
694 ******************************************************************************}
696 Procedure
FSplit(Path
: PathStr
; Var Dir
: DirStr
; Var Name
: NameStr
;Var Ext
: ExtStr
);
698 Linux
.FSplit(Path
,Dir
,Name
,Ext
);
703 Function
FExpand(Const Path
: PathStr
): PathStr
;
705 FExpand
:=Linux
.FExpand(Path
);
710 Function
FSearch(path
: pathstr
;dirlist
: string
) : pathstr
;
714 if (length(Path
)>0) and (path
[1]='/') and FStat(path
,info
) then
717 FSearch
:=Linux
.FSearch(path
,dirlist
);
722 Procedure
GetFAttr(var f
; var attr
: word
);
728 if not FStat(strpas(@textrec(f
).name
),info
) then
736 if S_ISDIR(LinAttr
) then
740 if not Access(strpas(@textrec(f
).name
),W_OK
) then
742 if (not S_ISDIR(LinAttr
)) and (filerec(f
).name
[0]='.') then
748 Procedure
getftime (var f
; var time
: longint
);
754 if not fstat(filerec(f
).handle
,info
) then
761 UnixDateToDT(Info
.mTime
,DT
);
767 {******************************************************************************
769 ******************************************************************************}
771 Function EnvCount
: Longint
;
777 p
:=envp
; {defined in syslinux
}
788 Function
EnvStr(Index
: Integer
): String
;
793 p
:=envp
; {defined in syslinux
}
795 while (i
<Index
) and (p^
<>nil) do
808 Function
GetEnv(EnvVar
: String
): String
;
812 p
:=Linux
.GetEnv(EnvVar
);
820 {******************************************************************************
821 --- Do Nothing Procedures
/Functions
---
822 ******************************************************************************}
824 Procedure
Intr (intno
: byte
; var regs
: registers
);
826 {! No Linux equivalent
!}
831 Procedure
msdos(var regs
: registers
);
833 {! No Linux equivalent
!}
838 Procedure
getintvec(intno
: byte
;var vector
: pointer
);
840 {! No Linux equivalent
!}
845 Procedure
setintvec(intno
: byte
;vector
: pointer
);
847 {! No Linux equivalent
!}
852 Procedure SwapVectors
;
854 {! No Linux equivalent
!}
859 Procedure
keep(exitcode
: word
);
861 {! No Linux equivalent
!}
866 Procedure
setftime(var f
; time
: longint
);
868 {! No Linux equivalent
!}
873 Procedure
setfattr (var f
;attr
: word
);
875 {! No Linux equivalent
!}
880 Procedure
GetCBreak(Var BreakValue
: Boolean
);
882 {! No Linux equivalent
!}
888 Procedure
SetCBreak(BreakValue
: Boolean
);
890 {! No Linux equivalent
!}
895 Procedure
GetVerify(Var Verify
: Boolean
);
897 {! No Linux equivalent
!}
903 Procedure
SetVerify(Verify
: Boolean
);
905 {! No Linux equivalent
!}
909 {******************************************************************************
910 --- Initialization
---
911 ******************************************************************************}
917 Revision
1.1 2002/02/19 08:26:15 sasu
920 Revision
1.1.2.1 2000/09/14 13:38:25 marco
921 * Moved from Linux dir
. now start of generic unix dir
, from which the
922 really exotic features should be moved to the target specific dirs
.
924 Revision
1.1 2000/07/13 06:30:53 michael
927 Revision
1.21 2000/04/18 08:03:40 michael
928 Corrected fix
for bug
902
930 Revision
1.20 2000/04/17 20:43:27 pierre
931 fix bug
902 for win32
and linux
933 Revision
1.19 2000/03/19 18:48:19 peter
934 * dosexitcode finally works correct
936 Revision
1.18 2000/03/16 15:23:02 marco
937 * Added one BSD
conditional (uname
not supported
)
939 Revision
1.17 2000/02/09 16:59:31 peter
942 Revision
1.16 2000/02/02 15:07:05 peter
943 * gettime supports now also sec100
944 * removed crtlib code as it was
broken (still available
in old releases
)
945 * int64 disksize
/diskfree
947 Revision
1.15 2000/01/07 16:41:40 daniel
950 Revision
1.14 2000/01/07 16:32:26 daniel
951 * copyright
2000 added
953 Revision
1.13 1999/09/08 16:14:41 peter
956 Revision
1.12 1999/07/28 23:18:35 peter
957 * closedir fixes
, which now disposes the pdir itself
959 Revision
1.11 1999/07/24 11:18:11 peter
960 * fixed getfattr which didn
't reset doserror