unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#11508: 24.1.50; Off-by-one error in xg_select?
@ 2012-05-18 13:13 Ken Brown
  2012-05-19  8:05 ` Jan Djärv
  0 siblings, 1 reply; 7+ messages in thread
From: Ken Brown @ 2012-05-18 13:13 UTC (permalink / raw)
  To: 11508

I apologize in advance for the noise if I'm misunderstanding something,
but it seems to me that there is an error in the calculation of the
first argument in the call to select in xgselect.c:105. (Line numbers
refer to the current trunk; xgselect.c was last changed in bzr revno
108249.)

The parameter "max_fds" in xg_select, in spite of its name, is initially
1 higher than the maximal file descriptor in the fd_sets in the other
parameters.  If max_fds doesn't get increased in line 78 or 83, then
line 104 does the wrong thing, causing the first argument to select in
line 105 to be 1 higher than it should be.

I think the following patch fixes this.  It also renames "max_fds" to
"fds_lim" to more accurately reflect what it represents.

=== modified file 'src/xgselect.c'
--- src/xgselect.c	2012-05-16 02:22:53 +0000
+++ src/xgselect.c	2012-05-18 12:28:27 +0000
@@ -32,7 +32,7 @@
 static ptrdiff_t gfds_size;
 
 int
-xg_select (int max_fds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
+xg_select (int fds_lim, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
 	   EMACS_TIME *timeout)
 {
   SELECT_TYPE all_rfds, all_wfds;
@@ -41,10 +41,10 @@
   GMainContext *context;
   int have_wfds = wfds != NULL;
   int n_gfds = 0, our_tmo = 0, retval = 0, our_fds = 0;
-  int i, nfds, fds_lim, tmo_in_millisec;
+  int i, nfds, tmo_in_millisec;
 
   if (inhibit_window_system || !display_arg)
-    return select (max_fds, rfds, wfds, efds, timeout);
+    return select (fds_lim, rfds, wfds, efds, timeout);
 
   if (rfds) memcpy (&all_rfds, rfds, sizeof (all_rfds));
   else FD_ZERO (&all_rfds);
@@ -75,12 +75,12 @@
       if (gfds[i].events & G_IO_IN)
         {
           FD_SET (gfds[i].fd, &all_rfds);
-          if (gfds[i].fd > max_fds) max_fds = gfds[i].fd;
+          if (gfds[i].fd >= fds_lim) fds_lim = gfds[i].fd + 1;
         }
       if (gfds[i].events & G_IO_OUT)
         {
           FD_SET (gfds[i].fd, &all_wfds);
-          if (gfds[i].fd > max_fds) max_fds = gfds[i].fd;
+          if (gfds[i].fd >= fds_lim) fds_lim = gfds[i].fd + 1;
           have_wfds = 1;
         }
     }
@@ -101,7 +101,6 @@
       if (our_tmo) tmop = &tmo;
     }
 
-  fds_lim = max_fds + 1;
   nfds = select (fds_lim, &all_rfds, have_wfds ? &all_wfds : NULL, efds, tmop);
 
   if (nfds < 0)







^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#11508: 24.1.50; Off-by-one error in xg_select?
  2012-05-18 13:13 bug#11508: 24.1.50; Off-by-one error in xg_select? Ken Brown
@ 2012-05-19  8:05 ` Jan Djärv
  2012-05-19  8:29   ` Jan Djärv
  0 siblings, 1 reply; 7+ messages in thread
From: Jan Djärv @ 2012-05-19  8:05 UTC (permalink / raw)
  To: Ken Brown; +Cc: 11508

Hello.

I think you misunderstand how select works.  Here is a snippet from the BSD man page:

   "The first nfds descriptors are checked in
     each set; i.e., the descriptors from 0 through nfds-1 in the descriptor
     sets are examined.  (Example: If you have set two file descriptors "4"
     and "17", nfds should  not be "2", but rather "17 + 1" or "18".) "


	Jan D.

18 maj 2012 kl. 15:13 skrev Ken Brown:

> I apologize in advance for the noise if I'm misunderstanding something,
> but it seems to me that there is an error in the calculation of the
> first argument in the call to select in xgselect.c:105. (Line numbers
> refer to the current trunk; xgselect.c was last changed in bzr revno
> 108249.)
> 
> The parameter "max_fds" in xg_select, in spite of its name, is initially
> 1 higher than the maximal file descriptor in the fd_sets in the other
> parameters.  If max_fds doesn't get increased in line 78 or 83, then
> line 104 does the wrong thing, causing the first argument to select in
> line 105 to be 1 higher than it should be.
> 
> I think the following patch fixes this.  It also renames "max_fds" to
> "fds_lim" to more accurately reflect what it represents.
> 
> === modified file 'src/xgselect.c'
> --- src/xgselect.c	2012-05-16 02:22:53 +0000
> +++ src/xgselect.c	2012-05-18 12:28:27 +0000
> @@ -32,7 +32,7 @@
> static ptrdiff_t gfds_size;
> 
> int
> -xg_select (int max_fds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
> +xg_select (int fds_lim, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
> 	   EMACS_TIME *timeout)
> {
>   SELECT_TYPE all_rfds, all_wfds;
> @@ -41,10 +41,10 @@
>   GMainContext *context;
>   int have_wfds = wfds != NULL;
>   int n_gfds = 0, our_tmo = 0, retval = 0, our_fds = 0;
> -  int i, nfds, fds_lim, tmo_in_millisec;
> +  int i, nfds, tmo_in_millisec;
> 
>   if (inhibit_window_system || !display_arg)
> -    return select (max_fds, rfds, wfds, efds, timeout);
> +    return select (fds_lim, rfds, wfds, efds, timeout);
> 
>   if (rfds) memcpy (&all_rfds, rfds, sizeof (all_rfds));
>   else FD_ZERO (&all_rfds);
> @@ -75,12 +75,12 @@
>       if (gfds[i].events & G_IO_IN)
>         {
>           FD_SET (gfds[i].fd, &all_rfds);
> -          if (gfds[i].fd > max_fds) max_fds = gfds[i].fd;
> +          if (gfds[i].fd >= fds_lim) fds_lim = gfds[i].fd + 1;
>         }
>       if (gfds[i].events & G_IO_OUT)
>         {
>           FD_SET (gfds[i].fd, &all_wfds);
> -          if (gfds[i].fd > max_fds) max_fds = gfds[i].fd;
> +          if (gfds[i].fd >= fds_lim) fds_lim = gfds[i].fd + 1;
>           have_wfds = 1;
>         }
>     }
> @@ -101,7 +101,6 @@
>       if (our_tmo) tmop = &tmo;
>     }
> 
> -  fds_lim = max_fds + 1;
>   nfds = select (fds_lim, &all_rfds, have_wfds ? &all_wfds : NULL, efds, tmop);
> 
>   if (nfds < 0)
> 
> 
> 
> 






^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#11508: 24.1.50; Off-by-one error in xg_select?
  2012-05-19  8:05 ` Jan Djärv
