xref: /openbmc/linux/arch/um/kernel/exitcode.c (revision 64c70b1c)
1 /*
2  * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3  * Licensed under the GPL
4  */
5 
6 #include "linux/kernel.h"
7 #include "linux/init.h"
8 #include "linux/ctype.h"
9 #include "linux/proc_fs.h"
10 #include "asm/uaccess.h"
11 
12 /* If read and write race, the read will still atomically read a valid
13  * value.
14  */
15 int uml_exitcode = 0;
16 
17 static int read_proc_exitcode(char *page, char **start, off_t off,
18 			      int count, int *eof, void *data)
19 {
20 	int len, val;
21 
22 	/* Save uml_exitcode in a local so that we don't need to guarantee
23 	 * that sprintf accesses it atomically.
24 	 */
25 	val = uml_exitcode;
26 	len = sprintf(page, "%d\n", val);
27 	len -= off;
28 	if(len <= off+count)
29 		*eof = 1;
30 	*start = page + off;
31 	if(len > count)
32 		len = count;
33 	if(len < 0)
34 		len = 0;
35 	return len;
36 }
37 
38 static int write_proc_exitcode(struct file *file, const char __user *buffer,
39 			       unsigned long count, void *data)
40 {
41 	char *end, buf[sizeof("nnnnn\0")];
42 	int tmp;
43 
44 	if(copy_from_user(buf, buffer, count))
45 		return -EFAULT;
46 
47 	tmp = simple_strtol(buf, &end, 0);
48 	if((*end != '\0') && !isspace(*end))
49 		return -EINVAL;
50 
51 	uml_exitcode = tmp;
52 	return count;
53 }
54 
55 static int make_proc_exitcode(void)
56 {
57 	struct proc_dir_entry *ent;
58 
59 	ent = create_proc_entry("exitcode", 0600, &proc_root);
60 	if(ent == NULL){
61 		printk(KERN_WARNING "make_proc_exitcode : Failed to register "
62 		       "/proc/exitcode\n");
63 		return 0;
64 	}
65 
66 	ent->read_proc = read_proc_exitcode;
67 	ent->write_proc = write_proc_exitcode;
68 
69 	return 0;
70 }
71 
72 __initcall(make_proc_exitcode);
73