Example #1
1
func listenStream(netw, addr string) (l net.Listener, err error) {
	var (
		file *os.File
	)

	fd, err := listen(netw, addr)
	if err != nil {
		return nil, err
	}

	// Set backlog size to the maximum
	if err = syscall.Listen(fd, syscall.SOMAXCONN); err != nil {
		syscall.Close(fd)
		return nil, err
	}

	file = os.NewFile(uintptr(fd), filePrefix+strconv.Itoa(os.Getpid()))
	if l, err = net.FileListener(file); err != nil {
		syscall.Close(fd)
		return nil, err
	}

	if err = file.Close(); err != nil {
		syscall.Close(fd)
		l.Close()
		return nil, err
	}

	return l, err
}
Example #2
0
func newfile(fd uintptr, name string) *os.File {
	p, err := winPath(name)
	if err != nil {
		return os.NewFile(fd, name)
	}
	return os.NewFile(fd, p)
}
Example #3
0
func newPipeFd() (*Pipe, error) {
	r2pipeIn := os.Getenv("R2PIPE_IN")
	r2pipeOut := os.Getenv("R2PIPE_OUT")
	if r2pipeIn == "" || r2pipeOut == "" {
		return nil, errors.New("missing R2PIPE_{IN,OUT} vars")
	}
	r2pipeInFd, err := strconv.Atoi(r2pipeIn)
	if err != nil {
		return nil, err
	}
	r2pipeOutFd, err := strconv.Atoi(r2pipeOut)
	if err != nil {
		return nil, err
	}
	stdout := os.NewFile(uintptr(r2pipeInFd), "R2PIPE_IN")
	stdin := os.NewFile(uintptr(r2pipeOutFd), "R2PIPE_OUT")

	r2p := &Pipe{
		File:   "",
		r2cmd:  nil,
		stdin:  stdin,
		stdout: stdout,
	}
	return r2p, nil
}
Example #4
0
func newSocketPair(name string) (*os.File, *os.File, error) {
	pair, err := syscall.Socketpair(syscall.AF_UNIX, syscall.SOCK_STREAM, 0)
	if err != nil {
		return nil, nil, err
	}
	return os.NewFile(uintptr(pair[0]), name), os.NewFile(uintptr(pair[1]), name), nil
}
Example #5
0
// Pty returns a UNIX 98 pseudoterminal device.
// Pty returns a pair of fds representing the master and slave pair.
func Pty() (*os.File, *os.File, error) {
	open := func(path string) (uintptr, error) {
		fd, err := syscall.Open(path, syscall.O_NOCTTY|syscall.O_RDWR|syscall.O_CLOEXEC, 0666)
		if err != nil {
			return 0, fmt.Errorf("unable to open %q: %v", path, err)
		}
		return uintptr(fd), nil
	}

	ptm, err := open("/dev/ptmx")
	if err != nil {
		return nil, nil, err
	}

	sname, err := ptsname(ptm)
	if err != nil {
		return nil, nil, err
	}

	err = grantpt(ptm)
	if err != nil {
		return nil, nil, err
	}

	err = unlockpt(ptm)
	if err != nil {
		return nil, nil, err
	}

	pts, err := open(sname)
	if err != nil {
		return nil, nil, err
	}
	return os.NewFile(uintptr(ptm), "ptm"), os.NewFile(uintptr(pts), sname), nil
}
Example #6
0
File: pty.go Project: pkg/term
// Pty returns a UNIX 98 pseudoterminal device.
// Pty returns a pair of fds representing the master and slave pair.
func Pty() (*os.File, *os.File, error) {
	ptm, err := open_pty_master()
	if err != nil {
		return nil, nil, err
	}

	sname, err := Ptsname(ptm)
	if err != nil {
		return nil, nil, err
	}

	err = grantpt(ptm)
	if err != nil {
		return nil, nil, err
	}

	err = unlockpt(ptm)
	if err != nil {
		return nil, nil, err
	}

	pts, err := open_device(sname)
	if err != nil {
		return nil, nil, err
	}
	return os.NewFile(uintptr(ptm), "ptm"), os.NewFile(uintptr(pts), sname), nil
}
Example #7
0
// Opens a pseudo-terminal, forks, sets up the pty slave as the new child process's controlling terminal and
// stdin/stdout/stderr, and execs the given command in the child process.  Returns the master
// terminal control, the child pid, and an Error if any.
func ForkPty(name string, argv []string, attr *Attributes, size *WindowSize) (*Terminal, int, os.Error) {
	master, slave, err := OpenPty(attr, size)
	if err != nil {
		return nil, -1, err
	}

	procattr := &os.ProcAttr{
		Dir: "",
		Env: nil,
		Files: []*os.File{
			os.NewFile(slave.Fd(), "/dev/stdin"),
			os.NewFile(slave.Fd(), "/dev/stdout"),
			os.NewFile(slave.Fd(), "/dev/stderr"),
		},
		Sys: &syscall.SysProcAttr{
			Setsid:  true,
			Setctty: true,
		},
	}

	proc, err := os.StartProcess(name, argv, procattr)
	if err != nil {
		return nil, -1, err
	}
	return master, proc.Pid, nil
}
Example #8
0
func newPipe() (parent *os.File, child *os.File, err error) {
	fds, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM|syscall.SOCK_CLOEXEC, 0)
	if err != nil {
		return nil, nil, err
	}
	return os.NewFile(uintptr(fds[1]), "parent"), os.NewFile(uintptr(fds[0]), "child"), nil
}
Example #9
0
func newFakeVTYServer() (*fakeVTYServer, error) {
	fds, err := syscall.Socketpair(syscall.AF_UNIX, syscall.SOCK_STREAM, 0)
	if err != nil {
		return nil, err
	}

	vtyClientFile := os.NewFile(uintptr(fds[1]), "vty-client")
	vtyClientConn, err := net.FileConn(vtyClientFile)
	if err != nil {
		return nil, err
	}

	vtyServerFile := os.NewFile(uintptr(fds[0]), "vty-server")
	vtyServerConn, err := net.FileConn(vtyServerFile)
	if err != nil {
		return nil, err
	}
	syscall.SetNonblock(fds[0], false)

	vs := &fakeVTYServer{
		clientConn: vtyClientConn,
		serverConn: vtyServerConn,
		clientFile: vtyClientFile,
		serverFile: vtyServerFile,

		send:     make(chan []byte),
		received: make(chan []byte),
	}

	go vs.read()
	go vs.write()

	return vs, nil
}
Example #10
0
func createAttachment(stream *spdystream.Stream) (*os.File, error) {
	if stream.IsFinished() {
		return nil, fmt.Errorf("stream already finished")
	}

	socketFds, socketErr := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM|syscall.FD_CLOEXEC, 0)
	if socketErr != nil {
		return nil, socketErr
	}
	pipe := os.NewFile(uintptr(socketFds[1]), "")
	defer pipe.Close()
	conn, connErr := net.FileConn(pipe)
	if connErr != nil {
		return nil, connErr
	}

	go func() {
		io.Copy(conn, stream)
		conn.Close()
	}()
	go func() {
		io.Copy(stream, conn)
	}()

	return os.NewFile(uintptr(socketFds[0]), ""), nil
}
Example #11
0
func socketPair() (sock1 *os.File, sock2 *os.File, err error) {
	var fds [2]int
	fds, err = syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM, 0)
	if err != nil {
		fmt.Println(err.Error())
	}
	return os.NewFile(uintptr(fds[0]), "|0"), os.NewFile(uintptr(fds[1]), "|1"), err
}
Example #12
0
func mount(dir string, ready chan<- struct{}, errp *error) (fusefd *os.File, err error) {
	// linux mount is never delayed
	close(ready)

	fds, err := syscall.Socketpair(syscall.AF_FILE, syscall.SOCK_STREAM, 0)
	if err != nil {
		return nil, fmt.Errorf("socketpair error: %v", err)
	}
	defer syscall.Close(fds[0])
	defer syscall.Close(fds[1])

	cmd := exec.Command("fusermount", "--", dir)
	cmd.Env = append(os.Environ(), "_FUSE_COMMFD=3")

	writeFile := os.NewFile(uintptr(fds[0]), "fusermount-child-writes")
	defer writeFile.Close()
	cmd.ExtraFiles = []*os.File{writeFile}

	out, err := cmd.CombinedOutput()
	if len(out) > 0 || err != nil {
		return nil, fmt.Errorf("fusermount: %q, %v", out, err)
	}

	readFile := os.NewFile(uintptr(fds[1]), "fusermount-parent-reads")
	defer readFile.Close()
	c, err := net.FileConn(readFile)
	if err != nil {
		return nil, fmt.Errorf("FileConn from fusermount socket: %v", err)
	}
	defer c.Close()

	uc, ok := c.(*net.UnixConn)
	if !ok {
		return nil, fmt.Errorf("unexpected FileConn type; expected UnixConn, got %T", c)
	}

	buf := make([]byte, 32) // expect 1 byte
	oob := make([]byte, 32) // expect 24 bytes
	_, oobn, _, _, err := uc.ReadMsgUnix(buf, oob)
	scms, err := syscall.ParseSocketControlMessage(oob[:oobn])
	if err != nil {
		return nil, fmt.Errorf("ParseSocketControlMessage: %v", err)
	}
	if len(scms) != 1 {
		return nil, fmt.Errorf("expected 1 SocketControlMessage; got scms = %#v", scms)
	}
	scm := scms[0]
	gotFds, err := syscall.ParseUnixRights(&scm)
	if err != nil {
		return nil, fmt.Errorf("syscall.ParseUnixRights: %v", err)
	}
	if len(gotFds) != 1 {
		return nil, fmt.Errorf("wanted 1 fd; got %#v", gotFds)
	}
	f := os.NewFile(uintptr(gotFds[0]), "/dev/fuse")
	return f, nil
}
Example #13
0
func newCtlSockets() (*os.File, *os.File, error) {
	fds, err := syscall.Socketpair(syscall.AF_UNIX, syscall.SOCK_SEQPACKET, 0)
	if err != nil {
		return nil, nil, err
	}

	f1 := os.NewFile(uintptr(fds[0]), "ctl")
	f2 := os.NewFile(uintptr(fds[1]), "ctl")
	return f1, f2, nil
}
Example #14
0
func unixgramSocketpair() (l, r *os.File, err error) {
	fd, err := syscall.Socketpair(syscall.AF_UNIX, syscall.SOCK_SEQPACKET, 0)
	if err != nil {
		return nil, nil, os.NewSyscallError("socketpair",
			err.(syscall.Errno))
	}
	l = os.NewFile(uintptr(fd[0]), "socketpair-half1")
	r = os.NewFile(uintptr(fd[1]), "socketpair-half2")
	return
}
Example #15
0
// either gets a pipe off the pool or returns a brand new one
func initPipe() (p *pipe, err error) {
	var pp [2]int32
	_, _, e := syscall.RawSyscall(syscall.SYS_PIPE2, uintptr(unsafe.Pointer(&pp)), syscall.O_CLOEXEC, 0)
	if e != 0 {
		return nil, os.NewSyscallError("pipe", e)
	}
	fmt.Printf("Got new pipe, read fd %d, write fd %d\n", pp[0], pp[1])
	return &pipe{os.NewFile(uintptr(pp[0]), "|0"), os.NewFile(uintptr(pp[1]), "|1"), 0}, nil

}
Example #16
0
func (c *Client) GetStdout() (*os.File, *os.File, error) {
	var fds []fdrpc.FD
	if err := c.c.Call("ContainerInit.GetStdout", struct{}{}, &fds); err != nil {
		return nil, nil, err
	}
	if len(fds) != 2 {
		return nil, nil, fmt.Errorf("containerinit: got %d fds, expected 2", len(fds))
	}
	return os.NewFile(uintptr(fds[0].FD), "stdout"), os.NewFile(uintptr(fds[1].FD), "stderr"), nil
}
Example #17
0
func run() int {
	flag.Parse()

	runtime := flag.Args()[1] // e.g. runc
	dir := flag.Args()[2]     // bundlePath for run, processPath for exec
	containerId := flag.Args()[3]

	signals := make(chan os.Signal, 100)
	signal.Notify(signals, syscall.SIGCHLD)

	fd3 := os.NewFile(3, "/proc/self/fd/3")
	logFile := fmt.Sprintf("/proc/%d/fd/4", os.Getpid())
	logFD := os.NewFile(4, "/proc/self/fd/4")
	syncPipe := os.NewFile(5, "/proc/self/fd/5")
	pidFilePath := filepath.Join(dir, "pidfile")

	stdin, stdout, stderr, winsz := openPipes(dir)

	syncPipe.Write([]byte{0})

	var runcStartCmd *exec.Cmd
	if *tty {
		ttySlave := setupTty(stdin, stdout, pidFilePath, winsz, garden.WindowSize{Rows: *rows, Columns: *cols})
		runcStartCmd = exec.Command(runtime, "-debug", "-log", logFile, "exec", "-d", "-tty", "-console", ttySlave.Name(), "-p", fmt.Sprintf("/proc/%d/fd/0", os.Getpid()), "-pid-file", pidFilePath, containerId)
	} else {
		runcStartCmd = exec.Command(runtime, "-debug", "-log", logFile, "exec", "-p", fmt.Sprintf("/proc/%d/fd/0", os.Getpid()), "-d", "-pid-file", pidFilePath, containerId)
		runcStartCmd.Stdin = stdin
		runcStartCmd.Stdout = stdout
		runcStartCmd.Stderr = stderr
	}

	// we need to be the subreaper so we can wait on the detached container process
	system.SetSubreaper(os.Getpid())

	if err := runcStartCmd.Start(); err != nil {
		fd3.Write([]byte{2})
		return 2
	}

	var status syscall.WaitStatus
	var rusage syscall.Rusage
	_, err := syscall.Wait4(runcStartCmd.Process.Pid, &status, 0, &rusage)
	check(err)    // Start succeeded but Wait4 failed, this can only be a programmer error
	logFD.Close() // No more logs from runc so close fd

	fd3.Write([]byte{byte(status.ExitStatus())})
	if status.ExitStatus() != 0 {
		return 3 // nothing to wait for, container didn't launch
	}

	containerPid, err := parsePid(pidFilePath)
	check(err)

	return waitForContainerToExit(dir, containerPid, signals)
}
Example #18
0
func Socketpair(typ int) (a, b *os.File, err error) {
	fd, err := syscall.Socketpair(syscall.AF_UNIX, typ, 0)
	if err != nil {
		e := os.NewSyscallError("socketpair", err.(syscall.Errno))
		return nil, nil, e
	}

	a = os.NewFile(uintptr(fd[0]), "socketpair-a")
	b = os.NewFile(uintptr(fd[1]), "socketpair-b")
	return
}
Example #19
0
func (sp *SocketPair) init() {
	fds, err := syscall.Socketpair(syscall.AF_UNIX, syscall.SOCK_STREAM, 0)

	if err != nil {
		fmt.Println(err)
		return
	}
	sp.LocalFile = os.NewFile(uintptr(fds[0]), "sp-0")
	sp.RemoteFile = os.NewFile(uintptr(fds[1]), "sp-1")

}
Example #20
0
func NewSyncPipeFromFd(parendFd, childFd uintptr) (*SyncPipe, error) {
	s := &SyncPipe{}
	if parendFd > 0 {
		s.parent = os.NewFile(parendFd, "parendPipe")
	} else if childFd > 0 {
		s.child = os.NewFile(childFd, "childPipe")
	} else {
		return nil, fmt.Errorf("no valid sync pipe fd specified")
	}
	return s, nil
}
Example #21
0
// initd listens on a socket, spawns requested processes and reaps their
// exit statuses.
func main() {
	defer func() {
		if r := recover(); r != nil {
			fmt.Fprintf(os.Stderr, "initd: panicked: %s\n", r)
			os.Exit(4)
		}
	}()

	dropCaps := flag.Bool("dropCapabilities", false, "drop capabilities before running processes")
	flag.Parse()

	container_daemon.Detach("/dev/null", "/dev/null")
	logger := lager.NewLogger("initd")

	syncWriter := os.NewFile(uintptr(4), "/dev/sync_writer")
	syscall.RawSyscall(syscall.SYS_FCNTL, uintptr(4), syscall.F_SETFD, syscall.FD_CLOEXEC)
	defer syncWriter.Close()

	sync := &containerizer.PipeSynchronizer{
		Writer: syncWriter,
	}

	reaper := system.StartReaper(logger)
	defer reaper.Stop()

	daemon := &container_daemon.ContainerDaemon{
		CmdPreparer: &container_daemon.ProcessSpecPreparer{
			Users:                  container_daemon.LibContainerUser{},
			Rlimits:                &container_daemon.RlimitsManager{},
			ProcStarterPath:        "/sbin/proc_starter",
			AlwaysDropCapabilities: *dropCaps,
		},
		Spawner: &container_daemon.Spawn{
			Runner: reaper,
			PTY:    system.KrPty,
		},
	}

	socketFile := os.NewFile(uintptr(5), "/dev/host.sock")
	listener, err := unix_socket.NewListenerFromFile(socketFile)
	if err != nil {
		fail(fmt.Sprintf("initd: failed to create listener: %s\n", err), 5)
	}

	socketFile.Close()

	if err := sync.SignalSuccess(); err != nil {
		fail(fmt.Sprintf("signal host: %s", err), 6)
	}

	if err := daemon.Run(listener); err != nil {
		fail(fmt.Sprintf("run daemon: %s", err), 7)
	}
}
Example #22
0
// Gets a channel on which to publish events.
//
// Returns a file on which the process is supposed to write data, which then
// translate into these events.
func startProcessNotifier(ready chan<- bool) (w *os.File, err error) {
	fds, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_DGRAM, 0)
	if err != nil {
		return
	}
	r := os.NewFile(uintptr(fds[0]), "notify:r") // File name is arbitrary
	w = os.NewFile(uintptr(fds[1]), "notify:w")

	go runProcessNotifier(r, ready)

	return w, nil
}
Example #23
0
func NewSyncPipe() (s *SyncPipe, err error) {
	s = &SyncPipe{}

	fds, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM|syscall.SOCK_CLOEXEC, 0)
	if err != nil {
		return nil, err
	}

	s.child = os.NewFile(uintptr(fds[0]), "child syncpipe")
	s.parent = os.NewFile(uintptr(fds[1]), "parent syncpipe")

	return s, nil
}
Example #24
0
func main() {
	// I assume that in is 0
	in2, err := syscall.Dup(0)
	if err != nil {
		log.Fatal("dupping 0", err)
	}

	out2, err := syscall.Dup(1)
	if err != nil {
		log.Fatal("dupping 1", err)
	}

	os.Stdin.Close()
	os.Stdout.Close()
	os.Stdout = os.NewFile(uintptr(2), "/dev/stdout")

	/* Connections to the application. */
	cin := os.NewFile(uintptr(in2), "fromapp")
	cout := os.NewFile(uintptr(out2), "toapp")

	modifyEnvironment()

	// Fire up a new devdraw here
	devdraw, err := drawfcall.New()
	if err != nil {
		log.Fatal("making a Conn", err)
	}

	// There is probably a nicer way to do this.
	// TODO(rjkroege): do it the nicer way.
	var app App
	app.o = cout
	app.i = cin

	json := NewJsonRecorder()

	for {
		// read crap from cin
		log.Print("about to read from host")
		inbuffy, err := drawfcall.ReadMsg(cin)
		log.Print("read from host")
		if err != nil {
			devdraw.Close()
			break
		}
		go marshalsxtx(inbuffy, &app, devdraw, json)
	}

	log.Print("waiting on completion")
	json.WaitToComplete()
}
Example #25
0
func createStreamMessage(stream *spdystream.Stream, mode int, streamChans streamChanProvider, ret libchan.Sender) (*libchan.Message, error) {
	dataString := stream.Headers()["Data"]
	if len(dataString) != 1 {
		if len(dataString) == 0 {
			return nil, fmt.Errorf("Stream(%s) is missing data header", stream)
		} else {
			return nil, fmt.Errorf("Stream(%s) has multiple data headers", stream)
		}
	}

	data, decodeErr := base64.URLEncoding.DecodeString(dataString[0])
	if decodeErr != nil {
		return nil, decodeErr
	}

	var attach *os.File
	if !stream.IsFinished() {
		socketFds, socketErr := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM|syscall.FD_CLOEXEC, 0)
		if socketErr != nil {
			return nil, socketErr
		}
		attach = os.NewFile(uintptr(socketFds[0]), "")
		conn, connErr := net.FileConn(os.NewFile(uintptr(socketFds[1]), ""))
		if connErr != nil {
			return nil, connErr
		}

		go func() {
			io.Copy(conn, stream)
		}()
		go func() {
			io.Copy(stream, conn)
		}()
	}

	retSender := ret
	if retSender == nil || libchan.RetPipe.Equals(retSender) {
		retSender = &StreamSender{stream: stream, streamChans: streamChans}
	}

	if mode&libchan.Ret == 0 {
		retSender.Close()
	}

	return &libchan.Message{
		Data: data,
		Fd:   attach,
		Ret:  retSender,
	}, nil
}
// DeserializeFDMessageStream takes a string description of the form
// "tao::FDMessageStream(X, Y)" and returns a MessageStream that uses file
// descriptor X as the reader and file descriptor Y as the writer.
func DeserializeFDMessageStream(s string) (*MessageStream, error) {
	var readfd, writefd uintptr
	_, err := fmt.Sscanf(s, "tao::FDMessageChannel(%d, %d)", &readfd, &writefd)
	if err != nil {
		return nil, errors.New("unrecognized channel spec " + s)
	}
	if readfd == writefd {
		rw := os.NewFile(readfd, "read/write pipe")
		return NewMessageStream(rw), nil
	}
	r := os.NewFile(readfd, "read pipe")
	w := os.NewFile(writefd, "write pipe")
	rw := NewPairReadWriteCloser(r, w)
	return NewMessageStream(rw), nil
}
Example #27
0
func Pipe() (master *os.File, slave *os.File, err error) {
	fd_master := C.int(-1)
	fd_slave := C.int(-1)

	C.create_pipe(&fd_master, &fd_slave)

	if fd_master == -1 || fd_slave == -1 {
		return nil, nil, errors.New("Failed to create a new pipe")
	}

	master = os.NewFile(uintptr(fd_master), "master")
	slave = os.NewFile(uintptr(fd_slave), "slave")

	return master, slave, nil
}
Example #28
0
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 = bazilfuse.Errno(*fFlushError)
	}

	if *fFsyncError != 0 {
		fsyncErr = bazilfuse.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
}
Example #29
0
// TestLinuxSendfileChild isn't a real test. It's used as a helper process
// for TestLinuxSendfile.
func TestLinuxSendfileChild(*testing.T) {
	if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
		return
	}
	defer os.Exit(0)
	fd3 := os.NewFile(3, "ephemeral-port-listener")
	ln, err := net.FileListener(fd3)
	if err != nil {
		panic(err)
	}
	mux := http.NewServeMux()

	fs := &FileServer{
		http.Dir("testdata"),
		inject.CopyInject{},
		ricetemp.MustMakeTemplates(rice.MustFindBox("../templates")),
	}

	mux.Handle("/", fs)
	mux.HandleFunc("/quit", func(http.ResponseWriter, *http.Request) {
		os.Exit(0)
	})
	s := &http.Server{Handler: mux}
	err = s.Serve(ln)
	if err != nil {
		panic(err)
	}
}
Example #30
0
func (r *trServiceManager) run(gracefulProtos string) error {

	// TODO If a listen-spec changes in the config and a graceful
	// restart is issued, the new config will not take effect as the
	// open file is reused.

	if gracefulProtos == "" {
		for _, service := range r.services {
			if err := service.Start(nil); err != nil {
				return err
			}
		}
	} else {

		protos := strings.Split(gracefulProtos, ",")

		for n, p := range protos {
			f := os.NewFile(uintptr(n+3), "")
			if r.services[p] != nil {
				if err := r.services[p].Start(f); err != nil {
					return err
				}
			}
		}
	}
	return nil
}