|
@@ -1,343 +0,0 @@
|
|
|
-{
|
|
|
- $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
|
|
|
-
|
|
|
-}
|