Skip to content

Commit 46fb7b9

Browse files
Merge a64662f into 42c2af2
2 parents 42c2af2 + a64662f commit 46fb7b9

File tree

6 files changed

+179
-46
lines changed

6 files changed

+179
-46
lines changed

platforms/Cross/plugins/FilePlugin/FilePlugin.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ sqInt sqFileSync(SQFile *f);
6767
sqInt sqFileTruncate(SQFile *f,squeakFileOffsetType offset);
6868
sqInt sqFileThisSession(void);
6969
sqInt sqFileStdioHandlesInto(SQFile files[3]);
70+
sqInt sqIsFileDescriptorATTY(int fdNum);
7071

7172
/* directories */
7273

platforms/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,15 @@ sqFileStdioHandlesInto(SQFile files[])
569569
return 7;
570570
}
571571

572+
/*
573+
* Allow to test if the standard input/output files are from a console or not
574+
* 1 if stdio is redirected to a console pipe, else 0 (and in this case, a file should be created)
575+
*/
576+
sqInt sqIsFileDescriptorATTY(int fdNum) {
577+
return isatty(fdNum);
578+
}
579+
580+
572581
size_t
573582
sqFileReadIntoAt(SQFile *f, size_t count, char *byteArrayIndex, size_t startIndex) {
574583
/* Read count bytes from the given file into byteArray starting at

platforms/RiscOS/plugins/FilePlugin/sqFilePluginBasicPrims.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,11 @@ sqInt sqFileStdioHandlesInto(SQFile files[3]) {
407407
return 0;
408408
}
409409

410+
sqInt sqIsFileDescriptorATTY(int fdNum) {
411+
//Not implemented
412+
return 0;
413+
}
414+
410415
size_t sqFileReadIntoAt(SQFile *f, size_t count, char* byteArrayIndex, size_t startIndex) {
411416
/* Read count bytes from the given file into byteArray starting at
412417
* startIndex. byteArray is the address of the first byte of a

platforms/win32/plugins/FilePlugin/sqWin32FilePrims.c

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
* (Max Leske)
2424
*
2525
*****************************************************************************/
26+
2627
#include <windows.h>
2728
#include <malloc.h>
2829
#include "sq.h"
@@ -285,8 +286,15 @@ sqConnectToFile(SQFile *sqFile, void *file, sqInt writeFlag)
285286
return 1;
286287
}
287288

288-
289-
289+
void
290+
sqFileStdioHandlesIntoFile_WithHandle_IsWritable(SQFile * file, HANDLE handle, int isWritable) {
291+
file->sessionID = thisSession;
292+
file->file = handle;
293+
file->writable = isWritable;
294+
file->lastOp = 0; /* unused on win32 */
295+
file->isStdioStream = isFileHandleATTY(handle);
296+
AddHandleToTable(win32Files, handle);
297+
}
290298

291299
/*
292300
* Fill-in files with handles for stdin, stdout and seterr as available and
@@ -296,32 +304,23 @@ sqConnectToFile(SQFile *sqFile, void *file, sqInt writeFlag)
296304
sqInt
297305
sqFileStdioHandlesInto(SQFile files[3])
298306
{
299-
DWORD mode;
300-
301-
files[0].sessionID = thisSession;
302-
files[0].file = GetStdHandle(STD_INPUT_HANDLE);
303-
files[0].writable = false;
304-
files[0].lastOp = 0; /* unused on win32 */
305-
files[0].isStdioStream = GetConsoleMode(files[0].file, &mode) != 0;
306-
AddHandleToTable(win32Files, files[0].file);
307-
308-
files[1].sessionID = thisSession;
309-
files[1].file = GetStdHandle(STD_OUTPUT_HANDLE);
310-
files[1].writable = true;
311-
files[1].lastOp = 0; /* unused on win32 */
312-
files[1].isStdioStream = GetConsoleMode(files[1].file, &mode) != 0;
313-
AddHandleToTable(win32Files, files[1].file);
314-
315-
files[2].sessionID = thisSession;
316-
files[2].file = GetStdHandle(STD_ERROR_HANDLE);
317-
files[2].writable = true;
318-
files[2].lastOp = 0; /* unused on win32 */
319-
files[2].isStdioStream = GetConsoleMode(files[2].file, &mode) != 0;
320-
AddHandleToTable(win32Files, files[2].file);
307+
sqFileStdioHandlesIntoFile_WithHandle_IsWritable(&files[0], GetStdHandle(STD_INPUT_HANDLE), false);
308+
sqFileStdioHandlesIntoFile_WithHandle_IsWritable(&files[1], GetStdHandle(STD_OUTPUT_HANDLE), true);
309+
sqFileStdioHandlesIntoFile_WithHandle_IsWritable(&files[2], GetStdHandle(STD_ERROR_HANDLE), true);
321310

