Ninja
browse.cc
Go to the documentation of this file.
00001 // Copyright 2011 Google Inc. All Rights Reserved.
00002 //
00003 // Licensed under the Apache License, Version 2.0 (the "License");
00004 // you may not use this file except in compliance with the License.
00005 // You may obtain a copy of the License at
00006 //
00007 //     http://www.apache.org/licenses/LICENSE-2.0
00008 //
00009 // Unless required by applicable law or agreed to in writing, software
00010 // distributed under the License is distributed on an "AS IS" BASIS,
00011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00012 // See the License for the specific language governing permissions and
00013 // limitations under the License.
00014 
00015 #include "browse.h"
00016 
00017 #include <stdio.h>
00018 #include <stdlib.h>
00019 #include <unistd.h>
00020 
00021 #include "../build/browse_py.h"
00022 
00023 void RunBrowsePython(State* state, const char* ninja_command,
00024                      const char* initial_target) {
00025   // Fork off a Python process and have it run our code via its stdin.
00026   // (Actually the Python process becomes the parent.)
00027   int pipefd[2];
00028   if (pipe(pipefd) < 0) {
00029     perror("ninja: pipe");
00030     return;
00031   }
00032 
00033   pid_t pid = fork();
00034   if (pid < 0) {
00035     perror("ninja: fork");
00036     return;
00037   }
00038 
00039   if (pid > 0) {  // Parent.
00040     close(pipefd[1]);
00041     do {
00042       if (dup2(pipefd[0], 0) < 0) {
00043         perror("ninja: dup2");
00044         break;
00045       }
00046 
00047       // exec Python, telling it to run the program from stdin.
00048       const char* command[] = {
00049         NINJA_PYTHON, "-", ninja_command, initial_target, NULL
00050       };
00051       execvp(command[0], (char**)command);
00052       perror("ninja: execvp");
00053     } while (false);
00054     _exit(1);
00055   } else {  // Child.
00056     close(pipefd[0]);
00057 
00058     // Write the script file into the stdin of the Python process.
00059     ssize_t len = write(pipefd[1], kBrowsePy, sizeof(kBrowsePy));
00060     if (len < (ssize_t)sizeof(kBrowsePy))
00061       perror("ninja: write");
00062     close(pipefd[1]);
00063     exit(0);
00064   }
00065 }