#ifndef MSP_IO_BASE_H_
#define MSP_IO_BASE_H_
+#include <cstddef>
#include <sigc++/sigc++.h>
+#include <msp/core/mutex.h>
+#include <msp/core/noncopyable.h>
+#include "handle.h"
#include "mode.h"
#include "poll.h"
-#include "types.h"
namespace Msp {
namespace IO {
/**
Common interface for all I/O objects.
-
-A derived class must call set_events(P_NONE) before it is destroyed to avoid
-leaving stale pointers in an EventDispatcher.
*/
-class Base
+class Base: private NonCopyable
{
public:
- /** Emitted when there is data available for reading. If all data is not
- read, the signal is emitted again immediately. */
- sigc::signal<void> signal_data_available;
+ /** RAII synchronization primitive. Prevents concurrent access to the
+ target object during the lifetime of the Synchronize object. */
+ class Synchronize
+ {
+ private:
+ Base &io;
+
+ public:
+ Synchronize(Base &);
+ ~Synchronize();
+ };
/** Emitted when there is no more data to be read. */
sigc::signal<void> signal_end_of_file;
seeked) and any data buffered by upper layers needs to be flushed. */
sigc::signal<void> signal_flush_required;
- /** Emitted when the I/O object has closed. */
- sigc::signal<void> signal_closed;
-
- /** Emitted when the mask of interesting events changes. Mainly for use by
- EventDispatcher. */
- sigc::signal<void, PollEvent> signal_events_changed;
-
/** Emitted when the object is deleted. Mainly for use by
EventDispatcher. */
sigc::signal<void> signal_deleted;
protected:
- Mode mode;
- PollEvent events;
- bool eof_flag;
+ Mode mode = M_READ;
+ bool eof_flag = false;
+ Mutex *mutex = 0;
Base();
-private:
- Base(const Base &);
- Base &operator=(const Base &);
public:
virtual ~Base();
was done.
Blocking is enabled by default. */
- virtual void set_block(bool) { }
+ 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; }
protected:
- virtual unsigned do_write(const char *, unsigned) =0;
- virtual unsigned do_read(char *, unsigned) =0;
+ void check_access(Mode) const;
+
+ virtual std::size_t do_write(const char *, std::size_t) = 0;
+ virtual std::size_t do_read(char *, std::size_t) = 0;
public:
/** Writes data from a buffer. Subject to blocking. Returns the number of
bytes written, which may be zero for a non-blockin operation. */
- unsigned write(const char *b, unsigned c) { return do_write(b, c); }
+ std::size_t write(const char *b, std::size_t c) { return do_write(b, c); }
/** Writes a string. This is identical to calling
write(s.data(), s.size()). */
- unsigned write(const std::string &s) { return do_write(s.data(), s.size()); }
+ std::size_t write(const std::string &s) { return do_write(s.data(), s.size()); }
/** Writes a single character. This is identical to calling
write(&c, 1). */
- virtual unsigned put(char c) { return do_write(&c, 1); }
+ virtual std::size_t put(char c) { return do_write(&c, 1); }
/** Reads data into a buffer. Subject to blocking. Returns the number of
bytes read, which may be zero for a non-blocking operation. */
- unsigned read(char *b, unsigned c) { return do_read(b, c); }
+ std::size_t read(char *b, std::size_t c) { return do_read(b, c); }
/** Reads characters up to the next linefeed or end-of-file. The linefeed
is not included in the line. Returns true if a line was successfully read,
to end-of-file or non-blocking operation. */
virtual int get();
- /** Returns the end-of-file flag. */
- bool eof() const { return eof_flag; }
-
protected:
- void set_events(PollEvent);
+ void set_eof();
public:
- /** Returns a mask of the currently interesting events. Used by
- EventDispatcher. */
- PollEvent get_events() const { return events; }
-
- /** Returns a handle for polling. Should throw if the object does not have
- an event handle. */
- virtual Handle get_event_handle() =0;
-
- /** Notifies the object of an event. Used by EventDispatcher. */
- void event(PollEvent);
+ /** Returns the end-of-file flag. Note that some types of objects won't
+ indicate end-of-file until you try to read at least one byte past the actual
+ end, while others indicate it when you've read the last byte. */
+ bool eof() const { return eof_flag; }
-protected:
- virtual void on_event(PollEvent) { }
+ /** Returns the system-level handle for the object. Used by Console to
+ perform redirections. */
+ virtual const Handle &get_handle(Mode) = 0;
};
} // namespace IO