PDA

View Full Version : using popen



frs
06-14-2010, 10:48 AM
I'm using ubuntu 10.04

I'm writing a small program to read the input of a gamepad (ps3) that needs a driver (sixad). I used popen to create a process and run the driver in background. Also I want to know when the gamepad is connected, so I need to catch the sixad messages, I made popen("sixad -s (start) 2>&1, "r")) to read from both stdout and stderr. When I got the message that the gamepad is connected I was thinking in breaking the while loop, and to proceed with the rest of the program.
I tested the following code, but I don't understand the results (more below), why the loop isn't always running?.
I'm a complete newbie, I don't know if this is the correct way of doing what I want, so any suggestions will be very appreciated.



FILE *fp1;
printf("popen\n");

if ((fp1 = popen("sixad -s 2>&1","r")) == NULL)
{
fprintf(stderr, "Fail opening popen\n");
exit(EXIT_FAILURE);
}

char linha[400];
printf("\n1");
while(fgets(linha,400,fp1)!=NULL)
{
printf("\n2");
char *n=strstr(linha,"Connected PLAYSTATION(R)3 Controller");
printf("\n3");
printf("\n[%s]%s",n,linha);

printf("\n4");
if(n=='\0')
{
printf("\n5");
}
printf("\n6");
}
printf("\n7");

Terminal: when I don't press the PS button


1
2
3
[(null)]sixad[2114]: sixad started, press the PS button now

4
5


Terminal: when I press the PS button @5 and the gamepad is sucessfully connected

1
2
3
[(null)]sixad[2432]: sixad started, press the PS button now

4
5
6
2
3
[Connected PLAYSTATION(R)3 Controller (00:23:06:A4:E6:AA)
]sixad[2446]: Connected PLAYSTATION(R)3 Controller (00:23:06:A4:E6:AA)

4

rags_to_riches
06-14-2010, 11:12 AM
And cross-posted across forums as well (http://www.dreamincode.net/forums/topic/177668-using-popen/)

Salem
06-14-2010, 11:15 AM
Well it will only print something when the thing at the other end of the pipe bothers to output some text. No output, no loop.

If you need to break out of the loop because you've waited too long, then you need to use real pipes, which give you more control (but more code to write).

> char *n=strstr(linha,"Connected PLAYSTATION(R)3 Controller");
ALWAYS check the return result. If the string isn't found, then you get NULL.

> [(null)]sixad[2432]: sixad started, press the PS button now
Don't rely on everyone elses printf implementations to do something nice with a NULL pointer. Others may just crash.

frs
06-14-2010, 11:33 AM
@Salem

Thank you for the help.
Sorry for the cross posting. I didn't know the correct place to post.

Yes I want to break the loop because of waiting too long. What are real pipes btw? If you can get me some tutorials or indications about that I'll be very thankful.

Salem
06-14-2010, 11:42 AM
pipe(2): create pipe - Linux man page (http://linux.die.net/man/2/pipe)
To create a pipe between two processes.

select(2): synchronous I/O multiplexing - Linux man page (http://linux.die.net/man/2/select)
To monitor file descriptors for a change in state, possibly with a timeout

fopen(3): stream open functions - Linux man page (http://linux.die.net/man/3/fopen)
Associate a FILE* with a descriptor, so you can use fgets() etc

frs
06-14-2010, 12:18 PM
@Salem

thank you once again.

I only need to use these 3 functions? and forget popen? how I launch the driver then? I have no experience with processes.. can you make me the basic code if isn't asking too much?

Salem
06-14-2010, 01:26 PM
Seeing as there are plenty of examples on the board, maybe search and try yourself first.