Implement controls for file descriptor inheritance
[libs/core.git] / source / io / pipe.cpp
1 #include "pipe.h"
2
3 using namespace std;
4
5 namespace Msp {
6 namespace IO {
7
8 Pipe::Pipe():
9         reader(read_handle, 1024)
10 {
11         mode = M_RDWR;
12
13         platform_init();
14
15         set_events(P_INPUT);
16 }
17
18 Pipe::~Pipe()
19 {
20         set_events(P_NONE);
21
22         signal_flush_required.emit();
23         sys_close(read_handle);
24         sys_close(write_handle);
25 }
26
27 void Pipe::set_mode(Mode m)
28 {
29         m = m&M_RDWR;
30         if(!m)
31                 throw invalid_argument("Pipe::set_mode");
32
33         check_access(m);
34
35         Mode close = mode&M_RDWR&~m;
36         if(close&M_READ)
37                 sys_close(read_handle);
38         if(close&M_WRITE)
39                 sys_close(write_handle);
40         mode = (mode&~M_RDWR)|m;
41 }
42
43 void Pipe::set_block(bool b)
44 {
45         adjust_mode(mode, M_NONBLOCK, !b);
46         sys_set_blocking(read_handle, b);
47         sys_set_blocking(write_handle, b);
48 }
49
50 void Pipe::set_inherit(bool i)
51 {
52         adjust_mode(mode, M_INHERIT, i);
53         sys_set_inherit(read_handle, i);
54         sys_set_inherit(write_handle, i);
55 }
56
57 unsigned Pipe::do_write(const char *buf, unsigned size)
58 {
59         if(size==0)
60                 return 0;
61
62         return sys_write(write_handle, buf, size);
63 }
64
65 unsigned Pipe::do_read(char *buf, unsigned size)
66 {
67         if(size==0)
68                 return 0;
69
70         unsigned ret = reader.read(buf, size);
71         if(ret==0)
72                 set_eof();
73
74         return ret;
75 }
76
77 const Handle &Pipe::get_handle(Mode m)
78 {
79         if(m==M_READ)
80                 return read_handle;
81         else if(m==M_WRITE)
82                 return write_handle;
83         else
84                 throw invalid_argument("Pipe::get_handle");
85 }
86
87 } // namespace IO
88 } // namespace Msp