diff --git a/main-loop.c b/main-loop.c
index 12b0213..49e97ff 100644
--- a/main-loop.c
+++ b/main-loop.c
@@ -503,13 +503,13 @@ int main_loop_wait(int nonblocking)
 
 #ifdef CONFIG_SLIRP
     slirp_update_timeout(&timeout);
-    slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
+    slirp_pollfds_fill(gpollfds);
 #endif
     qemu_iohandler_fill(&nfds, &rfds, &wfds, &xfds);
     ret = os_host_main_loop_wait(timeout);
     qemu_iohandler_poll(&rfds, &wfds, &xfds, ret);
 #ifdef CONFIG_SLIRP
-    slirp_select_poll(&rfds, &wfds, &xfds, (ret < 0));
+    slirp_pollfds_poll(gpollfds, (ret < 0));
 #endif
 
     qemu_run_all_timers();
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 49609c2..ceabff8 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -17,11 +17,9 @@ Slirp *slirp_init(int restricted, struct in_addr vnetwork,
 void slirp_cleanup(Slirp *slirp);
 
 void slirp_update_timeout(uint32_t *timeout);
-void slirp_select_fill(int *pnfds,
-                       fd_set *readfds, fd_set *writefds, fd_set *xfds);
+void slirp_pollfds_fill(GArray *pollfds);
 
-void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds,
-                       int select_error);
+void slirp_pollfds_poll(GArray *pollfds, int select_error);
 
 void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len);
 
diff --git a/slirp/main.h b/slirp/main.h
index 66e4f92..f2e58cf 100644
--- a/slirp/main.h
+++ b/slirp/main.h
@@ -31,7 +31,6 @@ extern int ctty_closed;
 extern char *slirp_tty;
 extern char *exec_shell;
 extern u_int curtime;
