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