This program is currently meant to test standard file handles and
current working directory (since these are settable via posix_spawn),
but could be extended to add additional checks if other cygwin-to-win32
process properties need to be tested.

Change cygrun environment variable to mingwtestdir, and use that instead
in cygrun.sh, so that other tests can find mingw test executables using
the environment variable.

Signed-off-by: Jeremy Drake <cyg...@jdrake.com>
---

BTW, I noticed while editing mingw/Makefile.am, shouldn't cygload have
-Wl,--disable-high-entropy-va in LDFLAGS?

 winsup/testsuite/Makefile.am                  |   2 +-
 winsup/testsuite/cygrun.sh                    |   4 +-
 winsup/testsuite/mingw/Makefile.am            |   7 +-
 .../winsup.api/posix_spawn/winchild.c         | 130 ++++++++++++++++++
 4 files changed, 139 insertions(+), 4 deletions(-)
 create mode 100644 winsup/testsuite/winsup.api/posix_spawn/winchild.c

diff --git a/winsup/testsuite/Makefile.am b/winsup/testsuite/Makefile.am
index 957554a828..03f65d8184 100644
--- a/winsup/testsuite/Makefile.am
+++ b/winsup/testsuite/Makefile.am
@@ -349,7 +349,7 @@ XFAIL_TESTS = \
 LOG_COMPILER = $(srcdir)/cygrun.sh

 export runtime_root=$(abs_builddir)/testinst/bin
-export cygrun=$(builddir)/mingw/cygrun
+export mingwtestdir=$(builddir)/mingw

 # Set up things in the Cygwin 'installation' at testsuite/testinst/ to provide
 # things which tests need to work
diff --git a/winsup/testsuite/cygrun.sh b/winsup/testsuite/cygrun.sh
index bf1d5cc6b5..f1673e4dbd 100755
--- a/winsup/testsuite/cygrun.sh
+++ b/winsup/testsuite/cygrun.sh
@@ -11,7 +11,7 @@ export PATH="$runtime_root:${PATH}"
 if [ "$1" = "./mingw/cygload" ]
 then
     windows_runtime_root=$(cygpath -m $runtime_root)
-    $cygrun "$exe -v -cygwin $windows_runtime_root/cygwin1.dll"
+    $mingwtestdir/cygrun "$exe -v -cygwin $windows_runtime_root/cygwin1.dll"
 else
-    cygdrop $cygrun $exe
+    cygdrop $mingwtestdir/cygrun $exe
 fi
diff --git a/winsup/testsuite/mingw/Makefile.am 
b/winsup/testsuite/mingw/Makefile.am
index 772e73405f..25300a15d9 100644
--- a/winsup/testsuite/mingw/Makefile.am
+++ b/winsup/testsuite/mingw/Makefile.am
@@ -16,7 +16,7 @@ override CC = @MINGW_CC@
 override CXX = @MINGW_CXX@
 AM_CPPFLAGS =

-noinst_PROGRAMS = cygrun cygload
+noinst_PROGRAMS = cygrun cygload winchild

 cygrun_SOURCES = \
        ../cygrun.c
@@ -24,3 +24,8 @@ cygrun_SOURCES = \
 cygload_SOURCES = \
        ../winsup.api/cygload.cc
 cygload_LDFLAGS=-static -Wl,-e,cygloadCRTStartup
