tload.c 5.05 KB
Newer Older
csmall's avatar
csmall committed
1 2 3 4 5 6 7 8 9 10
/*
 * tload.c	- terminal version of xload
 *
 * Options:
 *	-s initial scaling exponent (default = 6)
 *	-d delay
 *
 * Copyright (c) 1992 Branko Lankester
 * /proc changes by David Engel (david@ods.com)
 * Made a little more efficient by Michael K. Johnson (johnsonm@sunsite.unc.edu)
11 12 13 14 15 16 17 18 19 20 21 22 23 24
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
csmall's avatar
csmall committed
25
 */
26

csmall's avatar
csmall committed
27 28
#include "proc/version.h"
#include "proc/sysinfo.h"
Sami Kerola's avatar
Sami Kerola committed
29
#include "c.h"
30
#include "fileutils.h"
Sami Kerola's avatar
Sami Kerola committed
31
#include "nls.h"
32
#include "strutils.h"
33
#include "xalloc.h"
Sami Kerola's avatar
Sami Kerola committed
34

35 36 37
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
csmall's avatar
csmall committed
38 39
#include <setjmp.h>
#include <signal.h>
40 41
#include <stdio.h>
#include <stdlib.h>
csmall's avatar
csmall committed
42 43
#include <string.h>
#include <sys/ioctl.h>
44 45
#include <termios.h>
#include <unistd.h>
csmall's avatar
csmall committed
46 47 48 49 50 51

static char *screen;

static int nrows = 25;
static int ncols = 80;
static int scr_size;
52
static int fd = 1;
53
static unsigned int dly = 5;
csmall's avatar
csmall committed
54 55
static jmp_buf jb;

56
static void alrm(int signo __attribute__ ((__unused__)))
csmall's avatar
csmall committed
57
{
58 59
	signal(SIGALRM, alrm);
	alarm(dly);
csmall's avatar
csmall committed
60 61 62 63
}

static void setsize(int i)
{
64 65 66 67 68 69 70 71 72 73 74
	struct winsize win;

	signal(SIGWINCH, setsize);
	if (ioctl(fd, TIOCGWINSZ, &win) != -1) {
		if (win.ws_col > 0)
			ncols = win.ws_col;
		if (win.ws_row > 0)
			nrows = win.ws_row;
	}
	scr_size = nrows * ncols;
	if (screen == NULL)
75
		screen = (char *)xmalloc(scr_size);
76
	else
77
		screen = (char *)xrealloc(screen, scr_size);
78 79 80 81 82

	memset(screen, ' ', scr_size - 1);
	*(screen + scr_size - 2) = '\0';
	if (i)
		longjmp(jb, 0);
csmall's avatar
csmall committed
83 84
}

Sami Kerola's avatar
Sami Kerola committed
85
static void __attribute__ ((__noreturn__)) usage(FILE * out)
csmall's avatar
csmall committed
86
{
Sami Kerola's avatar
Sami Kerola committed
87
	fputs(USAGE_HEADER, out);
88 89
	fprintf(out,
	      _(" %s [options] [tty]\n"), program_invocation_short_name);
Sami Kerola's avatar
Sami Kerola committed
90
	fputs(USAGE_OPTIONS, out);
91 92
	fputs(_(" -d, --delay <secs>  update delay in seconds\n"), out);
	fputs(_(" -s, --scale <num>   vertical scale\n"), out);
Sami Kerola's avatar
Sami Kerola committed
93 94 95 96
	fputs(USAGE_SEPARATOR, out);
	fputs(USAGE_HELP, out);
	fputs(USAGE_VERSION, out);
	fprintf(out, USAGE_MAN_TAIL("tload(1)"));
97 98 99

	exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
}
csmall's avatar
csmall committed
100

