Wrote killall.
authorErik Andersen <andersen@codepoet.org>
Tue, 7 Mar 2000 07:41:42 +0000 (07:41 -0000)
committerErik Andersen <andersen@codepoet.org>
Tue, 7 Mar 2000 07:41:42 +0000 (07:41 -0000)
Adjusted mount, ps, utility.c, etc to handle my nifty new kernel
patches the allow busybox to run perfectly without /proc.
 -Erik

19 files changed:
Changelog
applets/busybox.c
busybox.c
busybox.def.h
chmod_chown_chgrp.c
halt.c
init/halt.c
init/poweroff.c
init/reboot.c
internal.h
kill.c
mount.c
poweroff.c
procps/kill.c
procps/ps.c
ps.c
reboot.c
util-linux/mount.c
utility.c

index f0c5e2f..fd560a8 100644 (file)
--- a/Changelog
+++ b/Changelog
@@ -1,5 +1,5 @@
 0.43
-       * Wrote basename, and uptime.
+       * Wrote basename, killall, and uptime.
        * Added freeramdisk, which will free up all memory associated
            with a ram disk.  Contributed by Emanuele Caratti <wiz@iol.it>
            and then adjusted a bit by me.
@@ -35,8 +35,8 @@
            - Fixes to the makefile for handling "strip"
        * An initial telnet implementation was added by 
            Randolph Chung <tausq@debian.org>.
-       * Fixed a bug where "sed 's/foo/bar/g'" would go into an 
-           infinite loop.
+       * Fixed a bug where "sed 's/foo/bar/g'" (i.e. a script w/o a "-e")
+           would go into an infinite loop.
 
 
        -Erik Andersen
