Tcl Source Code

Check-in [2f3da59db1]
Login

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

Overview
Comment:
* unix/tclUnixFCmd.c (TclUnixOpenTemporaryFile): [Bug 2933003]: Factor out all the code to do temporary file creation so that it is possible to make it correct in one place. Allow overriding of the back-stop default temporary file location at compile time by setting the TCL_TEMPORARY_FILE_DIRECTORY #def to a string containing the directory name (defaults to "/tmp" as that is the most common default).
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 2f3da59db1bf1d1d22fb6bb83f1120603b0a33bf
User & Date: dkf 2012-11-14 13:01:46
Context
2012-11-14
14:35
merge mark check-in: dc72be0dbc user: dkf tags: trunk
13:01
* unix/tclUnixFCmd.c (TclUnixOpenTemporaryFile): [Bug 2933003]: Factor out all the code to do temp...
check-in: 2f3da59db1 user: dkf tags: trunk
09:12
Workaround for mingw versions which don't provide _fpcontrol in float.h check-in: 73042d17c8 user: jan.nijtmans tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to ChangeLog.










1
2
3
4
5
6
7









2012-11-13  Joe Mistachkin  <[email protected]>

	* win/tclWinInit.c: also search for the library directory (init.tcl,
	encodings, etc) relative to the build directory associated with the
	source checkout.

2012-11-10  Miguel Sofer  <[email protected]>
>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2012-11-14  Donal K. Fellows  <[email protected]>

	* unix/tclUnixFCmd.c (TclUnixOpenTemporaryFile): [Bug 2933003]: Factor
	out all the code to do temporary file creation so that it is possible
	to make it correct in one place. Allow overriding of the back-stop
	default temporary file location at compile time by setting the
	TCL_TEMPORARY_FILE_DIRECTORY #def to a string containing the directory
	name (defaults to "/tmp" as that is the most common default).

2012-11-13  Joe Mistachkin  <[email protected]>

	* win/tclWinInit.c: also search for the library directory (init.tcl,
	encodings, etc) relative to the build directory associated with the
	source checkout.

2012-11-10  Miguel Sofer  <[email protected]>

Changes to generic/tclInt.decls.

1214
1215
1216
1217
1218
1219
1220






1221
1222
1223
1224
1225
1226
1227

# Added in 8.5:

declare 14 unix {
    int TclUnixCopyFile(const char *src, const char *dst,
	    const Tcl_StatBuf *statBufPtr, int dontCopyAtts)
}







################################
# Mac OS X specific functions

declare 15 macosx {
    int TclMacOSXGetFileAttribute(Tcl_Interp *interp, int objIndex,
	    Tcl_Obj *fileName, Tcl_Obj **attributePtrPtr)







>
>
>
>
>
>







1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233

# Added in 8.5:

declare 14 unix {
    int TclUnixCopyFile(const char *src, const char *dst,
	    const Tcl_StatBuf *statBufPtr, int dontCopyAtts)
}

# Added in 8.6; core of TclpOpenTemporaryFile
declare 20 unix {
    int TclUnixOpenTemporaryFile(Tcl_Obj *dirObj, Tcl_Obj *basenameObj,
	    Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj)
}

################################
# Mac OS X specific functions

declare 15 macosx {
    int TclMacOSXGetFileAttribute(Tcl_Interp *interp, int objIndex,
	    Tcl_Obj *fileName, Tcl_Obj **attributePtrPtr)

Changes to generic/tclIntPlatDecls.h.

80
81
82
83
84
85
86
87



88
89
90
91
92
93
94
				const Tcl_StatBuf *statBufPtr,
				int dontCopyAtts);
/* Slot 15 is reserved */
/* Slot 16 is reserved */
/* Slot 17 is reserved */
/* Slot 18 is reserved */
/* Slot 19 is reserved */
/* Slot 20 is reserved */



/* Slot 21 is reserved */
/* Slot 22 is reserved */
/* Slot 23 is reserved */
/* Slot 24 is reserved */
/* Slot 25 is reserved */
/* Slot 26 is reserved */
/* Slot 27 is reserved */







|
>
>
>







80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
				const Tcl_StatBuf *statBufPtr,
				int dontCopyAtts);
/* Slot 15 is reserved */
/* Slot 16 is reserved */
/* Slot 17 is reserved */
/* Slot 18 is reserved */
/* Slot 19 is reserved */
/* 20 */
EXTERN int		TclUnixOpenTemporaryFile(Tcl_Obj *dirObj,
				Tcl_Obj *basenameObj, Tcl_Obj *extensionObj,
				Tcl_Obj *resultingNameObj);
/* Slot 21 is reserved */
/* Slot 22 is reserved */
/* Slot 23 is reserved */
/* Slot 24 is reserved */
/* Slot 25 is reserved */
/* Slot 26 is reserved */
/* Slot 27 is reserved */
221
222
223
224
225
226
227
228



229
230
231
232
233
234
235
EXTERN int		TclMacOSXMatchType(Tcl_Interp *interp,
				const char *pathName, const char *fileName,
				Tcl_StatBuf *statBufPtr,
				Tcl_GlobTypeData *types);
/* 19 */
EXTERN void		TclMacOSXNotifierAddRunLoopMode(
				const void *runLoopMode);
/* Slot 20 is reserved */



/* Slot 21 is reserved */
/* Slot 22 is reserved */
/* Slot 23 is reserved */
/* Slot 24 is reserved */
/* Slot 25 is reserved */
/* Slot 26 is reserved */
/* Slot 27 is reserved */







|
>
>
>







224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
EXTERN int		TclMacOSXMatchType(Tcl_Interp *interp,
				const char *pathName, const char *fileName,
				Tcl_StatBuf *statBufPtr,
				Tcl_GlobTypeData *types);
/* 19 */
EXTERN void		TclMacOSXNotifierAddRunLoopMode(
				const void *runLoopMode);
/* 20 */
EXTERN int		TclUnixOpenTemporaryFile(Tcl_Obj *dirObj,
				Tcl_Obj *basenameObj, Tcl_Obj *extensionObj,
				Tcl_Obj *resultingNameObj);
/* Slot 21 is reserved */
/* Slot 22 is reserved */
/* Slot 23 is reserved */
/* Slot 24 is reserved */
/* Slot 25 is reserved */
/* Slot 26 is reserved */
/* Slot 27 is reserved */
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
    char * (*tclpInetNtoa) (struct in_addr addr); /* 13 */
    int (*tclUnixCopyFile) (const char *src, const char *dst, const Tcl_StatBuf *statBufPtr, int dontCopyAtts); /* 14 */
    void (*reserved15)(void);
    void (*reserved16)(void);
    void (*reserved17)(void);
    void (*reserved18)(void);
    void (*reserved19)(void);
    void (*reserved20)(void);
    void (*reserved21)(void);
    void (*reserved22)(void);
    void (*reserved23)(void);
    void (*reserved24)(void);
    void (*reserved25)(void);
    void (*reserved26)(void);
    void (*reserved27)(void);







|







265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
    char * (*tclpInetNtoa) (struct in_addr addr); /* 13 */
    int (*tclUnixCopyFile) (const char *src, const char *dst, const Tcl_StatBuf *statBufPtr, int dontCopyAtts); /* 14 */
    void (*reserved15)(void);
    void (*reserved16)(void);
    void (*reserved17)(void);
    void (*reserved18)(void);
    void (*reserved19)(void);
    int (*tclUnixOpenTemporaryFile) (Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj); /* 20 */
    void (*reserved21)(void);
    void (*reserved22)(void);
    void (*reserved23)(void);
    void (*reserved24)(void);
    void (*reserved25)(void);
    void (*reserved26)(void);
    void (*reserved27)(void);
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
    char * (*tclpInetNtoa) (struct in_addr addr); /* 13 */
    int (*tclUnixCopyFile) (const char *src, const char *dst, const Tcl_StatBuf *statBufPtr, int dontCopyAtts); /* 14 */
    int (*tclMacOSXGetFileAttribute) (Tcl_Interp *interp, int objIndex, Tcl_Obj *fileName, Tcl_Obj **attributePtrPtr); /* 15 */
    int (*tclMacOSXSetFileAttribute) (Tcl_Interp *interp, int objIndex, Tcl_Obj *fileName, Tcl_Obj *attributePtr); /* 16 */
    int (*tclMacOSXCopyFileAttributes) (const char *src, const char *dst, const Tcl_StatBuf *statBufPtr); /* 17 */
    int (*tclMacOSXMatchType) (Tcl_Interp *interp, const char *pathName, const char *fileName, Tcl_StatBuf *statBufPtr, Tcl_GlobTypeData *types); /* 18 */
    void (*tclMacOSXNotifierAddRunLoopMode) (const void *runLoopMode); /* 19 */
    void (*reserved20)(void);
    void (*reserved21)(void);
    void (*reserved22)(void);
    void (*reserved23)(void);
    void (*reserved24)(void);
    void (*reserved25)(void);
    void (*reserved26)(void);
    void (*reserved27)(void);







