summaryrefslogtreecommitdiff
path: root/apps/plugins/pdbox/PDa/extra/shell.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/pdbox/PDa/extra/shell.c')
-rw-r--r--apps/plugins/pdbox/PDa/extra/shell.c622
1 files changed, 311 insertions, 311 deletions
diff --git a/apps/plugins/pdbox/PDa/extra/shell.c b/apps/plugins/pdbox/PDa/extra/shell.c
index dd6b0e239d..51abc134bd 100644
--- a/apps/plugins/pdbox/PDa/extra/shell.c
+++ b/apps/plugins/pdbox/PDa/extra/shell.c
@@ -1,312 +1,312 @@
1/* (C) Guenter Geiger <geiger@epy.co.at> */ 1/* (C) Guenter Geiger <geiger@epy.co.at> */
2 2
3#include "m_pd.h" 3#include "m_pd.h"
4#ifdef NT 4#ifdef NT
5#pragma warning( disable : 4244 ) 5#pragma warning( disable : 4244 )
6#pragma warning( disable : 4305 ) 6#pragma warning( disable : 4305 )
7#endif 7#endif
8 8
9#include <unistd.h> 9#include <unistd.h>
10#include <stdlib.h> 10#include <stdlib.h>
11#include <string.h> 11#include <string.h>
12#include <stdio.h> 12#include <stdio.h>
13#include <sys/types.h> 13#include <sys/types.h>
14#include <sys/wait.h> 14#include <sys/wait.h>
15#include <signal.h> 15#include <signal.h>
16#include <sched.h> 16#include <sched.h>
17 17
18void sys_rmpollfn(int fd); 18void sys_rmpollfn(int fd);
19void sys_addpollfn(int fd, void* fn, void *ptr); 19void sys_addpollfn(int fd, void* fn, void *ptr);
20 20
21/* ------------------------ shell ----------------------------- */ 21/* ------------------------ shell ----------------------------- */
22 22
23#define INBUFSIZE 1024 23#define INBUFSIZE 1024
24 24
25static t_class *shell_class; 25static t_class *shell_class;
26 26
27 27
28static void drop_priority(void) 28static void drop_priority(void)
29{ 29{
30#ifdef _POSIX_PRIORITY_SCHEDULING 30#ifdef _POSIX_PRIORITY_SCHEDULING
31 struct sched_param par; 31 struct sched_param par;
32 int p1 ,p2, p3; 32 int p1 ,p2, p3;
33 par.sched_priority = 0; 33 par.sched_priority = 0;
34 sched_setscheduler(0,SCHED_OTHER,&par); 34 sched_setscheduler(0,SCHED_OTHER,&par);
35#endif 35#endif
36} 36}
37 37
38 38
39typedef struct _shell 39typedef struct _shell
40{ 40{
41 t_object x_obj; 41 t_object x_obj;
42 int x_echo; 42 int x_echo;
43 char *sr_inbuf; 43 char *sr_inbuf;
44 int sr_inhead; 44 int sr_inhead;
45 int sr_intail; 45 int sr_intail;
46 void* x_binbuf; 46 void* x_binbuf;
47 int fdpipe[2]; 47 int fdpipe[2];
48 int fdinpipe[2]; 48 int fdinpipe[2];
49 int pid; 49 int pid;
50 int x_del; 50 int x_del;
51 t_outlet* x_done; 51 t_outlet* x_done;
52 t_clock* x_clock; 52 t_clock* x_clock;
53} t_shell; 53} t_shell;
54 54
55static int shell_pid; 55static int shell_pid;
56 56
57 57
58void shell_cleanup(t_shell* x) 58void shell_cleanup(t_shell* x)
59{ 59{
60 sys_rmpollfn(x->fdpipe[0]); 60 sys_rmpollfn(x->fdpipe[0]);
61 61
62 if (x->fdpipe[0]>0) close(x->fdpipe[0]); 62 if (x->fdpipe[0]>0) close(x->fdpipe[0]);
63 if (x->fdpipe[1]>0) close(x->fdpipe[1]); 63 if (x->fdpipe[1]>0) close(x->fdpipe[1]);
64 if (x->fdinpipe[0]>0) close(x->fdinpipe[0]); 64 if (x->fdinpipe[0]>0) close(x->fdinpipe[0]);
65 if (x->fdinpipe[1]>0) close(x->fdinpipe[1]); 65 if (x->fdinpipe[1]>0) close(x->fdinpipe[1]);
66 66
67 x->fdpipe[0] = -1; 67 x->fdpipe[0] = -1;
68 x->fdpipe[1] = -1; 68 x->fdpipe[1] = -1;
69 x->fdinpipe[0] = -1; 69 x->fdinpipe[0] = -1;
70 x->fdinpipe[1] = -1; 70 x->fdinpipe[1] = -1;
71 clock_unset(x->x_clock); 71 clock_unset(x->x_clock);
72} 72}
73 73
74void shell_check(t_shell* x) 74void shell_check(t_shell* x)
75{ 75{
76 int ret; 76 int ret;
77 int status; 77 int status;
78 ret = waitpid(x->pid,&status,WNOHANG); 78 ret = waitpid(x->pid,&status,WNOHANG);
79 if (ret == x->pid) { 79 if (ret == x->pid) {
80 shell_cleanup(x); 80 shell_cleanup(x);
81 if (WIFEXITED(status)) { 81 if (WIFEXITED(status)) {
82 outlet_float(x->x_done,WEXITSTATUS(status)); 82 outlet_float(x->x_done,WEXITSTATUS(status));
83 } 83 }
84 else outlet_float(x->x_done,0); 84 else outlet_float(x->x_done,0);
85 } 85 }
86 else { 86 else {
87 if (x->x_del < 100) x->x_del+=2; /* increment poll times */ 87 if (x->x_del < 100) x->x_del+=2; /* increment poll times */
88 clock_delay(x->x_clock,x->x_del); 88 clock_delay(x->x_clock,x->x_del);
89 } 89 }
90} 90}
91 91
92 92
93void shell_bang(t_shell *x) 93void shell_bang(t_shell *x)
94{ 94{
95 post("bang"); 95 post("bang");
96} 96}
97 97
98/* snippet from pd's code */ 98/* snippet from pd's code */
99static void shell_doit(void *z, t_binbuf *b) 99static void shell_doit(void *z, t_binbuf *b)
100{ 100{
101 t_shell *x = (t_shell *)z; 101 t_shell *x = (t_shell *)z;
102 int msg, natom = binbuf_getnatom(b); 102 int msg, natom = binbuf_getnatom(b);
103 t_atom *at = binbuf_getvec(b); 103 t_atom *at = binbuf_getvec(b);
104 104
105 for (msg = 0; msg < natom;) 105 for (msg = 0; msg < natom;)
106 { 106 {
107 int emsg; 107 int emsg;
108 for (emsg = msg; emsg < natom && at[emsg].a_type != A_COMMA 108 for (emsg = msg; emsg < natom && at[emsg].a_type != A_COMMA
109 && at[emsg].a_type != A_SEMI; emsg++) 109 && at[emsg].a_type != A_SEMI; emsg++)
110 ; 110 ;
111 if (emsg > msg) 111 if (emsg > msg)
112 { 112 {
113 int i; 113 int i;
114 for (i = msg; i < emsg; i++) 114 for (i = msg; i < emsg; i++)
115 if (at[i].a_type == A_DOLLAR || at[i].a_type == A_DOLLSYM) 115 if (at[i].a_type == A_DOLLAR || at[i].a_type == A_DOLLSYM)
116 { 116 {
117 pd_error(x, "netreceive: got dollar sign in message"); 117 pd_error(x, "netreceive: got dollar sign in message");
118 goto nodice; 118 goto nodice;
119 } 119 }
120 if (at[msg].a_type == A_FLOAT) 120 if (at[msg].a_type == A_FLOAT)
121 { 121 {
122 if (emsg > msg + 1) 122 if (emsg > msg + 1)
123 outlet_list(x->x_obj.ob_outlet, 0, emsg-msg, at + msg); 123 outlet_list(x->x_obj.ob_outlet, 0, emsg-msg, at + msg);
124 else outlet_float(x->x_obj.ob_outlet, at[msg].a_w.w_float); 124 else outlet_float(x->x_obj.ob_outlet, at[msg].a_w.w_float);
125 } 125 }
126 else if (at[msg].a_type == A_SYMBOL) 126 else if (at[msg].a_type == A_SYMBOL)
127 outlet_anything(x->x_obj.ob_outlet, at[msg].a_w.w_symbol, 127 outlet_anything(x->x_obj.ob_outlet, at[msg].a_w.w_symbol,
128 emsg-msg-1, at + msg + 1); 128 emsg-msg-1, at + msg + 1);
129 } 129 }
130 nodice: 130 nodice:
131 msg = emsg + 1; 131 msg = emsg + 1;
132 } 132 }
133} 133}
134 134
135 135
136void shell_read(t_shell *x, int fd) 136void shell_read(t_shell *x, int fd)
137{ 137{
138 char buf[INBUFSIZE]; 138 char buf[INBUFSIZE];
139 t_binbuf* bbuf = binbuf_new(); 139 t_binbuf* bbuf = binbuf_new();
140 int i; 140 int i;
141 int readto = 141 int readto =
142 (x->sr_inhead >= x->sr_intail ? INBUFSIZE : x->sr_intail-1); 142 (x->sr_inhead >= x->sr_intail ? INBUFSIZE : x->sr_intail-1);
143 int ret; 143 int ret;
144 144
145 ret = read(fd, buf,INBUFSIZE-1); 145 ret = read(fd, buf,INBUFSIZE-1);
146 buf[ret] = '\0'; 146 buf[ret] = '\0';
147 147
148 for (i=0;i<ret;i++) 148 for (i=0;i<ret;i++)
149 if (buf[i] == '\n') buf[i] = ';'; 149 if (buf[i] == '\n') buf[i] = ';';
150 if (ret < 0) 150 if (ret < 0)
151 { 151 {
152 error("shell: pipe read error"); 152 error("shell: pipe read error");
153 sys_rmpollfn(fd); 153 sys_rmpollfn(fd);
154 x->fdpipe[0] = -1; 154 x->fdpipe[0] = -1;
155 close(fd); 155 close(fd);
156 return; 156 return;
157 } 157 }
158 else if (ret == 0) 158 else if (ret == 0)
159 { 159 {
160 post("EOF on socket %d\n", fd); 160 post("EOF on socket %d\n", fd);
161 sys_rmpollfn(fd); 161 sys_rmpollfn(fd);
162 x->fdpipe[0] = -1; 162 x->fdpipe[0] = -1;
163 close(fd); 163 close(fd);
164 return; 164 return;
165 } 165 }
166 else 166 else
167 { 167 {
168 int natom; 168 int natom;
169 t_atom *at; 169 t_atom *at;
170 binbuf_text(bbuf, buf, strlen(buf)); 170 binbuf_text(bbuf, buf, strlen(buf));
171 171
172 natom = binbuf_getnatom(bbuf); 172 natom = binbuf_getnatom(bbuf);
173 at = binbuf_getvec(bbuf); 173 at = binbuf_getvec(bbuf);
174 shell_doit(x,bbuf); 174 shell_doit(x,bbuf);
175 } 175 }
176 binbuf_free(bbuf); 176 binbuf_free(bbuf);
177} 177}
178 178
179 179
180static void shell_send(t_shell *x, t_symbol *s,int ac, t_atom *at) 180static void shell_send(t_shell *x, t_symbol *s,int ac, t_atom *at)
181{ 181{
182 int i; 182 int i;
183 char tmp[MAXPDSTRING]; 183 char tmp[MAXPDSTRING];
184 int size = 0; 184 int size = 0;
185 185
186 if (x->fdinpipe[0] == -1) return; /* nothing to send to */ 186 if (x->fdinpipe[0] == -1) return; /* nothing to send to */
187 187
188 for (i=0;i<ac;i++) { 188 for (i=0;i<ac;i++) {
189 atom_string(at,tmp+size,MAXPDSTRING - size); 189 atom_string(at,tmp+size,MAXPDSTRING - size);
190 at++; 190 at++;
191 size=strlen(tmp); 191 size=strlen(tmp);
192 tmp[size++] = ' '; 192 tmp[size++] = ' ';
193 } 193 }
194 tmp[size-1] = '\0'; 194 tmp[size-1] = '\0';
195 post("sending %s",tmp); 195 post("sending %s",tmp);
196 write(x->fdinpipe[0],tmp,strlen(tmp)); 196 write(x->fdinpipe[0],tmp,strlen(tmp));
197} 197}
198 198
199static void shell_anything(t_shell *x, t_symbol *s, int ac, t_atom *at) 199static void shell_anything(t_shell *x, t_symbol *s, int ac, t_atom *at)
200{ 200{
201 int i; 201 int i;
202 char* argv[20]; 202 char* argv[20];
203 t_symbol* sym; 203 t_symbol* sym;
204 204
205 if (!strcmp(s->s_name,"send")) { 205 if (!strcmp(s->s_name,"send")) {
206 post("send"); 206 post("send");
207 shell_send(x,s,ac,at); 207 shell_send(x,s,ac,at);
208 return; 208 return;
209 } 209 }
210 210
211 argv[0] = s->s_name; 211 argv[0] = s->s_name;
212 212
213 if (x->fdpipe[0] != -1) { 213 if (x->fdpipe[0] != -1) {
214 post("shell: old process still running"); 214 post("shell: old process still running");
215 kill(x->pid,SIGKILL); 215 kill(x->pid,SIGKILL);
216 shell_cleanup(x); 216 shell_cleanup(x);
217 } 217 }
218 218
219 219
220 if (pipe(x->fdpipe) < 0) { 220 if (pipe(x->fdpipe) < 0) {
221 error("unable to create pipe"); 221 error("unable to create pipe");
222 return; 222 return;
223 } 223 }
224 224
225 if (pipe(x->fdinpipe) < 0) { 225 if (pipe(x->fdinpipe) < 0) {
226 error("unable to create input pipe"); 226 error("unable to create input pipe");
227 return; 227 return;
228 } 228 }
229 229
230 230
231 sys_addpollfn(x->fdpipe[0],shell_read,x); 231 sys_addpollfn(x->fdpipe[0],shell_read,x);
232 232
233 if (!(x->pid = fork())) { 233 if (!(x->pid = fork())) {
234 int status; 234 int status;
235 char* cmd = getbytes(1024); 235 char* cmd = getbytes(1024);
236 char* tcmd = getbytes(1024); 236 char* tcmd = getbytes(1024);
237 strcpy(cmd,s->s_name); 237 strcpy(cmd,s->s_name);
238 238
239#if 0 239#if 0
240 for (i=1;i<=ac;i++) { 240 for (i=1;i<=ac;i++) {
241 argv[i] = getbytes(255); 241 argv[i] = getbytes(255);
242 atom_string(at,argv[i],255); 242 atom_string(at,argv[i],255);
243/* post("argument %s",argv[i]); */ 243/* post("argument %s",argv[i]); */
244 at++; 244 at++;
245 } 245 }
246 argv[i] = 0; 246 argv[i] = 0;
247#endif 247#endif
248 for (i=1;i<=ac;i++) { 248 for (i=1;i<=ac;i++) {
249 atom_string(at,tcmd,255); 249 atom_string(at,tcmd,255);
250 strcat(cmd," "); 250 strcat(cmd," ");
251 strcat(cmd,tcmd); 251 strcat(cmd,tcmd);
252 at++; 252 at++;
253 } 253 }
254 254
255 255
256 /* reassign stdout */ 256 /* reassign stdout */
257 dup2(x->fdpipe[1],1); 257 dup2(x->fdpipe[1],1);
258 dup2(x->fdinpipe[1],0); 258 dup2(x->fdinpipe[1],0);
259 259
260 /* drop privileges */ 260 /* drop privileges */
261 drop_priority(); 261 drop_priority();
262 seteuid(getuid()); /* lose setuid priveliges */ 262 seteuid(getuid()); /* lose setuid priveliges */
263 263
264 post("executing %s",cmd); 264 post("executing %s",cmd);
265 system(cmd); 265 system(cmd);
266// execvp(s->s_name,argv); 266// execvp(s->s_name,argv);
267 exit(0); 267 exit(0);
268 } 268 }
269 x->x_del = 4; 269 x->x_del = 4;
270 clock_delay(x->x_clock,x->x_del); 270 clock_delay(x->x_clock,x->x_del);
271 271
272 if (x->x_echo) 272 if (x->x_echo)
273 outlet_anything(x->x_obj.ob_outlet, s, ac, at); 273 outlet_anything(x->x_obj.ob_outlet, s, ac, at);
274} 274}
275 275
276 276
277 277
278void shell_free(t_shell* x) 278void shell_free(t_shell* x)
279{ 279{
280 binbuf_free(x->x_binbuf); 280 binbuf_free(x->x_binbuf);
281} 281}
282 282
283static void *shell_new(void) 283static void *shell_new(void)
284{ 284{
285 t_shell *x = (t_shell *)pd_new(shell_class); 285 t_shell *x = (t_shell *)pd_new(shell_class);
286 286
287 x->x_echo = 0; 287 x->x_echo = 0;
288 x->fdpipe[0] = -1; 288 x->fdpipe[0] = -1;
289 x->fdpipe[1] = -1; 289 x->fdpipe[1] = -1;
290 x->fdinpipe[0] = -1; 290 x->fdinpipe[0] = -1;
291 x->fdinpipe[1] = -1; 291 x->fdinpipe[1] = -1;
292 292
293 x->sr_inhead = x->sr_intail = 0; 293 x->sr_inhead = x->sr_intail = 0;
294 if (!(x->sr_inbuf = (char*) malloc(INBUFSIZE))) bug("t_shell");; 294 if (!(x->sr_inbuf = (char*) malloc(INBUFSIZE))) bug("t_shell");;
295 295
296 x->x_binbuf = binbuf_new(); 296 x->x_binbuf = binbuf_new();
297 297
298 outlet_new(&x->x_obj, &s_list); 298 outlet_new(&x->x_obj, &s_list);
299 x->x_done = outlet_new(&x->x_obj, &s_bang); 299 x->x_done = outlet_new(&x->x_obj, &s_bang);
300 x->x_clock = clock_new(x, (t_method) shell_check); 300 x->x_clock = clock_new(x, (t_method) shell_check);
301 return (x); 301 return (x);
302} 302}
303 303
304void shell_setup(void) 304void shell_setup(void)
305{ 305{
306 shell_class = class_new(gensym("shell"), (t_newmethod)shell_new, 306 shell_class = class_new(gensym("shell"), (t_newmethod)shell_new,
307 (t_method)shell_free,sizeof(t_shell), 0,0); 307 (t_method)shell_free,sizeof(t_shell), 0,0);
308 class_addbang(shell_class,shell_bang); 308 class_addbang(shell_class,shell_bang);
309 class_addanything(shell_class, shell_anything); 309 class_addanything(shell_class, shell_anything);
310} 310}
311 311
312 312