--- linux/fs/fcntl.c.sigio      Sat Jan 15 12:51:24 2000
+++ linux/fs/fcntl.c    Sat Jan 15 12:52:19 2000
@@ -8,6 +8,8 @@
#include <linux/file.h>
#include <linux/smp_lock.h>

+#include <asm/poll.h>
+#include <asm/siginfo.h>
#include <asm/uaccess.h>

extern int sock_fcntl (struct file *, unsigned int cmd, unsigned long arg);
@@ -236,7 +238,20 @@
       return err;
}

-static void send_sigio(struct fown_struct *fown, struct fasync_struct *fa)
+/* Table to convert sigio signal codes into poll band bitmaps */
+
+static int band_table[NSIGPOLL+1] = {
+       ~0,
+       POLLIN | POLLRDNORM,                    /* POLL_IN */
+       POLLOUT | POLLWRNORM | POLLWRBAND,      /* POLL_OUT */
+       POLLIN | POLLRDNORM | POLLMSG,          /* POLL_MSG */
+       POLLERR,                                /* POLL_ERR */
+       POLLPRI | POLLRDBAND,                   /* POLL_PRI */
+       POLLHUP | POLLERR                       /* POLL_HUP */
+};
+
+static void send_sigio(struct fown_struct *fown, struct fasync_struct *fa,
+       int reason)
{
       struct task_struct * p;
       int   pid       = fown->pid;
@@ -265,9 +280,11 @@
                          back to SIGIO in that case. --sct */
                       si.si_signo = fown->signum;
                       si.si_errno = 0;
-                       si.si_code  = SI_SIGIO;
-                       si.si_pid   = pid;
-                       si.si_uid   = uid;
+                        si.si_code  = reason;
+                        if (reason < 0 || reason > NSIGPOLL)
+                                si.si_band  = ~0;
+                        else
+                                si.si_band = band_table[reason];
                       si.si_fd    = fa->fa_fd;
                       if (!send_sig_info(fown->signum, &si, p))
                               break;
@@ -279,7 +296,7 @@
       read_unlock(&tasklist_lock);
}

-void kill_fasync(struct fasync_struct *fa, int sig)
+void kill_fasync(struct fasync_struct *fa, int sig, int band)
{
       while (fa) {
               struct fown_struct * fown;
@@ -289,8 +306,11 @@
                       return;
               }
               fown = &fa->fa_file->f_owner;
-               if (fown->pid)
-                       send_sigio(fown, fa);
+               /* Don't send SIGURG to processes which have not set a
+                  queued signum: SIGURG has its own default signalling
+                  mechanism. */
+               if (fown->pid && !(sig == SIGURG && fown->signum == 0))
+                       send_sigio(fown, fa, band);
               fa = fa->fa_next;
       }
}
--- linux/include/linux/fs.h.sigio      Sat Jan 15 12:51:24 2000
+++ linux/include/linux/fs.h    Sat Jan 15 12:52:19 2000
@@ -730,7 +730,7 @@
#define __getname()    ((char *) __get_free_page(GFP_KERNEL))
#define putname(name)  free_page((unsigned long)(name))

-extern void kill_fasync(struct fasync_struct *fa, int sig);
+extern void kill_fasync(struct fasync_struct *fa, int sig, int band);
extern int register_blkdev(unsigned int, const char *, struct file_operations *);
extern int unregister_blkdev(unsigned int major, const char * name);
extern int blkdev_open(struct inode * inode, struct file * filp);
--- linux/include/linux/net.h.sigio     Thu Apr 15 19:28:55 1999
+++ linux/include/linux/net.h   Sat Jan 15 12:52:19 2000
@@ -126,7 +126,7 @@
};

extern struct net_proto_family *net_families[];
-extern int     sock_wake_async(struct socket *sk, int how);
+extern int     sock_wake_async(struct socket *sk, int how, int band);
extern int     sock_register(struct net_proto_family *fam);
extern int     sock_unregister(int family);
extern struct socket *sock_alloc(void);
--- linux/net/unix/af_unix.c.sigio      Mon Aug  9 15:05:10 1999
+++ linux/net/unix/af_unix.c    Sat Jan 15 12:52:19 2000
@@ -1515,7 +1515,7 @@
               return;
       wake_up_interruptible(sk->sleep);
       if (sk->sndbuf - (int)atomic_read(&sk->wmem_alloc) >= MIN_WRITE_SPACE)
