/* execute a compiler backend, capturing all output to the given paths the full path to the compiler to run is in argv[0] */ int execute(char **argv, const char *path_stdout, const char *path_stderr) { pid_t pid; int status; cc_log_argv("Executing ", argv); pid = fork(); if (pid == -1) fatal("Failed to fork: %s", strerror(errno)); if (pid == 0) { int fd; tmp_unlink(path_stdout); fd = open(path_stdout, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_BINARY, 0666); if (fd == -1) { cc_log("Error creating %s: %s", path_stdout, strerror(errno)); exit(FAILED_TO_CREATE_STDOUT); } dup2(fd, 1); close(fd); tmp_unlink(path_stderr); fd = open(path_stderr, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_BINARY, 0666); if (fd == -1) { cc_log("Error creating %s: %s", path_stderr, strerror(errno)); exit(FAILED_TO_CREATE_STDERR); } dup2(fd, 2); close(fd); exit(execv(argv[0], argv)); } if (waitpid(pid, &status, 0) != pid) { fatal("waitpid failed: %s", strerror(errno)); } if (WEXITSTATUS(status) == 0 && WIFSIGNALED(status)) { return -1; } if (status == FAILED_TO_CREATE_STDOUT) { fatal("Could not create %s (permission denied?)", path_stdout); } else if (status == FAILED_TO_CREATE_STDERR) { fatal("Could not create %s (permission denied?)", path_stderr); } return WEXITSTATUS(status); }
/* * Release the lockfile for the given path. Assumes that we are the legitimate * owner. */ void lockfile_release(const char *path) { char *lockfile = format("%s.lock", path); cc_log("Releasing lock %s", lockfile); tmp_unlink(lockfile); free(lockfile); }
/* execute a compiler backend, capturing all output to the given paths the full path to the compiler to run is in argv[0] */ int execute(char **argv, const char *path_stdout, const char *path_stderr) { pid_t pid; int status, fd_out, fd_err; cc_log_argv("Executing ", argv); tmp_unlink(path_stdout); fd_out = open(path_stdout, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_BINARY, 0666); if (fd_out == -1) { fatal("Error creating %s: %s", path_stdout, strerror(errno)); } tmp_unlink(path_stderr); fd_err = open(path_stderr, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_BINARY, 0666); if (fd_err == -1) { fatal("Error creating %s: %s", path_stderr, strerror(errno)); } pid = fork(); if (pid == -1) fatal("Failed to fork: %s", strerror(errno)); if (pid == 0) { /* Child. */ dup2(fd_out, 1); close(fd_out); dup2(fd_err, 2); close(fd_err); exit(execv(argv[0], argv)); } close(fd_out); close(fd_err); if (waitpid(pid, &status, 0) != pid) { fatal("waitpid failed: %s", strerror(errno)); } if (WEXITSTATUS(status) == 0 && WIFSIGNALED(status)) { return -1; } return WEXITSTATUS(status); }
/* execute a compiler backend, capturing all output to the given paths the full path to the compiler to run is in argv[0] */ int execute(char **argv, const char *path_stdout, const char *path_stderr) { pid_t pid; int status; cc_log_argv("Executing ", argv); pid = fork(); if (pid == -1) fatal("Failed to fork"); if (pid == 0) { int fd; tmp_unlink(path_stdout); fd = open(path_stdout, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_BINARY, 0666); if (fd == -1) { exit(1); } dup2(fd, 1); close(fd); tmp_unlink(path_stderr); fd = open(path_stderr, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_BINARY, 0666); if (fd == -1) { exit(1); } dup2(fd, 2); close(fd); exit(execv(argv[0], argv)); } if (waitpid(pid, &status, 0) != pid) { fatal("waitpid failed"); } if (WEXITSTATUS(status) == 0 && WIFSIGNALED(status)) { return -1; } return WEXITSTATUS(status); }