We help IT Professionals succeed at work.

We've partnered with Certified Experts, Carl Webster and Richard Faulkner, to bring you a podcast all about Citrix Workspace, moving to the cloud, and analytics & intelligence. Episode 2 coming soon!Listen Now

x

UNIX Pipes problem

hld
hld asked
on
Medium Priority
324 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

Comment
Watch Question

Commented:


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



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);
}

}

Not the solution you were looking for? Getting a personalized solution is easy.

Ask the Experts
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);
}

}

hld

Author

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
Access more of Experts Exchange with a free account
Thanks for using Experts Exchange.

Create a free account to continue.

Limited access with a free account allows you to:

  • View three pieces of content (articles, solutions, posts, and videos)
  • Ask the experts questions (counted toward content limit)
  • Customize your dashboard and profile

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.