Browse Source

* unix interface cleanup

marco 21 years ago
parent
commit
780ba784d6
4 changed files with 665 additions and 543 deletions
  1. 5 1
      rtl/unix/aliasptp.inc
  2. 252 36
      rtl/unix/dos.pp
  3. 385 6
      rtl/unix/sysutils.pp
  4. 23 500
      rtl/unix/unix.pp

+ 5 - 1
rtl/unix/aliasptp.inc

@@ -70,6 +70,7 @@ type
     pthread_mutex_t   = UnixType.pthread_mutex_t;
     pthread_cond_t    = UnixType.pthread_cond_t;
     pthread_t         = UnixType.pthread_t;
+    tstatfs  = UnixType.TStatFs;	
 
 CONST
     ARG_MAX       = UnixType.ARG_MAX;
@@ -81,7 +82,10 @@ CONST
 
 {
   $Log$
-  Revision 1.2  2004-09-11 20:41:52  marco
+  Revision 1.3  2004-10-30 20:55:54  marco
+   * unix interface cleanup
+
+  Revision 1.2  2004/09/11 20:41:52  marco
    * already did 3 aliases needed for SDL port
 
   Revision 1.1  2004/03/04 22:15:16  marco

+ 252 - 36
rtl/unix/dos.pp

@@ -66,7 +66,11 @@ Procedure AddDisk(const path:string);
 Implementation
 
 Uses
-  Strings,UnixUtil,Unix,BaseUnix,UnixType;
+  Strings,SysUtils,Unix,BaseUnix,Syscall;
+
+
+{$i sysnr.inc}
+{$i settimeo.inc}
 
 {******************************************************************************
                            --- Link C Lib if set ---
@@ -87,6 +91,7 @@ type
                         --- Info / Date / Time ---
 ******************************************************************************}
 
+
 Const
 {Date Calculation}
   C1970 = 2440588;
@@ -104,6 +109,72 @@ type
     Second : Word;
   End;
 
+Function GregorianToJulian(Year,Month,Day:Longint):LongInt;
+Var
+  Century,XYear: LongInt;
+Begin
+  If Month<=2 Then
+   Begin
+     Dec(Year);
+     Inc(Month,12);
+   End;
+  Dec(Month,3);
+  Century:=(longint(Year Div 100)*D1) shr 2;
+  XYear:=(longint(Year Mod 100)*D0) shr 2;
+  GregorianToJulian:=((((Month*153)+2) div 5)+Day)+D2+XYear+Century;
+End;
+
+
+Function LocalToEpoch(year,month,day,hour,minute,second:Word):Longint;
+{
+  Transforms local time (year,month,day,hour,minutes,second) to Epoch time
+   (seconds since 00:00, january 1 1970, corrected for local time zone)
+}  
+Begin
+  LocalToEpoch:=((GregorianToJulian(Year,Month,Day)-c1970)*86400)+
+                (LongInt(Hour)*3600)+(Longint(Minute)*60)+Second-TZSeconds;
+End;
+
+Procedure JulianToGregorian(JulianDN:LongInt;Var Year,Month,Day:Word);
+Var
+  YYear,XYear,Temp,TempMonth : LongInt;
+Begin
+  Temp:=((JulianDN-D2) shl 2)-1;
+  JulianDN:=Temp Div D1;
+  XYear:=(Temp Mod D1) or 3;
+  YYear:=(XYear Div D0);
+  Temp:=((((XYear mod D0)+4) shr 2)*5)-3;
+  Day:=((Temp Mod 153)+5) Div 5;
+  TempMonth:=Temp Div 153;
+  If TempMonth>=10 Then
+   Begin
+     inc(YYear);
+     dec(TempMonth,12);
+   End;
+  inc(TempMonth,3);  
+  Month := TempMonth;
+  Year:=YYear+(JulianDN*100);
+end;
+
+Procedure EpochToLocal(epoch:longint;var year,month,day,hour,minute,second:Word);
+{
+  Transforms Epoch time into local time (hour, minute,seconds)
+}
+Var
+  DateNum: LongInt;
+Begin
+  inc(Epoch,TZSeconds);
+  Datenum:=(Epoch Div 86400) + c1970;
+  JulianToGregorian(DateNum,Year,Month,day);
+  Epoch:=Abs(Epoch Mod 86400);
+  Hour:=Epoch Div 3600;
+  Epoch:=Epoch Mod 3600;
+  Minute:=Epoch Div 60;
+  Second:=Epoch Mod 60;
+End;
+
+
+
 Function DosVersion:Word;
 Var
   Buffer : Array[0..255] of Char;
@@ -156,36 +227,59 @@ begin
    end;
 end;
 
+Procedure GetDate(Var Year, Month, MDay, WDay: Word);
 
+var t  :TSystemtime;
 
-Procedure GetDate(Var Year, Month, MDay, WDay: Word);
 Begin
-  Unix.GetDate(Year,Month,MDay);
+  sysutils.getlocaltime(t);
+  mday:=t.day;
+  month:=t.month;
+  year:=t.year;
   Wday:=weekday(Year,Month,MDay);
 end;
 
 
+procedure  SetTime(Hour,Minute,Second,sec100:word);
+var
+  dow,Year, Month, Day : Word;
+  
+  tv : timeval;
+begin
+  GetDate (Year, Month, Day,dow);
+  tv.tv_sec:= LocalToEpoch ( Year, Month, Day, Hour, Minute, Second ) ;
+  Settimeofday(@tv,nil);
+end;
 
-Procedure SetDate(Year, Month, Day: Word);
-Begin
-  Unix.SetDate ( Year, Month, Day );
-End;
-
-
+procedure SetDate(Year,Month,Day:Word);
+var
+  Hour, Min, Sec, Sec100 : Word;
+  tv : timeval;
+begin
+  GetTime ( Hour, Min, Sec, Sec100 );
+  tv.tv_sec:= LocalToEpoch ( Year, Month, Day, Hour, Min, Sec ) ;
+  Settimeofday(@tv,nil);
+end;
 
-Procedure GetTime(Var Hour, Minute, Second, Sec100: Word);
-Begin
-  Unix.GetTime(Hour,Minute,Second,Sec100);
+Function SetDateTime(Year,Month,Day,hour,minute,second:Word) : Boolean;
+var
+  tv : timeval;
+begin
+  tv.tv_sec:= LocalToEpoch ( Year, Month, Day, Hour, Minute, Second ) ;
+  SetDatetime:=Settimeofday(@tv,nil)=0;
 end;
 
+Procedure GetTime(Var Hour, Minute, Second, Sec100: Word);
 
+var t  :TSystemtime;
 
-Procedure SetTime(Hour, Minute, Second, Sec100: Word);
 Begin
-  Unix.SetTime ( Hour, Minute, Second );
-End;
-
-
+  sysutils.getlocaltime(t);
+  sec100:=0;
+  second:=t.second;
+  minute:=t.minute;
+  hour  :=t.hour; 
+end;
 
 Procedure packtime(var t : datetime;var p : longint);
 Begin
@@ -223,6 +317,29 @@ End;
                                --- Exec ---
 ******************************************************************************}
 
