Index: /trunk/src/kash/shfile.c
===================================================================
--- /trunk/src/kash/shfile.c	(revision 2306)
+++ /trunk/src/kash/shfile.c	(revision 2307)
@@ -84,5 +84,24 @@
 # define FDEV               0x40
 # define FTEXT              0x80
-#endif
+
+# define MY_ObjectBasicInformation 0
+typedef LONG (NTAPI * PFN_NtQueryObject)(HANDLE, int, void *, size_t, size_t *);
+
+typedef struct MY_OBJECT_BASIC_INFORMATION
+{
+    ULONG           Attributes;
+	ACCESS_MASK     GrantedAccess;
+	ULONG           HandleCount;
+	ULONG           PointerCount;
+	ULONG           PagedPoolUsage;
+	ULONG           NonPagedPoolUsage;
+	ULONG           Reserved[3];
+	ULONG           NameInformationLength;
+	ULONG           TypeInformationLength;
+	ULONG           SecurityDescriptorLength;
+	LARGE_INTEGER   CreateTime;
+} MY_OBJECT_BASIC_INFORMATION;
+
+#endif /* K_OS_WINDOWS */
 
 
@@ -117,9 +136,10 @@
  * @param   pfdtab      The file descriptor table.
  * @param   native      The native file handle.
- * @param   flags       The flags the it was created with.
+ * @param   oflags      The flags the it was opened/created with.
+ * @param   shflags     The shell file flags.
  * @param   fdMin       The minimum file descriptor number, pass -1 if any is ok.
  * @param   who         Who we're doing this for (for logging purposes).
  */
-static int shfile_insert(shfdtab *pfdtab, intptr_t native, unsigned flags, int fdMin, const char *who)
+static int shfile_insert(shfdtab *pfdtab, intptr_t native, unsigned oflags, unsigned shflags, int fdMin, const char *who)
 {
     shmtxtmp tmp;
@@ -164,5 +184,6 @@
             {
                 new_tab[i].fd = -1;
-                new_tab[i].flags = 0;
+                new_tab[i].oflags = 0;
+                new_tab[i].shflags = 0;
                 new_tab[i].native = -1;
             }
@@ -183,10 +204,10 @@
     {
         pfdtab->tab[fd].fd = fd;
-        pfdtab->tab[fd].flags = flags;
-        pfdtab->tab[fd].cloexec = 0;
+        pfdtab->tab[fd].oflags = oflags;
+        pfdtab->tab[fd].shflags = shflags;
         pfdtab->tab[fd].native = native;
     }
     else
-        shfile_native_close(native, flags);
+        shfile_native_close(native, oflags);
 
     shmtx_leave(&pfdtab->mtx, &tmp);
@@ -305,4 +326,5 @@
 
 # if K_OS == K_OS_WINDOWS
+
 /**
  * Converts a DOS(/Windows) error code to errno,
@@ -364,4 +386,29 @@
     return -1;
 }
+
+DWORD shfile_query_handle_access_mask(HANDLE h, PACCESS_MASK pMask)
+{
+    static PFN_NtQueryObject        s_pfnNtQueryObject = NULL;
+    MY_OBJECT_BASIC_INFORMATION     BasicInfo;
+    LONG                            Status;
+
+    if (!s_pfnNtQueryObject)
+    {
+        s_pfnNtQueryObject = (PFN_NtQueryObject)GetProcAddress(GetModuleHandle("NTDLL"), "NtQueryObject");
+        if (!s_pfnNtQueryObject)
+            return ERROR_NOT_SUPPORTED;
+    }
+
+    Status = s_pfnNtQueryObject(h, MY_ObjectBasicInformation, &BasicInfo, sizeof(BasicInfo), NULL);
+    if (Status >= 0)
+    {
+        *pMask = BasicInfo.GrantedAccess;
+        return NO_ERROR;
+    }
+    if (Status != STATUS_INVALID_HANDLE)
+        return ERROR_GEN_FAILURE;
+    return ERROR_INVALID_HANDLE;
+}
+
 # endif /* K_OS == K_OS_WINDOWS */
 
@@ -397,5 +444,5 @@
                 {
                     DWORD dwStdHandle;
-                    unsigned flags;
+                    unsigned fFlags;
                 } aStdHandles[3] =
                 {
@@ -404,6 +451,8 @@
                     { STD_ERROR_HANDLE,   _O_WRONLY }
                 };
-                unsigned            i;
-                STARTUPINFO         Info;
+                int             i;
+                STARTUPINFO     Info;
+                ACCESS_MASK     Mask;
+                DWORD           dwErr;
 
                 rc = 0;
@@ -415,32 +464,94 @@
                     memset(&Info, 0, sizeof(Info));
                 }