322311
return 7;
323312
}
324313

314+
315+
316+
/*
317+
* Allow to test if the standard input/output files are from a console or not
318+
* 1 if stdio is redirected to a console pipe, else 0 (and in this case, a file should be created)
319+
*/
320+
sqInt sqIsFileDescriptorATTY(int fdNum) {
321+
return isFileHandleATTY(_get_osfhandle(fdNum));
322+
}
323+
325324
size_t sqFileReadIntoAt(SQFile *f, size_t count, char* byteArrayIndex, size_t startIndex) {
326325
/* Read count bytes from the given file into byteArray starting at
327326
startIndex. byteArray is the address of the first byte of a

platforms/win32/vm/sqWin32Main.c

Lines changed: 109 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
* with Unicode support.
1313
*****************************************************************************/
1414
#include <windows.h>
15+
#include <errno.h>
1516
#include <stdio.h>
1617
#include <stdlib.h>
1718
#include <string.h>
@@ -36,6 +37,42 @@
3637
# endif
3738
#endif
3839

40+
41+
/************************************************************************************************************/
42+
/* few addtional definitions for those having older include files especially #include <fileextd.h> */
43+
/************************************************************************************************************/
44+
#if (WINVER < 0x0600)
45+
/*Copied from winbase.h*/
46+
typedef struct _FILE_NAME_INFO {
47+
DWORD FileNameLength;
48+
WCHAR FileName[1];
49+
} FILE_NAME_INFO, *PFILE_NAME_INFO;
50+
typedef enum _FILE_INFO_BY_HANDLE_CLASS {
51+
FileBasicInfo = 0,
52+
FileStandardInfo = 1,
53+
FileNameInfo = 2,
54+
FileRenameInfo = 3,
55+
FileDispositionInfo = 4,
56+
FileAllocationInfo = 5,
57+
FileEndOfFileInfo = 6,
58+
FileStreamInfo = 7,
59+
FileCompressionInfo = 8,
60+
FileAttributeTagInfo = 9,
61+
FileIdBothDirectoryInfo = 10, // 0xA
62+
FileIdBothDirectoryRestartInfo = 11, // 0xB
63+
FileIoPriorityHintInfo = 12, // 0xC
64+
FileRemoteProtocolInfo = 13, // 0xD
65+
FileFullDirectoryInfo = 14, // 0xE
66+
FileFullDirectoryRestartInfo = 15, // 0xF
67+
FileStorageInfo = 16, // 0x10
68+
FileAlignmentInfo = 17, // 0x11
69+
FileIdInfo = 18, // 0x12
70+
FileIdExtdDirectoryInfo = 19, // 0x13
71+
FileIdExtdDirectoryRestartInfo = 20, // 0x14
72+
MaximumFileInfoByHandlesClass
73+
} FILE_INFO_BY_HANDLE_CLASS, *PFILE_INFO_BY_HANDLE_CLASS;
74+
#endif //(WINVER < 0x0600)
75+
3976
#if !defined(IMAGE_SIZEOF_NT_OPTIONAL_HEADER)
4077
#include <winnt.h>
4178
#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER sizeof(IMAGE_OPTIONAL_HEADER)
@@ -833,6 +870,77 @@ getVersionInfo(int verbose)
833870
*/
834871
#define exit(ec) do { _cexit(ec); ExitProcess(ec); } while (0)
835872

873+
/*
874+
* Allow to test if the standard input/output files are from a console or not
875+
* 1 if stdio is redirected to a console pipe, else 0 (and in this case, a file should be created)
876+
* Inspired of: https://fossies.org/linux/misc/vim-8.0.tar.bz2/vim80/src/iscygpty.c?m=t
877+
*/
878+
sqInt isFileHandleATTY(HANDLE fdHandle) {
879+
if (fdHandle == INVALID_HANDLE_VALUE) {
880+
return 0;
881+
}
882+
883+
/* In case of Windows Shell case */
884+
DWORD fileType = GetFileType(fdHandle);
885+
if (fileType == FILE_TYPE_CHAR)
886+
/* The specified file is a character file, typically an LPT device or a console. */
887+
/* https://msdn.microsoft.com/en-us/library/windows/desktop/aa364960(v=vs.85).aspx */
888+
return 1;
889+
890+
/* In case of Unix emulator, we need to parse the name of the pipe */
891+
892+
/* Cygwin/msys's pty is a pipe. */
893+
if (fileType != FILE_TYPE_PIPE) {
894+
return 0;
895+
}
896+
897+
int size = sizeof(FILE_NAME_INFO) + sizeof(WCHAR) * MAX_PATH;
898+
FILE_NAME_INFO *nameinfo;
899+
WCHAR *p = NULL;
900+
901+
typedef BOOL(WINAPI *pfnGetFileInformationByHandleEx)(
902+
HANDLE hFile,
903+
FILE_INFO_BY_HANDLE_CLASS FileInformationClass,
904+
LPVOID lpFileInformation,
905+
DWORD dwBufferSize
906+
);
907+
static pfnGetFileInformationByHandleEx pGetFileInformationByHandleEx = NULL;
908+
if (!pGetFileInformationByHandleEx) {
909+
pGetFileInformationByHandleEx = (pfnGetFileInformationByHandleEx)
910+
GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetFileInformationByHandleEx");
911+
if (!pGetFileInformationByHandleEx)
912+
return 0;
913+
}
914+
915+
nameinfo = malloc(size);
916+
if (nameinfo == NULL) {
917+
return 0;
918+
}
919+
/* Check the name of the pipe: '\{cygwin,msys}-XXXXXXXXXXXXXXXX-ptyN-{from,to}-master' */
920+
if (pGetFileInformationByHandleEx(fdHandle, FileNameInfo, nameinfo, size)) {
921+
nameinfo->FileName[nameinfo->FileNameLength / sizeof(WCHAR)] = L'\0';
922+
p = nameinfo->FileName;
923+
//Check that the pipe name contains msys or cygwin
924+
if ((((wcsstr(p, L"msys-") || wcsstr(p, L"cygwin-"))) &&
925+
(wcsstr(p, L"-pty") && wcsstr(p, L"-master")))) {
926+
//The openned pipe is not a msys xor cygwin pipe to pty
927+
free(nameinfo);
928+
return 1;
929+
}
930+
}
931+
free(nameinfo);
932+
return 0;
933+
}
934+
935+
/*
936+
* Allow to test whether one of the standard input/output files is from a console or not
937+
* 1 if one of the stdio is redirected to a console pipe, else 0 (and in this case, a file should be created)
938+
*/
939+
sqInt isOneStdioDescriptorATTY() {
940+
return isFileHandleATTY(GetStdHandle(STD_INPUT_HANDLE)) ||
941+
isFileHandleATTY(GetStdHandle(STD_OUTPUT_HANDLE)) || isFileHandleATTY(GetStdHandle(STD_ERROR_HANDLE));
942+
}
943+
836944
static void
837945
versionInfo(void)
838946
{
@@ -1590,23 +1698,7 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
15901698
* allocation failures unless running as a console app because doing so
15911699
* via a MessageBox will make the system unusable.
15921700
*/
1593-
#if 0 /* This way used to work. Does no longer. */
1594-
DWORD mode;
1595-
1596-
fIsConsole = GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &mode);
1597-
#elif 0 /* This does /not/ work with STD_INPUT_HANDLE or STD_OUTPUT_HANDLE */
1598-
CONSOLE_SCREEN_BUFFER_INFO csbi;
1599-
1600-
if ((fIsConsole = GetConsoleScreenBufferInfo
1601-
(GetStdHandle(STD_INPUT_HANDLE), &csbi)))
1602-
fIsConsole = csbi.dwCursorPosition.X || csbi.dwCursorPosition.Y;
1603-
#else /* This /does/ work; see */
1604-
/* https://stackoverflow.com/questions/9009333/how-to-check-if-the-program-is-run-from-a-console */
1605-
HWND consoleWnd = GetConsoleWindow();
1606-
DWORD dwProcessId;
1607-
GetWindowThreadProcessId(consoleWnd, &dwProcessId);
1608-
fIsConsole = GetCurrentProcessId() != dwProcessId;
1609-
#endif
1701+
fIsConsole = isOneStdioDescriptorATTY();
16101702

16111703
/* a few things which need to be done first */
16121704
gatherSystemInfo();

src/plugins/FilePlugin/FilePlugin.c

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
/* Automatically generated by
2-
VMPluginCodeGenerator VMMaker.oscog-eem.2363 uuid: b7494837-187a-49a1-afb7-56c6fcb6186f
2+
VMPluginCodeGenerator * VMMaker.oscog-VB.2370 uuid: b61408e0-effc-5144-bd81-993254392346
33
from
4-
FilePlugin VMMaker.oscog-eem.2363 uuid: b7494837-187a-49a1-afb7-56c6fcb6186f
4+
FilePlugin * VMMaker.oscog-VB.2370 uuid: b61408e0-effc-5144-bd81-993254392346
55
*/
6-
static char __buildInfo[] = "FilePlugin VMMaker.oscog-eem.2363 uuid: b7494837-187a-49a1-afb7-56c6fcb6186f " __DATE__ ;
6+
static char __buildInfo[] = "FilePlugin * VMMaker.oscog-VB.2370 uuid: b61408e0-effc-5144-bd81-993254392346 " __DATE__ ;
77

88

99

@@ -100,6 +100,7 @@ EXPORT(sqInt) primitiveFileSync(void);
100100
EXPORT(sqInt) primitiveFileTruncate(void);
101101
EXPORT(sqInt) primitiveFileWrite(void);
102102
EXPORT(sqInt) primitiveHasFileAccess(void);
103+
EXPORT(sqInt) primitiveIsFileDescriptorATTY(void);
103104
EXPORT(sqInt) setInterpreter(struct VirtualMachine*anInterpreter);
104105
EXPORT(sqInt) setMacFileTypeAndCreator(char *fileName, char *typeString, char *creatorString);
105106
EXPORT(sqInt) shutdownModule(void);
@@ -208,9 +209,9 @@ extern
208209
struct VirtualMachine* interpreterProxy;
209210
static const char *moduleName =
210211
#ifdef SQUEAK_BUILTIN_PLUGIN
211-
"FilePlugin VMMaker.oscog-eem.2363 (i)"
212+
"FilePlugin * VMMaker.oscog-VB.2370 (i)"
212213
#else
213-
"FilePlugin VMMaker.oscog-eem.2363 (e)"
214+
"FilePlugin * VMMaker.oscog-VB.2370 (e)"
214215
#endif
215216
;
216217
static void * sCCPfn;
@@ -1724,6 +1725,30 @@ primitiveHasFileAccess(void)
17241725
return 0;
17251726
}
17261727

