Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | merge trunk |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | tip-458 |
Files: | files | file ages | folders |
SHA1: |
242a7d68cddde40f75cff3d24eac2f64 |
User & Date: | jan.nijtmans 2017-04-14 13:00:46.777 |
Context
2017-04-26
| ||
13:48 | Move some variable declarations closer to where they are used. No change in functionality. check-in: cf831b219f user: jan.nijtmans tags: tip-458 | |
2017-04-14
| ||
13:00 | merge trunk check-in: 242a7d68cd user: jan.nijtmans tags: tip-458 | |
09:06 | merge core-8-6-branch check-in: 71e6ac46c0 user: jan.nijtmans tags: trunk | |
2017-03-24
| ||
10:30 | Merge trunk check-in: 16f83d748c user: jan.nijtmans tags: tip-458 | |
Changes
Changes to doc/IntObj.3.
︙ | ︙ | |||
93 94 95 96 97 98 99 | with which values might be exchanged. The C integral types for which Tcl provides value exchange routines are \fBint\fR, \fBlong int\fR, \fBTcl_WideInt\fR, and \fBmp_int\fR. The \fBint\fR and \fBlong int\fR types are provided by the C language standard. The \fBTcl_WideInt\fR type is a typedef defined to be whatever signed integral type covers at least the 64-bit integer range (-9223372036854775808 to 9223372036854775807). Depending on the platform and the C compiler, the actual type might be | | | 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | with which values might be exchanged. The C integral types for which Tcl provides value exchange routines are \fBint\fR, \fBlong int\fR, \fBTcl_WideInt\fR, and \fBmp_int\fR. The \fBint\fR and \fBlong int\fR types are provided by the C language standard. The \fBTcl_WideInt\fR type is a typedef defined to be whatever signed integral type covers at least the 64-bit integer range (-9223372036854775808 to 9223372036854775807). Depending on the platform and the C compiler, the actual type might be \fBlong int\fR, \fBlong long int\fR, \fB__int64\fR, or something else. The \fBmp_int\fR type is a multiple-precision integer type defined by the LibTomMath multiple-precision integer library. .PP The \fBTcl_NewIntObj\fR, \fBTcl_NewLongObj\fR, \fBTcl_NewWideIntObj\fR, and \fBTcl_NewBignumObj\fR routines each create and return a new Tcl value initialized to the integral value of the argument. The returned Tcl value is unshared. |
︙ | ︙ |
Changes to generic/tcl.h.
︙ | ︙ | |||
371 372 373 374 375 376 377 | /* * Define Tcl_WideInt to be a type that is (at least) 64-bits wide, and define * Tcl_WideUInt to be the unsigned variant of that type (assuming that where * we have one, we can have the other.) * * Also defines the following macros: | | | < < < | < | 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 | /* * Define Tcl_WideInt to be a type that is (at least) 64-bits wide, and define * Tcl_WideUInt to be the unsigned variant of that type (assuming that where * we have one, we can have the other.) * * Also defines the following macros: * TCL_WIDE_INT_IS_LONG - if wide ints are really longs (i.e. we're on a * LP64 system such as modern Solaris or Linux ... not including Win64) * Tcl_WideAsLong - forgetful converter from wideInt to long. * Tcl_LongAsWide - sign-extending converter from long to wideInt. * Tcl_WideAsDouble - converter from wideInt to double. * Tcl_DoubleAsWide - converter from double to wideInt. * * The following invariant should hold for any long value 'longVal': * longVal == Tcl_WideAsLong(Tcl_LongAsWide(longVal)) * * Note on converting between Tcl_WideInt and strings. This implementation (in * tclObj.c) depends on the function * sprintf(...,"%" TCL_LL_MODIFIER "d",...). */ #if !defined(TCL_WIDE_INT_TYPE)&&!defined(TCL_WIDE_INT_IS_LONG) # if defined(_WIN32) # define TCL_WIDE_INT_TYPE __int64 # define TCL_LL_MODIFIER "I64" # elif defined(__GNUC__) # define TCL_WIDE_INT_TYPE long long # define TCL_LL_MODIFIER "ll" # else /* ! _WIN32 && ! __GNUC__ */ /* * Don't know what platform it is and configure hasn't discovered what is * going on for us. Try to guess... |
︙ | ︙ | |||
419 420 421 422 423 424 425 | # define TCL_WIDE_INT_TYPE long #endif /* TCL_WIDE_INT_IS_LONG */ typedef TCL_WIDE_INT_TYPE Tcl_WideInt; typedef unsigned TCL_WIDE_INT_TYPE Tcl_WideUInt; #ifdef TCL_WIDE_INT_IS_LONG | < < < < > > | | | | < | 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 | # define TCL_WIDE_INT_TYPE long #endif /* TCL_WIDE_INT_IS_LONG */ typedef TCL_WIDE_INT_TYPE Tcl_WideInt; typedef unsigned TCL_WIDE_INT_TYPE Tcl_WideUInt; #ifdef TCL_WIDE_INT_IS_LONG # ifndef TCL_LL_MODIFIER # define TCL_LL_MODIFIER "l" # endif /* !TCL_LL_MODIFIER */ #else /* TCL_WIDE_INT_IS_LONG */ /* * The next short section of defines are only done when not running on Windows * or some other strange platform. */ # ifndef TCL_LL_MODIFIER # define TCL_LL_MODIFIER "ll" # endif /* !TCL_LL_MODIFIER */ #endif /* TCL_WIDE_INT_IS_LONG */ #define Tcl_WideAsLong(val) ((long)((Tcl_WideInt)(val))) #define Tcl_LongAsWide(val) ((Tcl_WideInt)((long)(val))) #define Tcl_WideAsDouble(val) ((double)((Tcl_WideInt)(val))) #define Tcl_DoubleAsWide(val) ((Tcl_WideInt)((double)(val))) #if defined(_WIN32) # ifdef __BORLANDC__ typedef struct stati64 Tcl_StatBuf; # elif defined(_WIN64) typedef struct __stat64 Tcl_StatBuf; # elif (defined(_MSC_VER) && (_MSC_VER < 1400)) || defined(_USE_32BIT_TIME_T) typedef struct _stati64 Tcl_StatBuf; |
︙ | ︙ |
Changes to generic/tclBasic.c.
︙ | ︙ | |||
1067 1068 1069 1070 1071 1072 1073 | Tcl_InterpDeleteProc *proc, /* Function to call when interpreter is about * to be deleted. */ ClientData clientData) /* One-word value to pass to proc. */ { Interp *iPtr = (Interp *) interp; static Tcl_ThreadDataKey assocDataCounterKey; int *assocDataCounterPtr = | | | 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 | Tcl_InterpDeleteProc *proc, /* Function to call when interpreter is about * to be deleted. */ ClientData clientData) /* One-word value to pass to proc. */ { Interp *iPtr = (Interp *) interp; static Tcl_ThreadDataKey assocDataCounterKey; int *assocDataCounterPtr = Tcl_GetThreadData(&assocDataCounterKey, sizeof(int)); int isNew; char buffer[32 + TCL_INTEGER_SPACE]; AssocData *dPtr = ckalloc(sizeof(AssocData)); Tcl_HashEntry *hPtr; sprintf(buffer, "Assoc Data Key #%d", *assocDataCounterPtr); (*assocDataCounterPtr)++; |
︙ | ︙ | |||
5876 5877 5878 5879 5880 5881 5882 | * system in Tcl 8.0, we have to mirror the object result back into the * string result (some callers may expect it there). */ (void) Tcl_GetStringResult(interp); return code; } | < | 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 5888 5889 | * system in Tcl 8.0, we have to mirror the object result back into the * string result (some callers may expect it there). */ (void) Tcl_GetStringResult(interp); return code; } /* *---------------------------------------------------------------------- * * Tcl_EvalObj, Tcl_GlobalEvalObj -- * * These functions are deprecated but we keep them around for backwards |
︙ | ︙ | |||
5911 5912 5913 5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 | int Tcl_GlobalEvalObj( Tcl_Interp *interp, Tcl_Obj *objPtr) { return Tcl_EvalObjEx(interp, objPtr, TCL_EVAL_GLOBAL); } /* *---------------------------------------------------------------------- * * Tcl_EvalObjEx, TclEvalObjEx -- * * Execute Tcl commands stored in a Tcl object. These commands are | > | 5910 5911 5912 5913 5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 | int Tcl_GlobalEvalObj( Tcl_Interp *interp, Tcl_Obj *objPtr) { return Tcl_EvalObjEx(interp, objPtr, TCL_EVAL_GLOBAL); } #endif /* TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------- * * Tcl_EvalObjEx, TclEvalObjEx -- * * Execute Tcl commands stored in a Tcl object. These commands are |
︙ | ︙ | |||
8766 8767 8768 8769 8770 8771 8772 8773 8774 8775 8776 8777 8778 8779 | return TCL_OK; } /* *---------------------------------------------------------------------- * * NRCoroInjectObjCmd -- * * Implementation of [::tcl::unsupported::inject] command. * *---------------------------------------------------------------------- */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 8766 8767 8768 8769 8770 8771 8772 8773 8774 8775 8776 8777 8778 8779 8780 8781 8782 8783 8784 8785 8786 8787 8788 8789 8790 8791 8792 8793 8794 8795 8796 8797 8798 8799 8800 8801 8802 8803 8804 8805 8806 8807 8808 | return TCL_OK; } /* *---------------------------------------------------------------------- * * TclNREvalList -- * * Callback to invoke command as list, used in order to delayed * processing of canonical list command in sane environment. * *---------------------------------------------------------------------- */ static int TclNREvalList( ClientData data[], Tcl_Interp *interp, int result) { int objc; Tcl_Obj **objv; Tcl_Obj *listPtr = data[0]; Tcl_IncrRefCount(listPtr); TclMarkTailcall(interp); TclNRAddCallback(interp, TclNRReleaseValues, listPtr, NULL, NULL,NULL); TclListObjGetElements(NULL, listPtr, &objc, &objv); return TclNREvalObjv(interp, objc, objv, 0, NULL); } /* *---------------------------------------------------------------------- * * NRCoroInjectObjCmd -- * * Implementation of [::tcl::unsupported::inject] command. * *---------------------------------------------------------------------- */ |
︙ | ︙ | |||
8817 8818 8819 8820 8821 8822 8823 | /* * Add the callback to the coro's execEnv, so that it is the first thing * to happen when the coro is resumed. */ iPtr->execEnvPtr = corPtr->eePtr; | | > | 8846 8847 8848 8849 8850 8851 8852 8853 8854 8855 8856 8857 8858 8859 8860 8861 | /* * Add the callback to the coro's execEnv, so that it is the first thing * to happen when the coro is resumed. */ iPtr->execEnvPtr = corPtr->eePtr; TclNRAddCallback(interp, TclNREvalList, Tcl_NewListObj(objc-2, objv+2), NULL, NULL, NULL); iPtr->execEnvPtr = savedEEPtr; return TCL_OK; } int TclNRInterpCoroutine( |
︙ | ︙ |
Changes to generic/tclCkalloc.c.
︙ | ︙ | |||
85 86 87 88 89 90 91 | * mem_header. It is used to get back to the header pointer from the body * pointer that's used by clients. */ #define BODY_OFFSET \ ((size_t) (&((struct mem_header *) 0)->body)) | | | | | | | | 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | * mem_header. It is used to get back to the header pointer from the body * pointer that's used by clients. */ #define BODY_OFFSET \ ((size_t) (&((struct mem_header *) 0)->body)) static unsigned int total_mallocs = 0; static unsigned int total_frees = 0; static size_t current_bytes_malloced = 0; static size_t maximum_bytes_malloced = 0; static unsigned int current_malloc_packets = 0; static unsigned int maximum_malloc_packets = 0; static unsigned int break_on_malloc = 0; static unsigned int trace_on_at_malloc = 0; static int alloc_tracing = FALSE; static int init_malloced_bodies = TRUE; #ifdef MEM_VALIDATE static int validate_memory = TRUE; #else static int validate_memory = FALSE; #endif |
︙ | ︙ | |||
180 181 182 183 184 185 186 | { char buf[1024]; if (clientData == NULL) { return 0; } sprintf(buf, | | | | | | | | | | 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 | { char buf[1024]; if (clientData == NULL) { return 0; } sprintf(buf, "total mallocs %10u\n" "total frees %10u\n" "current packets allocated %10u\n" "current bytes allocated %10" TCL_LL_MODIFIER "u\n" "maximum packets allocated %10u\n" "maximum bytes allocated %10" TCL_LL_MODIFIER "u\n", total_mallocs, total_frees, current_malloc_packets, (Tcl_WideInt)current_bytes_malloced, maximum_malloc_packets, (Tcl_WideInt)maximum_bytes_malloced); if (flags == 0) { fprintf((FILE *)clientData, "%s", buf); } else { /* Assume objPtr to append to */ Tcl_AppendToObj((Tcl_Obj *) clientData, buf, -1); } return 1; |
︙ | ︙ | |||
355 356 357 358 359 360 361 | return TCL_ERROR; } } Tcl_MutexLock(ckallocMutexPtr); for (memScanP = allocHead; memScanP != NULL; memScanP = memScanP->flink) { address = &memScanP->body[0]; | | < | | 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 | return TCL_ERROR; } } Tcl_MutexLock(ckallocMutexPtr); for (memScanP = allocHead; memScanP != NULL; memScanP = memScanP->flink) { address = &memScanP->body[0]; fprintf(fileP, "%p - %p %" TCL_LL_MODIFIER "d @ %s %d %s", address, address + memScanP->length - 1, (Tcl_WideInt)memScanP->length, memScanP->file, memScanP->line, (memScanP->tagPtr == NULL) ? "" : memScanP->tagPtr->string); (void) fputc('\n', fileP); } Tcl_MutexUnlock(ckallocMutexPtr); if (fileP != stderr) { |
︙ | ︙ | |||
446 447 448 449 450 451 452 | allocHead->blink = result; } allocHead = result; total_mallocs++; if (trace_on_at_malloc && (total_mallocs >= trace_on_at_malloc)) { (void) fflush(stdout); | | | | 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 | allocHead->blink = result; } allocHead = result; total_mallocs++; if (trace_on_at_malloc && (total_mallocs >= trace_on_at_malloc)) { (void) fflush(stdout); fprintf(stderr, "reached malloc trace enable point (%u)\n", total_mallocs); fflush(stderr); alloc_tracing = TRUE; trace_on_at_malloc = 0; } if (alloc_tracing) { fprintf(stderr,"ckalloc %p %u %s %d\n", result->body, size, file, line); } if (break_on_malloc && (total_mallocs >= break_on_malloc)) { break_on_malloc = 0; (void) fflush(stdout); Tcl_Panic("reached malloc break limit (%u)", total_mallocs); } current_malloc_packets++; if (current_malloc_packets > maximum_malloc_packets) { maximum_malloc_packets = current_malloc_packets; } current_bytes_malloced += size; |
︙ | ︙ | |||
844 845 846 847 848 849 850 851 852 853 | Tcl_SetObjResult(interp, Tcl_ObjPrintf("error accessing %s: %s", argv[2], Tcl_PosixError(interp))); return TCL_ERROR; } return TCL_OK; } if (strcmp(argv[1],"break_on_malloc") == 0) { if (argc != 3) { goto argError; } | > | > | | | | 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 | Tcl_SetObjResult(interp, Tcl_ObjPrintf("error accessing %s: %s", argv[2], Tcl_PosixError(interp))); return TCL_ERROR; } return TCL_OK; } if (strcmp(argv[1],"break_on_malloc") == 0) { int value; if (argc != 3) { goto argError; } if (Tcl_GetInt(interp, argv[2], &value) != TCL_OK) { return TCL_ERROR; } break_on_malloc = (unsigned int) value; return TCL_OK; } if (strcmp(argv[1],"info") == 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "%-25s %10u\n%-25s %10u\n%-25s %10u\n%-25s %10" TCL_LL_MODIFIER"d\n%-25s %10u\n%-25s %10" TCL_LL_MODIFIER "d\n", "total mallocs", total_mallocs, "total frees", total_frees, "current packets allocated", current_malloc_packets, "current bytes allocated", (Tcl_WideInt)current_bytes_malloced, "maximum packets allocated", maximum_malloc_packets, "maximum bytes allocated", (Tcl_WideInt)maximum_bytes_malloced)); return TCL_OK; } if (strcmp(argv[1], "init") == 0) { if (argc != 3) { goto bad_suboption; } init_malloced_bodies = (strcmp(argv[2],"on") == 0); |
︙ | ︙ | |||
930 931 932 933 934 935 936 937 938 939 | goto bad_suboption; } alloc_tracing = (strcmp(argv[2],"on") == 0); return TCL_OK; } if (strcmp(argv[1],"trace_on_at_malloc") == 0) { if (argc != 3) { goto argError; } | > | > | 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 | goto bad_suboption; } alloc_tracing = (strcmp(argv[2],"on") == 0); return TCL_OK; } if (strcmp(argv[1],"trace_on_at_malloc") == 0) { int value; if (argc != 3) { goto argError; } if (Tcl_GetInt(interp, argv[2], &value) != TCL_OK) { return TCL_ERROR; } trace_on_at_malloc = value; return TCL_OK; } if (strcmp(argv[1],"validate") == 0) { if (argc != 3) { goto bad_suboption; } validate_memory = (strcmp(argv[2],"on") == 0); |
︙ | ︙ |
Changes to generic/tclClock.c.
︙ | ︙ | |||
1690 1691 1692 1693 1694 1695 1696 | const time_t *timePtr) /* Pointer to the number of seconds since the * local system's epoch */ { /* * Get a thread-local buffer to hold the returned time. */ | | | 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 | const time_t *timePtr) /* Pointer to the number of seconds since the * local system's epoch */ { /* * Get a thread-local buffer to hold the returned time. */ struct tm *tmPtr = Tcl_GetThreadData(&tmKey, sizeof(struct tm)); #ifdef HAVE_LOCALTIME_R localtime_r(timePtr, tmPtr); #else struct tm *sysTmPtr; Tcl_MutexLock(&clockMutex); sysTmPtr = localtime(timePtr); |
︙ | ︙ |
Changes to generic/tclDisassemble.c.
︙ | ︙ | |||
250 251 252 253 254 255 256 | ByteCode *codePtr = BYTECODE(objPtr); unsigned char *codeStart, *codeLimit, *pc; unsigned char *codeDeltaNext, *codeLengthNext; unsigned char *srcDeltaNext, *srcLengthNext; int codeOffset, codeLen, srcOffset, srcLen, numCmds, delta, i, line; Interp *iPtr = (Interp *) *codePtr->interpHandle; Tcl_Obj *bufferObj, *fileObj; | < < < | | | 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 | ByteCode *codePtr = BYTECODE(objPtr); unsigned char *codeStart, *codeLimit, *pc; unsigned char *codeDeltaNext, *codeLengthNext; unsigned char *srcDeltaNext, *srcLengthNext; int codeOffset, codeLen, srcOffset, srcLen, numCmds, delta, i, line; Interp *iPtr = (Interp *) *codePtr->interpHandle; Tcl_Obj *bufferObj, *fileObj; TclNewObj(bufferObj); if (codePtr->refCount <= 0) { return bufferObj; /* Already freed. */ } codeStart = codePtr->codeStart; codeLimit = codeStart + codePtr->numCodeBytes; numCmds = codePtr->numCommands; /* * Print header lines describing the ByteCode. */ Tcl_AppendPrintfToObj(bufferObj, "ByteCode %p, refCt %u, epoch %u, interp %p (epoch %u)\n", codePtr, codePtr->refCount, codePtr->compileEpoch, iPtr, iPtr->compileEpoch); Tcl_AppendToObj(bufferObj, " Source ", -1); PrintSourceToObj(bufferObj, codePtr->source, TclMin(codePtr->numSrcBytes, 55)); GetLocationInformation(interp, codePtr->procPtr, &fileObj, &line); if (line > -1 && fileObj != NULL) { Tcl_AppendPrintfToObj(bufferObj, "\n File \"%s\" Line %d", |
︙ | ︙ | |||
312 313 314 315 316 317 318 | * procedure's name since ByteCode's can be shared among procedures. */ if (codePtr->procPtr != NULL) { Proc *procPtr = codePtr->procPtr; int numCompiledLocals = procPtr->numCompiledLocals; | < | | | 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 | * procedure's name since ByteCode's can be shared among procedures. */ if (codePtr->procPtr != NULL) { Proc *procPtr = codePtr->procPtr; int numCompiledLocals = procPtr->numCompiledLocals; Tcl_AppendPrintfToObj(bufferObj, " Proc %p, refCt %d, args %d, compiled locals %d\n", procPtr, procPtr->refCount, procPtr->numArgs, numCompiledLocals); if (numCompiledLocals > 0) { CompiledLocal *localPtr = procPtr->firstLocalPtr; for (i = 0; i < numCompiledLocals; i++) { Tcl_AppendPrintfToObj(bufferObj, " slot %d%s%s%s%s%s%s", i, |
︙ | ︙ |
Changes to generic/tclEvent.c.
︙ | ︙ | |||
33 34 35 36 37 38 39 | /* * One of the structures below is associated with the "tclBgError" assoc data * for each interpreter. It keeps track of the head and tail of the list of * pending background errors for the interpreter. */ | | | 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | /* * One of the structures below is associated with the "tclBgError" assoc data * for each interpreter. It keeps track of the head and tail of the list of * pending background errors for the interpreter. */ typedef struct { Tcl_Interp *interp; /* Interpreter in which error occurred. */ Tcl_Obj *cmdPrefix; /* First word(s) of the handler command */ BgError *firstBgPtr; /* First in list of all background errors * waiting to be processed for this * interpreter (NULL if none). */ BgError *lastBgPtr; /* Last in list of all background errors * waiting to be processed for this |
︙ | ︙ |
Changes to generic/tclIO.c.
︙ | ︙ | |||
112 113 114 115 116 117 118 | * of the following structure. For multi-threaded implementations, there is * one instance of this structure for each thread. * * Notice that different structures with the same name appear in other files. * The structure defined below is used in this file only. */ | | | 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | * of the following structure. For multi-threaded implementations, there is * one instance of this structure for each thread. * * Notice that different structures with the same name appear in other files. * The structure defined below is used in this file only. */ typedef struct { NextChannelHandler *nestedHandlerPtr; /* This variable holds the list of nested * Tcl_NotifyChannel invocations. */ ChannelState *firstCSPtr; /* List of all channels currently open, * indexed by ChannelState, as only one * ChannelState exists per set of stacked * channels. */ |
︙ | ︙ | |||
317 318 319 320 321 322 323 | * a channel name in the context of an interp. Saves the lookup * result and values needed to check its continued validity. */ typedef struct ResolvedChanName { ChannelState *statePtr; /* The saved lookup result */ Tcl_Interp *interp; /* The interp in which the lookup was done. */ | | | 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 | * a channel name in the context of an interp. Saves the lookup * result and values needed to check its continued validity. */ typedef struct ResolvedChanName { ChannelState *statePtr; /* The saved lookup result */ Tcl_Interp *interp; /* The interp in which the lookup was done. */ size_t epoch; /* The epoch of the channel when the lookup * was done. Use to verify validity. */ size_t refCount; /* Share this struct among many Tcl_Obj. */ } ResolvedChanName; static void DupChannelIntRep(Tcl_Obj *objPtr, Tcl_Obj *copyPtr); static void FreeChannelIntRep(Tcl_Obj *objPtr); |
︙ | ︙ | |||
377 378 379 380 381 382 383 | } /* *--------------------------------------------------------------------------- * * ChanRead -- * | | | | | | < | | > | | > > > | > > | | | | | 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 | } /* *--------------------------------------------------------------------------- * * ChanRead -- * * Read up to dstSize bytes using the inputProc of chanPtr, store them at * dst, and return the number of bytes stored. * * Results: * The return value of the driver inputProc, * - number of bytes stored at dst, ot * - -1 on error, with a Posix error code available to the caller by * calling Tcl_GetErrno(). * * Side effects: * The CHANNEL_BLOCKED and CHANNEL_EOF flags of the channel state are set * as appropriate. On EOF, the inputEncodingFlags are set to perform * ending operations on decoding. * * TODO - Is this really the right place for that? * *--------------------------------------------------------------------------- */ static int ChanRead( Channel *chanPtr, char *dst, int dstSize) { int bytesRead, result; /* * If the caller asked for zero bytes, we'd force the inputProc to return * zero bytes, and then misinterpret that as EOF. */ assert(dstSize > 0); /* * Each read op must set the blocked and eof states anew, not let * the effect of prior reads leak through. */ if (GotFlag(chanPtr->state, CHANNEL_EOF)) { chanPtr->state->inputEncodingFlags |= TCL_ENCODING_START; } ResetFlag(chanPtr->state, CHANNEL_BLOCKED | CHANNEL_EOF); chanPtr->state->inputEncodingFlags &= ~TCL_ENCODING_END; if (WillRead(chanPtr) < 0) { return -1; } bytesRead = chanPtr->typePtr->inputProc(chanPtr->instanceData, dst, dstSize, &result); /* * Stop any flag leakage through stacked channel levels. */ if (GotFlag(chanPtr->state, CHANNEL_EOF)) { chanPtr->state->inputEncodingFlags |= TCL_ENCODING_START; } ResetFlag(chanPtr->state, CHANNEL_BLOCKED | CHANNEL_EOF); chanPtr->state->inputEncodingFlags &= ~TCL_ENCODING_END; if (bytesRead > 0) { /* * If we get a short read, signal up that we may be BLOCKED. We should * avoid calling the driver because on some platforms we will block in * the low level reading code even though the channel is set into * nonblocking mode. */ if (bytesRead < dstSize) { SetFlag(chanPtr->state, CHANNEL_BLOCKED); } } else if (bytesRead == 0) { SetFlag(chanPtr->state, CHANNEL_EOF); |
︙ | ︙ | |||
570 571 572 573 574 575 576 | { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); Channel *chanPtr = NULL; /* Iterates over open channels. */ ChannelState *statePtr; /* State of channel stack */ int active = 1; /* Flag == 1 while there's still work to do */ int doflushnb; | > | > > | 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 | { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); Channel *chanPtr = NULL; /* Iterates over open channels. */ ChannelState *statePtr; /* State of channel stack */ int active = 1; /* Flag == 1 while there's still work to do */ int doflushnb; /* * Fetch the pre-TIP#398 compatibility flag. */ { const char *s; Tcl_DString ds; s = TclGetEnv("TCL_FLUSH_NONBLOCKING_ON_EXIT", &ds); doflushnb = ((s != NULL) && strcmp(s, "0")); if (s != NULL) { |
︙ | ︙ | |||
615 616 617 618 619 620 621 | } /* * We've found a live (or bg-closing) channel. Close it. */ if (active) { | < > | | | > > | | | | 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 | } /* * We've found a live (or bg-closing) channel. Close it. */ if (active) { TclChannelPreserve((Tcl_Channel)chanPtr); /* * TIP #398: by default, we no longer set the channel back into * blocking mode. To restore the old blocking behavior, the * environment variable TCL_FLUSH_NONBLOCKING_ON_EXIT must be set * and not be "0". */ if (doflushnb) { /* * Set the channel back into blocking mode to ensure that we * wait for all data to flush out. */ (void) Tcl_SetChannelOption(NULL, (Tcl_Channel) chanPtr, "-blocking", "on"); } if ((chanPtr == (Channel *) tsdPtr->stdinChannel) || (chanPtr == (Channel *) tsdPtr->stdoutChannel) || |
︙ | ︙ | |||
1507 1508 1509 1510 1511 1512 1513 | */ resPtr = (ResolvedChanName *) objPtr->internalRep.twoPtrValue.ptr1; statePtr = resPtr->statePtr; if ((resPtr->interp == interp) /* Same interp context */ /* No epoch change in channel since lookup */ && (resPtr->epoch == statePtr->epoch)) { | | | > > > | > > | 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 | */ resPtr = (ResolvedChanName *) objPtr->internalRep.twoPtrValue.ptr1; statePtr = resPtr->statePtr; if ((resPtr->interp == interp) /* Same interp context */ /* No epoch change in channel since lookup */ && (resPtr->epoch == statePtr->epoch)) { /* * Have a valid saved lookup. Jump to end to return it. */ goto valid; } } chan = Tcl_GetChannel(interp, TclGetString(objPtr), NULL); if (chan == NULL) { if (resPtr) { FreeChannelIntRep(objPtr); } return TCL_ERROR; } if (resPtr && resPtr->refCount == 1) { /* * Re-use the ResolvedCmdName struct. */ Tcl_Release((ClientData) resPtr->statePtr); } else { TclFreeIntRep(objPtr); resPtr = (ResolvedChanName *) ckalloc(sizeof(ResolvedChanName)); resPtr->refCount = 1; |
︙ | ︙ | |||
1667 1668 1669 1670 1671 1672 1673 | statePtr->outputEncodingState = NULL; statePtr->outputEncodingFlags = TCL_ENCODING_START; /* * Set the channel up initially in AUTO input translation mode to accept * "\n", "\r" and "\r\n". Output translation mode is set to a platform * specific default value. The eofChar is set to 0 for both input and | | | 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 | statePtr->outputEncodingState = NULL; statePtr->outputEncodingFlags = TCL_ENCODING_START; /* * Set the channel up initially in AUTO input translation mode to accept * "\n", "\r" and "\r\n". Output translation mode is set to a platform * specific default value. The eofChar is set to 0 for both input and * output, so that Tcl does not look for an in-file EOF indicator (e.g., * ^Z) and does not append an EOF indicator to files. */ statePtr->inputTranslation = TCL_TRANSLATE_AUTO; statePtr->outputTranslation = TCL_PLATFORM_TRANSLATION; statePtr->inEofChar = 0; statePtr->outEofChar = 0; |
︙ | ︙ | |||
1895 1896 1897 1898 1899 1900 1901 | * the channel itself. We use the buffers in the channel below the new * transformation to hold the data. In the future this allows us to write * transformations which pre-read data and push the unused part back when * they are going away. */ if (((mask & TCL_READABLE) != 0) && (statePtr->inQueueHead != NULL)) { | < | 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 | * the channel itself. We use the buffers in the channel below the new * transformation to hold the data. In the future this allows us to write * transformations which pre-read data and push the unused part back when * they are going away. */ if (((mask & TCL_READABLE) != 0) && (statePtr->inQueueHead != NULL)) { /* * When statePtr->inQueueHead is not NULL, we know * prevChanPtr->inQueueHead must be NULL. */ assert(prevChanPtr->inQueueHead == NULL); assert(prevChanPtr->inQueueTail == NULL); |
︙ | ︙ | |||
2027 2028 2029 2030 2031 2032 2033 | if (chanPtr->downChanPtr != NULL) { /* * Instead of manipulating the per-thread / per-interp list/hashtable * of registered channels we wind down the state of the * transformation, and then restore the state of underlying channel * into the old structure. | < | < | 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 | if (chanPtr->downChanPtr != NULL) { /* * Instead of manipulating the per-thread / per-interp list/hashtable * of registered channels we wind down the state of the * transformation, and then restore the state of underlying channel * into the old structure. * * TODO: Figure out how to handle the situation where the chan * operations called below by this unstacking operation cause * another unstacking recursively. In that case the downChanPtr * value we're holding on to will not be the right thing. */ Channel *downChanPtr = chanPtr->downChanPtr; |
︙ | ︙ | |||
2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 | ChannelBuffer *bufPtr, /* The buffer to recycle. */ int mustDiscard) /* If nonzero, free the buffer to the OS, * always. */ { /* * Do we have to free the buffer to the OS? */ if (IsShared(bufPtr)) { mustDiscard = 1; } if (mustDiscard) { ReleaseChannelBuffer(bufPtr); return; } /* | > | | < | 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 | ChannelBuffer *bufPtr, /* The buffer to recycle. */ int mustDiscard) /* If nonzero, free the buffer to the OS, * always. */ { /* * Do we have to free the buffer to the OS? */ if (IsShared(bufPtr)) { mustDiscard = 1; } if (mustDiscard) { ReleaseChannelBuffer(bufPtr); return; } /* * Only save buffers which have the requested buffersize for the channel. * This is to honor dynamic changes of the buffersize made by the user. */ if ((bufPtr->bufLength - BUFFER_PADDING) != statePtr->bufSize) { ReleaseChannelBuffer(bufPtr); return; } |
︙ | ︙ | |||
2689 2690 2691 2692 2693 2694 2695 | if (CheckForDeadChannel(interp, statePtr)) { return -1; } /* * Should we shift the current output buffer over to the output queue? * First check that there are bytes in it. If so then... | > | | > | | | | > | | > | 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 | if (CheckForDeadChannel(interp, statePtr)) { return -1; } /* * Should we shift the current output buffer over to the output queue? * First check that there are bytes in it. If so then... * * If the output queue is empty, then yes, trusting the caller called us * only when written bytes ought to be flushed. * * If the current output buffer is full, then yes, so we can meet the * post-condition that on a successful return to caller we've left space * in the current output buffer for more writing (the flush call was to * make new room). * * If the channel is blocking, then yes, so we guarantee that blocking * flushes actually flush all pending data. * * Otherwise, no. Keep the current output buffer where it is so more * can be written to it, possibly filling it, to promote more efficient * buffer usage. */ bufPtr = statePtr->curOutPtr; if (bufPtr && BytesLeft(bufPtr) && /* Keep empties off queue */ |
︙ | ︙ | |||
2790 2791 2792 2793 2794 2795 2796 | * Decide whether to report the error upwards or defer it. */ if (calledFromAsyncFlush) { /* * TIP #219, Tcl Channel Reflection API. * When defering the error copy a message from the bypass into | | | | 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 | * Decide whether to report the error upwards or defer it. */ if (calledFromAsyncFlush) { /* * TIP #219, Tcl Channel Reflection API. * When defering the error copy a message from the bypass into * the unreported area. Or discard it if the new error is to * be ignored in favor of an earlier defered error. */ Tcl_Obj *msg = statePtr->chanMsg; if (statePtr->unreportedError == 0) { statePtr->unreportedError = errorCode; statePtr->unreportedMsg = msg; |
︙ | ︙ | |||
2843 2844 2845 2846 2847 2848 2849 | * queued. */ DiscardOutputQueued(statePtr); ReleaseChannelBuffer(bufPtr); break; } else { | > | | > > | 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 | * queued. */ DiscardOutputQueued(statePtr); ReleaseChannelBuffer(bufPtr); break; } else { /* * TODO: Consider detecting and reacting to short writes on * blocking channels. Ought not happen. See iocmd-24.2. */ wroteSome = 1; } bufPtr->nextRemoved += written; /* * If this buffer is now empty, recycle it. |
︙ | ︙ | |||
2878 2879 2880 2881 2882 2883 2884 | if (GotFlag(statePtr, BG_FLUSH_SCHEDULED)) { if (wroteSome) { goto done; } else if (statePtr->outQueueHead == NULL) { ResetFlag(statePtr, BG_FLUSH_SCHEDULED); ChanWatch(chanPtr, statePtr->interestMask); } else { | < | 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 | if (GotFlag(statePtr, BG_FLUSH_SCHEDULED)) { if (wroteSome) { goto done; } else if (statePtr->outQueueHead == NULL) { ResetFlag(statePtr, BG_FLUSH_SCHEDULED); ChanWatch(chanPtr, statePtr->interestMask); } else { /* * When we are calledFromAsyncFlush, that means a writable * state on the channel triggered the call, so we should be * able to write something. Either we did write something * and wroteSome should be set, or there was nothing left to * write in this call, and we've completed the BG flush. * These are the two cases above. If we get here, that means |
︙ | ︙ | |||
2923 2924 2925 2926 2927 2928 2929 | * buffer. */ if (GotFlag(statePtr, CHANNEL_CLOSEDWRITE) && (statePtr->outQueueHead == NULL) && ((statePtr->curOutPtr == NULL) || IsBufferEmpty(statePtr->curOutPtr))) { | | > | 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 | * buffer. */ if (GotFlag(statePtr, CHANNEL_CLOSEDWRITE) && (statePtr->outQueueHead == NULL) && ((statePtr->curOutPtr == NULL) || IsBufferEmpty(statePtr->curOutPtr))) { errorCode = CloseChannelPart(interp, chanPtr, errorCode, TCL_CLOSE_WRITE); goto done; } done: TclChannelRelease((Tcl_Channel)chanPtr); return errorCode; } |
︙ | ︙ | |||
3394 3395 3396 3397 3398 3399 3400 | * iso2022, the terminated escape sequence must write to the buffer. */ stickyError = 0; if (GotFlag(statePtr, TCL_WRITABLE) && (statePtr->encoding != NULL) && !(statePtr->outputEncodingFlags & TCL_ENCODING_START)) { | < | 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 | * iso2022, the terminated escape sequence must write to the buffer. */ stickyError = 0; if (GotFlag(statePtr, TCL_WRITABLE) && (statePtr->encoding != NULL) && !(statePtr->outputEncodingFlags & TCL_ENCODING_START)) { int code = CheckChannelErrors(statePtr, TCL_WRITABLE); if (code == 0) { statePtr->outputEncodingFlags |= TCL_ENCODING_END; code = WriteChars(chanPtr, "", 0); statePtr->outputEncodingFlags &= ~TCL_ENCODING_END; statePtr->outputEncodingFlags |= TCL_ENCODING_START; |
︙ | ︙ | |||
3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 | Tcl_SetErrno(stickyError); if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_PosixError(interp), -1)); } return TCL_ERROR; } /* * Bug 97069ea11a: set error message if a flush code is set and no error * message set up to now. */ if (flushcode != 0 && interp != NULL | > > | | 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 | Tcl_SetErrno(stickyError); if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_PosixError(interp), -1)); } return TCL_ERROR; } /* * Bug 97069ea11a: set error message if a flush code is set and no error * message set up to now. */ if (flushcode != 0 && interp != NULL && 0 == Tcl_GetCharLength(Tcl_GetObjResult(interp))) { Tcl_SetErrno(flushcode); Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_PosixError(interp), -1)); } if ((flushcode != 0) || (result != 0)) { return TCL_ERROR; } |
︙ | ︙ | |||
3584 3585 3586 3587 3588 3589 3590 | Tcl_SetObjResult(interp, Tcl_ObjPrintf( "Half-close of %s-side not possible, side not opened or" " already closed", msg)); return TCL_ERROR; } /* | | | | 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 | Tcl_SetObjResult(interp, Tcl_ObjPrintf( "Half-close of %s-side not possible, side not opened or" " already closed", msg)); return TCL_ERROR; } /* * A user may try to call half-close from within a channel close handler. * That won't do. */ if (statePtr->flags & CHANNEL_INCLOSE) { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "illegal recursive call to close through close-handler" " of channel", -1)); |
︙ | ︙ | |||
3656 3657 3658 3659 3660 3661 3662 | static int CloseWrite( Tcl_Interp *interp, /* Interpreter for errors. */ Channel *chanPtr) /* The channel whose write side is being * closed. May still be used by some * interpreter */ { | > | | > | > | 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 | static int CloseWrite( Tcl_Interp *interp, /* Interpreter for errors. */ Channel *chanPtr) /* The channel whose write side is being * closed. May still be used by some * interpreter */ { /* * Notes: clear-channel-handlers - write side only ? or keep around, just * not called. * * No close callbacks are run - channel is still open (read side) */ ChannelState *statePtr = chanPtr->state; /* State of real IO channel. */ int flushcode; int result = 0; /* |
︙ | ︙ | |||
3683 3684 3685 3686 3687 3688 3689 | * TIP #219. * Capture error messages put by the driver into the bypass area and put * them into the regular interpreter result. * * Notes: Due to the assertion of CHANNEL_CLOSEDWRITE in the flags * FlushChannel() has called CloseChannelPart(). While we can still access * "chan" (no structures were freed), the only place which may still | | | | | 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 | * TIP #219. * Capture error messages put by the driver into the bypass area and put * them into the regular interpreter result. * * Notes: Due to the assertion of CHANNEL_CLOSEDWRITE in the flags * FlushChannel() has called CloseChannelPart(). While we can still access * "chan" (no structures were freed), the only place which may still * contain a message is the interpreter itself, and "CloseChannelPart" * made sure to lift any channel message it generated into it. Hence the * NULL argument in the call below. */ if (TclChanCaughtErrorBypass(interp, NULL)) { result = EINVAL; } if ((flushcode != 0) || (result != 0)) { |
︙ | ︙ | |||
3909 3910 3911 3912 3913 3914 3915 | * Cancel any pending copy operation. */ StopCopy(statePtr->csPtrR); StopCopy(statePtr->csPtrW); /* | | | | | | 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 | * Cancel any pending copy operation. */ StopCopy(statePtr->csPtrR); StopCopy(statePtr->csPtrW); /* * Must set the interest mask now to 0, otherwise infinite loops will * occur if Tcl_DoOneEvent is called before the channel is finally deleted * in FlushChannel. This can happen if the channel has a background flush * active. */ statePtr->interestMask = 0; /* * Remove any EventScript records for this channel. */ |
︙ | ︙ | |||
4181 4182 4183 4184 4185 4186 4187 | } static int WillRead( Channel *chanPtr) { if (chanPtr->typePtr == NULL) { | > | > > < | | | | < | | > | 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 | } static int WillRead( Channel *chanPtr) { if (chanPtr->typePtr == NULL) { /* * Prevent read attempts on a closed channel. */ DiscardInputQueued(chanPtr->state, 0); Tcl_SetErrno(EINVAL); return -1; } if ((chanPtr->typePtr->seekProc != NULL) && (Tcl_OutputBuffered((Tcl_Channel) chanPtr) > 0)) { /* * CAVEAT - The assumption here is that FlushChannel() will push out * the bytes of any writes that are in progress. Since this is a * seekable channel, we assume it is not one that can block and force * bg flushing. Channels we know that can do that - sockets, pipes - * are not seekable. If the assumption is wrong, more drastic measures * may be required here like temporarily setting the channel into * blocking mode. */ if (FlushChannel(NULL, chanPtr, 0) != 0) { return -1; } } return 0; |
︙ | ︙ | |||
4288 4289 4290 4291 4292 4293 4294 | dstLen = SpaceLeft(bufPtr); result = Tcl_UtfToExternal(NULL, encoding, src, srcLimit, statePtr->outputEncodingFlags, &statePtr->outputEncodingState, dst, dstLen + BUFFER_PADDING, &srcRead, &dstWrote, NULL); | > | > > > | > > | 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 | dstLen = SpaceLeft(bufPtr); result = Tcl_UtfToExternal(NULL, encoding, src, srcLimit, statePtr->outputEncodingFlags, &statePtr->outputEncodingState, dst, dstLen + BUFFER_PADDING, &srcRead, &dstWrote, NULL); /* * See chan-io-1.[89]. Tcl Bug 506297. */ statePtr->outputEncodingFlags &= ~TCL_ENCODING_START; if ((result != TCL_OK) && (srcRead + dstWrote == 0)) { /* * We're reading from invalid/incomplete UTF-8. */ ReleaseChannelBuffer(bufPtr); if (total == 0) { Tcl_SetErrno(EINVAL); return -1; } break; } |
︙ | ︙ | |||
4332 4333 4334 4335 4336 4337 4338 | break; default: Tcl_Panic("unknown output translation requested"); break; } result |= Tcl_UtfToExternal(NULL, encoding, nl, nlLen, | | | | < | | | | | | | | | | | | | | > | 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 | break; default: Tcl_Panic("unknown output translation requested"); break; } result |= Tcl_UtfToExternal(NULL, encoding, nl, nlLen, statePtr->outputEncodingFlags, &statePtr->outputEncodingState, dst, dstLen + BUFFER_PADDING, &srcRead, &dstWrote, NULL); assert(srcRead == nlLen); bufPtr->nextAdded += dstWrote; src++; srcLen--; total += dstWrote; dst += dstWrote; dstLen -= dstWrote; nextNewLine = memchr(src, '\n', srcLen); needNlFlush = 1; } if (IsBufferOverflowing(bufPtr)) { /* * When translating from UTF-8 to external encoding, we allowed * the translation to produce a character that crossed the end of * the output buffer, so that we would get a completely full * buffer before flushing it. The extra bytes will be moved to the * beginning of the next buffer. */ saved = -SpaceLeft(bufPtr); memcpy(safe, dst + dstLen, (size_t) saved); bufPtr->nextAdded = bufPtr->bufLength; } if ((srcLen + saved == 0) && (result == TCL_OK)) { endEncoding = 0; } if (IsBufferFull(bufPtr)) { if (FlushChannel(NULL, chanPtr, 0) != 0) { ReleaseChannelBuffer(bufPtr); return -1; } flushed += statePtr->bufSize; /* * We just flushed. So if we have needNlFlush set to record that * we need to flush because theres a (translated) newline in the * buffer, that's likely not true any more. But there is a tricky * exception. If we have saved bytes that did not really get * flushed and those bytes came from a translation of a newline as * the last thing taken from the src array, then needNlFlush needs * to remain set to flag that the next buffer still needs a * newline flush. */ if (needNlFlush && (saved == 0 || src[-1] != '\n')) { needNlFlush = 0; } } ReleaseChannelBuffer(bufPtr); } if ((flushed < total) && (GotFlag(statePtr, CHANNEL_UNBUFFERED) || |
︙ | ︙ | |||
4488 4489 4490 4491 4492 4493 4494 | /* * If we're sitting ready to read the eofchar, there's no need to * do it. */ if (GotFlag(statePtr, CHANNEL_STICKY_EOF)) { SetFlag(statePtr, CHANNEL_EOF); | | | | 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 | /* * If we're sitting ready to read the eofchar, there's no need to * do it. */ if (GotFlag(statePtr, CHANNEL_STICKY_EOF)) { SetFlag(statePtr, CHANNEL_EOF); assert(statePtr->inputEncodingFlags & TCL_ENCODING_END); assert(!GotFlag(statePtr, CHANNEL_BLOCKED|INPUT_SAW_CR)); /* TODO: Do we need this? */ UpdateInterest(chanPtr); return -1; } /* |
︙ | ︙ | |||
4829 4830 4831 4832 4833 4834 4835 | /* * Update the notifier state so we don't block while there is still data * in the buffers. */ done: | | | | < | | > | | | < | 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 | /* * Update the notifier state so we don't block while there is still data * in the buffers. */ done: assert(!GotFlag(statePtr, CHANNEL_EOF) || GotFlag(statePtr, CHANNEL_STICKY_EOF) || Tcl_InputBuffered((Tcl_Channel)chanPtr) == 0); assert(!(GotFlag(statePtr, CHANNEL_EOF|CHANNEL_BLOCKED) == (CHANNEL_EOF|CHANNEL_BLOCKED))); /* * Regenerate the top channel, in case it was changed due to * self-modifying reflected transforms. */ if (chanPtr != statePtr->topChanPtr) { TclChannelRelease((Tcl_Channel)chanPtr); chanPtr = statePtr->topChanPtr; TclChannelPreserve((Tcl_Channel)chanPtr); } UpdateInterest(chanPtr); TclChannelRelease((Tcl_Channel)chanPtr); return copiedTotal; } /* *--------------------------------------------------------------------------- * * TclGetsObjBinary -- * * A variation of Tcl_GetsObj that works directly on the buffers until * end-of-line or end-of-file has been seen. Bytes read from the input * channel return as a ByteArray obj. * * WARNING! The notion of "binary" used here is different from notions * of "binary" used in other places. In particular, this "binary" routine * may be called when an -eofchar is set on the channel. * * Results: * Number of characters accumulated in the object or -1 if error, * blocked, or EOF. If -1, use Tcl_GetErrno() to retrieve the POSIX error * code for the error or condition that occurred. * * Side effects: |
︙ | ︙ | |||
4928 4929 4930 4931 4932 4933 4934 | */ eolChar = (statePtr->inputTranslation == TCL_TRANSLATE_LF) ? '\n' : '\r'; ResetFlag(statePtr, CHANNEL_BLOCKED); while (1) { /* | | | | | | > | | | | | | | | | 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 | */ eolChar = (statePtr->inputTranslation == TCL_TRANSLATE_LF) ? '\n' : '\r'; ResetFlag(statePtr, CHANNEL_BLOCKED); while (1) { /* * Subtract the number of bytes that were removed from channel buffer * during last call. */ if (bufPtr != NULL) { bufPtr->nextRemoved += rawLen; if (!IsBufferReady(bufPtr)) { bufPtr = bufPtr->nextPtr; } } if ((bufPtr == NULL) || (bufPtr->nextAdded == BUFFER_PADDING)) { /* * All channel buffers were exhausted and the caller still hasn't * seen EOL. Need to read more bytes from the channel device. Side * effect is to allocate another channel buffer. */ if (GetInput(chanPtr) != 0) { goto restore; } bufPtr = statePtr->inQueueTail; if (bufPtr == NULL) { goto restore; } } else { /* * Incoming CHANNEL_STICKY_EOF is filtered out on entry. A new * CHANNEL_STICKY_EOF set in this routine leads to return before * coming back here. When we are not dealing with * CHANNEL_STICKY_EOF, a CHANNEL_EOF implies an empty buffer. * Here the buffer is non-empty so we know we're a non-EOF. */ assert(!GotFlag(statePtr, CHANNEL_STICKY_EOF)); assert(!GotFlag(statePtr, CHANNEL_EOF)); } dst = (unsigned char *) RemovePoint(bufPtr); dstEnd = dst + BytesLeft(bufPtr); /* * Remember if EOF char is seen, then look for EOL anyhow, because the |
︙ | ︙ | |||
5029 5030 5031 5032 5033 5034 5035 | } if (GotFlag(statePtr, CHANNEL_BLOCKED|CHANNEL_NONBLOCKING) == (CHANNEL_BLOCKED|CHANNEL_NONBLOCKING)) { goto restore; } /* | | | | 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 | } if (GotFlag(statePtr, CHANNEL_BLOCKED|CHANNEL_NONBLOCKING) == (CHANNEL_BLOCKED|CHANNEL_NONBLOCKING)) { goto restore; } /* * Copy bytes from the channel buffer to the ByteArray. This may * realloc space, so keep track of result. */ rawLen = dstEnd - dst; byteArray = Tcl_SetByteArrayLength(objPtr, byteLen + rawLen); memcpy(byteArray + byteLen, dst, (size_t) rawLen); byteLen += rawLen; } |
︙ | ︙ | |||
5114 5115 5116 5117 5118 5119 5120 | /* * Update the notifier state so we don't block while there is still data * in the buffers. */ done: | | | | | | | 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 | /* * Update the notifier state so we don't block while there is still data * in the buffers. */ done: assert(!GotFlag(statePtr, CHANNEL_EOF) || GotFlag(statePtr, CHANNEL_STICKY_EOF) || Tcl_InputBuffered((Tcl_Channel)chanPtr) == 0); assert(!(GotFlag(statePtr, CHANNEL_EOF|CHANNEL_BLOCKED) == (CHANNEL_EOF|CHANNEL_BLOCKED))); UpdateInterest(chanPtr); TclChannelRelease((Tcl_Channel)chanPtr); return copiedTotal; } /* *--------------------------------------------------------------------------- |
︙ | ︙ | |||
5251 5252 5253 5254 5255 5256 5257 | if (bufPtr == NULL) { gsPtr->charsWrote = 0; gsPtr->rawRead = 0; return -1; } } else { /* | | | | < | | > | | | 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 | if (bufPtr == NULL) { gsPtr->charsWrote = 0; gsPtr->rawRead = 0; return -1; } } else { /* * Incoming CHANNEL_STICKY_EOF is filtered out on entry. A new * CHANNEL_STICKY_EOF set in this routine leads to return before * coming back here. When we are not dealing with CHANNEL_STICKY_EOF, * a CHANNEL_EOF implies an empty buffer. Here the buffer is * non-empty so we know we're a non-EOF. */ assert(!GotFlag(statePtr, CHANNEL_STICKY_EOF)); assert(!GotFlag(statePtr, CHANNEL_EOF)); } /* * Convert some of the bytes from the channel buffer to UTF-8. Space in * objPtr's string rep is used to hold the UTF-8 characters. Grow the * string rep if we need more space. */ |
︙ | ︙ | |||
5589 5590 5591 5592 5593 5594 5595 | int copied = 0; assert(bytesToRead > 0); if (CheckChannelErrors(statePtr, TCL_READABLE | CHANNEL_RAW_MODE) != 0) { return -1; } | > | > > | > > | > | | < | | > | < > > > | > > | | | < | | | | < > | 5620 5621 5622 5623 5624 5625 5626 5627 5628 5629 5630 5631 5632 5633 5634 5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 5664 5665 5666 5667 5668 5669 5670 5671 5672 5673 5674 5675 5676 5677 5678 5679 5680 5681 5682 5683 5684 5685 5686 5687 5688 5689 5690 5691 5692 5693 5694 5695 5696 5697 5698 5699 5700 5701 | int copied = 0; assert(bytesToRead > 0); if (CheckChannelErrors(statePtr, TCL_READABLE | CHANNEL_RAW_MODE) != 0) { return -1; } /* * First read bytes from the push-back buffers. */ while (chanPtr->inQueueHead && bytesToRead > 0) { ChannelBuffer *bufPtr = chanPtr->inQueueHead; int bytesInBuffer = BytesLeft(bufPtr); int toCopy = (bytesInBuffer < bytesToRead) ? bytesInBuffer : bytesToRead; /* * Copy the current chunk into the read buffer. */ memcpy(readBuf, RemovePoint(bufPtr), (size_t) toCopy); bufPtr->nextRemoved += toCopy; copied += toCopy; readBuf += toCopy; bytesToRead -= toCopy; /* * If the current buffer is empty recycle it. */ if (IsBufferEmpty(bufPtr)) { chanPtr->inQueueHead = bufPtr->nextPtr; if (chanPtr->inQueueHead == NULL) { chanPtr->inQueueTail = NULL; } RecycleBuffer(chanPtr->state, bufPtr, 0); } } /* * Go to the driver only if we got nothing from pushback. Have to do it * this way to avoid EOF mis-timings when we consider the ability that EOF * may not be a permanent condition in the driver, and in that case we * have to synchronize. */ if (copied) { return copied; } /* * This test not needed. */ if (bytesToRead > 0) { int nread = ChanRead(chanPtr, readBuf, bytesToRead); if (nread > 0) { /* * Successful read (short is OK) - add to bytes copied. */ copied += nread; } else if (nread < 0) { /* * An error signaled. If CHANNEL_BLOCKED, then the error is not * real, but an indication of blocked state. In that case, retain * the flag and let caller receive the short read of copied bytes * from the pushback. HOWEVER, if copied==0 bytes from pushback * then repeat signalling the blocked state as an error to caller * so there is no false report of an EOF. When !CHANNEL_BLOCKED, * the error is real and passes on to caller. */ if (!GotFlag(statePtr, CHANNEL_BLOCKED) || copied == 0) { copied = -1; } } else { /* * nread == 0. Driver is at EOF. Let that state filter up. */ |
︙ | ︙ | |||
5784 5785 5786 5787 5788 5789 5790 | TclGetString(objPtr); } } /* * Early out when next read will see eofchar. * | | | | | > | > > | > > | 5824 5825 5826 5827 5828 5829 5830 5831 5832 5833 5834 5835 5836 5837 5838 5839 5840 5841 5842 5843 5844 5845 5846 5847 5848 5849 5850 5851 5852 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875 5876 | TclGetString(objPtr); } } /* * Early out when next read will see eofchar. * * NOTE: See DoRead for argument that it's a bug (one we're keeping) to * have this escape before the one for zero-char read request. */ if (GotFlag(statePtr, CHANNEL_STICKY_EOF)) { SetFlag(statePtr, CHANNEL_EOF); assert(statePtr->inputEncodingFlags & TCL_ENCODING_END); assert(!GotFlag(statePtr, CHANNEL_BLOCKED|INPUT_SAW_CR)); /* TODO: We don't need this call? */ UpdateInterest(chanPtr); return 0; } /* * Special handling for zero-char read request. */ if (toRead == 0) { if (GotFlag(statePtr, CHANNEL_EOF)) { statePtr->inputEncodingFlags |= TCL_ENCODING_START; } ResetFlag(statePtr, CHANNEL_BLOCKED|CHANNEL_EOF); statePtr->inputEncodingFlags &= ~TCL_ENCODING_END; /* TODO: We don't need this call? */ UpdateInterest(chanPtr); return 0; } /* * This operation should occur at the top of a channel stack. */ chanPtr = statePtr->topChanPtr; TclChannelPreserve((Tcl_Channel)chanPtr); /* * Must clear the BLOCKED|EOF flags here since we check before reading. */ if (GotFlag(statePtr, CHANNEL_EOF)) { statePtr->inputEncodingFlags |= TCL_ENCODING_START; } ResetFlag(statePtr, CHANNEL_BLOCKED|CHANNEL_EOF); statePtr->inputEncodingFlags &= ~TCL_ENCODING_END; for (copied = 0; (unsigned) toRead > 0; ) { copiedNow = -1; |
︙ | ︙ | |||
5875 5876 5877 5878 5879 5880 5881 | } else { copied += copiedNow; toRead -= copiedNow; } } /* | | | | > > > | | | | | | 5920 5921 5922 5923 5924 5925 5926 5927 5928 5929 5930 5931 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 5948 5949 5950 5951 5952 5953 5954 5955 5956 5957 5958 5959 5960 5961 5962 5963 | } else { copied += copiedNow; toRead -= copiedNow; } } /* * Failure to fill a channel buffer may have left channel reporting a * "blocked" state, but so long as we fulfilled the request here, the * caller does not consider us blocked. */ if (toRead == 0) { ResetFlag(statePtr, CHANNEL_BLOCKED); } /* * Regenerate the top channel, in case it was changed due to * self-modifying reflected transforms. */ if (chanPtr != statePtr->topChanPtr) { TclChannelRelease((Tcl_Channel)chanPtr); chanPtr = statePtr->topChanPtr; TclChannelPreserve((Tcl_Channel)chanPtr); } /* * Update the notifier state so we don't block while there is still data * in the buffers. */ assert(!GotFlag(statePtr, CHANNEL_EOF) || GotFlag(statePtr, CHANNEL_STICKY_EOF) || Tcl_InputBuffered((Tcl_Channel)chanPtr) == 0); assert(!(GotFlag(statePtr, CHANNEL_EOF|CHANNEL_BLOCKED) == (CHANNEL_EOF|CHANNEL_BLOCKED))); UpdateInterest(chanPtr); TclChannelRelease((Tcl_Channel)chanPtr); return copied; } /* *--------------------------------------------------------------------------- |
︙ | ︙ | |||
6018 6019 6020 6021 6022 6023 6024 | ChannelBuffer *bufPtr = statePtr->inQueueHead; int savedIEFlags = statePtr->inputEncodingFlags; int savedFlags = statePtr->flags; char *dst, *src = RemovePoint(bufPtr); int numBytes, srcLen = BytesLeft(bufPtr); /* | | | | | < > | | | | | | < | | | | | | | | | | | < | | | | | | | | < | | < | | < | | | | < | | | | | | | | | | > | | | < | | | < | | | | | | | | 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 6117 6118 6119 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133 6134 6135 6136 6137 6138 6139 6140 6141 6142 6143 6144 6145 6146 6147 6148 6149 6150 6151 6152 6153 6154 6155 6156 6157 6158 6159 6160 6161 6162 6163 6164 6165 6166 6167 6168 6169 6170 6171 6172 6173 6174 6175 6176 6177 6178 6179 6180 6181 6182 6183 6184 6185 6186 6187 6188 6189 6190 6191 6192 6193 6194 6195 6196 6197 6198 6199 6200 6201 6202 6203 6204 6205 6206 6207 6208 6209 6210 6211 6212 6213 6214 6215 6216 6217 6218 6219 6220 6221 6222 6223 6224 6225 6226 6227 6228 6229 6230 6231 6232 6233 6234 6235 6236 6237 6238 6239 6240 6241 6242 6243 6244 6245 6246 6247 6248 | ChannelBuffer *bufPtr = statePtr->inQueueHead; int savedIEFlags = statePtr->inputEncodingFlags; int savedFlags = statePtr->flags; char *dst, *src = RemovePoint(bufPtr); int numBytes, srcLen = BytesLeft(bufPtr); /* * One src byte can yield at most one character. So when the number of * src bytes we plan to read is less than the limit on character count to * be read, clearly we will remain within that limit, and we can use the * value of "srcLen" as a tighter limit for sizing receiving buffers. */ int toRead = ((charsToRead<0)||(charsToRead > srcLen)) ? srcLen : charsToRead; /* * 'factor' is how much we guess that the bytes in the source buffer will * expand when converted to UTF-8 chars. This guess comes from analyzing * how many characters were produced by the previous pass. */ int factor = *factorPtr; int dstLimit = TCL_UTF_MAX - 1 + toRead * factor / UTF_EXPANSION_FACTOR; (void) TclGetStringFromObj(objPtr, &numBytes); Tcl_AppendToObj(objPtr, NULL, dstLimit); if (toRead == srcLen) { unsigned int size; dst = TclGetStringStorage(objPtr, &size) + numBytes; dstLimit = size - numBytes; } else { dst = TclGetString(objPtr) + numBytes; } /* * This routine is burdened with satisfying several constraints. It cannot * append more than 'charsToRead` chars onto objPtr. This is measured * after encoding and translation transformations are completed. There is * no precise number of src bytes that can be associated with the limit. * Yet, when we are done, we must know precisely the number of src bytes * that were consumed to produce the appended chars, so that all * subsequent bytes are left in the buffers for future read operations. * * The consequence is that we have no choice but to implement a "trial and * error" approach, where in general we may need to perform * transformations and copies multiple times to achieve a consistent set * of results. This takes the shape of a loop. */ while (1) { int dstDecoded, dstRead, dstWrote, srcRead, numChars, code; int flags = statePtr->inputEncodingFlags | TCL_ENCODING_NO_TERMINATE; if (charsToRead > 0) { flags |= TCL_ENCODING_CHAR_LIMIT; numChars = charsToRead; } /* * Perform the encoding transformation. Read no more than srcLen * bytes, write no more than dstLimit bytes. * * Some trickiness with encoding flags here. We do not want the end * of a buffer to be treated as the end of all input when the presence * of bytes in a next buffer are already known to exist. This is * checked with an assert() because so far no test case causing the * assertion to be false has been created. The normal operations of * channel reading appear to cause EOF and TCL_ENCODING_END setting to * appear only in situations where there are no further bytes in any * buffers. */ assert(bufPtr->nextPtr == NULL || BytesLeft(bufPtr->nextPtr) == 0 || (statePtr->inputEncodingFlags & TCL_ENCODING_END) == 0); code = Tcl_ExternalToUtf(NULL, encoding, src, srcLen, flags, &statePtr->inputEncodingState, dst, dstLimit, &srcRead, &dstDecoded, &numChars); /* * Perform the translation transformation in place. Read no more than * the dstDecoded bytes the encoding transformation actually produced. * Capture the number of bytes written in dstWrote. Capture the number * of bytes actually consumed in dstRead. */ dstWrote = dstLimit; dstRead = dstDecoded; TranslateInputEOL(statePtr, dst, dst, &dstWrote, &dstRead); if (dstRead < dstDecoded) { /* * The encoding transformation produced bytes that the translation * transformation did not consume. Why did this happen? */ if (statePtr->inEofChar && dst[dstRead] == statePtr->inEofChar) { /* * 1) There's an eof char set on the channel, and * we saw it and stopped translating at that point. * * NOTE the bizarre spec of TranslateInputEOL in this case. * Clearly the eof char had to be read in order to account for * the stopping, but the value of dstRead does not include it. * * Also rather bizarre, our caller can only notice an EOF * condition if we return the value -1 as the number of chars * read. This forces us to perform a 2-call dance where the * first call can read all the chars up to the eof char, and * the second call is solely for consuming the encoded eof * char then pointed at by src so that we can return that * magic -1 value. This seems really wasteful, especially * since the first decoding pass of each call is likely to * decode many bytes beyond that eof char that's all we care * about. */ if (dstRead == 0) { /* * Curious choice in the eof char handling. We leave the * eof char in the buffer. So, no need to compute a proper * srcRead value. At this point, there are no chars before * the eof char in the buffer. */ Tcl_SetObjLength(objPtr, numBytes); return -1; } { /* * There are chars leading the buffer before the eof char. * Adjust the dstLimit so we go back and read only those * and do not encounter the eof char this time. */ dstLimit = dstRead - 1 + TCL_UTF_MAX; statePtr->flags = savedFlags; statePtr->inputEncodingFlags = savedIEFlags; statePtr->inputEncodingState = savedState; continue; } } /* * 2) The other way to read fewer bytes than are decoded is when * the final byte is \r and we're in a CRLF translation mode so * we cannot decide whether to record \r or \n yet. */ assert(dst[dstRead] == '\r'); assert(statePtr->inputTranslation == TCL_TRANSLATE_CRLF); if (dstWrote > 0) { /* * There are chars we can read before we hit the bare CR. Go * back with a smaller dstLimit so we get them in the next * pass, compute a matching srcRead, and don't end up back * here in this call. */ dstLimit = dstRead - 1 + TCL_UTF_MAX; statePtr->flags = savedFlags; statePtr->inputEncodingFlags = savedIEFlags; statePtr->inputEncodingState = savedState; continue; } assert(dstWrote == 0); assert(dstRead == 0); /* * We decoded only the bare CR, and we cannot read a translated * char from that alone. We have to know what's next. So why do * we only have the one decoded char? */ if (code != TCL_OK) { char buffer[TCL_UTF_MAX + 1]; int read, decoded, count; /* |
︙ | ︙ | |||
6234 6235 6236 6237 6238 6239 6240 | statePtr->inputEncodingFlags &= ~TCL_ENCODING_START; Tcl_SetObjLength(objPtr, numBytes + 1); return 1; } } else if (statePtr->flags & CHANNEL_EOF) { | < | | | | | | | | | < | > | > | | | < | | | | > | | | < | | > | | | | | | | | > | | > | 6275 6276 6277 6278 6279 6280 6281 6282 6283 6284 6285 6286 6287 6288 6289 6290 6291 6292 6293 6294 6295 6296 6297 6298 6299 6300 6301 6302 6303 6304 6305 6306 6307 6308 6309 6310 6311 6312 6313 6314 6315 6316 6317 6318 6319 6320 6321 6322 6323 6324 6325 6326 6327 6328 6329 6330 6331 6332 6333 6334 6335 6336 6337 6338 6339 6340 6341 6342 6343 6344 6345 6346 6347 6348 6349 6350 6351 6352 6353 6354 6355 6356 6357 6358 6359 6360 6361 6362 6363 6364 6365 6366 6367 6368 6369 6370 6371 6372 6373 6374 6375 6376 6377 6378 6379 6380 6381 6382 6383 6384 6385 6386 6387 6388 6389 6390 6391 6392 6393 6394 6395 6396 6397 6398 6399 6400 6401 6402 6403 6404 6405 6406 6407 6408 6409 6410 6411 6412 | statePtr->inputEncodingFlags &= ~TCL_ENCODING_START; Tcl_SetObjLength(objPtr, numBytes + 1); return 1; } } else if (statePtr->flags & CHANNEL_EOF) { /* * The bare \r is the only char and we will never read a * subsequent char to make the determination. */ dst[0] = '\r'; bufPtr->nextRemoved = bufPtr->nextAdded; Tcl_SetObjLength(objPtr, numBytes + 1); return 1; } /* * Revise the dstRead value so that the numChars calc below * correctly computes zero characters read. */ dstRead = numChars; /* FALL THROUGH - get more data (dstWrote == 0) */ } /* * The translation transformation can only reduce the number of chars * when it converts \r\n into \n. The reduction in the number of chars * is the difference in bytes read and written. */ numChars -= (dstRead - dstWrote); if (charsToRead > 0 && numChars > charsToRead) { /* * TODO: This cannot happen anymore. * * We read more chars than allowed. Reset limits to prevent that * and try again. Don't forget the extra padding of TCL_UTF_MAX * bytes demanded by the Tcl_ExternalToUtf() call! */ dstLimit = Tcl_UtfAtIndex(dst, charsToRead) - 1 + TCL_UTF_MAX - dst; statePtr->flags = savedFlags; statePtr->inputEncodingFlags = savedIEFlags; statePtr->inputEncodingState = savedState; continue; } if (dstWrote == 0) { ChannelBuffer *nextPtr; /* * We were not able to read any chars. */ assert(numChars == 0); /* * There is one situation where this is the correct final result. * If the src buffer contains only a single \n byte, and we are in * TCL_TRANSLATE_AUTO mode, and when the translation pass was made * the INPUT_SAW_CR flag was set on the channel. In that case, the * correct behavior is to consume that \n and produce the empty * string. */ if (dstRead == 1 && dst[0] == '\n') { assert(statePtr->inputTranslation == TCL_TRANSLATE_AUTO); goto consume; } /* * Otherwise, reading zero characters indicates there's something * incomplete at the end of the src buffer. Maybe there were not * enough src bytes to decode into a char. Maybe a lone \r could * not be translated (crlf mode). Need to combine any unused src * bytes we have in the first buffer with subsequent bytes to try * again. */ nextPtr = bufPtr->nextPtr; if (nextPtr == NULL) { if (srcLen > 0) { SetFlag(statePtr, CHANNEL_NEED_MORE_DATA); } Tcl_SetObjLength(objPtr, numBytes); return -1; } /* * Space is made at the beginning of the buffer to copy the * previous unused bytes there. Check first if the buffer we are * using actually has enough space at its beginning for the data * we are copying. Because if not we will write over the buffer * management information, especially the 'nextPtr'. * * Note that the BUFFER_PADDING (See AllocChannelBuffer) is used * to prevent exactly this situation. I.e. it should never happen. * Therefore it is ok to panic should it happen despite the * precautions. */ if (nextPtr->nextRemoved - srcLen < 0) { Tcl_Panic("Buffer Underflow, BUFFER_PADDING not enough"); } nextPtr->nextRemoved -= srcLen; memcpy(RemovePoint(nextPtr), src, (size_t) srcLen); RecycleBuffer(statePtr, bufPtr, 0); statePtr->inQueueHead = nextPtr; Tcl_SetObjLength(objPtr, numBytes); return ReadChars(statePtr, objPtr, charsToRead, factorPtr); } statePtr->inputEncodingFlags &= ~TCL_ENCODING_START; consume: bufPtr->nextRemoved += srcRead; /* * If this read contained multibyte characters, revise factorPtr so * the next read will allocate bigger buffers. */ if (numChars && numChars < srcRead) { *factorPtr = srcRead * UTF_EXPANSION_FACTOR / numChars; } Tcl_SetObjLength(objPtr, numBytes + dstWrote); return numChars; } } |
︙ | ︙ | |||
6403 6404 6405 6406 6407 6408 6409 | { const char *eof = NULL; int dstLen = *dstLenPtr; int srcLen = *srcLenPtr; int inEofChar = statePtr->inEofChar; /* | | | | < > | > > > | > > | 6446 6447 6448 6449 6450 6451 6452 6453 6454 6455 6456 6457 6458 6459 6460 6461 6462 6463 6464 6465 6466 6467 6468 6469 6470 6471 6472 6473 6474 6475 6476 6477 6478 6479 6480 | { const char *eof = NULL; int dstLen = *dstLenPtr; int srcLen = *srcLenPtr; int inEofChar = statePtr->inEofChar; /* * Depending on the translation mode in use, there's no need to scan more * srcLen bytes at srcStart than can possibly transform to dstLen bytes. * This keeps the scan for eof char below from being pointlessly long. */ switch (statePtr->inputTranslation) { case TCL_TRANSLATE_LF: case TCL_TRANSLATE_CR: if (srcLen > dstLen) { /* * In these modes, each src byte become a dst byte. */ srcLen = dstLen; } break; default: /* * In other modes, at most 2 src bytes become a dst byte. */ if (srcLen/2 > dstLen) { srcLen = 2 * dstLen; } break; } if (inEofChar != '\0') { |
︙ | ︙ | |||
6751 6752 6753 6754 6755 6756 6757 | /* * Verify that all callers know better than to call us when * it's recorded that the next char waiting to be read is the * eofchar. */ | | | | | | | | | | | | | | | < < | < < | 6799 6800 6801 6802 6803 6804 6805 6806 6807 6808 6809 6810 6811 6812 6813 6814 6815 6816 6817 6818 6819 6820 6821 6822 6823 6824 6825 6826 6827 6828 6829 6830 6831 6832 6833 6834 6835 6836 6837 6838 6839 6840 6841 6842 6843 6844 6845 6846 6847 6848 | /* * Verify that all callers know better than to call us when * it's recorded that the next char waiting to be read is the * eofchar. */ assert(!GotFlag(statePtr, CHANNEL_STICKY_EOF)); /* * Prevent reading from a dead channel -- a channel that has been closed * but not yet deallocated, which can happen if the exit handler for * channel cleanup has run but the channel is still registered in some * interpreter. */ if (CheckForDeadChannel(NULL, statePtr)) { return EINVAL; } /* * WARNING: There was once a comment here claiming that it was a bad idea * to make another call to the inputproc of a channel driver when EOF has * already been detected on the channel. Through much of Tcl's history, * this warning was then completely negated by having all (most?) read * paths clear the EOF setting before reaching here. So we had a guard * that was never triggered. * * Don't be tempted to restore the guard. Even if EOF is set on the * channel, continue through and call the inputproc again. This is the * way to enable the ability to [read] again beyond the EOF, which seems a * strange thing to do, but for which use cases exist [Tcl Bug 5adc350683] * and which may even be essential for channels representing things like * ttys or other devices where the stream might take the logical form of a * series of 'files' separated by an EOF condition. * * First check for more buffers in the pushback area of the topmost * channel in the stack and use them. They can be the result of a * transformation which went away without reading all the information * placed in the area when it was stacked. */ if (chanPtr->inQueueHead != NULL) { /* TODO: Tests to cover this. */ assert(statePtr->inQueueHead == NULL); statePtr->inQueueHead = chanPtr->inQueueHead; statePtr->inQueueTail = chanPtr->inQueueTail; chanPtr->inQueueHead = NULL; chanPtr->inQueueTail = NULL; |
︙ | ︙ | |||
6820 6821 6822 6823 6824 6825 6826 | if ((bufPtr == NULL) || IsBufferFull(bufPtr)) { bufPtr = statePtr->saveInBufPtr; statePtr->saveInBufPtr = NULL; /* * Check the actual buffersize against the requested buffersize. | | | > | 6864 6865 6866 6867 6868 6869 6870 6871 6872 6873 6874 6875 6876 6877 6878 6879 6880 | if ((bufPtr == NULL) || IsBufferFull(bufPtr)) { bufPtr = statePtr->saveInBufPtr; statePtr->saveInBufPtr = NULL; /* * Check the actual buffersize against the requested buffersize. * Saved buffers of the wrong size are squashed. This is done to honor * dynamic changes of the buffersize made by the user. * * TODO: Tests to cover this. */ if ((bufPtr != NULL) && (bufPtr->bufLength - BUFFER_PADDING != statePtr->bufSize)) { ReleaseChannelBuffer(bufPtr); bufPtr = NULL; |
︙ | ︙ | |||
7128 7129 7130 7131 7132 7133 7134 | *--------------------------------------------------------------------------- * * Tcl_TruncateChannel -- * * Truncate a channel to the given length. * * Results: | | | 7173 7174 7175 7176 7177 7178 7179 7180 7181 7182 7183 7184 7185 7186 7187 | *--------------------------------------------------------------------------- * * Tcl_TruncateChannel -- * * Truncate a channel to the given length. * * Results: * TCL_OK on success, TCL_ERROR if the operation failed (e.g., is not * supported by the type of channel, or the underlying OS operation * failed in some way). * * Side effects: * Seeks the channel to the current location. Sets errno on OS error. * *--------------------------------------------------------------------------- |
︙ | ︙ | |||
9272 9273 9274 9275 9276 9277 9278 | /* Split the overflowing buffer in two */ int extra = (int) (inBytes - csPtr->toRead); /* Note that going with int for extra assumes that inBytes is not too * much over toRead to require a wide itself. If that gets violated * then the calculations involving extra must be made wide too. * * Noted with Win32/MSVC debug build treating the warning (possible of | | | 9317 9318 9319 9320 9321 9322 9323 9324 9325 9326 9327 9328 9329 9330 9331 | /* Split the overflowing buffer in two */ int extra = (int) (inBytes - csPtr->toRead); /* Note that going with int for extra assumes that inBytes is not too * much over toRead to require a wide itself. If that gets violated * then the calculations involving extra must be made wide too. * * Noted with Win32/MSVC debug build treating the warning (possible of * data in __int64 to int conversion) as error. */ bufPtr = AllocChannelBuffer(extra); tail->nextAdded -= extra; memcpy(InsertPoint(bufPtr), InsertPoint(tail), extra); bufPtr->nextAdded += extra; |
︙ | ︙ | |||
9488 9489 9490 9491 9492 9493 9494 | Tcl_DeleteChannelHandler(outChan, CopyEventProc, csPtr); } Tcl_CreateChannelHandler(inChan, TCL_READABLE, CopyEventProc, csPtr); } if (size == 0) { if (!GotFlag(inStatePtr, CHANNEL_NONBLOCKING)) { | > | > > | 9533 9534 9535 9536 9537 9538 9539 9540 9541 9542 9543 9544 9545 9546 9547 9548 9549 9550 | Tcl_DeleteChannelHandler(outChan, CopyEventProc, csPtr); } Tcl_CreateChannelHandler(inChan, TCL_READABLE, CopyEventProc, csPtr); } if (size == 0) { if (!GotFlag(inStatePtr, CHANNEL_NONBLOCKING)) { /* * We allowed a short read. Keep trying. */ continue; } if (bufObj != NULL) { TclDecrRefCount(bufObj); bufObj = NULL; } return TCL_OK; |
︙ | ︙ | |||
9702 9703 9704 9705 9706 9707 9708 | char *dst, /* Where to store input read. */ int bytesToRead, /* Maximum number of bytes to read. */ int allowShortReads) /* Allow half-blocking (pipes,sockets) */ { ChannelState *statePtr = chanPtr->state; char *p = dst; | | | | > | > > | | | | | | > | > > > | > > | | | | | | > | > > | > > | > > > | > > > | > | 9750 9751 9752 9753 9754 9755 9756 9757 9758 9759 9760 9761 9762 9763 9764 9765 9766 9767 9768 9769 9770 9771 9772 9773 9774 9775 9776 9777 9778 9779 9780 9781 9782 9783 9784 9785 9786 9787 9788 9789 9790 9791 9792 9793 9794 9795 9796 9797 9798 9799 9800 9801 9802 9803 9804 9805 9806 9807 9808 9809 9810 9811 9812 9813 9814 9815 9816 9817 9818 9819 9820 9821 9822 9823 9824 9825 9826 9827 9828 9829 9830 9831 9832 9833 9834 9835 9836 9837 9838 9839 9840 9841 9842 9843 9844 9845 9846 9847 9848 9849 9850 9851 9852 9853 9854 9855 9856 9857 9858 9859 9860 9861 9862 9863 9864 9865 9866 9867 9868 9869 9870 9871 9872 9873 9874 9875 9876 9877 9878 9879 9880 9881 9882 9883 9884 9885 9886 9887 9888 9889 9890 9891 9892 9893 9894 9895 9896 9897 9898 9899 9900 9901 9902 9903 9904 9905 9906 9907 9908 9909 9910 9911 9912 9913 9914 9915 9916 9917 9918 9919 9920 9921 9922 9923 | char *dst, /* Where to store input read. */ int bytesToRead, /* Maximum number of bytes to read. */ int allowShortReads) /* Allow half-blocking (pipes,sockets) */ { ChannelState *statePtr = chanPtr->state; char *p = dst; assert(bytesToRead >= 0); /* * Early out when we know a read will get the eofchar. * * NOTE: This seems to be a bug. The special handling for * a zero-char read request ought to come first. As coded * the EOF due to eofchar has distinguishing behavior from * the EOF due to reported EOF on the underlying device, and * that seems undesirable. However recent history indicates * that new inconsistent behavior in a patchlevel has problems * too. Keep on keeping on for now. */ if (GotFlag(statePtr, CHANNEL_STICKY_EOF)) { SetFlag(statePtr, CHANNEL_EOF); assert(statePtr->inputEncodingFlags & TCL_ENCODING_END); assert(!GotFlag(statePtr, CHANNEL_BLOCKED|INPUT_SAW_CR)); /* TODO: Don't need this call */ UpdateInterest(chanPtr); return 0; } /* * Special handling for zero-char read request. */ if (bytesToRead == 0) { if (GotFlag(statePtr, CHANNEL_EOF)) { statePtr->inputEncodingFlags |= TCL_ENCODING_START; } ResetFlag(statePtr, CHANNEL_BLOCKED|CHANNEL_EOF); statePtr->inputEncodingFlags &= ~TCL_ENCODING_END; /* TODO: Don't need this call */ UpdateInterest(chanPtr); return 0; } TclChannelPreserve((Tcl_Channel)chanPtr); while (bytesToRead) { /* * Each pass through the loop is intended to process up to one channel * buffer. */ int bytesRead, bytesWritten; ChannelBuffer *bufPtr = statePtr->inQueueHead; /* * Don't read more data if we have what we need. */ while (!bufPtr || /* We got no buffer! OR */ (!IsBufferFull(bufPtr) && /* Our buffer has room AND */ (BytesLeft(bufPtr) < bytesToRead))) { /* Not enough bytes in it yet * to fill the dst */ int code; moreData: code = GetInput(chanPtr); bufPtr = statePtr->inQueueHead; assert(bufPtr != NULL); if (GotFlag(statePtr, CHANNEL_EOF|CHANNEL_BLOCKED)) { /* * Further reads cannot do any more. */ break; } if (code) { /* * Read error */ UpdateInterest(chanPtr); TclChannelRelease((Tcl_Channel)chanPtr); return -1; } assert(IsBufferFull(bufPtr)); } assert(bufPtr != NULL); bytesRead = BytesLeft(bufPtr); bytesWritten = bytesToRead; TranslateInputEOL(statePtr, p, RemovePoint(bufPtr), &bytesWritten, &bytesRead); bufPtr->nextRemoved += bytesRead; p += bytesWritten; bytesToRead -= bytesWritten; if (!IsBufferEmpty(bufPtr)) { /* * Buffer is not empty. How can that be? * * 0) We stopped early because we got all the bytes we were * seeking. That's fine. */ if (bytesToRead == 0) { break; } /* * 1) We're @EOF because we saw eof char. */ if (GotFlag(statePtr, CHANNEL_STICKY_EOF)) { break; } /* * 2) The buffer holds a \r while in CRLF translation, followed by * the end of the buffer. */ assert(statePtr->inputTranslation == TCL_TRANSLATE_CRLF); assert(RemovePoint(bufPtr)[0] == '\r'); assert(BytesLeft(bufPtr) == 1); if (bufPtr->nextPtr == NULL) { /* * There's no more buffered data... */ if (statePtr->flags & CHANNEL_EOF) { /* * ...and there never will be. */ *p++ = '\r'; bytesToRead--; bufPtr->nextRemoved++; } else if (statePtr->flags & CHANNEL_BLOCKED) { /* * ...and we cannot get more now. */ SetFlag(statePtr, CHANNEL_NEED_MORE_DATA); break; } else { /* * ...so we need to get some. */ goto moreData; } } if (bufPtr->nextPtr) { /* * There's a next buffer. Shift orphan \r to it. */ ChannelBuffer *nextPtr = bufPtr->nextPtr; nextPtr->nextRemoved -= 1; RemovePoint(nextPtr)[0] = '\r'; bufPtr->nextRemoved++; } |
︙ | ︙ | |||
9865 9866 9867 9868 9869 9870 9871 | if ((GotFlag(statePtr, CHANNEL_NONBLOCKING) || allowShortReads) && GotFlag(statePtr, CHANNEL_BLOCKED)) { break; } /* | | | | | | | | | 9934 9935 9936 9937 9938 9939 9940 9941 9942 9943 9944 9945 9946 9947 9948 9949 9950 9951 9952 9953 9954 9955 9956 9957 9958 9959 9960 9961 9962 9963 9964 9965 | if ((GotFlag(statePtr, CHANNEL_NONBLOCKING) || allowShortReads) && GotFlag(statePtr, CHANNEL_BLOCKED)) { break; } /* * When there's no buffered data to read, and we're at EOF, escape to * the caller. */ if (GotFlag(statePtr, CHANNEL_EOF) && (bufPtr == NULL || IsBufferEmpty(bufPtr))) { break; } } if (bytesToRead == 0) { ResetFlag(statePtr, CHANNEL_BLOCKED); } assert(!GotFlag(statePtr, CHANNEL_EOF) || GotFlag(statePtr, CHANNEL_STICKY_EOF) || Tcl_InputBuffered((Tcl_Channel)chanPtr) == 0); assert(!(GotFlag(statePtr, CHANNEL_EOF|CHANNEL_BLOCKED) == (CHANNEL_EOF|CHANNEL_BLOCKED))); UpdateInterest(chanPtr); TclChannelRelease((Tcl_Channel)chanPtr); return (int)(p - dst); } /* *---------------------------------------------------------------------- |
︙ | ︙ |
Changes to generic/tclIOCmd.c.
︙ | ︙ | |||
21 22 23 24 25 26 27 | } AcceptCallback; /* * Thread local storage used to maintain a per-thread stdout channel obj. * It must be per-thread because of std channel limitations. */ | | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | } AcceptCallback; /* * Thread local storage used to maintain a per-thread stdout channel obj. * It must be per-thread because of std channel limitations. */ typedef struct { int initialized; /* Set to 1 when the module is initialized. */ Tcl_Obj *stdoutObjPtr; /* Cached stdout channel Tcl_Obj */ } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; /* |
︙ | ︙ | |||
109 110 111 112 113 114 115 | { Tcl_Channel chan; /* The channel to puts on. */ Tcl_Obj *string; /* String to write. */ Tcl_Obj *chanObjPtr = NULL; /* channel object. */ int newline; /* Add a newline at end? */ int result; /* Result of puts operation. */ int mode; /* Mode in which channel is opened. */ | < | 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | { Tcl_Channel chan; /* The channel to puts on. */ Tcl_Obj *string; /* String to write. */ Tcl_Obj *chanObjPtr = NULL; /* channel object. */ int newline; /* Add a newline at end? */ int result; /* Result of puts operation. */ int mode; /* Mode in which channel is opened. */ switch (objc) { case 2: /* [puts $x] */ string = objv[1]; newline = 1; break; |
︙ | ︙ | |||
156 157 158 159 160 161 162 | default: /* [puts] or * [puts some bad number of arguments...] */ Tcl_WrongNumArgs(interp, 1, objv, "?-nonewline? ?channelId? string"); return TCL_ERROR; } if (chanObjPtr == NULL) { | | | 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | default: /* [puts] or * [puts some bad number of arguments...] */ Tcl_WrongNumArgs(interp, 1, objv, "?-nonewline? ?channelId? string"); return TCL_ERROR; } if (chanObjPtr == NULL) { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); if (!tsdPtr->initialized) { tsdPtr->initialized = 1; TclNewLiteralStringObj(tsdPtr->stdoutObjPtr, "stdout"); Tcl_IncrRefCount(tsdPtr->stdoutObjPtr); Tcl_CreateThreadExitHandler(FinalizeIOCmdTSD, NULL); } |
︙ | ︙ | |||
1614 1615 1616 1617 1618 1619 1620 | if (!server && (reusea != -1 || reusep != -1)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "options -reuseaddr and -reuseport are only valid for servers", -1)); return TCL_ERROR; } | > | | > > | > > | > | > > | > > | > | | > > | | > > | < | | | 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 | if (!server && (reusea != -1 || reusep != -1)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "options -reuseaddr and -reuseport are only valid for servers", -1)); return TCL_ERROR; } /* * Set the options to their default value if the user didn't override * their value. */ if (reusep == -1) { reusep = 0; } if (reusea == -1) { reusea = 1; } /* * Build the bitset with the flags values. */ if (reusea) { flags |= TCL_TCPSERVER_REUSEADDR; } if (reusep) { flags |= TCL_TCPSERVER_REUSEPORT; } /* * All the arguments should have been parsed by now, 'a' points to the * last one, the port number. */ if (a != objc-1) { goto wrongNumArgs; } port = TclGetString(objv[a]); if (server) { AcceptCallback *acceptCallbackPtr = ckalloc(sizeof(AcceptCallback)); Tcl_IncrRefCount(script); acceptCallbackPtr->script = script; acceptCallbackPtr->interp = interp; chan = Tcl_OpenTcpServerEx(interp, port, host, flags, AcceptCallbackProc, acceptCallbackPtr); if (chan == NULL) { Tcl_DecrRefCount(script); ckfree(acceptCallbackPtr); return TCL_ERROR; } /* |
︙ | ︙ |
Changes to generic/tclIORChan.c.
︙ | ︙ | |||
230 231 232 233 234 235 236 | * command handler thread (CT), and the thread managing the channel (MT), * executed in CT. Tcl_Obj's are not allowed to cross thread boundaries. So we * forward an operation code, the argument details, and reference to results. * The command is assembled in the CT and belongs fully to that thread. No * sharing problems. */ | | | 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 | * command handler thread (CT), and the thread managing the channel (MT), * executed in CT. Tcl_Obj's are not allowed to cross thread boundaries. So we * forward an operation code, the argument details, and reference to results. * The command is assembled in the CT and belongs fully to that thread. No * sharing problems. */ typedef struct { int code; /* O: Ok/Fail of the cmd handler */ char *msgStr; /* O: Error message for handler failure */ int mustFree; /* O: True if msgStr is allocated, false if * otherwise (static). */ } ForwardParamBase; /* |
︙ | ︙ | |||
305 306 307 308 309 310 311 | typedef struct ForwardingResult ForwardingResult; /* * General event structure, with reference to operation specific data. */ | | | 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 | typedef struct ForwardingResult ForwardingResult; /* * General event structure, with reference to operation specific data. */ typedef struct { Tcl_Event event; /* Basic event data, has to be first item */ ForwardingResult *resultPtr; ForwardedOperation op; /* Forwarded driver operation */ ReflectedChannel *rcPtr; /* Channel instance */ ForwardParam *param; /* Packaged arguments and return values, a * ForwardParam pointer. */ } ForwardingEvent; |
︙ | ︙ | |||
342 343 344 345 346 347 348 | int result; /* TCL_OK or TCL_ERROR */ ForwardingEvent *evPtr; /* Event the result belongs to. */ ForwardingResult *prevPtr, *nextPtr; /* Links into the list of pending forwarded * results. */ }; | | | 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 | int result; /* TCL_OK or TCL_ERROR */ ForwardingEvent *evPtr; /* Event the result belongs to. */ ForwardingResult *prevPtr, *nextPtr; /* Links into the list of pending forwarded * results. */ }; typedef struct { /* * Table of all reflected channels owned by this thread. This is the * per-thread version of the per-interpreter map. */ ReflectedChannelMap *rcmPtr; } ThreadSpecificData; |
︙ | ︙ | |||
719 720 721 722 723 724 725 | Tcl_NewStringObj(chanPtr->state->channelName, -1)); return TCL_OK; error: Tcl_DecrRefCount(rcPtr->name); Tcl_DecrRefCount(rcPtr->methods); Tcl_DecrRefCount(rcPtr->cmd); | | | 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 | Tcl_NewStringObj(chanPtr->state->channelName, -1)); return TCL_OK; error: Tcl_DecrRefCount(rcPtr->name); Tcl_DecrRefCount(rcPtr->methods); Tcl_DecrRefCount(rcPtr->cmd); ckfree(rcPtr); return TCL_ERROR; #undef MODE #undef CMD } /* |
︙ | ︙ | |||
744 745 746 747 748 749 750 | * Side effects: * Posts events to a reflected channel, invokes event handlers. The * latter implies that arbitrary side effects are possible. * *---------------------------------------------------------------------- */ | | | 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 | * Side effects: * Posts events to a reflected channel, invokes event handlers. The * latter implies that arbitrary side effects are possible. * *---------------------------------------------------------------------- */ typedef struct { Tcl_Event header; ReflectedChannel *rcPtr; int events; } ReflectEvent; static int ReflectEventRun( |
︙ | ︙ | |||
847 848 849 850 851 852 853 | Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can not find reflected channel named \"%s\"", chanId)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CHANNEL", chanId, NULL); return TCL_ERROR; } /* | | > | | | 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 | Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can not find reflected channel named \"%s\"", chanId)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CHANNEL", chanId, NULL); return TCL_ERROR; } /* * Note that the search above subsumes several of the older checks, * namely: * * (1) Does the channel handle refer to a reflected channel? * (2) Is the post event issued from the interpreter holding the handler * of the reflected channel? * * A successful search answers yes to both. Because the map holds only * handles of reflected channels, and only of such whose handler is * defined in this interpreter. * * We keep the old checks for both, for paranioa, but abort now instead of * throwing errors, as failure now means that our internal datastructures |
︙ | ︙ | |||
935 936 937 938 939 940 941 | * Force creation of the RCM, for proper cleanup on thread teardown. * The teardown of unprocessed events is currently coupled to the * thread reflected channel map */ (void) GetThreadReflectedChannelMap(); | > | | 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 | * Force creation of the RCM, for proper cleanup on thread teardown. * The teardown of unprocessed events is currently coupled to the * thread reflected channel map */ (void) GetThreadReflectedChannelMap(); /* * XXX Race condition !! * XXX The destination thread may not exist anymore already. * XXX (Delayed postevent executed after channel got removed). * XXX Can we detect this ? (check the validity of the owner threadid ?) * XXX Actually, in that case the channel should be dead also ! */ Tcl_ThreadQueueEvent(rcPtr->owner, (Tcl_Event *) ev, TCL_QUEUE_TAIL); |
︙ | ︙ | |||
1217 1218 1219 1220 1221 1222 1223 | if (hPtr) { Tcl_DeleteHashEntry(hPtr); } } #endif tctPtr = ((Channel *)rcPtr->chan)->typePtr; if (tctPtr && tctPtr != &tclRChannelType) { | | | | 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 | if (hPtr) { Tcl_DeleteHashEntry(hPtr); } } #endif tctPtr = ((Channel *)rcPtr->chan)->typePtr; if (tctPtr && tctPtr != &tclRChannelType) { ckfree(tctPtr); ((Channel *)rcPtr->chan)->typePtr = NULL; } Tcl_EventuallyFree(rcPtr, (Tcl_FreeProc *) FreeReflectedChannel); return (result == TCL_OK) ? EOK : EINVAL; } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
1268 1269 1270 1271 1272 1273 1274 | p.input.buf = buf; p.input.toRead = toRead; ForwardOpToHandlerThread(rcPtr, ForwardedInput, &p); if (p.base.code != TCL_OK) { if (p.base.code < 0) { | > | > > | 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 | p.input.buf = buf; p.input.toRead = toRead; ForwardOpToHandlerThread(rcPtr, ForwardedInput, &p); if (p.base.code != TCL_OK) { if (p.base.code < 0) { /* * No error message, this is an errno signal. */ *errorCodePtr = -p.base.code; } else { PassReceivedError(rcPtr->chan, &p); *errorCodePtr = EINVAL; } p.input.toRead = -1; } else { |
︙ | ︙ | |||
1371 1372 1373 1374 1375 1376 1377 | p.output.buf = buf; p.output.toWrite = toWrite; ForwardOpToHandlerThread(rcPtr, ForwardedOutput, &p); if (p.base.code != TCL_OK) { if (p.base.code < 0) { | > | > > | 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 | p.output.buf = buf; p.output.toWrite = toWrite; ForwardOpToHandlerThread(rcPtr, ForwardedOutput, &p); if (p.base.code != TCL_OK) { if (p.base.code < 0) { /* * No error message, this is an errno signal. */ *errorCodePtr = -p.base.code; } else { PassReceivedError(rcPtr->chan, &p); *errorCodePtr = EINVAL; } p.output.toWrite = -1; } else { |
︙ | ︙ | |||
1422 1423 1424 1425 1426 1427 1428 | if (Tcl_GetIntFromObj(rcPtr->interp, resObj, &written) != TCL_OK) { Tcl_SetChannelError(rcPtr->chan, MarshallError(rcPtr->interp)); goto invalid; } if ((written == 0) && (toWrite > 0)) { /* | | | | 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 | if (Tcl_GetIntFromObj(rcPtr->interp, resObj, &written) != TCL_OK) { Tcl_SetChannelError(rcPtr->chan, MarshallError(rcPtr->interp)); goto invalid; } if ((written == 0) && (toWrite > 0)) { /* * The handler claims to have written nothing of what it was given. * That is bad. */ SetChannelErrorStr(rcPtr->chan, msg_write_nothing); goto invalid; } if (toWrite < written) { /* |
︙ | ︙ | |||
2369 2370 2371 2372 2373 2374 2375 | * Results: * The negative errno found in the error result, or 0. * * Side effects: * None. * * Users: | | | | 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 | * Results: * The negative errno found in the error result, or 0. * * Side effects: * None. * * Users: * ReflectInput/Output(), to enable the signaling of EAGAIN on 0-sized * short reads/writes. * *---------------------------------------------------------------------- */ static int ErrnoReturn( ReflectedChannel *rcPtr, |
︙ | ︙ | |||
2556 2557 2558 2559 2560 2561 2562 | * receiver, or this thread, as part of other parts in the thread * teardown. Such results are ignored. See ticket [b47b176adf] for the * identical race condition in Tcl 8.6 IORTrans. */ evPtr = resultPtr->evPtr; | > | > > | 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 | * receiver, or this thread, as part of other parts in the thread * teardown. Such results are ignored. See ticket [b47b176adf] for the * identical race condition in Tcl 8.6 IORTrans. */ evPtr = resultPtr->evPtr; /* * Basic crash safety until this routine can get revised [3411310] */ if (evPtr == NULL) { continue; } paramPtr = evPtr->param; if (!evPtr) { continue; } |
︙ | ︙ | |||
2671 2672 2673 2674 2675 2676 2677 | * The origin thread for one or more reflected channels is gone. * NOTE: If this function is called due to a thread getting killed the * per-interp DeleteReflectedChannelMap is apparently not called. */ /* * Go through the list of pending results and cancel all whose events were | | | | 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 | * The origin thread for one or more reflected channels is gone. * NOTE: If this function is called due to a thread getting killed the * per-interp DeleteReflectedChannelMap is apparently not called. */ /* * Go through the list of pending results and cancel all whose events were * destined for this thread. While this is in progress we block any other * access to the list of pending results. */ Tcl_MutexLock(&rcForwardMutex); for (resultPtr = forwardList; resultPtr != NULL; resultPtr = resultPtr->nextPtr) { |
︙ | ︙ | |||
2703 2704 2705 2706 2707 2708 2709 | * receiver, or this thread, as part of other parts in the thread * teardown. Such results are ignored. See ticket [b47b176adf] for the * identical race condition in Tcl 8.6 IORTrans. */ evPtr = resultPtr->evPtr; | > | > > | 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 | * receiver, or this thread, as part of other parts in the thread * teardown. Such results are ignored. See ticket [b47b176adf] for the * identical race condition in Tcl 8.6 IORTrans. */ evPtr = resultPtr->evPtr; /* * Basic crash safety until this routine can get revised [3411310] */ if (evPtr == NULL ) { continue; } paramPtr = evPtr->param; if (!evPtr) { continue; } |
︙ | ︙ | |||
2757 2758 2759 2760 2761 2762 2763 | static void ForwardOpToHandlerThread( ReflectedChannel *rcPtr, /* Channel instance */ ForwardedOperation op, /* Forwarded driver operation */ const void *param) /* Arguments */ { /* | | | | 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 | static void ForwardOpToHandlerThread( ReflectedChannel *rcPtr, /* Channel instance */ ForwardedOperation op, /* Forwarded driver operation */ const void *param) /* Arguments */ { /* * Core of the communication from OWNER to HANDLER thread. The receiver is * ForwardProc() below. */ Tcl_ThreadId dst = rcPtr->thread; ForwardingEvent *evPtr; ForwardingResult *resultPtr; /* |
︙ | ︙ | |||
2808 2809 2810 2811 2812 2813 2814 | resultPtr->evPtr = evPtr; /* * Now execute the forward. */ TclSpliceIn(resultPtr, forwardList); | > > | > | 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 | resultPtr->evPtr = evPtr; /* * Now execute the forward. */ TclSpliceIn(resultPtr, forwardList); /* * Do not unlock here. That is done by the ConditionWait. */ /* * Ensure cleanup of the event if the origin thread exits while this event * is pending or in progress. Exit of the destination thread is handled by * DeleteThreadReflectedChannelMap(), this is set up by * GetThreadReflectedChannelMap(). This is what we use the 'forwardList' * (see above) for. |
︙ | ︙ | |||
2884 2885 2886 2887 2888 2889 2890 | * The receiver part for the operations coming from the OWNER thread. * See ForwardOpToHandlerThread() for the transmitter. * * Notes regarding access to the referenced data. * * In principle the data belongs to the originating thread (see | | | 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 | * The receiver part for the operations coming from the OWNER thread. * See ForwardOpToHandlerThread() for the transmitter. * * Notes regarding access to the referenced data. * * In principle the data belongs to the originating thread (see * evPtr->src), however this thread is currently blocked at (*), i.e., * quiescent. Because of this we can treat the data as belonging to us, * without fear of race conditions. I.e. we can read and write as we like. * * The only thing we cannot be sure of is the resultPtr. This can be be * NULLed if the originating thread went away while the event is handled * here now. */ |
︙ | ︙ |
Changes to generic/tclIORTrans.c.
︙ | ︙ | |||
325 326 327 328 329 330 331 | int result; /* TCL_OK or TCL_ERROR */ ForwardingEvent *evPtr; /* Event the result belongs to. */ ForwardingResult *prevPtr, *nextPtr; /* Links into the list of pending forwarded * results. */ }; | | | 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 | int result; /* TCL_OK or TCL_ERROR */ ForwardingEvent *evPtr; /* Event the result belongs to. */ ForwardingResult *prevPtr, *nextPtr; /* Links into the list of pending forwarded * results. */ }; typedef struct { /* * Table of all reflected transformations owned by this thread. */ ReflectedTransformMap *rtmPtr; } ThreadSpecificData; |
︙ | ︙ |
Changes to generic/tclIOSock.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tclInt.h" #if defined(_WIN32) && defined(UNICODE) | > | > | | > > > | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tclInt.h" #if defined(_WIN32) && defined(UNICODE) /* * On Windows, we need to do proper Unicode->UTF-8 conversion. */ typedef struct { int initialized; Tcl_DString errorMsg; /* UTF-8 encoded error-message */ } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; #undef gai_strerror static const char * gai_strerror( int code) { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); if (tsdPtr->initialized) { Tcl_DStringFree(&tsdPtr->errorMsg); } else { tsdPtr->initialized = 1; } |
︙ | ︙ | |||
122 123 124 125 126 127 128 | if (current < size) { len = sizeof(int); setsockopt((SOCKET)(size_t) sock, SOL_SOCKET, SO_SNDBUF, (char *) &size, len); } len = sizeof(int); getsockopt((SOCKET)(size_t) sock, SOL_SOCKET, SO_RCVBUF, | | | 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | if (current < size) { len = sizeof(int); setsockopt((SOCKET)(size_t) sock, SOL_SOCKET, SO_SNDBUF, (char *) &size, len); } len = sizeof(int); getsockopt((SOCKET)(size_t) sock, SOL_SOCKET, SO_RCVBUF, (char *) ¤t, &len); if (current < size) { len = sizeof(int); setsockopt((SOCKET)(size_t) sock, SOL_SOCKET, SO_RCVBUF, (char *) &size, len); } return TCL_OK; } |
︙ | ︙ | |||
211 212 213 214 215 216 217 | hints.ai_socktype = SOCK_STREAM; #if 0 /* * We found some problems when using AI_ADDRCONFIG, e.g. on systems that * have no networking besides the loopback interface and want to resolve * localhost. See [Bugs 3385024, 3382419, 3382431]. As the advantage of | | | 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | hints.ai_socktype = SOCK_STREAM; #if 0 /* * We found some problems when using AI_ADDRCONFIG, e.g. on systems that * have no networking besides the loopback interface and want to resolve * localhost. See [Bugs 3385024, 3382419, 3382431]. As the advantage of * using AI_ADDRCONFIG is probably low even in situations where it works, * we'll leave it out for now. After all, it is just an optimisation. * * Missing on: OpenBSD, NetBSD. * Causes failure when used on AIX 5.1 and HP-UX */ #if defined(AI_ADDRCONFIG) && !defined(_AIX) && !defined(__hpux) |
︙ | ︙ | |||
296 297 298 299 300 301 302 | * is left in the interp's result if interp is not NULL. * * Side effects: * Opens a server socket and creates a new channel. * *---------------------------------------------------------------------- */ | > > > | > | > | < | | 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 | * is left in the interp's result if interp is not NULL. * * Side effects: * Opens a server socket and creates a new channel. * *---------------------------------------------------------------------- */ Tcl_Channel Tcl_OpenTcpServer( Tcl_Interp *interp, int port, const char *host, Tcl_TcpAcceptProc *acceptProc, ClientData callbackData) { char portbuf[TCL_INTEGER_SPACE]; TclFormatInt(portbuf, port); return Tcl_OpenTcpServerEx(interp, portbuf, host, TCL_TCPSERVER_REUSEADDR, acceptProc, callbackData); } /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * End: */ |
Changes to generic/tclIOUtil.c.
︙ | ︙ | |||
53 54 55 56 57 58 59 | * This structure holds per-thread private copy of the current directory * maintained by the global cwdPathPtr. This structure holds per-thread * private copies of some global data. This way we avoid most of the * synchronization calls which boosts performance, at cost of having to update * this information each time the corresponding epoch counter changes. */ | | | 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | * This structure holds per-thread private copy of the current directory * maintained by the global cwdPathPtr. This structure holds per-thread * private copies of some global data. This way we avoid most of the * synchronization calls which boosts performance, at cost of having to update * this information each time the corresponding epoch counter changes. */ typedef struct { int initialized; size_t cwdPathEpoch; size_t filesystemEpoch; Tcl_Obj *cwdPathPtr; ClientData cwdClientData; FilesystemRecord *filesystemList; size_t claims; |
︙ | ︙ | |||
607 608 609 610 611 612 613 614 615 616 617 618 619 620 | } tsdPtr->filesystemList = list; tsdPtr->filesystemEpoch = theFilesystemEpoch; Tcl_MutexUnlock(&filesystemMutex); while (toFree) { FilesystemRecord *next = toFree->nextPtr; toFree->fsPtr = NULL; ckfree(toFree); toFree = next; } /* * Make sure the above gets released on thread exit. | > | 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 | } tsdPtr->filesystemList = list; tsdPtr->filesystemEpoch = theFilesystemEpoch; Tcl_MutexUnlock(&filesystemMutex); while (toFree) { FilesystemRecord *next = toFree->nextPtr; toFree->fsPtr = NULL; ckfree(toFree); toFree = next; } /* * Make sure the above gets released on thread exit. |
︙ | ︙ | |||
668 669 670 671 672 673 674 | size_t TclFSEpoch(void) { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey); return tsdPtr->filesystemEpoch; } | < | 669 670 671 672 673 674 675 676 677 678 679 680 681 682 | size_t TclFSEpoch(void) { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey); return tsdPtr->filesystemEpoch; } /* * If non-NULL, clientData is owned by us and must be freed later. */ static void FsUpdateCwd( |
︙ | ︙ | |||
780 781 782 783 784 785 786 | * needed. */ fsRecPtr = filesystemList; while (fsRecPtr != NULL) { FilesystemRecord *tmpFsRecPtr = fsRecPtr->nextPtr; | > | > | 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 | * needed. */ fsRecPtr = filesystemList; while (fsRecPtr != NULL) { FilesystemRecord *tmpFsRecPtr = fsRecPtr->nextPtr; /* * The native filesystem is static, so we don't free it. */ if (fsRecPtr != &nativeFilesystemRecord) { ckfree(fsRecPtr); } fsRecPtr = tmpFsRecPtr; } if (++theFilesystemEpoch == 0) { |
︙ | ︙ | |||
943 944 945 946 947 948 949 | * updated immediately. * *---------------------------------------------------------------------- */ int Tcl_FSUnregister( | | | 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 | * updated immediately. * *---------------------------------------------------------------------- */ int Tcl_FSUnregister( const Tcl_Filesystem *fsPtr)/* The filesystem record to remove. */ { int retVal = TCL_ERROR; FilesystemRecord *fsRecPtr; Tcl_MutexLock(&filesystemMutex); /* |
︙ | ︙ | |||
1229 1230 1231 1232 1233 1234 1235 | if (path[len-1] == '/') { /* * Deal with the root of the volume. */ len--; } | | | 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 | if (path[len-1] == '/') { /* * Deal with the root of the volume. */ len--; } len++; /* account for '/' in the mElt [Bug 1602539] */ mElt = TclNewFSPathObj(pathPtr, mount + len, mlen - len); Tcl_ListObjAppendElement(NULL, resultPtr, mElt); } /* * No need to increment gLength, since we don't want to compare * mounts against mounts. */ |
︙ | ︙ | |||
1399 1400 1401 1402 1403 1404 1405 | { FilesystemRecord *fsRecPtr, *firstFsRecPtr; /* * Call each of the "normalise path" functions in succession. This is a * special case, in which if we have a native filesystem handler, we call * it first. This is because the root of Tcl's filesystem is always a | | | 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 | { FilesystemRecord *fsRecPtr, *firstFsRecPtr; /* * Call each of the "normalise path" functions in succession. This is a * special case, in which if we have a native filesystem handler, we call * it first. This is because the root of Tcl's filesystem is always a * native filesystem (i.e., '/' on unix is native). */ firstFsRecPtr = FsGetFirstFilesystem(); Claim(); for (fsRecPtr=firstFsRecPtr; fsRecPtr!=NULL; fsRecPtr=fsRecPtr->nextPtr) { if (fsRecPtr->fsPtr != &tclNativeFilesystem) { |
︙ | ︙ | |||
1521 1522 1523 1524 1525 1526 1527 | * operations. */ { int mode, modeArgc, c, i, gotRW; const char **modeArgv, *flag; #define RW_MODES (O_RDONLY|O_WRONLY|O_RDWR) /* | | | 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 | * operations. */ { int mode, modeArgc, c, i, gotRW; const char **modeArgv, *flag; #define RW_MODES (O_RDONLY|O_WRONLY|O_RDWR) /* * Check for the simpler fopen-like access modes (e.g., "r"). They are * distinguished from the POSIX access modes by the presence of a * lower-case first letter. */ *seekFlagPtr = 0; *binaryPtr = 0; mode = 0; |
︙ | ︙ | |||
2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 | fsRecPtr = FsGetFirstFilesystem(); Claim(); for (; (retVal == NULL) && (fsRecPtr != NULL); fsRecPtr = fsRecPtr->nextPtr) { ClientData retCd; TclFSGetCwdProc2 *proc2; if (fsRecPtr->fsPtr->getCwdProc == NULL) { continue; } if (fsRecPtr->fsPtr->version == TCL_FILESYSTEM_VERSION_1) { retVal = fsRecPtr->fsPtr->getCwdProc(interp); continue; | > | 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 | fsRecPtr = FsGetFirstFilesystem(); Claim(); for (; (retVal == NULL) && (fsRecPtr != NULL); fsRecPtr = fsRecPtr->nextPtr) { ClientData retCd; TclFSGetCwdProc2 *proc2; if (fsRecPtr->fsPtr->getCwdProc == NULL) { continue; } if (fsRecPtr->fsPtr->version == TCL_FILESYSTEM_VERSION_1) { retVal = fsRecPtr->fsPtr->getCwdProc(interp); continue; |
︙ | ︙ | |||
3139 3140 3141 3142 3143 3144 3145 | *---------------------------------------------------------------------- */ /* * Workaround for issue with modern HPUX which do allow the unlink (no ETXTBSY * error) yet somehow trash some internal data structures which prevents the * second and further shared libraries from getting properly loaded. Only the | | | | > > | | > | | | | < > | > | | > | 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 | *---------------------------------------------------------------------- */ /* * Workaround for issue with modern HPUX which do allow the unlink (no ETXTBSY * error) yet somehow trash some internal data structures which prevents the * second and further shared libraries from getting properly loaded. Only the * first is ok. We try to get around the issue by not unlinking, i.e., * emulating the behaviour of the older HPUX which denied removal. * * Doing the unlink is also an issue within docker containers, whose AUFS * bungles this as well, see * https://github.com/dotcloud/docker/issues/1911 * * For these situations the change below makes the execution of the unlink * semi-controllable at runtime. * * An AUFS filesystem (if it can be detected) will force avoidance of * unlink. The env variable TCL_TEMPLOAD_NO_UNLINK allows detection of a * users general request (unlink and not. * * By default the unlink is done (if not in AUFS). However if the variable is * present and set to true (any integer > 0) then the unlink is skipped. */ int TclSkipUnlink( Tcl_Obj *shlibFile) { /* * Order of testing: * 1. On hpux we generally want to skip unlink in general * * Outside of hpux then: * 2. For a general user request (TCL_TEMPLOAD_NO_UNLINK present, * non-empty, => int) * 3. For general AUFS environment (statfs, if available). * * Ad 2: This variable can disable/override the AUFS detection, i.e. for * testing if a newer AUFS does not have the bug any more. * * Ad 3: This is conditionally compiled in. Condition currently must be * set manually. This part needs proper tests in the configure(.in). */ #ifdef hpux return 1; #else char *skipstr = getenv("TCL_TEMPLOAD_NO_UNLINK"); if (skipstr && (skipstr[0] != '\0')) { return atoi(skipstr); } #ifdef TCL_TEMPLOAD_NO_UNLINK #ifndef NO_FSTATFS { struct statfs fs; /* * Have fstatfs. May not have the AUFS super magic ... Indeed our build * box is too old to have it directly in the headers. Define taken from * http://mooon.googlecode.com/svn/trunk/linux_include/linux/aufs_type.h * http://aufs.sourceforge.net/ * Better reference will be gladly taken. */ #ifndef AUFS_SUPER_MAGIC #define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's') #endif /* AUFS_SUPER_MAGIC */ if ((statfs(Tcl_GetString (shlibFile), &fs) == 0) && (fs.f_type == AUFS_SUPER_MAGIC)) { return 1; } } #endif /* ... NO_FSTATFS */ #endif /* ... TCL_TEMPLOAD_NO_UNLINK */ /* * Fallback: !hpux, no EV override, no AUFS (detection, nor detected): * Don't skip */ return 0; #endif /* hpux */ } int Tcl_LoadFile( Tcl_Interp *interp, /* Used for error reporting. */ |
︙ | ︙ | |||
3411 3412 3413 3414 3415 3416 3417 | } /* * Try to delete the file immediately - this is possible in some OSes, and * avoids any worries about leaving the copy laying around on exit. */ | < | | | 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 | } /* * Try to delete the file immediately - this is possible in some OSes, and * avoids any worries about leaving the copy laying around on exit. */ if (!TclSkipUnlink(copyToPtr) && (Tcl_FSDeleteFile(copyToPtr) == TCL_OK)) { Tcl_DecrRefCount(copyToPtr); /* * We tell our caller about the real shared library which was loaded. * Note that this does mean that the package list maintained by 'load' * will store the original (vfs) path alongside the temporary load * handle and unload proc ptr. |
︙ | ︙ |
Changes to generic/tclInt.h.
︙ | ︙ | |||
1353 1354 1355 1356 1357 1358 1359 | void *data); /* * This is a convenience macro used to initialize a thread local storage ptr. */ #define TCL_TSD_INIT(keyPtr) \ | | | 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 | void *data); /* * This is a convenience macro used to initialize a thread local storage ptr. */ #define TCL_TSD_INIT(keyPtr) \ Tcl_GetThreadData((keyPtr), sizeof(ThreadSpecificData)) /* *---------------------------------------------------------------- * Data structures related to bytecode compilation and execution. These are * used primarily in tclCompile.c, tclExecute.c, and tclBasic.c. *---------------------------------------------------------------- */ |
︙ | ︙ |
Changes to generic/tclNamesp.c.
︙ | ︙ | |||
27 28 29 30 31 32 33 | #include "tclCompile.h" /* for TclLogCommandInfo visibility */ /* * Thread-local storage used to avoid having a global lock on data that is not * limited to a single interpreter. */ | | | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | #include "tclCompile.h" /* for TclLogCommandInfo visibility */ /* * Thread-local storage used to avoid having a global lock on data that is not * limited to a single interpreter. */ typedef struct { size_t numNsCreated; /* Count of the number of namespaces created * within the thread. This value is used as a * unique id for each namespace. Cannot be * per-interp because the nsId is used to * distinguish objects which can be passed * around between interps in the same thread, * but does not need to be global because |
︙ | ︙ |
Changes to generic/tclOOCall.c.
︙ | ︙ | |||
615 616 617 618 619 620 621 622 623 624 625 626 627 628 | int isNew; hPtr = Tcl_CreateHashEntry(namesPtr, (char *) namePtr, &isNew); if (isNew) { int isWanted = (!(flags & PUBLIC_METHOD) || (mPtr->flags & PUBLIC_METHOD)) ? IN_LIST : 0; Tcl_SetHashValue(hPtr, INT2PTR(isWanted)); } else if ((PTR2INT(Tcl_GetHashValue(hPtr)) & NO_IMPLEMENTATION) && mPtr->typePtr != NULL) { int isWanted = PTR2INT(Tcl_GetHashValue(hPtr)); isWanted &= ~NO_IMPLEMENTATION; Tcl_SetHashValue(hPtr, INT2PTR(isWanted)); | > | 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 | int isNew; hPtr = Tcl_CreateHashEntry(namesPtr, (char *) namePtr, &isNew); if (isNew) { int isWanted = (!(flags & PUBLIC_METHOD) || (mPtr->flags & PUBLIC_METHOD)) ? IN_LIST : 0; isWanted |= (mPtr->typePtr == NULL ? NO_IMPLEMENTATION : 0); Tcl_SetHashValue(hPtr, INT2PTR(isWanted)); } else if ((PTR2INT(Tcl_GetHashValue(hPtr)) & NO_IMPLEMENTATION) && mPtr->typePtr != NULL) { int isWanted = PTR2INT(Tcl_GetHashValue(hPtr)); isWanted &= ~NO_IMPLEMENTATION; Tcl_SetHashValue(hPtr, INT2PTR(isWanted)); |
︙ | ︙ |
Changes to generic/tclObj.c.
︙ | ︙ | |||
71 72 73 74 75 76 77 | * of the following structure. For multi-threaded implementations, there is * one instance of this structure for each thread. * * Notice that different structures with the same name appear in other files. * The structure defined below is used in this file only. */ | | | 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | * of the following structure. For multi-threaded implementations, there is * one instance of this structure for each thread. * * Notice that different structures with the same name appear in other files. * The structure defined below is used in this file only. */ typedef struct { Tcl_HashTable *lineCLPtr; /* This table remembers for each Tcl_Obj * generated by a call to the function * TclSubstTokens() from a literal text * where bs+nl sequences occured in it, if * any. I.e. this table keeps track of * invisible and stripped continuation lines. * Its keys are Tcl_Obj pointers, the values |
︙ | ︙ | |||
4451 4452 4453 4454 4455 4456 4457 | int Tcl_RepresentationCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { | < < | | | > > > > | | | < < > | 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 | int Tcl_RepresentationCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Tcl_Obj *descObj; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "value"); return TCL_ERROR; } /* * Value is a bignum with a refcount of 14, object pointer at 0x12345678, * internal representation 0x45671234:0x98765432, string representation * "1872361827361287" */ descObj = Tcl_ObjPrintf("value is a %s with a refcount of %d," " object pointer at %p", objv[1]->typePtr ? objv[1]->typePtr->name : "pure string", objv[1]->refCount, objv[1]); if (objv[1]->typePtr) { if (objv[1]->typePtr == &tclDoubleType) { Tcl_AppendPrintfToObj(descObj, ", internal representation %g", objv[1]->internalRep.doubleValue); } else { Tcl_AppendPrintfToObj(descObj, ", internal representation %p:%p", (void *) objv[1]->internalRep.twoPtrValue.ptr1, (void *) objv[1]->internalRep.twoPtrValue.ptr2); } } if (objv[1]->bytes) { Tcl_AppendToObj(descObj, ", string representation \"", -1); Tcl_AppendLimitedToObj(descObj, objv[1]->bytes, objv[1]->length, 16, "..."); Tcl_AppendToObj(descObj, "\"", -1); |
︙ | ︙ |
Changes to generic/tclRegexp.c.
︙ | ︙ | |||
60 61 62 63 64 65 66 | /* * Thread local storage used to maintain a per-thread cache of compiled * regular expressions. */ #define NUM_REGEXPS 30 | | | 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | /* * Thread local storage used to maintain a per-thread cache of compiled * regular expressions. */ #define NUM_REGEXPS 30 typedef struct { int initialized; /* Set to 1 when the module is initialized. */ char *patterns[NUM_REGEXPS];/* Strings corresponding to compiled regular * expression patterns. NULL means that this * slot isn't used. Malloc-ed. */ int patLengths[NUM_REGEXPS];/* Number of non-null characters in * corresponding entry in patterns. -1 means * entry isn't used. */ |
︙ | ︙ | |||
675 676 677 678 679 680 681 | * Assume that there will never be more than INT_MAX subexpressions. This * is a pretty reasonable assumption; the RE engine doesn't scale _that_ * well and Tcl has other limits that constrain things as well... */ resultObj = Tcl_NewObj(); Tcl_ListObjAppendElement(NULL, resultObj, | | | 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 | * Assume that there will never be more than INT_MAX subexpressions. This * is a pretty reasonable assumption; the RE engine doesn't scale _that_ * well and Tcl has other limits that constrain things as well... */ resultObj = Tcl_NewObj(); Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewWideIntObj((Tcl_WideInt) regexpPtr->re.re_nsub)); /* * Now append a list of all the bit-flags set for the RE. */ TclNewObj(infoObj); for (inf=infonames ; inf->bit != 0 ; inf++) { |
︙ | ︙ |
Changes to generic/tclStrToD.c.
︙ | ︙ | |||
3801 3802 3803 3804 3805 3806 3807 | if (m2plus > m2minus) { mp_mul_2d(&mplus, 1, &mplus); } mp_div_d(&S, 5, &S, NULL); --s5; /* | | | 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 | if (m2plus > m2minus) { mp_mul_2d(&mplus, 1, &mplus); } mp_div_d(&S, 5, &S, NULL); --s5; /* * IDEA: It might possibly be a win to fall back to int64_t * arithmetic here if S < 2**64/10. But it's a win only for * a fairly narrow range of magnitudes so perhaps not worth * bothering. We already know that we shorten the * denominator by at least 1 mp_digit, perhaps 2, as we do * the conversion for 17 digits of significance. * Possible savings: * 10**26 1 trip through loop before fallback possible |
︙ | ︙ | |||
3966 3967 3968 3969 3970 3971 3972 | } mp_mul_2d(&b, g, &b); /* * As with the shortening bignum conversion, it's possible at this * point that we will have reduced the denominator to less than * 2**64/10, at which point it would be possible to fall back to | | | 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 | } mp_mul_2d(&b, g, &b); /* * As with the shortening bignum conversion, it's possible at this * point that we will have reduced the denominator to less than * 2**64/10, at which point it would be possible to fall back to * to int64_t arithmetic. But the potential payoff is tremendously * less - unless we're working in F format - because we know that * three groups of digits will always suffice for %#.17e, the * longest format that doesn't introduce empty precision. * * Extract the next group of digits. */ |
︙ | ︙ |
Changes to generic/tclStringObj.c.
︙ | ︙ | |||
1666 1667 1668 1669 1670 1671 1672 | /* * Format string is NUL-terminated. */ while (*format != '\0') { char *end; | | | > > > | 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 | /* * Format string is NUL-terminated. */ while (*format != '\0') { char *end; int gotMinus = 0, gotHash = 0, gotZero = 0, gotSpace = 0, gotPlus = 0; int width, gotPrecision, precision, sawFlag, useShort = 0, useBig = 0; #ifndef TCL_WIDE_INT_IS_LONG int useWide = 0; #endif int newXpg, numChars, allocSegment = 0, segmentLimit, segmentNumBytes; Tcl_Obj *segment; Tcl_UniChar ch; int step = Tcl_UtfToUniChar(format, &ch); format += step; if (ch != '%') { |
︙ | ︙ | |||
1743 1744 1745 1746 1747 1748 1749 | goto errorMsg; } /* * Step 2. Set of flags. */ | < | 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 | goto errorMsg; } /* * Step 2. Set of flags. */ sawFlag = 1; do { switch (ch) { case '-': gotMinus = 1; break; case '#': |
︙ | ︙ | |||
1844 1845 1846 1847 1848 1849 1850 | step = Tcl_UtfToUniChar(format, &ch); } /* * Step 5. Length modifier. */ | < > | | | > | > > > > | | | > > > > > > | > > > > > > > > | 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 | step = Tcl_UtfToUniChar(format, &ch); } /* * Step 5. Length modifier. */ if (ch == 'h') { useShort = 1; format += step; step = Tcl_UtfToUniChar(format, &ch); } else if (ch == 'l') { format += step; step = Tcl_UtfToUniChar(format, &ch); if (ch == 'l') { useBig = 1; format += step; step = Tcl_UtfToUniChar(format, &ch); #ifndef TCL_WIDE_INT_IS_LONG } else { useWide = 1; #endif } } else if (ch == 'I') { if ((format[1] == '6') && (format[2] == '4')) { format += (step + 2); step = Tcl_UtfToUniChar(format, &ch); #ifndef TCL_WIDE_INT_IS_LONG useWide = 1; #endif } else if ((format[1] == '3') && (format[2] == '2')) { format += (step + 2); step = Tcl_UtfToUniChar(format, &ch); } else { format += step; step = Tcl_UtfToUniChar(format, &ch); } } else if ((ch == 't') || (ch == 'z')) { format += step; step = Tcl_UtfToUniChar(format, &ch); #ifndef TCL_WIDE_INT_IS_LONG if (sizeof(size_t) > sizeof(int)) { useWide = 1; } #endif } else if ((ch == 'q') ||(ch == 'j')) { format += step; step = Tcl_UtfToUniChar(format, &ch); #ifndef TCL_WIDE_INT_IS_LONG useWide = 1; #endif } format += step; span = format; /* * Step 6. The actual conversion character. |
︙ | ︙ | |||
1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 | if (useBig) { msg = "unsigned bignum format is invalid"; errCode = "BADUNSIGNED"; goto errorMsg; } case 'd': case 'o': case 'x': case 'X': case 'b': { short s = 0; /* Silence compiler warning; only defined and * used when useShort is true. */ long l; Tcl_WideInt w; mp_int big; int toAppend, isNegative = 0; if (useBig) { if (Tcl_GetBignumFromObj(interp, segment, &big) != TCL_OK) { goto error; } isNegative = (mp_cmp_d(&big, 0) == MP_LT); } else if (useWide) { if (Tcl_GetWideIntFromObj(NULL, segment, &w) != TCL_OK) { Tcl_Obj *objPtr; if (Tcl_GetBignumFromObj(interp,segment,&big) != TCL_OK) { goto error; } mp_mod_2d(&big, (int) CHAR_BIT*sizeof(Tcl_WideInt), &big); objPtr = Tcl_NewBignumObj(&big); Tcl_IncrRefCount(objPtr); Tcl_GetWideIntFromObj(NULL, objPtr, &w); Tcl_DecrRefCount(objPtr); } isNegative = (w < (Tcl_WideInt) 0); } else if (TclGetLongFromObj(NULL, segment, &l) != TCL_OK) { if (Tcl_GetWideIntFromObj(NULL, segment, &w) != TCL_OK) { Tcl_Obj *objPtr; if (Tcl_GetBignumFromObj(interp,segment,&big) != TCL_OK) { goto error; } | > > > > > > > > | 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 | if (useBig) { msg = "unsigned bignum format is invalid"; errCode = "BADUNSIGNED"; goto errorMsg; } case 'd': case 'o': case 'p': case 'x': case 'X': case 'b': { short s = 0; /* Silence compiler warning; only defined and * used when useShort is true. */ long l; Tcl_WideInt w; mp_int big; int toAppend, isNegative = 0; #ifndef TCL_WIDE_INT_IS_LONG if (ch == 'p') { useWide = 1; } #endif if (useBig) { if (Tcl_GetBignumFromObj(interp, segment, &big) != TCL_OK) { goto error; } isNegative = (mp_cmp_d(&big, 0) == MP_LT); #ifndef TCL_WIDE_INT_IS_LONG } else if (useWide) { if (Tcl_GetWideIntFromObj(NULL, segment, &w) != TCL_OK) { Tcl_Obj *objPtr; if (Tcl_GetBignumFromObj(interp,segment,&big) != TCL_OK) { goto error; } mp_mod_2d(&big, (int) CHAR_BIT*sizeof(Tcl_WideInt), &big); objPtr = Tcl_NewBignumObj(&big); Tcl_IncrRefCount(objPtr); Tcl_GetWideIntFromObj(NULL, objPtr, &w); Tcl_DecrRefCount(objPtr); } isNegative = (w < (Tcl_WideInt) 0); #endif } else if (TclGetLongFromObj(NULL, segment, &l) != TCL_OK) { if (Tcl_GetWideIntFromObj(NULL, segment, &w) != TCL_OK) { Tcl_Obj *objPtr; if (Tcl_GetBignumFromObj(interp,segment,&big) != TCL_OK) { goto error; } |
︙ | ︙ | |||
1989 1990 1991 1992 1993 1994 1995 | if ((isNegative || gotPlus || gotSpace) && (useBig || ch=='d')) { Tcl_AppendToObj(segment, (isNegative ? "-" : gotPlus ? "+" : " "), 1); segmentLimit -= 1; } | | > > > | 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 | if ((isNegative || gotPlus || gotSpace) && (useBig || ch=='d')) { Tcl_AppendToObj(segment, (isNegative ? "-" : gotPlus ? "+" : " "), 1); segmentLimit -= 1; } if (gotHash || (ch == 'p')) { switch (ch) { case 'o': Tcl_AppendToObj(segment, "0", 1); segmentLimit -= 1; precision--; break; case 'p': case 'x': case 'X': Tcl_AppendToObj(segment, "0x", 2); segmentLimit -= 2; break; case 'b': Tcl_AppendToObj(segment, "0b", 2); segmentLimit -= 2; break; } } switch (ch) { case 'd': { int length; Tcl_Obj *pure; const char *bytes; if (useShort) { pure = Tcl_NewIntObj((int) s); #ifndef TCL_WIDE_INT_IS_LONG } else if (useWide) { pure = Tcl_NewWideIntObj(w); #endif } else if (useBig) { pure = Tcl_NewBignumObj(&big); } else { pure = Tcl_NewLongObj(l); } Tcl_IncrRefCount(pure); bytes = TclGetStringFromObj(pure, &length); |
︙ | ︙ | |||
2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 | Tcl_AppendToObj(segment, bytes, toAppend); Tcl_DecrRefCount(pure); break; } case 'u': case 'o': case 'x': case 'X': case 'b': { Tcl_WideUInt bits = (Tcl_WideUInt) 0; Tcl_WideInt numDigits = (Tcl_WideInt) 0; int length, numBits = 4, base = 16, index = 0, shift = 0; Tcl_Obj *pure; | > | 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 | Tcl_AppendToObj(segment, bytes, toAppend); Tcl_DecrRefCount(pure); break; } case 'u': case 'o': case 'p': case 'x': case 'X': case 'b': { Tcl_WideUInt bits = (Tcl_WideUInt) 0; Tcl_WideInt numDigits = (Tcl_WideInt) 0; int length, numBits = 4, base = 16, index = 0, shift = 0; Tcl_Obj *pure; |
︙ | ︙ | |||
2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 | unsigned short us = (unsigned short) s; bits = (Tcl_WideUInt) us; while (us) { numDigits++; us /= base; } } else if (useWide) { Tcl_WideUInt uw = (Tcl_WideUInt) w; bits = uw; while (uw) { numDigits++; uw /= base; } } else if (useBig && big.used) { int leftover = (big.used * DIGIT_BIT) % numBits; mp_digit mask = (~(mp_digit)0) << (DIGIT_BIT-leftover); numDigits = 1 + (((Tcl_WideInt) big.used * DIGIT_BIT) / numBits); while ((mask & big.dp[big.used-1]) == 0) { | > > | 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 | unsigned short us = (unsigned short) s; bits = (Tcl_WideUInt) us; while (us) { numDigits++; us /= base; } #ifndef TCL_WIDE_INT_IS_LONG } else if (useWide) { Tcl_WideUInt uw = (Tcl_WideUInt) w; bits = uw; while (uw) { numDigits++; uw /= base; } #endif } else if (useBig && big.used) { int leftover = (big.used * DIGIT_BIT) % numBits; mp_digit mask = (~(mp_digit)0) << (DIGIT_BIT-leftover); numDigits = 1 + (((Tcl_WideInt) big.used * DIGIT_BIT) / numBits); while ((mask & big.dp[big.used-1]) == 0) { |
︙ | ︙ | |||
2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 | break; } case 'c': case 'i': case 'u': case 'd': case 'o': case 'x': case 'X': seekingConversion = 0; switch (size) { case -1: case 0: Tcl_ListObjAppendElement(NULL, list, Tcl_NewLongObj( | > | 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 | break; } case 'c': case 'i': case 'u': case 'd': case 'o': case 'p': case 'x': case 'X': seekingConversion = 0; switch (size) { case -1: case 0: Tcl_ListObjAppendElement(NULL, list, Tcl_NewLongObj( |
︙ | ︙ | |||
2513 2514 2515 2516 2517 2518 2519 | p++; break; /* TODO: support for bignum arguments */ case 'l': ++size; p++; break; | | > > > > > > > > > > > > | 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 | p++; break; /* TODO: support for bignum arguments */ case 'l': ++size; p++; break; case 't': case 'z': if (sizeof(size_t) == sizeof(Tcl_WideInt)) { size = 2; } p++; break; case 'j': case 'q': size = 2; p++; break; case 'I': if (p[1]=='6' && p[2]=='4') { p += 2; size = 2; } else if (p[1]=='3' && p[2]=='2') { p += 2; } else if (sizeof(size_t) == sizeof(Tcl_WideInt)) { size = 2; } p++; break; case 'h': size = -1; default: p++; |
︙ | ︙ | |||
2728 2729 2730 2731 2732 2733 2734 | objResultPtr = objPtr; } if (0 == Tcl_AttemptSetObjLength(objResultPtr, count*length)) { if (interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "string size overflow: unable to alloc %" | | | 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 | objResultPtr = objPtr; } if (0 == Tcl_AttemptSetObjLength(objResultPtr, count*length)) { if (interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "string size overflow: unable to alloc %" TCL_LL_MODIFIER "d bytes", (Tcl_WideUInt)STRING_SIZE(count*length))); Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL); } return TCL_ERROR; } Tcl_SetObjLength(objResultPtr, length); while (count - done > done) { |
︙ | ︙ | |||
2952 2953 2954 2955 2956 2957 2958 | /* Ugly interface! Force resize of the unicode array. */ Tcl_GetUnicodeFromObj(objResultPtr, &start); Tcl_InvalidateStringRep(objResultPtr); if (0 == Tcl_AttemptSetObjLength(objResultPtr, length)) { if (interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "concatenation failed: unable to alloc %" | | | | 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 | /* Ugly interface! Force resize of the unicode array. */ Tcl_GetUnicodeFromObj(objResultPtr, &start); Tcl_InvalidateStringRep(objResultPtr); if (0 == Tcl_AttemptSetObjLength(objResultPtr, length)) { if (interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "concatenation failed: unable to alloc %" TCL_LL_MODIFIER "d bytes", (Tcl_WideUInt)STRING_SIZE(length))); Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL); } return TCL_ERROR; } dst = Tcl_GetUnicode(objResultPtr) + start; } else { Tcl_UniChar ch = 0; /* Ugly interface! No scheme to init array size. */ objResultPtr = Tcl_NewUnicodeObj(&ch, 0); /* PANIC? */ if (0 == Tcl_AttemptSetObjLength(objResultPtr, length)) { if (interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "concatenation failed: unable to alloc %" TCL_LL_MODIFIER "d bytes", (Tcl_WideUInt)STRING_SIZE(length))); Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL); } return TCL_ERROR; } dst = Tcl_GetUnicode(objResultPtr); } |
︙ | ︙ |
Changes to generic/tclStubInit.c.
︙ | ︙ | |||
37 38 39 40 41 42 43 | #undef Tcl_ValidateAllMemory #undef Tcl_FindHashEntry #undef Tcl_CreateHashEntry #undef Tcl_Panic #undef Tcl_FindExecutable #undef TclpGetPid #undef TclSockMinimumBuffers | < > | > > > > > > > > > > > | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | #undef Tcl_ValidateAllMemory #undef Tcl_FindHashEntry #undef Tcl_CreateHashEntry #undef Tcl_Panic #undef Tcl_FindExecutable #undef TclpGetPid #undef TclSockMinimumBuffers #undef Tcl_SetIntObj #undef TclpInetNtoa #undef TclWinGetServByName #undef TclWinGetSockOpt #undef TclWinSetSockOpt #undef TclWinNToHS /* See bug 510001: TclSockMinimumBuffers needs plat imp */ #if defined(_WIN64) || defined(TCL_NO_DEPRECATED) # define TclSockMinimumBuffersOld 0 #else #define TclSockMinimumBuffersOld sockMinimumBuffersOld static int TclSockMinimumBuffersOld(int sock, int size) { return TclSockMinimumBuffers(INT2PTR(sock), size); } #endif #if defined(TCL_NO_DEPRECATED) # define TclSetStartupScriptPath 0 # define TclGetStartupScriptPath 0 # define TclSetStartupScriptFileName 0 # define TclGetStartupScriptFileName 0 # define TclpInetNtoa 0 # define TclWinGetServByName 0 # define TclWinGetSockOpt 0 # define TclWinSetSockOpt 0 # define TclWinNToHS 0 #else #define TclSetStartupScriptPath setStartupScriptPath static void TclSetStartupScriptPath(Tcl_Obj *path) { Tcl_SetStartupScript(path, NULL); } #define TclGetStartupScriptPath getStartupScriptPath static Tcl_Obj *TclGetStartupScriptPath(void) |
︙ | ︙ | |||
88 89 90 91 92 93 94 95 96 97 98 99 100 101 | #if defined(_WIN32) || defined(__CYGWIN__) #undef TclWinNToHS #define TclWinNToHS winNToHS static unsigned short TclWinNToHS(unsigned short ns) { return ntohs(ns); } #endif #ifdef _WIN32 # define TclUnixWaitForFile 0 # define TclUnixCopyFile 0 # define TclUnixOpenTemporaryFile 0 # define TclpReaddir 0 # define TclpIsAtty 0 | > | 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | #if defined(_WIN32) || defined(__CYGWIN__) #undef TclWinNToHS #define TclWinNToHS winNToHS static unsigned short TclWinNToHS(unsigned short ns) { return ntohs(ns); } #endif #endif /* TCL_NO_DEPRECATED */ #ifdef _WIN32 # define TclUnixWaitForFile 0 # define TclUnixCopyFile 0 # define TclUnixOpenTemporaryFile 0 # define TclpReaddir 0 # define TclpIsAtty 0 |
︙ | ︙ | |||
283 284 285 286 287 288 289 | } #define Tcl_UniCharNcasecmp (int(*)(const Tcl_UniChar*,const Tcl_UniChar*,unsigned long))uniCharNcasecmp static int formatInt(char *buffer, int n){ return TclFormatInt(buffer, (long)n); } #define TclFormatInt (int(*)(char *, long))formatInt | | < < < < < < < < | | 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 | } #define Tcl_UniCharNcasecmp (int(*)(const Tcl_UniChar*,const Tcl_UniChar*,unsigned long))uniCharNcasecmp static int formatInt(char *buffer, int n){ return TclFormatInt(buffer, (long)n); } #define TclFormatInt (int(*)(char *, long))formatInt #endif /* TCL_WIDE_INT_IS_LONG */ #endif /* __CYGWIN__ */ #ifdef TCL_NO_DEPRECATED # define Tcl_SeekOld 0 # define Tcl_TellOld 0 # undef Tcl_SetBooleanObj # define Tcl_SetBooleanObj 0 # undef Tcl_PkgPresent |
︙ | ︙ | |||
347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 | # define Tcl_DiscardResult 0 # undef Tcl_SetResult # define Tcl_SetResult 0 # undef Tcl_EvalObj # define Tcl_EvalObj 0 # undef Tcl_GlobalEvalObj # define Tcl_GlobalEvalObj 0 #else /* TCL_NO_DEPRECATED */ # define Tcl_SeekOld seekOld # define Tcl_TellOld tellOld static int seekOld( Tcl_Channel chan, /* The channel on which to seek. */ int offset, /* Offset to seek to. */ int mode) /* Relative to which location to seek? */ { | > > > > > > > > > > > > > > | 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 | # define Tcl_DiscardResult 0 # undef Tcl_SetResult # define Tcl_SetResult 0 # undef Tcl_EvalObj # define Tcl_EvalObj 0 # undef Tcl_GlobalEvalObj # define Tcl_GlobalEvalObj 0 # define TclBackgroundException 0 # undef TclpReaddir # define TclpReaddir 0 # undef TclpGetDate # define TclpGetDate 0 # undef TclpLocaltime # define TclpLocaltime 0 # undef TclpGmtime # define TclpGmtime 0 # define TclpLocaltime_unix 0 # define TclpGmtime_unix 0 #else /* TCL_NO_DEPRECATED */ # define Tcl_SeekOld seekOld # define Tcl_TellOld tellOld # define TclBackgroundException Tcl_BackgroundException # define TclpLocaltime_unix TclpLocaltime # define TclpGmtime_unix TclpGmtime static int seekOld( Tcl_Channel chan, /* The channel on which to seek. */ int offset, /* Offset to seek to. */ int mode) /* Relative to which location to seek? */ { |
︙ | ︙ |
Changes to generic/tclTest.c.
︙ | ︙ | |||
62 63 64 65 66 67 68 69 70 71 72 73 74 75 | int id; /* Identifier for this handler. */ Tcl_AsyncHandler handler; /* Tcl's token for the handler. */ char *command; /* Command to invoke when the handler is * invoked. */ struct TestAsyncHandler *nextPtr; /* Next is list of handlers. */ } TestAsyncHandler; TCL_DECLARE_MUTEX(asyncTestMutex) static TestAsyncHandler *firstHandler = NULL; /* * The dynamic string below is used by the "testdstring" command to test the | > > > > > > > > > > > > | 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | int id; /* Identifier for this handler. */ Tcl_AsyncHandler handler; /* Tcl's token for the handler. */ char *command; /* Command to invoke when the handler is * invoked. */ struct TestAsyncHandler *nextPtr; /* Next is list of handlers. */ } TestAsyncHandler; /* * Start of the socket driver state structure to acces field testFlags */ typedef struct TcpState TcpState; struct TcpState { Tcl_Channel channel; /* Channel associated with this socket. */ int testFlags; /* bit field for tests. Is set by testsocket * test procedure */ }; TCL_DECLARE_MUTEX(asyncTestMutex) static TestAsyncHandler *firstHandler = NULL; /* * The dynamic string below is used by the "testdstring" command to test the |
︙ | ︙ | |||
359 360 361 362 363 364 365 366 367 368 369 370 371 372 | int objc, Tcl_Obj *const objv[]); static int TestGetIndexFromObjStructObjCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); static int TestChannelCmd(ClientData clientData, Tcl_Interp *interp, int argc, const char **argv); static int TestChannelEventCmd(ClientData clientData, Tcl_Interp *interp, int argc, const char **argv); static int TestFilesystemObjCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); static int TestSimpleFilesystemObjCmd( ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); | > > | 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 | int objc, Tcl_Obj *const objv[]); static int TestGetIndexFromObjStructObjCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); static int TestChannelCmd(ClientData clientData, Tcl_Interp *interp, int argc, const char **argv); static int TestChannelEventCmd(ClientData clientData, Tcl_Interp *interp, int argc, const char **argv); static int TestSocketCmd(ClientData clientData, Tcl_Interp *interp, int argc, const char **argv); static int TestFilesystemObjCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); static int TestSimpleFilesystemObjCmd( ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); |
︙ | ︙ | |||
671 672 673 674 675 676 677 678 679 680 681 682 683 684 | Tcl_CreateCommand(interp, "testseterrorcode", TestseterrorcodeCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testsetobjerrorcode", TestsetobjerrorcodeCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testnumutfchars", TestNumUtfCharsCmd, NULL, NULL); Tcl_CreateCommand(interp, "testsetplatform", TestsetplatformCmd, NULL, NULL); Tcl_CreateCommand(interp, "teststaticpkg", TeststaticpkgCmd, NULL, NULL); Tcl_CreateCommand(interp, "testtranslatefilename", TesttranslatefilenameCmd, NULL, NULL); Tcl_CreateCommand(interp, "testupvar", TestupvarCmd, NULL, NULL); #ifndef TCL_NO_DEPRECATED | > > | 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 | Tcl_CreateCommand(interp, "testseterrorcode", TestseterrorcodeCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testsetobjerrorcode", TestsetobjerrorcodeCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testnumutfchars", TestNumUtfCharsCmd, NULL, NULL); Tcl_CreateCommand(interp, "testsetplatform", TestsetplatformCmd, NULL, NULL); Tcl_CreateCommand(interp, "testsocket", TestSocketCmd, NULL, NULL); Tcl_CreateCommand(interp, "teststaticpkg", TeststaticpkgCmd, NULL, NULL); Tcl_CreateCommand(interp, "testtranslatefilename", TesttranslatefilenameCmd, NULL, NULL); Tcl_CreateCommand(interp, "testupvar", TestupvarCmd, NULL, NULL); #ifndef TCL_NO_DEPRECATED |
︙ | ︙ | |||
3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 | TestprintObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { Tcl_WideInt argv1 = 0; if (objc < 2 || objc > 3) { Tcl_WrongNumArgs(interp, 1, objv, "format wideint"); } if (objc > 1) { Tcl_GetWideIntFromObj(interp, objv[2], &argv1); } | > > | | 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 | TestprintObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { Tcl_WideInt argv1 = 0; size_t argv2; if (objc < 2 || objc > 3) { Tcl_WrongNumArgs(interp, 1, objv, "format wideint"); } if (objc > 1) { Tcl_GetWideIntFromObj(interp, objv[2], &argv1); } argv2 = (size_t)argv1; Tcl_SetObjResult(interp, Tcl_ObjPrintf(Tcl_GetString(objv[1]), argv1, argv2, argv2)); return TCL_OK; } /* *---------------------------------------------------------------------- * * TestregexpObjCmd -- |
︙ | ︙ | |||
6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 | TclChannelEventScriptInvoker, (ClientData) esPtr); return TCL_OK; } Tcl_AppendResult(interp, "bad command ", cmd, ", must be one of " "add, delete, list, set, or removeall", NULL); return TCL_ERROR; } /* *---------------------------------------------------------------------- * * TestWrongNumArgsObjCmd -- * * Test the Tcl_WrongNumArgs function. | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 6089 6090 6091 6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 6117 6118 6119 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133 6134 6135 6136 6137 6138 6139 6140 6141 6142 6143 6144 6145 6146 6147 6148 6149 6150 6151 6152 6153 6154 6155 6156 6157 6158 6159 6160 6161 6162 6163 6164 6165 6166 6167 6168 6169 6170 6171 | TclChannelEventScriptInvoker, (ClientData) esPtr); return TCL_OK; } Tcl_AppendResult(interp, "bad command ", cmd, ", must be one of " "add, delete, list, set, or removeall", NULL); return TCL_ERROR; } /* *---------------------------------------------------------------------- * * TestSocketCmd -- * * Implements the Tcl "testsocket" debugging command and its * subcommands. This is part of the testing environment. * * Results: * A standard Tcl result. * * Side effects: * None. * *---------------------------------------------------------------------- */ /* ARGSUSED */ static int TestSocketCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter for result. */ int argc, /* Count of additional args. */ const char **argv) /* Additional arg strings. */ { const char *cmdName; /* Sub command. */ size_t len; /* Length of subcommand string. */ if (argc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " subcommand ?additional args..?\"", NULL); return TCL_ERROR; } cmdName = argv[1]; len = strlen(cmdName); if ((cmdName[0] == 't') && (strncmp(cmdName, "testflags", len) == 0)) { Tcl_Channel hChannel; int modePtr; TcpState *statePtr; /* Set test value in the socket driver */ /* Check for argument "channel name" */ if (argc < 4) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " testflags channel flags\"", NULL); return TCL_ERROR; } hChannel = Tcl_GetChannel(interp, argv[2], &modePtr); if ( NULL == hChannel ) { Tcl_AppendResult(interp, "unknown channel:", argv[2], NULL); return TCL_ERROR; } statePtr = (TcpState *)Tcl_GetChannelInstanceData(hChannel); if ( NULL == statePtr) { Tcl_AppendResult(interp, "No channel instance data:", argv[2], NULL); return TCL_ERROR; } statePtr->testFlags = atoi(argv[3]); return TCL_OK; } Tcl_AppendResult(interp, "bad option \"", cmdName, "\": should be " "testflags", NULL); return TCL_ERROR; } /* *---------------------------------------------------------------------- * * TestWrongNumArgsObjCmd -- * * Test the Tcl_WrongNumArgs function. |
︙ | ︙ |
Changes to generic/tclThreadTest.c.
︙ | ︙ | |||
337 338 339 340 341 342 343 | */ if (objc == 2) { idObj = Tcl_NewWideIntObj((Tcl_WideInt)(size_t)Tcl_GetCurrentThread()); } else if (objc == 3 && strcmp("-main", Tcl_GetString(objv[2])) == 0) { Tcl_MutexLock(&threadMutex); | | | 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 | */ if (objc == 2) { idObj = Tcl_NewWideIntObj((Tcl_WideInt)(size_t)Tcl_GetCurrentThread()); } else if (objc == 3 && strcmp("-main", Tcl_GetString(objv[2])) == 0) { Tcl_MutexLock(&threadMutex); idObj = Tcl_NewWideIntObj((Tcl_WideInt)(size_t)mainThreadId); Tcl_MutexUnlock(&threadMutex); } else { Tcl_WrongNumArgs(interp, 2, objv, NULL); return TCL_ERROR; } Tcl_SetObjResult(interp, idObj); |
︙ | ︙ |
Changes to generic/tclTimer.c.
︙ | ︙ | |||
1049 1050 1051 1052 1053 1054 1055 | if (diff > LONG_MAX) { diff = LONG_MAX; } #endif if (diff > TCL_TIME_MAXIMUM_SLICE) { diff = TCL_TIME_MAXIMUM_SLICE; } | | > > | > > | > > | 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 | if (diff > LONG_MAX) { diff = LONG_MAX; } #endif if (diff > TCL_TIME_MAXIMUM_SLICE) { diff = TCL_TIME_MAXIMUM_SLICE; } if (diff == 0 && TCL_TIME_BEFORE(now, endTime)) { diff = 1; } if (diff > 0) { Tcl_Sleep((long) diff); if (diff < SLEEP_OFFLOAD_GETTIMEOFDAY) { break; } } else { break; } } else { diff = TCL_TIME_DIFF_MS(iPtr->limit.time, now); #ifndef TCL_WIDE_INT_IS_LONG if (diff > LONG_MAX) { diff = LONG_MAX; } #endif |
︙ | ︙ |
Changes to generic/tclUtil.c.
︙ | ︙ | |||
3149 3150 3151 3152 3153 3154 3155 | * at least TCL_DOUBLE_SPACE characters. */ { char *p, c; int exponent; int signum; char *digits; char *end; | | | 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 | * at least TCL_DOUBLE_SPACE characters. */ { char *p, c; int exponent; int signum; char *digits; char *end; int *precisionPtr = Tcl_GetThreadData(&precisionKey, sizeof(int)); /* * Handle NaN. */ if (TclIsNaN(value)) { TclFormatNaN(value, dst); |
︙ | ︙ | |||
3322 3323 3324 3325 3326 3327 3328 | Tcl_Interp *interp, /* Interpreter containing variable. */ const char *name1, /* Name of variable. */ const char *name2, /* Second part of variable name. */ int flags) /* Information about what happened. */ { Tcl_Obj *value; int prec; | | | 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 | Tcl_Interp *interp, /* Interpreter containing variable. */ const char *name1, /* Name of variable. */ const char *name2, /* Second part of variable name. */ int flags) /* Information about what happened. */ { Tcl_Obj *value; int prec; int *precisionPtr = Tcl_GetThreadData(&precisionKey, sizeof(int)); /* * If the variable is unset, then recreate the trace. */ if (flags & TCL_TRACE_UNSETS) { if ((flags & TCL_TRACE_DESTROYED) && !Tcl_InterpDeleted(interp)) { |
︙ | ︙ |
library/clock.tcl became a regular file.
︙ | ︙ |
Changes to library/msgs/ar.msg.
1 2 3 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset ar DAYS_OF_WEEK_ABBREV [list \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset ar DAYS_OF_WEEK_ABBREV [list \ "ح"\ "ن"\ "ث"\ "ر"\ "خ"\ "ج"\ "س"] ::msgcat::mcset ar DAYS_OF_WEEK_FULL [list \ "الأحد"\ "الاثنين"\ "الثلاثاء"\ "الأربعاء"\ "الخميس"\ "الجمعة"\ "السبت"] ::msgcat::mcset ar MONTHS_ABBREV [list \ "ينا"\ "فبر"\ "مار"\ "أبر"\ "ماي"\ "يون"\ "يول"\ "أغس"\ "سبت"\ "أكت"\ "نوف"\ "ديس"\ ""] ::msgcat::mcset ar MONTHS_FULL [list \ "يناير"\ "فبراير"\ "مارس"\ "أبريل"\ "مايو"\ "يونيو"\ "يوليو"\ "أغسطس"\ "سبتمبر"\ "أكتوبر"\ "نوفمبر"\ "ديسمبر"\ ""] ::msgcat::mcset ar BCE "ق.م" ::msgcat::mcset ar CE "م" ::msgcat::mcset ar AM "ص" ::msgcat::mcset ar PM "م" ::msgcat::mcset ar DATE_FORMAT "%d/%m/%Y" ::msgcat::mcset ar TIME_FORMAT_12 "%I:%M:%S %P" ::msgcat::mcset ar DATE_TIME_FORMAT "%d/%m/%Y %I:%M:%S %P %z" } |
Changes to library/msgs/ar_jo.msg.
1 2 3 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset ar_JO DAYS_OF_WEEK_ABBREV [list \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset ar_JO DAYS_OF_WEEK_ABBREV [list \ "الأحد"\ "الاثنين"\ "الثلاثاء"\ "الأربعاء"\ "الخميس"\ "الجمعة"\ "السبت"] ::msgcat::mcset ar_JO MONTHS_ABBREV [list \ "كانون الثاني"\ "شباط"\ "آذار"\ "نيسان"\ "نوار"\ "حزيران"\ "تموز"\ "آب"\ "أيلول"\ "تشرين الأول"\ "تشرين الثاني"\ "كانون الأول"\ ""] ::msgcat::mcset ar_JO MONTHS_FULL [list \ "كانون الثاني"\ "شباط"\ "آذار"\ "نيسان"\ "نوار"\ "حزيران"\ "تموز"\ "آب"\ "أيلول"\ "تشرين الأول"\ "تشرين الثاني"\ "كانون الأول"\ ""] } |
Changes to library/msgs/ar_lb.msg.
1 2 3 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset ar_LB DAYS_OF_WEEK_ABBREV [list \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset ar_LB DAYS_OF_WEEK_ABBREV [list \ "الأحد"\ "الاثنين"\ "الثلاثاء"\ "الأربعاء"\ "الخميس"\ "الجمعة"\ "السبت"] ::msgcat::mcset ar_LB MONTHS_ABBREV [list \ "كانون الثاني"\ "شباط"\ "آذار"\ "نيسان"\ "نوار"\ "حزيران"\ "تموز"\ "آب"\ "أيلول"\ "تشرين الأول"\ "تشرين الثاني"\ "كانون الأول"\ ""] ::msgcat::mcset ar_LB MONTHS_FULL [list \ "كانون الثاني"\ "شباط"\ "آذار"\ "نيسان"\ "نوار"\ "حزيران"\ "تموز"\ "آب"\ "أيلول"\ "تشرين الأول"\ "تشرين الثاني"\ "كانون الأول"\ ""] } |
Changes to library/msgs/ar_sy.msg.
1 2 3 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset ar_SY DAYS_OF_WEEK_ABBREV [list \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset ar_SY DAYS_OF_WEEK_ABBREV [list \ "الأحد"\ "الاثنين"\ "الثلاثاء"\ "الأربعاء"\ "الخميس"\ "الجمعة"\ "السبت"] ::msgcat::mcset ar_SY MONTHS_ABBREV [list \ "كانون الثاني"\ "شباط"\ "آذار"\ "نيسان"\ "نوار"\ "حزيران"\ "تموز"\ "آب"\ "أيلول"\ "تشرين الأول"\ "تشرين الثاني"\ "كانون الأول"\ ""] ::msgcat::mcset ar_SY MONTHS_FULL [list \ "كانون الثاني"\ "شباط"\ "آذار"\ "نيسان"\ "نواران"\ "حزير"\ "تموز"\ "آب"\ "أيلول"\ "تشرين الأول"\ "تشرين الثاني"\ "كانون الأول"\ ""] } |
Changes to library/msgs/be.msg.
1 2 3 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset be DAYS_OF_WEEK_ABBREV [list \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset be DAYS_OF_WEEK_ABBREV [list \ "нд"\ "пн"\ "ат"\ "ср"\ "чц"\ "пт"\ "сб"] ::msgcat::mcset be DAYS_OF_WEEK_FULL [list \ "нядзеля"\ "панядзелак"\ "аўторак"\ "серада"\ "чацвер"\ "пятніца"\ "субота"] ::msgcat::mcset be MONTHS_ABBREV [list \ "стд"\ "лют"\ "скв"\ "крс"\ "май"\ "чрв"\ "лпн"\ "жнв"\ "врс"\ "кст"\ "лст"\ "снж"\ ""] ::msgcat::mcset be MONTHS_FULL [list \ "студзеня"\ "лютага"\ "сакавіка"\ "красавіка"\ "мая"\ "чрвеня"\ "ліпеня"\ "жніўня"\ "верасня"\ "кастрычніка"\ "листапада"\ "снежня"\ ""] ::msgcat::mcset be BCE "да н.е." ::msgcat::mcset be CE "н.е." ::msgcat::mcset be DATE_FORMAT "%e.%m.%Y" ::msgcat::mcset be TIME_FORMAT "%k.%M.%S" ::msgcat::mcset be DATE_TIME_FORMAT "%e.%m.%Y %k.%M.%S %z" } |
Changes to library/msgs/bg.msg.
1 2 3 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset bg DAYS_OF_WEEK_ABBREV [list \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset bg DAYS_OF_WEEK_ABBREV [list \ "Нд"\ "Пн"\ "Вт"\ "Ср"\ "Чт"\ "Пт"\ "Сб"] ::msgcat::mcset bg DAYS_OF_WEEK_FULL [list \ "Неделя"\ "Понеделник"\ "Вторник"\ "Сряда"\ "Четвъртък"\ "Петък"\ "Събота"] ::msgcat::mcset bg MONTHS_ABBREV [list \ "I"\ "II"\ "III"\ "IV"\ "V"\ "VI"\ "VII"\ "VIII"\ "IX"\ "X"\ "XI"\ "XII"\ ""] ::msgcat::mcset bg MONTHS_FULL [list \ "Януари"\ "Февруари"\ "Март"\ "Април"\ "Май"\ "Юни"\ "Юли"\ "Август"\ "Септември"\ "Октомври"\ "Ноември"\ "Декември"\ ""] ::msgcat::mcset bg BCE "пр.н.е." ::msgcat::mcset bg CE "н.е." ::msgcat::mcset bg DATE_FORMAT "%Y-%m-%e" ::msgcat::mcset bg TIME_FORMAT "%k:%M:%S" ::msgcat::mcset bg DATE_TIME_FORMAT "%Y-%m-%e %k:%M:%S %z" } |
Changes to library/msgs/bn.msg.
1 2 3 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset bn DAYS_OF_WEEK_ABBREV [list \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset bn DAYS_OF_WEEK_ABBREV [list \ "রবি"\ "সোম"\ "মঙগল"\ "বুধ"\ "বৃহস্পতি"\ "শুক্র"\ "শনি"] ::msgcat::mcset bn DAYS_OF_WEEK_FULL [list \ "রবিবার"\ "সোমবার"\ "মঙগলবার"\ "বুধবার"\ "বৃহস্পতিবার"\ "শুক্রবার"\ "শনিবার"] ::msgcat::mcset bn MONTHS_ABBREV [list \ "জানুয়ারী"\ "ফেব্রুয়ারী"\ "মার্চ"\ "এপ্রিল"\ "মে"\ "জুন"\ "জুলাই"\ "আগস্ট"\ "সেপ্টেম্বর"\ "অক্টোবর"\ "নভেম্বর"\ "ডিসেম্বর"\ ""] ::msgcat::mcset bn MONTHS_FULL [list \ "জানুয়ারী"\ "ফেব্রুয়ারী"\ "মার্চ"\ "এপ্রিল"\ "মে"\ "জুন"\ "জুলাই"\ "আগস্ট"\ "সেপ্টেম্বর"\ "অক্টোবর"\ "নভেম্বর"\ "ডিসেম্বর"\ ""] ::msgcat::mcset bn AM "পূর্বাহ্ণ" ::msgcat::mcset bn PM "অপরাহ্ণ" } |
Changes to library/msgs/ca.msg.
︙ | ︙ | |||
15 16 17 18 19 20 21 | "dimecres"\ "dijous"\ "divendres"\ "dissabte"] ::msgcat::mcset ca MONTHS_ABBREV [list \ "gen."\ "feb."\ | | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | "dimecres"\ "dijous"\ "divendres"\ "dissabte"] ::msgcat::mcset ca MONTHS_ABBREV [list \ "gen."\ "feb."\ "març"\ "abr."\ "maig"\ "juny"\ "jul."\ "ag."\ "set."\ "oct."\ "nov."\ "des."\ ""] ::msgcat::mcset ca MONTHS_FULL [list \ "gener"\ "febrer"\ "març"\ "abril"\ "maig"\ "juny"\ "juliol"\ "agost"\ "setembre"\ "octubre"\ |
︙ | ︙ |
Changes to library/msgs/cs.msg.
1 2 3 4 5 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset cs DAYS_OF_WEEK_ABBREV [list \ "Ne"\ "Po"\ | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset cs DAYS_OF_WEEK_ABBREV [list \ "Ne"\ "Po"\ "Út"\ "St"\ "Čt"\ "Pá"\ "So"] ::msgcat::mcset cs DAYS_OF_WEEK_FULL [list \ "Neděle"\ "Pondělí"\ "Úterý"\ "Středa"\ "Čtvrtek"\ "Pátek"\ "Sobota"] ::msgcat::mcset cs MONTHS_ABBREV [list \ "I"\ "II"\ "III"\ "IV"\ "V"\ "VI"\ "VII"\ "VIII"\ "IX"\ "X"\ "XI"\ "XII"\ ""] ::msgcat::mcset cs MONTHS_FULL [list \ "leden"\ "únor"\ "březen"\ "duben"\ "květen"\ "červen"\ "červenec"\ "srpen"\ "září"\ "říjen"\ "listopad"\ "prosinec"\ ""] ::msgcat::mcset cs BCE "př.Kr." ::msgcat::mcset cs CE "po Kr." ::msgcat::mcset cs AM "dop." ::msgcat::mcset cs PM "odp." ::msgcat::mcset cs DATE_FORMAT "%e.%m.%Y" ::msgcat::mcset cs TIME_FORMAT "%k:%M:%S" ::msgcat::mcset cs DATE_TIME_FORMAT "%e.%m.%Y %k:%M:%S %z" } |
Changes to library/msgs/da.msg.
1 2 3 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset da DAYS_OF_WEEK_ABBREV [list \ | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset da DAYS_OF_WEEK_ABBREV [list \ "sø"\ "ma"\ "ti"\ "on"\ "to"\ "fr"\ "lø"] ::msgcat::mcset da DAYS_OF_WEEK_FULL [list \ "søndag"\ "mandag"\ "tirsdag"\ "onsdag"\ "torsdag"\ "fredag"\ "lørdag"] ::msgcat::mcset da MONTHS_ABBREV [list \ "jan"\ "feb"\ "mar"\ "apr"\ "maj"\ "jun"\ |
︙ | ︙ |
Changes to library/msgs/de.msg.
︙ | ︙ | |||
29 30 31 32 33 34 35 | "Okt"\ "Nov"\ "Dez"\ ""] ::msgcat::mcset de MONTHS_FULL [list \ "Januar"\ "Februar"\ | | | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | "Okt"\ "Nov"\ "Dez"\ ""] ::msgcat::mcset de MONTHS_FULL [list \ "Januar"\ "Februar"\ "März"\ "April"\ "Mai"\ "Juni"\ "Juli"\ "August"\ "September"\ "Oktober"\ |
︙ | ︙ |
Changes to library/msgs/de_at.msg.
1 2 3 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset de_AT MONTHS_ABBREV [list \ | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset de_AT MONTHS_ABBREV [list \ "Jän"\ "Feb"\ "Mär"\ "Apr"\ "Mai"\ "Jun"\ "Jul"\ "Aug"\ "Sep"\ "Okt"\ "Nov"\ "Dez"\ ""] ::msgcat::mcset de_AT MONTHS_FULL [list \ "Jänner"\ "Februar"\ "März"\ "April"\ "Mai"\ "Juni"\ "Juli"\ "August"\ "September"\ "Oktober"\ |
︙ | ︙ |
Changes to library/msgs/de_be.msg.
︙ | ︙ | |||
15 16 17 18 19 20 21 | "Mittwoch"\ "Donnerstag"\ "Freitag"\ "Samstag"] ::msgcat::mcset de_BE MONTHS_ABBREV [list \ "Jan"\ "Feb"\ | | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | "Mittwoch"\ "Donnerstag"\ "Freitag"\ "Samstag"] ::msgcat::mcset de_BE MONTHS_ABBREV [list \ "Jan"\ "Feb"\ "Mär"\ "Apr"\ "Mai"\ "Jun"\ "Jul"\ "Aug"\ "Sep"\ "Okt"\ "Nov"\ "Dez"\ ""] ::msgcat::mcset de_BE MONTHS_FULL [list \ "Januar"\ "Februar"\ "März"\ "April"\ "Mai"\ "Juni"\ "Juli"\ "August"\ "September"\ "Oktober"\ |
︙ | ︙ |
Changes to library/msgs/el.msg.
1 2 3 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset el DAYS_OF_WEEK_ABBREV [list \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset el DAYS_OF_WEEK_ABBREV [list \ "Κυρ"\ "Δευ"\ "Τρι"\ "Τετ"\ "Πεμ"\ "Παρ"\ "Σαβ"] ::msgcat::mcset el DAYS_OF_WEEK_FULL [list \ "Κυριακή"\ "Δευτέρα"\ "Τρίτη"\ "Τετάρτη"\ "Πέμπτη"\ "Παρασκευή"\ "Σάββατο"] ::msgcat::mcset el MONTHS_ABBREV [list \ "Ιαν"\ "Φεβ"\ "Μαρ"\ "Απρ"\ "Μαϊ"\ "Ιουν"\ "Ιουλ"\ "Αυγ"\ "Σεπ"\ "Οκτ"\ "Νοε"\ "Δεκ"\ ""] ::msgcat::mcset el MONTHS_FULL [list \ "Ιανουάριος"\ "Φεβρουάριος"\ "Μάρτιος"\ "Απρίλιος"\ "Μάϊος"\ "Ιούνιος"\ "Ιούλιος"\ "Αύγουστος"\ "Σεπτέμβριος"\ "Οκτώβριος"\ "Νοέμβριος"\ "Δεκέμβριος"\ ""] ::msgcat::mcset el AM "πμ" ::msgcat::mcset el PM "μμ" ::msgcat::mcset el DATE_FORMAT "%e/%m/%Y" ::msgcat::mcset el TIME_FORMAT_12 "%l:%M:%S %P" ::msgcat::mcset el DATE_TIME_FORMAT "%e/%m/%Y %l:%M:%S %P %z" } |
Changes to library/msgs/eo.msg.
1 2 3 4 5 6 7 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset eo DAYS_OF_WEEK_ABBREV [list \ "di"\ "lu"\ "ma"\ "me"\ | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset eo DAYS_OF_WEEK_ABBREV [list \ "di"\ "lu"\ "ma"\ "me"\ "ĵa"\ "ve"\ "sa"] ::msgcat::mcset eo DAYS_OF_WEEK_FULL [list \ "dimanĉo"\ "lundo"\ "mardo"\ "merkredo"\ "ĵaŭdo"\ "vendredo"\ "sabato"] ::msgcat::mcset eo MONTHS_ABBREV [list \ "jan"\ "feb"\ "mar"\ "apr"\ "maj"\ "jun"\ "jul"\ "aŭg"\ "sep"\ "okt"\ "nov"\ "dec"\ ""] ::msgcat::mcset eo MONTHS_FULL [list \ "januaro"\ "februaro"\ "marto"\ "aprilo"\ "majo"\ "junio"\ "julio"\ "aŭgusto"\ "septembro"\ "oktobro"\ "novembro"\ "decembro"\ ""] ::msgcat::mcset eo BCE "aK" ::msgcat::mcset eo CE "pK" |
︙ | ︙ |
Changes to library/msgs/es.msg.
1 2 3 4 5 6 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset es DAYS_OF_WEEK_ABBREV [list \ "dom"\ "lun"\ "mar"\ | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset es DAYS_OF_WEEK_ABBREV [list \ "dom"\ "lun"\ "mar"\ "mié"\ "jue"\ "vie"\ "sáb"] ::msgcat::mcset es DAYS_OF_WEEK_FULL [list \ "domingo"\ "lunes"\ "martes"\ "miércoles"\ "jueves"\ "viernes"\ "sábado"] ::msgcat::mcset es MONTHS_ABBREV [list \ "ene"\ "feb"\ "mar"\ "abr"\ "may"\ "jun"\ |
︙ | ︙ |
Changes to library/msgs/et.msg.
1 2 3 4 5 6 7 8 9 10 11 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset et DAYS_OF_WEEK_ABBREV [list \ "P"\ "E"\ "T"\ "K"\ "N"\ "R"\ "L"] ::msgcat::mcset et DAYS_OF_WEEK_FULL [list \ | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset et DAYS_OF_WEEK_ABBREV [list \ "P"\ "E"\ "T"\ "K"\ "N"\ "R"\ "L"] ::msgcat::mcset et DAYS_OF_WEEK_FULL [list \ "pühapäev"\ "esmaspäev"\ "teisipäev"\ "kolmapäev"\ "neljapäev"\ "reede"\ "laupäev"] ::msgcat::mcset et MONTHS_ABBREV [list \ "Jaan"\ "Veebr"\ "Märts"\ "Apr"\ "Mai"\ "Juuni"\ "Juuli"\ "Aug"\ "Sept"\ "Okt"\ "Nov"\ "Dets"\ ""] ::msgcat::mcset et MONTHS_FULL [list \ "Jaanuar"\ "Veebruar"\ "Märts"\ "Aprill"\ "Mai"\ "Juuni"\ "Juuli"\ "August"\ "September"\ "Oktoober"\ |
︙ | ︙ |
Changes to library/msgs/fa.msg.
1 2 3 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset fa DAYS_OF_WEEK_ABBREV [list \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset fa DAYS_OF_WEEK_ABBREV [list \ "ی∔"\ "د∔"\ "س∔"\ "چ∔"\ "پ∔"\ "ج∔"\ "ش∔"] ::msgcat::mcset fa DAYS_OF_WEEK_FULL [list \ "ییشنبه"\ "دوشنبه"\ "سهشنبه"\ "چهارشنبه"\ "پنجشنبه"\ "جمعه"\ "شنبه"] ::msgcat::mcset fa MONTHS_ABBREV [list \ "ژان"\ "فور"\ "مار"\ "آور"\ "مـه"\ "ژون"\ "ژوی"\ "اوت"\ "سپت"\ "اكت"\ "نوا"\ "دسا"\ ""] ::msgcat::mcset fa MONTHS_FULL [list \ "ژانویه"\ "فورویه"\ "مارس"\ "آوریل"\ "مه"\ "ژوئن"\ "ژوئیه"\ "اوت"\ "سپتامبر"\ "اكتبر"\ "نوامبر"\ "دسامبر"\ ""] } |
Changes to library/msgs/fa_in.msg.
1 2 3 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset fa_IN DAYS_OF_WEEK_ABBREV [list \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset fa_IN DAYS_OF_WEEK_ABBREV [list \ "ی∔"\ "د∔"\ "س∔"\ "چ∔"\ "پ∔"\ "ج∔"\ "ش∔"] ::msgcat::mcset fa_IN DAYS_OF_WEEK_FULL [list \ "ییشنبه"\ "دوشنبه"\ "سهشنبه"\ "چهارشنبه"\ "پنجشنبه"\ "جمعه"\ "شنبه"] ::msgcat::mcset fa_IN MONTHS_ABBREV [list \ "ژان"\ "فور"\ "مار"\ "آور"\ "مـه"\ "ژون"\ "ژوی"\ "اوت"\ "سپت"\ "اكت"\ "نوا"\ "دسا"\ ""] ::msgcat::mcset fa_IN MONTHS_FULL [list \ "ژانویه"\ "فورویه"\ "مارس"\ "آوریل"\ "مه"\ "ژوئن"\ "ژوئیه"\ "اوت"\ "سپتامبر"\ "اكتبر"\ "نوامبر"\ "دسامبر"\ ""] ::msgcat::mcset fa_IN AM "صبح" ::msgcat::mcset fa_IN PM "عصر" ::msgcat::mcset fa_IN DATE_FORMAT "%A %d %B %Y" ::msgcat::mcset fa_IN TIME_FORMAT_12 "%I:%M:%S %z" ::msgcat::mcset fa_IN DATE_TIME_FORMAT "%A %d %B %Y %I:%M:%S %z %z" } |
Changes to library/msgs/fa_ir.msg.
1 2 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { | | | | | | 1 2 3 4 5 6 7 8 9 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset fa_IR AM "صبح" ::msgcat::mcset fa_IR PM "عصر" ::msgcat::mcset fa_IR DATE_FORMAT "%d⁄%m⁄%Y" ::msgcat::mcset fa_IR TIME_FORMAT "%S:%M:%H" ::msgcat::mcset fa_IR TIME_FORMAT_12 "%S:%M:%l %P" ::msgcat::mcset fa_IR DATE_TIME_FORMAT "%d⁄%m⁄%Y %S:%M:%H %z" } |
Changes to library/msgs/fi.msg.
︙ | ︙ | |||
18 19 20 21 22 23 24 | "lauantai"] ::msgcat::mcset fi MONTHS_ABBREV [list \ "tammi"\ "helmi"\ "maalis"\ "huhti"\ "touko"\ | | | | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | "lauantai"] ::msgcat::mcset fi MONTHS_ABBREV [list \ "tammi"\ "helmi"\ "maalis"\ "huhti"\ "touko"\ "kesä"\ "heinä"\ "elo"\ "syys"\ "loka"\ "marras"\ "joulu"\ ""] ::msgcat::mcset fi MONTHS_FULL [list \ "tammikuu"\ "helmikuu"\ "maaliskuu"\ "huhtikuu"\ "toukokuu"\ "kesäkuu"\ "heinäkuu"\ "elokuu"\ "syyskuu"\ "lokakuu"\ "marraskuu"\ "joulukuu"\ ""] ::msgcat::mcset fi DATE_FORMAT "%e.%m.%Y" |
︙ | ︙ |
Changes to library/msgs/fo.msg.
1 2 3 4 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset fo DAYS_OF_WEEK_ABBREV [list \ "sun"\ | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset fo DAYS_OF_WEEK_ABBREV [list \ "sun"\ "mán"\ "týs"\ "mik"\ "hós"\ "frí"\ "ley"] ::msgcat::mcset fo DAYS_OF_WEEK_FULL [list \ "sunnudagur"\ "mánadagur"\ "týsdagur"\ "mikudagur"\ "hósdagur"\ "fríggjadagur"\ "leygardagur"] ::msgcat::mcset fo MONTHS_ABBREV [list \ "jan"\ "feb"\ "mar"\ "apr"\ "mai"\ "jun"\ "jul"\ "aug"\ "sep"\ "okt"\ "nov"\ "des"\ ""] ::msgcat::mcset fo MONTHS_FULL [list \ "januar"\ "februar"\ "mars"\ "apríl"\ "mai"\ "juni"\ "juli"\ "august"\ "september"\ "oktober"\ "november"\ "desember"\ ""] } |
Changes to library/msgs/fr.msg.
︙ | ︙ | |||
14 15 16 17 18 19 20 | "mardi"\ "mercredi"\ "jeudi"\ "vendredi"\ "samedi"] ::msgcat::mcset fr MONTHS_ABBREV [list \ "janv."\ | | | | | | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | "mardi"\ "mercredi"\ "jeudi"\ "vendredi"\ "samedi"] ::msgcat::mcset fr MONTHS_ABBREV [list \ "janv."\ "févr."\ "mars"\ "avr."\ "mai"\ "juin"\ "juil."\ "août"\ "sept."\ "oct."\ "nov."\ "déc."\ ""] ::msgcat::mcset fr MONTHS_FULL [list \ "janvier"\ "février"\ "mars"\ "avril"\ "mai"\ "juin"\ "juillet"\ "août"\ "septembre"\ "octobre"\ "novembre"\ "décembre"\ ""] ::msgcat::mcset fr BCE "av. J.-C." ::msgcat::mcset fr CE "ap. J.-C." ::msgcat::mcset fr DATE_FORMAT "%e %B %Y" ::msgcat::mcset fr TIME_FORMAT "%H:%M:%S" ::msgcat::mcset fr DATE_TIME_FORMAT "%e %B %Y %H:%M:%S %z" } |
Changes to library/msgs/ga.msg.
1 2 3 4 5 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset ga DAYS_OF_WEEK_ABBREV [list \ "Domh"\ "Luan"\ | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset ga DAYS_OF_WEEK_ABBREV [list \ "Domh"\ "Luan"\ "Máirt"\ "Céad"\ "Déar"\ "Aoine"\ "Sath"] ::msgcat::mcset ga DAYS_OF_WEEK_FULL [list \ "Dé Domhnaigh"\ "Dé Luain"\ "Dé Máirt"\ "Dé Céadaoin"\ "Déardaoin"\ "Dé hAoine"\ "Dé Sathairn"] ::msgcat::mcset ga MONTHS_ABBREV [list \ "Ean"\ "Feabh"\ "Márta"\ "Aib"\ "Beal"\ "Meith"\ "Iúil"\ "Lún"\ "MFómh"\ "DFómh"\ "Samh"\ "Noll"\ ""] ::msgcat::mcset ga MONTHS_FULL [list \ "Eanáir"\ "Feabhra"\ "Márta"\ "Aibreán"\ "Mí na Bealtaine"\ "Meith"\ "Iúil"\ "Lúnasa"\ "Meán Fómhair"\ "Deireadh Fómhair"\ "Mí na Samhna"\ "Mí na Nollag"\ ""] } |
Changes to library/msgs/gl.msg.
1 2 3 4 5 6 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset gl DAYS_OF_WEEK_ABBREV [list \ "Dom"\ "Lun"\ "Mar"\ | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset gl DAYS_OF_WEEK_ABBREV [list \ "Dom"\ "Lun"\ "Mar"\ "Mér"\ "Xov"\ "Ven"\ "Sáb"] ::msgcat::mcset gl DAYS_OF_WEEK_FULL [list \ "Domingo"\ "Luns"\ "Martes"\ "Mércores"\ "Xoves"\ "Venres"\ "Sábado"] ::msgcat::mcset gl MONTHS_ABBREV [list \ "Xan"\ "Feb"\ "Mar"\ "Abr"\ "Mai"\ "Xuñ"\ "Xul"\ "Ago"\ "Set"\ "Out"\ "Nov"\ "Dec"\ ""] ::msgcat::mcset gl MONTHS_FULL [list \ "Xaneiro"\ "Febreiro"\ "Marzo"\ "Abril"\ "Maio"\ "Xuño"\ "Xullo"\ "Agosto"\ "Setembro"\ "Outubro"\ "Novembro"\ "Decembro"\ ""] |
︙ | ︙ |
Changes to library/msgs/he.msg.
1 2 3 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset he DAYS_OF_WEEK_ABBREV [list \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset he DAYS_OF_WEEK_ABBREV [list \ "א"\ "ב"\ "ג"\ "ד"\ "ה"\ "ו"\ "ש"] ::msgcat::mcset he DAYS_OF_WEEK_FULL [list \ "יום ראשון"\ "יום שני"\ "יום שלישי"\ "יום רביעי"\ "יום חמישי"\ "יום שישי"\ "שבת"] ::msgcat::mcset he MONTHS_ABBREV [list \ "ינו"\ "פבר"\ "מרץ"\ "אפר"\ "מאי"\ "יונ"\ "יול"\ "אוג"\ "ספט"\ "אוק"\ "נוב"\ "דצמ"\ ""] ::msgcat::mcset he MONTHS_FULL [list \ "ינואר"\ "פברואר"\ "מרץ"\ "אפריל"\ "מאי"\ "יוני"\ "יולי"\ "אוגוסט"\ "ספטמבר"\ "אוקטובר"\ "נובמבר"\ "דצמבר"\ ""] ::msgcat::mcset he BCE "לסה"נ" ::msgcat::mcset he CE "לפסה"נ" ::msgcat::mcset he DATE_FORMAT "%d/%m/%Y" ::msgcat::mcset he TIME_FORMAT "%H:%M:%S" ::msgcat::mcset he DATE_TIME_FORMAT "%d/%m/%Y %H:%M:%S %z" } |
Changes to library/msgs/hi.msg.
1 2 3 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset hi DAYS_OF_WEEK_FULL [list \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset hi DAYS_OF_WEEK_FULL [list \ "रविवार"\ "सोमवार"\ "मंगलवार"\ "बुधवार"\ "गुरुवार"\ "शुक्रवार"\ "शनिवार"] ::msgcat::mcset hi MONTHS_ABBREV [list \ "जनवरी"\ "फ़रवरी"\ "मार्च"\ "अप्रेल"\ "मई"\ "जून"\ "जुलाई"\ "अगस्त"\ "सितम्बर"\ "अक्टूबर"\ "नवम्बर"\ "दिसम्बर"] ::msgcat::mcset hi MONTHS_FULL [list \ "जनवरी"\ "फ़रवरी"\ "मार्च"\ "अप्रेल"\ "मई"\ "जून"\ "जुलाई"\ "अगस्त"\ "सितम्बर"\ "अक्टूबर"\ "नवम्बर"\ "दिसम्बर"] ::msgcat::mcset hi AM "ईसापूर्व" ::msgcat::mcset hi PM "." } |
Changes to library/msgs/hr.msg.
1 2 3 4 5 6 7 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset hr DAYS_OF_WEEK_ABBREV [list \ "ned"\ "pon"\ "uto"\ "sri"\ | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset hr DAYS_OF_WEEK_ABBREV [list \ "ned"\ "pon"\ "uto"\ "sri"\ "čet"\ "pet"\ "sub"] ::msgcat::mcset hr DAYS_OF_WEEK_FULL [list \ "nedjelja"\ "ponedjeljak"\ "utorak"\ "srijeda"\ "četvrtak"\ "petak"\ "subota"] ::msgcat::mcset hr MONTHS_ABBREV [list \ "sij"\ "vel"\ "ožu"\ "tra"\ "svi"\ "lip"\ "srp"\ "kol"\ "ruj"\ "lis"\ "stu"\ "pro"\ ""] ::msgcat::mcset hr MONTHS_FULL [list \ "siječanj"\ "veljača"\ "ožujak"\ "travanj"\ "svibanj"\ "lipanj"\ "srpanj"\ "kolovoz"\ "rujan"\ "listopad"\ |
︙ | ︙ |
Changes to library/msgs/hu.msg.
1 2 3 4 5 6 7 8 9 10 11 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset hu DAYS_OF_WEEK_ABBREV [list \ "V"\ "H"\ "K"\ "Sze"\ "Cs"\ "P"\ "Szo"] ::msgcat::mcset hu DAYS_OF_WEEK_FULL [list \ | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset hu DAYS_OF_WEEK_ABBREV [list \ "V"\ "H"\ "K"\ "Sze"\ "Cs"\ "P"\ "Szo"] ::msgcat::mcset hu DAYS_OF_WEEK_FULL [list \ "vasárnap"\ "hétfő"\ "kedd"\ "szerda"\ "csütörtök"\ "péntek"\ "szombat"] ::msgcat::mcset hu MONTHS_ABBREV [list \ "jan."\ "febr."\ "márc."\ "ápr."\ "máj."\ "jún."\ "júl."\ "aug."\ "szept."\ "okt."\ "nov."\ "dec."\ ""] ::msgcat::mcset hu MONTHS_FULL [list \ "január"\ "február"\ "március"\ "április"\ "május"\ "június"\ "július"\ "augusztus"\ "szeptember"\ "október"\ "november"\ "december"\ ""] ::msgcat::mcset hu BCE "i.e." ::msgcat::mcset hu CE "i.u." ::msgcat::mcset hu AM "DE" ::msgcat::mcset hu PM "DU" |
︙ | ︙ |
Changes to library/msgs/is.msg.
1 2 3 4 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset is DAYS_OF_WEEK_ABBREV [list \ "sun."\ | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset is DAYS_OF_WEEK_ABBREV [list \ "sun."\ "mán."\ "þri."\ "mið."\ "fim."\ "fös."\ "lau."] ::msgcat::mcset is DAYS_OF_WEEK_FULL [list \ "sunnudagur"\ "mánudagur"\ "þriðjudagur"\ "miðvikudagur"\ "fimmtudagur"\ "föstudagur"\ "laugardagur"] ::msgcat::mcset is MONTHS_ABBREV [list \ "jan."\ "feb."\ "mar."\ "apr."\ "maí"\ "jún."\ "júl."\ "ágú."\ "sep."\ "okt."\ "nóv."\ "des."\ ""] ::msgcat::mcset is MONTHS_FULL [list \ "janúar"\ "febrúar"\ "mars"\ "apríl"\ "maí"\ "júní"\ "júlí"\ "ágúst"\ "september"\ "október"\ "nóvember"\ "desember"\ ""] ::msgcat::mcset is DATE_FORMAT "%e.%m.%Y" ::msgcat::mcset is TIME_FORMAT "%H:%M:%S" ::msgcat::mcset is DATE_TIME_FORMAT "%e.%m.%Y %H:%M:%S %z" } |
Changes to library/msgs/it.msg.
1 2 3 4 5 6 7 8 9 10 11 12 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset it DAYS_OF_WEEK_ABBREV [list \ "dom"\ "lun"\ "mar"\ "mer"\ "gio"\ "ven"\ "sab"] ::msgcat::mcset it DAYS_OF_WEEK_FULL [list \ "domenica"\ | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset it DAYS_OF_WEEK_ABBREV [list \ "dom"\ "lun"\ "mar"\ "mer"\ "gio"\ "ven"\ "sab"] ::msgcat::mcset it DAYS_OF_WEEK_FULL [list \ "domenica"\ "lunedì"\ "martedì"\ "mercoledì"\ "giovedì"\ "venerdì"\ "sabato"] ::msgcat::mcset it MONTHS_ABBREV [list \ "gen"\ "feb"\ "mar"\ "apr"\ "mag"\ |
︙ | ︙ |
Changes to library/msgs/ja.msg.
1 2 3 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset ja DAYS_OF_WEEK_ABBREV [list \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset ja DAYS_OF_WEEK_ABBREV [list \ "日"\ "月"\ "火"\ "水"\ "木"\ "金"\ "土"] ::msgcat::mcset ja DAYS_OF_WEEK_FULL [list \ "日曜日"\ "月曜日"\ "火曜日"\ "水曜日"\ "木曜日"\ "金曜日"\ "土曜日"] ::msgcat::mcset ja MONTHS_FULL [list \ "1月"\ "2月"\ "3月"\ "4月"\ "5月"\ "6月"\ "7月"\ "8月"\ "9月"\ "10月"\ "11月"\ "12月"] ::msgcat::mcset ja BCE "紀元前" ::msgcat::mcset ja CE "西暦" ::msgcat::mcset ja AM "午前" ::msgcat::mcset ja PM "午後" ::msgcat::mcset ja DATE_FORMAT "%Y/%m/%d" ::msgcat::mcset ja TIME_FORMAT "%k:%M:%S" ::msgcat::mcset ja TIME_FORMAT_12 "%P %I:%M:%S" ::msgcat::mcset ja DATE_TIME_FORMAT "%Y/%m/%d %k:%M:%S %z" ::msgcat::mcset ja LOCALE_DATE_FORMAT "%EY年%m月%d日" ::msgcat::mcset ja LOCALE_TIME_FORMAT "%H時%M分%S秒" ::msgcat::mcset ja LOCALE_DATE_TIME_FORMAT "%EY年%m月%d日 (%a) %H時%M分%S秒 %z" ::msgcat::mcset ja LOCALE_ERAS "{-9223372036854775808 西暦 0} {-3061011600 明治 1867} {-1812186000 大正 1911} {-1357635600 昭和 1925} {600220800 平成 1988}" } |
Changes to library/msgs/ko.msg.
1 2 3 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset ko DAYS_OF_WEEK_ABBREV [list \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset ko DAYS_OF_WEEK_ABBREV [list \ "일"\ "월"\ "화"\ "수"\ "목"\ "금"\ "토"] ::msgcat::mcset ko DAYS_OF_WEEK_FULL [list \ "일요일"\ "월요일"\ "화요일"\ "수요일"\ "목요일"\ "금요일"\ "토요일"] ::msgcat::mcset ko MONTHS_ABBREV [list \ "1월"\ "2월"\ "3월"\ "4월"\ "5월"\ "6월"\ "7월"\ "8월"\ "9월"\ "10월"\ "11월"\ "12월"\ ""] ::msgcat::mcset ko MONTHS_FULL [list \ "1월"\ "2월"\ "3월"\ "4월"\ "5월"\ "6월"\ "7월"\ "8월"\ "9월"\ "10월"\ "11월"\ "12월"\ ""] ::msgcat::mcset ko AM "오전" ::msgcat::mcset ko PM "오후" ::msgcat::mcset ko DATE_FORMAT "%Y-%m-%d" ::msgcat::mcset ko TIME_FORMAT_12 "%P %l:%M:%S" ::msgcat::mcset ko DATE_TIME_FORMAT "%Y-%m-%d %P %l:%M:%S %z" ::msgcat::mcset ko LOCALE_DATE_FORMAT "%Y년%B%Od일" ::msgcat::mcset ko LOCALE_TIME_FORMAT "%H시%M분%S초" ::msgcat::mcset ko LOCALE_DATE_TIME_FORMAT "%A %Y년%B%Od일%H시%M분%S초 %z" } |
Changes to library/msgs/ko_kr.msg.
1 2 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { | | | | 1 2 3 4 5 6 7 8 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset ko_KR BCE "기원전" ::msgcat::mcset ko_KR CE "서기" ::msgcat::mcset ko_KR DATE_FORMAT "%Y.%m.%d" ::msgcat::mcset ko_KR TIME_FORMAT_12 "%P %l:%M:%S" ::msgcat::mcset ko_KR DATE_TIME_FORMAT "%Y.%m.%d %P %l:%M:%S %z" } |
Changes to library/msgs/kok.msg.
1 2 3 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset kok DAYS_OF_WEEK_FULL [list \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset kok DAYS_OF_WEEK_FULL [list \ "आदित्यवार"\ "सोमवार"\ "मंगळार"\ "बुधवार"\ "गुरुवार"\ "शुक्रवार"\ "शनिवार"] ::msgcat::mcset kok MONTHS_ABBREV [list \ "जानेवारी"\ "फेबृवारी"\ "मार्च"\ "एप्रिल"\ "मे"\ "जून"\ "जुलै"\ "ओगस्ट"\ "सेप्टेंबर"\ "ओक्टोबर"\ "नोव्हेंबर"\ "डिसेंबर"] ::msgcat::mcset kok MONTHS_FULL [list \ "जानेवारी"\ "फेब्रुवारी"\ "मार्च"\ "एप्रिल"\ "मे"\ "जून"\ "जुलै"\ "ओगस्ट"\ "सेप्टेंबर"\ "ओक्टोबर"\ "नोव्हेंबर"\ "डिसेंबर"] ::msgcat::mcset kok AM "क्रिस्तपूर्व" ::msgcat::mcset kok PM "क्रिस्तशखा" } |
Changes to library/msgs/lt.msg.
1 2 3 4 5 6 7 8 9 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset lt DAYS_OF_WEEK_ABBREV [list \ "Sk"\ "Pr"\ "An"\ "Tr"\ "Kt"\ "Pn"\ | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset lt DAYS_OF_WEEK_ABBREV [list \ "Sk"\ "Pr"\ "An"\ "Tr"\ "Kt"\ "Pn"\ "Št"] ::msgcat::mcset lt DAYS_OF_WEEK_FULL [list \ "Sekmadienis"\ "Pirmadienis"\ "Antradienis"\ "Trečiadienis"\ "Ketvirtadienis"\ "Penktadienis"\ "Šeštadienis"] ::msgcat::mcset lt MONTHS_ABBREV [list \ "Sau"\ "Vas"\ "Kov"\ "Bal"\ "Geg"\ "Bir"\ "Lie"\ "Rgp"\ "Rgs"\ "Spa"\ "Lap"\ "Grd"\ ""] ::msgcat::mcset lt MONTHS_FULL [list \ "Sausio"\ "Vasario"\ "Kovo"\ "Balandžio"\ "Gegužės"\ "Birželio"\ "Liepos"\ "Rugpjūčio"\ "Rugsėjo"\ "Spalio"\ "Lapkričio"\ "Gruodžio"\ ""] ::msgcat::mcset lt BCE "pr.Kr." ::msgcat::mcset lt CE "po.Kr." ::msgcat::mcset lt DATE_FORMAT "%Y.%m.%e" ::msgcat::mcset lt TIME_FORMAT "%H.%M.%S" ::msgcat::mcset lt DATE_TIME_FORMAT "%Y.%m.%e %H.%M.%S %z" } |
Changes to library/msgs/lv.msg.
1 2 3 4 5 6 7 8 9 10 11 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset lv DAYS_OF_WEEK_ABBREV [list \ "Sv"\ "P"\ "O"\ "T"\ "C"\ "Pk"\ "S"] ::msgcat::mcset lv DAYS_OF_WEEK_FULL [list \ | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset lv DAYS_OF_WEEK_ABBREV [list \ "Sv"\ "P"\ "O"\ "T"\ "C"\ "Pk"\ "S"] ::msgcat::mcset lv DAYS_OF_WEEK_FULL [list \ "svētdiena"\ "pirmdiena"\ "otrdiena"\ "trešdiena"\ "ceturdien"\ "piektdiena"\ "sestdiena"] ::msgcat::mcset lv MONTHS_ABBREV [list \ "Jan"\ "Feb"\ "Mar"\ "Apr"\ "Maijs"\ "Jūn"\ "Jūl"\ "Aug"\ "Sep"\ "Okt"\ "Nov"\ "Dec"\ ""] ::msgcat::mcset lv MONTHS_FULL [list \ "janvāris"\ "februāris"\ "marts"\ "aprīlis"\ "maijs"\ "jūnijs"\ "jūlijs"\ "augusts"\ "septembris"\ "oktobris"\ "novembris"\ "decembris"\ ""] ::msgcat::mcset lv BCE "pmē" ::msgcat::mcset lv CE "mē" ::msgcat::mcset lv DATE_FORMAT "%Y.%e.%m" ::msgcat::mcset lv TIME_FORMAT "%H:%M:%S" ::msgcat::mcset lv DATE_TIME_FORMAT "%Y.%e.%m %H:%M:%S %z" } |
Changes to library/msgs/mk.msg.
1 2 3 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset mk DAYS_OF_WEEK_ABBREV [list \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset mk DAYS_OF_WEEK_ABBREV [list \ "нед."\ "пон."\ "вт."\ "сре."\ "чет."\ "пет."\ "саб."] ::msgcat::mcset mk DAYS_OF_WEEK_FULL [list \ "недела"\ "понеделник"\ "вторник"\ "среда"\ "четврток"\ "петок"\ "сабота"] ::msgcat::mcset mk MONTHS_ABBREV [list \ "јан."\ "фев."\ "мар."\ "апр."\ "мај."\ "јун."\ "јул."\ "авг."\ "септ."\ "окт."\ "ноем."\ "декем."\ ""] ::msgcat::mcset mk MONTHS_FULL [list \ "јануари"\ "февруари"\ "март"\ "април"\ "мај"\ "јуни"\ "јули"\ "август"\ "септември"\ "октомври"\ "ноември"\ "декември"\ ""] ::msgcat::mcset mk BCE "пр.н.е." ::msgcat::mcset mk CE "ае." ::msgcat::mcset mk DATE_FORMAT "%e.%m.%Y" ::msgcat::mcset mk TIME_FORMAT "%H:%M:%S %z" ::msgcat::mcset mk DATE_TIME_FORMAT "%e.%m.%Y %H:%M:%S %z %z" } |
Changes to library/msgs/mr.msg.
1 2 3 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset mr DAYS_OF_WEEK_FULL [list \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset mr DAYS_OF_WEEK_FULL [list \ "रविवार"\ "सोमवार"\ "मंगळवार"\ "मंगळवार"\ "गुरुवार"\ "शुक्रवार"\ "शनिवार"] ::msgcat::mcset mr MONTHS_ABBREV [list \ "जानेवारी"\ "फेबृवारी"\ "मार्च"\ "एप्रिल"\ "मे"\ "जून"\ "जुलै"\ "ओगस्ट"\ "सेप्टेंबर"\ "ओक्टोबर"\ "नोव्हेंबर"\ "डिसेंबर"] ::msgcat::mcset mr MONTHS_FULL [list \ "जानेवारी"\ "फेबृवारी"\ "मार्च"\ "एप्रिल"\ "मे"\ "जून"\ "जुलै"\ "ओगस्ट"\ "सेप्टेंबर"\ "ओक्टोबर"\ "नोव्हेंबर"\ "डिसेंबर"] ::msgcat::mcset mr AM "BC" ::msgcat::mcset mr PM "AD" } |
Changes to library/msgs/mt.msg.
1 2 3 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset mt DAYS_OF_WEEK_ABBREV [list \ | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset mt DAYS_OF_WEEK_ABBREV [list \ "Ħad"\ "Tne"\ "Tli"\ "Erb"\ "Ħam"\ "Ġim"] ::msgcat::mcset mt MONTHS_ABBREV [list \ "Jan"\ "Fra"\ "Mar"\ "Apr"\ "Mej"\ "Ġun"\ "Lul"\ "Awi"\ "Set"\ "Ott"\ "Nov"] ::msgcat::mcset mt BCE "QK" ::msgcat::mcset mt CE "" |
︙ | ︙ |
Changes to library/msgs/nb.msg.
1 2 3 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset nb DAYS_OF_WEEK_ABBREV [list \ | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset nb DAYS_OF_WEEK_ABBREV [list \ "sø"\ "ma"\ "ti"\ "on"\ "to"\ "fr"\ "lø"] ::msgcat::mcset nb DAYS_OF_WEEK_FULL [list \ "søndag"\ "mandag"\ "tirsdag"\ "onsdag"\ "torsdag"\ "fredag"\ "lørdag"] ::msgcat::mcset nb MONTHS_ABBREV [list \ "jan"\ "feb"\ "mar"\ "apr"\ "mai"\ "jun"\ |
︙ | ︙ |
Changes to library/msgs/nn.msg.
1 2 3 4 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset nn DAYS_OF_WEEK_ABBREV [list \ "su"\ | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset nn DAYS_OF_WEEK_ABBREV [list \ "su"\ "må"\ "ty"\ "on"\ "to"\ "fr"\ "lau"] ::msgcat::mcset nn DAYS_OF_WEEK_FULL [list \ "sundag"\ "måndag"\ "tysdag"\ "onsdag"\ "torsdag"\ "fredag"\ "laurdag"] ::msgcat::mcset nn MONTHS_ABBREV [list \ "jan"\ |
︙ | ︙ |
Changes to library/msgs/pl.msg.
1 2 3 4 5 6 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset pl DAYS_OF_WEEK_ABBREV [list \ "N"\ "Pn"\ "Wt"\ | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset pl DAYS_OF_WEEK_ABBREV [list \ "N"\ "Pn"\ "Wt"\ "Śr"\ "Cz"\ "Pt"\ "So"] ::msgcat::mcset pl DAYS_OF_WEEK_FULL [list \ "niedziela"\ "poniedziałek"\ "wtorek"\ "środa"\ "czwartek"\ "piątek"\ "sobota"] ::msgcat::mcset pl MONTHS_ABBREV [list \ "sty"\ "lut"\ "mar"\ "kwi"\ "maj"\ "cze"\ "lip"\ "sie"\ "wrz"\ "paź"\ "lis"\ "gru"\ ""] ::msgcat::mcset pl MONTHS_FULL [list \ "styczeń"\ "luty"\ "marzec"\ "kwiecień"\ "maj"\ "czerwiec"\ "lipiec"\ "sierpień"\ "wrzesień"\ "październik"\ "listopad"\ "grudzień"\ ""] ::msgcat::mcset pl BCE "p.n.e." ::msgcat::mcset pl CE "n.e." ::msgcat::mcset pl DATE_FORMAT "%Y-%m-%d" ::msgcat::mcset pl TIME_FORMAT "%H:%M:%S" ::msgcat::mcset pl DATE_TIME_FORMAT "%Y-%m-%d %H:%M:%S %z" } |
Changes to library/msgs/pt.msg.
1 2 3 4 5 6 7 8 9 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset pt DAYS_OF_WEEK_ABBREV [list \ "Dom"\ "Seg"\ "Ter"\ "Qua"\ "Qui"\ "Sex"\ | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset pt DAYS_OF_WEEK_ABBREV [list \ "Dom"\ "Seg"\ "Ter"\ "Qua"\ "Qui"\ "Sex"\ "Sáb"] ::msgcat::mcset pt DAYS_OF_WEEK_FULL [list \ "Domingo"\ "Segunda-feira"\ "Terça-feira"\ "Quarta-feira"\ "Quinta-feira"\ "Sexta-feira"\ "Sábado"] ::msgcat::mcset pt MONTHS_ABBREV [list \ "Jan"\ "Fev"\ "Mar"\ "Abr"\ "Mai"\ "Jun"\ "Jul"\ "Ago"\ "Set"\ "Out"\ "Nov"\ "Dez"\ ""] ::msgcat::mcset pt MONTHS_FULL [list \ "Janeiro"\ "Fevereiro"\ "Março"\ "Abril"\ "Maio"\ "Junho"\ "Julho"\ "Agosto"\ "Setembro"\ "Outubro"\ |
︙ | ︙ |
Changes to library/msgs/ro.msg.
1 2 3 4 5 6 7 8 9 10 11 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset ro DAYS_OF_WEEK_ABBREV [list \ "D"\ "L"\ "Ma"\ "Mi"\ "J"\ "V"\ "S"] ::msgcat::mcset ro DAYS_OF_WEEK_FULL [list \ | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset ro DAYS_OF_WEEK_ABBREV [list \ "D"\ "L"\ "Ma"\ "Mi"\ "J"\ "V"\ "S"] ::msgcat::mcset ro DAYS_OF_WEEK_FULL [list \ "duminică"\ "luni"\ "marţi"\ "miercuri"\ "joi"\ "vineri"\ "sîmbătă"] ::msgcat::mcset ro MONTHS_ABBREV [list \ "Ian"\ "Feb"\ "Mar"\ "Apr"\ "Mai"\ "Iun"\ |
︙ | ︙ | |||
41 42 43 44 45 46 47 | "august"\ "septembrie"\ "octombrie"\ "noiembrie"\ "decembrie"\ ""] ::msgcat::mcset ro BCE "d.C." | | | 41 42 43 44 45 46 47 48 49 50 51 52 | "august"\ "septembrie"\ "octombrie"\ "noiembrie"\ "decembrie"\ ""] ::msgcat::mcset ro BCE "d.C." ::msgcat::mcset ro CE "î.d.C." ::msgcat::mcset ro DATE_FORMAT "%d.%m.%Y" ::msgcat::mcset ro TIME_FORMAT "%H:%M:%S" ::msgcat::mcset ro DATE_TIME_FORMAT "%d.%m.%Y %H:%M:%S %z" } |
Changes to library/msgs/ru.msg.
1 2 3 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset ru DAYS_OF_WEEK_ABBREV [list \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset ru DAYS_OF_WEEK_ABBREV [list \ "Вс"\ "Пн"\ "Вт"\ "Ср"\ "Чт"\ "Пт"\ "Сб"] ::msgcat::mcset ru DAYS_OF_WEEK_FULL [list \ "воскресенье"\ "понедельник"\ "вторник"\ "среда"\ "четверг"\ "пятница"\ "суббота"] ::msgcat::mcset ru MONTHS_ABBREV [list \ "янв"\ "фев"\ "мар"\ "апр"\ "май"\ "июн"\ "июл"\ "авг"\ "сен"\ "окт"\ "ноя"\ "дек"\ ""] ::msgcat::mcset ru MONTHS_FULL [list \ "Январь"\ "Февраль"\ "Март"\ "Апрель"\ "Май"\ "Июнь"\ "Июль"\ "Август"\ "Сентябрь"\ "Октябрь"\ "Ноябрь"\ "Декабрь"\ ""] ::msgcat::mcset ru BCE "до н.э." ::msgcat::mcset ru CE "н.э." ::msgcat::mcset ru DATE_FORMAT "%d.%m.%Y" ::msgcat::mcset ru TIME_FORMAT "%k:%M:%S" ::msgcat::mcset ru DATE_TIME_FORMAT "%d.%m.%Y %k:%M:%S %z" } |
Changes to library/msgs/sh.msg.
1 2 3 4 5 6 7 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset sh DAYS_OF_WEEK_ABBREV [list \ "Ned"\ "Pon"\ "Uto"\ "Sre"\ | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset sh DAYS_OF_WEEK_ABBREV [list \ "Ned"\ "Pon"\ "Uto"\ "Sre"\ "Čet"\ "Pet"\ "Sub"] ::msgcat::mcset sh DAYS_OF_WEEK_FULL [list \ "Nedelja"\ "Ponedeljak"\ "Utorak"\ "Sreda"\ "Četvrtak"\ "Petak"\ "Subota"] ::msgcat::mcset sh MONTHS_ABBREV [list \ "Jan"\ "Feb"\ "Mar"\ "Apr"\ |
︙ | ︙ |
Changes to library/msgs/sk.msg.
1 2 3 4 5 6 7 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset sk DAYS_OF_WEEK_ABBREV [list \ "Ne"\ "Po"\ "Ut"\ "St"\ | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset sk DAYS_OF_WEEK_ABBREV [list \ "Ne"\ "Po"\ "Ut"\ "St"\ "Št"\ "Pa"\ "So"] ::msgcat::mcset sk DAYS_OF_WEEK_FULL [list \ "Nedeľe"\ "Pondelok"\ "Utorok"\ "Streda"\ "Štvrtok"\ "Piatok"\ "Sobota"] ::msgcat::mcset sk MONTHS_ABBREV [list \ "jan"\ "feb"\ "mar"\ "apr"\ "máj"\ "jún"\ "júl"\ "aug"\ "sep"\ "okt"\ "nov"\ "dec"\ ""] ::msgcat::mcset sk MONTHS_FULL [list \ "január"\ "február"\ "marec"\ "apríl"\ "máj"\ "jún"\ "júl"\ "august"\ "september"\ "október"\ "november"\ "december"\ ""] ::msgcat::mcset sk BCE "pred n.l." ::msgcat::mcset sk CE "n.l." ::msgcat::mcset sk DATE_FORMAT "%e.%m.%Y" ::msgcat::mcset sk TIME_FORMAT "%k:%M:%S" |
︙ | ︙ |
Changes to library/msgs/sl.msg.
1 2 3 4 5 6 7 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset sl DAYS_OF_WEEK_ABBREV [list \ "Ned"\ "Pon"\ "Tor"\ "Sre"\ | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset sl DAYS_OF_WEEK_ABBREV [list \ "Ned"\ "Pon"\ "Tor"\ "Sre"\ "Čet"\ "Pet"\ "Sob"] ::msgcat::mcset sl DAYS_OF_WEEK_FULL [list \ "Nedelja"\ "Ponedeljek"\ "Torek"\ "Sreda"\ "Četrtek"\ "Petek"\ "Sobota"] ::msgcat::mcset sl MONTHS_ABBREV [list \ "jan"\ "feb"\ "mar"\ "apr"\ |
︙ | ︙ | |||
40 41 42 43 44 45 46 | "julij"\ "avgust"\ "september"\ "oktober"\ "november"\ "december"\ ""] | | | 40 41 42 43 44 45 46 47 48 49 50 51 52 | "julij"\ "avgust"\ "september"\ "oktober"\ "november"\ "december"\ ""] ::msgcat::mcset sl BCE "pr.n.š." ::msgcat::mcset sl CE "po Kr." ::msgcat::mcset sl DATE_FORMAT "%Y.%m.%e" ::msgcat::mcset sl TIME_FORMAT "%k:%M:%S" ::msgcat::mcset sl DATE_TIME_FORMAT "%Y.%m.%e %k:%M:%S %z" } |
Changes to library/msgs/sq.msg.
1 2 3 4 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset sq DAYS_OF_WEEK_ABBREV [list \ "Die"\ | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset sq DAYS_OF_WEEK_ABBREV [list \ "Die"\ "Hën"\ "Mar"\ "Mër"\ "Enj"\ "Pre"\ "Sht"] ::msgcat::mcset sq DAYS_OF_WEEK_FULL [list \ "e diel"\ "e hënë"\ "e martë"\ "e mërkurë"\ "e enjte"\ "e premte"\ "e shtunë"] ::msgcat::mcset sq MONTHS_ABBREV [list \ "Jan"\ "Shk"\ "Mar"\ "Pri"\ "Maj"\ "Qer"\ "Kor"\ "Gsh"\ "Sht"\ "Tet"\ "Nën"\ "Dhj"\ ""] ::msgcat::mcset sq MONTHS_FULL [list \ "janar"\ "shkurt"\ "mars"\ "prill"\ "maj"\ "qershor"\ "korrik"\ "gusht"\ "shtator"\ "tetor"\ "nëntor"\ "dhjetor"\ ""] ::msgcat::mcset sq BCE "p.e.r." ::msgcat::mcset sq CE "n.e.r." ::msgcat::mcset sq AM "PD" ::msgcat::mcset sq PM "MD" ::msgcat::mcset sq DATE_FORMAT "%Y-%m-%d" |
︙ | ︙ |
Changes to library/msgs/sr.msg.
1 2 3 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset sr DAYS_OF_WEEK_ABBREV [list \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset sr DAYS_OF_WEEK_ABBREV [list \ "Нед"\ "Пон"\ "Уто"\ "Сре"\ "Чет"\ "Пет"\ "Суб"] ::msgcat::mcset sr DAYS_OF_WEEK_FULL [list \ "Недеља"\ "Понедељак"\ "Уторак"\ "Среда"\ "Четвртак"\ "Петак"\ "Субота"] ::msgcat::mcset sr MONTHS_ABBREV [list \ "Јан"\ "Феб"\ "Мар"\ "Апр"\ "Мај"\ "Јун"\ "Јул"\ "Авг"\ "Сеп"\ "Окт"\ "Нов"\ "Дец"\ ""] ::msgcat::mcset sr MONTHS_FULL [list \ "Јануар"\ "Фебруар"\ "Март"\ "Април"\ "Мај"\ "Јуни"\ "Јули"\ "Август"\ "Септембар"\ "Октобар"\ "Новембар"\ "Децембар"\ ""] ::msgcat::mcset sr BCE "п. н. е." ::msgcat::mcset sr CE "н. е" ::msgcat::mcset sr DATE_FORMAT "%Y.%m.%e" ::msgcat::mcset sr TIME_FORMAT "%k.%M.%S" ::msgcat::mcset sr DATE_TIME_FORMAT "%Y.%m.%e %k.%M.%S %z" } |
Changes to library/msgs/sv.msg.
1 2 3 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset sv DAYS_OF_WEEK_ABBREV [list \ | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset sv DAYS_OF_WEEK_ABBREV [list \ "sö"\ "må"\ "ti"\ "on"\ "to"\ "fr"\ "lö"] ::msgcat::mcset sv DAYS_OF_WEEK_FULL [list \ "söndag"\ "måndag"\ "tisdag"\ "onsdag"\ "torsdag"\ "fredag"\ "lördag"] ::msgcat::mcset sv MONTHS_ABBREV [list \ "jan"\ "feb"\ "mar"\ "apr"\ "maj"\ "jun"\ |
︙ | ︙ |
Changes to library/msgs/ta.msg.
1 2 3 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset ta DAYS_OF_WEEK_FULL [list \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset ta DAYS_OF_WEEK_FULL [list \ "ஞாயிறு"\ "திங்கள்"\ "செவ்வாய்"\ "புதன்"\ "வியாழன்"\ "வெள்ளி"\ "சனி"] ::msgcat::mcset ta MONTHS_ABBREV [list \ "ஜனவரி"\ "பெப்ரவரி"\ "மார்ச்"\ "ஏப்ரல்"\ "மே"\ "ஜூன்"\ "ஜூலை"\ "ஆகஸ்ட்"\ "செப்டம்பர்"\ "அக்டோபர்"\ "நவம்பர்"\ "டிசம்பர்r"] ::msgcat::mcset ta MONTHS_FULL [list \ "ஜனவரி"\ "பெப்ரவரி"\ "மார்ச்"\ "ஏப்ரல்"\ "மே"\ "ஜூன்"\ "ஜூலை"\ "ஆகஸ்ட்"\ "செப்டம்பர்"\ "அக்டோபர்"\ "நவம்பர்"\ "டிசம்பர்r"] ::msgcat::mcset ta AM "கிமு" ::msgcat::mcset ta PM "கிபி" } |
Changes to library/msgs/te.msg.
1 2 3 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset te DAYS_OF_WEEK_ABBREV [list \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset te DAYS_OF_WEEK_ABBREV [list \ "ఆది"\ "సోమ"\ "మంగళ"\ "బుధ"\ "గురు"\ "శుక్ర"\ "శని"] ::msgcat::mcset te DAYS_OF_WEEK_FULL [list \ "ఆదివారం"\ "సోమవారం"\ "మంగళవారం"\ "బుధవారం"\ "గురువారం"\ "శుక్రవారం"\ "శనివారం"] ::msgcat::mcset te MONTHS_ABBREV [list \ "జనవరి"\ "ఫిబ్రవరి"\ "మార్చి"\ "ఏప్రిల్"\ "మే"\ "జూన్"\ "జూలై"\ "ఆగస్టు"\ "సెప్టెంబర్"\ "అక్టోబర్"\ "నవంబర్"\ "డిసెంబర్"\ ""] ::msgcat::mcset te MONTHS_FULL [list \ "జనవరి"\ "ఫిబ్రవరి"\ "మార్చి"\ "ఏప్రిల్"\ "మే"\ "జూన్"\ "జూలై"\ "ఆగస్టు"\ "సెప్టెంబర్"\ "అక్టోబర్"\ "నవంబర్"\ "డిసెంబర్"\ ""] } |
Changes to library/msgs/te_in.msg.
1 2 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { | | | | 1 2 3 4 5 6 7 8 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset te_IN AM "పూర్వాహ్న" ::msgcat::mcset te_IN PM "అపరాహ్న" ::msgcat::mcset te_IN DATE_FORMAT "%d/%m/%Y" ::msgcat::mcset te_IN TIME_FORMAT_12 "%I:%M:%S %P" ::msgcat::mcset te_IN DATE_TIME_FORMAT "%d/%m/%Y %I:%M:%S %P %z" } |
Changes to library/msgs/th.msg.
1 2 3 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset th DAYS_OF_WEEK_ABBREV [list \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset th DAYS_OF_WEEK_ABBREV [list \ "อา."\ "จ."\ "อ."\ "พ."\ "พฤ."\ "ศ."\ "ส."] ::msgcat::mcset th DAYS_OF_WEEK_FULL [list \ "วันอาทิตย์"\ "วันจันทร์"\ "วันอังคาร"\ "วันพุธ"\ "วันพฤหัสบดี"\ "วันศุกร์"\ "วันเสาร์"] ::msgcat::mcset th MONTHS_ABBREV [list \ "ม.ค."\ "ก.พ."\ "มี.ค."\ "เม.ย."\ "พ.ค."\ "มิ.ย."\ "ก.ค."\ "ส.ค."\ "ก.ย."\ "ต.ค."\ "พ.ย."\ "ธ.ค."\ ""] ::msgcat::mcset th MONTHS_FULL [list \ "มกราคม"\ "กุมภาพันธ์"\ "มีนาคม"\ "เมษายน"\ "พฤษภาคม"\ "มิถุนายน"\ "กรกฎาคม"\ "สิงหาคม"\ "กันยายน"\ "ตุลาคม"\ "พฤศจิกายน"\ "ธันวาคม"\ ""] ::msgcat::mcset th BCE "ลที่" ::msgcat::mcset th CE "ค.ศ." ::msgcat::mcset th AM "ก่อนเที่ยง" ::msgcat::mcset th PM "หลังเที่ยง" ::msgcat::mcset th DATE_FORMAT "%e/%m/%Y" ::msgcat::mcset th TIME_FORMAT "%k:%M:%S" ::msgcat::mcset th DATE_TIME_FORMAT "%e/%m/%Y %k:%M:%S %z" } |
Changes to library/msgs/tr.msg.
1 2 3 4 5 6 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset tr DAYS_OF_WEEK_ABBREV [list \ "Paz"\ "Pzt"\ "Sal"\ | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset tr DAYS_OF_WEEK_ABBREV [list \ "Paz"\ "Pzt"\ "Sal"\ "Çar"\ "Per"\ "Cum"\ "Cmt"] ::msgcat::mcset tr DAYS_OF_WEEK_FULL [list \ "Pazar"\ "Pazartesi"\ "Salı"\ "Çarşamba"\ "Perşembe"\ "Cuma"\ "Cumartesi"] ::msgcat::mcset tr MONTHS_ABBREV [list \ "Oca"\ "Şub"\ "Mar"\ "Nis"\ "May"\ "Haz"\ "Tem"\ "Ağu"\ "Eyl"\ "Eki"\ "Kas"\ "Ara"\ ""] ::msgcat::mcset tr MONTHS_FULL [list \ "Ocak"\ "Şubat"\ "Mart"\ "Nisan"\ "Mayıs"\ "Haziran"\ "Temmuz"\ "Ağustos"\ "Eylül"\ "Ekim"\ "Kasım"\ "Aralık"\ ""] ::msgcat::mcset tr DATE_FORMAT "%d.%m.%Y" ::msgcat::mcset tr TIME_FORMAT "%H:%M:%S" ::msgcat::mcset tr DATE_TIME_FORMAT "%d.%m.%Y %H:%M:%S %z" } |
Changes to library/msgs/uk.msg.
1 2 3 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset uk DAYS_OF_WEEK_ABBREV [list \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset uk DAYS_OF_WEEK_ABBREV [list \ "нд"\ "пн"\ "вт"\ "ср"\ "чт"\ "пт"\ "сб"] ::msgcat::mcset uk DAYS_OF_WEEK_FULL [list \ "неділя"\ "понеділок"\ "вівторок"\ "середа"\ "четвер"\ "п'ятниця"\ "субота"] ::msgcat::mcset uk MONTHS_ABBREV [list \ "січ"\ "лют"\ "бер"\ "квіт"\ "трав"\ "черв"\ "лип"\ "серп"\ "вер"\ "жовт"\ "лист"\ "груд"\ ""] ::msgcat::mcset uk MONTHS_FULL [list \ "січня"\ "лютого"\ "березня"\ "квітня"\ "травня"\ "червня"\ "липня"\ "серпня"\ "вересня"\ "жовтня"\ "листопада"\ "грудня"\ ""] ::msgcat::mcset uk BCE "до н.е." ::msgcat::mcset uk CE "після н.е." ::msgcat::mcset uk DATE_FORMAT "%e/%m/%Y" ::msgcat::mcset uk TIME_FORMAT "%k:%M:%S" ::msgcat::mcset uk DATE_TIME_FORMAT "%e/%m/%Y %k:%M:%S %z" } |
Changes to library/msgs/vi.msg.
1 2 3 4 5 6 7 8 9 10 11 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset vi DAYS_OF_WEEK_ABBREV [list \ "Th 2"\ "Th 3"\ "Th 4"\ "Th 5"\ "Th 6"\ "Th 7"\ "CN"] ::msgcat::mcset vi DAYS_OF_WEEK_FULL [list \ | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset vi DAYS_OF_WEEK_ABBREV [list \ "Th 2"\ "Th 3"\ "Th 4"\ "Th 5"\ "Th 6"\ "Th 7"\ "CN"] ::msgcat::mcset vi DAYS_OF_WEEK_FULL [list \ "Thứ hai"\ "Thứ ba"\ "Thứ tư"\ "Thứ năm"\ "Thứ sáu"\ "Thứ bảy"\ "Chủ nhật"] ::msgcat::mcset vi MONTHS_ABBREV [list \ "Thg 1"\ "Thg 2"\ "Thg 3"\ "Thg 4"\ "Thg 5"\ "Thg 6"\ "Thg 7"\ "Thg 8"\ "Thg 9"\ "Thg 10"\ "Thg 11"\ "Thg 12"\ ""] ::msgcat::mcset vi MONTHS_FULL [list \ "Tháng một"\ "Tháng hai"\ "Tháng ba"\ "Tháng tư"\ "Tháng năm"\ "Tháng sáu"\ "Tháng bảy"\ "Tháng tám"\ "Tháng chín"\ "Tháng mười"\ "Tháng mười một"\ "Tháng mười hai"\ ""] ::msgcat::mcset vi DATE_FORMAT "%d %b %Y" ::msgcat::mcset vi TIME_FORMAT "%H:%M:%S" ::msgcat::mcset vi DATE_TIME_FORMAT "%d %b %Y %H:%M:%S %z" } |
Changes to library/msgs/zh.msg.
1 2 3 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset zh DAYS_OF_WEEK_ABBREV [list \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset zh DAYS_OF_WEEK_ABBREV [list \ "星期日"\ "星期一"\ "星期二"\ "星期三"\ "星期四"\ "星期五"\ "星期六"] ::msgcat::mcset zh DAYS_OF_WEEK_FULL [list \ "星期日"\ "星期一"\ "星期二"\ "星期三"\ "星期四"\ "星期五"\ "星期六"] ::msgcat::mcset zh MONTHS_ABBREV [list \ "一月"\ "二月"\ "三月"\ "四月"\ "五月"\ "六月"\ "七月"\ "八月"\ "九月"\ "十月"\ "十一月"\ "十二月"\ ""] ::msgcat::mcset zh MONTHS_FULL [list \ "一月"\ "二月"\ "三月"\ "四月"\ "五月"\ "六月"\ "七月"\ "八月"\ "九月"\ "十月"\ "十一月"\ "十二月"\ ""] ::msgcat::mcset zh BCE "公元前" ::msgcat::mcset zh CE "公元" ::msgcat::mcset zh AM "上午" ::msgcat::mcset zh PM "下午" ::msgcat::mcset zh LOCALE_NUMERALS "〇 一 二 三 四 五 六 七 八 九 十 十一 十二 十三 十四 十五 十六 十七 十八 十九 二十 廿一 廿二 廿三 廿四 廿五 廿六 廿七 廿八 廿九 三十 卅一 卅二 卅三 卅四 卅五 卅六 卅七 卅八 卅九 四十 四十一 四十二 四十三 四十四 四十五 四十六 四十七 四十八 四十九 五十 五十一 五十二 五十三 五十四 五十五 五十六 五十七 五十八 五十九 六十 六十一 六十二 六十三 六十四 六十五 六十六 六十七 六十八 六十九 七十 七十一 七十二 七十三 七十四 七十五 七十六 七十七 七十八 七十九 八十 八十一 八十二 八十三 八十四 八十五 八十六 八十七 八十八 八十九 九十 九十一 九十二 九十三 九十四 九十五 九十六 九十七 九十八 九十九" ::msgcat::mcset zh LOCALE_DATE_FORMAT "公元%Y年%B%Od日" ::msgcat::mcset zh LOCALE_TIME_FORMAT "%OH时%OM分%OS秒" ::msgcat::mcset zh LOCALE_DATE_TIME_FORMAT "%A %Y年%B%Od日%OH时%OM分%OS秒 %z" } |
Changes to library/msgs/zh_cn.msg.
1 2 3 4 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset zh_CN DATE_FORMAT "%Y-%m-%e" ::msgcat::mcset zh_CN TIME_FORMAT "%k:%M:%S" | | | 1 2 3 4 5 6 7 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset zh_CN DATE_FORMAT "%Y-%m-%e" ::msgcat::mcset zh_CN TIME_FORMAT "%k:%M:%S" ::msgcat::mcset zh_CN TIME_FORMAT_12 "%P%I时%M分%S秒" ::msgcat::mcset zh_CN DATE_TIME_FORMAT "%Y-%m-%e %k:%M:%S %z" } |
Changes to library/msgs/zh_hk.msg.
1 2 3 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset zh_HK DAYS_OF_WEEK_ABBREV [list \ | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset zh_HK DAYS_OF_WEEK_ABBREV [list \ "日"\ "一"\ "二"\ "三"\ "四"\ "五"\ "六"] ::msgcat::mcset zh_HK MONTHS_ABBREV [list \ "1月"\ "2月"\ "3月"\ "4月"\ "5月"\ "6月"\ "7月"\ "8月"\ "9月"\ "10月"\ "11月"\ "12月"\ ""] ::msgcat::mcset zh_HK DATE_FORMAT "%Y年%m月%e日" ::msgcat::mcset zh_HK TIME_FORMAT_12 "%P%I:%M:%S" ::msgcat::mcset zh_HK DATE_TIME_FORMAT "%Y年%m月%e日 %P%I:%M:%S %z" } |
Changes to library/msgs/zh_sg.msg.
1 2 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { | | | | 1 2 3 4 5 6 7 8 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset zh_SG AM "上午" ::msgcat::mcset zh_SG PM "中午" ::msgcat::mcset zh_SG DATE_FORMAT "%d %B %Y" ::msgcat::mcset zh_SG TIME_FORMAT_12 "%P %I:%M:%S" ::msgcat::mcset zh_SG DATE_TIME_FORMAT "%d %B %Y %P %I:%M:%S %z" } |
Changes to library/msgs/zh_tw.msg.
1 2 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { | | | | 1 2 3 4 5 6 7 8 | # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset zh_TW BCE "民國前" ::msgcat::mcset zh_TW CE "民國" ::msgcat::mcset zh_TW DATE_FORMAT "%Y/%m/%e" ::msgcat::mcset zh_TW TIME_FORMAT_12 "%P %I:%M:%S" ::msgcat::mcset zh_TW DATE_TIME_FORMAT "%Y/%m/%e %P %I:%M:%S %z" } |
Changes to tests/chanio.test.
︙ | ︙ | |||
5334 5335 5336 5337 5338 5339 5340 | chan close $f } -result {zzy abzzy} test chan-io-40.2 {POSIX open access modes: CREAT} -setup { file delete $path(test3) } -constraints {unix} -body { set f [open $path(test3) {WRONLY CREAT} 0600] file stat $path(test3) stats | | | | | | 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 | chan close $f } -result {zzy abzzy} test chan-io-40.2 {POSIX open access modes: CREAT} -setup { file delete $path(test3) } -constraints {unix} -body { set f [open $path(test3) {WRONLY CREAT} 0600] file stat $path(test3) stats set x [format "%#o" [expr $stats(mode)&0o777]] chan puts $f "line 1" chan close $f set f [open $path(test3) r] lappend x [chan gets $f] } -cleanup { chan close $f } -result {0o600 {line 1}} test chan-io-40.3 {POSIX open access modes: CREAT} -setup { file delete $path(test3) } -constraints {unix umask} -body { # This test only works if your umask is 2, like ouster's. chan close [open $path(test3) {WRONLY CREAT}] file stat $path(test3) stats format "%#o" [expr $stats(mode)&0o777] } -result [format %#5o [expr {0o666 & ~ $umaskValue}]] test chan-io-40.4 {POSIX open access modes: CREAT} -setup { file delete $path(test3) } -body { set f [open $path(test3) w] chan configure $f -eofchar {} chan puts $f xyzzy chan close $f |
︙ | ︙ |
Changes to tests/coroutine.test.
︙ | ︙ | |||
736 737 738 739 740 741 742 743 744 745 746 747 748 749 | proc boom {} { cc ; # coro created at level 2 C ; # and called at level 1 } boom ; # does not crash: the coro floor is a good insulator list } -result {} # cleanup unset lambda ::tcltest::cleanupTests return | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 | proc boom {} { cc ; # coro created at level 2 C ; # and called at level 1 } boom ; # does not crash: the coro floor is a good insulator list } -result {} test coroutine-8.0.0 {coro inject executed} -body { coroutine demo apply {{} { foreach i {1 2} yield }} demo set ::result none tcl::unsupported::inject demo set ::result inject-executed demo set ::result } -result {inject-executed} test coroutine-8.0.1 {coro inject after error} -body { coroutine demo apply {{} { foreach i {1 2} yield; error test }} demo set ::result none tcl::unsupported::inject demo set ::result inject-executed lappend ::result [catch {demo} err] $err } -result {inject-executed 1 test} test coroutine-8.1.1 {coro inject, ticket 42202ba1e5ff566e} -body { interp create slave slave eval { coroutine demo apply {{} { while {1} yield }} demo tcl::unsupported::inject demo set ::result inject-executed } interp delete slave } -result {} test coroutine-8.1.2 {coro inject with result, ticket 42202ba1e5ff566e} -body { interp create slave slave eval { coroutine demo apply {{} { while {1} yield }} demo tcl::unsupported::inject demo set ::result inject-executed } slave eval demo set result [slave eval {set ::result}] interp delete slave set result } -result {inject-executed} # cleanup unset lambda ::tcltest::cleanupTests return |
︙ | ︙ |
Changes to tests/format.test.
︙ | ︙ | |||
17 18 19 20 21 22 23 24 25 26 27 28 29 30 | # %u output depends on word length, so this test is not portable. testConstraint longIs32bit [expr {int(0x80000000) < 0}] testConstraint longIs64bit [expr {int(0x8000000000000000) < 0}] testConstraint wideIs64bit \ [expr {(wide(0x80000000) > 0) && (wide(0x8000000000000000) < 0)}] testConstraint wideBiggerThanInt [expr {wide(0x80000000) != int(0x80000000)}] test format-1.1 {integer formatting} { format "%*d %d %d %d" 6 34 16923 -12 -1 } { 34 16923 -12 -1} test format-1.2 {integer formatting} { format "%4d %4d %4d %4d %d %#x %#X" 6 34 16923 -12 -1 14 12 } { 6 34 16923 -12 -1 0xe 0XC} | > | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | # %u output depends on word length, so this test is not portable. testConstraint longIs32bit [expr {int(0x80000000) < 0}] testConstraint longIs64bit [expr {int(0x8000000000000000) < 0}] testConstraint wideIs64bit \ [expr {(wide(0x80000000) > 0) && (wide(0x8000000000000000) < 0)}] testConstraint wideBiggerThanInt [expr {wide(0x80000000) != int(0x80000000)}] testConstraint pointerIs64bit [expr {$tcl_platform(pointerSize) >= 8}] test format-1.1 {integer formatting} { format "%*d %d %d %d" 6 34 16923 -12 -1 } { 34 16923 -12 -1} test format-1.2 {integer formatting} { format "%4d %4d %4d %4d %d %#x %#X" 6 34 16923 -12 -1 14 12 } { 6 34 16923 -12 -1 0xe 0XC} |
︙ | ︙ | |||
48 49 50 51 52 53 54 | test format-1.7 {integer formatting} longIs32bit { format "%4x %4x %4x %4x" 6 34 16923 -12 -1 } { 6 22 421b fffffff4} test format-1.7.1 {integer formatting} longIs64bit { format "%4x %4x %4x %4x" 6 34 16923 -12 -1 } { 6 22 421b fffffffffffffff4} test format-1.8 {integer formatting} longIs32bit { | | | | | | | | | | | | | | | | | | | | 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | test format-1.7 {integer formatting} longIs32bit { format "%4x %4x %4x %4x" 6 34 16923 -12 -1 } { 6 22 421b fffffff4} test format-1.7.1 {integer formatting} longIs64bit { format "%4x %4x %4x %4x" 6 34 16923 -12 -1 } { 6 22 421b fffffffffffffff4} test format-1.8 {integer formatting} longIs32bit { format "%#x %#x %#X %#X %#x" 0 6 34 16923 -12 -1 } {0x0 0x6 0X22 0X421B 0xfffffff4} test format-1.8.1 {integer formatting} longIs64bit { format "%#x %#x %#X %#X %#x" 0 6 34 16923 -12 -1 } {0x0 0x6 0X22 0X421B 0xfffffffffffffff4} test format-1.9 {integer formatting} longIs32bit { format "%#5x %#20x %#20x %#20x %#20x" 0 6 34 16923 -12 -1 } { 0x0 0x6 0x22 0x421b 0xfffffff4} test format-1.9.1 {integer formatting} longIs64bit { format "%#5x %#20x %#20x %#20x %#20x" 0 6 34 16923 -12 -1 } { 0x0 0x6 0x22 0x421b 0xfffffffffffffff4} test format-1.10 {integer formatting} longIs32bit { format "%-#5x %-#20x %-#20x %-#20x %-#20x" 0 6 34 16923 -12 -1 } {0x0 0x6 0x22 0x421b 0xfffffff4 } test format-1.10.1 {integer formatting} longIs64bit { format "%-#5x %-#20x %-#20x %-#20x %-#20x" 0 6 34 16923 -12 -1 } {0x0 0x6 0x22 0x421b 0xfffffffffffffff4 } test format-1.11 {integer formatting} longIs32bit { format "%-#5o %-#20o %#-20o %#-20o %#-20o" 0 6 34 16923 -12 -1 } {0 06 042 041033 037777777764 } test format-1.11.1 {integer formatting} longIs64bit { format "%-#5o %-#20o %#-20o %#-20o %#-20o" 0 6 34 16923 -12 -1 } {0 06 042 041033 01777777777777777777764} test format-1.12 {integer formatting} { format "%b %#b %#b %llb" 5 0 5 [expr {2**100}] } {101 0b0 0b101 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000} test format-2.1 {string formatting} { format "%s %s %c %s" abcd {This is a very long test string.} 120 x } {abcd This is a very long test string. x x} test format-2.2 {string formatting} { format "%20s %20s %20c %20s" abcd {This is a very long test string.} 120 x } { abcd This is a very long test string. x x} |
︙ | ︙ | |||
345 346 347 348 349 350 351 | catch {format ab% 12} msg set msg } {format string ended in middle of field specifier} test format-8.19 {error conditions} { catch {format %q x} } 1 test format-8.20 {error conditions} { | | | > > > > > > > > > > > > > > > > > > > > | 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 | catch {format ab% 12} msg set msg } {format string ended in middle of field specifier} test format-8.19 {error conditions} { catch {format %q x} } 1 test format-8.20 {error conditions} { catch {format %r x} msg set msg } {bad field specifier "r"} test format-8.21 {error conditions} { catch {format %d} } 1 test format-8.22 {error conditions} { catch {format %d} msg set msg } {not enough arguments for all format specifiers} test format-8.23 {error conditions} { catch {format "%d %d" 24 xyz} msg set msg } {expected integer but got "xyz"} # Since "%zd" and "%td" are equivalent to "%lld" in 64-bit platforms and # equivalent to "%d" in 32-bit platforms, they are really not useful in # scripts, therefore they are not documented. It's intended use is through # the function Tcl_AppendPrintfToObj (et al). test format-8.24 {Undocumented formats} -body { format "%zd %td %d" [expr 2**30] [expr 2**30] [expr 2**30] } -result {1073741824 1073741824 1073741824} test format-8.25 {Undocumented formats} -constraints pointerIs64bit -body { format "%zd %td %lld" [expr 2**33] [expr 2**33] [expr 2**33] } -result {8589934592 8589934592 8589934592} # Since "%p" is equivalent to "%#llx" in 64-bit platforms and equivalent # to "%#x" in 32-bit platforms, it are really not useful in scripts, # therefore they are not documented. It's intended use is through the # function Tcl_AppendPrintfToObj (et al). test format-8.26 {Undocumented formats} -body { format "%p %#x" [expr 2**31] [expr 2**31] } -result {0x80000000 0x80000000} test format-8.27 {Undocumented formats} -constraints pointerIs64bit -body { format "%p %#llx" [expr 2**33] [expr 2**33] } -result {0x200000000 0x200000000} test format-9.1 {long result} { set a {1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z} format {1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG %s %s} $a $a } {1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG 1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z} test format-10.1 {"h" format specifier} { |
︙ | ︙ | |||
524 525 526 527 528 529 530 531 532 533 534 535 536 537 | } 7810179016327718216 test format-17.3 {testing %ld with non-wide} {wideIs64bit} { format %ld 42 } 42 test format-17.4 {testing %l with non-integer} { format %lf 1 } 1.000000 test format-18.1 {do not demote existing numeric values} { set a 0xaaaaaaaa # Ensure $a and $b are separate objects set b 0xaaaa append b aaaa set result [expr {$a == $b}] | > > > > > > | 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 | } 7810179016327718216 test format-17.3 {testing %ld with non-wide} {wideIs64bit} { format %ld 42 } 42 test format-17.4 {testing %l with non-integer} { format %lf 1 } 1.000000 test format-17.5 {testing %llu with positive bignum} -body { format %llu 0xabcdef0123456789abcdef } -returnCodes 1 -result {unsigned bignum format is invalid} test format-17.6 {testing %llu with negative number} -body { format %llu -1 } -returnCodes 1 -result {unsigned bignum format is invalid} test format-18.1 {do not demote existing numeric values} { set a 0xaaaaaaaa # Ensure $a and $b are separate objects set b 0xaaaa append b aaaa set result [expr {$a == $b}] |
︙ | ︙ |
Changes to tests/http.test.
︙ | ︙ | |||
32 33 34 35 36 37 38 | proc bgerror {args} { global errorInfo puts stderr "http.test bgerror" puts stderr [join $args] puts stderr $errorInfo } | < < | | < < | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | proc bgerror {args} { global errorInfo puts stderr "http.test bgerror" puts stderr [join $args] puts stderr $errorInfo } set bindata "This is binary data\x0d\x0amore\x0dmore\x0amore\x00null" catch {unset data} # Ensure httpd file exists set origFile [file join [pwd] [file dirname [info script]] httpd] set httpdFile [file join [temporaryDirectory] httpd_[pid]] if {![file exists $httpdFile]} { makeFile "" $httpdFile file delete $httpdFile file copy $origFile $httpdFile set removeHttpd 1 } catch {package require Thread 2.7-} if {[catch {package present Thread}] == 0 && [file exists $httpdFile]} { set httpthread [thread::create -preserved] thread::send $httpthread [list source $httpdFile] thread::send $httpthread [list set bindata $bindata] thread::send $httpthread {httpd_init 0; set port} port puts "Running httpd in thread $httpthread" } else { if {![file exists $httpdFile]} { puts "Cannot read $httpdFile script, http test skipped" unset port return } source $httpdFile # Let the OS pick the port; that's much more flexible if {[catch {httpd_init 0} listen]} { puts "Cannot start http server, http test skipped" catch {unset port} return } } test http-1.1 {http::config} { http::config -useragent UserAgent http::config } [list -accept */* -proxyfilter http::ProxyRequired -proxyhost {} -proxyport {} -urlencoding utf-8 -useragent "UserAgent"] |
︙ | ︙ |
Changes to tests/httpd.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # -*- tcl -*- # # The httpd_ procedures implement a stub http server. # # Copyright (c) 1997-1998 Sun Microsystems, Inc. # Copyright (c) 1999-2000 Scriptics Corporation # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. #set httpLog 1 proc httpd_init {{port 8015}} { | | > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # -*- tcl -*- # # The httpd_ procedures implement a stub http server. # # Copyright (c) 1997-1998 Sun Microsystems, Inc. # Copyright (c) 1999-2000 Scriptics Corporation # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. #set httpLog 1 proc httpd_init {{port 8015}} { set s [socket -server httpdAccept $port] # Save the actual port number in a global variable. # This is important when we're called with port 0 # for picking an unused port at random. set ::port [lindex [chan configure $s -sockname] 2] return $s } proc httpd_log {args} { global httpLog if {[info exists httpLog] && $httpLog} { puts stderr "httpd: [join $args { }]" } } |
︙ | ︙ |
Changes to tests/httpold.test.
1 2 3 4 5 6 7 | # Commands covered: http_config, http_get, http_wait, http_reset # # This file contains a collection of tests for the http script library. # Sourcing this file into Tcl runs the tests and # generates output for errors. No output means no errors were found. # # Copyright (c) 1991-1993 The Regents of the University of California. | > | 1 2 3 4 5 6 7 8 | # -*- tcl -*- # Commands covered: http_config, http_get, http_wait, http_reset # # This file contains a collection of tests for the http script library. # Sourcing this file into Tcl runs the tests and # generates output for errors. No output means no errors were found. # # Copyright (c) 1991-1993 The Regents of the University of California. |
︙ | ︙ | |||
37 38 39 40 41 42 43 | catch {unset data} ## ## The httpd script implement a stub http server ## source [file join [file dirname [info script]] httpd] | < | | | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | catch {unset data} ## ## The httpd script implement a stub http server ## source [file join [file dirname [info script]] httpd] if [catch {httpd_init 0} listen] { puts "Cannot start http server, http test skipped" catch {unset port} ::tcltest::cleanupTests return } test httpold-1.1 {http_config} { http_config } {-accept */* -proxyfilter httpProxyRequired -proxyhost {} -proxyport {} -useragent {Tcl http client package 1.0}} |
︙ | ︙ |
Changes to tests/io.test.
︙ | ︙ | |||
5648 5649 5650 5651 5652 5653 5654 | } {0o600 {line 1}} test io-40.3 {POSIX open access modes: CREAT} {unix umask} { # This test only works if your umask is 2, like ouster's. file delete $path(test3) set f [open $path(test3) {WRONLY CREAT}] close $f file stat $path(test3) stats | | | | 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 | } {0o600 {line 1}} test io-40.3 {POSIX open access modes: CREAT} {unix umask} { # This test only works if your umask is 2, like ouster's. file delete $path(test3) set f [open $path(test3) {WRONLY CREAT}] close $f file stat $path(test3) stats format "%#o" [expr $stats(mode)&0o777] } [format %#5o [expr {0o666 & ~ $umaskValue}]] test io-40.4 {POSIX open access modes: CREAT} { file delete $path(test3) set f [open $path(test3) w] fconfigure $f -eofchar {} puts $f xyzzy close $f set f [open $path(test3) {WRONLY CREAT}] |
︙ | ︙ |
Changes to tests/oo.test.
︙ | ︙ | |||
2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 | oo::class create foo } -cleanup { rename foo {} } -body { oo::define foo unexport {*}[info class methods foo -all] info class methods foo -all } -result {} test oo-18.1 {OO: define command support} { list [catch {oo::define oo::object {error foo}} msg] $msg $errorInfo } {1 foo {foo while executing "error foo" (in definition script for class "::oo::object" line 1) | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 | oo::class create foo } -cleanup { rename foo {} } -body { oo::define foo unexport {*}[info class methods foo -all] info class methods foo -all } -result {} set stdmethods {<cloned> destroy eval unknown variable varname} test oo-17.11 {OO: object method unexport (bug 900cb0284bc)} -setup { oo::object create o oo::objdefine o unexport m } -body { lsort [info object methods o -all -private] } -cleanup { o destroy } -result $stdmethods test oo-17.12 {OO: instance method unexport (bug 900cb0284bc)} -setup { oo::class create c c create o oo::objdefine o unexport m } -body { lsort [info object methods o -all -private] } -cleanup { o destroy c destroy } -result $stdmethods test oo-17.13 {OO: class method unexport (bug 900cb0284bc)} -setup { oo::class create c oo::define c unexport m } -body { lsort [info class methods c -all -private] } -cleanup { c destroy } -result $stdmethods test oo-17.14 {OO: instance method unexport (bug 900cb0284bc)} -setup { oo::class create c oo::define c unexport m c create o } -body { lsort [info object methods o -all -private] } -cleanup { o destroy c destroy } -result $stdmethods test oo-18.1 {OO: define command support} { list [catch {oo::define oo::object {error foo}} msg] $msg $errorInfo } {1 foo {foo while executing "error foo" (in definition script for class "::oo::object" line 1) |
︙ | ︙ |
Changes to tests/scan.test.
︙ | ︙ | |||
537 538 539 540 541 542 543 544 545 546 547 548 549 550 | } 0 test scan-5.15 {Bug be003d570f} { scan 0x40 %o } 0 test scan-5.16 {Bug be003d570f} { scan 0x40 %b } 0 test scan-6.1 {floating-point scanning} -setup { set a {}; set b {}; set c {}; set d {} } -body { list [scan "2.1 -3.0e8 .99962 a" "%f%g%e%f" a b c d] $a $b $c $d } -result {3 2.1 -300000000.0 0.99962 {}} test scan-6.2 {floating-point scanning} -setup { | > > > > > > > > > > > > > > > > > > | 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 565 566 567 568 | } 0 test scan-5.15 {Bug be003d570f} { scan 0x40 %o } 0 test scan-5.16 {Bug be003d570f} { scan 0x40 %b } 0 test scan-5.17 {bigint scanning} -setup { set a {}; set b {}; set c {} } -body { list [scan "207698809136909011942886895,abcdef0123456789abcdef,125715736004432126361152746757" \ %lld,%llx,%llo a b c] $a $b $c } -result {3 207698809136909011942886895 207698809136909011942886895 207698809136909011942886895} test scan-5.18 {bigint scanning underflow} -setup { set a {}; } -body { list [scan "-207698809136909011942886895" \ %llu a] $a } -returnCodes 1 -result {unsigned bignum scans are invalid} test scan-5.18 {bigint scanning invalid} -setup { set a {}; } -body { list [scan "207698809136909011942886895" \ %llu a] $a } -returnCodes 1 -result {unsigned bignum scans are invalid} test scan-6.1 {floating-point scanning} -setup { set a {}; set b {}; set c {}; set d {} } -body { list [scan "2.1 -3.0e8 .99962 a" "%f%g%e%f" a b c d] $a $b $c $d } -result {3 2.1 -300000000.0 0.99962 {}} test scan-6.2 {floating-point scanning} -setup { |
︙ | ︙ |
Changes to tests/socket.test.
︙ | ︙ | |||
56 57 58 59 60 61 62 | # either in Tcl or in the environment; if they are, it attempts to connect to # the server. If the connection is successful, the tests using the remote # server will be performed; otherwise, it will attempt to start the remote # server (via exec) on platforms that support this, on the local host, # listening at port 2048. If all fails, a message is printed and the tests # using the remote server are not performed. | > | | > > > > | > > > > > > > > > > > > > > > > > > > > > > > | 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | # either in Tcl or in the environment; if they are, it attempts to connect to # the server. If the connection is successful, the tests using the remote # server will be performed; otherwise, it will attempt to start the remote # server (via exec) on platforms that support this, on the local host, # listening at port 2048. If all fails, a message is printed and the tests # using the remote server are not performed. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] # Some tests require the Thread package or exec command testConstraint thread [expr {0 == [catch {package require Thread 2.7-}]}] testConstraint exec [llength [info commands exec]] # Produce a random port number in the Dynamic/Private range # from 49152 through 65535. proc randport {} { # firstly try dynamic port via server-socket(0): set port 0x7fffffff catch { set port [lindex [fconfigure [set s [socket -server {} 0]] -sockname] 2] close $s } while {[catch { close [socket -server {} $port] } msg]} { if {[incr i] > 1000} {return -code error "too many iterations to get free random port: $msg"} # try random port: set port [expr {int(rand()*16383+49152)}] } return $port } # Check if testsocket testflags is available testConstraint testsocket_testflags [expr {![catch { set h [socket -async localhost [randport]] testsocket testflags $h 0 close $h }]}] # Test the latency of tcp connections over the loopback interface. Some OSes # (e.g. NetBSD) seem to use the Nagle algorithm and delayed ACKs, so it takes # up to 200ms for a packet sent to localhost to arrive. We're measuring this # here, so that OSes that don't have this problem can run the tests at full # speed. set server [socket -server {apply {{s a p} {set ::s1 $s}}} 0] |
︙ | ︙ | |||
2262 2263 2264 2265 2266 2267 2268 | vwait x close $sock } -cleanup { catch {close $sock} unset x } -result {socket is not connected} -returnCodes 1 test socket-14.11.1 {pending [socket -async] and nonblocking [puts], no listener, flush} \ | | > > > > > | 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 | vwait x close $sock } -cleanup { catch {close $sock} unset x } -result {socket is not connected} -returnCodes 1 test socket-14.11.1 {pending [socket -async] and nonblocking [puts], no listener, flush} \ -constraints {socket testsocket_testflags} \ -body { set sock [socket -async localhost [randport]] # Set the socket in async test mode. # The async connect will not be continued on the following fconfigure # and puts/flush. Thus, the connect will fail after them. testsocket testflags $sock 1 fconfigure $sock -blocking 0 puts $sock ok flush $sock testsocket testflags $sock 0 fileevent $sock writable {set x 1} vwait x close $sock } -cleanup { catch {close $sock} catch {unset x} } -result {socket is not connected} -returnCodes 1 |
︙ | ︙ |
Changes to tests/util.test.
︙ | ︙ | |||
4023 4024 4025 4026 4027 4028 4029 | } {9223372036854775807} test util-18.2 {Tcl_ObjPrintf} {testprint} { testprint %I64d [expr 2**63-1] } {9223372036854775807} test util-18.3 {Tcl_ObjPrintf} {testprint} { | | | | | > > > > | > > > > > > > > > > > > > > > > > > > > | 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 | } {9223372036854775807} test util-18.2 {Tcl_ObjPrintf} {testprint} { testprint %I64d [expr 2**63-1] } {9223372036854775807} test util-18.3 {Tcl_ObjPrintf} {testprint} { testprint %qd [expr 2**63-1] } {9223372036854775807} test util-18.4 {Tcl_ObjPrintf} {testprint} { testprint %jd [expr 2**63-1] } {9223372036854775807} test util-18.5 {Tcl_ObjPrintf} {testprint} { testprint %lld [expr -2**63] } {-9223372036854775808} test util-18.6 {Tcl_ObjPrintf} {testprint} { testprint %I64d [expr -2**63] } {-9223372036854775808} test util-18.7 {Tcl_ObjPrintf} {testprint} { testprint %qd [expr -2**63] } {-9223372036854775808} test util-18.8 {Tcl_ObjPrintf} {testprint} { testprint %jd [expr -2**63] } {-9223372036854775808} test util-18.9 {Tcl_ObjPrintf} {testprint} { testprint "%I64d %I32d" [expr -2**63+2] } {-9223372036854775806 2} test util-18.10 {Tcl_ObjPrintf} {testprint} { testprint "%I64d %p" 65535 } {65535 0xffff} test util-18.11 {Tcl_ObjPrintf} {testprint} { testprint "%I64d %td" 65536 } {65536 65536} test util-18.12 {Tcl_ObjPrintf} {testprint} { testprint "%I64d %Id" 65537 } {65537 65537} set ::tcl_precision $saved_precision # cleanup ::tcltest::cleanupTests return |
︙ | ︙ |
Changes to tests/zlib.test.
︙ | ︙ | |||
326 327 328 329 330 331 332 | catch {close $inSide} } -result {260 222 {need dictionary} {TCL ZLIB NEED_DICT 2381337010} 2381337010} test zlib-8.9 {transformation and fconfigure} -setup { lassign [chan pipe] inSide outSide set strm [zlib stream decompress] } -constraints zlib -body { zlib push compress $outSide -dictionary $spdyDict | | | | 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 | catch {close $inSide} } -result {260 222 {need dictionary} {TCL ZLIB NEED_DICT 2381337010} 2381337010} test zlib-8.9 {transformation and fconfigure} -setup { lassign [chan pipe] inSide outSide set strm [zlib stream decompress] } -constraints zlib -body { zlib push compress $outSide -dictionary $spdyDict fconfigure $outSide -blocking 1 -translation binary -buffering none fconfigure $inSide -blocking 1 -translation binary puts -nonewline $outSide $spdyHeaders set result [fconfigure $outSide -checksum] chan pop $outSide chan close $outSide $strm put -dictionary $spdyDict [read $inSide] lappend result [string length $spdyHeaders] [string length [$strm get]] } -cleanup { catch {close $outSide} catch {close $inSide} catch {$strm close} } -result {3064818174 358 358} test zlib-8.10 {transformation and fconfigure} -setup { lassign [chan pipe] inSide outSide } -constraints {zlib recentZlib} -body { zlib push deflate $outSide -dictionary $spdyDict fconfigure $outSide -blocking 1 -translation binary -buffering none fconfigure $inSide -blocking 1 -translation binary puts -nonewline $outSide $spdyHeaders chan pop $outSide chan close $outSide set compressed [read $inSide] catch { zlib inflate $compressed |
︙ | ︙ | |||
365 366 367 368 369 370 371 | catch {close $inSide} } -result {254 212 {data error} {TCL ZLIB DATA}} test zlib-8.11 {transformation and fconfigure} -setup { lassign [chan pipe] inSide outSide set strm [zlib stream inflate] } -constraints zlib -body { zlib push deflate $outSide -dictionary $spdyDict | | | | | | | 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 | catch {close $inSide} } -result {254 212 {data error} {TCL ZLIB DATA}} test zlib-8.11 {transformation and fconfigure} -setup { lassign [chan pipe] inSide outSide set strm [zlib stream inflate] } -constraints zlib -body { zlib push deflate $outSide -dictionary $spdyDict fconfigure $outSide -blocking 1 -translation binary -buffering none fconfigure $inSide -blocking 1 -translation binary puts -nonewline $outSide $spdyHeaders chan pop $outSide chan close $outSide $strm put -dictionary $spdyDict [read $inSide] list [string length $spdyHeaders] [string length [$strm get]] } -cleanup { catch {close $outSide} catch {close $inSide} catch {$strm close} } -result {358 358} test zlib-8.12 {transformation and fconfigure} -setup { lassign [chan pipe] inSide outSide set strm [zlib stream compress] } -constraints zlib -body { $strm put -dictionary $spdyDict -finalize $spdyHeaders zlib push decompress $inSide fconfigure $outSide -blocking 1 -translation binary fconfigure $inSide -translation binary -dictionary $spdyDict puts -nonewline $outSide [$strm get] close $outSide list [string length $spdyHeaders] [string length [read $inSide]] \ [fconfigure $inSide -checksum] } -cleanup { catch {close $outSide} catch {close $inSide} catch {$strm close} } -result {358 358 3064818174} test zlib-8.13 {transformation and fconfigure} -setup { lassign [chan pipe] inSide outSide set strm [zlib stream compress] } -constraints zlib -body { $strm put -dictionary $spdyDict -finalize $spdyHeaders zlib push decompress $inSide -dictionary $spdyDict fconfigure $outSide -blocking 1 -translation binary fconfigure $inSide -translation binary puts -nonewline $outSide [$strm get] close $outSide list [string length $spdyHeaders] [string length [read $inSide]] \ [fconfigure $inSide -checksum] } -cleanup { catch {close $outSide} catch {close $inSide} catch {$strm close} } -result {358 358 3064818174} test zlib-8.14 {transformation and fconfigure} -setup { lassign [chan pipe] inSide outSide set strm [zlib stream deflate] } -constraints zlib -body { $strm put -finalize -dictionary $spdyDict $spdyHeaders zlib push inflate $inSide fconfigure $outSide -blocking 1 -buffering none -translation binary fconfigure $inSide -translation binary -dictionary $spdyDict puts -nonewline $outSide [$strm get] close $outSide list [string length $spdyHeaders] [string length [read $inSide]] } -cleanup { catch {close $outSide} catch {close $inSide} catch {$strm close} } -result {358 358} test zlib-8.15 {transformation and fconfigure} -setup { lassign [chan pipe] inSide outSide set strm [zlib stream deflate] } -constraints zlib -body { $strm put -finalize -dictionary $spdyDict $spdyHeaders zlib push inflate $inSide -dictionary $spdyDict fconfigure $outSide -blocking 1 -buffering none -translation binary fconfigure $inSide -translation binary puts -nonewline $outSide [$strm get] close $outSide list [string length $spdyHeaders] [string length [read $inSide]] } -cleanup { catch {close $outSide} catch {close $inSide} |
︙ | ︙ |
Changes to tools/loadICU.tcl.
︙ | ︙ | |||
22 23 24 25 26 27 28 29 30 31 32 33 34 35 | # #---------------------------------------------------------------------- # # Copyright (c) 2004 by Kevin B. Kenny. All rights reserved. # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. #---------------------------------------------------------------------- # Calculate the Chinese numerals from zero to ninety-nine. set zhDigits [list {} \u4e00 \u4e8c \u4e09 \u56db \ \u4e94 \u516d \u4e03 \u516b \u4e5d] set t 0 foreach zt $zhDigits { | > > > | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | # #---------------------------------------------------------------------- # # Copyright (c) 2004 by Kevin B. Kenny. All rights reserved. # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. #---------------------------------------------------------------------- puts stdout "TODO: output in UTF-8 in stead of using \\uhhhh sequences" exit; # Remove those two lines after modifying this tool. # Calculate the Chinese numerals from zero to ninety-nine. set zhDigits [list {} \u4e00 \u4e8c \u4e09 \u56db \ \u4e94 \u516d \u4e03 \u516b \u4e5d] set t 0 foreach zt $zhDigits { |
︙ | ︙ |
Changes to tools/tcltk-man2html.tcl.
1 2 3 4 5 6 | #!/usr/bin/env tclsh if {[catch {package require Tcl 8.6-} msg]} { puts stderr "ERROR: $msg" puts stderr "If running this script from 'make html', set the\ NATIVE_TCLSH environment\nvariable to point to an installed\ | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #!/usr/bin/env tclsh if {[catch {package require Tcl 8.6-} msg]} { puts stderr "ERROR: $msg" puts stderr "If running this script from 'make html', set the\ NATIVE_TCLSH environment\nvariable to point to an installed\ tclsh8.7 (or the equivalent tclsh87.exe\non Windows)." exit 1 } # Convert Ousterhout format man pages into highly crosslinked hypertext. # # Along the way detect many unmatched font changes and other odd things. # # Note well, this program is a hack rather than a piece of software # engineering. In that sense it's probably a good example of things # that a scripting language, like Tcl, can do well. It is offered as # an example of how someone might convert a specific set of man pages # into hypertext, not as a general solution to the problem. If you # try to use this, you'll be very much on your own. # # Copyright (c) 1995-1997 Roger E. Critchlow Jr # Copyright (c) 2004-2010 Donal K. Fellows set ::Version "50/8.7" set ::CSSFILE "docs.css" ## ## Source the utility functions that provide most of the ## implementation of the transformation from nroff to html. ## source [file join [file dirname [info script]] tcltk-man2html-utils.tcl] |
︙ | ︙ |
Changes to unix/tclUnixSock.c.
︙ | ︙ | |||
15 16 17 18 19 20 21 22 23 24 25 26 27 28 | * Helper macros to make parts of this file clearer. The macros do exactly * what they say on the tin. :-) They also only ever refer to their arguments * once, and so can be used without regard to side effects. */ #define SET_BITS(var, bits) ((var) |= (bits)) #define CLEAR_BITS(var, bits) ((var) &= ~(bits)) /* "sock" + a pointer in hex + \0 */ #define SOCK_CHAN_LENGTH (4 + sizeof(void *) * 2 + 1) #define SOCK_TEMPLATE "sock%lx" #undef SOCKET /* Possible conflict with win32 SOCKET */ | > | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | * Helper macros to make parts of this file clearer. The macros do exactly * what they say on the tin. :-) They also only ever refer to their arguments * once, and so can be used without regard to side effects. */ #define SET_BITS(var, bits) ((var) |= (bits)) #define CLEAR_BITS(var, bits) ((var) &= ~(bits)) #define GOT_BITS(var, bits) (((var) & (bits)) != 0) /* "sock" + a pointer in hex + \0 */ #define SOCK_CHAN_LENGTH (4 + sizeof(void *) * 2 + 1) #define SOCK_TEMPLATE "sock%lx" #undef SOCKET /* Possible conflict with win32 SOCKET */ |
︙ | ︙ | |||
48 49 50 51 52 53 54 55 56 57 58 59 60 61 | TcpState *statePtr; int fd; struct TcpFdList *next; } TcpFdList; struct TcpState { Tcl_Channel channel; /* Channel associated with this file. */ TcpFdList fds; /* The file descriptors of the sockets. */ int flags; /* ORed combination of the bitfields defined * below. */ int interest; /* Event types of interest */ /* * Only needed for server sockets | > > | 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | TcpState *statePtr; int fd; struct TcpFdList *next; } TcpFdList; struct TcpState { Tcl_Channel channel; /* Channel associated with this file. */ int testFlags; /* bit field for tests. Is set by testsocket * test procedure */ TcpFdList fds; /* The file descriptors of the sockets. */ int flags; /* ORed combination of the bitfields defined * below. */ int interest; /* Event types of interest */ /* * Only needed for server sockets |
︙ | ︙ | |||
88 89 90 91 92 93 94 95 96 97 98 99 100 101 | #define TCP_ASYNC_CONNECT (1<<1) /* Async connect in progress. */ #define TCP_ASYNC_PENDING (1<<4) /* TcpConnect was called to * process an async connect. This * flag indicates that reentry is * still pending */ #define TCP_ASYNC_FAILED (1<<5) /* An async connect finally failed */ /* * The following defines the maximum length of the listen queue. This is the * number of outstanding yet-to-be-serviced requests for a connection on a * server socket, more than this number of outstanding requests and the * connection request will fail. */ | > > > > > > > > > | 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | #define TCP_ASYNC_CONNECT (1<<1) /* Async connect in progress. */ #define TCP_ASYNC_PENDING (1<<4) /* TcpConnect was called to * process an async connect. This * flag indicates that reentry is * still pending */ #define TCP_ASYNC_FAILED (1<<5) /* An async connect finally failed */ /* * These bits may be ORed together into the "testFlags" field of a TcpState * structure. */ #define TCP_ASYNC_TEST_MODE (1<<0) /* Async testing activated. Do not * automatically continue connection * process. */ /* * The following defines the maximum length of the listen queue. This is the * number of outstanding yet-to-be-serviced requests for a connection on a * server socket, more than this number of outstanding requests and the * connection request will fail. */ |
︙ | ︙ | |||
113 114 115 116 117 118 119 | #define SOCKET_BUFSIZE 4096 /* * Static routines for this file: */ | | < | 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | #define SOCKET_BUFSIZE 4096 /* * Static routines for this file: */ static int TcpConnect(Tcl_Interp *interp, TcpState *state); static void TcpAccept(ClientData data, int mask); static int TcpBlockModeProc(ClientData data, int mode); static int TcpCloseProc(ClientData instanceData, Tcl_Interp *interp); static int TcpClose2Proc(ClientData instanceData, Tcl_Interp *interp, int flags); static int TcpGetHandleProc(ClientData instanceData, |
︙ | ︙ | |||
169 170 171 172 173 174 175 | static TclInitProcessGlobalValueProc InitializeHostName; static ProcessGlobalValue hostName = {0, 0, NULL, NULL, InitializeHostName, NULL, NULL}; #if 0 /* printf debugging */ | > > | > > | < | | | | 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | static TclInitProcessGlobalValueProc InitializeHostName; static ProcessGlobalValue hostName = {0, 0, NULL, NULL, InitializeHostName, NULL, NULL}; #if 0 /* printf debugging */ void printaddrinfo( struct addrinfo *addrlist, char *prefix) { char host[NI_MAXHOST], port[NI_MAXSERV]; struct addrinfo *ai; for (ai = addrlist; ai != NULL; ai = ai->ai_next) { getnameinfo(ai->ai_addr, ai->ai_addrlen, host, sizeof(host), port, sizeof(port), NI_NUMERICHOST|NI_NUMERICSERV); fprintf(stderr,"%s: %s:%s\n", prefix, host, port); } } #endif /* * ---------------------------------------------------------------------- * * InitializeHostName -- * * This routine sets the process global value of the name of the local * host on which the process is running. * * Results: * None. * * ---------------------------------------------------------------------- */ static void InitializeHostName( char **valuePtr, size_t *lengthPtr, Tcl_Encoding *encodingPtr) |
︙ | ︙ | |||
272 273 274 275 276 277 278 | *encodingPtr = Tcl_GetEncoding(NULL, NULL); *lengthPtr = strlen(native); *valuePtr = ckalloc(*lengthPtr + 1); memcpy(*valuePtr, native, *lengthPtr + 1); } /* | | | | | | | | | | | | | | | | | | < | | | | | | | | | | > > > > > > > > > > > > > > | | > > | | > | | | 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 | *encodingPtr = Tcl_GetEncoding(NULL, NULL); *lengthPtr = strlen(native); *valuePtr = ckalloc(*lengthPtr + 1); memcpy(*valuePtr, native, *lengthPtr + 1); } /* * ---------------------------------------------------------------------- * * Tcl_GetHostName -- * * Returns the name of the local host. * * Results: * A string containing the network name for this machine, or an empty * string if we can't figure out the name. The caller must not modify or * free this string. * * Side effects: * Caches the name to return for future calls. * * ---------------------------------------------------------------------- */ const char * Tcl_GetHostName(void) { return Tcl_GetString(TclGetProcessGlobalValue(&hostName)); } /* * ---------------------------------------------------------------------- * * TclpHasSockets -- * * Detect if sockets are available on this platform. * * Results: * Returns TCL_OK. * * Side effects: * None. * * ---------------------------------------------------------------------- */ int TclpHasSockets( Tcl_Interp *interp) /* Not used. */ { return TCL_OK; } /* * ---------------------------------------------------------------------- * * TclpFinalizeSockets -- * * Performs per-thread socket subsystem finalization. * * Results: * None. * * Side effects: * None. * * ---------------------------------------------------------------------- */ void TclpFinalizeSockets(void) { return; } /* * ---------------------------------------------------------------------- * * TcpBlockModeProc -- * * This function is invoked by the generic IO level to set blocking and * nonblocking mode on a TCP socket based channel. * * Results: * 0 if successful, errno when failed. * * Side effects: * Sets the device into blocking or nonblocking mode. * * ---------------------------------------------------------------------- */ /* ARGSUSED */ static int TcpBlockModeProc( ClientData instanceData, /* Socket state. */ int mode) /* The mode to set. Can be one of * TCL_MODE_BLOCKING or * TCL_MODE_NONBLOCKING. */ { TcpState *statePtr = instanceData; if (mode == TCL_MODE_BLOCKING) { CLEAR_BITS(statePtr->flags, TCP_NONBLOCKING); } else { SET_BITS(statePtr->flags, TCP_NONBLOCKING); } if (GOT_BITS(statePtr->flags, TCP_ASYNC_CONNECT)) { statePtr->cachedBlocking = mode; return 0; } if (TclUnixSetBlockingMode(statePtr->fds.fd, mode) < 0) { return errno; } return 0; } /* * ---------------------------------------------------------------------- * * WaitForConnect -- * * Check the state of an async connect process. If a connection attempt * terminated, process it, which may finalize it or may start the next * attempt. If a connect error occures, it is saved in * statePtr->connectError to be reported by 'fconfigure -error'. * * There are two modes of operation, defined by errorCodePtr: * * non-NULL: Called by explicite read/write command. Blocks if the * socket is blocking. * May return two error codes: * * EWOULDBLOCK: if connect is still in progress * * ENOTCONN: if connect failed. This would be the error message * of a rect or sendto syscall so this is emulated here. * * NULL: Called by a backround operation. Do not block and do not * return any error code. * * Results: * 0 if the connection has completed, -1 if still in progress or there is * an error. * * Side effects: * Processes socket events off the system queue. May process * asynchroneous connects. * *---------------------------------------------------------------------- */ static int WaitForConnect( TcpState *statePtr, /* State of the socket. */ int *errorCodePtr) { int timeout; /* * Check if an async connect failed already and error reporting is * demanded, return the error ENOTCONN */ if (errorCodePtr != NULL && GOT_BITS(statePtr->flags, TCP_ASYNC_FAILED)) { *errorCodePtr = ENOTCONN; return -1; } /* * Check if an async connect is running. If not return ok */ if (!GOT_BITS(statePtr->flags, TCP_ASYNC_PENDING)) { return 0; } /* * In socket test mode do not continue with the connect. * Exceptions are: * - Call by recv/send and blocking socket * (errorCodePtr != NULL && !GOT_BITS(flags, TCP_NONBLOCKING)) */ if (GOT_BITS(statePtr->testFlags, TCP_ASYNC_TEST_MODE) && !(errorCodePtr != NULL && !GOT_BITS(statePtr->flags, TCP_NONBLOCKING))) { *errorCodePtr = EWOULDBLOCK; return -1; } if (errorCodePtr == NULL || GOT_BITS(statePtr->flags, TCP_NONBLOCKING)) { timeout = 0; } else { timeout = -1; } do { if (TclUnixWaitForFile(statePtr->fds.fd, TCL_WRITABLE | TCL_EXCEPTION, timeout) != 0) { TcpConnect(NULL, statePtr); } /* * Do this only once in the nonblocking case and repeat it until the * socket is final when blocking. */ } while (timeout == -1 && GOT_BITS(statePtr->flags, TCP_ASYNC_CONNECT)); if (errorCodePtr != NULL) { if (GOT_BITS(statePtr->flags, TCP_ASYNC_PENDING)) { *errorCodePtr = EAGAIN; return -1; } else if (statePtr->connectError != 0) { *errorCodePtr = ENOTCONN; return -1; } } |
︙ | ︙ | |||
611 612 613 614 615 616 617 618 619 620 621 622 623 624 | errorCode = errno; } } fds = statePtr->fds.next; while (fds != NULL) { TcpFdList *next = fds->next; ckfree(fds); fds = next; } if (statePtr->addrlist != NULL) { freeaddrinfo(statePtr->addrlist); } if (statePtr->myaddrlist != NULL) { | > | 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 | errorCode = errno; } } fds = statePtr->fds.next; while (fds != NULL) { TcpFdList *next = fds->next; ckfree(fds); fds = next; } if (statePtr->addrlist != NULL) { freeaddrinfo(statePtr->addrlist); } if (statePtr->myaddrlist != NULL) { |
︙ | ︙ | |||
681 682 683 684 685 686 687 | } /* *---------------------------------------------------------------------- * * TcpHostPortList -- * | | | | < | < | > | | > | < > > | > > > | | > > | > > > | > > | 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 | } /* *---------------------------------------------------------------------- * * TcpHostPortList -- * * This function is called by the -gethostname and -getpeername switches * of TcpGetOptionProc() to add three list elements with the textual * representation of the given address to the given DString. * * Results: * None. * * Side effects: * Adds three elements do dsPtr * *---------------------------------------------------------------------- */ static void TcpHostPortList( Tcl_Interp *interp, Tcl_DString *dsPtr, address addr, socklen_t salen) { #define SUPPRESS_RDNS_VAR "::tcl::unsupported::noReverseDNS" char host[NI_MAXHOST], nhost[NI_MAXHOST], nport[NI_MAXSERV]; int flags = 0; getnameinfo(&addr.sa, salen, nhost, sizeof(nhost), nport, sizeof(nport), NI_NUMERICHOST | NI_NUMERICSERV); Tcl_DStringAppendElement(dsPtr, nhost); /* * We don't want to resolve INADDR_ANY and sin6addr_any; they can * sometimes cause problems (and never have a name). */ if (addr.sa.sa_family == AF_INET) { if (addr.sa4.sin_addr.s_addr == INADDR_ANY) { flags |= NI_NUMERICHOST; } #ifndef NEED_FAKE_RFC2553 } else if (addr.sa.sa_family == AF_INET6) { if ((IN6_ARE_ADDR_EQUAL(&addr.sa6.sin6_addr, &in6addr_any)) || (IN6_IS_ADDR_V4MAPPED(&addr.sa6.sin6_addr) && addr.sa6.sin6_addr.s6_addr[12] == 0 && addr.sa6.sin6_addr.s6_addr[13] == 0 && addr.sa6.sin6_addr.s6_addr[14] == 0 && addr.sa6.sin6_addr.s6_addr[15] == 0)) { flags |= NI_NUMERICHOST; } #endif /* NEED_FAKE_RFC2553 */ } /* * Check if reverse DNS has been switched off globally. */ if (interp != NULL && Tcl_GetVar2(interp, SUPPRESS_RDNS_VAR, NULL, 0) != NULL) { flags |= NI_NUMERICHOST; } if (getnameinfo(&addr.sa, salen, host, sizeof(host), NULL, 0, flags) == 0) { /* * Reverse mapping worked. */ Tcl_DStringAppendElement(dsPtr, host); } else { /* * Reverse mapping failed - use the numeric rep once more. */ Tcl_DStringAppendElement(dsPtr, nhost); } Tcl_DStringAppendElement(dsPtr, nport); } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
788 789 790 791 792 793 794 | len = strlen(optionName); } if ((len > 1) && (optionName[1] == 'e') && (strncmp(optionName, "-error", len) == 0)) { socklen_t optlen = sizeof(int); | | > | > > > | | < | | > > | 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 | len = strlen(optionName); } if ((len > 1) && (optionName[1] == 'e') && (strncmp(optionName, "-error", len) == 0)) { socklen_t optlen = sizeof(int); if (GOT_BITS(statePtr->flags, TCP_ASYNC_CONNECT)) { /* * Suppress errors as long as we are not done. */ errno = 0; } else if (statePtr->connectError != 0) { errno = statePtr->connectError; statePtr->connectError = 0; } else { int err; getsockopt(statePtr->fds.fd, SOL_SOCKET, SO_ERROR, (char *) &err, &optlen); errno = err; } if (errno != 0) { Tcl_DStringAppend(dsPtr, Tcl_ErrnoMsg(errno), -1); } return TCL_OK; } if ((len > 1) && (optionName[1] == 'c') && (strncmp(optionName, "-connecting", len) == 0)) { Tcl_DStringAppend(dsPtr, GOT_BITS(statePtr->flags, TCP_ASYNC_CONNECT) ? "1" : "0", -1); return TCL_OK; } if ((len == 0) || ((len > 1) && (optionName[1] == 'p') && (strncmp(optionName, "-peername", len) == 0))) { address peername; socklen_t size = sizeof(peername); if (GOT_BITS(statePtr->flags, TCP_ASYNC_CONNECT)) { /* * In async connect output an empty string */ if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-peername"); Tcl_DStringAppendElement(dsPtr, ""); } else { return TCL_OK; } } else if (getpeername(statePtr->fds.fd, &peername.sa, &size) >= 0) { /* * Peername fetch succeeded - output list */ if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-peername"); Tcl_DStringStartSublist(dsPtr); } TcpHostPortList(interp, dsPtr, peername, size); if (len) { return TCL_OK; |
︙ | ︙ | |||
872 873 874 875 876 877 878 | socklen_t size; int found = 0; if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-sockname"); Tcl_DStringStartSublist(dsPtr); } | | > | | 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 | socklen_t size; int found = 0; if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-sockname"); Tcl_DStringStartSublist(dsPtr); } if (GOT_BITS(statePtr->flags, TCP_ASYNC_CONNECT)) { /* * In async connect output an empty string */ found = 1; } else { for (fds = &statePtr->fds; fds != NULL; fds = fds->next) { size = sizeof(sockname); if (getsockname(fds->fd, &(sockname.sa), &size) >= 0) { found = 1; TcpHostPortList(interp, dsPtr, sockname, size); } |
︙ | ︙ | |||
901 902 903 904 905 906 907 | "can't get sockname: %s", Tcl_PosixError(interp))); } return TCL_ERROR; } } if (len > 0) { | | > | | | | | | < | | | | > | 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 | "can't get sockname: %s", Tcl_PosixError(interp))); } return TCL_ERROR; } } if (len > 0) { return Tcl_BadChannelOption(interp, optionName, "connecting peername sockname"); } return TCL_OK; } /* * ---------------------------------------------------------------------- * * TcpWatchProc -- * * Initialize the notifier to watch the fd from this channel. * * Results: * None. * * Side effects: * Sets up the notifier so that a future event on the channel will be * seen by Tcl. * * ---------------------------------------------------------------------- */ static void WrapNotify( ClientData clientData, int mask) { TcpState *statePtr = (TcpState *) clientData; int newmask = mask & statePtr->interest; if (newmask == 0) { /* * There was no overlap between the states the channel is interested * in notifications for, and the states that are reported present on * the file descriptor by select(). The only way that can happen is * when the channel is interested in a writable condition, and only a * readable state is reported present (see TcpWatchProc() below). In * that case, signal back to the caller the writable state, which is * really an error condition. As an extra check on that assumption, * check for a non-zero value of errno before reporting an artificial * writable state. */ if (errno == 0) { return; } newmask = TCL_WRITABLE; } Tcl_NotifyChannel(statePtr->channel, newmask); } |
︙ | ︙ | |||
968 969 970 971 972 973 974 975 976 977 | if (statePtr->acceptProc != NULL) { /* * Make sure we don't mess with server sockets since they will never * be readable or writable at the Tcl level. This keeps Tcl scripts * from interfering with the -accept behavior (bug #3394732). */ return; } | > | > | | > > | | | | < | | | | | | < | | | > | | | | | | | > | | 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 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 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 | if (statePtr->acceptProc != NULL) { /* * Make sure we don't mess with server sockets since they will never * be readable or writable at the Tcl level. This keeps Tcl scripts * from interfering with the -accept behavior (bug #3394732). */ return; } if (GOT_BITS(statePtr->flags, TCP_ASYNC_PENDING)) { /* * Async sockets use a FileHandler internally while connecting, so we * need to cache this request until the connection has succeeded. */ statePtr->filehandlers = mask; } else if (mask) { /* * Whether it is a bug or feature or otherwise, it is a fact of life * that on at least some Linux kernels select() fails to report that a * socket file descriptor is writable when the other end of the socket * is closed. This is in contrast to the guarantees Tcl makes that * its channels become writable and fire writable events on an error * conditon. This has caused a leak of file descriptors in a state of * background flushing. See Tcl ticket 1758a0b603. * * As a workaround, when our caller indicates an interest in writable * notifications, we must tell the notifier built around select() that * we are interested in the readable state of the file descriptor as * well, as that is the only reliable means to get notified of error * conditions. Then it is the task of WrapNotify() above to untangle * the meaning of these channel states and report the chan events as * best it can. We save a copy of the mask passed in to assist with * that. */ statePtr->interest = mask; Tcl_CreateFileHandler(statePtr->fds.fd, mask|TCL_READABLE, (Tcl_FileProc *) WrapNotify, statePtr); } else { Tcl_DeleteFileHandler(statePtr->fds.fd); } } /* * ---------------------------------------------------------------------- * * TcpGetHandleProc -- * * Called from Tcl_GetChannelHandle to retrieve OS handles from inside a * TCP socket based channel. * * Results: * Returns TCL_OK with the fd in handlePtr, or TCL_ERROR if there is no * handle for the specified direction. * * Side effects: * None. * * ---------------------------------------------------------------------- */ /* ARGSUSED */ static int TcpGetHandleProc( ClientData instanceData, /* The socket state. */ int direction, /* Not used. */ ClientData *handlePtr) /* Where to store the handle. */ { TcpState *statePtr = instanceData; *handlePtr = INT2PTR(statePtr->fds.fd); return TCL_OK; } /* * ---------------------------------------------------------------------- * * TcpAsyncCallback -- * * Called by the event handler that TcpConnect sets up internally for * [socket -async] to get notified when the asyncronous connection * attempt has succeeded or failed. * * ---------------------------------------------------------------------- */ static void TcpAsyncCallback( ClientData clientData, /* The socket state. */ int mask) /* Events of interest; an OR-ed combination of * TCL_READABLE, TCL_WRITABLE and * TCL_EXCEPTION. */ { TcpConnect(NULL, clientData); } /* * ---------------------------------------------------------------------- * * TcpConnect -- * * This function opens a new socket in client mode. * * Results: * TCL_OK, if the socket was successfully connected or an asynchronous |
︙ | ︙ | |||
1084 1085 1086 1087 1088 1089 1090 | * two nested loops over the local and remote addresses. Once the first * connection attempt is in progress, it sets up itself as a writable * event handler for that socket, and returns. When the callback occurs, * control is transferred to the "reenter" label, right after the initial * return and the loops resume as if they had never been interrupted. * For syncronously connecting sockets, the loops work the usual way. * | | | | < | > | 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 | * two nested loops over the local and remote addresses. Once the first * connection attempt is in progress, it sets up itself as a writable * event handler for that socket, and returns. When the callback occurs, * control is transferred to the "reenter" label, right after the initial * return and the loops resume as if they had never been interrupted. * For syncronously connecting sockets, the loops work the usual way. * * ---------------------------------------------------------------------- */ static int TcpConnect( Tcl_Interp *interp, /* For error reporting; can be NULL. */ TcpState *statePtr) { socklen_t optlen; int async_callback = GOT_BITS(statePtr->flags, TCP_ASYNC_PENDING); int ret = -1, error = EHOSTUNREACH; int async = GOT_BITS(statePtr->flags, TCP_ASYNC_CONNECT); if (async_callback) { goto reenter; } for (statePtr->addr = statePtr->addrlist; statePtr->addr != NULL; statePtr->addr = statePtr->addr->ai_next) { for (statePtr->myaddr = statePtr->myaddrlist; statePtr->myaddr != NULL; statePtr->myaddr = statePtr->myaddr->ai_next) { int reuseaddr = 1; /* * No need to try combinations of local and remote addresses of * different families. */ |
︙ | ︙ | |||
1128 1129 1130 1131 1132 1133 1134 | if (statePtr->fds.fd >= 0) { close(statePtr->fds.fd); statePtr->fds.fd = -1; errno = 0; } | | > | > > | | > > | > > | > | 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 | if (statePtr->fds.fd >= 0) { close(statePtr->fds.fd); statePtr->fds.fd = -1; errno = 0; } statePtr->fds.fd = socket(statePtr->addr->ai_family, SOCK_STREAM, 0); if (statePtr->fds.fd < 0) { continue; } /* * Set the close-on-exec flag so that the socket will not get * inherited by child processes. */ fcntl(statePtr->fds.fd, F_SETFD, FD_CLOEXEC); /* * Set kernel space buffering */ TclSockMinimumBuffers(INT2PTR(statePtr->fds.fd), SOCKET_BUFSIZE); if (async) { ret = TclUnixSetBlockingMode(statePtr->fds.fd, TCL_MODE_NONBLOCKING); if (ret < 0) { continue; } } /* * Must reset the error variable here, before we use it for the * first time in this iteration. */ error = 0; (void) setsockopt(statePtr->fds.fd, SOL_SOCKET, SO_REUSEADDR, (char *) &reuseaddr, sizeof(reuseaddr)); ret = bind(statePtr->fds.fd, statePtr->myaddr->ai_addr, statePtr->myaddr->ai_addrlen); if (ret < 0) { error = errno; continue; } /* * Attempt to connect. The connect may fail at present with an * EINPROGRESS but at a later time it will complete. The caller * will set up a file handler on the socket if she is interested * in being informed when the connect completes. */ ret = connect(statePtr->fds.fd, statePtr->addr->ai_addr, statePtr->addr->ai_addrlen); if (ret < 0) { error = errno; } if (ret < 0 && errno == EINPROGRESS) { Tcl_CreateFileHandler(statePtr->fds.fd, TCL_WRITABLE | TCL_EXCEPTION, TcpAsyncCallback, statePtr); errno = EWOULDBLOCK; SET_BITS(statePtr->flags, TCP_ASYNC_PENDING); return TCL_OK; reenter: CLEAR_BITS(statePtr->flags, TCP_ASYNC_PENDING); Tcl_DeleteFileHandler(statePtr->fds.fd); |
︙ | ︙ | |||
1206 1207 1208 1209 1210 1211 1212 | } if (error == 0) { goto out; } } } | | | 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 | } if (error == 0) { goto out; } } } out: statePtr->connectError = error; CLEAR_BITS(statePtr->flags, TCP_ASYNC_CONNECT); if (async_callback) { /* * An asynchonous connection has finally succeeded or failed. */ |
︙ | ︙ | |||
1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 | } return NULL; } /* * Allocate a new TcpState for this socket. */ statePtr = ckalloc(sizeof(TcpState)); memset(statePtr, 0, sizeof(TcpState)); statePtr->flags = async ? TCP_ASYNC_CONNECT : 0; statePtr->cachedBlocking = TCL_MODE_BLOCKING; statePtr->addrlist = addrlist; statePtr->myaddrlist = myaddrlist; statePtr->fds.fd = -1; /* * Create a new client socket and wrap it in a channel. */ if (TcpConnect(interp, statePtr) != TCL_OK) { TcpCloseProc(statePtr, NULL); return NULL; } sprintf(channelName, SOCK_TEMPLATE, (long) statePtr); | > > | | | 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 | } return NULL; } /* * Allocate a new TcpState for this socket. */ statePtr = ckalloc(sizeof(TcpState)); memset(statePtr, 0, sizeof(TcpState)); statePtr->flags = async ? TCP_ASYNC_CONNECT : 0; statePtr->cachedBlocking = TCL_MODE_BLOCKING; statePtr->addrlist = addrlist; statePtr->myaddrlist = myaddrlist; statePtr->fds.fd = -1; /* * Create a new client socket and wrap it in a channel. */ if (TcpConnect(interp, statePtr) != TCL_OK) { TcpCloseProc(statePtr, NULL); return NULL; } sprintf(channelName, SOCK_TEMPLATE, (long) statePtr); statePtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName, statePtr, TCL_READABLE | TCL_WRITABLE); if (Tcl_SetChannelOption(interp, statePtr->channel, "-translation", "auto crlf") == TCL_ERROR) { Tcl_Close(NULL, statePtr->channel); return NULL; } return statePtr->channel; } |
︙ | ︙ | |||
1352 1353 1354 1355 1356 1357 1358 | *---------------------------------------------------------------------- */ Tcl_Channel Tcl_MakeTcpClientChannel( ClientData sock) /* The socket to wrap up into a channel. */ { | | > | 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 | *---------------------------------------------------------------------- */ Tcl_Channel Tcl_MakeTcpClientChannel( ClientData sock) /* The socket to wrap up into a channel. */ { return (Tcl_Channel) TclpMakeTcpClientChannelMode(sock, TCL_READABLE | TCL_WRITABLE); } /* *---------------------------------------------------------------------- * * TclpMakeTcpClientChannelMode -- * |
︙ | ︙ | |||
1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 | * might fail to bind() with EADDRINUSE if a port is free on the first * address family in the list but already used on the other. In this case * we revert everything we've done so far and start from scratch hoping * that next time we'll find a port number that is usable on all address * families. We try this at most MAXRETRY times to avoid an endless loop * if all ports are taken. */ int retry = 0; #define MAXRETRY 10 repeat: if (retry > 0) { if (statePtr != NULL) { TcpCloseProc(statePtr, NULL); | > | 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 | * might fail to bind() with EADDRINUSE if a port is free on the first * address family in the list but already used on the other. In this case * we revert everything we've done so far and start from scratch hoping * that next time we'll find a port number that is usable on all address * families. We try this at most MAXRETRY times to avoid an endless loop * if all ports are taken. */ int retry = 0; #define MAXRETRY 10 repeat: if (retry > 0) { if (statePtr != NULL) { TcpCloseProc(statePtr, NULL); |
︙ | ︙ | |||
1477 1478 1479 1480 1481 1482 1483 | chosenport = 0; if (TclSockGetPort(interp, service, "tcp", &port) != TCL_OK) { errorMsg = "invalid port number"; goto error; } | | > | 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 | chosenport = 0; if (TclSockGetPort(interp, service, "tcp", &port) != TCL_OK) { errorMsg = "invalid port number"; goto error; } if (!TclCreateSocketAddress(interp, &addrlist, myHost, port, 1, &errorMsg)) { my_errno = errno; goto error; } for (addrPtr = addrlist; addrPtr != NULL; addrPtr = addrPtr->ai_next) { sock = socket(addrPtr->ai_family, addrPtr->ai_socktype, addrPtr->ai_protocol); |
︙ | ︙ | |||
1510 1511 1512 1513 1514 1515 1516 | TclSockMinimumBuffers(INT2PTR(sock), SOCKET_BUFSIZE); /* * Set up to reuse server addresses and/or ports if requested. */ | | | | | | > | > | > > | 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 | TclSockMinimumBuffers(INT2PTR(sock), SOCKET_BUFSIZE); /* * Set up to reuse server addresses and/or ports if requested. */ if (GOT_BITS(flags, TCL_TCPSERVER_REUSEADDR)) { optvalue = 1; (void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &optvalue, sizeof(optvalue)); } if (GOT_BITS(flags, TCL_TCPSERVER_REUSEPORT)) { #ifndef SO_REUSEPORT /* * If the platform doesn't support the SO_REUSEPORT flag we can't * do much beside erroring out. */ errorMsg = "SO_REUSEPORT isn't supported by this platform"; goto error; #else optvalue = 1; (void) setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (char *) &optvalue, sizeof(optvalue)); #endif } /* * Make sure we use the same port number when opening two server * sockets for IPv4 and IPv6 on a random port. * * As sockaddr_in6 uses the same offset and size for the port member * as sockaddr_in, we can handle both through the IPv4 API. */ if (port == 0 && chosenport != 0) { ((struct sockaddr_in *) addrPtr->ai_addr)->sin_port = htons(chosenport); } #ifdef IPV6_V6ONLY /* * Missing on: Solaris 2.8 */ if (addrPtr->ai_family == AF_INET6) { int v6only = 1; (void) setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &v6only, sizeof(v6only)); } #endif /* IPV6_V6ONLY */ |
︙ | ︙ | |||
1697 1698 1699 1700 1701 1702 1703 | newSockState = ckalloc(sizeof(TcpState)); memset(newSockState, 0, sizeof(TcpState)); newSockState->flags = 0; newSockState->fds.fd = newsock; sprintf(channelName, SOCK_TEMPLATE, (long) newSockState); newSockState->channel = Tcl_CreateChannel(&tcpChannelType, channelName, | | | 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 | newSockState = ckalloc(sizeof(TcpState)); memset(newSockState, 0, sizeof(TcpState)); newSockState->flags = 0; newSockState->fds.fd = newsock; sprintf(channelName, SOCK_TEMPLATE, (long) newSockState); newSockState->channel = Tcl_CreateChannel(&tcpChannelType, channelName, newSockState, TCL_READABLE | TCL_WRITABLE); Tcl_SetChannelOption(NULL, newSockState->channel, "-translation", "auto crlf"); if (fds->statePtr->acceptProc != NULL) { getnameinfo(&addr.sa, len, host, sizeof(host), port, sizeof(port), NI_NUMERICHOST|NI_NUMERICSERV); |
︙ | ︙ |
Changes to unix/tclUnixThrd.c.
︙ | ︙ | |||
640 641 642 643 644 645 646 647 648 649 650 651 652 653 | * Notes: * TclpReaddir is no longer used by the core (see 1095909), but it * appears in the internal stubs table (see #589526). * *---------------------------------------------------------------------- */ Tcl_DirEntry * TclpReaddir( DIR * dir) { return TclOSreaddir(dir); } | > | 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 | * Notes: * TclpReaddir is no longer used by the core (see 1095909), but it * appears in the internal stubs table (see #589526). * *---------------------------------------------------------------------- */ #ifndef TCL_NO_DEPRECATED Tcl_DirEntry * TclpReaddir( DIR * dir) { return TclOSreaddir(dir); } |
︙ | ︙ | |||
662 663 664 665 666 667 668 669 670 671 672 673 674 675 | sprintf(tsdPtr->nabuf, "%u.%u.%u.%u", b[0], b[1], b[2], b[3]); return tsdPtr->nabuf; #else return inet_ntoa(addr); #endif } #ifdef TCL_THREADS /* * Additions by AOL for specialized thread memory allocator. */ #ifdef USE_THREAD_ALLOC | > | 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 | sprintf(tsdPtr->nabuf, "%u.%u.%u.%u", b[0], b[1], b[2], b[3]); return tsdPtr->nabuf; #else return inet_ntoa(addr); #endif } #endif /* TCL_NO_DEPRECATED */ #ifdef TCL_THREADS /* * Additions by AOL for specialized thread memory allocator. */ #ifdef USE_THREAD_ALLOC |
︙ | ︙ |
Changes to unix/tclUnixTime.c.
︙ | ︙ | |||
18 19 20 21 22 23 24 25 26 27 28 29 30 31 | /* * TclpGetDate is coded to return a pointer to a 'struct tm'. For thread * safety, this structure must be in thread-specific data. The 'tmKey' * variable is the key to this buffer. */ static Tcl_ThreadDataKey tmKey; typedef struct { struct tm gmtime_buf; struct tm localtime_buf; } ThreadSpecificData; /* | > | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | /* * TclpGetDate is coded to return a pointer to a 'struct tm'. For thread * safety, this structure must be in thread-specific data. The 'tmKey' * variable is the key to this buffer. */ #ifndef TCL_NO_DEPRECATED static Tcl_ThreadDataKey tmKey; typedef struct { struct tm gmtime_buf; struct tm localtime_buf; } ThreadSpecificData; /* |
︙ | ︙ | |||
41 42 43 44 45 46 47 48 49 50 51 52 53 54 | /* * Static functions declared in this file. */ static void SetTZIfNecessary(void); static void CleanupMemory(ClientData clientData); static void NativeScaleTime(Tcl_Time *timebuf, ClientData clientData); static void NativeGetTime(Tcl_Time *timebuf, ClientData clientData); /* * TIP #233 (Virtualized Time): Data for the time hooks, if any. | > > | 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | /* * Static functions declared in this file. */ static void SetTZIfNecessary(void); static void CleanupMemory(ClientData clientData); #endif /* TCL_NO_DEPRECATED */ static void NativeScaleTime(Tcl_Time *timebuf, ClientData clientData); static void NativeGetTime(Tcl_Time *timebuf, ClientData clientData); /* * TIP #233 (Virtualized Time): Data for the time hooks, if any. |
︙ | ︙ | |||
259 260 261 262 263 264 265 266 267 268 269 270 271 272 | * * Side effects: * None. * *---------------------------------------------------------------------- */ struct tm * TclpGetDate( const time_t *time, int useGMT) { if (useGMT) { return TclpGmtime(time); | > | 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 | * * Side effects: * None. * *---------------------------------------------------------------------- */ #ifndef TCL_NO_DEPRECATED struct tm * TclpGetDate( const time_t *time, int useGMT) { if (useGMT) { return TclpGmtime(time); |
︙ | ︙ | |||
348 349 350 351 352 353 354 355 356 357 358 359 360 361 | Tcl_MutexLock(&tmMutex); memcpy(&tsdPtr->localtime_buf, localtime(timePtr), sizeof(struct tm)); Tcl_MutexUnlock(&tmMutex); #endif return &tsdPtr->localtime_buf; } /* *---------------------------------------------------------------------- * * Tcl_SetTimeProc -- * * TIP #233 (Virtualized Time): Registers two handlers for the | > | 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 | Tcl_MutexLock(&tmMutex); memcpy(&tsdPtr->localtime_buf, localtime(timePtr), sizeof(struct tm)); Tcl_MutexUnlock(&tmMutex); #endif return &tsdPtr->localtime_buf; } #endif /* TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------- * * Tcl_SetTimeProc -- * * TIP #233 (Virtualized Time): Registers two handlers for the |
︙ | ︙ | |||
482 483 484 485 486 487 488 489 490 491 492 493 494 495 | * If 'tzset' has never been called in the current process, or if the * value of the environment variable TZ has changed since the last call * to 'tzset', then 'tzset' is called again. * *---------------------------------------------------------------------- */ static void SetTZIfNecessary(void) { const char *newTZ = getenv("TZ"); Tcl_MutexLock(&tmMutex); if (newTZ == NULL) { | > | 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 | * If 'tzset' has never been called in the current process, or if the * value of the environment variable TZ has changed since the last call * to 'tzset', then 'tzset' is called again. * *---------------------------------------------------------------------- */ #ifndef TCL_NO_DEPRECATED static void SetTZIfNecessary(void) { const char *newTZ = getenv("TZ"); Tcl_MutexLock(&tmMutex); if (newTZ == NULL) { |
︙ | ︙ | |||
527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 | static void CleanupMemory( ClientData ignored) { ckfree(lastTZ); } /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * End: */ | > | 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 | static void CleanupMemory( ClientData ignored) { ckfree(lastTZ); } #endif /* TCL_NO_DEPRECATED */ /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * End: */ |
win/tclWinFile.c became a regular file.
︙ | ︙ |
Changes to win/tclWinSock.c.
︙ | ︙ | |||
65 66 67 68 69 70 71 72 73 74 75 76 77 78 | * Helper macros to make parts of this file clearer. The macros do exactly * what they say on the tin. :-) They also only ever refer to their arguments * once, and so can be used without regard to side effects. */ #define SET_BITS(var, bits) ((var) |= (bits)) #define CLEAR_BITS(var, bits) ((var) &= ~(bits)) /* "sock" + a pointer in hex + \0 */ #define SOCK_CHAN_LENGTH (4 + sizeof(void *) * 2 + 1) #define SOCK_TEMPLATE "sock%p" /* * The following variable is used to tell whether this module has been | > | 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | * Helper macros to make parts of this file clearer. The macros do exactly * what they say on the tin. :-) They also only ever refer to their arguments * once, and so can be used without regard to side effects. */ #define SET_BITS(var, bits) ((var) |= (bits)) #define CLEAR_BITS(var, bits) ((var) &= ~(bits)) #define GOT_BITS(var, bits) (((var) & (bits)) != 0) /* "sock" + a pointer in hex + \0 */ #define SOCK_CHAN_LENGTH (4 + sizeof(void *) * 2 + 1) #define SOCK_TEMPLATE "sock%p" /* * The following variable is used to tell whether this module has been |
︙ | ︙ | |||
120 121 122 123 124 125 126 127 128 129 130 131 132 133 | TcpState *statePtr; SOCKET fd; struct TcpFdList *next; } TcpFdList; struct TcpState { Tcl_Channel channel; /* Channel associated with this socket. */ struct TcpFdList *sockets; /* Windows SOCKET handle. */ int flags; /* Bit field comprised of the flags described * below. */ int watchEvents; /* OR'ed combination of FD_READ, FD_WRITE, * FD_CLOSE, FD_ACCEPT and FD_CONNECT that * indicate which events are interesting. */ volatile int readyEvents; /* OR'ed combination of FD_READ, FD_WRITE, | > > | 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | TcpState *statePtr; SOCKET fd; struct TcpFdList *next; } TcpFdList; struct TcpState { Tcl_Channel channel; /* Channel associated with this socket. */ int testFlags; /* bit field for tests. Is set by testsocket * test procedure */ struct TcpFdList *sockets; /* Windows SOCKET handle. */ int flags; /* Bit field comprised of the flags described * below. */ int watchEvents; /* OR'ed combination of FD_READ, FD_WRITE, * FD_CLOSE, FD_ACCEPT and FD_CONNECT that * indicate which events are interesting. */ volatile int readyEvents; /* OR'ed combination of FD_READ, FD_WRITE, |
︙ | ︙ | |||
179 180 181 182 183 184 185 186 187 188 189 190 191 192 | * socket */ #define TCP_ASYNC_PENDING (1<<4) /* TcpConnect was called to * process an async connect. This * flag indicates that reentry is * still pending */ #define TCP_ASYNC_FAILED (1<<5) /* An async connect finally failed */ /* * The following structure is what is added to the Tcl event queue when a * socket event occurs. */ typedef struct { Tcl_Event header; /* Information that is standard for all | > > > > > > > > > | 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | * socket */ #define TCP_ASYNC_PENDING (1<<4) /* TcpConnect was called to * process an async connect. This * flag indicates that reentry is * still pending */ #define TCP_ASYNC_FAILED (1<<5) /* An async connect finally failed */ /* * These bits may be ORed together into the "testFlags" field of a TcpState * structure. */ #define TCP_ASYNC_TEST_MODE (1<<0) /* Async testing activated. Do not * automatically continue connection * process */ /* * The following structure is what is added to the Tcl event queue when a * socket event occurs. */ typedef struct { Tcl_Event header; /* Information that is standard for all |
︙ | ︙ | |||
288 289 290 291 292 293 294 295 296 297 298 299 | /* * The following variable holds the network name of this host. */ static TclInitProcessGlobalValueProc InitializeHostName; static ProcessGlobalValue hostName = {0, 0, NULL, NULL, InitializeHostName, NULL, NULL}; /* * Address print debug functions */ #if 0 | > > > > > > > > > > > | > > | < | > > > | > > | 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 | /* * The following variable holds the network name of this host. */ static TclInitProcessGlobalValueProc InitializeHostName; static ProcessGlobalValue hostName = {0, 0, NULL, NULL, InitializeHostName, NULL, NULL}; /* * Simple wrapper round the SendMessage syscall. */ #define SendSelectMessage(tsdPtr, message, payload) \ SendMessage((tsdPtr)->hwnd, SOCKET_SELECT, \ (WPARAM) (message), (LPARAM) (payload)) /* * Address print debug functions */ #if 0 void printaddrinfo( struct addrinfo *ai, char *prefix) { char host[NI_MAXHOST], port[NI_MAXSERV]; getnameinfo(ai->ai_addr, ai->ai_addrlen, host, sizeof(host), port, sizeof(port), NI_NUMERICHOST|NI_NUMERICSERV); } void printaddrinfolist( struct addrinfo *addrlist, char *prefix) { struct addrinfo *ai; for (ai = addrlist; ai != NULL; ai = ai->ai_next) { printaddrinfo(ai, prefix); } } #endif /* |
︙ | ︙ | |||
520 521 522 523 524 525 526 | int mode) /* The mode to set. Can be one of * TCL_MODE_BLOCKING or * TCL_MODE_NONBLOCKING. */ { TcpState *statePtr = instanceData; if (mode == TCL_MODE_NONBLOCKING) { | | | | | | | | | | | < | | | | | | | | < | | | | > > > > > > > > > > > > > > > > > > < > | < > > > | > > | | | > | | > | > > | | > > | > > | | > | | | > | > > | | | | | 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 | int mode) /* The mode to set. Can be one of * TCL_MODE_BLOCKING or * TCL_MODE_NONBLOCKING. */ { TcpState *statePtr = instanceData; if (mode == TCL_MODE_NONBLOCKING) { SET_BITS(statePtr->flags, TCP_NONBLOCKING); } else { CLEAR_BITS(statePtr->flags, TCP_NONBLOCKING); } return 0; } /* *---------------------------------------------------------------------- * * WaitForConnect -- * * Check the state of an async connect process. If a connection attempt * terminated, process it, which may finalize it or may start the next * attempt. If a connect error occures, it is saved in * statePtr->connectError to be reported by 'fconfigure -error'. * * There are two modes of operation, defined by errorCodePtr: * * non-NULL: Called by explicite read/write command. Block if socket * is blocking. * May return two error codes: * * EWOULDBLOCK: if connect is still in progress * * ENOTCONN: if connect failed. This would be the error message * of a rect or sendto syscall so this is emulated here. * * Null: Called by a backround operation. Do not block and don't * return any error code. * * Results: * 0 if the connection has completed, -1 if still in progress or there is * an error. * * Side effects: * Processes socket events off the system queue. May process * asynchroneous connect. * *---------------------------------------------------------------------- */ static int WaitForConnect( TcpState *statePtr, /* State of the socket. */ int *errorCodePtr) /* Where to store errors? A passed * null-pointer activates background mode. */ { int result; int oldMode; ThreadSpecificData *tsdPtr; /* * Check if an async connect failed already and error reporting is * demanded, return the error ENOTCONN. */ if (errorCodePtr != NULL && GOT_BITS(statePtr->flags, TCP_ASYNC_FAILED)) { *errorCodePtr = ENOTCONN; return -1; } /* * Check if an async connect is running. If not return ok */ if (!GOT_BITS(statePtr->flags, TCP_ASYNC_CONNECT)) { return 0; } /* * In socket test mode do not continue with the connect * Exceptions are: * - Call by recv/send and blocking socket * (errorCodePtr != NULL && !GOT_BITS(flags, TCP_NONBLOCKING)) * - Call by the event queue (errorCodePtr == NULL) */ if (GOT_BITS(statePtr->testFlags, TCP_ASYNC_TEST_MODE) && errorCodePtr != NULL && GOT_BITS(statePtr->flags, TCP_NONBLOCKING)) { *errorCodePtr = EWOULDBLOCK; return -1; } /* * Be sure to disable event servicing so we are truly modal. */ oldMode = Tcl_SetServiceMode(TCL_SERVICE_NONE); /* * Loop in the blocking case until the connect signal is present */ while (1) { /* * Get the statePtr lock. */ tsdPtr = TclThreadDataKeyGet(&dataKey); WaitForSingleObject(tsdPtr->socketListLock, INFINITE); /* * Check for connect event. */ if (GOT_BITS(statePtr->readyEvents, FD_CONNECT)) { /* * Consume the connect event. */ CLEAR_BITS(statePtr->readyEvents, FD_CONNECT); /* * For blocking sockets and foreground processing, disable async * connect as we continue now synchoneously. */ if (errorCodePtr != NULL && !GOT_BITS(statePtr->flags, TCP_NONBLOCKING)) { CLEAR_BITS(statePtr->flags, TCP_ASYNC_CONNECT); } /* * Free list lock. */ SetEvent(tsdPtr->socketListLock); /* * Continue connect. If switched to synchroneous connect, the * connect is terminated. */ result = TcpConnect(NULL, statePtr); /* * Restore event service mode. */ (void) Tcl_SetServiceMode(oldMode); /* * Check for Succesfull connect or async connect restart */ if (result == TCL_OK) { /* * Check for async connect restart (not possible for * foreground blocking operation) */ if (GOT_BITS(statePtr->flags, TCP_ASYNC_PENDING)) { if (errorCodePtr != NULL) { *errorCodePtr = EWOULDBLOCK; } return -1; } return 0; } /* * Connect finally failed. For foreground operation return * ENOTCONN. */ if (errorCodePtr != NULL) { *errorCodePtr = ENOTCONN; } return -1; } /* * Free list lock. */ SetEvent(tsdPtr->socketListLock); /* * Background operation returns with no action as there was no connect * event */ if (errorCodePtr == NULL) { return -1; } /* * A non blocking socket waiting for an asyncronous connect returns * directly the error EWOULDBLOCK. */ if (GOT_BITS(statePtr->flags, TCP_NONBLOCKING)) { *errorCodePtr = EWOULDBLOCK; return -1; } /* * Wait until something happens. */ |
︙ | ︙ | |||
741 742 743 744 745 746 747 | } /* * First check to see if EOF was already detected, to prevent calling the * socket stack after the first time EOF is detected. */ | | | 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 | } /* * First check to see if EOF was already detected, to prevent calling the * socket stack after the first time EOF is detected. */ if (GOT_BITS(statePtr->flags, SOCKET_EOF)) { return 0; } /* * Check if there is an async connect running. * For blocking sockets terminate connect, otherwise do one step. * For a non blocking socket return EWOULDBLOCK if connect not terminated |
︙ | ︙ | |||
764 765 766 767 768 769 770 | * that we clear the FD_READ bit because read events are level triggered * so a new event will be generated if there is still data available to be * read. We have to simulate blocking behavior here since we are always * using non-blocking sockets. */ while (1) { | | | > | > > > | | | | | > | | | 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 | * that we clear the FD_READ bit because read events are level triggered * so a new event will be generated if there is still data available to be * read. We have to simulate blocking behavior here since we are always * using non-blocking sockets. */ while (1) { SendSelectMessage(tsdPtr, UNSELECT, statePtr); /* * Single fd operation: this proc is only called for a connected * socket. */ bytesRead = recv(statePtr->sockets->fd, buf, bufSize, 0); CLEAR_BITS(statePtr->readyEvents, FD_READ); /* * Check for end-of-file condition or successful read. */ if (bytesRead == 0) { SET_BITS(statePtr->flags, SOCKET_EOF); } if (bytesRead != SOCKET_ERROR) { break; } /* * If an error occurs after the FD_CLOSE has arrived, then ignore the * error and report an EOF. */ if (GOT_BITS(statePtr->readyEvents, FD_CLOSE)) { SET_BITS(statePtr->flags, SOCKET_EOF); bytesRead = 0; break; } error = WSAGetLastError(); /* * If an RST comes, then ignore the error and report an EOF just like * on unix. */ if (error == WSAECONNRESET) { SET_BITS(statePtr->flags, SOCKET_EOF); bytesRead = 0; break; } /* * Check for error condition or underflow in non-blocking case. */ if (GOT_BITS(statePtr->flags, TCP_NONBLOCKING) || (error != WSAEWOULDBLOCK)) { TclWinConvertError(error); *errorCodePtr = Tcl_GetErrno(); bytesRead = -1; break; } /* * In the blocking case, wait until the file becomes readable or * closed and try again. */ if (!WaitForSocketEvent(statePtr, FD_READ|FD_CLOSE, errorCodePtr)) { bytesRead = -1; break; } } SendSelectMessage(tsdPtr, SELECT, statePtr); return bytesRead; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
885 886 887 888 889 890 891 | */ if (WaitForConnect(statePtr, errorCodePtr) != 0) { return -1; } while (1) { | | < > | > > > | > | | | 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 | */ if (WaitForConnect(statePtr, errorCodePtr) != 0) { return -1; } while (1) { SendSelectMessage(tsdPtr, UNSELECT, statePtr); /* * Single fd operation: this proc is only called for a connected * socket. */ written = send(statePtr->sockets->fd, buf, toWrite, 0); if (written != SOCKET_ERROR) { /* * Since Windows won't generate a new write event until we hit an * overflow condition, we need to force the event loop to poll * until the condition changes. */ if (GOT_BITS(statePtr->watchEvents, FD_WRITE)) { Tcl_Time blockTime = { 0, 0 }; Tcl_SetMaxBlockTime(&blockTime); } break; } /* * Check for error condition or overflow. In the event of overflow, we * need to clear the FD_WRITE flag so we can detect the next writable * event. Note that Windows only sends a new writable event after a * send fails with WSAEWOULDBLOCK. */ error = WSAGetLastError(); if (error == WSAEWOULDBLOCK) { CLEAR_BITS(statePtr->readyEvents, FD_WRITE); if (GOT_BITS(statePtr->flags, TCP_NONBLOCKING)) { *errorCodePtr = EWOULDBLOCK; written = -1; break; } } else { TclWinConvertError(error); *errorCodePtr = Tcl_GetErrno(); |
︙ | ︙ | |||
937 938 939 940 941 942 943 | if (!WaitForSocketEvent(statePtr, FD_WRITE|FD_CLOSE, errorCodePtr)) { written = -1; break; } } | | | 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 | if (!WaitForSocketEvent(statePtr, FD_WRITE|FD_CLOSE, errorCodePtr)) { written = -1; break; } } SendSelectMessage(tsdPtr, SELECT, statePtr); return written; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
984 985 986 987 988 989 990 | if (SocketsEnabled()) { /* * Clean up the OS socket handle. The default Windows setting for a * socket is SO_DONTLINGER, which does a graceful shutdown in the * background. */ | | < > > > | | > > > | > > | 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 | if (SocketsEnabled()) { /* * Clean up the OS socket handle. The default Windows setting for a * socket is SO_DONTLINGER, which does a graceful shutdown in the * background. */ while (statePtr->sockets != NULL) { TcpFdList *thisfd = statePtr->sockets; statePtr->sockets = thisfd->next; if (closesocket(thisfd->fd) == SOCKET_ERROR) { TclWinConvertError((DWORD) WSAGetLastError()); errorCode = Tcl_GetErrno(); } ckfree(thisfd); } } if (statePtr->addrlist != NULL) { freeaddrinfo(statePtr->addrlist); } if (statePtr->myaddrlist != NULL) { freeaddrinfo(statePtr->myaddrlist); } /* * Clear an eventual tsd info list pointer. * * This may be called, if an async socket connect fails or is closed * between connect and thread action callback. */ if (tsdPtr->pendingTcpState != NULL && tsdPtr->pendingTcpState == statePtr) { /* * Get infoPtr lock, because this concerns the notifier thread. */ WaitForSingleObject(tsdPtr->socketListLock, INFINITE); tsdPtr->pendingTcpState = NULL; /* * Free list lock. */ SetEvent(tsdPtr->socketListLock); } /* * TIP #218. Removed the code removing the structure from the global * socket list. This is now done by the thread action callbacks, and only * there. This happens before this code is called. We can free without |
︙ | ︙ | |||
1077 1078 1079 1080 1081 1082 1083 | if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "socket close2proc called bidirectionally", -1)); } return TCL_ERROR; } | > | | > > | 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 | if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "socket close2proc called bidirectionally", -1)); } return TCL_ERROR; } /* * Single fd operation: Tcl_OpenTcpServer() does not set TCL_READABLE or * TCL_WRITABLE so this should never be called for a server socket. */ if (shutdown(statePtr->sockets->fd, sd) == SOCKET_ERROR) { TclWinConvertError((DWORD) WSAGetLastError()); errorCode = Tcl_GetErrno(); } return errorCode; } |
︙ | ︙ | |||
1130 1131 1132 1133 1134 1135 1136 | Tcl_SetObjResult(interp, Tcl_NewStringObj( "winsock is not initialized", -1)); } return TCL_ERROR; } #ifdef TCL_FEATURE_KEEPALIVE_NAGLE | | | 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 | Tcl_SetObjResult(interp, Tcl_NewStringObj( "winsock is not initialized", -1)); } return TCL_ERROR; } #ifdef TCL_FEATURE_KEEPALIVE_NAGLE #error "TCL_FEATURE_KEEPALIVE_NAGLE not reviewed for whether to treat statePtr->sockets as single fd or list" sock = statePtr->sockets->fd; if (!strcasecmp(optionName, "-keepalive")) { BOOL val = FALSE; int boolVar, rtn; if (Tcl_GetBoolean(interp, value, &boolVar) != TCL_OK) { |
︙ | ︙ | |||
1239 1240 1241 1242 1243 1244 1245 | "winsock is not initialized", -1)); } return TCL_ERROR; } /* * Go one step in async connect | > | > > > | > < | | < | < | | | | < < | | > > | | > > | > | > < | > | | > | > > | 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 | "winsock is not initialized", -1)); } return TCL_ERROR; } /* * Go one step in async connect * * If any error is thrown save it as backround error to report eventually * below. */ if (!GOT_BITS(statePtr->testFlags, TCP_ASYNC_TEST_MODE)) { WaitForConnect(statePtr, NULL); } sock = statePtr->sockets->fd; if (optionName != NULL) { len = strlen(optionName); } if ((len > 1) && (optionName[1] == 'e') && (strncmp(optionName, "-error", len) == 0)) { /* * Do not return any errors if async connect is running. */ if (!GOT_BITS(statePtr->flags, TCP_ASYNC_PENDING)) { if (GOT_BITS(statePtr->flags, TCP_ASYNC_FAILED)) { /* * In case of a failed async connect, eventually report the * connect error only once. Do not report the system error, * as this comes again and again. */ if (statePtr->connectError != 0) { Tcl_DStringAppend(dsPtr, Tcl_ErrnoMsg(statePtr->connectError), -1); statePtr->connectError = 0; } } else { /* * Report an eventual last error of the socket system. */ int optlen; int ret; DWORD err; /* * Populate the err variable with a POSIX error */ optlen = sizeof(int); ret = getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *)&err, &optlen); /* * The error was not returned directly but should be taken * from WSA. */ if (ret == SOCKET_ERROR) { err = WSAGetLastError(); } /* * Return error message. */ if (err) { TclWinConvertError(err); Tcl_DStringAppend(dsPtr, Tcl_ErrnoMsg(Tcl_GetErrno()), -1); } } } return TCL_OK; } if ((len > 1) && (optionName[1] == 'c') && (strncmp(optionName, "-connecting", len) == 0)) { Tcl_DStringAppend(dsPtr, GOT_BITS(statePtr->flags, TCP_ASYNC_PENDING) ? "1" : "0", -1); return TCL_OK; } if (interp != NULL && Tcl_GetVar2(interp, SUPPRESS_RDNS_VAR, NULL, 0) != NULL) { reverseDNS = NI_NUMERICHOST; } if ((len == 0) || ((len > 1) && (optionName[1] == 'p') && (strncmp(optionName, "-peername", len) == 0))) { address peername; socklen_t size = sizeof(peername); if (GOT_BITS(statePtr->flags, TCP_ASYNC_PENDING)) { /* * In async connect output an empty string */ if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-peername"); Tcl_DStringAppendElement(dsPtr, ""); } else { return TCL_OK; } } else if (getpeername(sock, (LPSOCKADDR) &(peername.sa), &size) == 0) { /* * Peername fetch succeeded - output list */ if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-peername"); Tcl_DStringStartSublist(dsPtr); } getnameinfo(&(peername.sa), size, host, sizeof(host), NULL, 0, NI_NUMERICHOST); |
︙ | ︙ | |||
1386 1387 1388 1389 1390 1391 1392 | socklen_t size; int found = 0; if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-sockname"); Tcl_DStringStartSublist(dsPtr); } | | > | | | > > | 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 | socklen_t size; int found = 0; if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-sockname"); Tcl_DStringStartSublist(dsPtr); } if (GOT_BITS(statePtr->flags, TCP_ASYNC_PENDING)) { /* * In async connect output an empty string */ found = 1; } else { for (fds = statePtr->sockets; fds != NULL; fds = fds->next) { sock = fds->fd; size = sizeof(sockname); if (getsockname(sock, &(sockname.sa), &size) >= 0) { int flags = reverseDNS; found = 1; getnameinfo(&sockname.sa, size, host, sizeof(host), NULL, 0, NI_NUMERICHOST); Tcl_DStringAppendElement(dsPtr, host); /* * We don't want to resolve INADDR_ANY and sin6addr_any; * they can sometimes cause problems (and never have a * name). */ flags |= NI_NUMERICSERV; if (sockname.sa.sa_family == AF_INET) { if (sockname.sa4.sin_addr.s_addr == INADDR_ANY) { flags |= NI_NUMERICHOST; } } else if (sockname.sa.sa_family == AF_INET6) { if ((IN6_ARE_ADDR_EQUAL(&sockname.sa6.sin6_addr, |
︙ | ︙ | |||
1490 1491 1492 1493 1494 1495 1496 | #endif /*TCL_FEATURE_KEEPALIVE_NAGLE*/ if (len > 0) { #ifdef TCL_FEATURE_KEEPALIVE_NAGLE return Tcl_BadChannelOption(interp, optionName, "connecting peername sockname keepalive nagle"); #else | | > | 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 | #endif /*TCL_FEATURE_KEEPALIVE_NAGLE*/ if (len > 0) { #ifdef TCL_FEATURE_KEEPALIVE_NAGLE return Tcl_BadChannelOption(interp, optionName, "connecting peername sockname keepalive nagle"); #else return Tcl_BadChannelOption(interp, optionName, "connecting peername sockname"); #endif /*TCL_FEATURE_KEEPALIVE_NAGLE*/ } return TCL_OK; } /* |
︙ | ︙ | |||
1531 1532 1533 1534 1535 1536 1537 | /* * Update the watch events mask. Only if the socket is not a server * socket. [Bug 557878] */ if (!statePtr->acceptProc) { statePtr->watchEvents = 0; | | | | | | 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 | /* * Update the watch events mask. Only if the socket is not a server * socket. [Bug 557878] */ if (!statePtr->acceptProc) { statePtr->watchEvents = 0; if (GOT_BITS(mask, TCL_READABLE)) { SET_BITS(statePtr->watchEvents, FD_READ | FD_CLOSE); } if (GOT_BITS(mask, TCL_WRITABLE)) { SET_BITS(statePtr->watchEvents, FD_WRITE | FD_CLOSE); } /* * If there are any conditions already set, then tell the notifier to * poll rather than block. */ |
︙ | ︙ | |||
1626 1627 1628 1629 1630 1631 1632 | static int TcpConnect( Tcl_Interp *interp, /* For error reporting; can be NULL. */ TcpState *statePtr) { DWORD error; | < > | > | < | | | | < | > | < > > | > > > | > > | > > > | > > | > | > | > > > > | > > | | > > | | > | | > > | > | | < | < > | > | > > | > > > > | > > > > | > > | > > | > > | | > | | < < > > < | < | < > > > > | > > > > | > > | > > | > > | > > | > > > > | > > > > | 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 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 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 | static int TcpConnect( Tcl_Interp *interp, /* For error reporting; can be NULL. */ TcpState *statePtr) { DWORD error; int async_connect = GOT_BITS(statePtr->flags, TCP_ASYNC_CONNECT); /* We are started with async connect and the * connect notification was not yet * received. */ int async_callback = GOT_BITS(statePtr->flags, TCP_ASYNC_PENDING); /* We were called by the event procedure and * continue our loop. */ ThreadSpecificData *tsdPtr = TclThreadDataKeyGet(&dataKey); if (async_callback) { goto reenter; } for (statePtr->addr = statePtr->addrlist; statePtr->addr != NULL; statePtr->addr = statePtr->addr->ai_next) { for (statePtr->myaddr = statePtr->myaddrlist; statePtr->myaddr != NULL; statePtr->myaddr = statePtr->myaddr->ai_next) { /* * No need to try combinations of local and remote addresses * of different families. */ if (statePtr->myaddr->ai_family != statePtr->addr->ai_family) { continue; } /* * Close the socket if it is still open from the last unsuccessful * iteration. */ if (statePtr->sockets->fd != INVALID_SOCKET) { closesocket(statePtr->sockets->fd); } /* * Get statePtr lock. */ WaitForSingleObject(tsdPtr->socketListLock, INFINITE); /* * Reset last error from last try */ statePtr->notifierConnectError = 0; Tcl_SetErrno(0); statePtr->sockets->fd = socket(statePtr->myaddr->ai_family, SOCK_STREAM, 0); /* * Free list lock. */ SetEvent(tsdPtr->socketListLock); /* * Continue on socket creation error. */ if (statePtr->sockets->fd == INVALID_SOCKET) { TclWinConvertError((DWORD) WSAGetLastError()); continue; } /* * Win-NT has a misfeature that sockets are inherited in child * processes by default. Turn off the inherit bit. */ SetHandleInformation((HANDLE) statePtr->sockets->fd, HANDLE_FLAG_INHERIT, 0); /* * Set kernel space buffering */ TclSockMinimumBuffers((void *) statePtr->sockets->fd, TCP_BUFFER_SIZE); /* * Try to bind to a local port. */ if (bind(statePtr->sockets->fd, statePtr->myaddr->ai_addr, statePtr->myaddr->ai_addrlen) == SOCKET_ERROR) { TclWinConvertError((DWORD) WSAGetLastError()); continue; } /* * For asyncroneous connect set the socket in nonblocking mode * and activate connect notification */ if (async_connect) { TcpState *statePtr2; int in_socket_list = 0; /* * Get statePtr lock. */ WaitForSingleObject(tsdPtr->socketListLock, INFINITE); /* * Bugfig for 336441ed59 to not ignore notifications until the * infoPtr is in the list. * Check if my statePtr is already in the tsdPtr->socketList * It is set after this call by TcpThreadActionProc and is set * on a second round. * * If not, we buffer my statePtr in the tsd memory so it is * not lost by the event procedure */ for (statePtr2 = tsdPtr->socketList; statePtr2 != NULL; statePtr2 = statePtr2->nextPtr) { if (statePtr2 == statePtr) { in_socket_list = 1; break; } } if (!in_socket_list) { tsdPtr->pendingTcpState = statePtr; } /* * Set connect mask to connect events * * This is activated by a SOCKET_SELECT message to the * notifier thread. */ SET_BITS(statePtr->selectEvents, FD_CONNECT); /* * Free list lock. */ SetEvent(tsdPtr->socketListLock); /* * Activate accept notification. */ SendSelectMessage(tsdPtr, SELECT, statePtr); } /* * Attempt to connect to the remote socket. */ connect(statePtr->sockets->fd, statePtr->addr->ai_addr, statePtr->addr->ai_addrlen); error = WSAGetLastError(); TclWinConvertError(error); if (async_connect && error == WSAEWOULDBLOCK) { /* * Asynchroneous connect * * Remember that we jump back behind this next round */ SET_BITS(statePtr->flags, TCP_ASYNC_PENDING); return TCL_OK; reenter: /* * Re-entry point for async connect after connect event or * blocking operation * * Clear the reenter flag */ CLEAR_BITS(statePtr->flags, TCP_ASYNC_PENDING); /* * Get statePtr lock. */ WaitForSingleObject(tsdPtr->socketListLock, INFINITE); /* * Get signaled connect error. */ TclWinConvertError((DWORD) statePtr->notifierConnectError); /* * Clear eventual connect flag. */ CLEAR_BITS(statePtr->selectEvents, FD_CONNECT); /* * Free list lock. */ SetEvent(tsdPtr->socketListLock); } /* * Clear the tsd socket list pointer if we did not wait for the * FD_CONNECT asynchronously. */ tsdPtr->pendingTcpState = NULL; if (Tcl_GetErrno() == 0) { goto out; } } } out: /* * Socket connected or connection failed */ /* * Async connect terminated */ CLEAR_BITS(statePtr->flags, TCP_ASYNC_CONNECT); if (Tcl_GetErrno() == 0) { /* * Succesfully connected * * Set up the select mask for read/write events. */ statePtr->selectEvents = FD_READ | FD_WRITE | FD_CLOSE; /* * Register for interest in events in the select mask. Note that this * automatically places the socket into non-blocking mode. */ SendSelectMessage(tsdPtr, SELECT, statePtr); } else { /* * Connect failed * * For async connect schedule a writable event to report the fail. */ if (async_callback) { /* * Set up the select mask for read/write events. */ statePtr->selectEvents = FD_WRITE|FD_READ; /* * Get statePtr lock. */ WaitForSingleObject(tsdPtr->socketListLock, INFINITE); /* * Signal ready readable and writable events. */ SET_BITS(statePtr->readyEvents, FD_WRITE | FD_READ); /* * Flag error to event routine. */ SET_BITS(statePtr->flags, TCP_ASYNC_FAILED); /* * Save connect error to be reported by 'fconfigure -error'. */ statePtr->connectError = Tcl_GetErrno(); /* * Free list lock. */ SetEvent(tsdPtr->socketListLock); } /* * Error message on syncroneous connect */ if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't open socket: %s", Tcl_PosixError(interp))); } return TCL_ERROR; } return TCL_OK; |
︙ | ︙ | |||
1934 1935 1936 1937 1938 1939 1940 | return NULL; } statePtr = NewSocketInfo(INVALID_SOCKET); statePtr->addrlist = addrlist; statePtr->myaddrlist = myaddrlist; if (async) { | | | 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 | return NULL; } statePtr = NewSocketInfo(INVALID_SOCKET); statePtr->addrlist = addrlist; statePtr->myaddrlist = myaddrlist; if (async) { SET_BITS(statePtr->flags, TCP_ASYNC_CONNECT); } /* * Create a new client socket and wrap it in a channel. */ if (TcpConnect(interp, statePtr) != TCL_OK) { TcpCloseProc(statePtr, NULL); |
︙ | ︙ | |||
2004 2005 2006 2007 2008 2009 2010 | statePtr = NewSocketInfo((SOCKET) sock); /* * Start watching for read/write events on the socket. */ statePtr->selectEvents = FD_READ | FD_CLOSE | FD_WRITE; | | | 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 | statePtr = NewSocketInfo((SOCKET) sock); /* * Start watching for read/write events on the socket. */ statePtr->selectEvents = FD_READ | FD_CLOSE | FD_WRITE; SendSelectMessage(tsdPtr, SELECT, statePtr); sprintf(channelName, SOCK_TEMPLATE, statePtr); statePtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName, statePtr, (TCL_READABLE | TCL_WRITABLE)); Tcl_SetChannelOption(NULL, statePtr->channel, "-translation", "auto crlf"); return statePtr->channel; } |
︙ | ︙ | |||
2074 2075 2076 2077 2078 2079 2080 | */ if (TclSockGetPort(interp, service, "tcp", &port) != TCL_OK) { errorMsg = "invalid port number"; goto error; } | | > | 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 | */ if (TclSockGetPort(interp, service, "tcp", &port) != TCL_OK) { errorMsg = "invalid port number"; goto error; } if (!TclCreateSocketAddress(interp, &addrlist, myHost, port, 1, &errorMsg)) { goto error; } for (addrPtr = addrlist; addrPtr != NULL; addrPtr = addrPtr->ai_next) { sock = socket(addrPtr->ai_family, addrPtr->ai_socktype, addrPtr->ai_protocol); if (sock == INVALID_SOCKET) { |
︙ | ︙ | |||
2113 2114 2115 2116 2117 2118 2119 | if (port == 0 && chosenport != 0) { ((struct sockaddr_in *) addrPtr->ai_addr)->sin_port = htons(chosenport); } /* | | | > | | | | | 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 | if (port == 0 && chosenport != 0) { ((struct sockaddr_in *) addrPtr->ai_addr)->sin_port = htons(chosenport); } /* * The SO_REUSEADDR option on Windows behaves like SO_REUSEPORT on * unix systems. */ if (GOT_BITS(flags, TCL_TCPSERVER_REUSEPORT)) { optvalue = 1; (void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &optvalue, sizeof(optvalue)); } /* * Bind to the specified port. * * Bind should not be affected by the socket having already been * set into nonblocking mode. If there is trouble, this is one * place to look for bugs. */ if (bind(sock, addrPtr->ai_addr, addrPtr->ai_addrlen) == SOCKET_ERROR) { TclWinConvertError((DWORD) WSAGetLastError()); closesocket(sock); continue; } if (port == 0 && chosenport == 0) { address sockname; socklen_t namelen = sizeof(sockname); |
︙ | ︙ | |||
2166 2167 2168 2169 2170 2171 2172 2173 2174 | continue; } if (statePtr == NULL) { /* * Add this socket to the global list of sockets. */ statePtr = NewSocketInfo(sock); } else { | > | | | 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 | continue; } if (statePtr == NULL) { /* * Add this socket to the global list of sockets. */ statePtr = NewSocketInfo(sock); } else { AddSocketInfoFd(statePtr, sock); } } error: if (addrlist != NULL) { freeaddrinfo(addrlist); } if (statePtr != NULL) { ThreadSpecificData *tsdPtr = TclThreadDataKeyGet(&dataKey); |
︙ | ︙ | |||
2197 2198 2199 2200 2201 2202 2203 | /* * Register for interest in events in the select mask. Note that this * automatically places the socket into non-blocking mode. */ ioctlsocket(sock, (long) FIONBIO, &flag); | < | | 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 | /* * Register for interest in events in the select mask. Note that this * automatically places the socket into non-blocking mode. */ ioctlsocket(sock, (long) FIONBIO, &flag); SendSelectMessage(tsdPtr, SELECT, statePtr); if (Tcl_SetChannelOption(interp, statePtr->channel, "-eofchar", "") == TCL_ERROR) { Tcl_Close(NULL, statePtr->channel); return NULL; } return statePtr->channel; } |
︙ | ︙ | |||
2267 2268 2269 2270 2271 2272 2273 | newInfoPtr = NewSocketInfo(newSocket); /* * Select on read/write events and create the channel. */ newInfoPtr->selectEvents = (FD_READ | FD_WRITE | FD_CLOSE); | < | | 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 | newInfoPtr = NewSocketInfo(newSocket); /* * Select on read/write events and create the channel. */ newInfoPtr->selectEvents = (FD_READ | FD_WRITE | FD_CLOSE); SendSelectMessage(tsdPtr, SELECT, newInfoPtr); sprintf(channelName, SOCK_TEMPLATE, newInfoPtr); newInfoPtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName, newInfoPtr, (TCL_READABLE | TCL_WRITABLE)); if (Tcl_SetChannelOption(NULL, newInfoPtr->channel, "-translation", "auto crlf") == TCL_ERROR) { Tcl_Close(NULL, newInfoPtr->channel); |
︙ | ︙ | |||
2499 2500 2501 2502 2503 2504 2505 | ClientData data, /* Not used. */ int flags) /* Event flags as passed to Tcl_DoOneEvent. */ { TcpState *statePtr; Tcl_Time blockTime = { 0, 0 }; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); | | | | < | 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 | ClientData data, /* Not used. */ int flags) /* Event flags as passed to Tcl_DoOneEvent. */ { TcpState *statePtr; Tcl_Time blockTime = { 0, 0 }; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); if (!GOT_BITS(flags, TCL_FILE_EVENTS)) { return; } /* * Check to see if there is a ready socket. If so, poll. */ WaitForSingleObject(tsdPtr->socketListLock, INFINITE); for (statePtr = tsdPtr->socketList; statePtr != NULL; statePtr = statePtr->nextPtr) { if (GOT_BITS(statePtr->readyEvents, statePtr->watchEvents | FD_CONNECT | FD_ACCEPT)) { Tcl_SetMaxBlockTime(&blockTime); break; } } SetEvent(tsdPtr->socketListLock); } |
︙ | ︙ | |||
2545 2546 2547 2548 2549 2550 2551 | ClientData data, /* Not used. */ int flags) /* Event flags as passed to Tcl_DoOneEvent. */ { TcpState *statePtr; SocketEvent *evPtr; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); | | | | | < | | 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 | ClientData data, /* Not used. */ int flags) /* Event flags as passed to Tcl_DoOneEvent. */ { TcpState *statePtr; SocketEvent *evPtr; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); if (!GOT_BITS(flags, TCL_FILE_EVENTS)) { return; } /* * Queue events for any ready sockets that don't already have events * queued (caused by persistent states that won't generate WinSock * events). */ WaitForSingleObject(tsdPtr->socketListLock, INFINITE); for (statePtr = tsdPtr->socketList; statePtr != NULL; statePtr = statePtr->nextPtr) { if (GOT_BITS(statePtr->readyEvents, statePtr->watchEvents | FD_CONNECT | FD_ACCEPT) && !GOT_BITS(statePtr->flags, SOCKET_PENDING)) { SET_BITS(statePtr->flags, SOCKET_PENDING); evPtr = ckalloc(sizeof(SocketEvent)); evPtr->header.proc = SocketEventProc; evPtr->socket = statePtr->sockets->fd; Tcl_QueueEvent((Tcl_Event *) evPtr, TCL_QUEUE_TAIL); } } SetEvent(tsdPtr->socketListLock); |
︙ | ︙ | |||
2608 2609 2610 2611 2612 2613 2614 | int mask = 0, events; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); TcpFdList *fds; SOCKET newSocket; address addr; int len; | | | 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 | int mask = 0, events; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); TcpFdList *fds; SOCKET newSocket; address addr; int len; if (!GOT_BITS(flags, TCL_FILE_EVENTS)) { return 0; } /* * Find the specified socket on the socket list. */ |
︙ | ︙ | |||
2637 2638 2639 2640 2641 2642 2643 | return 1; } /* * Clear flag that (this) event is pending */ | | | | < < < | > | < | | < > > | | | | > > | | | > | > | | | | | > > | > | | | < | < | | < | < | | | < | | | 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 | return 1; } /* * Clear flag that (this) event is pending */ CLEAR_BITS(statePtr->flags, SOCKET_PENDING); /* * Continue async connect if pending and ready */ if (GOT_BITS(statePtr->readyEvents, FD_CONNECT)) { if (GOT_BITS(statePtr->flags, TCP_ASYNC_PENDING)) { /* * Do one step and save eventual connect error */ SetEvent(tsdPtr->socketListLock); WaitForConnect(statePtr,NULL); } else { /* * No async connect reenter pending. Just clear event. */ CLEAR_BITS(statePtr->readyEvents, FD_CONNECT); SetEvent(tsdPtr->socketListLock); } return 1; } /* * Handle connection requests directly. */ if (GOT_BITS(statePtr->readyEvents, FD_ACCEPT)) { for (fds = statePtr->sockets; fds != NULL; fds = fds->next) { /* * Accept the incoming connection request. */ len = sizeof(address); newSocket = accept(fds->fd, &(addr.sa), &len); /* * On Tcl server sockets with multiple OS fds we loop over the fds * trying an accept() on each, so we expect INVALID_SOCKET. There * are also other network stack conditions that can result in * FD_ACCEPT but a subsequent failure on accept() by the time we * get around to it. * * Access to sockets (acceptEventCount, readyEvents) in socketList * is still protected by the lock (prevents reintroduction of * SF Tcl Bug 3056775. */ if (newSocket == INVALID_SOCKET) { /* int err = WSAGetLastError(); */ continue; } /* * It is possible that more than one FD_ACCEPT has been sent, so * an extra count must be kept. Decrement the count, and reset the * readyEvent bit if the count is no longer > 0. */ statePtr->acceptEventCount--; if (statePtr->acceptEventCount <= 0) { CLEAR_BITS(statePtr->readyEvents, FD_ACCEPT); } SetEvent(tsdPtr->socketListLock); /* * Caution: TcpAccept() has the side-effect of evaluating the * server accept script (via AcceptCallbackProc() in tclIOCmd.c), * which can close the server socket and invalidate statePtr and * fds. If TcpAccept() accepts a socket we must return immediately * and let SocketCheckProc queue additional FD_ACCEPT events. */ TcpAccept(fds, newSocket, addr); return 1; } /* * Loop terminated with no sockets accepted; clear the ready mask so * we can detect the next connection request. Note that connection * requests are level triggered, so if there is a request already * pending, a new event will be generated. */ statePtr->acceptEventCount = 0; CLEAR_BITS(statePtr->readyEvents, FD_ACCEPT); SetEvent(tsdPtr->socketListLock); return 1; } SetEvent(tsdPtr->socketListLock); /* * Mask off unwanted events and compute the read/write mask so we can * notify the channel. */ events = statePtr->readyEvents & statePtr->watchEvents; if (GOT_BITS(events, FD_CLOSE)) { /* * If the socket was closed and the channel is still interested in * read events, then we need to ensure that we keep polling for this * event until someone does something with the channel. Note that we * do this before calling Tcl_NotifyChannel so we don't have to watch * out for the channel being deleted out from under us. This may cause * a redundant trip through the event loop, but it's simpler than * trying to do unwind protection. */ Tcl_Time blockTime = { 0, 0 }; Tcl_SetMaxBlockTime(&blockTime); SET_BITS(mask, TCL_READABLE | TCL_WRITABLE); } else if (GOT_BITS(events, FD_READ)) { /* * Throw the readable event if an async connect failed. */ if (GOT_BITS(statePtr->flags, TCP_ASYNC_FAILED)) { SET_BITS(mask, TCL_READABLE); } else { fd_set readFds; struct timeval timeout; /* * We must check to see if data is really available, since someone * could have consumed the data in the meantime. Turn off async * notification so select will work correctly. If the socket is * still readable, notify the channel driver, otherwise reset the * async select handler and keep waiting. */ SendSelectMessage(tsdPtr, UNSELECT, statePtr); FD_ZERO(&readFds); FD_SET(statePtr->sockets->fd, &readFds); timeout.tv_usec = 0; timeout.tv_sec = 0; if (select(0, &readFds, NULL, NULL, &timeout) != 0) { SET_BITS(mask, TCL_READABLE); } else { CLEAR_BITS(statePtr->readyEvents, FD_READ); SendSelectMessage(tsdPtr, SELECT, statePtr); } } } /* * writable event */ if (GOT_BITS(events, FD_WRITE)) { SET_BITS(mask, TCL_WRITABLE); } /* * Call registered event procedures */ if (mask) { |
︙ | ︙ | |||
2833 2834 2835 2836 2837 2838 2839 | static void AddSocketInfoFd( TcpState *statePtr, SOCKET socket) { TcpFdList *fds = statePtr->sockets; | | > | > > > | > > | > | > > | 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 | static void AddSocketInfoFd( TcpState *statePtr, SOCKET socket) { TcpFdList *fds = statePtr->sockets; if (fds == NULL) { /* * Add the first FD. */ statePtr->sockets = ckalloc(sizeof(TcpFdList)); fds = statePtr->sockets; } else { /* * Find end of list and append FD. */ while (fds->next != NULL) { fds = fds->next; } fds->next = ckalloc(sizeof(TcpFdList)); fds = fds->next; } /* * Populate new FD. */ fds->fd = socket; fds->statePtr = statePtr; fds->next = NULL; } /* |
︙ | ︙ | |||
2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 | * FD_READ or FD_WRITE. */ int *errorCodePtr) /* Where to store errors? */ { int result = 1; int oldMode; ThreadSpecificData *tsdPtr = TclThreadDataKeyGet(&dataKey); /* * Be sure to disable event servicing so we are truly modal. */ oldMode = Tcl_SetServiceMode(TCL_SERVICE_NONE); /* * Reset WSAAsyncSelect so we have a fresh set of events pending. */ | > < | < | > | > > > | > > | > | > > > | > > > | > > | 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 | * FD_READ or FD_WRITE. */ int *errorCodePtr) /* Where to store errors? */ { int result = 1; int oldMode; ThreadSpecificData *tsdPtr = TclThreadDataKeyGet(&dataKey); /* * Be sure to disable event servicing so we are truly modal. */ oldMode = Tcl_SetServiceMode(TCL_SERVICE_NONE); /* * Reset WSAAsyncSelect so we have a fresh set of events pending. */ SendSelectMessage(tsdPtr, UNSELECT, statePtr); SendSelectMessage(tsdPtr, SELECT, statePtr); while (1) { int event_found; /* * Get statePtr lock. */ WaitForSingleObject(tsdPtr->socketListLock, INFINITE); /* * Check if event occured. */ event_found = GOT_BITS(statePtr->readyEvents, events); /* * Free list lock. */ SetEvent(tsdPtr->socketListLock); /* * Exit loop if event occured. */ if (event_found) { break; } /* * Exit loop if event did not occur but this is a non-blocking channel */ if (statePtr->flags & TCP_NONBLOCKING) { *errorCodePtr = EWOULDBLOCK; result = 0; break; } /* |
︙ | ︙ | |||
3106 3107 3108 3109 3110 3111 3112 | /* * Find the specified socket on the socket list and update its * eventState flag. */ for (statePtr = tsdPtr->socketList; statePtr != NULL; statePtr = statePtr->nextPtr) { | | > | < > | | < | | | | | | > > > | > | 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 | /* * Find the specified socket on the socket list and update its * eventState flag. */ for (statePtr = tsdPtr->socketList; statePtr != NULL; statePtr = statePtr->nextPtr) { if (FindFDInList(statePtr, socket)) { info_found = 1; break; } } /* * Check if there is a pending info structure not jet in the list. */ if (!info_found && tsdPtr->pendingTcpState != NULL && FindFDInList(tsdPtr->pendingTcpState, socket)) { statePtr = tsdPtr->pendingTcpState; info_found = 1; } if (info_found) { /* * Update the socket state. * * A count of FD_ACCEPTS is stored, so if an FD_CLOSE event * happens, then clear the FD_ACCEPT count. Otherwise, increment * the count if the current event is an FD_ACCEPT. */ if (GOT_BITS(event, FD_CLOSE)) { statePtr->acceptEventCount = 0; CLEAR_BITS(statePtr->readyEvents, FD_WRITE | FD_ACCEPT); } else if (GOT_BITS(event, FD_ACCEPT)) { statePtr->acceptEventCount++; } if (GOT_BITS(event, FD_CONNECT)) { /* * Remember any error that occurred so we can report * connection failures. */ if (error != ERROR_SUCCESS) { statePtr->notifierConnectError = error; } } /* * Inform main thread about signaled events */ SET_BITS(statePtr->readyEvents, event); /* * Wake up the Main Thread. */ SetEvent(tsdPtr->readyEvent); Tcl_ThreadAlert(tsdPtr->threadId); } SetEvent(tsdPtr->socketListLock); break; case SOCKET_SELECT: |
︙ | ︙ | |||
3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 | * * Side effects: * As defined for each function. * *---------------------------------------------------------------------- */ #undef TclWinGetSockOpt int TclWinGetSockOpt( SOCKET s, int level, int optname, char *optval, | > | 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 | * * Side effects: * As defined for each function. * *---------------------------------------------------------------------- */ #ifndef TCL_NO_DEPRECATED #undef TclWinGetSockOpt int TclWinGetSockOpt( SOCKET s, int level, int optname, char *optval, |
︙ | ︙ | |||
3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 | struct servent * TclWinGetServByName( const char *name, const char *proto) { return getservbyname(name, proto); } /* *---------------------------------------------------------------------- * * TcpThreadActionProc -- * * Insert or remove any thread local refs to this channel. | > | 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 | struct servent * TclWinGetServByName( const char *name, const char *proto) { return getservbyname(name, proto); } #endif /* TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------- * * TcpThreadActionProc -- * * Insert or remove any thread local refs to this channel. |
︙ | ︙ | |||
3363 3364 3365 3366 3367 3368 3369 | } /* * Ensure that, or stop, notifications for the socket occur in this * thread. */ | | < | 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 | } /* * Ensure that, or stop, notifications for the socket occur in this * thread. */ SendSelectMessage(tsdPtr, notifyCmd, statePtr); } /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * tab-width: 8 * indent-tabs-mode: nil * End: */ |
Changes to win/tclWinTime.c.
︙ | ︙ | |||
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | #define SAMPLES 64 /* * The following arrays contain the day of year for the last day of each * month, where index 1 is January. */ static const int normalDays[] = { -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364 }; static const int leapDays[] = { -1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }; typedef struct { char tzName[64]; /* Time zone name */ struct tm tm; /* time information */ } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; /* * Data for managing high-resolution timers. */ typedef struct { CRITICAL_SECTION cs; /* Mutex guarding this structure. */ | > > | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | #define SAMPLES 64 /* * The following arrays contain the day of year for the last day of each * month, where index 1 is January. */ #ifndef TCL_NO_DEPRECATED static const int normalDays[] = { -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364 }; static const int leapDays[] = { -1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }; typedef struct { char tzName[64]; /* Time zone name */ struct tm tm; /* time information */ } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; #endif /* TCL_NO_DEPRECATED */ /* * Data for managing high-resolution timers. */ typedef struct { CRITICAL_SECTION cs; /* Mutex guarding this structure. */ |
︙ | ︙ | |||
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | 0 }; /* * Declarations for functions defined later in this file. */ static struct tm * ComputeGMT(const time_t *tp); static void StopCalibration(ClientData clientData); static DWORD WINAPI CalibrationThread(LPVOID arg); static void UpdateTimeEachSecond(void); static void ResetCounterSamples(Tcl_WideUInt fileTime, Tcl_WideInt perfCounter, Tcl_WideInt perfFreq); static Tcl_WideInt AccumulateSample(Tcl_WideInt perfCounter, Tcl_WideUInt fileTime); | > > | 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | 0 }; /* * Declarations for functions defined later in this file. */ #ifndef TCL_NO_DEPRECATED static struct tm * ComputeGMT(const time_t *tp); #endif /* TCL_NO_DEPRECATED */ static void StopCalibration(ClientData clientData); static DWORD WINAPI CalibrationThread(LPVOID arg); static void UpdateTimeEachSecond(void); static void ResetCounterSamples(Tcl_WideUInt fileTime, Tcl_WideInt perfCounter, Tcl_WideInt perfFreq); static Tcl_WideInt AccumulateSample(Tcl_WideInt perfCounter, Tcl_WideUInt fileTime); |
︙ | ︙ | |||
518 519 520 521 522 523 524 525 526 527 528 529 530 531 | * * Side effects: * None. * *---------------------------------------------------------------------- */ struct tm * TclpGetDate( const time_t *t, int useGMT) { struct tm *tmPtr; time_t time; | > | 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 | * * Side effects: * None. * *---------------------------------------------------------------------- */ #ifndef TCL_NO_DEPRECATED struct tm * TclpGetDate( const time_t *t, int useGMT) { struct tm *tmPtr; time_t time; |
︙ | ︙ | |||
720 721 722 723 724 725 726 727 728 729 730 731 732 733 | tmPtr->tm_wday %= 7; if (tmPtr->tm_wday < 0) { tmPtr->tm_wday += 7; } return tmPtr; } /* *---------------------------------------------------------------------- * * CalibrationThread -- * * Thread that manages calibration of the hi-resolution time derived from | > | 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 | tmPtr->tm_wday %= 7; if (tmPtr->tm_wday < 0) { tmPtr->tm_wday += 7; } return tmPtr; } #endif /* TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------- * * CalibrationThread -- * * Thread that manages calibration of the hi-resolution time derived from |
︙ | ︙ | |||
1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 | * * Side effects: * Invokes gmtime or gmtime_r as appropriate. * *---------------------------------------------------------------------- */ struct tm * TclpGmtime( const time_t *timePtr) /* Pointer to the number of seconds since the * local system's epoch */ { /* * The MS implementation of gmtime is thread safe because it returns the | > | 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 | * * Side effects: * Invokes gmtime or gmtime_r as appropriate. * *---------------------------------------------------------------------- */ #ifndef TCL_NO_DEPRECATED struct tm * TclpGmtime( const time_t *timePtr) /* Pointer to the number of seconds since the * local system's epoch */ { /* * The MS implementation of gmtime is thread safe because it returns the |
︙ | ︙ | |||
1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 | * The MS implementation of localtime is thread safe because it returns * the time in a block of thread-local storage, and Windows does not * provide a Posix localtime_r function. */ return localtime(timePtr); } /* *---------------------------------------------------------------------- * * Tcl_SetTimeProc -- * * TIP #233 (Virtualized Time): Registers two handlers for the | > | 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 | * The MS implementation of localtime is thread safe because it returns * the time in a block of thread-local storage, and Windows does not * provide a Posix localtime_r function. */ return localtime(timePtr); } #endif /* TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------- * * Tcl_SetTimeProc -- * * TIP #233 (Virtualized Time): Registers two handlers for the |
︙ | ︙ |