PDA

View Full Version : C interprocess communication



Mirge
June 3rd, 2009, 11:51 PM
Anybody know of a good guide that demonstrates the use of IPC with C?

Example, I use sshfs... and I want to be able to write a C program that waits for the "enter password" prompt, then sends the password to the process with a newline... basically "automatically" mounting a remote filesystem.

Thanks!

Volt9000
June 4th, 2009, 12:42 AM
Here are a couple of links I found on another forum. Not sure if this will accomplish what you want, but it's a start. :)

http://linuxgazette.net/104/ramankutty.html
http://linuxgazette.net/105/ramankutty.html

PS. Google is your friend.

Mirge
June 4th, 2009, 12:46 AM
Heh, I've done a TON of searching before even posting. I'll give those a read as well. Beej's guide looks pretty promising.

johnl
June 4th, 2009, 12:52 AM
If you don't actually need/want to write a program to do this, expect (http://en.wikipedia.org/wiki/Expect) can do it for you.

Mirge
June 4th, 2009, 01:27 AM
If you don't actually need/want to write a program to do this, expect (http://en.wikipedia.org/wiki/Expect) can do it for you.

Wow, that's really neat! Bookmarked that.

I also want to build this C app for practice & learning. I dabbled with C years ago, but I'm trying to refresh my memory now and progress. It's frustrating because a lot of my Google searches turn up with C++ references rather than C lol.

SledgeHammer_999
June 4th, 2009, 01:37 AM
Maybe you should give D-bus a try.
http://www.freedesktop.org/wiki/Software/dbus

Mirge
June 4th, 2009, 02:12 AM
Maybe you should give D-bus a try.
http://www.freedesktop.org/wiki/Software/dbus

Now that looks really cool too... reading about it. Thanks folks :). And if I come up with a solution I'll be sure to post it back here.. an example anyway haha.

ThinkBuntu
June 4th, 2009, 03:01 AM
[deleted]

alternatealias
June 4th, 2009, 01:56 PM
There's a book by W. Richard Stevens on the topic of IPC in C for Unix which is quite good.

http://www.kohala.com/start/unpv22e/unpv22e.html

His "Networking API's" book is also a "must have" for network programming on Unix systems.

I know the books are costly ($60 when I bought mine a number of years ago), but you will never regret buying them.

alternatealias
June 4th, 2009, 01:59 PM
Maybe you should give D-bus a try.
http://www.freedesktop.org/wiki/Software/dbus

I don't think D-Bus will help him in this particular case since he's trying to communicate with an already-existing process (presumably he would like to do so without modifying the other process).

alternatealias
June 4th, 2009, 02:14 PM
Anybody know of a good guide that demonstrates the use of IPC with C?

Example, I use sshfs... and I want to be able to write a C program that waits for the "enter password" prompt, then sends the password to the process with a newline... basically "automatically" mounting a remote filesystem.

Thanks!

The following code is untested, but should be fairly close to correct:

The easiest way to do this is probably to use popen():

FILE *sshfs = popen ("sshfs -o password_stdin", "w");
int fd = fileno (sshfs);
struct pollfd fds[1];

fds[0].fd = fd;
fds[0].events = POLLOUT;
fds[0].revents = 0;

/* wait for the sshfs to become ready to accept the passwd on stdin */
poll (fds, 1, -1);

if (fds[0].revents & POLLOUT)
fwrite ("MyP@$$w0rd\n", 1, 12, sshfs);

pclose (sshfs);


Now, granted, you should do proper error checking and you may want to put a timeout on the poll (-1 is infinite), but this general approach should work.

Mirge
June 4th, 2009, 04:24 PM
There's a book by W. Richard Stevens on the topic of IPC in C for Unix which is quite good.

http://www.kohala.com/start/unpv22e/unpv22e.html

His "Networking API's" book is also a "must have" for network programming on Unix systems.

I know the books are costly ($60 when I bought mine a number of years ago), but you will never regret buying them.

Nice thanks, I'll definitely look into that.

I printed off a PDF version of:
http://beej.us/guide/bgipc/

And have been reading it. I've gone through most of it before, but this was several years ago, so it's all pretty "new" to me again.

Mirge
June 4th, 2009, 04:53 PM
parent.c


#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>


