Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.19-rc4 152 lines 3.4 kB view raw
1/* 2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) 3 * Licensed under the GPL 4 */ 5 6#include <stdlib.h> 7#include <unistd.h> 8#include <errno.h> 9#include <signal.h> 10#include <string.h> 11#include <sys/poll.h> 12#include <sys/types.h> 13#include <sys/time.h> 14#include "user_util.h" 15#include "kern_util.h" 16#include "user.h" 17#include "process.h" 18#include "sigio.h" 19#include "irq_user.h" 20#include "os.h" 21#include "um_malloc.h" 22 23static struct pollfd *pollfds = NULL; 24static int pollfds_num = 0; 25static int pollfds_size = 0; 26 27int os_waiting_for_events(struct irq_fd *active_fds) 28{ 29 struct irq_fd *irq_fd; 30 int i, n, err; 31 32 n = poll(pollfds, pollfds_num, 0); 33 if (n < 0) { 34 err = -errno; 35 if (errno != EINTR) 36 printk("sigio_handler: os_waiting_for_events:" 37 " poll returned %d, errno = %d\n", n, errno); 38 return err; 39 } 40 41 if (n == 0) 42 return 0; 43 44 irq_fd = active_fds; 45 46 for (i = 0; i < pollfds_num; i++) { 47 if (pollfds[i].revents != 0) { 48 irq_fd->current_events = pollfds[i].revents; 49 pollfds[i].fd = -1; 50 } 51 irq_fd = irq_fd->next; 52 } 53 return n; 54} 55 56int os_create_pollfd(int fd, int events, void *tmp_pfd, int size_tmpfds) 57{ 58 if (pollfds_num == pollfds_size) { 59 if (size_tmpfds <= pollfds_size * sizeof(pollfds[0])) { 60 /* return min size needed for new pollfds area */ 61 return((pollfds_size + 1) * sizeof(pollfds[0])); 62 } 63 64 if (pollfds != NULL) { 65 memcpy(tmp_pfd, pollfds, 66 sizeof(pollfds[0]) * pollfds_size); 67 /* remove old pollfds */ 68 kfree(pollfds); 69 } 70 pollfds = tmp_pfd; 71 pollfds_size++; 72 } else 73 kfree(tmp_pfd); /* remove not used tmp_pfd */ 74 75 pollfds[pollfds_num] = ((struct pollfd) { .fd = fd, 76 .events = events, 77 .revents = 0 }); 78 pollfds_num++; 79 80 return 0; 81} 82 83void os_free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg, 84 struct irq_fd *active_fds, struct irq_fd ***last_irq_ptr2) 85{ 86 struct irq_fd **prev; 87 int i = 0; 88 89 prev = &active_fds; 90 while (*prev != NULL) { 91 if ((*test)(*prev, arg)) { 92 struct irq_fd *old_fd = *prev; 93 if ((pollfds[i].fd != -1) && 94 (pollfds[i].fd != (*prev)->fd)) { 95 printk("os_free_irq_by_cb - mismatch between " 96 "active_fds and pollfds, fd %d vs %d\n", 97 (*prev)->fd, pollfds[i].fd); 98 goto out; 99 } 100 101 pollfds_num--; 102 103 /* This moves the *whole* array after pollfds[i] 104 * (though it doesn't spot as such)! 105 */ 106 memmove(&pollfds[i], &pollfds[i + 1], 107 (pollfds_num - i) * sizeof(pollfds[0])); 108 if(*last_irq_ptr2 == &old_fd->next) 109 *last_irq_ptr2 = prev; 110 111 *prev = (*prev)->next; 112 if(old_fd->type == IRQ_WRITE) 113 ignore_sigio_fd(old_fd->fd); 114 kfree(old_fd); 115 continue; 116 } 117 prev = &(*prev)->next; 118 i++; 119 } 120 out: 121 return; 122} 123 124int os_get_pollfd(int i) 125{ 126 return pollfds[i].fd; 127} 128 129void os_set_pollfd(int i, int fd) 130{ 131 pollfds[i].fd = fd; 132} 133 134void os_set_ioignore(void) 135{ 136 signal(SIGIO, SIG_IGN); 137} 138 139void init_irq_signals(int on_sigstack) 140{ 141 int flags; 142 143 flags = on_sigstack ? SA_ONSTACK : 0; 144 145 set_handler(SIGVTALRM, (__sighandler_t) alarm_handler, 146 flags | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1); 147 set_handler(SIGALRM, (__sighandler_t) alarm_handler, 148 flags | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1); 149 set_handler(SIGIO, (__sighandler_t) sig_handler, flags | SA_RESTART, 150 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); 151 signal(SIGWINCH, SIG_IGN); 152}