func lck(fd, from, ln int) (err error) { fmt.Printf("lck:%v %v %v\n", fd, from, ln) fmt.Println(os.Getpid()) // ol := windows.Overlapped{Offset: uint32(from), OffsetHigh: uint32(from >> 32), HEvent: windows.Handle(0)} // r1, _, err := procLockFileEx.Call(uintptr(fd), uintptr(LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY), uintptr(0), uintptr(int32(ln)), uintptr(int32(ln >> 32)), uintptr(unsafe.Pointer(&ol))) // if r1 != 1 { // return err // } // return nil lk := unix.Flock_t{Type: unix.F_WRLCK, Whence: int16(os.SEEK_SET), Start: int64(from), Len: int64(ln)} //return unix.FcntlFlock(uintptr(fd), unix.F_SETLKW, &lk) r1, _, errno := unix.Syscall(unix.SYS_FCNTL, uintptr(fd), uintptr(unix.F_GETFL), uintptr(unsafe.Pointer(&lk))) fmt.Printf("\tlck_test:%v %v %v\n", r1, lk, errno) lk = unix.Flock_t{Type: unix.F_WRLCK, Whence: int16(os.SEEK_SET), Start: int64(from), Len: int64(ln)} r1, _, errno = unix.Syscall(unix.SYS_FCNTL, uintptr(fd), uintptr(unix.F_SETLK), uintptr(unsafe.Pointer(&lk))) fmt.Printf("\tlck:%v %v %v\n", r1, lk, errno) if errno == 0 { return nil } err = errno return err }
// In environments where svlogd is used, the pipe that becomes STDIN of this // program can be non-blocking. Go's File implementation does not play well // with non-blocking pipes, in particular it does not recover from an EAGAIN // error from read(2). // This function defensively sets its 0th file descriptor to be blocking so // that we do not have to handle EAGAIN errors. func setSTDINToBlock() error { oldflags, _, errno := unix.Syscall(unix.SYS_FCNTL, 0, unix.F_GETFL, 0) if errno != 0 { return fmt.Errorf("unix.FCNTL F_GETFL errno: %d", errno) } _, _, errno = unix.Syscall(unix.SYS_FCNTL, 0, unix.F_SETFL, oldflags&^unix.O_NONBLOCK) if errno != 0 { return fmt.Errorf("unix.FCNTL F_SETFL errno: %d", errno) } return nil }
func ioCtl(fd *os.File) (bufLen int, err error) { bufLen = 1 _, _, errno := unix.Syscall(unix.SYS_IOCTL, fd.Fd(), uintptr(unix.BIOCIMMEDIATE), uintptr(unsafe.Pointer(&bufLen))) if errno != 0 { err = errno return } _, _, errno = unix.Syscall(unix.SYS_IOCTL, fd.Fd(), uintptr(unix.BIOCGBLEN), uintptr(unsafe.Pointer(&bufLen))) if errno != 0 { err = errno } return }
func JailAttach(jid int) error { if _, _, err := unix.Syscall(unix.SYS_JAIL_ATTACH, uintptr(jid), 0, 0); err == 0 { return nil } else { return err } }
// GetWinsize gets the winsize struct with the terminal size set by the kernel. func GetWinsize(fd int, ws *Winsize) (err error) { _, _, e1 := unix.Syscall(unix.SYS_IOCTL, uintptr(fd), uintptr(TIOCGWINSZ), uintptr(unsafe.Pointer(ws))) if e1 != 0 { err = e1 } return }
func Getattr(fd int, state *Termios) (err error) { _, _, e1 := unix.Syscall(unix.SYS_IOCTL, uintptr(fd), uintptr(TCGETS), uintptr(unsafe.Pointer(state))) if e1 != 0 { err = e1 } return }
func setns(fd int) error { ret, _, err := unix.Syscall(SYS_SETNS, uintptr(uint(fd)), uintptr(CLONE_NEWNS), 0) if ret != 0 { return fmt.Errorf("syscall SYS_SETNS failed: %v", err) } return nil }
func insert(fd uintptr, s string) error { for _, c := range s { ptr := uintptr(unsafe.Pointer(&c)) if _, _, e := unix.Syscall(unix.SYS_IOCTL, fd, unix.TIOCSTI, ptr); e != 0 { return fmt.Errorf("syscall errno: %d\n", e) } } return nil }
func getwinsize() winsize { ws := winsize{} _, _, err := unix.Syscall(syscall.SYS_IOCTL, uintptr(0), uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&ws))) if err != 0 { log.Fatalf("TIOCGWINSZ failed to get terminal size: %s\n", err) } return ws }
func (ns *netNS) Set() error { if err := ns.errorIfClosed(); err != nil { return err } if _, _, err := unix.Syscall(unix.SYS_SETNS, ns.Fd(), uintptr(unix.CLONE_NEWNET), 0); err != 0 { return fmt.Errorf("Error switching to ns %v: %v", ns.file.Name(), err) } return nil }
// Mprotect calls mprotect(2) on the mmapped region. func (m Map) Mprotect(prot Perms) (err error) { _, _, e1 := unix.Syscall( unix.SYS_MPROTECT, uintptr(m.Start), uintptr(m.End-m.Start), uintptr(prot), ) if e1 != 0 { return e1 } return }
func rlck(fd, from, ln int) (err error) { // ol := windows.Overlapped{Offset: uint32(from), OffsetHigh: uint32(from >> 32), HEvent: windows.Handle(0)} // r1, _, err := procLockFileEx.Call(uintptr(fd), uintptr(LOCKFILE_FAIL_IMMEDIATELY), uintptr(0), uintptr(int32(ln)), uintptr(int32(ln >> 32)), uintptr(unsafe.Pointer(&ol))) // if r1 != 1 { // return err // } // return nil // type Flock_t struct { // Type int16 // Whence int16 // Pad_cgo_0 [4]byte // Start int64 // Len int64 // Pid int32 // Pad_cgo_1 [4]byte // } // FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command. // func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error { // _, _, errno := Syscall(fcntl64Syscall, fd, uintptr(cmd), uintptr(unsafe.Pointer(lk))) // if errno == 0 { // return nil // } // return errno // } fmt.Printf("rlck:%v %v %v\n", fd, from, ln) fmt.Println(os.Getpid()) lk := unix.Flock_t{Type: unix.F_RDLCK, Whence: int16(os.SEEK_SET), Start: int64(from), Len: int64(ln)} r1, _, errno := unix.Syscall(unix.SYS_FCNTL, uintptr(fd), uintptr(unix.F_GETFL), uintptr(unsafe.Pointer(&lk))) fmt.Printf("\trlck_test:%v %v %v\n", r1, lk, errno) lk = unix.Flock_t{Type: unix.F_RDLCK, Whence: int16(os.SEEK_SET), Start: int64(from), Len: int64(ln)} r1, _, errno = unix.Syscall(unix.SYS_FCNTL, uintptr(fd), uintptr(unix.F_SETLK), uintptr(unsafe.Pointer(&lk))) fmt.Printf("\trlck:%v %v %v\n", r1, lk, errno) if errno == 0 { return nil } err = errno return err }
func ifReq(fd *os.File, ifName string) (err error) { req := struct { Name [0x10]byte pad [0x28 - 0x10]byte }{} copy(req.Name[:], ifName) _, _, errno := unix.Syscall(unix.SYS_IOCTL, fd.Fd(), uintptr(unix.BIOCSETIF), uintptr(unsafe.Pointer(&req))) if errno != 0 { err = errno return err } return }
func main() { flag.Parse() l := uintptr(3) if *clearSyslog { l = 4 } b := make([]byte, 256*1024) if amt, _, err := unix.Syscall(unix.SYS_SYSLOG, l, uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); err == 0 { os.Stdout.Write(b[:amt]) } else { log.Fatalf("syslog failed: %v", err) } }
func (m *Mixer) writeVolume(channelVolume int) error { _, _, err := unix.Syscall( unix.SYS_IOCTL, m.device.Fd(), SOUND_MIXER_WRITE_VOLUME, uintptr(unsafe.Pointer(&channelVolume)), ) if err != 0 { return err } return nil }
// Call msync(2) with the MS_SYNC flag on a slice previously returned by // mmap(2). func msync(p []byte) (err error) { _, _, errno := unix.Syscall( unix.SYS_MSYNC, uintptr(unsafe.Pointer(&p[0])), uintptr(len(p)), unix.MS_SYNC) if errno != 0 { err = errno return } return }
// mmap the given file, get the mincore vector, then // return it as an []bool func FileMincore(f *os.File, size int64) ([]bool, error) { //skip could not mmap error when the file size is 0 if int(size) == 0 { return nil, nil } // mmap is a []byte mmap, err := unix.Mmap(int(f.Fd()), 0, int(size), unix.PROT_NONE, unix.MAP_SHARED) if err != nil { return nil, fmt.Errorf("could not mmap: %v", err) } // TODO: check for MAP_FAILED which is ((void *) -1) // but maybe unnecessary since it looks like errno is always set when MAP_FAILED // one byte per page, only LSB is used, remainder is reserved and clear vecsz := (size + int64(os.Getpagesize()) - 1) / int64(os.Getpagesize()) vec := make([]byte, vecsz) // get all of the arguments to the mincore syscall converted to uintptr mmap_ptr := uintptr(unsafe.Pointer(&mmap[0])) size_ptr := uintptr(size) vec_ptr := uintptr(unsafe.Pointer(&vec[0])) // use Go's ASM to submit directly to the kernel, no C wrapper needed // mincore(2): int mincore(void *addr, size_t length, unsigned char *vec); // 0 on success, takes the pointer to the mmap, a size, which is the // size that came from f.Stat(), and the vector, which is a pointer // to the memory behind an []byte // this writes a snapshot of the data into vec which a list of 8-bit flags // with the LSB set if the page in that position is currently in VFS cache ret, _, err := unix.Syscall(unix.SYS_MINCORE, mmap_ptr, size_ptr, vec_ptr) if ret != 0 { return nil, fmt.Errorf("syscall SYS_MINCORE failed: %v", err) } defer unix.Munmap(mmap) mc := make([]bool, vecsz) // there is no bitshift only bool for i, b := range vec { if b%2 == 1 { mc[i] = true } else { mc[i] = false } } return mc, nil }
func MakeNetworkNS(containerID string) string { namespace := "/var/run/netns/" + containerID err := os.MkdirAll("/var/run/netns", 0600) Expect(err).NotTo(HaveOccurred()) // create an empty file at the mount point mountPointFd, err := os.Create(namespace) Expect(err).NotTo(HaveOccurred()) mountPointFd.Close() var wg sync.WaitGroup wg.Add(1) // do namespace work in a dedicated goroutine, so that we can safely // Lock/Unlock OSThread without upsetting the lock/unlock state of // the caller of this function. See block comment above. go (func() { defer wg.Done() runtime.LockOSThread() defer runtime.UnlockOSThread() defer GinkgoRecover() // capture current thread's original netns currentThreadNetNSPath := getCurrentThreadNetNSPath() originalNetNS, err := unix.Open(currentThreadNetNSPath, unix.O_RDONLY, 0) Expect(err).NotTo(HaveOccurred()) defer unix.Close(originalNetNS) // create a new netns on the current thread err = unix.Unshare(unix.CLONE_NEWNET) Expect(err).NotTo(HaveOccurred()) // bind mount the new netns from the current thread onto the mount point err = unix.Mount(currentThreadNetNSPath, namespace, "none", unix.MS_BIND, "") Expect(err).NotTo(HaveOccurred()) // reset current thread's netns to the original _, _, e1 := unix.Syscall(unix.SYS_SETNS, uintptr(originalNetNS), uintptr(unix.CLONE_NEWNET), 0) Expect(e1).To(BeZero()) })() wg.Wait() return namespace }
func (m *Mixer) readVolume() (int, error) { var currentVolume int _, _, err := unix.Syscall( unix.SYS_IOCTL, m.device.Fd(), SOUND_MIXER_READ_VOLUME, uintptr(unsafe.Pointer(¤tVolume)), ) if err != 0 { return 0, err } return currentVolume & 0xff, nil }
func Setattr(fd int, action uint, state *Termios) (err error) { switch action { case TCSANOW: action = TCSETS case TCSADRAIN: action = TCSETSW case TCSAFLUSH: action = TCSETSF } _, _, e1 := unix.Syscall(unix.SYS_IOCTL, uintptr(fd), uintptr(action), uintptr(unsafe.Pointer(state))) if e1 != 0 { err = e1 } return }
func unlck(fd, from, ln int) (err error) { fmt.Printf("unlck:%v %v %v\n", fd, from, ln) // ol := windows.Overlapped{Offset: uint32(from), OffsetHigh: uint32(from >> 32), HEvent: windows.Handle(0)} // r1, _, err := procUnlockFileEx.Call(uintptr(fd), uintptr(0), uintptr(int32(ln)), uintptr(int32(ln >> 32)), uintptr(unsafe.Pointer(&ol))) // if r1 != 1 { // return err // } // return nil//windows.CloseHandle(windows.Handle(fd)) lk := unix.Flock_t{Type: unix.F_UNLCK, Whence: int16(os.SEEK_SET), Start: int64(from), Len: int64(ln)} //return unix.FcntlFlock(uintptr(fd), unix.F_SETLKW, &lk) r1, _, errno := unix.Syscall(unix.SYS_FCNTL, uintptr(fd), uintptr(unix.F_SETLK), uintptr(unsafe.Pointer(&lk))) fmt.Printf("\tunlck:%v %v %v\n", r1, lk, errno) if errno == 0 { return nil } err = errno return err }
func removexattr(path string, attr string) (err error) { var _p0 *byte _p0, err = unix.BytePtrFromString(path) if err != nil { return } var _p1 *byte _p1, err = unix.BytePtrFromString(attr) if err != nil { return } _, _, e1 := unix.Syscall(unix.SYS_REMOVEXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) use(unsafe.Pointer(_p0)) use(unsafe.Pointer(_p1)) if e1 != 0 { err = syscall.Errno(e1) } return }
func makeNetworkNS(containerID string) string { namespace := "/var/run/netns/" + containerID pid := unix.Getpid() tid := unix.Gettid() err := os.MkdirAll("/var/run/netns", 0600) Expect(err).NotTo(HaveOccurred()) runtime.LockOSThread() defer runtime.UnlockOSThread() go (func() { defer GinkgoRecover() err = unix.Unshare(unix.CLONE_NEWNET) Expect(err).NotTo(HaveOccurred()) fd, err := os.Create(namespace) Expect(err).NotTo(HaveOccurred()) defer fd.Close() err = unix.Mount("/proc/self/ns/net", namespace, "none", unix.MS_BIND, "") Expect(err).NotTo(HaveOccurred()) })() Eventually(namespace).Should(BeAnExistingFile()) fd, err := unix.Open(fmt.Sprintf("/proc/%d/task/%d/ns/net", pid, tid), unix.O_RDONLY, 0) Expect(err).NotTo(HaveOccurred()) defer unix.Close(fd) _, _, e1 := unix.Syscall(unix.SYS_SETNS, uintptr(fd), uintptr(unix.CLONE_NEWNET), 0) Expect(e1).To(BeZero()) return namespace }
func ioctl(f *os.File, req int, ptr unsafe.Pointer) syscall.Errno { _, _, err := unix.Syscall(unix.SYS_IOCTL, uintptr(f.Fd()), uintptr(req), uintptr(ptr)) return err }
func ioctl(fd, op, arg uintptr) error { if _, _, ep := unix.Syscall(unix.SYS_IOCTL, fd, op, arg); ep != 0 { return ep } return nil }