Ninja
browse.cc
Go to the documentation of this file.
1 // Copyright 2011 Google Inc. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "browse.h"
16 
17 #include <errno.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <unistd.h>
21 #include <vector>
22 
23 #include "build/browse_py.h"
24 
25 void RunBrowsePython(State* state, const char* ninja_command,
26  const char* input_file, int argc, char* argv[]) {
27  // Fork off a Python process and have it run our code via its stdin.
28  // (Actually the Python process becomes the parent.)
29  int pipefd[2];
30  if (pipe(pipefd) < 0) {
31  perror("ninja: pipe");
32  return;
33  }
34 
35  pid_t pid = fork();
36  if (pid < 0) {
37  perror("ninja: fork");
38  return;
39  }
40 
41  if (pid > 0) { // Parent.
42  close(pipefd[1]);
43  do {
44  if (dup2(pipefd[0], 0) < 0) {
45  perror("ninja: dup2");
46  break;
47  }
48 
49  std::vector<const char *> command;
50  command.push_back(NINJA_PYTHON);
51  command.push_back("-");
52  command.push_back("--ninja-command");
53  command.push_back(ninja_command);
54  command.push_back("-f");
55  command.push_back(input_file);
56  for (int i = 0; i < argc; i++) {
57  command.push_back(argv[i]);
58  }
59  command.push_back(NULL);
60  execvp(command[0], (char**)&command[0]);
61  if (errno == ENOENT) {
62  printf("ninja: %s is required for the browse tool\n", NINJA_PYTHON);
63  } else {
64  perror("ninja: execvp");
65  }
66  } while (false);
67  _exit(1);
68  } else { // Child.
69  close(pipefd[0]);
70 
71  // Write the script file into the stdin of the Python process.
72  ssize_t len = write(pipefd[1], kBrowsePy, sizeof(kBrowsePy));
73  if (len < (ssize_t)sizeof(kBrowsePy))
74  perror("ninja: write");
75  close(pipefd[1]);
76  exit(0);
77  }
78 }
void RunBrowsePython(State *state, const char *ninja_command, const char *input_file, int argc, char *argv[])
Run in "browse" mode, which execs a Python webserver.
Definition: browse.cc:25
Global state (file status) for a single run.
Definition: state.h:85