func TestStat(t *testing.T) { mnt, err := fstestutil.MountedT(t, &NzbFS{"testdb"}) if err != nil { t.Error(err) } defer mnt.Close() var stat syscall.Stat_t err = syscall.Lstat(path.Join(mnt.Dir, "hello"), &stat) if err != nil { t.Error(err) } if (stat.Mode & syscall.S_IFREG) == 0 { t.Error("hello file was not reported as a file") } err = syscall.Lstat(path.Join(mnt.Dir, "noexist"), &stat) if err == nil { t.Error("Should have failed on nonexistant file") } err = syscall.Lstat(path.Join(mnt.Dir, "foo"), &stat) if err != nil { t.Error(err) } if (stat.Mode & syscall.S_IFDIR) == 0 { t.Error("foo directory was not reported as a directory") } }
// Deal correctly with hard links implied by matching client inode // numbers. func TestLinkExisting(t *testing.T) { tc := NewTestCase(t) defer tc.Cleanup() c := RandomData(5) err := ioutil.WriteFile(tc.orig+"/file1", c, 0644) CheckSuccess(err) err = os.Link(tc.orig+"/file1", tc.orig+"/file2") CheckSuccess(err) var s1, s2 syscall.Stat_t err = syscall.Lstat(tc.mnt+"/file1", &s1) CheckSuccess(err) err = syscall.Lstat(tc.mnt+"/file2", &s2) CheckSuccess(err) if s1.Ino != s2.Ino { t.Errorf("linked files should have identical inodes %v %v", s1.Ino, s2.Ino) } back, err := ioutil.ReadFile(tc.mnt + "/file1") CheckSuccess(err) CompareSlices(t, back, c) }
// Deal correctly with hard links implied by matching client inode // numbers. func TestLinkForget(t *testing.T) { tc := NewTestCase(t) defer tc.Cleanup() c := "hello" err := ioutil.WriteFile(tc.orig+"/file1", []byte(c), 0644) if err != nil { t.Fatalf("WriteFile failed: %v", err) } err = os.Link(tc.orig+"/file1", tc.orig+"/file2") if err != nil { t.Fatalf("Link failed: %v", err) } var s1, s2 syscall.Stat_t err = syscall.Lstat(tc.mnt+"/file1", &s1) if err != nil { t.Fatalf("Lstat failed: %v", err) } tc.pathFs.ForgetClientInodes() err = syscall.Lstat(tc.mnt+"/file2", &s2) if err != nil { t.Fatalf("Lstat failed: %v", err) } if s1.Ino == s2.Ino { t.Error("After forget, we should not export links") } }
func TestMemUnionFsCopyChmod(t *testing.T) { wd, _, clean := setupMemUfs(t) defer clean() contents := "hello" fn := wd + "/mnt/y" err := ioutil.WriteFile(fn, []byte(contents), 0644) CheckSuccess(err) err = os.Chmod(fn, 0755) CheckSuccess(err) st := syscall.Stat_t{} err = syscall.Lstat(fn, &st) CheckSuccess(err) if st.Mode&0111 == 0 { t.Errorf("1st attr error %o", st.Mode) } time.Sleep(entryTtl * 11 / 10) err = syscall.Lstat(fn, &st) CheckSuccess(err) if st.Mode&0111 == 0 { t.Errorf("uncached attr error %o", st.Mode) } }
func TestMemUnionFsLink(t *testing.T) { wd, _, clean := setupMemUfs(t) defer clean() content := "blabla" fn := wd + "/ro/file" err := ioutil.WriteFile(fn, []byte(content), 0666) CheckSuccess(err) err = os.Link(wd+"/mnt/file", wd+"/mnt/linked") CheckSuccess(err) var st2 syscall.Stat_t err = syscall.Lstat(wd+"/mnt/linked", &st2) CheckSuccess(err) var st1 syscall.Stat_t err = syscall.Lstat(wd+"/mnt/file", &st1) CheckSuccess(err) if st1.Ino != st2.Ino { t.Errorf("inode numbers should be equal for linked files %v, %v", st1.Ino, st2.Ino) } c, err := ioutil.ReadFile(wd + "/mnt/linked") if string(c) != content { t.Errorf("content mismatch got %q want %q", string(c), content) } }
// Deal correctly with hard links implied by matching client inode // numbers. func TestLinkExisting(t *testing.T) { me := NewTestCase(t) defer me.Cleanup() c := "hello" err := ioutil.WriteFile(me.orig+"/file1", []byte(c), 0644) CheckSuccess(err) err = os.Link(me.orig+"/file1", me.orig+"/file2") CheckSuccess(err) var s1, s2 syscall.Stat_t err = syscall.Lstat(me.mnt+"/file1", &s1) CheckSuccess(err) err = syscall.Lstat(me.mnt+"/file2", &s2) CheckSuccess(err) if s1.Ino != s2.Ino { t.Errorf("linked files should have identical inodes %v %v", s1.Ino, s2.Ino) } c1, err := ioutil.ReadFile(me.mnt + "/file1") CheckSuccess(err) if string(c1) != c { t.Errorf("Content mismatch relative to original.") } }
// Deal correctly with hard links implied by matching client inode // numbers. func TestLinkExisting(t *testing.T) { tc := NewTestCase(t) defer tc.Cleanup() c := RandomData(5) err := ioutil.WriteFile(tc.orig+"/file1", c, 0644) if err != nil { t.Fatalf("WriteFile failed: %v", err) } err = os.Link(tc.orig+"/file1", tc.orig+"/file2") if err != nil { t.Fatalf("Link failed: %v", err) } var s1, s2 syscall.Stat_t err = syscall.Lstat(tc.mnt+"/file1", &s1) if err != nil { t.Fatalf("Lstat failed: %v", err) } err = syscall.Lstat(tc.mnt+"/file2", &s2) if err != nil { t.Fatalf("Lstat failed: %v", err) } if s1.Ino != s2.Ino { t.Errorf("linked files should have identical inodes %v %v", s1.Ino, s2.Ino) } back, err := ioutil.ReadFile(tc.mnt + "/file1") if err != nil { t.Fatalf("ReadFile failed: %v", err) } CompareSlices(t, back, c) }
func TestLinkCreate(t *testing.T) { tc := NewTestCase(t) defer tc.Cleanup() content := RandomData(125) err := ioutil.WriteFile(tc.origFile, content, 0700) if err != nil { t.Fatalf("WriteFile failed: %v", err) } err = os.Mkdir(tc.origSubdir, 0777) if err != nil { t.Fatalf("Mkdir failed: %v", err) } // Link. mountSubfile := filepath.Join(tc.mountSubdir, "subfile") err = os.Link(tc.mountFile, mountSubfile) if err != nil { t.Fatalf("Link failed: %v", err) } var subStat, stat syscall.Stat_t err = syscall.Lstat(mountSubfile, &subStat) if err != nil { t.Fatalf("Lstat failed: %v", err) } err = syscall.Lstat(tc.mountFile, &stat) if err != nil { t.Fatalf("Lstat failed: %v", err) } if stat.Nlink != 2 { t.Errorf("Expect 2 links: %v", stat) } if stat.Ino != subStat.Ino { t.Errorf("Link succeeded, but inode numbers different: %v %v", stat.Ino, subStat.Ino) } readback, err := ioutil.ReadFile(mountSubfile) if err != nil { t.Fatalf("ReadFile failed: %v", err) } CompareSlices(t, readback, content) err = os.Remove(tc.mountFile) if err != nil { t.Fatalf("Remove failed: %v", err) } _, err = ioutil.ReadFile(mountSubfile) if err != nil { t.Fatalf("ReadFile failed: %v", err) } }
// Deal correctly with hard links implied by matching client inode // numbers. func TestLinkForget(t *testing.T) { tc := NewTestCase(t) defer tc.Cleanup() c := "hello" tc.WriteFile(tc.orig+"/file1", []byte(c), 0644) err := os.Link(tc.orig+"/file1", tc.orig+"/file2") if err != nil { t.Fatalf("Link failed: %v", err) } for _, fn := range []string{"file1", "file2"} { var s syscall.Stat_t err = syscall.Lstat(tc.mnt+"/"+fn, &s) if err != nil { t.Fatalf("Lstat failed: %v", err) } tc.pathFs.ForgetClientInodes() } // Now, the backing files are still hardlinked, but go-fuse's // view of them should not be because of the // ForgetClientInodes call. To prove this, we swap out the // files in the backing store, and prove that they are // distinct by truncating to different lengths. for _, fn := range []string{"file1", "file2"} { fn = tc.orig + "/" + fn if err := os.Remove(fn); err != nil { t.Fatalf("Remove", err) } tc.WriteFile(fn, []byte(c), 0644) } for i, fn := range []string{"file1", "file2"} { fn = tc.mnt + "/" + fn if err := os.Truncate(fn, int64(i)); err != nil { t.Fatalf("Truncate", err) } } for i, fn := range []string{"file1", "file2"} { var s syscall.Stat_t err = syscall.Lstat(tc.mnt+"/"+fn, &s) if err != nil { t.Fatalf("Lstat failed: %v", err) } if s.Size != int64(i) { t.Errorf("Lstat(%q): got size %d, want %d", fn, s.Size, i) } } }
// TestFromStatT tests fromStatT for a tempfile func TestFromStatT(t *testing.T) { file, _, _, dir := prepareFiles(t) defer os.RemoveAll(dir) stat := &syscall.Stat_t{} err := syscall.Lstat(file, stat) s, err := fromStatT(stat) if err != nil { t.Fatal(err) } if stat.Mode != s.Mode() { t.Fatal("got invalid mode") } if stat.Uid != s.UID() { t.Fatal("got invalid uid") } if stat.Gid != s.Gid() { t.Fatal("got invalid gid") } if stat.Rdev != s.Rdev() { t.Fatal("got invalid rdev") } if stat.Mtim != s.Mtim() { t.Fatal("got invalid mtim") } }
func (file *File) unlink() error { // Remove whatever was there. // NOTE: We will generally require the // write lock to be held for this routine. if file.write_deleted { err := cleardelattr(file.write_path) if err != nil { return err } } var stat syscall.Stat_t err := syscall.Lstat(file.write_path, &stat) if err == nil { if stat.Mode&syscall.S_IFDIR != 0 { err = syscall.Rmdir(file.write_path) if err != nil { return err } } else { err = syscall.Unlink(file.write_path) if err != nil { return err } } } file.write_exists = false file.write_deleted = false return nil }
func TestMemUnionResetDelete(t *testing.T) { wd, ufs, clean := setupMemUfs(t) defer clean() ioutil.WriteFile(wd+"/ro/todelete", []byte{42}, 0644) var before, after, afterReset syscall.Stat_t syscall.Lstat(wd+"/mnt/todelete", &before) before.Ino = 0 os.Remove(wd + "/mnt/todelete") syscall.Lstat(wd+"/mnt/todelete", &after) testEq(t, after, before, false) ufs.Reset() syscall.Lstat(wd+"/mnt/todelete", &afterReset) afterReset.Ino = 0 testEq(t, afterReset, before, true) }
func TestTouch(t *testing.T) { ts := NewTestCase(t) defer ts.Cleanup() contents := []byte{1, 2, 3} err := ioutil.WriteFile(ts.origFile, []byte(contents), 0700) if err != nil { t.Fatalf("WriteFile failed: %v", err) } err = os.Chtimes(ts.mountFile, time.Unix(42, 0), time.Unix(43, 0)) if err != nil { t.Fatalf("Chtimes failed: %v", err) } var stat syscall.Stat_t err = syscall.Lstat(ts.mountFile, &stat) if err != nil { t.Fatalf("Lstat failed: %v", err) } if stat.Atim.Sec != 42 { t.Errorf("Got atime.sec %d, want 42. Stat_t was %#v", stat.Atim.Sec, stat) } if stat.Mtim.Sec != 43 { t.Errorf("Got mtime.sec %d, want 43. Stat_t was %#v", stat.Mtim.Sec, stat) } }
func TestNegativeTime(t *testing.T) { ts := NewTestCase(t) defer ts.Cleanup() _, err := os.Create(ts.origFile) if err != nil { t.Fatalf("Create failed: %v", err) } var stat syscall.Stat_t // set negative nanosecond will occur errors on UtimesNano as invalid argument ut := time.Date(1960, time.January, 10, 23, 0, 0, 0, time.UTC) tim := []syscall.Timespec{ syscall.NsecToTimespec(ut.UnixNano()), syscall.NsecToTimespec(ut.UnixNano()), } err = syscall.UtimesNano(ts.mountFile, tim) if err != nil { t.Fatalf("UtimesNano failed: %v", err) } err = syscall.Lstat(ts.mountFile, &stat) if err != nil { t.Fatalf("Lstat failed: %v", err) } if stat.Atim.Sec >= 0 || stat.Mtim.Sec >= 0 { t.Errorf("Got wrong timestamps %v", stat) } }
func (imdb *ImageDataBase) scanDirectory(dirname string) error { file, err := os.Open(path.Join(imdb.baseDir, dirname)) if err != nil { return err } names, err := file.Readdirnames(-1) file.Close() for _, name := range names { filename := path.Join(dirname, name) var stat syscall.Stat_t err := syscall.Lstat(path.Join(imdb.baseDir, filename), &stat) if err != nil { if err == syscall.ENOENT { continue } return err } if stat.Mode&syscall.S_IFMT == syscall.S_IFDIR { err = imdb.scanDirectory(filename) } else if stat.Mode&syscall.S_IFMT == syscall.S_IFREG { err = imdb.loadFile(filename) } if err != nil { if err == syscall.ENOENT { continue } return err } } return nil }
// emptyExitedGarbage discards sufficiently aged pods from exitedGarbageDir() func emptyExitedGarbage(gracePeriod time.Duration) error { if err := walkPods(includeExitedGarbageDir, func(p *pod) { gp := p.path() st := &syscall.Stat_t{} if err := syscall.Lstat(gp, st); err != nil { if err != syscall.ENOENT { stderr("Unable to stat %q, ignoring: %v", gp, err) } return } if expiration := time.Unix(st.Ctim.Unix()).Add(gracePeriod); time.Now().After(expiration) { if err := p.ExclusiveLock(); err != nil { return } stdout("Garbage collecting pod %q", p.uuid) deletePod(p) } else { stderr("Pod %q not removed: still within grace period (%s)", p.uuid, gracePeriod) } }); err != nil { return err } return nil }
func (s idsFromStat) IDs() (int, int, error) { var stat syscall.Stat_t if err := syscall.Lstat(s.path, &stat); err != nil { return -1, -1, errwrap.Wrap( fmt.Errorf("unable to stat file %q", s.path), err, ) } if s.r == nil { return int(stat.Uid), int(stat.Gid), nil } uid, _, err := s.r.UnshiftRange(stat.Uid, stat.Gid) if err != nil { return -1, -1, errwrap.Wrap(errors.New("unable to determine real uid"), err) } _, gid, err := s.r.UnshiftRange(stat.Uid, stat.Gid) if err != nil { return -1, -1, errwrap.Wrap(errors.New("unable to determine real gid"), err) } return int(uid), int(gid), nil }
// Lstat takes a path to a file and returns // a system.StatT type pertaining to that file. // // Throws an error if the file does not exist func Lstat(path string) (*StatT, error) { s := &syscall.Stat_t{} if err := syscall.Lstat(path, s); err != nil { return nil, err } return fromStatT(s) }
func getattrHandle(tConn *TcfsConn, msgbuf []byte) { rootdir := tConn.RootDir buf := tConn.Buf fixpath := rootdir + string(msgbuf) var stat syscall.Stat_t err := syscall.Lstat(fixpath, &stat) if err != nil { binary.BigEndian.PutUint32(buf[0:4], 4) var ret int32 = -2 binary.BigEndian.PutUint32(buf[4:8], uint32(ret)) tConn.Write(buf[:8]) return } binary.BigEndian.PutUint32(buf[0:4], 11*4) binary.BigEndian.PutUint32(buf[4:8], 0) binary.BigEndian.PutUint32(buf[8:12], uint32(stat.Dev)) binary.BigEndian.PutUint32(buf[12:16], uint32(stat.Ino)) binary.BigEndian.PutUint32(buf[16:20], stat.Mode) binary.BigEndian.PutUint32(buf[20:24], uint32(stat.Nlink)) binary.BigEndian.PutUint32(buf[24:28], stat.Uid) binary.BigEndian.PutUint32(buf[28:32], stat.Gid) binary.BigEndian.PutUint32(buf[32:36], uint32(stat.Size)) binary.BigEndian.PutUint32(buf[36:40], uint32(stat.Atim.Sec)) binary.BigEndian.PutUint32(buf[40:44], uint32(stat.Mtim.Sec)) binary.BigEndian.PutUint32(buf[44:48], uint32(stat.Ctim.Sec)) tConn.Write(buf[:48]) }
func getUidGid(path string) (uint32, uint32, error) { var st syscall.Stat_t if err := syscall.Lstat(path, &st); err != nil { return 0, 0, err } return st.Uid, st.Gid, nil }
func SetSymlinkUser(filename, username string, live bool) (bool, error) { userData, err := user.Lookup(username) if err != nil { return false, err } uid, err := strconv.Atoi(userData.Uid) if err != nil { return false, err } var stat syscall.Stat_t err = syscall.Lstat(filename, &stat) if err != nil { return false, err } if int(stat.Uid) == uid { return false, nil } if live { err = os.Lchown(filename, uid, int(stat.Gid)) if err != nil { return false, err } } return true, nil }
// emptyExitedGarbage discards sufficiently aged pods from exitedGarbageDir() func emptyExitedGarbage(gracePeriod time.Duration) error { if err := pkgPod.WalkPods(getDataDir(), pkgPod.IncludeExitedGarbageDir, func(p *pkgPod.Pod) { gp := p.Path() st := &syscall.Stat_t{} if err := syscall.Lstat(gp, st); err != nil { if err != syscall.ENOENT { stderr.PrintE(fmt.Sprintf("unable to stat %q, ignoring", gp), err) } return } if expiration := time.Unix(st.Ctim.Unix()).Add(gracePeriod); time.Now().After(expiration) { if err := p.ExclusiveLock(); err != nil { return } stdout.Printf("Garbage collecting pod %q", p.UUID) deletePod(p) } else { stderr.Printf("pod %q not removed: still within grace period (%s)", p.UUID, gracePeriod) } }); err != nil { return err } return nil }
/* we don't even implement opendir because it never * made any sense. Just call ReadDir with a node * you walked to and we're done. * What should we do if there are too many entries? Interesting question. */ func (node *LocalFileNode) ReadDir(name string) ([]FileInfo, error) { if DebugPrint { log.Printf("server: filenode.ReadDir node %v\n", node) } if DebugPrint { log.Printf("server: filenode.ReadDir file %v\n", node.File) } osfi, err := ioutil.ReadDir(name) if err != nil { log.Print(err) return nil, err } fi := make([]FileInfo, len(osfi)) for i, _ := range fi { fi[i].Name = osfi[i].Name() fullpath := path.Join(name, fi[i].Name) // Interesting problem. What if this one stat fails, and all others // succeed? In most Unix-like systems, the readdir will show the // name, and the stat will return as garbage. Not returning any results // because one Lstat failed is wrong; hiding the name because the Lstat // failed is wrong. If we log an error for every busted dirent we'll be // doing a LOT of logging. Conclusion: for now, ignore the error. _ = syscall.Lstat(fullpath, &fi[i].Stat) } return fi, err }
// DeviceForPath returns the device ID for the specified volume. func DeviceForPath(path string) (int32, error) { stat := syscall.Stat_t{} if err := syscall.Lstat(path, &stat); err != nil { return 0, err } return stat.Dev, nil }
func TestSysUtimensat(t *testing.T) { symlink := "/tmp/TestSysUtimensat" os.Remove(symlink) err := os.Symlink("/nonexisting/file", symlink) if err != nil { t.Fatal(err) } var ts [2]syscall.Timespec // Atime ts[0].Nsec = 1111 ts[0].Sec = 2222 // Mtime ts[1].Nsec = 3333 ts[1].Sec = 4444 err = sysUtimensat(0, symlink, &ts, _AT_SYMLINK_NOFOLLOW) if err != nil { t.Fatal(err) } var st syscall.Stat_t err = syscall.Lstat(symlink, &st) if err != nil { t.Fatal(err) } if !reflect.DeepEqual(st.Atim, ts[0]) { t.Errorf("Wrong atime: %v", st.Atim) } if !reflect.DeepEqual(st.Mtim, ts[1]) { t.Errorf("Wrong mtime: %v", st.Mtim) } }
// Checks whether the file can be considered a match according to given options // Existing option requires the file to exist // Symlink option allows the file to be a symlink func fileOkay(path string, options *Options) (bool, error) { var fi syscall.Stat_t err := syscall.Lstat(path, &fi) if err != nil && err != syscall.ENOENT { return false, err } if options.Existing && (err == syscall.ENOENT) { return false, nil } // Drop dead files... if options.Accessable { // FIXME(utkan): No R_OK(=4) in syscall package! err = syscall.Access(path, 4) if err != nil { return false, nil } } issym := fi.Mode&syscall.S_IFLNK == syscall.S_IFLNK if options.Symlink == false && issym { return false, nil } // ...and symlinks, if necessary. return true, nil }
func Lstat(path string, statbuf *Stat_t) error { var rawStatbuf syscall.Stat_t if err := syscall.Lstat(path, &rawStatbuf); err != nil { return err } convertStat(statbuf, &rawStatbuf) return nil }
// Lstat returns the Dir structure describing the named file and an error, if any. // If the file is a symbolic link, the returned Dir describes the // symbolic link. Lstat makes no attempt to follow the link. func Lstat(name string) (dir *Dir, err Error) { var stat syscall.Stat_t e := syscall.Lstat(name, &stat) if e != 0 { return nil, &PathError{"lstat", name, Errno(e)} } return dirFromStat(name, new(Dir), &stat, &stat), nil }
// Lstat returns a FileInfo describing the named file. // If the file is a symbolic link, the returned FileInfo // describes the symbolic link. Lstat makes no attempt to follow the link. // If there is an error, it will be of type *PathError. func Lstat(name string) (fi FileInfo, err error) { var stat syscall.Stat_t err = syscall.Lstat(name, &stat) if err != nil { return nil, &PathError{"lstat", name, err} } return fileInfoFromStat(&stat, name), nil }
func statAtimeMtime(fullpath string) (time.Time, time.Time, error) { var st syscall.Stat_t if err := syscall.Lstat(fullpath, &st); err != nil { var nulltime time.Time return nulltime, nulltime, err } return timespecToTime(st.Atimespec), timespecToTime(st.Mtimespec), nil }