On Dec 17, 2012, at 12:05 PM, mickeyf <mic...@thesweetoasis.com> 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 - Mono-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-list