11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 31da177e4SLinus Torvalds * Licensed under the GPL 41da177e4SLinus Torvalds */ 51da177e4SLinus Torvalds 61da177e4SLinus Torvalds #include "linux/errno.h" 71da177e4SLinus Torvalds #include "linux/slab.h" 81da177e4SLinus Torvalds #include "linux/signal.h" 91da177e4SLinus Torvalds #include "linux/interrupt.h" 101da177e4SLinus Torvalds #include "asm/irq.h" 111da177e4SLinus Torvalds #include "irq_user.h" 121da177e4SLinus Torvalds #include "irq_kern.h" 131da177e4SLinus Torvalds #include "kern_util.h" 141da177e4SLinus Torvalds #include "os.h" 151da177e4SLinus Torvalds #include "xterm.h" 161da177e4SLinus Torvalds 171da177e4SLinus Torvalds struct xterm_wait { 181da177e4SLinus Torvalds struct completion ready; 191da177e4SLinus Torvalds int fd; 201da177e4SLinus Torvalds int pid; 211da177e4SLinus Torvalds int new_fd; 221da177e4SLinus Torvalds }; 231da177e4SLinus Torvalds 24*7bea96fdSAl Viro static irqreturn_t xterm_interrupt(int irq, void *data) 251da177e4SLinus Torvalds { 261da177e4SLinus Torvalds struct xterm_wait *xterm = data; 271da177e4SLinus Torvalds int fd; 281da177e4SLinus Torvalds 291da177e4SLinus Torvalds fd = os_rcv_fd(xterm->fd, &xterm->pid); 301da177e4SLinus Torvalds if(fd == -EAGAIN) 311da177e4SLinus Torvalds return(IRQ_NONE); 321da177e4SLinus Torvalds 331da177e4SLinus Torvalds xterm->new_fd = fd; 341da177e4SLinus Torvalds complete(&xterm->ready); 351da177e4SLinus Torvalds return(IRQ_HANDLED); 361da177e4SLinus Torvalds } 371da177e4SLinus Torvalds 381da177e4SLinus Torvalds int xterm_fd(int socket, int *pid_out) 391da177e4SLinus Torvalds { 401da177e4SLinus Torvalds struct xterm_wait *data; 411da177e4SLinus Torvalds int err, ret; 421da177e4SLinus Torvalds 431da177e4SLinus Torvalds data = kmalloc(sizeof(*data), GFP_KERNEL); 441da177e4SLinus Torvalds if(data == NULL){ 451da177e4SLinus Torvalds printk(KERN_ERR "xterm_fd : failed to allocate xterm_wait\n"); 461da177e4SLinus Torvalds return(-ENOMEM); 471da177e4SLinus Torvalds } 481da177e4SLinus Torvalds 491da177e4SLinus Torvalds /* This is a locked semaphore... */ 501da177e4SLinus Torvalds *data = ((struct xterm_wait) 511da177e4SLinus Torvalds { .fd = socket, 521da177e4SLinus Torvalds .pid = -1, 531da177e4SLinus Torvalds .new_fd = -1 }); 541da177e4SLinus Torvalds init_completion(&data->ready); 551da177e4SLinus Torvalds 561da177e4SLinus Torvalds err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt, 57bd6aa650SThomas Gleixner IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM, 581da177e4SLinus Torvalds "xterm", data); 591da177e4SLinus Torvalds if (err){ 601da177e4SLinus Torvalds printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, " 611da177e4SLinus Torvalds "err = %d\n", err); 621da177e4SLinus Torvalds ret = err; 631da177e4SLinus Torvalds goto out; 641da177e4SLinus Torvalds } 651da177e4SLinus Torvalds 661da177e4SLinus Torvalds /* ... so here we wait for an xterm interrupt. 671da177e4SLinus Torvalds * 681da177e4SLinus Torvalds * XXX Note, if the xterm doesn't work for some reason (eg. DISPLAY 691da177e4SLinus Torvalds * isn't set) this will hang... */ 701da177e4SLinus Torvalds wait_for_completion(&data->ready); 711da177e4SLinus Torvalds 721da177e4SLinus Torvalds free_irq(XTERM_IRQ, data); 731da177e4SLinus Torvalds 741da177e4SLinus Torvalds ret = data->new_fd; 751da177e4SLinus Torvalds *pid_out = data->pid; 761da177e4SLinus Torvalds out: 771da177e4SLinus Torvalds kfree(data); 781da177e4SLinus Torvalds 791da177e4SLinus Torvalds return(ret); 801da177e4SLinus Torvalds } 811da177e4SLinus Torvalds 821da177e4SLinus Torvalds /* 831da177e4SLinus Torvalds * Overrides for Emacs so that we follow Linus's tabbing style. 841da177e4SLinus Torvalds * Emacs will notice this stuff at the end of the file and automatically 851da177e4SLinus Torvalds * adjust the settings for this buffer only. This must remain at the end 861da177e4SLinus Torvalds * of the file. 871da177e4SLinus Torvalds * --------------------------------------------------------------------------- 881da177e4SLinus Torvalds * Local variables: 891da177e4SLinus Torvalds * c-file-style: "linux" 901da177e4SLinus Torvalds * End: 911da177e4SLinus Torvalds */ 92