[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

fselect for exceptional conditions patch...



 Hi fellas!

 Now here's something which might interest you: A patch to add the
functionality to select for exceptional conditions to MiNT. The patch
is relative to Michael Hohmuth's 1.10 V3 meta patch.

 Note that this does *not* say there currently is any device driver which
supports this! I merely did it so that Kay Roemer can use it in his socket
device, because I think we'll need it for telnet and things like this. Since
he already depends on `unofficial' patches, there isn't much point in
mocking about adding an extra one.. ;)

 A device driver which want's to support this must also support a select
mode of 2 (besides 0 for `read' and 1 for 'write', which all drivers should
support) and should implement an FIOEXCEPT ioctl call to determine if a
particular file pointers has got an exceptional condition to offer (just
like FIONREAD and FIONWRITE for read/write selects), in which case it
should set it's argument pointer to 1.

 If you should select an old device driver for exceptional conditions, it
should just behave the way it has done without this, say block, because it
neither understands the select mode 2 (and therefore can't be activated to
select), nor the FIOEXCEPT call (and therefore won't never report success).
Since this is only theory and even MiNT's internal device drivers do not
always explicitly check both of the `old' possible modes, but use constructs
like `if (mode != O_RDONLY)', some patches have been necessary to be sure.
At least it doesn't seem to disturb my setup now... :-)

 But then, I didn't had a great chance to test the *real* goal... ;)

ciao,
TeSche
--
Torsten Scherer (TeSche, Schiller...)
Faculty of Technology, University of Bielefeld, Germany, Europe, Earth...
| Use any of "finger itschere@129.70.131.2-15" for adresses and more.|
| Last updated: 14. April 1994.|


--- file.h.origSun Jun 19 17:54:16 1994
+++ file.hSun Jun 19 18:31:18 1994
@@ -340,6 +340,7 @@
 #define FSTAT(('F'<< 8) | 0)/* handled by kernel */
 #define FIONREAD(('F'<< 8) | 1)
 #define FIONWRITE(('F'<< 8) | 2)
+#define FIOEXCEPT(('F'<< 8) | 3)
 #define TIOCGETP(('T'<< 8) | 0)
 #define TIOCSETN(('T'<< 8) | 1)
 #define TIOCGETC(('T'<< 8) | 2)
--- dosfile.c.origSun Jun 19 17:54:26 1994
+++ dosfile.cSun Jun 19 17:54:24 1994
@@ -954,11 +954,11 @@
  * integers containing bitmasks that describe which file descriptors
  * we're interested in. These masks are changed to represent which
  * file descriptors actually have data waiting (rfd), are ready to
- * output (wfd), or have exceptional conditions (xfd -- currently
- * ignored). If timeout is 0, fselect blocks until some file descriptor
- * is ready; otherwise, it waits only "timeout" milliseconds.
- * Return value: number of file descriptors that are available for
- * reading/writing; or a negative error number.
+ * output (wfd), or have exceptional conditions (xfd). If timeout is 0,
+ * fselect blocks until some file descriptor is ready; otherwise, it
+ * waits only "timeout" milliseconds. Return value: number of file
+ * descriptors that are available for reading/writing; or a negative
+ * error number.
  */
 
 /* helper function for time outs */
@@ -974,7 +974,7 @@
 unsigned timeout;
 long *rfdp, *wfdp, *xfdp;
 {
-long rfd, wfd;
+long rfd, wfd, xfd;
 long mask, bytes;
 int i, count;
 FILEPTR *f;
@@ -982,9 +982,6 @@
 TIMEOUT *t;
 short sr;
 
-if (xfdp)
-*xfdp = 0;
-
 if (rfdp) {
 rfd = *rfdp; *rfdp = 0;
 }
@@ -995,14 +992,19 @@
 }
 else
 wfd = 0;
+if (xfdp) {
+xfd = *xfdp; *xfdp = 0;
+}
+else
+xfd = 0;
 
-TRACE(("Fselect(%u, %lx, %lx)", timeout, rfd, wfd));
+TRACE(("Fselect(%u, %lx, %lx, %lx)", timeout, rfd, wfd, xfd));
 p = curproc;/* help the optimizer out */
 
 /* first, validate the masks */
 mask = 1L;
 for (i = 0; i < MAX_OPEN; i++) {
-if ( ((rfd & mask) || (wfd & mask)) && !(p->handle[i]) ) {
+if ( ((rfd & mask) || (wfd & mask) || (xfd & mask)) && !(p->handle[i]) ) {
 DEBUG(("Fselect: invalid handle: %d", i));
 return EIHNDL;
 }
@@ -1044,6 +1046,17 @@
 *wfdp |= mask;
 }
 }
+if (xfd & mask) {
+f = p->handle[i];
+/* tesche: anybody worried about using O_RDWR for exceptional data? ;) */
+if ((*f->dev->select)(f, (long)p, O_RDWR) == 1) {
+/*  tesche: for old device drivers, which don't understand this
+ * call, this will never be true and therefore won't disturb us here.
+ */
+count++;
+*xfdp |= mask;
+}
+}
 mask = mask << 1L;
 }
 
