perl 3.0 patch #3 Patch #2 continued
[p5sagit/p5-mst-13.2.git] / eval.c
CommitLineData
bf38876a 1/* $Header: eval.c,v 3.0.1.1 89/11/11 04:31:51 lwall Locked $
a687059c 2 *
3 * Copyright (c) 1989, Larry Wall
4 *
5 * You may distribute under the terms of the GNU General Public License
6 * as specified in the README file that comes with the perl 3.0 kit.
378cc40b 7 *
8 * $Log: eval.c,v $
bf38876a 9 * Revision 3.0.1.1 89/11/11 04:31:51 lwall
10 * patch2: mkdir and rmdir needed to quote argument when passed to shell
11 * patch2: mkdir and rmdir now return better error codes
12 * patch2: fileno, seekdir, rewinddir and closedir now disallow defaults
13 *
a687059c 14 * Revision 3.0 89/10/18 15:17:04 lwall
15 * 3.0 baseline
378cc40b 16 *
17 */
18
19#include "EXTERN.h"
20#include "perl.h"
21
22#include <signal.h>
23#include <errno.h>
24
a687059c 25#ifdef I_VFORK
26# include <vfork.h>
27#endif
28
378cc40b 29extern int errno;
30
31#ifdef VOIDSIG
32static void (*ihand)();
33static void (*qhand)();
34#else
35static int (*ihand)();
36static int (*qhand)();
37#endif
38
39ARG *debarg;
40STR str_args;
a687059c 41static STAB *stab2;
42static STIO *stio;
43static struct lstring *lstr;
44static char old_record_separator;
378cc40b 45
a687059c 46double sin(), cos(), atan2(), pow();
47
48char *getlogin();
49
50extern int sys_nerr;
51extern char *sys_errlist[];
52
53int
54eval(arg,gimme,sp)
378cc40b 55register ARG *arg;
a687059c 56int gimme;
57register int sp;
378cc40b 58{
59 register STR *str;
60 register int anum;
61 register int optype;
a687059c 62 register STR **st;
378cc40b 63 int maxarg;
378cc40b 64 double value;
378cc40b 65 register char *tmps;
66 char *tmps2;
67 int argflags;
68 int argtype;
69 union argptr argptr;
a687059c 70 int arglast[8]; /* highest sp for arg--valid only for non-O_LIST args */
378cc40b 71 unsigned long tmplong;
72 long when;
73 FILE *fp;
74 STR *tmpstr;
75 FCMD *form;
76 STAB *stab;
77 ARRAY *ary;
78 bool assigning = FALSE;
79 double exp(), log(), sqrt(), modf();
80 char *crypt(), *getenv();
a687059c 81 extern void grow_dlevel();
378cc40b 82
83 if (!arg)
a687059c 84 goto say_undef;
378cc40b 85 optype = arg->arg_type;
a687059c 86 maxarg = arg->arg_len;
87 arglast[0] = sp;
88 str = arg->arg_ptr.arg_str;
89 if (sp + maxarg > stack->ary_max)
90 astore(stack, sp + maxarg, Nullstr);
91 st = stack->ary_array;
92
378cc40b 93#ifdef DEBUGGING
94 if (debug) {
95 if (debug & 8) {
96 deb("%s (%lx) %d args:\n",opname[optype],arg,maxarg);
97 }
98 debname[dlevel] = opname[optype][0];
a687059c 99 debdelim[dlevel] = ':';
100 if (++dlevel >= dlmax)
101 grow_dlevel();
378cc40b 102 }
103#endif
378cc40b 104
a687059c 105#include "evalargs.xc"
106
107 st += arglast[0];
378cc40b 108 switch (optype) {
a687059c 109 case O_RCAT:
110 STABSET(str);
111 break;
378cc40b 112 case O_ITEM:
a687059c 113 if (gimme == G_ARRAY)
378cc40b 114 goto array_return;
a687059c 115 STR_SSET(str,st[1]);
378cc40b 116 STABSET(str);
117 break;
118 case O_ITEM2:
a687059c 119 if (gimme == G_ARRAY)
120 goto array_return;
121 --anum;
122 STR_SSET(str,st[arglast[anum]-arglast[0]]);
378cc40b 123 STABSET(str);
124 break;
125 case O_ITEM3:
a687059c 126 if (gimme == G_ARRAY)
127 goto array_return;
128 --anum;
129 STR_SSET(str,st[arglast[anum]-arglast[0]]);
378cc40b 130 STABSET(str);
131 break;
132 case O_CONCAT:
a687059c 133 STR_SSET(str,st[1]);
134 str_scat(str,st[2]);
378cc40b 135 STABSET(str);
136 break;
137 case O_REPEAT:
a687059c 138 STR_SSET(str,st[1]);
139 anum = (int)str_gnum(st[2]);
378cc40b 140 if (anum >= 1) {
a687059c 141 tmpstr = Str_new(50,0);
378cc40b 142 str_sset(tmpstr,str);
143 while (--anum > 0)
144 str_scat(str,tmpstr);
145 }
146 else
147 str_sset(str,&str_no);
148 STABSET(str);
149 break;
150 case O_MATCH:
a687059c 151 sp = do_match(str,arg,
152 gimme,arglast);
153 if (gimme == G_ARRAY)
378cc40b 154 goto array_return;
378cc40b 155 STABSET(str);
156 break;
157 case O_NMATCH:
a687059c 158 sp = do_match(str,arg,
159 gimme,arglast);
160 if (gimme == G_ARRAY)
161 goto array_return;
162 str_sset(str, str_true(str) ? &str_no : &str_yes);
378cc40b 163 STABSET(str);
164 break;
165 case O_SUBST:
a687059c 166 sp = do_subst(str,arg,arglast[0]);
167 goto array_return;
378cc40b 168 case O_NSUBST:
a687059c 169 sp = do_subst(str,arg,arglast[0]);
378cc40b 170 str = arg->arg_ptr.arg_str;
a687059c 171 str_set(str, str_true(str) ? No : Yes);
172 goto array_return;
378cc40b 173 case O_ASSIGN:
a687059c 174 if (arg[1].arg_flags & AF_ARYOK) {
175 if (arg->arg_len == 1) {
176 arg->arg_type = O_LOCAL;
a687059c 177 goto local;
178 }
179 else {
180 arg->arg_type = O_AASSIGN;
181 goto aassign;
182 }
183 }
378cc40b 184 else {
a687059c 185 arg->arg_type = O_SASSIGN;
186 goto sassign;
378cc40b 187 }
a687059c 188 case O_LOCAL:
189 local:
190 arglast[2] = arglast[1]; /* push a null array */
191 /* FALL THROUGH */
192 case O_AASSIGN:
193 aassign:
194 sp = do_assign(arg,
195 gimme,arglast);
196 goto array_return;
197 case O_SASSIGN:
198 sassign:
199 STR_SSET(str, st[2]);
200 STABSET(str);
378cc40b 201 break;
202 case O_CHOP:
a687059c 203 st -= arglast[0];
378cc40b 204 str = arg->arg_ptr.arg_str;
a687059c 205 for (sp = arglast[0] + 1; sp <= arglast[1]; sp++)
206 do_chop(str,st[sp]);
207 st += arglast[0];
378cc40b 208 break;
a687059c 209 case O_DEFINED:
210 if (arg[1].arg_type & A_DONT) {
211 sp = do_defined(str,arg,
212 gimme,arglast);
213 goto array_return;
214 }
215 else if (str->str_pok || str->str_nok)
216 goto say_yes;
217 goto say_no;
218 case O_UNDEF:
219 if (arg[1].arg_type & A_DONT) {
220 sp = do_undef(str,arg,
221 gimme,arglast);
222 goto array_return;
223 }
224 else if (str != stab_val(defstab)) {
225 str->str_pok = str->str_nok = 0;
226 STABSET(str);
227 }
228 goto say_undef;
378cc40b 229 case O_STUDY:
a687059c 230 sp = do_study(str,arg,
231 gimme,arglast);
232 goto array_return;
233 case O_POW:
234 value = str_gnum(st[1]);
235 value = pow(value,str_gnum(st[2]));
378cc40b 236 goto donumset;
237 case O_MULTIPLY:
a687059c 238 value = str_gnum(st[1]);
239 value *= str_gnum(st[2]);
378cc40b 240 goto donumset;
241 case O_DIVIDE:
a687059c 242 if ((value = str_gnum(st[2])) == 0.0)
378cc40b 243 fatal("Illegal division by zero");
a687059c 244 value = str_gnum(st[1]) / value;
378cc40b 245 goto donumset;
246 case O_MODULO:
a687059c 247 tmplong = (long) str_gnum(st[2]);
248 if (tmplong == 0L)
378cc40b 249 fatal("Illegal modulus zero");
a687059c 250 when = (long)str_gnum(st[1]);
251#ifndef lint
252 if (when >= 0)
253 value = (double)(when % tmplong);
254 else
255 value = (double)(tmplong - (-when % tmplong));
256#endif
378cc40b 257 goto donumset;
258 case O_ADD:
a687059c 259 value = str_gnum(st[1]);
260 value += str_gnum(st[2]);
378cc40b 261 goto donumset;
262 case O_SUBTRACT:
a687059c 263 value = str_gnum(st[1]);
264 value -= str_gnum(st[2]);
378cc40b 265 goto donumset;
266 case O_LEFT_SHIFT:
a687059c 267 value = str_gnum(st[1]);
268 anum = (int)str_gnum(st[2]);
269#ifndef lint
270 value = (double)(((long)value) << anum);
271#endif
378cc40b 272 goto donumset;
273 case O_RIGHT_SHIFT:
a687059c 274 value = str_gnum(st[1]);
275 anum = (int)str_gnum(st[2]);
276#ifndef lint
277 value = (double)(((long)value) >> anum);
278#endif
378cc40b 279 goto donumset;
280 case O_LT:
a687059c 281 value = str_gnum(st[1]);
282 value = (value < str_gnum(st[2])) ? 1.0 : 0.0;
378cc40b 283 goto donumset;
284 case O_GT:
a687059c 285 value = str_gnum(st[1]);
286 value = (value > str_gnum(st[2])) ? 1.0 : 0.0;
378cc40b 287 goto donumset;
288 case O_LE:
a687059c 289 value = str_gnum(st[1]);
290 value = (value <= str_gnum(st[2])) ? 1.0 : 0.0;
378cc40b 291 goto donumset;
292 case O_GE:
a687059c 293 value = str_gnum(st[1]);
294 value = (value >= str_gnum(st[2])) ? 1.0 : 0.0;
378cc40b 295 goto donumset;
296 case O_EQ:
a687059c 297 if (dowarn) {
298 if ((!st[1]->str_nok && !looks_like_number(st[1])) ||
299 (!st[2]->str_nok && !looks_like_number(st[2])) )
300 warn("Possible use of == on string value");
301 }
302 value = str_gnum(st[1]);
303 value = (value == str_gnum(st[2])) ? 1.0 : 0.0;
378cc40b 304 goto donumset;
305 case O_NE:
a687059c 306 value = str_gnum(st[1]);
307 value = (value != str_gnum(st[2])) ? 1.0 : 0.0;
378cc40b 308 goto donumset;
309 case O_BIT_AND:
a687059c 310 if (!sawvec || st[1]->str_nok || st[2]->str_nok) {
311 value = str_gnum(st[1]);
312#ifndef lint
313 value = (double)(((long)value) & (long)str_gnum(st[2]));
314#endif
315 goto donumset;
316 }
317 else
318 do_vop(optype,str,st[1],st[2]);
319 break;
378cc40b 320 case O_XOR:
a687059c 321 if (!sawvec || st[1]->str_nok || st[2]->str_nok) {
322 value = str_gnum(st[1]);
323#ifndef lint
324 value = (double)(((long)value) ^ (long)str_gnum(st[2]));
325#endif
326 goto donumset;
327 }
328 else
329 do_vop(optype,str,st[1],st[2]);
330 break;
378cc40b 331 case O_BIT_OR:
a687059c 332 if (!sawvec || st[1]->str_nok || st[2]->str_nok) {
333 value = str_gnum(st[1]);
334#ifndef lint
335 value = (double)(((long)value) | (long)str_gnum(st[2]));
336#endif
337 goto donumset;
338 }
339 else
340 do_vop(optype,str,st[1],st[2]);
341 break;
342/* use register in evaluating str_true() */
378cc40b 343 case O_AND:
a687059c 344 if (str_true(st[1])) {
378cc40b 345 anum = 2;
346 optype = O_ITEM2;
347 argflags = arg[anum].arg_flags;
a687059c 348 if (gimme == G_ARRAY)
349 argflags |= AF_ARYOK;
350 argtype = arg[anum].arg_type & A_MASK;
378cc40b 351 argptr = arg[anum].arg_ptr;
352 maxarg = anum = 1;
a687059c 353 sp = arglast[0];
354 st -= sp;
378cc40b 355 goto re_eval;
356 }
357 else {
358 if (assigning) {
a687059c 359 str_sset(str, st[1]);
378cc40b 360 STABSET(str);
361 }
362 else
a687059c 363 str = st[1];
378cc40b 364 break;
365 }
366 case O_OR:
a687059c 367 if (str_true(st[1])) {
378cc40b 368 if (assigning) {
a687059c 369 str_sset(str, st[1]);
378cc40b 370 STABSET(str);
371 }
372 else
a687059c 373 str = st[1];
378cc40b 374 break;
375 }
376 else {
377 anum = 2;
378 optype = O_ITEM2;
379 argflags = arg[anum].arg_flags;
a687059c 380 if (gimme == G_ARRAY)
381 argflags |= AF_ARYOK;
382 argtype = arg[anum].arg_type & A_MASK;
378cc40b 383 argptr = arg[anum].arg_ptr;
384 maxarg = anum = 1;
a687059c 385 sp = arglast[0];
386 st -= sp;
378cc40b 387 goto re_eval;
388 }
389 case O_COND_EXPR:
a687059c 390 anum = (str_true(st[1]) ? 2 : 3);
378cc40b 391 optype = (anum == 2 ? O_ITEM2 : O_ITEM3);
392 argflags = arg[anum].arg_flags;
a687059c 393 if (gimme == G_ARRAY)
394 argflags |= AF_ARYOK;
395 argtype = arg[anum].arg_type & A_MASK;
378cc40b 396 argptr = arg[anum].arg_ptr;
397 maxarg = anum = 1;
a687059c 398 sp = arglast[0];
399 st -= sp;
378cc40b 400 goto re_eval;
401 case O_COMMA:
a687059c 402 if (gimme == G_ARRAY)
403 goto array_return;
404 str = st[2];
378cc40b 405 break;
406 case O_NEGATE:
a687059c 407 value = -str_gnum(st[1]);
378cc40b 408 goto donumset;
409 case O_NOT:
a687059c 410 value = (double) !str_true(st[1]);
378cc40b 411 goto donumset;
412 case O_COMPLEMENT:
a687059c 413#ifndef lint
414 value = (double) ~(long)str_gnum(st[1]);
415#endif
378cc40b 416 goto donumset;
417 case O_SELECT:
a687059c 418 tmps = stab_name(defoutstab);
419 if (maxarg > 0) {
420 if ((arg[1].arg_type & A_MASK) == A_WORD)
421 defoutstab = arg[1].arg_ptr.arg_stab;
422 else
423 defoutstab = stabent(str_get(st[1]),TRUE);
424 if (!stab_io(defoutstab))
425 stab_io(defoutstab) = stio_new();
426 curoutstab = defoutstab;
427 }
428 str_set(str, tmps);
378cc40b 429 STABSET(str);
430 break;
431 case O_WRITE:
432 if (maxarg == 0)
433 stab = defoutstab;
a687059c 434 else if ((arg[1].arg_type & A_MASK) == A_WORD) {
435 if (!(stab = arg[1].arg_ptr.arg_stab))
436 stab = defoutstab;
437 }
378cc40b 438 else
a687059c 439 stab = stabent(str_get(st[1]),TRUE);
440 if (!stab_io(stab)) {
378cc40b 441 str_set(str, No);
442 STABSET(str);
443 break;
444 }
445 curoutstab = stab;
a687059c 446 fp = stab_io(stab)->ofp;
378cc40b 447 debarg = arg;
a687059c 448 if (stab_io(stab)->fmt_stab)
449 form = stab_form(stab_io(stab)->fmt_stab);
378cc40b 450 else
a687059c 451 form = stab_form(stab);
378cc40b 452 if (!form || !fp) {
a687059c 453 if (dowarn) {
454 if (form)
455 warn("No format for filehandle");
456 else {
457 if (stab_io(stab)->ifp)
458 warn("Filehandle only opened for input");
459 else
460 warn("Write on closed filehandle");
461 }
462 }
378cc40b 463 str_set(str, No);
464 STABSET(str);
465 break;
466 }
a687059c 467 format(&outrec,form,sp);
468 do_write(&outrec,stab_io(stab),sp);
469 if (stab_io(stab)->flags & IOF_FLUSH)
470 (void)fflush(fp);
378cc40b 471 str_set(str, Yes);
472 STABSET(str);
473 break;
a687059c 474 case O_DBMOPEN:
475#ifdef SOME_DBM
476 if ((arg[1].arg_type & A_MASK) == A_WORD)
477 stab = arg[1].arg_ptr.arg_stab;
478 else
479 stab = stabent(str_get(st[1]),TRUE);
480 anum = (int)str_gnum(st[3]);
481 value = (double)hdbmopen(stab_hash(stab),str_get(st[2]),anum);
482 goto donumset;
483#else
484 fatal("No dbm or ndbm on this machine");
485#endif
486 case O_DBMCLOSE:
487#ifdef SOME_DBM
488 if ((arg[1].arg_type & A_MASK) == A_WORD)
489 stab = arg[1].arg_ptr.arg_stab;
490 else
491 stab = stabent(str_get(st[1]),TRUE);
492 hdbmclose(stab_hash(stab));
493 goto say_yes;
494#else
495 fatal("No dbm or ndbm on this machine");
496#endif
378cc40b 497 case O_OPEN:
a687059c 498 if ((arg[1].arg_type & A_MASK) == A_WORD)
378cc40b 499 stab = arg[1].arg_ptr.arg_stab;
500 else
a687059c 501 stab = stabent(str_get(st[1]),TRUE);
502 if (do_open(stab,str_get(st[2]))) {
378cc40b 503 value = (double)forkprocess;
a687059c 504 stab_io(stab)->lines = 0;
378cc40b 505 goto donumset;
506 }
507 else
a687059c 508 goto say_undef;
378cc40b 509 break;
510 case O_TRANS:
511 value = (double) do_trans(str,arg);
512 str = arg->arg_ptr.arg_str;
513 goto donumset;
514 case O_NTRANS:
515 str_set(arg->arg_ptr.arg_str, do_trans(str,arg) == 0 ? Yes : No);
516 str = arg->arg_ptr.arg_str;
517 break;
518 case O_CLOSE:
a687059c 519 if (maxarg == 0)
520 stab = defoutstab;
521 else if ((arg[1].arg_type & A_MASK) == A_WORD)
378cc40b 522 stab = arg[1].arg_ptr.arg_stab;
523 else
a687059c 524 stab = stabent(str_get(st[1]),TRUE);
378cc40b 525 str_set(str, do_close(stab,TRUE) ? Yes : No );
526 STABSET(str);
527 break;
528 case O_EACH:
a687059c 529 sp = do_each(str,stab_hash(arg[1].arg_ptr.arg_stab),
530 gimme,arglast);
531 goto array_return;
378cc40b 532 case O_VALUES:
533 case O_KEYS:
a687059c 534 sp = do_kv(str,stab_hash(arg[1].arg_ptr.arg_stab), optype,
535 gimme,arglast);
536 goto array_return;
537 case O_LARRAY:
538 str->str_nok = str->str_pok = 0;
539 str->str_u.str_stab = arg[1].arg_ptr.arg_stab;
540 str->str_state = SS_ARY;
541 break;
378cc40b 542 case O_ARRAY:
a687059c 543 ary = stab_array(arg[1].arg_ptr.arg_stab);
544 maxarg = ary->ary_fill + 1;
545 if (gimme == G_ARRAY) { /* array wanted */
546 sp = arglast[0];
547 st -= sp;
548 if (maxarg > 0 && sp + maxarg > stack->ary_max) {
549 astore(stack,sp + maxarg, Nullstr);
550 st = stack->ary_array;
378cc40b 551 }
a687059c 552 Copy(ary->ary_array, &st[sp+1], maxarg, STR*);
553 sp += maxarg;
554 goto array_return;
378cc40b 555 }
556 else
a687059c 557 str = afetch(ary,maxarg - 1,FALSE);
558 break;
559 case O_AELEM:
560 str = afetch(stab_array(arg[1].arg_ptr.arg_stab),
561 ((int)str_gnum(st[2])) - arybase,FALSE);
378cc40b 562 if (!str)
a687059c 563 goto say_undef;
378cc40b 564 break;
565 case O_DELETE:
a687059c 566 tmpstab = arg[1].arg_ptr.arg_stab;
567 tmps = str_get(st[2]);
568 str = hdelete(stab_hash(tmpstab),tmps,st[2]->str_cur);
569 if (tmpstab == envstab)
570 setenv(tmps,Nullch);
378cc40b 571 if (!str)
a687059c 572 goto say_undef;
573 break;
574 case O_LHASH:
575 str->str_nok = str->str_pok = 0;
576 str->str_u.str_stab = arg[1].arg_ptr.arg_stab;
577 str->str_state = SS_HASH;
378cc40b 578 break;
579 case O_HASH:
a687059c 580 if (gimme == G_ARRAY) { /* array wanted */
581 sp = do_kv(str,stab_hash(arg[1].arg_ptr.arg_stab), optype,
582 gimme,arglast);
583 goto array_return;
584 }
585 else {
586 tmpstab = arg[1].arg_ptr.arg_stab;
587 sprintf(buf,"%d/%d",stab_hash(tmpstab)->tbl_fill,
588 stab_hash(tmpstab)->tbl_max+1);
589 str_set(str,buf);
590 }
591 break;
592 case O_HELEM:
593 tmpstab = arg[1].arg_ptr.arg_stab;
594 tmps = str_get(st[2]);
595 str = hfetch(stab_hash(tmpstab),tmps,st[2]->str_cur,FALSE);
378cc40b 596 if (!str)
a687059c 597 goto say_undef;
378cc40b 598 break;
a687059c 599 case O_LAELEM:
600 anum = ((int)str_gnum(st[2])) - arybase;
601 str = afetch(stab_array(arg[1].arg_ptr.arg_stab),anum,TRUE);
602 if (!str)
603 fatal("Assignment to non-creatable value, subscript %d",anum);
378cc40b 604 break;
a687059c 605 case O_LHELEM:
606 tmpstab = arg[1].arg_ptr.arg_stab;
607 tmps = str_get(st[2]);
608 anum = st[2]->str_cur;
609 str = hfetch(stab_hash(tmpstab),tmps,anum,TRUE);
610 if (!str)
611 fatal("Assignment to non-creatable value, subscript \"%s\"",tmps);
612 if (tmpstab == envstab) /* heavy wizardry going on here */
613 str_magic(str, tmpstab, 'E', tmps, anum); /* str is now magic */
378cc40b 614 /* he threw the brick up into the air */
a687059c 615 else if (tmpstab == sigstab)
616 str_magic(str, tmpstab, 'S', tmps, anum);
617#ifdef SOME_DBM
618 else if (stab_hash(tmpstab)->tbl_dbm)
619 str_magic(str, tmpstab, 'D', tmps, anum);
620#endif
378cc40b 621 break;
a687059c 622 case O_ASLICE:
623 anum = TRUE;
624 argtype = FALSE;
625 goto do_slice_already;
626 case O_HSLICE:
627 anum = FALSE;
628 argtype = FALSE;
629 goto do_slice_already;
630 case O_LASLICE:
631 anum = TRUE;
632 argtype = TRUE;
633 goto do_slice_already;
634 case O_LHSLICE:
635 anum = FALSE;
636 argtype = TRUE;
637 do_slice_already:
638 sp = do_slice(arg[1].arg_ptr.arg_stab,anum,argtype,
639 gimme,arglast);
640 goto array_return;
378cc40b 641 case O_PUSH:
a687059c 642 if (arglast[2] - arglast[1] != 1)
643 str = do_push(stab_array(arg[1].arg_ptr.arg_stab),arglast);
378cc40b 644 else {
a687059c 645 str = Str_new(51,0); /* must copy the STR */
646 str_sset(str,st[2]);
647 (void)apush(stab_array(arg[1].arg_ptr.arg_stab),str);
378cc40b 648 }
649 break;
650 case O_POP:
a687059c 651 str = apop(ary = stab_array(arg[1].arg_ptr.arg_stab));
652 goto staticalization;
378cc40b 653 case O_SHIFT:
a687059c 654 str = ashift(ary = stab_array(arg[1].arg_ptr.arg_stab));
655 staticalization:
656 if (!str)
657 goto say_undef;
658 if (ary->ary_flags & ARF_REAL)
659 (void)str_2static(str);
378cc40b 660 break;
a687059c 661 case O_UNPACK:
662 sp = do_unpack(str,gimme,arglast);
663 goto array_return;
378cc40b 664 case O_SPLIT:
a687059c 665 value = str_gnum(st[3]);
666 sp = do_split(str, arg[2].arg_ptr.arg_spat, (int)value,
667 gimme,arglast);
668 goto array_return;
378cc40b 669 case O_LENGTH:
a687059c 670 if (maxarg < 1)
671 value = (double)str_len(stab_val(defstab));
672 else
673 value = (double)str_len(st[1]);
378cc40b 674 goto donumset;
675 case O_SPRINTF:
a687059c 676 do_sprintf(str, sp-arglast[0], st+1);
378cc40b 677 break;
678 case O_SUBSTR:
a687059c 679 anum = ((int)str_gnum(st[2])) - arybase; /* anum=where to start*/
680 tmps = str_get(st[1]); /* force conversion to string */
681 if (argtype = (str == st[1]))
682 str = arg->arg_ptr.arg_str;
683 if (anum < 0)
684 anum += st[1]->str_cur + arybase;
685 if (anum < 0 || anum > st[1]->str_cur)
686 str_nset(str,"",0);
687 else {
688 optype = (int)str_gnum(st[3]);
689 if (optype < 0)
690 optype = 0;
691 tmps += anum;
692 anum = st[1]->str_cur - anum; /* anum=how many bytes left*/
693 if (anum > optype)
694 anum = optype;
378cc40b 695 str_nset(str, tmps, anum);
a687059c 696 if (argtype) { /* it's an lvalue! */
697 lstr = (struct lstring*)str;
698 str->str_magic = st[1];
699 st[1]->str_rare = 's';
700 lstr->lstr_offset = tmps - str_get(st[1]);
701 lstr->lstr_len = anum;
702 }
703 }
704 break;
705 case O_PACK:
706 (void)do_pack(str,arglast);
378cc40b 707 break;
a687059c 708 case O_GREP:
709 sp = do_grep(arg,str,gimme,arglast);
710 goto array_return;
378cc40b 711 case O_JOIN:
a687059c 712 do_join(str,arglast);
378cc40b 713 break;
714 case O_SLT:
a687059c 715 tmps = str_get(st[1]);
716 value = (double) (str_cmp(st[1],st[2]) < 0);
378cc40b 717 goto donumset;
718 case O_SGT:
a687059c 719 tmps = str_get(st[1]);
720 value = (double) (str_cmp(st[1],st[2]) > 0);
378cc40b 721 goto donumset;
722 case O_SLE:
a687059c 723 tmps = str_get(st[1]);
724 value = (double) (str_cmp(st[1],st[2]) <= 0);
378cc40b 725 goto donumset;
726 case O_SGE:
a687059c 727 tmps = str_get(st[1]);
728 value = (double) (str_cmp(st[1],st[2]) >= 0);
378cc40b 729 goto donumset;
730 case O_SEQ:
a687059c 731 tmps = str_get(st[1]);
732 value = (double) str_eq(st[1],st[2]);
378cc40b 733 goto donumset;
734 case O_SNE:
a687059c 735 tmps = str_get(st[1]);
736 value = (double) !str_eq(st[1],st[2]);
378cc40b 737 goto donumset;
738 case O_SUBR:
a687059c 739 sp = do_subr(arg,gimme,arglast);
740 st = stack->ary_array + arglast[0]; /* maybe realloced */
741 goto array_return;
742 case O_DBSUBR:
743 sp = do_dbsubr(arg,gimme,arglast);
744 st = stack->ary_array + arglast[0]; /* maybe realloced */
745 goto array_return;
378cc40b 746 case O_SORT:
a687059c 747 if ((arg[1].arg_type & A_MASK) == A_WORD)
748 stab = arg[1].arg_ptr.arg_stab;
749 else
750 stab = stabent(str_get(st[1]),TRUE);
751 if (!stab)
378cc40b 752 stab = defoutstab;
a687059c 753 sp = do_sort(str,stab,
754 gimme,arglast);
755 goto array_return;
756 case O_REVERSE:
757 sp = do_reverse(str,
758 gimme,arglast);
759 goto array_return;
760 case O_WARN:
761 if (arglast[2] - arglast[1] != 1) {
762 do_join(str,arglast);
763 tmps = str_get(st[1]);
764 }
378cc40b 765 else {
a687059c 766 str = st[2];
767 tmps = str_get(st[2]);
378cc40b 768 }
a687059c 769 if (!tmps || !*tmps)
770 tmps = "Warning: something's wrong";
771 warn("%s",tmps);
772 goto say_yes;
773 case O_DIE:
774 if (arglast[2] - arglast[1] != 1) {
775 do_join(str,arglast);
776 tmps = str_get(st[1]);
378cc40b 777 }
a687059c 778 else {
779 str = st[2];
780 tmps = str_get(st[2]);
781 }
782 if (!tmps || !*tmps)
783 exit(1);
784 fatal("%s",tmps);
785 goto say_zero;
378cc40b 786 case O_PRTF:
787 case O_PRINT:
a687059c 788 if ((arg[1].arg_type & A_MASK) == A_WORD)
789 stab = arg[1].arg_ptr.arg_stab;
790 else
791 stab = stabent(str_get(st[1]),TRUE);
792 if (!stab)
378cc40b 793 stab = defoutstab;
a687059c 794 if (!stab_io(stab)) {
795 if (dowarn)
796 warn("Filehandle never opened");
797 goto say_zero;
798 }
799 if (!(fp = stab_io(stab)->ofp)) {
800 if (dowarn) {
801 if (stab_io(stab)->ifp)
802 warn("Filehandle opened only for input");
803 else
804 warn("Print on closed filehandle");
805 }
806 goto say_zero;
378cc40b 807 }
378cc40b 808 else {
a687059c 809 if (optype == O_PRTF || arglast[2] - arglast[1] != 1)
810 value = (double)do_aprint(arg,fp,arglast);
378cc40b 811 else {
a687059c 812 value = (double)do_print(st[2],fp);
813 if (orslen && optype == O_PRINT)
814 if (fwrite(ors, 1, orslen, fp) == 0)
815 goto say_zero;
378cc40b 816 }
a687059c 817 if (stab_io(stab)->flags & IOF_FLUSH)
818 if (fflush(fp) == EOF)
819 goto say_zero;
378cc40b 820 }
821 goto donumset;
822 case O_CHDIR:
a687059c 823 if (maxarg < 1)
824 tmps = str_get(stab_val(defstab));
825 else
826 tmps = str_get(st[1]);
827 if (!tmps || !*tmps) {
828 tmpstr = hfetch(stab_hash(envstab),"HOME",4,FALSE);
829 if (tmpstr)
830 tmps = str_get(tmpstr);
831 }
832 if (!tmps || !*tmps) {
833 tmpstr = hfetch(stab_hash(envstab),"LOGDIR",6,FALSE);
834 if (tmpstr)
835 tmps = str_get(tmpstr);
836 }
837#ifdef TAINT
838 taintproper("Insecure dependency in chdir");
839#endif
378cc40b 840 value = (double)(chdir(tmps) >= 0);
841 goto donumset;
378cc40b 842 case O_EXIT:
a687059c 843 if (maxarg < 1)
844 anum = 0;
845 else
846 anum = (int)str_gnum(st[1]);
847 exit(anum);
848 goto say_zero;
378cc40b 849 case O_RESET:
a687059c 850 if (maxarg < 1)
851 tmps = "";
852 else
853 tmps = str_get(st[1]);
854 str_reset(tmps,arg[2].arg_ptr.arg_hash);
378cc40b 855 value = 1.0;
856 goto donumset;
857 case O_LIST:
a687059c 858 if (gimme == G_ARRAY)
859 goto array_return;
378cc40b 860 if (maxarg > 0)
a687059c 861 str = st[sp - arglast[0]]; /* unwanted list, return last item */
378cc40b 862 else
a687059c 863 str = &str_undef;
378cc40b 864 break;
865 case O_EOF:
866 if (maxarg <= 0)
867 stab = last_in_stab;
a687059c 868 else if ((arg[1].arg_type & A_MASK) == A_WORD)
378cc40b 869 stab = arg[1].arg_ptr.arg_stab;
870 else
a687059c 871 stab = stabent(str_get(st[1]),TRUE);
378cc40b 872 str_set(str, do_eof(stab) ? Yes : No);
873 STABSET(str);
874 break;
a687059c 875 case O_GETC:
378cc40b 876 if (maxarg <= 0)
a687059c 877 stab = stdinstab;
878 else if ((arg[1].arg_type & A_MASK) == A_WORD)
378cc40b 879 stab = arg[1].arg_ptr.arg_stab;
880 else
a687059c 881 stab = stabent(str_get(st[1]),TRUE);
882 if (do_eof(stab)) /* make sure we have fp with something */
883 str_set(str, No);
884 else {
885#ifdef TAINT
886 tainted = 1;
887#endif
888 str_set(str," ");
889 *str->str_ptr = getc(stab_io(stab)->ifp); /* should never be EOF */
890 }
891 STABSET(str);
892 break;
893 case O_TELL:
894 if (maxarg <= 0)
895 stab = last_in_stab;
896 else if ((arg[1].arg_type & A_MASK) == A_WORD)
897 stab = arg[1].arg_ptr.arg_stab;
898 else
899 stab = stabent(str_get(st[1]),TRUE);
900#ifndef lint
901 value = (double)do_tell(stab);
902#else
903 (void)do_tell(stab);
904#endif
905 goto donumset;
906 case O_RECV:
907 case O_READ:
908 if ((arg[1].arg_type & A_MASK) == A_WORD)
909 stab = arg[1].arg_ptr.arg_stab;
910 else
911 stab = stabent(str_get(st[1]),TRUE);
912 tmps = str_get(st[2]);
913 anum = (int)str_gnum(st[3]);
914 STR_GROW(st[2], anum+1), (tmps = str_get(st[2])); /* sneaky */
915 errno = 0;
916 if (!stab_io(stab) || !stab_io(stab)->ifp)
917 goto say_zero;
918#ifdef SOCKET
919 else if (optype == O_RECV) {
920 argtype = sizeof buf;
921 optype = (int)str_gnum(st[4]);
922 anum = recvfrom(fileno(stab_io(stab)->ifp), tmps, anum, optype,
923 buf, &argtype);
924 if (anum >= 0) {
925 st[2]->str_cur = anum;
926 st[2]->str_ptr[anum] = '\0';
927 str_nset(str,buf,argtype);
928 }
929 else
930 str_sset(str,&str_undef);
931 break;
932 }
933 else if (stab_io(stab)->type == 's') {
934 argtype = sizeof buf;
935 anum = recvfrom(fileno(stab_io(stab)->ifp), tmps, anum, 0,
936 buf, &argtype);
937 }
938#else
939 else if (optype == O_RECV)
940 goto badsock;
941#endif
942 else
943 anum = fread(tmps, 1, anum, stab_io(stab)->ifp);
944 if (anum < 0)
945 goto say_undef;
946 st[2]->str_cur = anum;
947 st[2]->str_ptr[anum] = '\0';
948 value = (double)anum;
949 goto donumset;
950 case O_SEND:
951#ifdef SOCKET
952 if ((arg[1].arg_type & A_MASK) == A_WORD)
953 stab = arg[1].arg_ptr.arg_stab;
954 else
955 stab = stabent(str_get(st[1]),TRUE);
956 tmps = str_get(st[2]);
957 anum = (int)str_gnum(st[3]);
958 optype = sp - arglast[0];
959 errno = 0;
960 if (optype > 4)
961 warn("Too many args on send");
962 if (optype >= 4) {
963 tmps2 = str_get(st[4]);
964 anum = sendto(fileno(stab_io(stab)->ifp), tmps, st[2]->str_cur,
965 anum, tmps2, st[4]->str_cur);
966 }
967 else
968 anum = send(fileno(stab_io(stab)->ifp), tmps, st[2]->str_cur, anum);
969 if (anum < 0)
970 goto say_undef;
971 value = (double)anum;
972 goto donumset;
973#else
974 goto badsock;
975#endif
976 case O_SEEK:
977 if ((arg[1].arg_type & A_MASK) == A_WORD)
978 stab = arg[1].arg_ptr.arg_stab;
378cc40b 979 else
a687059c 980 stab = stabent(str_get(st[1]),TRUE);
981 value = str_gnum(st[2]);
378cc40b 982 str_set(str, do_seek(stab,
a687059c 983 (long)value, (int)str_gnum(st[3]) ) ? Yes : No);
378cc40b 984 STABSET(str);
985 break;
a687059c 986 case O_RETURN:
987 tmps = "SUB"; /* just fake up a "last SUB" */
988 optype = O_LAST;
989 if (gimme == G_ARRAY) {
990 lastretstr = Nullstr;
991 lastspbase = arglast[1];
992 lastsize = arglast[2] - arglast[1];
993 }
994 else
995 lastretstr = str_static(st[arglast[2] - arglast[0]]);
996 goto dopop;
378cc40b 997 case O_REDO:
998 case O_NEXT:
999 case O_LAST:
1000 if (maxarg > 0) {
a687059c 1001 tmps = str_get(arg[1].arg_ptr.arg_str);
1002 dopop:
378cc40b 1003 while (loop_ptr >= 0 && (!loop_stack[loop_ptr].loop_label ||
1004 strNE(tmps,loop_stack[loop_ptr].loop_label) )) {
1005#ifdef DEBUGGING
1006 if (debug & 4) {
1007 deb("(Skipping label #%d %s)\n",loop_ptr,
1008 loop_stack[loop_ptr].loop_label);
1009 }
1010#endif
1011 loop_ptr--;
1012 }
1013#ifdef DEBUGGING
1014 if (debug & 4) {
1015 deb("(Found label #%d %s)\n",loop_ptr,
1016 loop_stack[loop_ptr].loop_label);
1017 }
1018#endif
1019 }
1020 if (loop_ptr < 0)
1021 fatal("Bad label: %s", maxarg > 0 ? tmps : "<null>");
a687059c 1022 if (!lastretstr && optype == O_LAST && lastsize) {
1023 st -= arglast[0];
1024 st += lastspbase + 1;
1025 optype = loop_stack[loop_ptr].loop_sp - lastspbase; /* negative */
1026 if (optype) {
1027 for (anum = lastsize; anum > 0; anum--,st++)
1028 st[optype] = str_static(st[0]);
1029 }
1030 longjmp(loop_stack[loop_ptr].loop_env, O_LAST);
1031 }
378cc40b 1032 longjmp(loop_stack[loop_ptr].loop_env, optype);
a687059c 1033 case O_DUMP:
378cc40b 1034 case O_GOTO:/* shudder */
a687059c 1035 goto_targ = str_get(arg[1].arg_ptr.arg_str);
1036 if (!*goto_targ)
1037 goto_targ = Nullch; /* just restart from top */
1038 if (optype == O_DUMP) {
1039 do_undump = 1;
1040 abort();
1041 }
378cc40b 1042 longjmp(top_env, 1);
1043 case O_INDEX:
a687059c 1044 tmps = str_get(st[1]);
1045#ifndef lint
1046 if (!(tmps2 = fbminstr((unsigned char*)tmps,
1047 (unsigned char*)tmps + st[1]->str_cur, st[2])))
1048#else
1049 if (tmps2 = fbminstr(Null(unsigned char*),Null(unsigned char*),Nullstr))
1050#endif
1051 value = (double)(-1 + arybase);
1052 else
1053 value = (double)(tmps2 - tmps + arybase);
1054 goto donumset;
1055 case O_RINDEX:
1056 tmps = str_get(st[1]);
1057 tmps2 = str_get(st[2]);
1058#ifndef lint
1059 if (!(tmps2 = rninstr(tmps, tmps + st[1]->str_cur,
1060 tmps2, tmps2 + st[2]->str_cur)))
1061#else
1062 if (tmps2 = rninstr(Nullch,Nullch,Nullch,Nullch))
1063#endif
378cc40b 1064 value = (double)(-1 + arybase);
1065 else
1066 value = (double)(tmps2 - tmps + arybase);
1067 goto donumset;
1068 case O_TIME:
a687059c 1069#ifndef lint
378cc40b 1070 value = (double) time(Null(long*));
a687059c 1071#endif
378cc40b 1072 goto donumset;
1073 case O_TMS:
a687059c 1074 sp = do_tms(str,gimme,arglast);
1075 goto array_return;
378cc40b 1076 case O_LOCALTIME:
a687059c 1077 if (maxarg < 1)
1078 (void)time(&when);
1079 else
1080 when = (long)str_gnum(st[1]);
1081 sp = do_time(str,localtime(&when),
1082 gimme,arglast);
1083 goto array_return;
378cc40b 1084 case O_GMTIME:
a687059c 1085 if (maxarg < 1)
1086 (void)time(&when);
1087 else
1088 when = (long)str_gnum(st[1]);
1089 sp = do_time(str,gmtime(&when),
1090 gimme,arglast);
1091 goto array_return;
1092 case O_LSTAT:
378cc40b 1093 case O_STAT:
a687059c 1094 sp = do_stat(str,arg,
1095 gimme,arglast);
1096 goto array_return;
378cc40b 1097 case O_CRYPT:
1098#ifdef CRYPT
a687059c 1099 tmps = str_get(st[1]);
1100#ifdef FCRYPT
1101 str_set(str,fcrypt(tmps,str_get(st[2])));
1102#else
1103 str_set(str,crypt(tmps,str_get(st[2])));
1104#endif
378cc40b 1105#else
1106 fatal(
1107 "The crypt() function is unimplemented due to excessive paranoia.");
1108#endif
1109 break;
a687059c 1110 case O_ATAN2:
1111 value = str_gnum(st[1]);
1112 value = atan2(value,str_gnum(st[2]));
1113 goto donumset;
1114 case O_SIN:
1115 if (maxarg < 1)
1116 value = str_gnum(stab_val(defstab));
1117 else
1118 value = str_gnum(st[1]);
1119 value = sin(value);
1120 goto donumset;
1121 case O_COS:
1122 if (maxarg < 1)
1123 value = str_gnum(stab_val(defstab));
1124 else
1125 value = str_gnum(st[1]);
1126 value = cos(value);
1127 goto donumset;
1128 case O_RAND:
1129 if (maxarg < 1)
1130 value = 1.0;
1131 else
1132 value = str_gnum(st[1]);
1133 if (value == 0.0)
1134 value = 1.0;
1135#if RANDBITS == 31
1136 value = rand() * value / 2147483648.0;
1137#else
1138#if RANDBITS == 16
1139 value = rand() * value / 65536.0;
1140#else
1141#if RANDBITS == 15
1142 value = rand() * value / 32768.0;
1143#else
1144 value = rand() * value / (double)(((unsigned long)1) << RANDBITS);
1145#endif
1146#endif
1147#endif
1148 goto donumset;
1149 case O_SRAND:
1150 if (maxarg < 1) {
1151 (void)time(&when);
1152 anum = when;
1153 }
1154 else
1155 anum = (int)str_gnum(st[1]);
1156 (void)srand(anum);
1157 goto say_yes;
378cc40b 1158 case O_EXP:
a687059c 1159 if (maxarg < 1)
1160 value = str_gnum(stab_val(defstab));
1161 else
1162 value = str_gnum(st[1]);
1163 value = exp(value);
378cc40b 1164 goto donumset;
1165 case O_LOG:
a687059c 1166 if (maxarg < 1)
1167 value = str_gnum(stab_val(defstab));
1168 else
1169 value = str_gnum(st[1]);
1170 value = log(value);
378cc40b 1171 goto donumset;
1172 case O_SQRT:
a687059c 1173 if (maxarg < 1)
1174 value = str_gnum(stab_val(defstab));
1175 else
1176 value = str_gnum(st[1]);
1177 value = sqrt(value);
378cc40b 1178 goto donumset;
1179 case O_INT:
a687059c 1180 if (maxarg < 1)
1181 value = str_gnum(stab_val(defstab));
1182 else
1183 value = str_gnum(st[1]);
378cc40b 1184 if (value >= 0.0)
a687059c 1185 (void)modf(value,&value);
378cc40b 1186 else {
a687059c 1187 (void)modf(-value,&value);
378cc40b 1188 value = -value;
1189 }
1190 goto donumset;
1191 case O_ORD:
a687059c 1192 if (maxarg < 1)
1193 tmps = str_get(stab_val(defstab));
1194 else
1195 tmps = str_get(st[1]);
1196#ifndef I286
1197 value = (double) *tmps;
1198#else
1199 anum = (int) *tmps;
1200 value = (double) anum;
1201#endif
378cc40b 1202 goto donumset;
1203 case O_SLEEP:
a687059c 1204 if (maxarg < 1)
1205 tmps = Nullch;
1206 else
1207 tmps = str_get(st[1]);
1208 (void)time(&when);
378cc40b 1209 if (!tmps || !*tmps)
1210 sleep((32767<<16)+32767);
1211 else
a687059c 1212 sleep((unsigned int)atoi(tmps));
1213#ifndef lint
378cc40b 1214 value = (double)when;
a687059c 1215 (void)time(&when);
378cc40b 1216 value = ((double)when) - value;
a687059c 1217#endif
378cc40b 1218 goto donumset;
a687059c 1219 case O_RANGE:
1220 sp = do_range(gimme,arglast);
1221 goto array_return;
1222 case O_F_OR_R:
1223 if (gimme == G_ARRAY) { /* it's a range */
1224 /* can we optimize to constant array? */
1225 if ((arg[1].arg_type & A_MASK) == A_SINGLE &&
1226 (arg[2].arg_type & A_MASK) == A_SINGLE) {
1227 st[2] = arg[2].arg_ptr.arg_str;
1228 sp = do_range(gimme,arglast);
1229 st = stack->ary_array;
1230 maxarg = sp - arglast[0];
1231 str_free(arg[1].arg_ptr.arg_str);
1232 str_free(arg[2].arg_ptr.arg_str);
1233 arg->arg_type = O_ARRAY;
1234 arg[1].arg_type = A_STAB|A_DONT;
1235 arg->arg_len = 1;
1236 stab = arg[1].arg_ptr.arg_stab = aadd(genstab());
1237 ary = stab_array(stab);
1238 afill(ary,maxarg - 1);
1239 st += arglast[0]+1;
1240 while (maxarg-- > 0)
1241 ary->ary_array[maxarg] = str_smake(st[maxarg]);
1242 goto array_return;
1243 }
1244 arg->arg_type = optype = O_RANGE;
1245 maxarg = arg->arg_len = 2;
1246 anum = 2;
1247 arg[anum].arg_flags &= ~AF_ARYOK;
1248 argflags = arg[anum].arg_flags;
1249 argtype = arg[anum].arg_type & A_MASK;
1250 arg[anum].arg_type = argtype;
1251 argptr = arg[anum].arg_ptr;
1252 sp = arglast[0];
1253 st -= sp;
1254 sp++;
1255 goto re_eval;
1256 }
1257 arg->arg_type = O_FLIP;
1258 /* FALL THROUGH */
378cc40b 1259 case O_FLIP:
a687059c 1260 if ((arg[1].arg_type & A_MASK) == A_SINGLE ?
1261 last_in_stab && (int)str_gnum(st[1]) == stab_io(last_in_stab)->lines
1262 :
1263 str_true(st[1]) ) {
378cc40b 1264 str_numset(str,0.0);
1265 anum = 2;
1266 arg->arg_type = optype = O_FLOP;
a687059c 1267 arg[2].arg_type &= ~A_DONT;
1268 arg[1].arg_type |= A_DONT;
378cc40b 1269 argflags = arg[2].arg_flags;
a687059c 1270 argtype = arg[2].arg_type & A_MASK;
378cc40b 1271 argptr = arg[2].arg_ptr;
a687059c 1272 sp = arglast[0];
1273 st -= sp;
378cc40b 1274 goto re_eval;
1275 }
1276 str_set(str,"");
1277 break;
1278 case O_FLOP:
1279 str_inc(str);
a687059c 1280 if ((arg[2].arg_type & A_MASK) == A_SINGLE ?
1281 last_in_stab && (int)str_gnum(st[2]) == stab_io(last_in_stab)->lines
1282 :
1283 str_true(st[2]) ) {
378cc40b 1284 arg->arg_type = O_FLIP;
a687059c 1285 arg[1].arg_type &= ~A_DONT;
1286 arg[2].arg_type |= A_DONT;
378cc40b 1287 str_cat(str,"E0");
1288 }
1289 break;
1290 case O_FORK:
a687059c 1291 anum = fork();
1292 if (!anum && (tmpstab = stabent("$",allstabs)))
1293 str_numset(STAB_STR(tmpstab),(double)getpid());
1294 value = (double)anum;
378cc40b 1295 goto donumset;
1296 case O_WAIT:
a687059c 1297#ifndef lint
378cc40b 1298 ihand = signal(SIGINT, SIG_IGN);
1299 qhand = signal(SIGQUIT, SIG_IGN);
a687059c 1300 anum = wait(&argflags);
1301 if (anum > 0)
1302 pidgone(anum,argflags);
1303 value = (double)anum;
1304#else
1305 ihand = qhand = 0;
1306#endif
1307 (void)signal(SIGINT, ihand);
1308 (void)signal(SIGQUIT, qhand);
378cc40b 1309 statusvalue = (unsigned short)argflags;
1310 goto donumset;
1311 case O_SYSTEM:
a687059c 1312#ifdef TAINT
1313 if (arglast[2] - arglast[1] == 1) {
1314 taintenv();
1315 tainted |= st[2]->str_tainted;
1316 taintproper("Insecure dependency in system");
1317 }
1318#endif
378cc40b 1319 while ((anum = vfork()) == -1) {
1320 if (errno != EAGAIN) {
1321 value = -1.0;
1322 goto donumset;
1323 }
1324 sleep(5);
1325 }
1326 if (anum > 0) {
a687059c 1327#ifndef lint
378cc40b 1328 ihand = signal(SIGINT, SIG_IGN);
1329 qhand = signal(SIGQUIT, SIG_IGN);
a687059c 1330 while ((argtype = wait(&argflags)) != anum && argtype >= 0)
1331 pidgone(argtype,argflags);
1332#else
1333 ihand = qhand = 0;
1334#endif
1335 (void)signal(SIGINT, ihand);
1336 (void)signal(SIGQUIT, qhand);
378cc40b 1337 statusvalue = (unsigned short)argflags;
1338 if (argtype == -1)
1339 value = -1.0;
1340 else {
1341 value = (double)((unsigned int)argflags & 0xffff);
1342 }
1343 goto donumset;
1344 }
a687059c 1345 if ((arg[1].arg_type & A_MASK) == A_STAB)
1346 value = (double)do_aexec(st[1],arglast);
1347 else if (arglast[2] - arglast[1] != 1)
1348 value = (double)do_aexec(Nullstr,arglast);
378cc40b 1349 else {
a687059c 1350 value = (double)do_exec(str_get(str_static(st[2])));
378cc40b 1351 }
1352 _exit(-1);
1353 case O_EXEC:
a687059c 1354 if ((arg[1].arg_type & A_MASK) == A_STAB)
1355 value = (double)do_aexec(st[1],arglast);
1356 else if (arglast[2] - arglast[1] != 1)
1357 value = (double)do_aexec(Nullstr,arglast);
378cc40b 1358 else {
a687059c 1359 value = (double)do_exec(str_get(str_static(st[2])));
378cc40b 1360 }
1361 goto donumset;
1362 case O_HEX:
1363 argtype = 4;
1364 goto snarfnum;
1365
1366 case O_OCT:
1367 argtype = 3;
1368
1369 snarfnum:
1370 anum = 0;
a687059c 1371 if (maxarg < 1)
1372 tmps = str_get(stab_val(defstab));
1373 else
1374 tmps = str_get(st[1]);
378cc40b 1375 for (;;) {
1376 switch (*tmps) {
1377 default:
1378 goto out;
1379 case '8': case '9':
1380 if (argtype != 4)
1381 goto out;
1382 /* FALL THROUGH */
1383 case '0': case '1': case '2': case '3': case '4':
1384 case '5': case '6': case '7':
1385 anum <<= argtype;
1386 anum += *tmps++ & 15;
1387 break;
1388 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
1389 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
1390 if (argtype != 4)
1391 goto out;
1392 anum <<= 4;
1393 anum += (*tmps++ & 7) + 9;
1394 break;
1395 case 'x':
1396 argtype = 4;
1397 tmps++;
1398 break;
1399 }
1400 }
1401 out:
1402 value = (double)anum;
1403 goto donumset;
1404 case O_CHMOD:
1405 case O_CHOWN:
1406 case O_KILL:
1407 case O_UNLINK:
1408 case O_UTIME:
a687059c 1409 value = (double)apply(optype,arglast);
378cc40b 1410 goto donumset;
1411 case O_UMASK:
a687059c 1412 if (maxarg < 1) {
1413 anum = umask(0);
1414 (void)umask(anum);
1415 }
1416 else
1417 anum = umask((int)str_gnum(st[1]));
1418 value = (double)anum;
1419#ifdef TAINT
1420 taintproper("Insecure dependency in umask");
1421#endif
378cc40b 1422 goto donumset;
1423 case O_RENAME:
a687059c 1424 tmps = str_get(st[1]);
1425 tmps2 = str_get(st[2]);
1426#ifdef TAINT
1427 taintproper("Insecure dependency in rename");
1428#endif
378cc40b 1429#ifdef RENAME
a687059c 1430 value = (double)(rename(tmps,tmps2) >= 0);
378cc40b 1431#else
378cc40b 1432 if (euid || stat(tmps2,&statbuf) < 0 ||
1433 (statbuf.st_mode & S_IFMT) != S_IFDIR )
a687059c 1434 (void)UNLINK(tmps2); /* avoid unlinking a directory */
378cc40b 1435 if (!(anum = link(tmps,tmps2)))
1436 anum = UNLINK(tmps);
1437 value = (double)(anum >= 0);
1438#endif
1439 goto donumset;
1440 case O_LINK:
a687059c 1441 tmps = str_get(st[1]);
1442 tmps2 = str_get(st[2]);
1443#ifdef TAINT
1444 taintproper("Insecure dependency in link");
1445#endif
1446 value = (double)(link(tmps,tmps2) >= 0);
1447 goto donumset;
1448 case O_MKDIR:
1449 tmps = str_get(st[1]);
1450 anum = (int)str_gnum(st[2]);
1451#ifdef TAINT
1452 taintproper("Insecure dependency in mkdir");
1453#endif
1454#ifdef MKDIR
1455 value = (double)(mkdir(tmps,anum) >= 0);
bf38876a 1456 goto donumset;
a687059c 1457#else
bf38876a 1458 (void)strcpy(buf,"mkdir ");
1459#endif
1460#if !defined(MKDIR) || !defined(RMDIR)
a687059c 1461 one_liner:
bf38876a 1462 for (tmps2 = buf+6; *tmps; ) {
1463 *tmps2++ = '\\';
1464 *tmps2++ = *tmps++;
1465 }
1466 (void)strcpy(tmps2," 2>&1");
a687059c 1467 rsfp = mypopen(buf,"r");
1468 if (rsfp) {
1469 *buf = '\0';
1470 tmps2 = fgets(buf,sizeof buf,rsfp);
1471 (void)mypclose(rsfp);
1472 if (tmps2 != Nullch) {
bf38876a 1473 for (errno = 1; errno < sys_nerr; errno++) {
a687059c 1474 if (instr(buf,sys_errlist[errno])) /* you don't see this */
1475 goto say_zero;
1476 }
1477 errno = 0;
bf38876a 1478#ifndef EACCES
1479#define EACCES EPERM
1480#endif
1481 if (instr(buf,"cannot make"))
1482 errno = EEXIST;
1483 else if (instr(buf,"non-exist"))
1484 errno = ENOENT;
1485 else if (instr(buf,"not empty"))
1486 errno = EBUSY;
1487 else if (instr(buf,"cannot access"))
1488 errno = EACCES;
1489 else
1490 errno = EPERM;
a687059c 1491 goto say_zero;
1492 }
bf38876a 1493 else { /* some mkdirs return no failure indication */
1494 tmps = str_get(st[1]);
1495 anum = (stat(tmps,&statbuf) >= 0);
1496 if (optype == O_RMDIR)
1497 anum = !anum;
1498 if (anum)
1499 errno = 0;
1500 else
1501 errno = EACCES; /* a guess */
1502 value = (double)anum;
1503 }
1504 goto donumset;
a687059c 1505 }
1506 else
1507 goto say_zero;
1508#endif
a687059c 1509 case O_RMDIR:
1510 if (maxarg < 1)
1511 tmps = str_get(stab_val(defstab));
1512 else
1513 tmps = str_get(st[1]);
1514#ifdef TAINT
1515 taintproper("Insecure dependency in rmdir");
1516#endif
1517#ifdef RMDIR
1518 value = (double)(rmdir(tmps) >= 0);
1519 goto donumset;
1520#else
bf38876a 1521 (void)strcpy(buf,"rmdir ");
a687059c 1522 goto one_liner; /* see above in MKDIR */
1523#endif
1524 case O_GETPPID:
1525 value = (double)getppid();
1526 goto donumset;
1527 case O_GETPGRP:
1528#ifdef GETPGRP
1529 if (maxarg < 1)
1530 anum = 0;
1531 else
1532 anum = (int)str_gnum(st[1]);
1533 value = (double)getpgrp(anum);
1534 goto donumset;
1535#else
1536 fatal("The getpgrp() function is unimplemented on this machine");
1537 break;
1538#endif
1539 case O_SETPGRP:
1540#ifdef SETPGRP
1541 argtype = (int)str_gnum(st[1]);
1542 anum = (int)str_gnum(st[2]);
1543#ifdef TAINT
1544 taintproper("Insecure dependency in setpgrp");
1545#endif
1546 value = (double)(setpgrp(argtype,anum) >= 0);
1547 goto donumset;
1548#else
1549 fatal("The setpgrp() function is unimplemented on this machine");
1550 break;
1551#endif
1552 case O_GETPRIORITY:
1553#ifdef GETPRIORITY
1554 argtype = (int)str_gnum(st[1]);
1555 anum = (int)str_gnum(st[2]);
1556 value = (double)getpriority(argtype,anum);
1557 goto donumset;
1558#else
1559 fatal("The getpriority() function is unimplemented on this machine");
1560 break;
1561#endif
1562 case O_SETPRIORITY:
1563#ifdef SETPRIORITY
1564 argtype = (int)str_gnum(st[1]);
1565 anum = (int)str_gnum(st[2]);
1566 optype = (int)str_gnum(st[3]);
1567#ifdef TAINT
1568 taintproper("Insecure dependency in setpriority");
1569#endif
1570 value = (double)(setpriority(argtype,anum,optype) >= 0);
378cc40b 1571 goto donumset;
a687059c 1572#else
1573 fatal("The setpriority() function is unimplemented on this machine");
1574 break;
1575#endif
1576 case O_CHROOT:
1577 if (maxarg < 1)
1578 tmps = str_get(stab_val(defstab));
1579 else
1580 tmps = str_get(st[1]);
1581#ifdef TAINT
1582 taintproper("Insecure dependency in chroot");
1583#endif
1584 value = (double)(chroot(tmps) >= 0);
1585 goto donumset;
1586 case O_FCNTL:
1587 case O_IOCTL:
1588 if (maxarg <= 0)
1589 stab = last_in_stab;
1590 else if ((arg[1].arg_type & A_MASK) == A_WORD)
1591 stab = arg[1].arg_ptr.arg_stab;
1592 else
1593 stab = stabent(str_get(st[1]),TRUE);
1594 argtype = (int)str_gnum(st[2]);
1595#ifdef TAINT
1596 taintproper("Insecure dependency in ioctl");
1597#endif
1598 anum = do_ctl(optype,stab,argtype,st[3]);
1599 if (anum == -1)
1600 goto say_undef;
1601 if (anum != 0)
1602 goto donumset;
1603 str_set(str,"0 but true");
1604 STABSET(str);
1605 break;
1606 case O_FLOCK:
1607#ifdef FLOCK
1608 if (maxarg <= 0)
1609 stab = last_in_stab;
1610 else if ((arg[1].arg_type & A_MASK) == A_WORD)
1611 stab = arg[1].arg_ptr.arg_stab;
1612 else
1613 stab = stabent(str_get(st[1]),TRUE);
1614 if (stab && stab_io(stab))
1615 fp = stab_io(stab)->ifp;
1616 else
1617 fp = Nullfp;
1618 if (fp) {
1619 argtype = (int)str_gnum(st[2]);
1620 value = (double)(flock(fileno(fp),argtype) >= 0);
1621 }
1622 else
1623 value = 0;
1624 goto donumset;
1625#else
1626 fatal("The flock() function is unimplemented on this machine");
1627 break;
1628#endif
378cc40b 1629 case O_UNSHIFT:
a687059c 1630 ary = stab_array(arg[1].arg_ptr.arg_stab);
1631 if (arglast[2] - arglast[1] != 1)
1632 do_unshift(ary,arglast);
378cc40b 1633 else {
a687059c 1634 str = Str_new(52,0); /* must copy the STR */
1635 str_sset(str,st[2]);
378cc40b 1636 aunshift(ary,1);
a687059c 1637 (void)astore(ary,0,str);
378cc40b 1638 }
1639 value = (double)(ary->ary_fill + 1);
1640 break;
1641 case O_DOFILE:
1642 case O_EVAL:
a687059c 1643 if (maxarg < 1)
1644 tmpstr = stab_val(defstab);
1645 else
1646 tmpstr =
1647 (arg[1].arg_type & A_MASK) != A_NULL ? st[1] : stab_val(defstab);
1648#ifdef TAINT
1649 tainted |= tmpstr->str_tainted;
1650 taintproper("Insecure dependency in eval");
1651#endif
1652 sp = do_eval(tmpstr, optype, arg[2].arg_ptr.arg_hash,
1653 gimme,arglast);
1654 goto array_return;
378cc40b 1655
1656 case O_FTRREAD:
1657 argtype = 0;
1658 anum = S_IREAD;
1659 goto check_perm;
1660 case O_FTRWRITE:
1661 argtype = 0;
1662 anum = S_IWRITE;
1663 goto check_perm;
1664 case O_FTREXEC:
1665 argtype = 0;
1666 anum = S_IEXEC;
1667 goto check_perm;
1668 case O_FTEREAD:
1669 argtype = 1;
1670 anum = S_IREAD;
1671 goto check_perm;
1672 case O_FTEWRITE:
1673 argtype = 1;
1674 anum = S_IWRITE;
1675 goto check_perm;
1676 case O_FTEEXEC:
1677 argtype = 1;
1678 anum = S_IEXEC;
1679 check_perm:
a687059c 1680 if (mystat(arg,st[1]) < 0)
1681 goto say_undef;
1682 if (cando(anum,argtype,&statcache))
1683 goto say_yes;
1684 goto say_no;
378cc40b 1685
1686 case O_FTIS:
a687059c 1687 if (mystat(arg,st[1]) < 0)
1688 goto say_undef;
1689 goto say_yes;
378cc40b 1690 case O_FTEOWNED:
1691 case O_FTROWNED:
a687059c 1692 if (mystat(arg,st[1]) < 0)
1693 goto say_undef;
1694 if (statcache.st_uid == (optype == O_FTEOWNED ? euid : uid) )
1695 goto say_yes;
1696 goto say_no;
378cc40b 1697 case O_FTZERO:
a687059c 1698 if (mystat(arg,st[1]) < 0)
1699 goto say_undef;
1700 if (!statcache.st_size)
1701 goto say_yes;
1702 goto say_no;
378cc40b 1703 case O_FTSIZE:
a687059c 1704 if (mystat(arg,st[1]) < 0)
1705 goto say_undef;
1706 if (statcache.st_size)
1707 goto say_yes;
1708 goto say_no;
378cc40b 1709
1710 case O_FTSOCK:
1711#ifdef S_IFSOCK
1712 anum = S_IFSOCK;
1713 goto check_file_type;
1714#else
a687059c 1715 goto say_no;
378cc40b 1716#endif
1717 case O_FTCHR:
1718 anum = S_IFCHR;
1719 goto check_file_type;
1720 case O_FTBLK:
1721 anum = S_IFBLK;
1722 goto check_file_type;
1723 case O_FTFILE:
1724 anum = S_IFREG;
1725 goto check_file_type;
1726 case O_FTDIR:
1727 anum = S_IFDIR;
1728 check_file_type:
a687059c 1729 if (mystat(arg,st[1]) < 0)
1730 goto say_undef;
1731 if ((statcache.st_mode & S_IFMT) == anum )
1732 goto say_yes;
1733 goto say_no;
378cc40b 1734 case O_FTPIPE:
1735#ifdef S_IFIFO
1736 anum = S_IFIFO;
1737 goto check_file_type;
1738#else
a687059c 1739 goto say_no;
378cc40b 1740#endif
1741 case O_FTLINK:
a687059c 1742#ifdef SYMLINK
1743 if (lstat(str_get(st[1]),&statcache) < 0)
1744 goto say_undef;
1745 if ((statcache.st_mode & S_IFMT) == S_IFLNK )
1746 goto say_yes;
378cc40b 1747#endif
a687059c 1748 goto say_no;
378cc40b 1749 case O_SYMLINK:
1750#ifdef SYMLINK
a687059c 1751 tmps = str_get(st[1]);
1752 tmps2 = str_get(st[2]);
1753#ifdef TAINT
1754 taintproper("Insecure dependency in symlink");
1755#endif
1756 value = (double)(symlink(tmps,tmps2) >= 0);
378cc40b 1757 goto donumset;
1758#else
1759 fatal("Unsupported function symlink()");
1760#endif
a687059c 1761 case O_READLINK:
1762#ifdef SYMLINK
1763 if (maxarg < 1)
1764 tmps = str_get(stab_val(defstab));
1765 else
1766 tmps = str_get(st[1]);
1767 anum = readlink(tmps,buf,sizeof buf);
1768 if (anum < 0)
1769 goto say_undef;
1770 str_nset(str,buf,anum);
1771 break;
1772#else
1773 fatal("Unsupported function readlink()");
1774#endif
378cc40b 1775 case O_FTSUID:
1776 anum = S_ISUID;
1777 goto check_xid;
1778 case O_FTSGID:
1779 anum = S_ISGID;
1780 goto check_xid;
1781 case O_FTSVTX:
1782 anum = S_ISVTX;
1783 check_xid:
a687059c 1784 if (mystat(arg,st[1]) < 0)
1785 goto say_undef;
1786 if (statcache.st_mode & anum)
1787 goto say_yes;
1788 goto say_no;
378cc40b 1789 case O_FTTTY:
a687059c 1790 if (arg[1].arg_type & A_DONT) {
378cc40b 1791 stab = arg[1].arg_ptr.arg_stab;
1792 tmps = "";
1793 }
1794 else
a687059c 1795 stab = stabent(tmps = str_get(st[1]),FALSE);
1796 if (stab && stab_io(stab) && stab_io(stab)->ifp)
1797 anum = fileno(stab_io(stab)->ifp);
378cc40b 1798 else if (isdigit(*tmps))
1799 anum = atoi(tmps);
1800 else
a687059c 1801 goto say_undef;
378cc40b 1802 if (isatty(anum))
a687059c 1803 goto say_yes;
1804 goto say_no;
378cc40b 1805 case O_FTTEXT:
1806 case O_FTBINARY:
a687059c 1807 str = do_fttext(arg,st[1]);
378cc40b 1808 break;
a687059c 1809#ifdef SOCKET
1810 case O_SOCKET:
1811 if ((arg[1].arg_type & A_MASK) == A_WORD)
1812 stab = arg[1].arg_ptr.arg_stab;
1813 else
1814 stab = stabent(str_get(st[1]),TRUE);
1815#ifndef lint
1816 value = (double)do_socket(stab,arglast);
1817#else
1818 (void)do_socket(stab,arglast);
1819#endif
1820 goto donumset;
1821 case O_BIND:
1822 if ((arg[1].arg_type & A_MASK) == A_WORD)
1823 stab = arg[1].arg_ptr.arg_stab;
1824 else
1825 stab = stabent(str_get(st[1]),TRUE);
1826#ifndef lint
1827 value = (double)do_bind(stab,arglast);
1828#else
1829 (void)do_bind(stab,arglast);
1830#endif
1831 goto donumset;
1832 case O_CONNECT:
1833 if ((arg[1].arg_type & A_MASK) == A_WORD)
1834 stab = arg[1].arg_ptr.arg_stab;
1835 else
1836 stab = stabent(str_get(st[1]),TRUE);
1837#ifndef lint
1838 value = (double)do_connect(stab,arglast);
1839#else
1840 (void)do_connect(stab,arglast);
1841#endif
1842 goto donumset;
1843 case O_LISTEN:
1844 if ((arg[1].arg_type & A_MASK) == A_WORD)
1845 stab = arg[1].arg_ptr.arg_stab;
1846 else
1847 stab = stabent(str_get(st[1]),TRUE);
1848#ifndef lint
1849 value = (double)do_listen(stab,arglast);
1850#else
1851 (void)do_listen(stab,arglast);
1852#endif
1853 goto donumset;
1854 case O_ACCEPT:
1855 if ((arg[1].arg_type & A_MASK) == A_WORD)
1856 stab = arg[1].arg_ptr.arg_stab;
1857 else
1858 stab = stabent(str_get(st[1]),TRUE);
1859 if ((arg[2].arg_type & A_MASK) == A_WORD)
1860 stab2 = arg[2].arg_ptr.arg_stab;
1861 else
1862 stab2 = stabent(str_get(st[2]),TRUE);
1863 do_accept(str,stab,stab2);
1864 STABSET(str);
1865 break;
1866 case O_GHBYNAME:
1867 if (maxarg < 1)
1868 goto say_undef;
1869 case O_GHBYADDR:
1870 case O_GHOSTENT:
1871 sp = do_ghent(optype,
1872 gimme,arglast);
1873 goto array_return;
1874 case O_GNBYNAME:
1875 if (maxarg < 1)
1876 goto say_undef;
1877 case O_GNBYADDR:
1878 case O_GNETENT:
1879 sp = do_gnent(optype,
1880 gimme,arglast);
1881 goto array_return;
1882 case O_GPBYNAME:
1883 if (maxarg < 1)
1884 goto say_undef;
1885 case O_GPBYNUMBER:
1886 case O_GPROTOENT:
1887 sp = do_gpent(optype,
1888 gimme,arglast);
1889 goto array_return;
1890 case O_GSBYNAME:
1891 if (maxarg < 1)
1892 goto say_undef;
1893 case O_GSBYPORT:
1894 case O_GSERVENT:
1895 sp = do_gsent(optype,
1896 gimme,arglast);
1897 goto array_return;
1898 case O_SHOSTENT:
1899 value = (double) sethostent((int)str_gnum(st[1]));
1900 goto donumset;
1901 case O_SNETENT:
1902 value = (double) setnetent((int)str_gnum(st[1]));
1903 goto donumset;
1904 case O_SPROTOENT:
1905 value = (double) setprotoent((int)str_gnum(st[1]));
1906 goto donumset;
1907 case O_SSERVENT:
1908 value = (double) setservent((int)str_gnum(st[1]));
1909 goto donumset;
1910 case O_EHOSTENT:
1911 value = (double) endhostent();
1912 goto donumset;
1913 case O_ENETENT:
1914 value = (double) endnetent();
1915 goto donumset;
1916 case O_EPROTOENT:
1917 value = (double) endprotoent();
1918 goto donumset;
1919 case O_ESERVENT:
1920 value = (double) endservent();
1921 goto donumset;
1922 case O_SSELECT:
1923 sp = do_select(gimme,arglast);
1924 goto array_return;
1925 case O_SOCKETPAIR:
1926 if ((arg[1].arg_type & A_MASK) == A_WORD)
1927 stab = arg[1].arg_ptr.arg_stab;
1928 else
1929 stab = stabent(str_get(st[1]),TRUE);
1930 if ((arg[2].arg_type & A_MASK) == A_WORD)
1931 stab2 = arg[2].arg_ptr.arg_stab;
1932 else
1933 stab2 = stabent(str_get(st[2]),TRUE);
1934#ifndef lint
1935 value = (double)do_spair(stab,stab2,arglast);
1936#else
1937 (void)do_spair(stab,stab2,arglast);
1938#endif
1939 goto donumset;
1940 case O_SHUTDOWN:
1941 if ((arg[1].arg_type & A_MASK) == A_WORD)
1942 stab = arg[1].arg_ptr.arg_stab;
1943 else
1944 stab = stabent(str_get(st[1]),TRUE);
1945#ifndef lint
1946 value = (double)do_shutdown(stab,arglast);
1947#else
1948 (void)do_shutdown(stab,arglast);
1949#endif
1950 goto donumset;
1951 case O_GSOCKOPT:
1952 case O_SSOCKOPT:
1953 if ((arg[1].arg_type & A_MASK) == A_WORD)
1954 stab = arg[1].arg_ptr.arg_stab;
1955 else
1956 stab = stabent(str_get(st[1]),TRUE);
1957 sp = do_sopt(optype,stab,arglast);
1958 goto array_return;
1959 case O_GETSOCKNAME:
1960 case O_GETPEERNAME:
1961 if ((arg[1].arg_type & A_MASK) == A_WORD)
1962 stab = arg[1].arg_ptr.arg_stab;
1963 else
1964 stab = stabent(str_get(st[1]),TRUE);
1965 sp = do_getsockname(optype,stab,arglast);
1966 goto array_return;
1967
1968#else /* SOCKET not defined */
1969 case O_SOCKET:
1970 case O_BIND:
1971 case O_CONNECT:
1972 case O_LISTEN:
1973 case O_ACCEPT:
1974 case O_SSELECT:
1975 case O_SOCKETPAIR:
1976 case O_GHBYNAME:
1977 case O_GHBYADDR:
1978 case O_GHOSTENT:
1979 case O_GNBYNAME:
1980 case O_GNBYADDR:
1981 case O_GNETENT:
1982 case O_GPBYNAME:
1983 case O_GPBYNUMBER:
1984 case O_GPROTOENT:
1985 case O_GSBYNAME:
1986 case O_GSBYPORT:
1987 case O_GSERVENT:
1988 case O_SHOSTENT:
1989 case O_SNETENT:
1990 case O_SPROTOENT:
1991 case O_SSERVENT:
1992 case O_EHOSTENT:
1993 case O_ENETENT:
1994 case O_EPROTOENT:
1995 case O_ESERVENT:
1996 case O_SHUTDOWN:
1997 case O_GSOCKOPT:
1998 case O_SSOCKOPT:
1999 case O_GETSOCKNAME:
2000 case O_GETPEERNAME:
2001 badsock:
2002 fatal("Unsupported socket function");
2003#endif /* SOCKET */
2004 case O_FILENO:
bf38876a 2005 if (maxarg < 1)
2006 goto say_undef;
a687059c 2007 if ((arg[1].arg_type & A_MASK) == A_WORD)
2008 stab = arg[1].arg_ptr.arg_stab;
2009 else
2010 stab = stabent(str_get(st[1]),TRUE);
2011 if (!stab || !(stio = stab_io(stab)) || !(fp = stio->ifp))
2012 goto say_undef;
2013 value = fileno(fp);
2014 goto donumset;
2015 case O_VEC:
2016 sp = do_vec(str == st[1], arg->arg_ptr.arg_str, arglast);
2017 goto array_return;
2018 case O_GPWNAM:
2019 case O_GPWUID:
2020 case O_GPWENT:
2021 sp = do_gpwent(optype,
2022 gimme,arglast);
2023 goto array_return;
2024 case O_SPWENT:
2025 value = (double) setpwent();
2026 goto donumset;
2027 case O_EPWENT:
2028 value = (double) endpwent();
2029 goto donumset;
2030 case O_GGRNAM:
2031 case O_GGRGID:
2032 case O_GGRENT:
2033 sp = do_ggrent(optype,
2034 gimme,arglast);
2035 goto array_return;
2036 case O_SGRENT:
2037 value = (double) setgrent();
2038 goto donumset;
2039 case O_EGRENT:
2040 value = (double) endgrent();
2041 goto donumset;
2042 case O_GETLOGIN:
2043 if (!(tmps = getlogin()))
2044 goto say_undef;
2045 str_set(str,tmps);
2046 break;
2047 case O_OPENDIR:
2048 case O_READDIR:
2049 case O_TELLDIR:
2050 case O_SEEKDIR:
2051 case O_REWINDDIR:
2052 case O_CLOSEDIR:
bf38876a 2053 if (maxarg < 1)
2054 goto say_undef;
a687059c 2055 if ((arg[1].arg_type & A_MASK) == A_WORD)
2056 stab = arg[1].arg_ptr.arg_stab;
2057 else
2058 stab = stabent(str_get(st[1]),TRUE);
2059 sp = do_dirop(optype,stab,gimme,arglast);
2060 goto array_return;
2061 case O_SYSCALL:
2062 value = (double)do_syscall(arglast);
2063 goto donumset;
378cc40b 2064 }
a687059c 2065
2066 normal_return:
2067 st[1] = str;
378cc40b 2068#ifdef DEBUGGING
2069 if (debug) {
2070 dlevel--;
2071 if (debug & 8)
2072 deb("%s RETURNS \"%s\"\n",opname[optype],str_get(str));
2073 }
2074#endif
a687059c 2075 return arglast[0] + 1;
378cc40b 2076
2077array_return:
2078#ifdef DEBUGGING
2079 if (debug) {
2080 dlevel--;
2081 if (debug & 8)
a687059c 2082 deb("%s RETURNS ARRAY OF %d ARGS\n",opname[optype],sp - arglast[0]);
378cc40b 2083 }
2084#endif
a687059c 2085 return sp;
2086
2087say_yes:
2088 str = &str_yes;
2089 goto normal_return;
2090
2091say_no:
2092 str = &str_no;
2093 goto normal_return;
2094
2095say_undef:
2096 str = &str_undef;
2097 goto normal_return;
2098
2099say_zero:
2100 value = 0.0;
2101 /* FALL THROUGH */
378cc40b 2102
2103donumset:
2104 str_numset(str,value);
2105 STABSET(str);
a687059c 2106 st[1] = str;
378cc40b 2107#ifdef DEBUGGING
2108 if (debug) {
2109 dlevel--;
2110 if (debug & 8)
2111 deb("%s RETURNS \"%f\"\n",opname[optype],value);
2112 }
2113#endif
a687059c 2114 return arglast[0] + 1;
378cc40b 2115}