-               sock_wake_async(sk->socket, 2);
+               sock_wake_async(sk->socket, 2, POLL_OUT);
}

#ifdef CONFIG_PROC_FS
--- linux/net/core/sock.c.sigio Mon May 10 12:55:25 1999
+++ linux/net/core/sock.c       Sat Jan 15 12:52:19 2000
@@ -982,7 +982,7 @@
{
       if (!sk->dead) {
               wake_up_interruptible(sk->sleep);
-               sock_wake_async(sk->socket,0);
+               sock_wake_async(sk->socket,0,POLL_ERR);
       }
}

@@ -990,7 +990,7 @@
{
       if(!sk->dead) {
               wake_up_interruptible(sk->sleep);
-               sock_wake_async(sk->socket,1);
+               sock_wake_async(sk->socket,1,POLL_IN);
       }
}

@@ -1005,7 +1005,7 @@

               /* Should agree with poll, otherwise some programs break */
               if (sock_writeable(sk))
-                       sock_wake_async(sk->socket, 2);
+                       sock_wake_async(sk->socket, 2, POLL_OUT);
       }
}

--- linux/net/ipv4/tcp.c.sigio  Tue Jan  4 13:12:26 2000
+++ linux/net/ipv4/tcp.c        Sat Jan 15 12:52:19 2000
@@ -615,7 +615,7 @@
       wake_up_interruptible(sk->sleep);
       if (sock_wspace(sk) >=
           tcp_min_write_space(sk))
-               sock_wake_async(sk->socket, 2);
+               sock_wake_async(sk->socket, 2, POLL_OUT);
}


--- linux/net/ipv4/tcp_input.c.sigio    Tue Jan  4 13:12:27 2000
+++ linux/net/ipv4/tcp_input.c  Sat Jan 15 12:52:19 2000
@@ -1131,7 +1131,7 @@

       if (!sk->dead) {
               sk->state_change(sk);
-               sock_wake_async(sk->socket, 1);
+               sock_wake_async(sk->socket, 1, POLL_HUP);
       }

       switch(sk->state) {
@@ -1669,6 +1669,7 @@
                       kill_proc(sk->proc, SIGURG, 1);
               else
                       kill_pg(-sk->proc, SIGURG, 1);
+               sock_wake_async(sk->socket, 3, POLL_PRI);
       }

       /* We may be adding urgent data when the last byte read was
@@ -2213,7 +2214,7 @@

                       if(!sk->dead) {
                               sk->state_change(sk);
-                               sock_wake_async(sk->socket, 0);
+                               sock_wake_async(sk->socket, 0, POLL_OUT);
                       }
               } else {
                       if(th->syn && !th->rst) {
--- linux/net/socket.c.sigio    Thu Apr 22 22:45:20 1999
+++ linux/net/socket.c  Sat Jan 15 12:52:19 2000
@@ -544,7 +544,7 @@
       return 0;
}

-int sock_wake_async(struct socket *sock, int how)
+int sock_wake_async(struct socket *sock, int how, int band)
{
       if (!sock || !sock->fasync_list)
               return -1;
@@ -561,8 +561,10 @@
               /* fall through */
       case 0:
       call_kill:
-               kill_fasync(sock->fasync_list, SIGIO);
+               kill_fasync(sock->fasync_list, SIGIO, band);
               break;
+       case 3:
+               kill_fasync(sock->fasync_list, SIGURG, band);
       }
       return 0;
}
--- linux/drivers/net/ppp.c.sigio       Tue Oct 26 20:53:40 1999
+++ linux/drivers/net/ppp.c     Sat Jan 15 12:52:19 2000
@@ -2372,7 +2372,7 @@

       wake_up_interruptible (&ppp->read_wait);
       if (ppp->tty->fasync != NULL)
