| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- #ifndef _CRT_SECURE_NO_WARNINGS
- # define _CRT_SECURE_NO_WARNINGS
- #endif
- #if defined(_MSC_VER) && _MSC_VER >= 1928
- # pragma warning(disable : 5105) /* macro expansion warning in windows.h */
- #endif
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #define MAX_MESSAGE_LENGTH 1023
- #define USAGE "Usage: %s <output_file>\n"
- // Extracts the jobserver details from the MAKEFLAGS environment variable.
- //
- // Returns a pointer to either a string of the form "R,W" where R and W are fds
- // or "fifo:PATH".
- //
- // Returns NULL if MAKEFLAGS is not set or does not contain recognized
- // jobserver flags.
- char* jobserver_auth(char* message)
- {
- const char* jobserver_flags[3] = { "--jobserver-auth=", "--jobserver-fds=",
- "-J" };
- char* start = NULL;
- char* end;
- char* result;
- size_t len;
- int i;
- char* makeflags = getenv("MAKEFLAGS");
- if (makeflags == NULL) {
- strncpy(message, "MAKEFLAGS not set", MAX_MESSAGE_LENGTH);
- return NULL;
- }
- fprintf(stdout, "MAKEFLAGS: %s\n", makeflags);
- for (i = 0; i < 3; i++) {
- start = strstr(makeflags, jobserver_flags[i]);
- if (start != NULL) {
- start += strlen(jobserver_flags[i]);
- break;
- }
- }
- if (start == NULL) {
- strncpy(message, "No jobserver flags found", MAX_MESSAGE_LENGTH);
- return NULL;
- }
- // Skip leading white space
- while (*start == ' ' || *start == '\t') {
- start++;
- }
- end = strchr(start, ' ');
- if (end == NULL) {
- end = start + strlen(start);
- }
- len = (size_t)(end - start);
- result = (char*)malloc(len + 1);
- strncpy(result, start, len);
- result[len] = '\0';
- return result;
- }
- #if defined(_WIN32)
- # include <windows.h>
- int windows_semaphore(const char* semaphore, char* message)
- {
- // Open the semaphore
- HANDLE hSemaphore = OpenSemaphoreA(SEMAPHORE_ALL_ACCESS, FALSE, semaphore);
- if (hSemaphore == NULL) {
- # if defined(_MSC_VER) && _MSC_VER < 1900
- sprintf(message, "Error opening semaphore: %s (%ld)\n", semaphore,
- GetLastError());
- # else
- snprintf(message, MAX_MESSAGE_LENGTH,
- "Error opening semaphore: %s (%ld)\n", semaphore, GetLastError());
- # endif
- return 1;
- }
- strncpy(message, "Success", MAX_MESSAGE_LENGTH);
- return 0;
- }
- #else
- # include <errno.h>
- # include <fcntl.h>
- int test_fd(int read_fd, int write_fd, char* message)
- {
- // Detect if the file descriptors are valid
- int read_good = fcntl(read_fd, F_GETFD) != -1;
- int read_error = errno;
- int write_good = fcntl(write_fd, F_GETFD) != -1;
- int write_error = errno;
- if (!read_good || !write_good) {
- snprintf(message, MAX_MESSAGE_LENGTH,
- "Error opening file descriptors: %d (%s), %d (%s)\n", read_fd,
- strerror(read_error), write_fd, strerror(write_error));
- return 1;
- }
- snprintf(message, MAX_MESSAGE_LENGTH, "Success\n");
- return 0;
- }
- int posix(const char* jobserver, char* message)
- {
- int read_fd;
- int write_fd;
- const char* path;
- // First try to parse as "R,W" file descriptors
- if (sscanf(jobserver, "%d,%d", &read_fd, &write_fd) == 2) {
- return test_fd(read_fd, write_fd, message);
- }
- // Then try to parse as "fifo:PATH"
- if (strncmp(jobserver, "fifo:", 5) == 0) {
- path = jobserver + 5;
- read_fd = open(path, O_RDONLY);
- write_fd = open(path, O_WRONLY);
- return test_fd(read_fd, write_fd, message);
- }
- // We don't understand the format
- snprintf(message, MAX_MESSAGE_LENGTH, "Unrecognized jobserver format: %s\n",
- jobserver);
- return 1;
- }
- #endif
- // Takes 1 argument: an outfile to write results to.
- int main(int argc, char** argv)
- {
- char message[MAX_MESSAGE_LENGTH + 1];
- char* output_file;
- FILE* fp;
- char* jobserver;
- int result;
- if (argc != 2) {
- fprintf(stderr, USAGE, argv[0]);
- return 2;
- }
- output_file = argv[1];
- fp = fopen(output_file, "w");
- if (fp == NULL) {
- fprintf(stderr, "Error opening output file: %s\n", output_file);
- return 2;
- }
- jobserver = jobserver_auth(message);
- if (jobserver == NULL) {
- fprintf(stderr, "%s\n", message);
- return 1;
- }
- #if defined(_WIN32)
- result = windows_semaphore(jobserver, message);
- #else
- result = posix(jobserver, message);
- #endif
- free(jobserver);
- message[MAX_MESSAGE_LENGTH] = '\0';
- return result;
- }
|