File: unnamedpipe.h

package info (click to toggle)
qepcad 1.74%2Bds-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 4,848 kB
  • sloc: ansic: 27,242; cpp: 2,995; makefile: 1,287; perl: 91
file content (131 lines) | stat: -rw-r--r-- 3,614 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/***************************************************************
 * This file defines a class UnnamedPipe whose sole purpose
 * in life is to create ... an unnamed pipe, of course.  It is
 * Unix specific, relying on the "pipe" system call.
 *
 * The key member functions are in() and out(), which are
 * somewhat confusingly named!  in() returns the istream
 * associated with the pipe and out() returns the ostream
 * associated with the pipe.  That means you use out() to write 
 * things to the pipe and in() to read things from the pipe.
 * 
 ***************************************************************/
#ifndef _UNNAMEDPIPE_
#define _UNNAMEDPIPE_
#include <cstdlib>
#include <cstdio>
#include <unistd.h>
#include <cstring>
#include <iostream>
#include <streambuf>
using namespace std;

/**************************************************
See "The C++ Standard Library", by Nicolai M. Josuttis
Chapter 13 for info on how fd(in|out)(buff|stream)
works.  This code is based on that stuff.
**************************************************/

class fdoutbuff : public streambuf
{
public:
  int fileDes;
  fdoutbuff(int fd) { fileDes = fd; }
  int_type overflow(int c) { 
    char cp = c;
    return (c == EOF || write(fileDes,&cp,1) != 1) ? EOF : c; 
  }
  streamsize xsputn (const char* s, streamsize n) { return write(fileDes,s,n); }
};

class fdostream : public ostream
{
public:
  fdoutbuff buff;
  fdostream(int fd) : buff(fd), ostream(&buff) { }
};

static const int unpbuffSize = 10;
static const int unpextra = 4;

class fdinbuff : public streambuf
{

public:
  char buff[unpbuffSize];
  int fileDes;
  fdinbuff(int fd) { fileDes = fd; char *tmp = buff+unpextra; setg(tmp,tmp,tmp); }
  int_type underflow()
  {
    if (gptr() >= egptr())
    {
      int leftover = min((long int)unpextra, (long int)(gptr() - eback())), readSize;
      memmove(buff + (unpextra-leftover), gptr() - leftover, leftover);
      if ((readSize=read(fileDes, buff + unpextra, unpbuffSize - unpextra)) <= 0) return EOF;
      setg(buff + (unpextra-leftover), buff + unpextra, buff + (4+readSize));
    }
    return *gptr();
  }
};

class fdistream : public istream
{
public:
  fdinbuff buff;
  fdistream(int fd) : buff(fd), istream(&buff) { }
};

/***************************************************************
 * UnnamedPipe
 ***************************************************************/
class UnnamedPipe 
{
public:
  fdostream *_out;
  fdistream *_in;
  int fd[2];
  bool openmask[2];
  UnnamedPipe()
  {    
    if (pipe(fd) == -1) { perror("Failed to create pipe!"); exit(1); }
    openmask[0] = openmask[1] = true;
    _in  = 0;
    _out = 0;
  }
  ~UnnamedPipe() { 
    if (_in) { 
      delete _in; 
    }
    if (openmask[0]) { 
      close(fd[0]); 
    } 
    if (_out) { 
      delete _out; 
    } 
    if (openmask[1]) { 
      close(fd[1]); 
    } 
  }

  fdistream& in()  { if (!_in) _in = new fdistream(fd[0]); return *_in; }
  fdostream& out() { if (!_out) _out = new fdostream(fd[1]); return *_out; }
  int fdin() { return fd[0]; }
  int fdout() { return fd[1]; }
  int setStdinToPipe() { return dup2(fdin(),fileno(stdin)); }
  int setStdoutToPipe() { return dup2(fdout(),fileno(stdout)); }
  int setStderrToPipe() { return dup2(fdout(),fileno(stderr)); }
  void closeIn() { 
    if (_in) { delete _in; _in = 0; }
    if (openmask[0]) { close(fd[0]); openmask[0] = false; } 
  }
  void closeOut() { 
    // const char ts[2] = {EOF,'\n'};
    if (_out) { delete _out; _out = 0; }
    if (openmask[1]) { 
      //      write(fd[1],ts,2); 
      close(fd[1]);  
      openmask[1] = false; }
  }
};

#endif