BSD 4 release
[unix-history] / usr / src / cmd / csh / sh.glob.c
index 04306b2..03ea8c7 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 1979 Regents of the University of California */
+static char *sccsid = "@(#)sh.glob.c 4.1 10/9/80";
 #include "sh.h"
 
 /*
 #include "sh.h"
 
 /*
@@ -20,7 +20,7 @@ char **
 glob(v)
        register char **v;
 {
 glob(v)
        register char **v;
 {
-       char agpath[160];
+       char agpath[BUFSIZ];
        char *agargv[GAVSIZ];
 
        gpath = agpath; gpathp = gpath; *gpathp = 0;
        char *agargv[GAVSIZ];
 
        gpath = agpath; gpathp = gpath; *gpathp = 0;
@@ -89,8 +89,10 @@ acollect(as)
        gpathp = gpath; *gpathp = 0; globbed = 0;
        expand(as);
        if (gargc == ogargc) {
        gpathp = gpath; *gpathp = 0; globbed = 0;
        expand(as);
        if (gargc == ogargc) {
-               if (nonomatch)
+               if (nonomatch) {
                        Gcat(as, "");
                        Gcat(as, "");
+                       sort();
+               }
        } else
                sort();
 }
        } else
                sort();
 }
@@ -154,7 +156,7 @@ expand(as)
                cs++, gpathp++;
        *gpathp = 0;
        if (*oldcs == '{') {
                cs++, gpathp++;
        *gpathp = 0;
        if (*oldcs == '{') {
-               execbrc(cs, 0);
+               execbrc(cs, NOSTR);
                return;
        }
        matchdir(cs);
                return;
        }
        matchdir(cs);
@@ -230,34 +232,38 @@ execbrc(p, s)
        case '{':
                brclev++;
                continue;
        case '{':
                brclev++;
                continue;
+
        case '}':
                if (brclev == 0)
                        goto pend;
                brclev--;
                continue;
        case '}':
                if (brclev == 0)
                        goto pend;
                brclev--;
                continue;
+
        case '[':
                for (pe++; *pe && *pe != ']'; pe++)
                        continue;
                if (!*pe)
                        error("Missing ]");
                continue;
        case '[':
                for (pe++; *pe && *pe != ']'; pe++)
                        continue;
                if (!*pe)
                        error("Missing ]");
                continue;
-
        }
 pend:
        if (brclev || !*pe)
                error("Missing }");
        for (pl = pm = p; pm <= pe; pm++)
        }
 pend:
        if (brclev || !*pe)
                error("Missing }");
        for (pl = pm = p; pm <= pe; pm++)
-       switch (*pm) {
+       switch (*pm & (QUOTE|TRIM)) {
 
        case '{':
                brclev++;
                continue;
 
        case '{':
                brclev++;
                continue;
+
        case '}':
                if (brclev) {
                        brclev--;
                        continue;
                }
                goto doit;
        case '}':
                if (brclev) {
                        brclev--;
                        continue;
                }
                goto doit;
+
+       case ','|QUOTE:
        case ',':
                if (brclev)
                        continue;
        case ',':
                if (brclev)
                        continue;
@@ -277,6 +283,7 @@ doit:
                sort();
                pl = pm + 1;
                continue;
                sort();
                pl = pm + 1;
                continue;
+
        case '[':
                for (pm++; *pm && *pm != ']'; pm++)
                        continue;
        case '[':
                for (pm++; *pm && *pm != ']'; pm++)
                        continue;
@@ -509,6 +516,14 @@ trim(c)
        return (c & TRIM);
 }
 
        return (c & TRIM);
 }
 
+tback(c)
+       char c;
+{
+
+       if (c == '`')
+               gflag = 1;
+}
+
 char *
 globone(str)
        register char *str;
 char *
 globone(str)
        register char *str;
@@ -533,14 +548,15 @@ globone(str)
                else if (*gvp) {
                        setname(str);
                        bferr("Ambiguous");
                else if (*gvp) {
                        setname(str);
                        bferr("Ambiguous");
-               }
+               } else
+                       cp = strip(cp);
 /*
                if (cp == 0 || *gvp) {
                        setname(str);
                        bferr(cp ? "Ambiguous" : "No output");
                }
 */
 /*
                if (cp == 0 || *gvp) {
                        setname(str);
                        bferr(cp ? "Ambiguous" : "No output");
                }
 */
