1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) 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 } 76