1 /* $Header: stab.c,v 3.0.1.10 90/11/10 02:02: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.10 90/11/10 02:02:05 lwall
10 * patch38: random cleanup
12 * Revision 3.0.1.9 90/10/16 10:32:05 lwall
13 * patch29: added -M, -A and -C
14 * patch29: taintperl now checks for world writable PATH components
15 * patch29: *foo now prints as *package'foo
16 * patch29: scripts now run at almost full speed under the debugger
17 * patch29: package behavior is now more consistent
19 * Revision 3.0.1.8 90/08/13 22:30:17 lwall
20 * patch28: the NSIG hack didn't work right on Xenix
22 * Revision 3.0.1.7 90/08/09 05:17:48 lwall
23 * patch19: fixed double include of <signal.h>
24 * patch19: $' broke on embedded nulls
25 * patch19: $< and $> better supported on machines without setreuid
26 * patch19: Added support for linked-in C subroutines
27 * patch19: %ENV wasn't forced to be global like it should
28 * patch19: $| didn't work before the filehandle was opened
29 * patch19: $! now returns "" in string context if errno == 0
31 * Revision 3.0.1.6 90/03/27 16:22:11 lwall
32 * patch16: support for machines that can't cast negative floats to unsigned ints
34 * Revision 3.0.1.5 90/03/12 17:00:11 lwall
35 * patch13: undef $/ didn't work as advertised
37 * Revision 3.0.1.4 90/02/28 18:19:14 lwall
38 * patch9: $0 is now always the command name
39 * patch9: you may now undef $/ to have no input record separator
40 * patch9: local($.) didn't work
41 * patch9: sometimes perl thought ordinary data was a symbol table entry
42 * patch9: stab_array() and stab_hash() weren't defined on MICROPORT
44 * Revision 3.0.1.3 89/12/21 20:18:40 lwall
45 * patch7: ANSI strerror() is now supported
46 * patch7: errno may now be a macro with an lvalue
47 * patch7: in stab.c, sighandler() may now return either void or int
49 * Revision 3.0.1.2 89/11/17 15:35:37 lwall
50 * patch5: sighandler() needed to be static
52 * Revision 3.0.1.1 89/11/11 04:55:07 lwall
53 * patch2: sys_errlist[sys_nerr] is illegal
55 * Revision 3.0 89/10/18 15:23:23 lwall
63 #if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
67 static char *sig_name[] = {
72 #define handlertype void
74 #define handlertype int
77 static handlertype sighandler();
83 STAB *stab = str->str_u.str_stab;
89 return stab_val(stab);
91 switch (*stab->str_magic->str_ptr) {
93 str_numset(stab_val(stab),(double)basetime);
95 case '1': case '2': case '3': case '4':
96 case '5': case '6': case '7': case '8': case '9': case '&':
98 paren = atoi(stab_name(stab));
100 if (curspat->spat_regexp &&
101 paren <= curspat->spat_regexp->nparens &&
102 (s = curspat->spat_regexp->startp[paren]) ) {
103 i = curspat->spat_regexp->endp[paren] - s;
105 str_nset(stab_val(stab),s,i);
107 str_sset(stab_val(stab),&str_undef);
110 str_sset(stab_val(stab),&str_undef);
115 paren = curspat->spat_regexp->lastparen;
121 if (curspat->spat_regexp &&
122 (s = curspat->spat_regexp->subbase) ) {
123 i = curspat->spat_regexp->startp[0] - s;
125 str_nset(stab_val(stab),s,i);
127 str_nset(stab_val(stab),"",0);
130 str_nset(stab_val(stab),"",0);
135 if (curspat->spat_regexp &&
136 (s = curspat->spat_regexp->endp[0]) ) {
137 str_nset(stab_val(stab),s, curspat->spat_regexp->subend - s);
140 str_nset(stab_val(stab),"",0);
146 str_numset(stab_val(stab),(double)stab_io(last_in_stab)->lines);
151 str_numset(stab_val(stab),(double)statusvalue);
154 s = stab_io(curoutstab)->top_name;
155 str_set(stab_val(stab),s);
158 s = stab_io(curoutstab)->fmt_name;
159 str_set(stab_val(stab),s);
163 str_numset(stab_val(stab),(double)stab_io(curoutstab)->page_len);
166 str_numset(stab_val(stab),(double)stab_io(curoutstab)->lines_left);
169 str_numset(stab_val(stab),(double)stab_io(curoutstab)->page);
173 if (record_separator != 12345) {
174 *tokenbuf = record_separator;
176 str_nset(stab_val(stab),tokenbuf,rslen);
180 str_numset(stab_val(stab),(double)arybase);
183 if (!stab_io(curoutstab))
184 stab_io(curoutstab) = stio_new();
185 str_numset(stab_val(stab),
186 (double)((stab_io(curoutstab)->flags & IOF_FLUSH) != 0) );
189 str_nset(stab_val(stab),ofs,ofslen);
192 str_nset(stab_val(stab),ors,orslen);
195 str_set(stab_val(stab),ofmt);
198 str_numset(stab_val(stab), (double)errno);
199 str_set(stab_val(stab), errno ? strerror(errno) : "");
200 stab_val(stab)->str_nok = 1; /* what a wonderful hack! */
203 str_numset(stab_val(stab),(double)uid);
206 str_numset(stab_val(stab),(double)euid);
210 (void)sprintf(s,"%d",(int)gid);
214 (void)sprintf(s,"%d",(int)egid);
222 GIDTYPE gary[NGROUPS];
224 i = getgroups(NGROUPS,gary);
226 (void)sprintf(s," %ld", (long)gary[i]);
231 str_set(stab_val(stab),buf);
235 struct ufuncs *uf = (struct ufuncs *)str->str_ptr;
237 if (uf && uf->uf_val)
238 (*uf->uf_val)(uf->uf_index, stab_val(stab));
242 return stab_val(stab);
249 STAB *stab = mstr->str_u.str_stab;
253 switch (mstr->str_rare) {
255 setenv(mstr->str_ptr,str_get(str));
256 /* And you'll never guess what the dog had */
257 /* in its mouth... */
259 if (strEQ(mstr->str_ptr,"PATH")) {
260 char *strend = str->str_ptr + str->str_cur;
264 s = cpytill(tokenbuf,s,strend,':',&i);
267 || (stat(tokenbuf,&statbuf) && (statbuf.st_mode & 2)) )
268 str->str_tainted = 2;
275 i = whichsig(mstr->str_ptr); /* ...no, a brick */
276 if (strEQ(s,"IGNORE"))
278 (void)signal(i,SIG_IGN);
282 else if (strEQ(s,"DEFAULT") || !*s)
283 (void)signal(i,SIG_DFL);
285 (void)signal(i,sighandler);
286 if (!index(s,'\'')) {
287 sprintf(tokenbuf, "main'%s",s);
288 str_set(str,tokenbuf);
294 hdbmstore(stab_hash(stab),mstr->str_ptr,mstr->str_cur,str);
302 str = afetch(stab_xarray(stab),atoi(mstr->str_ptr), FALSE);
303 cmd = str->str_magic->str_u.str_cmd;
304 cmd->c_flags &= ~CF_OPTIMIZE;
305 cmd->c_flags |= i? CFT_D1 : CFT_D0;
309 afill(stab_array(stab), (int)str_gnum(str) - arybase);
311 case 'X': /* merely a copy of a * string */
315 if (strNE(s,"StB") || str->str_cur != sizeof(STBP)) {
319 (void)savenostab(stab); /* schedule a free of this stab */
321 Safefree(stab->str_ptr);
322 Newz(601,stbp, 1, STBP);
323 stab->str_ptr = stbp;
324 stab->str_len = stab->str_cur = sizeof(STBP);
326 strcpy(stab_magic(stab),"StB");
327 stab_val(stab) = Str_new(70,0);
328 stab_line(stab) = curcmd->c_line;
331 stab = stabent(s,TRUE);
332 if (!stab_xarray(stab))
334 if (!stab_xhash(stab))
337 stab_io(stab) = stio_new();
343 struct lstring *lstr = (struct lstring*)str;
346 str->str_magic = Nullstr;
347 str_insert(mstr,lstr->lstr_offset,lstr->lstr_len,
348 str->str_ptr,str->str_cur);
357 switch (*stab->str_magic->str_ptr) {
358 case '\024': /* ^T */
359 basetime = (long)str_gnum(str);
363 savesptr((STR**)&last_in_stab);
366 Safefree(stab_io(curoutstab)->top_name);
367 stab_io(curoutstab)->top_name = s = savestr(str_get(str));
368 stab_io(curoutstab)->top_stab = stabent(s,TRUE);
371 Safefree(stab_io(curoutstab)->fmt_name);
372 stab_io(curoutstab)->fmt_name = s = savestr(str_get(str));
373 stab_io(curoutstab)->fmt_stab = stabent(s,TRUE);
376 stab_io(curoutstab)->page_len = (long)str_gnum(str);
379 stab_io(curoutstab)->lines_left = (long)str_gnum(str);
380 if (stab_io(curoutstab)->lines_left < 0L)
381 stab_io(curoutstab)->lines_left = 0L;
384 stab_io(curoutstab)->page = (long)str_gnum(str);
387 if (!stab_io(curoutstab))
388 stab_io(curoutstab) = stio_new();
389 stab_io(curoutstab)->flags &= ~IOF_FLUSH;
390 if (str_gnum(str) != 0.0) {
391 stab_io(curoutstab)->flags |= IOF_FLUSH;
395 i = (int)str_gnum(str);
396 multiline = (i != 0);
400 record_separator = *str_get(str);
401 rslen = str->str_cur;
404 record_separator = 12345; /* fake a non-existent char */
411 ors = savestr(str_get(str));
412 orslen = str->str_cur;
417 ofs = savestr(str_get(str));
418 ofslen = str->str_cur;
423 ofmt = savestr(str_get(str));
426 arybase = (int)str_gnum(str);
429 statusvalue = U_S(str_gnum(str));
432 errno = (int)str_gnum(str); /* will anyone ever use this? */
435 uid = (int)str_gnum(str);
438 delaymagic |= DM_REUID;
439 break; /* don't do magic till later */
441 #endif /* SETREUID */
443 if (setruid((UIDTYPE)uid) < 0)
447 if (setreuid((UIDTYPE)uid, (UIDTYPE)-1) < 0)
450 if (uid == euid) /* special case $< = $> */
453 fatal("setruid() not implemented");
458 euid = (int)str_gnum(str);
461 delaymagic |= DM_REUID;
462 break; /* don't do magic till later */
464 #endif /* SETREUID */
466 if (seteuid((UIDTYPE)euid) < 0)
467 euid = (int)geteuid();
470 if (setreuid((UIDTYPE)-1, (UIDTYPE)euid) < 0)
471 euid = (int)geteuid();
473 if (euid == uid) /* special case $> = $< */
476 fatal("seteuid() not implemented");
481 gid = (int)str_gnum(str);
484 delaymagic |= DM_REGID;
485 break; /* don't do magic till later */
487 #endif /* SETREGID */
489 (void)setrgid((GIDTYPE)gid);
492 (void)setregid((GIDTYPE)gid, (GIDTYPE)-1);
494 fatal("setrgid() not implemented");
499 egid = (int)str_gnum(str);
502 delaymagic |= DM_REGID;
503 break; /* don't do magic till later */
505 #endif /* SETREGID */
507 (void)setegid((GIDTYPE)egid);
510 (void)setregid((GIDTYPE)-1, (GIDTYPE)egid);
512 fatal("setegid() not implemented");
517 chopset = str_get(str);
521 struct ufuncs *uf = (struct ufuncs *)str->str_magic->str_ptr;
523 if (uf && uf->uf_set)
524 (*uf->uf_set)(uf->uf_index, str);
535 register char **sigv;
537 for (sigv = sig_name+1; *sigv; sigv++)
538 if (strEQ(sig,*sigv))
539 return sigv - sig_name;
541 if (strEQ(sig,"CHLD"))
545 if (strEQ(sig,"CLD"))
558 CMD *oldcurcmd = curcmd;
559 int oldsave = savestack->ary_fill;
560 ARRAY *oldstack = stack;
561 CSV *oldcurcsv = curcsv;
564 #ifdef OS2 /* or anybody else who requires SIG_ACK */
565 signal(sig, SIG_ACK);
569 str_get(hfetch(stab_hash(sigstab),sig_name[sig],strlen(sig_name[sig]),
571 sub = stab_sub(stab);
572 if (!sub && *sig_name[sig] == 'C' && instr(sig_name[sig],"LD")) {
573 if (sig_name[sig][1] == 'H')
574 stab = stabent(str_get(hfetch(stab_hash(sigstab),"CLD",3,TRUE)),
577 stab = stabent(str_get(hfetch(stab_hash(sigstab),"CHLD",4,TRUE)),
579 sub = stab_sub(stab); /* gag */
583 warn("SIG%s handler \"%s\" not defined.\n",
584 sig_name[sig], stab_name(stab) );
587 savearray = stab_xarray(defstab);
588 stab_xarray(defstab) = stack = anew(defstab);
589 stack->ary_flags = 0;
591 str_set(str,sig_name[sig]);
592 (void)apush(stab_xarray(defstab),str);
594 if (sub->depth >= 2) { /* save temporaries on recursion? */
595 if (sub->depth == 100 && dowarn)
596 warn("Deep recursion on subroutine \"%s\"",stab_name(stab));
597 savelist(sub->tosave->ary_array,sub->tosave->ary_fill);
600 (void)cmd_exec(sub->cmd,G_SCALAR,1); /* so do it already */
602 sub->depth--; /* assuming no longjumps out of here */
603 str_free(stack->ary_array[0]); /* free the one real string */
604 afree(stab_xarray(defstab)); /* put back old $_[] */
605 stab_xarray(defstab) = savearray;
607 if (savestack->ary_fill > oldsave)
608 restorelist(oldsave);
617 if (!stab_xarray(stab))
618 stab_xarray(stab) = anew(stab);
626 if (!stab_xhash(stab))
627 stab_xhash(stab) = hnew(COEFFSIZE);
638 sprintf(tmpbuf,"'_<%s", name);
639 stab = stabent(tmpbuf, TRUE);
640 str_set(stab_val(stab), name);
642 (void)hadd(aadd(stab));
654 register char *namend;
656 char *sawquote = Nullch;
657 char *prevquote = Nullch;
660 if (isascii(*name) && isupper(*name)) {
662 if (*name == 'S' && (
663 strEQ(name, "SIG") ||
664 strEQ(name, "STDIN") ||
665 strEQ(name, "STDOUT") ||
666 strEQ(name, "STDERR") ))
669 else if (*name > 'E') {
670 if (*name == 'I' && strEQ(name, "INC"))
673 else if (*name > 'A') {
674 if (*name == 'E' && strEQ(name, "ENV"))
677 else if (*name == 'A' && (
678 strEQ(name, "ARGV") ||
679 strEQ(name, "ARGVOUT") ))
682 for (namend = name; *namend; namend++) {
683 if (*namend == '\'' && namend[1])
684 prevquote = sawquote, sawquote = namend;
686 if (sawquote == name && name[1]) {
691 else if (!isalpha(*name) || global)
693 else if (curcmd == &compiling)
696 stash = curcmd->c_stash;
703 strncpy(tmpbuf,name,s-name+1);
704 d = tmpbuf+(s-name+1);
710 strcpy(tmpbuf+1,name);
712 stab = stabent(tmpbuf,TRUE);
713 if (!(stash = stab_xhash(stab)))
714 stash = stab_xhash(stab) = hnew(0);
715 if (!stash->tbl_name)
716 stash->tbl_name = savestr(name);
721 stab = (STAB*)hfetch(stash,name,len,add);
722 if (stab == (STAB*)&str_undef)
725 stab->str_pok |= SP_MULTI;
730 Safefree(stab->str_ptr);
731 Newz(602,stbp, 1, STBP);
732 stab->str_ptr = stbp;
733 stab->str_len = stab->str_cur = sizeof(STBP);
735 strcpy(stab_magic(stab),"StB");
736 stab_val(stab) = Str_new(72,0);
737 stab_line(stab) = curcmd->c_line;
738 str_magic(stab,stab,'*',name,len);
739 stab_stash(stab) = stash;
744 stab_fullname(str,stab)
748 str_set(str,stab_stash(stab)->tbl_name);
749 str_ncat(str,"'", 1);
750 str_scat(str,stab->str_magic);
758 Newz(603,stio,1,STIO);
767 register HENT *entry;
771 for (i = min; i <= max; i++) {
772 for (entry = defstash->tbl_array[i]; entry; entry = entry->hent_next) {
773 stab = (STAB*)entry->hent_val;
774 if (stab->str_pok & SP_MULTI)
776 curcmd->c_line = stab_line(stab);
777 warn("Possible typo: \"%s\"", stab_name(stab));
782 static int gensym = 0;
787 (void)sprintf(tokenbuf,"_GEN_%d",gensym++);
788 return stabent(tokenbuf,TRUE);
791 /* hopefully this is only called on local symbol table entries */
800 afree(stab_xarray(stab));
801 (void)hfree(stab_xhash(stab), FALSE);
802 str_free(stab_val(stab));
803 if (stio = stab_io(stab)) {
804 do_close(stab,FALSE);
805 Safefree(stio->top_name);
806 Safefree(stio->fmt_name);
808 if (sub = stab_sub(stab)) {
812 Safefree(stab->str_ptr);
813 stab->str_ptr = Null(STBP*);
818 #if defined(CRIPPLED_CC) && (defined(iAPX286) || defined(M_I286) || defined(I80286))
822 #ifdef MICROPORT /* Microport 2.4 hack */
823 ARRAY *stab_array(stab)
826 if (((STBP*)(stab->str_ptr))->stbp_array)
827 return ((STBP*)(stab->str_ptr))->stbp_array;
829 return ((STBP*)(aadd(stab)->str_ptr))->stbp_array;
832 HASH *stab_hash(stab)
835 if (((STBP*)(stab->str_ptr))->stbp_hash)
836 return ((STBP*)(stab->str_ptr))->stbp_hash;
838 return ((STBP*)(hadd(stab)->str_ptr))->stbp_hash;
840 #endif /* Microport 2.4 hack */