Skip to content

Instantly share code, notes, and snippets.

@kr

kr/Intro.md Secret

Created December 13, 2012 00:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kr/b4852e149f45a43fb17a to your computer and use it in GitHub Desktop.
Save kr/b4852e149f45a43fb17a to your computer and use it in GitHub Desktop.
Make jobserver fds still open in subprocess

Steps to reproduce:

  1. make x
  2. make -j4 foo

Expected output:

./x
rjob is 3
wjob is 4
number of jobs is 1

Observed output:

./x
rjob is 3
wjob is 4
read make job token 43 +
read make job token 43 +
read make job token 43 +
number of jobs is 4

The description in http://mad-scientist.net/make/jobserver.html says that make will close the jobserver fds when it runs a job that's not another make, which it decides by looking for $(MAKE) in the command or + at the beginning of the command. My reading of the make source code agrees with this description, but I'm seeing different behavior. I'm confused.

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
int
main()
{
int rjob = 0, wjob = 0;
int n = 1;
char c, *s;
s = strstr(getenv("MAKEFLAGS"), " --jobserver-fds=");
if (!s) {
puts("no jobserver flag");
}
s = s + 17; // length of " --jobserver-fds="
rjob = (int)strtol(s, &s, 10);
wjob = (int)strtol(s+1, NULL, 10); // skip comma
printf("rjob is %d\n", rjob);
printf("wjob is %d\n", wjob);
if (rjob) {
fcntl(rjob, F_SETFL, fcntl(3, F_GETFL)|O_NONBLOCK);
while (read(rjob, &c, 1) > 0) {
printf("read make job token %d %c\n", c, c);
n++;
}
}
printf("number of jobs is %d\n", n);
c = '+';
if (wjob) {
fcntl(wjob, F_SETFL, fcntl(4, F_GETFL)|O_NONBLOCK);
for (; n > 1; n--) {
write(wjob, &c, 1); // ignore error; nothing we can do anyway
}
}
return n;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment