Tcl Source Code

Changes On Branch tip-469
Login
Bounty program for improvements to Tcl and certain Tcl packages.

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch tip-469 Excluding Merge-Ins

This is equivalent to a diff from 85a4914711 to 30d5e6a673

2018-10-17
20:02
Merge 8.6 check-in: 849cc049e8 user: jan.nijtmans tags: core-8-branch
20:02
merge 8.7 check-in: 9e834efc20 user: dgp tags: dgp-string-insert
19:49
merge 8.7 Leaf check-in: 30d5e6a673 user: dgp tags: tip-469
19:47
merge 8.7 Leaf check-in: 740dc47d3e user: dgp tags: tip-465
16:37
merge 8.7 check-in: cd5dd34ec3 user: dgp tags: trunk
16:24
merge 8.6 check-in: 85a4914711 user: dgp tags: core-8-branch
16:12
Revert addition of "slowTest" as built-in constraint. (no TIP; no version bump). Let the test file t... check-in: fb856c43eb user: dgp tags: core-8-6-branch
2018-10-12
18:45
Minor doc update check-in: fe86f9e208 user: dkf tags: core-8-branch
2018-06-04
13:17
merge 8.7 check-in: c55441df99 user: dgp tags: tip-469

Changes to generic/tclIO.c.

  8921   8921   {
  8922   8922       Channel *chanPtr;		/* The channel to create the handler for. */
  8923   8923       ChannelState *statePtr;	/* State info for channel */
  8924   8924       Tcl_Channel chan;		/* The opaque type for the channel. */
  8925   8925       const char *chanName;
  8926   8926       int modeIndex;		/* Index of mode argument. */
  8927   8927       int mask;
  8928         -    static const char *const modeOptions[] = {"readable", "writable", NULL};
  8929         -    static const int maskArray[] = {TCL_READABLE, TCL_WRITABLE};
         8928  +    static const char *const modeOptions[] = {"readable", "writable", "exception", NULL};
         8929  +    static const int maskArray[] = {TCL_READABLE, TCL_WRITABLE, TCL_EXCEPTION };
  8930   8930   
  8931   8931       if ((objc != 3) && (objc != 4)) {
  8932   8932   	Tcl_WrongNumArgs(interp, 1, objv, "channelId event ?script?");
  8933   8933   	return TCL_ERROR;
  8934   8934       }
  8935   8935       if (Tcl_GetIndexFromObj(interp, objv[2], modeOptions, "event name", 0,
  8936   8936   	    &modeIndex) != TCL_OK) {
................................................................................
  8941   8941       chanName = TclGetString(objv[1]);
  8942   8942       chan = Tcl_GetChannel(interp, chanName, NULL);
  8943   8943       if (chan == NULL) {
  8944   8944   	return TCL_ERROR;
  8945   8945       }
  8946   8946       chanPtr = (Channel *) chan;
  8947   8947       statePtr = chanPtr->state;
  8948         -    if ((statePtr->flags & mask) == 0) {
         8948  +    if ( ((statePtr->flags | TCL_EXCEPTION) & mask) == 0) {
  8949   8949   	Tcl_SetObjResult(interp, Tcl_ObjPrintf("channel is not %s",
  8950   8950   		(mask == TCL_READABLE) ? "readable" : "writable"));
  8951   8951   	return TCL_ERROR;
  8952   8952       }
  8953   8953   
  8954   8954       /*
  8955   8955        * If we are supposed to return the script, do so.

Changes to tests/chanio.test.

  5494   5494       chan event gorp readable
  5495   5495   } -returnCodes error -result {can not find channel named "gorp"}
  5496   5496   test chan-io-41.4 {Tcl_FileeventCmd: errors} -constraints fileevent -body {
  5497   5497       chan event gorp writable
  5498   5498   } -returnCodes error -result {can not find channel named "gorp"}
  5499   5499   test chan-io-41.5 {Tcl_FileeventCmd: errors} -constraints fileevent -body {
  5500   5500       chan event gorp who-knows
  5501         -} -returnCodes error -result {bad event name "who-knows": must be readable or writable}
         5501  +} -returnCodes error -result {bad event name "who-knows": must be readable, writable, or exception}
  5502   5502   
  5503   5503   #
  5504   5504   # Test chan event on a file
  5505   5505   #
  5506   5506   
  5507   5507   set path(foo) [makeFile {} foo]
  5508   5508   set f [open $path(foo) w+]

Changes to tests/io.test.

  5793   5793       list [catch {fileevent gorp readable} msg] $msg
  5794   5794   } {1 {can not find channel named "gorp"}}
  5795   5795   test io-41.4 {Tcl_FileeventCmd: errors} {fileevent} {
  5796   5796       list [catch {fileevent gorp writable} msg] $msg
  5797   5797   } {1 {can not find channel named "gorp"}}
  5798   5798   test io-41.5 {Tcl_FileeventCmd: errors} {fileevent} {
  5799   5799       list [catch {fileevent gorp who-knows} msg] $msg
  5800         -} {1 {bad event name "who-knows": must be readable or writable}}
         5800  +} {1 {bad event name "who-knows": must be readable, writable, or exception}}
  5801   5801   
  5802   5802   #
  5803   5803   # Test fileevent on a file
  5804   5804   #
  5805   5805   
  5806   5806   set path(foo) [makeFile {} foo]
  5807   5807   set f [open $path(foo) w+]

Changes to tests/zlib.test.

   836    836       after cancel {set ::total timeout}
   837    837       after cancel {set ::total done}
   838    838       set ::total
   839    839   } -cleanup {
   840    840       close $srv
   841    841       rename bgerror {}
   842    842   } -returnCodes error \
   843         -  -result {bad event name "xyzzy": must be readable or writable}
          843  +  -result {bad event name "xyzzy": must be readable, writable, or exception}
   844    844   test zlib-10.1 "bug #2818131 (mismatch read)" -constraints {
   845    845       zlib
   846    846   } -setup {
   847    847       proc bgerror {s} {set ::total [list error $s]}
   848    848       proc zlibRead {c} {
   849    849           set d [read $c]
   850    850           if {[eof $c]} {

Changes to unix/tclEpollNotfy.c.

   217    217   	int isNew)
   218    218   {
   219    219       struct epoll_event newEvent;
   220    220       struct PlatformEventData *newPedPtr;
   221    221       struct stat fdStat;
   222    222   
   223    223       newEvent.events = 0;
   224         -    if (filePtr->mask & (TCL_READABLE | TCL_EXCEPTION)) {
          224  +    if (filePtr->mask & TCL_EXCEPTION) {
          225  +	newEvent.events |= EPOLLERR | EPOLLPRI;
          226  +    }
          227  +    if (filePtr->mask & TCL_READABLE) {
   225    228   	newEvent.events |= EPOLLIN;
   226    229       }
   227    230       if (filePtr->mask & TCL_WRITABLE) {
   228    231   	newEvent.events |= EPOLLOUT;
   229    232       }
   230    233       if (isNew) {
   231    234           newPedPtr = ckalloc(sizeof(*newPedPtr));
................................................................................
   238    241       /*
   239    242        * N.B.	As discussed in Tcl_WaitForEvent(), epoll(7) does not sup-
   240    243        *		port regular files (S_IFREG.) Therefore, filePtr is in these
   241    244        *		cases simply added or deleted from the list of FileHandlers
   242    245        *		associated with regular files belonging to tsdPtr.
   243    246        */
   244    247   
   245         -    if (fstat(filePtr->fd, &fdStat) == -1) {
          248  +    if (newEvent.events & EPOLLERR) {
          249  +	/* if exceptions are requested, ignore file type */
          250  +    } else if (fstat(filePtr->fd, &fdStat) == -1) {
   246    251   	Tcl_Panic("fstat: %s", strerror(errno));
   247    252       } else if ((fdStat.st_mode & S_IFMT) == S_IFREG) {
   248    253   	switch (op) {
   249    254   	case EPOLL_CTL_ADD:
   250    255   	    if (isNew) {
   251    256   		LIST_INSERT_HEAD(&tsdPtr->firstReadyFileHandlerPtr, filePtr, readyNode);
   252    257   	    }
   253    258   	    break;
   254    259   	case EPOLL_CTL_DEL:
   255    260   	    LIST_REMOVE(filePtr, readyNode);
   256    261   	    break;
   257    262   	}
   258    263   	return;
   259         -   } else if (epoll_ctl(tsdPtr->eventsFd, op, filePtr->fd, &newEvent) == -1) {
          264  +   }
          265  +   if (epoll_ctl(tsdPtr->eventsFd, op, filePtr->fd, &newEvent) == -1) {
   260    266   	Tcl_Panic("epoll_ctl: %s", strerror(errno));
   261    267      }
   262    268   }
   263    269   
   264    270   /*
   265    271    *----------------------------------------------------------------------
   266    272    *