C - Unwanted output characters

Let's say I have two programs - input.c and output.c All I want to do is send some payload / characters in half-pyramid format to another using the execl () function.

input.c

#include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> #define SIZE 1024 int length; int main(int argc, char *argv[]) { pid_t pid; char *target; //char payload[length+1]; char payload[SIZE + 1]; int status; int i = 0; if(argc < 2) { printf("Usage %s <length> <target>\n", argv[0]); exit(EXIT_FAILURE); } length = atoi(argv[1]); target = argv[2]; while(i < length) { pid = fork(); if(pid != 0) { waitpid(-1, &status, 0); //exit(0); } if(pid == 0) { payload[i] = 'A'; payload[i + 1] = '\0'; execl(target, target, payload, NULL); //printf("%s\n", payload); } ++i; } return 0; } 

Commented passages are for debugging purposes only. Because, as you can see (when trying), when you just want to print it, everything works correctly.

output.c (or if you want "target.c")

 #include <stdio.h> #include <string.h> int main(int argc, char *argv[]) { char buffer[30]; strncpy(buffer, argv[1], sizeof(buffer)); printf("Output: %s\n", buffer); return 0; } 

When I compile input.c as:

 gcc input.c -o input 

& output.c:

 gcc output.c -o output 

Ok Now everything is ready. Say I would like to send a payload of length 6

 ./input 6 ./output 

but all I get in the output is simple (or just with other junks characters):

 Output: A Output: 0A Output: 0,A Output: 0, A Output: 0, 8A Output: 0, 8 A 

I tried so many things, but they were all unsuccessful, and the output was the same as you can see above.

I would be very grateful if anyone could help me and maybe show me where the problem is. Could it be a problem when sharing fork () and execl ()?

+6
source share
2 answers

Having received this, you should not update payload in the code of the child block ...

Here's the fix (can't check it now):

  while(i < length) { pid = fork(); payload[i] = 'A'; payload[i + 1] = '\0'; if(pid != 0) { waitpid(-1, &status, 0); //exit(0); } if(pid == 0) { execl(target, target, payload, NULL); //printf("%s\n", payload); } ++i; } 

[removed unrelated sentence]

EDIT (additional clarification): The payload update must be in both the parent and child codes. If you do not understand why, I can add more explanations.

EDIT2 (on request). You want to update the payload for the next child process. In your code, all child codes are replaced by execl() with target . Thus, fork() is executed only by the first parent process (root).

You must update the payload with the first parent and make it available to all children as well. Entering this block into this block will also not work:

 // block only executed by the first parent. if(pid != 0) { waitpid(-1, &status, 0); } 

Therefore, you should update it in a place accessible to the parent and child: after the fork() block before the if(pid == 0) block.

In your code, you increment i in the shared block, but the parent payload never updated. So, in the child block, before execl() , you added ' A\0' to the end of the line of uninitialized C.

+5
source

When your fork program, it creates a new process. This new process after if(pid == 0) modifies payload and starts exec (i.e., executes output , which then dies. That is, your payload change remains in the child and does not affect the parent process. ++i only , so you see unified data.

Move the payload change before the fork (or at least from the child-only block), so it is also in the parent.

+2
source

Source: https://habr.com/ru/post/985279/


All Articles