summary refs log tree commit diff
path: root/arch/um/drivers/xterm_kern.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 15:20:36 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 15:20:36 -0700
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/um/drivers/xterm_kern.c
downloadlinux-1da177e4c3f41524e886b7f1b8a0c1fc7321cac2.tar.gz
Linux-2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.

Let it rip!
Diffstat (limited to 'arch/um/drivers/xterm_kern.c')
-rw-r--r--arch/um/drivers/xterm_kern.c93
1 files changed, 93 insertions, 0 deletions
diff --git a/arch/um/drivers/xterm_kern.c b/arch/um/drivers/xterm_kern.c
new file mode 100644
index 000000000000..7917b9d1cec8
--- /dev/null
+++ b/arch/um/drivers/xterm_kern.c
@@ -0,0 +1,93 @@
+/* 
+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#include "linux/errno.h"
+#include "linux/slab.h"
+#include "linux/signal.h"
+#include "linux/interrupt.h"
+#include "asm/semaphore.h"
+#include "asm/irq.h"
+#include "irq_user.h"
+#include "irq_kern.h"
+#include "kern_util.h"
+#include "os.h"
+#include "xterm.h"
+
+struct xterm_wait {
+	struct completion ready;
+	int fd;
+	int pid;
+	int new_fd;
+};
+
+static irqreturn_t xterm_interrupt(int irq, void *data, struct pt_regs *regs)
+{
+	struct xterm_wait *xterm = data;
+	int fd;
+
+	fd = os_rcv_fd(xterm->fd, &xterm->pid);
+	if(fd == -EAGAIN)
+		return(IRQ_NONE);
+
+	xterm->new_fd = fd;
+	complete(&xterm->ready);
+	return(IRQ_HANDLED);
+}
+
+int xterm_fd(int socket, int *pid_out)
+{
+	struct xterm_wait *data;
+	int err, ret;
+
+	data = kmalloc(sizeof(*data), GFP_KERNEL);
+	if(data == NULL){
+		printk(KERN_ERR "xterm_fd : failed to allocate xterm_wait\n");
+		return(-ENOMEM);
+	}
+
+	/* This is a locked semaphore... */
+	*data = ((struct xterm_wait) 
+		{ .fd 		= socket,
+		  .pid 		= -1,
+		  .new_fd 	= -1 });
+	init_completion(&data->ready);
+
+	err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt, 
+			     SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, 
+			     "xterm", data);
+	if (err){
+		printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, "
+		       "err = %d\n",  err);
+		ret = err;
+		goto out;
+	}
+
+	/* ... so here we wait for an xterm interrupt.
+	 *
+	 * XXX Note, if the xterm doesn't work for some reason (eg. DISPLAY
+	 * isn't set) this will hang... */
+	wait_for_completion(&data->ready);
+
+	free_irq_by_irq_and_dev(XTERM_IRQ, data);
+	free_irq(XTERM_IRQ, data);
+
+	ret = data->new_fd;
+	*pid_out = data->pid;
+ out:
+	kfree(data);
+
+	return(ret);
+}
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only.  This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-file-style: "linux"
+ * End:
+ */