17c478bd9Sstevel@tonic-gate /*
2*6c02b4a4Smuffin * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
37c478bd9Sstevel@tonic-gate * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate */
57c478bd9Sstevel@tonic-gate
67c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
77c478bd9Sstevel@tonic-gate /* All Rights Reserved */
87c478bd9Sstevel@tonic-gate
97c478bd9Sstevel@tonic-gate /*
107c478bd9Sstevel@tonic-gate * Copyright (c) 1980 Regents of the University of California.
117c478bd9Sstevel@tonic-gate * All rights reserved. The Berkeley Software License Agreement
127c478bd9Sstevel@tonic-gate * specifies the terms and conditions for redistribution.
137c478bd9Sstevel@tonic-gate */
147c478bd9Sstevel@tonic-gate
157c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
167c478bd9Sstevel@tonic-gate
177c478bd9Sstevel@tonic-gate #include "sh.h"
187c478bd9Sstevel@tonic-gate #include <locale.h>
197c478bd9Sstevel@tonic-gate #include <dirent.h>
20*6c02b4a4Smuffin #include <string.h>
217c478bd9Sstevel@tonic-gate /*
227c478bd9Sstevel@tonic-gate * #include <sys/ioctl.h>
237c478bd9Sstevel@tonic-gate * #include <stdlib.h>
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate #include "sh.tconst.h"
267c478bd9Sstevel@tonic-gate /*
277c478bd9Sstevel@tonic-gate * C Shell
287c478bd9Sstevel@tonic-gate */
297c478bd9Sstevel@tonic-gate
307c478bd9Sstevel@tonic-gate
317c478bd9Sstevel@tonic-gate bool errspl; /* Argument to error was spliced by seterr2 */
327c478bd9Sstevel@tonic-gate tchar one[2] = { '1', 0 };
337c478bd9Sstevel@tonic-gate tchar *onev[2] = { one, NOSTR };
347c478bd9Sstevel@tonic-gate /*
357c478bd9Sstevel@tonic-gate * contains DIR * for last opendir_(), its left open if an error
367c478bd9Sstevel@tonic-gate * longjmp (reset) occurs before it gets closed via closedir.
377c478bd9Sstevel@tonic-gate * if its not null in the error handler, then closedir it.
387c478bd9Sstevel@tonic-gate */
397c478bd9Sstevel@tonic-gate DIR *Dirp = NULL;
407c478bd9Sstevel@tonic-gate
417c478bd9Sstevel@tonic-gate /*
427c478bd9Sstevel@tonic-gate * Print error string s with optional argument arg.
437c478bd9Sstevel@tonic-gate * This routine always resets or exits. The flag haderr
447c478bd9Sstevel@tonic-gate * is set so the routine who catches the unwind can propogate
457c478bd9Sstevel@tonic-gate * it if they want.
467c478bd9Sstevel@tonic-gate *
477c478bd9Sstevel@tonic-gate * Note that any open files at the point of error will eventually
487c478bd9Sstevel@tonic-gate * be closed in the routine process in sh.c which is the only
497c478bd9Sstevel@tonic-gate * place error unwinds are ever caught.
507c478bd9Sstevel@tonic-gate */
517c478bd9Sstevel@tonic-gate /*VARARGS1*/
52*6c02b4a4Smuffin void
error(s,a1,a2)537c478bd9Sstevel@tonic-gate error(s, a1, a2)
547c478bd9Sstevel@tonic-gate char *s;
557c478bd9Sstevel@tonic-gate {
56*6c02b4a4Smuffin tchar **v;
57*6c02b4a4Smuffin char *ep;
587c478bd9Sstevel@tonic-gate
597c478bd9Sstevel@tonic-gate /*
607c478bd9Sstevel@tonic-gate * Must flush before we print as we wish output before the error
617c478bd9Sstevel@tonic-gate * to go on (some form of) standard output, while output after
627c478bd9Sstevel@tonic-gate * goes on (some form of) diagnostic output.
637c478bd9Sstevel@tonic-gate * If didfds then output will go to 1/2 else to FSHOUT/FSHDIAG.
647c478bd9Sstevel@tonic-gate * See flush in sh.print.c.
657c478bd9Sstevel@tonic-gate */
667c478bd9Sstevel@tonic-gate flush();
677c478bd9Sstevel@tonic-gate haderr = 1; /* Now to diagnostic output */
687c478bd9Sstevel@tonic-gate timflg = 0; /* This isn't otherwise reset */
697c478bd9Sstevel@tonic-gate if (v = pargv)
707c478bd9Sstevel@tonic-gate pargv = 0, blkfree(v);
717c478bd9Sstevel@tonic-gate if (v = gargv)
727c478bd9Sstevel@tonic-gate gargv = 0, blkfree(v);
737c478bd9Sstevel@tonic-gate
747c478bd9Sstevel@tonic-gate /*
757c478bd9Sstevel@tonic-gate * A zero arguments causes no printing, else print
767c478bd9Sstevel@tonic-gate * an error diagnostic here.
777c478bd9Sstevel@tonic-gate */
787c478bd9Sstevel@tonic-gate if (s) {
797c478bd9Sstevel@tonic-gate printf(s, a1, a2), printf("\n");
807c478bd9Sstevel@tonic-gate }
817c478bd9Sstevel@tonic-gate
827c478bd9Sstevel@tonic-gate
837c478bd9Sstevel@tonic-gate didfds = 0; /* Forget about 0,1,2 */
847c478bd9Sstevel@tonic-gate if ((ep = err) && errspl) {
857c478bd9Sstevel@tonic-gate errspl = 0;
867c478bd9Sstevel@tonic-gate xfree(ep);
877c478bd9Sstevel@tonic-gate }
887c478bd9Sstevel@tonic-gate errspl = 0;
897c478bd9Sstevel@tonic-gate
907c478bd9Sstevel@tonic-gate if ( Dirp ){
917c478bd9Sstevel@tonic-gate closedir(Dirp);
927c478bd9Sstevel@tonic-gate Dirp = NULL;
937c478bd9Sstevel@tonic-gate }
947c478bd9Sstevel@tonic-gate
957c478bd9Sstevel@tonic-gate /*
967c478bd9Sstevel@tonic-gate * Go away if -e or we are a child shell
977c478bd9Sstevel@tonic-gate */
987c478bd9Sstevel@tonic-gate if (exiterr || child) {
997c478bd9Sstevel@tonic-gate exit(1);
1007c478bd9Sstevel@tonic-gate }
1017c478bd9Sstevel@tonic-gate
1027c478bd9Sstevel@tonic-gate /*
1037c478bd9Sstevel@tonic-gate * Reset the state of the input.
1047c478bd9Sstevel@tonic-gate * This buffered seek to end of file will also
1057c478bd9Sstevel@tonic-gate * clear the while/foreach stack.
1067c478bd9Sstevel@tonic-gate */
1077c478bd9Sstevel@tonic-gate btoeof();
1087c478bd9Sstevel@tonic-gate
1097c478bd9Sstevel@tonic-gate setq(S_status, onev, &shvhed);
1107c478bd9Sstevel@tonic-gate if (tpgrp > 0)
1117c478bd9Sstevel@tonic-gate (void) ioctl(FSHTTY, TIOCSPGRP, (char *)&tpgrp);
1127c478bd9Sstevel@tonic-gate reset(); /* Unwind */
1137c478bd9Sstevel@tonic-gate }
1147c478bd9Sstevel@tonic-gate
1157c478bd9Sstevel@tonic-gate /*
1167c478bd9Sstevel@tonic-gate * Perror is the shells version of perror which should otherwise
1177c478bd9Sstevel@tonic-gate * never be called.
1187c478bd9Sstevel@tonic-gate */
119*6c02b4a4Smuffin void
Perror(tchar * s)120*6c02b4a4Smuffin Perror(tchar *s)
1217c478bd9Sstevel@tonic-gate {
1227c478bd9Sstevel@tonic-gate char chbuf[BUFSIZ];
1237c478bd9Sstevel@tonic-gate
1247c478bd9Sstevel@tonic-gate /*
1257c478bd9Sstevel@tonic-gate * Perror uses unit 2, thus if we didn't set up the fd's
1267c478bd9Sstevel@tonic-gate * we must set up unit 2 now else the diagnostic will disappear
1277c478bd9Sstevel@tonic-gate */
1287c478bd9Sstevel@tonic-gate if (!didfds) {
129*6c02b4a4Smuffin int oerrno = errno;
1307c478bd9Sstevel@tonic-gate
1317c478bd9Sstevel@tonic-gate (void) dcopy(SHDIAG, 2);
1327c478bd9Sstevel@tonic-gate errno = oerrno;
1337c478bd9Sstevel@tonic-gate }
1347c478bd9Sstevel@tonic-gate tstostr(chbuf, s);
1357c478bd9Sstevel@tonic-gate perror(chbuf);
1367c478bd9Sstevel@tonic-gate error(NULL); /* To exit or unwind */
1377c478bd9Sstevel@tonic-gate }
1387c478bd9Sstevel@tonic-gate
139*6c02b4a4Smuffin void
bferr(char * cp)140*6c02b4a4Smuffin bferr(char *cp)
1417c478bd9Sstevel@tonic-gate {
1427c478bd9Sstevel@tonic-gate
1437c478bd9Sstevel@tonic-gate flush();
1447c478bd9Sstevel@tonic-gate haderr = 1;
1457c478bd9Sstevel@tonic-gate if( bname) printf("%t: ", bname);
1467c478bd9Sstevel@tonic-gate error("%s", gettext(cp));
1477c478bd9Sstevel@tonic-gate }
1487c478bd9Sstevel@tonic-gate
1497c478bd9Sstevel@tonic-gate /*
1507c478bd9Sstevel@tonic-gate * The parser and scanner set up errors for later by calling seterr,
1517c478bd9Sstevel@tonic-gate * which sets the variable err as a side effect; later to be tested,
1527c478bd9Sstevel@tonic-gate * e.g. in process.
1537c478bd9Sstevel@tonic-gate */
154*6c02b4a4Smuffin void
seterr(char * s)155*6c02b4a4Smuffin seterr(char *s)
1567c478bd9Sstevel@tonic-gate {
1577c478bd9Sstevel@tonic-gate
1587c478bd9Sstevel@tonic-gate if (err == 0)
1597c478bd9Sstevel@tonic-gate err = s, errspl = 0;
1607c478bd9Sstevel@tonic-gate }
1617c478bd9Sstevel@tonic-gate
1627c478bd9Sstevel@tonic-gate /* Set err to a splice of cp and dp, to be freed later in error() */
163*6c02b4a4Smuffin void
seterr2(tchar * cp,char * dp)164*6c02b4a4Smuffin seterr2(tchar *cp, char *dp)
1657c478bd9Sstevel@tonic-gate {
1667c478bd9Sstevel@tonic-gate char chbuf[BUFSIZ];
1677c478bd9Sstevel@tonic-gate char *gdp;
1687c478bd9Sstevel@tonic-gate
1697c478bd9Sstevel@tonic-gate if (err)
1707c478bd9Sstevel@tonic-gate return;
1717c478bd9Sstevel@tonic-gate
1727c478bd9Sstevel@tonic-gate /* Concatinate cp and dp in the allocated space. */
1737c478bd9Sstevel@tonic-gate tstostr(chbuf, cp);
1747c478bd9Sstevel@tonic-gate gdp = gettext(dp);
1757c478bd9Sstevel@tonic-gate err = (char *)xalloc(strlen(chbuf)+strlen(gdp)+1);
1767c478bd9Sstevel@tonic-gate strcpy(err, chbuf);
1777c478bd9Sstevel@tonic-gate strcat(err, gdp);
1787c478bd9Sstevel@tonic-gate
1797c478bd9Sstevel@tonic-gate errspl++;/* Remember to xfree(err). */
1807c478bd9Sstevel@tonic-gate }
1817c478bd9Sstevel@tonic-gate
1827c478bd9Sstevel@tonic-gate /* Set err to a splice of cp with a string form of character d */
183*6c02b4a4Smuffin void
seterrc(char * cp,tchar d)184*6c02b4a4Smuffin seterrc(char *cp, tchar d)
1857c478bd9Sstevel@tonic-gate {
1867c478bd9Sstevel@tonic-gate char chbuf[MB_LEN_MAX+1];
1877c478bd9Sstevel@tonic-gate
1887c478bd9Sstevel@tonic-gate /* don't overwrite an existing error message */
1897c478bd9Sstevel@tonic-gate if (err)
1907c478bd9Sstevel@tonic-gate return;
1917c478bd9Sstevel@tonic-gate
1927c478bd9Sstevel@tonic-gate #ifdef MBCHAR
1937c478bd9Sstevel@tonic-gate {
1947c478bd9Sstevel@tonic-gate wchar_t wcd=(wchar_t)(d&TRIM);
1957c478bd9Sstevel@tonic-gate int i;
1967c478bd9Sstevel@tonic-gate
1977c478bd9Sstevel@tonic-gate i = wctomb(chbuf, wcd); /* chbuf holds d in multibyte representation. */
1987c478bd9Sstevel@tonic-gate chbuf[(i>0)?i:0] = (char) 0;
1997c478bd9Sstevel@tonic-gate }
2007c478bd9Sstevel@tonic-gate #else
2017c478bd9Sstevel@tonic-gate chbuf[0]=(char)(d&TRIM); chbuf[1]=(char)0;
2027c478bd9Sstevel@tonic-gate #endif
2037c478bd9Sstevel@tonic-gate
2047c478bd9Sstevel@tonic-gate
2057c478bd9Sstevel@tonic-gate /* Concatinate cp and d in the allocated space. */
2067c478bd9Sstevel@tonic-gate err = (char *)xalloc(strlen(cp)+strlen(chbuf)+1);
2077c478bd9Sstevel@tonic-gate strcpy(err, cp);
2087c478bd9Sstevel@tonic-gate strcat(err, chbuf);
2097c478bd9Sstevel@tonic-gate
2107c478bd9Sstevel@tonic-gate errspl++; /* Remember to xfree(err). */
2117c478bd9Sstevel@tonic-gate }
212