static ssize_t batadv_log_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { struct batadv_priv *bat_priv = file->private_data; struct batadv_debug_log *debug_log = bat_priv->debug_log; int error, i = 0; char *char_addr; char c; if ((file->f_flags & O_NONBLOCK) && batadv_log_empty(debug_log)) return -EAGAIN; if (!buf) return -EINVAL; if (count == 0) return 0; if (!access_ok(VERIFY_WRITE, buf, count)) return -EFAULT; error = wait_event_interruptible(debug_log->queue_wait, (!batadv_log_empty(debug_log))); if (error) return error; spin_lock_bh(&debug_log->lock); while ((!error) && (i < count) && (debug_log->log_start != debug_log->log_end)) { char_addr = batadv_log_char_addr(debug_log, debug_log->log_start); c = *char_addr; debug_log->log_start++; spin_unlock_bh(&debug_log->lock); error = __put_user(c, buf); spin_lock_bh(&debug_log->lock); buf++; i++; } spin_unlock_bh(&debug_log->lock); if (!error) return i; return error; }
static __poll_t batadv_log_poll(struct file *file, poll_table *wait) { struct batadv_priv *bat_priv = file->private_data; struct batadv_priv_debug_log *debug_log = bat_priv->debug_log; poll_wait(file, &debug_log->queue_wait, wait); if (!batadv_log_empty(debug_log)) return EPOLLIN | EPOLLRDNORM; return 0; }