-               xfree(gargv); gargv = 0;
+               xfree((char *)gargv); gargv = 0;
        } else {
                scan(gv, trim);
                cp = savestr(gv[0]);
        } else {
                scan(gv, trim);
                cp = savestr(gv[0]);
@@ -608,25 +624,42 @@ backeval(cp, literal)
        char *cp;
        bool literal;
 {
        char *cp;
        bool literal;
 {
-       int pvec[2], pid;
+       int pvec[2];
        int quoted = (literal || (cp[0] & QUOTE)) ? QUOTE : 0;
        int quoted = (literal || (cp[0] & QUOTE)) ? QUOTE : 0;
-       int (*oldint)();
        char ibuf[BUFSIZ];
        register int icnt = 0, c;
        register char *ip;
        bool hadnl = 0;
        char ibuf[BUFSIZ];
        register int icnt = 0, c;
        register char *ip;
        bool hadnl = 0;
-
-       oldint = signal(SIGINT, SIG_IGN);
+       char *fakecom[2];
+       struct command faket;
+
+       faket.t_dtyp = TCOM;
+       faket.t_dflg = 0;
+       faket.t_dlef = 0;
+       faket.t_drit = 0;
+       faket.t_dspr = 0;
+       faket.t_dcom = fakecom;
+       fakecom[0] = "` ... `";
+       fakecom[1] = 0;
+       /*
+        * We do the psave job to temporarily change the current job
+        * so that the following fork is considered a separate job.
+        * This is so that when backquotes are used in a
+        * builtin function that calls glob the "current job" is not corrupted.
+        * We only need one level of pushed jobs as long as we are sure to
+        * fork here.
+        */
+       psavejob();
+       /*
+        * It would be nicer if we could integrate this redirection more
+        * with the routines in sh.sem.c by doing a fake execute on a builtin
+        * function that was piped out.
+        */
        mypipe(pvec);
        mypipe(pvec);
-       pid = fork();
-       if (pid < 0)
-               bferr("No more processes");
-       if (pid == 0) {
+       if (pfork(&faket, -1) == 0) {
                struct wordent paraml;
                struct command *t;
 
                struct wordent paraml;
                struct command *t;
 
-               child++;
-               signal(SIGINT, oldint);
                close(pvec[0]);
                dmove(pvec[1], 1);
                dmove(SHDIAG, 2);
                close(pvec[0]);
                dmove(pvec[1], 1);
                dmove(SHDIAG, 2);
@@ -638,17 +671,15 @@ backeval(cp, literal)
                if (err)
                        error(err);
                alias(&paraml);
                if (err)
                        error(err);
                alias(&paraml);
-               t = syntax(paraml.next, &paraml);
+               t = syntax(paraml.next, &paraml, 0);
                if (err)
                        error(err);
                if (t)
                        t->t_dflg |= FPAR;
                if (err)
                        error(err);
                if (t)
                        t->t_dflg |= FPAR;
-               execute(t);
+               execute(t, -1);
                exitstat();
        }
                exitstat();
        }
-       cadd(pid, "``");
        xfree(cp);
        xfree(cp);
-       signal(SIGINT, oldint);
        close(pvec[1]);
        do {
                int cnt = 0;
        close(pvec[1]);
        do {
                int cnt = 0;
@@ -698,7 +729,8 @@ backeval(cp, literal)
        printf("also c = %c <%o>\n", c, c);
 #endif
        close(pvec[0]);
        printf("also c = %c <%o>\n", c, c);
 #endif
        close(pvec[0]);
-       pwait(pid);
+       pwait();
+       prestjob();
 }
 
 psave(c)
 }
 
 psave(c)