Reputation: 101
I have to figure out the available space in /mnt/ in my application. I wrote the following code. However, execute_cmd some times returns junk apart from the actual output. For ex: 4.5K(followed by junk). Where am I going wrong? Could some one review and let me know why execute_cmd returns a junk byte at the end? How do I improve the code?
char *execute_cmd(char *cmd)
{
FILE *fp;
char path[100];
int ii = 0;
//char ii = 0;
char *buffer = malloc(1024);
char len = 0;
/* Open the command for reading. */
fp = popen(cmd, "r");
if (fp == NULL) {
printf("Failed to run command\n" );
exit(1);
}
printf("Running command is: %s\n", cmd);
memset(buffer, 0, sizeof(buffer));
do {
len = fread(path, 100, 1, fp); /* Is it okay to use fread? I do not know how many bytes to read as this function is a generic function which can be used for executing any command */
strcat(buffer,path);
printf("Number of bytes is: %d\n", len);
} while (len != 0);
len = strlen(buffer);
printf("Buffer contents are: %s %d\n", buffer,len);
/* close */
pclose(fp);
}
void main()
{
char *buffer = "df -h | grep \"/mnt\" | awk '{ print $4}'"; /* FIXME */
char len;
char units;
float number;
char dummy = 0;
char *avail_space;
avail_space = execute_cmd(buffer);
len = strlen(avail_space);
units = avail_space[len - 1];
printf("Available space is: %s %d %c end here\n", avail_space, len, units);
number = strtof(avail_space, NULL);
printf("Number is: %f\n", number);
}
Upvotes: 0
Views: 333
Reputation: 241701
sizeof(buffer)
is sizeof(char*)
, which is probably 8 (or maybe 4). So your memset
only clears a little bit of buffer
. But with your use of fread
, it's not just buffer
that needs to be cleared; it's the temporary path
.
Uninitialized local variables like path
are not zero-initialised. You could use memset(path, 0, sizeof(path));
to clear it -- here the sizeof
works because path
really is an array -- but simpler is to initialise it in the declaration: char path[100] = "";
.
Since fread
does not NUL-terminate what it reads, there might be arbitrary garbage following it, making the strcat
Undefined Behaviour. In fact, the strcat
is totally unnecessary and a waste of cycles. You know how much data you read (it's in len
) so you know exactly where to read the next chunk and you can do so directly without a temporary buffer and without a copy.
For future reference, if you are planning on calling malloc
and then using memset
to clear the allocated region, you should instead use calloc
. That's what it's there for.
Upvotes: 1