diff options
| author | Paul Eggert | 2014-04-15 13:05:02 -0700 |
|---|---|---|
| committer | Paul Eggert | 2014-04-15 13:05:02 -0700 |
| commit | 3a31cae4677c7c5e501dcf7e5c520e49db16f75e (patch) | |
| tree | ca419d8f8bfd86149ee28c3b1aad2d961bc33695 /src | |
| parent | ad0dfd98e3579f203db3fb22fb74f77fe5f2c21e (diff) | |
| download | emacs-3a31cae4677c7c5e501dcf7e5c520e49db16f75e.tar.gz emacs-3a31cae4677c7c5e501dcf7e5c520e49db16f75e.zip | |
Revert previous change.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 9 | ||||
| -rw-r--r-- | src/xgselect.c | 83 |
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 @@ | |||
| 1 | 2014-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 | |||
| 10 | 2014-04-15 Stefan Monnier <monnier@iro.umontreal.ca> | 1 | 2014-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 | |||
| 33 | xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set *efds, | 33 | xg_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; |