162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci *  linux/fs/proc/kmsg.c
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci *  Copyright (C) 1992  by Linus Torvalds
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/types.h>
1062306a36Sopenharmony_ci#include <linux/errno.h>
1162306a36Sopenharmony_ci#include <linux/time.h>
1262306a36Sopenharmony_ci#include <linux/kernel.h>
1362306a36Sopenharmony_ci#include <linux/poll.h>
1462306a36Sopenharmony_ci#include <linux/proc_fs.h>
1562306a36Sopenharmony_ci#include <linux/fs.h>
1662306a36Sopenharmony_ci#include <linux/syslog.h>
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci#include <asm/io.h>
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_cistatic int kmsg_open(struct inode * inode, struct file * file)
2162306a36Sopenharmony_ci{
2262306a36Sopenharmony_ci	return do_syslog(SYSLOG_ACTION_OPEN, NULL, 0, SYSLOG_FROM_PROC);
2362306a36Sopenharmony_ci}
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_cistatic int kmsg_release(struct inode * inode, struct file * file)
2662306a36Sopenharmony_ci{
2762306a36Sopenharmony_ci	(void) do_syslog(SYSLOG_ACTION_CLOSE, NULL, 0, SYSLOG_FROM_PROC);
2862306a36Sopenharmony_ci	return 0;
2962306a36Sopenharmony_ci}
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_cistatic ssize_t kmsg_read(struct file *file, char __user *buf,
3262306a36Sopenharmony_ci			 size_t count, loff_t *ppos)
3362306a36Sopenharmony_ci{
3462306a36Sopenharmony_ci	if ((file->f_flags & O_NONBLOCK) &&
3562306a36Sopenharmony_ci	    !do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, SYSLOG_FROM_PROC))
3662306a36Sopenharmony_ci		return -EAGAIN;
3762306a36Sopenharmony_ci	return do_syslog(SYSLOG_ACTION_READ, buf, count, SYSLOG_FROM_PROC);
3862306a36Sopenharmony_ci}
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_cistatic __poll_t kmsg_poll(struct file *file, poll_table *wait)
4162306a36Sopenharmony_ci{
4262306a36Sopenharmony_ci	poll_wait(file, &log_wait, wait);
4362306a36Sopenharmony_ci	if (do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, SYSLOG_FROM_PROC))
4462306a36Sopenharmony_ci		return EPOLLIN | EPOLLRDNORM;
4562306a36Sopenharmony_ci	return 0;
4662306a36Sopenharmony_ci}
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_cistatic const struct proc_ops kmsg_proc_ops = {
5062306a36Sopenharmony_ci	.proc_flags	= PROC_ENTRY_PERMANENT,
5162306a36Sopenharmony_ci	.proc_read	= kmsg_read,
5262306a36Sopenharmony_ci	.proc_poll	= kmsg_poll,
5362306a36Sopenharmony_ci	.proc_open	= kmsg_open,
5462306a36Sopenharmony_ci	.proc_release	= kmsg_release,
5562306a36Sopenharmony_ci	.proc_lseek	= generic_file_llseek,
5662306a36Sopenharmony_ci};
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_cistatic int __init proc_kmsg_init(void)
5962306a36Sopenharmony_ci{
6062306a36Sopenharmony_ci	proc_create("kmsg", S_IRUSR, NULL, &kmsg_proc_ops);
6162306a36Sopenharmony_ci	return 0;
6262306a36Sopenharmony_ci}
6362306a36Sopenharmony_cifs_initcall(proc_kmsg_init);
64