Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Merge minimal fix for iocmd-23.11. Note that top channel regeneration is removed, so that Preserve/Release call pairs are sure to operate on the same pointers. Other bug fixes may need to change that. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
4c19c3927610d872576317bfddcb4267 |
User & Date: | dgp 2014-03-28 20:29:03 |
Context
2014-03-31
| ||
18:44 | Add missing @TCL_LIB_FLAG@ to tcl.pc.in (derived from ticket [5bcb5026ad]) check-in: 85f74e89a1 user: jan.nijtmans tags: trunk | |
08:09 | merge trunk check-in: 0f642ee045 user: dkf tags: dkf-http-cookies | |
2014-03-28
| ||
20:29 | Merge minimal fix for iocmd-23.11. Note that top channel regeneration is removed, so that Preserve/R... check-in: 4c19c39276 user: dgp tags: trunk | |
2014-03-27
| ||
21:35 | Minimal patch to fix iocmd-23.11. Might not be the best fix, but is *a* fix. check-in: b846182cdc user: dgp tags: core-8-5-branch | |
19:15 | Test iocmd-23.11 demos another segfault. check-in: 045e8076eb user: dgp tags: trunk | |
Changes
Changes to generic/tclIO.c.
︙ | ︙ | |||
4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 | } /* * This operation should occur at the top of a channel stack. */ chanPtr = statePtr->topChanPtr; bufPtr = statePtr->inQueueHead; encoding = statePtr->encoding; /* * Preserved so we can restore the channel's state in case we don't find a * newline in the available input. | > | 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 | } /* * This operation should occur at the top of a channel stack. */ chanPtr = statePtr->topChanPtr; Tcl_Preserve(chanPtr); bufPtr = statePtr->inQueueHead; encoding = statePtr->encoding; /* * Preserved so we can restore the channel's state in case we don't find a * newline in the available input. |
︙ | ︙ | |||
4489 4490 4491 4492 4493 4494 4495 | */ gotEOL: /* * Regenerate the top channel, in case it was changed due to * self-modifying reflected transforms. */ | | > | 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 | */ gotEOL: /* * Regenerate the top channel, in case it was changed due to * self-modifying reflected transforms. */ /* chanPtr = statePtr->topChanPtr; */ bufPtr = gs.bufPtr; if (bufPtr == NULL) { Tcl_Panic("Tcl_GetsObj: gotEOL reached with bufPtr==NULL"); } statePtr->inputEncodingState = gs.state; Tcl_ExternalToUtf(NULL, gs.encoding, RemovePoint(bufPtr), gs.rawRead, |
︙ | ︙ | |||
4524 4525 4526 4527 4528 4529 4530 | */ restore: /* * Regenerate the top channel, in case it was changed due to * self-modifying reflected transforms. */ | | | | 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 | */ restore: /* * Regenerate the top channel, in case it was changed due to * self-modifying reflected transforms. */ /* chanPtr = statePtr->topChanPtr; */ bufPtr = statePtr->inQueueHead; if (bufPtr == NULL) { Tcl_Panic("Tcl_GetsObj: restore reached with bufPtr==NULL"); } bufPtr->nextRemoved = oldRemoved; for (bufPtr = bufPtr->nextPtr; bufPtr != NULL; bufPtr = bufPtr->nextPtr) { |
︙ | ︙ | |||
4566 4567 4568 4569 4570 4571 4572 | */ done: /* * Regenerate the top channel, in case it was changed due to * self-modifying reflected transforms. */ | | | > | 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 | */ done: /* * Regenerate the top channel, in case it was changed due to * self-modifying reflected transforms. */ /* chanPtr = statePtr->topChanPtr; */ UpdateInterest(chanPtr); Tcl_Release(chanPtr); return copiedTotal; } /* *--------------------------------------------------------------------------- * * TclGetsObjBinary -- |
︙ | ︙ | |||
4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 | unsigned char *dst, *dstEnd, *eol, *eof, *byteArray; /* * This operation should occur at the top of a channel stack. */ chanPtr = statePtr->topChanPtr; bufPtr = statePtr->inQueueHead; /* * Preserved so we can restore the channel's state in case we don't find a * newline in the available input. */ | > | 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 | unsigned char *dst, *dstEnd, *eol, *eof, *byteArray; /* * This operation should occur at the top of a channel stack. */ chanPtr = statePtr->topChanPtr; Tcl_Preserve(chanPtr); bufPtr = statePtr->inQueueHead; /* * Preserved so we can restore the channel's state in case we don't find a * newline in the available input. */ |
︙ | ︙ | |||
4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 | /* * Update the notifier state so we don't block while there is still data * in the buffers. */ done: UpdateInterest(chanPtr); return copiedTotal; } /* *--------------------------------------------------------------------------- * * FreeBinaryEncoding -- | > | 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 | /* * Update the notifier state so we don't block while there is still data * in the buffers. */ done: UpdateInterest(chanPtr); Tcl_Release(chanPtr); return copiedTotal; } /* *--------------------------------------------------------------------------- * * FreeBinaryEncoding -- |
︙ | ︙ | |||
5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 | /* * Check for information in the push-back buffers. If there is some, use * it. Go to the driver only if there is none (anymore) and the caller * requests more bytes. */ for (copied = 0; copied < bytesToRead; copied += copiedNow) { copiedNow = CopyBuffer(chanPtr, bufPtr + copied, bytesToRead - copied); if (copiedNow == 0) { if (GotFlag(statePtr, CHANNEL_EOF)) { goto done; } | > | 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 | /* * Check for information in the push-back buffers. If there is some, use * it. Go to the driver only if there is none (anymore) and the caller * requests more bytes. */ Tcl_Preserve(chanPtr); for (copied = 0; copied < bytesToRead; copied += copiedNow) { copiedNow = CopyBuffer(chanPtr, bufPtr + copied, bytesToRead - copied); if (copiedNow == 0) { if (GotFlag(statePtr, CHANNEL_EOF)) { goto done; } |
︙ | ︙ | |||
5372 5373 5374 5375 5376 5377 5378 | if ((result == EWOULDBLOCK) || (result == EAGAIN)) { if (copied > 0) { /* * Information that was copied earlier has precedence * over EAGAIN/WOULDBLOCK handling. */ | | | > | > > | 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 | if ((result == EWOULDBLOCK) || (result == EAGAIN)) { if (copied > 0) { /* * Information that was copied earlier has precedence * over EAGAIN/WOULDBLOCK handling. */ goto done; } SetFlag(statePtr, CHANNEL_BLOCKED); result = EAGAIN; } Tcl_SetErrno(result); copied = -1; goto done; } copied += nread; goto done; } } done: Tcl_Release(chanPtr); return copied; } /* *--------------------------------------------------------------------------- * * Tcl_ReadChars -- |
︙ | ︙ | |||
5495 5496 5497 5498 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508 | /* * This operation should occur at the top of a channel stack. */ chanPtr = statePtr->topChanPtr; encoding = statePtr->encoding; factor = UTF_EXPANSION_FACTOR; if (appendFlag == 0) { if (encoding == NULL) { Tcl_SetByteArrayLength(objPtr, 0); } else { Tcl_SetObjLength(objPtr, 0); | > | 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 5516 5517 5518 | /* * This operation should occur at the top of a channel stack. */ chanPtr = statePtr->topChanPtr; encoding = statePtr->encoding; factor = UTF_EXPANSION_FACTOR; Tcl_Preserve(chanPtr); if (appendFlag == 0) { if (encoding == NULL) { Tcl_SetByteArrayLength(objPtr, 0); } else { Tcl_SetObjLength(objPtr, 0); |
︙ | ︙ | |||
5586 5587 5588 5589 5590 5591 5592 | */ done: /* * Regenerate the top channel, in case it was changed due to * self-modifying reflected transforms. */ | | | > | 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613 5614 | */ done: /* * Regenerate the top channel, in case it was changed due to * self-modifying reflected transforms. */ /* chanPtr = statePtr->topChanPtr; */ UpdateInterest(chanPtr); Tcl_Release(chanPtr); return copied; } /* *--------------------------------------------------------------------------- * * ReadBytes -- |
︙ | ︙ | |||
8097 8098 8099 8100 8101 8102 8103 8104 8105 8106 8107 8108 8109 8110 | static void UpdateInterest( Channel *chanPtr) /* Channel to update. */ { ChannelState *statePtr = chanPtr->state; /* State info for channel */ int mask = statePtr->interestMask; /* * If there are flushed buffers waiting to be written, then we need to * watch for the channel to become writable. */ if (GotFlag(statePtr, BG_FLUSH_SCHEDULED)) { | > > > > > | 8108 8109 8110 8111 8112 8113 8114 8115 8116 8117 8118 8119 8120 8121 8122 8123 8124 8125 8126 | static void UpdateInterest( Channel *chanPtr) /* Channel to update. */ { ChannelState *statePtr = chanPtr->state; /* State info for channel */ int mask = statePtr->interestMask; if (chanPtr->typePtr == NULL) { /* Do not update interest on a closed channel */ return; } /* * If there are flushed buffers waiting to be written, then we need to * watch for the channel to become writable. */ if (GotFlag(statePtr, BG_FLUSH_SCHEDULED)) { |
︙ | ︙ | |||
9201 9202 9203 9204 9205 9206 9207 9208 9209 9210 9211 9212 9213 9214 | /* * If we have not encountered a sticky EOF, clear the EOF bit. Either way * clear the BLOCKED bit. We want to discover these anew during each * operation. */ if (!GotFlag(statePtr, CHANNEL_STICKY_EOF)) { ResetFlag(statePtr, CHANNEL_EOF); } ResetFlag(statePtr, CHANNEL_BLOCKED | CHANNEL_NEED_MORE_DATA); for (copied = 0; copied < toRead; copied += copiedNow) { copiedNow = CopyAndTranslateBuffer(statePtr, bufPtr + copied, | > | 9217 9218 9219 9220 9221 9222 9223 9224 9225 9226 9227 9228 9229 9230 9231 | /* * If we have not encountered a sticky EOF, clear the EOF bit. Either way * clear the BLOCKED bit. We want to discover these anew during each * operation. */ Tcl_Preserve(chanPtr); if (!GotFlag(statePtr, CHANNEL_STICKY_EOF)) { ResetFlag(statePtr, CHANNEL_EOF); } ResetFlag(statePtr, CHANNEL_BLOCKED | CHANNEL_NEED_MORE_DATA); for (copied = 0; copied < toRead; copied += copiedNow) { copiedNow = CopyAndTranslateBuffer(statePtr, bufPtr + copied, |
︙ | ︙ | |||
9241 9242 9243 9244 9245 9246 9247 9248 9249 9250 9251 9252 9253 9254 | /* * Update the notifier state so we don't block while there is still data * in the buffers. */ done: UpdateInterest(chanPtr); return copied; } /* *---------------------------------------------------------------------- * * CopyAndTranslateBuffer -- | > | 9258 9259 9260 9261 9262 9263 9264 9265 9266 9267 9268 9269 9270 9271 9272 | /* * Update the notifier state so we don't block while there is still data * in the buffers. */ done: UpdateInterest(chanPtr); Tcl_Release(chanPtr); return copied; } /* *---------------------------------------------------------------------- * * CopyAndTranslateBuffer -- |
︙ | ︙ |
Changes to generic/tclIORChan.c.
︙ | ︙ | |||
582 583 584 585 586 587 588 589 590 591 592 593 594 595 | */ rcId = NextHandle(); rcPtr = NewReflectedChannel(interp, cmdObj, mode, rcId); chan = Tcl_CreateChannel(&tclRChannelType, TclGetString(rcId), rcPtr, mode); rcPtr->chan = chan; chanPtr = (Channel *) chan; /* * Invoke 'initialize' and validate that the handler is present and ok. * Squash the channel if not. * * Note: The conversion of 'mode' back into a Tcl_Obj ensures that | > | 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 | */ rcId = NextHandle(); rcPtr = NewReflectedChannel(interp, cmdObj, mode, rcId); chan = Tcl_CreateChannel(&tclRChannelType, TclGetString(rcId), rcPtr, mode); rcPtr->chan = chan; Tcl_Preserve(chan); chanPtr = (Channel *) chan; /* * Invoke 'initialize' and validate that the handler is present and ok. * Squash the channel if not. * * Note: The conversion of 'mode' back into a Tcl_Obj ensures that |
︙ | ︙ | |||
2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 | /* * Delete a cloned ChannelType structure. */ ckfree(chanPtr->typePtr); chanPtr->typePtr = NULL; } FreeReflectedChannelArgs(rcPtr); ckfree(rcPtr->argv); ckfree(rcPtr); } | > | 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 | /* * Delete a cloned ChannelType structure. */ ckfree(chanPtr->typePtr); chanPtr->typePtr = NULL; } Tcl_Release(chanPtr); FreeReflectedChannelArgs(rcPtr); ckfree(rcPtr->argv); ckfree(rcPtr); } |
︙ | ︙ |
Changes to tests/ioCmd.test.
︙ | ︙ | |||
1058 1059 1060 1061 1062 1063 1064 | set args [lassign $args sub id] if {$sub ne "read"} {return} close $id return {} } set c [chan create {r} foo] note [read $c] | < | | 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 | set args [lassign $args sub id] if {$sub ne "read"} {return} close $id return {} } set c [chan create {r} foo] note [read $c] rename foo {} set res } -result {{read rc* 4096} {}} # --- === *** ########################### # method write test iocmd-24.1 {chan write, regular write} -match glob -body { set res {} proc foo {args} { |
︙ | ︙ |