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.31 2010/09/22 02:42:51 dgp Exp $
* RCS: @(#) $Id: tclWinPipe.c,v 1.35.2.32 2010/10/12 13:17:26 dgp Exp $
*/
#include "tclWinInt.h"
#include <sys/stat.h>
/*
|
| ︙ | | |
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
|
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
|
-
-
+
+
-
+
|
static int
TempFileName(
TCHAR name[MAX_PATH]) /* Buffer in which name for temporary file
* gets stored. */
{
TCHAR *prefix = TEXT("TCL");
if (tclWinProcs->getTempPathProc(MAX_PATH, name) != 0) {
if (tclWinProcs->getTempFileNameProc(name, prefix, 0, name) != 0) {
if (GetTempPath(MAX_PATH, name) != 0) {
if (GetTempFileName(name, prefix, 0, name) != 0) {
return 1;
}
}
name[0] = '.';
name[1] = '\0';
return tclWinProcs->getTempFileNameProc(name, prefix, 0, name);
return GetTempFileName(name, prefix, 0, name);
}
/*
*----------------------------------------------------------------------
*
* TclpMakeFile --
*
|
| ︙ | | |
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
|
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
|
-
+
-
+
-
+
|
createMode = TRUNCATE_EXISTING;
break;
default:
createMode = OPEN_EXISTING;
break;
}
nativePath = tclWinProcs->utf2tchar(path, -1, &ds);
nativePath = Tcl_WinUtfToTChar(path, -1, &ds);
/*
* If the file is not being created, use the existing file attributes.
*/
flags = 0;
if (!(mode & O_CREAT)) {
flags = tclWinProcs->getFileAttributesProc(nativePath);
flags = GetFileAttributes(nativePath);
if (flags == 0xFFFFFFFF) {
flags = 0;
}
}
/*
* Set up the file sharing mode. We want to allow simultaneous access.
*/
shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
/*
* Now we get to create the file.
*/
handle = tclWinProcs->createFileProc(nativePath, accessMode, shareMode,
handle = CreateFile(nativePath, accessMode, shareMode,
NULL, createMode, flags, NULL);
Tcl_DStringFree(&ds);
if (handle == INVALID_HANDLE_VALUE) {
DWORD err;
err = GetLastError();
|
| ︙ | | |
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
|
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
|
-
+
|
Tcl_DString dstring;
HANDLE handle;
if (TempFileName(name) == 0) {
return NULL;
}
handle = tclWinProcs->createFileProc((TCHAR *) name,
handle = CreateFile(name,
GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_DELETE_ON_CLOSE, NULL);
if (handle == INVALID_HANDLE_VALUE) {
goto error;
}
/*
|
| ︙ | | |
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
|
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
|
-
+
|
if (contents != NULL) {
Tcl_DStringFree(&dstring);
}
TclWinConvertError(GetLastError());
CloseHandle(handle);
tclWinProcs->deleteFileProc((TCHAR *) name);
DeleteFile(name);
return NULL;
}
/*
*----------------------------------------------------------------------
*
* TclpTempFileName --
|
| ︙ | | |
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
|
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
|
-
+
|
* Additionally, when calling a 16-bit dos or windows application, all
* path names must use the short, cryptic, path format (e.g., using
* ab~1.def instead of "a b.default").
*/
BuildCommandLine(execPath, argc, argv, &cmdLine);
if (tclWinProcs->createProcessProc(NULL,
if (CreateProcess(NULL,
(TCHAR *) Tcl_DStringValue(&cmdLine), NULL, NULL, TRUE,
(DWORD) createFlags, NULL, NULL, &startInfo, &procInfo) == 0) {
TclWinConvertError(GetLastError());
Tcl_AppendResult(interp, "couldn't execute \"", argv[0],
"\": ", Tcl_PosixError(interp), (char *) NULL);
goto end;
}
|
| ︙ | | |
1315
1316
1317
1318
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
|
1315
1316
1317
1318
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
|
-
+
-
+
-
+
-
+
-
+
|
Tcl_DStringInit(&nameBuf);
Tcl_DStringAppend(&nameBuf, originalName, -1);
nameLen = Tcl_DStringLength(&nameBuf);
for (i = 0; i < (int) (sizeof(extensions) / sizeof(extensions[0])); i++) {
Tcl_DStringSetLength(&nameBuf, nameLen);
Tcl_DStringAppend(&nameBuf, extensions[i], -1);
nativeName = tclWinProcs->utf2tchar(Tcl_DStringValue(&nameBuf),
nativeName = Tcl_WinUtfToTChar(Tcl_DStringValue(&nameBuf),
Tcl_DStringLength(&nameBuf), &ds);
found = tclWinProcs->searchPathProc(NULL, nativeName, NULL, MAX_PATH,
found = SearchPath(NULL, nativeName, NULL, MAX_PATH,
nativeFullPath, &rest);
Tcl_DStringFree(&ds);
if (found == 0) {
continue;
}
/*
* Ignore matches on directories or data files, return if identified a
* known type.
*/
attr = tclWinProcs->getFileAttributesProc(nativeFullPath);
attr = GetFileAttributes(nativeFullPath);
if ((attr == 0xffffffff) || (attr & FILE_ATTRIBUTE_DIRECTORY)) {
continue;
}
strcpy(fullName, tclWinProcs->tchar2utf(nativeFullPath, -1, &ds));
strcpy(fullName, Tcl_WinTCharToUtf(nativeFullPath, -1, &ds));
Tcl_DStringFree(&ds);
ext = strrchr(fullName, '.');
if ((ext != NULL) && (strcasecmp(ext, ".bat") == 0)) {
applType = APPL_DOS;
break;
}
hFile = tclWinProcs->createFileProc(nativeFullPath,
hFile = CreateFile(nativeFullPath,
GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
continue;
}
header.e_magic = 0;
|
| ︙ | | |
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
|
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
|
-
-
-
+
+
|
/*
* Replace long path name of executable with short path name for
* 16-bit applications. Otherwise the application may not be able to
* correctly parse its own command line to separate off the
* application name from the arguments.
*/
tclWinProcs->getShortPathNameProc(nativeFullPath,
nativeFullPath, MAX_PATH);
strcpy(fullName, tclWinProcs->tchar2utf(nativeFullPath, -1, &ds));
GetShortPathName(nativeFullPath, nativeFullPath, MAX_PATH);
strcpy(fullName, Tcl_WinTCharToUtf(nativeFullPath, -1, &ds));
Tcl_DStringFree(&ds);
}
return applType;
}
/*
*----------------------------------------------------------------------
|
| ︙ | | |
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
|
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
|
-
+
|
}
Tcl_DStringAppend(&ds, start, (int) (special - start));
if (quote) {
Tcl_DStringAppend(&ds, "\"", 1);
}
}
Tcl_DStringFree(linePtr);
tclWinProcs->utf2tchar(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds), linePtr);
Tcl_WinUtfToTChar(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds), linePtr);
Tcl_DStringFree(&ds);
}
/*
*----------------------------------------------------------------------
*
* TclpCreateCommandChannel --
|
| ︙ | | |
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
3142
3143
3144
3145
3146
3147
|
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
3142
3143
3144
3145
3146
|
-
+
-
+
-
+
-
+
|
Tcl_DString buf;
if (!resultingNameObj) {
flags |= FILE_FLAG_DELETE_ON_CLOSE;
}
namePtr = (char *) name;
length = tclWinProcs->getTempPathProc(MAX_PATH, name);
length = GetTempPath(MAX_PATH, name);
if (length == 0) {
goto gotError;
}
namePtr += length * sizeof(TCHAR);
if (basenameObj) {
const char *string = Tcl_GetStringFromObj(basenameObj, &length);
tclWinProcs->utf2tchar(string, length, &buf);
Tcl_WinUtfToTChar(string, length, &buf);
memcpy(namePtr, Tcl_DStringValue(&buf), Tcl_DStringLength(&buf));
namePtr += Tcl_DStringLength(&buf);
Tcl_DStringFree(&buf);
} else {
TCHAR *baseStr = TEXT("TCL");
int length = 3 * sizeof(TCHAR);
memcpy(namePtr, baseStr, length);
namePtr += length;
}
counter = TclpGetClicks() % 65533;
counter2 = 1024; /* Only try this many times! Prevents
* an infinite loop. */
do {
char number[TCL_INTEGER_SPACE + 4];
sprintf(number, "%d.TMP", counter);
counter = (unsigned short) (counter + 1);
tclWinProcs->utf2tchar(number, strlen(number), &buf);
Tcl_WinUtfToTChar(number, strlen(number), &buf);
Tcl_DStringSetLength(&buf, Tcl_DStringLength(&buf) + 1);
memcpy(namePtr, Tcl_DStringValue(&buf), Tcl_DStringLength(&buf) + 1);
Tcl_DStringFree(&buf);
handle = tclWinProcs->createFileProc((TCHAR *) name,
handle = CreateFile(name,
GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_NEW, flags, NULL);
} while (handle == INVALID_HANDLE_VALUE
&& --counter2 > 0
&& GetLastError() == ERROR_FILE_EXISTS);
if (handle == INVALID_HANDLE_VALUE) {
goto gotError;
}
|
| ︙ | | |