GNU Octave  9.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
syscalls.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1996-2024 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 // Thomas Baier <baier@ci.tuwien.ac.at> added the original versions of
27 // the following functions:
28 //
29 // mkfifo unlink waitpid
30 
31 #if defined (HAVE_CONFIG_H)
32 # include "config.h"
33 #endif
34 
35 #include <cstdio>
36 #include <cstring>
37 
38 #include "cmd-hist.h"
39 #include "fcntl-wrappers.h"
40 #include "file-ops.h"
41 #include "file-stat.h"
42 #include "lo-utils.h"
43 #include "oct-env.h"
44 #include "oct-syscalls.h"
45 #include "oct-uname.h"
46 
47 #include "defun.h"
48 #include "error.h"
49 #include "errwarn.h"
50 #include "event-manager.h"
51 #include "input.h"
52 #include "interpreter.h"
53 #include "oct-hist.h"
54 #include "oct-map.h"
55 #include "oct-stdstrm.h"
56 #include "oct-stream.h"
57 #include "ovl.h"
58 #include "sysdep.h"
59 #include "utils.h"
60 #include "variables.h"
61 
63 
64 static octave_scalar_map
65 mk_stat_map (const sys::base_file_stat& fs)
66 {
67  static bool have_rdev
68  = sys::base_file_stat::have_struct_stat_st_rdev ();
69  static bool have_blksize
70  = sys::base_file_stat::have_struct_stat_st_blksize ();
71  static bool have_blocks
72  = sys::base_file_stat::have_struct_stat_st_blocks ();
73 
74  static double nan = numeric_limits<double>::NaN ();
75 
77 
78  m.assign ("dev", static_cast<double> (fs.dev ()));
79  m.assign ("ino", fs.ino ());
80  m.assign ("mode", fs.mode ());
81  m.assign ("modestr", fs.mode_as_string ());
82  m.assign ("nlink", fs.nlink ());
83  m.assign ("uid", fs.uid ());
84  m.assign ("gid", fs.gid ());
85  m.assign ("rdev", have_rdev ? static_cast<double> (fs.rdev ()) : nan);
86  m.assign ("size", fs.size ());
87  m.assign ("atime", fs.atime ());
88  m.assign ("mtime", fs.mtime ());
89  m.assign ("ctime", fs.ctime ());
90 
91  if (have_blksize)
92  m.assign ("blksize", fs.blksize ());
93  else
94  m.assign ("blksize", nan);
95 
96  if (have_blocks)
97  m.assign ("blocks", fs.blocks ());
98  else
99  m.assign ("blocks", nan);
100 
101  return m;
102 }
103 
104 static octave_value_list
105 mk_stat_result (const sys::base_file_stat& fs)
106 {
107  if (fs)
108  return ovl (octave_value (mk_stat_map (fs)), 0, "");
109  else
110  return ovl (Matrix (), -1, fs.error ());
111 }
112 
113 DEFMETHODX ("dup2", Fdup2, interp, args, ,
114  doc: /* -*- texinfo -*-
115 @deftypefn {} {[@var{fid}, @var{msg}] =} dup2 (@var{old}, @var{new})
116 Duplicate a file descriptor.
117 
118 If successful, @var{fid} is greater than zero and contains the new file ID@.
119 Otherwise, @var{fid} is negative and @var{msg} contains a system-dependent
120 error message.
121 @seealso{fopen, fclose, fcntl}
122 @end deftypefn */)
123 {
124  if (args.length () != 2)
125  print_usage ();
126 
127  stream_list& streams = interp.get_stream_list ();
128 
129  stream old_stream = streams.lookup (args(0), "dup2");
130 
131  stream new_stream = streams.lookup (args(1), "dup2");
132 
133  int i_old = old_stream.file_number ();
134  int i_new = new_stream.file_number ();
135 
136  if (i_old >= 0 && i_new >= 0)
137  {
138  std::string msg;
139 
140  int status = sys::dup2 (i_old, i_new, msg);
141 
142  return ovl (status, msg);
143  }
144  else
145  return ovl (-1, "");
146 }
147 
148 DEFMETHODX ("exec", Fexec, interp, args, ,
149  doc: /* -*- texinfo -*-
150 @deftypefn {} {[@var{err}, @var{msg}] =} exec (@var{file}, @var{args})
151 Replace current process with a new process.
152 
153 Calling @code{exec} without first calling @code{fork} will terminate your
154 current Octave process and replace it with the program named by @var{file}.
155 For example,
156 
157 @example
158 exec ("ls", "-l")
159 @end example
160 
161 @noindent
162 will run @code{ls} and return you to your shell prompt.
163 
164 If successful, @code{exec} does not return. If @code{exec} does return,
165 @var{err} will be nonzero, and @var{msg} will contain a system-dependent
166 error message.
167 @end deftypefn */)
168 {
169  int nargin = args.length ();
170 
171  if (nargin < 1 || nargin > 2)
172  print_usage ();
173 
174  std::string exec_file = args(0).xstring_value ("exec: FILE must be a string");
175 
176  string_vector exec_args;
177 
178  if (nargin == 2)
179  {
180  string_vector tmp = args(1).xstring_vector_value ("exec: all arguments must be strings");
181 
182  int len = tmp.numel ();
183 
184  exec_args.resize (len + 1);
185 
186  exec_args[0] = exec_file;
187 
188  for (int i = 0; i < len; i++)
189  exec_args[i+1] = tmp[i];
190  }
191  else
192  {
193  exec_args.resize (1);
194 
195  exec_args[0] = exec_file;
196  }
197 
198  history_system& history_sys = interp.get_history_system ();
199 
200  history_sys.write_timestamp ();
201 
204 
205  std::string msg;
206 
207  int status = sys::execvp (exec_file, exec_args, msg);
208 
209  return ovl (status, msg);
210 }
211 
212 DEFMETHODX ("popen2", Fpopen2, interp, args, ,
213  doc: /* -*- texinfo -*-
214 @deftypefn {} {[@var{in}, @var{out}, @var{pid}] =} popen2 (@var{command}, @var{args})
215 Start a subprocess with two-way communication.
216 
217 The name of the process is given by @var{command}, and @var{args} is an
218 array or cell array of strings containing options for the command.
219 
220 The file identifiers for the input and output streams of the subprocess are
221 returned in @var{in} and @var{out}. If execution of the command is
222 successful, @var{pid} contains the process ID of the subprocess. Otherwise,
223 @var{pid} is @minus{}1.
224 
225 For example:
226 
227 @example
228 [in, out, pid] = popen2 ("sort", "-r");
229 fputs (in, "these\nare\nsome\nstrings\n");
230 fclose (in);
231 EAGAIN = errno ("EAGAIN");
232 done = false;
233 do
234  s = fgets (out);
235  if (ischar (s))
236  fputs (stdout, s);
237  elseif (errno () == EAGAIN)
238  pause (0.1);
239  fclear (out);
240  else
241  done = true;
242  endif
243 until (done)
244 fclose (out);
245 waitpid (pid);
246 
247  @print{} these
248  @print{} strings
249  @print{} some
250  @print{} are
251 @end example
252 
253 Note that @code{popen2}, unlike @code{popen}, will not @nospell{"reap"}
254 the child process. If you don't use @code{waitpid} to check the child's
255 exit status, it will linger until Octave exits.
256 @seealso{popen, waitpid}
257 @end deftypefn */)
258 {
259  int nargin = args.length ();
260 
261  if (nargin < 1 || nargin > 3)
262  print_usage ();
263 
264  std::string exec_file = args(0).xstring_value ("popen2: COMMAND argument must be a string");
265 
266  string_vector arg_list;
267 
268  if (nargin >= 2)
269  {
270  string_vector tmp = args(1).xstring_vector_value ("popen2: all arguments must be strings");
271 
272  int len = tmp.numel ();
273 
274  arg_list.resize (len + 1);
275 
276  arg_list[0] = exec_file;
277 
278  for (int i = 0; i < len; i++)
279  arg_list[i+1] = tmp[i];
280  }
281  else
282  {
283  arg_list.resize (1);
284 
285  arg_list[0] = exec_file;
286  }
287 
288  bool sync_mode = (nargin == 3 ? args(2).bool_value () : false);
289 
290  int filedesc[2];
291  std::string msg;
292  pid_t pid;
293 
294  pid = sys::popen2 (exec_file, arg_list, sync_mode, filedesc, msg);
295 
296  if (pid < 0)
297  error ("%s", msg.c_str ());
298 
299  FILE *ifile = fdopen (filedesc[1], "r");
300  FILE *ofile = fdopen (filedesc[0], "w");
301 
302  stream is = stdiostream::create (exec_file + "-in", ifile, std::ios::in);
303 
304  stream os = stdiostream::create (exec_file + "-out", ofile, std::ios::out);
305 
306  stream_list& streams = interp.get_stream_list ();
307 
308  return ovl (streams.insert (os), streams.insert (is), pid);
309 }
310 
311 /*
312 
313 %!test # UNIX-style test
314 %! if (isunix () || ismac ())
315 %! [in, out, pid] = popen2 ("sort", "-r");
316 %! EAGAIN = errno ("EAGAIN");
317 %! fputs (in, "these\nare\nsome\nstrings\n");
318 %! fclose (in);
319 %! done = false;
320 %! str = {};
321 %! idx = 0;
322 %! errs = 0;
323 %! do
324 %! if (ismac ()) # FIXME: Is this necessary?
325 %! errno (0);
326 %! endif
327 %! s = fgets (out);
328 %! if (ischar (s))
329 %! idx++;
330 %! str{idx} = s;
331 %! elseif (errno () == EAGAIN)
332 %! fclear (out);
333 %! pause (0.1);
334 %! if (++errs == 100)
335 %! done = true;
336 %! endif
337 %! else
338 %! done = true;
339 %! endif
340 %! until (done)
341 %! fclose (out);
342 %! waitpid (pid);
343 %! assert (str, {"these\n","strings\n","some\n","are\n"});
344 %! endif
345 
346 %!test # Windows-style test
347 %! if (ispc () && ! isunix ())
348 %! [in, out, pid] = popen2 ('C:\Windows\system32\sort.exe', "/R");
349 %! EAGAIN = errno ("EINVAL");
350 %! fputs (in, "these\r\nare\r\nsome\r\nstrings\r\n");
351 %! fclose (in);
352 %! done = false;
353 %! str = {};
354 %! idx = 0;
355 %! errs = 0;
356 %! do
357 %! errno (0);
358 %! s = fgets (out);
359 %! if (ischar (s))
360 %! idx++;
361 %! str{idx} = s;
362 %! elseif (errno () == EAGAIN)
363 %! fclear (out);
364 %! pause (0.1);
365 %! if (++errs == 100)
366 %! done = true;
367 %! endif
368 %! else
369 %! done = true;
370 %! endif
371 %! until (done)
372 %! fclose (out);
373 %! waitpid (pid);
374 %! assert (str, {"these\r\n","strings\r\n","some\r\n","are\r\n"});
375 %! endif
376 
377 */
378 
379 DEFMETHODX ("fcntl", Ffcntl, interp, args, nargout,
380  doc: /* -*- texinfo -*-
381 @deftypefn {} {} fcntl (@var{fid}, @var{request}, @var{arg})
382 @deftypefnx {} {[@var{status}, @var{msg}] =} fcntl (@var{fid}, @var{request}, @var{arg})
383 Change the properties of the open file @var{fid}.
384 
385 The following values may be passed as @var{request}:
386 
387 @vtable @code
388 @item F_DUPFD
389 Return a duplicate file descriptor.
390 
391 @item F_GETFD
392 Return the file descriptor flags for @var{fid}.
393 
394 @item F_SETFD
395 Set the file descriptor flags for @var{fid}.
396 
397 @item F_GETFL
398 Return the file status flags for @var{fid}. The following codes may be
399 returned (some of the flags may be undefined on some systems).
400 
401 @vtable @code
402 @item O_RDONLY
403 Open for reading only.
404 
405 @item O_WRONLY
406 Open for writing only.
407 
408 @item O_RDWR
409 Open for reading and writing.
410 
411 @item O_APPEND
412 Append on each write.
413 
414 @item O_CREAT
415 Create the file if it does not exist.
416 
417 @item O_NONBLOCK
418 Non-blocking mode.
419 
420 @item O_SYNC
421 Wait for writes to complete.
422 
423 @item O_ASYNC
424 Asynchronous I/O.
425 @end vtable
426 
427 @item F_SETFL
428 Set the file status flags for @var{fid} to the value specified by @var{arg}.
429 The only flags that can be changed are @w{@code{O_APPEND}}@ and
430 @w{@code{O_NONBLOCK}}.
431 @end vtable
432 
433 If successful, @var{status} is 0 and @var{msg} is an empty string. Otherwise,
434 @var{status} is -1 and @var{msg} contains a system-dependent error
435 message.
436 @seealso{fopen, dup2}
437 @end deftypefn */)
438 {
439  if (args.length () != 3)
440  print_usage ();
441 
442  stream_list& streams = interp.get_stream_list ();
443 
444  stream strm = streams.lookup (args(0), "fcntl");
445 
446  int fid = strm.file_number ();
447 
448  // FIXME: Do we want to use xint_value and throw a warning message
449  // if input validation fails?
450  int req = args(1).int_value (true);
451  int arg = args(2).int_value (true);
452 
453  // FIXME: Need better checking here?
454  if (fid < 0)
455  error ("fcntl: invalid file id");
456 
457  octave_value_list retval;
458  std::string msg;
459 
460  int status = sys::fcntl (fid, req, arg, msg);
461 
462  if (nargout == 0)
463  {
464  if (status < 0)
465  error ("fcntl: operation failed: %s", msg.c_str ());
466  }
467  else
468  {
469  if (status < 0)
470  retval = ovl (-1.0, msg);
471  else
472  retval = ovl (0.0, "");
473  }
474 
475  return retval;
476 }
477 
478 DEFMETHODX ("fork", Ffork, interp, args, ,
479  doc: /* -*- texinfo -*-
480 @deftypefn {} {[@var{pid}, @var{msg}] =} fork ()
481 Create a copy of the current process.
482 
483 Fork can return one of the following values:
484 
485 @table @asis
486 @item > 0
487 You are in the parent process. The value returned from @code{fork} is the
488 process id of the child process. You should probably arrange to wait for
489 any child processes to exit.
490 
491 @item 0
492 You are in the child process. You can call @code{exec} to start another
493 process. If that fails, you should probably call @code{exit}.
494 
495 @item < 0
496 The call to @code{fork} failed for some reason. You must take evasive
497 action. A system dependent error message will be waiting in @var{msg}.
498 @end table
499 @end deftypefn */)
500 {
501  if (args.length () != 0)
502  print_usage ();
503 
504  if (interp.at_top_level ())
505  error ("fork: cannot be called from command line");
506 
507  std::string msg;
508 
509  pid_t pid = sys::fork (msg);
510 
511  return ovl (pid, msg);
512 }
513 
514 DEFUNX ("getpgrp", Fgetpgrp, args, ,
515  doc: /* -*- texinfo -*-
516 @deftypefn {} {pgid =} getpgrp ()
517 Return the process group id of the current process.
518 @end deftypefn */)
519 {
520  if (args.length () != 0)
521  print_usage ();
522 
523  std::string msg;
524 
525  pid_t pid = sys::getpgrp (msg);
526 
527  return ovl (pid, msg);
528 }
529 
530 DEFUNX ("getpid", Fgetpid, args, ,
531  doc: /* -*- texinfo -*-
532 @deftypefn {} {pid =} getpid ()
533 Return the process id of the current process.
534 @seealso{getppid}
535 @end deftypefn */)
536 {
537  if (args.length () != 0)
538  print_usage ();
539 
540  return ovl (sys::getpid ());
541 }
542 
543 DEFUNX ("getppid", Fgetppid, args, ,
544  doc: /* -*- texinfo -*-
545 @deftypefn {} {pid =} getppid ()
546 Return the process id of the parent process.
547 @seealso{getpid}
548 @end deftypefn */)
549 {
550  if (args.length () != 0)
551  print_usage ();
552 
553  return ovl (sys::getppid ());
554 }
555 
556 DEFUNX ("getegid", Fgetegid, args, ,
557  doc: /* -*- texinfo -*-
558 @deftypefn {} {egid =} getegid ()
559 Return the effective group id of the current process.
560 @seealso{getgid}
561 @end deftypefn */)
562 {
563  if (args.length () != 0)
564  print_usage ();
565 
566  return ovl (sys::getegid ());
567 }
568 
569 DEFUNX ("getgid", Fgetgid, args, ,
570  doc: /* -*- texinfo -*-
571 @deftypefn {} {gid =} getgid ()
572 Return the real group id of the current process.
573 @seealso{getegid}
574 @end deftypefn */)
575 {
576  if (args.length () != 0)
577  print_usage ();
578 
579  return ovl (sys::getgid ());
580 }
581 
582 DEFUNX ("geteuid", Fgeteuid, args, ,
583  doc: /* -*- texinfo -*-
584 @deftypefn {} {euid =} geteuid ()
585 Return the effective user id of the current process.
586 @seealso{getuid}
587 @end deftypefn */)
588 {
589  if (args.length () != 0)
590  print_usage ();
591 
592  return ovl (sys::geteuid ());
593 }
594 
595 DEFUNX ("getuid", Fgetuid, args, ,
596  doc: /* -*- texinfo -*-
597 @deftypefn {} {uid =} getuid ()
598 Return the real user id of the current process.
599 @seealso{geteuid}
600 @end deftypefn */)
601 {
602  if (args.length () != 0)
603  print_usage ();
604 
605  return ovl (sys::getuid ());
606 }
607 
608 DEFUNX ("kill", Fkill, args, nargout,
609  doc: /* -*- texinfo -*-
610 @deftypefn {} {} kill (@var{pid}, @var{sig})
611 @deftypefnx {} {[@var{status}, @var{msg}] =} kill (@var{pid}, @var{sig})
612 Send signal @var{sig} to process @var{pid}.
613 
614 If @var{pid} is positive, then signal @var{sig} is sent to @var{pid}.
615 
616 If @var{pid} is 0, then signal @var{sig} is sent to every process in the
617 process group of the current process.
618 
619 If @var{pid} is -1, then signal @var{sig} is sent to every process except
620 process 1.
621 
622 If @var{pid} is less than -1, then signal @var{sig} is sent to every process in
623 the process group @var{-pid}.
624 
625 If @var{sig} is 0, then no signal is sent, but error checking is still
626 performed.
627 
628 If successful, @var{status} is 0 and @var{msg} is an empty string.
629 Otherwise, @var{status} is -1 and @var{msg} contains a system-dependent
630 error message.
631 @end deftypefn */)
632 {
633  if (args.length () != 2)
634  print_usage ();
635 
636  pid_t pid = args(0).int_value (true);
637 
638  int sig = args(1).int_value (true);
639 
640  octave_value_list retval;
641  std::string msg;
642 
643  int status = sys::kill (pid, sig, msg);
644 
645  if (nargout == 0)
646  {
647  if (status < 0)
648  error ("kill: operation failed: %s", msg.c_str ());
649  }
650  else
651  {
652  if (status < 0)
653  retval = ovl (-1.0, msg);
654  else
655  retval = ovl (0.0, "");
656  }
657 
658  return retval;
659 }
660 
661 DEFUNX ("lstat", Flstat, args, ,
662  doc: /* -*- texinfo -*-
663 @deftypefn {} {@var{info} =} lstat (@var{symlink})
664 @deftypefnx {} {[@var{info}, @var{err}, @var{msg}] =} lstat (@var{symlink})
665 Return a structure @var{info} containing information about the symbolic link
666 @var{symlink}.
667 
668 The function outputs are described in the documentation for @code{stat}.
669 @seealso{stat, symlink}
670 @end deftypefn */)
671 {
672  if (args.length () != 1)
673  print_usage ();
674 
675  std::string fname = args(0).xstring_value ("lstat: NAME must be a string");
676 
677  sys::file_stat fs (fname, false);
678 
679  return mk_stat_result (fs);
680 }
681 
682 // FIXME: This routine also exists verbatim in file-io.cc.
683 // Maybe change to be a general utility routine.
684 static int
685 convert (int x, int ibase, int obase)
686 {
687  int retval = 0;
688 
689  int tmp = x % obase;
690 
691  if (tmp > ibase - 1)
692  error ("mkfifo: invalid digit");
693 
694  retval = tmp;
695  int mult = ibase;
696  while ((x = (x - tmp) / obase))
697  {
698  tmp = x % obase;
699 
700  if (tmp > ibase - 1)
701  error ("mkfifo: invalid digit");
702 
703  retval += mult * tmp;
704  mult *= ibase;
705  }
706 
707  return retval;
708 }
709 
710 DEFUNX ("mkfifo", Fmkfifo, args, nargout,
711  doc: /* -*- texinfo -*-
712 @deftypefn {} {} mkfifo (@var{name}, @var{mode})
713 @deftypefnx {} {[@var{status}, @var{msg}] =} mkfifo (@var{name}, @var{mode})
714 Create a FIFO special file named @var{name} with file mode @var{mode}.
715 
716 @var{mode} is interpreted as an octal number and is subject to umask
717 processing. The final calculated mode is @code{@var{mode} - @var{umask}}.
718 
719 If successful, @var{status} is 0 and @var{msg} is an empty string.
720 Otherwise, @var{status} is -1 and @var{msg} contains a system-dependent
721 error message.
722 @seealso{pipe, umask}
723 @end deftypefn */)
724 {
725  if (args.length () != 2)
726  print_usage ();
727 
728  std::string name = args(0).xstring_value ("mkfifo: FILE must be a string");
729 
730  int octal_mode = args(1).xint_value ("mkfifo: MODE must be an integer");
731 
732  if (octal_mode < 0)
733  error ("mkfifo: MODE must be a positive integer value");
734 
735  int mode = convert (octal_mode, 8, 10);
736 
737  octave_value_list retval;
738  std::string msg;
739 
740  int status = sys::mkfifo (name, mode, msg);
741 
742  if (nargout == 0)
743  {
744  if (status < 0)
745  error ("mkfifo: operation failed: %s", msg.c_str ());
746  }
747  else
748  {
749  if (status < 0)
750  retval = ovl (-1.0, msg);
751  else
752  retval = ovl (0.0, "");
753  }
754 
755  return retval;
756 }
757 
758 /*
759 
760 ## Test input validation
761 %!error mkfifo ()
762 %!error mkfifo ("abc")
763 %!error mkfifo ("abc", 777, 123)
764 %!error <FILE must be a string> mkfifo (123, 456)
765 ## FIXME: These tests should work, but lasterr is not being set correctly.
766 #%!error <MODE must be an integer> mkfifo ("abc", {456})
767 #%!error <MODE must be a positive integer value> mkfifo ("abc", -1)
768 
769 */
770 
771 DEFMETHODX ("pipe", Fpipe, interp, args, ,
772  doc: /* -*- texinfo -*-
773 @deftypefn {} {[@var{read_fd}, @var{write_fd}, @var{err}, @var{msg}] =} pipe ()
774 Create a pipe and return the reading and writing ends of the pipe into
775 @var{read_fd} and @var{write_fd} respectively.
776 
777 If successful, @var{err} is 0 and @var{msg} is an empty string.
778 Otherwise, @var{err} is nonzero and @var{msg} contains a system-dependent
779 error message.
780 @seealso{mkfifo}
781 @end deftypefn */)
782 {
783  if (args.length () != 0)
784  print_usage ();
785 
786  int fid[2];
787  std::string msg;
788 
789  int status = sys::pipe (fid, msg);
790 
791  if (status < 0)
792  return ovl (-1, -1, -1, msg);
793  else
794  {
795  FILE *ifile = fdopen (fid[0], "r");
796  FILE *ofile = fdopen (fid[1], "w");
797 
798  stream is = stdiostream::create ("pipe-in", ifile, std::ios::in);
799 
800  stream os = stdiostream::create ("pipe-out", ofile, std::ios::out);
801 
802  stream_list& streams = interp.get_stream_list ();
803 
804  return ovl (streams.insert (is), streams.insert (os), status, msg);
805  }
806 }
807 
808 DEFMETHODX ("stat", Fstat, interp, args, ,
809  doc: /* -*- texinfo -*-
810 @deftypefn {} {[@var{info}, @var{err}, @var{msg}] =} stat (@var{file})
811 @deftypefnx {} {[@var{info}, @var{err}, @var{msg}] =} stat (@var{fid})
812 @deftypefnx {} {[@var{info}, @var{err}, @var{msg}] =} lstat (@var{file})
813 @deftypefnx {} {[@var{info}, @var{err}, @var{msg}] =} lstat (@var{fid})
814 Return a structure @var{info} containing the following information about
815 @var{file} or file identifier @var{fid}.
816 
817 @table @code
818 @item dev
819 ID of device containing a directory entry for this file.
820 
821 @item ino
822 File number of the file.
823 
824 @item mode
825 File mode, as an integer. Use the functions @w{@code{S_ISREG}},
826 @w{@code{S_ISDIR}}, @w{@code{S_ISCHR}}, @w{@code{S_ISBLK}},
827 @w{@code{S_ISFIFO}}, @w{@code{S_ISLNK}}, or @w{@code{S_ISSOCK}}@ to extract
828 information from this value.
829 
830 @item modestr
831 File mode, as a string of ten letters or dashes as would be returned by
832 @kbd{ls -l}.
833 
834 @item nlink
835 Number of links.
836 
837 @item uid
838 User ID of file's owner.
839 
840 @item gid
841 Group ID of file's group.
842 
843 @item rdev
844 ID of device for block or character special files.
845 
846 @item size
847 Size in bytes.
848 
849 @item atime
850 Time of last access in the same form as time values returned from
851 @code{time}. @xref{Timing Utilities}.
852 
853 @item mtime
854 Time of last modification in the same form as time values returned from
855 @code{time}. @xref{Timing Utilities}.
856 
857 @item ctime
858 Time of last file status change in the same form as time values
859 returned from @code{time}. @xref{Timing Utilities}.
860 
861 @item blksize
862 Size of blocks in the file.
863 
864 @item blocks
865 Number of blocks allocated for file.
866 @end table
867 
868 If the call is successful @var{err} is 0 and @var{msg} is an empty string.
869 If the file does not exist, or some other error occurs, @var{info} is an
870 empty matrix, @var{err} is @minus{}1, and @var{msg} contains the
871 corresponding system error message.
872 
873 If @var{file} is a symbolic link, @code{stat} will return information about
874 the actual file that is referenced by the link. Use @code{lstat} if you
875 want information about the symbolic link itself.
876 
877 For example:
878 
879 @example
880 [info, err, msg] = stat ("/vmlinuz")
881  @result{} info =
882  @{
883  atime = 855399756
884  rdev = 0
885  ctime = 847219094
886  uid = 0
887  size = 389218
888  blksize = 4096
889  mtime = 847219094
890  gid = 6
891  nlink = 1
892  blocks = 768
893  mode = -rw-r--r--
894  modestr = -rw-r--r--
895  ino = 9316
896  dev = 2049
897  @}
898  @result{} err = 0
899  @result{} msg =
900 @end example
901 @seealso{lstat, ls, dir, isfile, isfolder}
902 @end deftypefn */)
903 {
904  if (args.length () != 1)
905  print_usage ();
906 
907  octave_value_list retval;
908 
909  if (args(0).is_scalar_type ())
910  {
911  stream_list& streams = interp.get_stream_list ();
912 
913  int fid = streams.get_file_number (args(0));
914 
915  sys::file_fstat fs (fid);
916 
917  retval = mk_stat_result (fs);
918  }
919  else
920  {
921  std::string fname = args(0).xstring_value ("stat: NAME must be a string");
922 
923  sys::file_stat fs (fname);
924 
925  retval = mk_stat_result (fs);
926  }
927 
928  return retval;
929 }
930 
931 DEFUNX ("S_ISREG", FS_ISREG, args, ,
932  doc: /* -*- texinfo -*-
933 @deftypefn {} {@var{tf} =} S_ISREG (@var{mode})
934 Return true if @var{mode} corresponds to a regular file.
935 
936 The value of @var{mode} is assumed to be returned from a call to
937 @code{stat}.
938 @seealso{stat, lstat}
939 @end deftypefn */)
940 {
941  if (args.length () != 1)
942  print_usage ();
943 
944  double mode = args(0).xdouble_value ("S_ISREG: invalid MODE value");
945 
946  return ovl (sys::file_stat::is_reg (static_cast<mode_t> (mode)));
947 }
948 
949 DEFUNX ("S_ISDIR", FS_ISDIR, args, ,
950  doc: /* -*- texinfo -*-
951 @deftypefn {} {@var{tf} =} S_ISDIR (@var{mode})
952 Return true if @var{mode} corresponds to a directory.
953 
954 The value of @var{mode} is assumed to be returned from a call to
955 @code{stat}.
956 @seealso{stat, lstat}
957 @end deftypefn */)
958 {
959  if (args.length () != 1)
960  print_usage ();
961 
962  double mode = args(0).xdouble_value ("S_ISDIR: invalid MODE value");
963 
964  return ovl (sys::file_stat::is_dir (static_cast<mode_t> (mode)));
965 }
966 
967 DEFUNX ("S_ISCHR", FS_ISCHR, args, ,
968  doc: /* -*- texinfo -*-
969 @deftypefn {} {@var{tf} =} S_ISCHR (@var{mode})
970 Return true if @var{mode} corresponds to a character device.
971 
972 The value of @var{mode} is assumed to be returned from a call to
973 @code{stat}.
974 @seealso{stat, lstat}
975 @end deftypefn */)
976 {
977  if (args.length () != 1)
978  print_usage ();
979 
980  double mode = args(0).xdouble_value ("S_ISCHR: invalid MODE value");
981 
982  return ovl (sys::file_stat::is_chr (static_cast<mode_t> (mode)));
983 }
984 
985 DEFUNX ("S_ISBLK", FS_ISBLK, args, ,
986  doc: /* -*- texinfo -*-
987 @deftypefn {} {@var{tf} =} S_ISBLK (@var{mode})
988 Return true if @var{mode} corresponds to a block device.
989 
990 The value of @var{mode} is assumed to be returned from a call to
991 @code{stat}.
992 @seealso{stat, lstat}
993 @end deftypefn */)
994 {
995  if (args.length () != 1)
996  print_usage ();
997 
998  double mode = args(0).xdouble_value ("S_ISBLK: invalid MODE value");
999 
1000  return ovl (sys::file_stat::is_blk (static_cast<mode_t> (mode)));
1001 }
1002 
1003 DEFUNX ("S_ISFIFO", FS_ISFIFO, args, ,
1004  doc: /* -*- texinfo -*-
1005 @deftypefn {} {@var{tf} =} S_ISFIFO (@var{mode})
1006 Return true if @var{mode} corresponds to a fifo.
1007 
1008 The value of @var{mode} is assumed to be returned from a call to
1009 @code{stat}.
1010 @seealso{stat, lstat}
1011 @end deftypefn */)
1012 {
1013  if (args.length () != 1)
1014  print_usage ();
1015 
1016  double mode = args(0).xdouble_value ("S_ISFIFO: invalid MODE value");
1017 
1018  return ovl (sys::file_stat::is_fifo (static_cast<mode_t> (mode)));
1019 }
1020 
1021 DEFUNX ("S_ISLNK", FS_ISLNK, args, ,
1022  doc: /* -*- texinfo -*-
1023 @deftypefn {} {@var{tf} =} S_ISLNK (@var{mode})
1024 Return true if @var{mode} corresponds to a symbolic link.
1025 
1026 The value of @var{mode} is assumed to be returned from a call to
1027 @code{stat}.
1028 @seealso{stat, lstat}
1029 @end deftypefn */)
1030 {
1031  if (args.length () != 1)
1032  print_usage ();
1033 
1034  double mode = args(0).xdouble_value ("S_ISLNK: invalid MODE value");
1035 
1036  return ovl (sys::file_stat::is_lnk (static_cast<mode_t> (mode)));
1037 }
1038 
1039 DEFUNX ("S_ISSOCK", FS_ISSOCK, args, ,
1040  doc: /* -*- texinfo -*-
1041 @deftypefn {} {@var{tf} =} S_ISSOCK (@var{mode})
1042 Return true if @var{mode} corresponds to a socket.
1043 
1044 The value of @var{mode} is assumed to be returned from a call to
1045 @code{stat}.
1046 @seealso{stat, lstat}
1047 @end deftypefn */)
1048 {
1049  if (args.length () != 1)
1050  print_usage ();
1051 
1052  double mode = args(0).xdouble_value ("S_ISSOCK: invalid MODE value");
1053 
1054  return ovl (sys::file_stat::is_sock (static_cast<mode_t> (mode)));
1055 }
1056 
1057 DEFUN (gethostname, args, ,
1058  doc: /* -*- texinfo -*-
1059 @deftypefn {} {@var{name} =} gethostname ()
1060 Return the hostname of the system where Octave is running.
1061 @end deftypefn */)
1062 {
1063  if (args.length () != 0)
1064  print_usage ();
1065 
1066  return ovl (sys::env::get_host_name ());
1067 }
1068 
1069 DEFUN (uname, args, ,
1070  doc: /* -*- texinfo -*-
1071 @deftypefn {} {[@var{uts}, @var{err}, @var{msg}] =} uname ()
1072 Return system information in the structure.
1073 
1074 For example:
1075 
1076 @example
1077 @group
1078 uname ()
1079  @result{} @{
1080  sysname = x86_64
1081  nodename = segfault
1082  release = 2.6.15-1-amd64-k8-smp
1083  version = Linux
1084  machine = #2 SMP Thu Feb 23 04:57:49 UTC 2006
1085  @}
1086 @end group
1087 @end example
1088 
1089 If successful, @var{err} is 0 and @var{msg} is an empty string.
1090 Otherwise, @var{err} is nonzero and @var{msg} contains a
1091 system-dependent error message.
1092 @end deftypefn */)
1093 {
1094  if (args.length () != 0)
1095  print_usage ();
1096 
1097  sys::uname sysinfo;
1098 
1100 
1101  m.assign ("sysname", sysinfo.sysname ());
1102  m.assign ("nodename", sysinfo.nodename ());
1103  m.assign ("release", sysinfo.release ());
1104  m.assign ("version", sysinfo.version ());
1105  m.assign ("machine", sysinfo.machine ());
1106 
1107  return ovl (m, sysinfo.error (), sysinfo.message ());
1108 }
1109 
1110 /*
1111 %!test <*51869>
1112 %! [info, status, msg] = uname ();
1113 %! if (status == 0)
1114 %! assert (isstruct (info))
1115 %! assert (ischar (msg) && isempty (msg))
1116 %! endif
1117 */
1118 
1119 DEFMETHODX ("unlink", Funlink, interp, args, nargout,
1120  doc: /* -*- texinfo -*-
1121 @deftypefn {} {} unlink (@var{file})
1122 @deftypefnx {} {[@var{status}, @var{msg}] =} unlink (@var{file})
1123 Delete the file named @var{file}.
1124 
1125 If successful, @var{status} is 0 and @var{msg} is an empty string.
1126 Otherwise, @var{status} is -1 and @var{msg} contains a system-dependent
1127 error message.
1128 @seealso{delete, rmdir}
1129 @end deftypefn */)
1130 {
1131  if (args.length () != 1)
1132  print_usage ();
1133 
1134  std::string name = args(0).xstring_value ("unlink: FILE must be a string");
1135 
1136  octave_value_list retval;
1137  std::string msg;
1138 
1139  event_manager& evmgr = interp.get_event_manager ();
1140 
1141  evmgr.file_remove (name, "");
1142 
1143  int status = sys::unlink (name, msg);
1144 
1145  evmgr.file_renamed (status == 0);
1146 
1147  if (nargout == 0)
1148  {
1149  if (status < 0)
1150  error ("unlink: operation failed: %s", msg.c_str ());
1151  }
1152  else
1153  {
1154  if (status < 0)
1155  retval = ovl (-1.0, msg);
1156  else
1157  retval = ovl (0.0, "");
1158  }
1159 
1160  return retval;
1161 }
1162 
1163 /*
1164 %!test
1165 %! file = tempname ();
1166 %! fid = fopen (file, "wt");
1167 %! if (fid < 0)
1168 %! error ("Could not open temporary file for unlink BIST test");
1169 %! endif
1170 %! fdisp (fid, pi);
1171 %! fclose (fid);
1172 %! [status, msg] = unlink (file);
1173 %! assert (status, 0);
1174 %! assert (msg, "");
1175 
1176 ## Test input validation
1177 %!error <Invalid call> unlink ()
1178 %!error <Invalid call> unlink ("a", "b")
1179 %!error <FILE must be a string> unlink (123)
1180 */
1181 
1182 DEFUNX ("waitpid", Fwaitpid, args, ,
1183  doc: /* -*- texinfo -*-
1184 @deftypefn {} {[@var{pid}, @var{status}, @var{msg}] =} waitpid (@var{pid}, @var{options})
1185 Wait for process @var{pid} to terminate.
1186 
1187 The @var{pid} argument can be:
1188 
1189 @table @asis
1190 @item @minus{}1
1191 Wait for any child process.
1192 
1193 @item 0
1194 Wait for any child process whose process group ID is equal to that of the
1195 Octave interpreter process.
1196 
1197 @item > 0
1198 Wait for termination of the child process with ID @var{pid}.
1199 @end table
1200 
1201 The @var{options} argument can be a bitwise OR of zero or more of the
1202 following constants:
1203 
1204 @table @code
1205 @item 0
1206 Wait until signal is received or a child process exits (this is the default
1207 if the @var{options} argument is missing).
1208 
1209 @item WNOHANG
1210 Do not hang if status is not immediately available.
1211 
1212 @item WUNTRACED
1213 Report the status of any child processes that are stopped, and whose status
1214 has not yet been reported since they stopped.
1215 
1216 @item WCONTINUE
1217 Return if a stopped child has been resumed by delivery of @code{SIGCONT}.
1218 This value may not be meaningful on all systems.
1219 @end table
1220 
1221 If the returned value of @var{pid} is greater than 0, it is the process ID
1222 of the child process that exited. If an error occurs, @var{pid} will be
1223 less than zero and @var{msg} will contain a system-dependent error message.
1224 The value of @var{status} contains additional system-dependent information
1225 about the subprocess that exited.
1226 @seealso{WCONTINUE, WCOREDUMP, WEXITSTATUS, WIFCONTINUED, WIFSIGNALED,
1227 WIFSTOPPED, WNOHANG, WSTOPSIG, WTERMSIG, WUNTRACED}
1228 @end deftypefn */)
1229 {
1230  int nargin = args.length ();
1231 
1232  if (nargin != 1 && nargin != 2)
1233  print_usage ();
1234 
1235  pid_t pid = args(0).xint_value ("waitpid: OPTIONS must be an integer");
1236 
1237  int options = 0;
1238 
1239  if (nargin == 2)
1240  options = args(1).xint_value ("waitpid: PID must be an integer value");
1241 
1242  std::string msg;
1243  int status;
1244 
1245  pid_t result = sys::waitpid (pid, &status, options, msg);
1246 
1247  return ovl (result, status, msg);
1248 }
1249 
1250 DEFUNX ("WIFEXITED", FWIFEXITED, args, ,
1251  doc: /* -*- texinfo -*-
1252 @deftypefn {} {@var{tf} =} WIFEXITED (@var{status})
1253 Given @var{status} from a call to @code{waitpid}, return
1254 true if the child terminated normally.
1255 @seealso{waitpid, WEXITSTATUS, WIFSIGNALED, WTERMSIG, WCOREDUMP, WIFSTOPPED,
1256 WSTOPSIG, WIFCONTINUED}
1257 @end deftypefn */)
1258 {
1259  if (args.length () != 1)
1260  print_usage ();
1261 
1262  int status = args(0).xint_value ("WIFEXITED: STATUS must be an integer");
1263 
1264  return ovl (sys::wifexited (status));
1265 }
1266 
1267 DEFUNX ("WEXITSTATUS", FWEXITSTATUS, args, ,
1268  doc: /* -*- texinfo -*-
1269 @deftypefn {} {@var{tf} =} WEXITSTATUS (@var{status})
1270 Given @var{status} from a call to @code{waitpid}, return
1271 the exit status of the child.
1272 
1273 This function should only be employed if @code{WIFEXITED} returned true.
1274 @seealso{waitpid, WIFEXITED, WIFSIGNALED, WTERMSIG, WCOREDUMP, WIFSTOPPED,
1275 WSTOPSIG, WIFCONTINUED}
1276 @end deftypefn */)
1277 {
1278  if (args.length () != 1)
1279  print_usage ();
1280 
1281  int status = args(0).xint_value ("WEXITSTATUS: STATUS must be an integer");
1282 
1283  return ovl (sys::wexitstatus (status));
1284 }
1285 
1286 DEFUNX ("WIFSIGNALED", FWIFSIGNALED, args, ,
1287  doc: /* -*- texinfo -*-
1288 @deftypefn {} {@var{tf} =} WIFSIGNALED (@var{status})
1289 Given @var{status} from a call to @code{waitpid}, return
1290 true if the child process was terminated by a signal.
1291 @seealso{waitpid, WIFEXITED, WEXITSTATUS, WTERMSIG, WCOREDUMP, WIFSTOPPED,
1292 WSTOPSIG, WIFCONTINUED}
1293 @end deftypefn */)
1294 {
1295  if (args.length () != 1)
1296  print_usage ();
1297 
1298  int status = args(0).xint_value ("WIFSIGNALED: STATUS must be an integer");
1299 
1300  return ovl (sys::wifsignaled (status));
1301 }
1302 
1303 DEFUNX ("WTERMSIG", FWTERMSIG, args, ,
1304  doc: /* -*- texinfo -*-
1305 @deftypefn {} {@var{tf} =} WTERMSIG (@var{status})
1306 Given @var{status} from a call to @code{waitpid}, return
1307 the number of the signal that caused the child process to terminate.
1308 
1309 This function should only be employed if @code{WIFSIGNALED} returned true.
1310 @seealso{waitpid, WIFEXITED, WEXITSTATUS, WIFSIGNALED, WCOREDUMP, WIFSTOPPED,
1311 WSTOPSIG, WIFCONTINUED}
1312 @end deftypefn */)
1313 {
1314  if (args.length () != 1)
1315  print_usage ();
1316 
1317  int status = args(0).xint_value ("WTERMSIG: STATUS must be an integer");
1318 
1319  return ovl (sys::wtermsig (status));
1320 }
1321 
1322 DEFUNX ("WCOREDUMP", FWCOREDUMP, args, ,
1323  doc: /* -*- texinfo -*-
1324 @deftypefn {} {@var{tf} =} WCOREDUMP (@var{status})
1325 Given @var{status} from a call to @code{waitpid}, return
1326 true if the child produced a core dump.
1327 
1328 This function should only be employed if @code{WIFSIGNALED} returned true.
1329 The macro used to implement this function is not specified in POSIX.1-2001
1330 and is not available on some Unix implementations (e.g., @nospell{AIX, SunOS}).
1331 @seealso{waitpid, WIFEXITED, WEXITSTATUS, WIFSIGNALED, WTERMSIG, WIFSTOPPED,
1332 WSTOPSIG, WIFCONTINUED}
1333 @end deftypefn */)
1334 {
1335  if (args.length () != 1)
1336  print_usage ();
1337 
1338  int status = args(0).xint_value ("WCOREDUMP: STATUS must be an integer");
1339 
1340  return ovl (sys::wcoredump (status));
1341 }
1342 
1343 DEFUNX ("WIFSTOPPED", FWIFSTOPPED, args, ,
1344  doc: /* -*- texinfo -*-
1345 @deftypefn {} {@var{tf} =} WIFSTOPPED (@var{status})
1346 Given @var{status} from a call to @code{waitpid}, return
1347 true if the child process was stopped by delivery of a signal.
1348 
1349 This is only possible if the call was done using @code{WUNTRACED} or when
1350 the child is being traced (see ptrace(2)).
1351 @seealso{waitpid, WIFEXITED, WEXITSTATUS, WIFSIGNALED, WTERMSIG, WCOREDUMP,
1352 WSTOPSIG, WIFCONTINUED}
1353 @end deftypefn */)
1354 {
1355  if (args.length () != 1)
1356  print_usage ();
1357 
1358  int status = args(0).xint_value ("WIFSTOPPED: STATUS must be an integer");
1359 
1360  return ovl (sys::wifstopped (status));
1361 }
1362 
1363 DEFUNX ("WSTOPSIG", FWSTOPSIG, args, ,
1364  doc: /* -*- texinfo -*-
1365 @deftypefn {} {@var{tf} =} WSTOPSIG (@var{status})
1366 Given @var{status} from a call to @code{waitpid}, return
1367 the number of the signal which caused the child to stop.
1368 
1369 This function should only be employed if @code{WIFSTOPPED} returned true.
1370 @seealso{waitpid, WIFEXITED, WEXITSTATUS, WIFSIGNALED, WTERMSIG, WCOREDUMP,
1371 WIFSTOPPED, WIFCONTINUED}
1372 @end deftypefn */)
1373 {
1374  if (args.length () != 1)
1375  print_usage ();
1376 
1377  int status = args(0).xint_value ("WSTOPSIG: STATUS must be an integer");
1378 
1379  return ovl (sys::wstopsig (status));
1380 }
1381 
1382 DEFUNX ("WIFCONTINUED", FWIFCONTINUED, args, ,
1383  doc: /* -*- texinfo -*-
1384 @deftypefn {} {@var{tf} =} WIFCONTINUED (@var{status})
1385 Given @var{status} from a call to @code{waitpid}, return
1386 true if the child process was resumed by delivery of @code{SIGCONT}.
1387 @seealso{waitpid, WIFEXITED, WEXITSTATUS, WIFSIGNALED, WTERMSIG, WCOREDUMP,
1388 WIFSTOPPED, WSTOPSIG}
1389 @end deftypefn */)
1390 {
1391  if (args.length () != 1)
1392  print_usage ();
1393 
1394  int status = args(0).xint_value ("WIFCONTINUED: STATUS must be an integer");
1395 
1396  return ovl (sys::wifcontinued (status));
1397 }
1398 
1399 DEFUNX ("canonicalize_file_name", Fcanonicalize_file_name, args, ,
1400  doc: /* -*- texinfo -*-
1401 @deftypefn {} {[@var{cname}, @var{status}, @var{msg}] =} canonicalize_file_name (@var{fname})
1402 Return the canonical name of file @var{fname}.
1403 
1404 If the file does not exist the empty string ("") is returned. No tilde
1405 expansion of @var{fname} is performed.
1406 @seealso{make_absolute_filename, is_absolute_filename,
1407 is_rooted_relative_filename, is_same_file, tilde_expand}
1408 @end deftypefn */)
1409 {
1410  if (args.length () != 1)
1411  print_usage ();
1412 
1413  std::string name = args(0).xstring_value ("canonicalize_file_name: NAME must be a string");
1414 
1415  std::string msg;
1416 
1417  std::string result = sys::canonicalize_file_name (name, msg);
1418 
1419  return ovl (result, msg.empty () ? 0 : -1, msg);
1420 }
1421 
1422 static inline octave_value
1423 const_value (const octave_value_list& args, int val)
1424 {
1425  if (args.length () != 0)
1426  print_usage ();
1427 
1428  return octave_value (val);
1429 }
1430 
1431 DEFUNX ("F_DUPFD", FF_DUPFD, args, ,
1432  doc: /* -*- texinfo -*-
1433 @deftypefn {} {@var{v} =} F_DUPFD ()
1434 Return the numerical value to pass to @code{fcntl} to return
1435 a duplicate file descriptor.
1436 @seealso{fcntl, F_GETFD, F_GETFL, F_SETFD, F_SETFL}
1437 @end deftypefn */)
1438 {
1439  static const int val = octave_f_dupfd_wrapper ();
1440 
1441  if (val < 0)
1442  err_disabled_feature ("F_DUPFD", "F_DUPFD");
1443 
1444  return const_value (args, val);
1445 }
1446 
1447 DEFUNX ("F_GETFD", FF_GETFD, args, ,
1448  doc: /* -*- texinfo -*-
1449 @deftypefn {} {@var{v} =} F_GETFD ()
1450 Return the numerical value to pass to @code{fcntl} to return
1451 the file descriptor flags.
1452 @seealso{fcntl, F_DUPFD, F_GETFL, F_SETFD, F_SETFL}
1453 @end deftypefn */)
1454 {
1455  static const int val = octave_f_getfd_wrapper ();
1456 
1457  if (val < 0)
1458  err_disabled_feature ("F_GETFD", "F_GETFD");
1459 
1460  return const_value (args, val);
1461 }
1462 
1463 DEFUNX ("F_GETFL", FF_GETFL, args, ,
1464  doc: /* -*- texinfo -*-
1465 @deftypefn {} {@var{v} =} F_GETFL ()
1466 Return the numerical value to pass to @code{fcntl} to return
1467 the file status flags.
1468 @seealso{fcntl, F_DUPFD, F_GETFD, F_SETFD, F_SETFL}
1469 @end deftypefn */)
1470 {
1471  static const int val = octave_f_getfl_wrapper ();
1472 
1473  if (val < 0)
1474  err_disabled_feature ("F_GETFL", "F_GETFL");
1475 
1476  return const_value (args, val);
1477 }
1478 
1479 DEFUNX ("F_SETFD", FF_SETFD, args, ,
1480  doc: /* -*- texinfo -*-
1481 @deftypefn {} {@var{v} =} F_SETFD ()
1482 Return the numerical value to pass to @code{fcntl} to set the file
1483 descriptor flags.
1484 @seealso{fcntl, F_DUPFD, F_GETFD, F_GETFL, F_SETFL}
1485 @end deftypefn */)
1486 {
1487  static const int val = octave_f_setfd_wrapper ();
1488 
1489  if (val < 0)
1490  err_disabled_feature ("F_SETFD", "F_SETFD");
1491 
1492  return const_value (args, val);
1493 }
1494 
1495 DEFUNX ("F_SETFL", FF_SETFL, args, ,
1496  doc: /* -*- texinfo -*-
1497 @deftypefn {} {@var{v} =} F_SETFL ()
1498 Return the numerical value to pass to @code{fcntl} to set the file
1499 status flags.
1500 @seealso{fcntl, F_DUPFD, F_GETFD, F_GETFL, F_SETFD}
1501 @end deftypefn */)
1502 {
1503  static const int val = octave_f_setfl_wrapper ();
1504 
1505  if (val < 0)
1506  err_disabled_feature ("F_SETFL", "F_SETFL");
1507 
1508  return const_value (args, val);
1509 }
1510 
1511 DEFUNX ("O_APPEND", FO_APPEND, args, ,
1512  doc: /* -*- texinfo -*-
1513 @deftypefn {} {@var{v} =} O_APPEND ()
1514 Return the numerical value of the @code{O_APPEND} macro.
1515 
1516 @code{O_APPEND} is file status flag that may be returned by @code{fcntl}
1517 to indicate each write operation appends, or that may be passed to
1518 @code{fcntl} to set the write mode to append.
1519 @seealso{fcntl, O_ASYNC, O_CREAT, O_EXCL, O_NONBLOCK, O_RDONLY, O_RDWR, O_SYNC,
1520 O_TRUNC, O_WRONLY}
1521 @end deftypefn */)
1522 {
1523  static const int val = octave_o_append_wrapper ();
1524 
1525  if (val < 0)
1526  err_disabled_feature ("O_APPEND", "O_APPEND");
1527 
1528  return const_value (args, val);
1529 }
1530 
1531 DEFUNX ("O_ASYNC", FO_ASYNC, args, ,
1532  doc: /* -*- texinfo -*-
1533 @deftypefn {} {@var{v} =} O_ASYNC ()
1534 Return the numerical value of the @code{O_ASYNC} macro.
1535 
1536 @code{O_ASYNC} is the file status flag that may be returned by
1537 @code{fcntl} to indicate asynchronous I/O.
1538 @seealso{fcntl, O_APPEND, O_CREAT, O_EXCL, O_NONBLOCK, O_RDONLY, O_RDWR, O_SYNC,
1539 O_TRUNC, O_WRONLY}
1540 @end deftypefn */)
1541 {
1542  static const int val = octave_o_async_wrapper ();
1543 
1544  if (val < 0)
1545  err_disabled_feature ("O_ASYNC", "O_ASYNC");
1546 
1547  return const_value (args, val);
1548 }
1549 
1550 DEFUNX ("O_CREAT", FO_CREAT, args, ,
1551  doc: /* -*- texinfo -*-
1552 @deftypefn {} {@var{v} =} O_CREAT ()
1553 Return the numerical value of the @code{O_CREAT}.
1554 
1555 @code{O_CREAT} is the file status flag that may be returned by
1556 @code{fcntl} to indicate that a file should be created if it does not
1557 exist.
1558 @seealso{fcntl, O_APPEND, O_ASYNC, O_EXCL, O_NONBLOCK, O_RDONLY, O_RDWR, O_SYNC,
1559 O_TRUNC, O_WRONLY}
1560 @end deftypefn */)
1561 {
1562  static const int val = octave_o_creat_wrapper ();
1563 
1564  if (val < 0)
1565  err_disabled_feature ("O_CREAT", "O_CREAT");
1566 
1567  return const_value (args, val);
1568 }
1569 
1570 DEFUNX ("O_EXCL", FO_EXCL, args, ,
1571  doc: /* -*- texinfo -*-
1572 @deftypefn {} {@var{v} =} O_EXCL ()
1573 Return the numerical value of the @code{O_EXCL}.
1574 
1575 @code{O_EXCL} is the file status flag that may be returned by
1576 @code{fcntl} to indicate that file locking is used.
1577 @seealso{fcntl, O_APPEND, O_ASYNC, O_CREAT, O_NONBLOCK, O_RDONLY, O_RDWR,
1578 O_SYNC, O_TRUNC, O_WRONLY}
1579 @end deftypefn */)
1580 {
1581  static const int val = octave_o_excl_wrapper ();
1582 
1583  if (val < 0)
1584  err_disabled_feature ("O_EXCL", "O_EXCL");
1585 
1586  return const_value (args, val);
1587 }
1588 
1589 DEFUNX ("O_NONBLOCK", FO_NONBLOCK, args, ,
1590  doc: /* -*- texinfo -*-
1591 @deftypefn {} {@var{v} =} O_NONBLOCK ()
1592 Return the numerical value of the @code{O_NONBLOCK}.
1593 
1594 @code{O_NONBLOCK} is the file status flag that may be returned by
1595 @code{fcntl} to indicate that non-blocking I/O is in use, or that may be
1596 passsed to @code{fcntl} to set non-blocking I/O.
1597 @seealso{fcntl, O_APPEND, O_ASYNC, O_CREAT, O_EXCL, O_RDONLY, O_RDWR, O_SYNC,
1598 O_TRUNC, O_WRONLY}
1599 @end deftypefn */)
1600 {
1601  static const int val = octave_o_nonblock_wrapper ();
1602 
1603  if (val < 0)
1604  err_disabled_feature ("O_NONBLOCK", "O_NONBLOCK");
1605 
1606  return const_value (args, val);
1607 }
1608 
1609 DEFUNX ("O_RDONLY", FO_RDONLY, args, ,
1610  doc: /* -*- texinfo -*-
1611 @deftypefn {} {@var{v} =} O_RDONLY ()
1612 Return the numerical value of the @code{O_RDONLY}.
1613 
1614 @code{O_RDONLY} is the file status flag that may be returned by
1615 @code{fcntl} to indicate that a file is open for reading only.
1616 @seealso{fcntl, O_APPEND, O_ASYNC, O_CREAT, O_EXCL, O_NONBLOCK, O_RDWR, O_SYNC,
1617 O_TRUNC, O_WRONLY}
1618 @end deftypefn */)
1619 {
1620  static const int val = octave_o_rdonly_wrapper ();
1621 
1622  if (val < 0)
1623  err_disabled_feature ("O_RDONLY", "O_RDONLY");
1624 
1625  return const_value (args, val);
1626 }
1627 
1628 DEFUNX ("O_RDWR", FO_RDWR, args, ,
1629  doc: /* -*- texinfo -*-
1630 @deftypefn {} {@var{v} =} O_RDWR ()
1631 Return the numerical value of the @code{O_RDWR}.
1632 
1633 @code{O_RDWR} is the file status flag that may be returned by
1634 @code{fcntl} to indicate that a file is open for both reading and
1635 writing.
1636 @seealso{fcntl, O_APPEND, O_ASYNC, O_CREAT, O_EXCL, O_NONBLOCK, O_RDONLY,
1637 O_SYNC, O_TRUNC, O_WRONLY}
1638 @end deftypefn */)
1639 {
1640  static const int val = octave_o_rdwr_wrapper ();
1641 
1642  if (val < 0)
1643  err_disabled_feature ("O_RDWR", "O_RDWR");
1644 
1645  return const_value (args, val);
1646 }
1647 
1648 DEFUNX ("O_SYNC", FO_SYNC, args, ,
1649  doc: /* -*- texinfo -*-
1650 @deftypefn {} {@var{v} =} O_SYNC ()
1651 Return the numerical value of the @code{O_SYNC}.
1652 
1653 @code{O_SYNC} is the file status flag that may be returned by
1654 @code{fcntl} to indicate that a file is open for synchronous I/O
1655 @seealso{fcntl, O_APPEND, O_ASYNC, O_CREAT, O_EXCL, O_NONBLOCK, O_RDONLY,
1656 O_RDWR, O_TRUNC, O_WRONLY}
1657 @end deftypefn */)
1658 {
1659  static const int val = octave_o_sync_wrapper ();
1660 
1661  if (val < 0)
1662  err_disabled_feature ("O_SYNC", "O_SYNC");
1663 
1664  return const_value (args, val);
1665 }
1666 
1667 DEFUNX ("O_TRUNC", FO_TRUNC, args, ,
1668  doc: /* -*- texinfo -*-
1669 @deftypefn {} {@var{v} =} O_TRUNC ()
1670 Return the numerical value of the @code{O_TRUNC}.
1671 
1672 @code{O_TRUNC} is the file status flag that may be returned by
1673 @code{fcntl} to indicate that if file exists, it should be truncated
1674 when writing.
1675 @seealso{fcntl, O_APPEND, O_ASYNC, O_CREAT, O_EXCL, O_NONBLOCK, O_RDONLY,
1676 O_RDWR, O_SYNC, O_WRONLY}
1677 @end deftypefn */)
1678 {
1679  static const int val = octave_o_trunc_wrapper ();
1680 
1681  if (val < 0)
1682  err_disabled_feature ("O_TRUNC", "O_TRUNC");
1683 
1684  return const_value (args, val);
1685 }
1686 
1687 DEFUNX ("O_WRONLY", FO_WRONLY, args, ,
1688  doc: /* -*- texinfo -*-
1689 @deftypefn {} {@var{v} =} O_WRONLY ()
1690 Return the numerical value of the @code{O_WRONLY}.
1691 
1692 @code{O_WRONLY} is the file status flag that may be returned by
1693 @code{fcntl} to indicate that a file is open for writing only
1694 @seealso{fcntl, O_APPEND, O_ASYNC, O_CREAT, O_EXCL, O_NONBLOCK, O_RDONLY,
1695 O_RDWR, O_SYNC, O_TRUNC}
1696 @end deftypefn */)
1697 {
1698  static const int val = octave_o_wronly_wrapper ();
1699 
1700  if (val < 0)
1701  err_disabled_feature ("O_WRONLY", "O_WRONLY");
1702 
1703  return const_value (args, val);
1704 }
1705 
1706 DEFUNX ("WNOHANG", FWNOHANG, args, ,
1707  doc: /* -*- texinfo -*-
1708 @deftypefn {} {@var{v} =} WNOHANG ()
1709 Return the numerical value of the @code{WNOHANG} macro.
1710 
1711 @code{WNOHANG} is the option argument that may be passed to
1712 @code{waitpid} to indicate that it should return its status immediately
1713 instead of waiting for a process to exit.
1714 @seealso{waitpid, WUNTRACED, WCONTINUE}
1715 @end deftypefn */)
1716 {
1717  return const_value (args, sys::wnohang ());
1718 }
1719 
1720 DEFUNX ("WUNTRACED", FWUNTRACED, args, ,
1721  doc: /* -*- texinfo -*-
1722 @deftypefn {} {@var{v} =} WUNTRACED ()
1723 Return the numerical value of the @code{WUNTRACED} macro.
1724 
1725 @code{WUNTRACED} is the option argument that may be passed to
1726 @code{waitpid} to indicate that it should also return if the child
1727 process has stopped but is not traced via the @code{ptrace} system call
1728 @seealso{waitpid, WNOHANG, WCONTINUE}
1729 @end deftypefn */)
1730 {
1731  return const_value (args, sys::wuntraced ());
1732 }
1733 
1734 DEFUNX ("WCONTINUE", FWCONTINUE, args, ,
1735  doc: /* -*- texinfo -*-
1736 @deftypefn {} {@var{v} =} WCONTINUE ()
1737 Return the numerical value of the @code{WCONTINUE} macro.
1738 
1739 @code{WCONTINUE} is the option argument that may be passed to
1740 @code{waitpid} to indicate that it should also return if a stopped child
1741 has been resumed by delivery of a @code{SIGCONT} signal.
1742 @seealso{waitpid, WNOHANG, WUNTRACED}
1743 @end deftypefn */)
1744 {
1745  return const_value (args, sys::wcontinue ());
1746 }
1747 
1748 OCTAVE_END_NAMESPACE(octave)
#define NaN
Definition: Faddeeva.cc:261
octave_value_list FO_NONBLOCK(const octave_value_list &=octave_value_list(), int=0)
octave_value_list FO_ASYNC(const octave_value_list &=octave_value_list(), int=0)
octave_value_list FO_EXCL(const octave_value_list &=octave_value_list(), int=0)
octave_value_list Fgetuid(const octave_value_list &=octave_value_list(), int=0)
octave_value_list Fpipe(octave::interpreter &, const octave_value_list &=octave_value_list(), int=0)
octave_value_list FF_SETFD(const octave_value_list &=octave_value_list(), int=0)
octave_value_list Fgetppid(const octave_value_list &=octave_value_list(), int=0)
octave_value_list FWCONTINUE(const octave_value_list &=octave_value_list(), int=0)
octave_value_list FWCOREDUMP(const octave_value_list &=octave_value_list(), int=0)
octave_value_list Fdup2(octave::interpreter &, const octave_value_list &=octave_value_list(), int=0)
octave_value_list FWTERMSIG(const octave_value_list &=octave_value_list(), int=0)
octave_value_list FF_DUPFD(const octave_value_list &=octave_value_list(), int=0)
octave_value_list Fgetpgrp(const octave_value_list &=octave_value_list(), int=0)
octave_value_list FWIFCONTINUED(const octave_value_list &=octave_value_list(), int=0)
octave_value_list Fmkfifo(const octave_value_list &=octave_value_list(), int=0)
octave_value_list Fpopen2(octave::interpreter &, const octave_value_list &=octave_value_list(), int=0)
octave_value_list Flstat(const octave_value_list &=octave_value_list(), int=0)
octave_value_list Fkill(const octave_value_list &=octave_value_list(), int=0)
octave_value_list FO_TRUNC(const octave_value_list &=octave_value_list(), int=0)
octave_value_list Fwaitpid(const octave_value_list &=octave_value_list(), int=0)
octave_value_list Fgetgid(const octave_value_list &=octave_value_list(), int=0)
octave_value_list FS_ISSOCK(const octave_value_list &=octave_value_list(), int=0)
octave_value_list FO_RDONLY(const octave_value_list &=octave_value_list(), int=0)
octave_value_list FO_APPEND(const octave_value_list &=octave_value_list(), int=0)
octave_value_list FWIFSIGNALED(const octave_value_list &=octave_value_list(), int=0)
octave_value_list FO_WRONLY(const octave_value_list &=octave_value_list(), int=0)
octave_value_list Fstat(octave::interpreter &, const octave_value_list &=octave_value_list(), int=0)
octave_value_list FS_ISFIFO(const octave_value_list &=octave_value_list(), int=0)
octave_value_list Funlink(octave::interpreter &, const octave_value_list &=octave_value_list(), int=0)
octave_value_list Fgetpid(const octave_value_list &=octave_value_list(), int=0)
octave_value_list FF_SETFL(const octave_value_list &=octave_value_list(), int=0)
octave_value_list FS_ISBLK(const octave_value_list &=octave_value_list(), int=0)
octave_value_list FWIFSTOPPED(const octave_value_list &=octave_value_list(), int=0)
octave_value_list Ffork(octave::interpreter &, const octave_value_list &=octave_value_list(), int=0)
octave_value_list FO_RDWR(const octave_value_list &=octave_value_list(), int=0)
octave_value_list FS_ISDIR(const octave_value_list &=octave_value_list(), int=0)
octave_value_list Fexec(octave::interpreter &, const octave_value_list &=octave_value_list(), int=0)
octave_value_list FWNOHANG(const octave_value_list &=octave_value_list(), int=0)
octave_value_list FWIFEXITED(const octave_value_list &=octave_value_list(), int=0)
octave_value_list FS_ISLNK(const octave_value_list &=octave_value_list(), int=0)
octave_value_list Fgeteuid(const octave_value_list &=octave_value_list(), int=0)
octave_value_list FS_ISREG(const octave_value_list &=octave_value_list(), int=0)
octave_value_list FF_GETFD(const octave_value_list &=octave_value_list(), int=0)
octave_value_list Ffcntl(octave::interpreter &, const octave_value_list &=octave_value_list(), int=0)
octave_value_list FS_ISCHR(const octave_value_list &=octave_value_list(), int=0)
octave_value_list FO_SYNC(const octave_value_list &=octave_value_list(), int=0)
octave_value_list Fcanonicalize_file_name(const octave_value_list &=octave_value_list(), int=0)
octave_value_list FWSTOPSIG(const octave_value_list &=octave_value_list(), int=0)
octave_value_list FWUNTRACED(const octave_value_list &=octave_value_list(), int=0)
octave_value_list Fgetegid(const octave_value_list &=octave_value_list(), int=0)
octave_value_list FF_GETFL(const octave_value_list &=octave_value_list(), int=0)
octave_value_list FO_CREAT(const octave_value_list &=octave_value_list(), int=0)
octave_value_list FWEXITSTATUS(const octave_value_list &=octave_value_list(), int=0)
Definition: dMatrix.h:42
static bool ignoring_entries()
Definition: cmd-hist.cc:611
static void clean_up_and_save(const std::string &="", int=-1)
Definition: cmd-hist.cc:769
Provides threadsafe access to octave.
void file_renamed(bool load_new)
void file_remove(const std::string &old_name, const std::string &new_name)
void write_timestamp()
Definition: oct-hist.cc:281
octave_idx_type length() const
Definition: ovl.h:113
static stream create(const std::string &n, FILE *f=nullptr, std::ios::openmode m=std::ios::in|std::ios::out, mach_info::float_format ff=mach_info::native_float_format(), const std::string &encoding="utf-8", c_file_ptr_buf::close_fcn cf=c_file_ptr_buf::file_close)
Definition: oct-stdstrm.h:137
int insert(stream &os)
Definition: oct-stream.cc:7413
int get_file_number(const octave_value &fid) const
Definition: oct-stream.cc:7676
stream lookup(int fid, const std::string &who="") const
Definition: oct-stream.cc:7454
int file_number()
Definition: oct-stream.h:427
void resize(octave_idx_type n, const std::string &rfv="")
Definition: str-vec.h:95
octave_idx_type numel() const
Definition: str-vec.h:100
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
void print_usage(void)
Definition: defun-int.h:72
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
Definition: defun.h:56
#define DEFUNX(name, fname, args_name, nargout_name, doc)
Macro to define a builtin function with certain internal name.
Definition: defun.h:85
void() error(const char *fmt,...)
Definition: error.cc:988
void err_disabled_feature(const std::string &fcn, const std::string &feature, const std::string &pkg)
Definition: errwarn.cc:53
int octave_o_trunc_wrapper(void)
int octave_f_dupfd_wrapper(void)
int octave_o_wronly_wrapper(void)
int octave_o_creat_wrapper(void)
int octave_o_append_wrapper(void)
int octave_o_sync_wrapper(void)
int octave_o_nonblock_wrapper(void)
int octave_o_excl_wrapper(void)
int octave_f_getfd_wrapper(void)
int octave_o_rdonly_wrapper(void)
int octave_f_setfd_wrapper(void)
int octave_o_rdwr_wrapper(void)
int octave_f_setfl_wrapper(void)
int octave_o_async_wrapper(void)
int octave_f_getfl_wrapper(void)
F77_RET_T const F77_DBLE * x
T octave_idx_type m
Definition: mx-inlines.cc:781
std::string canonicalize_file_name(const std::string &name)
Definition: file-ops.cc:798
int mkfifo(const std::string &nm, mode_t md)
Definition: file-ops.cc:488
int unlink(const std::string &name)
Definition: file-ops.cc:727
bool wifexited(int status)
int pipe(int *fildes)
pid_t fork(std::string &msg)
Definition: oct-syscalls.cc:99
int execvp(const std::string &file, const string_vector &argv)
Definition: oct-syscalls.cc:74
int wstopsig(int status)
int kill(pid_t pid, int sig)
pid_t getppid()
int wexitstatus(int status)
pid_t getpgrp(std::string &msg)
pid_t waitpid(pid_t pid, int *status, int options)
bool wifstopped(int status)
bool wifcontinued(int status)
bool wifsignaled(int status)
gid_t getegid()
int wtermsig(int status)
int wuntraced()
uid_t getuid()
gid_t getgid()
int wnohang()
int wcoredump(int status)
int fcntl(int fd, int cmd, long arg)
pid_t getpid()
uid_t geteuid()
pid_t popen2(const std::string &cmd, const string_vector &args, bool sync_mode, int *fildes)
int dup2(int old_fd, int new_fd)
Definition: oct-syscalls.cc:52
int wcontinue()
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
Definition: ovl.h:219
DEFMETHODX("quad", Fquad, interp, args,, doc:)
Definition: quad.cc:136
F77_RET_T len
Definition: xerbla.cc:61