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