|







329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
    char * (*tclpInetNtoa) (struct in_addr addr); /* 13 */
    int (*tclUnixCopyFile) (const char *src, const char *dst, const Tcl_StatBuf *statBufPtr, int dontCopyAtts); /* 14 */
    int (*tclMacOSXGetFileAttribute) (Tcl_Interp *interp, int objIndex, Tcl_Obj *fileName, Tcl_Obj **attributePtrPtr); /* 15 */
    int (*tclMacOSXSetFileAttribute) (Tcl_Interp *interp, int objIndex, Tcl_Obj *fileName, Tcl_Obj *attributePtr); /* 16 */
    int (*tclMacOSXCopyFileAttributes) (const char *src, const char *dst, const Tcl_StatBuf *statBufPtr); /* 17 */
    int (*tclMacOSXMatchType) (Tcl_Interp *interp, const char *pathName, const char *fileName, Tcl_StatBuf *statBufPtr, Tcl_GlobTypeData *types); /* 18 */
    void (*tclMacOSXNotifierAddRunLoopMode) (const void *runLoopMode); /* 19 */
    int (*tclUnixOpenTemporaryFile) (Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj); /* 20 */
    void (*reserved21)(void);
    void (*reserved22)(void);
    void (*reserved23)(void);
    void (*reserved24)(void);
    void (*reserved25)(void);
    void (*reserved26)(void);
    void (*reserved27)(void);
385
386
387
388
389
390
391
392

393
394
395
396
397
398
399
#define TclUnixCopyFile \
	(tclIntPlatStubsPtr->tclUnixCopyFile) /* 14 */
/* Slot 15 is reserved */
/* Slot 16 is reserved */
/* Slot 17 is reserved */
/* Slot 18 is reserved */
/* Slot 19 is reserved */
/* Slot 20 is reserved */

/* Slot 21 is reserved */
/* Slot 22 is reserved */
/* Slot 23 is reserved */
/* Slot 24 is reserved */
/* Slot 25 is reserved */
/* Slot 26 is reserved */
/* Slot 27 is reserved */







|
>







391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
#define TclUnixCopyFile \
	(tclIntPlatStubsPtr->tclUnixCopyFile) /* 14 */
/* Slot 15 is reserved */
/* Slot 16 is reserved */
/* Slot 17 is reserved */
/* Slot 18 is reserved */
/* Slot 19 is reserved */
#define TclUnixOpenTemporaryFile \
	(tclIntPlatStubsPtr->tclUnixOpenTemporaryFile) /* 20 */
/* Slot 21 is reserved */
/* Slot 22 is reserved */
/* Slot 23 is reserved */
/* Slot 24 is reserved */
/* Slot 25 is reserved */
/* Slot 26 is reserved */
/* Slot 27 is reserved */
497
498
499
500
501
502
503
504

505
506
507
508
509
510
511
	(tclIntPlatStubsPtr->tclMacOSXSetFileAttribute) /* 16 */
#define TclMacOSXCopyFileAttributes \
	(tclIntPlatStubsPtr->tclMacOSXCopyFileAttributes) /* 17 */
