summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.bin/make/defines.h3
-rw-r--r--usr.bin/make/engine.c48
-rw-r--r--usr.bin/make/engine.h5
-rw-r--r--usr.bin/make/gnode.h3
-rw-r--r--usr.bin/make/job.c229
-rw-r--r--usr.bin/make/main.c7
-rw-r--r--usr.bin/make/targ.c10
7 files changed, 162 insertions, 143 deletions
diff --git a/usr.bin/make/defines.h b/usr.bin/make/defines.h
index a0b20860d48..c7438cc6948 100644
--- a/usr.bin/make/defines.h
+++ b/usr.bin/make/defines.h
@@ -1,7 +1,7 @@
#ifndef DEFINES_H
#define DEFINES_H
-/* $OpenBSD: defines.h,v 1.11 2012/09/21 07:55:20 espie Exp $ */
+/* $OpenBSD: defines.h,v 1.12 2012/10/06 09:32:40 espie Exp $ */
/*
* Copyright (c) 2001 Marc Espie.
@@ -98,6 +98,7 @@ extern int debug;
#define DEBUG_NAME_MATCHING 0x2000
#define DEBUG_QUICKDEATH 0x4000
#define DEBUG_EXPENSIVE 0x8000
+#define DEBUG_KILL 0x10000
#define CONCAT(a,b) a##b
diff --git a/usr.bin/make/engine.c b/usr.bin/make/engine.c
index db622180df5..ff5c70f5092 100644
--- a/usr.bin/make/engine.c
+++ b/usr.bin/make/engine.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: engine.c,v 1.35 2012/10/04 13:20:46 espie Exp $ */
+/* $OpenBSD: engine.c,v 1.36 2012/10/06 09:32:40 espie Exp $ */
/*
* Copyright (c) 2012 Marc Espie.
*
@@ -99,6 +99,24 @@ static void setup_engine(void);
static char **recheck_command_for_shell(char **);
static void list_parents(GNode *, FILE *);
+/* XXX due to a bug in make's logic, targets looking like *.a or -l*
+ * have been silently dropped when make couldn't figure them out.
+ * Now, we warn about them until all Makefile bugs have been fixed.
+ */
+static bool
+drop_silently(const char *s)
+{
+ size_t len;
+
+ if (s[0] == '-' && s[1] == 'l')
+ return true;
+
+ len = strlen(s);
+ if (len >=2 && s[len-2] == '.' && s[len-1] == 'a')
+ return true;
+ return false;
+}
+
bool
node_find_valid_commands(GNode *gn)
{
@@ -111,11 +129,10 @@ node_find_valid_commands(GNode *gn)
gn->type |= OP_SILENT;
if (OP_NOP(gn->type) && Lst_IsEmpty(&gn->commands)) {
- /* XXX */
- if ((gn->type & OP_LIB)) {
+ if (drop_silently(gn->name)) {
printf("Warning: target %s", gn->name);
list_parents(gn, stdout);
- printf(" does not have any command\n");
+ printf(" does not have any command (BUG)\n");
return true;
}
/*
@@ -586,11 +603,22 @@ job_attach_node(Job *job, GNode *node)
job->exit_type = JOB_EXIT_OKAY;
job->location = NULL;
job->flags = 0;
+ job->sent_signal = 0;
}
void
job_handle_status(Job *job, int status)
{
+ bool silent;
+
+ /* if there's one job running and we don't keep going, no need
+ * to report right now.
+ */
+ if ((job->flags & JOB_ERRCHECK) && !keepgoing && runningJobs == NULL)
+ silent = !DEBUG(JOB);
+ else
+ silent = false;
+
debug_job_printf("Process %ld (%s) exited with status %d.\n",
(long)job->pid, job->node->name, status);
@@ -598,26 +626,30 @@ job_handle_status(Job *job, int status)
if (WIFEXITED(status)) {
job->code = WEXITSTATUS(status);/* exited */
if (status != 0) {
- printf("*** Error code %d", job->code);
+ if (!silent)
+ printf("*** Error %d", job->code);
job->exit_type = JOB_EXIT_BAD;
} else
job->exit_type = JOB_EXIT_OKAY;
} else {
job->exit_type = JOB_SIGNALED;
job->code = WTERMSIG(status); /* signaled */
- printf("*** Signal %d", job->code);
+ if (!silent)
+ printf("*** Signal %d", job->code);
}
/* if there is a problem, what's going on ? */
if (job->exit_type != JOB_EXIT_OKAY) {
- printf(" in target %s", job->node->name);
+ if (!silent)
+ printf(" in target '%s'", job->node->name);
if (job->flags & JOB_ERRCHECK) {
job->node->built_status = ERROR;
/* compute expensive status if we really want it */
if ((job->flags & JOB_SILENT) && job == &myjob)
determine_expensive_job(job);
if (!keepgoing) {
- printf("\n");
+ if (!silent)
+ printf("\n");
job->next = errorJobs;
errorJobs = job;
/* XXX don't free the command */
diff --git a/usr.bin/make/engine.h b/usr.bin/make/engine.h
index 74fa2ed482a..31ca704ba11 100644
--- a/usr.bin/make/engine.h
+++ b/usr.bin/make/engine.h
@@ -1,6 +1,6 @@
#ifndef ENGINE_H
#define ENGINE_H
-/* $OpenBSD: engine.h,v 1.10 2012/09/21 07:55:20 espie Exp $ */
+/* $OpenBSD: engine.h,v 1.11 2012/10/06 09:32:40 espie Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -97,6 +97,7 @@ struct Job_ {
#define JOB_EXIT_OKAY 0
#define JOB_EXIT_BAD 1
#define JOB_SIGNALED 2
+ int sent_signal;
int code; /* exit status or signal code */
LstNode next_cmd; /* Next command to run */
char *cmd; /* Last command run */
@@ -104,8 +105,8 @@ struct Job_ {
unsigned short flags;
#define JOB_SILENT 0x001 /* Command was silent */
#define JOB_IS_EXPENSIVE 0x002
+#define JOB_LOST 0x004 /* sent signal to non-existing pid ? */
#define JOB_ERRCHECK 0x008 /* command wants errcheck */
-#define JOB_MINE 0x010 /* XXX special job run by compat */
};
extern bool job_run_next(Job *);
diff --git a/usr.bin/make/gnode.h b/usr.bin/make/gnode.h
index b24330b286a..bf225880a07 100644
--- a/usr.bin/make/gnode.h
+++ b/usr.bin/make/gnode.h
@@ -1,6 +1,6 @@
#ifndef GNODE_H
#define GNODE_H
-/* $OpenBSD: gnode.h,v 1.21 2012/10/02 10:29:30 espie Exp $ */
+/* $OpenBSD: gnode.h,v 1.22 2012/10/06 09:32:40 espie Exp $ */
/*
* Copyright (c) 2001 Marc Espie.
@@ -230,7 +230,6 @@ struct command
/* Attributes applied by PMake */
#define OP_TRANSFORM 0x00040000 /* The node is a transformation rule */
#define OP_MEMBER 0x00080000 /* Target is a member of an archive */
-#define OP_LIB 0x00100000 /* Target is a library */
#define OP_ARCHV 0x00200000 /* Target is an archive construct */
#define OP_HAS_COMMANDS 0x00400000 /* Target has all the commands it should.
* Used when parsing to catch multiple
diff --git a/usr.bin/make/job.c b/usr.bin/make/job.c
index fab39a6dc82..ed2ea5ecf82 100644
--- a/usr.bin/make/job.c
+++ b/usr.bin/make/job.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: job.c,v 1.127 2012/10/04 13:20:46 espie Exp $ */
+/* $OpenBSD: job.c,v 1.128 2012/10/06 09:32:40 espie Exp $ */
/* $NetBSD: job.c,v 1.16 1996/11/06 17:59:08 christos Exp $ */
/*
@@ -131,16 +131,14 @@ Job *errorJobs; /* Jobs in error at end */
static Job *heldJobs; /* Jobs not running yet because of expensive */
static pid_t mypid;
-static volatile sig_atomic_t got_fatal, got_other;
+static volatile sig_atomic_t got_fatal;
static volatile sig_atomic_t got_SIGINT, got_SIGHUP, got_SIGQUIT, got_SIGTERM,
- got_SIGINFO, got_SIGTSTP, got_SIGTTOU, got_SIGTTIN, got_SIGCONT,
- got_SIGWINCH;
+ got_SIGINFO;
static sigset_t sigset, emptyset;
static void handle_fatal_signal(int);
-static void pass_job_control_signal(int);
static void handle_siginfo(void);
static void postprocess_job(Job *, bool);
static Job *prepare_job(GNode *);
@@ -157,22 +155,72 @@ static bool expensive_command(const char *);
static void setup_signal(int);
static void notice_signal(int);
static void setup_all_signals(void);
-static void setup_job_control_interrupts(void);
-static void killcheck(pid_t, int);
+static const char *really_kill(Job *, int);
+static void kill_with_sudo_maybe(pid_t, int, const char *);
+static void debug_kill_printf(const char *, ...);
+static void debug_vprintf(const char *, va_list);
+static void may_remove_target(Job *);
-static void
-killcheck(pid_t pid, int signo)
+static void
+kill_with_sudo_maybe(pid_t pid, int signo, const char *p)
{
- if (kill(pid, signo) == 0)
+ char buf[32]; /* largely enough */
+
+ for (;*p != '\0'; p++) {
+ if (*p != 's')
+ continue;
+ if (p[1] != 'u')
+ continue;
+ p++;
+ if (p[1] != 'd')
+ continue;
+ p++;
+ if (p[1] != 'o')
+ continue;
+ snprintf(buf, sizeof buf, "sudo -n /bin/kill -%d %ld",
+ signo, (long)pid);
+ debug_kill_printf("trying to kill with %s", buf);
+ system(buf);
return;
+ }
+
+}
+
+static const char *
+really_kill(Job *job, int signo)
+{
+ pid_t pid = job->pid;
+ job->sent_signal = signo;
+ if (getpgid(pid) != getpgrp()) {
+ if (killpg(pid, signo) == 0)
+ return "group got signal";
+ pid = -pid;
+ } else {
+ if (kill(pid, signo) == 0)
+ return "process got signal";
+ }
if (errno == ESRCH) {
- fprintf(stderr,
- "Can't send signal %d to %ld: pid not found\n",
- signo, (long)pid);
+ job->flags |= JOB_LOST;
+ return "not found";
} else if (errno == EPERM) {
- fprintf(stderr,
- "Can't send signal %d to %ld: not permitted\n",
- signo, (long)pid);
+ kill_with_sudo_maybe(pid, signo, job->cmd);
+ return "";
+ }
+}
+
+static void
+may_remove_target(Job *j)
+{
+ if ((j->sent_signal == SIGINT || j->sent_signal == SIGQUIT ||
+ j->sent_signal == SIGHUP || j->sent_signal == SIGTERM)
+ && !noExecute && !Targ_Precious(j->node)) {
+ const char *file = Var(TARGET_INDEX, j->node);
+ int r = eunlink(file);
+
+ if (DEBUG(JOB) && r == -1)
+ fprintf(stderr, " *** would unlink %s\n", file);
+ if (r != -1)
+ fprintf(stderr, " *** %s removed\n", file);
}
}
@@ -181,25 +229,34 @@ print_error(Job *j, Job *k)
{
const char *type;
- if (j->exit_type == JOB_EXIT_BAD)
- type = "Exit status";
- else if (j->exit_type == JOB_SIGNALED)
- type = "Received signal";
- else
- type = "Should not happen";
- fprintf(stderr, " %s %d (", type, j->code);
- fprintf(stderr, "line %lu",
- j->location->lineno);
+ if (j->exit_type == JOB_EXIT_BAD) {
+ fprintf(stderr, "*** Error %d", j->code);
+ if (j->sent_signal != 0 && j->code == j->sent_signal + 128)
+ fprintf(stderr, " (SIG%s in shell)",
+ sys_signame[j->sent_signal]);
+ } else if (j->exit_type == JOB_SIGNALED) {
+ if (j->code < NSIG)
+ fprintf(stderr, "*** SIG%s",
+ sys_signame[j->code]);
+ else
+ fprintf(stderr, "*** unknown signal %d", j->code);
+ } else
+ fprintf(stderr, "*** Should not happen %d", j->code);
+ if (DEBUG(KILL) && (j->flags & JOB_LOST))
+ fprintf(stderr, "!");
+ fprintf(stderr, " (line %lu", j->location->lineno);
if (j == k)
fprintf(stderr, " of %s,", j->location->fname);
else
fputs(",", stderr);
if ((j->flags & (JOB_SILENT | JOB_IS_EXPENSIVE)) == JOB_SILENT)
- fprintf(stderr, "\n target %s: %s", j->node->name, j->cmd);
+ fprintf(stderr, "\n target '%s': %s", j->node->name,
+ j->cmd);
else
- fprintf(stderr, " target %s", j->node->name);
+ fprintf(stderr, " target '%s'", j->node->name);
fputs(")\n", stderr);
free(j->cmd);
+ may_remove_target(j);
}
void
@@ -260,37 +317,9 @@ notice_signal(int sig)
break;
case SIGCHLD:
break;
- case SIGTSTP:
- got_SIGTSTP++;
- got_other = 1;
- break;
- case SIGTTOU:
- got_SIGTTOU++;
- got_other = 1;
- break;
- case SIGTTIN:
- got_SIGTTIN++;
- got_other = 1;
- break;
- case SIGCONT:
- got_SIGCONT++;
- got_other = 1;
- break;
- case SIGWINCH:
- got_SIGWINCH++;
- got_other = 1;
- break;
}
}
-static void
-setup_job_control_interrupts(void)
-{
- setup_signal(SIGTSTP);
- setup_signal(SIGTTOU);
- setup_signal(SIGTTIN);
-}
-
void
setup_all_signals(void)
{
@@ -309,7 +338,6 @@ setup_all_signals(void)
/* Have to see SIGCHLD */
setup_signal(SIGCHLD);
got_fatal = 0;
- got_other = 0;
}
static void
@@ -349,29 +377,6 @@ handle_all_signals(void)
{
if (got_SIGINFO)
handle_siginfo();
- while (got_other) {
- got_other = 0;
- if (got_SIGWINCH) {
- got_SIGWINCH=0;
- pass_job_control_signal(SIGWINCH);
- }
- if (got_SIGTTIN) {
- got_SIGTTIN=0;
- pass_job_control_signal(SIGTTIN);
- }
- if (got_SIGTTOU) {
- got_SIGTTOU=0;
- pass_job_control_signal(SIGTTOU);
- }
- if (got_SIGTSTP) {
- got_SIGTSTP=0;
- pass_job_control_signal(SIGTSTP);
- }
- if (got_SIGCONT) {
- got_SIGCONT=0;
- pass_job_control_signal(SIGCONT);
- }
- }
while (got_fatal) {
got_fatal = 0;
aborting = ABORT_INTERRUPT;
@@ -395,15 +400,32 @@ handle_all_signals(void)
}
}
+static void
+debug_vprintf(const char *fmt, va_list va)
+{
+ (void)printf("[%ld] ", (long)mypid);
+ (void)vprintf(fmt, va);
+ fflush(stdout);
+}
+
void
debug_job_printf(const char *fmt, ...)
{
if (DEBUG(JOB)) {
va_list va;
- (void)printf("[%ld] ", (long)mypid);
va_start(va, fmt);
- (void)vprintf(fmt, va);
- fflush(stdout);
+ debug_vprintf(fmt, va);
+ va_end(va);
+ }
+}
+
+static void
+debug_kill_printf(const char *fmt, ...)
+{
+ if (DEBUG(KILL)) {
+ va_list va;
+ va_start(va, fmt);
+ debug_vprintf(fmt, va);
va_end(va);
}
}
@@ -787,33 +809,6 @@ Job_Empty(void)
return runningJobs == NULL;
}
-static void
-pass_job_control_signal(int signo)
-{
- Job *job;
-
- debug_job_printf("pass_job_control_signal(%d) called.\n", signo);
-
-
- for (job = runningJobs; job != NULL; job = job->next) {
- debug_job_printf("pass_job_control_signal to "
- "child %ld running %s.\n", (long)job->pid,
- job->node->name);
- killcheck(job->pid, signo);
- }
- /* after forwarding the signal, those should interrupt us */
- if (signo == SIGTSTP || signo == SIGTTOU || signo == SIGTTIN) {
- sigprocmask(SIG_BLOCK, &sigset, NULL);
- signal(signo, SIG_DFL);
- kill(getpid(), signo);
- sigprocmask(SIG_SETMASK, &emptyset, NULL);
- }
- /* SIGWINCH is irrelevant for us, SIGCONT must put back normal
- * handling for other job control signals */
- if (signo == SIGCONT)
- setup_job_control_interrupts();
-}
-
/*-
*-----------------------------------------------------------------------
* handle_fatal_signal --
@@ -829,20 +824,14 @@ handle_fatal_signal(int signo)
{
Job *job;
- debug_job_printf("handle_fatal_signal(%d) called.\n", signo);
+ debug_kill_printf("handle_fatal_signal(%d) called.\n", signo);
for (job = runningJobs; job != NULL; job = job->next) {
- if (!Targ_Precious(job->node)) {
- const char *file = Var(TARGET_INDEX, job->node);
-
- if (!noExecute && eunlink(file) != -1)
- Error("*** %s removed", file);
- }
- debug_job_printf("handle_fatal_signal: passing to "
- "child %ld running %s.\n", (long)job->pid,
- job->node->name);
- killcheck(job->pid, signo);
+ debug_kill_printf("passing to "
+ "child %ld running %s: %s\n", (long)job->pid,
+ job->node->name, really_kill(job, signo));
+ may_remove_target(job);
}
if (signo == SIGINT && !touchFlag) {
diff --git a/usr.bin/make/main.c b/usr.bin/make/main.c
index 4aca9e7a0d8..5412f9ed0da 100644
--- a/usr.bin/make/main.c
+++ b/usr.bin/make/main.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: main.c,v 1.97 2012/10/02 10:29:31 espie Exp $ */
+/* $OpenBSD: main.c,v 1.98 2012/10/06 09:32:40 espie Exp $ */
/* $NetBSD: main.c,v 1.34 1997/03/24 20:56:36 gwr Exp $ */
/*
@@ -263,11 +263,14 @@ MainParseArgs(int argc, char **argv)
}
break;
case 'j':
- debug |= DEBUG_JOB;
+ debug |= DEBUG_JOB | DEBUG_KILL;
break;
case 'J':
/* ignore */
break;
+ case 'k':
+ debug |= DEBUG_KILL;
+ break;
case 'l':
debug |= DEBUG_LOUD;
break;
diff --git a/usr.bin/make/targ.c b/usr.bin/make/targ.c
index b55de852b99..d89eada51d5 100644
--- a/usr.bin/make/targ.c
+++ b/usr.bin/make/targ.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: targ.c,v 1.67 2012/10/02 10:29:31 espie Exp $ */
+/* $OpenBSD: targ.c,v 1.68 2012/10/06 09:32:40 espie Exp $ */
/* $NetBSD: targ.c,v 1.11 1997/02/20 16:51:50 christos Exp $ */
/*
@@ -150,12 +150,7 @@ Targ_NewGNi(const char *name, const char *ename)
gn = ohash_create_entry(&gnode_info, name, &ename);
gn->path = NULL;
- if ((name[0] == '-' && name[1] == 'l') ||
- (ename - name >=2 && ename[-1] == 'a' && ename[-2] == '.'))
- gn->type = OP_LIB;
- else
- gn->type = 0;
-
+ gn->type = 0;
gn->special = SPECIAL_NONE;
gn->unmade = 0;
gn->must_make = false;
@@ -290,7 +285,6 @@ Targ_PrintType(int type)
PRINTBIT(JOIN);
PRINTBIT(INVISIBLE);
PRINTBIT(NOTMAIN);
- PRINTDBIT(LIB);
/*XXX: MEMBER is defined, so CONCAT(OP_,MEMBER) gives OP_"%" */
case OP_MEMBER:
if (DEBUG(TARG))