+/*
+ Writes the indicated bytes (n2write) from buf onto the fd. Returns only after
+ full buffer is written, or there is a hard error (not eagain or eintr).
+ Returns the number written; if less than n2write the caller may assume
+ that there was a hard error and errno should reflect.
+*/
+static inline int write_all( int fd, char const* buf, int n2write ) {
+ ssize_t remain = 0; // number of bytes remaining to write
+ ssize_t wrote = 0; // number of bytes written thus far
+ ssize_t state = 0;
+
+ if( fd < 0 ) {
+ errno = EBADFD;
+ return 0;
+ }
+
+ errno = 0;
+ remain = n2write;
+ do {
+ if( (state = write( fd, buf + wrote, remain )) > 0 ) {
+ wrote += state;
+ remain = n2write - wrote;
+ }
+ } while( remain > 0 && (errno == EINTR || errno == EAGAIN) ) ;
+
+ return wrote;
+}
+
+/*
+ Similar to write_all, this will write all bytes in the buffer, but
+ will return failure if the first write attempt fails with 0 written
+ (assuming that the pipe has no reader). We use this when writing the
+ header bytes; we want to drop the message if we can't even write one
+ byte, but if we write one, we must loop until all are written.
+
+ Returns the number written. If that value is less than n2write, then
+ the caller may assume a hard error occurred and errno should reflect.
+ If 0 is returned it can be assumed that the FIFO would block/has no
+ reader.
+*/
+static inline int write_all_nb( int fd, char const* buf, int n2write ) {
+ ssize_t remain = 0; // number of bytes remaining to write
+ ssize_t wrote = 0; // number of bytes written
+
+ if( fd < 0 ) {
+ errno = EBADFD;
+ return 0;
+ }
+
+ errno = 0;
+ remain = n2write;
+ wrote = write( fd, buf, remain );
+ if( wrote < 0 ) { // report error with exception for broken pipe
+ return errno == EPIPE ? 0 : -1; // broken pipe we assume no reader and return 0 since nothing written
+ }
+
+ if( wrote < n2write && wrote > 0 ) { // if we wrote anything, we must tough it out and write all if it was short
+ wrote += write_all( fd, buf + wrote, n2write - wrote );
+ }
+
+ return wrote;
+}
+