commit e5d8efb32f734285dacf68ad73d893759c9477d0
parent 22921a859f1410afc65c5433c8ebdae58b326315
Author: Michael Forney <mforney@mforney.org>
Date: Sun, 1 Mar 2020 15:58:37 -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.
Diffstat:
5 files changed, 88 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -42,6 +42,7 @@
/md5sum
/mkdir
/mkfifo
+/mknod
/mktemp
/mv
/nice
diff --git a/Makefile b/Makefile
@@ -125,6 +125,7 @@ BIN =\
md5sum\
mkdir\
mkfifo\
+ mknod\
mktemp\
mv\
nice\
diff --git 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
@@ -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
@@ -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;
+}