-                if (    Info.cbReserved2 <= sizeof(int)
+
+                if (    Info.cbReserved2 > sizeof(int)
                     &&  (uintptr_t)Info.lpReserved2 >= 0x1000
-                    &&  *(int *)Info.lpReserved2 * (sizeof(int) + sizeof(intptr_t)) + 4 <= Info.cbReserved2
-                    &&  *(int *)Info.lpReserved2 <= 2048
-                    &&  *(int *)Info.lpReserved2 >= 1)
+                    &&  (i = *(int *)Info.lpReserved2) >= 1
+                    &&  i <= 2048
+                    &&  (   Info.cbReserved2 == i * 5 + 4
+                         //|| Info.cbReserved2 == i * 5 + 1 - check the cygwin sources.
+                         || Info.cbReserved2 == i * 9 + 4))
                 {
-                    unsigned    c       = *(int *)Info.lpReserved2;
-                    char       *aosfile = (char *)Info.lpReserved2 + sizeof(int);
-                    intptr_t   *aosfhnd = (intptr_t *)(aosfile + c);
-
-                    /** @todo process */
-
+                    uint8_t    *paf    = (uint8_t *)Info.lpReserved2 + sizeof(int);
+                    int         dwPerH = 1 + (Info.cbReserved2 == i * 9 + 4);
+                    DWORD      *ph     = (DWORD *)(paf + i) + dwPerH * i;
+                    HANDLE      aStdHandles2[3];
+                    int         j;
+
+                    //if (Info.cbReserved2 == i * 5 + 1) - check the cygwin sources.
+                    //    i--;
+
+                    for (j = 0; j < 3; j++)
+                        aStdHandles2[j] = GetStdHandle(aStdHandles[j].dwStdHandle);
+
+                    while (i-- > 0)
+                    {
+                        ph -= dwPerH;
+
+                        if (    (paf[i] & (FOPEN | FNOINHERIT)) == FOPEN
+                            &&  *ph != (uint32_t)INVALID_HANDLE_VALUE)
+                        {
+                            HANDLE  h = (HANDLE)(intptr_t)*ph;
+                            int     fd2;
+                            int     fFlags;
+                            int     fFlags2;
+
+                            if (    h == aStdHandles2[j = 0]
+                                ||  h == aStdHandles2[j = 1]
+                                ||  h == aStdHandles2[j = 2])
+                                fFlags = aStdHandles[j].fFlags;
+                            else
+                            {
+                                dwErr = shfile_query_handle_access_mask(h, &Mask);
+                                if (dwErr == ERROR_INVALID_HANDLE)
+                                    continue;
+                                else if (dwErr == NO_ERROR)
+                                {
+                                    fFlags = 0;
+                                    if (    (Mask & (GENERIC_READ | FILE_READ_DATA))
+                                        &&  (Mask & (GENERIC_WRITE | FILE_WRITE_DATA | FILE_APPEND_DATA)))
+                                        fFlags |= O_RDWR;
+                                    else if (Mask & (GENERIC_READ | FILE_READ_DATA))
+                                        fFlags |= O_RDONLY;
+                                    else if (Mask & (GENERIC_WRITE | FILE_WRITE_DATA | FILE_APPEND_DATA))
+                                        fFlags |= O_WRONLY;
+                                    else
+                                        fFlags |= O_RDWR;
+                                    if ((Mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) == FILE_APPEND_DATA)
+                                        fFlags |= O_APPEND;
+                                }
+                                else
+                                    fFlags = O_RDWR;
+                            }
+
+                            if (paf[i] & FPIPE)
+                                fFlags2 = SHFILE_FLAGS_PIPE;
+                            else if (paf[i] & FDEV)
+                                fFlags2 = SHFILE_FLAGS_TTY;
+                            else
+                                fFlags2 = 0;
+
+                            fd2 = shfile_insert(pfdtab, (intptr_t)h, fFlags, fFlags2, i, "shtab_init");
+                            assert(fd2 == i); (void)fd2;
+                            if (fd2 != i)
+                                rc = -1;
+                        }
+                    }
                 }
 
                 /* Check the three standard handles. */
                 for (i = 0; i < 3; i++)
