changeset 20200:d9f35ceff9e1

Change mkfifo to use an octal argument for MODE (bug #45054). * NEWS: Announce switch from decimal to octal MODE for mkfifo. * file-io.cc (convert): Add a FIXME note that this function is repeated in * syscalls.cc. * syscalls.cc (convert): New function to convert from one base to another. * syscalls.cc (Fmkfifo): Change docstring to note that MODE argument is now octal. Convert MODE from octal to decimal before calling octave_mkfifo(). Add BIST tests. * __gnuplot_get_var__.m, __gnuplot_ginput__.m: Change instances of MODE argument in m-files from decimal to octal.
author Rik <rik@octave.org>
date Sun, 17 May 2015 10:04:08 -0700
parents 5fb4bc5f70ce
children 70e8801a56f7
files NEWS libinterp/corefcn/file-io.cc libinterp/corefcn/syscalls.cc scripts/plot/util/private/__gnuplot_get_var__.m scripts/plot/util/private/__gnuplot_ginput__.m
diffstat 5 files changed, 70 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Sun May 17 09:48:12 2015 -0700
+++ b/NEWS	Sun May 17 10:04:08 2015 -0700
@@ -1,6 +1,9 @@
 Summary of important user-visible changes for version 4.2:
 ---------------------------------------------------------
 
+ ** mkfifo now interprets the MODE argument as an octal, not decimal, integer.
+    This is consistent with the equivalent shell command. 
+
  ** Other new functions added in 4.2:
 
       psi
--- a/libinterp/corefcn/file-io.cc	Sun May 17 09:48:12 2015 -0700
+++ b/libinterp/corefcn/file-io.cc	Sun May 17 10:04:08 2015 -0700
@@ -2204,6 +2204,8 @@
   return retval;
 }
 
+// FIXME: This routine also exists verbatim in syscalls.cc.
+//        Maybe change to be a general utility routine.
 static int
 convert (int x, int ibase, int obase)
 {
--- a/libinterp/corefcn/syscalls.cc	Sun May 17 09:48:12 2015 -0700
+++ b/libinterp/corefcn/syscalls.cc	Sun May 17 10:04:08 2015 -0700
@@ -819,15 +819,45 @@
   return retval;
 }
 
+// FIXME: This routine also exists verbatim in file-io.cc.
+//        Maybe change to be a general utility routine.
+static int
+convert (int x, int ibase, int obase)
+{
+  int retval = 0;
+
+  int tmp = x % obase;
+
+  if (tmp > ibase - 1)
+    ::error ("mkfifo: invalid digit");
+  else
+    {
+      retval = tmp;
+      int mult = ibase;
+      while ((x = (x - tmp) / obase))
+        {
+          tmp = x % obase;
+          if (tmp > ibase - 1)
+            {
+              ::error ("mkfifo: invalid digit");
+              break;
+            }
+          retval += mult * tmp;
+          mult *= ibase;
+        }
+    }
+
+  return retval;
+}
+
 DEFUNX ("mkfifo", Fmkfifo, args, ,
         "-*- texinfo -*-\n\
 @deftypefn  {Built-in Function} {@var{err} =} mkfifo (@var{name}, @var{mode})\n\
 @deftypefnx {Built-in Function} {[@var{err}, @var{msg}] =} mkfifo (@var{name}, @var{mode})\n\
 Create a FIFO special file named @var{name} with file mode @var{mode}.\n\
 \n\
-@var{mode} is interpreted as a decimal number (@emph{not} octal) and is\n\
-subject to umask processing.  The final calculated mode is\n\
-@code{@var{mode} - @var{umask}}.\n\
+@var{mode} is interpreted as an octal number and is subject to umask\n\
+processing.  The final calculated mode is @code{@var{mode} - @var{umask}}.\n\
 \n\
 If successful, @var{err} is 0 and @var{msg} is an empty string.\n\
 Otherwise, @var{err} is nonzero and @var{msg} contains a system-dependent\n\
@@ -835,7 +865,7 @@
 @seealso{pipe, umask}\n\
 @end deftypefn")
 {
-  octave_value_list retval;
+  octave_value_list retval (2);
 
   retval(1) = std::string ();
   retval(0) = -1;
@@ -848,23 +878,28 @@
         {
           std::string name = args(0).string_value ();
 
-          if (args(1).is_scalar_type ())
-            {
-              long mode = args(1).long_value ();
+          int octal_mode = args(1).int_value ();
 
-              if (! error_state)
+          if (! error_state)
+            {
+              if (octal_mode < 0)
+                error ("mkfifo: MODE must be a positive integer value");
+              else
                 {
-                  std::string msg;
+                  int mode = convert (octal_mode, 8, 10);
 
-                  int status = octave_mkfifo (name, mode, msg);
+                  if (! error_state)
+                    {
+                      std::string msg;
 
-                  retval(0) = status;
+                      int status = octave_mkfifo (name, mode, msg);
 
-                  if (status < 0)
-                    retval(1) = msg;
+                      retval(0) = status;
+
+                      if (status < 0)
+                        retval(1) = msg;
+                    }
                 }
-              else
-                error ("mkfifo: invalid MODE");
             }
           else
             error ("mkfifo: MODE must be an integer");
@@ -878,6 +913,19 @@
   return retval;
 }
 
+/*
+
+## Test input validation
+%!error mkfifo ()
+%!error mkfifo ("abc")
+%!error mkfifo ("abc", 777, 123)
+%!error <FILE must be a string> mkfifo (123, 456)
+## FIXME: These tests should work, but lasterr is not being set correctly.
+#%!error <MODE must be an integer> mkfifo ("abc", {456})
+#%!error <MODE must be a positive integer value> mkfifo ("abc", -1)
+
+*/
+
 DEFUNX ("pipe", Fpipe, args, ,
         "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {[@var{read_fd}, @var{write_fd}, @var{err}, @var{msg}] =} pipe ()\n\
--- a/scripts/plot/util/private/__gnuplot_get_var__.m	Sun May 17 09:48:12 2015 -0700
+++ b/scripts/plot/util/private/__gnuplot_get_var__.m	Sun May 17 10:04:08 2015 -0700
@@ -52,8 +52,7 @@
   if (use_mkfifo)
     gpin_name = tempname ();
 
-    ## Mode: 0600 == 6*8*8
-    [err, msg] = mkfifo (gpin_name, 6*8*8);
+    [err, msg] = mkfifo (gpin_name, 600);
 
     if (err)
       error ("__gnuplot_get_var__: Can not make FIFO (%s)", msg);
--- a/scripts/plot/util/private/__gnuplot_ginput__.m	Sun May 17 09:48:12 2015 -0700
+++ b/scripts/plot/util/private/__gnuplot_ginput__.m	Sun May 17 10:04:08 2015 -0700
@@ -63,8 +63,7 @@
   if (use_mkfifo)
     gpin_name = tempname ();
 
-    ##Mode: 6*8*8 ==  0600
-    [err, msg] = mkfifo (gpin_name, 6*8*8);
+    [err, msg] = mkfifo (gpin_name, 600);
 
     if (err)
       error ("ginput: Can not open fifo (%s)", msg);