@ 2012-05-19  8:29   ` Jan Djärv
  2012-05-19  9:52     ` Andreas Schwab
  0 siblings, 1 reply; 7+ messages in thread
From: Jan Djärv @ 2012-05-19  8:29 UTC (permalink / raw)
  To: Ken Brown; +Cc: 11508

Hello.

Disregard my previous comment, I didn't look carefully enough.
The case where max_fds does not get increased in line 78 or 83 is very rare.  Everytime some X connection is active, GLib will have added at least one fd (for signal handling).  Probably

So the question is, is it more effective to give select the exact value (select works fine if nfds has a higher value than strictly neccessary), or always increment by one in lines 78 and 83?

As the normal case is that there will be several file descriptors in GLib, I'd say that the code does the most efficent thing most of the time.

	Jan D.

> 
> I think you misunderstand how select works.  Here is a snippet from the BSD man page:
> 
>   "The first nfds descriptors are checked in
>     each set; i.e., the descriptors from 0 through nfds-1 in the descriptor
>     sets are examined.  (Example: If you have set two file descriptors "4"
>     and "17", nfds should  not be "2", but rather "17 + 1" or "18".) "
> 
> 
> 	Jan D.
> 
> 18 maj 2012 kl. 15:13 skrev Ken Brown:
> 
>> I apologize in advance for the noise if I'm misunderstanding something,
>> but it seems to me that there is an error in the calculation of the
>> first argument in the call to select in xgselect.c:105. (Line numbers
>> refer to the current trunk; xgselect.c was last changed in bzr revno
>> 108249.)
>> 
>> The parameter "max_fds" in xg_select, in spite of its name, is initially
>> 1 higher than the maximal file descriptor in the fd_sets in the other
>> parameters.  If max_fds doesn't get increased in line 78 or 83, then
>> line 104 does the wrong thing, causing the first argument to select in
>> line 105 to be 1 higher than it should be.
>> 
>> I think the following patch fixes this.  It also renames "max_fds" to
>> "fds_lim" to more accurately reflect what it represents.
>> 
>> === modified file 'src/xgselect.c'
>> --- src/xgselect.c	2012-05-16 02:22:53 +0000
>> +++ src/xgselect.c	2012-05-18 12:28:27 +0000
>> @@ -32,7 +32,7 @@
>> static ptrdiff_t gfds_size;
>> 
>> int
>> -xg_select (int max_fds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
>> +xg_select (int fds_lim, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
>> 	   EMACS_TIME *timeout)
>> {
>>  SELECT_TYPE all_rfds, all_wfds;
>> @@ -41,10 +41,10 @@
>>  GMainContext *context;
>>  int have_wfds = wfds != NULL;
>>  int n_gfds = 0, our_tmo = 0, retval = 0, our_fds = 0;
>> -  int i, nfds, fds_lim, tmo_in_millisec;
>> +  int i, nfds, tmo_in_millisec;
>> 
>>  if (inhibit_window_system || !display_arg)
>> -    return select (max_fds, rfds, wfds, efds, timeout);
>> +    return select (fds_lim, rfds, wfds, efds, timeout);
>> 
>>  if (rfds) memcpy (&all_rfds, rfds, sizeof (all_rfds));
>>  else FD_ZERO (&all_rfds);
>> @@ -75,12 +75,12 @@
>>      if (gfds[i].events & G_IO_IN)
>>        {
>>          FD_SET (gfds[i].fd, &all_rfds);
>> -          if (gfds[i].fd > max_fds) max_fds = gfds[i].fd;
>> +          if (gfds[i].fd >= fds_lim) fds_lim = gfds[i].fd + 1;
>>        }
>>      if (gfds[i].events & G_IO_OUT)
>>        {
>>          FD_SET (gfds[i].fd, &all_wfds);
>> -          if (gfds[i].fd > max_fds) max_fds = gfds[i].fd;
>> +          if (gfds[i].fd >= fds_lim) fds_lim = gfds[i].fd + 1;
>>          have_wfds = 1;
>>        }
>>    }
>> @@ -101,7 +101,6 @@
>>      if (our_tmo) tmop = &tmo;
>>    }
>> 
>> -  fds_lim = max_fds + 1;
>>  nfds = select (fds_lim, &all_rfds, have_wfds ? &all_wfds : NULL, efds, tmop);
>> 
>>  if (nfds < 0)
>> 
>> 
>> 
>> 
> 






