diff options
-rw-r--r-- | arch/um/os-Linux/sigio.c | 38 |
1 files changed, 20 insertions, 18 deletions
diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c index 925a65240cfe..b2e1fd8e3571 100644 --- a/arch/um/os-Linux/sigio.c +++ b/arch/um/os-Linux/sigio.c | |||
@@ -97,20 +97,22 @@ static int write_sigio_thread(void *unused) | |||
97 | 97 | ||
98 | static int need_poll(struct pollfds *polls, int n) | 98 | static int need_poll(struct pollfds *polls, int n) |
99 | { | 99 | { |
100 | if(n <= polls->size){ | 100 | struct pollfd *new; |
101 | polls->used = n; | 101 | |
102 | if(n <= polls->size) | ||
102 | return 0; | 103 | return 0; |
103 | } | 104 | |
104 | kfree(polls->poll); | 105 | new = um_kmalloc_atomic(n * sizeof(struct pollfd)); |
105 | polls->poll = um_kmalloc_atomic(n * sizeof(struct pollfd)); | 106 | if(new == NULL){ |
106 | if(polls->poll == NULL){ | ||
107 | printk("need_poll : failed to allocate new pollfds\n"); | 107 | printk("need_poll : failed to allocate new pollfds\n"); |
108 | polls->size = 0; | ||
109 | polls->used = 0; | ||
110 | return -ENOMEM; | 108 | return -ENOMEM; |
111 | } | 109 | } |
110 | |||
111 | memcpy(new, polls->poll, polls->used * sizeof(struct pollfd)); | ||
112 | kfree(polls->poll); | ||
113 | |||
114 | polls->poll = new; | ||
112 | polls->size = n; | 115 | polls->size = n; |
113 | polls->used = n; | ||
114 | return 0; | 116 | return 0; |
115 | } | 117 | } |
116 | 118 | ||
@@ -171,15 +173,15 @@ int add_sigio_fd(int fd) | |||
171 | goto out; | 173 | goto out; |
172 | } | 174 | } |
173 | 175 | ||
174 | n = current_poll.used + 1; | 176 | n = current_poll.used; |
175 | err = need_poll(&next_poll, n); | 177 | err = need_poll(&next_poll, n + 1); |
176 | if(err) | 178 | if(err) |
177 | goto out; | 179 | goto out; |
178 | 180 | ||
179 | for(i = 0; i < current_poll.used; i++) | 181 | memcpy(next_poll.poll, current_poll.poll, |
180 | next_poll.poll[i] = current_poll.poll[i]; | 182 | current_poll.used * sizeof(struct pollfd)); |
181 | 183 | next_poll.poll[n] = *p; | |
182 | next_poll.poll[n - 1] = *p; | 184 | next_poll.used = n + 1; |
183 | update_thread(); | 185 | update_thread(); |
184 | out: | 186 | out: |
185 | sigio_unlock(); | 187 | sigio_unlock(); |
@@ -214,6 +216,7 @@ int ignore_sigio_fd(int fd) | |||
214 | if(p->fd != fd) | 216 | if(p->fd != fd) |
215 | next_poll.poll[n++] = *p; | 217 | next_poll.poll[n++] = *p; |
216 | } | 218 | } |
219 | next_poll.used = current_poll.used - 1; | ||
217 | 220 | ||
218 | update_thread(); | 221 | update_thread(); |
219 | out: | 222 | out: |
@@ -331,10 +334,9 @@ void maybe_sigio_broken(int fd, int read) | |||
331 | 334 | ||
332 | sigio_lock(); | 335 | sigio_lock(); |
333 | err = need_poll(&all_sigio_fds, all_sigio_fds.used + 1); | 336 | err = need_poll(&all_sigio_fds, all_sigio_fds.used + 1); |
334 | if(err){ | 337 | if(err) |
335 | printk("maybe_sigio_broken - failed to add pollfd\n"); | ||
336 | goto out; | 338 | goto out; |
337 | } | 339 | |
338 | all_sigio_fds.poll[all_sigio_fds.used++] = | 340 | all_sigio_fds.poll[all_sigio_fds.used++] = |
339 | ((struct pollfd) { .fd = fd, | 341 | ((struct pollfd) { .fd = fd, |
340 | .events = read ? POLLIN : POLLOUT, | 342 | .events = read ? POLLIN : POLLOUT, |