+
+winchild_SOURCES = \
+       ../winsup.api/posix_spawn/winchild.c
+winchild_LDFLAGS=-municode
+winchild_LDADD=-lntdll
diff --git a/winsup/testsuite/winsup.api/posix_spawn/winchild.c 
b/winsup/testsuite/winsup.api/posix_spawn/winchild.c
new file mode 100644
index 0000000000..6fdfa002c0
--- /dev/null
+++ b/winsup/testsuite/winsup.api/posix_spawn/winchild.c
@@ -0,0 +1,130 @@
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <winternl.h>
+#include <ctype.h>
+#include <stdio.h>
+
+
+int wmain (int argc, wchar_t **argv)
+{
+  if (argc != 3)
+    {
+      fwprintf (stderr, L"Usage: %ls handle expected\n", argv[0]);
+      return 1;
+    }
+
+  if (!wcscmp (argv[1], L"CWD"))
+    {
+      LPWSTR buffer;
+      DWORD len = GetCurrentDirectoryW (0, NULL);
+      if (len == 0)
+        {
+         fwprintf (stderr, L"%ls: GetCurrentDirectory failed with error %lu\n",
+                   argv[0], GetLastError ());
+         return 2;
+       }
+      buffer = malloc (len * sizeof (WCHAR));
+      if (GetCurrentDirectoryW (len, buffer) != len - 1)
+        {
+         fwprintf (stderr, L"%ls: GetCurrentDirectory failed with error %lu\n",
+                   argv[0], GetLastError ());
+         return 2;
+       }
+      if (wcscmp (argv[2], buffer))
+        {
+         fwprintf (stderr, L"%ls: CWD '%ls' != expected '%ls'\n",
+                   argv[0], buffer, argv[2]);
+         free (buffer);
+         return 4;
+       }
+      free (buffer);
+    }
+  else if (iswdigit (argv[1][0]) && !argv[1][1])
+    {
+      HANDLE stdhandle;
+      DWORD nStdHandle;
+      switch (argv[1][0])
+      {
+       case L'0':
+         nStdHandle = STD_INPUT_HANDLE;
+         break;
+       case L'1':
+         nStdHandle = STD_OUTPUT_HANDLE;
+         break;
+       case L'2':
+         nStdHandle = STD_ERROR_HANDLE;
+         break;
+       default:
+         fwprintf (stderr, L"%ls: Unknown handle '%ls'\n", argv[0], argv[1]);
+         return 1;
+      }
+
+      stdhandle = GetStdHandle (nStdHandle);
+      if (stdhandle == INVALID_HANDLE_VALUE)
+        {
+         fwprintf (stderr, L"%ls: Failed getting standard handle %ls: %lu\n",
+             argv[0], argv[1], GetLastError ());
+         return 2;
+       }
+      else if (stdhandle == NULL)
+       {
+         if (wcscmp (argv[2], L"<CLOSED>"))
+           {
+             fwprintf (stderr,
+                       L"%ls: Handle %ls name '%ls' != expected '%ls'\n",
+                       argv[0], argv[1], L"<CLOSED>", argv[2]);
+             return 4;
+           }
+       }
+      else
+        {
+         LPWSTR buf, win32path;
+         buf = malloc (65536);
+         if (!GetFinalPathNameByHandleW (stdhandle, buf,
+                                         65536 / sizeof (WCHAR),
+                                         FILE_NAME_OPENED|VOLUME_NAME_DOS))
+           {
+             POBJECT_NAME_INFORMATION pinfo = (POBJECT_NAME_INFORMATION) buf;
+             DWORD err = GetLastError ();
+             ULONG len;
+             NTSTATUS status = NtQueryObject (stdhandle, ObjectNameInformation,
+                                              pinfo, 65536, &len);
+             if (!NT_SUCCESS (status))
+               {
+                 fwprintf (stderr,
+                     L"%ls: NtQueryObject for handle %ls failed: 0x%08x\n",
+                     argv[0], argv[1], status);
+                 free (buf);
+                 return 3;
+               }
+
+             pinfo->Name.Buffer[pinfo->Name.Length / sizeof (WCHAR)] = L'\0';
+             win32path = pinfo->Name.Buffer;
+           }
+         else
+           {
+             static const WCHAR prefix[] = L"\\\\?\\";
+             win32path = buf;
+             if (!wcsncmp (win32path, prefix,
+                           sizeof (prefix) / sizeof (WCHAR) - 1))
+               win32path += sizeof (prefix) / sizeof (WCHAR) - 1;
+           }
+
+         if (wcscmp (win32path, argv[2]))
+           {
+             fwprintf (stderr,
+                       L"%ls: Handle %ls name '%ls' != expected '%ls'\n",
+                       argv[0], argv[1], win32path, argv[2]);
+             free (buf);
+             return 4;
+           }
+         free (buf);
+       }
+    }
+  else
+    {
+      fwprintf (stderr, L"%ls: Unknown handle '%ls'\n", argv[0], argv[1]);
+      return 1;
+    }
+  return 0;
+}
-- 
2.49.0.windows.1

Reply via email to