-                {
-                    HANDLE hFile = GetStdHandle(aStdHandles[i].dwStdHandle);
-                    if (    hFile != INVALID_HANDLE_VALUE
-                        &&  (   (unsigned)i >= pfdtab->size
-                             || pfdtab->tab[i].fd == -1))
+                    if (    (unsigned)i >= pfdtab->size
+                        ||  pfdtab->tab[i].fd == -1)
                     {
-                        int fd2 = shfile_insert(pfdtab, (intptr_t)hFile, aStdHandles[i].flags, i, "shtab_init");
-                        assert(fd2 == i); (void)fd2;
-                        if (fd2 != i)
-                            rc = -1;
+                        HANDLE hFile = GetStdHandle(aStdHandles[i].dwStdHandle);
+                        if (hFile != INVALID_HANDLE_VALUE)
+                        {
+                            int fd2 = shfile_insert(pfdtab, (intptr_t)hFile, aStdHandles[i].fFlags, 0, i, "shtab_init");
+                            assert(fd2 == i); (void)fd2;
+                            if (fd2 != i)
+                                rc = -1;
+                        }
                     }
-                }
 # else
 # endif
@@ -486,6 +597,6 @@
             HANDLE hFile = (HANDLE)pfdtab->tab[i].native;
             if (set)
-                TRACE2((NULL, "  #%d: native=%#x flags=%#x cloexec=%d\n",
-                        i, pfdtab->tab[i].flags, hFile, pfdtab->tab[i].cloexec));
+                TRACE2((NULL, "  #%d: native=%#x oflags=%#x shflags=%#x\n",
+                        i, pfdtab->tab[i].oflags, pfdtab->tab[i].shflags, hFile));
             if (!SetHandleInformation(hFile, HANDLE_FLAG_INHERIT, fFlag))
             {
@@ -538,4 +649,6 @@
            ? pfdtab->size
            : (0x10000-4) / (1 + sizeof(HANDLE));
+    while (count > 3 && pfdtab->tab[count].fd == -1)
+        count--;
 
     if (prepare)
@@ -552,9 +665,9 @@
         {
             if (    pfdtab->tab[i].fd == i
-                &&  !pfdtab->tab[i].cloexec)
+                &&  !(pfdtab->tab[i].shflags & SHFILE_FLAGS_CLOSE_ON_EXEC))
             {
                 HANDLE hFile = (HANDLE)pfdtab->tab[i].native;
-                TRACE2((NULL, "  #%d: native=%#x flags=%#x\n",
-                        i, pfdtab->tab[i].flags, hFile));
+                TRACE2((NULL, "  #%d: native=%#x oflags=%#x shflags=%#x\n",
+                        i, pfdtab->tab[i].oflags, pfdtab->tab[i].shflags, hFile));
 
                 if (!SetHandleInformation(hFile, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT))
@@ -564,8 +677,13 @@
                 }
                 paf[i] = FOPEN;
-                if (pfdtab->tab[i].flags & _O_APPEND)
-                    paf[i] = FAPPEND;
-                if (pfdtab->tab[i].flags & _O_TEXT)
-                    paf[i] = FTEXT;
+                if (pfdtab->tab[i].oflags & _O_APPEND)
+                    paf[i] |= FAPPEND;
+                if (pfdtab->tab[i].oflags & _O_TEXT)
+                    paf[i] |= FTEXT;
+                switch (pfdtab->tab[i].shflags & SHFILE_FLAGS_TYPE_MASK)
+                {
+                    case SHFILE_FLAGS_TTY:  paf[i] |= FDEV; break;
+                    case SHFILE_FLAGS_PIPE: paf[i] |= FPIPE; break;
+                }
                 pah[i] = hFile;
             }
@@ -597,5 +715,5 @@
         {
             if (    pfdtab->tab[i].fd == i
-                &&  !pfdtab->tab[i].cloexec)
+                &&  !(pfdtab->tab[i].shflags & SHFILE_FLAGS_CLOSE_ON_EXEC))
             {
                 HANDLE hFile = (HANDLE)pfdtab->tab[i].native;
@@ -689,5 +807,5 @@
                             NULL /* hTemplateFile */);
         if (hFile != INVALID_HANDLE_VALUE)
-            fd = shfile_insert(pfdtab, (intptr_t)hFile, flags, -1, "shfile_open");
+            fd = shfile_insert(pfdtab, (intptr_t)hFile, flags, 0, -1, "shfile_open");
         else
             fd = shfile_dos2errno(GetLastError());
@@ -706,5 +824,5 @@
             errno = s;
             if (native != -1)
-                fd = shfile_insert(pfdtab, native, flags, -1, "shfile_open");
+                fd = shfile_insert(pfdtab, native, flags, 0, -1, "shfile_open");
             else
                 fd = -1;