-               kill_fasync (ppp->tty->fasync, SIGIO);
+               kill_fasync (ppp->tty->fasync, SIGIO, POLL_IN);

       return 1;
}
--- linux/drivers/net/sk_mca.h.sigio    Mon Jun  7 17:34:54 1999
+++ linux/drivers/net/sk_mca.h  Sat Jan 15 12:52:19 2000
@@ -168,7 +168,7 @@

#endif /* _SK_MCA_DRIVER_ */

-extern int skmca_probe(struct device *);
+extern int skmca_probe(struct net_device *);


#endif /* _SK_MCA_INCLUDE_ */
--- linux/drivers/char/busmouse.c.sigio Tue Jan  4 13:12:14 2000
+++ linux/drivers/char/busmouse.c       Sat Jan 15 12:52:19 2000
@@ -105,7 +105,7 @@
             mouse.dy =  2048;

         if (mouse.fasyncptr)
-             kill_fasync(mouse.fasyncptr, SIGIO);
+             kill_fasync(mouse.fasyncptr, SIGIO, POLL_IN);
       }
       MSE_INT_ON();
}
--- linux/drivers/char/dn_keyb.c.sigio  Mon Apr 26 16:28:07 1999
+++ linux/drivers/char/dn_keyb.c        Sat Jan 15 12:52:19 2000
@@ -468,7 +468,7 @@
                       if (mouse_dy >  2048)
                       mouse_dy =  2048;
                               if (mouse_fasyncptr)
-                       kill_fasync(mouse_fasyncptr, SIGIO);
+                       kill_fasync(mouse_fasyncptr, SIGIO, POLL_IN);
                       }
                       mouse_byte_count=0;
/*                     printk("mouse: %d, %d, %x\n",mouse_x,mouse_y,buttons); */
--- linux/drivers/char/n_hdlc.c.sigio   Tue Oct 26 20:53:40 1999
+++ linux/drivers/char/n_hdlc.c Sat Jan 15 12:52:19 2000
@@ -660,7 +660,7 @@
       /* wake up any blocked reads and perform async signalling */
       wake_up_interruptible (&n_hdlc->read_wait);
       if (n_hdlc->tty->fasync != NULL)
-               kill_fasync (n_hdlc->tty->fasync, SIGIO);
+               kill_fasync (n_hdlc->tty->fasync, SIGIO, POLL_IN);

}      /* end of n_hdlc_tty_receive() */

--- linux/drivers/char/n_tty.c.sigio    Tue Oct 26 20:53:40 1999
+++ linux/drivers/char/n_tty.c  Sat Jan 15 12:52:19 2000
@@ -604,7 +604,7 @@
                       tty->canon_head = tty->read_head;
                       tty->canon_data++;
                       if (tty->fasync)
-                               kill_fasync(tty->fasync, SIGIO);
+                               kill_fasync(tty->fasync, SIGIO, POLL_IN);
                       if (tty->read_wait)
                               wake_up_interruptible(&tty->read_wait);
                       return;
@@ -706,7 +706,7 @@

       if (!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) {
               if (tty->fasync)
-                       kill_fasync(tty->fasync, SIGIO);
+                       kill_fasync(tty->fasync, SIGIO, POLL_IN);
               if (tty->read_wait)
                       wake_up_interruptible(&tty->read_wait);
       }
--- linux/drivers/char/pc_keyb.c.sigio  Mon Aug  9 15:04:39 1999
+++ linux/drivers/char/pc_keyb.c        Sat Jan 15 12:52:19 2000
@@ -403,7 +403,7 @@
               if (head != queue->tail) {
                       queue->head = head;
                       if (queue->fasync)
-                               kill_fasync(queue->fasync, SIGIO);
+                               kill_fasync(queue->fasync, SIGIO, POLL_IN);
                       wake_up_interruptible(&queue->proc_list);
               }
       }
--- linux/drivers/char/atixlmouse.c.sigio       Mon Aug 24 16:02:43 1998
+++ linux/drivers/char/atixlmouse.c     Sat Jan 15 12:52:19 2000
@@ -90,7 +90,7 @@
               mouse.ready = 1;
               wake_up_interruptible(&mouse.wait);
               if (mouse.fasync)
