commit e5d8efb32f734285dacf68ad73d893759c9477d0
Author:     Michael Forney <[email protected]>
AuthorDate: Sun Mar 1 15:58:37 2020 -0800
Commit:     Michael Forney <[email protected]>
CommitDate: Sun Mar 1 16:33:11 2020 -0800

    Import mknod from ubase
    
    Although mknod is not a POSIX tool, it is widely available on nearly
    all UNIX-like systems. It also can be implemented portably apart
    from use of the makedev macros, which is already a requirement of
    a couple other tools in sbase.
    
    While we're at it, fix a few bugs:
    - Include sys/sysmacros.h if makedev was not defined by sys/types.h
    - The default mode should respect the user's umask, rather than
      assuming it is 022.
    - Clear the umask when -m is specified explicitly so that nodes can
      be created with permissions wider than the user's umask.
    - Utilize parsemode from libutil to support symbolic mode strings.

diff --git a/.gitignore b/.gitignore
index f4709cb..a533bfa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -42,6 +42,7 @@
 /md5sum
 /mkdir
 /mkfifo
+/mknod
 /mktemp
 /mv
 /nice
diff --git a/Makefile b/Makefile
index 75b1618..5473e5a 100644
--- a/Makefile
+++ b/Makefile
@@ -125,6 +125,7 @@ BIN =\
        md5sum\
        mkdir\
        mkfifo\
+       mknod\
        mktemp\
        mv\
        nice\
diff --git a/README b/README
index 8653552..d8e1bcc 100644
--- a/README
+++ b/README
@@ -84,6 +84,7 @@ The following tools are implemented:
 0=*|x md5sum          .
 0=*|o mkdir           .
 0=*|o mkfifo          .
+0=*|x mknod           .
 0=*|x mktemp          .
 0=*|o mv              (-i)
 0=*|o nice            .
diff --git a/mknod.1 b/mknod.1
new file mode 100644
index 0000000..180b9cd
--- /dev/null
+++ b/mknod.1
@@ -0,0 +1,37 @@
+.Dd 2015-02-02
+.Dt MKNOD 1
+.Os sbase
+.Sh NAME
+.Nm mknod
+.Nd create a special device file
+.Sh SYNOPSIS
+.Nm
+.Op Fl m Ar mode
+.Ar name
+.Ar type
+.Ar major
+.Ar minor
+.Sh DESCRIPTION
+.Nm
+creates a special device file named
+.Ar name
+with major number
+.Ar major ,
+and minor number
+.Ar minor .
+.Ar type
+specifies what kind of special file will be created and must be one of:
+.Bl -tag -width Ds
+.It Ar u | c
+A character device.
+.It Ar b
+A block device.
+.El
+.Sh OPTIONS
+.Bl -tag -width Ds
+.It Fl m
+Set the mode of the new file based on the octal value of
+.Ar mode .
+.El
+.Sh SEE ALSO
+.Xr mknod 2
diff --git a/mknod.c b/mknod.c
new file mode 100644
index 0000000..23869d7
--- /dev/null
+++ b/mknod.c
@@ -0,0 +1,48 @@
+/* See LICENSE file for copyright and license details. */
+#include <sys/stat.h>
+#include <sys/types.h>
+#ifndef makedev
+#include <sys/sysmacros.h>
+#endif
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "util.h"
+
+static void
+usage(void)
+{
+       eprintf("usage: %s [-m mode] name type major minor\n", argv0);
+}
+
+int
+main(int argc, char *argv[])
+{
+       mode_t type, mode = 0666;
+       dev_t dev;
+
+       ARGBEGIN {
+       case 'm':
+               mode = parsemode(EARGF(usage()), mode, umask(0));
+               break;
+       default:
+               usage();
+       } ARGEND;
+
+       if (argc != 4)
+               usage();
+
+       if (strlen(argv[1]) != 1 || !strchr("ucb", argv[1][0]))
+               eprintf("invalid type '%s'\n", argv[1]);
+       type = (argv[1][0] == 'b') ? S_IFBLK : S_IFCHR;
+
+       dev = makedev(estrtonum(argv[2], 0, LLONG_MAX), estrtonum(argv[3], 0, 
LLONG_MAX));
+
+       if (mknod(argv[0], type|mode, dev) == -1)
+               eprintf("mknod %s:", argv[0]);
+       return 0;
+}

Reply via email to