1 /* $Header: stab.c,v 3.0.1.9 90/10/16 10:32:05 lwall Locked $
3 * Copyright (c) 1989, Larry Wall
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.
9 * Revision 3.0.1.9 90/10/16 10:32:05 lwall
10 * patch29: added -M, -A and -C
11 * patch29: taintperl now checks for world writable PATH components
12 * patch29: *foo now prints as *package'foo
13 * patch29: scripts now run at almost full speed under the debugger
14 * patch29: package behavior is now more consistent
16 * Revision 3.0.1.8 90/08/13 22:30:17 lwall
17 * patch28: the NSIG hack didn't work right on Xenix
19 * Revision 3.0.1.7 90/08/09 05:17:48 lwall
20 * patch19: fixed double include of <signal.h>
21 * patch19: $' broke on embedded nulls
22 * patch19: $< and $> better supported on machines without setreuid
23 * patch19: Added support for linked-in C subroutines
24 * patch19: %ENV wasn't forced to be global like it should
25 * patch19: $| didn't work before the filehandle was opened
26 * patch19: $! now returns "" in string context if errno == 0
28 * Revision 3.0.1.6 90/03/27 16:22:11 lwall
29 * patch16: support for machines that can't cast negative floats to unsigned ints
31 * Revision 3.0.1.5 90/03/12 17:00:11 lwall
32 * patch13: undef $/ didn't work as advertised
34 * Revision 3.0.1.4 90/02/28 18:19:14 lwall
35 * patch9: $0 is now always the command name
36 * patch9: you may now undef $/ to have no input record separator
37 * patch9: local($.) didn't work
38 * patch9: sometimes perl thought ordinary data was a symbol table entry
39 * patch9: stab_array() and stab_hash() weren't defined on MICROPORT
41 * Revision 3.0.1.3 89/12/21 20:18:40 lwall
42 * patch7: ANSI strerror() is now supported
43 * patch7: errno may now be a macro with an lvalue
44 * patch7: in stab.c, sighandler() may now return either void or int
46 * Revision 3.0.1.2 89/11/17 15:35:37 lwall
47 * patch5: sighandler() needed to be static
49 * Revision 3.0.1.1 89/11/11 04:55:07 lwall
50 * patch2: sys_errlist[sys_nerr] is illegal
52 * Revision 3.0 89/10/18 15:23:23 lwall
60 #if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
64 static char *sig_name[] = {
69 #define handlertype void
71 #define handlertype int
78 STAB *stab = str->str_u.str_stab;
84 return stab_val(stab);
86 switch (*stab->str_magic->str_ptr) {
88 str_numset(stab_val(stab),(double)basetime);
90 case '1': case '2': case '3': case '4':
91 case '5': case '6': case '7': case '8': case '9': case '&':
93 paren = atoi(stab_name(stab));
95 if (curspat->spat_regexp &&
96 paren <= curspat->spat_regexp->nparens &&
97 (s = curspat->spat_regexp->startp[paren]) ) {
98 i = curspat->spat_regexp->endp[paren] - s;
100 str_nset(stab_val(stab),s,i);
102 str_sset(stab_val(stab),&str_undef);
105 str_sset(stab_val(stab),&str_undef);
110 paren = curspat->spat_regexp->lastparen;
116 if (curspat->spat_regexp &&
117 (s = curspat->spat_regexp->subbase) ) {
118 i = curspat->spat_regexp->startp[0] - s;
120 str_nset(stab_val(stab),s,i);
122 str_nset(stab_val(stab),"",0);
125 str_nset(stab_val(stab),"",0);
130 if (curspat->spat_regexp &&
131 (s = curspat->spat_regexp->endp[0]) ) {
132 str_nset(stab_val(stab),s, curspat->spat_regexp->subend - s);
135 str_nset(stab_val(stab),"",0);
141 str_numset(stab_val(stab),(double)stab_io(last_in_stab)->lines);
146 str_numset(stab_val(stab),(double)statusvalue);
149 s = stab_io(curoutstab)->top_name;
150 str_set(stab_val(stab),s);
153 s = stab_io(curoutstab)->fmt_name;
154 str_set(stab_val(stab),s);
158 str_numset(stab_val(stab),(double)stab_io(curoutstab)->page_len);
161 str_numset(stab_val(stab),(double)stab_io(curoutstab)->lines_left);
164 str_numset(stab_val(stab),(double)stab_io(curoutstab)->page);
168 if (record_separator != 12345) {
169 *tokenbuf = record_separator;
171 str_nset(stab_val(stab),tokenbuf,rslen);
175 str_numset(stab_val(stab),(double)arybase);
178 if (!stab_io(curoutstab))
179 stab_io(curoutstab) = stio_new();
180 str_numset(stab_val(stab),
181 (double)((stab_io(curoutstab)->flags & IOF_FLUSH) != 0) );
184 str_nset(stab_val(stab),ofs,ofslen);
187 str_nset(stab_val(stab),ors,orslen);
190 str_set(stab_val(stab),ofmt);
193 str_numset(stab_val(stab), (double)errno);
194 str_set(stab_val(stab), errno ? strerror(errno) : "");
195 stab_val(stab)->str_nok = 1; /* what a wonderful hack! */
198 str_numset(stab_val(stab),(double)uid);
201 str_numset(stab_val(stab),(double)euid);
205 (void)sprintf(s,"%d",(int)gid);
209 (void)sprintf(s,"%d",(int)egid);
217 GIDTYPE gary[NGROUPS];
219 i = getgroups(NGROUPS,gary);
221 (void)sprintf(s," %ld", (long)gary[i]);
226 str_set(stab_val(stab),buf);
230 struct ufuncs *uf = (struct ufuncs *)str->str_ptr;
232 if (uf && uf->uf_val)
233 (*uf->uf_val)(uf->uf_index, stab_val(stab));
237 return stab_val(stab);
244 STAB *stab = mstr->str_u.str_stab;
247 static handlertype sighandler();
249 switch (mstr->str_rare) {
251 setenv(mstr->str_ptr,str_get(str));
252 /* And you'll never guess what the dog had */
253 /* in its mouth... */
255 if (strEQ(mstr->str_ptr,"PATH")) {
256 char *strend = str->str_ptr + str->str_cur;
260 s = cpytill(tokenbuf,s,strend,':',&i);
263 || (stat(tokenbuf,&statbuf) && (statbuf.st_mode & 2)) )
264 str->str_tainted = 2;
271 i = whichsig(mstr->str_ptr); /* ...no, a brick */
272 if (strEQ(s,"IGNORE"))
274 (void)signal(i,SIG_IGN);
278 else if (strEQ(s,"DEFAULT") || !*s)
279 (void)signal(i,SIG_DFL);
281 (void)signal(i,sighandler);
282 if (!index(s,'\'')) {
283 sprintf(tokenbuf, "main'%s",s);
284 str_set(str,tokenbuf);
290 hdbmstore(stab_hash(stab),mstr->str_ptr,mstr->str_cur,str);
298 str = afetch(stab_xarray(stab),atoi(mstr->str_ptr));
299 cmd = str->str_magic->str_u.str_cmd;
300 cmd->c_flags &= ~CF_OPTIMIZE;
301 cmd->c_flags |= i? CFT_D1 : CFT_D0;
305 afill(stab_array(stab), (int)str_gnum(str) - arybase);
307 case 'X': /* merely a copy of a * string */
311 if (strNE(s,"StB") || str->str_cur != sizeof(STBP)) {
315 (void)savenostab(stab); /* schedule a free of this stab */
317 Safefree(stab->str_ptr);
318 Newz(601,stbp, 1, STBP);
319 stab->str_ptr = stbp;
320 stab->str_len = stab->str_cur = sizeof(STBP);
322 strcpy(stab_magic(stab),"StB");
323 stab_val(stab) = Str_new(70,0);
324 stab_line(stab) = curcmd->c_line;
327 stab = stabent(s,TRUE);
328 if (!stab_xarray(stab))
330 if (!stab_xhash(stab))
333 stab_io(stab) = stio_new();
339 struct lstring *lstr = (struct lstring*)str;
342 str->str_magic = Nullstr;
343 str_insert(mstr,lstr->lstr_offset,lstr->lstr_len,
344 str->str_ptr,str->str_cur);
353 switch (*stab->str_magic->str_ptr) {
354 case '\024': /* ^T */
355 basetime = (long)str_gnum(str);
359 savesptr((STR**)&last_in_stab);
362 Safefree(stab_io(curoutstab)->top_name);
363 stab_io(curoutstab)->top_name = s = savestr(str_get(str));
364 stab_io(curoutstab)->top_stab = stabent(s,TRUE);
367 Safefree(stab_io(curoutstab)->fmt_name);
368 stab_io(curoutstab)->fmt_name = s = savestr(str_get(str));
369 stab_io(curoutstab)->fmt_stab = stabent(s,TRUE);
372 stab_io(curoutstab)->page_len = (long)str_gnum(str);
375 stab_io(curoutstab)->lines_left = (long)str_gnum(str);
376 if (stab_io(curoutstab)->lines_left < 0L)
377 stab_io(curoutstab)->lines_left = 0L;
380 stab_io(curoutstab)->page = (long)str_gnum(str);
383 if (!stab_io(curoutstab))
384 stab_io(curoutstab) = stio_new();
385 stab_io(curoutstab)->flags &= ~IOF_FLUSH;
386 if (str_gnum(str) != 0.0) {
387 stab_io(curoutstab)->flags |= IOF_FLUSH;
391 i = (int)str_gnum(str);
392 multiline = (i != 0);
396 record_separator = *str_get(str);
397 rslen = str->str_cur;
400 record_separator = 12345; /* fake a non-existent char */
407 ors = savestr(str_get(str));
408 orslen = str->str_cur;
413 ofs = savestr(str_get(str));
414 ofslen = str->str_cur;
419 ofmt = savestr(str_get(str));
422 arybase = (int)str_gnum(str);
425 statusvalue = U_S(str_gnum(str));
428 errno = (int)str_gnum(str); /* will anyone ever use this? */
431 uid = (int)str_gnum(str);
434 delaymagic |= DM_REUID;
435 break; /* don't do magic till later */
437 #endif /* SETREUID */
439 if (setruid((UIDTYPE)uid) < 0)
443 if (setreuid((UIDTYPE)uid, (UIDTYPE)-1) < 0)
446 if (uid == euid) /* special case $< = $> */
449 fatal("setruid() not implemented");
454 euid = (int)str_gnum(str);
457 delaymagic |= DM_REUID;
458 break; /* don't do magic till later */
460 #endif /* SETREUID */
462 if (seteuid((UIDTYPE)euid) < 0)
463 euid = (int)geteuid();
466 if (setreuid((UIDTYPE)-1, (UIDTYPE)euid) < 0)
467 euid = (int)geteuid();
469 if (euid == uid) /* special case $> = $< */
472 fatal("seteuid() not implemented");
477 gid = (int)str_gnum(str);
480 delaymagic |= DM_REGID;
481 break; /* don't do magic till later */
483 #endif /* SETREGID */
485 (void)setrgid((GIDTYPE)gid);
488 (void)setregid((GIDTYPE)gid, (GIDTYPE)-1);
490 fatal("setrgid() not implemented");
495 egid = (int)str_gnum(str);
498 delaymagic |= DM_REGID;
499 break; /* don't do magic till later */
501 #endif /* SETREGID */
503 (void)setegid((GIDTYPE)egid);
506 (void)setregid((GIDTYPE)-1, (GIDTYPE)egid);
508 fatal("setegid() not implemented");
513 chopset = str_get(str);
517 struct ufuncs *uf = (struct ufuncs *)str->str_magic->str_ptr;
519 if (uf && uf->uf_set)
520 (*uf->uf_set)(uf->uf_index, str);
531 register char **sigv;
533 for (sigv = sig_name+1; *sigv; sigv++)
534 if (strEQ(sig,*sigv))
535 return sigv - sig_name;
537 if (strEQ(sig,"CHLD"))
541 if (strEQ(sig,"CLD"))
554 CMD *oldcurcmd = curcmd;
555 int oldsave = savestack->ary_fill;
556 ARRAY *oldstack = stack;
557 CSV *oldcurcsv = curcsv;
560 #ifdef OS2 /* or anybody else who requires SIG_ACK */
561 signal(sig, SIG_ACK);
565 str_get(hfetch(stab_hash(sigstab),sig_name[sig],strlen(sig_name[sig]),
567 sub = stab_sub(stab);
568 if (!sub && *sig_name[sig] == 'C' && instr(sig_name[sig],"LD")) {
569 if (sig_name[sig][1] == 'H')
570 stab = stabent(str_get(hfetch(stab_hash(sigstab),"CLD",3,TRUE)),
573 stab = stabent(str_get(hfetch(stab_hash(sigstab),"CHLD",4,TRUE)),
575 sub = stab_sub(stab); /* gag */
579 warn("SIG%s handler \"%s\" not defined.\n",
580 sig_name[sig], stab_name(stab) );
583 savearray = stab_xarray(defstab);
584 stab_xarray(defstab) = stack = anew(defstab);
585 stack->ary_flags = 0;
587 str_set(str,sig_name[sig]);
588 (void)apush(stab_xarray(defstab),str);
590 if (sub->depth >= 2) { /* save temporaries on recursion? */
591 if (sub->depth == 100 && dowarn)
592 warn("Deep recursion on subroutine \"%s\"",stab_name(stab));
593 savelist(sub->tosave->ary_array,sub->tosave->ary_fill);
596 (void)cmd_exec(sub->cmd,G_SCALAR,1); /* so do it already */
598 sub->depth--; /* assuming no longjumps out of here */
599 str_free(stack->ary_array[0]); /* free the one real string */
600 afree(stab_xarray(defstab)); /* put back old $_[] */
601 stab_xarray(defstab) = savearray;
603 if (savestack->ary_fill > oldsave)
604 restorelist(oldsave);
613 if (!stab_xarray(stab))
614 stab_xarray(stab) = anew(stab);
622 if (!stab_xhash(stab))
623 stab_xhash(stab) = hnew(COEFFSIZE);
634 sprintf(tmpbuf,"'_<%s", name);
635 stab = stabent(tmpbuf, TRUE);
636 str_set(stab_val(stab), name);
638 (void)hadd(aadd(stab));
650 register char *namend;
652 char *sawquote = Nullch;
653 char *prevquote = Nullch;
656 if (isascii(*name) && isupper(*name)) {
658 if (*name == 'S' && (
659 strEQ(name, "SIG") ||
660 strEQ(name, "STDIN") ||
661 strEQ(name, "STDOUT") ||
662 strEQ(name, "STDERR") ))
665 else if (*name > 'E') {
666 if (*name == 'I' && strEQ(name, "INC"))
669 else if (*name > 'A') {
670 if (*name == 'E' && strEQ(name, "ENV"))
673 else if (*name == 'A' && (
674 strEQ(name, "ARGV") ||
675 strEQ(name, "ARGVOUT") ))
678 for (namend = name; *namend; namend++) {
679 if (*namend == '\'' && namend[1])
680 prevquote = sawquote, sawquote = namend;
682 if (sawquote == name && name[1]) {
687 else if (!isalpha(*name) || global)
689 else if (curcmd == &compiling)
692 stash = curcmd->c_stash;
699 strncpy(tmpbuf,name,s-name+1);
700 d = tmpbuf+(s-name+1);
706 strcpy(tmpbuf+1,name);
708 stab = stabent(tmpbuf,TRUE);
709 if (!(stash = stab_xhash(stab)))
710 stash = stab_xhash(stab) = hnew(0);
711 if (!stash->tbl_name)
712 stash->tbl_name = savestr(name);
717 stab = (STAB*)hfetch(stash,name,len,add);
718 if (stab == (STAB*)&str_undef)
721 stab->str_pok |= SP_MULTI;
726 Safefree(stab->str_ptr);
727 Newz(602,stbp, 1, STBP);
728 stab->str_ptr = stbp;
729 stab->str_len = stab->str_cur = sizeof(STBP);
731 strcpy(stab_magic(stab),"StB");
732 stab_val(stab) = Str_new(72,0);
733 stab_line(stab) = curcmd->c_line;
734 str_magic(stab,stab,'*',name,len);
735 stab_stash(stab) = stash;
740 stab_fullname(str,stab)
744 str_set(str,stab_stash(stab)->tbl_name);
745 str_ncat(str,"'", 1);
746 str_scat(str,stab->str_magic);
754 Newz(603,stio,1,STIO);
763 register HENT *entry;
767 for (i = min; i <= max; i++) {
768 for (entry = defstash->tbl_array[i]; entry; entry = entry->hent_next) {
769 stab = (STAB*)entry->hent_val;
770 if (stab->str_pok & SP_MULTI)
772 curcmd->c_line = stab_line(stab);
773 warn("Possible typo: \"%s\"", stab_name(stab));
778 static int gensym = 0;
783 (void)sprintf(tokenbuf,"_GEN_%d",gensym++);
784 return stabent(tokenbuf,TRUE);
787 /* hopefully this is only called on local symbol table entries */
796 afree(stab_xarray(stab));
797 (void)hfree(stab_xhash(stab), FALSE);
798 str_free(stab_val(stab));
799 if (stio = stab_io(stab)) {
800 do_close(stab,FALSE);
801 Safefree(stio->top_name);
802 Safefree(stio->fmt_name);
804 if (sub = stab_sub(stab)) {
808 Safefree(stab->str_ptr);
809 stab->str_ptr = Null(STBP*);
814 #if defined(CRIPPLED_CC) && (defined(iAPX286) || defined(M_I286) || defined(I80286))
818 #ifdef MICROPORT /* Microport 2.4 hack */
819 ARRAY *stab_array(stab)
822 if (((STBP*)(stab->str_ptr))->stbp_array)
823 return ((STBP*)(stab->str_ptr))->stbp_array;
825 return ((STBP*)(aadd(stab)->str_ptr))->stbp_array;
828 HASH *stab_hash(stab)
831 if (((STBP*)(stab->str_ptr))->stbp_hash)
832 return ((STBP*)(stab->str_ptr))->stbp_hash;
834 return ((STBP*)(hadd(stab)->str_ptr))->stbp_hash;
836 #endif /* Microport 2.4 hack */