Bladeren bron

- disabled nanosleep for darwin for now
+ getcwd for darwin

Jonas Maebe 22 jaren geleden
bovenliggende
commit
0185f7684a
2 gewijzigde bestanden met toevoegingen van 356 en 2 verwijderingen
  1. 13 2
      rtl/bsd/ossysc.inc
  2. 343 0
      rtl/darwin/getcwd.inc

+ 13 - 2
rtl/bsd/ossysc.inc

@@ -517,11 +517,15 @@ end;
 
 
 Function FpNanoSleep(const req : timespec;var rem : timespec) : longint; [public, alias : 'FPC_SYSC_NANOSLEEP'];
 Function FpNanoSleep(const req : timespec;var rem : timespec) : longint; [public, alias : 'FPC_SYSC_NANOSLEEP'];
 begin
 begin
+{$ifndef darwin}
   FpNanoSleep:=Do_SysCall(syscall_nr_nanosleep,TSysParam(@req),TSysParam(@rem));
   FpNanoSleep:=Do_SysCall(syscall_nr_nanosleep,TSysParam(@req),TSysParam(@rem));
+{$else not darwin}
+{$warning: TODO: nanosleep!!!}
+{$endif not darwin}
 end;
 end;
 
 
 function Fpgetcwd(pt:pchar; _size:size_t):pchar;[public, alias :'FPC_SYSC_GETCWD'];
 function Fpgetcwd(pt:pchar; _size:size_t):pchar;[public, alias :'FPC_SYSC_GETCWD'];
-
+{$ifndef darwin}
 const intpathmax = 1024-4;	// didn't use POSIX data in libc
 const intpathmax = 1024-4;	// didn't use POSIX data in libc
 				// implementation.
 				// implementation.
 var ept,bpt : pchar;
 var ept,bpt : pchar;
@@ -570,12 +574,19 @@ begin
            End;
            End;
  Fpgetcwd:=pt;
  Fpgetcwd:=pt;
 end;
 end;
+{$else not darwin}
+{$i getcwd.inc}
+{$endif darwin}
 
 
 {$endif}
 {$endif}
 
 
 {
 {
  $Log$
  $Log$
- Revision 1.1  2003-01-05 19:01:28  marco
+ Revision 1.2  2003-05-26 21:29:16  jonas
+   - disabled nanosleep for darwin for now
+   + getcwd for darwin
+
+ Revision 1.1  2003/01/05 19:01:28  marco
   * FreeBSD compiles now with baseunix mods.
   * FreeBSD compiles now with baseunix mods.
 
 
  Revision 1.9  2002/11/13 18:15:08  marco
  Revision 1.9  2002/11/13 18:15:08  marco

+ 343 - 0
rtl/darwin/getcwd.inc

@@ -0,0 +1,343 @@
+{
+  $Id$
+}
+{*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License").  You may not use this file except in compliance with the
+ * License.  Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
+ * 
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ *
+ *
+ * Copyright (c) 1989, 1991, 1993
+ *  The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *  This product includes software developed by the University of
+ *  California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *}
+
+const
+  MAXPATHLEN = 1024;
+  MAXNAMLEN = 255;
+
+function getcwd_physical(pt: pchar; size: size_t): pchar;
+var
+  dp: pdirent;
+  dir: pdir;
+  dev: dev_t;
+  ino: ino_t;
+  first: longint;
+  bpt, bup: pchar;
+  s: stat;
+  root_dev: dev_t;
+  root_ino: ino_t;
+  ptsize, upsize: size_t;
+  save_errno: longint;
+  ept, eup, up: pchar;
+  len, off: size_t;
+
+  err, notfound: boolean;
+
+  {*
+   * If no buffer specified by the user, allocate one as necessary.
+   * If a buffer is specified, the size has to be non-zero.  The path
+   * is built from the end of the buffer backwards.
+   *}
+begin
+  err := false;
+  notfound := false;
+  if (pt <> nil) then
+    begin
+      ptsize := 0;
+      if (size = 0) then
+        begin
+          errno := ESysEINVAL;
+          getcwd_physical := nil;
+          exit;
+        end;
+      ept := pt + size;
+    end
+  else
+    begin
+      ptsize := 1024;
+      getmem(pt,ptsize);
+      ept := pt + ptsize;
+    end;
+  bpt := ept - 1;
+  bpt^ := #0;
+
+  {*
+   * Allocate bytes (1024 - malloc space) for the string of "../"'s.
+   * Should always be enough (it's 340 levels).  If it's not, allocate
+   * as necessary.  Special case the first stat, it's ".", not "..".
+   *}
+  upsize := 1024;
+  getmem(up,1024);
+  eup := up + MAXPATHLEN;
+  bup := up;
+  up[0] := '.';
+  up[1] := #0;
+
+  { Save root values, so know when to stop. }
+  if (Fpstat('/', s) = 0) THEN
+    begin
+      root_dev := s.st_dev;
+      root_ino := s.st_ino;
+    
+      errno := 0;      { XXX readdir has no error return. }
+
+      first := 1;
+      repeat
+        { Stat the current level. }
+        if (fplstat(up, s) <> 0) then
+          err := true
+        else
+          begin
+            { Save current node values. }
+            ino := s.st_ino;
+            dev := s.st_dev;
+        
+            { Check for reaching root. }
+            if ((root_dev = dev) and (root_ino = ino)) then
+              begin
+                dec(bpt);
+                bpt^ := '/';
+                {*
+                * It's unclear that it's a requirement to copy the
+                * path to the beginning of the buffer, but it's always
+                * been that way and stuff would probably break'.
+                *}
+                move(bpt^, pt^, ept - bpt);
+                freemem(up);
+                getcwd_physical := pt;
+                exit;
+              end;
+        
+            {
+            * Build pointer to the parent directory, allocating memory
+            * as necessary.  Max length is 3 for "../", the largest
+            * possible component name, plus a trailing NULL.
+            *}
+            if (bup + 3  + MAXNAMLEN + 1 >= eup) then
+              begin
+                upsize := upsize*2;
+                reallocmem(up,upsize);
+                bup := up;
+                eup := up + upsize;
+              end;
+
+            bup^ := '.';
+            inc(bup);
+            bup^ := '.';
+            inc(bup);
+            bup^ := #0;
+
+            {* Open and stat parent directory. *}
+            dir := Fpopendir(up);
+            if (pdir <> nil) then
+              begin
+                if (fpfstat(dir^.dd_fd,s) <> 0) then
+                  err := true;
+              end
+            else
+              err := true;
+            
+            if not err then
+              begin
+                { Add trailing slash for next directory. }
+                bup^ := '/';
+                inc(bup);
+            
+                {*
+                * If it's a mount point, have to stat each element because
+                * the inode number in the directory is for the entry in the
+                * parent directory, not the inode number of the mounted file.
+                *'}
+                save_errno := 0;
+                if (s.st_dev = dev) then
+                  begin
+                    repeat
+                      dp := Fpreaddir(dir);
+                      notfound := dp = nil;
+                    until notfound or
+                          (dp^.d_fileno = ino);
+                  end
+                else
+                  begin
+                    repeat
+                      dp := Fpreaddir(dir);
+                      if (dp = nil) then
+                        notfound := true
+                      else
+                        begin
+                          if (dp^.d_name[0] = '.') and
+                             ((dp^.d_name[1] = #0) or
+                              ((dp^.d_name[1] = '.') and
+                               (dp^.d_name[2] = #0))) then
+                            continue;
+                          move(dp^.d_name, bup^, dp^.d_namlen + 1);
+
+                          { Save the first error for later. }
+                          if (fplstat(up,s) <> 0) then
+                            begin
+                              if (save_errno = 0) then
+                                save_errno := errno;
+                              errno := 0;
+                              continue;
+                            end;
+                        end;
+                    until notfound or
+                          ((s.st_dev = dev) and
+                           (s.st_ino = ino));
+                  end;
+            
+                {*
+                * Check for length of the current name, preceding slash,
+                * leading slash.
+                *}
+                if not (notfound) then
+                  begin
+                    // was: (first ? 1 : 2), first can only be 1 or 0
+                    if (bpt - pt <= dp^.d_namlen + ((first xor 1) + 1)) then
+                      begin
+                        if ( ptsize <> 0) then
+                          begin
+                            errno := ESysERANGE;
+                            err := true;
+                          end
+                        else
+                          begin
+                            off := bpt - pt;
+                            len := ept - bpt;
+                            ptsize := ptsize *2;
+                            reallocmem(pt,ptsize);
+                            bpt := pt + off;
+                            ept := pt + ptsize;
+                            move(bpt^, (ept - len)^, len);
+                            bpt := ept - len;
+                          end;
+                      end;
+                    if (first = 0) then
+                      begin
+                        dec(bpt);
+                        bpt^ := '/';
+                      end;
+                    dec(bpt,dp^.d_namlen);
+                    move(dp^.d_name, bpt^, dp^.d_namlen);
+                    Fpclosedir(dir);
+                
+                    { Truncate any file name. }
+                    bup^ := #0;
+                    first := 0;
+                  end;
+              end;
+          end;
+      until err or notfound;
+    
+    if (notfound) then
+      begin
+        {*
+        * If readdir set errno, use it, not any saved error; otherwise,
+        * didn't find the current directory in its parent directory, set
+        * errno to ENOENT.'
+        *}
+        if (errno = 0) then
+          if save_errno <> 0 then
+            errno := save_errno
+          else
+            errno := ESysENOENT;
+      end;
+  end;
+  if (err) then
+    begin
+      if (ptsize <> 0) then
+        freemem(pt);
+      freemem(up);
+      getcwd_physical := nil;
+    end;
+end;
+
+
+function getcwd(pt: pchar; size: size_t): pchar;
+var
+  pwd: pchar;
+  pwdlen: size_t;
+  dev: dev_t;
+  ino: ino_t;
+  s: stat;
+begin
+(*
+  { Check $PWD -- if it's right, it's fast. }
+  if ((pwd = getenv("PWD")) != NULL && pwd[0] == '/' && stat(pwd, &s) != -1) {
+    dev = s.st_dev;
+    ino = s.st_ino;
+    if (stat(".", &s) != -1 && dev == s.st_dev && ino == s.st_ino) {
+      pwdlen = strlen(pwd);
+      if (pt) {
+        if (!size) {
+          errno = EINVAL;
+          return (NULL);
+        }
+        if (pwdlen + 1 > size) {
+          errno = ERANGE;
+          return (NULL);
+        }
+      } else if ((pt = malloc(pwdlen + 1)) == NULL) {
+        errno = ENOMEM;
+        return (NULL);
+      }
+      memmove(pt, pwd, pwdlen);
+      pt[pwdlen] = '\0';
+      return (pt);
+    }
+  }
+*)
+  getcwd := (getcwd_physical(pt, size));
+end;
+
+{
+  $Log$
+  Revision 1.1  2003-05-26 21:29:16  jonas
+    - disabled nanosleep for darwin for now
+    + getcwd for darwin
+
+}