aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/kernel
diff options
context:
space:
mode:
authorJeff Dike <jdike@addtoit.com>2005-09-16 22:27:49 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-17 14:50:00 -0400
commitb4fd310e163477236a241580b3b8c29aee65f4cc (patch)
tree3aec7527c4a9589824cb4d96f87446eb59bdef10 /arch/um/kernel
parent64b7673f91c0c3614028c5942b0d6a91d0b64a98 (diff)
[PATCH] uml: preserve errno in error paths
The poster child for this patch is the third tuntap_user hunk. When an ioctl fails, it properly closes the opened file descriptor and returns. However, the close resets errno to 0, and the 'return errno' that follows returns 0 rather than the value that ioctl set. This caused the caller to believe that the device open succeeded and had opened file descriptor 0, which caused no end of interesting behavior. The rest of this patch is a pass through the UML sources looking for places where errno could be reset before being passed back out. A common culprit is printk, which could call write, being called before errno is returned. In some cases, where the code ends up being much smaller, I just deleted the printk. There was another case where a caller of run_helper looked at errno after a failure, rather than the return value of run_helper, which was the errno value that it wanted. Signed-off-by: Jeff Dike <jdike@addtoit.com> Cc: Paolo Giarrusso <blaisorblade@yahoo.it> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/um/kernel')
-rw-r--r--arch/um/kernel/helper.c12
-rw-r--r--arch/um/kernel/user_util.c12
2 files changed, 11 insertions, 13 deletions
diff --git a/arch/um/kernel/helper.c b/arch/um/kernel/helper.c
index f83e1e8e2392..33fb0bd3b11a 100644
--- a/arch/um/kernel/helper.c
+++ b/arch/um/kernel/helper.c
@@ -85,8 +85,8 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
85 data.fd = fds[1]; 85 data.fd = fds[1];
86 pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data); 86 pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data);
87 if(pid < 0){ 87 if(pid < 0){
88 printk("run_helper : clone failed, errno = %d\n", errno);
89 ret = -errno; 88 ret = -errno;
89 printk("run_helper : clone failed, errno = %d\n", errno);
90 goto out_close; 90 goto out_close;
91 } 91 }
92 92
@@ -122,7 +122,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
122 unsigned long *stack_out, int stack_order) 122 unsigned long *stack_out, int stack_order)
123{ 123{
124 unsigned long stack, sp; 124 unsigned long stack, sp;
125 int pid, status; 125 int pid, status, err;
126 126
127 stack = alloc_stack(stack_order, um_in_interrupt()); 127 stack = alloc_stack(stack_order, um_in_interrupt());
128 if(stack == 0) return(-ENOMEM); 128 if(stack == 0) return(-ENOMEM);
@@ -130,16 +130,18 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
130 sp = stack + (page_size() << stack_order) - sizeof(void *); 130 sp = stack + (page_size() << stack_order) - sizeof(void *);
131 pid = clone(proc, (void *) sp, flags | SIGCHLD, arg); 131 pid = clone(proc, (void *) sp, flags | SIGCHLD, arg);
132 if(pid < 0){ 132 if(pid < 0){
133 err = -errno;
133 printk("run_helper_thread : clone failed, errno = %d\n", 134 printk("run_helper_thread : clone failed, errno = %d\n",
134 errno); 135 errno);
135 return(-errno); 136 return err;
136 } 137 }
137 if(stack_out == NULL){ 138 if(stack_out == NULL){
138 CATCH_EINTR(pid = waitpid(pid, &status, 0)); 139 CATCH_EINTR(pid = waitpid(pid, &status, 0));
139 if(pid < 0){ 140 if(pid < 0){
141 err = -errno;
140 printk("run_helper_thread - wait failed, errno = %d\n", 142 printk("run_helper_thread - wait failed, errno = %d\n",
141 errno); 143 errno);
142 pid = -errno; 144 pid = err;
143 } 145 }
144 if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) 146 if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0))
145 printk("run_helper_thread - thread returned status " 147 printk("run_helper_thread - thread returned status "
@@ -156,8 +158,8 @@ int helper_wait(int pid)
156 158
157 CATCH_EINTR(ret = waitpid(pid, NULL, WNOHANG)); 159 CATCH_EINTR(ret = waitpid(pid, NULL, WNOHANG));
158 if(ret < 0){ 160 if(ret < 0){
161 ret = -errno;
159 printk("helper_wait : waitpid failed, errno = %d\n", errno); 162 printk("helper_wait : waitpid failed, errno = %d\n", errno);
160 return(-errno);
161 } 163 }
162 return(ret); 164 return(ret);
163} 165}
diff --git a/arch/um/kernel/user_util.c b/arch/um/kernel/user_util.c
index 954ff67cc8b3..a25f3ea11fd7 100644
--- a/arch/um/kernel/user_util.c
+++ b/arch/um/kernel/user_util.c
@@ -109,18 +109,14 @@ int raw(int fd)
109 int err; 109 int err;
110 110
111 CATCH_EINTR(err = tcgetattr(fd, &tt)); 111 CATCH_EINTR(err = tcgetattr(fd, &tt));
112 if (err < 0) { 112 if(err < 0)
113 printk("tcgetattr failed, errno = %d\n", errno); 113 return -errno;
114 return(-errno);
115 }
116 114
117 cfmakeraw(&tt); 115 cfmakeraw(&tt);
118 116
119 CATCH_EINTR(err = tcsetattr(fd, TCSADRAIN, &tt)); 117 CATCH_EINTR(err = tcsetattr(fd, TCSADRAIN, &tt));
120 if (err < 0) { 118 if(err < 0)
121 printk("tcsetattr failed, errno = %d\n", errno); 119 return -errno;
122 return(-errno);
123 }
124 120
125 /* XXX tcsetattr could have applied only some changes 121 /* XXX tcsetattr could have applied only some changes
126 * (and cfmakeraw() is a set of changes) */ 122 * (and cfmakeraw() is a set of changes) */