Tcl Source Code

Check-in [9e83b1442d]
Login
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2019 Conference, Houston/TX, US, Nov 4-8
Send your abstracts to [email protected]
or submit via the online form by Sep 9.

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

Overview
Comment:Merge 8.7 Add Unsigned functions to the implementation. TIP text is still far behind describing what's going on here.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | tip-481
Files: files | file ages | folders
SHA3-256: 9e83b1442d208b60550ece3bfdd0c22979ec342a89cb5d866c37c59f821afa69
User & Date: jan.nijtmans 2018-10-09 18:12:41
Context
2018-10-11
18:54
Merge 8.7 check-in: 37418eb6d5 user: jan.nijtmans tags: tip-481
2018-10-09
18:12
Merge 8.7 Add Unsigned functions to the implementation. TIP text is still far behind describing what... check-in: 9e83b1442d user: jan.nijtmans tags: tip-481
17:56
Balance the [makeFile/makeDirectory] and [removeFile/removeDirectory] calls (conditional now, so avo... check-in: d25d034991 user: dkf tags: core-8-branch
2018-10-08
22:22
Re-base to 8.7 check-in: e007a2ab3c user: jan.nijtmans tags: tip-481
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to doc/DoubleObj.3.

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
.sp
Tcl_Obj *
\fBTcl_NewDoubleObj\fR(\fIdoubleValue\fR)
.sp
\fBTcl_SetDoubleObj\fR(\fIobjPtr, doubleValue\fR)
.sp
int
\fBTcl_GetDoubleFromObj\fR(\fIinterp, objPtr, doublePtr\fR)
.SH ARGUMENTS
.AS Tcl_Interp doubleValue in/out
.AP double doubleValue in
A double-precision floating-point value used to initialize or set a Tcl value.
.AP Tcl_Obj *objPtr in/out
For \fBTcl_SetDoubleObj\fR, this points to the value in which to store a
double value.
For \fBTcl_GetDoubleFromObj\fR, this refers to the value
from which to retrieve a double value.
.AP Tcl_Interp *interp in/out
When non-NULL, an error message is left here when double value retrieval fails.
.AP double *doublePtr out
Points to place to store the double value obtained from \fIobjPtr\fR.
.BE

.SH DESCRIPTION
.PP
These procedures are used to create, modify, and read Tcl values that
hold double-precision floating-point values.
.PP






|











|
|







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
.sp
Tcl_Obj *
\fBTcl_NewDoubleObj\fR(\fIdoubleValue\fR)
.sp
\fBTcl_SetDoubleObj\fR(\fIobjPtr, doubleValue\fR)
.sp
int
\fBTcl_GetDoubleFromObj\fR(\fIinterp, objPtr, ptr\fR)
.SH ARGUMENTS
.AS Tcl_Interp doubleValue in/out
.AP double doubleValue in
A double-precision floating-point value used to initialize or set a Tcl value.
.AP Tcl_Obj *objPtr in/out
For \fBTcl_SetDoubleObj\fR, this points to the value in which to store a
double value.
For \fBTcl_GetDoubleFromObj\fR, this refers to the value
from which to retrieve a double value.
.AP Tcl_Interp *interp in/out
When non-NULL, an error message is left here when double value retrieval fails.
.AP float|double *ptr out
Points to place to store the float or double value obtained from \fIobjPtr\fR.
.BE

.SH DESCRIPTION
.PP
These procedures are used to create, modify, and read Tcl values that
hold double-precision floating-point values.
.PP

Changes to doc/IntObj.3.

4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
..
27
28
29
30
31
32
33



34
35
36



37
38
39
40
41
42
43
..
67
68
69
70
71
72
73
74
75


76
77
78
79


80
81
82
83
84
85
86
...
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH Tcl_IntObj 3 8.5 Tcl "Tcl Library Procedures"
.so man.macros
.BS
.SH NAME
Tcl_NewIntObj, Tcl_NewLongObj, Tcl_NewWideIntObj, Tcl_SetIntObj, Tcl_SetLongObj, Tcl_SetWideIntObj, Tcl_GetIntFromObj, Tcl_GetLongFromObj, Tcl_GetWideIntFromObj, Tcl_NewBignumObj, Tcl_SetBignumObj, Tcl_GetBignumFromObj, Tcl_TakeBignumFromObj \- manipulate Tcl values as integers
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
Tcl_Obj *
\fBTcl_NewIntObj\fR(\fIintValue\fR)
.sp
................................................................................
\fBTcl_SetLongObj\fR(\fIobjPtr, longValue\fR)
.sp
\fBTcl_SetWideIntObj\fR(\fIobjPtr, wideValue\fR)
.sp
int
\fBTcl_GetIntFromObj\fR(\fIinterp, objPtr, intPtr\fR)
.sp



int
\fBTcl_GetLongFromObj\fR(\fIinterp, objPtr, longPtr\fR)
.sp



int
\fBTcl_GetWideIntFromObj\fR(\fIinterp, objPtr, widePtr\fR)
.sp
.sp
\fB#include <tclTomMath.h>\fR
.sp
Tcl_Obj *
................................................................................
integral value.  For \fBTcl_GetIntFromObj\fR, \fBTcl_GetLongFromObj\fR,
\fBTcl_GetWideIntFromObj\fR, \fBTcl_GetBignumFromObj\fR, and
\fBTcl_TakeBignumFromObj\fR, this refers to the value from which
to retrieve an integral value.
.AP Tcl_Interp *interp in/out
When non-NULL, an error message is left here when integral value
retrieval fails.
.AP int *intPtr out
Points to place to store the integer value retrieved from \fIobjPtr\fR.


.AP long *longPtr out
Points to place to store the long integer value retrieved from \fIobjPtr\fR.
.AP Tcl_WideInt *widePtr out
Points to place to store the wide integer value retrieved from \fIobjPtr\fR.


.AP mp_int *bigValue in/out
Points to a multi-precision integer structure declared by the LibTomMath
library.
.AP double doubleValue in
Double value from which the integer part is determined and
used to initialize a multi-precision integer value.
.BE
................................................................................
Tcl value pointed to by \fIobjPtr\fR to the integral value provided
by the other argument.  The \fIobjPtr\fR argument must point to an
unshared Tcl value.  Any attempt to set the value of a shared Tcl value
violates Tcl's copy-on-write policy.  Any existing string representation
or internal representation in the unshared Tcl value will be freed
as a consequence of setting the new value.
.PP
The \fBTcl_GetIntFromObj\fR, \fBTcl_GetLongFromObj\fR,
\fBTcl_GetWideIntFromObj\fR, \fBTcl_GetBignumFromObj\fR, and
\fBTcl_TakeBignumFromObj\fR routines attempt to retrieve an integral
value of the appropriate type from the Tcl value \fIobjPtr\fR.  If the
attempt succeeds, then \fBTCL_OK\fR is returned, and the value is
written to the storage provided by the caller.  The attempt might
fail if \fIobjPtr\fR does not hold an integral value, or if the
value exceeds the range of the target type.  If the attempt fails,






|







 







>
>
>



>
>
>







 







|

>
>




>
>







 







|







4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
..
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
..
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
...
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH Tcl_IntObj 3 8.5 Tcl "Tcl Library Procedures"
.so man.macros
.BS
.SH NAME
Tcl_NewIntObj, Tcl_NewLongObj, Tcl_NewWideIntObj, Tcl_SetIntObj, Tcl_SetLongObj, Tcl_SetWideIntObj, Tcl_GetIntFromObj, Tcl_GetUIntFromObj, Tcl_GetLongFromObj, Tcl_GetWideIntFromObj, Tcl_NewBignumObj, Tcl_SetBignumObj, Tcl_GetBignumFromObj, Tcl_TakeBignumFromObj \- manipulate Tcl values as integers
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
Tcl_Obj *
\fBTcl_NewIntObj\fR(\fIintValue\fR)
.sp
................................................................................
\fBTcl_SetLongObj\fR(\fIobjPtr, longValue\fR)
.sp
\fBTcl_SetWideIntObj\fR(\fIobjPtr, wideValue\fR)
.sp
int
\fBTcl_GetIntFromObj\fR(\fIinterp, objPtr, intPtr\fR)
.sp
int
\fBTcl_GetUIntFromObj\fR(\fIinterp, objPtr, uintPtr\fR)
.sp
int
\fBTcl_GetLongFromObj\fR(\fIinterp, objPtr, longPtr\fR)
.sp
int
\fBTcl_GetValue\fR(\fIinterp, objPtr, ptr, flags\fR)
.sp
int
\fBTcl_GetWideIntFromObj\fR(\fIinterp, objPtr, widePtr\fR)
.sp
.sp
\fB#include <tclTomMath.h>\fR
.sp
Tcl_Obj *
................................................................................
integral value.  For \fBTcl_GetIntFromObj\fR, \fBTcl_GetLongFromObj\fR,
\fBTcl_GetWideIntFromObj\fR, \fBTcl_GetBignumFromObj\fR, and
\fBTcl_TakeBignumFromObj\fR, this refers to the value from which
to retrieve an integral value.
.AP Tcl_Interp *interp in/out
When non-NULL, an error message is left here when integral value
retrieval fails.
.AP short|int|long|Tcl_WideInt *intPtr out
Points to place to store the integer value retrieved from \fIobjPtr\fR.
.AP unsigned short|int|long|Tcl_WideInt *uintPtr out
Points to place to store the unsigned integer value retrieved from \fIobjPtr\fR.
.AP long *longPtr out
Points to place to store the long integer value retrieved from \fIobjPtr\fR.
.AP Tcl_WideInt *widePtr out
Points to place to store the wide integer value retrieved from \fIobjPtr\fR.
.AP short|int|long|Tcl_WideInt|float|double *ptr out
Points to place to store the integer or float value retrieved from \fIobjPtr\fR.
.AP mp_int *bigValue in/out
Points to a multi-precision integer structure declared by the LibTomMath
library.
.AP double doubleValue in
Double value from which the integer part is determined and
used to initialize a multi-precision integer value.
.BE
................................................................................
Tcl value pointed to by \fIobjPtr\fR to the integral value provided
by the other argument.  The \fIobjPtr\fR argument must point to an
unshared Tcl value.  Any attempt to set the value of a shared Tcl value
violates Tcl's copy-on-write policy.  Any existing string representation
or internal representation in the unshared Tcl value will be freed
as a consequence of setting the new value.
.PP
The \fBTcl_GetIntFromObj\fR, \fBTcl_GetUIntFromObj\fR, \fBTcl_GetLongFromObj\fR,
\fBTcl_GetWideIntFromObj\fR, \fBTcl_GetBignumFromObj\fR, and
\fBTcl_TakeBignumFromObj\fR routines attempt to retrieve an integral
value of the appropriate type from the Tcl value \fIobjPtr\fR.  If the
attempt succeeds, then \fBTCL_OK\fR is returned, and the value is
written to the storage provided by the caller.  The attempt might
fail if \fIobjPtr\fR does not hold an integral value, or if the
value exceeds the range of the target type.  If the attempt fails,

Changes to doc/StringObj.3.

115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
.AP int last in
The index of the last Unicode character in the Unicode range to be
returned as a new value.
.AP Tcl_Obj *objPtr in/out
Points to a value to manipulate.
.AP Tcl_Obj *appendObjPtr in
The value to append to \fIobjPtr\fR in \fBTcl_AppendObjToObj\fR.
.AP int *lengthPtr out
If non-NULL, the location where \fBTcl_GetStringFromObj\fR will store
the length of a value's string representation.
.AP "const char" *string in
Null-terminated string value to append to \fIobjPtr\fR.
.AP va_list argList in
An argument list which must have been initialized using
\fBva_start\fR, and cleared using \fBva_end\fR.






|







115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
.AP int last in
The index of the last Unicode character in the Unicode range to be
returned as a new value.
.AP Tcl_Obj *objPtr in/out
Points to a value to manipulate.
.AP Tcl_Obj *appendObjPtr in
The value to append to \fIobjPtr\fR in \fBTcl_AppendObjToObj\fR.
.AP size_t | int *lengthPtr out
If non-NULL, the location where \fBTcl_GetStringFromObj\fR will store
the length of a value's string representation.
.AP "const char" *string in
Null-terminated string value to append to \fIobjPtr\fR.
.AP va_list argList in
An argument list which must have been initialized using
\fBva_start\fR, and cleared using \fBva_end\fR.

Changes to doc/process.n.

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
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
..
98
99
100
101
102
103
104


105



106
107
108
109
110
111
112
113


114




115
116
117

118
119
120
121
122
123
124
125

126
127
128
129
130
131
tcl::process \- Subprocess management
.SH SYNOPSIS
\fB::tcl::process \fIoption \fR?\fIarg arg ...\fR?
.BE
.SH DESCRIPTION
.PP
This command provides a way to manage subprocesses created by the \fBopen\fR

and \fBexec\fR commands. The legal \fIoptions\fR (which may be abbreviated) are:
.TP










\fB::tcl::process list\fR
.
Returns the list of subprocess PIDs.









.TP
\fB::tcl::process status\fR ?\fIswitches\fR? ?\fIpids\fR?
.
Returns a dictionary mapping subprocess PIDs to their respective status. If
\fIpids\fR is specified as a list of PIDs then the command only returns the
status of the matching subprocesses if they exist, and raises an error
otherwise. For active processes, the status is an empty value. For terminated
processes, the status is a list with the following format:
.QW "{code ?\fImsg errorCode\fR?}" ,
where:
.RS
.TP
\fBcode\fR\0
.
is a standard Tcl return code,

.TP
\fBmsg\fR\0
.
is the human-readable error message,
.TP
\fBerrorCode\fR\0
.
uses the same format as the \fBerrorCode\fR global variable
.RE
Note that \fBmsg\fR and \fBerrorCode\fR are only present for abnormally
terminated processes (i.e. those where \fBcode\fR is nonzero). Under the hood
this command calls \fBTcl_WaitPid\fR with the \fBWNOHANG\fR flag set for
non-blocking behavior, unless the \fB\-wait\fR switch is set (see below).
.RS
.PP
Additionally, \fB::tcl::process status\fR accepts the following switches:
.TP
\fB\-wait\fR\0
.
By default the command returns immediately (the underlying \fBTcl_WaitPid\fR is
called with the \fBWNOHANG\fR flag set) unless this switch is set. If \fBpids\fR
is specified as a list of PIDs then the command waits until the status of the
matching subprocesses are available. If \fBpids\fR is not specified then it
waits for all known subprocesses.
.TP
\fB\-\|\-\fR
.
Marks the end of switches.  The argument following this one will
be treated as the first \fIarg\fR even if it starts with a \fB\-\fR.
.RE
.TP
\fB::tcl::process purge ?\fIpids\fR?
.
Cleans up all data associated with terminated subprocesses. If \fBpids\fR is
specified as a list of PIDs then the command only cleanup data for the matching
subprocesses if they exist, and raises an error otherwise. If the process is
still active then it does nothing.
.TP
\fB::tcl::process autopurge ?\fIflag\fR?
.
Automatic purge facility. If \fBflag\fR is specified as a boolean value then it
activates or deactivate autopurge. In all cases it returns the current status as
a boolean value. When autopurge is active, \fBTcl_ReapDetachedProcs\fR is called
each time the exec command is executed or a pipe channel created by open is
closed. When autopurge is inactive, \fB::tcl::process\fR purge must be called
explicitly. By default autopurge is active.
.RE
.SH "EXAMPLES"
.PP



.CS
\fB::tcl::process autopurge\fR
     \fI\(-> true\fR
\fB::tcl::process autopurge\fR false
     \fI\(-> false\fR

set pid1 [exec command1 a b c | command2 d e f &]
................................................................................
set pid2 [pid $chan]
     \fI\(-> 789 1011\fR

\fB::tcl::process list\fR
     \fI\(-> 123 456 789 1011\fR

\fB::tcl::process status\fR


     \fI\(-> 123 0 456 {1 "child killed: write on pipe with no readers" {CHILDKILLED 456 SIGPIPE "write on pipe with no readers"}} 789 {1 "child suspended: background tty read" {CHILDSUSP 789 SIGTTIN "background tty read"}} 1011 {}\fR




\fB::tcl::process status\fR 123
     \fI\(-> 123 0\fR

\fB::tcl::process status\fR 1011
     \fI\(-> 1011 {}\fR

\fB::tcl::process status\fR -wait


     \fI\(-> 123 0 456 {1 "child killed: write on pipe with no readers" {CHILDKILLED 456 SIGPIPE "write on pipe with no readers"}} 789 {1 "child suspended: background tty read" {CHILDSUSP 789 SIGTTIN "background tty read"}} 1011 {1 "child process exited abnormally" {CHILDSTATUS 1011 -1}}\fR





\fB::tcl::process status\fR 1011
     \fI\(-> 1011 {1 "child process exited abnormally" {CHILDSTATUS 1011 -1}}\fR


\fB::tcl::process purge\fR
exec command1 1 2 3 &
     \fI\(-> 1213\fR
\fB::tcl::process list\fR
     \fI\(-> 1213\fR
.CE
.SH "SEE ALSO"

exec(n), open(n), Tcl_DetachPids(3), Tcl_WaitPid(3), Tcl_ReapDetachedProcs(3)
.SH "KEYWORDS"
background, child, detach, process, wait
'\" Local Variables:
'\" mode: nroff
'\" End:






>
|

>
>
>
>
>
>
>
>
>
>


|
>
>
>
>
>
>
>
>
>








|



|

|
>

|



|


|

|
|

<






|

|
|






<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


>
>
>







 







>
>
|
>
>
>








>
>
|
>
>
>
>


|
>








>
|





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
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
...
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
tcl::process \- Subprocess management
.SH SYNOPSIS
\fB::tcl::process \fIoption \fR?\fIarg arg ...\fR?
.BE
.SH DESCRIPTION
.PP
This command provides a way to manage subprocesses created by the \fBopen\fR
and \fBexec\fR commands, as identified by the process identifiers (PIDs) of
those subprocesses. The legal \fIoptions\fR (which may be abbreviated) are:
.TP
\fB::tcl::process autopurge\fR ?\fIflag\fR?
.
Automatic purge facility. If \fIflag\fR is specified as a boolean value then
it activates or deactivate autopurge. In all cases it returns the current
status as a boolean value. When autopurge is active,
\fBTcl_ReapDetachedProcs\fR is called each time the \fBexec\fR command is
executed or a pipe channel created by \fBopen\fR is closed. When autopurge is
inactive, \fB::tcl::process\fR purge must be called explicitly. By default
autopurge is active.
.TP
\fB::tcl::process list\fR
.
Returns the list of subprocess PIDs. This includes all currently executing
subprocesses and all terminated subprocesses that have not yet had their
corresponding process table entries purged.
.TP
\fB::tcl::process purge\fR ?\fIpids\fR?
.
Cleans up all data associated with terminated subprocesses. If \fIpids\fR is
specified as a list of PIDs then the command only cleanup data for the matching
subprocesses if they exist, and raises an error otherwise. If a process listed is
still active, this command does nothing to that process.
.TP
\fB::tcl::process status\fR ?\fIswitches\fR? ?\fIpids\fR?
.
Returns a dictionary mapping subprocess PIDs to their respective status. If
\fIpids\fR is specified as a list of PIDs then the command only returns the
status of the matching subprocesses if they exist, and raises an error
otherwise. For active processes, the status is an empty value. For terminated
processes, the status is a list with the following format:
.QW "\fB{\fIcode\fR ?\fImsg errorCode\fR?\fB}\fR" ,
where:
.RS
.TP
\fIcode\fR\0
.
is a standard Tcl return code, i.e., \fB0\fR for TCL_OK and \fB1\fR
for TCL_ERROR,
.TP
\fImsg\fR\0
.
is the human-readable error message,
.TP
\fIerrorCode\fR\0
.
uses the same format as the \fBerrorCode\fR global variable
.PP
Note that \fBmsg\fR and \fBerrorCode\fR are only present for abnormally
terminated processes (i.e. those where the \fIcode\fR is nonzero). Under the
hood this command calls \fBTcl_WaitPid\fR with the \fBWNOHANG\fR flag set for
non-blocking behavior, unless the \fB\-wait\fR switch is set (see below).

.PP
Additionally, \fB::tcl::process status\fR accepts the following switches:
.TP
\fB\-wait\fR\0
.
By default the command returns immediately (the underlying \fBTcl_WaitPid\fR is
called with the \fBWNOHANG\fR flag set) unless this switch is set. If \fIpids\fR
is specified as a list of PIDs then the command waits until the status of the
matching subprocesses are available. If \fIpids\fR was not specified, this
command will wait for all known subprocesses.
.TP
\fB\-\|\-\fR
.
Marks the end of switches.  The argument following this one will
be treated as the first \fIarg\fR even if it starts with a \fB\-\fR.
.RE

















.SH "EXAMPLES"
.PP
These show the use of \fB::tcl::process\fR. Some of the results from
\fB::tcl::process status\fR are split over multiple lines for readability.
.PP
.CS
\fB::tcl::process autopurge\fR
     \fI\(-> true\fR
\fB::tcl::process autopurge\fR false
     \fI\(-> false\fR

set pid1 [exec command1 a b c | command2 d e f &]
................................................................................
set pid2 [pid $chan]
     \fI\(-> 789 1011\fR

\fB::tcl::process list\fR
     \fI\(-> 123 456 789 1011\fR

\fB::tcl::process status\fR
     \fI\(-> 123 0
       456 {1 "child killed: write on pipe with no readers" {
         CHILDKILLED 456 SIGPIPE "write on pipe with no readers"}}
       789 {1 "child suspended: background tty read" {
         CHILDSUSP 789 SIGTTIN "background tty read"}}
       1011 {}\fR

\fB::tcl::process status\fR 123
     \fI\(-> 123 0\fR

\fB::tcl::process status\fR 1011
     \fI\(-> 1011 {}\fR

\fB::tcl::process status\fR -wait
     \fI\(-> 123 0
       456 {1 "child killed: write on pipe with no readers" {
         CHILDKILLED 456 SIGPIPE "write on pipe with no readers"}}
       789 {1 "child suspended: background tty read" {
         CHILDSUSP 789 SIGTTIN "background tty read"}}
       1011 {1 "child process exited abnormally" {
         CHILDSTATUS 1011 -1}}\fR

\fB::tcl::process status\fR 1011
     \fI\(-> 1011 {1 "child process exited abnormally" {
         CHILDSTATUS 1011 -1}}\fR

\fB::tcl::process purge\fR
exec command1 1 2 3 &
     \fI\(-> 1213\fR
\fB::tcl::process list\fR
     \fI\(-> 1213\fR
.CE
.SH "SEE ALSO"
exec(n), open(n), pid(n),
Tcl_DetachPids(3), Tcl_WaitPid(3), Tcl_ReapDetachedProcs(3)
.SH "KEYWORDS"
background, child, detach, process, wait
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to generic/tcl.h.

1107
1108
1109
1110
1111
1112
1113

1114
1115
1116
1117
1118
1119
1120
1121
1122
#define TCL_LINK_WIDE_UINT	14
#define TCL_LINK_READ_ONLY	0x80

/*
 * Types for Tcl_GetValue():
 */


#define TCL_TYPE_I(type) (0x100 | (int)sizeof(type)) /* signed integer */
#define TCL_TYPE_D(type) (0x300 | (int)sizeof(type)) /* float/double/long double */
 
/*
 *----------------------------------------------------------------------------
 * Forward declarations of Tcl_HashTable and related types.
 */

#ifndef TCL_HASH_TYPE






>
|
|







1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
#define TCL_LINK_WIDE_UINT	14
#define TCL_LINK_READ_ONLY	0x80

/*
 * Types for Tcl_GetValue():
 */

#define TCL_TYPE_D(type) (0x100 | (int)sizeof(type)) /* float/double/long double */
#define TCL_TYPE_I(type) (0x200 | (int)sizeof(type)) /* signed integer */
#define TCL_TYPE_U(type) (0x300 | (int)sizeof(type)) /* unsigned integer */
 
/*
 *----------------------------------------------------------------------------
 * Forward declarations of Tcl_HashTable and related types.
 */

#ifndef TCL_HASH_TYPE

Changes to generic/tclBinary.c.

264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
...
474
475
476
477
478
479
480

481



482
483
484
485
486
487
488
...
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
...
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
...
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
 * The following structure is the internal rep for a ByteArray object. Keeps
 * track of how much memory has been used and how much has been allocated for
 * the byte array to enable growing and shrinking of the ByteArray object with
 * fewer mallocs.
 */

typedef struct ByteArray {
    unsigned int used;		/* The number of bytes used in the byte
				 * array. */
    unsigned int allocated;	/* The amount of space actually allocated
				 * minus 1 byte. */
    unsigned char bytes[1];	/* The array of bytes. The actual size of this
				 * field depends on the 'allocated' field
				 * above. */
} ByteArray;

#define BYTEARRAY_SIZE(len) \
		(TclOffset(ByteArray, bytes) + (len))
#define GET_BYTEARRAY(objPtr) \
		((ByteArray *) (objPtr)->internalRep.twoPtrValue.ptr1)
#define SET_BYTEARRAY(objPtr, baPtr) \
		(objPtr)->internalRep.twoPtrValue.ptr1 = (void *) (baPtr)

int
TclIsPureByteArray(
................................................................................
    if ((objPtr->typePtr != &properByteArrayType)
	    && (objPtr->typePtr != &tclByteArrayType)) {
	SetByteArrayFromAny(NULL, objPtr);
    }
    baPtr = GET_BYTEARRAY(objPtr);

    if (lengthPtr != NULL) {

	*lengthPtr = baPtr->used;



    }
    return (unsigned char *) baPtr->bytes;
}
 
/*
 *----------------------------------------------------------------------
 *
................................................................................
    }
    if ((objPtr->typePtr != &properByteArrayType)
	    && (objPtr->typePtr != &tclByteArrayType)) {
	SetByteArrayFromAny(NULL, objPtr);
    }

    byteArrayPtr = GET_BYTEARRAY(objPtr);
    if ((size_t)length > byteArrayPtr->allocated) {
	byteArrayPtr = ckrealloc(byteArrayPtr, BYTEARRAY_SIZE(length));
	byteArrayPtr->allocated = length;
	SET_BYTEARRAY(objPtr, byteArrayPtr);
    }
    TclInvalidateStringRep(objPtr);
    byteArrayPtr->used = length;
    return byteArrayPtr->bytes;
................................................................................
void
TclAppendBytesToByteArray(
    Tcl_Obj *objPtr,
    const unsigned char *bytes,
    int len)
{
    ByteArray *byteArrayPtr;
    size_t needed;

    if (Tcl_IsShared(objPtr)) {
	Tcl_Panic("%s called with shared object","TclAppendBytesToByteArray");
    }
    if (len < 0) {
	Tcl_Panic("%s must be called with definite number of bytes to append",
		"TclAppendBytesToByteArray");
................................................................................
    }
    if ((objPtr->typePtr != &properByteArrayType)
	    && (objPtr->typePtr != &tclByteArrayType)) {
	SetByteArrayFromAny(NULL, objPtr);
    }
    byteArrayPtr = GET_BYTEARRAY(objPtr);

    if ((size_t)len + byteArrayPtr->used > INT_MAX) {
	Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX);
    }

    needed = byteArrayPtr->used + len;
    /*
     * If we need to, resize the allocated space in the byte array.
     */






|

|







|







 







>

>
>
>







 







|







 







|







 







|







264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
...
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
...
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
...
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
...
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
 * The following structure is the internal rep for a ByteArray object. Keeps
 * track of how much memory has been used and how much has been allocated for
 * the byte array to enable growing and shrinking of the ByteArray object with
 * fewer mallocs.
 */

typedef struct ByteArray {
    int used;			/* The number of bytes used in the byte
				 * array. */
    int allocated;		/* The amount of space actually allocated
				 * minus 1 byte. */
    unsigned char bytes[1];	/* The array of bytes. The actual size of this
				 * field depends on the 'allocated' field
				 * above. */
} ByteArray;

#define BYTEARRAY_SIZE(len) \
		((unsigned) (TclOffset(ByteArray, bytes) + (len)))
#define GET_BYTEARRAY(objPtr) \
		((ByteArray *) (objPtr)->internalRep.twoPtrValue.ptr1)
#define SET_BYTEARRAY(objPtr, baPtr) \
		(objPtr)->internalRep.twoPtrValue.ptr1 = (void *) (baPtr)

int
TclIsPureByteArray(
................................................................................
    if ((objPtr->typePtr != &properByteArrayType)
	    && (objPtr->typePtr != &tclByteArrayType)) {
	SetByteArrayFromAny(NULL, objPtr);
    }
    baPtr = GET_BYTEARRAY(objPtr);

    if (lengthPtr != NULL) {
#if TCL_MAJOR_VERSION > 8
	*lengthPtr = baPtr->used;
#else
	*lengthPtr = (unsigned)baPtr->used;
#endif
    }
    return (unsigned char *) baPtr->bytes;
}
 
/*
 *----------------------------------------------------------------------
 *
................................................................................
    }
    if ((objPtr->typePtr != &properByteArrayType)
	    && (objPtr->typePtr != &tclByteArrayType)) {
	SetByteArrayFromAny(NULL, objPtr);
    }

    byteArrayPtr = GET_BYTEARRAY(objPtr);
    if (length > byteArrayPtr->allocated) {
	byteArrayPtr = ckrealloc(byteArrayPtr, BYTEARRAY_SIZE(length));
	byteArrayPtr->allocated = length;
	SET_BYTEARRAY(objPtr, byteArrayPtr);
    }
    TclInvalidateStringRep(objPtr);
    byteArrayPtr->used = length;
    return byteArrayPtr->bytes;
................................................................................
void
TclAppendBytesToByteArray(
    Tcl_Obj *objPtr,
    const unsigned char *bytes,
    int len)
{
    ByteArray *byteArrayPtr;
    int needed;

    if (Tcl_IsShared(objPtr)) {
	Tcl_Panic("%s called with shared object","TclAppendBytesToByteArray");
    }
    if (len < 0) {
	Tcl_Panic("%s must be called with definite number of bytes to append",
		"TclAppendBytesToByteArray");
................................................................................
    }
    if ((objPtr->typePtr != &properByteArrayType)
	    && (objPtr->typePtr != &tclByteArrayType)) {
	SetByteArrayFromAny(NULL, objPtr);
    }
    byteArrayPtr = GET_BYTEARRAY(objPtr);

    if (len > INT_MAX - byteArrayPtr->used) {
	Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX);
    }

    needed = byteArrayPtr->used + len;
    /*
     * If we need to, resize the allocated space in the byte array.
     */

Changes to generic/tclDecls.h.

4045
4046
4047
4048
4049
4050
4051


4052
4053
4054
4055
4056
4057
4058
#undef Tcl_GetByteArrayFromObj
#undef Tcl_GetUnicode
#if defined(USE_TCL_STUBS)
#define Tcl_GetDoubleFromObj(interp, objPtr, dblPtr) \
	(sizeof(*dblPtr) == sizeof(double) ? tclStubsPtr->tcl_GetDoubleFromObj(interp, objPtr, (double *)dblPtr) : tclStubsPtr->tcl_GetValue(interp, objPtr, dblPtr, TCL_TYPE_D(*dblPtr)))
#define Tcl_GetIntFromObj(interp, objPtr, intPtr) \
	(sizeof(*intPtr) == sizeof(int) ? tclStubsPtr->tcl_GetIntFromObj(interp, objPtr, (int *)intPtr) : tclStubsPtr->tcl_GetValue(interp, objPtr, intPtr, TCL_TYPE_I(*intPtr)))


#define Tcl_GetStringFromObj(objPtr, sizePtr) \
	(sizeof(*sizePtr) <= sizeof(int) ? tclStubsPtr->tcl_GetStringFromObj(objPtr, (int *)sizePtr) : tclStubsPtr->tcl_GetStringFromObj2(objPtr, (size_t *)sizePtr))
#define Tcl_GetByteArrayFromObj(objPtr, sizePtr) \
	(sizeof(*sizePtr) <= sizeof(int) ? tclStubsPtr->tcl_GetByteArrayFromObj(objPtr, (int *)sizePtr) : tclStubsPtr->tcl_GetByteArrayFromObj2(objPtr, (size_t *)sizePtr))
#define Tcl_GetUnicodeFromObj(objPtr, sizePtr) \
	(sizeof(*sizePtr) <= sizeof(int) ? tclStubsPtr->tcl_GetUnicodeFromObj(objPtr, (int *)sizePtr) : tclStubsPtr->tcl_GetUnicodeFromObj2(objPtr, (size_t *)sizePtr))
#define Tcl_GetUnicode(objPtr) \






>
>







4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
#undef Tcl_GetByteArrayFromObj
#undef Tcl_GetUnicode
#if defined(USE_TCL_STUBS)
#define Tcl_GetDoubleFromObj(interp, objPtr, dblPtr) \
	(sizeof(*dblPtr) == sizeof(double) ? tclStubsPtr->tcl_GetDoubleFromObj(interp, objPtr, (double *)dblPtr) : tclStubsPtr->tcl_GetValue(interp, objPtr, dblPtr, TCL_TYPE_D(*dblPtr)))
#define Tcl_GetIntFromObj(interp, objPtr, intPtr) \
	(sizeof(*intPtr) == sizeof(int) ? tclStubsPtr->tcl_GetIntFromObj(interp, objPtr, (int *)intPtr) : tclStubsPtr->tcl_GetValue(interp, objPtr, intPtr, TCL_TYPE_I(*intPtr)))
#define Tcl_GetUIntFromObj(interp, objPtr, intPtr) \
	(tclStubsPtr->tcl_GetValue(interp, objPtr, intPtr, TCL_TYPE_U(*intPtr)))
#define Tcl_GetStringFromObj(objPtr, sizePtr) \
	(sizeof(*sizePtr) <= sizeof(int) ? tclStubsPtr->tcl_GetStringFromObj(objPtr, (int *)sizePtr) : tclStubsPtr->tcl_GetStringFromObj2(objPtr, (size_t *)sizePtr))
#define Tcl_GetByteArrayFromObj(objPtr, sizePtr) \
	(sizeof(*sizePtr) <= sizeof(int) ? tclStubsPtr->tcl_GetByteArrayFromObj(objPtr, (int *)sizePtr) : tclStubsPtr->tcl_GetByteArrayFromObj2(objPtr, (size_t *)sizePtr))
#define Tcl_GetUnicodeFromObj(objPtr, sizePtr) \
	(sizeof(*sizePtr) <= sizeof(int) ? tclStubsPtr->tcl_GetUnicodeFromObj(objPtr, (int *)sizePtr) : tclStubsPtr->tcl_GetUnicodeFromObj2(objPtr, (size_t *)sizePtr))
#define Tcl_GetUnicode(objPtr) \

Changes to generic/tclObj.c.

1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
....
2583
2584
2585
2586
2587
2588
2589
2590


2591










2592
2593













2594
2595
2596
2597
2598
2599
2600
2601



2602
2603
2604
2605
2606
2607
2608
		|| objPtr->bytes[objPtr->length] != '\0') {
	    Tcl_Panic("UpdateStringProc for type '%s' "
		    "failed to create a valid string rep",
		    objPtr->typePtr->name);
	}
    }
    if (lengthPtr != NULL) {
#if TK_MAJOR_VERSION > 8
	*lengthPtr = objPtr->length;
#else
	*lengthPtr = (unsigned)objPtr->length;
#endif
    }
    return objPtr->bytes;
}
................................................................................
    Tcl_Obj *objPtr,           /* The object from which to get a int. */
    void *ptr,                 /* Place to store resulting int. */
    int flags)
{
    double value;
    int result;
    if (flags == TCL_TYPE_I(int)) {
	return Tcl_GetIntFromObj(interp, objPtr, ptr);


    }










    if (flags == TCL_TYPE_I(Tcl_WideInt)) {
	return Tcl_GetWideIntFromObj(interp, objPtr, ptr);













    }
    result = Tcl_GetDoubleFromObj(interp, objPtr, &value);
    if (flags == TCL_TYPE_D(double)) {
	*(double *)ptr = value;
    } else if (flags == TCL_TYPE_D(float)) {
	*(float *)ptr = (float) value;
    } else {
	*(long double *)ptr = (long double) value;



    }
    return result;
}

 
/*
 *----------------------------------------------------------------------






|







 







|
>
>
|
>
>
>
>
>
>
>
>
>
>

|
>
>
>
>
>
>
>
>
>
>
>
>
>






|

>
>
>







1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
....
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
		|| objPtr->bytes[objPtr->length] != '\0') {
	    Tcl_Panic("UpdateStringProc for type '%s' "
		    "failed to create a valid string rep",
		    objPtr->typePtr->name);
	}
    }
    if (lengthPtr != NULL) {
#if TCL_MAJOR_VERSION > 8
	*lengthPtr = objPtr->length;
#else
	*lengthPtr = (unsigned)objPtr->length;
#endif
    }
    return objPtr->bytes;
}
................................................................................
    Tcl_Obj *objPtr,           /* The object from which to get a int. */
    void *ptr,                 /* Place to store resulting int. */
    int flags)
{
    double value;
    int result;
    if (flags == TCL_TYPE_I(int)) {
	result = Tcl_GetIntFromObj(interp, objPtr, ptr);
	if ((result == TCL_OK) && (objPtr->typePtr != &tclIntType)) {
	    goto toolarge;
	}
	return result;
    }
    if (flags == TCL_TYPE_U(int)) {
	result = Tcl_GetIntFromObj(interp, objPtr, ptr);
	if ((result == TCL_OK) && (objPtr->typePtr == &tclIntType)
		&& (objPtr->internalRep.wideValue < 0)) {
	    goto toolarge;
	}
	return result;
    }
    if (flags == TCL_TYPE_I(Tcl_WideInt)) {
	return Tcl_GetIntFromObj(interp, objPtr, ptr);
    }
    if (flags == TCL_TYPE_U(Tcl_WideInt)) {
	result = Tcl_GetIntFromObj(interp, objPtr, ptr);
	if ((result == TCL_OK) && (objPtr->internalRep.wideValue < 0)) {
	toolarge:
		if (interp != NULL) {
		    const char *s = "integer value too large to represent";
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(s, -1));
		    Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW", s, NULL);
		}
	    return TCL_ERROR;
	}
	return result;
    }
    result = Tcl_GetDoubleFromObj(interp, objPtr, &value);
    if (flags == TCL_TYPE_D(double)) {
	*(double *)ptr = value;
    } else if (flags == TCL_TYPE_D(float)) {
	*(float *)ptr = (float) value;
    } else if (flags == TCL_TYPE_D(long double)) {
	*(long double *)ptr = (long double) value;
    } else {
	Tcl_Panic("%s: invalid flags value: 0x%x", "Tcl_GetValue", flags);
	return TCL_ERROR;
    }
    return result;
}

 
/*
 *----------------------------------------------------------------------

Changes to generic/tclTest.c.

1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
	    d = d1;
	}
    }
    if (status != TCL_OK
	|| Tcl_GetIntFromObj(interp, objv[2], &ndigits) != TCL_OK
	|| Tcl_GetIndexFromObj(interp, objv[3], options, "conversion type",
			       TCL_EXACT, &type) != TCL_OK) {
	fprintf(stderr, "bad value? %Lg\n", d);
	return TCL_ERROR;
    }
    type = types[type];
    if (objc > 4) {
	if (strcmp(Tcl_GetString(objv[4]), "shorten")) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("bad flag", -1));
	    return TCL_ERROR;






|







1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
	    d = d1;
	}
    }
    if (status != TCL_OK
	|| Tcl_GetIntFromObj(interp, objv[2], &ndigits) != TCL_OK
	|| Tcl_GetIndexFromObj(interp, objv[3], options, "conversion type",
			       TCL_EXACT, &type) != TCL_OK) {
	fprintf(stderr, "bad value? %g\n", (double)d);
	return TCL_ERROR;
    }
    type = types[type];
    if (objc > 4) {
	if (strcmp(Tcl_GetString(objv[4]), "shorten")) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("bad flag", -1));
	    return TCL_ERROR;

Changes to generic/tclThreadTest.c.

259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
...
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
...
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
	arg = 2;
	if ((objc == 4) || (objc == 5)) {
	    if (strcmp("-unwind", Tcl_GetString(objv[arg])) == 0) {
		flags = TCL_CANCEL_UNWIND;
		arg++;
	    }
	}
	if (Tcl_GetWideIntFromObj(interp, objv[arg], &id) != TCL_OK) {
	    return TCL_ERROR;
	}
	arg++;
	if (arg < objc) {
	    result = Tcl_GetString(objv[arg]);
	} else {
	    result = NULL;
................................................................................
	Tcl_WideInt id;
	int result, status;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "id");
	    return TCL_ERROR;
	}
	if (Tcl_GetWideIntFromObj(interp, objv[2], &id) != TCL_OK) {
	    return TCL_ERROR;
	}

	result = Tcl_JoinThread((Tcl_ThreadId)(size_t)id, &status);
	if (result == TCL_OK) {
	    Tcl_SetIntObj(Tcl_GetObjResult(interp), status);
	} else {
................................................................................
	    }
	    wait = 0;
	    arg = 3;
	} else {
	    wait = 1;
	    arg = 2;
	}
	if (Tcl_GetWideIntFromObj(interp, objv[arg], &id) != TCL_OK) {
	    return TCL_ERROR;
	}
	arg++;
	script = Tcl_GetString(objv[arg]);
	return ThreadSend(interp, (Tcl_ThreadId)(size_t)id, script, wait);
    }
    case THREAD_EVENT: {






|







 







|







 







|







259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
...
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
...
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
	arg = 2;
	if ((objc == 4) || (objc == 5)) {
	    if (strcmp("-unwind", Tcl_GetString(objv[arg])) == 0) {
		flags = TCL_CANCEL_UNWIND;
		arg++;
	    }
	}
	if (Tcl_GetIntFromObj(interp, objv[arg], &id) != TCL_OK) {
	    return TCL_ERROR;
	}
	arg++;
	if (arg < objc) {
	    result = Tcl_GetString(objv[arg]);
	} else {
	    result = NULL;
................................................................................
	Tcl_WideInt id;
	int result, status;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "id");
	    return TCL_ERROR;
	}
	if (Tcl_GetIntFromObj(interp, objv[2], &id) != TCL_OK) {
	    return TCL_ERROR;
	}

	result = Tcl_JoinThread((Tcl_ThreadId)(size_t)id, &status);
	if (result == TCL_OK) {
	    Tcl_SetIntObj(Tcl_GetObjResult(interp), status);
	} else {
................................................................................
	    }
	    wait = 0;
	    arg = 3;
	} else {
	    wait = 1;
	    arg = 2;
	}
	if (Tcl_GetIntFromObj(interp, objv[arg], &id) != TCL_OK) {
	    return TCL_ERROR;
	}
	arg++;
	script = Tcl_GetString(objv[arg]);
	return ThreadSend(interp, (Tcl_ThreadId)(size_t)id, script, wait);
    }
    case THREAD_EVENT: {

Changes to tests/winPipe.test.

319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
...
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
	set path(echoArgs.bat) [makeFile "@[file native [interpreter]] $path(echoArgs.tcl) %*" "echoArgs.bat"]
    }
    set cmds [list [list [interpreter] $path(echoArgs.tcl)]]
    if {!($single & 2)} {
	lappend cmds [list $path(echoArgs.bat)]
    } else {
	if {![info exists path(echoArgs2.bat)] || ![file exists $path(echoArgs2.bat)]} {
	    file mkdir [file join [temporaryDirectory] test(Dir)Check]
	    set path(echoArgs2.bat) [makeFile "@[file native [interpreter]] $path(echoArgs.tcl) %*" \
		"test(Dir)Check/echo(Cmd)Test Args & Batch.bat"]
	}
	lappend cmds [list $path(echoArgs2.bat)]
    }
    set broken {}
    foreach args $args {
	if {$single & 1} {
	    # enclose single test-arg between 1st/3rd to be sure nothing is truncated
................................................................................
# cleanup
removeFile little
removeFile big
removeFile more
removeFile stdout
removeFile stderr
removeFile nothing
removeFile echoArgs.tcl
removeFile echoArgs.bat
file delete -force [file join [temporaryDirectory] test(Dir)Check]
::tcltest::cleanupTests
return

# Local Variables:
# mode: tcl
# End:






<

|







 







|
|
|






319
320
321
322
323
324
325

326
327
328
329
330
331
332
333
334
...
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
	set path(echoArgs.bat) [makeFile "@[file native [interpreter]] $path(echoArgs.tcl) %*" "echoArgs.bat"]
    }
    set cmds [list [list [interpreter] $path(echoArgs.tcl)]]
    if {!($single & 2)} {
	lappend cmds [list $path(echoArgs.bat)]
    } else {
	if {![info exists path(echoArgs2.bat)] || ![file exists $path(echoArgs2.bat)]} {

	    set path(echoArgs2.bat) [makeFile "@[file native [interpreter]] $path(echoArgs.tcl) %*" \
		"[makeDirectory test(Dir)Check]/echo(Cmd)Test Args & Batch.bat"]
	}
	lappend cmds [list $path(echoArgs2.bat)]
    }
    set broken {}
    foreach args $args {
	if {$single & 1} {
	    # enclose single test-arg between 1st/3rd to be sure nothing is truncated
................................................................................
# cleanup
removeFile little
removeFile big
removeFile more
removeFile stdout
removeFile stderr
removeFile nothing
if {[info exists path(echoArgs.tcl)]} { removeFile echoArgs.tcl }
if {[info exists path(echoArgs.bat)]} { removeFile echoArgs.bat }
if {[info exists path(echoArgs2.bat)]} { removeDirectory test(Dir)Check }
::tcltest::cleanupTests
return

# Local Variables:
# mode: tcl
# End:

Changes to unix/tclUnixFCmd.c.

1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
    Tcl_Obj *attributePtr)	/* The attribute to set. */
{
    long mode;
    mode_t newMode;
    int result = TCL_ERROR;
    const char *native;
    const char *modeStringPtr = TclGetString(attributePtr);
    int scanned = TclParseAllWhiteSpace(modeStringPtr, -1);

    /*
     * First supply support for octal number format
     */

    if ((modeStringPtr[scanned] == '0')
	    && (modeStringPtr[scanned+1] >= '0')






|







1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
    Tcl_Obj *attributePtr)	/* The attribute to set. */
{
    long mode;
    mode_t newMode;
    int result = TCL_ERROR;
    const char *native;
    const char *modeStringPtr = TclGetString(attributePtr);
    size_t scanned = TclParseAllWhiteSpace(modeStringPtr, -1);

    /*
     * First supply support for octal number format
     */

    if ((modeStringPtr[scanned] == '0')
	    && (modeStringPtr[scanned+1] >= '0')