#define TclMacOSXMatchType \
	(tclIntPlatStubsPtr->tclMacOSXMatchType) /* 18 */
#define TclMacOSXNotifierAddRunLoopMode \
	(tclIntPlatStubsPtr->tclMacOSXNotifierAddRunLoopMode) /* 19 */
/* Slot 20 is reserved */

/* Slot 21 is reserved */
/* Slot 22 is reserved */
/* Slot 23 is reserved */
/* Slot 24 is reserved */
/* Slot 25 is reserved */
/* Slot 26 is reserved */
/* Slot 27 is reserved */







|
>







504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
	(tclIntPlatStubsPtr->tclMacOSXSetFileAttribute) /* 16 */
#define TclMacOSXCopyFileAttributes \
	(tclIntPlatStubsPtr->tclMacOSXCopyFileAttributes) /* 17 */
#define TclMacOSXMatchType \
	(tclIntPlatStubsPtr->tclMacOSXMatchType) /* 18 */
#define TclMacOSXNotifierAddRunLoopMode \
	(tclIntPlatStubsPtr->tclMacOSXNotifierAddRunLoopMode) /* 19 */
#define TclUnixOpenTemporaryFile \
	(tclIntPlatStubsPtr->tclUnixOpenTemporaryFile) /* 20 */
/* Slot 21 is reserved */
/* Slot 22 is reserved */
/* Slot 23 is reserved */
/* Slot 24 is reserved */
/* Slot 25 is reserved */
/* Slot 26 is reserved */
/* Slot 27 is reserved */

Changes to generic/tclStubInit.c.

461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
    TclpInetNtoa, /* 13 */
    TclUnixCopyFile, /* 14 */
    0, /* 15 */
    0, /* 16 */
    0, /* 17 */
    0, /* 18 */
    0, /* 19 */
    0, /* 20 */
    0, /* 21 */
    0, /* 22 */
    0, /* 23 */
    0, /* 24 */
    0, /* 25 */
    0, /* 26 */
    0, /* 27 */







|







461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
    TclpInetNtoa, /* 13 */
    TclUnixCopyFile, /* 14 */
    0, /* 15 */
    0, /* 16 */
    0, /* 17 */
    0, /* 18 */
    0, /* 19 */
    TclUnixOpenTemporaryFile, /* 20 */
    0, /* 21 */
    0, /* 22 */
    0, /* 23 */
    0, /* 24 */
    0, /* 25 */
    0, /* 26 */
    0, /* 27 */
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
    TclpInetNtoa, /* 13 */
    TclUnixCopyFile, /* 14 */
    TclMacOSXGetFileAttribute, /* 15 */
    TclMacOSXSetFileAttribute, /* 16 */
    TclMacOSXCopyFileAttributes, /* 17 */
    TclMacOSXMatchType, /* 18 */
    TclMacOSXNotifierAddRunLoopMode, /* 19 */
    0, /* 20 */
    0, /* 21 */
    0, /* 22 */
    0, /* 23 */
    0, /* 24 */
    0, /* 25 */
    0, /* 26 */
    0, /* 27 */







|







525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
    TclpInetNtoa, /* 13 */
    TclUnixCopyFile, /* 14 */
    TclMacOSXGetFileAttribute, /* 15 */
    TclMacOSXSetFileAttribute, /* 16 */
    TclMacOSXCopyFileAttributes, /* 17 */
    TclMacOSXMatchType, /* 18 */
    TclMacOSXNotifierAddRunLoopMode, /* 19 */
    TclUnixOpenTemporaryFile, /* 20 */
    0, /* 21 */
    0, /* 22 */
    0, /* 23 */
    0, /* 24 */
    0, /* 25 */
    0, /* 26 */
    0, /* 27 */

Changes to unix/tclUnixFCmd.c.

57
58
59
60
61
62
63










64
65
66
67
68
69
70
 * TraverseUnixTree() calls the traverseProc()
 */

#define DOTREE_PRED	1	/* pre-order directory */
#define DOTREE_POSTD	2	/* post-order directory */
#define DOTREE_F	3	/* regular file */











