static ssize_t isert_listen_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) { struct isert_listener_dev *dev = filp->private_data; struct isert_conn_dev *conn_dev; int res = 0; char k_buff[sizeof("/dev/") + sizeof(ISER_CONN_DEV_PREFIX) + 3 + 1]; size_t to_write; TRACE_ENTRY(); if (!have_new_connection(dev)) { wait_for_connection: if (filp->f_flags & O_NONBLOCK) return -EAGAIN; res = wait_event_freezable(dev->waitqueue, !have_new_connection(dev)); if (res < 0) goto out; } spin_lock(&dev->conn_lock); if (list_empty(&dev->new_conn_list)) { /* could happen if we got disconnect */ spin_unlock(&dev->conn_lock); goto wait_for_connection; } conn_dev = list_first_entry(&dev->new_conn_list, struct isert_conn_dev, conn_list_entry); list_move(&conn_dev->conn_list_entry, &dev->curr_conn_list); spin_unlock(&dev->conn_lock); to_write = min_t(size_t, sizeof(k_buff), count); res = scnprintf(k_buff, to_write, "/dev/"ISER_CONN_DEV_PREFIX"%d", conn_dev->idx); ++res; /* copy trailing \0 as well */ if (unlikely(copy_to_user(buf, k_buff, res))) res = -EFAULT; out: TRACE_EXIT_RES(res); return res; }
static unsigned int isert_listen_poll(struct file *filp, struct poll_table_struct *wait) { struct isert_listener_dev *dev = filp->private_data; unsigned int mask = 0; poll_wait(filp, &dev->waitqueue, wait); if (have_new_connection(dev)) mask |= POLLIN | POLLRDNORM; return mask; }