Exemple #1
0
// Convert and validate the GOAGAIN_FD, GOAGAIN_NAME, and GOAGAIN_PPID
// environment variables.  If all three are present and in order, this
// is a child process that may pick up where the parent left off.
func GetEnvs() (l *net.TCPListener, ppid int, err error) {
	var fd uintptr
	_, err = fmt.Sscan(os.Getenv("GOAGAIN_FD"), &fd)
	if nil != err {
		return
	}
	var i net.Listener
	i, err = net.FileListener(os.NewFile(fd, os.Getenv("GOAGAIN_NAME")))
	if nil != err {
		return
	}
	l = i.(*net.TCPListener)
	if err = syscall.Close(int(fd)); nil != err {
		return
	}
	_, err = fmt.Sscan(os.Getenv("GOAGAIN_PPID"), &ppid)
	if nil != err {
		return
	}
	if syscall.Getppid() != ppid {
		err = errors.New(fmt.Sprintf(
			"GOAGAIN_PPID is %d but parent is %d\n",
			ppid,
			syscall.Getppid(),
		))
		return
	}
	return
}
Exemple #2
0
// Convert and validate the GOAGAIN_FD and GOAGAIN_PPID environment
// variables.  If both are present and in order, this is a child process
// that may pick up where the parent left off.
func GetEnvs() (*net.TCPListener, int, error) {
	envFd := os.Getenv("GOAGAIN_FD")
	if "" == envFd {
		return nil, 0, errors.New("GOAGAIN_FD not set")
	}
	var fd uintptr
	_, err := fmt.Sscan(envFd, &fd)
	if nil != err {
		return nil, 0, err
	}
	tmp, err := net.FileListener(os.NewFile(fd, "listener"))
	if nil != err {
		return nil, 0, err
	}
	l := tmp.(*net.TCPListener)
	envPpid := os.Getenv("GOAGAIN_PPID")
	if "" == envPpid {
		return l, 0, errors.New("GOAGAIN_PPID not set")
	}
	var ppid int
	_, err = fmt.Sscan(envPpid, &ppid)
	if nil != err {
		return l, 0, err
	}
	if syscall.Getppid() != ppid {
		return l, ppid, errors.New(fmt.Sprintf(
			"GOAGAIN_PPID is %d but parent is %d\n", ppid, syscall.Getppid()))
	}
	return l, ppid, nil
}
Exemple #3
0
func (srv *FoolServer) Run() { /*{{{*/
	logger = NewLog(srv.config.AccessLog, srv.config.ErrorLog, srv.config.RunLog)
	//解析模板
	CompileTpl(srv.config.ViewPath)
	//信号处理函数
	go srv.signalHandle()

	serverStat = STATE_RUNNING

	//kill父进程
	if isChild == true {
		parent := syscall.Getppid()

		if _, err := os.FindProcess(parent); err != nil {
			return
		}
		logger.RunLog(fmt.Sprintf("[Notice] Killing parent pid: %v", parent))
		syscall.Kill(parent, syscall.SIGQUIT)
	}
	srv.createPid(syscall.Getpid())

	logger.RunLog("[Notice] Server start.")
	//listen loop
	srv.Serve(srv.listener)

	logger.RunLog("[Notice] Waiting for connections to finish...")
	connWg.Wait()
	serverStat = STATE_TERMINATE
	logger.RunLog("[Notice] Server shuttdown.")
	return
} /*}}}*/
func TestCreateToolhelp32Snapshot(t *testing.T) {
	handle, err := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
	if err != nil {
		t.Fatal(err)
	}
	defer syscall.CloseHandle(syscall.Handle(handle))

	// Iterate over the snapshots until our PID is found.
	pid := uint32(syscall.Getpid())
	for {
		process, err := Process32Next(handle)
		if errors.Cause(err) == syscall.ERROR_NO_MORE_FILES {
			break
		}
		if err != nil {
			t.Fatal(err)
		}

		t.Logf("CreateToolhelp32Snapshot: ProcessEntry32=%v", process)

		if process.ProcessID == pid {
			assert.EqualValues(t, syscall.Getppid(), process.ParentProcessID)
			return
		}
	}

	assert.Fail(t, "Snapshot not found for PID=%v", pid)
}
Exemple #5
0
func daemon(nochdir, noclose int) int {
	var ret, ret2 uintptr
	var err syscall.Errno

	darwin := runtime.GOOS == "darwin"

	// already a daemon
	if syscall.Getppid() == 1 {
		return 0
	}

	// fork off the parent process
	ret, ret2, err = syscall.RawSyscall(syscall.SYS_FORK, 0, 0, 0)
	if err != 0 {
		return -1
	}

	// failure
	if ret2 < 0 {
		os.Exit(-1)
	}

	// handle exception for darwin
	if darwin && ret2 == 1 {
		ret = 0
	}

	// if we got a good PID, then we call exit the parent process.
	if ret > 0 {
		os.Exit(0)
	}

	/* Change the file mode mask */
	_ = syscall.Umask(0)

	// create a new SID for the child process
	s_ret, s_errno := syscall.Setsid()
	if s_errno != nil {
		log.Printf("Error: syscall.Setsid errno: %d", s_errno)
	}
	if s_ret < 0 {
		return -1
	}

	if nochdir == 0 {
		os.Chdir("/")
	}

	if noclose == 0 {
		f, e := os.OpenFile("/dev/null", os.O_RDWR, 0)
		if e == nil {
			fd := f.Fd()
			syscall.Dup2(int(fd), int(os.Stdin.Fd()))
			syscall.Dup2(int(fd), int(os.Stdout.Fd()))
			syscall.Dup2(int(fd), int(os.Stderr.Fd()))
		}
	}

	return 0
}
Exemple #6
0
func (t *trTransceiver) start(gracefulProtos string) error {
	t.startWorkers()
	t.startFlushers()
	t.startStatWorker()
	t.serviceMgr = newServiceManager(t)

	if err := t.serviceMgr.run(gracefulProtos); err != nil {
		return err
	}

	// Wait for workers/flushers to start correctly
	t.startWg.Wait()
	log.Printf("All workers running, good to go!")

	if gracefulProtos != "" {
		parent := syscall.Getppid()
		log.Printf("start(): Killing parent pid: %v", parent)
		syscall.Kill(parent, syscall.SIGTERM)
		log.Printf("start(): Waiting for the parent to signal that flush is complete...")
		ch := make(chan os.Signal)
		signal.Notify(ch, syscall.SIGUSR1)
		s := <-ch
		log.Printf("start(): Received %v, proceeding to load the data", s)
	}

	t.dss.reload() // *finally* load the data (because graceful restart)

	go t.dispatcher() // now start dispatcher

	return nil
}
Exemple #7
0
// RestoreParentDeathSignal sets the parent death signal to old.
func RestoreParentDeathSignal(old int) error {
	if old == 0 {
		return nil
	}

	current, err := system.GetParentDeathSignal()
	if err != nil {
		return fmt.Errorf("get parent death signal %s", err)
	}

	if old == current {
		return nil
	}

	if err := system.ParentDeathSignal(uintptr(old)); err != nil {
		return fmt.Errorf("set parent death signal %s", err)
	}

	// Signal self if parent is already dead. Does nothing if running in a new
	// PID namespace, as Getppid will always return 0.
	if syscall.Getppid() == 1 {
		return syscall.Kill(syscall.Getpid(), syscall.SIGKILL)
	}

	return nil
}
Exemple #8
0
func (this torUtil) SetDaemonMode(nochdir, noclose int) int {
	if syscall.Getppid() == 1 {
		return 0
	}
	ret, ret2, err := syscall.RawSyscall(syscall.SYS_FORK, 0, 0, 0)
	if err != 0 {
		return -1
	}
	if ret2 < 0 {
		os.Exit(-1)
	}
	if ret > 0 {
		os.Exit(0)
	}
	syscall.Umask(0)
	s_ret, s_errno := syscall.Setsid()
	if s_ret < 0 {
		return -1
	}
	if nochdir == 0 {
		os.Chdir("/")
	}
	if noclose == 0 {
		f, e := os.OpenFile("/dev/null", os.O_RDWR, 0)
		if e == nil {
			fd := f.Fd()
			syscall.Dup2(int(fd), int(os.Stdin.Fd()))
			syscall.Dup2(int(fd), int(os.Stdout.Fd()))
			syscall.Dup2(int(fd), int(os.Stderr.Fd()))
		}
	}
	return 0
}
Exemple #9
0
// blocks on the server ready and when ready, it sends
// a signal to the parent so that it knows it cna now exit
func childReady(srv *falcore.Server) {
	pid := syscall.Getpid()
	// wait for the ready signal
	<-srv.AcceptReady
	// grab the parent and send a signal that the child is ready
	parent := syscall.Getppid()
	fmt.Printf("%v Kill parent %v with SIGUSR1\n", pid, parent)
	syscall.Kill(parent, syscall.SIGUSR1)
}
Exemple #10
0
func start(c *cli.Context) {
	if pidfile != "" {
		pid, err := fileOrPid(pidfile)
		if err != nil {
			fmt.Fprintf(os.Stderr, err.Error())
			os.Exit(1)
		}
		if pid != 0 && pid != syscall.Getppid() {
			fmt.Fprintf(os.Stderr, "There is already a pidfile at '%s' that appears to belong to another apiplexy instance.")
			os.Exit(1)
		}
	}

	if configPath == "" {
		configPath = c.String("config")
	}

	ap, config, err := initApiplex(configPath)
	if err != nil {
		fmt.Fprintf(os.Stderr, err.Error())
		os.Exit(1)
	}

	server := &http.Server{
		Addr:           "0.0.0.0:" + strconv.Itoa(config.Serve.Port),
		Handler:        ap,
		ReadTimeout:    10 * time.Second,
		WriteTimeout:   10 * time.Second,
		MaxHeaderBytes: 1 << 16,
	}

	fmt.Printf("Launching apiplexy on port %d.\n", config.Serve.Port)
	l, err := net.Listen("tcp", server.Addr)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Couldn't start server on %s: %s\n", server.Addr, err.Error())
		os.Exit(1)
	}

	// write pidfile and wait for restart signal
	if pidfile != "" {
		ioutil.WriteFile(pidfile, []byte(strconv.Itoa(syscall.Getpid())), 0600)
	}

	defer func() {
		// server shuts down, delete pidfile if it's still our PID in there
		if pidfile != "" {
			rp, _ := ioutil.ReadFile(pidfile)
			p, _ := strconv.Atoi(string(rp))
			if p == syscall.Getpid() {
				os.Remove(pidfile)
			}
		}
	}()

	server.Serve(l)
}
Exemple #11
0
func NewDefaultFormatter(out io.Writer) Formatter {
	if syscall.Getppid() == 1 {
		// We're running under init, which may be systemd.
		f, err := NewJournaldFormatter()
		if err == nil {
			return f
		}
	}
	return NewPrettyFormatter(out, false)
}
Exemple #12
0
func _not_work_Fork(closeno bool) (pid int, err error) {
	// don't run this
	// not work with go threads
	// see: http://code.google.com/p/go/issues/detail?id=227

	darwin := runtime.GOOS == "darwin"

	// already a daemon
	if syscall.Getppid() == 1 {
		return 0, nil
	}

	// fork off the parent process
	ret, ret2, errno := syscall.RawSyscall(syscall.SYS_FORK, 0, 0, 0)

	if errno != 0 {
		return -1, fmt.Errorf("Fork failure: %s", errno)
	}

	// failure
	if ret2 < 0 {
		return -1, fmt.Errorf("Fork failure")
	}

	// handle exception for darwin
	if darwin && ret2 == 1 {
		ret = 0
	}

	// if we got a good PID, then we call exit the parent process.
	if ret > 0 {
		return 0, nil
	}

	// create a new SID for the child process
	s_ret, s_errno := syscall.Setsid()
	if s_errno != nil {
		return -1, fmt.Errorf("Error: syscall.Setsid: %s", s_errno)
	}
	if s_ret < 0 {
		return -1, fmt.Errorf("Error: syscall.Setsid: %s", s_errno)
	}

	if closeno {
		f, e := os.OpenFile("/dev/null", os.O_RDWR, 0)
		if e == nil {
			fd := int(f.Fd())
			syscall.Dup2(fd, int(os.Stdin.Fd()))
			syscall.Dup2(fd, int(os.Stdout.Fd()))
			syscall.Dup2(fd, int(os.Stderr.Fd()))
		}
	}

	return os.Getpid(), nil
}
Exemple #13
0
func main() {
	conf := flag.String("conf", "./conf/pmon.json", "config file")
	var gracefulChild bool
	flag.BoolVar(&gracefulChild, "graceful", false, "listen on fd open 3 (internal use only)")
	flag.Parse()
	defer glog.Flush()

	var err error
	confPath, err = filepath.Abs(*conf)
	if nil != err {
		glog.Errorf("%v", err)
		return
	}

	// sc := make(chan os.Signal, 1)
	// signal.Notify(sc, os.Interrupt, os.Kill)
	// go func() {
	// 	_ = <-sc
	// 	killAll(&LogWriter{})
	// 	glog.Flush()
	// 	os.Exit(1)
	// }()

	watchConfFile()

	//start admin server
	var l net.Listener

	if gracefulChild {
		f := os.NewFile(3, "")
		l, err = net.FileListener(f)
	} else {
		l, err = net.Listen("tcp", Cfg.Listen)
	}
	if nil != err {
		glog.Errorf("Bind socket failed:%v", err)
		return
	}
	tl := l.(*net.TCPListener)
	listenFile, _ = tl.File()
	if gracefulChild {
		parent := syscall.Getppid()
		glog.Infof("main: Killing parent pid: %v", parent)
		if proc, _ := os.FindProcess(parent); nil != proc {
			proc.Signal(syscall.SIGTERM)
		}
		//syscall.Kill(parent, syscall.SIGTERM)
	}
	for {
		c, _ := l.Accept()
		if nil != c {
			processAdminConn(c) //only ONE admin connection allowd
		}
	}
}
Exemple #14
0
// Convert and validate the GOAGAIN_FD, GOAGAIN_NAME, and GOAGAIN_PPID
// environment variables.  If all three are present and in order, this
// is a child process that may pick up where the parent left off.
func GetEnvs() (l net.Listener, ppid int, err error) {
	var fd uintptr
	_, err = fmt.Sscan(os.Getenv("GOAGAIN_FD"), &fd)
	if nil != err {
		return
	}
	var i net.Listener
	i, err = net.FileListener(os.NewFile(fd, os.Getenv("GOAGAIN_NAME")))
	if nil != err {
		return
	}
	switch i.(type) {
	case *net.TCPListener:
		l = i.(*net.TCPListener)
	case *net.UnixListener:
		l = i.(*net.UnixListener)
	default:
		err = errors.New(fmt.Sprintf(
			"file descriptor is %T not *net.TCPListener or *net.UnixListener",
			i,
		))
		return
	}
	if err = syscall.Close(int(fd)); nil != err {
		return
	}
	_, err = fmt.Sscan(os.Getenv("GOAGAIN_PPID"), &ppid)
	if nil != err {
		return
	}
	if syscall.Getppid() != ppid {
		err = errors.New(fmt.Sprintf(
			"GOAGAIN_PPID is %d but parent is %d",
			ppid,
			syscall.Getppid(),
		))
		return
	}
	return
}
Exemple #15
0
func daemon() error {
	isDarwin := runtime.GOOS == "darwin"

	// already a daemon
	if syscall.Getppid() == 1 {
		return nil
	}

	// fork off the parent process
	ret, ret2, errno := syscall.RawSyscall(syscall.SYS_FORK, 0, 0, 0)
	if errno != 0 {
		return errors.New(fmt.Sprintf("fork error! [errno=%d]", errno))
	}

	// failure
	if ret2 < 0 {
		os.Exit(1)
	}

	// handle exception for darwin
	if isDarwin && ret2 == 1 {
		ret = 0
	}

	// if we got a good PID, then we call exit the parent process.
	if int(ret) > 0 {
		os.Exit(0)
	}

	syscall.Umask(0)

	// create a new SID for the child process
	_, err := syscall.Setsid()
	if err != nil {
		return err
	}

	//os.Chdir("/")

	f, err := os.OpenFile("/dev/null", os.O_RDWR, 0)
	if err == nil {
		fd := f.Fd()
		syscall.Dup2(int(fd), int(os.Stdin.Fd()))
		syscall.Dup2(int(fd), int(os.Stdout.Fd()))
		syscall.Dup2(int(fd), int(os.Stderr.Fd()))
	}
	return nil
}
Exemple #16
0
// TestFcntlFlock tests whether the file locking structure matches
// the calling convention of each kernel.
// On some Linux systems, glibc uses another set of values for the
// commands and translates them to the correct value that the kernel
// expects just before the actual fcntl syscall. As Go uses raw
// syscalls directly, it must use the real value, not the glibc value.
// Thus this test also verifies that the Flock_t structure can be
// roundtripped with F_SETLK and F_GETLK.
func TestFcntlFlock(t *testing.T) {
	if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") {
		t.Skip("skipping; no child processes allowed on iOS")
	}
	flock := syscall.Flock_t{
		Type:  syscall.F_WRLCK,
		Start: 31415, Len: 271828, Whence: 1,
	}
	if os.Getenv("GO_WANT_HELPER_PROCESS") == "" {
		// parent
		name := filepath.Join(os.TempDir(), "TestFcntlFlock")
		fd, err := syscall.Open(name, syscall.O_CREAT|syscall.O_RDWR|syscall.O_CLOEXEC, 0)
		if err != nil {
			t.Fatalf("Open failed: %v", err)
		}
		defer syscall.Unlink(name)
		defer syscall.Close(fd)
		if err := syscall.Ftruncate(fd, 1<<20); err != nil {
			t.Fatalf("Ftruncate(1<<20) failed: %v", err)
		}
		if err := syscall.FcntlFlock(uintptr(fd), syscall.F_SETLK, &flock); err != nil {
			t.Fatalf("FcntlFlock(F_SETLK) failed: %v", err)
		}
		cmd := exec.Command(os.Args[0], "-test.run=^TestFcntlFlock$")
		cmd.Env = append(os.Environ(), "GO_WANT_HELPER_PROCESS=1")
		cmd.ExtraFiles = []*os.File{os.NewFile(uintptr(fd), name)}
		out, err := cmd.CombinedOutput()
		if len(out) > 0 || err != nil {
			t.Fatalf("child process: %q, %v", out, err)
		}
	} else {
		// child
		got := flock
		// make sure the child lock is conflicting with the parent lock
		got.Start--
		got.Len++
		if err := syscall.FcntlFlock(3, syscall.F_GETLK, &got); err != nil {
			t.Fatalf("FcntlFlock(F_GETLK) failed: %v", err)
		}
		flock.Pid = int32(syscall.Getppid())
		// Linux kernel always set Whence to 0
		flock.Whence = 0
		if got.Type == flock.Type && got.Start == flock.Start && got.Len == flock.Len && got.Pid == flock.Pid && got.Whence == flock.Whence {
			os.Exit(0)
		}
		t.Fatalf("FcntlFlock got %v, want %v", got, flock)
	}
}
Exemple #17
0
func main() {
	var numcalls int
	var err error
	args := Arguments()
	if !args.Exist() {
		numcalls = 10000000
	} else {
		numcalls, args, err = args.Int("n", 0, 0)
		Check(err)
	}

	log.Println("Calling syscall.Getppid()")

	for i := 0; i < numcalls; i++ {
		syscall.Getppid()
	}
}
Exemple #18
0
// 检查必要环境
func (s *GoServer) checkEnv() {
	if syscall.Getppid() == 1 {
		log.Fatal("server already started")
		os.Exit(1)
	}

	// 检查指定的worker用户是否合法
	s.checkWorkerUserName()

	// 检查log目录是否可读
	s.checkLogWriteAble()

	// 检查配置和语法错误等
	s.checkWorkersConfig()

	// 检查文件限制
	s.checkLimit()
}
Exemple #19
0
func Daemon(nochdir int) error {
	signal.Ignore(syscall.SIGINT, syscall.SIGHUP, syscall.SIGPIPE)

	if syscall.Getppid() == 1 {
		return nil
	}

	ret1, ret2, eno := syscall.RawSyscall(syscall.SYS_FORK, 0, 0, 0)
	if eno != 0 || ret2 < 0 {
		return errors.New("Fork fail")
	}

	/* exit parent */
	if ret1 > 0 {
		os.Exit(0)
	}

	_ = syscall.Umask(0)

	ret, err := syscall.Setsid()
	if ret < 0 || err != nil {
		return errors.New("Set sid failed")
	}

	if nochdir == 0 {
		err = os.Chdir("/")
		if err != nil {
			return errors.New("Chdir failed")
		}
	}

	file, err := os.OpenFile("/dev/null", os.O_RDWR, 0)
	if err == nil {
		fd := file.Fd()
		syscall.Dup2(int(fd), int(os.Stdin.Fd()))
		syscall.Dup2(int(fd), int(os.Stdout.Fd()))
		//	syscall.Dup2(int(fd), int(os.Stderr.Fd()))
	}

	return nil
}
Exemple #20
0
func DoDaemon(log, chdir string) (err error) {
	syscall.Umask(0)

	if chdir != "" {
		os.Chdir(chdir)
	}

	if syscall.Getppid() == 1 {
		return
	}

	files := make([]*os.File, 3, 6)
	if log != "" {
		fp, err := os.OpenFile(log, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)
		if err != nil {
			return err
		}
		files[0], files[1], files[2] = fp, fp, fp
	} else {
		files[0], files[1], files[2] = os.Stdin, os.Stdout, os.Stderr
	}

	dir, _ := os.Getwd()
	sysattrs := syscall.SysProcAttr{Setsid: true}
	prcattrs := os.ProcAttr{
		Dir:   dir,
		Env:   os.Environ(),
		Files: files,
		Sys:   &sysattrs,
	}

	proc, err := os.StartProcess(os.Args[0], os.Args, &prcattrs)
	if err != nil {
		return
	}

	proc.Release()
	os.Exit(0)

	return
}
func newContainerInit(t initType, pipe *os.File) (initer, error) {
	var config *initConfig
	if err := json.NewDecoder(pipe).Decode(&config); err != nil {
		return nil, err
	}
	if err := populateProcessEnvironment(config.Env); err != nil {
		return nil, err
	}
	switch t {
	case initSetns:
		return &linuxSetnsInit{
			config: config,
		}, nil
	case initStandard:
		return &linuxStandardInit{
			parentPid: syscall.Getppid(),
			config:    config,
		}, nil
	}
	return nil, fmt.Errorf("unknown init type %q", t)
}
Exemple #22
0
/*
ListenAndServeTLS listens on the TCP network address srv.EndlessListener.Addr() and then calls
Serve to handle requests on incoming TLS connections.

Filenames containing a certificate and matching private key for the server must
be provided. If the certificate is signed by a certificate authority, the
certFile should be the concatenation of the server's certificate followed by the
CA's certificate.

If srv.EndlessListener.Addr() is blank, ":https" is used.
*/
func (srv *endlessServer) ListenAndServeTLS(certFile, keyFile string) (err error) {
	addr := srv.Addr
	if addr == "" {
		addr = ":https"
	}

	config := &tls.Config{}

	if srv.TLSConfig() != nil {
		*config = *srv.TLSConfig()
	}

	if config.NextProtos == nil {
		config.NextProtos = []string{"http/1.1"}
	}

	config.Certificates = make([]tls.Certificate, 1)
	config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
	if err != nil {
		return
	}

	go srv.handleSignals()

	l, err := srv.getListener(addr)
	if err != nil {
		log.Println(err)
		return
	}

	srv.tlsInnerListener = newEndlessListener(l, srv)
	srv.EndlessListener = tls.NewListener(srv.tlsInnerListener, config)

	if srv.isChild {
		syscall.Kill(syscall.Getppid(), syscall.SIGTERM)
	}

	log.Println(syscall.Getpid(), srv.EndlessListener.Addr(), "ListenAndServeTLS")
	return srv.Serve()
}
Exemple #23
0
func Daemon(chdir bool, clstd bool) (err error) {
	var ret1, ret2 uintptr
	var er syscall.Errno

	darwin := runtime.GOOS == "darwin"
	if syscall.Getppid() == 1 {
		return
	}
	ret1, ret2, er = syscall.RawSyscall(syscall.SYS_FORK, 0, 0, 0)
	if er != 0 {
		err = errors.New("daemon fork fail")
		return
	}
	if ret2 < 0 {
		err = errors.New("fork return fail")
		os.Exit(-1)
	}
	if darwin && ret2 == 1 {
		ret1 = 0
	}
	if ret1 > 0 {
		os.Exit(0)
	}
	syscall.Umask(0)
	syscall.Setsid()
	if chdir {
		os.Chdir("/")
	}
	if clstd {
		fs, err := os.OpenFile(os.DevNull, os.O_RDWR, 0)
		if err == nil {
			fd := fs.Fd()
			syscall.Dup2(int(fd), int(os.Stdin.Fd()))
			syscall.Dup2(int(fd), int(os.Stdout.Fd()))
			syscall.Dup2(int(fd), int(os.Stderr.Fd()))
		}
	}
	return
}
Exemple #24
0
// Re-exec this same image without dropping the net.Listener.
func Exec(l net.Listener) error {
	var pid int
	fmt.Sscan(os.Getenv("GOAGAIN_PID"), &pid)
	if syscall.Getppid() == pid {
		return fmt.Errorf("goagain.Exec called by a child process")
	}
	argv0, err := lookPath()
	if nil != err {
		return err
	}
	if _, err := setEnvs(l); nil != err {
		return err
	}
	if err := os.Setenv(
		"GOAGAIN_SIGNAL",
		fmt.Sprintf("%d", syscall.SIGQUIT),
	); nil != err {
		return err
	}
	log.Println("re-executing", argv0)
	return syscall.Exec(argv0, os.Args, os.Environ())
}
Exemple #25
0
/*
ListenAndServe listens on the TCP network address srv.Addr and then calls Serve
to handle requests on incoming connections. If srv.Addr is blank, ":http" is
used.
*/
func (srv *endlessServer) ListenAndServe() (err error) {
	addr := srv.Addr
	if addr == "" {
		addr = ":http"
	}

	go srv.handleSignals()

	l, err := srv.getListener(addr)
	if err != nil {
		log.Println(err)
		return
	}

	srv.EndlessListener = newEndlessListener(l, srv)

	if srv.isChild {
		syscall.Kill(syscall.Getppid(), syscall.SIGTERM)
	}

	log.Println(syscall.Getpid(), srv.Addr)
	return srv.Serve()
}
Exemple #26
0
func Daemon(nochdir, noclose int) (int, error) {
	// already a daemon
	if syscall.Getppid() == 1 {
		/* Change the file mode mask */
		syscall.Umask(0)

		if nochdir == 0 {
			os.Chdir("/")
		}

		return 0, nil
	}

	files := make([]*os.File, 3, 6)
	if noclose == 0 {
		nullDev, err := os.OpenFile("/dev/null", 0, 0)
		if err != nil {
			return 1, err
		}
		files[0], files[1], files[2] = nullDev, nullDev, nullDev
	} else {
		files[0], files[1], files[2] = os.Stdin, os.Stdout, os.Stderr
	}

	dir, _ := os.Getwd()
	sysattrs := syscall.SysProcAttr{Setsid: true}
	attrs := os.ProcAttr{Dir: dir, Env: os.Environ(), Files: files, Sys: &sysattrs}

	proc, err := os.StartProcess(os.Args[0], os.Args, &attrs)
	if err != nil {
		return -1, fmt.Errorf("can't create process %s: %s", os.Args[0], err)
	}
	proc.Release()
	os.Exit(0)

	return 0, nil
}
Exemple #27
0
func (l *linuxStandardInit) Init() error {
	// do not inherit the parent's session keyring
	sessKeyId, err := keyctl.JoinSessionKeyring("")
	if err != nil {
		return err
	}
	// make session keyring searcheable
	// without user ns we need 'UID' search permissions
	// with user ns we need 'other' search permissions
	if err := keyctl.ModKeyringPerm(sessKeyId, 0xffffffff, 0x080008); err != nil {
		return err
	}

	// join any namespaces via a path to the namespace fd if provided
	if err := joinExistingNamespaces(l.config.Config.Namespaces); err != nil {
		return err
	}
	var console *linuxConsole
	if l.config.Console != "" {
		console = newConsoleFromPath(l.config.Console)
		if err := console.dupStdio(); err != nil {
			return err
		}
	}
	if _, err := syscall.Setsid(); err != nil {
		return err
	}
	if console != nil {
		if err := system.Setctty(); err != nil {
			return err
		}
	}
	if err := setupNetwork(l.config); err != nil {
		return err
	}
	if err := setupRoute(l.config.Config); err != nil {
		return err
	}
	if err := setupRlimits(l.config.Config); err != nil {
		return err
	}
	if err := setOomScoreAdj(l.config.Config.OomScoreAdj); err != nil {
		return err
	}
	label.Init()
	// InitializeMountNamespace() can be executed only for a new mount namespace
	if l.config.Config.Namespaces.Contains(configs.NEWNS) {
		if err := setupRootfs(l.config.Config, console); err != nil {
			return err
		}
	}
	if hostname := l.config.Config.Hostname; hostname != "" {
		if err := syscall.Sethostname([]byte(hostname)); err != nil {
			return err
		}
	}
	if err := apparmor.ApplyProfile(l.config.Config.AppArmorProfile); err != nil {
		return err
	}
	if err := label.SetProcessLabel(l.config.Config.ProcessLabel); err != nil {
		return err
	}

	for key, value := range l.config.Config.Sysctl {
		if err := writeSystemProperty(key, value); err != nil {
			return err
		}
	}
	for _, path := range l.config.Config.ReadonlyPaths {
		if err := remountReadonly(path); err != nil {
			return err
		}
	}
	for _, path := range l.config.Config.MaskPaths {
		if err := maskFile(path); err != nil {
			return err
		}
	}
	pdeath, err := system.GetParentDeathSignal()
	if err != nil {
		return err
	}
	if l.config.Config.NoNewPrivileges {
		if err := system.Prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); err != nil {
			return err
		}
	}
	// Tell our parent that we're ready to Execv. This must be done before the
	// Seccomp rules have been applied, because we need to be able to read and
	// write to a socket.
	if err := syncParentReady(l.pipe); err != nil {
		return err
	}
	if l.config.Config.Seccomp != nil {
		if err := seccomp.InitSeccomp(l.config.Config.Seccomp); err != nil {
			return err
		}
	}
	if err := finalizeNamespace(l.config); err != nil {
		return err
	}
	// finalizeNamespace can change user/group which clears the parent death
	// signal, so we restore it here.
	if err := pdeath.Restore(); err != nil {
		return err
	}
	// compare the parent from the inital start of the init process and make sure that it did not change.
	// if the parent changes that means it died and we were reparened to something else so we should
	// just kill ourself and not cause problems for someone else.
	if syscall.Getppid() != l.parentPid {
		return syscall.Kill(syscall.Getpid(), syscall.SIGKILL)
	}

	return system.Execv(l.config.Args[0], l.config.Args[0:], os.Environ())
}
Exemple #28
0
// Getppid returns the process id of the caller's parent.
func Getppid() int { return syscall.Getppid() }
Exemple #29
0
func Daemon(pfile, lfile string, uid, gid, nochdir, noclose int) int {
	if syscall.Getppid() == 1 {
		return 0
	}

	ret, mret, errno := syscall.RawSyscall(syscall.SYS_FORK, 0, 0, 0)
	if errno != 0 {
		return -1
	}

	if mret < 0 {
		os.Exit(-1)
	}

	if runtime.GOOS == "darwin" && mret == 1 {
		ret = 0
	}

	if ret > 0 {
		os.Exit(0)
	}

	_ = syscall.Umask(0)
	s_ret, err := syscall.Setsid()
	if err != nil {
		panic(err)
	}

	if s_ret < 0 {
		return -1
	}

	err = WriteFile(pfile, fmt.Sprintf("%d\n", os.Getpid()))
	if err != nil {
		panic(err)
	}

	/*
	   err = syscall.Setgid(gid)
	   if err != nil {
	       panic(err)
	   }

	   err = syscall.Setuid(uid)
	   if err != nil {
	       panic(err)
	   }
	*/

	if nochdir == 0 {
		os.Chdir("/")
	}

	if noclose == 0 {
		fp, err := os.OpenFile(lfile, os.O_RDWR|os.O_APPEND, 0)
		if err != nil {
			panic(err)
		}

		fd := fp.Fd()
		syscall.Dup2(int(fd), int(os.Stdin.Fd()))
		syscall.Dup2(int(fd), int(os.Stdout.Fd()))
		syscall.Dup2(int(fd), int(os.Stderr.Fd()))
	}

	return 0
}
Exemple #30
0
func (l *linuxStandardInit) Init() error {
	ringname, keepperms, newperms := l.getSessionRingParams()

	// do not inherit the parent's session keyring
	sessKeyId, err := keyctl.JoinSessionKeyring(ringname)
	if err != nil {
		return err
	}
	// make session keyring searcheable
	if err := keyctl.ModKeyringPerm(sessKeyId, keepperms, newperms); err != nil {
		return err
	}

	var console *linuxConsole
	if l.config.Console != "" {
		console = newConsoleFromPath(l.config.Console)
		if err := console.dupStdio(); err != nil {
			return err
		}
	}
	if console != nil {
		if err := system.Setctty(); err != nil {
			return err
		}
	}
	if err := setupNetwork(l.config); err != nil {
		return err
	}
	if err := setupRoute(l.config.Config); err != nil {
		return err
	}

	label.Init()
	// InitializeMountNamespace() can be executed only for a new mount namespace
	if l.config.Config.Namespaces.Contains(configs.NEWNS) {
		if err := setupRootfs(l.config.Config, console, l.pipe); err != nil {
			return err
		}
	}
	if hostname := l.config.Config.Hostname; hostname != "" {
		if err := syscall.Sethostname([]byte(hostname)); err != nil {
			return err
		}
	}
	if err := apparmor.ApplyProfile(l.config.AppArmorProfile); err != nil {
		return err
	}
	if err := label.SetProcessLabel(l.config.ProcessLabel); err != nil {
		return err
	}

	for key, value := range l.config.Config.Sysctl {
		if err := writeSystemProperty(key, value); err != nil {
			return err
		}
	}
	for _, path := range l.config.Config.ReadonlyPaths {
		if err := remountReadonly(path); err != nil {
			return err
		}
	}
	for _, path := range l.config.Config.MaskPaths {
		if err := maskFile(path); err != nil {
			return err
		}
	}
	pdeath, err := system.GetParentDeathSignal()
	if err != nil {
		return err
	}
	if l.config.NoNewPrivileges {
		if err := system.Prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); err != nil {
			return err
		}
	}
	// Tell our parent that we're ready to Execv. This must be done before the
	// Seccomp rules have been applied, because we need to be able to read and
	// write to a socket.
	if err := syncParentReady(l.pipe); err != nil {
		return err
	}
	// Without NoNewPrivileges seccomp is a privileged operation, so we need to
	// do this before dropping capabilities; otherwise do it as late as possible
	// just before execve so as few syscalls take place after it as possible.
	if l.config.Config.Seccomp != nil && !l.config.NoNewPrivileges {
		if err := seccomp.InitSeccomp(l.config.Config.Seccomp); err != nil {
			return err
		}
	}
	if err := finalizeNamespace(l.config); err != nil {
		return err
	}
	// finalizeNamespace can change user/group which clears the parent death
	// signal, so we restore it here.
	if err := pdeath.Restore(); err != nil {
		return err
	}
	// compare the parent from the inital start of the init process and make sure that it did not change.
	// if the parent changes that means it died and we were reparened to something else so we should
	// just kill ourself and not cause problems for someone else.
	if syscall.Getppid() != l.parentPid {
		return syscall.Kill(syscall.Getpid(), syscall.SIGKILL)
	}
	if l.config.Config.Seccomp != nil && l.config.NoNewPrivileges {
		if err := seccomp.InitSeccomp(l.config.Config.Seccomp); err != nil {
			return err
		}
	}

	return system.Execv(l.config.Args[0], l.config.Args[0:], os.Environ())
}