0

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 command\n" );
        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 command\n" );
    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?

7
  • try something like this: char gp123[50]; char gp124[50]; char *answer; answer=readCmd("cat /sys/class/gpio/gpio124/direction"); sprintf(gp124, "%s", answer); gp123=readCmd("cat /sys/class/gpio/gpio123/direction"); sprintf(gp123, "%s", answer); Commented Nov 13, 2015 at 18:11
  • I think the return of readCmd() is unique, so when it returns to gp123, the value of variable gp124 is changed to gp123's value. Commented Nov 13, 2015 at 18:12
  • Hey, Kizz, could you please, give me a like in my comment as it worked for you? =) Commented Nov 13, 2015 at 18:38
  • I don't have enough rep :( Commented Nov 13, 2015 at 18:52
  • using the 'edited' version of the code: there is no way the compiler did not produce any warnings. The unused parameter: argc and the unused paramter: argv[] will both cause the compiler to produce a warning. When compiling, always enable all the warnings. (for gcc, at a minimum use: -Wall -Wextra -pedantic ) To fix the compiler warnings declare main() as: int main( void ) Commented Nov 14, 2015 at 16:05

1 Answer 1

1

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)
Sign up to request clarification or add additional context in comments.

1 Comment

I changed path to static and converted the function to a char*. This gave me the correct output and eliminated all compiler warnings.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.