btwotch    

, Deutschland · männlich · registriert seit 2008 · heute zuletzt online


mailto, against spam!

3-way popen()

Sonstiges · · 1 Kommentar

NAME
popen, pclose - pipe stream to or from a process

SYNOPSIS
#include <stdio.h>

FILE *popen(const char *command, const char *type);

int pclose(FILE *stream);

Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

popen(), pclose(): _POSIX_C_SOURCE >= 2 || _XOPEN_SOURCE || _POSIX_SOURCE _BSD_SOURCE || _SVID_SOURCE

DESCRIPTION
The popen() function opens a process by creating a pipe, forking, and invoking the shell. Since a pipe is by definition unidirectional, the type argument may specify only reading or writing, not both; the resulting stream
is correspondingly read-only or write-only.

Hoert sich ja eigentlich ganz interessant an, wenn da nicht ein Problem waere:

The type argument is a pointer to a null-terminated string which must contain either the letter 'r' for reading or the letter 'w' for writing.

Man kann entweder lesen oder schreiben, von stderr ganz zu schweigen.
In Perl wuerde popen() in etwa so aussehen:

    1 #!/usr/bin/perl
    2 
    3 use strict;
    4 
    5 open F, "ls |";
    6 
    7 while (<F>) {
    8    print;
    9 }

Das Problem ist jedoch das gleiche.

Mein 3-way popen kann stdin, stdout und stderr gleichzeitig:

    1 #include <stdio.h>
    2 #include <string.h>
    3 #include <stdlib.h>
    4 #include <unistd.h>
    5 #include <fcntl.h>
    6 #include <sys/select.h>
    7 
    8 
    9 int max(int a, int b)
   10 {
   11   return a > b ? a : b;
   12 }
   13 
   14 void serv_proc(int stin, int stout, int sterr)
   15 {
   16   int n, i;
   17   char buf[100];
   18   fd_set rfds;
   19 
   20 
   21   FD_ZERO(&rfds);
   22   FD_SET(stout, &rfds);
   23   FD_SET(sterr, &rfds);
   24 
   25   write(stin, "/bin/ls\n", 8);
   26   write(stin, "echo bla > /dev/stderr\n", 23);
   27   write(stin, "/bin/ls /\n", 10);
   28   write(stin, "a=5\n", 4);
   29   write(stin, "echo $a > /dev/stderr\n", 24);
   30 
   31 
   32   while (select(max(stout, sterr)+1, &rfds, NULL, NULL, NULL) > 0)
   33     {
   34       if (FD_ISSET(stout, &rfds))
   35         {
   36           n=read(stout, buf, 100);
   37           printf("---> STDOUT: \n");
   38           for (i = 0; i < n; i++)
   39             printf("%c", buf[i]);
   40           printf("\n");
   41           //FD_CLR(stout, &rfds);
   42         }
   43       if (FD_ISSET(sterr, &rfds))
   44         {
   45           n=read(sterr, buf, 100);
   46           printf("---> STDERR: \n");
   47           for (i = 0; i < n; i++)
   48             printf("%c", buf[i]);
   49           printf("\n");
   50         }
   51       FD_SET(stout, &rfds);
   52       FD_SET(sterr, &rfds);
   53     }
   54 
   55   close(stout);
   56   close(sterr);
   57   close(stin);
   58 }
   59 
   60 
   61 void client_proc(int stin, int stout, int sterr)
   62 {
   63   dup2(stin, STDIN_FILENO);
   64   dup2(stout, STDOUT_FILENO);
   65   dup2(sterr, STDERR_FILENO);
   66 
   67   fcntl(STDIN_FILENO, F_SETFD, 0);
   68   fcntl(STDOUT_FILENO, F_SETFD, 0);
   69   fcntl(STDERR_FILENO, F_SETFD, 0);
   70 
   71   sleep(1);
   72 
   73   execl("/bin/bash", "sh", NULL);
   74 
   75   close(stin);
   76   close(stout);
   77   close(sterr);
   78 
   79 
   80 }
   81 
   82 
   83 int main()
   84 {
   85   int stin[2], stout[2], sterr[2];
   86   pipe(stout);
   87   pipe(sterr);
   88   pipe(stin);
   89 
   90   switch (fork())
   91     {
   92     case -1:
   93       exit(-1);
   94     case 0:
   95       close(stin[1]);
   96       close(stout[0]);
   97       close(sterr[0]);
   98       client_proc(stin[0], stout[1], sterr[1]);
   99       break;
  100     default:
  101       close(stin[0]);
  102       close(stout[1]);
  103       close(sterr[1]);
  104       serv_proc(stin[1], stout[0], sterr[0]);
  105       break;
  106     }
  107 
  108   return 0;
  109 }
21. Januar 2010 02:50

Tags:  ·  ·

List of strange bugs[1]

Computer ·

Program received signal SIGSEGV, Segmentation fault.
strlen () at ../sysdeps/x86_64/strlen.S:31
31 ../sysdeps/x86_64/strlen.S: No such file or directory.
in ../sysdeps/x86_64/strlen.S
Current language: auto
The current source language is "auto; currently asm".

Warum bekomm nur ich immer die besonderen Fehlermeldungen? Sehe ich vielleicht so aus, als wuerde ich strlen in ASM programmieren? - bestimmt wieder son debian-fuckup.

Siehe auch: http://www.spin.de/hp/btwotch/blog%2Fid%2F6269763

17. Januar 2010 22:47

Tags:  ·  ·

08. Januar 2010

Sonstiges ·

Endlich mal wieder kein Essen gebloggt ;)

08. Januar 2010 14:46

Tags:

Shortest Code

Computer · · 5 Kommentare

Kuerzester Code, den ich gefunden habe um von binaer nach dezimal zu konvertieren (ANSI C):

    1 int b=101,d=0,i=1;
    2 for (; b!=0; d+=i*(b%2),b/=10,i<<=1);

Wenn ihr was kuerzeres findet, so informiert mich einfach :zwinker: - Danke
-> Siehe Kommentare ...

02. Januar 2010 03:00

Tags:  ·  ·  ·

Blog durchsuchen
(nur öffentliche Einträge)

Willst du auch bloggen?
Kostenlos bloggen bei Spin.de
Diese Seite ist eine auf spin.de gelagerte persönliche Homepage, deren Verantwortlichkeit beim Nutzer liegt.
spin.de ist eine große Online-Community mit Chat, Blogs, Foren, Online-Spielen und vielem mehr.
Deine eigene Homepage mit Blog und Gästebuch

Impressum · Datenschutz · Sitemap