static int pipe_poll(struct fnode *f, uint16_t events, uint16_t *revents) { struct pipe_priv *pp; *revents = 0; if (f->owner != &mod_pipe) return -EINVAL; pp = (struct pipe_priv *)f->priv; if (!pp) { return -EINVAL; } if (f == pp->fno_w) { if(pp->fno_r == 0) { *revents |= POLLHUP; return 1; } else if ((events & POLLOUT) && (cirbuf_bytesfree(pp->cb) > 0)) { *revents = POLLOUT; return 1; } } if ((f == pp->fno_r) && (events & POLLIN) && (cirbuf_bytesinuse(pp->cb) > 0)) { *revents |= POLLIN; return 1; } return 0; }
static void printchar(char **str, int c) { if (str) { **str = c; ++(*str); } else { if (cirbuf_bytesfree(klog.buf)) { cirbuf_writebyte(klog.buf, c); if (klog.task != NULL) task_resume(klog.task); } } }
static int pipe_write(struct fnode *f, const void *buf, unsigned int len) { struct pipe_priv *pp; int out, len_available; const uint8_t *ptr = buf; if (f->owner != &mod_pipe) return -EINVAL; pp = (struct pipe_priv *)f->priv; if (!pp) return -EINVAL; if (pp->fno_w != f) return -EPERM; out = pp->w_off; len_available = cirbuf_bytesfree(pp->cb); if (len_available > (len - out)) len_available = (len - out); for(; out < len_available; out++) { /* write data */ if (cirbuf_writebyte(pp->cb, *(ptr + out)) != 0) break; } if (out < len) { pp->pid_w = scheduler_get_cur_pid(); pp->w_off = out; task_suspend(); return SYS_CALL_AGAIN; } pp->w_off = 0; pp->pid_w = 0; return out; }