+Procedure FSplit( Path:PathStr;Var Dir:DirStr;Var Name:NameStr;Var Ext:ExtStr);
+Var
+  DotPos,SlashPos,i : longint;
+Begin
+  SlashPos:=0;
+  DotPos:=256;
+  i:=Length(Path);
+  While (i>0) and (SlashPos=0) Do
+   Begin
+     If (DotPos=256) and (Path[i]='.') Then
+      begin
+        DotPos:=i;
+      end;
+     If (Path[i]='/') Then
+      SlashPos:=i;
+     Dec(i);
+   End;
+  Ext:=Copy(Path,DotPos,255);
+  Dir:=Copy(Path,1,SlashPos);
+  Name:=Copy(Path,SlashPos + 1,DotPos - SlashPos - 1);
+End;
+
+
 {$ifdef HASTHREADVAR}
 {$ifdef VER1_9_2}
 var
@@ -236,20 +353,35 @@ var
 
 Procedure Exec (Const Path: PathStr; Const ComLine: ComStr);
 var
-  pid    : longint;
-  // The Error-Checking in the previous Version failed, since halt($7F) gives an WaitPid-status of $7F00
+  pid      : longint; // pid_t?
+  cmdline2 : ppchar;
+  commandline : ansistring;	
+  realpath : ansistring;
+ 
+// The Error-Checking in the previous Version failed, since halt($7F) gives an WaitPid-status of $7F00
 Begin
   LastDosExitCode:=0;
   pid:=fpFork;
   if pid=0 then
    begin
-   {The child does the actual exec, and then exits}
-     if ComLine='' then
-      Execl(Path)
+     cmdline2:=nil;
+     realpath:=path;
+     if Comline<>'' Then
+       begin
+         CommandLine:=ComLine;  // conversion must live till after fpexec!
+         cmdline2:=StringtoPPChar(CommandLine,1);
+         cmdline2^:=pchar(realPath);
+       end
      else
-      Execl(Path+' '+ComLine);
+       begin
+         getmem(cmdline2,2*sizeof(pchar));
+         cmdline2^:=pchar(realPath);
+         cmdline2[1]:=nil;
+       end;
+   {The child does the actual exec, and then exits}
+   fpExecv(pchar(realPath),cmdline2);
    {If the execve fails, we return an exitvalue of 127, to let it be known}
-     fpExit(127);
+   fpExit(127);
    end
   else
    if pid=-1 then         {Fork failed}
@@ -343,6 +475,89 @@ End;
                        --- Findfirst FindNext ---
 ******************************************************************************}
 
+
+Function FNMatch(const Pattern,Name:string):Boolean;
+Var
+  LenPat,LenName : longint;
+
+  Function DoFNMatch(i,j:longint):Boolean;
+  Var
+    Found : boolean;
+  Begin
+  Found:=true;
+  While Found and (i<=LenPat) Do
+   Begin
+     Case Pattern[i] of
+      '?' : Found:=(j<=LenName);
+      '*' : Begin
+            {find the next character in pattern, different of ? and *}
+              while Found do
+                begin
+                inc(i);
+                if i>LenPat then Break;
+                case Pattern[i] of
+                  '*' : ;
+                  '?' : begin
+                          if j>LenName then begin DoFNMatch:=false; Exit; end;
+                          inc(j);
+                        end;
+                else
+                  Found:=false;
+                end;
+               end;
+              Assert((i>LenPat) or ( (Pattern[i]<>'*') and (Pattern[i]<>'?') ));
+            {Now, find in name the character which i points to, if the * or ?
+             wasn't the last character in the pattern, else, use up all the
+             chars in name}
+              Found:=false;
+              if (i<=LenPat) then
+              begin
+                repeat
+                  {find a letter (not only first !) which maches pattern[i]}
+                  while (j<=LenName) and (name[j]<>pattern[i]) do
+                    inc (j);
+                  if (j<LenName) then
+                  begin
+                    if DoFnMatch(i+1,j+1) then
+                    begin
+                      i:=LenPat;
+                      j:=LenName;{we can stop}
+                      Found:=true;
+                      Break;
+                    end else
+                      inc(j);{We didn't find one, need to look further}
+                  end else
+                  if j=LenName then
+                  begin
+                    Found:=true;
+                    Break;
+                  end;
+                  { This 'until' condition must be j>LenName, not j>=LenName.
+                    That's because when we 'need to look further' and
+                    j = LenName then loop must not terminate. }
+                until (j>LenName);
+              end else
+              begin
+                j:=LenName;{we can stop}
+                Found:=true;
+              end;
+            end;
+     else {not a wildcard character in pattern}
+       Found:=(j<=LenName) and (pattern[i]=name[j]);
+     end;
+     inc(i);
+     inc(j);
+   end;
+  DoFnMatch:=Found and (j>LenName);
+  end;
+
+Begin {start FNMatch}
+  LenPat:=Length(Pattern);
+  LenName:=Length(Name);
+  FNMatch:=DoFNMatch(1,1);
+End;
+
+
 Const
   RtlFindSize = 15;
 Type
@@ -449,6 +664,7 @@ Procedure FindNext(Var f: SearchRec);
   re-opens dir if not already in array and calls FindWorkProc
 }
 Var
