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

Reply via email to