Reputation: 93
I want to swapn a program and capture it's output. I use popen
to spawn it, but I just can't get the "contents" to be stored in a dynamically allocated c string (char *
).
This is what I got:
char *spawn(char *command, int *status) {
FILE *pipe = popen(command, "r");
char line[LINE_MAX];
char *buffer = NULL;
size_t buffer_size = 0;
while (fgets(line, sizeof (line), pipe)) {
size_t line_length = strlen(line);
buffer = realloc(buffer, (buffer_size + line_length) * sizeof *buffer);
memcpy(buffer + buffer_size, line, line_length);
buffer_size += line_length;
}
if (status) {
*status = WEXITSTATUS(pclose(pipe));
} else {
pclose(pipe);
}
return buffer;
}
For some weird reason the string is always slightly too long and I get random characters at the end (e.g. ���7V
). I already tried my own implementation of strlen
which counts until a newline character appears (including it), but it didn't help. I also tried strcpy
but this lead to a crash. I just can't find my mistake. Any help is greatly appreciated!
Upvotes: 0
Views: 520
Reputation: 153602
some weird reason the string is always slightly too long
Code is not forming a string in buffer
as it has no null character nor space for it. Better to allocate space for the '\0'
and copy it in.
// size_t buffer_size = 0;
size_t buffer_len = 0;
while (fgets(line, sizeof (line), pipe)) {
size_t line_length = strlen(line);
// buffer = realloc(buffer, (buffer_size + line_length) * sizeof *buffer);
buffer = realloc(buffer, (buffer_len + line_length + 1) * sizeof *buffer);
// memcpy(buffer + buffer_size, line, line_length);
memcpy(buffer + buffer_len, line, line_length + 1);
// buffer_size += line_length;
buffer_len += line_length;
}
Robust code would also check for allocation success.
Upvotes: 1