From ac47a00e2ec398b04c3141cd3434a6e4b95740b1 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 11 Apr 2017 19:17:59 +0200 Subject: partprobe: new applet function old new delta partprobe_main - 79 +79 packed_usage 31485 31511 +26 applet_names 2608 2618 +10 applet_main 1512 1516 +4 applet_install_loc 189 190 +1 ------------------------------------------------------------------------------ (add/remove: 2/0 grow/shrink: 4/0 up/down: 120/0) Total: 120 bytes Signed-off-by: Denys Vlasenko --- miscutils/partprobe.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 miscutils/partprobe.c (limited to 'miscutils') diff --git a/miscutils/partprobe.c b/miscutils/partprobe.c new file mode 100644 index 000000000..38831598d --- /dev/null +++ b/miscutils/partprobe.c @@ -0,0 +1,56 @@ +/* vi: set sw=4 ts=4: */ +/* + * Copyright (C) 2017 Denys Vlasenko + * + * Licensed under GPLv2, see file LICENSE in this source tree. + */ +//config:config PARTPROBE +//config: bool "partprobe" +//config: default y +//config: select PLATFORM_LINUX +//config: help +//config: Ask kernel to rescan partition table. + +//applet:IF_PARTPROBE(APPLET(partprobe, BB_DIR_USR_SBIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_PARTPROBE) += partprobe.o + +#include +#include "libbb.h" +#ifndef BLKRRPART +# define BLKRRPART _IO(0x12,95) +#endif + +//usage:#define partprobe_trivial_usage +//usage: "DEVICE..." +//usage:#define partprobe_full_usage "\n\n" +//usage: "Ask kernel to rescan partition table" +// +// partprobe (GNU parted) 3.2: +// -d, --dry-run Don't update the kernel +// -s, --summary Show a summary of devices and their partitions + +int partprobe_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int partprobe_main(int argc UNUSED_PARAM, char **argv) +{ + getopt32(argv, ""); + argv += optind; + + /* "partprobe" with no arguments just does nothing */ + + while (*argv) { + int fd = xopen(*argv, O_RDONLY); + /* + * Newer versions of parted scan partition tables themselves and + * use BLKPG ioctl (BLKPG_DEL_PARTITION / BLKPG_ADD_PARTITION) + * since this way kernel does not need to know + * partition table formats. + * We use good old BLKRRPART: + */ + ioctl_or_perror_and_die(fd, BLKRRPART, NULL, "%s", *argv); + close(fd); + argv++; + } + + return EXIT_SUCCESS; +} -- cgit v1.2.3-55-g6feb From 783d57af7bb2b851c16cf87df848e0365e5052da Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 12 Apr 2017 13:58:40 +0200 Subject: Sort some miscutils/ applets into coreutils or util-linux No code changes Signed-off-by: Denys Vlasenko --- coreutils/timeout.c | 127 ++++++++++++++++++++ miscutils/chrt.c | 149 ------------------------ miscutils/eject.c | 152 ------------------------ miscutils/ionice.c | 115 ------------------- miscutils/last.c | 166 --------------------------- miscutils/last_fancy.c | 300 ------------------------------------------------ miscutils/mountpoint.c | 105 ----------------- miscutils/setsid.c | 82 ------------- miscutils/taskset.c | 221 ----------------------------------- miscutils/timeout.c | 127 -------------------- miscutils/wall.c | 63 ---------- util-linux/chrt.c | 149 ++++++++++++++++++++++++ util-linux/eject.c | 152 ++++++++++++++++++++++++ util-linux/ionice.c | 115 +++++++++++++++++++ util-linux/last.c | 166 +++++++++++++++++++++++++++ util-linux/last_fancy.c | 300 ++++++++++++++++++++++++++++++++++++++++++++++++ util-linux/mountpoint.c | 105 +++++++++++++++++ util-linux/setsid.c | 82 +++++++++++++ util-linux/taskset.c | 221 +++++++++++++++++++++++++++++++++++ util-linux/wall.c | 63 ++++++++++ 20 files changed, 1480 insertions(+), 1480 deletions(-) create mode 100644 coreutils/timeout.c delete mode 100644 miscutils/chrt.c delete mode 100644 miscutils/eject.c delete mode 100644 miscutils/ionice.c delete mode 100644 miscutils/last.c delete mode 100644 miscutils/last_fancy.c delete mode 100644 miscutils/mountpoint.c delete mode 100644 miscutils/setsid.c delete mode 100644 miscutils/taskset.c delete mode 100644 miscutils/timeout.c delete mode 100644 miscutils/wall.c create mode 100644 util-linux/chrt.c create mode 100644 util-linux/eject.c create mode 100644 util-linux/ionice.c create mode 100644 util-linux/last.c create mode 100644 util-linux/last_fancy.c create mode 100644 util-linux/mountpoint.c create mode 100644 util-linux/setsid.c create mode 100644 util-linux/taskset.c create mode 100644 util-linux/wall.c (limited to 'miscutils') diff --git a/coreutils/timeout.c b/coreutils/timeout.c new file mode 100644 index 000000000..f29dc8a9c --- /dev/null +++ b/coreutils/timeout.c @@ -0,0 +1,127 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * COPYING NOTES + * + * timeout.c -- a timeout handler for shell commands + * + * Copyright (C) 2005-6, Roberto A. Foglietta + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * REVISION NOTES: + * released 17-11-2005 by Roberto A. Foglietta + * talarm 04-12-2005 by Roberto A. Foglietta + * modified 05-12-2005 by Roberto A. Foglietta + * sizerdct 06-12-2005 by Roberto A. Foglietta + * splitszf 12-05-2006 by Roberto A. Foglietta + * rewrite 14-11-2008 vda + */ +//config:config TIMEOUT +//config: bool "timeout" +//config: default y +//config: help +//config: Runs a program and watches it. If it does not terminate in +//config: specified number of seconds, it is sent a signal. + +//applet:IF_TIMEOUT(APPLET(timeout, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_TIMEOUT) += timeout.o + +//usage:#define timeout_trivial_usage +//usage: "[-t SECS] [-s SIG] PROG ARGS" +//usage:#define timeout_full_usage "\n\n" +//usage: "Runs PROG. Sends SIG to it if it is not gone in SECS seconds.\n" +//usage: "Defaults: SECS: 10, SIG: TERM." + +#include "libbb.h" + +int timeout_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int timeout_main(int argc UNUSED_PARAM, char **argv) +{ + int signo; + int status; + int parent = 0; + int timeout = 10; + pid_t pid; +#if !BB_MMU + char *sv1, *sv2; +#endif + const char *opt_s = "TERM"; + + /* -p option is not documented, it is needed to support NOMMU. */ + + /* -t SECONDS; -p PARENT_PID */ + /* '+': stop at first non-option */ + getopt32(argv, "+s:t:+" USE_FOR_NOMMU("p:+"), &opt_s, &timeout, &parent); + /*argv += optind; - no, wait for bb_daemonize_or_rexec! */ + signo = get_signum(opt_s); + if (signo < 0) + bb_error_msg_and_die("unknown signal '%s'", opt_s); + + /* We want to create a grandchild which will watch + * and kill the grandparent. Other methods: + * making parent watch child disrupts parent<->child link + * (example: "tcpsvd 0.0.0.0 1234 timeout service_prog" - + * it's better if service_prog is a child of tcpsvd!), + * making child watch parent results in programs having + * unexpected children. */ + + if (parent) /* we were re-execed, already grandchild */ + goto grandchild; + if (!argv[optind]) /* no PROG? */ + bb_show_usage(); + +#if !BB_MMU + sv1 = argv[optind]; + sv2 = argv[optind + 1]; +#endif + pid = xvfork(); + if (pid == 0) { + /* Child: spawn grandchild and exit */ + parent = getppid(); +#if !BB_MMU + argv[optind] = xasprintf("-p%u", parent); + argv[optind + 1] = NULL; +#endif + /* NB: exits with nonzero on error: */ + bb_daemonize_or_rexec(0, argv); + /* Here we are grandchild. Sleep, then kill grandparent */ + grandchild: + /* Just sleep(HUGE_NUM); kill(parent) may kill wrong process! */ + while (1) { + sleep(1); + if (--timeout <= 0) + break; + if (kill(parent, 0)) { + /* process is gone */ + return EXIT_SUCCESS; + } + } + kill(parent, signo); + return EXIT_SUCCESS; + } + + /* Parent */ + wait(&status); /* wait for child to die */ + /* Did intermediate [v]fork or exec fail? */ + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) + return EXIT_FAILURE; + /* Ok, exec a program as requested */ + argv += optind; +#if !BB_MMU + argv[0] = sv1; + argv[1] = sv2; +#endif + BB_EXECVP_or_die(argv); +} diff --git a/miscutils/chrt.c b/miscutils/chrt.c deleted file mode 100644 index 1604a6890..000000000 --- a/miscutils/chrt.c +++ /dev/null @@ -1,149 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * chrt - manipulate real-time attributes of a process - * Copyright (c) 2006-2007 Bernhard Reutner-Fischer - * - * Licensed under GPLv2 or later, see file LICENSE in this source tree. - */ -//config:config CHRT -//config: bool "chrt" -//config: default y -//config: help -//config: manipulate real-time attributes of a process. -//config: This requires sched_{g,s}etparam support in your libc. - -//applet:IF_CHRT(APPLET(chrt, BB_DIR_USR_BIN, BB_SUID_DROP)) - -//kbuild:lib-$(CONFIG_CHRT) += chrt.o - -//usage:#define chrt_trivial_usage -//usage: "[-prfom] [PRIO] [PID | PROG ARGS]" -//usage:#define chrt_full_usage "\n\n" -//usage: "Change scheduling priority and class for a process\n" -//usage: "\n -p Operate on PID" -//usage: "\n -r Set SCHED_RR class" -//usage: "\n -f Set SCHED_FIFO class" -//usage: "\n -o Set SCHED_OTHER class" -//usage: "\n -m Show min/max priorities" -//usage: -//usage:#define chrt_example_usage -//usage: "$ chrt -r 4 sleep 900; x=$!\n" -//usage: "$ chrt -f -p 3 $x\n" -//usage: "You need CAP_SYS_NICE privileges to set scheduling attributes of a process" - -#include -#include "libbb.h" - -static const struct { - int policy; - char name[sizeof("SCHED_OTHER")]; -} policies[] = { - {SCHED_OTHER, "SCHED_OTHER"}, - {SCHED_FIFO, "SCHED_FIFO"}, - {SCHED_RR, "SCHED_RR"} -}; - -//TODO: add -// -b, SCHED_BATCH -// -i, SCHED_IDLE - -static void show_min_max(int pol) -{ - const char *fmt = "%s min/max priority\t: %u/%u\n"; - int max, min; - - max = sched_get_priority_max(pol); - min = sched_get_priority_min(pol); - if ((max|min) < 0) - fmt = "%s not supported\n"; - printf(fmt, policies[pol].name, min, max); -} - -#define OPT_m (1<<0) -#define OPT_p (1<<1) -#define OPT_r (1<<2) -#define OPT_f (1<<3) -#define OPT_o (1<<4) - -int chrt_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -int chrt_main(int argc UNUSED_PARAM, 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; - - /* only one policy accepted */ - opt_complementary = "r--fo:f--ro:o--rf"; - opt = getopt32(argv, "+mprfo"); - if (opt & OPT_m) { /* print min/max and exit */ - show_min_max(SCHED_FIFO); - show_min_max(SCHED_RR); - show_min_max(SCHED_OTHER); - fflush_stdout_and_exit(EXIT_SUCCESS); - } - if (opt & OPT_r) - policy = SCHED_RR; - if (opt & OPT_f) - policy = SCHED_FIFO; - if (opt & OPT_o) - policy = SCHED_OTHER; - - argv += optind; - if (!argv[0]) - bb_show_usage(); - if (opt & OPT_p) { - pid_str = *argv++; - if (*argv) { /* "-p [...]" */ - priority = pid_str; - pid_str = *argv; - } - /* else "-p ", and *argv == NULL */ - pid = xatoul_range(pid_str, 1, ((unsigned)(pid_t)ULONG_MAX) >> 1); - } else { - priority = *argv++; - if (!*argv) - bb_show_usage(); - } - - current_new = "current\0new"; - if (opt & OPT_p) { - int pol; - print_rt_info: - pol = sched_getscheduler(pid); - if (pol < 0) - bb_perror_msg_and_die("can't %cet pid %d's policy", 'g', (int)pid); - printf("pid %d's %s scheduling policy: %s\n", - pid, current_new, policies[pol].name); - if (sched_getparam(pid, &sp)) - bb_perror_msg_and_die("can't get pid %d's attributes", (int)pid); - printf("pid %d's %s scheduling priority: %d\n", - (int)pid, current_new, sp.sched_priority); - if (!*argv) { - /* Either it was just "-p ", - * or it was "-p " and we came here - * for the second time (see goto below) */ - return EXIT_SUCCESS; - } - *argv = NULL; - current_new += 8; - } - - /* 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 static priority 0. - [...] SCHED_FIFO or SCHED_RR can have static priority in 1..99 range. - */ - sp.sched_priority = xstrtou_range(priority, 0, policy != SCHED_OTHER ? 1 : 0, 99); - - if (sched_setscheduler(pid, policy, &sp) < 0) - bb_perror_msg_and_die("can't %cet pid %d's policy", 's', (int)pid); - - if (!argv[0]) /* "-p [...]" */ - goto print_rt_info; - - BB_EXECVP_or_die(argv); -} diff --git a/miscutils/eject.c b/miscutils/eject.c deleted file mode 100644 index 667932f6c..000000000 --- a/miscutils/eject.c +++ /dev/null @@ -1,152 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * eject implementation for busybox - * - * Copyright (C) 2004 Peter Willis - * Copyright (C) 2005 Tito Ragusa - * - * Licensed under GPLv2 or later, see file LICENSE in this source tree. - */ - -/* - * This is a simple hack of eject based on something Erik posted in #uclibc. - * Most of the dirty work blatantly ripped off from cat.c =) - */ -//config:config EJECT -//config: bool "eject" -//config: default y -//config: select PLATFORM_LINUX -//config: help -//config: Used to eject cdroms. (defaults to /dev/cdrom) -//config: -//config:config FEATURE_EJECT_SCSI -//config: bool "SCSI support" -//config: default y -//config: depends on EJECT -//config: help -//config: Add the -s option to eject, this allows to eject SCSI-Devices and -//config: usb-storage devices. - -//applet:IF_EJECT(APPLET(eject, BB_DIR_USR_BIN, BB_SUID_DROP)) - -//kbuild:lib-$(CONFIG_EJECT) += eject.o - -//usage:#define eject_trivial_usage -//usage: "[-t] [-T] [DEVICE]" -//usage:#define eject_full_usage "\n\n" -//usage: "Eject DEVICE or default /dev/cdrom\n" -//usage: IF_FEATURE_EJECT_SCSI( -//usage: "\n -s SCSI device" -//usage: ) -//usage: "\n -t Close tray" -//usage: "\n -T Open/close tray (toggle)" - -#include -#include "libbb.h" -#if ENABLE_FEATURE_EJECT_SCSI -/* Must be after libbb.h: they need size_t */ -# include "fix_u32.h" -# include -# include -#endif - -#define dev_fd 3 - -/* Code taken from the original eject (http://eject.sourceforge.net/), - * refactored it a bit for busybox (ne-bb@nicoerfurth.de) */ - -#if ENABLE_FEATURE_EJECT_SCSI -static void eject_scsi(const char *dev) -{ - static const char sg_commands[3][6] ALIGN1 = { - { ALLOW_MEDIUM_REMOVAL, 0, 0, 0, 0, 0 }, - { START_STOP, 0, 0, 0, 1, 0 }, - { START_STOP, 0, 0, 0, 2, 0 } - }; - - unsigned i; - unsigned char sense_buffer[32]; - unsigned char inqBuff[2]; - sg_io_hdr_t io_hdr; - - if ((ioctl(dev_fd, SG_GET_VERSION_NUM, &i) < 0) || (i < 30000)) - bb_error_msg_and_die("not a sg device or old sg driver"); - - memset(&io_hdr, 0, sizeof(sg_io_hdr_t)); - io_hdr.interface_id = 'S'; - io_hdr.cmd_len = 6; - io_hdr.mx_sb_len = sizeof(sense_buffer); - io_hdr.dxfer_direction = SG_DXFER_NONE; - /* io_hdr.dxfer_len = 0; */ - io_hdr.dxferp = inqBuff; - io_hdr.sbp = sense_buffer; - io_hdr.timeout = 2000; - - for (i = 0; i < 3; i++) { - io_hdr.cmdp = (void *)sg_commands[i]; - ioctl_or_perror_and_die(dev_fd, SG_IO, (void *)&io_hdr, "%s", dev); - } - - /* force kernel to reread partition table when new disc is inserted */ - ioctl(dev_fd, BLKRRPART); -} -#else -# define eject_scsi(dev) ((void)0) -#endif - -/* various defines swiped from linux/cdrom.h */ -#define CDROMCLOSETRAY 0x5319 /* pendant of CDROMEJECT */ -#define CDROMEJECT 0x5309 /* Ejects the cdrom media */ -#define CDROM_DRIVE_STATUS 0x5326 /* Get tray position, etc. */ -/* drive status possibilities returned by CDROM_DRIVE_STATUS ioctl */ -#define CDS_TRAY_OPEN 2 - -#define FLAG_CLOSE 1 -#define FLAG_SMART 2 -#define FLAG_SCSI 4 - -static void eject_cdrom(unsigned flags, const char *dev) -{ - int cmd = CDROMEJECT; - - if (flags & FLAG_CLOSE - || ((flags & FLAG_SMART) && ioctl(dev_fd, CDROM_DRIVE_STATUS) == CDS_TRAY_OPEN) - ) { - cmd = CDROMCLOSETRAY; - } - - ioctl_or_perror_and_die(dev_fd, cmd, NULL, "%s", dev); -} - -int eject_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -int eject_main(int argc UNUSED_PARAM, char **argv) -{ - unsigned flags; - const char *device; - - opt_complementary = "?1:t--T:T--t"; - flags = getopt32(argv, "tT" IF_FEATURE_EJECT_SCSI("s")); - device = argv[optind] ? argv[optind] : "/dev/cdrom"; - - /* We used to do "umount " here, but it was buggy - if something was mounted OVER cdrom and - if cdrom is mounted many times. - - This works equally well (or better): - #!/bin/sh - umount /dev/cdrom - eject /dev/cdrom - */ - - xmove_fd(xopen_nonblocking(device), dev_fd); - - if (ENABLE_FEATURE_EJECT_SCSI && (flags & FLAG_SCSI)) - eject_scsi(device); - else - eject_cdrom(flags, device); - - if (ENABLE_FEATURE_CLEAN_UP) - close(dev_fd); - - return EXIT_SUCCESS; -} diff --git a/miscutils/ionice.c b/miscutils/ionice.c deleted file mode 100644 index c54b3a6e1..000000000 --- a/miscutils/ionice.c +++ /dev/null @@ -1,115 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * ionice implementation for busybox based on linux-utils-ng 2.14 - * - * Copyright (C) 2008 by - * - * Licensed under GPLv2 or later, see file LICENSE in this source tree. - */ -//config:config IONICE -//config: bool "ionice" -//config: default y -//config: select PLATFORM_LINUX -//config: help -//config: Set/set program io scheduling class and priority -//config: Requires kernel >= 2.6.13 - -//applet:IF_IONICE(APPLET(ionice, BB_DIR_BIN, BB_SUID_DROP)) - -//kbuild:lib-$(CONFIG_IONICE) += ionice.o - -//usage:#define ionice_trivial_usage -//usage: "[-c 1-3] [-n 0-7] [-p PID] [PROG]" -//usage:#define ionice_full_usage "\n\n" -//usage: "Change I/O priority and class\n" -//usage: "\n -c Class. 1:realtime 2:best-effort 3:idle" -//usage: "\n -n Priority" - -#include -#include -#include "libbb.h" - -static int ioprio_set(int which, int who, int ioprio) -{ - return syscall(SYS_ioprio_set, which, who, ioprio); -} - -static int ioprio_get(int which, int who) -{ - return syscall(SYS_ioprio_get, which, who); -} - -enum { - IOPRIO_WHO_PROCESS = 1, - IOPRIO_WHO_PGRP, - IOPRIO_WHO_USER -}; - -enum { - IOPRIO_CLASS_NONE, - IOPRIO_CLASS_RT, - IOPRIO_CLASS_BE, - IOPRIO_CLASS_IDLE -}; - -static const char to_prio[] ALIGN1 = "none\0realtime\0best-effort\0idle"; - -#define IOPRIO_CLASS_SHIFT 13 - -int ionice_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -int ionice_main(int argc UNUSED_PARAM, char **argv) -{ - /* Defaults */ - int ioclass = 0; - int pri = 0; - int pid = 0; /* affect own porcess */ - int opt; - enum { - OPT_n = 1, - OPT_c = 2, - OPT_p = 4, - }; - - /* Numeric params */ - /* '+': stop at first non-option */ - opt = getopt32(argv, "+n:+c:+p:+", &pri, &ioclass, &pid); - argv += optind; - - if (opt & OPT_c) { - if (ioclass > 3) - bb_error_msg_and_die("bad class %d", ioclass); -// Do we need this (compat?)? -// if (ioclass == IOPRIO_CLASS_NONE) -// ioclass = IOPRIO_CLASS_BE; -// if (ioclass == IOPRIO_CLASS_IDLE) { -// //if (opt & OPT_n) -// // bb_error_msg("ignoring priority for idle class"); -// pri = 7; -// } - } - - if (!(opt & (OPT_n|OPT_c))) { - if (!(opt & OPT_p) && *argv) - pid = xatoi_positive(*argv); - - pri = ioprio_get(IOPRIO_WHO_PROCESS, pid); - if (pri == -1) - bb_perror_msg_and_die("ioprio_%cet", 'g'); - - ioclass = (pri >> IOPRIO_CLASS_SHIFT) & 0x3; - pri &= 0xff; - printf((ioclass == IOPRIO_CLASS_IDLE) ? "%s\n" : "%s: prio %d\n", - nth_string(to_prio, ioclass), pri); - } else { -//printf("pri=%d class=%d val=%x\n", -//pri, ioclass, pri | (ioclass << IOPRIO_CLASS_SHIFT)); - pri |= (ioclass << IOPRIO_CLASS_SHIFT); - if (ioprio_set(IOPRIO_WHO_PROCESS, pid, pri) == -1) - bb_perror_msg_and_die("ioprio_%cet", 's'); - if (argv[0]) { - BB_EXECVP_or_die(argv); - } - } - - return EXIT_SUCCESS; -} diff --git a/miscutils/last.c b/miscutils/last.c deleted file mode 100644 index b3f125c3f..000000000 --- a/miscutils/last.c +++ /dev/null @@ -1,166 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * last implementation for busybox - * - * Copyright (C) 2003-2004 by Erik Andersen - * - * Licensed under GPLv2, see file LICENSE in this source tree. - */ -//config:config LAST -//config: bool "last" -//config: default y -//config: depends on FEATURE_WTMP -//config: help -//config: 'last' displays a list of the last users that logged into the system. -//config: -//config:config FEATURE_LAST_FANCY -//config: bool "Output extra information" -//config: default y -//config: depends on LAST -//config: help -//config: 'last' displays detailed information about the last users that -//config: logged into the system (mimics sysvinit last). +900 bytes. - -//applet:IF_LAST(APPLET(last, BB_DIR_USR_BIN, BB_SUID_DROP)) - -//kbuild:ifeq ($(CONFIG_FEATURE_LAST_FANCY),y) -//kbuild:lib-$(CONFIG_FEATURE_LAST_FANCY) += last_fancy.o -//kbuild:else -//kbuild:lib-$(CONFIG_LAST) += last.o -//kbuild:endif - -//usage:#define last_trivial_usage -//usage: ""IF_FEATURE_LAST_FANCY("[-HW] [-f FILE]") -//usage:#define last_full_usage "\n\n" -//usage: "Show listing of the last users that logged into the system" -//usage: IF_FEATURE_LAST_FANCY( "\n" -/* //usage: "\n -H Show header line" */ -//usage: "\n -W Display with no host column truncation" -//usage: "\n -f FILE Read from FILE instead of /var/log/wtmp" -//usage: ) - -#include "libbb.h" - -/* NB: ut_name and ut_user are the same field, use only one name (ut_user) - * to reduce confusion */ - -#ifndef SHUTDOWN_TIME -# define SHUTDOWN_TIME 254 -#endif - -/* Grr... utmp char[] members do not have to be nul-terminated. - * Do what we can while still keeping this reasonably small. - * Note: We are assuming the ut_id[] size is fixed at 4. */ - -#if defined UT_LINESIZE \ - && ((UT_LINESIZE != 32) || (UT_NAMESIZE != 32) || (UT_HOSTSIZE != 256)) -#error struct utmpx member char[] size(s) have changed! -#elif defined __UT_LINESIZE \ - && ((__UT_LINESIZE != 32) || (__UT_NAMESIZE != 32) || (__UT_HOSTSIZE != 256)) -/* __UT_NAMESIZE was checked with 64 above, but glibc-2.11 definitely uses 32! */ -#error struct utmpx member char[] size(s) have changed! -#endif - -#if EMPTY != 0 || RUN_LVL != 1 || BOOT_TIME != 2 || NEW_TIME != 3 || \ - OLD_TIME != 4 -#error Values for the ut_type field of struct utmpx changed -#endif - -int last_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -int last_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) -{ - struct utmpx ut; - int n, file = STDIN_FILENO; - time_t t_tmp; - off_t pos; - static const char _ut_usr[] ALIGN1 = - "runlevel\0" "reboot\0" "shutdown\0"; - static const char _ut_lin[] ALIGN1 = - "~\0" "{\0" "|\0" /* "LOGIN\0" "date\0" */; - enum { - TYPE_RUN_LVL = RUN_LVL, /* 1 */ - TYPE_BOOT_TIME = BOOT_TIME, /* 2 */ - TYPE_SHUTDOWN_TIME = SHUTDOWN_TIME - }; - enum { - _TILDE = EMPTY, /* 0 */ - TYPE_NEW_TIME, /* NEW_TIME, 3 */ - TYPE_OLD_TIME /* OLD_TIME, 4 */ - }; - - if (argv[1]) { - bb_show_usage(); - } - file = xopen(bb_path_wtmp_file, O_RDONLY); - - printf("%-10s %-14s %-18s %-12.12s %s\n", - "USER", "TTY", "HOST", "LOGIN", "TIME"); - /* yikes. We reverse over the file and that is a not too elegant way */ - pos = xlseek(file, 0, SEEK_END); - pos = lseek(file, pos - sizeof(ut), SEEK_SET); - while ((n = full_read(file, &ut, sizeof(ut))) > 0) { - if (n != sizeof(ut)) { - bb_perror_msg_and_die("short read"); - } - n = index_in_strings(_ut_lin, ut.ut_line); - if (n == _TILDE) { /* '~' */ -#if 1 -/* do we really need to be cautious here? */ - n = index_in_strings(_ut_usr, ut.ut_user); - if (++n > 0) - ut.ut_type = n != 3 ? n : SHUTDOWN_TIME; -#else - if (is_prefixed_with(ut.ut_user, "shutdown")) - ut.ut_type = SHUTDOWN_TIME; - else if (is_prefixed_with(ut.ut_user, "reboot")) - ut.ut_type = BOOT_TIME; - else if (is_prefixed_with(ut.ut_user, "runlevel")) - ut.ut_type = RUN_LVL; -#endif - } else { - if (ut.ut_user[0] == '\0' || strcmp(ut.ut_user, "LOGIN") == 0) { - /* Don't bother. This means we can't find how long - * someone was logged in for. Oh well. */ - goto next; - } - if (ut.ut_type != DEAD_PROCESS - && ut.ut_user[0] - && ut.ut_line[0] - ) { - ut.ut_type = USER_PROCESS; - } - if (strcmp(ut.ut_user, "date") == 0) { - if (n == TYPE_OLD_TIME) { /* '|' */ - ut.ut_type = OLD_TIME; - } - if (n == TYPE_NEW_TIME) { /* '{' */ - ut.ut_type = NEW_TIME; - } - } - } - - if (ut.ut_type != USER_PROCESS) { - switch (ut.ut_type) { - case OLD_TIME: - case NEW_TIME: - case RUN_LVL: - case SHUTDOWN_TIME: - goto next; - case BOOT_TIME: - strcpy(ut.ut_line, "system boot"); - } - } - /* manpages say ut_tv.tv_sec *is* time_t, - * but some systems have it wrong */ - t_tmp = (time_t)ut.ut_tv.tv_sec; - printf("%-10s %-14s %-18s %-12.12s\n", - ut.ut_user, ut.ut_line, ut.ut_host, ctime(&t_tmp) + 4); - next: - pos -= sizeof(ut); - if (pos <= 0) - break; /* done. */ - xlseek(file, pos, SEEK_SET); - } - - fflush_stdout_and_exit(EXIT_SUCCESS); -} diff --git a/miscutils/last_fancy.c b/miscutils/last_fancy.c deleted file mode 100644 index e56e0ba85..000000000 --- a/miscutils/last_fancy.c +++ /dev/null @@ -1,300 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * (sysvinit like) last implementation - * - * Copyright (C) 2008 by Patricia Muscalu - * - * Licensed under GPLv2 or later, see file LICENSE in this source tree. - */ - -#include "libbb.h" - -/* NB: ut_name and ut_user are the same field, use only one name (ut_user) - * to reduce confusion */ - -#ifndef SHUTDOWN_TIME -# define SHUTDOWN_TIME 254 -#endif - -#define HEADER_FORMAT "%-8.8s %-12.12s %-*.*s %-16.16s %-7.7s %s\n" -#define HEADER_LINE "USER", "TTY", \ - INET_ADDRSTRLEN, INET_ADDRSTRLEN, "HOST", "LOGIN", " TIME", "" -#define HEADER_LINE_WIDE "USER", "TTY", \ - INET6_ADDRSTRLEN, INET6_ADDRSTRLEN, "HOST", "LOGIN", " TIME", "" - -#if !defined __UT_LINESIZE && defined UT_LINESIZE -# define __UT_LINESIZE UT_LINESIZE -#endif - -enum { - NORMAL, - LOGGED, - DOWN, - REBOOT, - CRASH, - GONE -}; - -enum { - LAST_OPT_W = (1 << 0), /* -W wide */ - LAST_OPT_f = (1 << 1), /* -f input file */ - LAST_OPT_H = (1 << 2), /* -H header */ -}; - -#define show_wide (option_mask32 & LAST_OPT_W) - -static void show_entry(struct utmpx *ut, int state, time_t dur_secs) -{ - unsigned days, hours, mins; - char duration[sizeof("(%u+02:02)") + sizeof(int)*3]; - char login_time[17]; - char logout_time[8]; - const char *logout_str; - const char *duration_str; - time_t tmp; - - /* manpages say ut_tv.tv_sec *is* time_t, - * but some systems have it wrong */ - tmp = ut->ut_tv.tv_sec; - safe_strncpy(login_time, ctime(&tmp), 17); - tmp = dur_secs; - snprintf(logout_time, 8, "- %s", ctime(&tmp) + 11); - - dur_secs = MAX(dur_secs - (time_t)ut->ut_tv.tv_sec, (time_t)0); - /* unsigned int is easier to divide than time_t (which may be signed long) */ - mins = dur_secs / 60; - days = mins / (24*60); - mins = mins % (24*60); - hours = mins / 60; - mins = mins % 60; - -// if (days) { - sprintf(duration, "(%u+%02u:%02u)", days, hours, mins); -// } else { -// sprintf(duration, " (%02u:%02u)", hours, mins); -// } - - logout_str = logout_time; - duration_str = duration; - switch (state) { - case NORMAL: - break; - case LOGGED: - logout_str = " still"; - duration_str = "logged in"; - break; - case DOWN: - logout_str = "- down "; - break; - case REBOOT: - break; - case CRASH: - logout_str = "- crash"; - break; - case GONE: - logout_str = " gone"; - duration_str = "- no logout"; - break; - } - - printf(HEADER_FORMAT, - ut->ut_user, - ut->ut_line, - show_wide ? INET6_ADDRSTRLEN : INET_ADDRSTRLEN, - show_wide ? INET6_ADDRSTRLEN : INET_ADDRSTRLEN, - ut->ut_host, - login_time, - logout_str, - duration_str); -} - -static int get_ut_type(struct utmpx *ut) -{ - if (ut->ut_line[0] == '~') { - if (strcmp(ut->ut_user, "shutdown") == 0) { - return SHUTDOWN_TIME; - } - if (strcmp(ut->ut_user, "reboot") == 0) { - return BOOT_TIME; - } - if (strcmp(ut->ut_user, "runlevel") == 0) { - return RUN_LVL; - } - return ut->ut_type; - } - - if (ut->ut_user[0] == 0) { - return DEAD_PROCESS; - } - - if ((ut->ut_type != DEAD_PROCESS) - && (strcmp(ut->ut_user, "LOGIN") != 0) - && ut->ut_user[0] - && ut->ut_line[0] - ) { - ut->ut_type = USER_PROCESS; - } - - if (strcmp(ut->ut_user, "date") == 0) { - if (ut->ut_line[0] == '|') { - return OLD_TIME; - } - if (ut->ut_line[0] == '{') { - return NEW_TIME; - } - } - return ut->ut_type; -} - -static int is_runlevel_shutdown(struct utmpx *ut) -{ - if (((ut->ut_pid & 255) == '0') || ((ut->ut_pid & 255) == '6')) { - return 1; - } - - return 0; -} - -int last_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -int last_main(int argc UNUSED_PARAM, char **argv) -{ - struct utmpx ut; - const char *filename = _PATH_WTMP; - llist_t *zlist; - off_t pos; - time_t start_time; - time_t boot_time; - time_t down_time; - int file; - smallint going_down; - smallint boot_down; - - /*opt =*/ getopt32(argv, "Wf:" /* "H" */, &filename); -#ifdef BUT_UTIL_LINUX_LAST_HAS_NO_SUCH_OPT - if (opt & LAST_OPT_H) { - /* Print header line */ - if (opt & LAST_OPT_W) { - printf(HEADER_FORMAT, HEADER_LINE_WIDE); - } else { - printf(HEADER_FORMAT, HEADER_LINE); - } - } -#endif - - file = xopen(filename, O_RDONLY); - { - /* in case the file is empty... */ - struct stat st; - fstat(file, &st); - start_time = st.st_ctime; - } - - time(&down_time); - going_down = 0; - boot_down = NORMAL; /* 0 */ - zlist = NULL; - boot_time = 0; - /* get file size, rounding down to last full record */ - pos = xlseek(file, 0, SEEK_END) / sizeof(ut) * sizeof(ut); - for (;;) { - pos -= (off_t)sizeof(ut); - if (pos < 0) { - /* Beyond the beginning of the file boundary => - * the whole file has been read. */ - break; - } - xlseek(file, pos, SEEK_SET); - xread(file, &ut, sizeof(ut)); - /* rewritten by each record, eventially will have - * first record's ut_tv.tv_sec: */ - start_time = ut.ut_tv.tv_sec; - - switch (get_ut_type(&ut)) { - case SHUTDOWN_TIME: - down_time = ut.ut_tv.tv_sec; - boot_down = DOWN; - going_down = 1; - break; - case RUN_LVL: - if (is_runlevel_shutdown(&ut)) { - down_time = ut.ut_tv.tv_sec; - going_down = 1; - boot_down = DOWN; - } - break; - case BOOT_TIME: - strcpy(ut.ut_line, "system boot"); - show_entry(&ut, REBOOT, down_time); - boot_down = CRASH; - going_down = 1; - break; - case DEAD_PROCESS: - if (!ut.ut_line[0]) { - break; - } - /* add_entry */ - llist_add_to(&zlist, xmemdup(&ut, sizeof(ut))); - break; - case USER_PROCESS: { - int show; - - if (!ut.ut_line[0]) { - break; - } - /* find_entry */ - show = 1; - { - llist_t *el, *next; - for (el = zlist; el; el = next) { - struct utmpx *up = (struct utmpx *)el->data; - next = el->link; - if (strncmp(up->ut_line, ut.ut_line, __UT_LINESIZE) == 0) { - if (show) { - show_entry(&ut, NORMAL, up->ut_tv.tv_sec); - show = 0; - } - llist_unlink(&zlist, el); - free(el->data); - free(el); - } - } - } - - if (show) { - int state = boot_down; - - if (boot_time == 0) { - state = LOGGED; - /* Check if the process is alive */ - if ((ut.ut_pid > 0) - && (kill(ut.ut_pid, 0) != 0) - && (errno == ESRCH)) { - state = GONE; - } - } - show_entry(&ut, state, boot_time); - } - /* add_entry */ - llist_add_to(&zlist, xmemdup(&ut, sizeof(ut))); - break; - } - } - - if (going_down) { - boot_time = ut.ut_tv.tv_sec; - llist_free(zlist, free); - zlist = NULL; - going_down = 0; - } - } - - if (ENABLE_FEATURE_CLEAN_UP) { - llist_free(zlist, free); - } - - printf("\nwtmp begins %s", ctime(&start_time)); - - if (ENABLE_FEATURE_CLEAN_UP) - close(file); - fflush_stdout_and_exit(EXIT_SUCCESS); -} diff --git a/miscutils/mountpoint.c b/miscutils/mountpoint.c deleted file mode 100644 index 8b9e1d779..000000000 --- a/miscutils/mountpoint.c +++ /dev/null @@ -1,105 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * mountpoint implementation for busybox - * - * Copyright (C) 2005 Bernhard Reutner-Fischer - * - * Licensed under GPLv2 or later, see file LICENSE in this source tree. - * - * Based on sysvinit's mountpoint - */ -//config:config MOUNTPOINT -//config: bool "mountpoint" -//config: default y -//config: help -//config: mountpoint checks if the directory is a mountpoint. - -//applet:IF_MOUNTPOINT(APPLET(mountpoint, BB_DIR_BIN, BB_SUID_DROP)) - -//kbuild:lib-$(CONFIG_MOUNTPOINT) += mountpoint.o - -//usage:#define mountpoint_trivial_usage -//usage: "[-q] <[-dn] DIR | -x DEVICE>" -//usage:#define mountpoint_full_usage "\n\n" -//usage: "Check if the directory is a mountpoint\n" -//usage: "\n -q Quiet" -//usage: "\n -d Print major/minor device number of the filesystem" -//usage: "\n -n Print device name of the filesystem" -//usage: "\n -x Print major/minor device number of the blockdevice" -//usage: -//usage:#define mountpoint_example_usage -//usage: "$ mountpoint /proc\n" -//usage: "/proc is not a mountpoint\n" -//usage: "$ mountpoint /sys\n" -//usage: "/sys is a mountpoint\n" - -#include "libbb.h" - -int mountpoint_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -int mountpoint_main(int argc UNUSED_PARAM, char **argv) -{ - struct stat st; - const char *msg; - char *arg; - int rc, opt; - - opt_complementary = "=1"; /* must have one argument */ - opt = getopt32(argv, "qdxn"); -#define OPT_q (1) -#define OPT_d (2) -#define OPT_x (4) -#define OPT_n (8) - arg = argv[optind]; - msg = "%s"; - - rc = (opt & OPT_x) ? stat(arg, &st) : lstat(arg, &st); - if (rc != 0) - goto err; - - if (opt & OPT_x) { - if (S_ISBLK(st.st_mode)) { - printf("%u:%u\n", major(st.st_rdev), - minor(st.st_rdev)); - return EXIT_SUCCESS; - } - errno = 0; /* make perror_msg work as error_msg */ - msg = "%s: not a block device"; - goto err; - } - - errno = ENOTDIR; - if (S_ISDIR(st.st_mode)) { - dev_t st_dev = st.st_dev; - ino_t st_ino = st.st_ino; - char *p = xasprintf("%s/..", arg); - - if (stat(p, &st) == 0) { - //int is_mnt = (st_dev != st.st_dev) || (st_dev == st.st_dev && st_ino == st.st_ino); - int is_not_mnt = (st_dev == st.st_dev) && (st_ino != st.st_ino); - - if (opt & OPT_d) - printf("%u:%u\n", major(st_dev), minor(st_dev)); - if (opt & OPT_n) { - const char *d = find_block_device(arg); - /* name is undefined, but device is mounted -> anonymous superblock! */ - /* happens with btrfs */ - if (!d) { - d = "UNKNOWN"; - /* TODO: iterate /proc/mounts, or /proc/self/mountinfo - * to find out the device name */ - } - printf("%s %s\n", d, arg); - } - if (!(opt & (OPT_q | OPT_d | OPT_n))) - printf("%s is %sa mountpoint\n", arg, is_not_mnt ? "not " : ""); - return is_not_mnt; - } - arg = p; - /* else: stat had set errno, just fall through */ - } - - err: - if (!(opt & OPT_q)) - bb_perror_msg(msg, arg); - return EXIT_FAILURE; -} diff --git a/miscutils/setsid.c b/miscutils/setsid.c deleted file mode 100644 index 143a8f8fa..000000000 --- a/miscutils/setsid.c +++ /dev/null @@ -1,82 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * setsid.c -- execute a command in a new session - * Rick Sladkey - * In the public domain. - * - * 1999-02-22 Arkadiusz Mickiewicz - * - added Native Language Support - * - * 2001-01-18 John Fremlin - * - fork in case we are process group leader - * - * 2004-11-12 Paul Fox - * - busyboxed - */ -//config:config SETSID -//config: bool "setsid" -//config: default y -//config: help -//config: setsid runs a program in a new session - -//applet:IF_SETSID(APPLET(setsid, BB_DIR_USR_BIN, BB_SUID_DROP)) - -//kbuild:lib-$(CONFIG_SETSID) += setsid.o - -//usage:#define setsid_trivial_usage -//usage: "[-c] PROG ARGS" -//usage:#define setsid_full_usage "\n\n" -//usage: "Run PROG in a new session. PROG will have no controlling terminal\n" -//usage: "and will not be affected by keyboard signals (^C etc).\n" -//usage: "\n -c Set controlling terminal to stdin" - -#include "libbb.h" - -int setsid_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -int setsid_main(int argc UNUSED_PARAM, char **argv) -{ - unsigned opt; - - opt_complementary = "-1"; /* at least one arg */ - opt = getopt32(argv, "+c"); /* +: stop on first non-opt */ - argv += optind; - - /* setsid() is allowed only when we are not a process group leader. - * Otherwise our PID serves as PGID of some existing process group - * and cannot be used as PGID of a new process group. - * - * Example: setsid() below fails when run alone in interactive shell: - * $ setsid PROG - * because shell's child (setsid) is put in a new process group. - * But doesn't fail if shell is not interactive - * (and therefore doesn't create process groups for pipes), - * or if setsid is not the first process in the process group: - * $ true | setsid PROG - * or if setsid is executed in backquotes (`setsid PROG`)... - */ - if (setsid() < 0) { - pid_t pid = fork_or_rexec(argv); - if (pid != 0) { - /* parent */ - /* TODO: - * we can waitpid(pid, &status, 0) and then even - * emulate exitcode, making the behavior consistent - * in both forked and non forked cases. - * However, the code is larger and upstream - * does not do such trick. - */ - return EXIT_SUCCESS; - } - - /* child */ - /* now there should be no error: */ - setsid(); - } - - if (opt) { - /* -c: set (with stealing) controlling tty */ - ioctl(0, TIOCSCTTY, 1); - } - - BB_EXECVP_or_die(argv); -} diff --git a/miscutils/taskset.c b/miscutils/taskset.c deleted file mode 100644 index 94a07383a..000000000 --- a/miscutils/taskset.c +++ /dev/null @@ -1,221 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * taskset - retrieve or set a processes' CPU affinity - * Copyright (c) 2006 Bernhard Reutner-Fischer - * - * Licensed under GPLv2 or later, see file LICENSE in this source tree. - */ - -//config:config TASKSET -//config: bool "taskset" -//config: default y -//config: help -//config: Retrieve or set a processes's CPU affinity. -//config: This requires sched_{g,s}etaffinity support in your libc. -//config: -//config:config FEATURE_TASKSET_FANCY -//config: bool "Fancy output" -//config: default y -//config: depends on TASKSET -//config: help -//config: Needed for machines with more than 32-64 CPUs: -//config: affinity parameter 0xHHHHHHHHHHHHHHHHHHHH can be arbitrarily long -//config: in this case. Otherwise, it is limited to sizeof(long). - -//applet:IF_TASKSET(APPLET(taskset, BB_DIR_USR_BIN, BB_SUID_DROP)) -//kbuild:lib-$(CONFIG_TASKSET) += taskset.o - -//usage:#define taskset_trivial_usage -//usage: "[-p] [HEXMASK] PID | PROG ARGS" -//usage:#define taskset_full_usage "\n\n" -//usage: "Set or get CPU affinity\n" -//usage: "\n -p Operate on an existing PID" -//usage: -//usage:#define taskset_example_usage -//usage: "$ taskset 0x7 ./dgemm_test&\n" -//usage: "$ taskset -p 0x1 $!\n" -//usage: "pid 4790's current affinity mask: 7\n" -//usage: "pid 4790's new affinity mask: 1\n" -//usage: "$ taskset 0x7 /bin/sh -c './taskset -p 0x1 $$'\n" -//usage: "pid 6671's current affinity mask: 1\n" -//usage: "pid 6671's new affinity mask: 1\n" -//usage: "$ taskset -p 1\n" -//usage: "pid 1's current affinity mask: 3\n" -/* - * Not yet implemented: - * -a/--all-tasks (affect all threads) - * needs to get TIDs from /proc/PID/task/ and use _them_ as "pid" in sched_setaffinity(pid) - * -c/--cpu-list (specify CPUs via "1,3,5-7") - */ - -#include -#include "libbb.h" - -typedef unsigned long ul; -#define SZOF_UL (unsigned)(sizeof(ul)) -#define BITS_UL (unsigned)(sizeof(ul)*8) -#define MASK_UL (unsigned)(sizeof(ul)*8 - 1) - -#if ENABLE_FEATURE_TASKSET_FANCY -#define TASKSET_PRINTF_MASK "%s" -/* craft a string from the mask */ -static char *from_mask(const ul *mask, unsigned sz_in_bytes) -{ - char *str = xzalloc((sz_in_bytes+1) * 2); /* we will leak it */ - char *p = str; - for (;;) { - ul v = *mask++; - if (SZOF_UL == 4) - p += sprintf(p, "%08lx", v); - if (SZOF_UL == 8) - p += sprintf(p, "%016lx", v); - if (SZOF_UL == 16) - p += sprintf(p, "%032lx", v); /* :) */ - sz_in_bytes -= SZOF_UL; - if ((int)sz_in_bytes <= 0) - break; - } - while (str[0] == '0' && str[1]) - str++; - return str; -} -#else -#define TASKSET_PRINTF_MASK "%lx" -static unsigned long long from_mask(ul *mask, unsigned sz_in_bytes UNUSED_PARAM) -{ - return *mask; -} -#endif - -static unsigned long *get_aff(int pid, unsigned *sz) -{ - int r; - unsigned long *mask = NULL; - unsigned sz_in_bytes = *sz; - - for (;;) { - mask = xrealloc(mask, sz_in_bytes); - r = sched_getaffinity(pid, sz_in_bytes, (void*)mask); - if (r == 0) - break; - sz_in_bytes *= 2; - if (errno == EINVAL && (int)sz_in_bytes > 0) - continue; - bb_perror_msg_and_die("can't %cet pid %d's affinity", 'g', pid); - } - //bb_error_msg("get mask[0]:%lx sz_in_bytes:%d", mask[0], sz_in_bytes); - *sz = sz_in_bytes; - return mask; -} - -int taskset_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -int taskset_main(int argc UNUSED_PARAM, char **argv) -{ - ul *mask; - unsigned mask_size_in_bytes; - pid_t pid = 0; - unsigned opt_p; - const char *current_new; - char *aff; - - /* NB: we mimic util-linux's taskset: -p does not take - * an argument, i.e., "-pN" is NOT valid, only "-p N"! - * Indeed, util-linux-2.13-pre7 uses: - * getopt_long(argc, argv, "+pchV", ...), not "...p:..." */ - - opt_complementary = "-1"; /* at least 1 arg */ - opt_p = getopt32(argv, "+p"); - argv += optind; - - aff = *argv++; - if (opt_p) { - char *pid_str = aff; - if (*argv) { /* "-p ...rest.is.ignored..." */ - pid_str = *argv; /* NB: *argv != NULL in this case */ - } - /* else it was just "-p ", and *argv == NULL */ - pid = xatoul_range(pid_str, 1, ((unsigned)(pid_t)ULONG_MAX) >> 1); - } else { - /* */ - if (!*argv) - bb_show_usage(); - } - - mask_size_in_bytes = SZOF_UL; - current_new = "current"; - print_aff: - mask = get_aff(pid, &mask_size_in_bytes); - if (opt_p) { - printf("pid %d's %s affinity mask: "TASKSET_PRINTF_MASK"\n", - pid, current_new, from_mask(mask, mask_size_in_bytes)); - if (*argv == NULL) { - /* Either it was just "-p ", - * or it was "-p " and we came here - * for the second time (see goto below) */ - return EXIT_SUCCESS; - } - *argv = NULL; - current_new = "new"; - } - memset(mask, 0, mask_size_in_bytes); - - /* Affinity was specified, translate it into mask */ - /* it is always in hex, skip "0x" if it exists */ - if (aff[0] == '0' && (aff[1]|0x20) == 'x') - aff += 2; - - if (!ENABLE_FEATURE_TASKSET_FANCY) { - mask[0] = xstrtoul(aff, 16); - } else { - unsigned i; - char *last_char; - - i = 0; /* bit pos in mask[] */ - - /* aff is ASCII hex string, accept very long masks in this form. - * Process hex string AABBCCDD... to ulong mask[] - * from the rightmost nibble, which is least-significant. - * Bits not fitting into mask[] are ignored: (example: 1234 - * in 12340000000000000000000000000000000000000ff) - */ - last_char = strchrnul(aff, '\0'); - while (last_char > aff) { - char c; - ul val; - - last_char--; - c = *last_char; - if (isdigit(c)) - val = c - '0'; - else if ((c|0x20) >= 'a' && (c|0x20) <= 'f') - val = (c|0x20) - ('a' - 10); - else - bb_error_msg_and_die("bad affinity '%s'", aff); - - if (i < mask_size_in_bytes * 8) { - mask[i / BITS_UL] |= val << (i & MASK_UL); - //bb_error_msg("bit %d set", i); - } - /* else: - * We can error out here, but we don't. - * For one, kernel itself ignores bits in mask[] - * which do not map to any CPUs: - * if mask[] has one 32-bit long element, - * but you have only 8 CPUs, all bits beyond first 8 - * are ignored, silently. - * No point in making bits past 31th to be errors. - */ - i += 4; - } - } - - /* Set pid's or our own (pid==0) affinity */ - if (sched_setaffinity(pid, mask_size_in_bytes, (void*)mask)) - bb_perror_msg_and_die("can't %cet pid %d's affinity", 's', pid); - //bb_error_msg("set mask[0]:%lx", mask[0]); - - if (!argv[0]) /* "-p [...ignored...]" */ - goto print_aff; /* print new affinity and exit */ - - BB_EXECVP_or_die(argv); -} diff --git a/miscutils/timeout.c b/miscutils/timeout.c deleted file mode 100644 index f29dc8a9c..000000000 --- a/miscutils/timeout.c +++ /dev/null @@ -1,127 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * COPYING NOTES - * - * timeout.c -- a timeout handler for shell commands - * - * Copyright (C) 2005-6, Roberto A. Foglietta - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * REVISION NOTES: - * released 17-11-2005 by Roberto A. Foglietta - * talarm 04-12-2005 by Roberto A. Foglietta - * modified 05-12-2005 by Roberto A. Foglietta - * sizerdct 06-12-2005 by Roberto A. Foglietta - * splitszf 12-05-2006 by Roberto A. Foglietta - * rewrite 14-11-2008 vda - */ -//config:config TIMEOUT -//config: bool "timeout" -//config: default y -//config: help -//config: Runs a program and watches it. If it does not terminate in -//config: specified number of seconds, it is sent a signal. - -//applet:IF_TIMEOUT(APPLET(timeout, BB_DIR_USR_BIN, BB_SUID_DROP)) - -//kbuild:lib-$(CONFIG_TIMEOUT) += timeout.o - -//usage:#define timeout_trivial_usage -//usage: "[-t SECS] [-s SIG] PROG ARGS" -//usage:#define timeout_full_usage "\n\n" -//usage: "Runs PROG. Sends SIG to it if it is not gone in SECS seconds.\n" -//usage: "Defaults: SECS: 10, SIG: TERM." - -#include "libbb.h" - -int timeout_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -int timeout_main(int argc UNUSED_PARAM, char **argv) -{ - int signo; - int status; - int parent = 0; - int timeout = 10; - pid_t pid; -#if !BB_MMU - char *sv1, *sv2; -#endif - const char *opt_s = "TERM"; - - /* -p option is not documented, it is needed to support NOMMU. */ - - /* -t SECONDS; -p PARENT_PID */ - /* '+': stop at first non-option */ - getopt32(argv, "+s:t:+" USE_FOR_NOMMU("p:+"), &opt_s, &timeout, &parent); - /*argv += optind; - no, wait for bb_daemonize_or_rexec! */ - signo = get_signum(opt_s); - if (signo < 0) - bb_error_msg_and_die("unknown signal '%s'", opt_s); - - /* We want to create a grandchild which will watch - * and kill the grandparent. Other methods: - * making parent watch child disrupts parent<->child link - * (example: "tcpsvd 0.0.0.0 1234 timeout service_prog" - - * it's better if service_prog is a child of tcpsvd!), - * making child watch parent results in programs having - * unexpected children. */ - - if (parent) /* we were re-execed, already grandchild */ - goto grandchild; - if (!argv[optind]) /* no PROG? */ - bb_show_usage(); - -#if !BB_MMU - sv1 = argv[optind]; - sv2 = argv[optind + 1]; -#endif - pid = xvfork(); - if (pid == 0) { - /* Child: spawn grandchild and exit */ - parent = getppid(); -#if !BB_MMU - argv[optind] = xasprintf("-p%u", parent); - argv[optind + 1] = NULL; -#endif - /* NB: exits with nonzero on error: */ - bb_daemonize_or_rexec(0, argv); - /* Here we are grandchild. Sleep, then kill grandparent */ - grandchild: - /* Just sleep(HUGE_NUM); kill(parent) may kill wrong process! */ - while (1) { - sleep(1); - if (--timeout <= 0) - break; - if (kill(parent, 0)) { - /* process is gone */ - return EXIT_SUCCESS; - } - } - kill(parent, signo); - return EXIT_SUCCESS; - } - - /* Parent */ - wait(&status); /* wait for child to die */ - /* Did intermediate [v]fork or exec fail? */ - if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) - return EXIT_FAILURE; - /* Ok, exec a program as requested */ - argv += optind; -#if !BB_MMU - argv[0] = sv1; - argv[1] = sv2; -#endif - BB_EXECVP_or_die(argv); -} diff --git a/miscutils/wall.c b/miscutils/wall.c deleted file mode 100644 index 50658f457..000000000 --- a/miscutils/wall.c +++ /dev/null @@ -1,63 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * wall - write a message to all logged-in users - * Copyright (c) 2009 Bernhard Reutner-Fischer - * - * Licensed under GPLv2 or later, see file LICENSE in this source tree. - */ - -//config:config WALL -//config: bool "wall" -//config: default y -//config: depends on FEATURE_UTMP -//config: help -//config: Write a message to all users that are logged in. - -/* Needs to be run by root or be suid root - needs to write to /dev/TTY: */ -//applet:IF_WALL(APPLET(wall, BB_DIR_USR_BIN, BB_SUID_REQUIRE)) - -//kbuild:lib-$(CONFIG_WALL) += wall.o - -//usage:#define wall_trivial_usage -//usage: "[FILE]" -//usage:#define wall_full_usage "\n\n" -//usage: "Write content of FILE or stdin to all logged-in users" -//usage: -//usage:#define wall_sample_usage -//usage: "echo foo | wall\n" -//usage: "wall ./mymessage" - -#include "libbb.h" - -int wall_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -int wall_main(int argc UNUSED_PARAM, char **argv) -{ - struct utmpx *ut; - char *msg; - int fd; - - fd = STDIN_FILENO; - if (argv[1]) { - /* The applet is setuid. - * Access to the file must be under user's uid/gid. - */ - fd = xopen_as_uid_gid(argv[1], O_RDONLY, getuid(), getgid()); - } - msg = xmalloc_read(fd, NULL); - if (ENABLE_FEATURE_CLEAN_UP && argv[1]) - close(fd); - setutxent(); - while ((ut = getutxent()) != NULL) { - char *line; - if (ut->ut_type != USER_PROCESS) - continue; - line = concat_path_file("/dev", ut->ut_line); - xopen_xwrite_close(line, msg); - free(line); - } - if (ENABLE_FEATURE_CLEAN_UP) { - endutxent(); - free(msg); - } - return EXIT_SUCCESS; -} diff --git a/util-linux/chrt.c b/util-linux/chrt.c new file mode 100644 index 000000000..1604a6890 --- /dev/null +++ b/util-linux/chrt.c @@ -0,0 +1,149 @@ +/* vi: set sw=4 ts=4: */ +/* + * chrt - manipulate real-time attributes of a process + * Copyright (c) 2006-2007 Bernhard Reutner-Fischer + * + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + */ +//config:config CHRT +//config: bool "chrt" +//config: default y +//config: help +//config: manipulate real-time attributes of a process. +//config: This requires sched_{g,s}etparam support in your libc. + +//applet:IF_CHRT(APPLET(chrt, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_CHRT) += chrt.o + +//usage:#define chrt_trivial_usage +//usage: "[-prfom] [PRIO] [PID | PROG ARGS]" +//usage:#define chrt_full_usage "\n\n" +//usage: "Change scheduling priority and class for a process\n" +//usage: "\n -p Operate on PID" +//usage: "\n -r Set SCHED_RR class" +//usage: "\n -f Set SCHED_FIFO class" +//usage: "\n -o Set SCHED_OTHER class" +//usage: "\n -m Show min/max priorities" +//usage: +//usage:#define chrt_example_usage +//usage: "$ chrt -r 4 sleep 900; x=$!\n" +//usage: "$ chrt -f -p 3 $x\n" +//usage: "You need CAP_SYS_NICE privileges to set scheduling attributes of a process" + +#include +#include "libbb.h" + +static const struct { + int policy; + char name[sizeof("SCHED_OTHER")]; +} policies[] = { + {SCHED_OTHER, "SCHED_OTHER"}, + {SCHED_FIFO, "SCHED_FIFO"}, + {SCHED_RR, "SCHED_RR"} +}; + +//TODO: add +// -b, SCHED_BATCH +// -i, SCHED_IDLE + +static void show_min_max(int pol) +{ + const char *fmt = "%s min/max priority\t: %u/%u\n"; + int max, min; + + max = sched_get_priority_max(pol); + min = sched_get_priority_min(pol); + if ((max|min) < 0) + fmt = "%s not supported\n"; + printf(fmt, policies[pol].name, min, max); +} + +#define OPT_m (1<<0) +#define OPT_p (1<<1) +#define OPT_r (1<<2) +#define OPT_f (1<<3) +#define OPT_o (1<<4) + +int chrt_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int chrt_main(int argc UNUSED_PARAM, 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; + + /* only one policy accepted */ + opt_complementary = "r--fo:f--ro:o--rf"; + opt = getopt32(argv, "+mprfo"); + if (opt & OPT_m) { /* print min/max and exit */ + show_min_max(SCHED_FIFO); + show_min_max(SCHED_RR); + show_min_max(SCHED_OTHER); + fflush_stdout_and_exit(EXIT_SUCCESS); + } + if (opt & OPT_r) + policy = SCHED_RR; + if (opt & OPT_f) + policy = SCHED_FIFO; + if (opt & OPT_o) + policy = SCHED_OTHER; + + argv += optind; + if (!argv[0]) + bb_show_usage(); + if (opt & OPT_p) { + pid_str = *argv++; + if (*argv) { /* "-p [...]" */ + priority = pid_str; + pid_str = *argv; + } + /* else "-p ", and *argv == NULL */ + pid = xatoul_range(pid_str, 1, ((unsigned)(pid_t)ULONG_MAX) >> 1); + } else { + priority = *argv++; + if (!*argv) + bb_show_usage(); + } + + current_new = "current\0new"; + if (opt & OPT_p) { + int pol; + print_rt_info: + pol = sched_getscheduler(pid); + if (pol < 0) + bb_perror_msg_and_die("can't %cet pid %d's policy", 'g', (int)pid); + printf("pid %d's %s scheduling policy: %s\n", + pid, current_new, policies[pol].name); + if (sched_getparam(pid, &sp)) + bb_perror_msg_and_die("can't get pid %d's attributes", (int)pid); + printf("pid %d's %s scheduling priority: %d\n", + (int)pid, current_new, sp.sched_priority); + if (!*argv) { + /* Either it was just "-p ", + * or it was "-p " and we came here + * for the second time (see goto below) */ + return EXIT_SUCCESS; + } + *argv = NULL; + current_new += 8; + } + + /* 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 static priority 0. + [...] SCHED_FIFO or SCHED_RR can have static priority in 1..99 range. + */ + sp.sched_priority = xstrtou_range(priority, 0, policy != SCHED_OTHER ? 1 : 0, 99); + + if (sched_setscheduler(pid, policy, &sp) < 0) + bb_perror_msg_and_die("can't %cet pid %d's policy", 's', (int)pid); + + if (!argv[0]) /* "-p [...]" */ + goto print_rt_info; + + BB_EXECVP_or_die(argv); +} diff --git a/util-linux/eject.c b/util-linux/eject.c new file mode 100644 index 000000000..667932f6c --- /dev/null +++ b/util-linux/eject.c @@ -0,0 +1,152 @@ +/* vi: set sw=4 ts=4: */ +/* + * eject implementation for busybox + * + * Copyright (C) 2004 Peter Willis + * Copyright (C) 2005 Tito Ragusa + * + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + */ + +/* + * This is a simple hack of eject based on something Erik posted in #uclibc. + * Most of the dirty work blatantly ripped off from cat.c =) + */ +//config:config EJECT +//config: bool "eject" +//config: default y +//config: select PLATFORM_LINUX +//config: help +//config: Used to eject cdroms. (defaults to /dev/cdrom) +//config: +//config:config FEATURE_EJECT_SCSI +//config: bool "SCSI support" +//config: default y +//config: depends on EJECT +//config: help +//config: Add the -s option to eject, this allows to eject SCSI-Devices and +//config: usb-storage devices. + +//applet:IF_EJECT(APPLET(eject, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_EJECT) += eject.o + +//usage:#define eject_trivial_usage +//usage: "[-t] [-T] [DEVICE]" +//usage:#define eject_full_usage "\n\n" +//usage: "Eject DEVICE or default /dev/cdrom\n" +//usage: IF_FEATURE_EJECT_SCSI( +//usage: "\n -s SCSI device" +//usage: ) +//usage: "\n -t Close tray" +//usage: "\n -T Open/close tray (toggle)" + +#include +#include "libbb.h" +#if ENABLE_FEATURE_EJECT_SCSI +/* Must be after libbb.h: they need size_t */ +# include "fix_u32.h" +# include +# include +#endif + +#define dev_fd 3 + +/* Code taken from the original eject (http://eject.sourceforge.net/), + * refactored it a bit for busybox (ne-bb@nicoerfurth.de) */ + +#if ENABLE_FEATURE_EJECT_SCSI +static void eject_scsi(const char *dev) +{ + static const char sg_commands[3][6] ALIGN1 = { + { ALLOW_MEDIUM_REMOVAL, 0, 0, 0, 0, 0 }, + { START_STOP, 0, 0, 0, 1, 0 }, + { START_STOP, 0, 0, 0, 2, 0 } + }; + + unsigned i; + unsigned char sense_buffer[32]; + unsigned char inqBuff[2]; + sg_io_hdr_t io_hdr; + + if ((ioctl(dev_fd, SG_GET_VERSION_NUM, &i) < 0) || (i < 30000)) + bb_error_msg_and_die("not a sg device or old sg driver"); + + memset(&io_hdr, 0, sizeof(sg_io_hdr_t)); + io_hdr.interface_id = 'S'; + io_hdr.cmd_len = 6; + io_hdr.mx_sb_len = sizeof(sense_buffer); + io_hdr.dxfer_direction = SG_DXFER_NONE; + /* io_hdr.dxfer_len = 0; */ + io_hdr.dxferp = inqBuff; + io_hdr.sbp = sense_buffer; + io_hdr.timeout = 2000; + + for (i = 0; i < 3; i++) { + io_hdr.cmdp = (void *)sg_commands[i]; + ioctl_or_perror_and_die(dev_fd, SG_IO, (void *)&io_hdr, "%s", dev); + } + + /* force kernel to reread partition table when new disc is inserted */ + ioctl(dev_fd, BLKRRPART); +} +#else +# define eject_scsi(dev) ((void)0) +#endif + +/* various defines swiped from linux/cdrom.h */ +#define CDROMCLOSETRAY 0x5319 /* pendant of CDROMEJECT */ +#define CDROMEJECT 0x5309 /* Ejects the cdrom media */ +#define CDROM_DRIVE_STATUS 0x5326 /* Get tray position, etc. */ +/* drive status possibilities returned by CDROM_DRIVE_STATUS ioctl */ +#define CDS_TRAY_OPEN 2 + +#define FLAG_CLOSE 1 +#define FLAG_SMART 2 +#define FLAG_SCSI 4 + +static void eject_cdrom(unsigned flags, const char *dev) +{ + int cmd = CDROMEJECT; + + if (flags & FLAG_CLOSE + || ((flags & FLAG_SMART) && ioctl(dev_fd, CDROM_DRIVE_STATUS) == CDS_TRAY_OPEN) + ) { + cmd = CDROMCLOSETRAY; + } + + ioctl_or_perror_and_die(dev_fd, cmd, NULL, "%s", dev); +} + +int eject_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int eject_main(int argc UNUSED_PARAM, char **argv) +{ + unsigned flags; + const char *device; + + opt_complementary = "?1:t--T:T--t"; + flags = getopt32(argv, "tT" IF_FEATURE_EJECT_SCSI("s")); + device = argv[optind] ? argv[optind] : "/dev/cdrom"; + + /* We used to do "umount " here, but it was buggy + if something was mounted OVER cdrom and + if cdrom is mounted many times. + + This works equally well (or better): + #!/bin/sh + umount /dev/cdrom + eject /dev/cdrom + */ + + xmove_fd(xopen_nonblocking(device), dev_fd); + + if (ENABLE_FEATURE_EJECT_SCSI && (flags & FLAG_SCSI)) + eject_scsi(device); + else + eject_cdrom(flags, device); + + if (ENABLE_FEATURE_CLEAN_UP) + close(dev_fd); + + return EXIT_SUCCESS; +} diff --git a/util-linux/ionice.c b/util-linux/ionice.c new file mode 100644 index 000000000..c54b3a6e1 --- /dev/null +++ b/util-linux/ionice.c @@ -0,0 +1,115 @@ +/* vi: set sw=4 ts=4: */ +/* + * ionice implementation for busybox based on linux-utils-ng 2.14 + * + * Copyright (C) 2008 by + * + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + */ +//config:config IONICE +//config: bool "ionice" +//config: default y +//config: select PLATFORM_LINUX +//config: help +//config: Set/set program io scheduling class and priority +//config: Requires kernel >= 2.6.13 + +//applet:IF_IONICE(APPLET(ionice, BB_DIR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_IONICE) += ionice.o + +//usage:#define ionice_trivial_usage +//usage: "[-c 1-3] [-n 0-7] [-p PID] [PROG]" +//usage:#define ionice_full_usage "\n\n" +//usage: "Change I/O priority and class\n" +//usage: "\n -c Class. 1:realtime 2:best-effort 3:idle" +//usage: "\n -n Priority" + +#include +#include +#include "libbb.h" + +static int ioprio_set(int which, int who, int ioprio) +{ + return syscall(SYS_ioprio_set, which, who, ioprio); +} + +static int ioprio_get(int which, int who) +{ + return syscall(SYS_ioprio_get, which, who); +} + +enum { + IOPRIO_WHO_PROCESS = 1, + IOPRIO_WHO_PGRP, + IOPRIO_WHO_USER +}; + +enum { + IOPRIO_CLASS_NONE, + IOPRIO_CLASS_RT, + IOPRIO_CLASS_BE, + IOPRIO_CLASS_IDLE +}; + +static const char to_prio[] ALIGN1 = "none\0realtime\0best-effort\0idle"; + +#define IOPRIO_CLASS_SHIFT 13 + +int ionice_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int ionice_main(int argc UNUSED_PARAM, char **argv) +{ + /* Defaults */ + int ioclass = 0; + int pri = 0; + int pid = 0; /* affect own porcess */ + int opt; + enum { + OPT_n = 1, + OPT_c = 2, + OPT_p = 4, + }; + + /* Numeric params */ + /* '+': stop at first non-option */ + opt = getopt32(argv, "+n:+c:+p:+", &pri, &ioclass, &pid); + argv += optind; + + if (opt & OPT_c) { + if (ioclass > 3) + bb_error_msg_and_die("bad class %d", ioclass); +// Do we need this (compat?)? +// if (ioclass == IOPRIO_CLASS_NONE) +// ioclass = IOPRIO_CLASS_BE; +// if (ioclass == IOPRIO_CLASS_IDLE) { +// //if (opt & OPT_n) +// // bb_error_msg("ignoring priority for idle class"); +// pri = 7; +// } + } + + if (!(opt & (OPT_n|OPT_c))) { + if (!(opt & OPT_p) && *argv) + pid = xatoi_positive(*argv); + + pri = ioprio_get(IOPRIO_WHO_PROCESS, pid); + if (pri == -1) + bb_perror_msg_and_die("ioprio_%cet", 'g'); + + ioclass = (pri >> IOPRIO_CLASS_SHIFT) & 0x3; + pri &= 0xff; + printf((ioclass == IOPRIO_CLASS_IDLE) ? "%s\n" : "%s: prio %d\n", + nth_string(to_prio, ioclass), pri); + } else { +//printf("pri=%d class=%d val=%x\n", +//pri, ioclass, pri | (ioclass << IOPRIO_CLASS_SHIFT)); + pri |= (ioclass << IOPRIO_CLASS_SHIFT); + if (ioprio_set(IOPRIO_WHO_PROCESS, pid, pri) == -1) + bb_perror_msg_and_die("ioprio_%cet", 's'); + if (argv[0]) { + BB_EXECVP_or_die(argv); + } + } + + return EXIT_SUCCESS; +} diff --git a/util-linux/last.c b/util-linux/last.c new file mode 100644 index 000000000..b3f125c3f --- /dev/null +++ b/util-linux/last.c @@ -0,0 +1,166 @@ +/* vi: set sw=4 ts=4: */ +/* + * last implementation for busybox + * + * Copyright (C) 2003-2004 by Erik Andersen + * + * Licensed under GPLv2, see file LICENSE in this source tree. + */ +//config:config LAST +//config: bool "last" +//config: default y +//config: depends on FEATURE_WTMP +//config: help +//config: 'last' displays a list of the last users that logged into the system. +//config: +//config:config FEATURE_LAST_FANCY +//config: bool "Output extra information" +//config: default y +//config: depends on LAST +//config: help +//config: 'last' displays detailed information about the last users that +//config: logged into the system (mimics sysvinit last). +900 bytes. + +//applet:IF_LAST(APPLET(last, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:ifeq ($(CONFIG_FEATURE_LAST_FANCY),y) +//kbuild:lib-$(CONFIG_FEATURE_LAST_FANCY) += last_fancy.o +//kbuild:else +//kbuild:lib-$(CONFIG_LAST) += last.o +//kbuild:endif + +//usage:#define last_trivial_usage +//usage: ""IF_FEATURE_LAST_FANCY("[-HW] [-f FILE]") +//usage:#define last_full_usage "\n\n" +//usage: "Show listing of the last users that logged into the system" +//usage: IF_FEATURE_LAST_FANCY( "\n" +/* //usage: "\n -H Show header line" */ +//usage: "\n -W Display with no host column truncation" +//usage: "\n -f FILE Read from FILE instead of /var/log/wtmp" +//usage: ) + +#include "libbb.h" + +/* NB: ut_name and ut_user are the same field, use only one name (ut_user) + * to reduce confusion */ + +#ifndef SHUTDOWN_TIME +# define SHUTDOWN_TIME 254 +#endif + +/* Grr... utmp char[] members do not have to be nul-terminated. + * Do what we can while still keeping this reasonably small. + * Note: We are assuming the ut_id[] size is fixed at 4. */ + +#if defined UT_LINESIZE \ + && ((UT_LINESIZE != 32) || (UT_NAMESIZE != 32) || (UT_HOSTSIZE != 256)) +#error struct utmpx member char[] size(s) have changed! +#elif defined __UT_LINESIZE \ + && ((__UT_LINESIZE != 32) || (__UT_NAMESIZE != 32) || (__UT_HOSTSIZE != 256)) +/* __UT_NAMESIZE was checked with 64 above, but glibc-2.11 definitely uses 32! */ +#error struct utmpx member char[] size(s) have changed! +#endif + +#if EMPTY != 0 || RUN_LVL != 1 || BOOT_TIME != 2 || NEW_TIME != 3 || \ + OLD_TIME != 4 +#error Values for the ut_type field of struct utmpx changed +#endif + +int last_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int last_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) +{ + struct utmpx ut; + int n, file = STDIN_FILENO; + time_t t_tmp; + off_t pos; + static const char _ut_usr[] ALIGN1 = + "runlevel\0" "reboot\0" "shutdown\0"; + static const char _ut_lin[] ALIGN1 = + "~\0" "{\0" "|\0" /* "LOGIN\0" "date\0" */; + enum { + TYPE_RUN_LVL = RUN_LVL, /* 1 */ + TYPE_BOOT_TIME = BOOT_TIME, /* 2 */ + TYPE_SHUTDOWN_TIME = SHUTDOWN_TIME + }; + enum { + _TILDE = EMPTY, /* 0 */ + TYPE_NEW_TIME, /* NEW_TIME, 3 */ + TYPE_OLD_TIME /* OLD_TIME, 4 */ + }; + + if (argv[1]) { + bb_show_usage(); + } + file = xopen(bb_path_wtmp_file, O_RDONLY); + + printf("%-10s %-14s %-18s %-12.12s %s\n", + "USER", "TTY", "HOST", "LOGIN", "TIME"); + /* yikes. We reverse over the file and that is a not too elegant way */ + pos = xlseek(file, 0, SEEK_END); + pos = lseek(file, pos - sizeof(ut), SEEK_SET); + while ((n = full_read(file, &ut, sizeof(ut))) > 0) { + if (n != sizeof(ut)) { + bb_perror_msg_and_die("short read"); + } + n = index_in_strings(_ut_lin, ut.ut_line); + if (n == _TILDE) { /* '~' */ +#if 1 +/* do we really need to be cautious here? */ + n = index_in_strings(_ut_usr, ut.ut_user); + if (++n > 0) + ut.ut_type = n != 3 ? n : SHUTDOWN_TIME; +#else + if (is_prefixed_with(ut.ut_user, "shutdown")) + ut.ut_type = SHUTDOWN_TIME; + else if (is_prefixed_with(ut.ut_user, "reboot")) + ut.ut_type = BOOT_TIME; + else if (is_prefixed_with(ut.ut_user, "runlevel")) + ut.ut_type = RUN_LVL; +#endif + } else { + if (ut.ut_user[0] == '\0' || strcmp(ut.ut_user, "LOGIN") == 0) { + /* Don't bother. This means we can't find how long + * someone was logged in for. Oh well. */ + goto next; + } + if (ut.ut_type != DEAD_PROCESS + && ut.ut_user[0] + && ut.ut_line[0] + ) { + ut.ut_type = USER_PROCESS; + } + if (strcmp(ut.ut_user, "date") == 0) { + if (n == TYPE_OLD_TIME) { /* '|' */ + ut.ut_type = OLD_TIME; + } + if (n == TYPE_NEW_TIME) { /* '{' */ + ut.ut_type = NEW_TIME; + } + } + } + + if (ut.ut_type != USER_PROCESS) { + switch (ut.ut_type) { + case OLD_TIME: + case NEW_TIME: + case RUN_LVL: + case SHUTDOWN_TIME: + goto next; + case BOOT_TIME: + strcpy(ut.ut_line, "system boot"); + } + } + /* manpages say ut_tv.tv_sec *is* time_t, + * but some systems have it wrong */ + t_tmp = (time_t)ut.ut_tv.tv_sec; + printf("%-10s %-14s %-18s %-12.12s\n", + ut.ut_user, ut.ut_line, ut.ut_host, ctime(&t_tmp) + 4); + next: + pos -= sizeof(ut); + if (pos <= 0) + break; /* done. */ + xlseek(file, pos, SEEK_SET); + } + + fflush_stdout_and_exit(EXIT_SUCCESS); +} diff --git a/util-linux/last_fancy.c b/util-linux/last_fancy.c new file mode 100644 index 000000000..e56e0ba85 --- /dev/null +++ b/util-linux/last_fancy.c @@ -0,0 +1,300 @@ +/* vi: set sw=4 ts=4: */ +/* + * (sysvinit like) last implementation + * + * Copyright (C) 2008 by Patricia Muscalu + * + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + */ + +#include "libbb.h" + +/* NB: ut_name and ut_user are the same field, use only one name (ut_user) + * to reduce confusion */ + +#ifndef SHUTDOWN_TIME +# define SHUTDOWN_TIME 254 +#endif + +#define HEADER_FORMAT "%-8.8s %-12.12s %-*.*s %-16.16s %-7.7s %s\n" +#define HEADER_LINE "USER", "TTY", \ + INET_ADDRSTRLEN, INET_ADDRSTRLEN, "HOST", "LOGIN", " TIME", "" +#define HEADER_LINE_WIDE "USER", "TTY", \ + INET6_ADDRSTRLEN, INET6_ADDRSTRLEN, "HOST", "LOGIN", " TIME", "" + +#if !defined __UT_LINESIZE && defined UT_LINESIZE +# define __UT_LINESIZE UT_LINESIZE +#endif + +enum { + NORMAL, + LOGGED, + DOWN, + REBOOT, + CRASH, + GONE +}; + +enum { + LAST_OPT_W = (1 << 0), /* -W wide */ + LAST_OPT_f = (1 << 1), /* -f input file */ + LAST_OPT_H = (1 << 2), /* -H header */ +}; + +#define show_wide (option_mask32 & LAST_OPT_W) + +static void show_entry(struct utmpx *ut, int state, time_t dur_secs) +{ + unsigned days, hours, mins; + char duration[sizeof("(%u+02:02)") + sizeof(int)*3]; + char login_time[17]; + char logout_time[8]; + const char *logout_str; + const char *duration_str; + time_t tmp; + + /* manpages say ut_tv.tv_sec *is* time_t, + * but some systems have it wrong */ + tmp = ut->ut_tv.tv_sec; + safe_strncpy(login_time, ctime(&tmp), 17); + tmp = dur_secs; + snprintf(logout_time, 8, "- %s", ctime(&tmp) + 11); + + dur_secs = MAX(dur_secs - (time_t)ut->ut_tv.tv_sec, (time_t)0); + /* unsigned int is easier to divide than time_t (which may be signed long) */ + mins = dur_secs / 60; + days = mins / (24*60); + mins = mins % (24*60); + hours = mins / 60; + mins = mins % 60; + +// if (days) { + sprintf(duration, "(%u+%02u:%02u)", days, hours, mins); +// } else { +// sprintf(duration, " (%02u:%02u)", hours, mins); +// } + + logout_str = logout_time; + duration_str = duration; + switch (state) { + case NORMAL: + break; + case LOGGED: + logout_str = " still"; + duration_str = "logged in"; + break; + case DOWN: + logout_str = "- down "; + break; + case REBOOT: + break; + case CRASH: + logout_str = "- crash"; + break; + case GONE: + logout_str = " gone"; + duration_str = "- no logout"; + break; + } + + printf(HEADER_FORMAT, + ut->ut_user, + ut->ut_line, + show_wide ? INET6_ADDRSTRLEN : INET_ADDRSTRLEN, + show_wide ? INET6_ADDRSTRLEN : INET_ADDRSTRLEN, + ut->ut_host, + login_time, + logout_str, + duration_str); +} + +static int get_ut_type(struct utmpx *ut) +{ + if (ut->ut_line[0] == '~') { + if (strcmp(ut->ut_user, "shutdown") == 0) { + return SHUTDOWN_TIME; + } + if (strcmp(ut->ut_user, "reboot") == 0) { + return BOOT_TIME; + } + if (strcmp(ut->ut_user, "runlevel") == 0) { + return RUN_LVL; + } + return ut->ut_type; + } + + if (ut->ut_user[0] == 0) { + return DEAD_PROCESS; + } + + if ((ut->ut_type != DEAD_PROCESS) + && (strcmp(ut->ut_user, "LOGIN") != 0) + && ut->ut_user[0] + && ut->ut_line[0] + ) { + ut->ut_type = USER_PROCESS; + } + + if (strcmp(ut->ut_user, "date") == 0) { + if (ut->ut_line[0] == '|') { + return OLD_TIME; + } + if (ut->ut_line[0] == '{') { + return NEW_TIME; + } + } + return ut->ut_type; +} + +static int is_runlevel_shutdown(struct utmpx *ut) +{ + if (((ut->ut_pid & 255) == '0') || ((ut->ut_pid & 255) == '6')) { + return 1; + } + + return 0; +} + +int last_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int last_main(int argc UNUSED_PARAM, char **argv) +{ + struct utmpx ut; + const char *filename = _PATH_WTMP; + llist_t *zlist; + off_t pos; + time_t start_time; + time_t boot_time; + time_t down_time; + int file; + smallint going_down; + smallint boot_down; + + /*opt =*/ getopt32(argv, "Wf:" /* "H" */, &filename); +#ifdef BUT_UTIL_LINUX_LAST_HAS_NO_SUCH_OPT + if (opt & LAST_OPT_H) { + /* Print header line */ + if (opt & LAST_OPT_W) { + printf(HEADER_FORMAT, HEADER_LINE_WIDE); + } else { + printf(HEADER_FORMAT, HEADER_LINE); + } + } +#endif + + file = xopen(filename, O_RDONLY); + { + /* in case the file is empty... */ + struct stat st; + fstat(file, &st); + start_time = st.st_ctime; + } + + time(&down_time); + going_down = 0; + boot_down = NORMAL; /* 0 */ + zlist = NULL; + boot_time = 0; + /* get file size, rounding down to last full record */ + pos = xlseek(file, 0, SEEK_END) / sizeof(ut) * sizeof(ut); + for (;;) { + pos -= (off_t)sizeof(ut); + if (pos < 0) { + /* Beyond the beginning of the file boundary => + * the whole file has been read. */ + break; + } + xlseek(file, pos, SEEK_SET); + xread(file, &ut, sizeof(ut)); + /* rewritten by each record, eventially will have + * first record's ut_tv.tv_sec: */ + start_time = ut.ut_tv.tv_sec; + + switch (get_ut_type(&ut)) { + case SHUTDOWN_TIME: + down_time = ut.ut_tv.tv_sec; + boot_down = DOWN; + going_down = 1; + break; + case RUN_LVL: + if (is_runlevel_shutdown(&ut)) { + down_time = ut.ut_tv.tv_sec; + going_down = 1; + boot_down = DOWN; + } + break; + case BOOT_TIME: + strcpy(ut.ut_line, "system boot"); + show_entry(&ut, REBOOT, down_time); + boot_down = CRASH; + going_down = 1; + break; + case DEAD_PROCESS: + if (!ut.ut_line[0]) { + break; + } + /* add_entry */ + llist_add_to(&zlist, xmemdup(&ut, sizeof(ut))); + break; + case USER_PROCESS: { + int show; + + if (!ut.ut_line[0]) { + break; + } + /* find_entry */ + show = 1; + { + llist_t *el, *next; + for (el = zlist; el; el = next) { + struct utmpx *up = (struct utmpx *)el->data; + next = el->link; + if (strncmp(up->ut_line, ut.ut_line, __UT_LINESIZE) == 0) { + if (show) { + show_entry(&ut, NORMAL, up->ut_tv.tv_sec); + show = 0; + } + llist_unlink(&zlist, el); + free(el->data); + free(el); + } + } + } + + if (show) { + int state = boot_down; + + if (boot_time == 0) { + state = LOGGED; + /* Check if the process is alive */ + if ((ut.ut_pid > 0) + && (kill(ut.ut_pid, 0) != 0) + && (errno == ESRCH)) { + state = GONE; + } + } + show_entry(&ut, state, boot_time); + } + /* add_entry */ + llist_add_to(&zlist, xmemdup(&ut, sizeof(ut))); + break; + } + } + + if (going_down) { + boot_time = ut.ut_tv.tv_sec; + llist_free(zlist, free); + zlist = NULL; + going_down = 0; + } + } + + if (ENABLE_FEATURE_CLEAN_UP) { + llist_free(zlist, free); + } + + printf("\nwtmp begins %s", ctime(&start_time)); + + if (ENABLE_FEATURE_CLEAN_UP) + close(file); + fflush_stdout_and_exit(EXIT_SUCCESS); +} diff --git a/util-linux/mountpoint.c b/util-linux/mountpoint.c new file mode 100644 index 000000000..8b9e1d779 --- /dev/null +++ b/util-linux/mountpoint.c @@ -0,0 +1,105 @@ +/* vi: set sw=4 ts=4: */ +/* + * mountpoint implementation for busybox + * + * Copyright (C) 2005 Bernhard Reutner-Fischer + * + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + * + * Based on sysvinit's mountpoint + */ +//config:config MOUNTPOINT +//config: bool "mountpoint" +//config: default y +//config: help +//config: mountpoint checks if the directory is a mountpoint. + +//applet:IF_MOUNTPOINT(APPLET(mountpoint, BB_DIR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_MOUNTPOINT) += mountpoint.o + +//usage:#define mountpoint_trivial_usage +//usage: "[-q] <[-dn] DIR | -x DEVICE>" +//usage:#define mountpoint_full_usage "\n\n" +//usage: "Check if the directory is a mountpoint\n" +//usage: "\n -q Quiet" +//usage: "\n -d Print major/minor device number of the filesystem" +//usage: "\n -n Print device name of the filesystem" +//usage: "\n -x Print major/minor device number of the blockdevice" +//usage: +//usage:#define mountpoint_example_usage +//usage: "$ mountpoint /proc\n" +//usage: "/proc is not a mountpoint\n" +//usage: "$ mountpoint /sys\n" +//usage: "/sys is a mountpoint\n" + +#include "libbb.h" + +int mountpoint_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int mountpoint_main(int argc UNUSED_PARAM, char **argv) +{ + struct stat st; + const char *msg; + char *arg; + int rc, opt; + + opt_complementary = "=1"; /* must have one argument */ + opt = getopt32(argv, "qdxn"); +#define OPT_q (1) +#define OPT_d (2) +#define OPT_x (4) +#define OPT_n (8) + arg = argv[optind]; + msg = "%s"; + + rc = (opt & OPT_x) ? stat(arg, &st) : lstat(arg, &st); + if (rc != 0) + goto err; + + if (opt & OPT_x) { + if (S_ISBLK(st.st_mode)) { + printf("%u:%u\n", major(st.st_rdev), + minor(st.st_rdev)); + return EXIT_SUCCESS; + } + errno = 0; /* make perror_msg work as error_msg */ + msg = "%s: not a block device"; + goto err; + } + + errno = ENOTDIR; + if (S_ISDIR(st.st_mode)) { + dev_t st_dev = st.st_dev; + ino_t st_ino = st.st_ino; + char *p = xasprintf("%s/..", arg); + + if (stat(p, &st) == 0) { + //int is_mnt = (st_dev != st.st_dev) || (st_dev == st.st_dev && st_ino == st.st_ino); + int is_not_mnt = (st_dev == st.st_dev) && (st_ino != st.st_ino); + + if (opt & OPT_d) + printf("%u:%u\n", major(st_dev), minor(st_dev)); + if (opt & OPT_n) { + const char *d = find_block_device(arg); + /* name is undefined, but device is mounted -> anonymous superblock! */ + /* happens with btrfs */ + if (!d) { + d = "UNKNOWN"; + /* TODO: iterate /proc/mounts, or /proc/self/mountinfo + * to find out the device name */ + } + printf("%s %s\n", d, arg); + } + if (!(opt & (OPT_q | OPT_d | OPT_n))) + printf("%s is %sa mountpoint\n", arg, is_not_mnt ? "not " : ""); + return is_not_mnt; + } + arg = p; + /* else: stat had set errno, just fall through */ + } + + err: + if (!(opt & OPT_q)) + bb_perror_msg(msg, arg); + return EXIT_FAILURE; +} diff --git a/util-linux/setsid.c b/util-linux/setsid.c new file mode 100644 index 000000000..143a8f8fa --- /dev/null +++ b/util-linux/setsid.c @@ -0,0 +1,82 @@ +/* vi: set sw=4 ts=4: */ +/* + * setsid.c -- execute a command in a new session + * Rick Sladkey + * In the public domain. + * + * 1999-02-22 Arkadiusz Mickiewicz + * - added Native Language Support + * + * 2001-01-18 John Fremlin + * - fork in case we are process group leader + * + * 2004-11-12 Paul Fox + * - busyboxed + */ +//config:config SETSID +//config: bool "setsid" +//config: default y +//config: help +//config: setsid runs a program in a new session + +//applet:IF_SETSID(APPLET(setsid, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_SETSID) += setsid.o + +//usage:#define setsid_trivial_usage +//usage: "[-c] PROG ARGS" +//usage:#define setsid_full_usage "\n\n" +//usage: "Run PROG in a new session. PROG will have no controlling terminal\n" +//usage: "and will not be affected by keyboard signals (^C etc).\n" +//usage: "\n -c Set controlling terminal to stdin" + +#include "libbb.h" + +int setsid_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int setsid_main(int argc UNUSED_PARAM, char **argv) +{ + unsigned opt; + + opt_complementary = "-1"; /* at least one arg */ + opt = getopt32(argv, "+c"); /* +: stop on first non-opt */ + argv += optind; + + /* setsid() is allowed only when we are not a process group leader. + * Otherwise our PID serves as PGID of some existing process group + * and cannot be used as PGID of a new process group. + * + * Example: setsid() below fails when run alone in interactive shell: + * $ setsid PROG + * because shell's child (setsid) is put in a new process group. + * But doesn't fail if shell is not interactive + * (and therefore doesn't create process groups for pipes), + * or if setsid is not the first process in the process group: + * $ true | setsid PROG + * or if setsid is executed in backquotes (`setsid PROG`)... + */ + if (setsid() < 0) { + pid_t pid = fork_or_rexec(argv); + if (pid != 0) { + /* parent */ + /* TODO: + * we can waitpid(pid, &status, 0) and then even + * emulate exitcode, making the behavior consistent + * in both forked and non forked cases. + * However, the code is larger and upstream + * does not do such trick. + */ + return EXIT_SUCCESS; + } + + /* child */ + /* now there should be no error: */ + setsid(); + } + + if (opt) { + /* -c: set (with stealing) controlling tty */ + ioctl(0, TIOCSCTTY, 1); + } + + BB_EXECVP_or_die(argv); +} diff --git a/util-linux/taskset.c b/util-linux/taskset.c new file mode 100644 index 000000000..94a07383a --- /dev/null +++ b/util-linux/taskset.c @@ -0,0 +1,221 @@ +/* vi: set sw=4 ts=4: */ +/* + * taskset - retrieve or set a processes' CPU affinity + * Copyright (c) 2006 Bernhard Reutner-Fischer + * + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + */ + +//config:config TASKSET +//config: bool "taskset" +//config: default y +//config: help +//config: Retrieve or set a processes's CPU affinity. +//config: This requires sched_{g,s}etaffinity support in your libc. +//config: +//config:config FEATURE_TASKSET_FANCY +//config: bool "Fancy output" +//config: default y +//config: depends on TASKSET +//config: help +//config: Needed for machines with more than 32-64 CPUs: +//config: affinity parameter 0xHHHHHHHHHHHHHHHHHHHH can be arbitrarily long +//config: in this case. Otherwise, it is limited to sizeof(long). + +//applet:IF_TASKSET(APPLET(taskset, BB_DIR_USR_BIN, BB_SUID_DROP)) +//kbuild:lib-$(CONFIG_TASKSET) += taskset.o + +//usage:#define taskset_trivial_usage +//usage: "[-p] [HEXMASK] PID | PROG ARGS" +//usage:#define taskset_full_usage "\n\n" +//usage: "Set or get CPU affinity\n" +//usage: "\n -p Operate on an existing PID" +//usage: +//usage:#define taskset_example_usage +//usage: "$ taskset 0x7 ./dgemm_test&\n" +//usage: "$ taskset -p 0x1 $!\n" +//usage: "pid 4790's current affinity mask: 7\n" +//usage: "pid 4790's new affinity mask: 1\n" +//usage: "$ taskset 0x7 /bin/sh -c './taskset -p 0x1 $$'\n" +//usage: "pid 6671's current affinity mask: 1\n" +//usage: "pid 6671's new affinity mask: 1\n" +//usage: "$ taskset -p 1\n" +//usage: "pid 1's current affinity mask: 3\n" +/* + * Not yet implemented: + * -a/--all-tasks (affect all threads) + * needs to get TIDs from /proc/PID/task/ and use _them_ as "pid" in sched_setaffinity(pid) + * -c/--cpu-list (specify CPUs via "1,3,5-7") + */ + +#include +#include "libbb.h" + +typedef unsigned long ul; +#define SZOF_UL (unsigned)(sizeof(ul)) +#define BITS_UL (unsigned)(sizeof(ul)*8) +#define MASK_UL (unsigned)(sizeof(ul)*8 - 1) + +#if ENABLE_FEATURE_TASKSET_FANCY +#define TASKSET_PRINTF_MASK "%s" +/* craft a string from the mask */ +static char *from_mask(const ul *mask, unsigned sz_in_bytes) +{ + char *str = xzalloc((sz_in_bytes+1) * 2); /* we will leak it */ + char *p = str; + for (;;) { + ul v = *mask++; + if (SZOF_UL == 4) + p += sprintf(p, "%08lx", v); + if (SZOF_UL == 8) + p += sprintf(p, "%016lx", v); + if (SZOF_UL == 16) + p += sprintf(p, "%032lx", v); /* :) */ + sz_in_bytes -= SZOF_UL; + if ((int)sz_in_bytes <= 0) + break; + } + while (str[0] == '0' && str[1]) + str++; + return str; +} +#else +#define TASKSET_PRINTF_MASK "%lx" +static unsigned long long from_mask(ul *mask, unsigned sz_in_bytes UNUSED_PARAM) +{ + return *mask; +} +#endif + +static unsigned long *get_aff(int pid, unsigned *sz) +{ + int r; + unsigned long *mask = NULL; + unsigned sz_in_bytes = *sz; + + for (;;) { + mask = xrealloc(mask, sz_in_bytes); + r = sched_getaffinity(pid, sz_in_bytes, (void*)mask); + if (r == 0) + break; + sz_in_bytes *= 2; + if (errno == EINVAL && (int)sz_in_bytes > 0) + continue; + bb_perror_msg_and_die("can't %cet pid %d's affinity", 'g', pid); + } + //bb_error_msg("get mask[0]:%lx sz_in_bytes:%d", mask[0], sz_in_bytes); + *sz = sz_in_bytes; + return mask; +} + +int taskset_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int taskset_main(int argc UNUSED_PARAM, char **argv) +{ + ul *mask; + unsigned mask_size_in_bytes; + pid_t pid = 0; + unsigned opt_p; + const char *current_new; + char *aff; + + /* NB: we mimic util-linux's taskset: -p does not take + * an argument, i.e., "-pN" is NOT valid, only "-p N"! + * Indeed, util-linux-2.13-pre7 uses: + * getopt_long(argc, argv, "+pchV", ...), not "...p:..." */ + + opt_complementary = "-1"; /* at least 1 arg */ + opt_p = getopt32(argv, "+p"); + argv += optind; + + aff = *argv++; + if (opt_p) { + char *pid_str = aff; + if (*argv) { /* "-p ...rest.is.ignored..." */ + pid_str = *argv; /* NB: *argv != NULL in this case */ + } + /* else it was just "-p ", and *argv == NULL */ + pid = xatoul_range(pid_str, 1, ((unsigned)(pid_t)ULONG_MAX) >> 1); + } else { + /* */ + if (!*argv) + bb_show_usage(); + } + + mask_size_in_bytes = SZOF_UL; + current_new = "current"; + print_aff: + mask = get_aff(pid, &mask_size_in_bytes); + if (opt_p) { + printf("pid %d's %s affinity mask: "TASKSET_PRINTF_MASK"\n", + pid, current_new, from_mask(mask, mask_size_in_bytes)); + if (*argv == NULL) { + /* Either it was just "-p ", + * or it was "-p " and we came here + * for the second time (see goto below) */ + return EXIT_SUCCESS; + } + *argv = NULL; + current_new = "new"; + } + memset(mask, 0, mask_size_in_bytes); + + /* Affinity was specified, translate it into mask */ + /* it is always in hex, skip "0x" if it exists */ + if (aff[0] == '0' && (aff[1]|0x20) == 'x') + aff += 2; + + if (!ENABLE_FEATURE_TASKSET_FANCY) { + mask[0] = xstrtoul(aff, 16); + } else { + unsigned i; + char *last_char; + + i = 0; /* bit pos in mask[] */ + + /* aff is ASCII hex string, accept very long masks in this form. + * Process hex string AABBCCDD... to ulong mask[] + * from the rightmost nibble, which is least-significant. + * Bits not fitting into mask[] are ignored: (example: 1234 + * in 12340000000000000000000000000000000000000ff) + */ + last_char = strchrnul(aff, '\0'); + while (last_char > aff) { + char c; + ul val; + + last_char--; + c = *last_char; + if (isdigit(c)) + val = c - '0'; + else if ((c|0x20) >= 'a' && (c|0x20) <= 'f') + val = (c|0x20) - ('a' - 10); + else + bb_error_msg_and_die("bad affinity '%s'", aff); + + if (i < mask_size_in_bytes * 8) { + mask[i / BITS_UL] |= val << (i & MASK_UL); + //bb_error_msg("bit %d set", i); + } + /* else: + * We can error out here, but we don't. + * For one, kernel itself ignores bits in mask[] + * which do not map to any CPUs: + * if mask[] has one 32-bit long element, + * but you have only 8 CPUs, all bits beyond first 8 + * are ignored, silently. + * No point in making bits past 31th to be errors. + */ + i += 4; + } + } + + /* Set pid's or our own (pid==0) affinity */ + if (sched_setaffinity(pid, mask_size_in_bytes, (void*)mask)) + bb_perror_msg_and_die("can't %cet pid %d's affinity", 's', pid); + //bb_error_msg("set mask[0]:%lx", mask[0]); + + if (!argv[0]) /* "-p [...ignored...]" */ + goto print_aff; /* print new affinity and exit */ + + BB_EXECVP_or_die(argv); +} diff --git a/util-linux/wall.c b/util-linux/wall.c new file mode 100644 index 000000000..50658f457 --- /dev/null +++ b/util-linux/wall.c @@ -0,0 +1,63 @@ +/* vi: set sw=4 ts=4: */ +/* + * wall - write a message to all logged-in users + * Copyright (c) 2009 Bernhard Reutner-Fischer + * + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + */ + +//config:config WALL +//config: bool "wall" +//config: default y +//config: depends on FEATURE_UTMP +//config: help +//config: Write a message to all users that are logged in. + +/* Needs to be run by root or be suid root - needs to write to /dev/TTY: */ +//applet:IF_WALL(APPLET(wall, BB_DIR_USR_BIN, BB_SUID_REQUIRE)) + +//kbuild:lib-$(CONFIG_WALL) += wall.o + +//usage:#define wall_trivial_usage +//usage: "[FILE]" +//usage:#define wall_full_usage "\n\n" +//usage: "Write content of FILE or stdin to all logged-in users" +//usage: +//usage:#define wall_sample_usage +//usage: "echo foo | wall\n" +//usage: "wall ./mymessage" + +#include "libbb.h" + +int wall_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int wall_main(int argc UNUSED_PARAM, char **argv) +{ + struct utmpx *ut; + char *msg; + int fd; + + fd = STDIN_FILENO; + if (argv[1]) { + /* The applet is setuid. + * Access to the file must be under user's uid/gid. + */ + fd = xopen_as_uid_gid(argv[1], O_RDONLY, getuid(), getgid()); + } + msg = xmalloc_read(fd, NULL); + if (ENABLE_FEATURE_CLEAN_UP && argv[1]) + close(fd); + setutxent(); + while ((ut = getutxent()) != NULL) { + char *line; + if (ut->ut_type != USER_PROCESS) + continue; + line = concat_path_file("/dev", ut->ut_line); + xopen_xwrite_close(line, msg); + free(line); + } + if (ENABLE_FEATURE_CLEAN_UP) { + endutxent(); + free(msg); + } + return EXIT_SUCCESS; +} -- cgit v1.2.3-55-g6feb From 10ad622dc2a9fb6563fab13719ead8baf15ff9e4 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 17 Apr 2017 16:13:32 +0200 Subject: Spelling fixes in comments, documentation, tests and examples By klemens Signed-off-by: Denys Vlasenko --- archival/dpkg.c | 26 +++++++++++++------------- archival/libarchive/decompress_bunzip2.c | 2 +- archival/libarchive/unxz/xz_dec_lzma2.c | 4 ++-- archival/tar.c | 4 ++-- coreutils/dos2unix.c | 2 +- docs/sigint.htm | 10 +++++----- docs/style-guide.txt | 2 +- editors/sed.c | 8 ++++---- examples/var_service/dhcp_if/dhcp_handler | 2 +- findutils/find.c | 2 +- findutils/grep.c | 4 ++-- libbb/getopt32.c | 2 +- libpwdgrp/pwd_grp.c | 4 ++-- loginutils/cryptpw.c | 2 +- miscutils/inotifyd.c | 2 +- miscutils/less.c | 2 +- miscutils/time.c | 2 +- modutils/Config.src | 2 +- modutils/modinfo.c | 2 +- modutils/modprobe-small.c | 4 ++-- networking/dnsd.c | 2 +- networking/ifenslave.c | 2 +- networking/isrv.c | 2 +- networking/nc_bloaty.c | 4 ++-- networking/ntpd.c | 6 +++--- networking/ping.c | 4 ++-- networking/tcpudp.c | 2 +- networking/udhcp/dhcpc.c | 2 +- networking/udhcp/dhcprelay.c | 2 +- networking/vconfig.c | 2 +- shell/ash.c | 12 ++++++------ shell/ash_test/ash-misc/unicode1.tests | 2 +- shell/hush.c | 12 ++++++------ shell/hush_test/hush-misc/unicode1.tests | 2 +- sysklogd/logread.c | 4 ++-- testsuite/readlink.tests | 2 +- util-linux/cal.c | 2 +- util-linux/hwclock.c | 2 +- util-linux/renice.c | 2 +- util-linux/switch_root.c | 2 +- util-linux/volume_id/udf.c | 2 +- 41 files changed, 80 insertions(+), 80 deletions(-) (limited to 'miscutils') diff --git a/archival/dpkg.c b/archival/dpkg.c index f133299e3..1cd45eda4 100644 --- a/archival/dpkg.c +++ b/archival/dpkg.c @@ -18,7 +18,7 @@ * known difference between busybox dpkg and the official dpkg that i don't * consider important, its worth keeping a note of differences anyway, just to * make it easier to maintain. - * - the first value for the confflile: field isnt placed on a new line. + * - the first value for the confflile: field isn't placed on a new line. * - when installing a package the status: field is placed at the end of the * section, rather than just after the package: field. * @@ -110,7 +110,7 @@ typedef struct common_node_s { edge_t **edge; } common_node_t; -/* Currently it doesnt store packages that have state-status of not-installed +/* Currently it doesn't store packages that have state-status of not-installed * So it only really has to be the size of the maximum number of packages * likely to be installed at any one time, so there is a bit of leeway here */ #define STATUS_HASH_PRIME 8191 @@ -205,7 +205,7 @@ static int search_name_hashtable(const char *key) return probe_address; } -/* this DOESNT add the key to the hashtable +/* this DOESN'T add the key to the hashtable * TODO make it consistent with search_name_hashtable */ static unsigned search_status_hashtable(const char *key) @@ -467,7 +467,7 @@ static void add_split_dependencies(common_node_t *parent_node, const char *whole version = strchr(field2, '('); if (version == NULL) { edge->operator = VER_ANY; - /* Get the versions hash number, adding it if the number isnt already in there */ + /* Get the versions hash number, adding it if the number isn't already in there */ edge->version = search_name_hashtable("ANY"); } else { /* Skip leading ' ' or '(' */ @@ -496,7 +496,7 @@ static void add_split_dependencies(common_node_t *parent_node, const char *whole /* Truncate version at trailing ' ' or ')' */ version[strcspn(version, " )")] = '\0'; - /* Get the versions hash number, adding it if the number isnt already in there */ + /* Get the versions hash number, adding it if the number isn't already in there */ edge->version = search_name_hashtable(version); } @@ -562,7 +562,7 @@ static int read_package_field(const char *package_buffer, char **field_name, cha offset_name_end = offset; offset_value_start = next_offset; } - /* TODO: Name might still have trailing spaces if ':' isnt + /* TODO: Name might still have trailing spaces if ':' isn't * immediately after name */ break; case '\n': @@ -776,7 +776,7 @@ static void index_status_file(const char *filename) const unsigned package_num = fill_package_struct(control_buffer); if (package_num != -1) { status_node = xmalloc(sizeof(status_node_t)); - /* fill_package_struct doesnt handle the status field */ + /* fill_package_struct doesn't handle the status field */ status_line = strstr(control_buffer, "Status:"); if (status_line != NULL) { status_line += 7; @@ -850,7 +850,7 @@ static void write_status_file(deb_file_t **deb_file) if (status_hashtable[status_num] != NULL) { const char *status_from_hashtable = name_hashtable[status_hashtable[status_num]->status]; if (strcmp(status_from_file, status_from_hashtable) != 0) { - /* New status isnt exactly the same as old status */ + /* New status isn't exactly the same as old status */ const int state_status = get_status(status_num, 3); if ((strcmp("installed", name_hashtable[state_status]) == 0) || (strcmp("unpacked", name_hashtable[state_status]) == 0) @@ -919,7 +919,7 @@ static void write_status_file(deb_file_t **deb_file) } } } - /* If the package from the status file wasnt handle above, do it now*/ + /* If the package from the status file wasn't handle above, do it now*/ if (!write_flag) { fprintf(new_status_file, "%s\n\n", control_buffer); } @@ -946,7 +946,7 @@ static void write_status_file(deb_file_t **deb_file) if (errno != ENOENT) bb_error_msg_and_die("can't create backup status file"); /* Its ok if renaming the status file fails because status - * file doesnt exist, maybe we are starting from scratch */ + * file doesn't exist, maybe we are starting from scratch */ bb_error_msg("no status file found, creating new one"); } @@ -1061,7 +1061,7 @@ static int check_deps(deb_file_t **deb_file, int deb_start /*, int dep_max_count } - /* Check dependendcies */ + /* Check dependentcies */ for (i = 0; i < PACKAGE_HASH_PRIME; i++) { int status_num = 0; int number_of_alternatives = 0; @@ -1244,7 +1244,7 @@ static void run_package_script_or_die(const char *package_name, const char *scri script_path = xasprintf("/var/lib/dpkg/info/%s.%s", package_name, script_type); - /* If the file doesnt exist is isnt fatal */ + /* If the file doesn't exist it isn't fatal */ result = access(script_path, F_OK) ? EXIT_SUCCESS : system(script_path); free(script_path); if (result) @@ -1839,7 +1839,7 @@ int dpkg_main(int argc UNUSED_PARAM, char **argv) ) { status_node = xmalloc(sizeof(status_node_t)); status_node->package = deb_file[deb_count]->package; - /* reinstreq isnt changed to "ok" until the package control info + /* reinstreq isn't changed to "ok" until the package control info * is written to the status file*/ status_node->status = search_name_hashtable("install reinstreq not-installed"); status_hashtable[status_num] = status_node; diff --git a/archival/libarchive/decompress_bunzip2.c b/archival/libarchive/decompress_bunzip2.c index 4fb989c29..803702f75 100644 --- a/archival/libarchive/decompress_bunzip2.c +++ b/archival/libarchive/decompress_bunzip2.c @@ -308,7 +308,7 @@ static int get_next_block(bunzip_data *bd) base = hufGroup->base - 1; limit = hufGroup->limit - 1; - /* Calculate permute[]. Concurently, initialize temp[] and limit[]. */ + /* Calculate permute[]. Concurrently, initialize temp[] and limit[]. */ pp = 0; for (i = minLen; i <= maxLen; i++) { int k; diff --git a/archival/libarchive/unxz/xz_dec_lzma2.c b/archival/libarchive/unxz/xz_dec_lzma2.c index 351251f7c..bca41e705 100644 --- a/archival/libarchive/unxz/xz_dec_lzma2.c +++ b/archival/libarchive/unxz/xz_dec_lzma2.c @@ -486,11 +486,11 @@ static __always_inline void XZ_FUNC rc_normalize(struct rc_dec *rc) } /* - * Decode one bit. In some versions, this function has been splitted in three + * Decode one bit. In some versions, this function has been split in three * functions so that the compiler is supposed to be able to more easily avoid * an extra branch. In this particular version of the LZMA decoder, this * doesn't seem to be a good idea (tested with GCC 3.3.6, 3.4.6, and 4.3.3 - * on x86). Using a non-splitted version results in nicer looking code too. + * on x86). Using a non-split version results in nicer looking code too. * * NOTE: This must return an int. Do not make it return a bool or the speed * of the code generated by GCC 3.x decreases 10-15 %. (GCC 4.3 doesn't care, diff --git a/archival/tar.c b/archival/tar.c index b1d58a2df..b70e00a8b 100644 --- a/archival/tar.c +++ b/archival/tar.c @@ -529,8 +529,8 @@ static int FAST_FUNC writeFileToTarball(const char *fileName, struct stat *statb /* * Check to see if we are dealing with a hard link. * If so - - * Treat the first occurance of a given dev/inode as a file while - * treating any additional occurances as hard links. This is done + * Treat the first occurrence of a given dev/inode as a file while + * treating any additional occurrences as hard links. This is done * by adding the file information to the HardLinkInfo linked list. */ tbInfo->hlInfo = NULL; diff --git a/coreutils/dos2unix.c b/coreutils/dos2unix.c index 6d2347163..9d81ccca6 100644 --- a/coreutils/dos2unix.c +++ b/coreutils/dos2unix.c @@ -2,7 +2,7 @@ /* * dos2unix for BusyBox * - * dos2unix '\n' convertor 0.5.0 + * dos2unix '\n' converter 0.5.0 * based on Unix2Dos 0.9.0 by Peter Hanecak (made 19.2.1997) * Copyright 1997,.. by Peter Hanecak . * All rights reserved. diff --git a/docs/sigint.htm b/docs/sigint.htm index e230f4df7..d656aeb8c 100644 --- a/docs/sigint.htm +++ b/docs/sigint.htm @@ -45,7 +45,7 @@ intention. Required knowledge: You have to know what it means to catch SIGINT or SIGQUIT and how -processes are waiting for other processes (childs) they spawned. +processes are waiting for other processes (children) they spawned. @@ -366,7 +366,7 @@ signal, it has to take care of communicating the signal status itself.

