0

I am using the libconfig library to read some configuration data from a file. I am having trouble extracting out the function for parsing the information and cleaning up afterwards.

Running strcpy(*hostname, tmp) causes a core dump.

hostname, port, and ip are initialized to NULL.

int parseConfig(char **hostname, char **port, char **ip) {

    config_t cfg, *cf;
    const char *tmp;

    cf = &cfg;
    config_init(cf);

    if(!config_read_file(cf, CONFIG)) {
        fprintf(stderr, "%s:%d - %s\n",
            config_error_file(cf),
            config_error_line(cf),
            config_error_text(cf));
        config_destroy(cf);
        return(EXIT_FAILURE);
    }

    config_lookup_string(cf, "hostname",  &tmp);
    strcpy(*hostname, tmp);
    config_lookup_string(cf, "ip", &tmp);
    strcpy(*ip, tmp);
    config_lookup_string(cf, "port", &tmp);
    strcpy(*port, tmp);

    config_destroy(cf);

    return(EXIT_SUCCESS);
}
timrau
  • 22,578
  • 4
  • 51
  • 64
TheEndIsNear
  • 395
  • 3
  • 17
  • How is `parseConfig` called? Did you compile with all warnings & debug info (`gcc -Wall -Wextra -g`)? Did you use the debugger (`gdb`)? [valgrind](http://valgrind.org/) ? – Basile Starynkevitch Aug 27 '15 at 07:08
  • better to supply an array with a maxsize for hostname instead of **hostname, that way the user of your function will not get a surprise when he supplies a too small buffer. e.g. char hostName[100]; `parseConfig(char* hostName, int maxLenHostName, ...);` – AndersK Aug 27 '15 at 07:17

2 Answers2

3

Since they were initialized to NULL, you should allocate enough memory space for them.

config_lookup_string(cf, "hostname",  &tmp);
*hostname = malloc(strlen(tmp)+1);
strcpy(*hostname, tmp);
config_lookup_string(cf, "ip", &tmp);
*ip = malloc(strlen(tmp)+1);
strcpy(*ip, tmp);
config_lookup_string(cf, "port", &tmp);
*port = malloc(strlen(tmp)+1);
strcpy(*port, tmp);

Or, if you have strdup() available,

config_lookup_string(cf, "hostname",  &tmp);
*hostname = strdup(tmp);
config_lookup_string(cf, "ip", &tmp);
*ip = strdup(tmp);
config_lookup_string(cf, "port", &tmp);
*port = strdup(tmp);
timrau
  • 22,578
  • 4
  • 51
  • 64
0

Cut the middleman.

config_lookup_string(cf, "hostname",  hostname);

This requires you to never destroy cfg, as it owns memory allocated for config strings.

static config_t cfg;
config_t *cf;

// config_destroy(cf); <-- don't!

This shouldn't be a problem if you only read the configuration once per program run.

n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243