comparison src/syscalls.cc @ 2075:ad74682dc97e

[project @ 1996-04-23 23:59:15 by jwe] Initial revision
author jwe
date Tue, 23 Apr 1996 23:59:15 +0000
parents
children 4d43f960f2cc
comparison
equal deleted inserted replaced
2074:ffff1fea99df 2075:ad74682dc97e
1 /*
2
3 Copyright (C) 1996 John W. Eaton
4
5 This file is part of Octave.
6
7 Octave is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
10 later version.
11
12 Octave is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20
21 */
22
23 // Thomas Baier <baier@ci.tuwien.ac.at> added the original versions of
24 // the following functions:
25 //
26 // mkfifo unlink waitpid
27
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31
32 #include <cstdio>
33
34 #ifdef HAVE_UNISTD_H
35 #include <sys/types.h>
36 #include <unistd.h>
37 #endif
38
39 #ifdef HAVE_FCNTL_H
40 #include <fcntl.h>
41 #endif
42
43 #include "defun.h"
44 #include "error.h"
45 #include "file-ops.h"
46 #include "help.h"
47 #include "lo-utils.h"
48 #include "oct-map.h"
49 #include "oct-obj.h"
50 #include "oct-stdstrm.h"
51 #include "oct-stream.h"
52 #include "sysdep.h"
53 #include "syswait.h"
54 #include "utils.h"
55
56 static Octave_map
57 mk_stat_map (const file_stat& fs)
58 {
59 Octave_map m;
60
61 m["dev"] = (double) fs.dev ();
62 m["ino"] = (double) fs.ino ();
63 m["modestr"] = fs.mode_as_string ();
64 m["nlink"] = (double) fs.nlink ();
65 m["uid"] = (double) fs.uid ();
66 m["gid"] = (double) fs.gid ();
67 #if defined (HAVE_ST_RDEV)
68 m["rdev"] = (double) fs.rdev ();
69 #endif
70 m["size"] = (double) fs.size ();
71 m["atime"] = (double) fs.atime ();
72 m["mtime"] = (double) fs.mtime ();
73 m["ctime"] = (double) fs.ctime ();
74 #if defined (HAVE_ST_BLKSIZE)
75 m["blksize"] = (double) fs.blksize ();
76 #endif
77 #if defined (HAVE_ST_BLOCKS)
78 m["blocks"] = (double) fs.blocks ();
79 #endif
80
81 return m;
82 }
83
84 static void
85 gripe_not_supported (const char *fcn)
86 {
87 error ("%s: not supported on this system", fcn);
88 }
89
90 DEFUN(dup2, args, ,
91 "fid = dup2 (old, new)")
92 {
93 double retval = -1.0;
94
95 #if defined (HAVE_DUP2)
96 int nargin = args.length ();
97
98 if (nargin == 2)
99 {
100 double d_old = args(0).double_value ();
101 double d_new = args(1).double_value ();
102
103 if (! error_state)
104 {
105 if (D_NINT (d_old) == d_old && D_NINT (d_new) == d_new)
106 {
107 int i_old = NINT (d_old);
108 int i_new = NINT (d_new);
109
110 // XXX FIXME XXX -- are these checks sufficient?
111 if (i_old >= 0 && i_new >= 0)
112 retval = (double) dup2 (i_old, i_new);
113 else
114 error ("dup2: invalid file id");
115 }
116 else
117 error ("dup2: arguments must be integer values");
118 }
119 }
120 else
121 print_usage ("dup2");
122 #else
123 gripe_not_supported ("dup2");
124 #endif
125
126 return retval;
127 }
128
129 DEFUN(exec, args, ,
130 "exec (file, args)")
131 {
132 double retval = -1.0;
133
134 #if defined (HAVE_EXECVP)
135 int nargin = args.length ();
136
137 if (nargin == 1 || nargin == 2)
138 {
139 string exec_file = args(0).string_value ();
140
141 if (! error_state)
142 {
143 char **exec_args = 0;
144
145 if (nargin == 2)
146 {
147 charMatrix chm = args(1).all_strings ();
148
149 if (! error_state)
150 {
151 int nr = chm.rows ();
152 int nc = chm.cols ();
153
154 exec_args = new char * [nr+2];
155
156 // XXX FIXME XXX -- potential leak?
157
158 exec_args[0] = strsave (exec_file.c_str ());
159 exec_args[nr+1] = 0;
160
161 for (int i = 0; i < nr; i++)
162 {
163 exec_args[i+1] = new char [nc+1];
164
165 for (int j = 0; j < nc; j++)
166 exec_args[i+1][j] = chm.elem (i, j);
167
168 exec_args[i+1][nc] = '\0';
169 }
170 }
171 else
172 error ("exec: arguments must be strings");
173 }
174 else
175 {
176 exec_args = new char * [2];
177
178 exec_args[0] = strsave (exec_file.c_str ());
179 exec_args[1] = 0;
180 }
181
182 if (! error_state)
183 execvp (exec_file.c_str (), exec_args);
184 }
185 else
186 error ("exec: first argument must be a string");
187 }
188 else
189 print_usage ("exec");
190 #else
191 gripe_not_supported ("exec");
192 #endif
193
194 return retval;
195 }
196
197 DEFUN(fcntl, args, ,
198 "fcntl (fid, request, argument)")
199 {
200 double retval = -1.0;
201
202 #if defined (HAVE_FCNTL)
203 int nargin = args.length ();
204
205 if (nargin == 3)
206 {
207 double d_fid = args(0).double_value ();
208 double d_req = args(1).double_value ();
209 double d_arg = args(2).double_value ();
210
211 if (! error_state
212 && D_NINT (d_fid) == d_fid
213 && D_NINT (d_req) == d_req
214 && D_NINT (d_arg) == d_arg)
215 {
216 int fid = NINT (d_fid);
217 int req = NINT (d_req);
218 int arg = NINT (d_arg);
219
220 // XXX FIXME XXX -- Need better checking here?
221 if (fid < 0)
222 error ("fcntl: invalid file id");
223 else
224 retval = fcntl (fid, req, arg);
225 }
226 else
227 error ("fcntl: file id must be an integer");
228 }
229 else
230 print_usage ("fcntl");
231 #else
232 gripe_not_supported ("fcntl");
233 #endif
234
235 return retval;
236 }
237
238 DEFUN(fork, args, ,
239 "fork (): create a copy of the current process")
240 {
241 double retval = -1.0;
242
243 #if defined (HAVE_FORK)
244 int nargin = args.length ();
245
246 if (nargin == 0)
247 retval = fork ();
248 else
249 print_usage ("fork");
250 #else
251 gripe_not_supported ("fork");
252 #endif
253
254 return retval;
255 }
256
257 DEFUN(getpgrp, args, ,
258 "pgid = getpgrp (): return the process group id of the current process")
259 {
260 double retval = -1.0;
261
262 #if defined (HAVE_GETPGRP)
263 int nargin = args.length ();
264
265 if (nargin == 0)
266 retval = getpgrp ();
267 else
268 print_usage ("getpgrp");
269 #else
270 gripe_not_supported ("getpgrp");
271 #endif
272
273 return retval;
274 }
275
276 DEFUN(getpid, args, ,
277 "pid = getpid (): return the process id of the current process")
278 {
279 double retval = -1.0;
280
281 #if defined (HAVE_GETPID)
282 int nargin = args.length ();
283
284 if (nargin == 0)
285 retval = getpid ();
286 else
287 print_usage ("getpid");
288 #else
289 gripe_not_supported ("getpid");
290 #endif
291
292 return retval;
293 }
294
295 DEFUN(getppid, args, ,
296 "pid = getppid (): return the process id of the parent process")
297 {
298 double retval = -1.0;
299
300 #if defined (HAVE_GETPPID)
301 int nargin = args.length ();
302
303 if (nargin == 0)
304 retval = getppid ();
305 else
306 print_usage ("getppid");
307 #else
308 gripe_not_supported ("getppid");
309 #endif
310
311 return retval;
312 }
313
314 DEFUN (lstat, args, ,
315 "lstat (NAME)\n\
316 \n\
317 Like stat (NAME), but if NAME refers to a symbolic link, returns\n\
318 information about the link itself, not the file that it points to.")
319 {
320 tree_constant retval = -1.0;
321
322 if (args.length () == 1)
323 {
324 string fname = oct_tilde_expand (args(0).string_value ());
325
326 if (! error_state)
327 {
328 file_stat fs (fname, false);
329
330 if (fs)
331 retval = tree_constant (mk_stat_map (fs));
332 }
333 }
334 else
335 print_usage ("lstat");
336
337 return retval;
338 }
339
340 DEFUN (mkfifo, args, ,
341 "STATUS = mkfifo (NAME, MODE)\n\
342 \n\
343 Create a FIFO special file named NAME with file mode MODE\n\
344 \n\
345 STATUS is:\n\
346 \n\
347 != 0 : if mkfifo failed\n\
348 0 : if the FIFO special file could be created")
349 {
350 double retval = -1.0;
351
352 int nargin = args.length ();
353
354 if (nargin == 2)
355 {
356 if (args(0).is_string ())
357 {
358 string name = args(0).string_value ();
359
360 if (args(1).is_scalar_type ())
361 {
362 long mode = (long) args(1).double_value ();
363
364 retval = oct_mkfifo (name, mode);
365 }
366 else
367 error ("mkfifo: MODE must be an integer");
368 }
369 else
370 error ("mkfifo: file name must be a string");
371
372 }
373 else
374 print_usage ("mkfifo");
375
376 return retval;
377 }
378
379 DEFUN (pipe, args, ,
380 "[file_ids, status] = pipe ()")
381 {
382 Octave_object retval (2, tree_constant (-1.0));
383
384 #if defined (HAVE_PIPE)
385 int nargin = args.length ();
386
387 if (nargin == 0)
388 {
389 int fid[2];
390
391 if (pipe (fid) >= 0)
392 {
393 FILE *in_file = fdopen (fid[0], "r");
394 FILE *out_file = fdopen (fid[1], "w");
395
396 octave_istdiostream *is
397 = new octave_istdiostream (string (), in_file);
398
399 octave_ostdiostream *os
400 = new octave_ostdiostream (string (), out_file);
401
402 Matrix file_ids (1, 2);
403
404 file_ids.elem (0, 0) = octave_stream_list::insert (is);
405 file_ids.elem (0, 1) = octave_stream_list::insert (os);
406
407 retval(0) = file_ids;
408 retval(1) = 0.0;
409 }
410 }
411 else
412 print_usage ("pipe");
413 #else
414 gripe_not_supported ("pipe");
415 #endif
416
417 return retval;
418 }
419
420 DEFUN (stat, args, ,
421 "stat (NAME)\n\
422 \n\
423 Given the name of a file, return a structure with the following
424 elements:\n\
425 \n\
426 dev : id of device containing a directory entry for this file\n\
427 ino : file number of the file\n\
428 modestr : file mode, as a string of ten letters or dashes as in ls -l\n\
429 nlink : number of links\n\
430 uid : user id of file's owner\n\
431 gid : group id of file's group \n\
432 rdev : id of device for block or character special files\n\
433 size : size in bytes\n\
434 atime : time of last access\n\
435 mtime : time of last modification\n\
436 ctime : time of last file status change\n\
437 blksize : size of blocks in the file\n\
438 blocks : number of blocks allocated for file\n\
439 \n\
440 If the file does not exist, -1 is returned.")
441 {
442 tree_constant retval = -1.0;
443
444 if (args.length () == 1)
445 {
446 string fname = oct_tilde_expand (args(0).string_value ());
447
448 if (! error_state)
449 {
450 file_stat fs (fname);
451
452 if (fs)
453 retval = tree_constant (mk_stat_map (fs));
454 }
455 }
456 else
457 print_usage ("stat");
458
459 return retval;
460 }
461
462 DEFUN (unlink, args, ,
463 "STATUS = unlink (NAME)\n\
464 \n\
465 Delete the file NAME\n\
466 \n\
467 STATUS is:\n\
468 \n\
469 != 0 : if unlink failed\n\
470 0 : if the file could be successfully deleted")
471 {
472 double retval = -1.0;
473
474 int nargin = args.length ();
475
476 if (nargin == 1)
477 {
478 if (args(0).is_string ())
479 {
480 string name = args(0).string_value ();
481
482 retval = oct_unlink (name);
483 }
484 else
485 error ("unlink: file name must be a string");
486 }
487 else
488 print_usage ("unlink");
489
490 return retval;
491 }
492
493 DEFUN (waitpid, args, ,
494 "STATUS = waitpid (PID, OPTIONS)\n\
495 \n\
496 wait for process PID to terminate\n\
497 \n\
498 PID can be:\n\
499 \n\
500 -1 : wait for any child process\n\
501 0 : wait for any child process whose process group ID is equal to\n\
502 that of the Octave interpreter process.\n\
503 > 0 : wait for termination of the child process with ID PID.\n\
504 \n\
505 OPTIONS is:\n\
506 \n\
507 0 : wait until signal is received or a child process exits (this\n\
508 is the default if the OPTIONS argument is missing) \n\
509 1 : do not hang if status is not immediately available\n\
510 2 : report the status of any child processes that are\n\
511 stopped, and whose status has not yet been reported\n\
512 since they stopped\n\
513 3 : implies both 1 and 2\n\
514 \n\
515 STATUS is:\n\
516 \n\
517 -1 : if an error occured\n\
518 > 0 : the process ID of the child process that exited")
519 {
520 double retval = -1.0;
521
522 #if defined (HAVE_WAITPID)
523 int nargin = args.length ();
524
525 if (nargin == 1 || nargin == 2)
526 {
527 double pid_num = args(0).double_value ();
528
529 if (! error_state)
530 {
531 if (D_NINT (pid_num) != pid_num)
532 error ("waitpid: PID must be an integer value");
533 else
534 {
535 pid_t pid = (pid_t) pid_num;
536
537 int options = 0;
538
539 if (args.length () == 2)
540 {
541 double options_num = args(1).double_value ();
542
543 if (! error_state)
544 {
545 if (D_NINT (options_num) != options_num)
546 error ("waitpid: PID must be an integer value");
547 else
548 {
549 options = NINT (options_num);
550 if (options < 0 || options > 3)
551 error ("waitpid: invalid OPTIONS value specified");
552 }
553 }
554 }
555
556 if (! error_state)
557 retval = waitpid (pid, 0, options);
558 }
559 }
560 }
561 else
562 print_usage ("waitpid");
563 #else
564 gripe_not_supported ("waitpid");
565 #endif
566
567 return retval;
568 }
569
570 #if !defined (O_NONBLOCK) && defined (O_NDELAY)
571 #define O_NONBLOCK O_NDELAY
572 #endif
573
574 void
575 symbols_of_syscalls (void)
576 {
577 #if defined (F_DUPFD)
578 DEFCONST (F_DUPFD, (double) F_DUPFD, 0, 0,
579 "");
580 #endif
581
582 #if defined (F_GETFD)
583 DEFCONST (F_GETFD, (double) F_GETFD, 0, 0,
584 "");
585 #endif
586
587 #if defined (F_GETFL)
588 DEFCONST (F_GETFL, (double) F_GETFL, 0, 0,
589 "");
590 #endif
591
592 #if defined (F_SETFD)
593 DEFCONST (F_SETFD, (double) F_SETFD, 0, 0,
594 "");
595 #endif
596
597 #if defined (F_SETFL)
598 DEFCONST (F_SETFL, (double) F_SETFL, 0, 0,
599 "");
600 #endif
601
602 #if defined (O_APPEND)
603 DEFCONST (O_APPEND, (double) O_APPEND, 0, 0,
604 "");
605 #endif
606
607 #if defined (O_CREAT)
608 DEFCONST (O_CREAT, (double) O_CREAT, 0, 0,
609 "");
610 #endif
611
612 #if defined (O_EXCL)
613 DEFCONST (O_EXCL, (double) O_EXCL, 0, 0,
614 "");
615 #endif
616
617 #if defined (O_NONBLOCK)
618 DEFCONST (O_NONBLOCK, (double) O_NONBLOCK, 0, 0,
619 "");
620 #endif
621
622 #if defined (O_RDONLY)
623 DEFCONST (O_RDONLY, (double) O_RDONLY, 0, 0,
624 "");
625 #endif
626
627 #if defined (O_RDWR)
628 DEFCONST (O_RDWR, (double) O_RDWR, 0, 0,
629 "");
630 #endif
631
632 #if defined (O_TRUNC)
633 DEFCONST (O_TRUNC, (double) O_TRUNC, 0, 0,
634 "");
635 #endif
636
637 #if defined (O_WRONLY)
638 DEFCONST (O_WRONLY, (double) O_WRONLY, 0, 0,
639 "");
640 #endif
641 }
642
643 /*
644 ;;; Local Variables: ***
645 ;;; mode: C++ ***
646 ;;; End: ***
647 */