func Tcsetpgrp(fd int, pid int) error { i := syscall.Errno(C.f(C.int(fd), C.pid_t(pid))) if i != 0 { return syscall.Errno(i) } return nil }
func (s *resultSrv) Run() { var o *syscall.Overlapped var key uint32 var r ioResult for { r.err = syscall.GetQueuedCompletionStatus(s.iocp, &(r.qty), &key, &o, 0) if r.err == syscall.Errno(syscall.WAIT_TIMEOUT) && o == nil { runtime_blockingSyscallHint() r.err = syscall.GetQueuedCompletionStatus(s.iocp, &(r.qty), &key, &o, syscall.INFINITE) } switch { case r.err == nil: // Dequeued successfully completed IO packet. case r.err == syscall.Errno(syscall.WAIT_TIMEOUT) && o == nil: // Wait has timed out (should not happen now, but might be used in the future). panic("GetQueuedCompletionStatus timed out") case o == nil: // Failed to dequeue anything -> report the error. panic("GetQueuedCompletionStatus failed " + r.err.Error()) default: // Dequeued failed IO packet. } (*anOp)(unsafe.Pointer(o)).resultc <- r } }
// GetsockoptInt wraps syscall.GetsockoptInt. func (sw *Switch) GetsockoptInt(s, level, opt int) (soerr int, err error) { so := sw.sockso(s) if so == nil { return syscall.GetsockoptInt(s, level, opt) } sw.fmu.RLock() f, _ := sw.fltab[FilterGetsockoptInt] sw.fmu.RUnlock() af, err := f.apply(so) if err != nil { return -1, err } soerr, so.Err = syscall.GetsockoptInt(s, level, opt) so.SocketErr = syscall.Errno(soerr) if err = af.apply(so); err != nil { return -1, err } if so.Err != nil { return -1, so.Err } if opt == syscall.SO_ERROR && (so.SocketErr == syscall.Errno(0) || so.SocketErr == syscall.EISCONN) { sw.smu.Lock() sw.stats.getLocked(so.Cookie).Connected++ sw.smu.Unlock() } return soerr, nil }
func TestIsError(t *testing.T) { if !IsErrorTemporary(ErrTimeout) { t.Fatal("ErrTimeout not temporary!") } if !IsErrorTimeout(ErrTimeout) { t.Fatal("ErrTimeout not timeout!") } if !IsErrorTemporary(syscall.Errno(syscall.EINTR)) { t.Fatal("EINTR not temporary!") } if IsErrorTimeout(syscall.Errno(syscall.EINTR)) { t.Fatal("EINTR is timeout!") } if IsErrorTemporary(ErrClosing) { t.Fatal("ErrClosing is temporary!") } if IsErrorTimeout(ErrClosing) { t.Fatal("ErrClosing is timeout!") } if IsErrorTemporary(syscall.Errno(syscall.EFAULT)) { t.Fatal("EFAULT is temporary!") } if IsErrorTimeout(syscall.Errno(syscall.EFAULT)) { t.Fatal("EFAULT is timeout!") } }
// DOES NOT LOCK OR CHECK VALIDITY // Assumes caller has already done this // Wrapper for seccomp_rule_add_... functions func (f *ScmpFilter) addRuleWrapper(call ScmpSyscall, action ScmpAction, exact bool, cond C.scmp_cast_t) error { var length C.uint if cond != nil { length = 1 } else { length = 0 } var retCode C.int if exact { retCode = C.seccomp_rule_add_exact_array(f.filterCtx, action.toNative(), C.int(call), length, cond) } else { retCode = C.seccomp_rule_add_array(f.filterCtx, action.toNative(), C.int(call), length, cond) } if syscall.Errno(-1*retCode) == syscall.EFAULT { return fmt.Errorf("unrecognized syscall") } else if syscall.Errno(-1*retCode) == syscall.EPERM { return fmt.Errorf("requested action matches default action of filter") } else if retCode != 0 { return syscall.Errno(-1 * retCode) } return nil }
// MsglvlSet returns the read-msglvl, post-set-msglvl of the given interface. func (e *Ethtool) MsglvlSet(intf string, valset uint32) (uint32, uint32, error) { edata := ethtoolValue{ cmd: ETHTOOL_GMSGLVL, } var name [IFNAMSIZ]byte copy(name[:], []byte(intf)) ifr := ifreq{ ifr_name: name, ifr_data: uintptr(unsafe.Pointer(&edata)), } _, _, ep := syscall.Syscall(syscall.SYS_IOCTL, uintptr(e.fd), SIOCETHTOOL, uintptr(unsafe.Pointer(&ifr))) if ep != 0 { return 0, 0, syscall.Errno(ep) } readval := edata.data edata.cmd = ETHTOOL_SMSGLVL edata.data = valset _, _, ep = syscall.Syscall(syscall.SYS_IOCTL, uintptr(e.fd), SIOCETHTOOL, uintptr(unsafe.Pointer(&ifr))) if ep != 0 { return 0, 0, syscall.Errno(ep) } return readval, edata.data, nil }
func (fd *netFD) connect(la, ra syscall.Sockaddr, deadline time.Time) error { // Do not need to call fd.writeLock here, // because fd is not yet accessible to user, // so no concurrent operations are possible. switch err := connectFunc(fd.sysfd, ra); err { case syscall.EINPROGRESS, syscall.EALREADY, syscall.EINTR: case nil, syscall.EISCONN: if !deadline.IsZero() && deadline.Before(time.Now()) { return errTimeout } if err := fd.init(); err != nil { return err } return nil case syscall.EINVAL: // On Solaris we can see EINVAL if the socket has // already been accepted and closed by the server. // Treat this as a successful connection--writes to // the socket will see EOF. For details and a test // case in C see https://golang.org/issue/6828. if runtime.GOOS == "solaris" { return nil } fallthrough default: return os.NewSyscallError("connect", err) } if err := fd.init(); err != nil { return err } if !deadline.IsZero() { fd.setWriteDeadline(deadline) defer fd.setWriteDeadline(noDeadline) } for { // Performing multiple connect system calls on a // non-blocking socket under Unix variants does not // necessarily result in earlier errors being // returned. Instead, once runtime-integrated network // poller tells us that the socket is ready, get the // SO_ERROR socket option to see if the connection // succeeded or failed. See issue 7474 for further // details. if err := fd.pd.WaitWrite(); err != nil { return err } nerr, err := getsockoptIntFunc(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_ERROR) if err != nil { return os.NewSyscallError("getsockopt", err) } switch err := syscall.Errno(nerr); err { case syscall.EINPROGRESS, syscall.EALREADY, syscall.EINTR: case syscall.Errno(0), syscall.EISCONN: return nil default: return os.NewSyscallError("getsockopt", err) } } }
func lookup(gid int, groupname string, lookupByName bool) (*Group, error) { var ( grp C.struct_group result *C.struct_group ) var bufSize C.long if runtime.GOOS == "freebsd" { // FreeBSD doesn't have _SC_GETPW_R_SIZE_MAX // and just returns -1. So just use the same // size that Linux returns bufSize = 1024 } else { bufSize = C.sysconf(C._SC_GETPW_R_SIZE_MAX) if bufSize <= 0 || bufSize > 1<<20 { return nil, fmt.Errorf( "user: unreasonable _SC_GETPW_R_SIZE_MAX of %d", bufSize) } } buf := C.malloc(C.size_t(bufSize)) defer C.free(buf) var rv C.int if lookupByName { nameC := C.CString(groupname) defer C.free(unsafe.Pointer(nameC)) rv = C.getgrnam_r(nameC, &grp, (*C.char)(buf), C.size_t(bufSize), &result) if rv != 0 { return nil, fmt.Errorf( "group: lookup groupname %s: %s", groupname, syscall.Errno(rv)) } if result == nil { return nil, UnknownGroupError(groupname) } } else { rv = C.mygetgrgid_r(C.int(gid), &grp, (*C.char)(buf), C.size_t(bufSize), &result) if rv != 0 { return nil, fmt.Errorf("group: lookup groupid %d: %s", gid, syscall.Errno(rv)) } if result == nil { return nil, UnknownGroupIdError(gid) } } g := &Group{ Gid: strconv.Itoa(int(grp.gr_gid)), Name: C.GoString(grp.gr_name), Members: getMembers(grp), } return g, nil }
// Change the coloring to c, but only in those bits where m is 1. func (w *Wrapper) SetMask(c Color, m uint16) error { current := w32.GetConsoleScreenBufferInfo(w.h) if current == nil { return syscall.Errno(w32.GetLastError()) } if !w32.SetConsoleTextAttribute(w.h, apply(current.WAttributes, uint16(c), uint16(m))) { return syscall.Errno(w32.GetLastError()) } return nil }
// GetUniqueValues returns all unique values for a given field. func (j *Journal) GetUniqueValues(field string) ([]string, error) { var result []string sd_journal_query_unique, err := getFunction("sd_journal_query_unique") if err != nil { return nil, err } sd_journal_enumerate_unique, err := getFunction("sd_journal_enumerate_unique") if err != nil { return nil, err } sd_journal_restart_unique, err := getFunction("sd_journal_restart_unique") if err != nil { return nil, err } j.mu.Lock() defer j.mu.Unlock() f := C.CString(field) defer C.free(unsafe.Pointer(f)) r := C.my_sd_journal_query_unique(sd_journal_query_unique, j.cjournal, f) if r < 0 { return nil, fmt.Errorf("failed to query journal: %d", syscall.Errno(-r)) } // Implements the SD_JOURNAL_FOREACH_UNIQUE macro from sd-journal.h var d unsafe.Pointer var l C.size_t C.my_sd_journal_restart_unique(sd_journal_restart_unique, j.cjournal) for { r = C.my_sd_journal_enumerate_unique(sd_journal_enumerate_unique, j.cjournal, &d, &l) if r == 0 { break } if r < 0 { return nil, fmt.Errorf("failed to read message field: %d", syscall.Errno(-r)) } msg := C.GoStringN((*C.char)(d), C.int(l)) kv := strings.SplitN(msg, "=", 2) if len(kv) < 2 { return nil, fmt.Errorf("failed to parse field") } result = append(result, kv[1]) } return result, nil }
// netstat -ano | findstr 202.89.233.104 func getTCPTable() *MIB_TCPTABLE2 { getTCPTable2 := syscall.NewLazyDLL("Iphlpapi.dll").NewProc("GetTcpTable2") var n uint32 if err, _, _ := getTCPTable2.Call(uintptr(unsafe.Pointer(&MIB_TCPTABLE2{})), uintptr(unsafe.Pointer(&n)), 1); syscall.Errno(err) != syscall.ERROR_INSUFFICIENT_BUFFER { common.Error("Error calling GetTcpTable2: %v", syscall.Errno(err)) } b := make([]byte, n) if err, _, _ := getTCPTable2.Call(uintptr(unsafe.Pointer(&b[0])), uintptr(unsafe.Pointer(&n)), 1); err != 0 { common.Error("Error calling GetTcpTable2: %v", syscall.Errno(err)) } table := newTCPTable(NewClassReader(b)) return table }
// The GetExtendedTcpTableIPv4 function retrieves a table that contains a list of TCP // endpoints available to the application. func GetExtendedTcpTableIPv4() (MIB_TCPTABLE_OWNER_PID, error) { var ( TcpTable MIB_TCPTABLE_OWNER_PID TcpTableSize uint32 ) TcpTableSize = uint32(unsafe.Sizeof(TcpTable)) tableSlice := make([]byte, TcpTableSize) r, _, _ := procGetExtendedTcpTable.Call( uintptr(unsafe.Pointer(&tableSlice[0])), uintptr(unsafe.Pointer(&TcpTableSize)), uintptr(0), uintptr(syscall.AF_INET), uintptr(TCP_TABLE_OWNER_PID_ALL), uintptr(0)) if syscall.Errno(r) == syscall.ERROR_INSUFFICIENT_BUFFER { tableSlice = make([]byte, TcpTableSize) r, _, _ = procGetExtendedTcpTable.Call( uintptr(unsafe.Pointer(&tableSlice[0])), uintptr(unsafe.Pointer(&TcpTableSize)), uintptr(0), uintptr(syscall.AF_INET), uintptr(TCP_TABLE_OWNER_PID_ALL), uintptr(0)) } buf := bytes.NewReader(tableSlice) err := binary.Read(buf, binary.LittleEndian, &TcpTable.NumEntries) if err != nil { return TcpTable, err } TcpTable.Table = make([]MIB_TCPROW_OWNER_PID, TcpTable.NumEntries) for i := 0; i < int(TcpTable.NumEntries); i++ { err := binary.Read(buf, binary.LittleEndian, &TcpTable.Table[i]) if err != nil { break } } if r != 0 { return TcpTable, syscall.Errno(r) } return TcpTable, nil }
func lookupUnix(gid int, groupname string, lookupByName bool) (*Group, error) { var grp C.struct_group var result *C.struct_group var bufSize C.long if runtime.GOOS == "freebsd" { panic("Don't know how to deal with freebsd.") } else { bufSize = C.sysconf(C._SC_GETGR_R_SIZE_MAX) * 20 if bufSize <= 0 || bufSize > 1<<20 { return nil, fmt.Errorf("group: unreasonable _SC_GETGR_R_SIZE_MAX of %d", bufSize) } } buf := C.malloc(C.size_t(bufSize)) defer C.free(buf) var rv C.int if lookupByName { nameC := C.CString(groupname) defer C.free(unsafe.Pointer(nameC)) rv = C.mygetgrnam_r(nameC, &grp, (*C.char)(buf), C.size_t(bufSize), &result) if rv != 0 { return nil, fmt.Errorf("group: lookup groupname %s: %s", groupname, syscall.Errno(rv)) } if result == nil { return nil, UnknownGroupError(groupname) } } else { rv = C.mygetgrgid_r(C.int(gid), &grp, (*C.char)(buf), C.size_t(bufSize), &result) if rv != 0 { return nil, fmt.Errorf("group: lookup groupid %d: %s", gid, syscall.Errno(rv)) } if result == nil { return nil, UnknownGroupIdError(gid) } } u := &Group{ Gid: strconv.Itoa(int(grp.gr_gid)), Groupname: C.GoString(grp.gr_name), } return u, nil }
// this is close to the connect() function inside stdlib/net func connect(fd int, ra syscall.Sockaddr, deadline time.Time) error { switch err := syscall.Connect(fd, ra); err { case syscall.EINPROGRESS, syscall.EALREADY, syscall.EINTR: case nil, syscall.EISCONN: if !deadline.IsZero() && deadline.Before(time.Now()) { return errTimeout } return nil default: return err } poller, err := poll.New(fd) if err != nil { return err } defer poller.Close() for { if err = poller.WaitWrite(deadline); err != nil { return err } // if err := fd.pd.WaitWrite(); err != nil { // return err // } // i'd use the above fd.pd.WaitWrite to poll io correctly, just like net sockets... // but of course, it uses the damn runtime_* functions that _cannot_ be used by // non-go-stdlib source... seriously guys, this is not nice. // we're relegated to using syscall.Select (what nightmare that is) or using // a simple but totally bogus time-based wait. such garbage. var nerr int nerr, err = syscall.GetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_ERROR) if err != nil { return err } switch err = syscall.Errno(nerr); err { case syscall.EINPROGRESS, syscall.EALREADY, syscall.EINTR: continue case syscall.Errno(0), syscall.EISCONN: if !deadline.IsZero() && deadline.Before(time.Now()) { return errTimeout } return nil default: return err } } }
func makeFlushFS() (server fuse.Server, err error) { // Check the flags. if *fFlushesFile == 0 || *fFsyncsFile == 0 { err = fmt.Errorf("You must set the flushfs flags.") return } // Set up the files. flushes := os.NewFile(uintptr(*fFlushesFile), "(flushes file)") fsyncs := os.NewFile(uintptr(*fFsyncsFile), "(fsyncs file)") // Set up errors. var flushErr error var fsyncErr error if *fFlushError != 0 { flushErr = syscall.Errno(*fFlushError) } if *fFsyncError != 0 { fsyncErr = syscall.Errno(*fFsyncError) } // Report flushes and fsyncs by writing the contents followed by a newline. report := func(f *os.File, outErr error) func(string) error { return func(s string) (err error) { buf := []byte(s) buf = append(buf, '\n') _, err = f.Write(buf) if err != nil { err = fmt.Errorf("Write: %v", err) return } err = outErr return } } reportFlush := report(flushes, flushErr) reportFsync := report(fsyncs, fsyncErr) // Create the file system. server, err = flushfs.NewFileSystem(reportFlush, reportFsync) return }
func BtrfsReflink(fd_out, fd_in uintptr) error { res := C.btrfs_reflink(C.int(fd_out), C.int(fd_in)) if res != 0 { return syscall.Errno(res) } return nil }
// CmdGetMapped returns the interface settings in a map func (e *Ethtool) CmdGetMapped(intf string) (map[string]uint64, error) { ecmd := EthtoolCmd{ Cmd: ETHTOOL_GSET, } var name [IFNAMSIZ]byte copy(name[:], []byte(intf)) ifr := ifreq{ ifr_name: name, ifr_data: uintptr(unsafe.Pointer(&ecmd)), } _, _, ep := syscall.Syscall(syscall.SYS_IOCTL, uintptr(e.fd), SIOCETHTOOL, uintptr(unsafe.Pointer(&ifr))) if ep != 0 { return nil, syscall.Errno(ep) } var result = make(map[string]uint64) // ref https://gist.github.com/drewolson/4771479 // Golang Reflection Example ecmd.reflect(&result) var speedval uint32 = (uint32(ecmd.Speed_hi) << 16) | (uint32(ecmd.Speed) & 0xffff) result["speed"] = uint64(speedval) return result, nil }
func RegEnumValue(key syscall.Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, value *uint16, valueLen *uint32) (regerrno error) { r0, _, _ := syscall.Syscall9(procRegEnumValueW.Addr(), 8, uintptr(key), uintptr(index), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(value)), uintptr(unsafe.Pointer(valueLen)), 0) if r0 != 0 { regerrno = syscall.Errno(r0) } return }
// Serve serves the FUSE connection by making calls to the methods // of fs and the Nodes and Handles it makes available. It returns only // when the connection has been closed or an unexpected error occurs. func (s *Server) Serve(c *fuse.Conn) error { sc := serveConn{ fs: s.FS, debug: s.Debug, req: map[fuse.RequestID]*serveRequest{}, dynamicInode: GenerateDynamicInode, } if sc.debug == nil { sc.debug = fuse.Debug } if dyn, ok := sc.fs.(FSInodeGenerator); ok { sc.dynamicInode = dyn.GenerateInode } root, err := sc.fs.Root() if err != nil { return fmt.Errorf("cannot obtain root node: %v", syscall.Errno(err.(fuse.Errno)).Error()) } sc.node = append(sc.node, nil, &serveNode{inode: 1, node: root, refs: 1}) sc.handle = append(sc.handle, nil) for { req, err := c.ReadRequest() if err != nil { if err == io.EOF { break } return err } go sc.serve(req) } return nil }
// Because Go is like... naaaaa, no groups aren't a thing! // Based on Go's src/os/user/lookup_unix.go func currentUserAndGroup() (*userAndGroup, error) { u, err := user.Current() if err != nil { return nil, err } gid, err := strconv.Atoi(u.Gid) if err != nil { return nil, err } var grp C.struct_group var result *C.struct_group buflen := C.sysconf(C._SC_GETPW_R_SIZE_MAX) if buflen <= 0 || buflen > 1<<20 { return nil, fmt.Errorf("unreasonable _SC_GETGR_R_SIZE_MAX of %d", buflen) } buf := C.malloc(C.size_t(buflen)) defer C.free(buf) r := C.mygetgrgid_r(C.gid_t(gid), &grp, (*C.char)(buf), C.size_t(buflen), &result) if r != 0 { return nil, fmt.Errorf("lookup gid %d: %s", gid, syscall.Errno(r)) } if result == nil { return nil, fmt.Errorf("lookup gid %d failed", gid) } return &userAndGroup{ User: u, Groupname: C.GoString(grp.gr_name), }, nil }
func unmap(addr, len uintptr) error { _, _, errno := syscall.Syscall(syscall.SYS_MUNMAP, addr, len, 0) if errno != 0 { return syscall.Errno(errno) } return nil }
func lock(addr, len uintptr) error { _, _, errno := syscall.Syscall(syscall.SYS_MLOCK, addr, len, 0) if errno != 0 { return syscall.Errno(errno) } return nil }
func flush(addr, len uintptr) error { _, _, errno := syscall.Syscall(syscall.SYS_MSYNC, addr, len, syscall.MS_SYNC) if errno != 0 { return syscall.Errno(errno) } return nil }
func open(c *Conn) error { var err error c.file, err = os.OpenFile("/dev/net/tun", os.O_RDWR, 0) if err != nil { return err } ifr := &ifReq{} ifr.Flags = iff_TUN | iff_NO_PI | iff_TUN_EXCL _, _, e := syscall.Syscall(syscall.SYS_IOCTL, c.file.Fd(), tunSETIFF, uintptr(unsafe.Pointer(ifr))) if e != 0 { return syscall.Errno(e) } i := 0 for ifr.Name[i] != 0 { i++ } s := string(ifr.Name[:i]) ifi, err := net.InterfaceByName(s) if err != nil { c.file.Close() return err } c.ifindex = ifi.Index return nil }
func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) { r0, _, _ := syscall.Syscall6(procGetAdaptersAddresses.Addr(), 5, uintptr(family), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(adapterAddresses)), uintptr(unsafe.Pointer(sizePointer)), 0) if r0 != 0 { errcode = syscall.Errno(r0) } return }
func NetShareDel(serverName *uint16, netName *uint16, reserved uint32) (neterr error) { r0, _, _ := syscall.Syscall(procNetShareDel.Addr(), 3, uintptr(unsafe.Pointer(serverName)), uintptr(unsafe.Pointer(netName)), uintptr(reserved)) if r0 != 0 { neterr = syscall.Errno(r0) } return }
func NetShareAdd(serverName *uint16, level uint32, buf *byte, parmErr *uint16) (neterr error) { r0, _, _ := syscall.Syscall6(procNetShareAdd.Addr(), 4, uintptr(unsafe.Pointer(serverName)), uintptr(level), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(parmErr)), 0, 0) if r0 != 0 { neterr = syscall.Errno(r0) } return }
// CurrentUnitName attempts to retrieve the name of the systemd system unit // from which the calling process has been invoked. It wraps the systemd // `sd_pid_get_unit` call, with the same caveat: for processes not part of a // systemd system unit, this function will return an error. func CurrentUnitName() (unit string, err error) { var h *libHandle h, err = getHandle() if err != nil { return } defer func() { if err1 := h.Close(); err1 != nil { err = err1 } }() sym := C.CString("sd_pid_get_unit") defer C.free(unsafe.Pointer(sym)) sd_pid_get_unit := C.dlsym(h.handle, sym) if sd_pid_get_unit == nil { err = fmt.Errorf("error resolving sd_pid_get_unit function") return } var s string u := C.CString(s) defer C.free(unsafe.Pointer(u)) ret := C.my_sd_pid_get_unit(sd_pid_get_unit, 0, &u) if ret < 0 { err = fmt.Errorf("error calling sd_pid_get_unit: %v", syscall.Errno(-ret)) return } unit = C.GoString(u) return }
// GetRunningSlice attempts to retrieve the name of the systemd slice in which // the current process is running. // This function is a wrapper around the libsystemd C library; if it cannot be // opened, an error is returned. func GetRunningSlice() (slice string, err error) { var h *libHandle h, err = getHandle() if err != nil { return } defer func() { if err1 := h.Close(); err1 != nil { err = err1 } }() sym := C.CString("sd_pid_get_slice") defer C.free(unsafe.Pointer(sym)) sd_pid_get_slice := C.dlsym(h.handle, sym) if sd_pid_get_slice == nil { err = fmt.Errorf("error resolving sd_pid_get_slice function") return } var s string sl := C.CString(s) defer C.free(unsafe.Pointer(sl)) ret := C.my_sd_pid_get_slice(sd_pid_get_slice, 0, &sl) if ret < 0 { err = fmt.Errorf("error calling sd_pid_get_slice: %v", syscall.Errno(-ret)) return } return C.GoString(sl), nil }
func PtraceDetach(tid, sig int) error { _, _, err := sys.Syscall6(sys.SYS_PTRACE, sys.PT_DETACH, uintptr(tid), 1, uintptr(sig), 0, 0) if err != syscall.Errno(0) { return err } return nil }