On Dec 17, 2012, at 12:05 PM, mickeyf <[email protected]> wrote:
> I have been using this with some success, but I am relatively new to Linux,
> and the mono documentation that I have found is missing or incomplete.
Is it?
http://docs.go-mono.com/?link=T%3aMono.Unix.UnixPipes
http://docs.go-mono.com/?link=M%3aMono.Unix.UnixPipes.CreatePipes()
http://docs.go-mono.com/?link=T%3aMono.Unix.UnixStream
Granted, there aren't any unit tests or "full" examples using it, but there's
certainly documentation... Of course, there's always source:
https://github.com/mono/mono/blob/master/mcs/class/Mono.Posix/Mono.Unix/UnixPipes.cs
> The Linux manual pages docs on pipes are clearly referring to a different
> animal than this.
UnixPipes wraps the "pipe" construct documented in the pipe(2) man page.
pipe(2) opens a pair of file descriptors for reading and writing;
UnixPipes.CreatePipes() calls pipe(2), wraps the reading file descriptor in the
UnixPipes.Reading field, and wraps the writing file descriptor in the
UnixPipes.Writing field.
> It appears that I can read a pipe as mypipes.readend.Read(buffer_to_read_to,
> read_position, bytes_to_read).
Correct. However, you may be misinterpreting "read_position"; "read_position"
is the offset within buffer_to_read_to at which to start writing bytes_to_read
bytes worth of data. It does _not_ imply any form of seeking at all.
For example, given:
byte[] buffer = new byte [3];
stream.Read (buffer, 1, 2);
After `stream.Read()`, buffer[0] will always be 0x00, because it will never
have been written to. The `1` specifies the position within `buffer` to start
writing, that's all, and has nothing to do with the underlying Stream.
See also:
http://msdn.microsoft.com/en-us/library/system.io.stream.read.aspx
> offset
> Type: System.Int32
> The zero-based byte offset in buffer at which to begin storing the data read
> from the current stream.
> I understand that I can't actually fseek using read_position,
You're dealing with pipes; you want POSIX functions, not libc functions.
(Granted, in C-land you could use fdopen(3), then use fseek(3)...)
Consequently, the appropriate seek function is lseek(2), which errors out with
ESPIPE when using pipes:
[ESPIPE] Fildes is associated with a pipe, socket, or FIFO.
No seeking on pipes. It's POSIX.
> but it seems that if I do not read the entire bytes_to_read, I can then
> continue to adjust read_position to read the remaining data.
I believe you're misunderstanding the `offset` parameter in the
Stream.Read(buffer, offset, count) method.
> 2) Since I can't find documentation specific to this, it's not clear what the
> return values from Read will be when I can't actually read anything.
UnixStream needs to conform to the System.IO.Stream contract, which MSDN
documents:
http://msdn.microsoft.com/en-us/library/system.io.stream.read.aspx
> Return Value
> Type: System.Int32
> The total number of bytes read into the buffer. This can be less than the
> number of bytes requested if that many bytes are not currently available, or
> zero (0) if the end of the stream has been reached.
> Does -1 indicate error, or simply "no data available"? What about 0?
-1 should not be returned, ever. (If read(2) returns -1, UnixStream.Read()
translates that into an exception.) If 0 is returned, then End-Of-Stream has
been reached. If "no data is available", the Read() method will _block_ until
data is available.
> 3) Can I set the write end to disable O_NONBLOCK,
Syscall.fcntl() can be used to set O_NONBLOCK.
> and does this guarantee that both the write and the read are atomic and that
> all bytes will in fact be read in a single read on the read end of the pipe?
As far as I am aware, _nothing_ can guarantee that. I could be wrong.
> Or, since what I really want to do is guarantee that a entire (privately
> defined) data packet as written by my C library code is read by my mono app,
> perhaps there is an entirely different, and better way to do this? Sockets?
As far as I am aware, no Stream-like API will support this, including sockets.
Data structure "boundaries" need to be dealt with at a higher level, e.g.
having a "protocol" that sends a length "packet" before sending the data. This
would allow the reader to read (and block reading, or read until it has read)
~4 bytes, examine the length, and then read the specified amount of data.
- Jon
_______________________________________________
Mono-list maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-list