Search code examples
cmemcpy

How to copy **argv to a new variable?


I want to make a copy of a variable such as char **argv using something like memcpy but how? can I know the size and how to parameterize it since memcpy doesn't take a two-star as a parameter. Do I have to write a loop?

I have to build up the pipeline before I execute it. Therefore I want to "spawn" variables like argv in every iteration of the loop.

    token = strtok(cmd, "|");
    i = 0;
    while (token != NULL)
    {   
        printf("token %s\n", token);       
        makeArgs(token, &argc, &argv);
        for (int b = 0; b < argc; b++) {
           printf("makeargs %d: %s\n", b, argv[b]);   
        }   

        // Will copy argc characters from array1 to array2
       /* memcpy(makearg,argc, argc*18*sizeof(int));*/    
        shellcommand[i].argv = argv;
        i++;
        token = strtok(NULL, "|");
    }           
   /* do stuff */
   fork_pipes(argc, shellcommand);

My aim is to build up the pipeline like the following.

/*  who | awk '{print $1}' | sort | uniq -c | sort -n */
static char *cmd0[] = { "who",                0 };
static char *cmd1[] = { "awk",  "{print $1}", 0 };
static char *cmd2[] = { "sort",               0 };
static char *cmd3[] = { "uniq", "-c",         0 };
static char *cmd4[] = { "sort", "-n",         0 };

static char **cmds[] = { cmd0, cmd1, cmd2, cmd3, cmd4 };

Solution

  • This code makes a deep copy of argv:

    #include <stdlib.h>
    #include <string.h>
    #include <stdio.h>
    
    int main(int argc, char** argv)
    {
        // allocate memory and copy strings
        char** new_argv = malloc((argc+1) * sizeof *new_argv);
        for(int i = 0; i < argc; ++i)
        {
            size_t length = strlen(argv[i])+1;
            new_argv[i] = malloc(length);
            memcpy(new_argv[i], argv[i], length);
        }
        new_argv[argc] = NULL;
    
        // do operations on new_argv
        for(int i = 0; i < argc; ++i)
        {
            printf("%s\n", new_argv[i]);
        }
    
        // free memory
        for(int i = 0; i < argc; ++i)
        {
            free(new_argv[i]);
        }
        free(new_argv);
    }