int write(int fd, const void *buf, size_t nbytes) { if (fd < 0 || fd >= NOFILE) { fd = EBADF; return -1; } switch (files[fd].type) { case FTYPE_SAVEFILE: { int ret = 0, tot = nbytes; while (nbytes > 0) { ret = xencons_ring_send(files[fd].cons.dev, (char *)buf, nbytes); nbytes -= ret; buf = (char *)buf + ret; } return tot - nbytes; } case FTYPE_CONSOLE: console_print(files[fd].cons.dev, (char *)buf, nbytes); return nbytes; #ifdef HAVE_LWIP case FTYPE_SOCKET: return lwip_write(files[fd].socket.fd, (void*) buf, nbytes); #endif case FTYPE_TAP: netfront_xmit(files[fd].tap.dev, (void*) buf, nbytes); return nbytes; default: break; } printk("write(%d): Bad descriptor\n", fd); errno = EBADF; return -1; }
static void __xencons_tx_flush(void) { int sent, sz, work_done = 0; if (x_char) { if (is_initial_xendomain()) kcons_write_dom0(NULL, &x_char, 1); else while (x_char) if (xencons_ring_send(&x_char, 1) == 1) break; x_char = 0; work_done = 1; } while (wc != wp) { sz = wp - wc; if (sz > (wbuf_size - WBUF_MASK(wc))) sz = wbuf_size - WBUF_MASK(wc); if (is_initial_xendomain()) { kcons_write_dom0(NULL, &wbuf[WBUF_MASK(wc)], sz); wc += sz; } else { sent = xencons_ring_send(&wbuf[WBUF_MASK(wc)], sz); if (sent == 0) break; wc += sent; } work_done = 1; } if (work_done && (xencons_tty != NULL)) { wake_up_interruptible(&xencons_tty->write_wait); if ((xencons_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && (xencons_tty->ldisc.write_wakeup != NULL)) (xencons_tty->ldisc.write_wakeup)(xencons_tty); } }
/*** Forcibly flush console data before dying. ***/ void xcons_force_flush(void) { int sz; if (xen_initial_domain()) return; /* Spin until console data is flushed through to the domain controller. */ while (wc != wp) { int sent = 0; if ((sz = wp - wc) == 0) continue; sent = xencons_ring_send(&wbuf[WBUF_MASK(wc)], sz); if (sent > 0) wc += sent; } }
int write(int fd, const void *buf, size_t nbytes) { switch (files[fd].type) { case FTYPE_SAVEFILE: { int ret = 0, tot = nbytes; while (nbytes > 0) { ret = xencons_ring_send(files[fd].cons.dev, (char *)buf, nbytes); nbytes -= ret; buf = (char *)buf + ret; } return tot - nbytes; } case FTYPE_CONSOLE: console_print(files[fd].cons.dev, (char *)buf, nbytes); return nbytes; #ifdef HAVE_LWIP case FTYPE_SOCKET: return lwip_write(files[fd].socket.fd, (void*) buf, nbytes); #endif #ifdef CONFIG_NETFRONT case FTYPE_TAP: netfront_xmit(files[fd].tap.dev, (void*) buf, nbytes); return nbytes; #endif #ifdef CONFIG_BLKFRONT case FTYPE_BLK: return blkfront_posix_write(fd, buf, nbytes); #endif #ifdef CONFIG_TPMFRONT case FTYPE_TPMFRONT: return tpmfront_posix_write(fd, buf, nbytes); #endif #ifdef CONFIG_TPM_TIS case FTYPE_TPM_TIS: return tpm_tis_posix_write(fd, buf, nbytes); #endif default: break; } printk("write(%d): Bad descriptor\n", fd); errno = EBADF; return -1; }
/*** Forcibly flush console data before dying. ***/ void xencons_force_flush(void) { int sz; /* Emergency console is synchronous, so there's nothing to flush. */ if (!is_running_on_xen() || is_initial_xendomain() || !xen_start_info->console.domU.evtchn) return; /* Spin until console data is flushed through to the daemon. */ while (wc != wp) { int sent = 0; if ((sz = wp - wc) == 0) continue; sent = xencons_ring_send(&wbuf[WBUF_MASK(wc)], sz); if (sent > 0) wc += sent; } }
static void __xencons_tx_flush(void) { int sz; CN_LOCK(cn_mtx); while (wc != wp) { int sent; sz = wp - wc; if (sz > (WBUF_SIZE - WBUF_MASK(wc))) sz = WBUF_SIZE - WBUF_MASK(wc); if (xen_initial_domain()) { HYPERVISOR_console_io(CONSOLEIO_write, sz, &wbuf[WBUF_MASK(wc)]); wc += sz; } else { sent = xencons_ring_send(&wbuf[WBUF_MASK(wc)], sz); if (sent == 0) break; wc += sent; } } CN_UNLOCK(cn_mtx); }