aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2014-04-15 13:05:02 -0700
committerPaul Eggert2014-04-15 13:05:02 -0700
commit3a31cae4677c7c5e501dcf7e5c520e49db16f75e (patch)
treeca419d8f8bfd86149ee28c3b1aad2d961bc33695 /src
parentad0dfd98e3579f203db3fb22fb74f77fe5f2c21e (diff)
downloademacs-3a31cae4677c7c5e501dcf7e5c520e49db16f75e.tar.gz
emacs-3a31cae4677c7c5e501dcf7e5c520e49db16f75e.zip
Revert previous change.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog9
-rw-r--r--src/xgselect.c83
2 files changed, 39 insertions, 53 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index f6d9622d5ab..51861c6ca7d 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,12 +1,3 @@
12014-04-15 Paul Eggert <eggert@penguin.cs.ucla.edu>
2
3 Fix some xgselect-vs-pselect bugs (Bug#17172).
4 This may not fix Bug#17172, but it fixes some bugs discovering
5 while auditing xgselect.c for that bug.
6 when one of glib's file descriptors is greater than FDS_LIM.
7 Treat rfds, wfds, efds consistently, and test G_IO_PRI too.
8 Clear input masks when pselect returns zero.
9
102014-04-15 Stefan Monnier <monnier@iro.umontreal.ca> 12014-04-15 Stefan Monnier <monnier@iro.umontreal.ca>
11 2
12 * buffer.c (Foverlays_at): Add argument `sorted'. 3 * buffer.c (Foverlays_at): Add argument `sorted'.
diff --git a/src/xgselect.c b/src/xgselect.c
index 7decca34edf..1d3f916c9f8 100644
--- a/src/xgselect.c
+++ b/src/xgselect.c
@@ -33,15 +33,16 @@ int
33xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set *efds, 33xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set *efds,
34 struct timespec const *timeout, sigset_t const *sigmask) 34 struct timespec const *timeout, sigset_t const *sigmask)
35{ 35{
36 fd_set all_rfds, all_wfds, all_efds; 36 fd_set all_rfds, all_wfds;
37 struct timespec tmo; 37 struct timespec tmo;
38 struct timespec const *tmop = timeout; 38 struct timespec const *tmop = timeout;
39 39
40 GMainContext *context; 40 GMainContext *context;
41 int have_wfds = wfds != NULL;
41 GPollFD gfds_buf[128]; 42 GPollFD gfds_buf[128];
42 GPollFD *gfds = gfds_buf; 43 GPollFD *gfds = gfds_buf;
43 int gfds_size = sizeof gfds_buf / sizeof *gfds_buf; 44 int gfds_size = sizeof gfds_buf / sizeof *gfds_buf;
44 int n_gfds, retval = 0, all_lim = fds_lim; 45 int n_gfds, retval = 0, our_fds = 0, max_fds = fds_lim - 1;
45 int i, nfds, tmo_in_millisec; 46 int i, nfds, tmo_in_millisec;
46 bool need_to_dispatch; 47 bool need_to_dispatch;
47 USE_SAFE_ALLOCA; 48 USE_SAFE_ALLOCA;
@@ -58,8 +59,6 @@ xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set *efds,
58 else FD_ZERO (&all_rfds); 59 else FD_ZERO (&all_rfds);
59 if (wfds) all_wfds = *wfds; 60 if (wfds) all_wfds = *wfds;
60 else FD_ZERO (&all_wfds); 61 else FD_ZERO (&all_wfds);
61 if (efds) all_efds = *efds;
62 else FD_ZERO (&all_efds);
63 62
64 n_gfds = g_main_context_query (context, G_PRIORITY_LOW, &tmo_in_millisec, 63 n_gfds = g_main_context_query (context, G_PRIORITY_LOW, &tmo_in_millisec,
65 gfds, gfds_size); 64 gfds, gfds_size);
@@ -72,22 +71,19 @@ xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set *efds,
72 } 71 }
73 72
74 for (i = 0; i < n_gfds; ++i) 73 for (i = 0; i < n_gfds; ++i)
75 if (gfds[i].events & (G_IO_IN | G_IO_OUT | G_IO_PRI)) 74 {
76 { 75 if (gfds[i].events & G_IO_IN)
77 int fd = gfds[i].fd; 76 {
78 for (; all_lim <= fd; all_lim++) 77 FD_SET (gfds[i].fd, &all_rfds);
79 { 78 if (gfds[i].fd > max_fds) max_fds = gfds[i].fd;
80 FD_CLR (all_lim, &all_rfds); 79 }
81 FD_CLR (all_lim, &all_wfds); 80 if (gfds[i].events & G_IO_OUT)
82 FD_CLR (all_lim, &all_efds); 81 {
83 } 82 FD_SET (gfds[i].fd, &all_wfds);
84 if (gfds[i].events & G_IO_IN) 83 if (gfds[i].fd > max_fds) max_fds = gfds[i].fd;
85 FD_SET (fd, &all_rfds); 84 have_wfds = 1;
86 if (gfds[i].events & G_IO_OUT) 85 }
87 FD_SET (fd, &all_wfds); 86 }
88 if (gfds[i].events & G_IO_PRI)
89 FD_SET (fd, &all_efds);
90 }
91 87
92 SAFE_FREE (); 88 SAFE_FREE ();
93 89
@@ -99,35 +95,34 @@ xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set *efds,
99 tmop = &tmo; 95 tmop = &tmo;
100 } 96 }
101 97
102 nfds = pselect (all_lim, &all_rfds, &all_wfds, &all_efds, tmop, sigmask); 98 fds_lim = max_fds + 1;
99 nfds = pselect (fds_lim, &all_rfds, have_wfds ? &all_wfds : NULL,
100 efds, tmop, sigmask);
103 101
104 if (nfds < 0) 102 if (nfds < 0)
105 retval = nfds; 103 retval = nfds;
106 else 104 else if (nfds > 0)
107 { 105 {
108 for (i = 0; i < fds_lim; ++i) 106 for (i = 0; i < fds_lim; ++i)
109 { 107 {
110 if (rfds && FD_ISSET (i, rfds)) 108 if (FD_ISSET (i, &all_rfds))
111 { 109 {
112 if (FD_ISSET (i, &all_rfds)) 110 if (rfds && FD_ISSET (i, rfds)) ++retval;
113 retval++; 111 else ++our_fds;
114 else 112 }
115 FD_CLR (i, rfds); 113 else if (rfds)
116 } 114 FD_CLR (i, rfds);
117 if (wfds && FD_ISSET (i, wfds)) 115
118 { 116 if (have_wfds && FD_ISSET (i, &all_wfds))
119 if (FD_ISSET (i, &all_wfds)) 117 {
120 retval++; 118 if (wfds && FD_ISSET (i, wfds)) ++retval;
121 else 119 else ++our_fds;
122 FD_CLR (i, wfds); 120 }
123 } 121 else if (wfds)
124 if (efds && FD_ISSET (i, efds)) 122 FD_CLR (i, wfds);
125 { 123
126 if (FD_ISSET (i, &all_efds)) 124 if (efds && FD_ISSET (i, efds))
127 retval++; 125 ++retval;
128 else
129 FD_CLR (i, efds);
130 }
131 } 126 }
132 } 127 }
133 128
@@ -147,7 +142,7 @@ xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set *efds,
147 } 142 }
148 143
149 /* To not have to recalculate timeout, return like this. */ 144 /* To not have to recalculate timeout, return like this. */
150 if (retval == 0 && (0 < nfds || tmop == &tmo)) 145 if ((our_fds > 0 || (nfds == 0 && tmop == &tmo)) && (retval == 0))
151 { 146 {
152 retval = -1; 147 retval = -1;
153 errno = EINTR; 148 errno = EINTR;