Solved

UNIX Pipes problem

Posted on 1997-09-04
4
286 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

In this article, I'll describe -- and show pictures of -- some of the significant additions that have been made available to programmers in the MFC Feature Pack for Visual C++ 2008.  These same feature are in the MFC libraries that come with Visual …
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.
I've attached the XLSM Excel spreadsheet I used in the video and also text files containing the macros used below. https://filedb.experts-exchange.com/incoming/2017/03_w12/1151775/Permutations.txt https://filedb.experts-exchange.com/incoming/201…

752 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