+
   DirName  : Array[0..256] of Char;
   i,
   ArrayPos : Longint;
@@ -456,7 +672,7 @@ Var
   SName    : string;
   Found,
   Finished : boolean;
-  p        : PDirEnt;
+  p        : pdirent;
 Begin
   If f.SearchType=0 Then
    Begin
@@ -583,17 +799,15 @@ End;
                                --- File ---
 ******************************************************************************}
 
-Procedure FSplit(Path: PathStr; Var Dir: DirStr; Var Name: NameStr;Var Ext: ExtStr);
-Begin
-  UnixUtil.FSplit(Path,Dir,Name,Ext);
-End;
 
+{$DEFINE FPC_FEXPAND_TILDE} { Tilde is expanded to home }
+{$DEFINE FPC_FEXPAND_GETENVPCHAR} { GetEnv result is a PChar }
 
+{$I fexpand.inc}
+
+{$UNDEF FPC_FEXPAND_GETENVPCHAR}
+{$UNDEF FPC_FEXPAND_TILDE}
 
-Function FExpand(Const Path: PathStr): PathStr;
-Begin
-  FExpand:=Unix.FExpand(Path);
-End;
 
 
 Function FSearch(path : pathstr;dirlist : string) : pathstr;
@@ -652,13 +866,12 @@ Procedure setftime(var f; time : longint);
 Var
   utim: utimbuf;
   DT: DateTime;
-  index: Integer;
 
 Begin
   doserror:=0;
   with utim do
     begin
-      actime:=getepochtime;
+      actime:=fptime;
       UnPackTime(Time,DT);
       modtime:=DTToUnixDate(DT);
     end;
