public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2.4] sys_select() return error on bad file
@ 2004-03-03  8:46 Armin Schindler
  2004-03-04  7:22 ` Willy Tarreau
  0 siblings, 1 reply; 7+ messages in thread
From: Armin Schindler @ 2004-03-03  8:46 UTC (permalink / raw)
  To: Linux Kernel Mailinglist; +Cc: Armin Schindler

Hi,

the following patch now returns -EBADF in sys_select()/do_select()
if all specified file-descriptors are bad (e.g. were closed by another
thread).

Without this patch, the for-loop in do_select() won't stop if there are no
valid files any more. It stops only if a specified timeout occured or a
signal arrived.

If there are no objections on this patch, I would also create a patch for
kernel 2.6 and the poll() code. I didn't have a closer look at this yet.

Armin

--- linux/fs/select.c_orig	2004-03-02 19:06:44.000000000 +0100
+++ linux/fs/select.c	2004-03-03 09:25:24.000000000 +0100
@@ -183,6 +183,8 @@
 		wait = NULL;
 	retval = 0;
 	for (;;) {
+		int file_err = 1;
+
 		set_current_state(TASK_INTERRUPTIBLE);
 		for (i = 0 ; i < n; i++) {
 			unsigned long bit = BIT(i);
@@ -199,6 +201,7 @@
 						  i /*  The fd*/,
 						  __timeout,
 						  NULL);
+				file_err = 0;
 				mask = DEFAULT_POLLMASK;
 				if (file->f_op && file->f_op->poll)
 					mask = file->f_op->poll(file, wait);
@@ -227,6 +230,10 @@
 			retval = table.error;
 			break;
 		}
+		if (file_err) {
+			retval = -EBADF;
+			break;
+		}
 		__timeout = schedule_timeout(__timeout);
 	}
 	current->state = TASK_RUNNING;


^ permalink raw reply	[flat|nested] 7+ messages in thread
* Re: [PATCH 2.4] sys_select() return error on bad file
@ 2004-03-14 18:18 Manfred Spraul
  2004-03-15 10:33 ` Armin Schindler
  0 siblings, 1 reply; 7+ messages in thread
From: Manfred Spraul @ 2004-03-14 18:18 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: linux-kernel, Armin Schindler

[-- Attachment #1: Type: text/plain, Size: 1482 bytes --]

Marcelo wrote:

>> 
>> Anyway, I don't see how your proposal would do better performance?
>> My patch just adds a new variable on the stack, which should not make any
>> difference in performance. And later, it is the same if the new or another
>> variable gets changed or checked.
>
>Curiosity: Does SuS/POSIX define behaviour for "all fds are closed" ? 
>  
>
I'd interpret SuS that a closed fd is ready for reading and writing:
 From the select page:
<<<
A descriptor shall be considered ready for reading when a call to an 
input function with O_NONBLOCK clear would not block, whether or not the 
function would transfer data successfully. (The function might return 
data, an end-of-file indication, or an error other than one indicating 
that it is blocked, and in each of these cases the descriptor shall be 
considered ready for reading.)
<<<
read(fd,,) will return immediately with EBADF, thus the fd is ready.

But that's a grey area, especially if you close the fd during the select 
call. For example HP UX just kills the current process if an fd that is 
polled is closed by overwriting it with dup2. I didn't test select, but 
I'd expect a similar behavior.

Armin: did you compare the Linux behavior with other unices? Are there 
other unices that return EBADF for select() if all fds are closed?

Attached is an untested proposal, against 2.6, but I'm not sure if it's 
really a good idea to change the current code - it might break existing 
apps.

--
    Manfred

[-- Attachment #2: patch-select-2.6 --]
[-- Type: text/plain, Size: 1013 bytes --]

--- 2.6/fs/select.c	2004-03-14 14:28:28.000000000 +0100
+++ build-2.6/fs/select.c	2004-03-14 19:08:57.000000000 +0100
@@ -223,25 +223,25 @@
 					break;
 				if (!(bit & all_bits))
 					continue;
+				mask = DEFAULT_POLLMASK;
 				file = fget(i);
 				if (file) {
 					f_op = file->f_op;
-					mask = DEFAULT_POLLMASK;
 					if (f_op && f_op->poll)
 						mask = (*f_op->poll)(file, retval ? NULL : wait);
 					fput(file);
-					if ((mask & POLLIN_SET) && (in & bit)) {
-						res_in |= bit;
-						retval++;
-					}
-					if ((mask & POLLOUT_SET) && (out & bit)) {
-						res_out |= bit;
-						retval++;
-					}
-					if ((mask & POLLEX_SET) && (ex & bit)) {
-						res_ex |= bit;
-						retval++;
-					}
+				}
+				if ((mask & POLLIN_SET) && (in & bit)) {
+					res_in |= bit;
+					retval++;
+				}
+				if ((mask & POLLOUT_SET) && (out & bit)) {
+					res_out |= bit;
+					retval++;
+				}
+				if ((mask & POLLEX_SET) && (ex & bit)) {
+					res_ex |= bit;
+					retval++;
 				}
 			}
 			if (res_in)

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

end of thread, other threads:[~2004-03-15 10:33 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-03-03  8:46 [PATCH 2.4] sys_select() return error on bad file Armin Schindler
2004-03-04  7:22 ` Willy Tarreau
2004-03-04  9:20   ` Armin Schindler
2004-03-04 13:48     ` Willy Tarreau
2004-03-14 15:58     ` Marcelo Tosatti
  -- strict thread matches above, loose matches on Subject: below --
2004-03-14 18:18 Manfred Spraul
2004-03-15 10:33 ` Armin Schindler

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox