Skip to content

Instantly share code, notes, and snippets.

@mbcrawfo
Last active August 29, 2015 14:16
Show Gist options
  • Save mbcrawfo/53616e8c924f26748773 to your computer and use it in GitHub Desktop.
Save mbcrawfo/53616e8c924f26748773 to your computer and use it in GitHub Desktop.
setpgid race condition
#include <unistd.h>
int main()
{
while (1)
{
sleep(1);
}
}
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
char* args[] = {
"./infy",
NULL
};
int main(int argc, char* argv[])
{
if (argc != 2)
{
fprintf(stderr, "Usage: %s [num]\n", argv[0]);
return 1;
}
int num = strtol(argv[1], NULL, 10);
if (num < 2)
{
fprintf(stderr, "Invalid number of processes\n");
return 1;
}
pid_t pid = fork();
if (pid > 0)
{
int s;
waitpid(pid, &s, 0);
fprintf(stderr, "Children done\n");
}
else
{
pid_t pgid = -1;
int i;
for (i = 1; i < num; i++)
{
pid_t pid2 = fork();
if (pid2 > 0)
{
if (pgid == -1)
{
pgid = pid2;
}
}
else
{
if (setpgid(0, pgid == -1 ? 0 : pgid) != 0)
{
perror("setpgid failed in non-last process");
}
execve(args[0], args, NULL);
perror("exec failed");
exit(1);
}
}
// uncomment me to fix
//fprintf(stderr, "pgid %d\n", pgid);
if (setpgid(0, pgid) != 0)
{
perror("setpgid failed in last process");
}
execve(args[0], args, NULL);
perror("exec failed");
exit(1);
}
}
@mbcrawfo
Copy link
Author

Compile each file as a separate program. After executing ./test 3 (or any number > 2), ps jx will show that all of the infy processes are in the same group. ./test 2 will present an error that setpgid has failed. Uncommenting line 58 will cause ./test 2 to work as expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment