brnstnd@stealth.acf.nyu.edu (01/07/90)
I'd like to write to a file descriptor without blocking. select() tells me that I can write at least one character, but I don't want to have to write the characters individually. The FNDELAY fcntl() is inappropriate because it affects other processes. If select() says the fd is writable, is the write() guaranteed not to block? In that case, as long as it isn't interrupted, will the write() always return the correct count of characters written? If not, is there a solution? ---Dan
guy@auspex.auspex.com (Guy Harris) (01/09/90)
>If select() says the fd is writable, is the write() guaranteed not to >block? Which "write()"? Not all "write()"s are guaranteed not to block. It's guaranteed that you can write *some* amount of data without blocking, but no guarantee as to how much is made, in general. Sorry, but you really *are* expected to use non-blocking I/O in that case....
brnstnd@stealth.acf.nyu.edu (01/11/90)
In article <2799@auspex.auspex.com> guy@auspex.auspex.com (Guy Harris) writes: > It's > guaranteed that you can write *some* amount of data without blocking, > but no guarantee as to how much is made, in general. Can you show me a program that blocks on a write() after select() has indicated that the descriptor is writable? (select() on this machine is slightly buggy, so I'm not sure my tests are accurate.) > Sorry, but you > really *are* expected to use non-blocking I/O in that case.... Okay, Guy, tell me how I accomplish this: Process A writes data to a pipe connected to Process B. Process A must not block on its writes, because it has to handle other descriptors as well. Process B is an already-written program that assumes that its reads are non-blocking; it'll take EWOULDBLOCK as a read error and die horribly. Process A can avoid blocking by using select() and writing just one character at a time. Is there any other way? C'mon, guys, this is a simple question! ---Dan
guy@auspex.auspex.com (Guy Harris) (01/12/90)
>Can you show me a program that blocks on a write() after select() has >indicated that the descriptor is writable? Sure - a program that writes 50,000 characters on a "write", if the "select()" returns true because there are 2 bytes of buffer space available in the socket. (Or, more generally, a program that writes N characters on a "write", when the "select()" returns true because there are M < N bytes of buffer space left in the socket.) Whether this will actually occur in the real world depends on the value of "N" for any particular write, and the value of "M" for any particular select wakeup; the latter would depend on all sorts of things, like the type of socket, whether you've set SO_SNDBUF, etc.. >Okay, Guy, tell me how I accomplish this: Process A writes data to a >pipe connected to Process B. Process A must not block on its writes, >because it has to handle other descriptors as well. Process B is an >already-written program that assumes that its reads are non-blocking; >it'll take EWOULDBLOCK as a read error and die horribly. I have no idea how you'd accomplish that and, since it's not a problem I've personally run into, it's not exactly high on my list of problems to solve. You have my sympathy, but that's about it.... >C'mon, guys, this is a simple question! And it may have a simple answer like "sorry, you can't do it".
brnstnd@stealth.acf.nyu.edu (01/17/90)
I'm trying to write a ``multitee'' program so that, e.g., multitee 0:6,7 6:1 would send all input from fd 0 to fd 6 and fd 7, while sending all input from fd 6 to fd 1. It's a trivial problem, except that multitee should do its best to never block on writes. (Otherwise it could enter a deadlock with another process.) Buffering is easy, but how to avoid blocking? One correct answer is to always write just one character per write() call. Unfortunately, this usually forces a hellish overhead. Another answer is to use fcntl() and set FNDELAY on the descriptor. Unfortunately, this doesn't just affect the descriptor; it affects the entire open file, including possibly other processes. (This is the real problem.) Another answer is that multitee should fork into separate processes, one for each input descriptor. This works and solves the flow control problems, but it's not very polite to other processes unless the system supports threads. In article <2816@auspex.auspex.com> guy@auspex.auspex.com (Guy Harris) writes: > >C'mon, guys, this is a simple question! > And it may have a simple answer like "sorry, you can't do it". I guess it's a good question, then... ---Dan