Initial revision
This commit is contained in:
parent
ed7c8e8d02
commit
76193d7cb0
223 changed files with 32479 additions and 0 deletions
306
src/cmd/mk/unix.c
Normal file
306
src/cmd/mk/unix.c
Normal file
|
|
@ -0,0 +1,306 @@
|
|||
#include "mk.h"
|
||||
#include <sys/wait.h>
|
||||
#include <signal.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
char *shell = "/bin/sh";
|
||||
char *shellname = "sh";
|
||||
|
||||
extern char **environ;
|
||||
|
||||
static void
|
||||
mkperror(char *s)
|
||||
{
|
||||
fprint(2, "%s: %r\n", s);
|
||||
}
|
||||
|
||||
void
|
||||
readenv(void)
|
||||
{
|
||||
char **p, *s;
|
||||
Word *w;
|
||||
|
||||
for(p = environ; *p; p++){
|
||||
s = shname(*p);
|
||||
if(*s == '=') {
|
||||
*s = 0;
|
||||
w = newword(s+1);
|
||||
} else
|
||||
w = newword("");
|
||||
if (symlook(*p, S_INTERNAL, 0))
|
||||
continue;
|
||||
s = strdup(*p);
|
||||
setvar(s, (void *)w);
|
||||
symlook(s, S_EXPORTED, (void*)"")->value = (void*)"";
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* done on child side of fork, so parent's env is not affected
|
||||
* and we don't care about freeing memory because we're going
|
||||
* to exec immediately after this.
|
||||
*/
|
||||
void
|
||||
exportenv(Envy *e)
|
||||
{
|
||||
int i;
|
||||
char **p;
|
||||
char buf[4096];
|
||||
|
||||
p = 0;
|
||||
for(i = 0; e->name; e++, i++) {
|
||||
p = (char**) Realloc(p, (i+2)*sizeof(char*));
|
||||
if(e->values)
|
||||
sprint(buf, "%s=%s", e->name, wtos(e->values, IWS));
|
||||
else
|
||||
sprint(buf, "%s=", e->name);
|
||||
p[i] = strdup(buf);
|
||||
}
|
||||
p[i] = 0;
|
||||
environ = p;
|
||||
}
|
||||
|
||||
int
|
||||
waitfor(char *msg)
|
||||
{
|
||||
int status;
|
||||
int pid;
|
||||
|
||||
*msg = 0;
|
||||
pid = wait(&status);
|
||||
if(pid > 0) {
|
||||
if(status&0x7f) {
|
||||
if(status&0x80)
|
||||
snprint(msg, ERRMAX, "signal %d, core dumped", status&0x7f);
|
||||
else
|
||||
snprint(msg, ERRMAX, "signal %d", status&0x7f);
|
||||
} else if(status&0xff00)
|
||||
snprint(msg, ERRMAX, "exit(%d)", (status>>8)&0xff);
|
||||
}
|
||||
return pid;
|
||||
}
|
||||
|
||||
void
|
||||
expunge(int pid, char *msg)
|
||||
{
|
||||
if(strcmp(msg, "interrupt"))
|
||||
kill(pid, SIGINT);
|
||||
else
|
||||
kill(pid, SIGHUP);
|
||||
}
|
||||
|
||||
int
|
||||
execsh(char *args, char *cmd, Bufblock *buf, Envy *e)
|
||||
{
|
||||
char *p;
|
||||
int tot, n, pid, in[2], out[2];
|
||||
|
||||
if(buf && pipe(out) < 0){
|
||||
mkperror("pipe");
|
||||
Exit();
|
||||
}
|
||||
pid = fork();
|
||||
if(pid < 0){
|
||||
mkperror("mk fork");
|
||||
Exit();
|
||||
}
|
||||
if(pid == 0){
|
||||
if(buf)
|
||||
close(out[0]);
|
||||
if(pipe(in) < 0){
|
||||
mkperror("pipe");
|
||||
Exit();
|
||||
}
|
||||
pid = fork();
|
||||
if(pid < 0){
|
||||
mkperror("mk fork");
|
||||
Exit();
|
||||
}
|
||||
if(pid != 0){
|
||||
dup2(in[0], 0);
|
||||
if(buf){
|
||||
dup2(out[1], 1);
|
||||
close(out[1]);
|
||||
}
|
||||
close(in[0]);
|
||||
close(in[1]);
|
||||
if (e)
|
||||
exportenv(e);
|
||||
if(shflags)
|
||||
execl(shell, shellname, shflags, args, 0);
|
||||
else
|
||||
execl(shell, shellname, args, 0);
|
||||
mkperror(shell);
|
||||
_exit(1);
|
||||
}
|
||||
close(out[1]);
|
||||
close(in[0]);
|
||||
if(DEBUG(D_EXEC))
|
||||
fprint(1, "starting: %s\n", cmd);
|
||||
p = cmd+strlen(cmd);
|
||||
while(cmd < p){
|
||||
n = write(in[1], cmd, p-cmd);
|
||||
if(n < 0)
|
||||
break;
|
||||
cmd += n;
|
||||
}
|
||||
close(in[1]);
|
||||
_exit(0);
|
||||
}
|
||||
if(buf){
|
||||
close(out[1]);
|
||||
tot = 0;
|
||||
for(;;){
|
||||
if (buf->current >= buf->end)
|
||||
growbuf(buf);
|
||||
n = read(out[0], buf->current, buf->end-buf->current);
|
||||
if(n <= 0)
|
||||
break;
|
||||
buf->current += n;
|
||||
tot += n;
|
||||
}
|
||||
if (tot && buf->current[-1] == '\n')
|
||||
buf->current--;
|
||||
close(out[0]);
|
||||
}
|
||||
return pid;
|
||||
}
|
||||
|
||||
int
|
||||
pipecmd(char *cmd, Envy *e, int *fd)
|
||||
{
|
||||
int pid, pfd[2];
|
||||
|
||||
if(DEBUG(D_EXEC))
|
||||
fprint(1, "pipecmd='%s'\n", cmd);/**/
|
||||
|
||||
if(fd && pipe(pfd) < 0){
|
||||
mkperror("pipe");
|
||||
Exit();
|
||||
}
|
||||
pid = fork();
|
||||
if(pid < 0){
|
||||
mkperror("mk fork");
|
||||
Exit();
|
||||
}
|
||||
if(pid == 0){
|
||||
if(fd){
|
||||
close(pfd[0]);
|
||||
dup2(pfd[1], 1);
|
||||
close(pfd[1]);
|
||||
}
|
||||
if(e)
|
||||
exportenv(e);
|
||||
if(shflags)
|
||||
execl(shell, shellname, shflags, "-c", cmd, 0);
|
||||
else
|
||||
execl(shell, shellname, "-c", cmd, 0);
|
||||
mkperror(shell);
|
||||
_exit(1);
|
||||
}
|
||||
if(fd){
|
||||
close(pfd[1]);
|
||||
*fd = pfd[0];
|
||||
}
|
||||
return pid;
|
||||
}
|
||||
|
||||
void
|
||||
Exit(void)
|
||||
{
|
||||
while(wait(0) >= 0)
|
||||
;
|
||||
exits("error");
|
||||
}
|
||||
|
||||
static struct
|
||||
{
|
||||
int sig;
|
||||
char *msg;
|
||||
} sigmsgs[] =
|
||||
{
|
||||
SIGALRM, "alarm",
|
||||
SIGFPE, "sys: fp: fptrap",
|
||||
SIGPIPE, "sys: write on closed pipe",
|
||||
SIGILL, "sys: trap: illegal instruction",
|
||||
SIGSEGV, "sys: segmentation violation",
|
||||
0, 0
|
||||
};
|
||||
|
||||
static void
|
||||
notifyf(int sig)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; sigmsgs[i].msg; i++)
|
||||
if(sigmsgs[i].sig == sig)
|
||||
killchildren(sigmsgs[i].msg);
|
||||
|
||||
/* should never happen */
|
||||
signal(sig, SIG_DFL);
|
||||
kill(getpid(), sig);
|
||||
}
|
||||
|
||||
void
|
||||
catchnotes()
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; sigmsgs[i].msg; i++)
|
||||
signal(sigmsgs[i].sig, notifyf);
|
||||
}
|
||||
|
||||
char*
|
||||
maketmp(int *pfd)
|
||||
{
|
||||
static char temp[] = "/tmp/mkargXXXXXX";
|
||||
static char buf[100];
|
||||
int fd;
|
||||
|
||||
strcpy(buf, temp);
|
||||
fd = mkstemp(buf);
|
||||
if(fd < 0)
|
||||
return 0;
|
||||
*pfd = fd;
|
||||
return buf;
|
||||
}
|
||||
|
||||
int
|
||||
chgtime(char *name)
|
||||
{
|
||||
if(access(name, 0) >= 0)
|
||||
return utimes(name, 0);
|
||||
return close(creat(name, 0666));
|
||||
}
|
||||
|
||||
void
|
||||
rcopy(char **to, Resub *match, int n)
|
||||
{
|
||||
int c;
|
||||
char *p;
|
||||
|
||||
*to = match->s.sp; /* stem0 matches complete target */
|
||||
for(to++, match++; --n > 0; to++, match++){
|
||||
if(match->s.sp && match->e.ep){
|
||||
p = match->e.ep;
|
||||
c = *p;
|
||||
*p = 0;
|
||||
*to = strdup(match->s.sp);
|
||||
*p = c;
|
||||
}
|
||||
else
|
||||
*to = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ulong
|
||||
mkmtime(char *name)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if(stat(name, &st) < 0)
|
||||
return 0;
|
||||
|
||||
return st.st_mtime;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue