Dennis
Dennis

Reputation: 1169

strtok returns too many strings

I am developing a program that's a sort of heartbeat designed to run on a variety of servers. The function in question, reproduced below, retrieves the list of "friends," and for each "friend" in the list, it executes a handshake operation (via ping_and_report, not shown).

The problem is that on first call to this routine, strtok_r seems to return more strings than are present in the source, and I have not been able to determine why. The code:

void pingServerList(int dummy) {
    char *p ;
    char *my_friends ;
    char *nextSvr, *savePtr ; ;
    char  *separators = ",; \t" ;
    server_list_t *ent = NULL ;
    static long round_nbr = 0  ;
    unsigned int len ;
    time_t now ;
    char   message[4096] ;
    char   *hex ;

    round_nbr++ ;
    p = get_server_list() ;
    if (p) {
        len =strlen(p) ;
        my_friends = malloc(len+1) ;
        strncpy(my_friends, p, len) ;
        }
    nextSvr = strtok_r(my_friends, separators, &savePtr) ;
    while (nextSvr) {
        // Ensure that nobody messes with nextSvr. . .
        char *workSvr = malloc(strlen(nextSvr) + 1) ;
        strcpy(workSvr, nextSvr) ;
        if (debug) {
            len = strlen(workSvr) * 2 + 3 ;
            hex = malloc(len) ;
            get_hex_val(workSvr, hex, len) ;
            write_log(fp_debug
                    , "Server: %s (x'%s')"
                    , workSvr, hex) ;
            free(hex) ;
            }
        ping_and_report(workSvr, round_nbr) ;
        free(workSvr) ;
        nextSvr = strtok_r(NULL, separators, &savePtr) ;
        }

... is not too complex at that point, I think. And I don't see any room for mucking with the values. But the log file reveals the issue here:

2012-07-09 23:26 Debug activated...
2012-07-09 23:26 get_server_list() returning velmicro, stora-2 (x'76656C6D6963726F2C2073746F72612D32')
2012-07-09 23:26 Server: velmicro (x'76656C6D6963726F')
2012-07-09 23:26 Server: stora-2 (x'73746F72612D32')
2012-07-09 23:26 Server: re (x'726519')

The crazy thing is that (at least from several executions of the code) this will only fail on the first call. Calls 2-n (where n is in the hundreds) do not exhibit this problem.

Do any of you folks see what I'm obviously missing? (BTW: this fails exactly the same way on four different systems with versions of linux.)

Upvotes: 0

Views: 165

Answers (1)

AndersK
AndersK

Reputation: 36102

when you write this

strncpy(my_friends, p, len) ;

you are not ensuring that my_friends ends with a \0

try

strncpy(my_friends, p, len)[len-1] = '\0';

alt. use calloc to allocate my_friends

Upvotes: 3

Related Questions