d9ngle
d9ngle

Reputation: 1469

How to pass a pointer using exec argv in C?

I'm trying to demonstrate that programs started using exec can't derefernce inherited pointers but my pointer looks different. Is this intended?

p1.c:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

void main()
{
    int *pint = malloc(sizeof(int));
    *pint = 25;
    printf("[main] pint: @%p = %d\n", pint, *pint);

    int h = fork();

    if(h == 0) {
        (*pint)++;
        printf("[fork] pint: @%p = %d\n", pint, *pint);
        char *fname="./p2";
        char *arg[3];
        arg[0] = "./p2";
        arg[1] = (char*)pint;
        arg[2] = NULL;
        printf("[fork] arg1: @%p = %d\n", arg[1], *arg[1]);
        execvp(fname, arg);
    } else {
        sleep(1);
        printf("[main] pint: @%p = %d\n", pint, *pint);
    }

}

p2.c:

#include <stdio.h>

int main(int argc,void *argv[])
{
    printf("[ p2 ] arg1: @%p\n", argv[1]);
}

Here's a sample output that I'm getting:

$ ./p1
[main] pint: @0x55de8f6db260 = 25
[fork] pint: @0x55de8f6db260 = 26
[fork] arg1: @0x55de8f6db260 = 26
[ p2 ] arg1: @0x7ffe13b9fc65 // <--- mismatch
[main] pint: @0x55de8f6db260 = 25

Upvotes: 1

Views: 536

Answers (2)

d9ngle
d9ngle

Reputation: 1469

As mentioned by kaylum, rici and Some programmer dude, one needs to convert pointer to string and then cast that string back to pointer to accomplish this, so:

p1.c:

char arg1[64];
snprintf(arg1, sizeof arg1, "%p", pint);
printf("[fork] arg1: @%s\n", arg1);

arg[0] = "./p2";
arg[1] = arg1;
arg[2] = NULL;

p2.c:

unsigned long long int *pint;
pint = (int*)strtoull(argv[1], NULL, 16);

Upvotes: 0

Some programmer dude
Some programmer dude

Reputation: 409364

The arguments you pass must be strings. That means

arg[1] = (char*)pint;

is wrong.

You need to create a string, and copy the textual representation of the value into the string.

Something like

char arg1[64];
snprintf(arg1, sizeof arg1, "%d", *pint);
arg[1] = arg1;

The requirement that the arguments are strings also means that void *argv[] is wrong as well.

Upvotes: 3

Related Questions