^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#11508: 24.1.50; Off-by-one error in xg_select?
  2012-05-19  8:29   ` Jan Djärv
@ 2012-05-19  9:52     ` Andreas Schwab
  2012-05-20 22:44       ` Ken Brown
  0 siblings, 1 reply; 7+ messages in thread
From: Andreas Schwab @ 2012-05-19  9:52 UTC (permalink / raw)
  To: Jan Djärv; +Cc: 11508

Jan Djärv <jan.h.d@swipnet.se> writes:

> So the question is, is it more effective to give select the exact value
> (select works fine if nfds has a higher value than strictly neccessary),
> or always increment by one in lines 78 and 83?

IMHO it doesn't hurt to be exact, and the patch removes an inconsistency
which makes it easier to understand the code.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."





^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#11508: 24.1.50; Off-by-one error in xg_select?
  2012-05-19  9:52     ` Andreas Schwab
@ 2012-05-20 22:44       ` Ken Brown
  2012-05-21  5:30         ` Jan Djärv
  0 siblings, 1 reply; 7+ messages in thread
From: Ken Brown @ 2012-05-20 22:44 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: 11508

On 5/19/2012 5:52 AM, Andreas Schwab wrote:
> Jan Djärv<jan.h.d@swipnet.se>  writes:
>
>> So the question is, is it more effective to give select the exact value
>> (select works fine if nfds has a higher value than strictly neccessary),
>> or always increment by one in lines 78 and 83?
>
> IMHO it doesn't hurt to be exact, and the patch removes an inconsistency
> which makes it easier to understand the code.

So can I go ahead and make this change?  Jan, do you still object?

Ken






^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#11508: 24.1.50; Off-by-one error in xg_select?
  2012-05-20 22:44       ` Ken Brown
@ 2012-05-21  5:30         ` Jan Djärv
  2012-05-21 13:38           ` Ken Brown
  0 siblings, 1 reply; 7+ messages in thread
From: Jan Djärv @ 2012-05-21  5:30 UTC (permalink / raw)
  To: Ken Brown; +Cc: Andreas Schwab, 11508@debbugs.gnu.org

Hello. 

Go ahead and make the change.

     Jan D. 

21 maj 2012 kl. 00:44 skrev Ken Brown <kbrown@cornell.edu>:

> On 5/19/2012 5:52 AM, Andreas Schwab wrote:
>> Jan Djärv<jan.h.d@swipnet.se>  writes:
>> 
>>> So the question is, is it more effective to give select the exact value
>>> (select works fine if nfds has a higher value than strictly neccessary),
>>> or always increment by one in lines 78 and 83?
>> 
>> IMHO it doesn't hurt to be exact, and the patch removes an inconsistency
>> which makes it easier to understand the code.
> 
> So can I go ahead and make this change?  Jan, do you still object?
> 
> Ken





^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#11508: 24.1.50; Off-by-one error in xg_select?
  2012-05-21  5:30         ` Jan Djärv
@ 2012-05-21 13:38           ` Ken Brown
  0 siblings, 0 replies; 7+ messages in thread
From: Ken Brown @ 2012-05-21 13:38 UTC (permalink / raw)
  To: Jan Djärv; +Cc: Andreas Schwab, 11508-done

Version: 24.2

I've committed a simpler version of the change as bzr revision 108325, 
and I'm closing the bug.

Ken





^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2012-05-21 13:38 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-05-18 13:13 bug#11508: 24.1.50; Off-by-one error in xg_select? Ken Brown
2012-05-19  8:05 ` Jan Djärv
2012-05-19  8:29   ` Jan Djärv
2012-05-19  9:52     ` Andreas Schwab
2012-05-20 22:44       ` Ken Brown
2012-05-21  5:30         ` Jan Djärv
2012-05-21 13:38           ` Ken Brown

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).