1728+
/* FilePlugin>>#primitiveIsFileDescriptorATTY */
1729+
EXPORT(sqInt)
1730+
primitiveIsFileDescriptorATTY(void)
1731+
{
1732+
int fd;
1733+
sqInt fdPointer;
1734+
sqInt isStdoutRedirected;
1735+
1736+
fdPointer = stackValue(0);
1737+
if (!(isIntegerObject(fdPointer))) {
1738+
return primitiveFailFor(PrimErrBadArgument);
1739+
}
1740+
fd = integerValueOf(fdPointer);
1741+
if (failed()) {
1742+
1743+
/* Ensure that the appropriate failure code has been set */
1744+
return primitiveFailFor(PrimErrBadArgument);
1745+
}
1746+
isStdoutRedirected = sqIsFileDescriptorATTY(fd) ;
1747+
pop(2);
1748+
pushBool(isStdoutRedirected);
1749+
return 0;
1750+
}
1751+
17271752

17281753
/* Note: This is coded so that it can be run in Squeak. */
17291754

@@ -1850,6 +1875,7 @@ void* FilePlugin_exports[][3] = {
18501875
{(void*)_m, "primitiveFileTruncate\000\001", (void*)primitiveFileTruncate},
18511876
{(void*)_m, "primitiveFileWrite\000\001", (void*)primitiveFileWrite},
18521877
{(void*)_m, "primitiveHasFileAccess\000\377", (void*)primitiveHasFileAccess},
1878+
{(void*)_m, "primitiveIsFileDescriptorATTY\000\000", (void*)primitiveIsFileDescriptorATTY},
18531879
{(void*)_m, "setInterpreter", (void*)setInterpreter},
18541880
{(void*)_m, "setMacFileTypeAndCreator", (void*)setMacFileTypeAndCreator},
18551881
{(void*)_m, "shutdownModule\000\377", (void*)shutdownModule},
@@ -1880,5 +1906,6 @@ signed char primitiveFileSizeAccessorDepth = 1;
18801906
signed char primitiveFileSyncAccessorDepth = 1;
18811907
signed char primitiveFileTruncateAccessorDepth = 1;
18821908
signed char primitiveFileWriteAccessorDepth = 1;
1909+
signed char primitiveIsFileDescriptorATTYAccessorDepth = 0;
18831910

18841911
#endif /* ifdef SQ_BUILTIN_PLUGIN */

0 commit comments

Comments
 (0)