Mercurial > hg > octave-nkf
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 */ |