-                       kill_fasync(mouse.fasync, SIGIO);
+                       kill_fasync(mouse.fasync, SIGIO, POLL_IN);
       }
       ATIXL_MSE_ENABLE_UPDATE();
}
--- linux/drivers/char/adbmouse.c.sigio Thu Apr 29 15:53:48 1999
+++ linux/drivers/char/adbmouse.c       Sat Jan 15 12:52:19 2000
@@ -134,7 +134,7 @@
    mouse.ready = 1;
    wake_up_interruptible(&mouse.wait);
    if (mouse.fasyncptr)
-       kill_fasync(mouse.fasyncptr, SIGIO);
+       kill_fasync(mouse.fasyncptr, SIGIO, POLL_IN);
}

static int fasync_mouse(int fd, struct file *filp, int on)
--- linux/drivers/char/amigamouse.c.sigio       Mon Aug 24 16:02:43 1998
+++ linux/drivers/char/amigamouse.c     Sat Jan 15 12:52:19 2000
@@ -154,7 +154,7 @@
             mouse.dy =  2048;

         if (mouse.fasyncptr)
-             kill_fasync(mouse.fasyncptr, SIGIO);
+             kill_fasync(mouse.fasyncptr, SIGIO, POLL_IN);
       }
       AMI_MSE_INT_ON();
}
--- linux/drivers/char/atarimouse.c.sigio       Mon Aug 24 16:02:43 1998
+++ linux/drivers/char/atarimouse.c     Sat Jan 15 12:52:19 2000
@@ -49,7 +49,7 @@
    mouse.ready = 1;
    wake_up_interruptible(&mouse.wait);
    if (mouse.fasyncptr)
-       kill_fasync(mouse.fasyncptr, SIGIO);
+       kill_fasync(mouse.fasyncptr, SIGIO, POLL_IN);

/*    ikbd_mouse_rel_pos(); */
}
--- linux/drivers/char/msbusmouse.c.sigio       Tue Jan  4 13:12:14 2000
+++ linux/drivers/char/msbusmouse.c     Sat Jan 15 12:52:19 2000
@@ -89,7 +89,7 @@
               mouse.ready = 1;
               wake_up_interruptible(&mouse.wait);
               if (mouse.fasyncptr)
-                       kill_fasync(mouse.fasyncptr, SIGIO);
+                       kill_fasync(mouse.fasyncptr, SIGIO, POLL_IN);
       }
}

--- linux/drivers/char/pc110pad.c.sigio Wed Jun  2 14:29:28 1999
+++ linux/drivers/char/pc110pad.c       Sat Jan 15 12:52:19 2000
@@ -75,7 +75,7 @@
{
       wake_up_interruptible(&queue);
       if(asyncptr)
-               kill_fasync(asyncptr, SIGIO);
+               kill_fasync(asyncptr, SIGIO, POLL_IN);
}


--- linux/drivers/char/qpmouse.c.sigio  Mon Aug  9 15:04:39 1999
+++ linux/drivers/char/qpmouse.c        Sat Jan 15 12:52:19 2000
@@ -134,7 +134,7 @@
       }
       queue->head = head;
       if (queue->fasync)
-               kill_fasync(queue->fasync, SIGIO);
+               kill_fasync(queue->fasync, SIGIO, POLL_IN);
       wake_up_interruptible(&queue->proc_list);
}

--- linux/drivers/scsi/sg.c.sigio       Tue Jan  4 13:12:21 2000
+++ linux/drivers/scsi/sg.c     Sat Jan 15 12:53:25 2000
@@ -808,7 +808,7 @@
    if (sfp && srp) {
        wake_up_interruptible(&sfp->read_wait);
        if (sfp->async_qp)
-            kill_fasync(sfp->async_qp, SIGPOLL);
+            kill_fasync(sfp->async_qp, SIGIO, POLL_IN);
    }
}

--- linux/drivers/sbus/char/pcikbd.c.sigio      Tue Jan  4 13:12:19 2000
+++ linux/drivers/sbus/char/pcikbd.c    Sat Jan 15 12:52:19 2000
@@ -774,7 +774,7 @@
       queue->head = head;
       aux_ready = 1;
       if (queue->fasync)
