Solved

Redirecting stdin/stdout/stderr [Linux]

Posted on 2004-03-20
4
1,559 Views
Last Modified: 2008-02-01
Hello,
i need to run a command-line program, read its stdout/stdin and write its stdin.
In few words i need to do what this python script does:

import popen2
r,w,e = popen2.popen3('mount -t reiserfs ./MyDisks/ecnrypteddisk ./mnt/mydisk -o loop,encryption=AES256,rw -p 0');
w.write('password');
w.close();
for line in e.readlines():
    print 'E: ' + line
for line in r.readlines():
    print 'R: ' + line

r.close();
e.close();

Thank you,
   Luca
0
Comment
Question by:lucat
[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 12

Assisted Solution

by:stefan73
stefan73 earned 100 total points
ID: 10642227
Hi lucat,
popen2/popen3 are using a combination of pipe/fork/exec/dup2, basically like this:

pid_t son_pid;
int son_stdin[2];
int son_stdout[2];

son_pid = fork();

pipe(son_stdin);   /* 0 = father end of pipe, 1=son end */
pipe(son_stdout);  /* dito */

if(son_pid>0){ /* Parent process */
    /* Now you have your son's handles in son_stdin[0] and son_stdout[0] */

} else if (son_pid==0){ /* Son process */
    dup2(0,son_stdin[1]);  /* Set son's stdin to pipe */
    dup2(1,son_stdout[1]); /* Same with stdout        */
    exec("your command"); /* Do "apropos exec" and see which exec variant fits best for you here */
} else { /* Error */ }

pipes from the pipe() command are bi-directional, so you could do with only a single pipe - but it fits illustration better to use two of them. And AFAIK you can't do two fdopen() calls for a single fd.

Cheers!

Stefan
0
 
LVL 12

Expert Comment

by:stefan73
ID: 10642234
Ah, popen3 also dups stderr (fd=2). But then it gets messy for your program, as you need non-blocking I/O. You'd better just do a dup2 for stderr, also redirecting it to the stdout pipe.
0
 

Author Comment

by:lucat
ID: 10642302
Hmmm why this doesn't work?
It segfault on me... even thought the "ls" command is correctly executed (i know it because if i write "kwrite" instead than "ls" kwrite shows up).
I believe i am doing something wrong with fscanf (if i comment it out it doesn't give any error).
Is it correct how i use dup2?

Thanx,
   Luca

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

int main()
{
      int fdin[2];
      int fdout[2];
      int fderr[2];
      pid_t pid;
      char s[256];

      pipe(fdin);
      pipe(fdout);
      pipe(fderr);

      pid = fork();
      if (pid == (pid_t) 0) {
            close(fdin[1]);
            close(fdout[1]);
            close(fderr[1]);
            dup2(fdin[0],STDIN_FILENO);
            dup2(fdout[0],STDOUT_FILENO);
            dup2(fderr[0],STDERR_FILENO);
            execlp("ls","ls",0);
      }
      else {
            close(fdin[0]);
            close(fdout[0]);
            close(fderr[0]);
            FILE* streamin;
            FILE* streamout;
            FILE* streamerr;
            streamin = fdopen(fdin[1],"w");
            streamout = fdopen(fdout[1],"r");
            streamerr = fdopen(fderr[1],"r");
            fscanf(streamout,"%[^]",s);
            printf("%s",s);
            close(fdin[1]);
            close(fdout[1]);
            close(fderr[1]);
            waitpid(pid, NULL, 0);
      }

      return 0;
}
0
 
LVL 84

Accepted Solution

by:
ozo earned 150 total points
ID: 10642863
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#define put 1
#define take 0
int main()
{
     int fdin[2];
     int fdout[2];
     int fderr[2];
     pid_t pid;
     char s[256];

     pipe(fdin);
     pipe(fdout);
     pipe(fderr);

     pid = fork();
     if (pid == (pid_t) 0) {
          close(fdin[put]);
          close(fdout[take]);
          close(fderr[take]);
          dup2(fdin[take],STDIN_FILENO);
          dup2(fdout[put],STDOUT_FILENO);
          dup2(fderr[put],STDERR_FILENO);
          execlp("ls","ls",0);
     }
     else {
          close(fdin[take]);
          close(fdout[put]);
          close(fderr[put]);
          FILE* streamin;
          FILE* streamout;
          FILE* streamerr;
          streamin = fdopen(fdin[put],"w");
          streamout = fdopen(fdout[take],"r");
          streamerr = fdopen(fderr[take],"r");
          fscanf(streamout,"%255[^]",s);
          printf("%s",s);
          close(fdin[put]);
          close(fdout[take]);
          close(fderr[take]);
          waitpid(pid, NULL, 0);
     }

     return 0;
}
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
negation in C function 14 177
how to understand recursion 12 236
asp.net web app 3 57
Excel Macro update each line based on another worksheet 2 52
Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
The goal of this video is to provide viewers with basic examples to understand recursion in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to use strings and some functions related to them in the C programming language.

737 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