changeset 10197:4d433bd2d4dc

attempt to avoid trouble with gnulib #defines in a consistent way
author John W. Eaton <jwe@octave.org>
date Tue, 26 Jan 2010 00:45:04 -0500
parents 69bb6e1e10d2
children 025564630c8d
files liboctave/ChangeLog liboctave/file-ops.cc liboctave/file-ops.h liboctave/lo-cutils.c liboctave/lo-utils.h src/ChangeLog src/DLD-FUNCTIONS/urlwrite.cc src/dirfns.cc src/file-io.cc src/oct-hist.cc src/syscalls.cc
diffstat 11 files changed, 646 insertions(+), 711 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/ChangeLog	Sat Jan 23 06:58:30 2010 +0100
+++ b/liboctave/ChangeLog	Tue Jan 26 00:45:04 2010 -0500
@@ -1,3 +1,16 @@
+2010-01-26  John W. Eaton  <jwe@octave.org>
+
+	* lo-cutils.c, lo-utils.h (octave_link, octave_symlink,
+	octave_readlink, octave_mkdir, octave_mkfifo, octave_rmdir,
+	octave_rename, octave_tempnam, octave_umask, octave_unlink):
+	Delete.
+	* file-io.h, file-io.cc (octave_mkdir,  octave_mkfifo,
+	octave_link, octave_symlink, octave_readlink, octave_rename,
+	octave_rmdir, octave_recursive_rmdir, octave_umask,
+	octave_unlink, octave_tempnam): Rename from file_ops::X to
+	octave_X.  Change all uses.
+	(file_ops::static_members): Incorporate directly into file_ops class.
+
 2010-01-23  John W. Eaton  <jwe@octave.org>
 
 	* Makefile.am (LIBOCTAVE_C_SOURCES): Remove oct-getopt.c from the list.
--- a/liboctave/file-ops.cc	Sat Jan 23 06:58:30 2010 +0100
+++ b/liboctave/file-ops.cc	Tue Jan 26 00:45:04 2010 -0500
@@ -33,7 +33,9 @@
 #include <iostream>
 #include <vector>
 
+#include <sys/stat.h>
 #include <sys/types.h>
+#include <unistd.h>
 
 #include <pathmax.h>
 
@@ -47,484 +49,38 @@
 #include "str-vec.h"
 #include "oct-locbuf.h"
 
-file_ops::static_members *file_ops::static_members::instance = 0;
-
-file_ops::static_members::static_members (void)
-  :
-#if (defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) && ! defined (OCTAVE_HAVE_POSIX_FILESYSTEM))
-  xdir_sep_char ('\\'),
-  xdir_sep_str ("\\"),
-#else
-  xdir_sep_char ('/'),
-  xdir_sep_str ("/"), 
-#endif
-#if defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM)
-  xdir_sep_chars ("/\\")
-#else
-  xdir_sep_chars (xdir_sep_str)
-#endif
-{ }
+file_ops *file_ops::instance = 0;
 
 bool
-file_ops::static_members::instance_ok (void)
+file_ops::instance_ok (void)
 {
   bool retval = true;
 
   if (! instance)
-    instance = new static_members ();
-
-  if (! instance)
     {
-      (*current_liboctave_error_handler)
-        ("unable to create file_ops::static_members object!");
-
-      retval = false;
-    }
-
-  return retval;
-}
-
-// We provide a replacement for mkdir().
-
-int
-file_ops::mkdir (const std::string& nm, mode_t md)
-{
-  std::string msg;
-  return mkdir (nm, md, msg);
-}
-
-int
-file_ops::mkdir (const std::string& name, mode_t mode, std::string& msg)
-{
-  msg = std::string ();
-
-  int status = -1;
-
-  status = octave_mkdir (name.c_str (), mode);
-
-  if (status < 0)
-    {
-      using namespace std;
-      msg = ::strerror (errno);
-    }
-
-  return status;
-}
-
-// I don't know how to emulate this on systems that don't provide it.
-
-int
-file_ops::mkfifo (const std::string& nm, mode_t md)
-{
-  std::string msg;
-  return mkfifo (nm, md, msg);
-}
-
-int
-file_ops::mkfifo (const std::string& name, mode_t mode, std::string& msg)
-{
-  msg = std::string ();
-
-  int status = -1;
-
-  // With gnulib we will always have mkfifo, but some systems like MinGW
-  // don't have working mkfifo functions.  On those systems, mkfifo will
-  // always return -1 and set errno.
-
-  status = octave_mkfifo (name.c_str (), mode);
-
-  if (status < 0)
-    {
-      using namespace std;
-      msg = ::strerror (errno);
-    }
-
-  return status;
-}
-
-// I don't know how to emulate this on systems that don't provide it.
-
-int
-file_ops::link (const std::string& old_name, const std::string& new_name)
-{
-  std::string msg;
-  return link (old_name, new_name, msg);
-}
-
-int
-file_ops::link (const std::string& old_name,
-                const std::string& new_name, std::string& msg)
-{
-  msg = std::string ();
-
-  int status = -1;
-
-  status = octave_link (old_name.c_str (), new_name.c_str ());
-
-  if (status < 0)
-    {
-      using namespace std;
-      msg = ::strerror (errno);
-    }
-
-  return status;
-}
-
-// I don't know how to emulate this on systems that don't provide it.
-
-int
-file_ops::symlink (const std::string& old_name, const std::string& new_name)
-{
-  std::string msg;
-  return symlink (old_name, new_name, msg);
-}
-
-int
-file_ops::symlink (const std::string& old_name,
-                   const std::string& new_name, std::string& msg)
-{
-  msg = std::string ();
-
-  int status = -1;
-
-  status = octave_symlink (old_name.c_str (), new_name.c_str ());
-
-  if (status < 0)
-    {
-      using namespace std;
-      msg = ::strerror (errno);
-    }
-
-  return status;
-}
-
-// We provide a replacement for readlink().
-
-int
-file_ops::readlink (const std::string& path, std::string& result)
-{
-  std::string msg;
-  return readlink (path, result, msg);
-}
-
-int
-file_ops::readlink (const std::string& path, std::string& result,
-                    std::string& msg)
-{
-  int status = -1;
-
-  msg = std::string ();
-
-  char buf[MAXPATHLEN+1];
-
-  status = octave_readlink (path.c_str (), buf, MAXPATHLEN);
-
-  if (status < 0)
-    {
-      using namespace std;
-      msg = ::strerror (errno);
-    }
-  else
-    {
-      buf[status] = '\0';
-      result = std::string (buf);
-      status = 0;
-    }
-
-  return status;
-}
-
-// We provide a replacement for rename().
-
-int
-file_ops::rename (const std::string& from, const std::string& to)
-{
-  std::string msg;
-  return rename (from, to, msg);
-}
-
-int
-file_ops::rename (const std::string& from, const std::string& to,
-                  std::string& msg)
-{
-  int status = -1;
-
-  msg = std::string ();
-
-  status = octave_rename (from.c_str (), to.c_str ());
-
-  if (status < 0)
-    {
-      using namespace std;
-      msg = ::strerror (errno);
-    }
-
-  return status;
-}
-
-// We provide a replacement for rmdir().
-
-int
-file_ops::rmdir (const std::string& name)
-{
-  std::string msg;
-  return rmdir (name, msg);
-}
-
-int
-file_ops::rmdir (const std::string& name, std::string& msg)
-{
-  msg = std::string ();
-
-  int status = -1;
-
-  status = octave_rmdir (name.c_str ());
-
-  if (status < 0)
-    {
-      using namespace std;
-      msg = ::strerror (errno);
-    }
-
-  return status;
-}
-
-// And a version that works recursively.
-
-int
-file_ops::recursive_rmdir (const std::string& name)
-{
-  std::string msg;
-  return recursive_rmdir (name, msg);
-}
-
-int
-file_ops::recursive_rmdir (const std::string& name, std::string& msg)
-{
-  msg = std::string ();
-
-  int status = 0;
-
-  dir_entry dir (name);
-
-  if (dir)
-    {
-      string_vector dirlist = dir.read ();
-
-      for (octave_idx_type i = 0; i < dirlist.length (); i++)
-        {
-          octave_quit ();
-
-          std::string nm = dirlist[i];
-
-          // Skip current directory and parent.
-          if (nm == "." || nm == "..")
-            continue;
-
-          std::string fullnm = name + file_ops::dir_sep_str () + nm;
-
-          // Get info about the file.  Don't follow links.
-          file_stat fs (fullnm, false);
-
-          if (fs)
-            {
-              if (fs.is_dir ())
-                {
-                  status = recursive_rmdir (fullnm, msg);
-
-                  if (status < 0)
-                    break;
-                }
-              else
-                {
-                  status = unlink (fullnm, msg);
-
-                  if (status < 0)
-                    break;
-                }
-            }
-          else
-            {
-              msg = fs.error ();
-              break;
-            }
-        }
-
-      if (status >= 0)
-        {
-          dir.close ();
-          status = file_ops::rmdir (name, msg);
-        }
-    }
-  else
-    {
-      status = -1;
-
-      msg = dir.error ();
-    }
-
-  return status;
-}
-
-std::string
-file_ops::canonicalize_file_name (const std::string& name)
-{
-  std::string msg;
-  return canonicalize_file_name (name, msg);
-}
-
-std::string
-file_ops::canonicalize_file_name (const std::string& name, std::string& msg)
-{
-  msg = std::string ();
-
-  std::string retval;
-
-#if defined (HAVE_CANONICALIZE_FILE_NAME)
-
-  char *tmp = ::canonicalize_file_name (name.c_str ());
-
-  if (tmp)
-    {
-      retval = tmp;
-      ::free (tmp);
-    }
-
-#elif defined (HAVE_RESOLVEPATH)
-
-#if !defined (errno)
-extern int errno;
+#if (defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) && ! defined (OCTAVE_HAVE_POSIX_FILESYSTEM))
+      char system_dir_sep_char = '\\';
+      std::string system_dir_sep_str = "\\";
+#else
+      char system_dir_sep_char = '/';
+      std::string system_dir_sep_str = "/";
+#endif
+#if defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM)
+      std::string system_dir_sep_chars = "/\\";
+#else
+      std::string system_dir_sep_chars = system_dir_sep_str;
 #endif
 
-#if !defined (__set_errno)
-# define __set_errno(Val) errno = (Val)
-#endif
-
-  if (name.empty ())
-    {
-      __set_errno (ENOENT);
-      return retval;
-    }
-
-  // All known hosts with resolvepath (e.g. Solaris 7) don't turn
-  // relative names into absolute ones, so prepend the working
-  // directory if the path is not absolute.
-
-  std::string absolute_name
-    = octave_env::make_absolute (name, octave_env::getcwd ());
-
-  size_t resolved_size = absolute_name.length ();
-
-  while (true)
-    {
-      resolved_size = 2 * resolved_size + 1;
-
-      OCTAVE_LOCAL_BUFFER (char, resolved, resolved_size);
-
-      int resolved_len
-        = ::resolvepath (absolute_name.c_str (), resolved, resolved_size);
-
-      if (resolved_len < 0)
-        break;
-
-      if (resolved_len < resolved_size)
-        {
-          retval = resolved;
-          break;
-        }
-    }
-
-#elif defined (__WIN32__)
-
-  int n = 1024;
-
-  std::string win_path (n, '\0');
-
-  while (true)
-    {
-      int status = GetFullPathName (name.c_str (), n, &win_path[0], 0);
-
-      if (status == 0)
-        break;
-      else if (status < n)
-        {
-          win_path.resize (status);
-          retval = win_path;
-          break;
-        }
-      else
-        {
-          n *= 2;
-          win_path.resize (n);
-        }
-    }
-
-#elif defined (HAVE_REALPATH)
+      instance = new file_ops (system_dir_sep_char, system_dir_sep_str,
+                               system_dir_sep_chars);
 
-#if !defined (__set_errno)
-# define __set_errno(Val) errno = (Val)
-#endif
-
-  if (name.empty ())
-    {
-      __set_errno (ENOENT);
-      return retval;
-    }
-
-  OCTAVE_LOCAL_BUFFER (char, buf, PATH_MAX);
-
-  if (::realpath (name.c_str (), buf))
-    retval = buf;
-
-#else
-
-  // FIXME -- provide replacement here...
-  retval = name;
-
-#endif
-
-  if (retval.empty ())
-    {
-      using namespace std;
-      msg = ::strerror (errno);
-    }
-
-  return retval;
-}
+      if (! instance)
+        {
+          (*current_liboctave_error_handler)
+            ("unable to create file_ops object!");
 
-// We provide a replacement for tempnam().
-
-std::string
-file_ops::tempnam (const std::string& dir, const std::string& pfx)
-{
-  std::string msg;
-  return tempnam (dir, pfx, msg);
-}
-
-std::string
-file_ops::tempnam (const std::string& dir, const std::string& pfx,
-                   std::string& msg)
-{
-  msg = std::string ();
-
-  std::string retval;
-  
-  const char *pdir = dir.empty () ? 0 : dir.c_str ();
-
-  const char *ppfx = pfx.empty () ? 0 : pfx.c_str ();
-
-  char *tmp = octave_tempnam (pdir, ppfx);
-
-  if (tmp)
-    {
-      retval = tmp;
-
-      ::free (tmp);
-    }
-  else
-    {
-      using namespace std;
-      msg = ::strerror (errno);
+          retval = false;
+        }
     }
 
   return retval;
@@ -787,42 +343,11 @@
   retval.resize (n);
 
   for (int i = 0; i < n; i++)
-    retval[i] = file_ops::tilde_expand (names[i]);
+    retval[i] = tilde_expand (names[i]);
 
   return retval;
 }
 