101 102 103 104 105
int main(int argc, char **argv)
{
	int lines, row, col = 0;
	int i, opt;
	double av[3];
Sami Kerola's avatar
Sami Kerola committed
106
	static double max_scale = 0, scale_fact;
107
	long tmpdly;
108 109 110 111 112 113 114 115

	static const struct option longopts[] = {
		{"scale", required_argument, NULL, 's'},
		{"delay", required_argument, NULL, 'd'},
		{"help", no_argument, NULL, 'h'},
		{"version", no_argument, NULL, 'V'},
		{NULL, 0, NULL, 0}
	};
116
#ifdef HAVE_PROGRAM_INVOCATION_NAME
117
	program_invocation_name = program_invocation_short_name;
118
#endif
119 120 121
	setlocale (LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);
122
	atexit(close_stdout);
123 124 125

	while ((opt =
		getopt_long(argc, argv, "s:d:Vh", longopts, NULL)) != -1)
126 127
		switch (opt) {
		case 's':
Sami Kerola's avatar
Sami Kerola committed
128 129
			max_scale = strtod_or_err(optarg, _("failed to parse argument"));
			if (max_scale < 0)
130
			        xerrx(EXIT_FAILURE, _("scale cannot be negative"));
131 132
			break;
		case 'd':
133 134
			tmpdly = strtol_or_err(optarg, _("failed to parse argument"));
			if (tmpdly < 1)
135
				xerrx(EXIT_FAILURE, _("delay must be positive integer"));
136
			else if (UINT_MAX < tmpdly)
137
				xerrx(EXIT_FAILURE, _("too large delay value"));
138
			dly = tmpdly;
139 140
			break;
		case 'V':
Sami Kerola's avatar
Sami Kerola committed
141 142
			printf(PROCPS_NG_VERSION);
			return EXIT_SUCCESS;
143 144 145 146 147 148 149 150 151
			break;
		case 'h':
			usage(stdout);
		default:
			usage(stderr);
		}

	if (argc > optind)
		if ((fd = open(argv[optind], 1)) == -1)
152
			xerr(EXIT_FAILURE, _("can not open tty"));
153 154 155

	setsize(0);

Sami Kerola's avatar
Sami Kerola committed
156
	if (max_scale == 0)
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
		max_scale = nrows;

	scale_fact = max_scale;

	setjmp(jb);
	col = 0;
	alrm(0);

	while (1) {

		if (scale_fact < max_scale)
			scale_fact *= 2.0;	/* help it drift back up. */

		loadavg(&av[0], &av[1], &av[2]);

Jim Brown IV's avatar
Jim Brown IV committed
172
		do {
Sami Kerola's avatar
Sami Kerola committed
173 174 175 176 177 178 179 180 181
			lines = av[0] * scale_fact;
			row = nrows - 1;

			while (0 <= --lines) {
				*(screen + row * ncols + col) = '*';
				if (--row < 0) {
					scale_fact /= 2.0;
					break;
				}
182
			}
Jim Brown IV's avatar
Jim Brown IV committed
183
		} while (0 <= lines);
Sami Kerola's avatar
Sami Kerola committed
184

185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
		while (row >= 0)
			*(screen + row-- * ncols + col) = ' ';

		for (i = 1;; ++i) {
			char *p;
			row = nrows - (i * scale_fact);
			if (row < 0)
				break;
			if (*(p = screen + row * ncols + col) == ' ')
				*p = '-';
			else
				*p = '=';
		}

		if (++col == ncols) {
			--col;
			memmove(screen, screen + 1, scr_size - 1);

			for (row = nrows - 2; row >= 0; --row)
				*(screen + row * ncols + col) = ' ';
		}
		i = sprintf(screen, " %.2f, %.2f, %.2f", av[0], av[1], av[2]);
		if (i > 0)
			screen[i] = ' ';

210 211 212 213
		if (write(fd, "\033[H", 3) < 0)
			xerr(EXIT_FAILURE, _("writing to tty failed"));
		if (write(fd, screen, scr_size - 1) < 0)
			xerr(EXIT_FAILURE, _("writing to tty failed"));
214
		pause();
csmall's avatar
csmall committed
215 216
	}
}