aios::aios (int fd, size_t rbsz) : fd (fd), err (0), eof (false), weof (false), rlock (false), inb (rbsz), infn (&aios::rnone), wblock (false), timeoutval (0), timeoutcb (NULL), debugiov (-1) { _make_async (fd); }
int aios::flush () { ptr<aios> hold; if (fd >= 0 && outb.tosuio ()->resid ()) { hold = mkref (this); // Don't let this be freed under us make_sync (fd); output (); _make_async (fd); } return err; }
static void ainit () { if (sigpipes[0] == -1) { if (pipe (sigpipes) < 0) fatal ("could not create sigpipes: %m\n"); _make_async (sigpipes[0]); _make_async (sigpipes[1]); close_on_exec (sigpipes[0]); close_on_exec (sigpipes[1]); fdcb (sigpipes[0], selread, wrap (sigcb_set_checkbit)); /* Set SA_RESTART for SIGCHLD, primarily for the benefit of * stdio-using code like lex/flex scanners. These tend to flip out * if read ever returns EINTR. */ sigcb (SIGCHLD, wrap (chldcb_check), (SA_NOCLDSTOP #ifdef SA_RESTART | SA_RESTART #endif /* SA_RESTART */ )); sigcatch (SIGCHLD); } }
static void err_wcb () { int n; int cnt; if (!erruio->resid () || _err_output != _err_output_async) { fdcb (errfd, selwrite, NULL); return; } /* Try to write whole lines at a time. */ for (cnt = min (erruio->iovcnt (), (size_t) UIO_MAXIOV); cnt > 0 && (erruio->iov ()[cnt-1].iov_len == 0 || *((char *) erruio->iov ()[cnt-1].iov_base + erruio->iov ()[cnt-1].iov_len - 1) != '\n'); cnt--) ; if (!cnt) { if (erruio->iovcnt () < UIO_MAXIOV) { /* Wait for a carriage return */ fdcb (errfd, selwrite, NULL); return; } else cnt = -1; } /* Write asynchronously, but keep stderr synchronous in case of * emergency (e.g. maybe assert wants to fprintf to stderr). */ if (globaldestruction) n = erruio->output (errfd, cnt); else { _make_async (errfd); n = erruio->output (errfd, cnt); make_sync (errfd); } if (n < 0) err_reset (); if (erruio->resid () && !globaldestruction) fdcb (errfd, selwrite, wrap (err_wcb)); else fdcb (errfd, selwrite, NULL); }