@@ -739,8 +857,8 @@
     if (CreatePipe(&hRead, &hWrite, &SecurityAttributes, 4096))
     {
-        fds[0] = shfile_insert(pfdtab, (intptr_t)hRead, O_RDONLY, -1, "shfile_pipe");
+        fds[0] = shfile_insert(pfdtab, (intptr_t)hRead, O_RDONLY, SHFILE_FLAGS_PIPE, -1, "shfile_pipe");
         if (fds[0] != -1)
         {
-            fds[1] = shfile_insert(pfdtab, (intptr_t)hWrite, O_WRONLY, -1, "shfile_pipe");
+            fds[1] = shfile_insert(pfdtab, (intptr_t)hWrite, O_WRONLY, SHFILE_FLAGS_PIPE, -1, "shfile_pipe");
             if (fds[1] != -1)
                 rc = 0;
@@ -753,8 +871,8 @@
     if (!pipe(native_fds))
     {
-        fds[0] = shfile_insert(pfdtab, native_fds[0], O_RDONLY, -1, "shfile_pipe");
+        fds[0] = shfile_insert(pfdtab, native_fds[0], O_RDONLY, SHFILE_FLAGS_PIPE, -1, "shfile_pipe");
         if (fds[0] != -1)
         {
-            fds[1] = shfile_insert(pfdtab, native_fds[1], O_WRONLY, -1, "shfile_pipe");
+            fds[1] = shfile_insert(pfdtab, native_fds[1], O_WRONLY, SHFILE_FLAGS_PIPE, -1, "shfile_pipe");
             if (fds[1] != -1)
                 rc = 0;
@@ -770,5 +888,6 @@
                 rc = fds[0];
                 pfdtab->tab[rc].fd = -1;
-                pfdtab->tab[rc].flags = 0;
+                pfdtab->tab[rc].oflags = 0;
+                pfdtab->tab[rc].shflags = 0;
                 pfdtab->tab[rc].native = -1;
                 shmtx_leave(&pfdtab->mtx, &tmp);
@@ -822,8 +941,9 @@
     if (file)
     {
-        shfile_native_close(file->native, file->flags);
+        shfile_native_close(file->native, file->oflags);
 
         file->fd = -1;
-        file->flags = 0;
+        file->oflags = 0;
+        file->shflags = 0;
         file->native = -1;
 
@@ -951,5 +1071,5 @@
         {
             case F_GETFL:
-                rc = file->flags;
+                rc = file->oflags;
                 break;
 
@@ -966,5 +1086,5 @@
                 mask |= O_SYNC;
 # endif
-                if ((file->flags & mask) == (arg & mask))
+                if ((file->oflags & mask) == (arg & mask))
                     rc = 0;
                 else
@@ -994,5 +1114,5 @@
                                     FALSE /* bInheritHandle */,
                                     DUPLICATE_SAME_ACCESS))
-                    rc = shfile_insert(pfdtab, (intptr_t)hNew, file->flags, arg, "shfile_fcntl");
+                    rc = shfile_insert(pfdtab, (intptr_t)hNew, file->oflags, file->shflags, arg, "shfile_fcntl");
                 else
                     rc = shfile_dos2errno(GetLastError());
@@ -1000,5 +1120,5 @@
                 int nativeNew = fcntl(file->native F_DUPFD, SHFILE_UNIX_MIN_FD);
                 if (nativeNew != -1)
-                    rc = shfile_insert(pfdtab, nativeNew, file->flags, arg, "shfile_fcntl");
+                    rc = shfile_insert(pfdtab, nativeNew, file->oflags, file->shflags, arg, "shfile_fcntl");
 # endif
                 break;
@@ -1204,5 +1324,8 @@
     if (file)
     {
-        file->cloexec = !!(closeit);
+        if (closeit)
+            file->shflags |= SHFILE_FLAGS_CLOSE_ON_EXEC;
+        else
+            file->shflags &= ~SHFILE_FLAGS_CLOSE_ON_EXEC;
         shfile_put(pfdtab, file, &tmp);
     }
Index: /trunk/src/kash/shfile.h
===================================================================
--- /trunk/src/kash/shfile.h	(revision 2306)
+++ /trunk/src/kash/shfile.h	(revision 2307)
@@ -102,8 +102,19 @@
 {
     int                 fd;             /**< The shell file descriptor number. */
-    int                 flags;          /**< Open flags. */
-    unsigned            cloexec : 1;    /**< Close on exec flag. */
+    unsigned            oflags;         /**< Open flags. */
+    unsigned            shflags;        /**< The shell file descriptor flags. */
     intptr_t            native;         /**< The native file descriptor number. */
 } shfile;
+
+/** @name shfile::shflags values.
+ * @{
+ */
+#define SHFILE_FLAGS_CLOSE_ON_EXEC      0x0001
+#define SHFILE_FLAGS_TYPE_MASK          0x00f0
+#define SHFILE_FLAGS_FILE               0x0000
+#define SHFILE_FLAGS_PIPE               0x0010
+#define SHFILE_FLAGS_DIR                0x0020
+#define SHFILE_FLAGS_TTY                0x0030
+/** @} */
 
 /**
