func getProcAddr(lib syscall.Handle, name string) uintptr { addr, err := syscall.GetProcAddress(lib, name) if err != 0 { panic(name + " " + syscall.Errstr(err)) } return addr }
func lastError(win32FuncName string) os.Error { if errno := GetLastError(); errno != ERROR_SUCCESS { return newError(fmt.Sprintf("%s: %s", win32FuncName, syscall.Errstr(int(errno)))) } return nil }
func MustLoadLibrary(name string) uint32 { lib, errno := syscall.LoadLibrary(name) if errno != 0 { panic(fmt.Sprintf(`syscall.LoadLibrary("%s") failed: %s`, name, syscall.Errstr(errno))) } return lib }
func MustGetProcAddress(lib uintptr, name string) uintptr { addr, errno := syscall.GetProcAddress(syscall.Handle(lib), name) if errno != 0 { panic(fmt.Sprintf(`syscall.GetProcAddress(%d, "%s") failed: %s`, lib, name, syscall.Errstr(errno))) } return uintptr(addr) }
func readAndPrint(fd int, buf []byte) { _, errno := syscall.Read(fd, buf) if errno != 0 { fmt.Printf("readAndPrint: %v: %v\n", errno, syscall.Errstr(errno)) os.Exit(1) } println(string(buf)) }
func MustGetProcAddress(lib uint32, name string) uint32 { addr, errno := syscall.GetProcAddress(lib, name) if errno != 0 { panic(fmt.Sprintf(`syscall.GetProcAddress(%d, "%s") failed: %s`, lib, name, syscall.Errstr(errno))) } return addr }
func reffile(filename string) (int64, int64) { var st syscall.Stat_t if e := syscall.Stat(filename, &st); e != 0 { fmt.Fprintf(os.Stderr, "stat: Error %s\n", syscall.Errstr(e)) os.Exit(1) } //FIXME: bug in Go! Amd64 has following rest have Atimespec and Mtimespec return st.Atim.Sec, st.Mtim.Sec }
func cgoLookupIPCNAME(name string) (addrs []IP, cname string, err os.Error, completed bool) { var res *syscall.Addrinfo var hints syscall.Addrinfo // NOTE(rsc): In theory there are approximately balanced // arguments for and against including AI_ADDRCONFIG // in the flags (it includes IPv4 results only on IPv4 systems, // and similarly for IPv6), but in practice setting it causes // getaddrinfo to return the wrong canonical name on Linux. // So definitely leave it out. hints.Ai_flags = int32((syscall.AI_ALL | syscall.AI_V4MAPPED | syscall.AI_CANONNAME) & cgoAddrInfoMask()) h := syscall.StringBytePtr(name) gerrno := libc_getaddrinfo(h, nil, &hints, &res) if gerrno != 0 { var str string if gerrno == syscall.EAI_NONAME { str = noSuchHost } else if gerrno == syscall.EAI_SYSTEM { str = syscall.Errstr(syscall.GetErrno()) } else { str = bytePtrToString(libc_gai_strerror(gerrno)) } return nil, "", &DNSError{Error: str, Name: name}, true } defer libc_freeaddrinfo(res) if res != nil { cname = bytePtrToString((*byte)(unsafe.Pointer(res.Ai_canonname))) if cname == "" { cname = name } if len(cname) > 0 && cname[len(cname)-1] != '.' { cname += "." } } for r := res; r != nil; r = r.Ai_next { // Everything comes back twice, once for UDP and once for TCP. if r.Ai_socktype != syscall.SOCK_STREAM { continue } switch r.Ai_family { default: continue case syscall.AF_INET: sa := (*syscall.RawSockaddrInet4)(unsafe.Pointer(r.Ai_addr)) addrs = append(addrs, copyIP(sa.Addr[:])) case syscall.AF_INET6: sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(r.Ai_addr)) addrs = append(addrs, copyIP(sa.Addr[:])) } } return addrs, cname, nil, true }
func main() { fds, errno := syscall.Socketpair(syscall.AF_UNIX, syscall.SOCK_STREAM, 0) if errno != 0 { fmt.Printf("mycat: socketpair: %v: %v\n", errno, syscall.Errstr(errno)) os.Exit(errno) } fd0, fd1 := fds[0], fds[1] syscall.CloseOnExec(fd0) bin := "./openfile/openfile" argv := []string{bin, strconv.Itoa(fd1), os.Args[1]} pid, errno := syscall.ForkExec(bin, argv, nil) if errno != 0 { fmt.Printf("getFdFromChild: ForkExec: %v\n", syscall.Errstr(errno)) os.Exit(1) } syscall.Close(fd1) getFdFromChild(pid, fd0) syscall.Close(fd0) }
func startServer() { resultsrv = new(resultSrv) var errno int resultsrv.iocp, errno = syscall.CreateIoCompletionPort(syscall.InvalidHandle, 0, 0, 1) if errno != 0 { panic("CreateIoCompletionPort failed " + syscall.Errstr(errno)) } go resultsrv.Run() iosrv = new(ioSrv) iosrv.submchan = make(chan anOpIface) iosrv.canchan = make(chan anOpIface) go iosrv.ProcessRemoteIO() }
func init() { k32, err := syscall.LoadLibrary("kernel32.dll") if err != 0 { panic("LoadLibrary " + syscall.Errstr(err)) } defer syscall.FreeLibrary(k32) nSetCommState = getProcAddr(k32, "SetCommState") nSetCommTimeouts = getProcAddr(k32, "SetCommTimeouts") nSetCommMask = getProcAddr(k32, "SetCommMask") nSetupComm = getProcAddr(k32, "SetupComm") nGetOverlappedResult = getProcAddr(k32, "GetOverlappedResult") nCreateEvent = getProcAddr(k32, "CreateEventW") nResetEvent = getProcAddr(k32, "ResetEvent") }
func (self Timer) Start(verbose bool) (err os.Error) { if verbose { fmt.Printf("Pid %d : waiting for %f seconds to send %d\n", self.Pid, self.tickSecs(), self.Signal) } time.Sleep(self.Ticks) eno := syscall.Kill(self.Pid, self.Signal) if self.Signal > 0 && eno != 0 { err = os.NewError(syscall.Errstr(eno)) if verbose { fmt.Printf("Pid %d : Couldn't signal: %v\n", self.Pid, err) } } else if self.Signal == 0 && eno == 0 { err = os.NewError(fmt.Sprintf("alive after %f seconds\n", self.tickSecs())) fmt.Printf("Pid %d : %s", self.Pid, err.String()) } return }
func init() { // Library libole32 = MustLoadLibrary("ole32.dll") // Functions coGetClassObject = MustGetProcAddress(libole32, "CoGetClassObject") oleInitialize = MustGetProcAddress(libole32, "OleInitialize") oleSetContainedObject = MustGetProcAddress(libole32, "OleSetContainedObject") oleUninitialize = MustGetProcAddress(libole32, "OleUninitialize") // Initialize OLE stuff // FIXME: Find a way to call OleUninitialize at app shutdown // Maybe we should require explicit walk.Initialize/walk.Shutdown? if hr := OleInitialize(); FAILED(hr) { panic("OleInitialize Error: " + syscall.Errstr(int(hr))) } }
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, syscall.INFINITE) switch { case r.err == 0: // Dequeued successfully completed io packet. case r.err == 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 " + syscall.Errstr(r.err)) default: // Dequeued failed io packet. } (*anOp)(unsafe.Pointer(o)).resultc <- r } }
func getFdFromChild(pid, fd int) { var wstatus syscall.WaitStatus _, errno := syscall.Wait4(pid, &wstatus, 0, nil) if errno != 0 { fmt.Printf("getFdFromChild: Wait4: %v: %v\n", errno, syscall.Errstr(errno)) os.Exit(1) } if wstatus.ExitStatus() != 0 { fmt.Printf("openfile exited(%v) with status %v\n", wstatus.Exited(), wstatus.ExitStatus()) os.Exit(1) } var smallbuf [10]byte var largebuf [4096]byte readAndPrint(fd, smallbuf[:]) recvfd, err := fdpass.Receive(fd) if err != nil { fmt.Printf("getFdFromChild: fdpass.Receive: %v\n", err) os.Exit(1) } readAndPrint(recvfd, largebuf[:]) readAndPrint(fd, smallbuf[:]) }
func getTunTap(flags uint16) (tunfile *os.File, tundevice string, err os.Error) { var ifr IfreqFlags ifr.Flags = flags tunfile, err = os.OpenFile("/dev/net/tun", os.O_RDWR, 0666) if err != nil { return } _, _, errnop := syscall.Syscall(syscall.SYS_IOCTL, uintptr(tunfile.Fd()), uintptr(syscall.TUNSETIFF), uintptr(unsafe.Pointer(&ifr))) errno := int(errnop) if errno != 0 { err = os.NewError(syscall.Errstr(errno)) return } strlen := 16 for ; strlen > 0; strlen-- { if ifr.Name[strlen-1] != 0 { break } } tundevice = string(ifr.Name[0:strlen]) return }
func main() { flag.Parse() if flag.NArg() < 1 { fmt.Printf("USAGE: alarm [--alarmopts] CMD cmdflags\n") os.Exit(die_USAGE) } if *flag_squelch && *flag_log_stdout == "" { *flag_log_stdout = "memory" } if *flag_squelch && *flag_log_stderr == "" { *flag_log_stderr = "memory" } args := flag.Args() if *flag_arg0 == "" { *flag_arg0 = flag.Arg(0) } else { args = args[1:] } // We use a buffered channel so that we don't have to check intent to signal end of proc. iodone := make(chan int, 1) var memfd *os.File var memcloser io.Closer var err os.Error var membuffer *bytes.Buffer if *flag_log_stdout == "memory" || *flag_log_stderr == "memory" { membuffer = bytes.NewBuffer(make([]byte, 1024*(*flag_buff_size))) memfd, memcloser, err = memFD(membuffer) if err != nil { fmt.Printf("Couldn't setup memory FD: %v", err) os.Exit(die_FDSETUP) } go func() { io.Copy(membuffer, memfd) }() } files, close_local, err := procFileDescriptors(memfd, iodone) if err != nil { fmt.Printf("Couldn't setup file descriptors: %v", err) os.Exit(die_FDSETUP) } arg0 := Which(*flag_arg0, strings.Split(os.Getenv("PATH"), ":", -1)) if arg0 != *flag_arg0 && *flag_verbose { fmt.Printf("Implied arg0: (%s) => %s\n", *flag_arg0, arg0) } timers := []*Timer{} timer_strings := strings.Split(*flag_timeout, ",", -1) for ti := range timer_strings { if timer_strings[ti] == "" { continue } t, err := NewTimerString(timer_strings[ti]) if err != nil { fmt.Printf("Couldn't parse timer string '%s': %v\n", timer_strings[ti], err) os.Exit(die_BADTIMESPEC) } if t.Ticks > 0 { timers = append(timers, t) } else { if *flag_verbose { fmt.Printf("WARN: Ignoring useless timer %s\n", timer_strings[ti]) } } } pid, eno := syscall.ForkExec(arg0, args, &syscall.ProcAttr{ Dir: os.Getenv("PWD"), Env: os.Environ(), Files: files, }) if eno != 0 { fmt.Printf("There was an error running the command: %s\n", syscall.Errstr(eno)) os.Exit(die_EXEC) } for t := range timers { timers[t].Pid = pid go timers[t].Start(*flag_verbose) } // The process has started, so we close our dup()'s of the FIFO (if any) if memcloser != nil { memcloser.Close() } close_local() wmsg, err := os.Wait(pid, 0) iodone <- 1 if err != nil { fmt.Printf("There was an error waiting for pid: %v", err) os.Exit(die_WAITERROR) } if *flag_verbose { fmt.Printf("PID: %d exited with status %d\n", pid, wmsg.ExitStatus()) } if (wmsg.ExitStatus() != 0 && *flag_dump_log == "onerror") || (*flag_dump_log == "always") && (*flag_log_stdout == "memory" || *flag_log_stderr == "memory") { if *flag_verbose { fmt.Printf("Dumping logs [%d]\n----------\n", wmsg.ExitStatus()) } if membuffer != nil { _, err = io.Copy(os.Stdout, membuffer) } else { } if *flag_verbose { fmt.Printf("\n----------\nLogs complete: %v", err) } } // We're ok, but we'd like to bubble up the status os.Exit(wmsg.ExitStatus()) }
// dialExec will ForkExec a new process, and returns a wsConn that connects to its stdin func dialExec(binpath string) (rwc io.ReadWriteCloser, err os.Error) { listenBacklog := 1024 dir, file := path.Split(binpath) socketPath := "/tmp/" + file + ".sock" socketIndex := 0 // if the first socket is really in use (we are launching this same process more than once) // then the socketIndex will start incrementing so we assign .sock-1 to the second process, etc for { err := os.Remove(socketPath) // if the socket file is stale, but not in use, the Remove succeeds with no error if err == nil { goto haveSocket // success, found a stale socket we can re-use } // otherwise we have to check what the error was switch err.String() { case "remove " + socketPath + ": no such file or directory": goto haveSocket // success, we have found an unused socket. default: // if its really in use, we start incrementing socketIndex socketIndex += 1 socketPath = "/tmp/" + file + ".sock-" + strconv.Itoa(socketIndex) Log("Socket was in use, trying:", socketPath) } } haveSocket: var fd, cfd, errno int var sa syscall.Sockaddr // we can almost use UnixListener to do this except it doesn't expose the fd it's listening on // create a new socket if fd, errno = syscall.Socket(syscall.AF_UNIX, syscall.SOCK_STREAM, 0); errno != 0 { Log("Creating first new socket failed:", syscall.Errstr(errno)) return nil, os.NewError(fmt.Sprint("Creating first new socket failed:", syscall.Errstr(errno))) } // bind the new socket to socketPath if errno = syscall.Bind(fd, &syscall.SockaddrUnix{Name: socketPath}); errno != 0 { Log("Bind failed:", syscall.Errstr(errno)) return nil, os.NewError(fmt.Sprint("Bind failed:", syscall.Errstr(errno))) } // start to listen on that socket if errno = syscall.Listen(fd, listenBacklog); errno != 0 { Log("Listen failed:", syscall.Errstr(errno)) return nil, os.NewError(fmt.Sprint("Listen failed:", syscall.Errstr(errno))) } // then ForkExec a new process, and give this listening socket to them as stdin // DEBUG: for now, give the new process our stdout, and stderr, but the spec says these should be closed // in reality, we should redirect, capture, and possibly log separately if _, errno = syscall.ForkExec(file, []string{}, []string{}, dir, []int{fd, 1, 2}); errno != 0 { Log("ForkExec failed:", syscall.Errstr(errno)) return nil, os.NewError(fmt.Sprint("ForkExec failed:", syscall.Errstr(errno))) } // now create a socket for the client-side of the connection if cfd, errno = syscall.Socket(syscall.AF_UNIX, syscall.SOCK_STREAM, 0); errno != 0 { Log("Creating new socket on webserver failed:", syscall.Errstr(errno)) return nil, os.NewError(fmt.Sprint("Creating new socket on webserver failed:", syscall.Errstr(errno))) } // find the address of the socket we gave the new process if sa, errno = syscall.Getsockname(fd); errno != 0 { Log("Getsockname failed:", syscall.Errstr(errno)) return nil, os.NewError(fmt.Sprint("Getsockname failed:", syscall.Errstr(errno))) } // connect our client side to the remote address if errno = syscall.Connect(cfd, sa); errno != 0 { Log("Connect failed:", syscall.Errstr(errno)) return nil, os.NewError(fmt.Sprint("Connect failed:", syscall.Errstr(errno))) } // return a wrapper around the client side of this connection rwc = os.NewFile(cfd, "exec://"+binpath) return rwc, nil }
func errorFromHRESULT(funcName string, hr HRESULT) os.Error { return newError(fmt.Sprintf("%s: %s", funcName, syscall.Errstr(int(hr)))) }
func abort(funcname string, err int) { panic(funcname + " failed: " + syscall.Errstr(err)) }
func (_error *error) String() string { return fmt.Sprintf("%s (`%s` [%d]) -> (`%s` [%d])", _error.syscall, _error.path, _error.descriptor, syscall.Errstr(_error.errno), _error.errno) }
func abortErrNo(funcname string, err int) { abortf("%s failed: %d %s\n", funcname, err, syscall.Errstr(err)) }
// dialExec will ForkExec a new process, and returns a wsConn that connects to its // stdin func dialExec(binpath string) (io.ReadWriteCloser, os.Error) { listenBacklog := 1024 dir, file := path.Split(binpath) socketPath := "/tmp/" + file + ".sock" // if the first socket is really in use (we are launching this same process more // than once) then the socketIndex will start incrementing so we assign .sock-1 // to the second process, etc socketIndex := 0 err := os.Remove(socketPath) // if the socket file is stale but not in use, // Remove succeeds with no error for err != nil { pe, ok := err.(*os.PathError) if ok && pe.Error == os.ENOENT { // success, found a stale socket we can re-use break } // if it's really in use, we start incrementing socketIndex socketIndex++ socketPath = "/tmp/" + file + ".sock-" + strconv.Itoa(socketIndex) Log("Socket was in use, trying:", socketPath) err = os.Remove(socketPath) } var fd, cfd, errno int var sa syscall.Sockaddr // we can almost use UnixListener to do this except it doesn't expose the fd // it's listening on // create a new socket if fd, errno = syscall.Socket(syscall.AF_UNIX, syscall.SOCK_STREAM, 0); errno != 0 { msg := "Creating first new socket failed: " + syscall.Errstr(errno) Log(msg) return nil, os.NewError(msg) } // bind the new socket to socketPath if errno = syscall.Bind(fd, &syscall.SockaddrUnix{Name: socketPath}); errno != 0 { msg := "Bind failed: " + syscall.Errstr(errno) Log(msg) return nil, os.NewError(msg) } // start to listen on that socket if errno = syscall.Listen(fd, listenBacklog); errno != 0 { msg := "Listen failed: " + syscall.Errstr(errno) Log(msg) return nil, os.NewError(msg) } // then ForkExec a new process, and give this listening socket to them as stdin // DEBUG: for now, give the new process our stdout, and stderr, but the spec // says these should be closed // in reality, we should redirect, capture, and possibly log separately if _, errno = syscall.ForkExec(file, []string{}, []string{}, dir, []int{fd, 1, 2}); errno != 0 { msg := "ForkExec failed: " + syscall.Errstr(errno) Log(msg) return nil, os.NewError(msg) } // now create a socket for the client-side of the connection if cfd, errno = syscall.Socket(syscall.AF_UNIX, syscall.SOCK_STREAM, 0); errno != 0 { msg := "Creating new socket on webserved failed: " + syscall.Errstr(errno) Log(msg) return nil, os.NewError(msg) } // find the address of the socket we gave the new process if sa, errno = syscall.Getsockname(fd); errno != 0 { msg := "Getsockname failed: " + syscall.Errstr(errno) Log(msg) return nil, os.NewError(msg) } // connect our client side to the remote address if errno = syscall.Connect(cfd, sa); errno != 0 { msg := "Connected failed: " + syscall.Errstr(errno) Log(msg) return nil, os.NewError(msg) } // return a wrapper around the client side of this connection rwc := os.NewFile(cfd, "exec://"+binpath) return rwc, nil }
func toErr(eno int) (err os.Error) { if eno != 0 { err = os.NewError(syscall.Errstr(eno)) } return }
func (e Errno) String() string { return syscall.Errstr(int(e)) }
// Implements os.Error by using syscall.Errstr(-Code()) func (self Error) String() string { return syscall.Errstr(int(-self.Code())) }