1 /* $Header: stab.c,v 3.0.1.8 90/08/13 22:30:17 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.8 90/08/13 22:30:17 lwall
10 * patch28: the NSIG hack didn't work right on Xenix
12 * Revision 3.0.1.7 90/08/09 05:17:48 lwall
13 * patch19: fixed double include of <signal.h>
14 * patch19: $' broke on embedded nulls
15 * patch19: $< and $> better supported on machines without setreuid
16 * patch19: Added support for linked-in C subroutines
17 * patch19: %ENV wasn't forced to be global like it should
18 * patch19: $| didn't work before the filehandle was opened
19 * patch19: $! now returns "" in string context if errno == 0
21 * Revision 3.0.1.6 90/03/27 16:22:11 lwall
22 * patch16: support for machines that can't cast negative floats to unsigned ints
24 * Revision 3.0.1.5 90/03/12 17:00:11 lwall
25 * patch13: undef $/ didn't work as advertised
27 * Revision 3.0.1.4 90/02/28 18:19:14 lwall
28 * patch9: $0 is now always the command name
29 * patch9: you may now undef $/ to have no input record separator
30 * patch9: local($.) didn't work
31 * patch9: sometimes perl thought ordinary data was a symbol table entry
32 * patch9: stab_array() and stab_hash() weren't defined on MICROPORT
34 * Revision 3.0.1.3 89/12/21 20:18:40 lwall
35 * patch7: ANSI strerror() is now supported
36 * patch7: errno may now be a macro with an lvalue
37 * patch7: in stab.c, sighandler() may now return either void or int
39 * Revision 3.0.1.2 89/11/17 15:35:37 lwall
40 * patch5: sighandler() needed to be static
42 * Revision 3.0.1.1 89/11/11 04:55:07 lwall
43 * patch2: sys_errlist[sys_nerr] is illegal
45 * Revision 3.0 89/10/18 15:23:23 lwall
53 #if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
57 static char *sig_name[] = {
62 #define handlertype void
64 #define handlertype int
71 STAB *stab = str->str_u.str_stab;
77 return stab_val(stab);
79 switch (*stab->str_magic->str_ptr) {
80 case '1': case '2': case '3': case '4':
81 case '5': case '6': case '7': case '8': case '9': case '&':
83 paren = atoi(stab_name(stab));
85 if (curspat->spat_regexp &&
86 paren <= curspat->spat_regexp->nparens &&
87 (s = curspat->spat_regexp->startp[paren]) ) {
88 i = curspat->spat_regexp->endp[paren] - s;
90 str_nset(stab_val(stab),s,i);
92 str_sset(stab_val(stab),&str_undef);
95 str_sset(stab_val(stab),&str_undef);
100 paren = curspat->spat_regexp->lastparen;
106 if (curspat->spat_regexp &&
107 (s = curspat->spat_regexp->subbase) ) {
108 i = curspat->spat_regexp->startp[0] - s;
110 str_nset(stab_val(stab),s,i);
112 str_nset(stab_val(stab),"",0);
115 str_nset(stab_val(stab),"",0);
120 if (curspat->spat_regexp &&
121 (s = curspat->spat_regexp->endp[0]) ) {
122 str_nset(stab_val(stab),s, curspat->spat_regexp->subend - s);
125 str_nset(stab_val(stab),"",0);
131 str_numset(stab_val(stab),(double)stab_io(last_in_stab)->lines);
136 str_numset(stab_val(stab),(double)statusvalue);
139 s = stab_io(curoutstab)->top_name;
140 str_set(stab_val(stab),s);
143 s = stab_io(curoutstab)->fmt_name;
144 str_set(stab_val(stab),s);
148 str_numset(stab_val(stab),(double)stab_io(curoutstab)->page_len);
151 str_numset(stab_val(stab),(double)stab_io(curoutstab)->lines_left);
154 str_numset(stab_val(stab),(double)stab_io(curoutstab)->page);
158 if (record_separator != 12345) {
159 *tokenbuf = record_separator;
161 str_nset(stab_val(stab),tokenbuf,rslen);
165 str_numset(stab_val(stab),(double)arybase);
168 if (!stab_io(curoutstab))
169 stab_io(curoutstab) = stio_new();
170 str_numset(stab_val(stab),
171 (double)((stab_io(curoutstab)->flags & IOF_FLUSH) != 0) );
174 str_nset(stab_val(stab),ofs,ofslen);
177 str_nset(stab_val(stab),ors,orslen);
180 str_set(stab_val(stab),ofmt);
183 str_numset(stab_val(stab), (double)errno);
184 str_set(stab_val(stab), errno ? strerror(errno) : "");
185 stab_val(stab)->str_nok = 1; /* what a wonderful hack! */
188 str_numset(stab_val(stab),(double)uid);
191 str_numset(stab_val(stab),(double)euid);
195 (void)sprintf(s,"%d",(int)gid);
199 (void)sprintf(s,"%d",(int)egid);
207 GIDTYPE gary[NGROUPS];
209 i = getgroups(NGROUPS,gary);
211 (void)sprintf(s," %ld", (long)gary[i]);
216 str_set(stab_val(stab),buf);
220 struct ufuncs *uf = (struct ufuncs *)str->str_ptr;
222 if (uf && uf->uf_val)
223 uf->uf_val(uf->uf_index, stab_val(stab));
227 return stab_val(stab);
234 STAB *stab = mstr->str_u.str_stab;
237 static handlertype sighandler();
239 switch (mstr->str_rare) {
241 setenv(mstr->str_ptr,str_get(str));
242 /* And you'll never guess what the dog had */
243 break; /* in its mouth... */
246 i = whichsig(mstr->str_ptr); /* ...no, a brick */
247 if (strEQ(s,"IGNORE"))
249 (void)signal(i,SIG_IGN);
253 else if (strEQ(s,"DEFAULT") || !*s)
254 (void)signal(i,SIG_DFL);
256 (void)signal(i,sighandler);
260 hdbmstore(stab_hash(stab),mstr->str_ptr,mstr->str_cur,str);
264 afill(stab_array(stab), (int)str_gnum(str) - arybase);
266 case 'X': /* merely a copy of a * string */
270 if (strNE(s,"StB") || str->str_cur != sizeof(STBP)) {
274 (void)savenostab(stab); /* schedule a free of this stab */
276 Safefree(stab->str_ptr);
277 Newz(601,stbp, 1, STBP);
278 stab->str_ptr = stbp;
279 stab->str_len = stab->str_cur = sizeof(STBP);
281 strcpy(stab_magic(stab),"StB");
282 stab_val(stab) = Str_new(70,0);
283 stab_line(stab) = curcmd->c_line;
286 stab = stabent(s,TRUE);
287 if (!stab_xarray(stab))
289 if (!stab_xhash(stab))
292 stab_io(stab) = stio_new();
298 struct lstring *lstr = (struct lstring*)str;
301 str->str_magic = Nullstr;
302 str_insert(mstr,lstr->lstr_offset,lstr->lstr_len,
303 str->str_ptr,str->str_cur);
312 switch (*stab->str_magic->str_ptr) {
315 savesptr((STR**)&last_in_stab);
318 Safefree(stab_io(curoutstab)->top_name);
319 stab_io(curoutstab)->top_name = s = savestr(str_get(str));
320 stab_io(curoutstab)->top_stab = stabent(s,TRUE);
323 Safefree(stab_io(curoutstab)->fmt_name);
324 stab_io(curoutstab)->fmt_name = s = savestr(str_get(str));
325 stab_io(curoutstab)->fmt_stab = stabent(s,TRUE);
328 stab_io(curoutstab)->page_len = (long)str_gnum(str);
331 stab_io(curoutstab)->lines_left = (long)str_gnum(str);
332 if (stab_io(curoutstab)->lines_left < 0L)
333 stab_io(curoutstab)->lines_left = 0L;
336 stab_io(curoutstab)->page = (long)str_gnum(str);
339 if (!stab_io(curoutstab))
340 stab_io(curoutstab) = stio_new();
341 stab_io(curoutstab)->flags &= ~IOF_FLUSH;
342 if (str_gnum(str) != 0.0) {
343 stab_io(curoutstab)->flags |= IOF_FLUSH;
347 i = (int)str_gnum(str);
348 multiline = (i != 0);
352 record_separator = *str_get(str);
353 rslen = str->str_cur;
356 record_separator = 12345; /* fake a non-existent char */
363 ors = savestr(str_get(str));
364 orslen = str->str_cur;
369 ofs = savestr(str_get(str));
370 ofslen = str->str_cur;
375 ofmt = savestr(str_get(str));
378 arybase = (int)str_gnum(str);
381 statusvalue = U_S(str_gnum(str));
384 errno = (int)str_gnum(str); /* will anyone ever use this? */
387 uid = (int)str_gnum(str);
390 delaymagic |= DM_REUID;
391 break; /* don't do magic till later */
393 #endif /* SETREUID */
395 if (setruid((UIDTYPE)uid) < 0)
399 if (setreuid((UIDTYPE)uid, (UIDTYPE)-1) < 0)
402 if (uid == euid) /* special case $< = $> */
405 fatal("setruid() not implemented");
410 euid = (int)str_gnum(str);
413 delaymagic |= DM_REUID;
414 break; /* don't do magic till later */
416 #endif /* SETREUID */
418 if (seteuid((UIDTYPE)euid) < 0)
419 euid = (int)geteuid();
422 if (setreuid((UIDTYPE)-1, (UIDTYPE)euid) < 0)
423 euid = (int)geteuid();
425 if (euid == uid) /* special case $> = $< */
428 fatal("seteuid() not implemented");
433 gid = (int)str_gnum(str);
436 delaymagic |= DM_REGID;
437 break; /* don't do magic till later */
439 #endif /* SETREGID */
441 (void)setrgid((GIDTYPE)gid);
444 (void)setregid((GIDTYPE)gid, (GIDTYPE)-1);
446 fatal("setrgid() not implemented");
451 egid = (int)str_gnum(str);
454 delaymagic |= DM_REGID;
455 break; /* don't do magic till later */
457 #endif /* SETREGID */
459 (void)setegid((GIDTYPE)egid);
462 (void)setregid((GIDTYPE)-1, (GIDTYPE)egid);
464 fatal("setegid() not implemented");
469 chopset = str_get(str);
473 struct ufuncs *uf = (struct ufuncs *)str->str_magic->str_ptr;
475 if (uf && uf->uf_set)
476 uf->uf_set(uf->uf_index, str);
487 register char **sigv;
489 for (sigv = sig_name+1; *sigv; sigv++)
490 if (strEQ(sig,*sigv))
491 return sigv - sig_name;
493 if (strEQ(sig,"CHLD"))
497 if (strEQ(sig,"CLD"))
510 char *oldfile = filename;
511 int oldsave = savestack->ary_fill;
512 ARRAY *oldstack = stack;
515 #ifdef OS2 /* or anybody else who requires SIG_ACK */
516 signal(sig, SIG_ACK);
519 str_get(hfetch(stab_hash(sigstab),sig_name[sig],strlen(sig_name[sig]),
521 sub = stab_sub(stab);
522 if (!sub && *sig_name[sig] == 'C' && instr(sig_name[sig],"LD")) {
523 if (sig_name[sig][1] == 'H')
524 stab = stabent(str_get(hfetch(stab_hash(sigstab),"CLD",3,TRUE)),
527 stab = stabent(str_get(hfetch(stab_hash(sigstab),"CHLD",4,TRUE)),
529 sub = stab_sub(stab); /* gag */
533 warn("SIG%s handler \"%s\" not defined.\n",
534 sig_name[sig], stab_name(stab) );
537 savearray = stab_xarray(defstab);
538 stab_xarray(defstab) = stack = anew(defstab);
539 stack->ary_flags = 0;
541 str_set(str,sig_name[sig]);
542 (void)apush(stab_xarray(defstab),str);
544 if (sub->depth >= 2) { /* save temporaries on recursion? */
545 if (sub->depth == 100 && dowarn)
546 warn("Deep recursion on subroutine \"%s\"",stab_name(stab));
547 savelist(sub->tosave->ary_array,sub->tosave->ary_fill);
549 filename = sub->filename;
551 (void)cmd_exec(sub->cmd,G_SCALAR,1); /* so do it already */
553 sub->depth--; /* assuming no longjumps out of here */
554 str_free(stack->ary_array[0]); /* free the one real string */
555 afree(stab_xarray(defstab)); /* put back old $_[] */
556 stab_xarray(defstab) = savearray;
559 if (savestack->ary_fill > oldsave)
560 restorelist(oldsave);
567 if (!stab_xarray(stab))
568 stab_xarray(stab) = anew(stab);
576 if (!stab_xhash(stab))
577 stab_xhash(stab) = hnew(COEFFSIZE);
589 register char *namend;
591 char *sawquote = Nullch;
592 char *prevquote = Nullch;
595 if (isascii(*name) && isupper(*name)) {
597 if (*name == 'S' && (
598 strEQ(name, "SIG") ||
599 strEQ(name, "STDIN") ||
600 strEQ(name, "STDOUT") ||
601 strEQ(name, "STDERR") ))
604 else if (*name > 'E') {
605 if (*name == 'I' && strEQ(name, "INC"))
608 else if (*name > 'A') {
609 if (*name == 'E' && strEQ(name, "ENV"))
612 else if (*name == 'A' && (
613 strEQ(name, "ARGV") ||
614 strEQ(name, "ARGVOUT") ))
617 for (namend = name; *namend; namend++) {
618 if (*namend == '\'' && namend[1])
619 prevquote = sawquote, sawquote = namend;
621 if (sawquote == name && name[1]) {
626 else if (!isalpha(*name) || global)
636 strncpy(tmpbuf,name,s-name+1);
637 d = tmpbuf+(s-name+1);
643 strcpy(tmpbuf+1,name);
645 stab = stabent(tmpbuf,TRUE);
646 if (!(stash = stab_xhash(stab)))
647 stash = stab_xhash(stab) = hnew(0);
652 stab = (STAB*)hfetch(stash,name,len,add);
656 stab->str_pok |= SP_MULTI;
661 Safefree(stab->str_ptr);
662 Newz(602,stbp, 1, STBP);
663 stab->str_ptr = stbp;
664 stab->str_len = stab->str_cur = sizeof(STBP);
666 strcpy(stab_magic(stab),"StB");
667 stab_val(stab) = Str_new(72,0);
668 stab_line(stab) = curcmd->c_line;
669 str_magic(stab,stab,'*',name,len);
679 Newz(603,stio,1,STIO);
688 register HENT *entry;
692 for (i = min; i <= max; i++) {
693 for (entry = defstash->tbl_array[i]; entry; entry = entry->hent_next) {
694 stab = (STAB*)entry->hent_val;
695 if (stab->str_pok & SP_MULTI)
697 curcmd->c_line = stab_line(stab);
698 warn("Possible typo: \"%s\"", stab_name(stab));
703 static int gensym = 0;
708 (void)sprintf(tokenbuf,"_GEN_%d",gensym++);
709 return stabent(tokenbuf,TRUE);
712 /* hopefully this is only called on local symbol table entries */
721 afree(stab_xarray(stab));
722 (void)hfree(stab_xhash(stab));
723 str_free(stab_val(stab));
724 if (stio = stab_io(stab)) {
725 do_close(stab,FALSE);
726 Safefree(stio->top_name);
727 Safefree(stio->fmt_name);
729 if (sub = stab_sub(stab)) {
733 Safefree(stab->str_ptr);
734 stab->str_ptr = Null(STBP*);
739 #if defined(CRIPPLED_CC) && (defined(iAPX286) || defined(M_I286) || defined(I80286))
743 #ifdef MICROPORT /* Microport 2.4 hack */
744 ARRAY *stab_array(stab)
747 if (((STBP*)(stab->str_ptr))->stbp_array)
748 return ((STBP*)(stab->str_ptr))->stbp_array;
750 return ((STBP*)(aadd(stab)->str_ptr))->stbp_array;
753 HASH *stab_hash(stab)
756 if (((STBP*)(stab->str_ptr))->stbp_hash)
757 return ((STBP*)(stab->str_ptr))->stbp_hash;
759 return ((STBP*)(hadd(stab)->str_ptr))->stbp_hash;
761 #endif /* Microport 2.4 hack */