Reputation: 1169
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
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