-               kill_fasync(queue->fasync, SIGIO);
+               kill_fasync(queue->fasync, SIGIO, POLL_IN);
       wake_up_interruptible(&queue->proc_list);
}

--- linux/drivers/sbus/char/sunkbd.c.sigio      Thu Apr 22 22:24:51 1999
+++ linux/drivers/sbus/char/sunkbd.c    Sat Jan 15 12:52:19 2000
@@ -1278,7 +1278,7 @@
               kbd_head = next;
       }
       if (kb_fasync)
-               kill_fasync (kb_fasync, SIGIO);
+               kill_fasync (kb_fasync, SIGIO, POLL_IN);
       wake_up_interruptible (&kbd_wait);
}

--- linux/drivers/sbus/char/sunmouse.c.sigio    Tue Jan  4 13:12:19 2000
+++ linux/drivers/sbus/char/sunmouse.c  Sat Jan 15 12:52:19 2000
@@ -137,7 +137,7 @@
       }
       sunmouse.ready = 1;
       if (sunmouse.fasync)
-               kill_fasync (sunmouse.fasync, SIGIO);
+               kill_fasync (sunmouse.fasync, SIGIO, POLL_IN);
       wake_up_interruptible (&sunmouse.proc_list);
}

@@ -365,7 +365,7 @@
                */
               sunmouse.ready = 1;
               if (sunmouse.fasync)
-                       kill_fasync (sunmouse.fasync, SIGIO);
+                       kill_fasync (sunmouse.fasync, SIGIO, POLL_IN);
               wake_up_interruptible(&sunmouse.proc_list);
       }
       return;
--- linux/drivers/sgi/char/shmiq.c.sigio        Mon Aug  9 15:04:40 1999
+++ linux/drivers/sgi/char/shmiq.c      Sat Jan 15 12:52:19 2000
@@ -118,7 +118,7 @@
       s->tail = tail_next;
       shmiqs [device].tail = tail_next;
       if (shmiqs [device].fasync)
-               kill_fasync (shmiqs [device].fasync, SIGIO);
+               kill_fasync (shmiqs [device].fasync, SIGIO, POLL_IN);
       wake_up_interruptible (&shmiqs [device].proc_list);
}

--- linux/drivers/usb/mouse.c.sigio     Fri Apr 30 11:20:49 1999
+++ linux/drivers/usb/mouse.c   Sat Jan 15 12:52:19 2000
@@ -81,7 +81,7 @@

       wake_up_interruptible(&mouse->wait);
       if (mouse->fasync)
-               kill_fasync(mouse->fasync, SIGIO);
+               kill_fasync(mouse->fasync, SIGIO, POLL_IN);

       return 1;
}
--- linux/arch/sparc64/solaris/timod.c.sigio    Tue Apr 14 20:44:21 1998
+++ linux/arch/sparc64/solaris/timod.c  Sat Jan 15 12:52:19 2000
@@ -154,7 +154,7 @@
       sock = &current->files->fd[fd]->f_dentry->d_inode->u.socket_i;
       wake_up_interruptible(&sock->wait);
       if (sock->fasync_list && !(sock->flags & SO_WAITDATA))
-               kill_fasync(sock->fasync_list, SIGIO);
+               kill_fasync(sock->fasync_list, SIGIO, POLL_IN);
       SOLD("done");
}

--- linux/drivers/telephony/ixj.c.save  Sat Jan 15 14:07:45 2000
+++ linux/drivers/telephony/ixj.c       Sat Jan 15 14:09:33 2000
@@ -446,7 +446,7 @@
                                               j->m_hook = 0;
                                               j->ex.bits.hookstate = 1;
                                               if (j->async_queue)
-                                                       kill_fasync(j->async_queue, SIGIO);     // Send apps notice of change
+                                                       kill_fasync(j->async_queue, SIGIO, POLL_IN);    // Send apps notice of change
                                       }
                                       goto timer_end;
                               }
