changeset 23738:8acd390d16c9

don't use singleton for stream_list object * oct-stream.h, oct-stream.cc (stream_list): Don't use singleton pattern. Change all uses. (stream_list::stream_list): Initialize stdin, stdout, and stderr streams here. (stream_list::~stream_list): Close files here. (stream_list::m_stdin_file, stream_list::m_stdout_file, stream_list::m_stderr_file): New data members. (stream_list::stdin_file, stream_list::stdout_file, stream_list::stderr_file): New functions. * interpreter.h, interpreter.cc (interpreter::m_stream_list): New data member. (interpreter::interpreter): Initialize it. Don't call initialize_file_io. (interpreter::~interpreter): Don't call close_files. (interpreter::get_stream_list): New function. * file-io.h, file-io.cc (stdin_file, stdout_file, stderr_file, stdin_stream, stdout_stream, stderr_stream): Delete static variables. (initialize_file_io, close_files): Delete. These actions are now handled by the stream_list constructor and destructor.
author John W. Eaton <jwe@octave.org>
date Thu, 06 Jul 2017 13:34:31 -0400
parents 7fb957d36357
children 884e18e82e8f
files libinterp/corefcn/dlmread.cc libinterp/corefcn/file-io.cc libinterp/corefcn/file-io.h libinterp/corefcn/interpreter.cc libinterp/corefcn/interpreter.h libinterp/corefcn/oct-stream.cc libinterp/corefcn/oct-stream.h libinterp/corefcn/pr-output.cc libinterp/corefcn/syscalls.cc libinterp/dldfcn/__init_gnuplot__.cc
diffstat 10 files changed, 300 insertions(+), 332 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/dlmread.cc	Thu Jul 06 12:21:42 2017 -0400
+++ b/libinterp/corefcn/dlmread.cc	Thu Jul 06 13:34:31 2017 -0400
@@ -36,6 +36,7 @@
 #include "lo-ieee.h"
 
 #include "defun.h"
+#include "interpreter.h"
 #include "oct-stream.h"
 #include "error.h"
 #include "ovl.h"
@@ -158,8 +159,8 @@
   return stat;
 }
 
