Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
xterm_kern.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3  * Licensed under the GPL
4  */
5 
6 #include <linux/slab.h>
7 #include <linux/completion.h>
8 #include <linux/irqreturn.h>
9 #include <asm/irq.h>
10 #include <irq_kern.h>
11 #include <os.h>
12 
13 struct xterm_wait {
14  struct completion ready;
15  int fd;
16  int pid;
17  int new_fd;
18 };
19 
20 static irqreturn_t xterm_interrupt(int irq, void *data)
21 {
22  struct xterm_wait *xterm = data;
23  int fd;
24 
25  fd = os_rcv_fd(xterm->fd, &xterm->pid);
26  if (fd == -EAGAIN)
27  return IRQ_NONE;
28 
29  xterm->new_fd = fd;
30  complete(&xterm->ready);
31 
32  return IRQ_HANDLED;
33 }
34 
35 int xterm_fd(int socket, int *pid_out)
36 {
37  struct xterm_wait *data;
38  int err, ret;
39 
40  data = kmalloc(sizeof(*data), GFP_KERNEL);
41  if (data == NULL) {
42  printk(KERN_ERR "xterm_fd : failed to allocate xterm_wait\n");
43  return -ENOMEM;
44  }
45 
46  /* This is a locked semaphore... */
47  *data = ((struct xterm_wait) { .fd = socket,
48  .pid = -1,
49  .new_fd = -1 });
50  init_completion(&data->ready);
51 
52  err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt,
53  IRQF_SHARED, "xterm", data);
54  if (err) {
55  printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, "
56  "err = %d\n", err);
57  ret = err;
58  goto out;
59  }
60 
61  /* ... so here we wait for an xterm interrupt.
62  *
63  * XXX Note, if the xterm doesn't work for some reason (eg. DISPLAY
64  * isn't set) this will hang... */
65  wait_for_completion(&data->ready);
66 
67  um_free_irq(XTERM_IRQ, data);
68 
69  ret = data->new_fd;
70  *pid_out = data->pid;
71  out:
72  kfree(data);
73 
74  return ret;
75 }