int main(){

pid_t pid;
int rv;
int commpipe[2]; /* This holds the fd for the input & output of the pipe */

/* Setup communication pipeline first */
if(pipe(commpipe)){
fprintf(stderr,"Pipe error!\n");
exit(1);
}

/* Attempt to fork and check for errors */
if( (pid=fork()) == -1){
fprintf(stderr,"Fork error. Exiting.\n"); /* something went wrong */
exit(1);
}

if(pid){
/* A positive (non-negative) PID indicates the parent process */
dup2(commpipe[1],1); /* Replace stdout with out side of the pipe */
close(commpipe[0]); /* Close unused side of pipe (in side) */
setvbuf(stdout,(char*)NULL,_IONBF,0); /* Set non-buffered output on stdout */
sleep(2);
printf("Hello\n");
sleep(2);
printf("Goodbye\n");
sleep(2);
printf("exit\n");
wait(&rv); /* Wait for child process to end */
fprintf(stderr,"Child exited with a %d value\n",rv);
}
else{
/* A zero PID indicates that this is the child process */
dup2(commpipe[0],0); /* Replace stdin with the in side of the pipe */
close(commpipe[1]); /* Close unused side of pipe (out side) */
/* Replace the child fork with a new process */
if(execl("child","child",NULL) == -1){
fprintf(stderr,"execl Error!");
exit(1);
}
}
return 0;
}


child.c


#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]) {
char string[100];

printf("Child Process\n");
printf("-------------\n");
do{
printf("Enter Command: ");
fflush(stdout); /* Must flush to see command prompt */
fgets(string, 100, stdin);
printf("%s\n",string); /* No flush necessary because new line flushes */
}while(!strstr(string,"exit"));

return 0;
}


Found this example at:
http://www.gidforums.com/t-3369.html

Just googled around some more and finally ran into that.

It does what I want it to, sort of. It'd be nice to be able to "wait" for specific text to appear before sending output to the external process. But it DOES send data to the external process. Not sure how it works, but at least I have a functional example now.. so I'm continue studying. Thought I'd share that while it was fresh on my mind.

Mirge
June 4th, 2009, 07:20 PM
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(int argc, char** argv)
{
int pipe_fd[2];
char buf[31];
pid_t pid;

if(pipe(pipe_fd) == -1) {
perror("Error pipe()'ing...");
exit(1);
}


if( (pid = fork()) == -1 ) {
perror("Error fork()'ing...");
exit(1);
}

if(pid) {
// Parent.
// Read from pipe we made.
// Remember, 1=write, 0=read.
read(pipe_fd[0], buf, 30);
printf("PARENT: read... %s\n", buf);

wait(NULL);
} else {
// Child.
// Write to the pipe we made, so the parent has something to read!
// Again, 1=write, 0=read.
write(pipe_fd[1], "Hello, parent??", 16);
exit(0);
}

return 0;
}


Following Beej's IPC guide... threw that together (not optimal code).. works. Just trying to grasp IPC again. Throwing up samples as I find time to do 'em lol.

Mirge
June 4th, 2009, 08:47 PM
Heh, I still can't wrap my mind around it... writing to another process. I get seg faults when I try, after execl() errors. Meh.

Mirge
June 5th, 2009, 03:21 AM
Can someone point me in the direction of a good pipe() and fork() tutorial... maybe something more explanatory than Beej's guide? Or maybe try to explain it to me? Thanks in advance...

slavik
June 5th, 2009, 01:43 PM
fork() is a really simple command what questions do you have about it?

Mirge
June 5th, 2009, 02:47 PM
Yeah, I guess not really so much about fork(), but about pipe().

I understand what fork() is doing, but what I don't understand I guess is the pipe()'ing portion of this tidbit:



#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>


int main(){

pid_t pid;
int rv;
int commpipe[2]; /* This holds the fd for the input & output of the pipe */

/* Setup communication pipeline first */
if(pipe(commpipe)){
fprintf(stderr,"Pipe error!\n");
exit(1);
}

/* Attempt to fork and check for errors */
if( (pid=fork()) == -1){
fprintf(stderr,"Fork error. Exiting.\n"); /* something went wrong */
exit(1);
}

if(pid){
/* A positive (non-negative) PID indicates the parent process */
dup2(commpipe[1],1); /* Replace stdout with out side of the pipe */
close(commpipe[0]); /* Close unused side of pipe (in side) */
setvbuf(stdout,(char*)NULL,_IONBF,0); /* Set non-buffered output on stdout */
sleep(2);
printf("Hello\n");
sleep(2);
printf("Goodbye\n");
sleep(2);
printf("exit\n");
wait(&rv); /* Wait for child process to end */
fprintf(stderr,"Child exited with a %d value\n",rv);
}
else{
/* A zero PID indicates that this is the child process */
dup2(commpipe[0],0); /* Replace stdin with the in side of the pipe */
close(commpipe[1]); /* Close unused side of pipe (out side) */
/* Replace the child fork with a new process */
if(execl("child","child",NULL) == -1){
fprintf(stderr,"execl Error!");
exit(1);
}
}
return 0;
}


The parts I'm fuzzy on are the bold/underlined lines.