if(redirect)
{
+ // dup2 clears O_CLOEXEC
if(cin)
IO::cin.redirect(*cin);
if(cout)
Blocking is enabled by default. */
virtual void set_block(bool) = 0;
+ /** Sets inheritance mode. When inheritance is enabled, the file descriptor
+ will persist through Process::execute.
+
+ Inheritance is disabled by default. */
+ virtual void set_inherit(bool) = 0;
+
/** Returns the current mode flags. */
Mode get_mode() const { return mode; }
throw logic_error("Buffered::set_block");
}
+void Buffered::set_inherit(bool)
+{
+ throw logic_error("Buffered::set_block");
+}
+
void Buffered::flush()
{
if(cur_op==M_WRITE)
~Buffered();
virtual void set_block(bool);
+ virtual void set_inherit(bool);
void flush();
sys_set_blocking(handle, b);
}
+void Console::set_inherit(bool i)
+{
+ adjust_mode(mode, M_INHERIT, i);
+ sys_set_inherit(handle, i);
+}
+
unsigned Console::do_write(const char *buf, unsigned len)
{
check_access(M_WRITE);
~Console();
virtual void set_block(bool);
+ virtual void set_inherit(bool);
/** If local echo is enabled, characters will appear on the console as they
are typed. Can only be used on an input Console. */
sys_set_blocking(handle, b);
}
+void File::set_inherit(bool i)
+{
+ adjust_mode(mode, M_INHERIT, i);
+ sys_set_inherit(handle, i);
+}
+
unsigned File::do_write(const char *buf, unsigned size)
{
check_access(M_WRITE);
file.set_block(b);
}
+void BufferedFile::set_inherit(bool)
+{
+ throw logic_error("BufferedFile::set_inherit");
+}
+
unsigned BufferedFile::do_write(const char *buf, unsigned size)
{
unsigned ret = buffer.write(buf, size);
virtual ~File();
virtual void set_block(bool);
+ virtual void set_inherit(bool);
protected:
virtual unsigned do_write(const char *, unsigned);
BufferedFile(const std::string &, Mode = M_READ, File::CreateMode = File::C_OVERWRITE);
virtual void set_block(bool);
+ virtual void set_inherit(bool);
protected:
virtual unsigned do_write(const char *, unsigned);
void sys_set_blocking(Handle &, bool);
+void sys_set_inherit(Handle &, bool);
unsigned sys_read(Handle &, char *, unsigned);
unsigned sys_write(Handle &, const char *, unsigned);
void sys_close(Handle &);
throw logic_error("Memory::set_block");
}
+void Memory::set_inherit(bool)
+{
+ throw logic_error("Memory::set_inherit");
+}
+
unsigned Memory::do_write(const char *buf, unsigned size)
{
check_access(M_WRITE);
public:
virtual void set_block(bool);
+ virtual void set_inherit(bool);
private:
virtual unsigned do_write(const char *, unsigned);
M_WRITE = 2,
M_RDWR = M_READ|M_WRITE,
M_APPEND = 4,
- M_NONBLOCK = 8
+ M_NONBLOCK = 8,
+ M_INHERIT = 16
};
inline Mode operator|(Mode m, Mode n)
sys_set_blocking(write_handle, b);
}
+void Pipe::set_inherit(bool i)
+{
+ adjust_mode(mode, M_INHERIT, i);
+ sys_set_inherit(read_handle, i);
+ sys_set_inherit(write_handle, i);
+}
+
unsigned Pipe::do_write(const char *buf, unsigned size)
{
if(size==0)
void set_mode(Mode);
virtual void set_block(bool);
+ virtual void set_inherit(bool);
protected:
virtual unsigned do_write(const char *, unsigned);
sys_set_blocking(handle, b);
}
+void Serial::set_inherit(bool i)
+{
+ adjust_mode(mode, M_INHERIT, i);
+ sys_set_inherit(handle, i);
+}
+
void Serial::set_baud_rate(unsigned rate)
{
DeviceState state;
public:
virtual void set_block(bool);
+ virtual void set_inherit(bool);
void set_baud_rate(unsigned);
void set_data_bits(unsigned);
throw logic_error("Slice::set_block");
}
+void Slice::set_inherit(bool)
+{
+ throw logic_error("Slice::set_inherit");
+}
+
void Slice::flush()
{
sync_position = true;
Slice(Seekable &, SeekOffset, SeekOffset);
virtual void set_block(bool);
+ virtual void set_inherit(bool);
private:
void flush();
flags |= O_APPEND;
if(mode&M_NONBLOCK)
flags |= O_NONBLOCK;
+ if(!(mode&M_INHERIT))
+ flags |= O_CLOEXEC;
*handle = ::open(fn.c_str(), flags, 0666);
if(!handle)
fcntl(*handle, F_SETFL, (flags&~O_NONBLOCK)|(b?0:O_NONBLOCK));
}
+void sys_set_inherit(Handle &handle, bool i)
+{
+ int flags = fcntl(*handle, F_GETFD);
+ fcntl(*handle, F_SETFD, (flags&~O_CLOEXEC)|(i?O_CLOEXEC:0));
+}
+
unsigned sys_read(Handle &handle, char *buf, unsigned size)
{
int ret = read(*handle, buf, size);
else
share_flags = FILE_SHARE_READ;
+ SECURITY_ATTRIBUTES sec_attr;
+ sec_attr.nLength = sizeof(SECURITY_ATTRIBUTES);
+ sec_attr.lpSecurityDescriptor = 0;
+ sec_attr.bInheritHandle = !!(mode&M_INHERIT);
+
*handle = CreateFile(fn.c_str(), flags, share_flags, 0, create_flags, FILE_ATTRIBUTE_NORMAL, 0);
if(!handle)
{
{
}
+void sys_set_inherit(Handle &, bool)
+{
+}
+
unsigned sys_read(Handle &handle, char *buf, unsigned size)
{
DWORD ret;
throw logic_error("ZlibCompressed::set_block");
}
+void ZlibCompressed::set_inherit(bool)
+{
+ throw logic_error("ZlibCompressed::set_inherit");
+}
+
void ZlibCompressed::flush()
{
#ifdef WITH_ZLIB
virtual ~ZlibCompressed();
virtual void set_block(bool);
+ virtual void set_inherit(bool);
void flush();