-
Notifications
You must be signed in to change notification settings - Fork 960
Expand file tree
/
Copy pathmain.c
More file actions
51 lines (47 loc) · 1.58 KB
/
main.c
File metadata and controls
51 lines (47 loc) · 1.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define CHILD_MARKER "child"
#define EXPECTED_MAIN_ARG "--extra-arg"
int main(int argc, char* argv[]) {
/* Child mode: invoked via execvp(argv[0], ...) from the parent.
* Verify that the command's main_args are NOT re-injected a second time. */
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], CHILD_MARKER) == 0) {
if (argc != 2) {
fprintf(stderr, "FAIL: child expected argc=2 but got %d\n", argc);
for (int j = 0; j < argc; j++) {
fprintf(stderr, " argv[%d] = %s\n", j, argv[j]);
}
return 1;
}
/* Success: main_args were not re-injected into the re-exec'd process */
return 0;
}
}
/* Parent mode: verify that the command's main_args were injected for us */
int found_main_arg = 0;
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], EXPECTED_MAIN_ARG) == 0) {
found_main_arg = 1;
break;
}
}
if (!found_main_arg) {
fprintf(stderr, "FAIL: parent expected '%s' in argv but did not find it\n",
EXPECTED_MAIN_ARG);
for (int j = 0; j < argc; j++) {
fprintf(stderr, " argv[%d] = %s\n", j, argv[j]);
}
return 1;
}
/* Re-exec ourselves via argv[0] with the child marker.
* After the fix, argv[0] is the atom name (not the command name), so
* execvp will find the raw atom binary without command metadata, preventing
* main_args from being re-injected. */
char* new_argv[] = {argv[0], CHILD_MARKER, NULL};
execvp(argv[0], new_argv);
perror("execvp failed");
return 1;
}