@@ -1106,6 +1119,20 @@
     }
 }
 }
+if (xfd & mask) {
+f = p->handle[i];
+if (f) {
+/*  tesche: since old device drivers won't understand this call,
+ * we set up `no exceptional condition' as default.
+ */
+    bytes = 0L;
+    (void)(*f->dev->ioctl)(f, FIOEXCEPT,&bytes);
+    if (bytes > 0) {
+*xfdp |= mask;
+count++;
+    }
+}
+}
 mask = mask << 1L;
 }
 }
@@ -1125,6 +1152,11 @@
 if (f)
 (*f->dev->unselect)(f, (long)p, O_WRONLY);
 }
+if (xfd & mask) {
+f = p->handle[i];
+if (f)
+(*f->dev->unselect)(f, (long)p, O_RDWR);
+}
 mask = mask << 1L;
 }
 
--- biosfs.c.origMon Jun 20 14:28:52 1994
+++ biosfs.cMon Jun 20 14:33:36 1994
@@ -1090,11 +1090,12 @@
 FILEPTR *f; int mode; void *buf;
 {
 UNUSED(f);
-if (mode == FIONREAD) {
+if (mode == FIONREAD)
 *((long *)buf) = 0;
-}
 else if (mode == FIONWRITE)
 *((long *)buf) = 1;
+else if (mode == FIOEXCEPT)
+*((long *)buf) = 0;
 else
 return EINVFN;
 return 0;
@@ -1130,8 +1131,10 @@
 int mode;
 {
 UNUSED(f); UNUSED(p);
-UNUSED(mode);
-return 1;/* we're always ready to read/write */
+if ((mode == O_RDONLY) || (mode == O_WRONLY))
+return 1;/* we're always ready to read/write */
+
+return 0;/* other things we don't care about */
 }
 
 void ARGS_ON_STACK 
@@ -1339,6 +1342,9 @@
 else
 *r = 0;
 break;
+case FIOEXCEPT:
+*r = 0;
+break;
 case TIOCFLUSH:
     {
 int oldmap;
@@ -1878,6 +1884,10 @@
 if (r < 0) r += MOUSESIZ;
 *((long *)buf) = r;
 }
+else if (mode == FIONWRITE)
+*((long *)buf) = 0;
+else if (mode == FIOEXCEPT)
+*((long *)buf) = 0;
 else
 return EINVFN;
 return 0;
@@ -1891,8 +1901,12 @@
 {
 UNUSED(f);
 
-if (mode != O_RDONLY)
-return 1;/* we can always take output :-) */
+if (mode != O_RDONLY) {
+if (mode == O_WRONLY)
+return 1;/* we can always take output :-) */
+else
+return 0;/* but don't care for anything else */
+}
 
 if (mousetail - mousehead)
 return 1;/* input waiting already */
--- fasttext.c.origMon Jun 20 14:28:38 1994
+++ fasttext.cMon Jun 20 14:30:48 1994
@@ -1322,6 +1322,9 @@
 else if (mode == FIONWRITE) {
 *r = 1;
 }
+else if (mode == FIOEXCEPT) {
+*r = 0;
+}
 else if (mode == TIOCFLUSH) {
 /* BUG: this should flush the input/output buffers */
 return 0;
--- pipefs.c.origMon Jun 20 14:35:42 1994
+++ pipefs.cMon Jun 20 14:37:16 1994
@@ -782,6 +782,9 @@
 }
 *((long *) buf) = r;
 break;
+case FIOEXCEPT:
+*((long *) buf) = 0;
+break;
 case F_SETLK:
 case F_SETLKW:
 lck = (struct flock *)buf;
--- procfs.c.origMon Jun 20 14:37:30 1994
+++ procfs.cMon Jun 20 14:38:08 1994
@@ -693,6 +693,9 @@
 case FIONWRITE:
 *((long *)buf) = 1L;/* we're always ready for i/o */
 return 0;
+case FIOEXCEPT:
+*((long *)buf) = 0L;
+return 0;
 default:
 DEBUG(("procfs: bad Fcntl command"));
 }
--- tosfs.c.origMon Jun 20 14:34:46 1994
+++ tosfs.cMon Jun 20 14:35:04 1994
@@ -1314,6 +1314,9 @@
 case FIONWRITE:
 *((long *)buf) = 1;
 return 0;
+case FIOEXCEPT:
+*((long *)buf) = 0;
+return 0;
 case F_SETLK:
 case F_SETLKW:
 case F_GETLK: