busybox/coreutils/mknod.c
<<
>>
Prefs
   1/* vi: set sw=4 ts=4: */
   2/*
   3 * mknod implementation for busybox
   4 *
   5 * Copyright (C) 2003  Manuel Novoa III  <mjn3@codepoet.org>
   6 *
   7 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
   8 */
   9//config:config MKNOD
  10//config:       bool "mknod"
  11//config:       default y
  12//config:       help
  13//config:         mknod is used to create FIFOs or block/character special
  14//config:         files with the specified names.
  15
  16//applet:IF_MKNOD(APPLET_NOEXEC(mknod, mknod, BB_DIR_BIN, BB_SUID_DROP, mknod))
  17
  18//kbuild:lib-$(CONFIG_MKNOD) += mknod.o
  19
  20/* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */
  21
  22//usage:#define mknod_trivial_usage
  23//usage:       "[-m MODE] " IF_SELINUX("[-Z] ") "NAME TYPE MAJOR MINOR"
  24//usage:#define mknod_full_usage "\n\n"
  25//usage:       "Create a special file (block, character, or pipe)\n"
  26//usage:     "\n        -m MODE Creation mode (default a=rw)"
  27//usage:        IF_SELINUX(
  28//usage:     "\n        -Z      Set security context"
  29//usage:        )
  30//usage:     "\nTYPE:"
  31//usage:     "\n        b       Block device"
  32//usage:     "\n        c or u  Character device"
  33//usage:     "\n        p       Named pipe (MAJOR and MINOR are ignored)"
  34//usage:
  35//usage:#define mknod_example_usage
  36//usage:       "$ mknod /dev/fd0 b 2 0\n"
  37//usage:       "$ mknod -m 644 /tmp/pipe p\n"
  38
  39#include <sys/sysmacros.h>  // For makedev
  40
  41#include "libbb.h"
  42#include "libcoreutils/coreutils.h"
  43
  44/* This is a NOEXEC applet. Be very careful! */
  45
  46static const char modes_chars[] ALIGN1 = { 'p', 'c', 'u', 'b', 0, 1, 1, 2 };
  47static const mode_t modes_cubp[] = { S_IFIFO, S_IFCHR, S_IFBLK };
  48
  49int mknod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  50int mknod_main(int argc, char **argv)
  51{
  52        mode_t mode;
  53        dev_t dev;
  54        const char *name;
  55
  56        mode = getopt_mk_fifo_nod(argv);
  57        argv += optind;
  58        argc -= optind;
  59
  60        if (argc >= 2) {
  61                name = strchr(modes_chars, argv[1][0]);
  62                if (name != NULL) {
  63                        mode |= modes_cubp[(int)(name[4])];
  64
  65                        dev = 0;
  66                        if (*name != 'p') {
  67                                argc -= 2;
  68                                if (argc == 2) {
  69                                        /* Autodetect what the system supports; these macros should
  70                                         * optimize out to two constants. */
  71                                        dev = makedev(xatoul_range(argv[2], 0, major(UINT_MAX)),
  72                                                        xatoul_range(argv[3], 0, minor(UINT_MAX)));
  73                                }
  74                        }
  75
  76                        if (argc == 2) {
  77                                name = *argv;
  78                                if (mknod(name, mode, dev) == 0) {
  79                                        return EXIT_SUCCESS;
  80                                }
  81                                bb_simple_perror_msg_and_die(name);
  82                        }
  83                }
  84        }
  85        bb_show_usage();
  86}
  87