Reputation: 35
I would like to open an bash application(prog1) and send command to that application with C program. I tried and wrote the following code.
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
FILE * fp;
char message[10] = "command1\n";
fp = popen("sudo prog1","r");
write(STDIN_FILENO, message, 10);
pclose(fp);
execlp("sudo prog1", "sudo prog1", "-l", NULL);
return 0;
}
This code gives an output:
Linux:~$ ./ prog 2 // running the code
command // prints "command"
prog1-> // Then opens "prog1" (prog1 waits for user commands)
But I want it to be
Linux:~$ ./ prog 2 // running the code
prog1-> command // open "prog1" and write command (instead of getting it from user)
It either writes after quitting prog1 or before starting prog1. Please let me know how to write the "command" in prog1, after opening the application prog1. Thank you.
Note: If I make
fp = popen("sudo prog1","w"); //to write
It throws the following error tcgetattr : Inappropriate ioctl for device
Upvotes: 0
Views: 357
Reputation: 20842
Your main bug is thinking that popen() somehow associates your child process with your STDIN_FILENO. It doesn't. STDIN_FILENO is not associated with your "sudo prog1" child. You'd have to create a pipe, dup the descriptors to stdin/stdout, and fork+exec to do that. But you used popen() so don't do that either.
Instead, you should be writing and reading from fp.
Something like:
fprintf(fp, message);
fgets(response, 100, fp);
Since fprintf() is buffered, you should use \n at the end of the line, or fflush().
Also, there is no point is using exec/execlp at the end when you've already called popen(). Looks like you may be mixing two approaches that you've seen by example.
popen() essentially does a combination of (pipe, dup stdin/stdout/stderr, fork, execl) to take care of redirecting a child process to a file stream connected to the parent. So no need to reimplement unless you need different semantics than popen().
You technically are implementing "expect" functionality, so you might want to look into expect, or expect modules for different languages. Expect is included with Linux distributions but is usually optional.
http://expect.sourceforge.net/
http://search.cpan.org/~rgiersig/Expect-1.21/Expect.pod
And not to mention, Perl has a Sudo module already.
http://search.cpan.org/~landman/Sudo-0.21/lib/Sudo.pm
Upvotes: 3