Matthew Ronchetto
Matthew Ronchetto

Reputation: 33

Unsure how strcpy works in this situation

I am very new to C and working through a project as a way to help motivate me to learn. I was having a hard time getting the output from an sh popen. After much searching and hours of trial and i stumbled across a very old post where they used

strcpy(str + size - 1,buf);

This was the first and only example of this i could find and it is working. It looks like it overwrites the termination character at the end of str with what's in buf. Is that safe? I still havent fully gotten the grasp of how it stores all of this data and changing that number on the end to anything higher than a +2 causes segmentation faults or invalid next size. The full code is below

int dns_probe(char * hostname)
{
    char * digLoop[4] = {"ns ","a ","cname ","mx "};
    int i;
    char outage[1];
    char *str = NULL;
    char *temp = NULL;
    unsigned int size = 1;
    unsigned int strlength;

    for ( i = 0; i < 4; i++)
    {
        char *digcmd = concatCMD(digLoop[i],hostname);

        FILE * dig = popen(digcmd,"r");
        char bufer[256];
        while(fgets(buf,sizeof(buf),dig) != 0){

            strlength = strlen(buf);

            temp = realloc(str, size + strlength);
            str = temp;

            strcpy(str + size - 1,buf);
            size += strlength;
        }

       pclose(dig);
       free(digcmd);

    }
    printf("%s",str);
}

Really just wanna make sure I am not setting myself up with problems down the road.

Upvotes: 2

Views: 92

Answers (2)

Addison
Addison

Reputation: 121

        `temp = realloc(str, size + strlength);`

//buf of str is re-allocated to length (size+strlength),and then more bytes are written to this newly allocated. with an initial length 1, buffer of str is safe here. However, strcpy is highly recommended which is safer.

And here, https://www.tutorialspoint.com/c_standard_library/c_function_strcpy.htm you can find some simple cases for study.

Upvotes: 0

unwind
unwind

Reputation: 399713

Yes, this is safe as long as the realloc() ensures that the buffer is large enough (and it does).

Before the realloc() you might have:

     +---+---+---+----+
buf: | f | o | o | \0 | size=4
     +---+---+---+----+

Then let's assume "bar" is read, so that:

strlength = strlen("bar") = 3

Then temp will be realloc()ated to length 4 + 3 = 7:

      +---+---+---+----+---+---+---+
temp: | f | o | o | \0 | ? | ? | ? | 
      +---+---+---+----+---+---+---+

Then buf is set to temp (there should be NULL-checks here, btw).

Finally we strcpy() "bar" to buf + 4 - 1, i.e. buf[3]:

      +---+---+---+---+---+---+----+
 buf: | f | o | o | b | a | r | \0 |
      +---+---+---+---+---+---+----+

Clearly this buffer is the same size as before, and no character outside the buffer has been touched.

Upvotes: 3

Related Questions