Exemplo n.º 1
0
func ext۰os۰Pipe(fr *frame, args []value) value {
	// This is an inlining of linux's os.Pipe.
	// func os.Pipe() (r *File, w *File, err error)
	var p [2]int
	if err := syscall.Pipe2(p[:], syscall.O_CLOEXEC); err != nil {
		// TODO(adonovan): fix: return an *os.SyscallError.
		return tuple{nil, nil, wrapError(err)}
	}

	NewFile := fr.i.prog.ImportedPackage("os").Func("NewFile")
	r := call(fr.i, fr, 0, NewFile, []value{uintptr(p[0]), "|0"})
	w := call(fr.i, fr, 0, NewFile, []value{uintptr(p[1]), "|1"})
	return tuple{r, w, wrapError(nil)}
}
Exemplo n.º 2
0
// Create a new inotify poller.
// This creates an inotify handler, and an epoll handler.
func newFdPoller(fd int) (*fdPoller, error) {
	var errno error
	poller := emptyPoller(fd)
	defer func() {
		if errno != nil {
			poller.close()
		}
	}()
	poller.fd = fd

	// Create epoll fd
	poller.epfd, errno = syscall.EpollCreate1(0)
	if poller.epfd == -1 {
		return nil, errno
	}
	// Create pipe; pipe[0] is the read end, pipe[1] the write end.
	errno = syscall.Pipe2(poller.pipe[:], syscall.O_NONBLOCK)
	if errno != nil {
		return nil, errno
	}

	// Register inotify fd with epoll
	event := syscall.EpollEvent{
		Fd:     int32(poller.fd),
		Events: syscall.EPOLLIN,
	}
	errno = syscall.EpollCtl(poller.epfd, syscall.EPOLL_CTL_ADD, poller.fd, &event)
	if errno != nil {
		return nil, errno
	}

	// Register pipe fd with epoll
	event = syscall.EpollEvent{
		Fd:     int32(poller.pipe[0]),
		Events: syscall.EPOLLIN,
	}
	errno = syscall.EpollCtl(poller.epfd, syscall.EPOLL_CTL_ADD, poller.pipe[0], &event)
	if errno != nil {
		return nil, errno
	}

	return poller, nil
}
Exemplo n.º 3
0
// Pipe returns a connected pair of Files; reads from r return bytes written to w.
// It returns the files and an error, if any.
func Pipe() (r *File, w *File, err error) {
	var p [2]int

	e := syscall.Pipe2(p[0:], syscall.O_CLOEXEC)
	// pipe2 was added in 2.6.27 and our minimum requirement is 2.6.23, so it
	// might not be implemented.
	if e == syscall.ENOSYS {
		// See ../syscall/exec.go for description of lock.
		syscall.ForkLock.RLock()
		e = syscall.Pipe(p[0:])
		if e != nil {
			syscall.ForkLock.RUnlock()
			return nil, nil, NewSyscallError("pipe", e)
		}
		syscall.CloseOnExec(p[0])
		syscall.CloseOnExec(p[1])
		syscall.ForkLock.RUnlock()
	} else if e != nil {
		return nil, nil, NewSyscallError("pipe2", e)
	}

	return NewFile(uintptr(p[0]), "|0"), NewFile(uintptr(p[1]), "|1"), nil
}
Exemplo n.º 4
0
Arquivo: main.go Projeto: rhenium/poe
func main() {
	runtime.GOMAXPROCS(8)
	dec := json.NewDecoder(os.Stdin)
	var plan plan
	if err := dec.Decode(&plan); err != nil {
		panic(fmt.Sprintf("failed to parse plan: %s", err))
	}
	//fmt.Fprintf(os.Stderr, "plan: %+v\n", plan)

	runtime.LockOSThread()
	if err := syscall.Setresuid(0, 0, 0); err != nil {
		poePanic(err, "setuid failed")
	}
	if err := InitializeSystemdBus(); err != nil {
		poePanic(err, "failed to connect to systemd")
	}
	runtime.UnlockOSThread()

	rootdir, errx := PlaygroundCreate(plan.Base, plan.Compiler.Overlay)
	if errx != nil {
		poePanic(errx, "playground_create failed")
	}

	progfile, errx := PlaygroundCopy(rootdir, plan.Source)
	if errx != nil {
		poePanic(errx, "playground_copy failed")
	}

	var stdin_fd, stdout_fd, stderr_fd [2]int
	if err := syscall.Pipe2(stdin_fd[:], 0); err != nil {
		poePanic(err, "pipe2 failed")
	}
	if err := syscall.Pipe2(stdout_fd[:], syscall.O_DIRECT); err != nil {
		poePanic(err, "pipe2 failed")
	}
	if err := syscall.Pipe2(stderr_fd[:], syscall.O_DIRECT); err != nil {
		poePanic(err, "pipe2 failed")
	}

	pid_, _, err := syscall.Syscall(syscall.SYS_CLONE, uintptr(syscall.SIGCHLD|syscall.CLONE_NEWIPC|syscall.CLONE_NEWNS|syscall.CLONE_NEWPID|syscall.CLONE_NEWUTS|syscall.CLONE_NEWNET), 0, 0)
	pid := int(pid_)
	if err != 0 {
		poePanic(error(err), "clone failed")
	} else if pid == 0 {
		runtime.LockOSThread()
		if err, msg := doChild(rootdir, progfile, plan, stdin_fd, stdout_fd, stderr_fd); err != nil {
			fmt.Fprintf(os.Stderr, "%s (%s)", msg, err.Error())
			os.Exit(127)
		}
		// unreachable
	} else {
		res := doParent(pid, stdin_fd, stdout_fd, stderr_fd)
		cleanup()
		var buf bytes.Buffer
		binary.Write(&buf, binary.LittleEndian, int32(res.result))
		binary.Write(&buf, binary.LittleEndian, int32(res.status))
		if _, err := os.Stderr.Write(buf.Bytes()); err != nil {
			poePanic(err, "stderr write failed")
		}
		if _, err := os.Stderr.Write([]byte(res.msg)); err != nil {
			poePanic(err, "stderr write failed")
		}
		os.Exit(0)
		// unreachable
	}
}