int ipcs_main(int argc UNUSED_PARAM, char **argv) { int id = 0; unsigned flags = 0; unsigned opt; char *opt_i; #define flag_print (1<<0) #define flag_msg (1<<1) #define flag_sem (1<<2) #define flag_shm (1<<3) opt = getopt32(argv, "i:aqsmtcplu", &opt_i); if (opt & 0x1) { // -i id = xatoi(opt_i); flags |= flag_print; } if (opt & 0x2) flags |= flag_msg | flag_sem | flag_shm; // -a if (opt & 0x4) flags |= flag_msg; // -q if (opt & 0x8) flags |= flag_sem; // -s if (opt & 0x10) flags |= flag_shm; // -m if (opt & 0x20) format = TIME; // -t if (opt & 0x40) format = CREATOR; // -c if (opt & 0x80) format = PID; // -p if (opt & 0x100) format = LIMITS; // -l if (opt & 0x200) format = STATUS; // -u if (flags & flag_print) { if (flags & flag_shm) { print_shm(id); fflush_stdout_and_exit(EXIT_SUCCESS); } if (flags & flag_sem) { print_sem(id); fflush_stdout_and_exit(EXIT_SUCCESS); } if (flags & flag_msg) { print_msg(id); fflush_stdout_and_exit(EXIT_SUCCESS); } bb_show_usage(); } if (!(flags & (flag_shm | flag_msg | flag_sem))) flags |= flag_msg | flag_shm | flag_sem; bb_putchar('\n'); if (flags & flag_shm) { do_shm(); bb_putchar('\n'); } if (flags & flag_sem) { do_sem(); bb_putchar('\n'); } if (flags & flag_msg) { do_msg(); bb_putchar('\n'); } fflush_stdout_and_exit(EXIT_SUCCESS); }
int ipcs_main(int argc UNUSED_PARAM, char **argv) { int format = 0; unsigned opt; char *opt_i; opt = getopt32(argv, "i:aqsmtcplu", &opt_i); #define flag_msg (1<<2) #define flag_sem (1<<3) #define flag_shm (1<<4) if (opt & (1<<5)) format = TIME; // -t if (opt & (1<<6)) format = CREATOR; // -c if (opt & (1<<7)) format = PID; // -p if (opt & (1<<8)) format = LIMITS; // -l if (opt & (1<<9)) format = STATUS; // -u if (opt & (1<<0)) { // -i int id; id = xatoi(opt_i); if (opt & flag_shm) { print_shm(id); fflush_stdout_and_exit(EXIT_SUCCESS); } if (opt & flag_sem) { print_sem(id); fflush_stdout_and_exit(EXIT_SUCCESS); } if (opt & flag_msg) { print_msg(id); fflush_stdout_and_exit(EXIT_SUCCESS); } bb_show_usage(); } if ((opt & (1<<1)) // -a || !(opt & (flag_msg | flag_sem | flag_shm)) // none of -q,-s,-m == all ) { opt |= flag_msg | flag_sem | flag_shm; } bb_putchar('\n'); if (opt & flag_msg) { do_msg(format); bb_putchar('\n'); } if (opt & flag_shm) { do_shm(format); bb_putchar('\n'); } if (opt & flag_sem) { do_sem(format); bb_putchar('\n'); } fflush_stdout_and_exit(EXIT_SUCCESS); }
int catv_main(int argc ATTRIBUTE_UNUSED, char **argv) { int retval = EXIT_SUCCESS; int fd; unsigned flags; flags = getopt32(argv, "etv"); #define CATV_OPT_e (1<<0) #define CATV_OPT_t (1<<1) #define CATV_OPT_v (1<<2) flags ^= CATV_OPT_v; argv += optind; /* Read from stdin if there's nothing else to do. */ if (!argv[0]) *--argv = (char*)"-"; do { fd = open_or_warn_stdin(*argv); if (fd < 0) { retval = EXIT_FAILURE; continue; } for (;;) { int i, res; #define read_buf bb_common_bufsiz1 res = read(fd, read_buf, COMMON_BUFSIZE); if (res < 0) retval = EXIT_FAILURE; if (res < 1) break; for (i = 0; i < res; i++) { unsigned char c = read_buf[i]; if (c > 126 && (flags & CATV_OPT_v)) { if (c == 127) { printf("^?"); continue; } printf("M-"); c -= 128; } if (c < 32) { if (c == 10) { if (flags & CATV_OPT_e) bb_putchar('$'); } else if (flags & (c==9 ? CATV_OPT_t : CATV_OPT_v)) { printf("^%c", c+'@'); continue; } } bb_putchar(c); } } if (ENABLE_FEATURE_CLEAN_UP && fd) close(fd); } while (*++argv); fflush_stdout_and_exit(retval); }
int rx_main(int argc, char **argv) { struct termios tty, orig_tty; int termios_err; int file_fd; int n; if (argc != 2) bb_show_usage(); /* Disabled by vda: * why we can't receive from stdin? Why we *require* * controlling tty?? */ /*read_fd = xopen(CURRENT_TTY, O_RDWR);*/ file_fd = xopen(argv[1], O_RDWR|O_CREAT|O_TRUNC); termios_err = tcgetattr(read_fd, &tty); if (termios_err == 0) { orig_tty = tty; cfmakeraw(&tty); tcsetattr(read_fd, TCSAFLUSH, &tty); } /* No SA_RESTART: we want ALRM to interrupt read() */ signal_no_SA_RESTART_empty_mask(SIGALRM, sigalrm_handler); n = receive(file_fd); if (termios_err == 0) tcsetattr(read_fd, TCSAFLUSH, &orig_tty); if (ENABLE_FEATURE_CLEAN_UP) close(file_fd); fflush_stdout_and_exit(n >= 0); }
int which_main(int argc, char **argv) { int status = EXIT_SUCCESS; char *p; if (argc <= 1 || argv[1][0] == '-') { bb_show_usage(); } /* We shouldn't do this. Ever. Not our business. if (!getenv("PATH")) { putenv((char*)bb_PATH_root_path); } */ while (--argc > 0) { argv++; if (strchr(*argv, '/')) { if (execable_file(*argv)) { puts(*argv); continue; } } else { p = find_execable(*argv); if (p) { puts(p); free(p); continue; } } status = EXIT_FAILURE; } fflush_stdout_and_exit(status); }
int which_main(int argc, char **argv) { int status = EXIT_SUCCESS; char *p; if (argc <= 1 || argv[1][0] == '-') { bb_show_usage(); } if (!getenv("PATH")) { setenv("PATH", "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin", 1); } while (--argc > 0) { argv++; if (strchr(*argv, '/')) { if (execable_file(*argv)) { puts(*argv); continue; } } else { p = find_execable(*argv); if (p) { puts(p); free(p); continue; } } status = EXIT_FAILURE; } fflush_stdout_and_exit(status); }
int time_main(int argc UNUSED_PARAM, char **argv) { resource_t res; const char *output_format = default_format; int opt; opt_complementary = "-1"; /* at least one arg */ /* "+": stop on first non-option */ opt = getopt32(argv, "+vp"); argv += optind; if (opt & 1) output_format = long_format; if (opt & 2) output_format = posix_format; run_command(argv, &res); /* Cheat. printf's are shorter :) */ /* (but see bb_putchar() body for additional wrinkle!) */ xdup2(2, 1); /* just in case libc does something silly :( */ stdout = stderr; summarize(output_format, argv, &res); if (WIFSTOPPED(res.waitstatus)) return WSTOPSIG(res.waitstatus); if (WIFSIGNALED(res.waitstatus)) return WTERMSIG(res.waitstatus); if (WIFEXITED(res.waitstatus)) return WEXITSTATUS(res.waitstatus); fflush_stdout_and_exit(EXIT_SUCCESS); }
int time_main(int argc UNUSED_PARAM, char **argv) { resource_t res; const char *output_format = default_format; int opt; opt_complementary = "-1"; /* at least one arg */ /* "+": stop on first non-option */ opt = getopt32(argv, "+vp"); argv += optind; if (opt & 1) output_format = long_format; if (opt & 2) output_format = posix_format; run_command(argv, &res); /* Cheat. printf's are shorter :) */ xdup2(STDERR_FILENO, STDOUT_FILENO); summarize(output_format, argv, &res); if (WIFSTOPPED(res.waitstatus)) return WSTOPSIG(res.waitstatus); if (WIFSIGNALED(res.waitstatus)) return WTERMSIG(res.waitstatus); if (WIFEXITED(res.waitstatus)) return WEXITSTATUS(res.waitstatus); fflush_stdout_and_exit(EXIT_SUCCESS); }
int tty_main(int argc, char **argv) { const char *s; int silent; /* Note: No longer relevant in SUSv3. */ int retval; xfunc_error_retval = 2; /* SUSv3 requires > 1 for error. */ silent = getopt32(argc, argv, "s"); /* gnu tty outputs a warning that it is ignoring all args. */ bb_warn_ignoring_args(argc - optind); retval = 0; if ((s = ttyname(0)) == NULL) { /* According to SUSv3, ttyname can on fail with EBADF or ENOTTY. * We know the file descriptor is good, so failure means not a tty. */ s = "not a tty"; retval = 1; } if (!silent) { puts(s); } fflush_stdout_and_exit(retval); }
int printenv_main(int argc UNUSED_PARAM, char **argv) { int exit_code = EXIT_SUCCESS; /* no variables specified, show whole env */ if (!argv[1]) { char **e = environ; /* environ can be NULL! (for example, after clearenv()) * Check for that: */ if (e) while (*e) puts(*e++); } else { /* search for specified variables and print them out if found */ char *arg, *env; while ((arg = *++argv) != NULL) { env = getenv(arg); if (env) puts(env); else exit_code = EXIT_FAILURE; } } fflush_stdout_and_exit(exit_code); }
int realpath_main(int argc ATTRIBUTE_UNUSED, char **argv) { int retval = EXIT_SUCCESS; #if PATH_MAX > (BUFSIZ+1) RESERVE_CONFIG_BUFFER(resolved_path, PATH_MAX); # define resolved_path_MUST_FREE 1 #else #define resolved_path bb_common_bufsiz1 # define resolved_path_MUST_FREE 0 #endif if (!*++argv) { bb_show_usage(); } do { if (realpath(*argv, resolved_path) != NULL) { puts(resolved_path); } else { retval = EXIT_FAILURE; bb_simple_perror_msg(*argv); } } while (*++argv); #if ENABLE_FEATURE_CLEAN_UP && resolved_path_MUST_FREE RELEASE_CONFIG_BUFFER(resolved_path); #endif fflush_stdout_and_exit(retval); }
int whoami_main(int argc, char **argv) { if (argc > 1) bb_show_usage(); puts(bb_getpwuid(NULL, geteuid(), -1)); /* exits on error */ fflush_stdout_and_exit(EXIT_SUCCESS); }
/* Exit the program gracefully */ static void less_exit(int code) { /* TODO: We really should save the terminal state when we start, * and restore it when we exit. Less does this with the * "ti" and "te" termcap commands; can this be done with * only termios.h? */ bb_putchar('\n'); fflush_stdout_and_exit(code); }
int catv_main(int argc UNUSED_PARAM, char **argv) { int retval = EXIT_SUCCESS; int fd; unsigned opts; #define CATV_OPT_e (1<<0) #define CATV_OPT_t (1<<1) #define CATV_OPT_v (1<<2) typedef char BUG_const_mismatch[ CATV_OPT_e == VISIBLE_ENDLINE && CATV_OPT_t == VISIBLE_SHOW_TABS ? 1 : -1 ]; opts = getopt32(argv, "etv"); argv += optind; #if 0 /* These consts match, we can just pass "opts" to visible() */ if (opts & CATV_OPT_e) flags |= VISIBLE_ENDLINE; if (opts & CATV_OPT_t) flags |= VISIBLE_SHOW_TABS; #endif /* Read from stdin if there's nothing else to do. */ if (!argv[0]) *--argv = (char*)"-"; do { fd = open_or_warn_stdin(*argv); if (fd < 0) { retval = EXIT_FAILURE; continue; } for (;;) { int i, res; #define read_buf bb_common_bufsiz1 res = read(fd, read_buf, COMMON_BUFSIZE); if (res < 0) retval = EXIT_FAILURE; if (res <= 0) break; for (i = 0; i < res; i++) { unsigned char c = read_buf[i]; if (opts & CATV_OPT_v) { putchar(c); } else { char buf[sizeof("M-^c")]; visible(c, buf, opts); fputs(buf, stdout); } } } if (ENABLE_FEATURE_CLEAN_UP && fd) close(fd); } while (*++argv); fflush_stdout_and_exit(retval); }
int hostid_main(int argc, char ATTRIBUTE_UNUSED **argv) { if (argc > 1) { bb_show_usage(); } printf("%lx\n", gethostid()); fflush_stdout_and_exit(EXIT_SUCCESS); }
int length_main(int argc, char **argv) { if ((argc != 2) || (**(++argv) == '-')) { bb_show_usage(); } printf("%lu\n", (unsigned long)strlen(*argv)); fflush_stdout_and_exit(EXIT_SUCCESS); }
int catv_main(int argc, char **argv) { int retval = EXIT_SUCCESS, fd; unsigned flags; flags = getopt32(argc, argv, "etv"); #define CATV_OPT_e (1<<0) #define CATV_OPT_t (1<<1) #define CATV_OPT_v (1<<2) flags ^= CATV_OPT_v; argv += optind; do { /* Read from stdin if there's nothing else to do. */ fd = 0; if (*argv && 0 > (fd = xopen(*argv, O_RDONLY))) retval = EXIT_FAILURE; else for (;;) { int i, res; res = read(fd, bb_common_bufsiz1, sizeof(bb_common_bufsiz1)); if (res < 0) retval = EXIT_FAILURE; if (res < 1) break; for (i = 0; i < res; i++) { char c = bb_common_bufsiz1[i]; if (c > 126 && (flags & CATV_OPT_v)) { if (c == 127) { printf("^?"); continue; } else { printf("M-"); c -= 128; } } if (c < 32) { if (c == 10) { if (flags & CATV_OPT_e) putchar('$'); } else if (flags & (c==9 ? CATV_OPT_t : CATV_OPT_v)) { printf("^%c", c+'@'); continue; } } putchar(c); } } if (ENABLE_FEATURE_CLEAN_UP && fd) close(fd); } while (*++argv); fflush_stdout_and_exit(retval); }
int uname_main(int argc, char **argv) { uname_info_t uname_info; #if defined(__sparc__) && defined(__linux__) char *fake_sparc = getenv("FAKE_SPARC"); #endif const unsigned short int *delta; char toprint; toprint = getopt32(argc, argv, options); if (argc != optind) { bb_show_usage(); } if (toprint & (1 << 6)) { toprint = 0x3f; } if (toprint == 0) { toprint = 1; /* sysname */ } if (uname(&uname_info.name) == -1) { bb_error_msg_and_die("cannot get system name"); } #if defined(__sparc__) && defined(__linux__) if ((fake_sparc != NULL) && ((fake_sparc[0] == 'y') || (fake_sparc[0] == 'Y'))) { strcpy(uname_info.name.machine, "sparc"); } #endif strcpy(uname_info.processor, "unknown"); delta = utsname_offset; do { if (toprint & 1) { printf(((char *)(&uname_info)) + *delta); if (toprint > 1) { putchar(' '); } } ++delta; } while (toprint >>= 1); putchar('\n'); fflush_stdout_and_exit(EXIT_SUCCESS); }
int env_main(int argc UNUSED_PARAM, char **argv) { char **ep; unsigned opt; llist_t *unset_env = NULL; opt_complementary = "u::"; #if ENABLE_FEATURE_ENV_LONG_OPTIONS applet_long_options = env_longopts; #endif opt = getopt32(argv, "+iu:", &unset_env); argv += optind; if (*argv && LONE_DASH(argv[0])) { opt |= 1; ++argv; } if (opt & 1) { clearenv(); } while (unset_env) { char *var = llist_pop(&unset_env); /* This does not handle -uVAR=VAL * (coreutils _sets_ the variable in that case): */ /*unsetenv(var);*/ /* This does, but uses somewhan undocumented feature that * putenv("name_without_equal_sign") unsets the variable: */ putenv(var); } while (*argv && (strchr(*argv, '=') != NULL)) { if (putenv(*argv) < 0) { bb_perror_msg_and_die("putenv"); } ++argv; } if (*argv) { BB_EXECVP(*argv, argv); /* SUSv3-mandated exit codes. */ xfunc_error_retval = (errno == ENOENT) ? 127 : 126; bb_simple_perror_msg_and_die(*argv); } for (ep = environ; *ep; ep++) { puts(*ep); } fflush_stdout_and_exit(EXIT_SUCCESS); }
int env_main(int argc ATTRIBUTE_UNUSED, char **argv) { /* cleanenv was static - why? */ char *cleanenv[1]; char **ep; unsigned opt; llist_t *unset_env = NULL; opt_complementary = "u::"; #if ENABLE_FEATURE_ENV_LONG_OPTIONS applet_long_options = env_longopts; #endif opt = getopt32(argv, "+iu:", &unset_env); argv += optind; if (*argv && LONE_DASH(argv[0])) { opt |= 1; ++argv; } if (opt & 1) { cleanenv[0] = NULL; environ = cleanenv; } else { while (unset_env) { unsetenv(unset_env->data); unset_env = unset_env->link; } } while (*argv && (strchr(*argv, '=') != NULL)) { if (putenv(*argv) < 0) { bb_perror_msg_and_die("putenv"); } ++argv; } if (*argv) { BB_EXECVP(*argv, argv); /* SUSv3-mandated exit codes. */ xfunc_error_retval = (errno == ENOENT) ? 127 : 126; bb_simple_perror_msg_and_die(*argv); } for (ep = environ; *ep; ep++) { puts(*ep); } fflush_stdout_and_exit(0); }
static int catv(unsigned opts, char **argv) { int retval = EXIT_SUCCESS; int fd; BUILD_BUG_ON(CATV_OPT_e != VISIBLE_ENDLINE); BUILD_BUG_ON(CATV_OPT_t != VISIBLE_SHOW_TABS); #if 0 /* These consts match, we can just pass "opts" to visible() */ if (opts & CATV_OPT_e) flags |= VISIBLE_ENDLINE; if (opts & CATV_OPT_t) flags |= VISIBLE_SHOW_TABS; #endif /* Read from stdin if there's nothing else to do. */ if (!argv[0]) *--argv = (char*)"-"; #define read_buf bb_common_bufsiz1 setup_common_bufsiz(); do { fd = open_or_warn_stdin(*argv); if (fd < 0) { retval = EXIT_FAILURE; continue; } for (;;) { int i, res; res = read(fd, read_buf, COMMON_BUFSIZE); if (res < 0) retval = EXIT_FAILURE; if (res <= 0) break; for (i = 0; i < res; i++) { unsigned char c = read_buf[i]; char buf[sizeof("M-^c")]; visible(c, buf, opts); fputs(buf, stdout); } } if (ENABLE_FEATURE_CLEAN_UP && fd) close(fd); } while (*++argv); fflush_stdout_and_exit(retval); }
int expr_main(int argc UNUSED_PARAM, char **argv) { VALUE *v; xfunc_error_retval = 2; /* coreutils compat */ G.args = argv + 1; if (*G.args == NULL) { bb_error_msg_and_die("too few arguments"); } v = eval(); if (*G.args) bb_error_msg_and_die("syntax error"); if (v->type == INTEGER) printf("%" PF_REZ "d\n", PF_REZ_TYPE v->u.i); else puts(v->u.s); fflush_stdout_and_exit(null(v)); }
int time_main(int argc, char **argv) { resource_t res; const char *output_format = default_format; char c; goto next; /* Parse any options -- don't use getopt() here so we don't * consume the args of our client application... */ while (argc > 0 && argv[0][0] == '-') { while ((c = *++*argv)) { switch (c) { case 'v': output_format = long_format; break; case 'p': output_format = posix_format; break; default: bb_show_usage(); } } next: argv++; argc--; if (!argc) bb_show_usage(); } run_command(argv, &res); /* Cheat. printf's are shorter :) */ stdout = stderr; dup2(2, 1); /* just in case libc does something silly :( */ summarize(output_format, argv, &res); if (WIFSTOPPED(res.waitstatus)) return WSTOPSIG(res.waitstatus); if (WIFSIGNALED(res.waitstatus)) return WTERMSIG(res.waitstatus); if (WIFEXITED(res.waitstatus)) return WEXITSTATUS(res.waitstatus); fflush_stdout_and_exit(0); }
int uuencode_main(int argc UNUSED_PARAM, char **argv) { struct stat stat_buf; int src_fd = STDIN_FILENO; const char *tbl; mode_t mode; char src_buf[SRC_BUF_SIZE]; char dst_buf[DST_BUF_SIZE + 1]; tbl = bb_uuenc_tbl_std; mode = 0666 & ~umask(0666); opt_complementary = "-1:?2"; /* must have 1 or 2 args */ if (getopt32(argv, "m")) { tbl = bb_uuenc_tbl_base64; } argv += optind; if (argv[1]) { src_fd = xopen(*argv, O_RDONLY); fstat(src_fd, &stat_buf); mode = stat_buf.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO); argv++; } printf("begin%s %o %s", tbl == bb_uuenc_tbl_std ? "" : "-base64", mode, *argv); while (1) { size_t size = full_read(src_fd, src_buf, SRC_BUF_SIZE); if (!size) break; if ((ssize_t)size < 0) bb_perror_msg_and_die(bb_msg_read_error); /* Encode the buffer we just read in */ bb_uuencode(dst_buf, src_buf, size, tbl); bb_putchar('\n'); if (tbl == bb_uuenc_tbl_std) { bb_putchar(tbl[size]); } fflush(stdout); xwrite(STDOUT_FILENO, dst_buf, 4 * ((size + 2) / 3)); } printf(tbl == bb_uuenc_tbl_std ? "\n`\nend\n" : "\n====\n"); fflush_stdout_and_exit(EXIT_SUCCESS); }
int nice_main(int argc, char **argv) { int old_priority, adjustment; old_priority = getpriority(PRIO_PROCESS, 0); if (!*++argv) { /* No args, so (GNU) output current nice value. */ printf("%d\n", old_priority); fflush_stdout_and_exit(EXIT_SUCCESS); } adjustment = 10; /* Set default adjustment. */ if (argv[0][0] == '-') { if (argv[0][1] == 'n') { /* -n */ if (argv[0][2]) { /* -nNNNN (w/o space) */ argv[0] += 2; argv--; argc++; } } else { /* -NNN (NNN may be negative) == -n NNN */ argv[0] += 1; argv--; argc++; } if (argc < 4) { /* Missing priority and/or utility! */ bb_show_usage(); } adjustment = xatoi_range(argv[1], INT_MIN/2, INT_MAX/2); argv += 2; } { /* Set our priority. */ int prio = old_priority + adjustment; if (setpriority(PRIO_PROCESS, 0, prio) < 0) { bb_perror_msg_and_die("setpriority(%d)", prio); } } execvp(*argv, argv); /* Now exec the desired program. */ /* The exec failed... */ xfunc_error_retval = (errno == ENOENT) ? 127 : 126; /* SUSv3 */ bb_perror_msg_and_die("%s", *argv); }
int printenv_main(int argc ATTRIBUTE_UNUSED, char **argv) { /* no variables specified, show whole env */ if (!argv[1]) { int e = 0; while (environ[e]) puts(environ[e++]); } else { /* search for specified variables and print them out if found */ char *arg, *env; while ((arg = *++argv) != NULL) { env = getenv(arg); if (env) puts(env); } } fflush_stdout_and_exit(EXIT_SUCCESS); }
int realpath_main(int argc UNUSED_PARAM, char **argv) { int retval = EXIT_SUCCESS; if (!*++argv) { bb_show_usage(); } do { char *resolved_path = xmalloc_realpath(*argv); if (resolved_path != NULL) { puts(resolved_path); free(resolved_path); } else { retval = EXIT_FAILURE; bb_simple_perror_msg(*argv); } } while (*++argv); fflush_stdout_and_exit(retval); }
int basename_main(int argc, char **argv) { size_t m, n; char *s; if (((unsigned int)(argc-2)) >= 2) { bb_show_usage(); } s = bb_get_last_path_component(*++argv); if (*++argv) { n = strlen(*argv); m = strlen(s); if ((m > n) && ((strcmp)(s+m-n, *argv) == 0)) { s[m-n] = '\0'; } } puts(s); fflush_stdout_and_exit(EXIT_SUCCESS); }
int chrt_main(int argc ATTRIBUTE_UNUSED, char **argv) { pid_t pid = 0; unsigned opt; struct sched_param sp; char *pid_str; char *priority = priority; /* for compiler */ const char *current_new; int policy = SCHED_RR; /* at least 1 arg; only one policy accepted */ opt_complementary = "-1:r--fo:f--ro:r--fo"; opt = getopt32(argv, "+mprfo"); if (opt & OPT_r) policy = SCHED_RR; if (opt & OPT_f) policy = SCHED_FIFO; if (opt & OPT_o) policy = SCHED_OTHER; if (opt & OPT_m) { /* print min/max */ show_min_max(SCHED_FIFO); show_min_max(SCHED_RR); show_min_max(SCHED_OTHER); fflush_stdout_and_exit(EXIT_SUCCESS); } argv += optind; if (opt & OPT_p) { pid_str = *argv++; if (*argv) { /* "-p <priority> <pid> [...]" */ priority = pid_str; pid_str = *argv; } /* else "-p <pid>", and *argv == NULL */ pid = xatoul_range(pid_str, 1, ((unsigned)(pid_t)ULONG_MAX) >> 1); } else {
int chrt_main(int argc, char **argv) { pid_t pid = 0; unsigned opt; struct sched_param sp; char *p_opt = NULL, *priority = NULL; const char *state = "current\0new"; int prio = 0, policy = SCHED_RR; opt_complementary = "r--fo:f--ro:r--fo"; /* only one policy accepted */ opt = getopt32(argv, "+mp:rfo", &p_opt); if (opt & OPT_r) policy = SCHED_RR; if (opt & OPT_f) policy = SCHED_FIFO; if (opt & OPT_o) policy = SCHED_OTHER; if (opt & OPT_m) { /* print min/max */ show_min_max(SCHED_FIFO); show_min_max(SCHED_RR); show_min_max(SCHED_OTHER); fflush_stdout_and_exit(EXIT_SUCCESS); } if (opt & OPT_p) { if (argc == optind+1) { /* -p <priority> <pid> */ priority = p_opt; p_opt = argv[optind]; } argv += optind; /* me -p <arg> */ pid = xatoul_range(p_opt, 1, ULONG_MAX); /* -p <pid> */ } else { argv += optind; /* me -p <arg> */ priority = *argv; } if (priority) { /* from the manpage of sched_getscheduler: [...] sched_priority can have a value in the range 0 to 99. [...] SCHED_OTHER or SCHED_BATCH must be assigned the static priority 0. [...] SCHED_FIFO or SCHED_RR can have a static priority in the range 1 to 99. */ prio = xstrtol_range(priority, 0, policy == SCHED_OTHER ? 0 : 1, 99); } if (opt & OPT_p) { int pol = 0; print_rt_info: pol = sched_getscheduler(pid); if (pol < 0) bb_perror_msg_and_die("failed to %cet pid %d's policy", 'g', pid); printf("pid %d's %s scheduling policy: %s\n", pid, state, policies[pol].name); if (sched_getparam(pid, &sp)) bb_perror_msg_and_die("failed to get pid %d's attributes", pid); printf("pid %d's %s scheduling priority: %d\n", pid, state, sp.sched_priority); if (!*argv) /* no new prio given or we did print already, done. */ return EXIT_SUCCESS; } sp.sched_priority = prio; if (sched_setscheduler(pid, policy, &sp) < 0) bb_perror_msg_and_die("failed to %cet pid %d's policy", 's', pid); if (opt & OPT_p) { state += 8; ++argv; goto print_rt_info; } ++argv; BB_EXECVP(*argv, argv); bb_simple_perror_msg_and_die(*argv); }