]> Cypherpunks repositories - gostls13.git/commitdiff
missing darwin files; g4 nothave.
authorRuss Cox <rsc@golang.org>
Thu, 4 Jun 2009 20:33:57 +0000 (13:33 -0700)
committerRuss Cox <rsc@golang.org>
Thu, 4 Jun 2009 20:33:57 +0000 (13:33 -0700)
R=r
DELTA=115  (115 added, 0 deleted, 0 changed)
OCL=29884
CL=29888

src/lib/os/dir_darwin_386.go [new file with mode: 0644]
src/lib/os/stat_darwin_386.go [new file with mode: 0644]

diff --git a/src/lib/os/dir_darwin_386.go b/src/lib/os/dir_darwin_386.go
new file mode 100644 (file)
index 0000000..2803ece
--- /dev/null
@@ -0,0 +1,76 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package os
+
+import (
+       "os";
+       "syscall";
+       "unsafe";
+)
+
+const (
+       blockSize = 4096        // TODO(r): use statfs
+)
+
+// Negative count means read until EOF.
+func readdirnames(file *File, count int) (names []string, err Error) {
+       // If this file has no dirinfo, create one.
+       if file.dirinfo == nil {
+               file.dirinfo = new(dirInfo);
+               // The buffer must be at least a block long.
+               // TODO(r): use fstatfs to find fs block size.
+               file.dirinfo.buf = make([]byte, blockSize);
+       }
+       d := file.dirinfo;
+       size := count;
+       if size < 0 {
+               size = 100
+       }
+       names = make([]string, 0, size);        // Empty with room to grow.
+       for count != 0 {
+               // Refill the buffer if necessary
+               if d.bufp >= d.nbuf {
+                       var errno int;
+                       d.bufp = 0;
+                       // Final argument is (basep *uintptr) and the syscall doesn't take nil.
+                       d.nbuf, errno = syscall.Getdirentries(file.fd, d.buf, new(uintptr));
+                       if errno != 0 {
+                               d.nbuf = 0;
+                               return names, ErrnoToError(errno)
+                       }
+                       if d.nbuf == 0 {
+                               break   // EOF
+                       }
+               }
+               // Drain the buffer
+               for count != 0 && d.bufp < d.nbuf {
+                       dirent := (*syscall.Dirent)(unsafe.Pointer(&d.buf[d.bufp]));
+                       if dirent.Reclen == 0 {
+                               d.bufp = d.nbuf;
+                               break
+                       }
+                       d.bufp += int(dirent.Reclen);
+                       if dirent.Ino == 0 {    // File absent in directory.
+                               continue
+                       }
+                       bytes := (*[len(dirent.Name)]byte)(unsafe.Pointer(&dirent.Name[0]));
+                       var name = string(bytes[0:dirent.Namlen]);
+                       if name == "." || name == ".." {        // Useless names
+                               continue
+                       }
+                       count--;
+                       if len(names) == cap(names) {
+                               nnames := make([]string, len(names), 2*len(names));
+                               for i := 0; i < len(names); i++ {
+                                       nnames[i] = names[i]
+                               }
+                               names = nnames;
+                       }
+                       names = names[0:len(names)+1];
+                       names[len(names)-1] = name;
+               }
+       }
+       return names, nil
+}
diff --git a/src/lib/os/stat_darwin_386.go b/src/lib/os/stat_darwin_386.go
new file mode 100644 (file)
index 0000000..a6d7b78
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// 386, Darwin
+
+package os
+
+import syscall "syscall"
+import os "os"
+
+func isSymlink(stat *syscall.Stat_t) bool {
+       return stat.Mode & syscall.S_IFMT == syscall.S_IFLNK
+}
+
+func dirFromStat(name string, dir *Dir, lstat, stat *syscall.Stat_t) *Dir {
+       dir.Dev = uint64(stat.Dev);
+       dir.Ino = stat.Ino;
+       dir.Nlink = uint64(stat.Nlink);
+       dir.Mode = uint32(stat.Mode);
+       dir.Uid = stat.Uid;
+       dir.Gid = stat.Gid;
+       dir.Rdev = uint64(stat.Rdev);
+       dir.Size = uint64(stat.Size);
+       dir.Blksize = uint64(stat.Blksize);
+       dir.Blocks = uint64(stat.Blocks);
+       dir.Atime_ns = uint64(syscall.TimespecToNsec(stat.Atimespec));
+       dir.Mtime_ns = uint64(syscall.TimespecToNsec(stat.Mtimespec));
+       dir.Ctime_ns = uint64(syscall.TimespecToNsec(stat.Ctimespec));
+       for i := len(name) - 1; i >= 0; i-- {
+               if name[i] == '/' {
+                       name = name[i+1:len(name)];
+                       break;
+               }
+       }
+       dir.Name = name;
+       if isSymlink(lstat) && !isSymlink(stat) {
+               dir.FollowedSymlink = true;
+       }
+       return dir;
+}