/*
 * Callbacks for file attributes code.
 */

static int		GetGroupAttribute(Tcl_Interp *interp, int objIndex,
			    Tcl_Obj *fileName, Tcl_Obj **attributePtrPtr);
static int		GetOwnerAttribute(Tcl_Interp *interp, int objIndex,







>
>
>
>
>
>
>
>
>
>







57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
 * TraverseUnixTree() calls the traverseProc()
 */

#define DOTREE_PRED	1	/* pre-order directory */
#define DOTREE_POSTD	2	/* post-order directory */
#define DOTREE_F	3	/* regular file */

/*
 * Fallback temporary file location the temporary file generation code. Can be
 * overridden at compile time for when it is known that temp files can't be
 * written to /tmp (hello, iOS!).
 */

#ifndef TCL_TEMPORARY_FILE_DIRECTORY
#define TCL_TEMPORARY_FILE_DIRECTORY	"/tmp"
#endif

/*
 * Callbacks for file attributes code.
 */

static int		GetGroupAttribute(Tcl_Interp *interp, int objIndex,
			    Tcl_Obj *fileName, Tcl_Obj **attributePtrPtr);
static int		GetOwnerAttribute(Tcl_Interp *interp, int objIndex,
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106





2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117


2118













2119
2120
2121
2122




2123
2124
2125
2126
2127
2128
2129

    return nextCheckpoint;
}

/*
 *----------------------------------------------------------------------
 *
 * TclpOpenTemporaryFile --
 *
 *	Creates a temporary file, possibly based on the supplied bits and
 *	pieces of template supplied in the first three arguments. If the
 *	fourth argument is non-NULL, it contains a Tcl_Obj to store the name
 *	of the temporary file in (and it is caller's responsibility to clean
 *	up). If the fourth argument is NULL, try to arrange for the temporary
 *	file to go away once it is no longer needed.
 *
 * Results:
 *	A read-write Tcl Channel open on the file.





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

Tcl_Channel
TclpOpenTemporaryFile(
    Tcl_Obj *dirObj,
    Tcl_Obj *basenameObj,
    Tcl_Obj *extensionObj,
    Tcl_Obj *resultingNameObj)
{


    Tcl_Channel chan;













    Tcl_DString template, tmp;
    const char *string;
    int len, fd;





    if (dirObj) {
	string = Tcl_GetStringFromObj(dirObj, &len);
	Tcl_UtfToExternalDString(NULL, string, len, &template);
    } else {
	Tcl_DStringInit(&template);
	Tcl_DStringAppend(&template, DefaultTempDir(), -1); /* INTL: native */
    }







|









|
>
>
>
>
>











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




>
>
>
>







2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163

    return nextCheckpoint;
}

/*
 *----------------------------------------------------------------------
 *
 * TclpOpenTemporaryFile, TclUnixOpenTemporaryFile --
 *
 *	Creates a temporary file, possibly based on the supplied bits and
 *	pieces of template supplied in the first three arguments. If the
 *	fourth argument is non-NULL, it contains a Tcl_Obj to store the name
 *	of the temporary file in (and it is caller's responsibility to clean
 *	up). If the fourth argument is NULL, try to arrange for the temporary
 *	file to go away once it is no longer needed.
 *
 * Results:
 *	A read-write Tcl Channel open on the file for TclpOpenTemporaryFile,
 *	or a file descriptor (or -1 on failure) for TclUnixOpenTemporaryFile.
 *
 * Side effects:
 *	Accesses the filesystem. Will set the contents of the Tcl_Obj fourth
 *	argument (if that is non-NULL).
 *
 *----------------------------------------------------------------------
 */

Tcl_Channel
TclpOpenTemporaryFile(
    Tcl_Obj *dirObj,
    Tcl_Obj *basenameObj,
    Tcl_Obj *extensionObj,
    Tcl_Obj *resultingNameObj)
{
    int fd = TclUnixOpenTemporaryFile(dirObj, basenameObj, extensionObj,
	    resultingNameObj);

    if (fd == -1) {
	return NULL;
    }
    return Tcl_MakeFileChannel(INT2PTR(fd), TCL_READABLE|TCL_WRITABLE);
}

