func coalesce(parentFile *os.File, childFile *os.File) error { blockSize, err := getFileSystemBlockSize(childFile) if err != nil { panic("can't get FS block size, error: " + err.Error()) } var data, hole int64 for { data, err = syscall.Seek(int(childFile.Fd()), hole, seekData) if err != nil { // reaches EOF errno := err.(syscall.Errno) if errno == syscall.ENXIO { break } else { // unexpected errors log.Fatal("Failed to syscall.Seek SEEK_DATA") return err } } hole, err = syscall.Seek(int(childFile.Fd()), data, seekHole) if err != nil { log.Fatal("Failed to syscall.Seek SEEK_HOLE") return err } // now we have a data start offset and length(hole - data) // let's read from child and write to parent file block by block _, err = parentFile.Seek(data, os.SEEK_SET) if err != nil { log.Fatal("Failed to os.Seek os.SEEK_SET") return err } offset := data buffer := fio.AllocateAligned(blockSize) for offset != hole { // read a block from child, maybe use bufio or Reader stream n, err := fio.ReadAt(childFile, buffer, offset) if n != len(buffer) || err != nil { log.Fatal("Failed to read from childFile") return err } // write a block to parent n, err = fio.WriteAt(parentFile, buffer, offset) if n != len(buffer) || err != nil { log.Fatal("Failed to write to parentFile") return err } offset += int64(n) } } return nil }
func (k *PosixKernel) Lseek(fd co.Fd, offset co.Off, whence int) uint64 { off, err := syscall.Seek(int(fd), int64(offset), whence) if err != nil { return Errno(err) } return uint64(off) }
func main() { flag.Var(&windowSize, "window-size", "Window size in Go `duration` format (default \"10m\")") flag.IntVar(&maxRestarts, "max-restarts", 5, "Max `restarts` within window-size duration") flag.StringVar(&metadataDir, "metadata-dir", "/run/runlimit", "Metadata `dir`, where metadata files are stored") flag.StringVar(&metadataKey, "metadata-key", "", "Metadata key, which will form part of the metadata file name") flag.StringVar(&svCmd, "sv-cmd", "", "Command to use to stop a service") flag.Parse() if windowSize == 0 || maxRestarts == 0 { fatal("-max-restarts and/or -window-size cannot be 0") } cmdline := flag.Args() if len(cmdline) < 1 { fatal("No command supplied") } cwd, err := os.Getwd() assert(err) if metadataKey == "" { metadataKey = nonalphanumeric.ReplaceAllString(cwd, "_") } metafile := filepath.Join(metadataDir, fmt.Sprintf("%s.meta", metadataKey)) f, err := os.OpenFile(metafile, os.O_RDWR|os.O_CREATE, os.FileMode(0644)) assert(err) defer f.Close() assert(syscall.Flock(int(f.Fd()), syscall.LOCK_NB|syscall.LOCK_EX)) metadata := &Metadata{} if err := json.NewDecoder(f).Decode(metadata); err != nil && err != io.EOF { warning("metadata corrupted, ignoring...") } if limit(metadata, time.Duration(windowSize), maxRestarts) { signals := make(chan os.Signal) signal.Notify(signals, syscall.SIGTERM) if svCmd != "" { parts, err := shlex.Split(svCmd, true) assert(err) go func() { if out, err := exec.Command(parts[0], parts[1:]...).Output(); err != nil { warning("command exited abnormally with output %s", string(out)) } }() select { case <-signals: break case <-time.After(5 * time.Second): warning("timed out while waiting for TERM from %s", parts[0]) } } fatal("max restart intensity reached") } assert(syscall.Ftruncate(int(f.Fd()), 0)) _, err = syscall.Seek(int(f.Fd()), 0, 0) assert(err) if err := json.NewEncoder(f).Encode(metadata); err != nil { warning("could not write metadata: %s", err.Error()) } assert(chainlib.Exec(cmdline, nil)) }
// OpenFile is the generalized open call; most users will use Open // or Create instead. It opens the named file with specified flag // (O_RDONLY etc.) and perm, (0666 etc.) if applicable. If successful, // methods on the returned File can be used for I/O. // If there is an error, it will be of type *PathError. func OpenFile(name string, flag int, perm FileMode) (file *File, err error) { if DisableWritesForAppEngine && flag&(O_WRONLY|O_RDWR|O_CREATE|O_EXCL) != 0 { return nil, &PathError{"open", name, errDisabledWrites} } var ( fd int e error create bool excl bool trunc bool append bool ) if flag&O_CREATE == O_CREATE { flag = flag & ^O_CREATE create = true } if flag&O_EXCL == O_EXCL { excl = true } if flag&O_TRUNC == O_TRUNC { trunc = true } // O_APPEND is emulated on Plan 9 if flag&O_APPEND == O_APPEND { flag = flag &^ O_APPEND append = true } syscall.ForkLock.RLock() if (create && trunc) || excl { fd, e = syscall.Create(name, flag, syscallMode(perm)) } else { fd, e = syscall.Open(name, flag) if e != nil && create { var e1 error fd, e1 = syscall.Create(name, flag, syscallMode(perm)) if e1 == nil { e = nil } } } syscall.ForkLock.RUnlock() if e != nil { return nil, &PathError{"open", name, e} } if append { if _, e = syscall.Seek(fd, 0, SEEK_END); e != nil { return nil, &PathError{"seek", name, e} } } return NewFile(uintptr(fd), name), nil }
// pread reads len(b) bytes from the File starting at byte offset off. // It returns the number of bytes read and the error, if any. // EOF is signaled by a zero count with err set to 0. func (f *File) pread(b []byte, off int64) (n int, err int) { f.l.Lock() defer f.l.Unlock() curoffset, e := syscall.Seek(f.fd, 0, 1) if e != 0 { return 0, e } defer syscall.Seek(f.fd, curoffset, 0) o := syscall.Overlapped{ OffsetHigh: uint32(off >> 32), Offset: uint32(off), } var done uint32 e = syscall.ReadFile(int32(f.fd), b, &done, &o) if e != 0 { return 0, e } return int(done), 0 }
// pwrite writes len(b) bytes to the File starting at byte offset off. // It returns the number of bytes written and an error, if any. func (f *File) pwrite(b []byte, off int64) (n int, err error) { f.l.Lock() defer f.l.Unlock() curoffset, e := syscall.Seek(f.fd, 0, 1) if e != nil { return 0, e } defer syscall.Seek(f.fd, curoffset, 0) o := syscall.Overlapped{ OffsetHigh: uint32(off >> 32), Offset: uint32(off), } var done uint32 e = syscall.WriteFile(syscall.Handle(f.fd), b, &done, &o) if e != nil { return 0, e } return int(done), nil }
// Seek sets the offset for the next Read or Write on file to offset, interpreted // according to whence: 0 means relative to the origin of the file, 1 means // relative to the current offset, and 2 means relative to the end. // It returns the new offset and an Error, if any. func (file *File) Seek(offset int64, whence int) (ret int64, err Error) { r, e := syscall.Seek(file.fd, offset, whence) if e == 0 && file.dirinfo != nil && r != 0 { e = syscall.EISDIR } if e != 0 { return 0, &PathError{"seek", file.name, Errno(e)} } return r, nil }
func (file *File) Seek(offset int64, whence int) (ret int, err os.Error) { if file == nil { return -1, os.EINVAL } fmt.Printf("file.Seek(%d,%d)\n", offset, whence) r, e := syscall.Seek(file.fd, offset, whence) if e != 0 { err = os.Errno(e) } return int(r), err }
func TestSeekFailure(t *testing.T) { _, err := syscall.Seek(-1, 0, 0) if err == nil { t.Fatalf("Seek(-1, 0, 0) did not fail") } str := err.Error() // used to crash on Linux t.Logf("Seek: %v", str) if str == "" { t.Fatalf("Seek(-1, 0, 0) return error with empty message") } }
// OpenFile is the generalized open call; most users will use Open // or Create instead. It opens the named file with specified flag // (O_RDONLY etc.) and perm, (0666 etc.) if applicable. If successful, // methods on the returned File can be used for I/O. // It returns the File and an error, if any. func OpenFile(name string, flag int, perm uint32) (file *File, err error) { var ( fd int e syscall.Error create bool excl bool trunc bool append bool ) if flag&O_CREATE == O_CREATE { flag = flag & ^O_CREATE create = true } if flag&O_EXCL == O_EXCL { excl = true } if flag&O_TRUNC == O_TRUNC { trunc = true } // O_APPEND is emulated on Plan 9 if flag&O_APPEND == O_APPEND { flag = flag &^ O_APPEND append = true } syscall.ForkLock.RLock() if (create && trunc) || excl { fd, e = syscall.Create(name, flag, perm) } else { fd, e = syscall.Open(name, flag) if e != nil && create { var e1 syscall.Error fd, e1 = syscall.Create(name, flag, perm) if e1 == nil { e = nil } } } syscall.ForkLock.RUnlock() if e != nil { return nil, &PathError{"open", name, e} } if append { if _, e = syscall.Seek(fd, 0, SEEK_END); e != nil { return nil, &PathError{"seek", name, e} } } return NewFile(fd, name), nil }
func (dio *DiskIO) WriteBlock(blockaddr uint64, buffer []byte) (uint, error) { var noff int64 = int64(blockaddr) * int64(dio.BlockSize) _, err := syscall.Seek(dio.fileDescriptor, noff, 0) if err != nil { return 0, err } num, err := syscall.Write(dio.fileDescriptor, buffer) if err != nil { return 0, err } return uint(num), nil }
// OpenFile is the generalized open call; most users will use Open // or Create instead. It opens the named file with specified flag // (O_RDONLY etc.) and perm, (0666 etc.) if applicable. If successful, // methods on the returned File can be used for I/O. // If there is an error, it will be of type *PathError. func OpenFile(name string, flag int, perm FileMode) (*File, error) { var ( fd int e error create bool excl bool trunc bool append bool ) if flag&O_CREATE == O_CREATE { flag = flag & ^O_CREATE create = true } if flag&O_EXCL == O_EXCL { excl = true } if flag&O_TRUNC == O_TRUNC { trunc = true } // O_APPEND is emulated on Plan 9 if flag&O_APPEND == O_APPEND { flag = flag &^ O_APPEND append = true } if (create && trunc) || excl { fd, e = syscall.Create(name, flag, syscallMode(perm)) } else { fd, e = syscall.Open(name, flag) if e != nil && create { var e1 error fd, e1 = syscall.Create(name, flag, syscallMode(perm)) if e1 == nil { e = nil } } } if e != nil { return nil, &PathError{"open", name, e} } if append { if _, e = syscall.Seek(fd, 0, io.SeekEnd); e != nil { return nil, &PathError{"seek", name, e} } } return NewFile(uintptr(fd), name), nil }
// pread reads len(b) bytes from the File starting at byte offset off. // It returns the number of bytes read and the error, if any. // EOF is signaled by a zero count with err set to 0. func (f *File) pread(b []byte, off int64) (n int, err error) { f.l.Lock() defer f.l.Unlock() curoffset, e := syscall.Seek(f.fd, 0, 1) if e != nil { return 0, e } defer syscall.Seek(f.fd, curoffset, 0) o := syscall.Overlapped{ OffsetHigh: uint32(off >> 32), Offset: uint32(off), } var done uint32 e = syscall.ReadFile(syscall.Handle(f.fd), b, &done, &o) if e != nil { if e == syscall.ERROR_HANDLE_EOF { // end of file return 0, nil } return 0, e } return int(done), nil }
func (_entity *Entity) HashData(_hasher1 hasher.Hasher) (_hash []byte, _error Error) { if !_entity.IsRegular() { return nil, newError("dup", _entity.Path, -1, syscall.EBADF) } var _descriptor, _errno int _descriptor = _entity.Descriptor if _descriptor < 0 { return nil, newError("dup", _entity.Path, _entity.Descriptor, syscall.EBADF) } _descriptor, _errno = syscall.Dup(_descriptor) if _errno != 0 { return nil, newError("dup", _entity.Path, _entity.Descriptor, _errno) } defer syscall.Close(_descriptor) _, _errno = syscall.Seek(_descriptor, 0, 0 /* syscall.SEEK_SET */) if _errno != 0 { return nil, newError("seek", _entity.Path, _descriptor, _errno) } _hasher := _hasher1.Create() _buffer := make([]byte, _bufferSize) for { var _limit int _limit, _errno = syscall.Read(_descriptor, _buffer) if _errno != 0 { return nil, newError("read", _entity.Path, _descriptor, _errno) } if _limit == 0 { break } _error = hasher.HashUpdate(_hasher, _buffer[:_limit]) if _error != nil { return nil, newError("hash", _entity.Path, _descriptor, syscall.EIO) } } _hash, _error = hasher.HashFinalize(_hasher) if _error != nil { return nil, newError("hash", _entity.Path, _descriptor, syscall.EIO) } if _entity.Hashes == nil { _entity.Hashes = make(map[string][]byte, 1) } _entity.Hashes[_hasher1.Identifier()] = _hash return _hash, nil }
func (g *GPIO) Wait() (bool, error) { if g.fd == 0 { fd, err := syscall.Open(g.valuePath, syscall.O_RDONLY, 0666) if err != nil { return false, err } g.fd = fd g.fdSet = new(syscall.FdSet) FD_SET(g.fd, g.fdSet) g.buf = make([]byte, 64) syscall.Read(g.fd, g.buf) } syscall.Select(g.fd+1, nil, nil, g.fdSet, nil) syscall.Seek(g.fd, 0, 0) _, err := syscall.Read(g.fd, g.buf) if err != nil { return false, err } return string(g.buf[:2]) == "1\n", nil }
func preadn(fd uintptr, buf []byte, off int) error { whence := 0 if off < 0 { whence = 2 } if _, err := syscall.Seek(int(fd), int64(off), whence); err != nil { return err } for len(buf) > 0 { m, err := syscall.Read(int(fd), buf) if m <= 0 { if err == nil { return errors.New("short read") } return err } buf = buf[m:] } return nil }
func readValues(indices []int, filename string) []int32 { results := make([]int32, len(indices)) b := make([]byte, 4) f, _ := os.Open(filename) fd := syscall.Handle(f.Fd()) //value := int32(0) for i, cellIndex := range indices { syscall.Seek(fd, int64(cellIndex*4), os.SEEK_SET) // f.Seek(int64(cellIndex*4), os.SEEK_SET) syscall.Read(fd, b) //f.Read(b) value := bytes2int(b) // around 10-20% faster then binary.Read //package "encoding/binary" //binary.Read(f,binary.LittleEndian, &value) if value != -2147483648 { results[i] = value } else { results[i] = 99999 } } return results }
// seek sets the offset for the next Read or Write on file to offset, interpreted // according to whence: 0 means relative to the origin of the file, 1 means // relative to the current offset, and 2 means relative to the end. // It returns the new offset and an error, if any. func (f *File) seek(offset int64, whence int) (ret int64, err error) { return syscall.Seek(f.fd, offset, whence) }
// seek sets the offset for the next Read or Write on file to offset, interpreted // according to whence: 0 means relative to the origin of the file, 1 means // relative to the current offset, and 2 means relative to the end. // It returns the new offset and an error, if any. func (f *File) seek(offset int64, whence int) (ret int64, err error) { f.l.Lock() defer f.l.Unlock() return syscall.Seek(f.fd, offset, whence) }
func (watcher *PinWatcher) pinHandler() { exf, exf_err := os.OpenFile("/sys/class/gpio/export", syscall.O_WRONLY, 0400) if exf_err != nil { log.Panicln("Error opening /sys/class/gpio/export:", exf_err) } _, ex_err := exf.WriteString(fmt.Sprintf("%d", watcher.pin)) if ex_err != nil { log.Panicln("Error writing to /sys/class/gpio/export:", ex_err) } exf.Close() time.Sleep(time.Microsecond) edge_file := fmt.Sprintf("/sys/class/gpio/gpio%d/edge", watcher.pin) edgef, edgef_err := os.OpenFile(edge_file, syscall.O_WRONLY, 0400) if edgef_err != nil { log.Panicf("Error opening %s: %s\n", edge_file, edgef_err) } _, edge_err := edgef.WriteString("both") if edge_err != nil { log.Panicf("Error writing to %s: %s\n", edge_file, edge_err) } edgef.Close() time.Sleep(time.Microsecond) value_file := fmt.Sprintf("/sys/class/gpio/gpio%d/value", watcher.pin) irq_fd, irq_err := syscall.Open(value_file, syscall.O_RDONLY|syscall.O_NONBLOCK, syscall.S_IREAD) if irq_err != nil { log.Panicln("Error opening %s: %s\n", value_file, irq_err) } epfd, eperr := syscall.EpollCreate1(syscall.EPOLL_CLOEXEC) if eperr != nil { log.Panicln("Error creating epoll:", eperr) } event := new(syscall.EpollEvent) event.Fd = int32(irq_fd) event.Events |= syscall.EPOLLPRI if ctlerr := syscall.EpollCtl(epfd, syscall.EPOLL_CTL_ADD, irq_fd, event); ctlerr != nil { log.Panicln("Error on epoll control operation:", ctlerr) } var events_buffer [10]syscall.EpollEvent var buf [1]byte for !watcher.shutdown { n, werr := syscall.EpollWait(epfd, events_buffer[0:], 4000) if werr != nil { log.Println("Epoll error:", werr) } else if n == 1 { syscall.Seek(irq_fd, 0, 0) syscall.Read(irq_fd, buf[0:]) log.Println("Interrupt!", events_buffer[0].Fd, events_buffer[0].Events, buf) } else { log.Println("Timeout") } } syscall.Close(irq_fd) unexf, unexf_err := os.OpenFile("/sys/class/gpio/unexport", syscall.O_WRONLY|syscall.O_SYNC, 0400) if unexf_err != nil { log.Panicln("Error opening /sys/class/gpio/unexport:", unexf_err) } _, unex_err := unexf.WriteString(fmt.Sprintf("%d", watcher.pin)) if unex_err != nil { log.Panicln("Error writing to /sys/class/gpio/unexport:", unex_err) } unexf.Close() watcher.wg.Done() }
func lseek(u U, a []uint64) uint64 { fd, offset, whence := int(a[0]), int64(a[1]), int(a[2]) off, _ := syscall.Seek(fd, offset, whence) return uint64(off) }
// RetrieveLayoutStream0 streams sparse file data/hole layout // Deprecated; Based on file.seek; use RetrieveLayoutStream instead // To abort: abortStream <- error // Check status: err := <- errStream // Usage: go RetrieveLayoutStream(...) func RetrieveLayoutStream0(abortStream <-chan error, file *os.File, r Interval, layoutStream chan<- FileInterval, errStream chan<- error) { curr := r.Begin // Data or hole? offsetData, errData := file.Seek(curr, seekData) offsetHole, errHole := file.Seek(curr, seekHole) var interval FileInterval if errData != nil { // Hole only interval = FileInterval{SparseHole, Interval{curr, r.End}} if interval.Len() > 0 { layoutStream <- interval } close(layoutStream) errStream <- nil return } else if errHole != nil { // Data only interval = FileInterval{SparseData, Interval{curr, r.End}} if interval.Len() > 0 { layoutStream <- interval } close(layoutStream) errStream <- nil return } if offsetData < offsetHole { interval = FileInterval{SparseData, Interval{curr, offsetHole}} curr = offsetHole } else { interval = FileInterval{SparseHole, Interval{curr, offsetData}} curr = offsetData } if interval.Len() > 0 { layoutStream <- interval } for curr < r.End { // Check abort condition select { case err := <-abortStream: close(layoutStream) errStream <- err return default: } var whence int if SparseData == interval.Kind { whence = seekData } else { whence = seekHole } // Note: file.Seek masks syscall.ENXIO hence syscall is used instead next, errno := syscall.Seek(int(file.Fd()), curr, whence) if errno != nil { switch errno { case syscall.ENXIO: // no more intervals next = r.End // close the last interval default: // mimic standard "os"" package error handler close(layoutStream) errStream <- &os.PathError{Op: "seek", Path: file.Name(), Err: errno} return } } if SparseData == interval.Kind { // End of data, handle the last hole if any interval = FileInterval{SparseHole, Interval{curr, next}} } else { // End of hole, handle the last data if any interval = FileInterval{SparseData, Interval{curr, next}} } curr = next if interval.Len() > 0 { layoutStream <- interval } } close(layoutStream) errStream <- nil return }
// This test is inspired on xfstest, t_dir_offset2.c func TestReaddirPlusSeek(t *testing.T) { tc := NewTestCase(t) defer tc.Cleanup() var names []string for i := 0; i < 20; i++ { names = append(names, fmt.Sprintf("abcd%d", i)) } for _, n := range names { if err := os.MkdirAll(filepath.Join(tc.origSubdir, n), 0755); err != nil { t.Fatalf("Mkdir failed: %v", err) } } fd, err := syscall.Open(tc.mountSubdir, syscall.O_RDONLY, 0755) if err != nil { t.Fatalf("Open(%q): %v", tc.mountSubdir, err) } defer syscall.Close(int(fd)) // store offsets type entryOff struct { ino uint64 off int64 } previous := map[int]entryOff{} var bufdata [1024]byte for { buf := bufdata[:] n, err := syscall.ReadDirent(fd, buf) if err != nil { t.Fatalf("ReadDirent: %v", err) } if n == 0 { break } buf = buf[:n] for _, d := range parseDirents(buf) { if d.name == "." || d.name == ".." { continue } i := len(previous) previous[i] = entryOff{d.ino, d.off} } } for i := len(previous) - 1; i >= 0; i-- { var off int64 if i > 0 { off = previous[i-1].off } if _, err := syscall.Seek(fd, off, 0); err != nil { t.Fatalf("Seek %v", err) } buf := bufdata[:] n, err := syscall.ReadDirent(fd, buf) if err != nil { t.Fatalf("readdir after seek %d: %v", i, err) } if n == 0 { t.Fatalf("no dirent after seek to %d", i) } ds := parseDirents(buf[:n]) if ds[0].ino != previous[i].ino { t.Errorf("got ino %d, want %d", ds[0].ino, previous[i].ino) } } // Delete has a forget as side-effect: make sure we get the lookup counts correct. for _, n := range names { full := filepath.Join(tc.mountSubdir, n) if err := syscall.Rmdir(full); err != nil { t.Fatalf("Rmdir(%q): %v", n, err) } } }