Пример #1
0
func (s *Contester) LocalExecuteConnected(request *contester_proto.LocalExecuteConnected, response *contester_proto.LocalExecuteConnectedResult) error {
	firstSandbox, err := findSandbox(s.Sandboxes, request.First)
	if err != nil {
		return err
	}

	secondSandbox, err := findSandbox(s.Sandboxes, request.Second)
	if err != nil {
		return err
	}

	firstSandbox.Mutex.Lock()
	defer firstSandbox.Mutex.Unlock()

	secondSandbox.Mutex.Lock()
	defer secondSandbox.Mutex.Unlock()

	err = chmodRequestIfNeeded(firstSandbox, request.First)
	if err != nil {
		return err
	}

	err = chmodRequestIfNeeded(secondSandbox, request.Second)
	if err != nil {
		return err
	}

	first, err := s.setupSubprocess(request.First, firstSandbox, false)
	if err != nil {
		return err
	}

	second, err := s.setupSubprocess(request.Second, secondSandbox, false)
	if err != nil {
		return err
	}

	err = subprocess.Interconnect(first, second, nil, nil)
	if err != nil {
		return err
	}

	cs := make(chan runResult, 1)
	outstanding := 2

	go execAndSend(first, cs, false)
	go execAndSend(second, cs, true)

	for outstanding > 0 {
		r := <-cs
		outstanding--

		if r.second {
			if r.e != nil {
				err = r.e
			} else {
				response.Second = &contester_proto.LocalExecutionResult{}
				fillResult(r.r, response.Second)
			}
		} else {
			if r.e != nil {
				err = r.e
			} else {
				response.First = &contester_proto.LocalExecutionResult{}
				fillResult(r.r, response.First)
			}
		}
	}

	return err
}
Пример #2
0
func main() {
	programFlags, globalFlags, err := ParseFlags(true, os.Args[1:])

	if err != nil {
		Fail(globalFlags.Xml, err, "Parse main flags")
	}

	if globalFlags.Logfile != "" {
		logfile, err := os.Create(globalFlags.Logfile)
		if err != nil {
			log.Fatal(err)
		}
		log.SetOutput(logfile)
	}

	var interactorFlags *ProcessConfig

	if globalFlags.Interactor != "" {
		interactorFlags, _, err = ParseFlags(false, strings.Split(globalFlags.Interactor, " "))
		if err != nil {
			Fail(globalFlags.Xml, err, "Parse interator flags")
		}
	}

	if globalFlags.Xml {
		fmt.Println(XML_HEADER)
	}

	desktop, err := CreateDesktopIfNeeded(programFlags, interactorFlags)
	if err != nil {
		Fail(globalFlags.Xml, err, "Create desktop if needed")
	}

	loadLibrary, err := GetLoadLibraryIfNeeded(programFlags, interactorFlags)
	if err != nil {
		Fail(globalFlags.Xml, err, "Load library if needed")
	}

	var program, interactor *subprocess.Subprocess
	program, err = SetupSubprocess(programFlags, desktop, loadLibrary)
	if err != nil {
		Fail(globalFlags.Xml, err, "Setup main subprocess")
	}

	if interactorFlags != nil {
		interactor, err = SetupSubprocess(interactorFlags, desktop, loadLibrary)
		if err != nil {
			Fail(globalFlags.Xml, err, "Setup interactor subprocess")
		}

		var recordI, recordO *os.File

		if globalFlags.RecordProgramInput != "" {
			recordI, err = os.Create(globalFlags.RecordProgramInput)
			if err != nil {
				Fail(globalFlags.Xml, err, "Create input recorded")
			}
		}
		if globalFlags.RecordProgramOutput != "" {
			recordO, err = os.Create(globalFlags.RecordProgramOutput)
			if err != nil {
				Fail(globalFlags.Xml, err, "Create output recorder")
			}
		}

		err = subprocess.Interconnect(program, interactor, recordI, recordO)
		if err != nil {
			Fail(globalFlags.Xml, err, "Interconnect")
		}
	}

	cs := make(chan RunResult, 1)
	outstanding := 1
	if interactor != nil {
		outstanding++
		go ExecAndSend(interactor, cs, INTERACTOR)
	}
	go ExecAndSend(program, cs, PROGRAM)

	var results [2]*RunResult

	var programReturnCode int

	for outstanding > 0 {
		r := <-cs
		outstanding--
		results[int(r.T)] = &r
		if r.T == PROGRAM && r.R != nil {
			programReturnCode = int(r.R.ExitCode)
		}
	}

	if globalFlags.Xml {
		fmt.Println(XML_RESULTS_START)
	}

	for _, result := range results {
		if result == nil {
			continue
		}

		PrintResult(globalFlags.Xml, globalFlags.ShowKernelModeTime, result)
	}

	if globalFlags.Xml {
		fmt.Println(XML_RESULTS_END)
	}

	if globalFlags.ReturnExitCode {
		os.Exit(programReturnCode)
	}
}