Clean up some job status messages

Stop printing anything for jobs terminated via ^C.
Don't list the job number if it's the only job.

Fixes #1119
This commit is contained in:
ridiculousfish 2014-11-03 10:56:16 -08:00
parent c31ad3ed07
commit 6db82c162c
2 changed files with 83 additions and 25 deletions

107
proc.cpp
View file

@ -103,13 +103,17 @@ job_iterator_t::job_iterator_t(job_list_t &jobs) : job_list(&jobs)
this->reset(); this->reset();
} }
job_iterator_t::job_iterator_t() : job_list(&parser_t::principal_parser().job_list()) job_iterator_t::job_iterator_t() : job_list(&parser_t::principal_parser().job_list())
{ {
ASSERT_IS_MAIN_THREAD(); ASSERT_IS_MAIN_THREAD();
this->reset(); this->reset();
} }
size_t job_iterator_t::count() const
{
return this->job_list->size();
}
void print_jobs(void) void print_jobs(void)
{ {
job_iterator_t jobs; job_iterator_t jobs;
@ -644,16 +648,55 @@ void job_handle_signal(int signal, siginfo_t *info, void *con)
got_signal = 1; got_signal = 1;
} }
/* Given a command like "cat file", truncate it to a reasonable length */
static wcstring truncate_command(const wcstring &cmd)
{
const size_t max_len = 32;
if (cmd.size() <= max_len)
{
// No truncation necessary
return cmd;
}
// Truncation required
const bool ellipsis_is_unicode = (ellipsis_char == L'\x2026');
const size_t ellipsis_length = ellipsis_is_unicode ? 1 : 3;
size_t trunc_length = max_len - ellipsis_length;
// Eat trailing whitespace
while (trunc_length > 0 && iswspace(cmd.at(trunc_length - 1)))
{
trunc_length -= 1;
}
wcstring result = wcstring(cmd, 0, trunc_length);
// Append ellipsis
if (ellipsis_is_unicode)
{
result.push_back(ellipsis_char);
}
else
{
result.append(L"...");
}
return result;
}
/** /**
Format information about job status for the user to look at. Format information about job status for the user to look at.
\param j the job to test \param j the job to test
\param status a string description of the job exit type \param status a string description of the job exit type
*/ */
static void format_job_info(const job_t *j, const wchar_t *status) static void format_job_info(const job_t *j, const wchar_t *status, size_t job_count)
{ {
fwprintf(stdout, L"\r"); fwprintf(stdout, L"\r");
fwprintf(stdout, _(L"Job %d, \'%ls\' has %ls"), j->job_id, j->command_wcstr(), status); if (job_count == 1)
{
fwprintf(stdout, _(L"\'%ls\' has %ls"), truncate_command(j->command()).c_str(), status);
}
else
{
fwprintf(stdout, _(L"Job %d, \'%ls\' has %ls"), j->job_id, truncate_command(j->command()).c_str(), status);
}
fflush(stdout); fflush(stdout);
tputs(clr_eol,1,&writeb); tputs(clr_eol,1,&writeb);
fwprintf(stdout, L"\n"); fwprintf(stdout, L"\n");
@ -692,6 +735,7 @@ int job_reap(bool interactive)
const int saved_status = proc_get_last_status(); const int saved_status = proc_get_last_status();
job_iterator_t jobs; job_iterator_t jobs;
const size_t job_count = jobs.count();
jnext = jobs.next(); jnext = jobs.next();
while (jnext) while (jnext)
{ {
@ -734,26 +778,39 @@ int job_reap(bool interactive)
job_set_flag(j, JOB_NOTIFIED, 1); job_set_flag(j, JOB_NOTIFIED, 1);
if (!job_get_flag(j, JOB_SKIP_NOTIFICATION)) if (!job_get_flag(j, JOB_SKIP_NOTIFICATION))
{ {
if (proc_is_job) /* Print nothing if we get SIGINT in the foreground process group, to avoid spamming obvious stuff on the console (#1119). If we get SIGINT for the foreground process, assume the user typed ^C and can see it working. It's possible they didn't, and the signal was delivered via pkill, etc., but the SIGINT/SIGTERM distinction is precisely to allow INT to be from a UI and TERM to be programmatic, so this assumption is keeping with the design of signals.
fwprintf(stdout, If echoctl is on, then the terminal will have written ^C to the console. If off, it won't have. We don't echo ^C either way, so as to respect the user's preference. */
_(L"%ls: Job %d, \'%ls\' terminated by signal %ls (%ls)"), if (WTERMSIG(p->status) != SIGINT || ! job_get_flag(j, JOB_FOREGROUND))
program_name, {
j->job_id, if (proc_is_job)
j->command_wcstr(), {
sig2wcs(WTERMSIG(p->status)), // We want to report the job number, unless it's the only job, in which case we don't need to
signal_get_desc(WTERMSIG(p->status))); const wcstring job_number_desc = (job_count == 1) ? wcstring() : format_string(L"Job %d, ", j->job_id);
else fwprintf(stdout,
fwprintf(stdout, _(L"%ls: %ls\'%ls\' terminated by signal %ls (%ls)"),
_(L"%ls: Process %d, \'%ls\' from job %d, \'%ls\' terminated by signal %ls (%ls)"), program_name,
program_name, job_number_desc.c_str(),
p->pid, truncate_command(j->command()).c_str(),
p->argv0(), sig2wcs(WTERMSIG(p->status)),
j->job_id, signal_get_desc(WTERMSIG(p->status)));
j->command_wcstr(), }
sig2wcs(WTERMSIG(p->status)), else
signal_get_desc(WTERMSIG(p->status))); {
tputs(clr_eol,1,&writeb); const wcstring job_number_desc = (job_count == 1) ? wcstring() : format_string(L"from job %d, ", j->job_id);
fwprintf(stdout, L"\n"); // This case is pretty rare
fwprintf(stdout,
_(L"%ls: Process %d, \'%ls\' %ls\'%ls\' terminated by signal %ls (%ls)"),
program_name,
p->pid,
p->argv0(),
job_number_desc.c_str(),
truncate_command(j->command()).c_str(),
sig2wcs(WTERMSIG(p->status)),
signal_get_desc(WTERMSIG(p->status)));
}
tputs(clr_eol,1,&writeb);
fwprintf(stdout, L"\n");
}
found=1; found=1;
} }
@ -773,7 +830,7 @@ int job_reap(bool interactive)
{ {
if (!job_get_flag(j, JOB_FOREGROUND) && !job_get_flag(j, JOB_NOTIFIED) && !job_get_flag(j, JOB_SKIP_NOTIFICATION)) if (!job_get_flag(j, JOB_FOREGROUND) && !job_get_flag(j, JOB_NOTIFIED) && !job_get_flag(j, JOB_SKIP_NOTIFICATION))
{ {
format_job_info(j, _(L"ended")); format_job_info(j, _(L"ended"), job_count);
found=1; found=1;
} }
proc_fire_event(L"JOB_EXIT", EVENT_EXIT, -j->pgid, 0); proc_fire_event(L"JOB_EXIT", EVENT_EXIT, -j->pgid, 0);
@ -788,7 +845,7 @@ int job_reap(bool interactive)
*/ */
if (!job_get_flag(j, JOB_SKIP_NOTIFICATION)) if (!job_get_flag(j, JOB_SKIP_NOTIFICATION))
{ {
format_job_info(j, _(L"stopped")); format_job_info(j, _(L"stopped"), job_count);
found=1; found=1;
} }
job_set_flag(j, JOB_NOTIFIED, 1); job_set_flag(j, JOB_NOTIFIED, 1);

1
proc.h
View file

@ -424,6 +424,7 @@ public:
job_iterator_t(job_list_t &jobs); job_iterator_t(job_list_t &jobs);
job_iterator_t(); job_iterator_t();
size_t count() const;
}; };
/** /**