1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
-
+
|
/*
* tclWinPipe.c --
*
* This file implements the Windows-specific exec pipeline functions, the
* "pipe" channel driver, and the "pid" Tcl command.
*
* Copyright (c) 1996-1997 by Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* RCS: @(#) $Id: tclWinPipe.c,v 1.35.2.17 2008/11/10 02:18:42 dgp Exp $
* RCS: @(#) $Id: tclWinPipe.c,v 1.35.2.18 2008/12/01 16:44:51 dgp Exp $
*/
#include "tclWinInt.h"
#include <fcntl.h>
#include <io.h>
#include <sys/stat.h>
|
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
|
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
|
-
+
-
-
+
-
-
+
-
-
-
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
-
-
+
+
-
-
+
-
+
-
-
+
-
|
* "file%d" as the base name for pipes even though it would be more
* natural to use "pipe%d". Use the pointer to keep the channel names
* unique, in case channels share handles (stdin/stdout).
*/
wsprintfA(channelName, "file%lx", infoPtr);
infoPtr->channel = Tcl_CreateChannel(&pipeChannelType, channelName,
(ClientData) infoPtr, infoPtr->validMask);
infoPtr, infoPtr->validMask);
/*
* Pipes have AUTO translation mode on Windows and ^Z eof char, which
* means that a ^Z will be appended to them at close. This is needed for
* Windows programs that expect a ^Z at EOF.
*/
Tcl_SetChannelOption((Tcl_Interp *) NULL, infoPtr->channel,
"-translation", "auto");
Tcl_SetChannelOption(NULL, infoPtr->channel, "-translation", "auto");
Tcl_SetChannelOption((Tcl_Interp *) NULL, infoPtr->channel,
"-eofchar", "\032 {}");
Tcl_SetChannelOption(NULL, infoPtr->channel, "-eofchar", "\032 {}");
return infoPtr->channel;
}
/*
*----------------------------------------------------------------------
*
* Tcl_CreatePipe --
*
* System dependent interface to create a pipe for the [chan pipe]
* command. Stolen from TclX.
*
* Parameters:
* o interp - Errors returned in result.
* o rchan, wchan - Returned read and write side.
* o flags - Reserved for future use.
* Results:
* TCL_OK or TCL_ERROR.
* TCL_OK or TCL_ERROR.
*
*----------------------------------------------------------------------
*/
int
Tcl_CreatePipe (
Tcl_Interp *interp,
Tcl_Channel *rchan,
Tcl_Channel *wchan,
int flags
Tcl_CreatePipe(
Tcl_Interp *interp, /* Errors returned in result.*/
Tcl_Channel *rchan, /* Where to return the read side. */
Tcl_Channel *wchan, /* Where to return the write side. */
int flags) /* Reserved for future use. */
)
{
HANDLE readHandle, writeHandle;
SECURITY_ATTRIBUTES sec;
sec.nLength = sizeof(SECURITY_ATTRIBUTES);
sec.lpSecurityDescriptor = NULL;
sec.bInheritHandle = FALSE;
if (!CreatePipe (&readHandle, &writeHandle, &sec, 0)) {
TclWinConvertError (GetLastError ());
Tcl_AppendResult (interp, "pipe creation failed: ",
Tcl_PosixError (interp), (char *) NULL);
return TCL_ERROR;
if (!CreatePipe(&readHandle, &writeHandle, &sec, 0)) {
TclWinConvertError(GetLastError());
Tcl_AppendResult(interp, "pipe creation failed: ",
Tcl_PosixError(interp), NULL);
return TCL_ERROR;
}
*rchan = Tcl_MakeFileChannel ((ClientData) readHandle,
*rchan = Tcl_MakeFileChannel((ClientData) readHandle, TCL_READABLE);
TCL_READABLE);
Tcl_RegisterChannel (interp, *rchan);
Tcl_RegisterChannel(interp, *rchan);
*wchan = Tcl_MakeFileChannel ((ClientData) writeHandle,
*wchan = Tcl_MakeFileChannel((ClientData) writeHandle, TCL_WRITABLE);
TCL_WRITABLE);
Tcl_RegisterChannel (interp, *wchan);
Tcl_RegisterChannel(interp, *wchan);
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
* TclGetAndDetachPids --
*
* Stores a list of the command PIDs for a command channel in the
|
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
|
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
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
infoPtr->threadId = Tcl_GetChannelThread(infoPtr->channel);
}
} else {
infoPtr->threadId = NULL;
}
Tcl_MutexUnlock(&pipeMutex);
}
/*
*----------------------------------------------------------------------
*
* 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)
{
WCHAR name[MAX_PATH];
HANDLE handle;
DWORD flags = FILE_ATTRIBUTE_TEMPORARY;
if (!resultingNameObj) {
flags |= FILE_FLAG_DELETE_ON_CLOSE;
}
do {
if (TempFileName(name) == 0) {
TclWinConvertError(GetLastError());
return NULL;
}
handle = tclWinProcs->createFileProc((TCHAR *) name,
GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_NEW, flags, NULL);
} while (handle == INVALID_HANDLE_VALUE
&& GetLastError() == ERROR_FILE_EXISTS);
if (handle == INVALID_HANDLE_VALUE) {
TclWinConvertError(GetLastError());
return NULL;
}
if (resultingNameObj) {
Tcl_Obj *tmpObj = TclpNativeToNormalized(name);
Tcl_AppendObjToObj(resultingNameObj, tmpObj);
TclDecrRefCount(tmpObj);
}
return Tcl_MakeFileChannel((ClientData) handle,
TCL_READABLE|TCL_WRITABLE);
}
/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* End:
*/
|