Status FBIDBServiceHandler::launch()

in idb_companion/Server/FBIDBServiceHandler.mm [1039:1091]


Status FBIDBServiceHandler::launch(grpc::ServerContext *context, grpc::ServerReaderWriter<idb::LaunchResponse, idb::LaunchRequest> *stream)
{@autoreleasepool{
  idb::LaunchRequest request;
  stream->Read(&request);
  idb::LaunchRequest_Start start = request.start();
  NSError *error = nil;
  FBProcessOutput *stdOut = FBProcessOutput.outputForNullDevice;
  FBProcessOutput *stdErr = FBProcessOutput.outputForNullDevice;
  NSMutableArray<FBFuture *> *completions = NSMutableArray.array;
  if (start.wait_for()) {
    dispatch_queue_t writeQueue = dispatch_queue_create("com.facebook.idb.launch.write", DISPATCH_QUEUE_SERIAL);
    id<FBDataConsumer, FBDataConsumerLifecycle> consumer = pipe_output(idb::ProcessOutput_Interface_STDOUT, writeQueue, stream);
    [completions addObject:consumer.finishedConsuming];
    stdOut = [FBProcessOutput outputForDataConsumer:consumer];
    consumer = pipe_output(idb::ProcessOutput_Interface_STDERR, writeQueue, stream);
    [completions addObject:consumer.finishedConsuming];
    stdErr = [FBProcessOutput outputForDataConsumer:consumer];
  }
  FBProcessIO *io = [[FBProcessIO alloc]
    initWithStdIn:nil
    stdOut:stdOut
    stdErr:stdErr];
  FBApplicationLaunchConfiguration *configuration = [[FBApplicationLaunchConfiguration alloc]
    initWithBundleID:nsstring_from_c_string(start.bundle_id())
    bundleName:nil
    arguments:extract_string_array(start.app_args())
    environment:extract_str_dict(start.env())
    waitForDebugger:(start.wait_for_debugger() ? YES : NO)
    io:io
    launchMode:start.foreground_if_running() ? FBApplicationLaunchModeForegroundIfRunning : FBApplicationLaunchModeFailIfRunning];
  id<FBLaunchedApplication> launchedApp = [[_commandExecutor launch_app:configuration] block:&error];
  if (!launchedApp) {
    if (error.code != 0) {
      return Status(grpc::StatusCode::INTERNAL, error.localizedDescription.UTF8String);
    } else {
      return Status(grpc::StatusCode::FAILED_PRECONDITION, error.localizedDescription.UTF8String);
    }
  }
  // Respond with the pid of the launched process
  idb::LaunchResponse response;
  idb::DebuggerInfo *debugger_info = response.mutable_debugger();
  debugger_info->set_pid(launchedApp.processIdentifier);
  stream->Write(response);
  // Return early if not waiting for output
  if (!start.wait_for()) {
    return Status::OK;
  }
  // Otherwise wait for the client to hang up.
  stream->Read(&request);
  [[launchedApp.applicationTerminated cancel] block:nil];
  [[FBFuture futureWithFutures:completions] block:nil];
  return Status::OK;
}}