GNU Octave  9.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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