int
TclUnixOpenTemporaryFile(
    Tcl_Obj *dirObj,
    Tcl_Obj *basenameObj,
    Tcl_Obj *extensionObj,
    Tcl_Obj *resultingNameObj)
{
    Tcl_DString template, tmp;
    const char *string;
    int len, fd;

    /*
     * We should also check against making more then TMP_MAX of these.
     */

    if (dirObj) {
	string = Tcl_GetStringFromObj(dirObj, &len);
	Tcl_UtfToExternalDString(NULL, string, len, &template);
    } else {
	Tcl_DStringInit(&template);
	Tcl_DStringAppend(&template, DefaultTempDir(), -1); /* INTL: native */
    }
2151
2152
2153
2154
2155
2156
2157

2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
    } else
#endif
    {
	fd = mkstemp(Tcl_DStringValue(&template));
    }

    if (fd == -1) {

	return NULL;
    }
    chan = Tcl_MakeFileChannel(INT2PTR(fd), TCL_READABLE|TCL_WRITABLE);
    if (resultingNameObj) {
	Tcl_ExternalToUtfDString(NULL, Tcl_DStringValue(&template),
		Tcl_DStringLength(&template), &tmp);
	Tcl_SetStringObj(resultingNameObj, Tcl_DStringValue(&tmp),
		Tcl_DStringLength(&tmp));
	Tcl_DStringFree(&tmp);
    } else {
	/*
	 * Try to delete the file immediately since we're not reporting the
	 * name to anyone. Note that we're *not* handling any errors from
	 * this!
	 */

	unlink(Tcl_DStringValue(&template));
	errno = 0;
    }
    Tcl_DStringFree(&template);

    return chan;
}

/*
 * Helper that does *part* of what tempnam() does.
 */

static const char *







>
|

|


















|







2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
    } else
#endif
    {
	fd = mkstemp(Tcl_DStringValue(&template));
    }

    if (fd == -1) {
	Tcl_DStringFree(&template);
	return -1;
    }

    if (resultingNameObj) {
	Tcl_ExternalToUtfDString(NULL, Tcl_DStringValue(&template),
		Tcl_DStringLength(&template), &tmp);
	Tcl_SetStringObj(resultingNameObj, Tcl_DStringValue(&tmp),
		Tcl_DStringLength(&tmp));
	Tcl_DStringFree(&tmp);
    } else {
	/*
	 * Try to delete the file immediately since we're not reporting the
	 * name to anyone. Note that we're *not* handling any errors from
	 * this!
	 */

	unlink(Tcl_DStringValue(&template));
	errno = 0;
    }
    Tcl_DStringFree(&template);

    return fd;
}

/*
 * Helper that does *part* of what tempnam() does.
 */

static const char *
2199
2200
2201
2202
2203
2204
2205

2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
    dir = P_tmpdir;
    if (stat(dir, &buf) == 0 && S_ISDIR(buf.st_mode) && access(dir, W_OK)) {
	return dir;
    }
#endif

    /*

     * Assume that "/tmp" is always an existing writable directory; we've no
     * recovery mechanism if it isn't.
     */

    return "/tmp";
}

#if defined(HAVE_CHFLAGS) && defined(UF_IMMUTABLE)
/*
 *----------------------------------------------------------------------
 *
 * GetReadOnlyAttribute







>
|
|


|







2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
    dir = P_tmpdir;
    if (stat(dir, &buf) == 0 && S_ISDIR(buf.st_mode) && access(dir, W_OK)) {
	return dir;
    }
#endif

    /*
     * Assume that the default location ("/tmp" if not overridden) is always
     * an existing writable directory; we've no recovery mechanism if it
     * isn't.
     */

    return TCL_TEMPORARY_FILE_DIRECTORY;
}

#if defined(HAVE_CHFLAGS) && defined(UF_IMMUTABLE)
/*
 *----------------------------------------------------------------------
 *
 * GetReadOnlyAttribute

Changes to unix/tclUnixPipe.c.

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
 *----------------------------------------------------------------------
 */