Some programs don't do this. On SIGINT, they do cleanup and exit -immediatly, but the calling shell isn't told about the non-normal exit +immediately, but the calling shell isn't told about the non-normal exit and it will call the next program in the script.

As a result, the user hits SIGINT and while one program exits, the @@ -446,7 +446,7 @@ handlers, so it is portable. trap command. Here, the same as for C programs apply. If the intention of SIGINT is to end your program, you have to exit in a way that the calling programs "sees" that you have been killed. If -you don't catch SIGINT, this happend automatically, but of you catch +you don't catch SIGINT, this happened automatically, but of you catch SIGINT, i.e. to do cleanup work, you have to end the program by killing yourself, not by calling exit. @@ -466,7 +466,7 @@ files (which isn't really portable in C, though). bourne shell. Every language implementation that lets you catch SIGINT should also give you the option to reset the signal and kill yourself. -

It is always desireable to exit the right way, even if you don't +

It is always desirable to exit the right way, even if you don't expect your usual callers to depend on it, some unusual one will come along. This proper exit status will be needed for WCE and will not hurt when the calling shell uses IUE or WUE. @@ -565,7 +565,7 @@ comments the scripts echo. What happens when a shellscript called emacs, the user did not use C-c and the script has additional commands in it? What happens if a non-interactive child catches SIGINT? -To behave properly, childs must do what? +To behave properly, children must do what? diff --git a/docs/style-guide.txt b/docs/style-guide.txt index 10ed893dc..9eed7f125 100644 --- a/docs/style-guide.txt +++ b/docs/style-guide.txt @@ -329,7 +329,7 @@ With "const int" compiler may fail to optimize it out and will reserve a real storage in rodata for it! (Hopefully, newer gcc will get better at it...). With "define", you have slight risk of polluting namespace (#define doesn't allow you to redefine the name in the inner scopes), -and complex "define" are evaluated each time they uesd, not once +and complex "define" are evaluated each time they used, not once at declarations like enums. Also, the preprocessor does _no_ type checking whatsoever, making it much more error prone. diff --git a/editors/sed.c b/editors/sed.c index 637a6851b..ca9ab2054 100644 --- a/editors/sed.c +++ b/editors/sed.c @@ -337,7 +337,7 @@ static int get_address(const char *my_str, int *linenum, regex_t ** regex) if (isdigit(*my_str)) { *linenum = strtol(my_str, (char**)&pos, 10); - /* endstr shouldnt ever equal NULL */ + /* endstr shouldn't ever equal NULL */ } else if (*my_str == '$') { *linenum = -1; pos++; @@ -444,7 +444,7 @@ static int parse_subst_cmd(sed_cmd_t *sed_cmd, const char *substr) free(fname); break; } - /* Ignore case (gnu exension) */ + /* Ignore case (gnu extension) */ case 'i': case 'I': cflags |= REG_ICASE; @@ -587,7 +587,7 @@ static const char *parse_cmd_args(sed_cmd_t *sed_cmd, const char *cmdstr) free(match); free(replace); } - /* if it wasnt a single-letter command that takes no arguments + /* if it wasn't a single-letter command that takes no arguments * then it must be an invalid command. */ else if (idx >= IDX_nul) { /* not d,D,g,G,h,H,l,n,N,p,P,q,x,=,{,} */ @@ -751,7 +751,7 @@ static void do_subst_w_backrefs(char *line, char *replace) continue; } /* I _think_ it is impossible to get '\' to be - * the last char in replace string. Thus we dont check + * the last char in replace string. Thus we don't check * for replace[i] == NUL. (counterexample anyone?) */ /* if we find a backslash escaped character, print the character */ pipe_putc(replace[i]); diff --git a/examples/var_service/dhcp_if/dhcp_handler b/examples/var_service/dhcp_if/dhcp_handler index 3d2a5cb79..3d44a6022 100755 --- a/examples/var_service/dhcp_if/dhcp_handler +++ b/examples/var_service/dhcp_if/dhcp_handler @@ -21,7 +21,7 @@ # ntpsrv=10.34.32.125 10.34.255.7 # # renew: lease is renewed. Environment is similar to "bound". -# The IP address does not change, however, the other DHCP paramaters, +# The IP address does not change, however, the other DHCP parameters, # such as the default gateway, subnet mask, and dns server may change. # # nak: udhcpc received a NAK message. diff --git a/findutils/find.c b/findutils/find.c index 67aa40b21..0596c0059 100644 --- a/findutils/find.c +++ b/findutils/find.c @@ -182,7 +182,7 @@ //config: default y //config: depends on FIND //config: help -//config: If the file is a directory, dont descend into it. Useful for +//config: If the file is a directory, don't descend into it. Useful for //config: exclusion .svn and CVS directories. //config: //config:config FEATURE_FIND_DELETE diff --git a/findutils/grep.c b/findutils/grep.c index 261e563d5..d66d85a53 100644 --- a/findutils/grep.c +++ b/findutils/grep.c @@ -515,7 +515,7 @@ static int grep_file(FILE *file) if (option_mask32 & OPT_o) { if (FGREP_FLAG) { /* -Fo just prints the pattern - * (unless -v: -Fov doesnt print anything at all) */ + * (unless -v: -Fov doesn't print anything at all) */ if (found) print_line(gl->pattern, strlen(gl->pattern), linenum, ':'); } else while (1) { @@ -823,7 +823,7 @@ int grep_main(int argc UNUSED_PARAM, char **argv) grep_done: ; } while (*argv && *++argv); - /* destroy all the elments in the pattern list */ + /* destroy all the elements in the pattern list */ if (ENABLE_FEATURE_CLEAN_UP) { while (pattern_head) { llist_t *pattern_head_ptr = pattern_head; diff --git a/libbb/getopt32.c b/libbb/getopt32.c index 3104826ef..b87b83538 100644 --- a/libbb/getopt32.c +++ b/libbb/getopt32.c @@ -128,7 +128,7 @@ const char *opt_complementary "abc" If groups of two or more chars are specified, the first char is the main option and the other chars are secondary options. Their flags will be turned on if the main option is found even - if they are not specifed on the command line. For example: + if they are not specified on the command line. For example: opt_complementary = "abc"; flags = getopt32(argv, "abcd") diff --git a/libpwdgrp/pwd_grp.c b/libpwdgrp/pwd_grp.c index cefbc8a7e..c9bbc8bda 100644 --- a/libpwdgrp/pwd_grp.c +++ b/libpwdgrp/pwd_grp.c @@ -14,7 +14,7 @@ * exit using the atexit function to make valgrind happy. * 2) the passwd/group files: * a) must contain the expected number of fields (as per count of field - * delimeters ":") or we will complain with a error message. + * delimiters ":") or we will complain with a error message. * b) leading and trailing whitespace in fields is stripped. * c) some fields are not allowed to be empty (e.g. username, uid/gid), * and in this case NULL is returned and errno is set to EINVAL. @@ -149,7 +149,7 @@ static struct statics *get_S(void) /* Internal functions */ /* Divide the passwd/group/shadow record in fields - * by substituting the given delimeter + * by substituting the given delimiter * e.g. ':' or ',' with '\0'. * Returns the number of fields found. * Strips leading and trailing whitespace in fields. diff --git a/loginutils/cryptpw.c b/loginutils/cryptpw.c index 696e169fc..3dc8232e0 100644 --- a/loginutils/cryptpw.c +++ b/loginutils/cryptpw.c @@ -64,7 +64,7 @@ OPTIONS $1$. -R, --rounds=NUMBER Use NUMBER rounds. This argument is ignored if the method - choosen does not support variable rounds. For the OpenBSD Blowfish + chosen does not support variable rounds. For the OpenBSD Blowfish method this is the logarithm of the number of rounds. -m, --method=TYPE Compute the password using the TYPE method. If TYPE is 'help' diff --git a/miscutils/inotifyd.c b/miscutils/inotifyd.c index 601df6465..db8ddce92 100644 --- a/miscutils/inotifyd.c +++ b/miscutils/inotifyd.c @@ -12,7 +12,7 @@ * Use as follows: * # inotifyd /user/space/agent dir/or/file/being/watched[:mask] ... * - * When a filesystem event matching the specified mask is occured on specified file (or directory) + * When a filesystem event matching the specified mask is occurred on specified file (or directory) * a userspace agent is spawned and given the following parameters: * $1. actual event(s) * $2. file (or directory) name diff --git a/miscutils/less.c b/miscutils/less.c index 0b0a9aed4..507e579c4 100644 --- a/miscutils/less.c +++ b/miscutils/less.c @@ -267,7 +267,7 @@ struct globals { /* flines[] are lines read from stdin, each in malloc'ed buffer. * Line numbers are stored as uint32_t prepended to each line. * Pointer is adjusted so that flines[i] points directly past - * line number. Accesor: */ + * line number. Accessor: */ #define MEMPTR(p) ((char*)(p) - 4) #define LINENO(p) (*(uint32_t*)((p) - 4)) diff --git a/miscutils/time.c b/miscutils/time.c index a73a837d8..2be750664 100644 --- a/miscutils/time.c +++ b/miscutils/time.c @@ -397,7 +397,7 @@ static void run_command(char *const *cmd, resource_t *resp) } /* Have signals kill the child but not self (if possible). */ -//TODO: just block all sigs? and reenable them in the very end in main? +//TODO: just block all sigs? and re-enable them in the very end in main? interrupt_signal = signal(SIGINT, SIG_IGN); quit_signal = signal(SIGQUIT, SIG_IGN); diff --git a/modutils/Config.src b/modutils/Config.src index 5f0b0cec4..9b76c83d2 100644 --- a/modutils/Config.src +++ b/modutils/Config.src @@ -75,7 +75,7 @@ config FEATURE_INSMOD_KSYMOOPS_SYMBOLS depends on FEATURE_2_4_MODULES && (INSMOD || MODPROBE) help By adding module symbols to the kernel symbol table, Oops messages - occuring within kernel modules can be properly debugged. By enabling + occurring within kernel modules can be properly debugged. By enabling this feature, module symbols will always be added to the kernel symbol table for proper debugging support. If you are not interested in Oops messages from kernel modules, say N. diff --git a/modutils/modinfo.c b/modutils/modinfo.c index aa641ad54..ead2cf16f 100644 --- a/modutils/modinfo.c +++ b/modutils/modinfo.c @@ -104,7 +104,7 @@ static void modinfo(const char *path, const char *version, char *after_pattern; ptr = memchr(ptr, *pattern, len - (ptr - (char*)the_module)); - if (ptr == NULL) /* no occurance left, done */ + if (ptr == NULL) /* no occurrence left, done */ break; after_pattern = is_prefixed_with(ptr, pattern); if (after_pattern && *after_pattern == '=') { diff --git a/modutils/modprobe-small.c b/modutils/modprobe-small.c index 1285783d0..053a7df89 100644 --- a/modutils/modprobe-small.c +++ b/modutils/modprobe-small.c @@ -169,7 +169,7 @@ static char* find_keyword(char *ptr, size_t len, const char *word) /* search for the first char in word */ ptr = memchr(ptr, word[0], len); - if (ptr == NULL) /* no occurance left, done */ + if (ptr == NULL) /* no occurrence left, done */ break; after_word = is_prefixed_with(ptr, word); if (after_word) @@ -411,7 +411,7 @@ static FAST_FUNC int fileAction(const char *pathname, if (load_module(pathname, module_load_options) == 0) { /* Load was successful, there is nothing else to do. * This can happen ONLY for "top-level" module load, - * not a dep, because deps dont do dirscan. */ + * not a dep, because deps don't do dirscan. */ exit(EXIT_SUCCESS); } } diff --git a/networking/dnsd.c b/networking/dnsd.c index 7be90018d..1b85618c6 100644 --- a/networking/dnsd.c +++ b/networking/dnsd.c @@ -360,7 +360,7 @@ RDATA a variable length string of octets that describes the resource. In order to reduce the size of messages, domain names coan be compressed. An entire domain name or a list of labels at the end of a domain name -is replaced with a pointer to a prior occurance of the same name. +is replaced with a pointer to a prior occurrence of the same name. The pointer takes the form of a two octet sequence: +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ diff --git a/networking/ifenslave.c b/networking/ifenslave.c index 1cb765e23..070931209 100644 --- a/networking/ifenslave.c +++ b/networking/ifenslave.c @@ -55,7 +55,7 @@ * * - 2003/03/18 - Tsippy Mendelson and * Shmulik Hen - * - Moved setting the slave's mac address and openning it, from + * - Moved setting the slave's mac address and opening it, from * the application to the driver. This enables support of modes * that need to use the unique mac address of each slave. * The driver also takes care of closing the slave and restoring its diff --git a/networking/isrv.c b/networking/isrv.c index 3673db715..97f5c6d4e 100644 --- a/networking/isrv.c +++ b/networking/isrv.c @@ -191,7 +191,7 @@ static void handle_accept(isrv_state_t *state, int fd) DPRINTF("new_peer(%d)", newfd); n = state->new_peer(state, newfd); if (n) - remove_peer(state, n); /* unsuccesful peer start */ + remove_peer(state, n); /* unsuccessful peer start */ } static void handle_fd_set(isrv_state_t *state, fd_set *fds, int (*h)(int, void **)) diff --git a/networking/nc_bloaty.c b/networking/nc_bloaty.c index f8c375362..3db784982 100644 --- a/networking/nc_bloaty.c +++ b/networking/nc_bloaty.c @@ -459,7 +459,7 @@ create new one, and bind() it. TODO */ so I don't feel bad. The *real* question is why BFD sockets wasn't designed to allow listens for connections *from* specific hosts/ports, instead of requiring the caller to - accept the connection and then reject undesireable ones by closing. + accept the connection and then reject undesirable ones by closing. In other words, we need a TCP MSG_PEEK. */ /* bbox: removed most of it */ lcladdr = xmalloc_sockaddr2dotted(&ouraddr->u.sa); @@ -502,7 +502,7 @@ static int udptest(void) /* use the tcp-ping trick: try connecting to a normally refused port, which causes us to block for the time that SYN gets there and RST gets back. Not completely reliable, but it *does* mostly work. */ - /* Set a temporary connect timeout, so packet filtration doesnt cause + /* Set a temporary connect timeout, so packet filtration doesn't cause us to hang forever, and hit it */ o_wait = 5; /* enough that we'll notice?? */ rr = xsocket(ouraddr->u.sa.sa_family, SOCK_STREAM, 0); diff --git a/networking/ntpd.c b/networking/ntpd.c index 5cc71ca7a..73d27ac20 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c @@ -393,7 +393,7 @@ struct globals { * too big and we will step. I observed it with -6. * * OTOH, setting precision_sec far too small would result in futile - * attempts to syncronize to an unachievable precision. + * attempts to synchronize to an unachievable precision. * * -6 is 1/64 sec, -7 is 1/128 sec and so on. * -8 is 1/256 ~= 0.003906 (worked well for me --vda) @@ -754,7 +754,7 @@ reset_peer_stats(peer_t *p, double offset) bool small_ofs = fabs(offset) < STEP_THRESHOLD; /* Used to set p->filter_datapoint[i].d_dispersion = MAXDISP - * and clear reachable bits, but this proved to be too agressive: + * and clear reachable bits, but this proved to be too aggressive: * after step (tested with suspending laptop for ~30 secs), * this caused all previous data to be considered invalid, * making us needing to collect full ~8 datapoints per peer @@ -1715,7 +1715,7 @@ update_local_clock(peer_t *p) * It looks like Linux kernel's PLL is far too gentle in changing * tmx.freq in response to clock offset. Offset keeps growing * and eventually we fall back to smaller poll intervals. - * We can make correction more agressive (about x2) by supplying + * We can make correction more aggressive (about x2) by supplying * PLL time constant which is one less than the real one. * To be on a safe side, let's do it only if offset is significantly * larger than jitter. diff --git a/networking/ping.c b/networking/ping.c index ef31e000b..94fb007f5 100644 --- a/networking/ping.c +++ b/networking/ping.c @@ -478,7 +478,7 @@ static void sendping_tail(void (*sp)(int), int size_pkt) } else { /* -c NN, and all NN are sent (and no deadline) */ /* Wait for the last ping to come back. * -W timeout: wait for a response in seconds. - * Affects only timeout in absense of any responses, + * Affects only timeout in absence of any responses, * otherwise ping waits for two RTTs. */ unsigned expire = timeout; @@ -712,7 +712,7 @@ static void ping4(len_and_sockaddr *lsa) if (opt_ttl != 0) { setsockopt_int(pingsock, IPPROTO_IP, IP_TTL, opt_ttl); - /* above doesnt affect packets sent to bcast IP, so... */ + /* above doesn't affect packets sent to bcast IP, so... */ setsockopt_int(pingsock, IPPROTO_IP, IP_MULTICAST_TTL, opt_ttl); } diff --git a/networking/tcpudp.c b/networking/tcpudp.c index 3a6c68646..3ebe7d5fc 100644 --- a/networking/tcpudp.c +++ b/networking/tcpudp.c @@ -683,7 +683,7 @@ prog -E no special environment. Do not set up TCP-related environment variables. -v - verbose. Print verbose messsages to standard output. + verbose. Print verbose messages to standard output. -vv more verbose. Print more verbose messages to standard output. * no difference between -v and -vv in busyboxed version diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 881512cf3..c45a0af1a 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -1460,7 +1460,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) already_waited_sec += (unsigned)monotonic_sec() - timestamp_before_wait; continue; } - /* Else: an error occured, panic! */ + /* Else: an error occurred, panic! */ bb_perror_msg_and_die("select"); } } diff --git a/networking/udhcp/dhcprelay.c b/networking/udhcp/dhcprelay.c index 7cb19b14e..ea84c0dd7 100644 --- a/networking/udhcp/dhcprelay.c +++ b/networking/udhcp/dhcprelay.c @@ -361,7 +361,7 @@ int dhcprelay_main(int argc, char **argv) // which the reply must be sent (i.e., the host or router interface // connected to the same network as the BOOTP client). If the content // of the 'giaddr' field does not match one of the relay agent's -// directly-connected logical interfaces, the BOOTREPLY messsage MUST be +// directly-connected logical interfaces, the BOOTREPLY message MUST be // silently discarded. if (udhcp_read_interface(iface_list[i], NULL, &dhcp_msg.gateway_nip, NULL)) { /* Fall back to our IP on server iface */ diff --git a/networking/vconfig.c b/networking/vconfig.c index f3020409a..854eca0a1 100644 --- a/networking/vconfig.c +++ b/networking/vconfig.c @@ -138,7 +138,7 @@ int vconfig_main(int argc, char **argv) /* I suppose one could try to combine some of the function calls below, * since ifr.u.flag, ifr.u.VID, and ifr.u.skb_priority are all same-sized * (unsigned) int members of a unions. But because of the range checking, - * doing so wouldn't save that much space and would also make maintainence + * doing so wouldn't save that much space and would also make maintenance * more of a pain. */ if (ifr.cmd == SET_VLAN_FLAG_CMD) { diff --git a/shell/ash.c b/shell/ash.c index e170bec2a..70ee15ed8 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -3849,7 +3849,7 @@ setjobctl(int on) } /* fd is a tty at this point */ fd = fcntl(fd, F_DUPFD, 10); - if (ofd >= 0) /* if it is "/dev/tty", close. If 0/1/2, dont */ + if (ofd >= 0) /* if it is "/dev/tty", close. If 0/1/2, don't */ close(ofd); if (fd < 0) goto out; /* F_DUPFD failed */ @@ -6310,7 +6310,7 @@ static char *evalvar(char *p, int flags, struct strlist *var_str_list); * $@ like $* since no splitting will be performed. * * var_str_list (can be NULL) is a list of "VAR=val" strings which take precedence - * over shell varables. Needed for "A=a B=$A; echo $B" case - we use it + * over shell variables. Needed for "A=a B=$A; echo $B" case - we use it * for correct expansion of "B=$A" word. */ static void @@ -6520,8 +6520,8 @@ scanright(char *startp, char *rmesc, char *rmescend, if (try2optimize) { /* Maybe we can optimize this: * if pattern ends with unescaped *, we can avoid checking - * shorter strings: if "foo*" doesnt match "raw_value_of_v", - * it wont match truncated "raw_value_of_" strings too. + * shorter strings: if "foo*" doesn't match "raw_value_of_v", + * it won't match truncated "raw_value_of_" strings too. */ unsigned plen = strlen(pattern); /* Does it end with "*"? */ @@ -7248,7 +7248,7 @@ expandmeta(struct strlist *str /*, int flag*/) // Which means you need to unescape the string, right? Not so fast: // if there _is_ a file named "file\?" (with backslash), it is returned // as "file\?" too (whichever pattern you used to find it, say, "file*"). -// You DONT KNOW by looking at the result whether you need to unescape it. +// You DON'T KNOW by looking at the result whether you need to unescape it. // // Worse, globbing of "file\?" in a directory with two files, "file?" and "file\?", // returns "file\?" - which is WRONG: "file\?" pattern matches "file?" file. @@ -13088,7 +13088,7 @@ exportcmd(int argc UNUSED_PARAM, char **argv) } flag_off = ~flag_off; - /*if (opt_p_not_specified) - bash doesnt check this. Try "export -p NAME" */ + /*if (opt_p_not_specified) - bash doesn't check this. Try "export -p NAME" */ { aptr = argptr; name = *aptr; diff --git a/shell/ash_test/ash-misc/unicode1.tests b/shell/ash_test/ash-misc/unicode1.tests index 8788ba910..b8479cb41 100755 --- a/shell/ash_test/ash-misc/unicode1.tests +++ b/shell/ash_test/ash-misc/unicode1.tests @@ -5,7 +5,7 @@ a=`printf "\xcc\x80"` # Should print 1 echo ${#a} -# A Japanese katakana charachter U+30a3 +# A Japanese katakana character U+30a3 a=`printf "\xe3\x82\xa3"` # Should print 1 echo ${#a} diff --git a/shell/hush.c b/shell/hush.c index 4123cc19e..e18920f50 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -1908,7 +1908,7 @@ static int check_and_run_traps(void) G.count_SIGCHLD++; //bb_error_msg("[%d] check_and_run_traps: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD); /* Note: - * We dont do 'last_sig = sig' here -> NOT returning this sig. + * We don't do 'last_sig = sig' here -> NOT returning this sig. * This simplifies wait builtin a bit. */ break; @@ -1917,7 +1917,7 @@ static int check_and_run_traps(void) debug_printf_exec("%s: sig:%d default handling is to ignore\n", __func__, sig); /* SIGTERM, SIGQUIT, SIGTTIN, SIGTTOU, SIGTSTP */ /* Note: - * We dont do 'last_sig = sig' here -> NOT returning this sig. + * We don't do 'last_sig = sig' here -> NOT returning this sig. * Example: wait is not interrupted by TERM * in interactive shell, because TERM is ignored. */ @@ -2280,7 +2280,7 @@ static void reinit_unicode_for_hush(void) * AT\ * H\ * \ - * It excercises a lot of corner cases. + * It exercises a lot of corner cases. */ static void cmdedit_update_prompt(void) { @@ -5235,7 +5235,7 @@ static void o_addblock_duplicate_backslash(o_string *o, const char *str, int len /* And now we want to add { or } and continue: * o_addchr(o, c); * continue; - * luckily, just falling throught achieves this. + * luckily, just falling through achieves this. */ } #endif @@ -5830,7 +5830,7 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg) arg++; /* Can't just stuff it into output o_string, * expanded result may need to be globbed - * and $IFS-splitted */ + * and $IFS-split */ debug_printf_subst("SUBST '%s' first_ch %x\n", arg, first_ch); G.last_exitcode = process_command_subs(&subst_result, arg); debug_printf_subst("SUBST RES:%d '%s'\n", G.last_exitcode, subst_result.data); @@ -7320,7 +7320,7 @@ static int process_wait_result(struct pipe *fg_pipe, pid_t childpid, int status) /* There are still running processes in the fg_pipe */ return -1; } - /* It wasnt in fg_pipe, look for process in bg pipes */ + /* It wasn't in fg_pipe, look for process in bg pipes */ } #if ENABLE_HUSH_JOB diff --git a/shell/hush_test/hush-misc/unicode1.tests b/shell/hush_test/hush-misc/unicode1.tests index 8788ba910..b8479cb41 100755 --- a/shell/hush_test/hush-misc/unicode1.tests +++ b/shell/hush_test/hush-misc/unicode1.tests @@ -5,7 +5,7 @@ a=`printf "\xcc\x80"` # Should print 1 echo ${#a} -# A Japanese katakana charachter U+30a3 +# A Japanese katakana character U+30a3 a=`printf "\xe3\x82\xa3"` # Should print 1 echo ${#a} diff --git a/sysklogd/logread.c b/sysklogd/logread.c index 1f0c6252d..71459941e 100644 --- a/sysklogd/logread.c +++ b/sysklogd/logread.c @@ -24,7 +24,7 @@ //config: default y //config: depends on LOGREAD //config: help -//config: 'logread' ouput to slow serial terminals can have +//config: 'logread' output to slow serial terminals can have //config: side effects on syslog because of the semaphore. //config: This option make logread to double buffer copy //config: from circular buffer, minimizing semaphore @@ -159,7 +159,7 @@ int logread_main(int argc UNUSED_PARAM, char **argv) cur, shbuf_tail, shbuf_size); if (!(follow & 1)) { /* not -f */ - /* if -F, "convert" it to -f, so that we dont + /* if -F, "convert" it to -f, so that we don't * dump the entire buffer on each iteration */ follow >>= 1; diff --git a/testsuite/readlink.tests b/testsuite/readlink.tests index e9d8da0fc..27b52f6c4 100755 --- a/testsuite/readlink.tests +++ b/testsuite/readlink.tests @@ -29,7 +29,7 @@ pwd=`$pwd` testing "readlink -f on a file" "readlink -f ./$TESTFILE" "$pwd/$TESTFILE\n" "" "" testing "readlink -f on a link" "readlink -f ./$TESTLINK" "$pwd/$TESTFILE\n" "" "" testing "readlink -f on an invalid link" "readlink -f ./$FAILLINK" "" "" "" -testing "readlink -f on a wierd dir" "readlink -f $TESTDIR/../$TESTFILE" "$pwd/$TESTFILE\n" "" "" +testing "readlink -f on a weird dir" "readlink -f $TESTDIR/../$TESTFILE" "$pwd/$TESTFILE\n" "" "" # clean up diff --git a/util-linux/cal.c b/util-linux/cal.c index af02608f0..8196619b0 100644 --- a/util-linux/cal.c +++ b/util-linux/cal.c @@ -35,7 +35,7 @@ #include "libbb.h" #include "unicode.h" -/* We often use "unsigned" intead of "int", it's easier to div on most CPUs */ +/* We often use "unsigned" instead of "int", it's easier to div on most CPUs */ #define THURSDAY 4 /* for reformation */ #define SATURDAY 6 /* 1 Jan 1 was a Saturday */ diff --git a/util-linux/hwclock.c b/util-linux/hwclock.c index d65011a71..8cb908cb3 100644 --- a/util-linux/hwclock.c +++ b/util-linux/hwclock.c @@ -167,7 +167,7 @@ static void from_sys_clock(const char **pp_rtcname, int utc) * On x86, even though code does set hw clock within <1ms of exact * whole seconds, apparently hw clock (at least on some machines) * doesn't reset internal fractional seconds to 0, - * making all this a pointless excercise. + * making all this a pointless exercise. */ /* If we see that we are N usec away from whole second, * we'll sleep for N-ADJ usecs. ADJ corrects for the fact diff --git a/util-linux/renice.c b/util-linux/renice.c index 64213c680..4da3394a8 100644 --- a/util-linux/renice.c +++ b/util-linux/renice.c @@ -141,7 +141,7 @@ int renice_main(int argc UNUSED_PARAM, char **argv) retval = EXIT_FAILURE; } - /* No need to check for errors outputing to stderr since, if it + /* No need to check for errors outputting to stderr since, if it * was used, the HAD_ERROR label was reached and retval was set. */ return retval; diff --git a/util-linux/switch_root.c b/util-linux/switch_root.c index aaee35a3e..f18e8a5ce 100644 --- a/util-linux/switch_root.c +++ b/util-linux/switch_root.c @@ -183,7 +183,7 @@ So there's a step that needs to be sort of atomic but can't be as a shell script. (You can work around this with static linking or very carefully laid out paths and sequencing, but it's brittle, ugly, and non-obvious.) -2) The "find | rm" bit will acually delete everything because the mount points +2) The "find | rm" bit will actually delete everything because the mount points still show up (even if their contents don't), and rm -rf will then happily zap that. So the first line is an oversimplification of what you need to do _not_ to descend into other filesystems and delete their contents. diff --git a/util-linux/volume_id/udf.c b/util-linux/volume_id/udf.c index 613c80c86..fa5dccee7 100644 --- a/util-linux/volume_id/udf.c +++ b/util-linux/volume_id/udf.c @@ -137,7 +137,7 @@ anchor: if (type != 2) /* TAG_ID_AVDP */ goto found; - /* get desriptor list address and block count */ + /* get descriptor list address and block count */ count = le32_to_cpu(vd->type.anchor.length) / bs; loc = le32_to_cpu(vd->type.anchor.location); dbg("0x%x descriptors starting at logical secor 0x%x", count, loc); -- cgit v1.2.3-55-g6feb From 9c7ee1439aded3f72fb314b516c0eb488076c179 Mon Sep 17 00:00:00 2001 From: Markus Gothe Date: Tue, 18 Apr 2017 19:25:49 +0200 Subject: lsscsi: new applet function old new delta lsscsi_main - 326 +326 applet_names 2613 2620 +7 applet_main 1512 1516 +4 applet_install_loc 189 190 +1 packed_usage 31566 31560 -6 ------------------------------------------------------------------------------ (add/remove: 2/0 grow/shrink: 3/1 up/down: 338/-6) Total: 332 bytes Signed-off-by: Markus Gothe Signed-off-by: Denys Vlasenko --- miscutils/lsscsi.c | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 miscutils/lsscsi.c (limited to 'miscutils') diff --git a/miscutils/lsscsi.c b/miscutils/lsscsi.c new file mode 100644 index 000000000..1521680ac --- /dev/null +++ b/miscutils/lsscsi.c @@ -0,0 +1,123 @@ +/* vi: set sw=4 ts=4: */ +/* + * lsscsi implementation for busybox + * + * Copyright (C) 2017 Markus Gothe + * + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + */ +//config:config LSSCSI +//config: bool "lsscsi" +//config: default y +//config: #select PLATFORM_LINUX +//config: help +//config: lsscsi is a utility for displaying information about SCSI buses in the +//config: system and devices connected to them. +//config: +//config: This version uses sysfs (/sys/bus/scsi/devices) only. + +//applet:IF_LSSCSI(APPLET(lsscsi, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_LSSCSI) += lsscsi.o + +//usage:#define lsscsi_trivial_usage NOUSAGE_STR +//usage:#define lsscsi_full_usage "" + +#include "libbb.h" + +static char *get_line(const char *filename, char *buf, unsigned *bufsize_p) +{ + unsigned bufsize = *bufsize_p; + ssize_t sz; + + if ((int)(bufsize - 2) <= 0) + return buf; + + sz = open_read_close(filename, buf, bufsize - 2); + if (sz < 0) + sz = 0; + buf[sz] = '\0'; + trim(buf); + + sz = strlen(buf) + 1; + bufsize -= sz; + buf += sz; + buf[0] = '\0'; + + *bufsize_p = bufsize; + return buf; +} + +int lsscsi_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int lsscsi_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) +{ + struct dirent *de; + DIR *dir; + + xchdir("/sys/bus/scsi/devices"); + + dir = xopendir("."); + while ((de = readdir(dir)) != NULL) { + char buf[256]; + char *ptr; + unsigned bufsize; + const char *vendor; + const char *type_str; + const char *type_name; + const char *model; + const char *rev; + unsigned type; + + if (!isdigit(de->d_name[0])) + continue; + if (!strchr(de->d_name, ':')) + continue; + if (chdir(de->d_name) != 0) + continue; + + bufsize = sizeof(buf); + vendor = buf; + ptr = get_line("vendor", buf, &bufsize); + type_str = ptr; + ptr = get_line("type", ptr, &bufsize); + model = ptr; + ptr = get_line("model", ptr, &bufsize); + rev = ptr; + ptr = get_line("rev", ptr, &bufsize); + + printf("[%s]\t", de->d_name); + +#define scsi_device_types \ + "disk\0" "tape\0" "printer\0" "process\0" \ + "worm\0" "\0" "scanner\0" "optical\0" \ + "mediumx\0" "comms\0" "\0" "\0" \ + "storage\0" "enclosu\0" "sim dsk\0" "opti rd\0" \ + "bridge\0" "osd\0" "adi\0" "\0" \ + "\0" "\0" "\0" "\0" \ + "\0" "\0" "\0" "\0" \ + "\0" "\0" "wlun\0" "no dev" + type = bb_strtou(type_str, NULL, 10); + if (errno + || type >= 0x20 + || (type_name = nth_string(scsi_device_types, type))[0] == '\0' + ) { + printf("(%s)\t", type_str); + } else { + printf("%s\t", type_name); + } + + printf("%s\t""%s\t""%s\n", + vendor, + model, + rev + ); + /* TODO: also output device column, e.g. "/dev/sdX" */ + + xchdir(".."); + } + + if (ENABLE_FEATURE_CLEAN_UP) + closedir(dir); + + return EXIT_SUCCESS; +} -- cgit v1.2.3-55-g6feb From 854174f7ddc21350c0dbf826c76400910b33806c Mon Sep 17 00:00:00 2001 From: Tommi Rantala Date: Mon, 24 Apr 2017 19:08:53 +0300 Subject: time: document -p in usage Signed-off-by: Tommi Rantala Signed-off-by: Denys Vlasenko --- miscutils/time.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'miscutils') diff --git a/miscutils/time.c b/miscutils/time.c index 2be750664..7c457a91a 100644 --- a/miscutils/time.c +++ b/miscutils/time.c @@ -21,10 +21,11 @@ //kbuild:lib-$(CONFIG_TIME) += time.o //usage:#define time_trivial_usage -//usage: "[-v] PROG ARGS" +//usage: "[-vp] PROG ARGS" //usage:#define time_full_usage "\n\n" //usage: "Run PROG, display resource usage when it exits\n" //usage: "\n -v Verbose" +//usage: "\n -p POSIX output format" #include "libbb.h" #include /* getrusage */ -- cgit v1.2.3-55-g6feb From 5fe5be210c7d22c94f07036d4933dae0b2010286 Mon Sep 17 00:00:00 2001 From: Tommi Rantala Date: Fri, 28 Apr 2017 17:54:14 +0200 Subject: time: implement -a, -o FILE function old new delta time_main 1052 1076 +24 packed_usage 31571 31577 +6 Signed-off-by: Tommi Rantala Signed-off-by: Denys Vlasenko --- miscutils/time.c | 41 +++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) (limited to 'miscutils') diff --git a/miscutils/time.c b/miscutils/time.c index 7c457a91a..dd0c0208a 100644 --- a/miscutils/time.c +++ b/miscutils/time.c @@ -21,11 +21,13 @@ //kbuild:lib-$(CONFIG_TIME) += time.o //usage:#define time_trivial_usage -//usage: "[-vp] PROG ARGS" +//usage: "[-vpa] [-o FILE] PROG ARGS" //usage:#define time_full_usage "\n\n" //usage: "Run PROG, display resource usage when it exits\n" //usage: "\n -v Verbose" //usage: "\n -p POSIX output format" +//usage: "\n -o FILE Write result to FILE" +//usage: "\n -a Append (else overwrite)" #include "libbb.h" #include /* getrusage */ @@ -414,28 +416,47 @@ int time_main(int argc UNUSED_PARAM, char **argv) { resource_t res; const char *output_format = default_format; + char *output_filename; + int output_fd; int opt; + int ex; + enum { + OPT_v = (1 << 0), + OPT_p = (1 << 1), + OPT_a = (1 << 2), + OPT_o = (1 << 3), + }; opt_complementary = "-1"; /* at least one arg */ /* "+": stop on first non-option */ - opt = getopt32(argv, "+vp"); + opt = getopt32(argv, "+vpao:", &output_filename); argv += optind; - if (opt & 1) + if (opt & OPT_v) output_format = long_format; - if (opt & 2) + if (opt & OPT_p) output_format = posix_format; + output_fd = STDERR_FILENO; + if (opt & OPT_o) { + output_fd = xopen(output_filename, + (opt & OPT_a) /* append? */ + ? (O_CREAT | O_WRONLY | O_CLOEXEC | O_APPEND) + : (O_CREAT | O_WRONLY | O_CLOEXEC | O_TRUNC) + ); + } run_command(argv, &res); /* Cheat. printf's are shorter :) */ - xdup2(STDERR_FILENO, STDOUT_FILENO); + xdup2(output_fd, STDOUT_FILENO); summarize(output_format, argv, &res); + ex = WEXITSTATUS(res.waitstatus); + /* Impossible: we do not use WUNTRACED flag in wait()... if (WIFSTOPPED(res.waitstatus)) - return WSTOPSIG(res.waitstatus); + ex = 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); + ex = WTERMSIG(res.waitstatus); + + fflush_stdout_and_exit(ex); } -- cgit v1.2.3-55-g6feb From a1a3b595e1c96c3568818d019864bb23cd33e673 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 28 Apr 2017 18:01:18 +0200 Subject: time: inplement -f FMT function old new delta time_main 1076 1134 +58 packed_usage 31577 31572 -5 Signed-off-by: Denys Vlasenko --- miscutils/time.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'miscutils') diff --git a/miscutils/time.c b/miscutils/time.c index dd0c0208a..e377bb6b7 100644 --- a/miscutils/time.c +++ b/miscutils/time.c @@ -26,6 +26,7 @@ //usage: "Run PROG, display resource usage when it exits\n" //usage: "\n -v Verbose" //usage: "\n -p POSIX output format" +//usage: "\n -f FMT Custom format" //usage: "\n -o FILE Write result to FILE" //usage: "\n -a Append (else overwrite)" @@ -415,7 +416,8 @@ int time_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int time_main(int argc UNUSED_PARAM, char **argv) { resource_t res; - const char *output_format = default_format; + /* $TIME has lowest prio (-v,-p,-f FMT overrride it) */ + const char *output_format = getenv("TIME") ? : default_format; char *output_filename; int output_fd; int opt; @@ -425,11 +427,12 @@ int time_main(int argc UNUSED_PARAM, char **argv) OPT_p = (1 << 1), OPT_a = (1 << 2), OPT_o = (1 << 3), + OPT_f = (1 << 4), }; opt_complementary = "-1"; /* at least one arg */ /* "+": stop on first non-option */ - opt = getopt32(argv, "+vpao:", &output_filename); + opt = getopt32(argv, "+vpao:f:", &output_filename, &output_format); argv += optind; if (opt & OPT_v) output_format = long_format; -- cgit v1.2.3-55-g6feb