• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
RunBrowsePython(State * state,const char * ninja_command,const char * input_file,int argc,char * argv[])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 }
79