void unmap(char *progname) { char buf[1024], *p; char rbuf[2048]; int cc, fd; fd = linux_open("/proc/self/maps", 0, 0); p = &buf[0]; while (0 < (cc = linux_read(fd, rbuf, sizeof(rbuf)))) { int i; for (i = 0; i < cc; ++i) { int c = rbuf[i]; if ('\n' != c) *p++ = c; else { *p = '\0'; /* When a line from /proc/self/maps shows up as having been * mapped in from this running program, ld.so or libc, unmap it. * This will keep the exec'd program's address space a lot * cleaner. But even a 32-bit address space can hold 2 copies * of glibc without ill effects, so you don't really have to * munmap() anything other than the program calling ul_exec() */ if (strstr(buf, progname) || strstr(buf, "libdl") || strstr(buf, "/usr/lib/ld-") || strstr(buf, "/lib64/ld-") || strstr(buf, "libc")) { char *u; char *first, *second; unsigned long low, high; u = strchr(buf, ' '); *u = '\0'; first = buf; second = strchr(first, '-'); *second = '\0'; ++second; low = strtoul(first, NULL, 0x10); high = strtoul(second, NULL, 0x10); linux_munmap((void *)low, high-low); } p = &buf[0]; } } } linux_close(fd); }
static ssize_t hf_read(struct cdev *cdev, void *buf, size_t count, loff_t offset, ulong flags) { struct hf_platform_data *hf = cdev->priv; int fd = hf->fd; if (linux_lseek(fd, offset) != offset) return -EINVAL; return linux_read(fd, buf, count); }
void print_maps(void) { char rbuf[1024]; int fd, cc; fd = linux_open("/proc/self/maps", 0, 0); while (0 < (cc = linux_read(fd, rbuf, sizeof(rbuf)))) linux_write(1, rbuf, cc); linux_close(fd); }
static int linux_console_getchar() { char c; /* read from stdin */ if (linux_read(0, &c, 1) < 0) { DBG("linux_console read failed (%s)\n", linux_strerror(linux_errno)); return 0; } /* backspace seems to be returned as ascii del, map it here */ if (c == 0x7f) return KEY_BACKSPACE; else return c; }
static int linux_console_getc(struct console_device *cdev) { struct device_d *dev = cdev->dev; struct linux_console_data *d = dev->platform_data; static char old_c; char c; linux_read(d->stdinfd, &c, 1); if (old_c == 0x1c && c == 'q') panic("^\\q pressed - exiting"); old_c = c; return c; }
/** * Read from PCI configuration space * * @v pci PCI device * @v where Address within configuration space * @v value Data buffer * @v len Length to read * @ret rc Return status code */ int linux_pci_read ( struct pci_device *pci, unsigned long where, unsigned long *value, size_t len ) { uint32_t tmp = 0; int fd; int check_len; int rc; /* Return "missing device" in case of error */ *value = -1UL; /* Open configuration space */ fd = linux_pci_open ( pci, O_RDONLY, where ); if ( fd < 0 ) { rc = fd; goto err_open; } /* Read value */ check_len = linux_read ( fd, &tmp, len ); if ( check_len < 0 ) { DBGC ( pci, "PCI could not read from " PCI_FMT " %#02lx+%#zx: " "%s\n", PCI_ARGS ( pci ), where, len, linux_strerror ( linux_errno ) ); rc = -ELINUX ( linux_errno ); goto err_read; } if ( ( size_t ) check_len != len ) { DBGC ( pci, "PCI read only %#x bytes from " PCI_FMT " %#02lx+%#zx\n", check_len, PCI_ARGS ( pci ), where, len ); rc = -EIO; goto err_read; } /* Return value */ *value = le32_to_cpu ( tmp ); /* Success */ rc = 0; err_read: linux_close ( fd ); err_open: return rc; }
/** * Get noise sample * * @ret noise Noise sample * @ret rc Return status code */ static int linux_get_noise ( noise_sample_t *noise ) { uint8_t byte; ssize_t len; /* Read a single byte from entropy source */ len = linux_read ( entropy_fd, &byte, sizeof ( byte ) ); if ( len < 0 ) { DBGC ( &entropy_fd, "ENTROPY could not read from %s: %s\n", entropy_filename, linux_strerror ( linux_errno ) ); return len; } if ( len == 0 ) { DBGC ( &entropy_fd, "ENTROPY EOF on reading from %s: %s\n", entropy_filename, linux_strerror ( linux_errno ) ); return -EPIPE; } *noise = byte; return 0; }
/** Poll for new packets */ static void af_packet_nic_poll ( struct net_device *netdev ) { struct af_packet_nic * nic = netdev->priv; struct pollfd pfd; struct io_buffer * iobuf; int r; pfd.fd = nic->fd; pfd.events = POLLIN; if (linux_poll(&pfd, 1, 0) == -1) { DBGC(nic, "af_packet %p poll failed (%s)\n", nic, linux_strerror(linux_errno)); return; } if ((pfd.revents & POLLIN) == 0) return; /* At this point we know there is at least one new packet to be read */ iobuf = alloc_iob(RX_BUF_SIZE); if (! iobuf) goto allocfail; while ((r = linux_read(nic->fd, iobuf->data, RX_BUF_SIZE)) > 0) { DBGC2(nic, "af_packet %p read %d bytes\n", nic, r); iob_put(iobuf, r); netdev_rx(netdev, iobuf); iobuf = alloc_iob(RX_BUF_SIZE); if (! iobuf) goto allocfail; } free_iob(iobuf); return; allocfail: DBGC(nic, "af_packet %p alloc_iob failed\n", nic); }
int linux_read_nonblock(int fd, void *buf, size_t count) { int oldflags, ret; oldflags = fcntl(fd, F_GETFL); if (oldflags == -1) goto err_out; if (fcntl(fd, F_SETFL, oldflags | O_NONBLOCK) == -1) goto err_out; ret = linux_read(fd, buf, count); if (fcntl(fd, F_SETFL, oldflags) == -1) goto err_out; return ret; err_out: perror("fcntl"); return -1; }