aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/builtin_jobs.cpp
diff options
context:
space:
mode:
authorGravatar ridiculousfish <corydoras@ridiculousfish.com>2015-07-24 00:50:58 -0700
committerGravatar ridiculousfish <corydoras@ridiculousfish.com>2015-07-24 00:59:27 -0700
commitb4f53143b0e05fd3061cdf2e65e17a6a2904090b (patch)
tree4785bf31f7b89fc2420aa740d9a6967dc6c6f9b1 /src/builtin_jobs.cpp
parent9c2fdc6da57032c4448b59de5872086eea626b74 (diff)
Migrate source files into src/ directory
This change moves source files into a src/ directory, and puts object files into an obj/ directory. The Makefile and xcode project are updated accordingly. Fixes #1866
Diffstat (limited to 'src/builtin_jobs.cpp')
-rw-r--r--src/builtin_jobs.cpp351
1 files changed, 351 insertions, 0 deletions
diff --git a/src/builtin_jobs.cpp b/src/builtin_jobs.cpp
new file mode 100644
index 00000000..02bf94f2
--- /dev/null
+++ b/src/builtin_jobs.cpp
@@ -0,0 +1,351 @@
+/** \file builtin_jobs.c
+ Functions for executing the jobs builtin.
+*/
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <wchar.h>
+#include <unistd.h>
+#include <termios.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <wctype.h>
+
+#include "fallback.h"
+#include "util.h"
+
+#include "wutil.h"
+#include "builtin.h"
+#include "proc.h"
+#include "parser.h"
+#include "common.h"
+#include "wgetopt.h"
+
+
+/**
+ Print modes for the jobs builtin
+*/
+enum
+{
+ JOBS_DEFAULT, /**< Print lots of general info */
+ JOBS_PRINT_PID, /**< Print pid of each process in job */
+ JOBS_PRINT_COMMAND, /**< Print command name of each process in job */
+ JOBS_PRINT_GROUP, /**< Print group id of job */
+}
+;
+
+
+
+#ifdef HAVE__PROC_SELF_STAT
+/**
+ Calculates the cpu usage (in percent) of the specified job.
+*/
+static int cpu_use(const job_t *j)
+{
+ double u=0;
+ process_t *p;
+
+ for (p=j->first_process; p; p=p->next)
+ {
+ struct timeval t;
+ int jiffies;
+ gettimeofday(&t, 0);
+ jiffies = proc_get_jiffies(p);
+
+ double t1 = 1000000.0*p->last_time.tv_sec+p->last_time.tv_usec;
+ double t2 = 1000000.0*t.tv_sec+t.tv_usec;
+
+ /* fwprintf( stderr, L"t1 %f t2 %f p1 %d p2 %d\n",
+ t1, t2, jiffies, p->last_jiffies );
+ */
+
+ u += ((double)(jiffies-p->last_jiffies))/(t2-t1);
+ }
+ return u*1000000;
+}
+#endif
+
+/**
+ Print information about the specified job
+*/
+static void builtin_jobs_print(const job_t *j, int mode, int header)
+{
+ process_t *p;
+ switch (mode)
+ {
+ case JOBS_DEFAULT:
+ {
+
+ if (header)
+ {
+ /*
+ Print table header before first job
+ */
+ stdout_buffer.append(_(L"Job\tGroup\t"));
+#ifdef HAVE__PROC_SELF_STAT
+ stdout_buffer.append(_(L"CPU\t"));
+#endif
+ stdout_buffer.append(_(L"State\tCommand\n"));
+ }
+
+ append_format(stdout_buffer, L"%d\t%d\t", j->job_id, j->pgid);
+
+#ifdef HAVE__PROC_SELF_STAT
+ append_format(stdout_buffer, L"%d%%\t", cpu_use(j));
+#endif
+ stdout_buffer.append(job_is_stopped(j)?_(L"stopped"):_(L"running"));
+ stdout_buffer.append(L"\t");
+ stdout_buffer.append(j->command_wcstr());
+ stdout_buffer.append(L"\n");
+ break;
+ }
+
+ case JOBS_PRINT_GROUP:
+ {
+ if (header)
+ {
+ /*
+ Print table header before first job
+ */
+ stdout_buffer.append(_(L"Group\n"));
+ }
+ append_format(stdout_buffer, L"%d\n", j->pgid);
+ break;
+ }
+
+ case JOBS_PRINT_PID:
+ {
+ if (header)
+ {
+ /*
+ Print table header before first job
+ */
+ stdout_buffer.append(_(L"Process\n"));
+ }
+
+ for (p=j->first_process; p; p=p->next)
+ {
+ append_format(stdout_buffer, L"%d\n", p->pid);
+ }
+ break;
+ }
+
+ case JOBS_PRINT_COMMAND:
+ {
+ if (header)
+ {
+ /*
+ Print table header before first job
+ */
+ stdout_buffer.append(_(L"Command\n"));
+ }
+
+ for (p=j->first_process; p; p=p->next)
+ {
+ append_format(stdout_buffer, L"%ls\n", p->argv0());
+ }
+ break;
+ }
+ }
+
+}
+
+
+
+/**
+ The jobs builtin. Used fopr printing running jobs. Defined in builtin_jobs.c.
+*/
+static int builtin_jobs(parser_t &parser, wchar_t **argv)
+{
+ int argc=0;
+ int found=0;
+ int mode=JOBS_DEFAULT;
+ int print_last = 0;
+
+ argc = builtin_count_args(argv);
+ woptind=0;
+
+ while (1)
+ {
+ static const struct woption
+ long_options[] =
+ {
+ {
+ L"pid", no_argument, 0, 'p'
+ }
+ ,
+ {
+ L"command", no_argument, 0, 'c'
+ }
+ ,
+ {
+ L"group", no_argument, 0, 'g'
+ }
+ ,
+ {
+ L"last", no_argument, 0, 'l'
+ }
+ ,
+ {
+ L"help", no_argument, 0, 'h'
+ }
+ ,
+ {
+ 0, 0, 0, 0
+ }
+ }
+ ;
+
+ int opt_index = 0;
+
+ int opt = wgetopt_long(argc,
+ argv,
+ L"pclgh",
+ long_options,
+ &opt_index);
+ if (opt == -1)
+ break;
+
+ switch (opt)
+ {
+ case 0:
+ if (long_options[opt_index].flag != 0)
+ break;
+ append_format(stderr_buffer,
+ BUILTIN_ERR_UNKNOWN,
+ argv[0],
+ long_options[opt_index].name);
+
+ builtin_print_help(parser, argv[0], stderr_buffer);
+
+
+ return 1;
+
+
+ case 'p':
+ mode=JOBS_PRINT_PID;
+ break;
+
+ case 'c':
+ mode=JOBS_PRINT_COMMAND;
+ break;
+
+ case 'g':
+ mode=JOBS_PRINT_GROUP;
+ break;
+
+ case 'l':
+ {
+ print_last = 1;
+ break;
+ }
+
+ case 'h':
+ builtin_print_help(parser, argv[0], stdout_buffer);
+ return 0;
+
+ case '?':
+ builtin_unknown_option(parser, argv[0], argv[woptind-1]);
+ return 1;
+
+ }
+ }
+
+
+ /*
+ Do not babble if not interactive
+ */
+ if (builtin_out_redirect)
+ {
+ found=1;
+ }
+
+ if (print_last)
+ {
+ /*
+ Ignore unconstructed jobs, i.e. ourself.
+ */
+ job_iterator_t jobs;
+ const job_t *j;
+ while ((j = jobs.next()))
+ {
+
+ if ((j->flags & JOB_CONSTRUCTED) && !job_is_completed(j))
+ {
+ builtin_jobs_print(j, mode, !found);
+ return 0;
+ }
+ }
+
+ }
+ else
+ {
+ if (woptind < argc)
+ {
+ int i;
+
+ found = 1;
+
+ for (i=woptind; i<argc; i++)
+ {
+ int pid;
+ wchar_t *end;
+ errno=0;
+ pid=fish_wcstoi(argv[i], &end, 10);
+ if (errno || *end)
+ {
+ append_format(stderr_buffer,
+ _(L"%ls: '%ls' is not a job\n"),
+ argv[0],
+ argv[i]);
+ return 1;
+ }
+
+ const job_t *j = job_get_from_pid(pid);
+
+ if (j && !job_is_completed(j))
+ {
+ builtin_jobs_print(j, mode, !found);
+ }
+ else
+ {
+ append_format(stderr_buffer,
+ _(L"%ls: No suitable job: %d\n"),
+ argv[0],
+ pid);
+ return 1;
+ }
+ }
+ }
+ else
+ {
+ job_iterator_t jobs;
+ const job_t *j;
+ while ((j = jobs.next()))
+ {
+ /*
+ Ignore unconstructed jobs, i.e. ourself.
+ */
+ if ((j->flags & JOB_CONSTRUCTED) && !job_is_completed(j))
+ {
+ builtin_jobs_print(j, mode, !found);
+ found = 1;
+ }
+ }
+ }
+ }
+
+ if (!found)
+ {
+ append_format(stdout_buffer,
+ _(L"%ls: There are no jobs\n"),
+ argv[0]);
+ return 1;
+ }
+
+ return 0;
+}
+