Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | merge trunk |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | novem |
Files: | files | file ages | folders |
SHA1: |
33f13ba67c8c4e1c9cb2a899d12b98d8 |
User & Date: | jan.nijtmans 2014-03-31 18:47:26 |
Context
2014-04-07
| ||
14:56 | merge trunk check-in: f24df1717c user: jan.nijtmans tags: novem | |
2014-03-31
| ||
18:47 | merge trunk check-in: 33f13ba67c user: jan.nijtmans tags: novem | |
18:44 | Add missing @TCL_LIB_FLAG@ to tcl.pc.in (derived from ticket [5bcb5026ad]) check-in: 85f74e89a1 user: jan.nijtmans tags: trunk | |
2014-03-20
| ||
10:14 | merge trunk check-in: 386ead73ae user: jan.nijtmans tags: novem | |
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 -- |
︙ | ︙ | |||
8056 8057 8058 8059 8060 8061 8062 8063 8064 8065 8066 8067 8068 8069 | 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)) { | > > > > > | 8067 8068 8069 8070 8071 8072 8073 8074 8075 8076 8077 8078 8079 8080 8081 8082 8083 8084 8085 | 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)) { |
︙ | ︙ | |||
9148 9149 9150 9151 9152 9153 9154 9155 9156 9157 9158 9159 9160 9161 | /* * 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, | > | 9164 9165 9166 9167 9168 9169 9170 9171 9172 9173 9174 9175 9176 9177 9178 | /* * 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, |
︙ | ︙ | |||
9188 9189 9190 9191 9192 9193 9194 9195 9196 9197 9198 9199 9200 9201 | /* * Update the notifier state so we don't block while there is still data * in the buffers. */ done: UpdateInterest(chanPtr); return copied; } /* *---------------------------------------------------------------------- * * CopyAndTranslateBuffer -- | > | 9205 9206 9207 9208 9209 9210 9211 9212 9213 9214 9215 9216 9217 9218 9219 | /* * 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.
︙ | ︙ | |||
1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 | note [eof $c] set res } -cleanup { close $c rename foo {} unset res } -result {{read rc* 4096} {} 0} # --- === *** ########################### # method write test iocmd-24.1 {chan write, regular write} -match glob -body { set res {} proc foo {args} { | > > > > > > > > > > > > > > | 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 | note [eof $c] set res } -cleanup { close $c rename foo {} unset res } -result {{read rc* 4096} {} 0} test iocmd-23.11 {chan read, close pulls the rug out} -match glob -body { set res {} proc foo {args} { oninit; onfinal; track 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} { |
︙ | ︙ |
Changes to tests/ioTrans.test.
︙ | ︙ | |||
532 533 534 535 536 537 538 539 540 541 542 543 544 545 | chan pop $fd chan push $fd [list foo $fd] } set c [chan push [set c [tempchan]] [list foo $c]] lappend res [read $c] #lappend res [gets $c] } -cleanup { tempdone rename foo {} } -result {{read rt* {test data }} file*} test iortrans-4.9 {chan read, gets, bug 2921116} -setup { set res {} } -match glob -body { | > > > > > > > > > > > > > > > > > > > | 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 | chan pop $fd chan push $fd [list foo $fd] } set c [chan push [set c [tempchan]] [list foo $c]] lappend res [read $c] #lappend res [gets $c] } -cleanup { tempdone rename foo {} } -result {{read rt* {test data }} file*} test iortrans-4.8.1 {chan read, bug 721ec69271} -setup { set res {} } -match glob -body { proc foo {fd args} { handle.initialize handle.finalize lappend ::res $args # Kill and recreate transform while it is operating chan pop $fd chan push $fd [list foo $fd] } set c [chan push [set c [tempchan]] [list foo $c]] chan configure $c -buffersize 2 lappend res [read $c] } -cleanup { tempdone rename foo {} } -result {{read rt* {test data }} file*} test iortrans-4.9 {chan read, gets, bug 2921116} -setup { set res {} } -match glob -body { |
︙ | ︙ |
Changes to tests/iogt.test.
︙ | ︙ | |||
215 216 217 218 219 220 221 222 223 224 225 226 227 228 | #catch {puts stdout "\t>* $res" ; flush stdout} #catch {puts stdout "x$res"} msg lappend trail [list $op $data $res] return $res } proc counter {var op data} { namespace upvar [namespace current] $var n switch -- $op { create/write - create/read - delete/write - delete/read - clear_read { #ignore | > > > > > > > > > > > > > > > > > > > > | 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 | #catch {puts stdout "\t>* $res" ; flush stdout} #catch {puts stdout "x$res"} msg lappend trail [list $op $data $res] return $res } proc id_torture {chan op data} { switch -- $op { create/write - create/read - delete/write - delete/read - clear_read {;#ignore} flush/write - flush/read - write - read { testchannel unstack $chan testchannel transform $chan \ -command [namespace code [list id_torture $chan]] return $data } query/maxRead {return -1} } } proc counter {var op data} { namespace upvar [namespace current] $var n switch -- $op { create/write - create/read - delete/write - delete/read - clear_read { #ignore |
︙ | ︙ | |||
322 323 324 325 326 327 328 329 330 331 332 333 334 335 | } proc audit_ops {var -attach channel} { testchannel transform $channel -command [namespace code [list id_optrail $var]] } proc audit_flow {var -attach channel} { testchannel transform $channel -command [namespace code [list id_fulltrail $var]] } proc stopafter {var n -attach channel} { namespace upvar [namespace current] $var vn set vn $n testchannel transform $channel -command [namespace code [list counter $var]] } proc stopafter_audit {var trail n -attach channel} { namespace upvar [namespace current] $var vn | > > > > > | 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 | } proc audit_ops {var -attach channel} { testchannel transform $channel -command [namespace code [list id_optrail $var]] } proc audit_flow {var -attach channel} { testchannel transform $channel -command [namespace code [list id_fulltrail $var]] } proc torture {-attach channel} { testchannel transform $channel -command [namespace code [list id_torture $channel]] } proc stopafter {var n -attach channel} { namespace upvar [namespace current] $var vn set vn $n testchannel transform $channel -command [namespace code [list counter $var]] } proc stopafter_audit {var trail n -attach channel} { namespace upvar [namespace current] $var vn |
︙ | ︙ | |||
541 542 543 544 545 546 547 548 549 550 551 552 553 554 | write %^&*()_+-= %^&*()_+-= write { } { } delete/read {} *ignored* flush/write {} {} delete/write {} *ignored*} test iogt-3.0 {Tcl_Channel valid after stack/unstack, fevent handling} -setup { proc DoneCopy {n {err {}}} { variable copy 1 } } -constraints {testchannel hangs} -body { # This test to check the validity of aquired Tcl_Channel references is not | > > > > > > > > > > | 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 | write %^&*()_+-= %^&*()_+-= write { } { } delete/read {} *ignored* flush/write {} {} delete/write {} *ignored*} test iogt-2.4 {basic I/O, mixed trail} {testchannel} { set fh [open $path(dummy) r] torture -attach $fh chan configure $fh -buffersize 2 set x [read $fh] testchannel unstack $fh close $fh set x } {} test iogt-3.0 {Tcl_Channel valid after stack/unstack, fevent handling} -setup { proc DoneCopy {n {err {}}} { variable copy 1 } } -constraints {testchannel hangs} -body { # This test to check the validity of aquired Tcl_Channel references is not |
︙ | ︙ |
Changes to unix/tcl.pc.in.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # tcl pkg-config source file prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: Tool Command Language Description: Tcl is a powerful, easy-to-learn dynamic programming language, suitable for a wide range of uses. URL: http://www.tcl.tk/ Version: @TCL_VERSION@ Requires: Conflicts: | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | # tcl pkg-config source file prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: Tool Command Language Description: Tcl is a powerful, easy-to-learn dynamic programming language, suitable for a wide range of uses. URL: http://www.tcl.tk/ Version: @TCL_VERSION@ Requires: Conflicts: Libs: -L${libdir} @TCL_LIB_FLAG@ @TCL_LIBS@ Cflags: -I${includedir} |
Changes to unix/tclUnixFCmd.c.
︙ | ︙ | |||
85 86 87 88 89 90 91 | static int SetOwnerAttribute(Tcl_Interp *interp, int objIndex, Tcl_Obj *fileName, Tcl_Obj *attributePtr); static int SetPermissionsAttribute(Tcl_Interp *interp, int objIndex, Tcl_Obj *fileName, Tcl_Obj *attributePtr); static int GetModeFromPermString(Tcl_Interp *interp, const char *modeStringPtr, mode_t *modePtr); | | | | | 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | static int SetOwnerAttribute(Tcl_Interp *interp, int objIndex, Tcl_Obj *fileName, Tcl_Obj *attributePtr); static int SetPermissionsAttribute(Tcl_Interp *interp, int objIndex, Tcl_Obj *fileName, Tcl_Obj *attributePtr); static int GetModeFromPermString(Tcl_Interp *interp, const char *modeStringPtr, mode_t *modePtr); #if defined(HAVE_CHFLAGS) && defined(UF_IMMUTABLE) || defined(__CYGWIN__) static int GetUnixFileAttributes(Tcl_Interp *interp, int objIndex, Tcl_Obj *fileName, Tcl_Obj **attributePtrPtr); static int SetUnixFileAttributes(Tcl_Interp *interp, int objIndex, Tcl_Obj *fileName, Tcl_Obj *attributePtr); #endif /* * Prototype for the TraverseUnixTree callback function. */ |
︙ | ︙ | |||
118 119 120 121 122 123 124 | */ extern TclFileAttrProcs tclpFileAttrProcs[]; extern const char *const tclpFileAttrStrings[]; #else /* !DJGPP */ enum { | > > > > > > > | | > > > > > > > > > > | | > > > > > > > > > | | > > > | 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | */ extern TclFileAttrProcs tclpFileAttrProcs[]; extern const char *const tclpFileAttrStrings[]; #else /* !DJGPP */ enum { #if defined(__CYGWIN__) UNIX_ARCHIVE_ATTRIBUTE, #endif UNIX_GROUP_ATTRIBUTE, #if defined(__CYGWIN__) UNIX_HIDDEN_ATTRIBUTE, #endif UNIX_OWNER_ATTRIBUTE, UNIX_PERMISSIONS_ATTRIBUTE, #if defined(HAVE_CHFLAGS) && defined(UF_IMMUTABLE) || defined(__CYGWIN__) UNIX_READONLY_ATTRIBUTE, #endif #if defined(__CYGWIN__) UNIX_SYSTEM_ATTRIBUTE, #endif #ifdef MAC_OSX_TCL MACOSX_CREATOR_ATTRIBUTE, MACOSX_TYPE_ATTRIBUTE, MACOSX_HIDDEN_ATTRIBUTE, MACOSX_RSRCLENGTH_ATTRIBUTE, #endif UNIX_INVALID_ATTRIBUTE /* lint - last enum value needs no trailing , */ }; MODULE_SCOPE const char *const tclpFileAttrStrings[]; const char *const tclpFileAttrStrings[] = { #if defined(__CYGWIN__) "-archive", #endif "-group", #if defined(__CYGWIN__) "-hidden", #endif "-owner", "-permissions", #if defined(HAVE_CHFLAGS) && defined(UF_IMMUTABLE) || defined(__CYGWIN__) "-readonly", #endif #if defined(__CYGWIN__) "-system", #endif #ifdef MAC_OSX_TCL "-creator", "-type", "-hidden", "-rsrclength", #endif NULL }; MODULE_SCOPE const TclFileAttrProcs tclpFileAttrProcs[]; const TclFileAttrProcs tclpFileAttrProcs[] = { #if defined(__CYGWIN__) {GetUnixFileAttributes, SetUnixFileAttributes}, #endif {GetGroupAttribute, SetGroupAttribute}, #if defined(__CYGWIN__) {GetUnixFileAttributes, SetUnixFileAttributes}, #endif {GetOwnerAttribute, SetOwnerAttribute}, {GetPermissionsAttribute, SetPermissionsAttribute}, #if defined(HAVE_CHFLAGS) && defined(UF_IMMUTABLE) || defined(__CYGWIN__) {GetUnixFileAttributes, SetUnixFileAttributes}, #endif #if defined(__CYGWIN__) {GetUnixFileAttributes, SetUnixFileAttributes}, #endif #ifdef MAC_OSX_TCL {TclMacOSXGetFileAttribute, TclMacOSXSetFileAttribute}, {TclMacOSXGetFileAttribute, TclMacOSXSetFileAttribute}, {TclMacOSXGetFileAttribute, TclMacOSXSetFileAttribute}, {TclMacOSXGetFileAttribute, TclMacOSXSetFileAttribute}, #endif |
︙ | ︙ | |||
2240 2241 2242 2243 2244 2245 2246 | * an existing writable directory; we've no recovery mechanism if it * isn't. */ return TCL_TEMPORARY_FILE_DIRECTORY; } | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 | * an existing writable directory; we've no recovery mechanism if it * isn't. */ return TCL_TEMPORARY_FILE_DIRECTORY; } #if defined(__CYGWIN__) static void StatError( Tcl_Interp *interp, /* The interp that has the error */ Tcl_Obj *fileName) /* The name of the file which caused the * error. */ { TclWinConvertError(GetLastError()); Tcl_SetObjResult(interp, Tcl_ObjPrintf("could not read \"%s\": %s", TclGetString(fileName), Tcl_PosixError(interp))); } static WCHAR * winPathFromObj( Tcl_Obj *fileName) { int size; const char *native = Tcl_FSGetNativePath(fileName); WCHAR *winPath; size = cygwin_conv_path(1, native, NULL, 0); winPath = ckalloc(size); cygwin_conv_path(1, native, winPath, size); return winPath; } static const int attributeArray[] = { 0x20, 0, 2, 0, 0, 1, 4}; /* *---------------------------------------------------------------------- * * GetUnixFileAttributes * * Gets the readonly attribute of a file. * * Results: * Standard TCL result. Returns a new Tcl_Obj in attributePtrPtr if there * is no error. The object will have ref count 0. * * Side effects: * A new object is allocated. * *---------------------------------------------------------------------- */ static int GetUnixFileAttributes( Tcl_Interp *interp, /* The interp we are using for errors. */ int objIndex, /* The index of the attribute. */ Tcl_Obj *fileName, /* The name of the file (UTF-8). */ Tcl_Obj **attributePtrPtr) /* A pointer to return the object with. */ { int fileAttributes; WCHAR *winPath = winPathFromObj(fileName); fileAttributes = GetFileAttributesW(winPath); ckfree(winPath); if (fileAttributes == -1) { StatError(interp, fileName); return TCL_ERROR; } *attributePtrPtr = Tcl_NewIntObj((fileAttributes&attributeArray[objIndex])!=0); return TCL_OK; } /* *--------------------------------------------------------------------------- * * SetUnixFileAttributes * * Sets the readonly attribute of a file. * * Results: * Standard TCL result. * * Side effects: * The readonly attribute of the file is changed. * *--------------------------------------------------------------------------- */ static int SetUnixFileAttributes( Tcl_Interp *interp, /* The interp we are using for errors. */ int objIndex, /* The index of the attribute. */ Tcl_Obj *fileName, /* The name of the file (UTF-8). */ Tcl_Obj *attributePtr) /* The attribute to set. */ { int yesNo, fileAttributes, old; WCHAR *winPath; if (Tcl_GetBooleanFromObj(interp, attributePtr, &yesNo) != TCL_OK) { return TCL_ERROR; } winPath = winPathFromObj(fileName); fileAttributes = old = GetFileAttributesW(winPath); if (fileAttributes == -1) { ckfree(winPath); StatError(interp, fileName); return TCL_ERROR; } if (yesNo) { fileAttributes |= attributeArray[objIndex]; } else { fileAttributes &= ~attributeArray[objIndex]; } if ((fileAttributes != old) && !SetFileAttributesW(winPath, fileAttributes)) { ckfree(winPath); StatError(interp, fileName); return TCL_ERROR; } ckfree(winPath); return TCL_OK; } #elif defined(HAVE_CHFLAGS) && defined(UF_IMMUTABLE) /* *---------------------------------------------------------------------- * * GetUnixFileAttributes * * Gets the readonly attribute (user immutable flag) of a file. * * Results: * Standard TCL result. Returns a new Tcl_Obj in attributePtrPtr if there * is no error. The object will have ref count 0. * * Side effects: * A new object is allocated. * *---------------------------------------------------------------------- */ static int GetUnixFileAttributes( Tcl_Interp *interp, /* The interp we are using for errors. */ int objIndex, /* The index of the attribute. */ Tcl_Obj *fileName, /* The name of the file (UTF-8). */ Tcl_Obj **attributePtrPtr) /* A pointer to return the object with. */ { Tcl_StatBuf statBuf; int result; |
︙ | ︙ | |||
2287 2288 2289 2290 2291 2292 2293 | return TCL_OK; } /* *--------------------------------------------------------------------------- * | | | | 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 | return TCL_OK; } /* *--------------------------------------------------------------------------- * * SetUnixFileAttributes * * Sets the readonly attribute (user immutable flag) of a file. * * Results: * Standard TCL result. * * Side effects: * The readonly attribute of the file is changed. * *--------------------------------------------------------------------------- */ static int SetUnixFileAttributes( Tcl_Interp *interp, /* The interp we are using for errors. */ int objIndex, /* The index of the attribute. */ Tcl_Obj *fileName, /* The name of the file (UTF-8). */ Tcl_Obj *attributePtr) /* The attribute to set. */ { Tcl_StatBuf statBuf; int result, readonly; |
︙ | ︙ |
Changes to unix/tclUnixPort.h.
︙ | ︙ | |||
89 90 91 92 93 94 95 96 97 98 99 100 101 102 | __declspec(dllimport) extern __stdcall int GetModuleFileNameW(void *, const char *, int); __declspec(dllimport) extern __stdcall int WideCharToMultiByte(int, int, const char *, int, const char *, int, const char *, const char *); __declspec(dllimport) extern __stdcall int MultiByteToWideChar(int, int, const char *, int, WCHAR *, int); __declspec(dllimport) extern __stdcall void OutputDebugStringW(const WCHAR *); __declspec(dllimport) extern __stdcall int IsDebuggerPresent(); __declspec(dllimport) extern int cygwin_conv_path(int, const void *, void *, int); __declspec(dllimport) extern int cygwin_conv_path_list(int, const void *, void *, int); # define USE_PUTENV 1 # define USE_PUTENV_FOR_UNSET 1 /* On Cygwin, the environment is imported from the Cygwin DLL. */ #ifndef __x86_64__ | > > > | 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | __declspec(dllimport) extern __stdcall int GetModuleFileNameW(void *, const char *, int); __declspec(dllimport) extern __stdcall int WideCharToMultiByte(int, int, const char *, int, const char *, int, const char *, const char *); __declspec(dllimport) extern __stdcall int MultiByteToWideChar(int, int, const char *, int, WCHAR *, int); __declspec(dllimport) extern __stdcall void OutputDebugStringW(const WCHAR *); __declspec(dllimport) extern __stdcall int IsDebuggerPresent(); __declspec(dllimport) extern __stdcall int GetLastError(); __declspec(dllimport) extern __stdcall int GetFileAttributesW(const WCHAR *); __declspec(dllimport) extern __stdcall int SetFileAttributesW(const WCHAR *, int); __declspec(dllimport) extern int cygwin_conv_path(int, const void *, void *, int); __declspec(dllimport) extern int cygwin_conv_path_list(int, const void *, void *, int); # define USE_PUTENV 1 # define USE_PUTENV_FOR_UNSET 1 /* On Cygwin, the environment is imported from the Cygwin DLL. */ #ifndef __x86_64__ |
︙ | ︙ |
Changes to win/tclWinChan.c.
︙ | ︙ | |||
658 659 660 661 662 663 664 665 666 667 668 669 670 671 | { FileInfo *infoPtr = instanceData; DWORD bytesRead; *errorCode = 0; /* * Note that we will block on reads from a console buffer until a full * line has been entered. The only way I know of to get around this is to * write a console driver. We should probably do this at some point, but * for now, we just block. The same problem exists for files being read * over the network. */ | > > > > | 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 | { FileInfo *infoPtr = instanceData; DWORD bytesRead; *errorCode = 0; /* * TODO: This comment appears to be out of date. We *do* have a * console driver, over in tclWinConsole.c. After some Windows * developer confirms, this comment should be revised. * * Note that we will block on reads from a console buffer until a full * line has been entered. The only way I know of to get around this is to * write a console driver. We should probably do this at some point, but * for now, we just block. The same problem exists for files being read * over the network. */ |
︙ | ︙ |
Changes to win/tclWinConsole.c.
︙ | ︙ | |||
752 753 754 755 756 757 758 759 760 761 762 763 764 765 | * Attempt to read bufSize bytes. The read will return immediately if * there is any data available. Otherwise it will block until at least one * byte is available or an EOF occurs. */ if (ReadConsoleBytes(infoPtr->handle, (LPVOID) buf, (DWORD) bufSize, &count) == TRUE) { buf[count] = '\0'; return count; } return -1; } | > > > > > > > | 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 | * Attempt to read bufSize bytes. The read will return immediately if * there is any data available. Otherwise it will block until at least one * byte is available or an EOF occurs. */ if (ReadConsoleBytes(infoPtr->handle, (LPVOID) buf, (DWORD) bufSize, &count) == TRUE) { /* * TODO: This potentially writes beyond the limits specified * by the caller. In practice this is harmless, since all writes * are into ChannelBuffers, and those have padding, but still * ought to remove this, unless some Windows wizard can give * a reason not to. */ buf[count] = '\0'; return count; } return -1; } |
︙ | ︙ |
Changes to win/tclWinFCmd.c.
︙ | ︙ | |||
1821 1822 1823 1824 1825 1826 1827 | static int SetWinFileAttributes( Tcl_Interp *interp, /* The interp we are using for errors. */ int objIndex, /* The index of the attribute. */ Tcl_Obj *fileName, /* The name of the file. */ Tcl_Obj *attributePtr) /* The new value of the attribute. */ { | | | > | | 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 | static int SetWinFileAttributes( Tcl_Interp *interp, /* The interp we are using for errors. */ int objIndex, /* The index of the attribute. */ Tcl_Obj *fileName, /* The name of the file. */ Tcl_Obj *attributePtr) /* The new value of the attribute. */ { DWORD fileAttributes, old; int yesNo, result; const TCHAR *nativeName; nativeName = Tcl_FSGetNativePath(fileName); fileAttributes = old = GetFileAttributes(nativeName); if (fileAttributes == 0xffffffff) { StatError(interp, fileName); return TCL_ERROR; } result = Tcl_GetBooleanFromObj(interp, attributePtr, &yesNo); if (result != TCL_OK) { return result; } if (yesNo) { fileAttributes |= (attributeArray[objIndex]); } else { fileAttributes &= ~(attributeArray[objIndex]); } if ((fileAttributes != old) && !SetFileAttributes(nativeName, fileAttributes)) { StatError(interp, fileName); return TCL_ERROR; } return result; } |
︙ | ︙ |
Changes to win/tclWinPipe.c.
︙ | ︙ | |||
77 78 79 80 81 82 83 84 85 86 87 88 89 90 | /* * Bit masks used in the sharedFlags field of the PipeInfo structure below. */ #define PIPE_EOF (1<<2) /* Pipe has reached EOF. */ #define PIPE_EXTRABYTE (1<<3) /* The reader thread has consumed one byte. */ /* * This structure describes per-instance data for a pipe based channel. */ typedef struct PipeInfo { struct PipeInfo *nextPtr; /* Pointer to next registered pipe. */ Tcl_Channel channel; /* Pointer to channel structure. */ | > > > > > > | 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | /* * Bit masks used in the sharedFlags field of the PipeInfo structure below. */ #define PIPE_EOF (1<<2) /* Pipe has reached EOF. */ #define PIPE_EXTRABYTE (1<<3) /* The reader thread has consumed one byte. */ /* * TODO: It appears the whole EXTRABYTE machinery is in place to support * outdated Win 95 systems. If this can be confirmed, much code can be * deleted. */ /* * This structure describes per-instance data for a pipe based channel. */ typedef struct PipeInfo { struct PipeInfo *nextPtr; /* Pointer to next registered pipe. */ Tcl_Channel channel; /* Pointer to channel structure. */ |
︙ | ︙ |