I have the following code:
#include <stdio.h> #include <stdlib.h> int readCmd(char* cmd) { FILE *fp; char path[1024]; /* Open the command for reading. */ fp = popen(cmd, "r"); if (fp == NULL) { printf("Failed to run commandn" ); exit(1); } /* Read the output a line at a time - output it. */ while (fgets(path, sizeof(path)-1, fp) != NULL) { printf("%s", path); } /* close */ pclose(fp); return path; } int main( int argc, char *argv[] ) { char* gp123; char* gp124; gp124=readCmd("cat /sys/class/gpio/gpio124/direction"); gp123=readCmd("cat /sys/class/gpio/gpio123/direction"); printf("123: %s n124: %s n",gp123,gp124); }
With the following output:
out in 123: in 124: in
As you can see, gpio pin 123 is set to ‘in’ and 124 is set to ‘out’.
However, both gp123 and gp124 are being assigned ‘in’. I am rusty with functions and C. Could you fellas help me out a little please?
More specifically, why is it failing to assign the returned value for each command I read? Is this a local/global variable issue?
Thanks!
EDIT:
#include <stdio.h> #include <stdlib.h> char* readCmd(char* cmd) { FILE *fp; static char path[1024]; /* Open the command for reading. */ fp = popen(cmd, "r"); if (fp == NULL) { printf("Failed to run commandn" ); exit(1); } /* Read the output a line at a time - output it. */ while (fgets(path, sizeof(path)-1, fp) != NULL) { printf("%s", path); } /* close */ pclose(fp); return path; } int main( int argc, char *argv[] ) { char gp123[50]; char gp124[50]; char *answer; answer=readCmd("cat /sys/class/gpio/gpio124/direction"); sprintf(gp124, "%s", answer); answer=readCmd("cat /sys/class/gpio/gpio123/direction"); sprintf(gp123, "%s", answer); printf("123: %s n124: %s n",gp123,gp124); }
This seems to work correctly, is there anything here I should change to be more correct?
Advertisement
Answer
You can’t return a pointer to automatic memory from a function. The path array only exists for the duration of the readCmd function (which should return char*, not an int).
To solve it, you can:
- declare the array static (or use a global array–pretty much the same thing) and embrace non-reenterability
- use the heap (malloc the array or use the GNU getline function)
- ask the caller to provide provide a pointer to where to save the output (its size should be passed in too)