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