123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482 |
- /*
- * Do the actual making for make
- *
- * $Header$
- */
- #include <stdio.h>
- #ifdef unix
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <errno.h>
- #endif
- #ifdef eon
- #include <sys/stat.h>
- #include <sys/err.h>
- #endif
- #ifdef os9
- #include <time.h>
- #include <os9.h>
- #include <modes.h>
- #include <direct.h>
- #include <errno.h>
- #endif
- #include "h.h"
- /*
- * Exec a shell that returns exit status correctly (/bin/esh).
- * The standard EON shell returns the process number of the last
- * async command, used by the debugger (ugg).
- * [exec on eon is like a fork+exec on unix]
- */
- int
- dosh(string, shell)
- char * string;
- char * shell;
- {
- int number;
- #ifdef unix
- return system(string);
- #endif
- #ifdef eon
- return ((number = execl(shell, shell,"-c", string, 0)) == -1) ?
- -1: /* couldn't start the shell */
- wait(number); /* return its exit status */
- #endif
- #ifdef os9
- int status, pid;
- strcat(string, "\n");
- if ((number = os9fork(shell, strlen(string), string, 0, 0, 0)) == -1)
- return -1; /* Couldn't start a shell */
- do
- {
- if ((pid = wait(&status)) == -1)
- return -1; /* child already died!?!? */
- } while (pid != number);
- return status;
- #endif
- }
- /*
- * Do commands to make a target
- */
- void
- docmds1(np, lp)
- struct name * np;
- struct line * lp;
- {
- bool ssilent;
- bool signore;
- int estat;
- register char * q;
- register char * p;
- char * shell;
- register struct cmd * cp;
- if (*(shell = getmacro("SHELL")) == '\0')
- #ifdef eon
- shell = ":bin/esh";
- #endif
- #ifdef unix
- shell = "/bin/sh";
- #endif
- #ifdef os9
- shell = "shell";
- #endif
- for (cp = lp->l_cmd; cp; cp = cp->c_next)
- {
- strcpy(str1, cp->c_cmd);
- expand(str1);
- q = str1;
- ssilent = silent;
- signore = ignore;
- while ((*q == '@') || (*q == '-'))
- {
- if (*q == '@') /* Specific silent */
- ssilent = TRUE;
- else /* Specific ignore */
- signore = TRUE;
- q++; /* Not part of the command */
- }
- if (!domake)
- ssilent = 0;
- if (!ssilent)
- fputs(" ", stdout);
- for (p=q; *p; p++)
- {
- if (*p == '\n' && p[1] != '\0')
- {
- *p = ' ';
- if (!ssilent)
- fputs("\\\n", stdout);
- }
- else if (!ssilent)
- putchar(*p);
- }
- if (!ssilent) {
- putchar('\n');
- fflush(stdout);
- }
- if (domake)
- { /* Get the shell to execute it */
- if ((estat = dosh(q, shell)) != 0)
- {
- if (estat == -1)
- fatal("Couldn't execute %s", shell);
- else
- {
- printf("%s: Error code %d", myname, estat);
- if (signore)
- fputs(" (Ignored)\n", stdout);
- else
- {
- putchar('\n');
- if (!(np->n_flag & N_PREC))
- if (unlink(np->n_name) == 0)
- printf("%s: '%s' removed.\n", myname, np->n_name);
- exit(1);
- }
- }
- fflush(stdout);
- }
- }
- }
- }
- docmds(np)
- struct name * np;
- {
- register struct line * lp;
- for (lp = np->n_line; lp; lp = lp->l_next)
- docmds1(np, lp);
- }
- #ifdef os9
- /*
- * Some stuffing around to get the modified time of a file
- * in an os9 file system
- */
- getmdate(fd, tbp)
- struct sgtbuf * tbp;
- {
- struct registers regs;
- static struct fildes fdbuf;
- regs.rg_a = fd;
- regs.rg_b = SS_FD;
- regs.rg_x = &fdbuf;
- regs.rg_y = sizeof (fdbuf);
- if (_os9(I_GETSTT, ®s) == -1)
- {
- errno = regs.rg_b & 0xff;
- return -1;
- }
- if (tbp)
- {
- _strass(tbp, fdbuf.fd_date, sizeof (fdbuf.fd_date));
- tbp->t_second = 0; /* Files are only acurate to mins */
- }
- return 0;
- }
- /*
- * Kludge routine to return an aproximation of how many
- * seconds since 1980. Dates will be in order, but will not
- * be lineer
- */
- time_t
- cnvtime(tbp)
- struct sgtbuf *tbp;
- {
- long acc;
- acc = tbp->t_year - 80; /* Baseyear is 1980 */
- acc = acc * 12 + tbp->t_month;
- acc = acc * 31 + tbp->t_day;
- acc = acc * 24 + tbp->t_hour;
- acc = acc * 60 + tbp->t_minute;
- acc = acc * 60 + tbp->t_second;
- return acc;
- }
- /*
- * Get the current time in the internal format
- */
- time(tp)
- time_t * tp;
- {
- struct sgtbuf tbuf;
- if (getime(&tbuf) < 0)
- return -1;
- if (tp)
- *tp = cnvtime(&tbuf);
- return 0;
- }
- #endif
- /*
- * Get the modification time of a file. If the first
- * doesn't exist, it's modtime is set to 0.
- */
- void
- modtime(np)
- struct name * np;
- {
- #ifdef unix
- struct stat info;
- if (stat(np->n_name, &info) < 0)
- {
- if (errno != ENOENT)
- fatal("Can't open %s; error %d", np->n_name, errno);
- np->n_time = 0L;
- }
- else
- np->n_time = info.st_mtime;
- #endif
- #ifdef eon
- struct stat info;
- int fd;
- if ((fd = open(np->n_name, 0)) < 0)
- {
- if (errno != ER_NOTF)
- fatal("Can't open %s; error %02x", np->n_name, errno);
- np->n_time = 0L;
- }
- else if (getstat(fd, &info) < 0)
- fatal("Can't getstat %s; error %02x", np->n_name, errno);
- else
- np->n_time = info.st_mod;
- close(fd);
- #endif
- #ifdef os9
- struct sgtbuf info;
- int fd;
- if ((fd = open(np->n_name, 0)) < 0)
- {
- if (errno != E_PNNF)
- fatal("Can't open %s; error %02x", np->n_name, errno);
- np->n_time = 0L;
- }
- else if (getmdate(fd, &info) < 0)
- fatal("Can't getstat %s; error %02x", np->n_name, errno);
- else
- np->n_time = cnvtime(&info);
- close(fd);
- #endif
- }
- /*
- * Update the mod time of a file to now.
- */
- void
- touch(np)
- struct name * np;
- {
- char c;
- int fd;
- if (!domake || !silent)
- printf(" touch(%s)\n", np->n_name);
- if (domake)
- {
- #ifdef unix
- long a[2];
- long time();
- a[0] = a[1] = time((long *)0);
- if (utime(np->n_name, &a[0]) < 0)
- printf("%s: '%s' not touched - non-existant\n",
- myname, np->n_name);
- #endif
- #ifdef eon
- if ((fd = open(np->n_name, 0)) < 0)
- printf("%s: '%s' not touched - non-existant\n",
- myname, np->n_name);
- else
- {
- uread(fd, &c, 1, 0);
- uwrite(fd, &c, 1);
- }
- close(fd);
- #endif
- #ifdef os9
- /*
- * Strange that something almost as totally useless
- * as this is easy to do in os9!
- */
- if ((fd = open(np->n_name, S_IWRITE)) < 0)
- printf("%s: '%s' not touched - non-existant\n",
- myname, np->n_name);
- close(fd);
- #endif
- }
- }
- /*
- * Recursive routine to make a target.
- */
- int
- make(np, level)
- struct name * np;
- int level;
- {
- register struct depend * dp;
- register struct line * lp;
- register struct depend * qdp;
- time_t dtime = 1;
- bool didsomething = 0;
- int dynamic = 0;
- if (np->n_flag & N_DONE)
- return 0;
- if (!np->n_time)
- modtime(np); /* Gets modtime of this file */
- if (rules)
- {
- for (lp = np->n_line; lp; lp = lp->l_next)
- if (lp->l_cmd)
- break;
- if (!lp) {
- dyndep(np);
- dynamic = 1;
- }
- }
- if (!(np->n_flag & N_TARG) && np->n_time == 0L)
- fatal("Don't know how to make %s", np->n_name);
- for (qdp = (struct depend *)0, lp = np->n_line; lp; lp = lp->l_next)
- {
- for (dp = lp->l_dep; dp; dp = dp->d_next)
- {
- char *sv = 0;
- if (dynamic) {
- char *s = getmacro("<");
- if (s) {
- sv = malloc((unsigned)(strlen(s)+1));
- if (!sv) {
- fatal("no space for saved $<");
- }
- strcpy(sv, s);
- }
- }
- make(dp->d_name, level+1);
- if (dynamic && sv) {
- setmacro("<", sv, 4);
- free(sv);
- }
- if (np->n_time < dp->d_name->n_time)
- qdp = newdep(dp->d_name, qdp);
- dtime = max(dtime, dp->d_name->n_time);
- }
- if (!quest && (np->n_flag & N_DOUBLE) && (np->n_time < dtime))
- {
- make1(np, lp, qdp); /* free()'s qdp */
- dtime = 1;
- qdp = (struct depend *)0;
- didsomething++;
- }
- }
- np->n_flag |= N_DONE;
- if (quest)
- {
- long t;
- t = np->n_time;
- time(&np->n_time);
- return t < dtime;
- }
- else if (np->n_time < dtime && !(np->n_flag & N_DOUBLE))
- {
- make1(np, (struct line *)0, qdp); /* free()'s qdp */
- time(&np->n_time);
- }
- else if (level == 0 && !didsomething)
- printf("%s: '%s' is up to date\n", myname, np->n_name);
- return 0;
- }
- make1(np, lp, qdp)
- register struct depend * qdp;
- struct line * lp;
- struct name * np;
- {
- register struct depend * dp;
- register char *p;
- char *rindex();
- if (dotouch)
- touch(np);
- else
- {
- strcpy(str1, "");
- for (dp = qdp; dp; dp = qdp)
- {
- if (strlen(str1))
- strcat(str1, " ");
- strcat(str1, dp->d_name->n_name);
- qdp = dp->d_next;
- free((char *)dp);
- }
- setmacro("?", str1, 4);
- setmacro("@", np->n_name, 4);
- p = rindex(np->n_name, '.');
- if (p) *p = 0;
- setmacro("*", np->n_name, 4);
- if (p) *p = '.';
- if (lp) /* lp set if doing a :: rule */
- docmds1(np, lp);
- else
- docmds(np);
- }
- }
|