Solved

UNIX Pipes problem

Posted on 1997-09-04
4
238 Views
Last Modified: 2013-12-26
Various (book) examples shows how to communicate between parent/child processes using one pipe. I need to create an FTP wrapper which requires I create two pipes, one for read and one for write. Furthermore I need to
capture stderr as well as stdout from the FTP child process using dup2.

I CAN'T GET THIS TO WORK I can get only stderr or stdout not both, and sometimes my parent process read hangs up!!. Can anyone send my som sample
code or explain this. It would be highly appreciated..

Thanks

Henrik

0
Comment
Question by:hld
  • 2
4 Comments
 
LVL 4

Expert Comment

by:rembo
ID: 1294767


You can't execute ftp using pipe communication.  I would
recommend using the expect tool.  You can find it at:

ftp.cme.nist.gov

Here's a sample script that should do what you want:

#!/usr/local/bin/expect

set bug [lindex $argv 0]
set vers [lindex $argv 1]

send_user "Getting bug # $bug for RDBMS Version $vers\n"
send_user "This will take a minute, please be patient.\n"

exec mkdir bug$bug
exec cd bug$bug

spawn ftp tcpatch
expect
send "patch\r"
expect
send "Weav1r\r"
expect
send "cd ATT/bug_fixes/$vers/bug$bug \r"
expect send "binary\r"
expect
send "prompt\r"
expect
send "mget *\r "
expect
send "quit\r"
expect



0
 

Accepted Solution

by:
aditya070797 earned 100 total points
ID: 1294768
Hi,
I am not completely sure of what your problem is, but you seem
to want a program that would fork off a child that would execute the FTP program and a parent that would control it. The below code should be able to show you how you can go about doing that.
The code shows two pipes for two-way communication between the parent and child. The STDOUT and STDERR of the child are
dup'ed onto the write end of a pipe in the child which the parent reads at the other end. This should give you a server that can actually monitor the child executing the FTP program. The parent  
would be able to read all of the child's output and can write to the child through the pipe. Since the pipe-ends are all duped in the child, the stdout, stderr and stdin of the child ( becomes the FTP program after exec )all refer to the pipe-ends from the parent.

/******************************************
 * This code is purely for illustration,
 * might contain errors.
 * Here's the first :)
 * --Aditya Vedula.
 *******************************************/

#include <stdio.h>
#include <unistd.h>

main(argv, argc)
char **argv;
int argc;
{
int pipefd1[2];
int pipefd2[2];
int rv;

pipe(pipefd1);
pipe(pipefd2);

rv = fork()

if (rv > 0) { /* PARENT */

close (pipfd1[1]); /* close write-end, read from pipefd1[0] */
{
int pipefd1[2];
int pipefd2[2];
int rv;

pipe(pipefd1);
pipe(pipefd2);

rv = fork()

if (rv > 0) { /* PARENT */

close (pipfd1[1]); /* close write-end, read from pipefd1[0] */
close (pipefd2[0]); /* close read-end, write into pipefd2[1] */

        /* do the parent thing... */

/*
 * Ex: read 50 chars from ftp child and write 50 chars to pipe
 *     read (pipefd1[0], buf1, 50);
 *     write (pipefd2[1], buf2, 50);
 */
}

else if (rv == 0) { /* CHILD */

close (pipefd1[0]); /* used by parent to read */
close (pipefd2[1]); /* used by parent to write */

        /* redirect stdout and stderr from child to pipefd1[1] */

close (1);        /* STDOUT, equivalent to dup2(pipefd1[1], 1) */
dup (pipefd1[1]);

dup2 (pipefd1[1], 2); /* STDERR */

close (pipefd1[1]);

        /* from now on, all stdout and stderr from this process
         * should go to pipefd1[1] to be read by parent at pipefd1[0]
         */

dup2 (pipefd2[1], 0);  /* STDIN */

        /* from now on, all stdin into this process will be from pipefd2[1]
         */

        /* do the child thing.... */

execlp("ftp", "ftp", arg1, NULL); /* Ex: execlp("ftp", "ftp", "129.78.4.8", NULL
 ); */
perror("Cannot exec..");
exit(2);

}
else { /* FORK FAILED */
        perror("Cannot fork...");
        exit(1);
}

}

0
 

Expert Comment

by:aditya070797
ID: 1294769
Whoops.. looks like the cut-and-paste messed up.
Here is the code again:
-----------------------------------------------------------------
#include <stdio.h>
#include <unistd.h>

main(argv, argc)
char **argv;
int argc;
{
int pipefd1[2];
int pipefd2[2];
int rv;

pipe(pipefd1);
pipe(pipefd2);

rv = fork();

if (rv > 0) { /* PARENT */

close (pipfd1[1]); /* close write-end, read from pipefd1[0] */
close (pipefd2[0]); /* close read-end, write into pipefd2[1] */

        /* do the parent thing... */

/*
 * Ex: read 50 chars from ftp child and write 50 chars to pipe
 *     read (pipefd1[0], buf1, 50);
 *     write (pipefd2[1], buf2, 50);
 */

}

else if (rv == 0) { /* CHILD */

close (pipefd1[0]); /* used by parent to read */
close (pipefd2[1]); /* used by parent to write */

        /* redirect stdout and stderr from child to pipefd1[1] */

close (1);        /* STDOUT, equivalent to dup2(pipefd1[1], 1) */
dup (pipefd1[1]);

dup2 (pipefd1[1], 2); /* STDERR */

close (pipefd1[1]);

        /* from now on, all stdout and stderr from this process
         * should go to pipefd1[1] to be read by parent at pipefd1[0]
         */

dup2 (pipefd2[1], 0);  /* STDIN */

        /* from now on, all stdin into this process will be from pipefd2[1]
         */

        /* do the child thing.... */

execlp("ftp", "ftp", arg1, NULL); /* Ex: execlp("ftp", "ftp", "129.78.4.8", NULL
 ); */
perror("Cannot exec..");
exit(2);

}
else { /* FORK FAILED */
        perror("Cannot fork...");
        exit(1);
}

}

0
 

Author Comment

by:hld
ID: 1294770
Aditya's , you fully undestood my problem and it looks like you solved it. I will try it out. Thank You, Thank You

Henrik
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Introduction: Database storage, where is the exe actually on the disc? Playing a game selected randomly (how to generate random numbers).  Error trapping with try..catch to help the code run even if something goes wrong. Continuing from the seve…
Have you tried to learn about Unicode, UTF-8, and multibyte text encoding and all the articles are just too "academic" or too technical? This article aims to make the whole topic easy for just about anyone to understand.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…

759 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now