index 36cf0a0..cea191c 100644 (file)
@@ -139,6 +139,9 @@ static const struct Applet applets[] = {
 #ifdef BB_KILL                                 //bin
        {"kill", kill_main},
 #endif
+#ifdef BB_KILLALL                              //usr/bin
+       {"killall", kill_main},
+#endif
 #ifdef BB_LENGTH                               //usr/bin
        {"length", length_main},
 #endif
index 36cf0a0..cea191c 100644 (file)
--- a/busybox.c
+++ b/busybox.c
@@ -139,6 +139,9 @@ static const struct Applet applets[] = {
 #ifdef BB_KILL                                 //bin
        {"kill", kill_main},
 #endif
+#ifdef BB_KILLALL                              //usr/bin
+       {"killall", kill_main},
+#endif
 #ifdef BB_LENGTH                               //usr/bin
        {"length", length_main},
 #endif
index 306133b..da34055 100644 (file)
@@ -39,6 +39,7 @@
 // Don't turn BB_INSMOD on.  It doesn't work.
 //#define BB_INSMOD
 #define BB_KILL
+#define BB_KILLALL
 #define BB_KLOGD
 //#define BB_LENGTH
 #define BB_LN
 // pretty/useful).
 //
 //
+// Turn this on to use Erik's very cool devps, devmtab, 
+// etc. kernel drivers, thereby eliminating the need for 
+// the /proc filesystem and thereby saving lots and lots 
+// memory for more important things.
+// You can't use this and USE_PROCFS at the same time...
+//#define BB_FEATURE_USE_DEVPS_N_DEVMTAB
+//
+//
 // enable features that use the /proc filesystem (apps that 
 // break without this will tell you on compile)...
+// You can't use this and DEVPS_N_DEVMTAB at the same time...
 #define BB_FEATURE_USE_PROCFS
 //
 // Use termios to manipulate the screen ('more' is prettier with this on)
 // just like an initrd does.  Requires a kernel patch by Werner Almesberger. 
 // ftp://icaftp.epfl.ch/pub/people/almesber/misc/umount-root-*.tar.gz
 #ifdef BB_MOUNT
-#define BB_FEATURE_INIT_CHROOT
+//#define BB_FEATURE_INIT_CHROOT
 #endif
 //
index 4e5e9b0..e197ee3 100644 (file)
@@ -98,13 +98,11 @@ int chmod_chown_chgrp_main(int argc, char **argv)
        char *p;
        const char *appUsage;
 
-       whichApp =
-               (strcmp(*argv, "chown") == 0)? 
+       whichApp = (strcmp(*argv, "chown") == 0)? 
                        CHOWN_APP : (strcmp(*argv, "chmod") == 0)? 
                                CHMOD_APP : CHGRP_APP;
 
-       appUsage =
-               (whichApp == CHOWN_APP)? 
+       appUsage = (whichApp == CHOWN_APP)? 
                        chown_usage : (whichApp == CHMOD_APP) ? chmod_usage : chgrp_usage;
 
        if (argc < 2)
diff --git a/halt.c b/halt.c
index d61c387..f2c9828 100644 (file)
--- a/halt.c
+++ b/halt.c
@@ -27,5 +27,5 @@
 extern int halt_main(int argc, char **argv)
 {
        /* don't assume init's pid == 1 */
-       exit(kill(findInitPid(), SIGUSR1));
+       exit(kill(findPidByName("init"), SIGUSR1));
 }
index d61c387..f2c9828 100644 (file)
@@ -27,5 +27,5 @@
 extern int halt_main(int argc, char **argv)
 {
        /* don't assume init's pid == 1 */
-       exit(kill(findInitPid(), SIGUSR1));
+       exit(kill(findPidByName("init"), SIGUSR1));
 }
index 7f9abf1..14dc2f5 100644 (file)
@@ -27,5 +27,5 @@
 extern int poweroff_main(int argc, char **argv)
 {
        /* don't assume init's pid == 1 */
-       exit(kill(findInitPid(), SIGUSR2));
+       exit(kill(findPidByName("init"), SIGUSR2));
 }
index f782fa1..fc01ea0 100644 (file)
@@ -27,7 +27,7 @@
 extern int reboot_main(int argc, char **argv)
 {
        /* don't assume init's pid == 1 */
-       exit(kill(findInitPid(), SIGINT));
+       exit(kill(findPidByName("init"), SIGINT));
 }
 
 /*
index fcb24dc..2e2556d 100644 (file)
@@ -203,7 +203,7 @@ extern char *mtab_next(void **iter);
 extern char *mtab_getinfo(const char *match, const char which);
 extern int check_wildcard_match(const char* text, const char* pattern);
 extern long getNum (const char *cp);
-extern pid_t findInitPid();
+extern pid_t findPidByName( char* pidName);
 extern void *xmalloc (size_t size);
 #if defined BB_INIT || defined BB_SYSLOGD
 extern int device_open(char *device, int mode);
diff --git a/kill.c b/kill.c
index 5166212..8a99e0f 100644 (file)
--- a/kill.c
+++ b/kill.c
@@ -24,6 +24,7 @@
 #include "internal.h"
 #include <stdio.h>
 #include <stdlib.h>
+#include <errno.h>
 #include <unistd.h>
 #include <signal.h>
 #include <ctype.h>
@@ -35,6 +36,14 @@ static const char *kill_usage =
        "Send a signal (default is SIGTERM) to the specified process(es).\n\n"
        "Options:\n" "\t-l\tList all signal names and numbers.\n\n";
 
+static const char *killall_usage =
+       "killall [-signal] process-name [process-name ...]\n\n"
+       "Send a signal (default is SIGTERM) to the specified process(es).\n\n"
+       "Options:\n" "\t-l\tList all signal names and numbers.\n\n";
+
+
+#define KILL   0
+#define KILLALL        1
 
 struct signal_name {
        const char *name;
@@ -120,13 +129,19 @@ const struct signal_name signames[] = {
 
 extern int kill_main(int argc, char **argv)
 {
-       int sig = SIGTERM;
+       int whichApp, sig = SIGTERM;
+       const char *appUsage;
+
+       /* Figure out what we are trying to do here */
+       whichApp = (strcmp(*argv, "killall") == 0)? 
+               KILLALL : KILL; 
+       appUsage = (whichApp == KILLALL)?  killall_usage : kill_usage;
 
        argc--;
        argv++;
        /* Parse any options */
        if (argc < 1)
-               usage(kill_usage);
+               usage(appUsage);
 
        while (argc > 0 && **argv == '-') {
                while (*++(*argv)) {
@@ -150,7 +165,7 @@ extern int kill_main(int argc, char **argv)
                                }
                                break;
                        case '-':
-                               usage(kill_usage);
+                               usage(appUsage);
                        default:
                                {
                                        if (isdigit(**argv)) {
@@ -186,32 +201,34 @@ extern int kill_main(int argc, char **argv)
 
   do_it_now:
 
-       while (--argc >= 0) {
-               int pid;
-               struct stat statbuf;
-               char pidpath[20] = "/proc/";
+       if (whichApp == KILL) {
+               /* Looks like they want to do a kill. Do that */
+               while (--argc >= 0) {
+                       int pid;
 
-               if (!isdigit(**argv)) {
-                       fprintf(stderr, "bad PID: %s\n", *argv);
-                       exit(FALSE);
-               }
-               pid = atoi(*argv);
-               snprintf(pidpath, 20, "/proc/%s/stat", *argv);
-               if (stat(pidpath, &statbuf) != 0) {
-                       fprintf(stderr, "kill: (%d) - No such pid\n", pid);
-                       exit(FALSE);
+                       if (!isdigit(**argv))
+                               fatalError( "Bad PID: %s\n", strerror(errno));
+                       pid = strtol(*argv, NULL, 0);
+                       if (kill(pid, sig) != 0) 
+                               fatalError( "Could not kill pid '%d': %s\n", pid, strerror(errno));
+                       argv++;
                }
-               fprintf(stderr, "sig = %d\n", sig);
-               if (kill(pid, sig) != 0) {
-                       perror(*argv);
-                       exit(FALSE);
+       } else {
+               /* Looks like they want to do a killall.  Do that */
+               while (--argc >= 0) {
+                       int pid;
+
+                       while((pid = findPidByName( *argv))) {
+                               if (kill(pid, sig) != 0) 
+                                       fatalError( "Could not kill pid '%d': %s\n", pid, strerror(errno));
+                       }
+                       argv++;
                }
-               argv++;
        }
+
        exit(TRUE);
 
 
   end:
-       fprintf(stderr, "bad signal name: %s\n", *argv);
-       exit(TRUE);
+       fatalError( "bad signal name: %s\n", *argv);
 }
diff --git a/mount.c b/mount.c
index 37f789d..f46664b 100644 (file)
--- a/mount.c
+++ b/mount.c
 #include <sys/mount.h>
 #include <ctype.h>
 #include <fstab.h>
+#if defined BB_FEATURE_USE_DEVPS_N_DEVMTAB
+#include <linux/devmtab.h>
+#endif
+
 
 #if defined BB_FEATURE_MOUNT_LOOP
 #include <fcntl.h>
@@ -221,9 +225,8 @@ mount_one(char *blockDevice, char *directory, char *filesystemType,
 {
        int status = 0;
 
-       char buf[255];
-
 #if defined BB_FEATURE_USE_PROCFS
+       char buf[255];
        if (strcmp(filesystemType, "auto") == 0) {
                FILE *f = fopen("/proc/filesystems", "r");
 
@@ -252,6 +255,43 @@ mount_one(char *blockDevice, char *directory, char *filesystemType,
                fclose(f);
        } else
 #endif
+#if defined BB_FEATURE_USE_DEVPS_N_DEVMTAB
+       if (strcmp(filesystemType, "auto") == 0) {
+               int fd, i, numfilesystems;
+               char device[] = "/dev/mtab";
+               struct k_fstype *fslist;
+
+               /* open device */ 
+               fd = open(device, O_RDONLY);
+               if (fd < 0)
+                       fatalError("open failed for `%s': %s\n", device, strerror (errno));
+
+               /* How many filesystems?  We need to know to allocate enough space */
+               numfilesystems = ioctl (fd, DEVMTAB_COUNT_FILESYSTEMS);
+               if (numfilesystems<0)
+                       fatalError("\nDEVMTAB_COUNT_FILESYSTEMS: %s\n", strerror (errno));
+               fslist = (struct k_fstype *) calloc ( numfilesystems, sizeof(struct k_fstype));
+
+               /* Grab the list of available filesystems */
+               status = ioctl (fd, DEVMTAB_GET_FILESYSTEMS, fslist);
+               if (status<0)
+                       fatalError("\nDEVMTAB_GET_FILESYSTEMS: %s\n", strerror (errno));
+
+               /* Walk the list trying to mount filesystems 
+                * that do not claim to be nodev filesystems */
+               for( i = 0 ; i < numfilesystems ; i++) {
+                       if (fslist[i].mnt_nodev)
+                               continue;
+                       status = do_mount(blockDevice, directory, fslist[i].mnt_type,
+                                                         flags | MS_MGC_VAL, string_flags,
+                                                         useMtab, fakeIt, mtab_opts);
+                       if (status == TRUE)
+                               break;
+               }
+               free( fslist);
+               close(fd);
+       } else
+#endif
        {
                status = do_mount(blockDevice, directory, filesystemType,
                                                  flags | MS_MGC_VAL, string_flags, useMtab,
@@ -285,6 +325,39 @@ extern int mount_main(int argc, char **argv)
        /* Only compiled in if BB_MTAB is not defined */
        whine_if_fstab_is_missing();
 
+#if defined BB_FEATURE_USE_DEVPS_N_DEVMTAB
+       if (argc == 1) {
+               int fd, i, numfilesystems;
+               char device[] = "/dev/mtab";
+               struct k_mntent *mntentlist;
+
+               /* open device */ 
+               fd = open(device, O_RDONLY);
+               if (fd < 0)
+                       fatalError("open failed for `%s': %s\n", device, strerror (errno));
+
+               /* How many mounted filesystems?  We need to know to 
+                * allocate enough space for later... */
+               numfilesystems = ioctl (fd, DEVMTAB_COUNT_MOUNTS);
+               if (numfilesystems<0)
+                       fatalError( "\nDEVMTAB_COUNT_MOUNTS: %s\n", strerror (errno));
+               mntentlist = (struct k_mntent *) calloc ( numfilesystems, sizeof(struct k_mntent));
+               
+               /* Grab the list of mounted filesystems */
+               if (ioctl (fd, DEVMTAB_GET_MOUNTS, mntentlist)<0)
+                       fatalError( "\nDEVMTAB_GET_MOUNTS: %s\n", strerror (errno));
+
+               for( i = 0 ; i < numfilesystems ; i++) {
+                       fprintf( stdout, "%s %s %s %s %d %d\n", mntentlist[i].mnt_fsname,
+                                       mntentlist[i].mnt_dir, mntentlist[i].mnt_type, 
+                                       mntentlist[i].mnt_opts, mntentlist[i].mnt_freq, 
+                                       mntentlist[i].mnt_passno);
+               }
+               free( mntentlist);
+               close(fd);
+               exit(TRUE);
+       }
+#else
        if (argc == 1) {
                FILE *mountTable = setmntent(mtab_file, "r");
 
@@ -310,7 +383,7 @@ extern int mount_main(int argc, char **argv)
                }
                exit(TRUE);
        }
-
+#endif
 
        /* Parse options */
        i = --argc;
@@ -372,10 +445,9 @@ extern int mount_main(int argc, char **argv)
                struct mntent *m;
                FILE *f = setmntent("/etc/fstab", "r");
 
-               if (f == NULL) {
-                       perror("/etc/fstab");
-                       exit(FALSE);
-               }
+               if (f == NULL)
+                       fatalError( "\nCannot ream /etc/fstab: %s\n", strerror (errno));
+
                while ((m = getmntent(f)) != NULL) {
                        // If the file system isn't noauto, 
                        // and isn't swap or nfs, then mount it
index 7f9abf1..14dc2f5 100644 (file)
@@ -27,5 +27,5 @@
 extern int poweroff_main(int argc, char **argv)
 {
        /* don't assume init's pid == 1 */
-       exit(kill(findInitPid(), SIGUSR2));
+       exit(kill(findPidByName("init"), SIGUSR2));
 }
index 5166212..8a99e0f 100644 (file)
@@ -24,6 +24,7 @@
 #include "internal.h"
 #include <stdio.h>
 #include <stdlib.h>
+#include <errno.h>
 #include <unistd.h>
 #include <signal.h>
 #include <ctype.h>
@@ -35,6 +36,14 @@ static const char *kill_usage =
        "Send a signal (default is SIGTERM) to the specified process(es).\n\n"
        "Options:\n" "\t-l\tList all signal names and numbers.\n\n";
 
+static const char *killall_usage =
+       "killall [-signal] process-name [process-name ...]\n\n"
+       "Send a signal (default is SIGTERM) to the specified process(es).\n\n"
+       "Options:\n" "\t-l\tList all signal names and numbers.\n\n";
+
+
+#define KILL   0
+#define KILLALL        1
 
 struct signal_name {
        const char *name;
@@ -120,13 +129,19 @@ const struct signal_name signames[] = {
 
 extern int kill_main(int argc, char **argv)
 {
-       int sig = SIGTERM;
+       int whichApp, sig = SIGTERM;
+       const char *appUsage;
+
+       /* Figure out what we are trying to do here */
+       whichApp = (strcmp(*argv, "killall") == 0)? 
+               KILLALL : KILL; 
+       appUsage = (whichApp == KILLALL)?  killall_usage : kill_usage;
 
        argc--;
        argv++;
        /* Parse any options */
        if (argc < 1)
-               usage(kill_usage);
+               usage(appUsage);
 
        while (argc > 0 && **argv == '-') {
                while (*++(*argv)) {
@@ -150,7 +165,7 @@ extern int kill_main(int argc, char **argv)
                                }
                                break;
                        case '-':
-                               usage(kill_usage);
+                               usage(appUsage);
                        default:
                                {
                                        if (isdigit(**argv)) {
@@ -186,32 +201,34 @@ extern int kill_main(int argc, char **argv)
 
   do_it_now:
 
-       while (--argc >= 0) {
-               int pid;
-               struct stat statbuf;
-               char pidpath[20] = "/proc/";
+       if (whichApp == KILL) {
+               /* Looks like they want to do a kill. Do that */
+               while (--argc >= 0) {
+                       int pid;
 
-               if (!isdigit(**argv)) {
-                       fprintf(stderr, "bad PID: %s\n", *argv);
-                       exit(FALSE);
-               }
-               pid = atoi(*argv);
-               snprintf(pidpath, 20, "/proc/%s/stat", *argv);
-               if (stat(pidpath, &statbuf) != 0) {
-                       fprintf(stderr, "kill: (%d) - No such pid\n", pid);
-                       exit(FALSE);
+                       if (!isdigit(**argv))
+                               fatalError( "Bad PID: %s\n", strerror(errno));
+                       pid = strtol(*argv, NULL, 0);
+                       if (kill(pid, sig) != 0) 
+                               fatalError( "Could not kill pid '%d': %s\n", pid, strerror(errno));
+                       argv++;
                }
-               fprintf(stderr, "sig = %d\n", sig);
-               if (kill(pid, sig) != 0) {
-                       perror(*argv);
-                       exit(FALSE);
+       } else {
+               /* Looks like they want to do a killall.  Do that */
+               while (--argc >= 0) {
+                       int pid;
+
+                       while((pid = findPidByName( *argv))) {
+                               if (kill(pid, sig) != 0) 
+                                       fatalError( "Could not kill pid '%d': %s\n", pid, strerror(errno));
+                       }
+                       argv++;
                }
-               argv++;
        }
+
        exit(TRUE);
 
 
   end:
-       fprintf(stderr, "bad signal name: %s\n", *argv);
-       exit(TRUE);
+       fatalError( "bad signal name: %s\n", *argv);
 }
index 207cdaa..b0933ab 100644 (file)
@@ -1,34 +1,47 @@
 /* vi: set sw=4 ts=4: */
 /*
- * Mini ps implementation for busybox
+ * Mini ps implementation(s) for busybox
  *
+ * Copyright (C) 1999 by Lineo, inc.  Written by Erik Andersen
+ * <andersen@lineo.com>, <andersee@debian.org>
  *
- * Copyright (C) 1999 by Lineo, inc.
- * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
  *
- * 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; either version 2 of the License, or
- * (at your option) any later version.
+ * This contains _two_ implementations of ps for Linux.  One uses the
+ * traditional /proc virtual filesystem, and the other use the devps kernel
+ * driver (written by Erik Andersen to avoid using /proc thereby saving 100k+).
  *
- * 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
+ *
+ * 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; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * 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
  *
  */
 
 #include "internal.h"
+#include <stdio.h>
 #include <unistd.h>
 #include <dirent.h>
-#include <stdio.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <ctype.h>
 
+#if ! defined BB_FEATURE_USE_DEVPS_N_DEVMTAB
+
+/* The following is the first ps implementation --
+ * the one using the /proc virtual filesystem.
+ */
+
 #if ! defined BB_FEATURE_USE_PROCFS
 #error Sorry, I depend on the /proc filesystem right now.
 #endif
@@ -105,16 +118,12 @@ extern int ps_main(int argc, char **argv)
        char groupName[10] = "";
        int i, c;
 
-       if (argc > 1 && **(argv + 1) == '-') {
-               usage
-                       ("ps\n\nReport process status\n\nThis version of ps accepts no options.\n");
-       }
+       if (argc > 1 && **(argv + 1) == '-')
+               usage ("ps\n\nReport process status\n\nThis version of ps accepts no options.\n");
 
        dir = opendir("/proc");
-       if (!dir) {
-               perror("Can't open /proc");
-               exit(FALSE);
-       }
+       if (!dir)
+               fatalError("Can't open /proc");
 
        fprintf(stdout, "%5s  %-8s %-3s %5s %s\n", "PID", "Uid", "Gid",
                        "State", "Command");
@@ -131,9 +140,9 @@ extern int ps_main(int argc, char **argv)
 
                /* Make some adjustments as needed */
                my_getpwuid(uidName, p.ruid);
-               my_getgrgid(groupName, p.rgid);
                if (*uidName == '\0')
                        sprintf(uidName, "%d", p.ruid);
+               my_getgrgid(groupName, p.rgid);
                if (*groupName == '\0')
                        sprintf(groupName, "%d", p.rgid);
 
@@ -141,10 +150,8 @@ extern int ps_main(int argc, char **argv)
                                p.state);
                sprintf(path, "/proc/%s/cmdline", entry->d_name);
                file = fopen(path, "r");
-               if (file == NULL) {
-                       perror(path);
-                       exit(FALSE);
-               }
+               if (file == NULL)
+                       fatalError("Can't open %s: %s\n", path, strerror(errno));
                i = 0;
                while (((c = getc(file)) != EOF) && (i < 53)) {
                        i++;
@@ -159,3 +166,90 @@ extern int ps_main(int argc, char **argv)
        closedir(dir);
        exit(TRUE);
 }
+
+
+#else /* BB_FEATURE_USE_DEVPS_N_DEVMTAB */
+
+
+/* The following is the second ps implementation --
+ * this one uses the nifty new devps kernel device.
+ */
+
+#include <sys/ioctl.h>
+#include <linux/devps.h>
+
+
+extern int ps_main(int argc, char **argv)
+{
+       char device[] = "/dev/ps";
+       int i, fd;
+       pid_t num_pids;
+       pid_t* pid_array = NULL;
+       struct pid_info info;
+       char uidName[10] = "";
+       char groupName[10] = "";
+
+       if (argc > 1 && **(argv + 1) == '-') 
+               usage("ps-devps\n\nReport process status\n\nThis version of ps accepts no options.\n\n");
+
+       /* open device */ 
+       fd = open(device, O_RDONLY);
+       if (fd < 0) 
+               fatalError( "open failed for `%s': %s\n", device, strerror (errno));
+
+       /* Find out how many processes there are */
+       if (ioctl (fd, DEVPS_GET_NUM_PIDS, &num_pids)<0) 
+               fatalError( "\nDEVPS_GET_PID_LIST: %s\n", strerror (errno));
+       
+       /* Allocate some memory -- grab a few extras just in case 
+        * some new processes start up while we wait. The kernel will
+        * just ignore any extras if we give it too many, and will trunc.
+        * the list if we give it too few.  */
+       pid_array = (pid_t*) calloc( num_pids+10, sizeof(pid_t));
+       pid_array[0] = num_pids+10;
+
+       /* Now grab the pid list */
+       if (ioctl (fd, DEVPS_GET_PID_LIST, pid_array)<0) 
+               fatalError("\nDEVPS_GET_PID_LIST: %s\n", strerror (errno));
+
+       /* Print up a ps listing */
+       fprintf(stdout, "%5s  %-8s %-3s %5s %s\n", "PID", "Uid", "Gid",
+                       "State", "Command");
+
+       for (i=1; i<pid_array[0] ; i++) {
+               uidName[0] = '\0';
+               groupName[0] = '\0';
+           info.pid = pid_array[i];
+
+           if (ioctl (fd, DEVPS_GET_PID_INFO, &info)<0)
+                       fatalError("\nDEVPS_GET_PID_INFO: %s\n", strerror (errno));
+           
+               /* Make some adjustments as needed */
+               my_getpwuid(uidName, info.euid);
+               if (*uidName == '\0')
+                       sprintf(uidName, "%ld", info.euid);
+               my_getgrgid(groupName, info.egid);
+               if (*groupName == '\0')
+                       sprintf(groupName, "%ld", info.egid);
+
+               fprintf(stdout, "%5d %-8s %-8s %c ", info.pid, uidName, groupName, info.state);
+
+               if (strlen(info.command_line) > 1)
+                       fprintf(stdout, "%s\n", info.command_line);
+               else
+                       fprintf(stdout, "[%s]\n", info.name);
+
+       }
+
+       /* Free memory */
+       free( pid_array);
+
+       /* close device */
+       if (close (fd) != 0) 
+               fatalError("close failed for `%s': %s\n", device, strerror (errno));
+       exit (0);
+}
+
+#endif /* BB_FEATURE_USE_DEVPS_N_DEVMTAB */
+
diff --git a/ps.c b/ps.c
index 207cdaa..b0933ab 100644 (file)
--- a/ps.c
+++ b/ps.c
@@ -1,34 +1,47 @@
 /* vi: set sw=4 ts=4: */
 /*
- * Mini ps implementation for busybox
+ * Mini ps implementation(s) for busybox
  *
+ * Copyright (C) 1999 by Lineo, inc.  Written by Erik Andersen
+ * <andersen@lineo.com>, <andersee@debian.org>
  *
- * Copyright (C) 1999 by Lineo, inc.
- * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
  *
- * 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; either version 2 of the License, or
- * (at your option) any later version.
+ * This contains _two_ implementations of ps for Linux.  One uses the
+ * traditional /proc virtual filesystem, and the other use the devps kernel
+ * driver (written by Erik Andersen to avoid using /proc thereby saving 100k+).
  *
- * 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
+ *
+ * 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; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * 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
  *
  */
 
 #include "internal.h"
+#include <stdio.h>
 #include <unistd.h>
 #include <dirent.h>
-#include <stdio.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <ctype.h>
 
+#if ! defined BB_FEATURE_USE_DEVPS_N_DEVMTAB
+
+/* The following is the first ps implementation --
+ * the one using the /proc virtual filesystem.
+ */
+
 #if ! defined BB_FEATURE_USE_PROCFS
 #error Sorry, I depend on the /proc filesystem right now.
 #endif
@@ -105,16 +118,12 @@ extern int ps_main(int argc, char **argv)
        char groupName[10] = "";
        int i, c;
 
-       if (argc > 1 && **(argv + 1) == '-') {
-               usage
-                       ("ps\n\nReport process status\n\nThis version of ps accepts no options.\n");
-       }
+       if (argc > 1 && **(argv + 1) == '-')
+               usage ("ps\n\nReport process status\n\nThis version of ps accepts no options.\n");
 
        dir = opendir("/proc");
-       if (!dir) {
-               perror("Can't open /proc");
-               exit(FALSE);
-       }
+       if (!dir)
+               fatalError("Can't open /proc");
 
        fprintf(stdout, "%5s  %-8s %-3s %5s %s\n", "PID", "Uid", "Gid",
                        "State", "Command");
@@ -131,9 +140,9 @@ extern int ps_main(int argc, char **argv)
 
                /* Make some adjustments as needed */
                my_getpwuid(uidName, p.ruid);
-               my_getgrgid(groupName, p.rgid);
                if (*uidName == '\0')
                        sprintf(uidName, "%d", p.ruid);
+               my_getgrgid(groupName, p.rgid);
                if (*groupName == '\0')
                        sprintf(groupName, "%d", p.rgid);
 
@@ -141,10 +150,8 @@ extern int ps_main(int argc, char **argv)
                                p.state);
                sprintf(path, "/proc/%s/cmdline", entry->d_name);
                file = fopen(path, "r");
-               if (file == NULL) {
-                       perror(path);
-                       exit(FALSE);
-               }
+               if (file == NULL)
+                       fatalError("Can't open %s: %s\n", path, strerror(errno));
                i = 0;
                while (((c = getc(file)) != EOF) && (i < 53)) {
                        i++;
@@ -159,3 +166,90 @@ extern int ps_main(int argc, char **argv)
        closedir(dir);
        exit(TRUE);
 }
+
+
+#else /* BB_FEATURE_USE_DEVPS_N_DEVMTAB */
+
+
+/* The following is the second ps implementation --
+ * this one uses the nifty new devps kernel device.
+ */
+
+#include <sys/ioctl.h>
+#include <linux/devps.h>
+
+
+extern int ps_main(int argc, char **argv)
+{
+       char device[] = "/dev/ps";
+       int i, fd;
+       pid_t num_pids;
+       pid_t* pid_array = NULL;
+       struct pid_info info;
+       char uidName[10] = "";
+       char groupName[10] = "";
+
+       if (argc > 1 && **(argv + 1) == '-') 
+               usage("ps-devps\n\nReport process status\n\nThis version of ps accepts no options.\n\n");
+
+       /* open device */ 
+       fd = open(device, O_RDONLY);
+       if (fd < 0) 
+               fatalError( "open failed for `%s': %s\n", device, strerror (errno));
+
+       /* Find out how many processes there are */
+       if (ioctl (fd, DEVPS_GET_NUM_PIDS, &num_pids)<0) 
+               fatalError( "\nDEVPS_GET_PID_LIST: %s\n", strerror (errno));
+       
+       /* Allocate some memory -- grab a few extras just in case 
+        * some new processes start up while we wait. The kernel will
+        * just ignore any extras if we give it too many, and will trunc.
+        * the list if we give it too few.  */
+       pid_array = (pid_t*) calloc( num_pids+10, sizeof(pid_t));
+       pid_array[0] = num_pids+10;
+
+       /* Now grab the pid list */
+       if (ioctl (fd, DEVPS_GET_PID_LIST, pid_array)<0) 
+               fatalError("\nDEVPS_GET_PID_LIST: %s\n", strerror (errno));
+
+       /* Print up a ps listing */
+       fprintf(stdout, "%5s  %-8s %-3s %5s %s\n", "PID", "Uid", "Gid",
+                       "State", "Command");
+
+       for (i=1; i<pid_array[0] ; i++) {
+               uidName[0] = '\0';
+               groupName[0] = '\0';
+           info.pid = pid_array[i];
+
+           if (ioctl (fd, DEVPS_GET_PID_INFO, &info)<0)
+                       fatalError("\nDEVPS_GET_PID_INFO: %s\n", strerror (errno));
+           
+               /* Make some adjustments as needed */
+               my_getpwuid(uidName, info.euid);
+               if (*uidName == '\0')
+                       sprintf(uidName, "%ld", info.euid);
+               my_getgrgid(groupName, info.egid);
+               if (*groupName == '\0')
+                       sprintf(groupName, "%ld", info.egid);
+
+               fprintf(stdout, "%5d %-8s %-8s %c ", info.pid, uidName, groupName, info.state);
+
+               if (strlen(info.command_line) > 1)
+                       fprintf(stdout, "%s\n", info.command_line);
+               else
+                       fprintf(stdout, "[%s]\n", info.name);
+
+       }
+
+       /* Free memory */
+       free( pid_array);
+
+       /* close device */
+       if (close (fd) != 0) 
+               fatalError("close failed for `%s': %s\n", device, strerror (errno));
+       exit (0);
+}
+
+#endif /* BB_FEATURE_USE_DEVPS_N_DEVMTAB */
+
index f782fa1..fc01ea0 100644 (file)
--- a/reboot.c
+++ b/reboot.c
@@ -27,7 +27,7 @@
 extern int reboot_main(int argc, char **argv)
 {
        /* don't assume init's pid == 1 */
-       exit(kill(findInitPid(), SIGINT));
+       exit(kill(findPidByName("init"), SIGINT));
 }
 
 /*
index 37f789d..f46664b 100644 (file)
 #include <sys/mount.h>
 #include <ctype.h>
 #include <fstab.h>
+#if defined BB_FEATURE_USE_DEVPS_N_DEVMTAB
+#include <linux/devmtab.h>
+#endif
+
 
 #if defined BB_FEATURE_MOUNT_LOOP
 #include <fcntl.h>
@@ -221,9 +225,8 @@ mount_one(char *blockDevice, char *directory, char *filesystemType,
 {
        int status = 0;
 
-       char buf[255];
-
 #if defined BB_FEATURE_USE_PROCFS
+       char buf[255];
        if (strcmp(filesystemType, "auto") == 0) {
                FILE *f = fopen("/proc/filesystems", "r");
 
@@ -252,6 +255,43 @@ mount_one(char *blockDevice, char *directory, char *filesystemType,
                fclose(f);
        } else
 #endif
+#if defined BB_FEATURE_USE_DEVPS_N_DEVMTAB
+       if (strcmp(filesystemType, "auto") == 0) {
+               int fd, i, numfilesystems;
+               char device[] = "/dev/mtab";
+               struct k_fstype *fslist;
+
+               /* open device */ 
+               fd = open(device, O_RDONLY);
+               if (fd < 0)
+                       fatalError("open failed for `%s': %s\n", device, strerror (errno));
+
+               /* How many filesystems?  We need to know to allocate enough space */
+               numfilesystems = ioctl (fd, DEVMTAB_COUNT_FILESYSTEMS);
+               if (numfilesystems<0)
+                       fatalError("\nDEVMTAB_COUNT_FILESYSTEMS: %s\n", strerror (errno));
+               fslist = (struct k_fstype *) calloc ( numfilesystems, sizeof(struct k_fstype));
+
+               /* Grab the list of available filesystems */
+               status = ioctl (fd, DEVMTAB_GET_FILESYSTEMS, fslist);
+               if (status<0)
+                       fatalError("\nDEVMTAB_GET_FILESYSTEMS: %s\n", strerror (errno));
+
+               /* Walk the list trying to mount filesystems 
+                * that do not claim to be nodev filesystems */
+               for( i = 0 ; i < numfilesystems ; i++) {
+                       if (fslist[i].mnt_nodev)
+                               continue;
+                       status = do_mount(blockDevice, directory, fslist[i].mnt_type,
+                                                         flags | MS_MGC_VAL, string_flags,
+                                                         useMtab, fakeIt, mtab_opts);
+                       if (status == TRUE)
+                               break;
+               }
+               free( fslist);
+               close(fd);
+       } else
+#endif
        {
                status = do_mount(blockDevice, directory, filesystemType,
                                                  flags | MS_MGC_VAL, string_flags, useMtab,
@@ -285,6 +325,39 @@ extern int mount_main(int argc, char **argv)
        /* Only compiled in if BB_MTAB is not defined */
        whine_if_fstab_is_missing();
 
+#if defined BB_FEATURE_USE_DEVPS_N_DEVMTAB
+       if (argc == 1) {
+               int fd, i, numfilesystems;
+               char device[] = "/dev/mtab";
+               struct k_mntent *mntentlist;
+
+               /* open device */ 
+               fd = open(device, O_RDONLY);
+               if (fd < 0)
+                       fatalError("open failed for `%s': %s\n", device, strerror (errno));
+
+               /* How many mounted filesystems?  We need to know to 
+                * allocate enough space for later... */
+               numfilesystems = ioctl (fd, DEVMTAB_COUNT_MOUNTS);
+               if (numfilesystems<0)
+                       fatalError( "\nDEVMTAB_COUNT_MOUNTS: %s\n", strerror (errno));
+               mntentlist = (struct k_mntent *) calloc ( numfilesystems, sizeof(struct k_mntent));
+               
+               /* Grab the list of mounted filesystems */
+               if (ioctl (fd, DEVMTAB_GET_MOUNTS, mntentlist)<0)
+                       fatalError( "\nDEVMTAB_GET_MOUNTS: %s\n", strerror (errno));
+
+               for( i = 0 ; i < numfilesystems ; i++) {
+                       fprintf( stdout, "%s %s %s %s %d %d\n", mntentlist[i].mnt_fsname,
+                                       mntentlist[i].mnt_dir, mntentlist[i].mnt_type, 
+                                       mntentlist[i].mnt_opts, mntentlist[i].mnt_freq, 
+                                       mntentlist[i].mnt_passno);
+               }
+               free( mntentlist);
+               close(fd);
+               exit(TRUE);
+       }
+#else
        if (argc == 1) {
                FILE *mountTable = setmntent(mtab_file, "r");
 
@@ -310,7 +383,7 @@ extern int mount_main(int argc, char **argv)
                }
                exit(TRUE);
        }
-
+#endif
 
        /* Parse options */
        i = --argc;
@@ -372,10 +445,9 @@ extern int mount_main(int argc, char **argv)
                struct mntent *m;
                FILE *f = setmntent("/etc/fstab", "r");
 
-               if (f == NULL) {
-                       perror("/etc/fstab");
-                       exit(FALSE);
-               }
+               if (f == NULL)
+                       fatalError( "\nCannot ream /etc/fstab: %s\n", strerror (errno));
+
                while ((m = getmntent(f)) != NULL) {
                        // If the file system isn't noauto, 
                        // and isn't swap or nfs, then mount it
index 64c1a48..7de9974 100644 (file)
--- a/utility.c
+++ b/utility.c
 #include <linux/loop.h>
 #endif
 
+/* Busybox mount uses either /proc/filesystems or /dev/mtab to get the 
+ * list of available filesystems used for the -t auto option */ 
+#if defined BB_FEATURE_USE_PROCFS && defined BB_FEATURE_USE_DEVPS_N_DEVMTAB
+//#error Sorry, but busybox can't use both /proc and /dev/ps at the same time -- Pick one and try again.
+#error "Sorry, but busybox can't use both /proc and /dev/ps at the same time -- Pick one and try again."
+#endif
+
 
 #if defined BB_MOUNT || defined BB_UMOUNT || defined BB_DF
 #  if defined BB_FEATURE_USE_PROCFS
@@ -64,9 +71,13 @@ const char mtab_file[] = "/proc/mounts";
 #    if defined BB_MTAB
 const char mtab_file[] = "/etc/mtab";
 #    else
-#      error With (BB_MOUNT||BB_UMOUNT||BB_DF) defined, you must define either BB_MTAB or BB_FEATURE_USE_PROCFS
+#      if defined BB_FEATURE_USE_DEVPS_N_DEVMTAB
+const char mtab_file[] = "/dev/mtab";
+#    else
+#        error With (BB_MOUNT||BB_UMOUNT||BB_DF) defined, you must define either BB_MTAB or ( BB_FEATURE_USE_PROCFS | BB_FEATURE_USE_DEVPS_N_DEVMTAB)
 #    endif
 #  endif
+#  endif
 #endif
 
 
@@ -1238,29 +1249,96 @@ extern int device_open(char *device, int mode)
 
 #if defined BB_INIT || defined BB_HALT || defined BB_REBOOT
 
+#ifdef BB_FEATURE_USE_DEVPS_N_DEVMTAB
+#include <linux/devps.h>
+#endif
+
+#if defined BB_FEATURE_USE_DEVPS_N_DEVMTAB
+/* findPidByName()
+ *  
+ *  This finds the pid of the specified process,
+ *  by using the /dev/ps device driver.
+ *
+ *  [return]
+ *  0      failure
+ *  pid            when the pid is found.
+ */
+extern pid_t findPidByName( char* pidName)
+{
+       int fd, i;
+       char device[] = "/dev/ps";
+       pid_t thePid = 0;
+       pid_t num_pids;
+       pid_t* pid_array = NULL;
+
+       /* open device */ 
+       fd = open(device, O_RDONLY);
+       if (fd < 0)
+               fatalError( "open failed for `%s': %s\n", device, strerror (errno));
+
+       /* Find out how many processes there are */
+       if (ioctl (fd, DEVPS_GET_NUM_PIDS, &num_pids)<0) 
+               fatalError( "\nDEVPS_GET_PID_LIST: %s\n", strerror (errno));
+       
+       /* Allocate some memory -- grab a few extras just in case 
+        * some new processes start up while we wait. The kernel will
+        * just ignore any extras if we give it too many, and will trunc.
+        * the list if we give it too few.  */
+       pid_array = (pid_t*) calloc( num_pids+10, sizeof(pid_t));
+       pid_array[0] = num_pids+10;
+
+       /* Now grab the pid list */
+       if (ioctl (fd, DEVPS_GET_PID_LIST, pid_array)<0) 
+               fatalError( "\nDEVPS_GET_PID_LIST: %s\n", strerror (errno));
+
+       /* Now search for a match */
+       for (i=1; i<pid_array[0] ; i++) {
+               struct pid_info info;
+
+           info.pid = pid_array[i];
+           if (ioctl (fd, DEVPS_GET_PID_INFO, &info)<0)
+                       fatalError( "\nDEVPS_GET_PID_INFO: %s\n", strerror (errno));
+
+               if ((strstr(info.command_line, pidName) != NULL)) {
+                       thePid = info.pid;
+                       break;
+               }
+       }
+
+       /* Free memory */
+       free( pid_array);
+
+       /* close device */
+       if (close (fd) != 0) 
+               fatalError( "close failed for `%s': %s\n",device, strerror (errno));
+
+       return thePid;
+}
+#else          /* BB_FEATURE_USE_DEVPS_N_DEVMTAB */
 #if ! defined BB_FEATURE_USE_PROCFS
 #error Sorry, I depend on the /proc filesystem right now.
 #endif
-/* findInitPid()
+/* findPidByName()
  *  
- *  This finds the pid of init (which is not always 1).
- *  Currently, it's implemented by rummaging through the proc filesystem.
+ *  This finds the pid of the specified process.
+ *  Currently, it's implemented by rummaging through 
+ *  the proc filesystem.
  *
  *  [return]
  *  0      failure
- *  pid            when init's pid is found.
+ *  pid            when the pid is found.
  */
-extern pid_t findInitPid()
+extern pid_t findPidByName( char* pidName)
 {
-       pid_t init_pid;
+       pid_t thePid;
        char filename[256];
        char buffer[256];
 
        /* no need to opendir ;) */
-       for (init_pid = 1; init_pid < 65536; init_pid++) {
+       for (thePid = 1; thePid < 65536; thePid++) {
                FILE *status;
 
-               sprintf(filename, "/proc/%d/cmdline", init_pid);
+               sprintf(filename, "/proc/%d/cmdline", thePid);
                status = fopen(filename, "r");
                if (!status) {
                        continue;
@@ -1268,12 +1346,13 @@ extern pid_t findInitPid()
                fgets(buffer, 256, status);
                fclose(status);
 
-               if ((strstr(buffer, "init") != NULL)) {
-                       return init_pid;
+               if ((strstr(buffer, pidName) != NULL)) {
+                       return thePid;
                }
        }
        return 0;
 }
+#endif                                                 /* BB_FEATURE_USE_DEVPS_N_DEVMTAB */
 #endif                                                 /* BB_INIT || BB_HALT || BB_REBOOT */
 
 #if defined BB_GUNZIP \