Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 311
  • Last Modified:

UNIX Pipes problem

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
hld
Asked:
hld
  • 2
1 Solution
 
remboCommented:


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
 
aditya070797Commented:
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
 
aditya070797Commented:
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
 
hldAuthor Commented:
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

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now