Index: fhandler_proc.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/fhandler_proc.cc,v
retrieving revision 1.2
diff -u -3 -p -u -p -a -w -r1.2 fhandler_proc.cc
--- fhandler_proc.cc	3 May 2002 02:43:45 -0000	1.2
+++ fhandler_proc.cc	3 May 2002 14:18:00 -0000
@@ -20,6 +20,8 @@ details. */
 #include "path.h"
 #include "sigproc.h"
 #include "pinfo.h"
+#include "dtable.h"
+#include "cygheap.h"
 #include <assert.h>
 #include <sys/utsname.h>
 
@@ -27,12 +29,14 @@ details. */
 #include <dirent.h>
 
 /* offsets in proc_listing */
-static const int PROC_REGISTRY = 0;     // /proc/registry
-static const int PROC_VERSION = 1;      // /proc/version
-static const int PROC_UPTIME = 2;       // /proc/uptime
+static const int PROC_REGISTRY = 2;     // /proc/registry
+static const int PROC_VERSION  = 3;     // /proc/version
+static const int PROC_UPTIME   = 4;     // /proc/uptime
 
 /* names of objects in /proc */
 static const char *proc_listing[] = {
+  ".",
+  "..",
   "registry",
   "version",
   "uptime",
@@ -45,6 +49,8 @@ static const int PROC_LINK_COUNT = (size
  * fhandler_proc.
  */
 static const DWORD proc_fhandlers[] = {
+  FH_PROC,
+  FH_PROC,
   FH_REGISTRY,
   FH_PROC,
   FH_PROC
@@ -92,7 +98,19 @@ fhandler_proc::get_proc_fhandler (const 
       if (p->pid == pid)
         return FH_PROCESS;
     }
+
+    bool has_subdir = false;
+    while (*path)
+            if (SLASH_P (*path++))
+                has_subdir = true;
+
+    if (has_subdir)
+        /* The user is trying to access a non-existent subdirectory of /proc. */
   return FH_BAD;
+    else
+        /* Return FH_PROC so that we can return EROFS if the user is trying to create
+           a file. */
+        return FH_PROC;
 }
 
 /* Returns 0 if path doesn't exist, >0 if path is a directory,
@@ -203,13 +221,13 @@ fhandler_proc::open (path_conv *pc, int 
 
   if (!*path)
     {
-      if ((mode & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
+      if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
         {
           set_errno (EEXIST);
           res = 0;
           goto out;
         }
-      else if (mode & O_WRONLY)
+      else if (flags & O_WRONLY)
         {
           set_errno (EISDIR);
           res = 0;
@@ -229,13 +247,13 @@ fhandler_proc::open (path_conv *pc, int 
         proc_file_no = i;
         if (proc_fhandlers[i] != FH_PROC)
           {
-            if ((mode & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
+            if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
               {
                 set_errno (EEXIST);
                 res = 0;
                 goto out;
               }
-            else if (mode & O_WRONLY)
+            else if (flags & O_WRONLY)
               {
                 set_errno (EISDIR);
                 res = 0;
@@ -251,7 +269,7 @@ fhandler_proc::open (path_conv *pc, int 
 
   if (proc_file_no == -1)
     {
-      if ((mode & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
+      if (flags & O_CREAT)
         {
           set_errno (EROFS);
           res = 0;
@@ -264,7 +282,7 @@ fhandler_proc::open (path_conv *pc, int 
           goto out;
         }
     }
-  if (mode & O_WRONLY)
+  if (flags & O_WRONLY)
     {
       set_errno (EROFS);
       res = 0;
@@ -278,7 +296,7 @@ fhandler_proc::open (path_conv *pc, int 
         uname (&uts_name);
         filesize = bufalloc = strlen (uts_name.sysname) + 1 +
           strlen (uts_name.release) + 1 + strlen (uts_name.version) + 2;
-        filebuf = new char[bufalloc];
+        filebuf = (char *) cmalloc (HEAP_BUF, bufalloc);
         __small_sprintf (filebuf, "%s %s %s\n", uts_name.sysname,
                          uts_name.release, uts_name.version);
         break;
@@ -290,7 +308,7 @@ fhandler_proc::open (path_conv *pc, int 
          * NT only dependancies.
          */
         DWORD ticks = GetTickCount ();
-        filebuf = new char[bufalloc = 40];
+        filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 40);
         __small_sprintf (filebuf, "%d.%02d\n", ticks / 1000,
                          (ticks / 10) % 100);
         filesize = strlen (filebuf);
Index: fhandler_process.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/fhandler_process.cc,v
retrieving revision 1.3
diff -u -3 -p -u -p -a -w -r1.3 fhandler_process.cc
--- fhandler_process.cc	3 May 2002 02:43:45 -0000	1.3
+++ fhandler_process.cc	3 May 2002 14:18:00 -0000
@@ -21,23 +21,27 @@ details. */
 #include "pinfo.h"
 #include "path.h"
 #include "shared_info.h"
+#include "dtable.h"
+#include "cygheap.h"
 #include <assert.h>
 
 #define _COMPILING_NEWLIB
 #include <dirent.h>
 
-static const int PROCESS_PPID = 0;
-static const int PROCESS_EXENAME = 1;
-static const int PROCESS_WINPID = 2;
-static const int PROCESS_WINEXENAME = 3;
-static const int PROCESS_STATUS = 4;
-static const int PROCESS_UID = 5;
-static const int PROCESS_GID = 6;
-static const int PROCESS_PGID = 7;
-static const int PROCESS_SID = 8;
-static const int PROCESS_CTTY = 9;
+static const int PROCESS_PPID = 2;
+static const int PROCESS_EXENAME = 3;
+static const int PROCESS_WINPID = 4;
+static const int PROCESS_WINEXENAME = 5;
+static const int PROCESS_STATUS = 6;
+static const int PROCESS_UID = 7;
+static const int PROCESS_GID = 8;
+static const int PROCESS_PGID = 9;
+static const int PROCESS_SID = 10;
+static const int PROCESS_CTTY = 11;
 
 static const char *process_listing[] = {
+  ".",
+  "..",
   "ppid",
   "exename",
   "winpid",
@@ -133,13 +137,13 @@ fhandler_process::open (path_conv *pc, i
 
   if (*path == 0)
     {
-      if ((mode & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
+      if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
         {
           set_errno (EEXIST);
           res = 0;
           goto out;
         }
-      else if (mode & O_WRONLY)
+      else if (flags & O_WRONLY)
         {
           set_errno (EISDIR);
           res = 0;
@@ -161,7 +165,7 @@ fhandler_process::open (path_conv *pc, i
     }
   if (process_file_no == -1)
     {
-      if ((mode & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
+      if (flags & O_CREAT)
         {
           set_errno (EROFS);
           res = 0;
@@ -174,7 +178,7 @@ fhandler_process::open (path_conv *pc, i
           goto out;
         }
     }
-  if (mode & O_WRONLY)
+  if (flags & O_WRONLY)
     {
       set_errno (EROFS);
       res = 0;
@@ -203,7 +207,7 @@ found:
     case PROCESS_CTTY:
     case PROCESS_PPID:
       {
-        filebuf = new char[bufalloc = 40];
+        filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 40);
         int num;
         switch (process_file_no)
           {
@@ -230,7 +234,7 @@ found:
       }
     case PROCESS_EXENAME:
       {
-        filebuf = new char[bufalloc = MAX_PATH];
+        filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = MAX_PATH);
         if (p->process_state & (PID_ZOMBIE | PID_EXITED))
           strcpy (filebuf, "<defunct>");
         else
@@ -249,7 +253,7 @@ found:
       }
     case PROCESS_WINPID:
       {
-        filebuf = new char[bufalloc = 40];
+        filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 40);
         __small_sprintf (filebuf, "%d\n", p->dwProcessId);
         filesize = strlen (filebuf);
         break;
@@ -257,7 +261,7 @@ found:
     case PROCESS_WINEXENAME:
       {
         int len = strlen (p->progname);
-        filebuf = new char[len + 2];
+        filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = (len + 2));
         strcpy (filebuf, p->progname);
         filebuf[len] = '\n';
         filesize = len + 1;
@@ -265,7 +269,7 @@ found:
       }
     case PROCESS_STATUS:
       {
-        filebuf = new char[bufalloc = 3];
+        filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 3);
         filebuf[0] = ' ';
         filebuf[1] = '\n';
         filebuf[2] = 0;
Index: fhandler_registry.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/fhandler_registry.cc,v
retrieving revision 1.2
diff -u -3 -p -u -p -a -w -r1.2 fhandler_registry.cc
--- fhandler_registry.cc	3 May 2002 02:43:45 -0000	1.2
+++ fhandler_registry.cc	3 May 2002 14:18:01 -0000
@@ -20,6 +20,8 @@ details. */
 #include "security.h"
 #include "fhandler.h"
 #include "path.h"
+#include "dtable.h"
+#include "cygheap.h"
 #include <assert.h>
 
 #define _COMPILING_NEWLIB
@@ -32,12 +34,15 @@ static const int registry_len = sizeof (
  * make up the value index if we are enuerating values.
  */
 static const __off32_t REG_ENUM_VALUES_MASK = 0x8000000;
+static const __off32_t REG_POSITION_MASK    = 0xffff;
 
 /* List of root keys in /proc/registry.
  * Possibly we should filter out those not relevant to the flavour of Windows
  * Cygwin is running on.
  */
 static const char *registry_listing[] = {
+  ".",
+  "..",
   "HKEY_CLASSES_ROOT",
   "HKEY_CURRENT_CONFIG",
   "HKEY_CURRENT_USER",
@@ -49,6 +54,8 @@ static const char *registry_listing[] = 
 };
 
 static const HKEY registry_keys[] = {
+  (HKEY) INVALID_HANDLE_VALUE,
+  (HKEY) INVALID_HANDLE_VALUE,
   HKEY_CLASSES_ROOT,
   HKEY_CURRENT_CONFIG,
   HKEY_CURRENT_USER,
@@ -60,6 +67,18 @@ static const HKEY registry_keys[] = {
 
 static const int ROOT_KEY_COUNT = sizeof(registry_keys) / sizeof(HKEY);
 
+/* These get added to each subdirectory in /proc/registry.
+ * If we wanted to implement writing, we could maybe add a '.writable' entry or
+ * suchlike.
+ */
+static const char *special_dot_files[] = {
+  ".",
+  "..",
+  NULL
+};
+
+static const int SPECIAL_DOT_FILE_COUNT = (sizeof(special_dot_files) / sizeof(const char *)) - 1;
+
 /* Name given to default values */
 static const char *DEFAULT_VALUE_NAME = "@";
 
@@ -213,6 +232,11 @@ fhandler_registry::readdir (DIR * dir)
     }
   if (dir->__d_u.__d_data.__handle == INVALID_HANDLE_VALUE)
     goto out;
+  if (dir->__d_position < SPECIAL_DOT_FILE_COUNT) {
+      strcpy (dir->__d_dirent->d_name, special_dot_files[dir->__d_position++]);
+      res = dir->__d_dirent;
+      goto out;
+  }
 retry:
   if (dir->__d_position & REG_ENUM_VALUES_MASK)
     /* For the moment, the type of key is ignored here. when write access is added,
@@ -223,8 +247,8 @@ retry:
                           buf, &buf_size, NULL, NULL, NULL, NULL);
   else
     error =
-      RegEnumKeyEx ((HKEY) dir->__d_u.__d_data.__handle, dir->__d_position,
-                    buf, &buf_size, NULL, NULL, NULL, NULL);
+      RegEnumKeyEx ((HKEY) dir->__d_u.__d_data.__handle, dir->__d_position -
+                    SPECIAL_DOT_FILE_COUNT, buf, &buf_size, NULL, NULL, NULL, NULL);
   if (error == ERROR_NO_MORE_ITEMS
       && (dir->__d_position & REG_ENUM_VALUES_MASK) == 0)
     {
@@ -260,7 +284,7 @@ out:
 __off64_t
 fhandler_registry::telldir (DIR * dir)
 {
-  return dir->__d_position & REG_ENUM_VALUES_MASK;
+  return dir->__d_position & REG_POSITION_MASK;
 }
 
 void
@@ -270,7 +294,7 @@ fhandler_registry::seekdir (DIR * dir, _
    * values.
    */
   rewinddir (dir);
-  while (loc > dir->__d_position)
+  while (loc > (dir->__d_position & REG_POSITION_MASK))
     if (!readdir (dir))
       break;
 }
@@ -318,13 +342,13 @@ fhandler_registry::open (path_conv *pc, 
   path = get_name () + proc_len + 1 + registry_len;
   if (!*path)
     {
-      if ((mode & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
+      if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
         {
           set_errno (EEXIST);
           res = 0;
           goto out;
         }
-      else if (mode & O_WRONLY)
+      else if (flags & O_WRONLY)
         {
           set_errno (EISDIR);
           res = 0;
@@ -351,13 +375,13 @@ fhandler_registry::open (path_conv *pc, 
         if (path_prefix_p
             (registry_listing[i], path, strlen (registry_listing[i])))
           {
-            if ((mode & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
+            if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
               {
                 set_errno (EEXIST);
                 res = 0;
                 goto out;
               }
-            else if (mode & O_WRONLY)
+            else if (flags & O_WRONLY)
               {
                 set_errno (EISDIR);
                 res = 0;
@@ -370,7 +394,7 @@ fhandler_registry::open (path_conv *pc, 
               }
           }
 
-      if ((mode & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
+      if (flags & O_CREAT)
         {
           set_errno (EROFS);
           res = 0;
@@ -384,15 +408,16 @@ fhandler_registry::open (path_conv *pc, 
         }
     }
 
-  hKey = open_key (path, KEY_READ, true);
-  if (hKey == (HKEY) INVALID_HANDLE_VALUE)
+  if (flags & O_WRONLY)
     {
+      set_errno (EROFS);
       res = 0;
       goto out;
     }
-  if (mode & O_WRONLY)
+
+  hKey = open_key (path, KEY_READ, true);
+  if (hKey == (HKEY) INVALID_HANDLE_VALUE)
     {
-      set_errno (EROFS);
       res = 0;
       goto out;
     }
@@ -409,7 +434,7 @@ fhandler_registry::open (path_conv *pc, 
           goto out;
         }
       bufalloc = size;
-      filebuf = new char[bufalloc];
+      filebuf = (char *) cmalloc (HEAP_BUF, bufalloc);
       error =
         RegQueryValueEx (hKey, file, NULL, NULL, (BYTE *) filebuf, &size);
       if (error != ERROR_SUCCESS)
@@ -428,8 +453,8 @@ fhandler_registry::open (path_conv *pc, 
           bufalloc += 1000;
           if (filebuf)
             {
-              delete filebuf;
-              filebuf = new char[bufalloc];
+              cfree (filebuf);
+              filebuf = (char *) cmalloc (HEAP_BUF, bufalloc);
             }
           error =
             RegQueryValueEx (hKey, file, NULL, &type, (BYTE *) filebuf,
Index: fhandler_virtual.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/fhandler_virtual.cc,v
retrieving revision 1.2
diff -u -3 -p -u -p -a -w -r1.2 fhandler_virtual.cc
--- fhandler_virtual.cc	3 May 2002 02:43:45 -0000	1.2
+++ fhandler_virtual.cc	3 May 2002 14:18:01 -0000
@@ -19,8 +19,8 @@ details. */
 #include "fhandler.h"
 #include "path.h"
 #include "dtable.h"
-#include "cygheap.h"
 #include "shared_info.h"
+#include "cygheap.h"
 #include <assert.h>
 
 #define _COMPILING_NEWLIB
@@ -132,18 +132,25 @@ fhandler_virtual::lseek (__off32_t offse
 int
 fhandler_virtual::dup (fhandler_base * child)
 {
+  int ret = fhandler_base::dup (child);
+
+  if (!ret)
+    {
   fhandler_virtual *fhproc_child = (fhandler_virtual *) child;
-  fhproc_child->filebuf = new char[filesize];
+      fhproc_child->filebuf = (char *) cmalloc (HEAP_BUF, filesize);
   fhproc_child->bufalloc = fhproc_child->filesize = filesize;
   fhproc_child->position = position;
-  return 0;
+      memcpy (fhproc_child->filebuf, filebuf, filesize);
+      fhproc_child->set_flags (get_flags ());
+    }
+  return ret;
 }
 
 int
 fhandler_virtual::close ()
 {
   if (filebuf)
-    delete[]filebuf;
+    cfree (filebuf);
   filebuf = NULL;
   bufalloc = -1;
   cygwin_shared->delqueue.process_queue ();
@@ -176,7 +183,7 @@ fhandler_virtual::read (void *ptr, size_
 int
 fhandler_virtual::write (const void *ptr, size_t len)
 {
-  set_errno (EROFS);
+  set_errno (EACCES);
   return -1;
 }
 
@@ -196,6 +203,8 @@ fhandler_virtual::open (path_conv *, int
   set_socket_p (false);
 
   set_flags (flags);
+
+  set_nohandle (true);
 
   return 1;
 }
Index: path.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/path.cc,v
retrieving revision 1.203
diff -u -3 -p -u -p -a -w -r1.203 path.cc
--- path.cc	3 May 2002 02:43:45 -0000	1.203
+++ path.cc	3 May 2002 14:18:12 -0000
@@ -525,13 +525,11 @@ path_conv::check (const char *src, unsig
               int file_type = fh->exists (path_copy);
               switch (file_type)
                 {
-                  case 0:
-                    error = ENOENT;
-		    break;
                   case 1:
                   case 2:
                     fileattr = FILE_ATTRIBUTE_DIRECTORY;
 		    break;
+                  default:
                   case -1:
                     fileattr = 0;
                 }