-int
-file_ops::umask (mode_t mode)
-{
-  return octave_umask (mode);
-}
-
-int
-file_ops::unlink (const std::string& name)
-{
-  std::string msg;
-  return unlink (name, msg);
-}
-
-int
-file_ops::unlink (const std::string& name, std::string& msg)
-{
-  msg = std::string ();
-
-  int status = -1;
-
-  status = octave_unlink (name.c_str ());
-
-  if (status < 0)
-    {
-      using namespace std;
-      msg = ::strerror (errno);
-    }
-
-  return status;
-}
-
 std::string
 file_ops::concat (const std::string& dir, const std::string& file)
 {
@@ -830,5 +355,471 @@
     ? file
     : (is_dir_sep (dir[dir.length()-1])
        ? dir + file
-       : dir + file_ops::dir_sep_char () + file);
+       : dir + dir_sep_char () + file);
+}
+
+
+std::string
+file_ops::canonicalize_file_name (const std::string& name)
+{
+  std::string msg;
+  return canonicalize_file_name (name, msg);
+}
+
+std::string
+file_ops::canonicalize_file_name (const std::string& name, std::string& msg)
+{
+  msg = std::string ();
+
+  std::string retval;
+
+#if defined (HAVE_CANONICALIZE_FILE_NAME)
+
+  char *tmp = ::canonicalize_file_name (name.c_str ());
+
+  if (tmp)
+    {
+      retval = tmp;
+      free (tmp);
+    }
+
+#elif defined (HAVE_RESOLVEPATH)
+
+#if !defined (errno)
+extern int errno;
+#endif
+
+#if !defined (__set_errno)
+# define __set_errno(Val) errno = (Val)
+#endif
+
+  if (name.empty ())
+    {
+      __set_errno (ENOENT);
+      return retval;
+    }
+
+  // All known hosts with resolvepath (e.g. Solaris 7) don't turn
+  // relative names into absolute ones, so prepend the working
+  // directory if the path is not absolute.
+
+  std::string absolute_name
+    = octave_env::make_absolute (name, octave_env::getcwd ());
+
+  size_t resolved_size = absolute_name.length ();
+
+  while (true)
+    {
+      resolved_size = 2 * resolved_size + 1;
+
+      OCTAVE_LOCAL_BUFFER (char, resolved, resolved_size);
+
+      int resolved_len
+        = resolvepath (absolute_name.c_str (), resolved, resolved_size);
+
+      if (resolved_len < 0)
+        break;
+
+      if (resolved_len < resolved_size)
+        {
+          retval = resolved;
+          break;
+        }
+    }
+
+#elif defined (__WIN32__)
+
+  int n = 1024;
+
+  std::string win_path (n, '\0');
+
+  while (true)
+    {
+      int status = GetFullPathName (name.c_str (), n, &win_path[0], 0);
+
+      if (status == 0)
+        break;
+      else if (status < n)
+        {
+          win_path.resize (status);
+          retval = win_path;
+          break;
+        }
+      else
+        {
+          n *= 2;
+          win_path.resize (n);
+        }
+    }
+
+#elif defined (HAVE_REALPATH)
+
+#if !defined (__set_errno)
+# define __set_errno(Val) errno = (Val)
+#endif
+
+  if (name.empty ())
+    {
+      __set_errno (ENOENT);
+      return retval;
+    }
+
+  OCTAVE_LOCAL_BUFFER (char, buf, PATH_MAX);
+
+  if (::realpath (name.c_str (), buf))
+    retval = buf;
+
+#else
+
+  // FIXME -- provide replacement here...
+  retval = name;
+
+#endif
+
+  if (retval.empty ())
+    {
+      using namespace std;
+      msg = strerror (errno);
+    }
+
+  return retval;
+}
+
+OCTAVE_API int
+octave_mkdir (const std::string& nm, mode_t md)
+{
+  std::string msg;
+  return octave_mkdir (nm, md, msg);
+}
+
+OCTAVE_API int
+octave_mkdir (const std::string& name, mode_t mode, std::string& msg)
+{
+  msg = std::string ();
+
+  int status = -1;
+
+  status = mkdir (name.c_str (), mode);
+
+  if (status < 0)
+    {
+      using namespace std;
+      msg = strerror (errno);
+    }
+
+  return status;
+}
+
+OCTAVE_API int
+octave_mkfifo (const std::string& nm, mode_t md)
+{
+  std::string msg;
+  return octave_mkfifo (nm, md, msg);
+}
+
+OCTAVE_API int
+octave_mkfifo (const std::string& name, mode_t mode, std::string& msg)
+{
+  msg = std::string ();
+
+  int status = -1;
+
+  // With gnulib we will always have mkfifo, but some systems like MinGW
+  // don't have working mkfifo functions.  On those systems, mkfifo will
+  // always return -1 and set errno.
+
+  status = mkfifo (name.c_str (), mode);
+
+  if (status < 0)
+    {
+      using namespace std;
+      msg = strerror (errno);
+    }
+
+  return status;
+}
+
+OCTAVE_API int
+octave_link (const std::string& old_name, const std::string& new_name)
+{
+  std::string msg;
+  return octave_link (old_name, new_name, msg);
+}
+
+OCTAVE_API int
+octave_link (const std::string& old_name,
+                const std::string& new_name, std::string& msg)
+{
+  msg = std::string ();
+
+  int status = -1;
+
+  status = link (old_name.c_str (), new_name.c_str ());
+
+  if (status < 0)
+    {
+      using namespace std;
+      msg = strerror (errno);
+    }
+
+  return status;
+}
+
+OCTAVE_API int
+octave_symlink (const std::string& old_name, const std::string& new_name)
+{
+  std::string msg;
+  return octave_symlink (old_name, new_name, msg);
 }
+
+OCTAVE_API int
+octave_symlink (const std::string& old_name,
+                   const std::string& new_name, std::string& msg)
+{
+  msg = std::string ();
+
+  int status = -1;
+
+  status = symlink (old_name.c_str (), new_name.c_str ());
+
+  if (status < 0)
+    {
+      using namespace std;
+      msg = strerror (errno);
+    }
+
+  return status;
+}
+
+OCTAVE_API int
+octave_readlink (const std::string& path, std::string& result)
+{
+  std::string msg;
+  return octave_readlink (path, result, msg);
+}
+
+OCTAVE_API int
+octave_readlink (const std::string& path, std::string& result,
+                    std::string& msg)
+{
+  int status = -1;
+
+  msg = std::string ();
+
+  char buf[MAXPATHLEN+1];
+
+  status = readlink (path.c_str (), buf, MAXPATHLEN);
+
+  if (status < 0)
+    {
+      using namespace std;
+      msg = strerror (errno);
+    }
+  else
+    {
+      buf[status] = '\0';
+      result = std::string (buf);
+      status = 0;
+    }
+
+  return status;
+}
+
+OCTAVE_API int
+octave_rename (const std::string& from, const std::string& to)
+{
+  std::string msg;
+  return octave_rename (from, to, msg);
+}
+
+OCTAVE_API int
+octave_rename (const std::string& from, const std::string& to,
+                  std::string& msg)
+{
+  int status = -1;
+
+  msg = std::string ();
+
+  status = rename (from.c_str (), to.c_str ());
+
+  if (status < 0)
+    {
+      using namespace std;
+      msg = strerror (errno);
+    }
+
+  return status;
+}
+
+OCTAVE_API int
+octave_rmdir (const std::string& name)
+{
+  std::string msg;
+  return octave_rmdir (name, msg);
+}
+
+OCTAVE_API int
+octave_rmdir (const std::string& name, std::string& msg)
+{
+  msg = std::string ();
+
+  int status = -1;
+
+  status = rmdir (name.c_str ());
+
+  if (status < 0)
+    {
+      using namespace std;
+      msg = strerror (errno);
+    }
+
+  return status;
+}
+
+// And a version that works recursively.
+
+OCTAVE_API int
+octave_recursive_rmdir (const std::string& name)
+{
+  std::string msg;
+  return octave_recursive_rmdir (name, msg);
+}
+
+OCTAVE_API int
+octave_recursive_rmdir (const std::string& name, std::string& msg)
+{
+  msg = std::string ();
+
+  int status = 0;
+
+  dir_entry dir (name);
+
+  if (dir)
+    {
+      string_vector dirlist = dir.read ();
+
+      for (octave_idx_type i = 0; i < dirlist.length (); i++)
+        {
+          octave_quit ();
+
+          std::string nm = dirlist[i];
+
+          // Skip current directory and parent.
+          if (nm == "." || nm == "..")
+            continue;
+
+          std::string fullnm = name + file_ops::dir_sep_str () + nm;
+
+          // Get info about the file.  Don't follow links.
+          file_stat fs (fullnm, false);
+
+          if (fs)
+            {
+              if (fs.is_dir ())
+                {
+                  status = octave_recursive_rmdir (fullnm, msg);
+
+                  if (status < 0)
+                    break;
+                }
+              else
+                {
+                  status = octave_unlink (fullnm, msg);
+
+                  if (status < 0)
+                    break;
+                }
+            }
+          else
+            {
+              msg = fs.error ();
+              break;
+            }
+        }
+
+      if (status >= 0)
+        {
+          dir.close ();
+          status = octave_rmdir (name, msg);
+        }
+    }
+  else
+    {
+      status = -1;
+
+      msg = dir.error ();
+    }
+
+  return status;
+}
+
+OCTAVE_API int
+octave_umask (mode_t mode)
+{
+#if defined (HAVE_UMASK)
+  return umask (mode);
+#else
+  return 0;
+#endif
+}
+
+OCTAVE_API int
+octave_unlink (const std::string& name)
+{
+  std::string msg;
+  return octave_unlink (name, msg);
+}
+
+OCTAVE_API int
+octave_unlink (const std::string& name, std::string& msg)
+{
+  msg = std::string ();
+
+  int status = -1;
+
+  status = unlink (name.c_str ());
+
+  if (status < 0)
+    {
+      using namespace std;
+      msg = strerror (errno);
+    }
+
+  return status;
+}
+
+OCTAVE_API std::string
+octave_tempnam (const std::string& dir, const std::string& pfx)
+{
+  std::string msg;
+  return octave_tempnam (dir, pfx, msg);
+}
+
+OCTAVE_API std::string
+octave_tempnam (const std::string& dir, const std::string& pfx,
+                std::string& msg)
+{
+  msg = std::string ();
+
+  std::string retval;
+  
+  const char *pdir = dir.empty () ? 0 : dir.c_str ();
+
+  const char *ppfx = pfx.empty () ? 0 : pfx.c_str ();
+
+  char *tmp = tempnam (pdir, ppfx);
+
+  if (tmp)
+    {
+      retval = tmp;
+
+      free (tmp);
+    }
+  else
+    {
+      using namespace std;
+      msg = strerror (errno);
+    }
+
+  return retval;
+}
--- a/liboctave/file-ops.h	Sat Jan 23 06:58:30 2010 +0100
+++ b/liboctave/file-ops.h	Tue Jan 26 00:45:04 2010 -0500
@@ -35,36 +35,15 @@
 {
 public:
 
-  static int mkdir (const std::string& nm, mode_t md);
-  static int mkdir (const std::string& nm, mode_t md, std::string& msg);
-
-  static int mkfifo (const std::string& nm, mode_t md);
-  static int mkfifo (const std::string& nm, mode_t md, std::string& msg);
-
-  static int link (const std::string&, const std::string&);
-  static int link (const std::string&, const std::string&, std::string&);
-
-  static int symlink (const std::string&, const std::string&);
-  static int symlink (const std::string&, const std::string&, std::string&);
-
-  static int readlink (const std::string&, std::string&);
-  static int readlink (const std::string&, std::string&, std::string&);
+  // Use a singleton class for dir_sep data members instead of just
+  // making them static members of the dir_path class so that we can
+  // ensure proper initialization.
 
-  static int rename (const std::string&, const std::string&);
-  static int rename (const std::string&, const std::string&, std::string&);
-
-  static int rmdir (const std::string&);
-  static int rmdir (const std::string&, std::string&);
-
-  static int recursive_rmdir (const std::string&);
-  static int recursive_rmdir (const std::string&, std::string&);
-
-  static std::string canonicalize_file_name (const std::string&);
-  static std::string canonicalize_file_name (const std::string&, std::string&);
-
-  static std::string tempnam (const std::string&, const std::string&);
-  static std::string tempnam (const std::string&, const std::string&,
-                              std::string&);
+  file_ops (char dir_sep_char_arg = 0,
+            const std::string& dir_sep_str_arg = std::string ("/"),
+            const std::string& dir_sep_chars_arg = std::string ("/"))
+    : xdir_sep_char (dir_sep_char_arg), xdir_sep_str (dir_sep_str_arg),
+      xdir_sep_chars (dir_sep_chars_arg) { }
 
   typedef std::string (*tilde_expansion_hook) (const std::string&);
 
@@ -76,13 +55,20 @@
 
   static string_vector tilde_additional_suffixes;
 
-  static std::string tilde_expand (const std::string&);
-  static string_vector tilde_expand (const string_vector&);
+  static char dir_sep_char (void)
+  {
+    return instance_ok () ? instance->xdir_sep_char : 0;
+  }
 
-  static int umask (mode_t);
+  static std::string dir_sep_str (void)
+  {
+    return instance_ok () ? instance->xdir_sep_str : std::string ();
+  }
 
-  static int unlink (const std::string&);
-  static int unlink (const std::string&, std::string&);
+  static std::string dir_sep_chars (void)
+  {
+    return instance_ok () ? instance->xdir_sep_chars : std::string ();
+  }
 
   static bool is_dir_sep (char c)
   {
@@ -90,25 +76,14 @@
     return tmp.find (c) != std::string::npos;
   }
 
+  static std::string tilde_expand (const std::string&);
+
+  static string_vector tilde_expand (const string_vector&);
+
   static std::string concat (const std::string&, const std::string&);
 
-  static char dir_sep_char (void)
-  {
-    return static_members::dir_sep_char ();
-  }
-
-  static std::string dir_sep_str (void)
-  {
-    return static_members::dir_sep_str ();
-  }
-
-  static std::string dir_sep_chars (void)
-  {
-    return static_members::dir_sep_chars ();
-  }
-
-  // Return the tail member of a path.
-  static std::string tail (std::string path)
+  // Return the tail member of a file name.
+  static std::string tail (const std::string& path)
   {
     size_t ipos = path.find_last_of (dir_sep_chars ());
 
@@ -120,54 +95,92 @@
     return path.substr (ipos);
   }
 
+  static std::string canonicalize_file_name (const std::string&);
+
+  static std::string canonicalize_file_name (const std::string&, std::string&);
+
 private:
 
-  static int mkdir_internal (const std::string&, mode_t, std::string&);
-
-  static int mkfifo_internal (const std::string&, mode_t, std::string&);
-
-  // Use a singleton class for these data members instead of just
-  // making them static members of the dir_path class so that we can
-  // ensure proper initialization.
+  static file_ops *instance;
 
-  class static_members
-  {
-  public:
+  // No copying!
 
-    static_members (void);
-
-    static char dir_sep_char (void)
-    {
-      return instance_ok () ? instance->xdir_sep_char : 0;
-    }
+  file_ops (const file_ops&);
 
-    static std::string dir_sep_str (void)
-    {
-      return instance_ok () ? instance->xdir_sep_str : std::string ();
-    }
+  file_ops& operator = (const file_ops&);
 
-    static std::string dir_sep_chars (void)
-    {
-      return instance_ok () ? instance->xdir_sep_chars : std::string ();
-    }
-
-  private:
+  static bool instance_ok (void);
 
-    // The real thing.
-    static static_members *instance;
-
-    // No copying!
-
-    static_members (const static_members&);
-
-    static_members& operator = (const static_members&);
-
-    static bool instance_ok (void);
-
-    char xdir_sep_char;
-    std::string xdir_sep_str;
-    std::string xdir_sep_chars;
-  };
+  char xdir_sep_char;
+  std::string xdir_sep_str;
+  std::string xdir_sep_chars;
 };
 
