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