| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) | 
|  | 3 | * Licensed under the GPL | 
|  | 4 | */ | 
|  | 5 |  | 
|  | 6 | #include "linux/errno.h" | 
|  | 7 | #include "linux/slab.h" | 
|  | 8 | #include "linux/signal.h" | 
|  | 9 | #include "linux/interrupt.h" | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 10 | #include "asm/irq.h" | 
|  | 11 | #include "irq_user.h" | 
|  | 12 | #include "irq_kern.h" | 
|  | 13 | #include "kern_util.h" | 
|  | 14 | #include "os.h" | 
|  | 15 | #include "xterm.h" | 
|  | 16 |  | 
|  | 17 | struct xterm_wait { | 
|  | 18 | struct completion ready; | 
|  | 19 | int fd; | 
|  | 20 | int pid; | 
|  | 21 | int new_fd; | 
|  | 22 | }; | 
|  | 23 |  | 
|  | 24 | static irqreturn_t xterm_interrupt(int irq, void *data, struct pt_regs *regs) | 
|  | 25 | { | 
|  | 26 | struct xterm_wait *xterm = data; | 
|  | 27 | int fd; | 
|  | 28 |  | 
|  | 29 | fd = os_rcv_fd(xterm->fd, &xterm->pid); | 
|  | 30 | if(fd == -EAGAIN) | 
|  | 31 | return(IRQ_NONE); | 
|  | 32 |  | 
|  | 33 | xterm->new_fd = fd; | 
|  | 34 | complete(&xterm->ready); | 
|  | 35 | return(IRQ_HANDLED); | 
|  | 36 | } | 
|  | 37 |  | 
|  | 38 | int xterm_fd(int socket, int *pid_out) | 
|  | 39 | { | 
|  | 40 | struct xterm_wait *data; | 
|  | 41 | int err, ret; | 
|  | 42 |  | 
|  | 43 | data = kmalloc(sizeof(*data), GFP_KERNEL); | 
|  | 44 | if(data == NULL){ | 
|  | 45 | printk(KERN_ERR "xterm_fd : failed to allocate xterm_wait\n"); | 
|  | 46 | return(-ENOMEM); | 
|  | 47 | } | 
|  | 48 |  | 
|  | 49 | /* This is a locked semaphore... */ | 
|  | 50 | *data = ((struct xterm_wait) | 
|  | 51 | { .fd 		= socket, | 
|  | 52 | .pid 		= -1, | 
|  | 53 | .new_fd 	= -1 }); | 
|  | 54 | init_completion(&data->ready); | 
|  | 55 |  | 
|  | 56 | err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt, | 
|  | 57 | SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, | 
|  | 58 | "xterm", data); | 
|  | 59 | if (err){ | 
|  | 60 | printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, " | 
|  | 61 | "err = %d\n",  err); | 
|  | 62 | ret = err; | 
|  | 63 | goto out; | 
|  | 64 | } | 
|  | 65 |  | 
|  | 66 | /* ... so here we wait for an xterm interrupt. | 
|  | 67 | * | 
|  | 68 | * XXX Note, if the xterm doesn't work for some reason (eg. DISPLAY | 
|  | 69 | * isn't set) this will hang... */ | 
|  | 70 | wait_for_completion(&data->ready); | 
|  | 71 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 72 | free_irq(XTERM_IRQ, data); | 
|  | 73 |  | 
|  | 74 | ret = data->new_fd; | 
|  | 75 | *pid_out = data->pid; | 
|  | 76 | out: | 
|  | 77 | kfree(data); | 
|  | 78 |  | 
|  | 79 | return(ret); | 
|  | 80 | } | 
|  | 81 |  | 
|  | 82 | /* | 
|  | 83 | * Overrides for Emacs so that we follow Linus's tabbing style. | 
|  | 84 | * Emacs will notice this stuff at the end of the file and automatically | 
|  | 85 | * adjust the settings for this buffer only.  This must remain at the end | 
|  | 86 | * of the file. | 
|  | 87 | * --------------------------------------------------------------------------- | 
|  | 88 | * Local variables: | 
|  | 89 | * c-file-style: "linux" | 
|  | 90 | * End: | 
|  | 91 | */ |