-extern fd_set *global_readfds, *global_writefds, *global_xfds;
 extern struct in_addr loopback_addr;
 extern unsigned long loopback_mask;
 extern char *username;
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 5d14e7f..bd9b7cb 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -39,9 +39,6 @@ static const uint8_t special_ethaddr[ETH_ALEN] = {
 
 static const uint8_t zero_ethaddr[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
 
-/* XXX: suppress those select globals */
-fd_set *global_readfds, *global_writefds, *global_xfds;
-
 u_int curtime;
 static u_int time_fasttimo, last_slowtimo;
 static int do_slowtimo;
@@ -261,7 +258,6 @@ void slirp_cleanup(Slirp *slirp)
 
 #define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
 #define CONN_CANFRCV(so) (((so)->so_state & (SS_FCANTRCVMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
-#define UPD_NFDS(x) if (nfds < (x)) nfds = (x)
 
 void slirp_update_timeout(uint32_t *timeout)
 {
@@ -270,23 +266,15 @@ void slirp_update_timeout(uint32_t *timeout)
     }
 }
 
-void slirp_select_fill(int *pnfds,
-                       fd_set *readfds, fd_set *writefds, fd_set *xfds)
+void slirp_pollfds_fill(GArray *pollfds)
 {
     Slirp *slirp;
     struct socket *so, *so_next;
-    int nfds;
 
     if (QTAILQ_EMPTY(&slirp_instances)) {
         return;
     }
 
-    /* fail safe */
-    global_readfds = NULL;
-    global_writefds = NULL;
-    global_xfds = NULL;
-
-    nfds = *pnfds;
     /*
      * First, TCP sockets
      */
@@ -302,8 +290,12 @@ void slirp_select_fill(int *pnfds,
 
         for (so = slirp->tcb.so_next; so != &slirp->tcb;
                 so = so_next) {
+            int events = 0;
+
             so_next = so->so_next;
 
+            so->pollfds_idx = -1;
+
             /*
              * See if we need a tcp_fasttimo
              */
@@ -323,8 +315,12 @@ void slirp_select_fill(int *pnfds,
              * Set for reading sockets which are accepting
              */
             if (so->so_state & SS_FACCEPTCONN) {
-                FD_SET(so->s, readfds);
-                UPD_NFDS(so->s);
+                GPollFD pfd = {
+                    .fd = so->s,
+                    .events = G_IO_IN | G_IO_HUP | G_IO_ERR,
+                };
+                so->pollfds_idx = pollfds->len;
+                g_array_append_val(pollfds, pfd);
                 continue;
             }
 
@@ -332,8 +328,12 @@ void slirp_select_fill(int *pnfds,
              * Set for writing sockets which are connecting
              */
             if (so->so_state & SS_ISFCONNECTING) {
-                FD_SET(so->s, writefds);
-                UPD_NFDS(so->s);
+                GPollFD pfd = {
+                    .fd = so->s,
+                    .events = G_IO_OUT | G_IO_ERR,
+                };
+                so->pollfds_idx = pollfds->len;
+                g_array_append_val(pollfds, pfd);
                 continue;
             }
 
@@ -342,8 +342,7 @@ void slirp_select_fill(int *pnfds,
              * we have something to send
              */
             if (CONN_CANFSEND(so) && so->so_rcv.sb_cc) {
-                FD_SET(so->s, writefds);
-                UPD_NFDS(so->s);
+                events |= G_IO_OUT | G_IO_ERR;
             }
 
             /*
@@ -352,9 +351,16 @@ void slirp_select_fill(int *pnfds,
              */
             if (CONN_CANFRCV(so) &&
                 (so->so_snd.sb_cc < (so->so_snd.sb_datalen/2))) {
-                FD_SET(so->s, readfds);
-                FD_SET(so->s, xfds);
-                UPD_NFDS(so->s);
+                events |= G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_PRI;
+            }
+
+            if (events) {
+                GPollFD pfd = {
+                    .fd = so->s,
+                    .events = events,
+                };
+                so->pollfds_idx = pollfds->len;
+                g_array_append_val(pollfds, pfd);
             }
         }
 
@@ -365,6 +371,8 @@ void slirp_select_fill(int *pnfds,
                 so = so_next) {
             so_next = so->so_next;
 
+            so->pollfds_idx = -1;
+
             /*
              * See if it's timed out
              */
@@ -388,8 +396,12 @@ void slirp_select_fill(int *pnfds,
              * (XXX <= 4 ?)
              */
             if ((so->so_state & SS_ISFCONNECTED) && so->so_queued <= 4) {
-                FD_SET(so->s, readfds);
-                UPD_NFDS(so->s);
+                GPollFD pfd = {
+                    .fd = so->s,
+                    .events = G_IO_IN | G_IO_HUP | G_IO_ERR,
+                };
+                so->pollfds_idx = pollfds->len;
+                g_array_append_val(pollfds, pfd);
             }
         }
 
@@ -400,6 +412,8 @@ void slirp_select_fill(int *pnfds,
                 so = so_next) {
             so_next = so->so_next;
 
+            so->pollfds_idx = -1;
+
             /*
              * See if it's timed out
              */
@@ -413,17 +427,18 @@ void slirp_select_fill(int *pnfds,
             }
 
             if (so->so_state & SS_ISFCONNECTED) {
-                FD_SET(so->s, readfds);
-                UPD_NFDS(so->s);
+                GPollFD pfd = {
+                    .fd = so->s,
+                    .events = G_IO_IN | G_IO_HUP | G_IO_ERR,
+                };
+                so->pollfds_idx = pollfds->len;
+                g_array_append_val(pollfds, pfd);
             }
         }
     }
-
-    *pnfds = nfds;
 }
 
-void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds,
-                       int select_error)
+void slirp_pollfds_poll(GArray *pollfds, int select_error)
 {
     Slirp *slirp;
     struct socket *so, *so_next;
@@ -433,10 +448,6 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds,
         return;
     }
 
-    global_readfds = readfds;
-    global_writefds = writefds;
-    global_xfds = xfds;
-
     curtime = qemu_get_clock_ms(rt_clock);
 
     QTAILQ_FOREACH(slirp, &slirp_instances, entry) {
@@ -462,12 +473,16 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds,
              */
             for (so = slirp->tcb.so_next; so != &slirp->tcb;
                     so = so_next) {
+                int revents;
+
                 so_next = so->so_next;
 
-                /*
-                 * FD_ISSET is meaningless on these sockets
-                 * (and they can crash the program)
-                 */
+                revents = 0;
+                if (so->pollfds_idx != -1) {
+                    revents = g_array_index(pollfds, GPollFD,
+                                            so->pollfds_idx).revents;
+                }
+
                 if (so->so_state & SS_NOFDREF || so->s == -1) {
                     continue;
                 }
@@ -475,15 +490,15 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds,
                 /*
                  * Check for URG data
                  * This will soread as well, so no need to
-                 * test for readfds below if this succeeds
+                 * test for G_IO_IN below if this succeeds
                  */
-                if (FD_ISSET(so->s, xfds)) {
+                if (revents & G_IO_PRI) {
                     sorecvoob(so);
                 }
                 /*
                  * Check sockets for reading
                  */
-                else if (FD_ISSET(so->s, readfds)) {
+                else if (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR)) {
                     /*
                      * Check for incoming connections
                      */
@@ -502,7 +517,8 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds,
                 /*
                  * Check sockets for writing
                  */
-                if (FD_ISSET(so->s, writefds)) {
+                if (!(so->so_state & SS_NOFDREF) &&
+                        (revents & (G_IO_OUT | G_IO_ERR))) {
                     /*
                      * Check for non-blocking, still-connecting sockets
                      */
@@ -588,9 +604,18 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds,
              */
             for (so = slirp->udb.so_next; so != &slirp->udb;
                     so = so_next) {
+                int revents;
+
                 so_next = so->so_next;
 
-                if (so->s != -1 && FD_ISSET(so->s, readfds)) {
+                revents = 0;
+                if (so->pollfds_idx != -1) {
+                    revents = g_array_index(pollfds, GPollFD,
+                            so->pollfds_idx).revents;
+                }
+
+                if (so->s != -1 &&
+                    (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR))) {
                     sorecvfrom(so);
                 }
             }
@@ -600,9 +625,18 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds,
              */
             for (so = slirp->icmp.so_next; so != &slirp->icmp;
                     so = so_next) {
-                so_next = so->so_next;
+                    int revents;
+
+                    so_next = so->so_next;
+
+                    revents = 0;
+                    if (so->pollfds_idx != -1) {
+                        revents = g_array_index(pollfds, GPollFD,
+                                                so->pollfds_idx).revents;
+                    }
 
-                if (so->s != -1 && FD_ISSET(so->s, readfds)) {
+                    if (so->s != -1 &&
+                        (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR))) {
                     icmp_receive(so);
                 }
             }
@@ -610,15 +644,6 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds,
 
         if_start(slirp);
     }
-
-    /* clear global file descriptor sets.
-     * these reside on the stack in vl.c
-     * so they're unusable if we're not in
-     * slirp_select_fill or slirp_select_poll.
-     */
-    global_readfds = NULL;
-    global_writefds = NULL;
-    global_xfds = NULL;
 }
 
 static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
diff --git a/slirp/socket.c b/slirp/socket.c
index 77b0c98..a7ab933 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -680,9 +680,6 @@ sofcantrcvmore(struct socket *so)
 {
 	if ((so->so_state & SS_NOFDREF) == 0) {
 		shutdown(so->s,0);
-		if(global_writefds) {
-		  FD_CLR(so->s,global_writefds);
-		}
 	}
 	so->so_state &= ~(SS_ISFCONNECTING);
 	if (so->so_state & SS_FCANTSENDMORE) {
@@ -698,12 +695,6 @@ sofcantsendmore(struct socket *so)
 {
 	if ((so->so_state & SS_NOFDREF) == 0) {
             shutdown(so->s,1);           /* send FIN to fhost */
-            if (global_readfds) {
-                FD_CLR(so->s,global_readfds);
-            }
-            if (global_xfds) {
-                FD_CLR(so->s,global_xfds);
-            }
 	}
 	so->so_state &= ~(SS_ISFCONNECTING);
 	if (so->so_state & SS_FCANTRCVMORE) {
diff --git a/slirp/socket.h b/slirp/socket.h
index 857b0da..57e0407 100644
--- a/slirp/socket.h
+++ b/slirp/socket.h
@@ -20,6 +20,8 @@ struct socket {
 
   int s;                           /* The actual socket */
 
+  int pollfds_idx;                 /* GPollFD GArray index */
+
   Slirp *slirp;			   /* managing slirp instance */
 
 			/* XXX union these with not-yet-used sbuf params */
diff --git a/stubs/slirp.c b/stubs/slirp.c
index 9a3309a..f1fc833 100644
--- a/stubs/slirp.c
+++ b/stubs/slirp.c
@@ -5,13 +5,11 @@ void slirp_update_timeout(uint32_t *timeout)
 {
 }
 
-void slirp_select_fill(int *pnfds, fd_set *readfds,
-                       fd_set *writefds, fd_set *xfds)
+void slirp_pollfds_fill(GArray *pollfds)
 {
 }
 
-void slirp_select_poll(fd_set *readfds, fd_set *writefds,
-                       fd_set *xfds, int select_error)
+void slirp_pollfds_poll(GArray *pollfds, int select_error)
 {
 }
 