+// We don't have these in the file_ops class with their simple names
+// (i.e., mkdir instead of octave_mdir) because function names in
+// standard headers may be #defined.
+
+extern OCTAVE_API int
+octave_mkdir (const std::string& nm, mode_t md);
+
+extern OCTAVE_API int
+octave_mkdir (const std::string& nm, mode_t md, std::string& msg);
+
+extern OCTAVE_API int
+octave_mkfifo (const std::string& nm, mode_t md);
+
+extern OCTAVE_API int
+octave_mkfifo (const std::string& nm, mode_t md, std::string& msg);
+
+extern OCTAVE_API int
+octave_link (const std::string&, const std::string&);
+
+extern OCTAVE_API int
+octave_link (const std::string&, const std::string&, std::string&);
+
+extern OCTAVE_API int
+octave_symlink (const std::string&, const std::string&);
+
+extern OCTAVE_API int
+octave_symlink (const std::string&, const std::string&, std::string&);
+
+extern OCTAVE_API int
+octave_readlink (const std::string&, std::string&);
+
+extern OCTAVE_API int
+octave_readlink (const std::string&, std::string&, std::string&);
+
+extern OCTAVE_API int
+octave_rename (const std::string&, const std::string&);
+
+extern OCTAVE_API int
+octave_rename (const std::string&, const std::string&, std::string&);
+
+extern OCTAVE_API int
+octave_rmdir (const std::string&);
+
+extern OCTAVE_API int
+octave_rmdir (const std::string&, std::string&);
+
+extern OCTAVE_API int
+octave_recursive_rmdir (const std::string&);
+
+extern OCTAVE_API int
+octave_recursive_rmdir (const std::string&, std::string&);
+
+extern OCTAVE_API int
+octave_umask (mode_t);
+
+extern OCTAVE_API int
+octave_unlink (const std::string&);
+
+extern OCTAVE_API int
+octave_unlink (const std::string&, std::string&);
+
+extern OCTAVE_API std::string
+octave_tempnam (const std::string&, const std::string&);
+
+extern OCTAVE_API std::string
+octave_tempnam (const std::string&, const std::string&, std::string&);
+
 #endif
