diff options
Diffstat (limited to 'src/main/main.c')
-rw-r--r-- | src/main/main.c | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/src/main/main.c b/src/main/main.c new file mode 100644 index 0000000..04bb816 --- /dev/null +++ b/src/main/main.c @@ -0,0 +1,164 @@ +/* + * Main program entry point - read the command line options, then perform + * the appropriate actions. + * + * Copyright 2012 Andrew Wood, distributed under the Artistic License 2.0. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "options.h" +#include "pv.h" + +/* #undef MAKE_STDOUT_NONBLOCKING */ + +#include <unistd.h> +#include <fcntl.h> +#include <termios.h> +#include <sys/ioctl.h> +#include <sys/types.h> + + +int remote_set(opts_t opts); +void remote_sig_init(opts_t opts); + + +/* + * Process command-line arguments and set option flags, then call functions + * to initialise, and finally enter the main loop. + */ +int main(int argc, char **argv) +{ + struct termios t, t_save; + opts_t opts; + int retcode = 0; + +#ifdef ENABLE_NLS + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); +#endif + + opts = opts_parse(argc, argv); + if (!opts) + return 1; + if (opts->do_nothing) { + opts_free(opts); + return 0; + } + + if (opts->remote > 0) { + if (opts->width < 0) + opts->width = 80; + if (opts->height < 0) + opts->height = 25; + if (opts->width > 999999) + opts->width = 999999; + if (opts->height > 999999) + opts->height = 999999; + if ((opts->interval != 0) && (opts->interval < 0.1)) + opts->interval = 0.1; + if (opts->interval > 600) + opts->interval = 600; + retcode = remote_set(opts); + opts_free(opts); + return retcode; + } + + /* + * If no files were given, pretend "-" was given (stdin). + */ + if (opts->argc == 0) { + opts->argv[opts->argc++] = "-"; + } + + if (opts->size == 0) { + pv_calc_total_size(opts); + } + + if (opts->size < 1) + opts->eta = 0; + + if ((isatty(STDERR_FILENO) == 0) + && (opts->force == 0) + && (opts->numeric == 0)) { + opts->no_op = 1; + } + + if (opts->width == 0) { + int tmpheight; + tmpheight = opts->height; + pv_screensize(opts); + if (tmpheight > 0) + opts->height = tmpheight; + } + + if (opts->height == 0) { + int tmpwidth; + tmpwidth = opts->width; + pv_screensize(opts); + if (tmpwidth > 0) + opts->width = tmpwidth; + } + + /* + * Width and height bounds checking (and defaults). + */ + if (opts->width < 1) + opts->width = 80; + + if (opts->height < 1) + opts->height = 25; + + if (opts->width > 999999) + opts->width = 999999; + + if (opts->height > 999999) + opts->height = 999999; + + /* + * Interval must be at least 0.1 second, and at most 10 minutes. + */ + if (opts->interval < 0.1) + opts->interval = 0.1; + if (opts->interval > 600) + opts->interval = 600; + +#ifdef MAKE_STDOUT_NONBLOCKING + /* + * Try and make standard output use non-blocking I/O. + * + * Note that this can cause problems with (broken) applications + * such as dd. + */ + fcntl(STDOUT_FILENO, F_SETFL, + O_NONBLOCK | fcntl(STDOUT_FILENO, F_GETFL)); +#endif /* MAKE_STDOUT_NONBLOCKING */ + + /* + * Set terminal option TOSTOP so we get signal SIGTTOU if we try to + * write to the terminal while backgrounded. + * + * Also, save the current terminal attributes for later restoration. + */ + tcgetattr(STDERR_FILENO, &t); + t_save = t; + t.c_lflag |= TOSTOP; + tcsetattr(STDERR_FILENO, TCSANOW, &t); + + opts->current_file = "(stdin)"; + + pv_sig_init(); + remote_sig_init(opts); + + retcode = pv_main_loop(opts); + + opts_free(opts); + + tcsetattr(STDERR_FILENO, TCSANOW, &t_save); + + return retcode; +} + +/* EOF */ |