2847
|
1 ## Copyright (C) 1996, 1997 John W. Eaton |
2313
|
2 ## |
|
3 ## This file is part of Octave. |
|
4 ## |
|
5 ## Octave is free software; you can redistribute it and/or modify it |
|
6 ## under the terms of the GNU General Public License as published by |
|
7 ## the Free Software Foundation; either version 2, or (at your option) |
|
8 ## any later version. |
|
9 ## |
|
10 ## Octave is distributed in the hope that it will be useful, but |
|
11 ## WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
13 ## General Public License for more details. |
|
14 ## |
|
15 ## You should have received a copy of the GNU General Public License |
|
16 ## along with Octave; see the file COPYING. If not, write to the Free |
5307
|
17 ## Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
|
18 ## 02110-1301, USA. |
2079
|
19 |
3301
|
20 ## -*- texinfo -*- |
3302
|
21 ## @deftypefn {Function File} {[@var{in}, @var{out}, @var{pid}] =} popen2 (@var{command}, @var{args}) |
3301
|
22 ## Start a subprocess with two-way communication. The name of the process |
|
23 ## is given by @var{command}, and @var{args} is an array of strings |
|
24 ## containing options for the command. The file identifiers for the input |
|
25 ## and output streams of the subprocess are returned in @var{in} and |
|
26 ## @var{out}. If execution of the command is successful, @var{pid} |
|
27 ## contains the process ID of the subprocess. Otherwise, @var{pid} is |
|
28 ## @minus{}1. |
3426
|
29 ## |
3301
|
30 ## For example, |
3426
|
31 ## |
3301
|
32 ## @example |
|
33 ## @group |
|
34 ## [in, out, pid] = popen2 ("sort", "-nr"); |
|
35 ## fputs (in, "these\nare\nsome\nstrings\n"); |
|
36 ## fclose (in); |
5465
|
37 ## EAGAIN = errno ("EAGAIN"); |
|
38 ## done = false; |
|
39 ## do |
|
40 ## s = fgets (out); |
|
41 ## if (ischar (s)) |
|
42 ## fputs (stdout, s); |
|
43 ## elseif (errno () == EAGAIN) |
|
44 ## sleep (0.1); |
|
45 ## fclear (out); |
|
46 ## else |
|
47 ## done = true; |
|
48 ## endif |
|
49 ## until (done) |
3301
|
50 ## fclose (out); |
|
51 ## @print{} are |
|
52 ## @print{} some |
|
53 ## @print{} strings |
|
54 ## @print{} these |
|
55 ## @end group |
|
56 ## @end example |
|
57 ## @end deftypefn |
2079
|
58 |
2314
|
59 ## Author: jwe |
|
60 |
2311
|
61 function [in, out, pid] = popen2 (command, args) |
2079
|
62 |
|
63 in = -1; |
|
64 out = -1; |
|
65 pid = -1; |
|
66 |
|
67 if (nargin == 1 || nargin == 2) |
|
68 |
|
69 if (nargin == 1) |
|
70 args = ""; |
|
71 endif |
|
72 |
5443
|
73 if (ischar (command)) |
2079
|
74 |
|
75 [stdin_pipe, stdin_status] = pipe (); |
|
76 [stdout_pipe, stdout_status] = pipe (); |
|
77 |
|
78 if (stdin_status == 0 && stdout_status == 0) |
|
79 |
3426
|
80 pid = fork (); |
2079
|
81 |
3426
|
82 if (pid == 0) |
2079
|
83 |
5143
|
84 ## In the child. |
|
85 |
3483
|
86 fclose (nth (stdin_pipe, 2)); |
|
87 fclose (nth (stdout_pipe, 1)); |
2079
|
88 |
3483
|
89 dup2 (nth (stdin_pipe, 1), stdin); |
|
90 fclose (nth (stdin_pipe, 1)); |
2079
|
91 |
3483
|
92 dup2 (nth (stdout_pipe, 2), stdout); |
|
93 fclose (nth (stdout_pipe, 2)); |
2079
|
94 |
3426
|
95 if (exec (command, args) < 0) |
|
96 error ("popen2: unable to start process `%s'", command); |
|
97 exit (0); |
|
98 endif |
2079
|
99 |
3426
|
100 elseif (pid) |
2079
|
101 |
5143
|
102 ## In the parent. |
|
103 |
3483
|
104 fclose (nth (stdin_pipe, 1)); |
|
105 fclose (nth (stdout_pipe, 2)); |
2079
|
106 |
4013
|
107 if (fcntl (nth (stdout_pipe, 1), F_SETFL, O_NONBLOCK) < 0) |
3426
|
108 error ("popen2: error setting file mode"); |
|
109 else |
3483
|
110 in = nth (stdin_pipe, 2); |
|
111 out = nth (stdout_pipe, 1); |
3426
|
112 endif |
2079
|
113 |
3426
|
114 elseif (pid < 0) |
|
115 error ("popen2: fork failed -- unable to create child process"); |
|
116 endif |
2079
|
117 else |
3426
|
118 error ("popen2: pipe creation failed"); |
2079
|
119 endif |
|
120 else |
|
121 error ("popen2: file name must be a string"); |
|
122 endif |
|
123 else |
|
124 usage ("[in, out, pid] = popen2 (command, args)"); |
|
125 endif |
|
126 |
|
127 endfunction |