--- a/liboctave/lo-cutils.c	Sat Jan 23 06:58:30 2010 +0100
+++ b/liboctave/lo-cutils.c	Tue Jan 26 00:45:04 2010 -0500
@@ -48,36 +48,6 @@
 
 #include "syswait.h"
 
-OCTAVE_API int
-octave_link (const char *old_name, const char *new_name)
-{
-  return link (old_name, new_name);
-}
-
-OCTAVE_API int
-octave_symlink (const char *old_name, const char *new_name)
-{
-  return symlink (old_name, new_name);
-}
-
-OCTAVE_API int
-octave_readlink (const char *name, char *buf, size_t size)
-{
-  return readlink (name, buf, size);
-}
-
-OCTAVE_API int
-octave_mkdir (const char *name, mode_t mode)
-{
-  return mkdir (name, mode);
-}
-
-OCTAVE_API int
-octave_mkfifo (const char *name, mode_t mode)
-{
-  return mkfifo (name, mode);
-}
-
 OCTAVE_API void
 octave_qsort (void *base, size_t n, size_t size,
               int (*cmp) (const void *, const void *))
@@ -118,18 +88,6 @@
 #endif
 
 OCTAVE_API int
-octave_rmdir (const char *name)
-{
-  return rmdir (name);
-}
-
-OCTAVE_API int
-octave_rename (const char *from, const char *to)
-{
-  return rename (from, to);
-}
-
-OCTAVE_API int
 octave_strcasecmp (const char *s1, const char *s2)
 {
   return strcasecmp (s1, s2);
@@ -141,28 +99,6 @@
   return strncasecmp (s1, s2, n);
 }
 