@@ -834,7 +1047,10 @@ End.
 
 {
   $Log$
-  Revision 1.35  2004-09-25 15:09:57  peter
+  Revision 1.36  2004-10-30 20:55:54  marco
+   * unix interface cleanup
+
+  Revision 1.35  2004/09/25 15:09:57  peter
     * remove strpas() before syscalls so it chooses the pchar overload
 
   Revision 1.34  2004/08/14 14:22:17  florian

+ 385 - 6
rtl/unix/sysutils.pp

@@ -28,26 +28,123 @@ interface
 {$DEFINE HASUNIX}
 
 uses
-  Unix,errors,sysconst;
+  Unix,errors,sysconst,Unixtype;
 
 { Include platform independent interface part }
 {$i sysutilh.inc}
 
 Procedure AddDisk(const path:string);
 
+var
+  Tzseconds : Longint = 0;
+
 implementation
 
-Uses UnixUtil,Baseunix,UnixType;
+Uses Syscall,Baseunix;
 
 {$Define OS_FILEISREADONLY} // Specific implementation for Unix.
 
+Function getenv(name:string):Pchar; external name 'FPC_SYSC_FPGETENV';
+
+Type
+  ComStr  = String[255];
+  PathStr = String[255];
+  DirStr  = String[255];
+  NameStr = String[255];
+  ExtStr  = String[255];
+
+
+{$DEFINE FPC_FEXPAND_TILDE} { Tilde is expanded to home }
+{$DEFINE FPC_FEXPAND_GETENVPCHAR} { GetEnv result is a PChar }
+
+{$I fexpand.inc}
+
+{$UNDEF FPC_FEXPAND_GETENVPCHAR}
+{$UNDEF FPC_FEXPAND_TILDE}
+
 { Include platform independent implementation part }
 {$i sysutils.inc}
 
+Const
+{Date Translation}
+  C1970=2440588;
+  D0   =   1461;
+  D1   = 146097;
+  D2   =1721119;
+
+
+Procedure JulianToGregorian(JulianDN:LongInt;Var Year,Month,Day:Word);
+Var
+  YYear,XYear,Temp,TempMonth : LongInt;
+Begin
+  Temp:=((JulianDN-D2) shl 2)-1;
+  JulianDN:=Temp Div D1;
+  XYear:=(Temp Mod D1) or 3;
+  YYear:=(XYear Div D0);
+  Temp:=((((XYear mod D0)+4) shr 2)*5)-3;
+  Day:=((Temp Mod 153)+5) Div 5;
+  TempMonth:=Temp Div 153;
+  If TempMonth>=10 Then
+   Begin
+     inc(YYear);
+     dec(TempMonth,12);
+   End;
+  inc(TempMonth,3);  
+  Month := TempMonth;
+  Year:=YYear+(JulianDN*100);
+end;
+
+
+
+Procedure EpochToLocal(epoch:longint;var year,month,day,hour,minute,second:Word);
+{
+  Transforms Epoch time into local time (hour, minute,seconds)
+}
+Var
+  DateNum: LongInt;
+Begin
+  inc(Epoch,TZSeconds);
+  Datenum:=(Epoch Div 86400) + c1970;
+  JulianToGregorian(DateNum,Year,Month,day);
+  Epoch:=Abs(Epoch Mod 86400);
+  Hour:=Epoch Div 3600;
+  Epoch:=Epoch Mod 3600;
+  Minute:=Epoch Div 60;
+  Second:=Epoch Mod 60;
+End;
+
+
+
+
 {****************************************************************************
                               File Functions
 ****************************************************************************}
 
+
+
+Procedure FSplit(const Path:PathStr;Var Dir:DirStr;Var Name:NameStr;Var Ext:ExtStr);
+Var
+  DotPos,SlashPos,i : longint;
+Begin
+  SlashPos:=0;
+  DotPos:=256;
+  i:=Length(Path);
+  While (i>0) and (SlashPos=0) Do
+   Begin
+     If (DotPos=256) and (Path[i]='.') Then
+      begin
+        DotPos:=i;
+      end;
+     If (Path[i]='/') Then
+      SlashPos:=i;
+     Dec(i);
+   End;
+  Ext:=Copy(Path,DotPos,255);
+  Dir:=Copy(Path,1,SlashPos);
+  Name:=Copy(Path,SlashPos + 1,DotPos - SlashPos - 1);
+End;
+
+
 Function FileOpen (Const FileName : string; Mode : Integer) : Longint;
 
 Var LinuxFlags : longint;
@@ -183,6 +280,217 @@ begin
      Result:=Result or faSysFile;
 end;
 
+type
+
+ pglob = ^tglob;
+  tglob = record
+    name : pchar;
+    next : pglob;
+  end;
+
+Function Dirname(Const path:pathstr):pathstr;
+{
+  This function returns the directory part of a complete path.
+  Unless the directory is root '/', The last character is not
+  a slash.
+}
+var
+  Dir  : PathStr;
+  Name : NameStr;
+  Ext  : ExtStr;
+begin
+  FSplit(Path,Dir,Name,Ext);
+  if length(Dir)>1 then
+   Delete(Dir,length(Dir),1);
+  DirName:=Dir;
+end;
+
+
+Function Basename(Const path:pathstr;Const suf:pathstr):pathstr;
+{
+  This function returns the filename part of a complete path. If suf is
+  supplied, it is cut off the filename.
+}
+var
+  Dir  : PathStr;
+  Name : NameStr;
+  Ext  : ExtStr;
+begin
+  FSplit(Path,Dir,Name,Ext);
+  if Suf<>Ext then
+   Name:=Name+Ext;
+  BaseName:=Name;
+end;
+
+
+Function FNMatch(const Pattern,Name:shortstring):Boolean;
+Var
+  LenPat,LenName : longint;
+
+  Function DoFNMatch(i,j:longint):Boolean;
+  Var
+    Found : boolean;
+  Begin
+  Found:=true;
+  While Found and (i<=LenPat) Do
+   Begin
+     Case Pattern[i] of
+      '?' : Found:=(j<=LenName);
+      '*' : Begin
+            {find the next character in pattern, different of ? and *}
+              while Found do
+                begin
+                inc(i);
+                if i>LenPat then Break;
+                case Pattern[i] of
+                  '*' : ;
+                  '?' : begin
+                          if j>LenName then begin DoFNMatch:=false; Exit; end;
+                          inc(j);
+                        end;
+                else
+                  Found:=false;
+                end;
+               end;
+              Assert((i>LenPat) or ( (Pattern[i]<>'*') and (Pattern[i]<>'?') ));
+            {Now, find in name the character which i points to, if the * or ?
+             wasn't the last character in the pattern, else, use up all the
+             chars in name}
+              Found:=false;
+              if (i<=LenPat) then
+              begin
+                repeat
+                  {find a letter (not only first !) which maches pattern[i]}
+                  while (j<=LenName) and (name[j]<>pattern[i]) do
+                    inc (j);
+                  if (j<LenName) then
+                  begin
+                    if DoFnMatch(i+1,j+1) then
+                    begin
+                      i:=LenPat;
+                      j:=LenName;{we can stop}
+                      Found:=true;
+                      Break;
+                    end else
+                      inc(j);{We didn't find one, need to look further}
+                  end else
+                  if j=LenName then
+                  begin
+                    Found:=true;
+                    Break;
+                  end;
+                  { This 'until' condition must be j>LenName, not j>=LenName.
+                    That's because when we 'need to look further' and
+                    j = LenName then loop must not terminate. }
+                until (j>LenName);
+              end else
+              begin
+                j:=LenName;{we can stop}
+                Found:=true;
+              end;
+            end;
+     else {not a wildcard character in pattern}
+       Found:=(j<=LenName) and (pattern[i]=name[j]);
+     end;
+     inc(i);
+     inc(j);
+   end;
+  DoFnMatch:=Found and (j>LenName);
+  end;
+
+Begin {start FNMatch}
+  LenPat:=Length(Pattern);
+  LenName:=Length(Name);
+  FNMatch:=DoFNMatch(1,1);
+End;
+
+
+Procedure Globfree(var p : pglob);
+{
+  Release memory occupied by pglob structure, and names in it.
+  sets p to nil.
+}
+var
+  temp : pglob;
+begin
+  while assigned(p) do
+   begin
+     temp:=p^.next;
+     if assigned(p^.name) then
+      freemem(p^.name);
+     dispose(p);
+     p:=temp;
+   end;
+end;
+
+
+Function Glob(Const path:pathstr):pglob;
+{
+  Fills a tglob structure with entries matching path,
+  and returns a pointer to it. Returns nil on error,
+  linuxerror is set accordingly.
+}
+var
+  temp,
+  temp2   : string[255];
+  thedir  : pdir;
+  buffer  : pdirent;
+  root,
+  current : pglob;
+begin
+{ Get directory }
+  temp:=dirname(path);
+  if temp='' then
+   temp:='.';
+  temp:=temp+#0;
+  thedir:=fpopendir(@temp[1]);
+  if thedir=nil then
+    exit(nil);
+  temp:=basename(path,''); { get the pattern }
+  if thedir^.dd_fd<0 then
+     exit(nil);
+{get the entries}
+  root:=nil;
+  current:=nil;
+  repeat
+    buffer:=fpreaddir(thedir^);
+    if buffer=nil then
+     break;
+    temp2:=strpas(@(buffer^.d_name[0]));
+    if fnmatch(temp,temp2) then
+     begin
+       if root=nil then
+        begin
+          new(root);
+          current:=root;
+        end
+       else
+        begin
+          new(current^.next);
+          current:=current^.next;
+        end;
+       if current=nil then
+        begin
+           fpseterrno(ESysENOMEM);
+          globfree(root);
+          break;
+        end;
+       current^.next:=nil;
+       getmem(current^.name,length(temp2)+1);
+       if current^.name=nil then
+        begin
+          fpseterrno(ESysENOMEM);
+          globfree(root);
+          break;
+        end;
+       move(buffer^.d_name[0],current^.name^,length(temp2)+1);
+     end;
+  until false;
+  fpclosedir(thedir^);
+  glob:=root;
+end;
+
+
 {
  GlobToSearch takes a glob entry, stats the file.
  The glob entry is removed.
@@ -191,7 +499,7 @@ end;
 
 Type
   TGlobSearchRec = Record
-    Path       : String;
+    Path       : shortString;
     GlobHandle : PGlob;
   end;
   PGlobSearchRec = ^TGlobSearchRec;
@@ -446,10 +754,78 @@ end;
                               Locale Functions
 ****************************************************************************}
 
+
+Function GetEpochTime: cint;
+{
+  Get the number of seconds since 00:00, January 1 1970, GMT
+  the time NOT corrected any way
+}
+begin
+  GetEpochTime:=fptime;
+end;
+
+procedure GetTime(var hour,min,sec,msec,usec:word);
+{
+  Gets the current time, adjusted to local time
+}
+var
+  year,day,month:Word;
+  tz:timeval;
+begin
+  fpgettimeofday(@tz,nil);
+  EpochToLocal(tz.tv_sec,year,month,day,hour,min,sec);
+  msec:=tz.tv_usec div 1000;
+  usec:=tz.tv_usec mod 1000;
+end;
+
+procedure GetTime(var hour,min,sec,sec100:word);
+{
+  Gets the current time, adjusted to local time
+}
+var
+  usec : word;
+begin
+  gettime(hour,min,sec,sec100,usec);
+  sec100:=sec100 div 10;
+end;
+
+Procedure GetTime(Var Hour,Min,Sec:Word);
+{
+  Gets the current time, adjusted to local time
+}
+var
+  msec,usec : Word;
+Begin
+  gettime(hour,min,sec,msec,usec);
+End;
+
+Procedure GetDate(Var Year,Month,Day:Word);
+{
+  Gets the current date, adjusted to local time
+}
+var
+  hour,minute,second : word;
+Begin
+  EpochToLocal(fptime,year,month,day,hour,minute,second);
+End;
+
+Procedure GetDateTime(Var Year,Month,Day,hour,minute,second:Word);
+{
+  Gets the current date, adjusted to local time
+}
+Begin
+  EpochToLocal(fptime,year,month,day,hour,minute,second);
+End;
+
+
+
+{ Include timezone handling routines which use /usr/share/timezone info }
+{$i timezone.inc}
+
 Procedure GetLocalTime(var SystemTime: TSystemTime);
 begin
-  Unix.GetTime(SystemTime.Hour, SystemTime.Minute, SystemTime.Second);
-  Unix.GetDate(SystemTime.Year, SystemTime.Month, SystemTime.Day);
+  GetTime(SystemTime.Hour, SystemTime.Minute, SystemTime.Second);
+  GetDate(SystemTime.Year, SystemTime.Month, SystemTime.Day);
   SystemTime.MilliSecond := 0;
 end ;
 
@@ -715,7 +1091,10 @@ end.
 {
 
   $Log$
-  Revision 1.48  2004-10-12 15:22:23  michael
+  Revision 1.49  2004-10-30 20:55:54  marco
+   * unix interface cleanup
+
+  Revision 1.48  2004/10/12 15:22:23  michael
   + Fixed sleep: file needs to be closed again
 
   Revision 1.47  2004/10/10 10:28:34  michael

+ 23 - 500
rtl/unix/unix.pp

@@ -16,10 +16,13 @@
 Unit Unix;
 Interface
 
-Uses UnixUtil,BaseUnix,UnixType;
+Uses BaseUnix,UnixType;
 
 {$i aliasptp.inc}
 
+type
+   pathstr = string[255];
+
 {$define POSIXWORKAROUND}
 { Get Types and Constants }
 {$i sysconst.inc}
@@ -37,6 +40,10 @@ Uses UnixUtil,BaseUnix,UnixType;
 {$I signal.inc}
 {$i ostypes.inc}
 
+var
+  Tzseconds : Longint;
+
+
 {********************
       File
 ********************}
@@ -54,13 +61,6 @@ Const
 Type
   Tpipe = baseunix.tfildes;	// compability.
 
-  pglob = ^tglob;
-  tglob = record
-    name : pchar;
-    next : pglob;
-  end;
-
-
 {******************************************************************************
                             Procedure/Functions
 ******************************************************************************}
@@ -79,40 +79,10 @@ procedure GetLocalTimezone(timer:cint);
 procedure ReadTimezoneFile(fn:string);
 function  GetTimezoneFile:string;
 
-Function  GetEpochTime: cint;
-procedure GetTime     (var hour,min,sec,msec,usec:word);
-procedure GetTime     (var hour,min,sec,sec100:word);
-procedure GetTime     (var hour,min,sec:word);
-Procedure GetDate     (Var Year,Month,Day:Word);
-Procedure GetDateTime (Var Year,Month,Day,hour,minute,second:Word);
-function  SetTime     (Hour,Min,Sec:word) : Boolean;
-function  SetDate     (Year,Month,Day:Word) : Boolean;
-function  SetDateTime (Year,Month,Day,hour,minute,second:Word) : Boolean;
-
 {**************************
      Process Handling
 ***************************}
 
-
-function CreateShellArgV (const prog:string):ppchar;
-function CreateShellArgV (const prog:Ansistring):ppchar;
-procedure FreeShellArgV(p:ppchar);
-
-// These are superceded by the fpExec functions that are more pascallike
-// and have less limitations. However I'll leave them in for a while, to
-// not frustrate things too much
-// but they might not make it to 2.0
-Function Execv   (const path:pathstr;args:ppchar):cint;          {$ifndef ver1_0}deprecated; {$endif}
-Function Execv   (const path: AnsiString;args:ppchar):cint;  	 {$ifndef ver1_0}deprecated; {$endif}
-Function Execvp  (Path: Pathstr;Args:ppchar;Ep:ppchar):cint;     {$ifndef ver1_0}deprecated; {$endif}
-Function Execvp  (Path: AnsiString; Args:ppchar;Ep:ppchar):cint; {$ifndef ver1_0}deprecated; {$endif}
-Function Execl   (const Todo: String):cint;			 {$ifndef ver1_0}deprecated; {$endif}
-Function Execl   (const Todo: Ansistring):cint;			 {$ifndef ver1_0}deprecated; {$endif}
-Function Execle  (Todo: String;Ep:ppchar):cint;			 {$ifndef ver1_0}deprecated; {$endif}           
-Function Execle  (Todo: AnsiString;Ep:ppchar):cint;		 {$ifndef ver1_0}deprecated; {$endif}
-Function Execlp  (Todo: string;Ep:ppchar):cint;			 {$ifndef ver1_0}deprecated; {$endif}
-Function Execlp  (Todo: Ansistring;Ep:ppchar):cint;		 {$ifndef ver1_0}deprecated; {$endif}
-
 //
 // These are much better, in nearly all ways.
 //
@@ -170,8 +140,8 @@ Function AssignPipe  (var pipe_in,pipe_out:file):cint;
 //Function PClose      (Var F:file) : cint;
 Function POpen       (var F:text;const Prog:String;rw:char):cint;
 Function POpen       (var F:file;const Prog:String;rw:char):cint;
-function AssignStream(Var StreamIn,Streamout:text;Const Prog:String) : cint;
-function AssignStream(var StreamIn, StreamOut, StreamErr: Text; const prog: String): cint;
+Function AssignStream(Var StreamIn,Streamout:text;Const Prog:ansiString;const args : array of ansistring) : cint;
+Function AssignStream(Var StreamIn,Streamout,streamerr:text;Const Prog:ansiString;const args : array of ansistring) : cint;
 
 Function  GetDomainName:String;
 Function  GetHostName:String;
@@ -224,13 +194,11 @@ Type
 		           CurrentDirectoryFirst,
 	                   CurrentDirectoryLast);
 
-Function  FExpand  (Const Path: PathStr):PathStr;
-Function  FSearch  (const path:pathstr;dirlist:string):pathstr;
+//Function  FExpand  (Const Path: PathStr):PathStr;
+//Function  FSearch  (const path:pathstr;dirlist:string):pathstr;
 
 Function  FSearch  (const path:AnsiString;dirlist:Ansistring;CurrentDirStrategy:TFSearchOption):AnsiString;
 Function  FSearch  (const path:AnsiString;dirlist:AnsiString):AnsiString;
-Function  Glob     (Const path:pathstr):pglob;
-Procedure Globfree (var p:pglob);
 
 procedure SigRaise (sig:integer);
 
@@ -249,7 +217,6 @@ const clib = 'c';
 
 Implementation
 
-
 Uses Strings{$ifndef FPC_USE_LIBC},Syscall{$endif};
 
 {$i unxovl.inc}
@@ -312,215 +279,6 @@ begin
    end;
 end;
 
-
-function InternalCreateShellArgV(cmd:pChar; len:cint):ppchar;
-{
-  Create an argv which executes a command in a shell using /bin/sh -c
-}
-const   Shell   = '/bin/sh'#0'-c'#0;
-var
-  pp,p : ppchar;
-//  temp : string; !! Never pass a local var back!!
-begin
-  getmem(pp,4*4);
-  p:=pp;
-  p^:=@Shell[1];
-  inc(p);
-  p^:=@Shell[9];
-  inc(p);
-  getmem(p^,len+1);
-  move(cmd^,p^^,len);
-  pchar(p^)[len]:=#0;
-  inc(p);
-  p^:=Nil;
-  InternalCreateShellArgV:=pp;
-end;
-
-function CreateShellArgV(const prog:string):ppchar;
-begin
-  CreateShellArgV:=InternalCreateShellArgV(@prog[1],length(prog));
-end;
-
-function CreateShellArgV(const prog:Ansistring):ppchar;
-{
-  Create an argv which executes a command in a shell using /bin/sh -c
-  using a AnsiString;
-}
-begin
-  CreateShellArgV:=InternalCreateShellArgV(@prog[1],length(prog)); // if ppc works like delphi this also work when @prog[1] is invalid (len=0)
-end;
-
-procedure FreeShellArgV(p:ppchar);
-begin
-  if (p<>nil) then begin
-    freemem(p[2]);
-    freemem(p);
-   end;
-end;
-
-Function Execv(const path: AnsiString;args:ppchar):cint;
-{
-  Overloaded ansistring version.
-}
-begin
-  Execv:=fpExecVe(Path,Args,envp);
-end;
-
-Function Execvp(Path: AnsiString; Args:ppchar;Ep:ppchar):cint;
-{
-  Overloaded ansistring version
-}
-var
-  thepath : Ansistring;
-begin
-  if path[1]<>'/' then
-   begin
-     Thepath:=strpas(fpgetenv('PATH'));
-     if thepath='' then
-      thepath:='.';
-     Path:=FSearch(path,thepath)
-   end
-  else
-   Path:='';
-  if Path='' then
-   Begin
-     fpsetErrno(ESysEnoEnt);
-     Exit(-1);
-   end
-  else
-   Execvp:=fpExecve(Path,args,ep);
-end;
-
-Function Execv(const path:pathstr;args:ppchar):cint;
-{
-  Replaces the current program by the program specified in path,
-  arguments in args are passed to Execve.
-  the current environment is passed on.
-}
-begin
-  Execv:=fpExecve(path,args,envp);
-end;
-
-Function Execvp(Path:Pathstr;Args:ppchar;Ep:ppchar):cint;
-{
-  This does the same as Execve, only it searches the PATH environment
-  for the place of the Executable, except when Path starts with a slash.
-  if the PATH environment variable is unavailable, the path is set to '.'
-}
-var
-  thepath : string;
-begin
-  if path[1]<>'/' then
-   begin
-     Thepath:=strpas(fpgetenv('PATH'));
-     if thepath='' then
-      thepath:='.';
-     Path:=FSearch(path,thepath)
-   end
-  else
-   Path:='';
-  if Path='' then
-   Begin
-     fpsetErrno(ESysEnoEnt);
-     Exit(-1);
-   end
-  else
-   execvp:=fpExecve(Path,args,ep);
-end;
-
-Function Execle(Todo:string;Ep:ppchar):cint;
-{
-  This procedure takes the string 'Todo', parses it for command and
-  command options, and Executes the command with the given options.
-  The string 'Todo' shoud be of the form 'command options', options
-  separated by commas.
-  the PATH environment is not searched for 'command'.
-  The specified environment(in 'ep') is passed on to command
-}
-var
-  p : ppchar;
-begin
-  p:=StringToPPChar(ToDo,0);
-  if (p=nil) or (p^=nil) then
-   Begin
-     fpsetErrno(ESysEnoEnt);
-     Exit(-1);
-   end
-  else
-    execle:=fpExecVE(p^,p,EP);
-end;
-
-function Execle(Todo:AnsiString;Ep:ppchar):cint;
-{
-  This procedure takes the string 'Todo', parses it for command and
-  command options, and Executes the command with the given options.
-  The string 'Todo' shoud be of the form 'command options', options
-  separated by commas.
-  the PATH environment is not searched for 'command'.
-  The specified environment(in 'ep') is passed on to command
-}
-var
-  p : ppchar;
-begin
-  p:=StringToPPChar(ToDo,0);
-  if (p=nil) or (p^=nil) then
-   Begin
-     fpsetErrno(ESysEnoEnt);
-     Exit(-1);
-   end;
-  ExecLe:=fpExecVE(p^,p,EP);
-end;
-
-Function Execl(const Todo:string):cint;
-{
-  This procedure takes the string 'Todo', parses it for command and
-  command options, and Executes the command with the given options.
-  The string 'Todo' shoud be of the form 'command options', options
-  separated by commas.
-  the PATH environment is not searched for 'command'.
-  The current environment is passed on to command
-}
-begin
-  Execl:=ExecLE(ToDo,EnvP);
-end;
-
-Function Execlp(Todo:string;Ep:ppchar):cint;
-{
-  This procedure takes the string 'Todo', parses it for command and
-  command options, and Executes the command with the given options.
-  The string 'Todo' shoud be of the form 'command options', options
-  separated by commas.
-  the PATH environment is searched for 'command'.
-  The specified environment (in 'ep') is passed on to command
-}
-var
-  p : ppchar;
-begin
-  p:=StringToPPchar(todo,0);
-  if (p=nil) or (p^=nil) then
-   Begin
-     fpsetErrno(ESysEnoEnt);
-     Exit(-1);
-   end;
-  Execlp:=ExecVP(StrPas(p^),p,EP);
-end;
-
-Function Execlp(Todo: Ansistring;Ep:ppchar):cint;
-{
-  Overloaded ansistring version.
-}
-var
-  p : ppchar;
-begin
-  p:=StringToPPchar(todo,0);
-  if (p=nil) or (p^=nil) then
-   Begin
-     fpsetErrno(ESysEnoEnt);
-     Exit(-1);
-   end;
-  execlp:=ExecVP(StrPas(p^),p,EP);
-end;
-
 function intFpExecVEMaybeP (Const PathName:AnsiString;Args,MyEnv:ppchar;SearchPath:Boolean):cint;
 // does an ExecVE, but still has to handle P
 // execv variants call this directly, execl variants indirectly via
@@ -805,130 +563,6 @@ begin
   W_STOPCODE:=(Signal shl 8) or $7F;
 end;
 
-{******************************************************************************
-                       Date and Time related calls
-******************************************************************************}
-
-Function GetEpochTime: cint;
-{
-  Get the number of seconds since 00:00, January 1 1970, GMT
-  the time NOT corrected any way
-}
-begin
-  GetEpochTime:=fptime;
-end;
-
-procedure GetTime(var hour,min,sec,msec,usec:word);
-{
-  Gets the current time, adjusted to local time
-}
-var
-  year,day,month:Word;
-  tz:timeval;
-begin
-  fpgettimeofday(@tz,nil);
-  EpochToLocal(tz.tv_sec,year,month,day,hour,min,sec);
-  msec:=tz.tv_usec div 1000;
-  usec:=tz.tv_usec mod 1000;
-end;
-
-procedure GetTime(var hour,min,sec,sec100:word);
-{
-  Gets the current time, adjusted to local time
-}
-var
-  usec : word;
-begin
-  gettime(hour,min,sec,sec100,usec);
-  sec100:=sec100 div 10;
-end;
-
-Procedure GetTime(Var Hour,Min,Sec:Word);
-{
-  Gets the current time, adjusted to local time
-}
-var
-  msec,usec : Word;
-Begin
-  gettime(hour,min,sec,msec,usec);
-End;
-
-Procedure GetDate(Var Year,Month,Day:Word);
-{
-  Gets the current date, adjusted to local time
-}
-var
-  hour,minute,second : word;
-Begin
-  EpochToLocal(fptime,year,month,day,hour,minute,second);
-End;
-
-Procedure GetDateTime(Var Year,Month,Day,hour,minute,second:Word);
-{
-  Gets the current date, adjusted to local time
-}
-Begin
-  EpochToLocal(fptime,year,month,day,hour,minute,second);
-End;
-
-{$ifndef BSD}			// this can be done nicer, but I still have
-				// to think about what to do with this func.
-	
-{$ifdef linux}
-{$ifdef FPC_USE_LIBC}
-function intstime (t:ptime_t):cint; external name 'stime';
-{$endif}
-
-Function stime (t : cint) : boolean;
-{$ifndef FPC_USE_LIBC}
-  {$ifdef cpux86_64}  
-  var
-    tv : ttimeval;
-  {$endif}
-{$endif}     
-begin
-  {$ifdef FPC_USE_LIBC}
-   stime:=intstime(@t)=0;
-  {$else}
-    {$ifdef cpux86_64}  
-      tv.tv_sec:=t;
-      tv.tv_usec:=0;
-      stime:=do_SysCall(Syscall_nr_settimeofday,TSysParam(@tv),0)=0;
-    {$else}
-      stime:=do_SysCall(Syscall_nr_stime,TSysParam(@t))=0;
-    {$endif}  
-  {$endif}
-end;
-{$endif}
-{$endif}
-
-{$ifdef BSD}
-Function stime (t : cint) : Boolean;
-begin
-end;
-{$endif}
-
-Function SetTime(Hour,Min,Sec:word) : boolean;
-var
-  Year, Month, Day : Word;
-begin
-  GetDate (Year, Month, Day);
-  SetTime:=stime ( LocalToEpoch ( Year, Month, Day, Hour, Min, Sec ) );
-end;
-
-Function SetDate(Year,Month,Day:Word) : boolean;
-var
-  Hour, Minute, Second, Sec100 : Word;
-begin
-  GetTime ( Hour, Minute, Second, Sec100 );
-  SetDate:=stime ( LocalToEpoch ( Year, Month, Day, Hour, Minute, Second ) );
-end;
-
-Function SetDateTime(Year,Month,Day,hour,minute,second:Word) : Boolean;
-
-begin
-  SetDateTime:=stime ( LocalToEpoch ( Year, Month, Day, Hour, Minute, Second ) );
-end;
 
 { Include timezone handling routines which use /usr/share/timezone info }
 {$i timezone.inc}
@@ -937,16 +571,6 @@ end;
                            FileSystem calls
 ******************************************************************************}
 
-Function Execl(const Todo:Ansistring):cint;
-
-{
-  Overloaded AnsiString Version of ExecL.
-}
-
-begin
-  Execl:=ExecLE(ToDo,EnvP);
-end;
-
 Function fpFlock (var T : text;mode : cint) : cint;
 begin
   fpFlock:=fpFlock(TextRec(T).Handle,mode);
@@ -1314,7 +938,7 @@ begin
  POpen:=0;
 end;
 
-Function AssignStream(Var StreamIn,Streamout:text;Const Prog:String) : cint;
+Function AssignStream(Var StreamIn,Streamout:text;Const Prog:ansiString;const args : array of ansistring) : cint;
 {
   Starts the program in 'Prog' and makes its input and output the
   other end of two pipes, which are the stdin and stdout of a program
@@ -1358,7 +982,7 @@ begin
      If fpdup2(pipo,output)=-1 Then
        halt (127);
      close(pipo);
-     Execl(Prog);
+     fpExecl(Prog,args);
      halt(127);
    end
   else
@@ -1378,7 +1002,8 @@ begin
    end;
 end;
 
-function AssignStream(var StreamIn, StreamOut, StreamErr: Text; const prog: String):cint;
+Function AssignStream(Var StreamIn,Streamout,streamerr:text;Const Prog:ansiString;const args : array of ansistring) : cint;
+
 {
   Starts the program in 'prog' and makes its input, output and error output the
   other end of three pipes, which are the stdin, stdout and stderr of a program
@@ -1448,7 +1073,7 @@ begin
      Halt(127);
     Close(PipeErr);
     // Execute program
-    Execl(Prog);
+    fpExecl(Prog,args);
     Halt(127);
   end else begin
     // *** We are in the parent ***
@@ -1545,26 +1170,6 @@ end;
 ******************************************************************************}
 
 {
-Function Octal(l:cint):cint;
-{
-  Convert an octal specified number to decimal;
-}
-var
-  octnr,
-  oct : cint;
-begin
-  octnr:=0;
-  oct:=0;
-  while (l>0) do
-   begin
-     oct:=oct or ((l mod 10) shl octnr);
-     l:=l div 10;
-     inc(octnr,3);
-   end;
-  Octal:=oct;
-end;
-}
-
 {$DEFINE FPC_FEXPAND_TILDE} { Tilde is expanded to home }
 {$DEFINE FPC_FEXPAND_GETENVPCHAR} { GetEnv result is a PChar }
 
@@ -1573,6 +1178,7 @@ end;
 {$UNDEF FPC_FEXPAND_GETENVPCHAR}
 {$UNDEF FPC_FEXPAND_TILDE}
 
+{}
 Function FSearch(const path:pathstr;dirlist:string):pathstr;
 {
   Searches for a file 'path' in the list of direcories in 'dirlist'.
@@ -1616,7 +1222,7 @@ Begin
      FSearch:=NewDir;
    End;
 End;
-
+}
 Function FSearch(const path:AnsiString;dirlist:Ansistring;CurrentDirStrategy:TFSearchOption):AnsiString;
 {
   Searches for a file 'path' in the list of direcories in 'dirlist'.
@@ -1678,92 +1284,6 @@ Begin
  FSearch:=FSearch(path,dirlist,CurrentDirectoryFirst);
 End;
 
-Procedure Globfree(var p : pglob);
-{
-  Release memory occupied by pglob structure, and names in it.
-  sets p to nil.
-}
-var
-  temp : pglob;
-begin
-  while assigned(p) do
-   begin
-     temp:=p^.next;
-     if assigned(p^.name) then
-      freemem(p^.name);
-     dispose(p);
-     p:=temp;
-   end;
-end;
-
-
-Function Glob(Const path:pathstr):pglob;
-{
-  Fills a tglob structure with entries matching path,
-  and returns a pointer to it. Returns nil on error,
-  linuxerror is set accordingly.
-}
-var
-  temp,
-  temp2   : string[255];
-  thedir  : pdir;
-  buffer  : pdirent;
-  root,
-  current : pglob;
-begin
-{ Get directory }
-  temp:=dirname(path);
-  if temp='' then
-   temp:='.';
-  temp:=temp+#0;
-  thedir:=fpopendir(@temp[1]);
-  if thedir=nil then
-    exit(nil);
-  temp:=basename(path,''); { get the pattern }
-  if thedir^.dd_fd<0 then
-     exit(nil);
-{get the entries}
-  root:=nil;
-  current:=nil;
-  repeat
-    buffer:=fpreaddir(thedir^);
-    if buffer=nil then
-     break;
-    temp2:=strpas(@(buffer^.d_name[0]));
-    if fnmatch(temp,temp2) then
-     begin
-       if root=nil then
-        begin
-          new(root);
-          current:=root;
-        end
-       else
-        begin
-          new(current^.next);
-          current:=current^.next;
-        end;
-       if current=nil then
-        begin
-           fpseterrno(ESysENOMEM);
-          globfree(root);
-          break;
-        end;
-       current^.next:=nil;
-       getmem(current^.name,length(temp2)+1);
-       if current^.name=nil then
-        begin
-          fpseterrno(ESysENOMEM);
-          globfree(root);
-          break;
-        end;
-       move(buffer^.d_name[0],current^.name^,length(temp2)+1);
-     end;
-  until false;
-  fpclosedir(thedir^);
-  glob:=root;
-end;
-
-
 {--------------------------------
       Stat.Mode Macro's
 --------------------------------}
@@ -1777,7 +1297,10 @@ End.
 
 {
   $Log$
-  Revision 1.74  2004-07-18 14:54:42  jonas
+  Revision 1.75  2004-10-30 20:55:54  marco
+   * unix interface cleanup
+
+  Revision 1.74  2004/07/18 14:54:42  jonas
     * fixed BSD getdomainname for FPC_USE_LIBC
 
   Revision 1.73  2004/07/18 11:27:54  marco