-DEFUN (dlmread, args, ,
-       doc: /* -*- texinfo -*-
+DEFMETHOD (dlmread, interp, args, ,
+           doc: /* -*- texinfo -*-
 @deftypefn  {} {@var{data} =} dlmread (@var{file})
 @deftypefnx {} {@var{data} =} dlmread (@var{file}, @var{sep})
 @deftypefnx {} {@var{data} =} dlmread (@var{file}, @var{sep}, @var{r0}, @var{c0})
@@ -228,7 +229,9 @@
     }
   else if (args(0).is_scalar_type ())
     {
-      octave::stream is = octave::stream_list::lookup (args(0), "dlmread");
+      octave::stream_list& streams = interp.get_stream_list ();
+
+      octave::stream is = streams.lookup (args(0), "dlmread");
 
       input = is.input_stream ();
 
--- a/libinterp/corefcn/file-io.cc	Thu Jul 06 12:21:42 2017 -0400
+++ b/libinterp/corefcn/file-io.cc	Thu Jul 06 13:34:31 2017 -0400
@@ -65,6 +65,7 @@
 #include "error.h"
 #include "errwarn.h"
 #include "file-io.h"
+#include "interpreter.h"
 #include "load-path.h"
 #include "oct-fstrm.h"
 #include "oct-iostrm.h"
@@ -79,37 +80,6 @@
 #include "utils.h"
 #include "variables.h"
 
-static octave_value stdin_file;
-static octave_value stdout_file;
-static octave_value stderr_file;
-
-static octave::stream stdin_stream;
-static octave::stream stdout_stream;
-static octave::stream stderr_stream;
-
-void
-initialize_file_io (void)
-{
-  stdin_stream = octave_istream::create (&std::cin, "stdin");
-
-  // This uses octave_stdout (see pager.h), not std::cout so that Octave's
-  // standard output stream will pass through the pager.
-
-  stdout_stream = octave_ostream::create (&octave_stdout, "stdout");
-
-  stderr_stream = octave_ostream::create (&std::cerr, "stderr");
-
-  stdin_file = octave::stream_list::insert (stdin_stream);
-  stdout_file = octave::stream_list::insert (stdout_stream);
-  stderr_file = octave::stream_list::insert (stderr_stream);
-}
-
-void
-close_files (void)
-{
-  octave::stream_list::clear ();
-}
-
 // List of files to delete when we exit or crash.
 //
 // FIXME: this should really be static,
@@ -233,8 +203,8 @@
   return retval;
 }
 
-DEFUN (fclose, args, ,
-       doc: /* -*- texinfo -*-
+DEFMETHOD (fclose, interp, args, ,
+           doc: /* -*- texinfo -*-
 @deftypefn  {} {} fclose (@var{fid})
 @deftypefnx {} {} fclose ("all")
 @deftypefnx {} {@var{status} =} fclose ("all")
@@ -250,11 +220,13 @@
   if (args.length () != 1)
     print_usage ();
 
-  return ovl (octave::stream_list::remove (args(0), "fclose"));
+  octave::stream_list& streams = interp.get_stream_list ();
+
+  return ovl (streams.remove (args(0), "fclose"));
 }
 
-DEFUN (fclear, args, ,
-       doc: /* -*- texinfo -*-
+DEFMETHOD (fclear, interp, args, ,
+           doc: /* -*- texinfo -*-
 @deftypefn {} {} fclear (@var{fid})
 Clear the stream state for the file specified by the file descriptor
 @var{fid}.
@@ -264,17 +236,19 @@
   if (args.length () != 1)
     print_usage ();
 
-  int fid = octave::stream_list::get_file_number (args(0));
-
-  octave::stream os = octave::stream_list::lookup (fid, "fclear");
+  octave::stream_list& streams = interp.get_stream_list ();
+
+  int fid = streams.get_file_number (args(0));
+
+  octave::stream os = streams.lookup (fid, "fclear");
 
   os.clearerr ();
 
   return ovl ();
 }
 
-DEFUN (fflush, args, ,
-       doc: /* -*- texinfo -*-
+DEFMETHOD (fflush, interp, args, ,
+           doc: /* -*- texinfo -*-
 @deftypefn {} {} fflush (@var{fid})
 Flush output to file descriptor @var{fid}.
 
@@ -293,8 +267,10 @@
 
   octave_value retval = -1;
 
+  octave::stream_list& streams = interp.get_stream_list ();
+
   // FIXME: any way to avoid special case for stdout?
-  int fid = octave::stream_list::get_file_number (args(0));
+  int fid = streams.get_file_number (args(0));
 
   if (fid == 1)
     {
@@ -304,7 +280,7 @@
     }
   else
     {
-      octave::stream os = octave::stream_list::lookup (fid, "fflush");
+      octave::stream os = streams.lookup (fid, "fflush");
 
       retval = os.flush ();
     }
@@ -312,8 +288,8 @@
   return retval;
 }
 
-DEFUN (fgetl, args, ,
-       doc: /* -*- texinfo -*-
+DEFMETHOD (fgetl, interp, args, ,
+           doc: /* -*- texinfo -*-
 @deftypefn  {} {@var{str} =} fgetl (@var{fid})
 @deftypefnx {} {@var{str} =} fgetl (@var{fid}, @var{len})
 Read characters from a file, stopping after a newline, or EOF,
@@ -338,7 +314,9 @@
   if (nargin < 1 || nargin > 2)
     print_usage ();
 
-  octave::stream os = octave::stream_list::lookup (args(0), who);
+  octave::stream_list& streams = interp.get_stream_list ();
+
+  octave::stream os = streams.lookup (args(0), who);
 
   octave_value len_arg = (nargin == 2) ? args(1) : octave_value ();
 
@@ -352,8 +330,8 @@
     return ovl (-1, 0);
 }
 
-DEFUN (fgets, args, ,
-       doc: /* -*- texinfo -*-
+DEFMETHOD (fgets, interp, args, ,
+           doc: /* -*- texinfo -*-
 @deftypefn  {} {@var{str} =} fgets (@var{fid})
 @deftypefnx {} {@var{str} =} fgets (@var{fid}, @var{len})
 Read characters from a file, stopping after a newline, or EOF,
@@ -378,7 +356,9 @@
   if (nargin < 1 || nargin > 2)
     print_usage ();
 
-  octave::stream os = octave::stream_list::lookup (args(0), who);
+  octave::stream_list& streams = interp.get_stream_list ();
+
+  octave::stream os = streams.lookup (args(0), who);
 
   octave_value len_arg = (nargin == 2) ? args(1) : octave_value ();
 
@@ -392,8 +372,8 @@
     return ovl (-1.0, 0.0);
 }
 
-DEFUN (fskipl, args, ,
-       doc: /* -*- texinfo -*-
+DEFMETHOD (fskipl, interp, args, ,
+           doc: /* -*- texinfo -*-
 @deftypefn  {} {@var{nlines} =} fskipl (@var{fid})
 @deftypefnx {} {@var{nlines} =} fskipl (@var{fid}, @var{count})
 @deftypefnx {} {@var{nlines} =} fskipl (@var{fid}, Inf)
@@ -418,7 +398,9 @@
   if (nargin < 1 || nargin > 2)
     print_usage ();
 
-  octave::stream os = octave::stream_list::lookup (args(0), who);
+  octave::stream_list& streams = interp.get_stream_list ();
+
+  octave::stream os = streams.lookup (args(0), who);
 
   octave_value count_arg = (nargin == 2) ? args(1) : octave_value ();
 
@@ -507,8 +489,8 @@
   return retval;
 }
 
-DEFUN (fopen, args, nargout,
-       doc: /* -*- texinfo -*-
+DEFMETHOD (fopen, interp, args, nargout,
+           doc: /* -*- texinfo -*-
 @deftypefn  {} {@var{fid} =} fopen (@var{name})
 @deftypefnx {} {@var{fid} =} fopen (@var{name}, @var{mode})
 @deftypefnx {} {@var{fid} =} fopen (@var{name}, @var{mode}, @var{arch})
@@ -615,6 +597,8 @@
 
   octave_value_list retval = ovl (-1.0);
 
+  octave::stream_list& streams = interp.get_stream_list ();
+
   if (nargin == 1)
     {
       if (args(0).is_string ())
@@ -624,11 +608,11 @@
           // with MODE = "r".  To open a file called "all", you have
           // to supply more than one argument.
           if (nargout < 2 && args(0).string_value () == "all")
-            return octave::stream_list::open_file_numbers ();
+            return streams.open_file_numbers ();
         }
       else
         {
-          string_vector tmp = octave::stream_list::get_info (args(0));
+          string_vector tmp = streams.get_info (args(0));
 
           retval = ovl (tmp(0), tmp(1), tmp(2));
 
@@ -647,7 +631,7 @@
   octave::stream os = do_stream_open (args(0), mode, arch, "fopen", fid);
 
   if (os)
-    retval = ovl (octave::stream_list::insert (os), "");
+    retval = ovl (streams.insert (os), "");
   else
     {
       int error_number = 0;
@@ -672,8 +656,8 @@
 %! assert (arch, "");
 */
 
-DEFUN (freport, args, ,
-       doc: /* -*- texinfo -*-
+DEFMETHOD (freport, interp, args, ,
+           doc: /* -*- texinfo -*-
 @deftypefn {} {} freport ()
 Print a list of which files have been opened, and whether they are open
 for reading, writing, or both.
@@ -698,13 +682,15 @@
   if (args.length () > 0)
     warning ("freport: ignoring extra arguments");
 
-  octave_stdout << octave::stream_list::list_open_files ();
+  octave::stream_list& streams = interp.get_stream_list ();
+
+  octave_stdout << streams.list_open_files ();
 
   return ovl ();
 }
 
-DEFUN (frewind, args, nargout,
-       doc: /* -*- texinfo -*-
+DEFMETHOD (frewind, interp, args, nargout,
+           doc: /* -*- texinfo -*-
 @deftypefn  {} {} frewind (@var{fid})
 @deftypefnx {} {@var{status} =} frewind (@var{fid})
 Move the file pointer to the beginning of the file specified by file
@@ -720,7 +706,9 @@
 
   int result = -1;
 
-  octave::stream os = octave::stream_list::lookup (args(0), "frewind");
+  octave::stream_list& streams = interp.get_stream_list ();
+
+  octave::stream os = streams.lookup (args(0), "frewind");
 
   result = os.rewind ();
 
@@ -730,8 +718,8 @@
     return ovl ();
 }
 
-DEFUN (fseek, args, ,
-       doc: /* -*- texinfo -*-
+DEFMETHOD (fseek, interp, args, ,
+           doc: /* -*- texinfo -*-
 @deftypefn  {} {} fseek (@var{fid}, @var{offset})
 @deftypefnx {} {} fseek (@var{fid}, @var{offset}, @var{origin})
 @deftypefnx {} {@var{status} =} fseek (@dots{})
@@ -754,15 +742,17 @@
   if (nargin < 2 || nargin > 3)
     print_usage ();
 
-  octave::stream os = octave::stream_list::lookup (args(0), "fseek");
+  octave::stream_list& streams = interp.get_stream_list ();
+
+  octave::stream os = streams.lookup (args(0), "fseek");
 
   octave_value origin_arg = (nargin == 3) ? args(2) : octave_value (-1.0);
 
   return ovl (os.seek (args(1), origin_arg));
 }
 
-DEFUN (ftell, args, ,
-       doc: /* -*- texinfo -*-
+DEFMETHOD (ftell, interp, args, ,
+           doc: /* -*- texinfo -*-
 @deftypefn {} {@var{pos} =} ftell (@var{fid})
 Return the position of the file pointer as the number of characters from the
 beginning of the file specified by file descriptor @var{fid}.
@@ -772,14 +762,16 @@
   if (args.length () != 1)
     print_usage ();
 
-  octave::stream os = octave::stream_list::lookup (args(0), "ftell");
+  octave::stream_list& streams = interp.get_stream_list ();
+
+  octave::stream os = streams.lookup (args(0), "ftell");
 
   return ovl (os.tell ());
 }
 
 static octave_value_list
-printf_internal (const std::string& who, const octave_value_list& args,
-                 int nargout)
+printf_internal (octave::interpreter& interp, const std::string& who,
+                 const octave_value_list& args, int nargout)
 {
   int nargin = args.length ();
 
@@ -791,12 +783,14 @@
   octave::stream os;
   int fmt_n = 0;
 
+  octave::stream_list& streams = interp.get_stream_list ();
+
   if (args(0).is_string ())
-    os = octave::stream_list::lookup (1, who);
+    os = streams.lookup (1, who);
   else
     {
       fmt_n = 1;
-      os = octave::stream_list::lookup (args(0), who);
+      os = streams.lookup (args(0), who);
     }
 
   if (! args(fmt_n).is_string ())
@@ -820,8 +814,8 @@
     return ovl ();
 }
 
-DEFUN (fprintf, args, nargout,
-       doc: /* -*- texinfo -*-
+DEFMETHOD (fprintf, interp, args, nargout,
+           doc: /* -*- texinfo -*-
 @deftypefn  {} {} fprintf (@var{fid}, @var{template}, @dots{})
 @deftypefnx {} {} fprintf (@var{template}, @dots{})
 @deftypefnx {} {@var{numbytes} =} fprintf (@dots{})
@@ -841,11 +835,11 @@
 {
   static std::string who = "fprintf";
 
-  return printf_internal (who, args, nargout);
+  return printf_internal (interp, who, args, nargout);
 }
 
-DEFUN (printf, args, nargout,
-       doc: /* -*- texinfo -*-
+DEFMETHOD (printf, interp, args, nargout,
+           doc: /* -*- texinfo -*-
 @deftypefn {} {} printf (@var{template}, @dots{})
 Print optional arguments under the control of the template string
 @var{template} to the stream @code{stdout} and return the number of
@@ -866,22 +860,26 @@
 
   octave_value_list tmp_args = args;
 
-  return printf_internal (who, tmp_args.prepend (octave_value (1)), nargout);
+  return printf_internal (interp, who, tmp_args.prepend (octave_value (1)),
+                          nargout);
 }
 
 static octave_value_list
-puts_internal (const std::string& who, const octave_value_list& args)
+puts_internal (octave::interpreter& interp, const std::string& who,
+               const octave_value_list& args)
 {
   if (args.length () != 2)
     print_usage ();
 
-  octave::stream os = octave::stream_list::lookup (args(0), who);
+  octave::stream_list& streams = interp.get_stream_list ();
+
+  octave::stream os = streams.lookup (args(0), who);
 
   return ovl (os.puts (args(1), who));
 }
 
-DEFUN (fputs, args, ,
-       doc: /* -*- texinfo -*-
+DEFMETHOD (fputs, interp, args, ,
+           doc: /* -*- texinfo -*-
 @deftypefn  {} {} fputs (@var{fid}, @var{string})
 @deftypefnx {} {@var{status} =} fputs (@var{fid}, @var{string})
 Write the string @var{string} to the file with file descriptor @var{fid}.
@@ -896,11 +894,11 @@
 {
   static std::string who = "fputs";
 
-  return puts_internal (who, args);
+  return puts_internal (interp, who, args);
 }
 
-DEFUN (puts, args, ,
-       doc: /* -*- texinfo -*-
+DEFMETHOD (puts, interp, args, ,
+           doc: /* -*- texinfo -*-
 @deftypefn  {} {} puts (@var{string})
 @deftypefnx {} {@var{status} =} puts (@var{string})
 Write a string to the standard output with no formatting.
@@ -916,7 +914,7 @@
 
   octave_value_list tmp_args = args;
 
-  return puts_internal (who, tmp_args.prepend (octave_value (1)));
+  return puts_internal (interp, who, tmp_args.prepend (octave_value (1)));
 }
 
 DEFUN (sprintf, args, ,
@@ -983,7 +981,8 @@
 }
 
 static octave_value_list
-scanf_internal (const std::string& who, const octave_value_list& args)
+scanf_internal (octave::interpreter& interp, const std::string& who,
+                const octave_value_list& args)
 {
   int nargin = args.length ();
 
@@ -992,7 +991,9 @@
 
   octave_value_list retval;
 
-  octave::stream os = octave::stream_list::lookup (args(0), who);
+  octave::stream_list& streams = interp.get_stream_list ();
+
+  octave::stream os = streams.lookup (args(0), who);
 
   if (! args(1).is_string ())
     error ("%s: format TEMPLATE must be a string", who.c_str ());
@@ -1018,8 +1019,8 @@
   return retval;
 }
 
-DEFUN (fscanf, args, ,
-       doc: /* -*- texinfo -*-
+DEFMETHOD (fscanf, interp, args, ,
+           doc: /* -*- texinfo -*-
 @deftypefn  {} {[@var{val}, @var{count}, @var{errmsg}] =} fscanf (@var{fid}, @var{template}, @var{size})
 @deftypefnx {} {[@var{v1}, @var{v2}, @dots{}, @var{count}, @var{errmsg}] =} fscanf (@var{fid}, @var{template}, "C")
 In the first form, read from @var{fid} according to @var{template},
@@ -1070,7 +1071,7 @@
 {
   static std::string who = "fscanf";
 
-  return scanf_internal (who, args);
+  return scanf_internal (interp, who, args);
 }
 
 static std::string
@@ -1146,8 +1147,8 @@
   return retval;
 }
 
-DEFUN (scanf, args, ,
-       doc: /* -*- texinfo -*-
+DEFMETHOD (scanf, interp, args, ,
+           doc: /* -*- texinfo -*-
 @deftypefn  {} {[@var{val}, @var{count}, @var{errmsg}] =} scanf (@var{template}, @var{size})
 @deftypefnx {} {[@var{v1}, @var{v2}, @dots{}, @var{count}, @var{errmsg}]] =} scanf (@var{template}, "C")
 This is equivalent to calling @code{fscanf} with @var{fid} = @code{stdin}.
@@ -1160,11 +1161,12 @@
 
   octave_value_list tmp_args = args;
 
-  return scanf_internal (who, tmp_args.prepend (octave_value (0)));
+  return scanf_internal (interp, who, tmp_args.prepend (octave_value (0)));
 }
 
 static octave_value_list
-textscan_internal (const std::string& who, const octave_value_list& args)
+textscan_internal (octave::interpreter& interp, const std::string& who,
+                   const octave_value_list& args)
 {
   if (args.length () < 1)
     print_usage (who);
@@ -1181,7 +1183,11 @@
         error ("%s: unable to create temporary input buffer", who.c_str ());
     }
   else
-    os =octave::stream_list::lookup (args(0), who);
+    {
+      octave::stream_list& streams = interp.get_stream_list ();
+
+      os = streams.lookup (args(0), who);
+    }
 
   int nskip = 1;
 
@@ -1231,8 +1237,8 @@
   return ovl (result, count, errmsg);
 }
 
-DEFUN (textscan, args, ,
-       doc: /* -*- texinfo -*-
+DEFMETHOD (textscan, interp, args, ,
+           doc: /* -*- texinfo -*-
 @deftypefn  {} {@var{C} =} textscan (@var{fid}, @var{format})
 @deftypefnx {} {@var{C} =} textscan (@var{fid}, @var{format}, @var{repeat})
 @deftypefnx {} {@var{C} =} textscan (@var{fid}, @var{format}, @var{param}, @var{value}, @dots{})
@@ -1498,11 +1504,11 @@
 {
   static std::string who = "textscan";
 
-  return textscan_internal (who, args);
+  return textscan_internal (interp, who, args);
 }
 
-DEFUN (__textscan__, args, ,
-       doc: /* -*- texinfo -*-
+DEFMETHOD (__textscan__, interp, args, ,
+           doc: /* -*- texinfo -*-
 @deftypefn {} {@var{C} =} __textscan__ (@var{who}, @dots{})
 Like @code{textscan} but accept additional argument @var{who} to use
 as the name of the function when reporting errors.
@@ -1511,7 +1517,8 @@
   if (args.length () == 0)
     print_usage ();
 
-  return textscan_internal (args(0).string_value (), args.splice (0, 1));
+  return textscan_internal (interp, args(0).string_value (),
+                            args.splice (0, 1));
 }
 
 /*
@@ -2285,8 +2292,8 @@
                   flt_fmt, count);
 }
 
-DEFUN (fread, args, ,
-       doc: /* -*- texinfo -*-
+DEFMETHOD (fread, interp, args, ,
+           doc: /* -*- texinfo -*-
 @deftypefn  {} {@var{val} =} fread (@var{fid})
 @deftypefnx {} {@var{val} =} fread (@var{fid}, @var{size})
 @deftypefnx {} {@var{val} =} fread (@var{fid}, @var{size}, @var{precision})
@@ -2461,7 +2468,9 @@
   if (nargin < 1 || nargin > 5)
     print_usage ();
 
-  octave::stream os = octave::stream_list::lookup (args(0), "fread");
+  octave::stream_list& streams = interp.get_stream_list ();
+
+  octave::stream os = streams.lookup (args(0), "fread");
 
   octave_value size = lo_ieee_inf_value ();
   octave_value prec = "uchar";
@@ -2532,8 +2541,8 @@
   return os.write (data, block_size, output_type, skip, flt_fmt);
 }
 
-DEFUN (fwrite, args, ,
-       doc: /* -*- texinfo -*-
+DEFMETHOD (fwrite, interp, args, ,
+           doc: /* -*- texinfo -*-
 @deftypefn  {} {} fwrite (@var{fid}, @var{data})
 @deftypefnx {} {} fwrite (@var{fid}, @var{data}, @var{precision})
 @deftypefnx {} {} fwrite (@var{fid}, @var{data}, @var{precision}, @var{skip})
@@ -2559,7 +2568,9 @@
   if (nargin < 2 || nargin > 5)
     print_usage ();
 
-  octave::stream os = octave::stream_list::lookup (args(0), "fwrite");
+  octave::stream_list& streams = interp.get_stream_list ();
+
+  octave::stream os = streams.lookup (args(0), "fwrite");
 
   octave_value prec = "uchar";
   octave_value skip = 0;
@@ -2586,8 +2597,8 @@
   return ovl (do_fwrite (os, data, prec, skip, arch));
 }
 
-DEFUNX ("feof", Ffeof, args, ,
-        doc: /* -*- texinfo -*-
+DEFMETHODX ("feof", Ffeof, interp, args, ,
+            doc: /* -*- texinfo -*-
 @deftypefn {} {@var{status} =} feof (@var{fid})
 Return 1 if an end-of-file condition has been encountered for the file
 specified by file descriptor @var{fid} and 0 otherwise.
@@ -2601,13 +2612,15 @@
   if (args.length () != 1)
     print_usage ();
 
-  octave::stream os = octave::stream_list::lookup (args(0), "feof");
+  octave::stream_list& streams = interp.get_stream_list ();
+
+  octave::stream os = streams.lookup (args(0), "feof");
 
   return ovl (os.eof () ? 1.0 : 0.0);
 }
 
-DEFUNX ("ferror", Fferror, args, ,
-        doc: /* -*- texinfo -*-
+DEFMETHODX ("ferror", Fferror, interp, args, ,
+            doc: /* -*- texinfo -*-
 @deftypefn  {} {@var{msg} =} ferror (@var{fid})
 @deftypefnx {} {[@var{msg}, @var{err}] =} ferror (@var{fid})
 @deftypefnx {} {[@dots{}] =} ferror (@var{fid}, "clear")
@@ -2632,7 +2645,9 @@
   if (nargin < 1 || nargin > 2)
     print_usage ();
 
-  octave::stream os = octave::stream_list::lookup (args(0), "ferror");
+  octave::stream_list& streams = interp.get_stream_list ();
+
+  octave::stream os = streams.lookup (args(0), "ferror");
 
   bool clear = false;
 
@@ -2650,8 +2665,8 @@
   return ovl (error_message, error_number);
 }
 
-DEFUNX ("popen", Fpopen, args, ,
-        doc: /* -*- texinfo -*-
+DEFMETHODX ("popen", Fpopen, interp, args, ,
+            doc: /* -*- texinfo -*-
 @deftypefn {} {@var{fid} =} popen (@var{command}, @var{mode})
 Start a process and create a pipe.
 
@@ -2696,17 +2711,19 @@
 
   octave_value retval;
 
+  octave::stream_list& streams = interp.get_stream_list ();
+
   if (mode == "r")
     {
       octave::stream ips = octave_iprocstream::create (name);
 
-      retval = octave::stream_list::insert (ips);
+      retval = streams.insert (ips);
     }
   else if (mode == "w")
     {
       octave::stream ops = octave_oprocstream::create (name);
 
-      retval = octave::stream_list::insert (ops);
+      retval = streams.insert (ops);
     }
   else
     error ("popen: invalid MODE specified");
@@ -2714,8 +2731,8 @@
   return retval;
 }
 
-DEFUNX ("pclose", Fpclose, args, ,
-        doc: /* -*- texinfo -*-
+DEFMETHODX ("pclose", Fpclose, interp, args, ,
+            doc: /* -*- texinfo -*-
 @deftypefn {} {} pclose (@var{fid})
 Close a file identifier that was opened by @code{popen}.
 
@@ -2726,7 +2743,9 @@
   if (args.length () != 1)
     print_usage ();
 
-  return ovl (octave::stream_list::remove (args(0), "pclose"));
+  octave::stream_list& streams = interp.get_stream_list ();
+
+  return ovl (streams.remove (args(0), "pclose"));
 }
 
 DEFUN (tempname, args, ,
@@ -2822,8 +2841,8 @@
 %! end_unwind_protect
 */
 
-DEFUN (tmpfile, args, ,
-       doc: /* -*- texinfo -*-
+DEFMETHOD (tmpfile, interp, args, ,
+           doc: /* -*- texinfo -*-
 @deftypefn {} {[@var{fid}, @var{msg}] =} tmpfile ()
 Return the file ID corresponding to a new temporary file with a unique
 name.
@@ -2855,7 +2874,9 @@
       if (! s)
         error ("tmpfile: failed to create octave_stdiostream object");
 
-      retval = ovl (octave::stream_list::insert (s), "");
+      octave::stream_list& streams = interp.get_stream_list ();
+
+      retval = ovl (streams.insert (s), "");
     }
   else
     {
@@ -2865,8 +2886,8 @@
   return retval;
 }
 
-DEFUN (mkstemp, args, ,
-       doc: /* -*- texinfo -*-
+DEFMETHOD (mkstemp, interp, args, ,
+           doc: /* -*- texinfo -*-
 @deftypefn  {} {[@var{fid}, @var{name}, @var{msg}] =} mkstemp ("@var{template}")
 @deftypefnx {} {[@var{fid}, @var{name}, @var{msg}] =} mkstemp ("@var{template}", @var{delete})
 Return the file descriptor @var{fid} corresponding to a new temporary file
@@ -2930,7 +2951,9 @@
           if (! s)
             error ("mkstemp: failed to create octave_stdiostream object");
 
-          retval(0) = octave::stream_list::insert (s);
+          octave::stream_list& streams = interp.get_stream_list ();
+
+          retval(0) = streams.insert (s);
           retval(1) = nm;
 
           if (nargin == 2 && args(1).is_true ())
@@ -3092,8 +3115,8 @@
   return octave_value (val);
 }
 
-DEFUNX ("stdin", Fstdin, args, ,
-        doc: /* -*- texinfo -*-
+DEFMETHODX ("stdin", Fstdin, interp, args, ,
+            doc: /* -*- texinfo -*-
 @deftypefn {} {} stdin ()
 Return the numeric value corresponding to the standard input stream.
 
@@ -3102,11 +3125,13 @@
 @seealso{stdout, stderr}
 @end deftypefn */)
 {
-  return const_value ("stdin", args, stdin_file);
+  octave::stream_list& streams = interp.get_stream_list ();
+
+  return const_value ("stdin", args, streams.stdin_file ());
 }
 
-DEFUNX ("stdout", Fstdout, args, ,
-        doc: /* -*- texinfo -*-
+DEFMETHODX ("stdout", Fstdout, interp, args, ,
+            doc: /* -*- texinfo -*-
 @deftypefn {} {} stdout ()
 Return the numeric value corresponding to the standard output stream.
 
@@ -3114,11 +3139,13 @@
 @seealso{stdin, stderr}
 @end deftypefn */)
 {
-  return const_value ("stdout", args, stdout_file);
+  octave::stream_list& streams = interp.get_stream_list ();
+
+  return const_value ("stdout", args, streams.stdout_file ());
 }
 
-DEFUNX ("stderr", Fstderr, args, ,
-        doc: /* -*- texinfo -*-
+DEFMETHODX ("stderr", Fstderr, interp, args, ,
+            doc: /* -*- texinfo -*-
 @deftypefn {} {} stderr ()
 Return the numeric value corresponding to the standard error stream.
 
@@ -3127,5 +3154,7 @@
 @seealso{stdin, stdout}
 @end deftypefn */)
 {
-  return const_value ("stderr", args, stderr_file);
+  octave::stream_list& streams = interp.get_stream_list ();
+
+  return const_value ("stderr", args, streams.stderr_file ());
 }
--- a/libinterp/corefcn/file-io.h	Thu Jul 06 12:21:42 2017 -0400
+++ b/libinterp/corefcn/file-io.h	Thu Jul 06 13:34:31 2017 -0400
@@ -29,10 +29,6 @@
 
 #include <string>
 
-extern OCTINTERP_API void initialize_file_io (void);
-
-extern OCTINTERP_API void close_files (void);
-
 extern OCTINTERP_API void mark_for_deletion (const std::string&);
 
 extern OCTINTERP_API void cleanup_tmp_files (void);
--- a/libinterp/corefcn/interpreter.cc	Thu Jul 06 12:21:42 2017 -0400
+++ b/libinterp/corefcn/interpreter.cc	Thu Jul 06 13:34:31 2017 -0400
@@ -354,6 +354,7 @@
       m_load_path (),
       m_symbol_table (),
       m_evaluator (*this),
+      m_stream_list (*this),
       m_cdef_manager (*this),
       m_interactive (false),
       m_read_site_files (true),
@@ -409,8 +410,6 @@
     else
       quit_allowed = false;
 
-    initialize_file_io ();
-
     install_types ();
 
     install_ops ();
@@ -1137,8 +1136,6 @@
 
     OCTAVE_SAFE_CALL (gtk_manager::unload_all_toolkits, ());
 
-    OCTAVE_SAFE_CALL (close_files, ());
-
     OCTAVE_SAFE_CALL (cleanup_tmp_files, ());
 
     // FIXME:  May still need something like this to ensure that
@@ -1172,6 +1169,11 @@
     return m_evaluator;
   }
 
+  stream_list& interpreter::get_stream_list (void)
+  {
+    return m_stream_list;
+  }
+
   symbol_table::scope *
   interpreter::get_current_scope (void)
   {
--- a/libinterp/corefcn/interpreter.h	Thu Jul 06 12:21:42 2017 -0400
+++ b/libinterp/corefcn/interpreter.h	Thu Jul 06 13:34:31 2017 -0400
@@ -34,6 +34,7 @@
 #include "environment.h"
 #include "help.h"
 #include "load-path.h"
+#include "oct-stream.h"
 #include "ov-classdef.h"
 #include "pt-eval.h"
 #include "symtab.h"
@@ -171,6 +172,8 @@
 
     tree_evaluator& get_evaluator (void);
 
+    stream_list& get_stream_list (void);
+
     cdef_manager& get_cdef_manager (void)
     {
       return m_cdef_manager;
@@ -224,6 +227,8 @@
 
     tree_evaluator m_evaluator;
 
+    stream_list m_stream_list;
+
     cdef_manager m_cdef_manager;
 
     // TRUE means this is an interactive interpreter (forced or not).
--- a/libinterp/corefcn/oct-stream.cc	Thu Jul 06 12:21:42 2017 -0400
+++ b/libinterp/corefcn/oct-stream.cc	Thu Jul 06 13:34:31 2017 -0400
@@ -52,10 +52,12 @@
 #include "input.h"
 #include "interpreter.h"
 #include "octave.h"
+#include "oct-iostrm.h"
 #include "oct-stdstrm.h"
 #include "oct-stream.h"
 #include "ov.h"
 #include "ovl.h"
+#include "pager.h"
 #include "utils.h"
 
 // Programming Note: There are two very different error functions used
@@ -7243,97 +7245,32 @@
     return retval;
   }
 
-  stream_list *stream_list::instance = nullptr;
-
-  bool
-  stream_list::instance_ok (void)
-  {
-    bool retval = true;
-
-    if (! instance)
-      {
-        instance = new stream_list ();
-
-        if (instance)
-          singleton_cleanup_list::add (cleanup_instance);
-      }
-
-    if (! instance)
-      ::error ("unable to create stream list object!");
-
-    return retval;
-  }
-
-  int
-  stream_list::insert (stream& os)
-  {
-    return (instance_ok ()) ? instance->do_insert (os) : -1;
-  }
-
-  stream
-  stream_list::lookup (int fid, const std::string& who)
-  {
-    return (instance_ok ()) ? instance->do_lookup (fid, who) : stream ();
-  }
-
-  stream
-  stream_list::lookup (const octave_value& fid, const std::string& who)
-  {
-    return (instance_ok ()) ? instance->do_lookup (fid, who) : stream ();
-  }
-
-  int
-  stream_list::remove (int fid, const std::string& who)
-  {
-    return (instance_ok ()) ? instance->do_remove (fid, who) : -1;
+  stream_list::stream_list (interpreter&)
+    : list (), lookup_cache (list.end ()), m_stdin_file (-1),
+      m_stdout_file (-1), m_stderr_file (-1)
+  {
+    stream stdin_stream = octave_istream::create (&std::cin, "stdin");
+
+    // This uses octave_stdout (see pager.h), not std::cout so that
+    // Octave's standard output stream will pass through the pager.
+
+    // FIXME: we should be accessing octave_stdout from the interpreter.
+
+    stream stdout_stream = octave_ostream::create (&octave_stdout, "stdout");
+
+    stream stderr_stream = octave_ostream::create (&std::cerr, "stderr");
+
+    m_stdin_file = insert (stdin_stream);
+    m_stdout_file = insert (stdout_stream);
+    m_stderr_file = insert (stderr_stream);
   }
 
-  int
-  stream_list::remove (const octave_value& fid, const std::string& who)
-  {
-    return (instance_ok ()) ? instance->do_remove (fid, who) : -1;
-  }
-
-  void
-  stream_list::clear (bool flush)
-  {
-    if (instance)
-      instance->do_clear (flush);
-  }
-
-  string_vector
-  stream_list::get_info (int fid)
-  {
-    return (instance_ok ()) ? instance->do_get_info (fid) : string_vector ();
+  stream_list::~stream_list (void)
+  {
+    clear ();
   }
 
-  string_vector
-  stream_list::get_info (const octave_value& fid)
-  {
-    return (instance_ok ()) ? instance->do_get_info (fid) : string_vector ();
-  }
-
-  std::string
-  stream_list::list_open_files (void)
-  {
-    return (instance_ok ()) ? instance->do_list_open_files () : "";
-  }
-
-  octave_value
-  stream_list::open_file_numbers (void)
-  {
-    return (instance_ok ())
-      ? instance->do_open_file_numbers () : octave_value ();
-  }
-
-  int
-  stream_list::get_file_number (const octave_value& fid)
-  {
-    return (instance_ok ()) ? instance->do_get_file_number (fid) : -1;
-  }
-
-  int
-  stream_list::do_insert (stream& os)
+  int stream_list::insert (stream& os)
   {
     // Insert item with key corresponding to file-descriptor.
 
@@ -7376,8 +7313,7 @@
 
 namespace octave
 {
-  stream
-  stream_list::do_lookup (int fid, const std::string& who) const
+  stream stream_list::lookup (int fid, const std::string& who) const
   {
     stream retval;
 
@@ -7400,17 +7336,15 @@
     return retval;
   }
 
-  stream
-  stream_list::do_lookup (const octave_value& fid,
-                          const std::string& who) const
+  stream stream_list::lookup (const octave_value& fid,
+                              const std::string& who) const
   {
     int i = get_file_number (fid);
 
-    return do_lookup (i, who);
+    return lookup (i, who);
   }
 
-  int
-  stream_list::do_remove (int fid, const std::string& who)
+  int stream_list::remove (int fid, const std::string& who)
   {
     // Can't remove stdin (std::cin), stdout (std::cout), or stderr (std::cerr).
     if (fid < 3)
@@ -7434,14 +7368,13 @@
     return 0;
   }
 
-  int
-  stream_list::do_remove (const octave_value& fid, const std::string& who)
+  int stream_list::remove (const octave_value& fid, const std::string& who)
   {
     int retval = -1;
 
     if (fid.is_string () && fid.string_value () == "all")
       {
-        do_clear (false);
+        clear (false);
 
         retval = 0;
       }
@@ -7449,14 +7382,13 @@
       {
         int i = get_file_number (fid);
 
-        retval = do_remove (i, who);
+        retval = remove (i, who);
       }
 
     return retval;
   }
 
-  void
-  stream_list::do_clear (bool flush)
+  void stream_list::clear (bool flush)
   {
     if (flush)
       {
@@ -7497,8 +7429,7 @@
     lookup_cache = list.end ();
   }
 
-  string_vector
-  stream_list::do_get_info (int fid) const
+  string_vector stream_list::get_info (int fid) const
   {
     string_vector retval (3);
 
@@ -7529,8 +7460,7 @@
     return retval;
   }
 
-  string_vector
-  stream_list::do_get_info (const octave_value& fid) const
+  string_vector stream_list::get_info (const octave_value& fid) const
   {
     int conv_err = 0;
 
@@ -7539,11 +7469,10 @@
     if (conv_err)
       ::error ("file id must be a file object or integer value");
 
-    return do_get_info (int_fid);
+    return get_info (int_fid);
   }
 
-  std::string
-  stream_list::do_list_open_files (void) const
+  std::string stream_list::list_open_files (void) const
   {
     std::ostringstream buf;
 
@@ -7575,8 +7504,7 @@
     return buf.str ();
   }
 
-  octave_value
-  stream_list::do_open_file_numbers (void) const
+  octave_value stream_list::open_file_numbers (void) const
   {
     Matrix retval (1, list.size (), 0.0);
 
@@ -7594,8 +7522,7 @@
     return retval;
   }
 
-  int
-  stream_list::do_get_file_number (const octave_value& fid) const
+  int stream_list::get_file_number (const octave_value& fid) const
   {
     int retval = -1;
 
@@ -7632,4 +7559,19 @@
 
     return retval;
   }
+
+  octave_value stream_list::stdin_file (void) const
+  {
+    return octave_value (m_stdin_file);
+  }
+
+  octave_value stream_list::stdout_file (void) const
+  {
+    return octave_value (m_stdout_file);
+  }
+
+  octave_value stream_list::stderr_file (void) const
+  {
+    return octave_value (m_stderr_file);
+  }
 }
--- a/libinterp/corefcn/oct-stream.h	Thu Jul 06 12:21:42 2017 -0400
+++ b/libinterp/corefcn/oct-stream.h	Thu Jul 06 13:34:31 2017 -0400
@@ -45,6 +45,8 @@
 
 namespace octave
 {
+  class interpreter;
+
   // These are only needed as arguments to private functions, so they
   // are also treated as private.
 
@@ -413,35 +415,37 @@
   OCTINTERP_API
   stream_list
   {
-  protected:
-
-    stream_list (void) : list (), lookup_cache (list.end ()) { }
-
   public:
 
-    ~stream_list (void) = default;
+    stream_list (interpreter& interp);
 
-    static bool instance_ok (void);
+    stream_list (const stream_list&) = delete;
+    stream_list& operator = (const stream_list&) = delete;
+
+    ~stream_list (void);
 
-    static int insert (stream& os);
+    int insert (stream& os);
 
-    static stream lookup (int fid, const std::string& who = "");
+    stream lookup (int fid, const std::string& who = "") const;
+    stream lookup (const octave_value& fid, const std::string& who = "") const;
 
-    static stream lookup (const octave_value& fid, const std::string& who = "");
+    int remove (int fid, const std::string& who = "");
+    int remove (const octave_value& fid, const std::string& who = "");
 
-    static int remove (int fid, const std::string& who = "");
-    static int remove (const octave_value& fid, const std::string& who = "");
+    void clear (bool flush = true);
 
-    static void clear (bool flush = true);
+    string_vector get_info (int fid) const;
+    string_vector get_info (const octave_value& fid) const;
+
+    std::string list_open_files (void) const;
 
-    static string_vector get_info (int fid);
-    static string_vector get_info (const octave_value& fid);
+    octave_value open_file_numbers (void) const;
+
+    int get_file_number (const octave_value& fid) const;
 
-    static std::string list_open_files (void);
-
-    static octave_value open_file_numbers (void);
-
-    static int get_file_number (const octave_value& fid);
+    octave_value stdin_file (void) const;
+    octave_value stdout_file (void) const;
+    octave_value stderr_file (void) const;
 
   private:
 
@@ -451,29 +455,9 @@
 
     mutable ostrl_map::const_iterator lookup_cache;
 
-    static stream_list *instance;
-
-    static void cleanup_instance (void) { delete instance; instance = 0; }
-
-    int do_insert (stream& os);
-
-    stream do_lookup (int fid, const std::string& who = "") const;
-    stream do_lookup (const octave_value& fid,
-                      const std::string& who = "") const;
-
-    int do_remove (int fid, const std::string& who = "");
-    int do_remove (const octave_value& fid, const std::string& who = "");
-
-    void do_clear (bool flush = true);
-
-    string_vector do_get_info (int fid) const;
-    string_vector do_get_info (const octave_value& fid) const;
-
-    std::string do_list_open_files (void) const;
-
-    octave_value do_open_file_numbers (void) const;
-
-    int do_get_file_number (const octave_value& fid) const;
+    int m_stdin_file;
+    int m_stdout_file;
+    int m_stderr_file;
   };
 }
 
--- a/libinterp/corefcn/pr-output.cc	Thu Jul 06 12:21:42 2017 -0400
+++ b/libinterp/corefcn/pr-output.cc	Thu Jul 06 13:34:31 2017 -0400
@@ -3502,8 +3502,8 @@
   return retval;
 }
 
-DEFUN (fdisp, args, ,
-       classes: cell char double function_handle int8 int16 int32 int64 logical single struct uint8 uint16 uint32 uint64
+DEFMETHOD (fdisp, interp, args, ,
+           classes: cell char double function_handle int8 int16 int32 int64 logical single struct uint8 uint16 uint32 uint64
        doc: /* -*- texinfo -*-
 @deftypefn {} {} fdisp (@var{fid}, @var{x})
 Display the value of @var{x} on the stream @var{fid}.
@@ -3527,9 +3527,11 @@
   if (args.length () != 2)
     print_usage ();
 
-  int fid = octave::stream_list::get_file_number (args(0));
-
-  octave::stream os = octave::stream_list::lookup (fid, "fdisp");
+  octave::stream_list& streams = interp.get_stream_list ();
+
+  int fid = streams.get_file_number (args(0));
+
+  octave::stream os = streams.lookup (fid, "fdisp");
 
   std::ostream *osp = os.output_stream ();
 
--- a/libinterp/corefcn/syscalls.cc	Thu Jul 06 12:21:42 2017 -0400
+++ b/libinterp/corefcn/syscalls.cc	Thu Jul 06 13:34:31 2017 -0400
@@ -106,8 +106,8 @@
     return ovl (Matrix (), -1, fs.error ());
 }
 
-DEFUNX ("dup2", Fdup2, args, ,
-        doc: /* -*- texinfo -*-
+DEFMETHODX ("dup2", Fdup2, interp, args, ,
+            doc: /* -*- texinfo -*-
 @deftypefn {} {[@var{fid}, @var{msg}] =} dup2 (@var{old}, @var{new})
 Duplicate a file descriptor.
 
@@ -120,9 +120,11 @@
   if (args.length () != 2)
     print_usage ();
 
-  octave::stream old_stream = octave::stream_list::lookup (args(0), "dup2");
+  octave::stream_list& streams = interp.get_stream_list ();
 
-  octave::stream new_stream = octave::stream_list::lookup (args(1), "dup2");
+  octave::stream old_stream = streams.lookup (args(0), "dup2");
+
+  octave::stream new_stream = streams.lookup (args(1), "dup2");
 
   int i_old = old_stream.file_number ();
   int i_new = new_stream.file_number ();
@@ -201,8 +203,8 @@
   return ovl (status, msg);
 }
 
-DEFUNX ("popen2", Fpopen2, args, ,
-        doc: /* -*- texinfo -*-
+DEFMETHODX ("popen2", Fpopen2, interp, args, ,
+            doc: /* -*- texinfo -*-
 @deftypefn {} {[@var{in}, @var{out}, @var{pid}] =} popen2 (@var{command}, @var{args})
 Start a subprocess with two-way communication.
 
@@ -297,9 +299,9 @@
   octave::stream os
     = octave_stdiostream::create (exec_file + "-out", ofile, std::ios::out);
 
-  return ovl (octave::stream_list::insert (os),
-              octave::stream_list::insert (is),
-              pid);
+  octave::stream_list& streams = interp.get_stream_list ();
+
+  return ovl (streams.insert (os), streams.insert (is), pid);
 }
 
 /*
@@ -370,8 +372,8 @@
 
 */
 
-DEFUNX ("fcntl", Ffcntl, args, ,
-        doc: /* -*- texinfo -*-
+DEFMETHODX ("fcntl", Ffcntl, interp, args, ,
+            doc: /* -*- texinfo -*-
 @deftypefn {} {[@var{err}, @var{msg}] =} fcntl (@var{fid}, @var{request}, @var{arg})
 Change the properties of the open file @var{fid}.
 
@@ -432,7 +434,9 @@
   if (args.length () != 3)
     print_usage ();
 
-  octave::stream strm = octave::stream_list::lookup (args(0), "fcntl");
+  octave::stream_list& streams = interp.get_stream_list ();
+
+  octave::stream strm = streams.lookup (args(0), "fcntl");
 
   int fid = strm.file_number ();
 
@@ -716,8 +720,8 @@
 
 */
 
-DEFUNX ("pipe", Fpipe, args, ,
-        doc: /* -*- texinfo -*-
+DEFMETHODX ("pipe", Fpipe, interp, args, ,
+            doc: /* -*- texinfo -*-
 @deftypefn {} {[@var{read_fd}, @var{write_fd}, @var{err}, @var{msg}] =} pipe ()
 Create a pipe and return the reading and writing ends of the pipe into
 @var{read_fd} and @var{write_fd} respectively.
@@ -749,15 +753,14 @@
       octave::stream os
         = octave_stdiostream::create ("pipe-out", ofile, std::ios::out);
 
-      return ovl (octave::stream_list::insert (is),
-                  octave::stream_list::insert (os),
-                  status,
-                  msg);
+      octave::stream_list& streams = interp.get_stream_list ();
+
+      return ovl (streams.insert (is), streams.insert (os), status, msg);
     }
 }
 
-DEFUNX ("stat", Fstat, args, ,
-        doc: /* -*- texinfo -*-
+DEFMETHODX ("stat", Fstat, interp, args, ,
+            doc: /* -*- texinfo -*-
 @deftypefn  {} {[@var{info}, @var{err}, @var{msg}] =} stat (@var{file})
 @deftypefnx {} {[@var{info}, @var{err}, @var{msg}] =} stat (@var{fid})
 @deftypefnx {} {[@var{info}, @var{err}, @var{msg}] =} lstat (@var{file})
@@ -859,7 +862,9 @@
 
   if (args(0).is_scalar_type ())
     {
-      int fid = octave::stream_list::get_file_number (args(0));
+      octave::stream_list& streams = interp.get_stream_list ();
+
+      int fid = streams.get_file_number (args(0));
 
       octave::sys::file_fstat fs (fid);
 
--- a/libinterp/dldfcn/__init_gnuplot__.cc	Thu Jul 06 12:21:42 2017 -0400
+++ b/libinterp/dldfcn/__init_gnuplot__.cc	Thu Jul 06 13:34:31 2017 -0400
@@ -156,14 +156,14 @@
         octave_value_list args;
         Matrix fids = pstream.matrix_value ();
 
-        Ffputs (ovl (fids(0), "\nquit;\n"));
+        Ffputs (m_interpreter, ovl (fids(0), "\nquit;\n"));
 
-        Ffflush (ovl (fids(0)));
-        Fpclose (ovl (fids(0)));
+        Ffflush (m_interpreter, ovl (fids(0)));
+        Fpclose (m_interpreter, ovl (fids(0)));
 
         if (fids.numel () > 1)
           {
-            Fpclose (ovl (fids(1)));
+            Fpclose (m_interpreter, ovl (fids(1)));
 
             if (fids.numel () > 2)
               Fwaitpid (ovl (fids(2)));