Пример #1
0
func BecomeProcessGroupLeader() int {
	pid := syscall.Getpid()
	pgid := syscall.Getpgrp()
	if pid != pgid {
		syscall.Setpgid(0, 0)
	}

	return pid
}
Пример #2
0
func (a *App) setProcessGroupForNelly() {
	// Nelly knows our pid and will check that there is always at
	// least one process in the process group with the same id as our pid
	mypid := syscall.Getpid()
	err := syscall.Setpgid(mypid, mypid)
	if err != nil {
		panic(fmt.Sprintf("Failed to setpgid]: %d - %d - %s\n", mypid, mypid, err.Error()))
	}
}
Пример #3
0
/*
	Execute a command (using arguments 'args')
	Redirect stdout to outFile    (unless file name is empty)
	Redirect stderr to errFile    (unless file name is empty)
	Write exit code to exitFile   (unless file name is empty)
	Timeout after timeout seconds (unless time is zero)
*/
func (be *BdsExec) executeCommand() int {
	if DEBUG {
		log.Printf("Debug: executeCommand %s\n", be.command)
	}

	// Redirect all signals to channel (e.g. Ctrl-C)
	osSignal := make(chan os.Signal)

	if be.taskLoggerFile != "" {
		signal.Notify(osSignal) // Capture all signals
	} else {
		// Set a new process group.
		// Since we want to kill all child processes, we'll send a kill signal to this process group.
		// But we don't want to kill the calling program...
		// fmt.Fprintf(os.Stderr, "bds: setting new process group\n")
		if err := syscall.Setpgid(0, 0); err != nil {
			// During an ssh remote execution we will no be albe to do this.
			// In this case, we assume that the SSH daemon will catch the sinals
			// and kill al child processes.
			if DEBUG {
				log.Printf("Error redirecting signals: %s", err)
			}
		}
	}

	// Create command
	be.cmd = exec.Command(be.command)
	be.cmd.Args = be.cmdargs

	// Copy stdout
	stdout := tee.NewTee(be.outFile, false)
	defer stdout.Close()
	be.cmd.Stdout = stdout

	// Copy stderr
	stderr := tee.NewTee(be.errFile, true)
	defer stderr.Close()
	be.cmd.Stderr = stderr

	// Connect to stdin
	be.cmd.Stdin = os.Stdin

	// Start process
	err := be.cmd.Start()
	if err != nil {
		log.Fatal(err)
	}

	be.exitCode = be.executeCommandTimeout(osSignal)
	if DEBUG {
		log.Printf("Debug, executeCommand: Exit code %d\n", be.exitCode)
	}
	return be.exitCode
}
Пример #4
0
func main() {
	flag.Parse()

	if err := syscall.Setpgid(os.Getpid(), os.Getpid()); err != nil {
		log.Fatalf("setpgid: %v", err)
	}
	forwardSignals()

	datastore := &Emulator{
		Command:       []string{"gcloud", "-q", "beta", "emulators", "pubsub", "start"},
		EnvCommand:    []string{"gcloud", "-q", "beta", "emulators", "pubsub", "env-init"},
		ReadySentinel: "Server started, listening",
	}
	if err := datastore.Start(); err != nil {
		log.Fatalf("Could not start datastore: %v", err)
	}

	pubsub := &Emulator{
		Command:       []string{"gcloud", "-q", "beta", "emulators", "datastore", "start", "--no-legacy"},
		EnvCommand:    []string{"gcloud", "-q", "beta", "emulators", "datastore", "env-init"},
		ReadySentinel: "is now running",
	}
	if err := pubsub.Start(); err != nil {
		log.Fatalf("Could not start pubsub: %v", err)
	}

	datastore.WaitReady()
	pubsub.WaitReady()

	env := os.Environ()
	env = append(env, datastore.Env()...)
	env = append(env, pubsub.Env()...)

	cmd := exec.Command(flag.Args()[0], flag.Args()[1:]...)
	cmd.SysProcAttr = sysprocattr()
	cmd.Env = env
	cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
	cmdErr := cmd.Run()

	if err := datastore.Stop(); err != nil {
		log.Fatalf("Could not stop datastore: %v", err)
	}
	if err := pubsub.Stop(); err != nil {
		log.Fatalf("Could not stop pubsub: %v", err)
	}
	if cmdErr != nil {
		log.Fatal(cmdErr)
	}
}
Пример #5
0
func startProxy(args []string) (cmd *exec.Cmd, stdio PipePair, err error) {
	cmd = exec.Command(args[0], args[1:]...)
	cmd.Stderr = os.Stderr
	in, err := cmd.StdinPipe()
	if err != nil {
		return
	}
	out, err := cmd.StdoutPipe()
	if err != nil {
		return
	}
	stdio = PipePair{out, in}
	err = cmd.Start()
	if err != nil {
		return
	}
	// Give the proxy its own process group, so it doesn't receive our signals.
	syscall.Setpgid(cmd.Process.Pid, cmd.Process.Pid)
	return
}
Пример #6
0
func realStart(cmd *cobra.Command, args []string) error {
	err := syscall.Setpgid(0, 0)
	if err != nil {
		glog.Errorln("Error setting process group ID")
		return err
	}
	socket := Viper.GetString("socket")
	os.Remove(socket)
	err = makeSocketDir(socket)
	if err != nil {
		glog.Errorln("Error creating directory for socket %q", socket)
	}
	l, err := server.NewUnixListener(Viper)
	defer l.Close()
	if err != nil {
		glog.Errorln("Error opening listening socket:", err)
		return err
	}
	server.Run(Viper, l)
	os.Remove(Viper.GetString("socket"))
	return nil
}
Пример #7
0
/*
	Execute a command (using arguments 'args')
	Redirect stdout to outFile    (unless file name is empty)
	Redirect stderr to errFile    (unless file name is empty)
	Write exit code to exitFile   (unless file name is empty)
	Timeout after timeout seconds (unless time is zero)
*/
func executeCommand(command string, args []string, timeSecs int, outFile, errFile, exitFile string) int {
	if DEBUG {
		log.Printf("Debug: executeCommand %s\n", command)
	}

	// Redirect all signals to channel (e.g. Ctrl-C)
	osSignal := make(chan os.Signal)

	if taskLoggerFile != "" {
		signal.Notify(osSignal) // Capture all signals
	} else {
		// Set a new process group.
		// Since we want to kill all child processes, we'll send a kill signal to this process group.
		// But we don't want to kill the calling program...
		// fmt.Fprintf(os.Stderr, "bds: setting new process group\n")
		if err := syscall.Setpgid(0, 0); err != nil {
			// During an ssh remote execution we will no be albe to do this.
			// In this case, we assume that the SSH daemon will catch the sinals
			// and kill al child processes.
			if DEBUG {
				log.Printf("Error redirecting signals: %s", err)
			}
		}
	}

	// Create command
	cmd := exec.Command(command)
	cmd.Args = args

	stdout := tee.NewTee(outFile, false)
	defer stdout.Close()
	cmd.Stdout = stdout

	// stdout, err := cmd.StdoutPipe()
	// if err != nil {
	// 	log.Fatal(err)
	// }
	//
	// // Copy to STDOUT to file (or to stdout)
	// if (outFile == "") || (outFile == "-") {
	// 	go tee(os.Stdout, stdout, false)
	// } else {
	// 	stdoutFile, err := os.Create(outFile)
	// 	if err != nil {
	// 		log.Fatal(err)
	// 	}
	// 	defer stdoutFile.Close()
	// 	go tee(stdoutFile, stdout, false)
	// }

	// stderr, err := cmd.StderrPipe()
	// if err != nil {
	// 	log.Fatal(err)
	// }
	//
	// // Copy to STDERR to file (or to stderr)
	// if (errFile == "") || (errFile == "-") {
	// 	go tee(os.Stderr, stderr, true)
	// } else {
	// 	stderrFile, err := os.Create(errFile)
	// 	if err != nil {
	// 		log.Fatal(err)
	// 	}
	// 	defer stderrFile.Close()
	// 	go tee(stderrFile, stderr, true)
	// }

	// Start process
	err := cmd.Start()
	if err != nil {
		log.Fatal(err)
	}

	exitCode := executeCommandTimeout(cmd, timeSecs, exitFile, osSignal)

	return exitCode
}
Пример #8
0
/*
	Execute a command (using arguments 'args')
	Redirect stdout to outFile    (unless file name is empty)
	Redirect stderr to errFile    (unless file name is empty)
	Write exit code to exitFile   (unless file name is empty)
	Timeout after timeout seconds (unless time is zero)
*/
func (be *BdsExec) executeCommand() int {
	if DEBUG {
		log.Printf("Debug, executeCommand %s\n", be.command)
	}

	// Redirect all signals to channel (e.g. Ctrl-C)
	osSignal := make(chan os.Signal)

	if be.taskLoggerFile != "" {
		// Main bds program
		signal.Notify(osSignal) // Capture all signals
	} else {
		// Set a new process group.
		// We want to be able to kill all child processes, without killing the
		// calling program. E.g. When running using a local executor, the Java Bds
		// calls 'bds exec', so sending a kill to the group when a timeOut occurs,
		// would also kill the parent Java program and kill the whole bds execution
		// (clearly not what we want).
		// To avoid this, we create a new group thus we can send a kill signal to
		// this new process group.

		gpidOri, _ := syscall.Getpgid(0)
		if err := syscall.Setpgid(0, 0); err != nil {
			// During an ssh remote execution we will no be albe to do this.
			// In this case, we assume that the SSH daemon will catch the sinals
			// and kill al child processes.
			if DEBUG {
				log.Printf("Error setting process group: %s", err)
			}
		}

		if DEBUG {
			gpidNew, _ := syscall.Getpgid(0)
			log.Printf("Info: Setting new process group. Original GPID: %d, new GPID: %d\n", gpidOri, gpidNew)
		}
	}

	// Create command
	be.cmd = exec.Command(be.command)
	be.cmd.Args = be.cmdargs

	// Copy stdout
	stdout := tee.NewTee(be.outFile, false)
	defer stdout.Close()
	be.cmd.Stdout = stdout

	// Copy stderr
	stderr := tee.NewTee(be.errFile, true)
	defer stderr.Close()
	be.cmd.Stderr = stderr

	// Connect to stdin
	be.cmd.Stdin = os.Stdin

	// Start process
	err := be.cmd.Start()
	if err != nil {
		log.Fatal(err)
	}

	be.exitCode = be.executeCommandTimeout(osSignal)
	if DEBUG {
		log.Printf("Debug, executeCommand: Exit code %d\n", be.exitCode)
	}
	return be.exitCode
}
Пример #9
0
func setpgidProxy(cmd *exec.Cmd) {
	// Give the proxy its own process group, so it doesn't receive our signals.
	syscall.Setpgid(cmd.Process.Pid, cmd.Process.Pid)
}