-OCTAVE_API char *
-octave_tempnam (const char *pdir, const char *ppfx)
-{
-  return tempnam (pdir, ppfx);
-}
-
-OCTAVE_API mode_t
-octave_umask (mode_t mode)
-{
-#if defined (HAVE_UMASK)
-  return umask (mode);
-#else
-  return 0;
-#endif
-}
-
-OCTAVE_API int
-octave_unlink (const char *name)
-{
-  return unlink (name);
-}
-
 OCTAVE_API int
 octave_gethostname (char *name, int namelen)
 {
--- a/liboctave/lo-utils.h	Sat Jan 23 06:58:30 2010 +0100
+++ b/liboctave/lo-utils.h	Tue Jan 26 00:45:04 2010 -0500
@@ -52,30 +52,10 @@
 
 extern "C" OCTAVE_API int octave_gethostname (char *, int);
 
-extern "C" OCTAVE_API int
-octave_link (const char *old_name, const char *new_name);
-
-extern "C" OCTAVE_API int
-octave_symlink (const char *old_name, const char *new_name);
-
-extern "C" OCTAVE_API int
-octave_readlink (const char *name, char *buf, size_t size);
-
-extern "C" OCTAVE_API int
-octave_mkdir (const char *name, mode_t mode);
-
-extern "C" OCTAVE_API int
-octave_mkfifo (const char *name, mode_t mode);
-
 extern "C" OCTAVE_API void
 octave_qsort (void *base, size_t n, size_t size,
               int (*cmp) (const void *, const void *));
 
-extern "C" OCTAVE_API int octave_rmdir (const char *name);
-
-extern "C" OCTAVE_API int
-octave_rename (const char *from, const char *to);
-
 extern "C" OCTAVE_API char *
 oct_strptime (const char *buf, const char *format, struct tm *tm);
 
@@ -85,13 +65,6 @@
 extern "C" OCTAVE_API int
 octave_strncasecmp (const char *s1, const char *s2, size_t n);
 
-extern "C" OCTAVE_API char *
-octave_tempnam (const char *pdir, const char *ppfx);
-
-extern "C" OCTAVE_API mode_t octave_umask (mode_t);
-
-extern "C" OCTAVE_API int octave_unlink (const char *name);
-
 template <typename T>
 T
 octave_read_value (std::istream& is)
--- a/src/ChangeLog	Sat Jan 23 06:58:30 2010 +0100
+++ b/src/ChangeLog	Tue Jan 26 00:45:04 2010 -0500
@@ -1,3 +1,11 @@
+2010-01-26  John W. Eaton  <jwe@octave.org>
+
+	* dirfns.cc (Fmkdir, Frmdir, Flink, Fsymlink, Freadlink,
+	Frename, Ftmpnam, Fumask): Use DEFUNX instead of DEFUN.
+	* syscall.scc (Fmkfifo, Funlink): Ditto.
+	* DLD-FUNCTIONS/urlwrite.cc (cleanup_urlwrite, reset_path,
+	delete_file): Now static.
+
 2010-01-23  John W. Eaton  <jwe@octave.org>
 
 	* octave.cc (octave_main): Use getopt directly instead of using
--- a/src/DLD-FUNCTIONS/urlwrite.cc	Sat Jan 23 06:58:30 2010 +0100
+++ b/src/DLD-FUNCTIONS/urlwrite.cc	Tue Jan 26 00:45:04 2010 -0500
@@ -660,21 +660,22 @@
 
 static curl_handles handles;
 
-static void 
+static void
 cleanup_urlwrite (std::string filename)
 {
-  file_ops::unlink (filename);
+  octave_unlink (filename);
 }
 
-static void 
+static void
 reset_path (const curl_handle curl)
 {
   curl.cwd ("..");
 }
 
-void delete_file (std::string file)
+static void
+delete_file (std::string file)
 {
-  file_ops::unlink (file);
+  octave_unlink (file);
 }
 #endif
 
@@ -1586,7 +1587,7 @@
   if (!fs || !fs.is_dir ())
     { 
       std::string msg;
-      int status = file_ops::mkdir (dir, 0777, msg);
+      int status = octave_mkdir (dir, 0777, msg);
 
       if (status < 0)
         error ("__ftp_mget__: can't create directory %s%s%s. %s", 
--- a/src/dirfns.cc	Sat Jan 23 06:58:30 2010 +0100
+++ b/src/dirfns.cc	Tue Jan 26 00:45:04 2010 -0500
@@ -202,7 +202,7 @@
 // FIXME -- should maybe also allow second arg to specify
 // mode?  OTOH, that might cause trouble with compatibility later...
 
-DEFUN (mkdir, args, ,
+DEFUNX ("mkdir", Fmkdir, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {[@var{status}, @var{msg}, @var{msgid}] =} mkdir (@var{dir})\n\
 @deftypefnx {Built-in Function} {[@var{status}, @var{msg}, @var{msgid}] =} mkdir (@var{parent}, @var{dir})\n\
@@ -268,7 +268,7 @@
 	}
       else
 	{
-	  int status = file_ops::mkdir (dirname, 0777, msg);
+	  int status = octave_mkdir (dirname, 0777, msg);
 
 	  if (status < 0)
 	    {
@@ -285,7 +285,7 @@
   return retval;
 }
 
-DEFUN (rmdir, args, ,
+DEFUNX ("rmdir", Frmdir, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {[@var{status}, @var{msg}, @var{msgid}] =} rmdir (@var{dir})\n\
 @deftypefnx {Built-in Function} {[@var{status}, @var{msg}, @var{msgid}] =} rmdir (@var{dir}, @code{\"s\"})\n\
@@ -336,13 +336,13 @@
 		    }
 
 		  if (doit)
-		    status = file_ops::recursive_rmdir (fulldir, msg);
+		    status = octave_recursive_rmdir (fulldir, msg);
 		}
 	      else
 		error ("rmdir: expecting second argument to be \"s\"");
 	    }
 	  else
-	    status = file_ops::rmdir (fulldir, msg);
+	    status = octave_rmdir (fulldir, msg);
 
 	  if (status < 0)
 	    {
@@ -359,7 +359,7 @@
   return retval;
 }
 
-DEFUN (link, args, ,
+DEFUNX ("link", Flink, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} link (@var{old}, @var{new})\n\
 Create a new link (also known as a hard link) to an existing file.\n\
@@ -391,7 +391,7 @@
 	    {
 	      std::string msg;
 
-	      int status = file_ops::link (from, to, msg);
+	      int status = octave_link (from, to, msg);
 
 	      retval(0) = status;
 
@@ -406,7 +406,7 @@
   return retval;
 }
 
-DEFUN (symlink, args, ,
+DEFUNX ("symlink", Fsymlink, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} symlink (@var{old}, @var{new})\n\
 Create a symbolic link @var{new} which contains the string @var{old}.\n\
@@ -438,7 +438,7 @@
 	    {
 	      std::string msg;
 
-	      int status = file_ops::symlink (from, to, msg);
+	      int status = octave_symlink (from, to, msg);
 
 	      retval(0) = status;
 
@@ -453,7 +453,7 @@
   return retval;
 }
 
-DEFUN (readlink, args, ,
+DEFUNX ("readlink", Freadlink, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {[@var{result}, @var{err}, @var{msg}] =} readlink (@var{symlink})\n\
 Read the value of the symbolic link @var{symlink}.\n\
@@ -482,7 +482,7 @@
 	  std::string result;
 	  std::string msg;
 
-	  int status = file_ops::readlink (symlink, result, msg);
+	  int status = octave_readlink (symlink, result, msg);
 
 	  retval(0) = result;
 
@@ -498,7 +498,7 @@
   return retval;
 }
 
-DEFUN (rename, args, ,
+DEFUNX ("rename", Frename, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} rename (@var{old}, @var{new})\n\
 Change the name of file @var{old} to @var{new}.\n\
@@ -530,7 +530,7 @@
 	    {
 	      std::string msg;
 
-	      int status = file_ops::rename (from, to, msg);
+	      int status = octave_rename (from, to, msg);
 
 	      retval(0) = status;
 
--- a/src/file-io.cc	Sat Jan 23 06:58:30 2010 +0100
+++ b/src/file-io.cc	Tue Jan 26 00:45:04 2010 -0500
@@ -1852,7 +1852,7 @@
   return retval;
 }
 
-DEFUN (tmpnam, args, ,
+DEFUNX ("tmpnam", Ftmpnam, args, ,
  "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} tmpnam (@var{dir}, @var{prefix})\n\
 Return a unique temporary file name as a string.\n\
@@ -1880,7 +1880,7 @@
 	    = len > 1 ? args(1).string_value () : std::string ("oct-");
 
 	  if (! error_state)
-	    retval = file_ops::tempnam (dir, pfx);
+	    retval = octave_tempnam (dir, pfx);
 	  else
 	    ::error ("expecting second argument to be a string");
 	}
@@ -2098,7 +2098,7 @@
   return retval;
 }
 
-DEFUN (umask, args, ,
+DEFUNX ("umask", Fumask, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} umask (@var{mask})\n\
 Set the permission mask for file creation.  The parameter @var{mask}\n\
@@ -2127,7 +2127,7 @@
 	      int oct_mask = convert (mask, 8, 10);
 
 	      if (! error_state)
-		status = convert (file_ops::umask (oct_mask), 10, 8);
+		status = convert (octave_umask (oct_mask), 10, 8);
 	    }
 	}
       else
--- a/src/oct-hist.cc	Sat Jan 23 06:58:30 2010 +0100
+++ b/src/oct-hist.cc	Tue Jan 26 00:45:04 2010 -0500
@@ -393,7 +393,7 @@
       reverse = 1;
     }
 
-  std::string name = file_ops::tempnam ("", "oct-");
+  std::string name = octave_tempnam ("", "oct-");
 
   std::fstream file (name.c_str (), std::ios::out);
 
--- a/src/syscalls.cc	Sat Jan 23 06:58:30 2010 +0100
+++ b/src/syscalls.cc	Tue Jan 26 00:45:04 2010 -0500
@@ -796,7 +796,7 @@
 
 
 
-DEFUN (mkfifo, args, ,
+DEFUNX ("mkfifo", Fmkfifo, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} mkfifo (@var{name}, @var{mode})\n\
 Create a @var{fifo} special file named @var{name} with file mode @var{mode}\n\
@@ -827,7 +827,7 @@
 		{
 		  std::string msg;
 
-		  int status = file_ops::mkfifo (name, mode, msg);
+		  int status = octave_mkfifo (name, mode, msg);
 
 		  retval(0) = status;
 
@@ -1247,7 +1247,7 @@
   return retval;
 }
 
-DEFUN (unlink, args, ,
+DEFUNX ("unlink", Funlink, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} unlink (@var{file})\n\
 Delete the file named @var{file}.\n\
@@ -1272,7 +1272,7 @@
 
 	  std::string msg;
 
-	  int status = file_ops::unlink (name, msg);
+	  int status = octave_unlink (name, msg);
 
 	  retval(0) = status;
 	  retval(1) = msg;