1 /* $Header: stab.c,v 3.0.1.2 89/11/17 15:35:37 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.2 89/11/17 15:35:37 lwall
10 * patch5: sighandler() needed to be static
12 * Revision 3.0.1.1 89/11/11 04:55:07 lwall
13 * patch2: sys_errlist[sys_nerr] is illegal
15 * Revision 3.0 89/10/18 15:23:23 lwall
25 static char *sig_name[] = {
31 extern char *sys_errlist[];
37 STAB *stab = str->str_u.str_stab;
43 return stab_val(stab);
45 switch (*stab->str_magic->str_ptr) {
46 case '0': case '1': case '2': case '3': case '4':
47 case '5': case '6': case '7': case '8': case '9': case '&':
49 paren = atoi(stab_name(stab));
51 if (curspat->spat_regexp &&
52 paren <= curspat->spat_regexp->nparens &&
53 (s = curspat->spat_regexp->startp[paren]) ) {
54 i = curspat->spat_regexp->endp[paren] - s;
56 str_nset(stab_val(stab),s,i);
58 str_sset(stab_val(stab),&str_undef);
61 str_sset(stab_val(stab),&str_undef);
66 paren = curspat->spat_regexp->lastparen;
72 if (curspat->spat_regexp &&
73 (s = curspat->spat_regexp->subbase) ) {
74 i = curspat->spat_regexp->startp[0] - s;
76 str_nset(stab_val(stab),s,i);
78 str_nset(stab_val(stab),"",0);
81 str_nset(stab_val(stab),"",0);
86 if (curspat->spat_regexp &&
87 (s = curspat->spat_regexp->endp[0]) ) {
88 str_set(stab_val(stab),s);
91 str_nset(stab_val(stab),"",0);
97 str_numset(stab_val(stab),(double)stab_io(last_in_stab)->lines);
102 str_numset(stab_val(stab),(double)statusvalue);
105 s = stab_io(curoutstab)->top_name;
106 str_set(stab_val(stab),s);
109 s = stab_io(curoutstab)->fmt_name;
110 str_set(stab_val(stab),s);
114 str_numset(stab_val(stab),(double)stab_io(curoutstab)->page_len);
117 str_numset(stab_val(stab),(double)stab_io(curoutstab)->lines_left);
120 str_numset(stab_val(stab),(double)stab_io(curoutstab)->page);
124 *tokenbuf = record_separator;
126 str_nset(stab_val(stab),tokenbuf,rslen);
129 str_numset(stab_val(stab),(double)arybase);
132 str_numset(stab_val(stab),
133 (double)((stab_io(curoutstab)->flags & IOF_FLUSH) != 0) );
136 str_nset(stab_val(stab),ofs,ofslen);
139 str_nset(stab_val(stab),ors,orslen);
142 str_set(stab_val(stab),ofmt);
145 str_numset(stab_val(stab), (double)errno);
146 str_set(stab_val(stab),
147 errno < 0 || errno >= sys_nerr ? "(unknown)" : sys_errlist[errno]);
148 stab_val(stab)->str_nok = 1; /* what a wonderful hack! */
151 str_numset(stab_val(stab),(double)uid);
154 str_numset(stab_val(stab),(double)euid);
158 (void)sprintf(s,"%d",(int)gid);
162 (void)sprintf(s,"%d",(int)egid);
170 GIDTYPE gary[NGROUPS];
172 i = getgroups(NGROUPS,gary);
174 (void)sprintf(s," %ld", (long)gary[i]);
179 str_set(stab_val(stab),buf);
182 return stab_val(stab);
189 STAB *stab = mstr->str_u.str_stab;
192 static int sighandler();
194 switch (mstr->str_rare) {
196 setenv(mstr->str_ptr,str_get(str));
197 /* And you'll never guess what the dog had */
198 break; /* in its mouth... */
201 i = whichsig(mstr->str_ptr); /* ...no, a brick */
202 if (strEQ(s,"IGNORE"))
204 (void)signal(i,SIG_IGN);
208 else if (strEQ(s,"DEFAULT") || !*s)
209 (void)signal(i,SIG_DFL);
211 (void)signal(i,sighandler);
215 hdbmstore(stab_hash(stab),mstr->str_ptr,mstr->str_cur,str);
219 afill(stab_array(stab), (int)str_gnum(str) - arybase);
221 case 'X': /* merely a copy of a * string */
225 if (strnNE(s,"Stab",4) || str->str_cur != sizeof(STBP)) {
229 (void)savenostab(stab); /* schedule a free of this stab */
231 Safefree(stab->str_ptr);
232 Newz(601,stbp, 1, STBP);
233 stab->str_ptr = stbp;
234 stab->str_len = stab->str_cur = sizeof(STBP);
236 strncpy(stab_magic(stab),"Stab",4);
237 stab_val(stab) = Str_new(70,0);
238 stab_line(stab) = line;
241 stab = stabent(s,TRUE);
246 struct lstring *lstr = (struct lstring*)str;
249 str->str_magic = Nullstr;
250 str_insert(mstr,lstr->lstr_offset,lstr->lstr_len,
251 str->str_ptr,str->str_cur);
260 switch (*stab->str_magic->str_ptr) {
262 Safefree(stab_io(curoutstab)->top_name);
263 stab_io(curoutstab)->top_name = s = savestr(str_get(str));
264 stab_io(curoutstab)->top_stab = stabent(s,TRUE);
267 Safefree(stab_io(curoutstab)->fmt_name);
268 stab_io(curoutstab)->fmt_name = s = savestr(str_get(str));
269 stab_io(curoutstab)->fmt_stab = stabent(s,TRUE);
272 stab_io(curoutstab)->page_len = (long)str_gnum(str);
275 stab_io(curoutstab)->lines_left = (long)str_gnum(str);
276 if (stab_io(curoutstab)->lines_left < 0L)
277 stab_io(curoutstab)->lines_left = 0L;
280 stab_io(curoutstab)->page = (long)str_gnum(str);
283 stab_io(curoutstab)->flags &= ~IOF_FLUSH;
284 if (str_gnum(str) != 0.0) {
285 stab_io(curoutstab)->flags |= IOF_FLUSH;
289 i = (int)str_gnum(str);
290 multiline = (i != 0);
293 record_separator = *str_get(str);
294 rslen = str->str_cur;
299 ors = savestr(str_get(str));
300 orslen = str->str_cur;
305 ofs = savestr(str_get(str));
306 ofslen = str->str_cur;
311 ofmt = savestr(str_get(str));
314 arybase = (int)str_gnum(str);
317 statusvalue = (unsigned short)str_gnum(str);
320 errno = (int)str_gnum(str); /* will anyone ever use this? */
323 uid = (int)str_gnum(str);
326 delaymagic |= DM_REUID;
327 break; /* don't do magic till later */
329 #endif /* SETREUID */
331 if (setruid((UIDTYPE)uid) < 0)
335 if (setreuid((UIDTYPE)uid, (UIDTYPE)-1) < 0)
338 fatal("setruid() not implemented");
343 euid = (int)str_gnum(str);
346 delaymagic |= DM_REUID;
347 break; /* don't do magic till later */
349 #endif /* SETREUID */
351 if (seteuid((UIDTYPE)euid) < 0)
352 euid = (int)geteuid();
355 if (setreuid((UIDTYPE)-1, (UIDTYPE)euid) < 0)
356 euid = (int)geteuid();
358 fatal("seteuid() not implemented");
363 gid = (int)str_gnum(str);
366 delaymagic |= DM_REGID;
367 break; /* don't do magic till later */
369 #endif /* SETREGID */
371 (void)setrgid((GIDTYPE)gid);
374 (void)setregid((GIDTYPE)gid, (GIDTYPE)-1);
376 fatal("setrgid() not implemented");
381 egid = (int)str_gnum(str);
384 delaymagic |= DM_REGID;
385 break; /* don't do magic till later */
387 #endif /* SETREGID */
389 (void)setegid((GIDTYPE)egid);
392 (void)setregid((GIDTYPE)-1, (GIDTYPE)egid);
394 fatal("setegid() not implemented");
399 chopset = str_get(str);
409 register char **sigv;
411 for (sigv = sig_name+1; *sigv; sigv++)
412 if (strEQ(sig,*sigv))
413 return sigv - sig_name;
415 if (strEQ(sig,"CHLD"))
419 if (strEQ(sig,"CLD"))
432 char *oldfile = filename;
433 int oldsave = savestack->ary_fill;
434 ARRAY *oldstack = stack;
438 str_get(hfetch(stab_hash(sigstab),sig_name[sig],strlen(sig_name[sig]),
440 sub = stab_sub(stab);
441 if (!sub && *sig_name[sig] == 'C' && instr(sig_name[sig],"LD")) {
442 if (sig_name[sig][1] == 'H')
443 stab = stabent(str_get(hfetch(stab_hash(sigstab),"CLD",3,TRUE)),
446 stab = stabent(str_get(hfetch(stab_hash(sigstab),"CHLD",4,TRUE)),
448 sub = stab_sub(stab); /* gag */
452 warn("SIG%s handler \"%s\" not defined.\n",
453 sig_name[sig], stab_name(stab) );
456 savearray = stab_xarray(defstab);
457 stab_xarray(defstab) = stack = anew(defstab);
458 stack->ary_flags = 0;
460 str_set(str,sig_name[sig]);
461 (void)apush(stab_xarray(defstab),str);
463 if (sub->depth >= 2) { /* save temporaries on recursion? */
464 if (sub->depth == 100 && dowarn)
465 warn("Deep recursion on subroutine \"%s\"",stab_name(stab));
466 savelist(sub->tosave->ary_array,sub->tosave->ary_fill);
468 filename = sub->filename;
470 (void)cmd_exec(sub->cmd,G_SCALAR,1); /* so do it already */
472 sub->depth--; /* assuming no longjumps out of here */
473 str_free(stack->ary_array[0]); /* free the one real string */
474 afree(stab_xarray(defstab)); /* put back old $_[] */
475 stab_xarray(defstab) = savearray;
478 if (savestack->ary_fill > oldsave)
479 restorelist(oldsave);
486 if (!stab_xarray(stab))
487 stab_xarray(stab) = anew(stab);
495 if (!stab_xhash(stab))
496 stab_xhash(stab) = hnew(COEFFSIZE);
508 register char *namend;
510 char *sawquote = Nullch;
511 char *prevquote = Nullch;
514 if (isascii(*name) && isupper(*name)) {
516 if (*name == 'S' && (
517 strEQ(name, "SIG") ||
518 strEQ(name, "STDIN") ||
519 strEQ(name, "STDOUT") ||
520 strEQ(name, "STDERR") ))
523 else if (*name > 'E') {
524 if (*name == 'I' && strEQ(name, "INC"))
527 else if (*name >= 'A') {
528 if (*name == 'E' && strEQ(name, "ENV"))
531 else if (*name == 'A' && (
532 strEQ(name, "ARGV") ||
533 strEQ(name, "ARGVOUT") ))
536 for (namend = name; *namend; namend++) {
537 if (*namend == '\'' && namend[1])
538 prevquote = sawquote, sawquote = namend;
540 if (sawquote == name && name[1]) {
545 else if (!isalpha(*name) || global)
555 strncpy(tmpbuf,name,s-name+1);
556 d = tmpbuf+(s-name+1);
562 strcpy(tmpbuf+1,name);
564 stab = stabent(tmpbuf,TRUE);
565 if (!(stash = stab_xhash(stab)))
566 stash = stab_xhash(stab) = hnew(0);
571 stab = (STAB*)hfetch(stash,name,len,add);
575 stab->str_pok |= SP_MULTI;
580 Safefree(stab->str_ptr);
581 Newz(602,stbp, 1, STBP);
582 stab->str_ptr = stbp;
583 stab->str_len = stab->str_cur = sizeof(STBP);
585 strncpy(stab_magic(stab),"Stab",4);
586 stab_val(stab) = Str_new(72,0);
587 stab_line(stab) = line;
588 str_magic(stab,stab,'*',name,len);
598 Newz(603,stio,1,STIO);
607 register HENT *entry;
611 for (i = min; i <= max; i++) {
612 for (entry = defstash->tbl_array[i]; entry; entry = entry->hent_next) {
613 stab = (STAB*)entry->hent_val;
614 if (stab->str_pok & SP_MULTI)
616 line = stab_line(stab);
617 warn("Possible typo: \"%s\"", stab_name(stab));
622 static int gensym = 0;
627 (void)sprintf(tokenbuf,"_GEN_%d",gensym++);
628 return stabent(tokenbuf,TRUE);
631 /* hopefully this is only called on local symbol table entries */
640 afree(stab_xarray(stab));
641 (void)hfree(stab_xhash(stab));
642 str_free(stab_val(stab));
643 if (stio = stab_io(stab)) {
644 do_close(stab,FALSE);
645 Safefree(stio->top_name);
646 Safefree(stio->fmt_name);
648 if (sub = stab_sub(stab)) {
652 Safefree(stab->str_ptr);
653 stab->str_ptr = Null(STBP*);