@@ -536,7 +536,7 @@
                                       if (!j->m_hook) {
                                               j->m_hook = j->ex.bits.hookstate = 1;
                                               if (j->async_queue)
-                                                       kill_fasync(j->async_queue, SIGIO);     // Send apps notice of change
+                                                       kill_fasync(j->async_queue, SIGIO, POLL_IN);    // Send apps notice of change
                                       }
                               } else {
                                       if ((j->dsp.low == 0x21 || j->dsp.low == 0x22) &&
@@ -552,7 +552,7 @@
                                               j->m_hook = 0;
                                               j->ex.bits.hookstate = 1;
                                               if (j->async_queue)
-                                                       kill_fasync(j->async_queue, SIGIO);     // Send apps notice of change
+                                                       kill_fasync(j->async_queue, SIGIO, POLL_IN);    // Send apps notice of change
                                       }
                               }
                       }
@@ -642,7 +642,7 @@
                       if (j->ex.bytes) {
                               wake_up_interruptible(&j->poll_q);      // Wake any blocked selects
                               if (j->async_queue)
-                                       kill_fasync(j->async_queue, SIGIO);     // Send apps notice of change
+                                       kill_fasync(j->async_queue, SIGIO, POLL_IN);    // Send apps notice of change
                       }
               } else {
                       break;
@@ -917,7 +917,7 @@
               if (j->port != PORT_POTS) {
                       j->ex.bits.hookstate = 1;
                       if (j->async_queue)
-                               kill_fasync(j->async_queue, SIGIO);     // Send apps notice of change
+                               kill_fasync(j->async_queue, SIGIO, POLL_IN);    // Send apps notice of change

               }
       }
@@ -1473,7 +1473,7 @@
                       wake_up_interruptible(&j->poll_q);      // Wake any blocked selects

                       if (j->async_queue)
-                               kill_fasync(j->async_queue, SIGIO);     // Send apps notice of frame
+                               kill_fasync(j->async_queue, SIGIO, POLL_IN);    // Send apps notice of frame

               }
       }
@@ -1559,7 +1559,7 @@
                       wake_up_interruptible(&j->poll_q);      // Wake any blocked selects

                       if (j->async_queue)
-                               kill_fasync(j->async_queue, SIGIO);     // Send apps notice of empty buffer
+                               kill_fasync(j->async_queue, SIGIO, POLL_IN);    // Send apps notice of empty buffer
#ifdef PERFMON_STATS
                       ++j->frameswritten;
#endif
--- linux/ibcs/iBCSemul/timod.c.save    Sat Jan 15 14:31:14 2000
+++ linux/ibcs/iBCSemul/timod.c Sat Jan 15 14:31:17 2000
@@ -46,7 +46,7 @@
#define esp u_regs[UREG_FP]
#endif

-extern void kill_fasync(struct fasync_struct *fa, int sig);
+extern void kill_fasync(struct fasync_struct *fa, int sig, int band);

#ifdef IBCS_TRACE
static char *
@@ -82,7 +82,7 @@

       wake_up_interruptible(&sock->wait);
       if (sock->fasync_list && !(sock->flags & SO_WAITDATA))
-               kill_fasync(sock->fasync_list, SIGIO);
+               kill_fasync(sock->fasync_list, SIGIO, POLL_IN);
}


--- linux/include/asm-sparc/poll.h.jj   Sun Jan 16 03:23:14 2000
+++ linux/include/asm-sparc/poll.h      Sun Jan 16 03:23:42 2000
@@ -11,6 +11,7 @@
#define POLLWRNORM     POLLOUT
#define POLLRDBAND     128
#define POLLWRBAND     256
+#define POLLMSG                512

struct pollfd {
       int fd;
--- linux/include/asm-sparc64/poll.h.jj Sun Jan 16 03:24:14 2000
+++ linux/include/asm-sparc64/poll.h    Sun Jan 16 03:25:07 2000
@@ -11,6 +11,7 @@
#define POLLWRNORM     POLLOUT
#define POLLRDBAND     128
#define POLLWRBAND     256
+#define POLLMSG                512

struct pollfd {
       int fd;