TclFile
TclpCreateTempFile(
    const char *contents)	/* String to write into temp file, or NULL. */
{
    char fileName[L_tmpnam + 9];
    const char *native;
    Tcl_DString dstring;
    int fd;

    /*
     * We should also check against making more then TMP_MAX of these.
     */

    strcpy(fileName, P_tmpdir);				/* INTL: Native. */
    if (fileName[strlen(fileName) - 1] != '/') {
	strcat(fileName, "/");				/* INTL: Native. */
    }
    strcat(fileName, "tclXXXXXX");
    fd = mkstemp(fileName);				/* INTL: Native. */
    if (fd == -1) {
	return NULL;
    }
    fcntl(fd, F_SETFD, FD_CLOEXEC);


    unlink(fileName);					/* INTL: Native. */

    if (contents != NULL) {
	native = Tcl_UtfToExternalDString(NULL, contents, -1, &dstring);
	if (write(fd, native, Tcl_DStringLength(&dstring)) == -1) {
	    close(fd);
	    Tcl_DStringFree(&dstring);
	    return NULL;
	}
	Tcl_DStringFree(&dstring);







<
<
<
<
|
<
<
<

<
<
<
<
<
<




>
>
|

<







184
185
186
187
188
189
190




191



192






193
194
195
196
197
198
199
200

201
202
203
204
205
206
207
 *----------------------------------------------------------------------
 */

TclFile
TclpCreateTempFile(
    const char *contents)	/* String to write into temp file, or NULL. */
{




    int fd = TclUnixOpenTemporaryFile(NULL, NULL, NULL, NULL);










    if (fd == -1) {
	return NULL;
    }
    fcntl(fd, F_SETFD, FD_CLOEXEC);
    if (contents != NULL) {
	Tcl_DString dstring;
	char *native;


	native = Tcl_UtfToExternalDString(NULL, contents, -1, &dstring);
	if (write(fd, native, Tcl_DStringLength(&dstring)) == -1) {
	    close(fd);
	    Tcl_DStringFree(&dstring);
	    return NULL;
	}
	Tcl_DStringFree(&dstring);
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258

259
260

261
262
263
264
265
266
267
268
269
270
271
272
273
 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
TclpTempFileName(void)
{
    char fileName[L_tmpnam + 9];
    Tcl_Obj *result = NULL;
    int fd;

    /*
     * We should also check against making more then TMP_MAX of these.
     */

    strcpy(fileName, P_tmpdir);		/* INTL: Native. */
    if (fileName[strlen(fileName) - 1] != '/') {
	strcat(fileName, "/");		/* INTL: Native. */
    }
    strcat(fileName, "tclXXXXXX");
    fd = mkstemp(fileName);		/* INTL: Native. */
    if (fd == -1) {

	return NULL;
    }

    fcntl(fd, F_SETFD, FD_CLOEXEC);
    unlink(fileName);			/* INTL: Native. */

    result = TclpNativeToNormalized(fileName);
    close(fd);
    return result;
}

/*
 *----------------------------------------------------------------------------
 *
 * TclpTempFileNameForLibrary --
 *







<
|


<
<
<
|
<
<
<
<
<
|

>


>

<
|
<

|







225
226
227
228
229
230
231

232
233
234



235





236
237
238
239
240
241
242

243

244
245
246
247
248
249
250
251
252
 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
TclpTempFileName(void)
{

    Tcl_Obj *nameObj = Tcl_NewObj();
    int fd;




    Tcl_IncrRefCount(nameObj);





    fd = TclUnixOpenTemporaryFile(NULL, NULL, NULL, nameObj);
    if (fd == -1) {
	Tcl_DecrRefCount(nameObj);
	return NULL;
    }

    fcntl(fd, F_SETFD, FD_CLOEXEC);

    TclpObjDeleteFile(nameObj);

    close(fd);
    return nameObj;
}

/*
 *----------------------------------------------------------------------------
 *
 * TclpTempFileNameForLibrary --
 *