logo

utils-std

Collection of commonly available Unix tools
commit: cc07e9b70a5cd570c5cee1213f4f8f437ea904cf
parent 1cab789b9c76b456f011015a9dadf01ea24e1d91
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date:   Sun, 21 Apr 2024 03:04:34 +0200

cmd/mknod: new

Diffstat:

MMakefile4++++
Acmd/mknod.167+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acmd/mknod.c154+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mcoreutils.txt2+-
Mlsb_commands.txt2+-
Mmakeless.sh1+
6 files changed, 228 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile @@ -95,6 +95,10 @@ cmd/mkdir: cmd/mkdir.c lib/mode.c Makefile rm -f ${<:=.gcov} ${@:=.gcda} ${@:=.gcno} $(CC) -std=c99 $(CFLAGS) -o $@ cmd/mkdir.c lib/mode.c $(LDFLAGS) $(LDSTATIC) +cmd/mknod: cmd/mknod.c lib/mode.c Makefile + rm -f ${<:=.gcov} ${@:=.gcda} ${@:=.gcno} + $(CC) -std=c99 $(CFLAGS) -o $@ cmd/mknod.c lib/mode.c $(LDFLAGS) $(LDSTATIC) + cmd/seq: cmd/seq.c lib/absu.h Makefile rm -f ${<:=.gcov} ${@:=.gcda} ${@:=.gcno} $(CC) -std=c99 $(CFLAGS) -o $@ cmd/seq.c -lm $(LDFLAGS) $(LDSTATIC) diff --git a/cmd/mknod.1 b/cmd/mknod.1 @@ -0,0 +1,67 @@ +.\" utils-std: Collection of commonly available Unix tools +.\" Copyright 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me> +.\" SPDX-License-Identifier: MPL-2.0 +.Dd 2024-04-21 +.Dt MKNOD 1 +.Os +.Sh NAME +.Nm mknod +.Nd Create FIFO, block-special, character-special files +.Sh SYNOPSIS +.Nm +.Op Fl m Ar mode +.Ar path +.Ar b Ns | Ns Ar c Ns | Ns Ar u +.Ar major +.Ar minor +.Nm +.Op Fl m Ar mode +.Ar path +.Ar p +.Sh DESCRIPTION +.Nm +creates special file at +.Ar path +of the given type: +.Bl -tag -width ___ +.It Ar b +Create block special file +.It Ar c Ns | Ns Ar u +Create character special file +.It Ar p +Create FIFO +.El +.Pp +Both +.Ar major +and +.Ar minor +must be secified when type is +.Ar b , +.Ar c , +or +.Ar u , +and they must be omitted when type is +.Ar p . +The numbers given in +.Ar major +and +.Ar minor +are interpreted as hexadecimal with a leading 0x or 0X, +octal with a leading 0, +decimal otherwise. +.Sh OPTIONS +.Bl -tag -width _m_mode +.It Fl m Ar mode +Set permission of new special file, +relative to 0666/rw-rw-rw using the same format as +.Xr chmod 1 . +.El +.Sh EXIT STATUS +.Ex -std +.Sh SEE ALSO +.Xr mkfifo 1 +.Sh STANDARDS +None known. +.Sh AUTHORS +.An Haelwenn (lanodan) Monnier Aq Mt contact+utils@hacktivis.me diff --git a/cmd/mknod.c b/cmd/mknod.c @@ -0,0 +1,154 @@ +// utils-std: Collection of commonly available Unix tools +// SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me> +// SPDX-License-Identifier: MPL-2.0 + +#define _POSIX_C_SOURCE 200809L +#define _XOPEN_SOURCE 700 // mknod is in XSI + +#include "../lib/mode.h" + +#include <assert.h> +#include <errno.h> +#include <stdio.h> // fprintf +#include <stdlib.h> // abort, exit +#include <string.h> // strerror, strrchr +#include <sys/stat.h> // mknod +#include <sys/sysmacros.h> // makedev +#include <unistd.h> // getopt + +mode_t filemask; + +static void +usage() +{ + fprintf(stderr, "Usage: mknod [-m mode] file <b|c|u|p> [major minor]\n"); +} + +static unsigned int +strtodev(char *arg) +{ + char *endptr = NULL; + assert(errno == 0); + long dev = strtol(arg, &endptr, 0); + if(errno != 0) + { + fprintf(stderr, "mknod: Failed parsing '%s' into a number: %s\n", arg, strerror(errno)); + exit(1); + } + if(endptr != NULL && endptr[0] != 0) + { + fprintf(stderr, + "mknod: Extraneous characters in '%s' while parsing it as a number: '%s'\n", + arg, + endptr); + exit(1); + } + + return (unsigned int)dev; +} + +int +main(int argc, char *argv[]) +{ + mode_t mode = 0666; + + const char *errstr = NULL; + + int c = -1; + while((c = getopt(argc, argv, ":m:")) != -1) + { + switch(c) + { + case 'm': + mode = new_mode(optarg, 0666, &errstr); + if(errstr != NULL) + { + fprintf(stderr, "mknod: Failed parsing '%s': %s\n", optarg, errstr); + return 1; + } + break; + case ':': + fprintf(stderr, "mknod: Error: Missing operand for option: '-%c'\n", optopt); + usage(); + return 1; + case '?': + fprintf(stderr, "mknod: Error: Unrecognised option: '-%c'\n", optopt); + usage(); + return 1; + default: + abort(); + } + } + + argc -= optind; + argv += optind; + + assert(errno == 0); + + if(argc < 2) + { + fprintf(stderr, "mknod: Missing operands\n"); + usage(); + return 1; + } + + char *file = argv[0]; + char *type = argv[1]; + + if(type[0] == 0 || type[1] != 0) + { + fprintf(stderr, "mknod: Invalid type '%s'\n", type); + usage(); + return 1; + } + + assert(errno == 0); + if(type[0] == 'p') + { + if(mknod(file, mode | S_IFIFO, 0) != 0) + { + fprintf(stderr, "mknod: Failed creating FIFO at '%s': %s\n", file, strerror(errno)); + return 1; + } + } + else + { + if(argc != 4) + { + fprintf(stderr, "mknod: non-FIFO device types requires major minor arguments to be given\n"); + return 1; + } + + unsigned int maj = strtodev(argv[2]); + unsigned int min = strtodev(argv[3]); + + char *type_name; + switch(type[0]) + { + case 'b': + mode |= S_IFBLK; + type_name = "block-special"; + break; + case 'c': + mode |= S_IFCHR; + type_name = "character-special"; + break; + case 'u': + mode |= S_IFCHR; + type_name = "character-special"; + break; + default: + fprintf(stderr, "mknod: Invalid type '%c'\n", type[0]); + usage(); + return 1; + } + + if(mknod(file, mode, makedev(maj, min)) != 0) + { + fprintf(stderr, "mknod: Failed creating %s at '%s': %s\n", type_name, file, strerror(errno)); + return 1; + } + } + + return 0; +} diff --git a/coreutils.txt b/coreutils.txt @@ -45,7 +45,7 @@ ls: ? md5sum: No mkdir: Done mkfifo: ? -mknod: Todo +mknod: Done mktemp: Todo mv: Todo nice: Done diff --git a/lsb_commands.txt b/lsb_commands.txt @@ -79,7 +79,7 @@ man: out of scope md5sum: No mkdir: Done mkfifo: ? -mknod: Todo +mknod: Done mktemp: Todo more: No mount: out of scope diff --git a/makeless.sh b/makeless.sh @@ -25,6 +25,7 @@ $CC -std=c99 $CFLAGS -o cmd/id cmd/id.c $LDFLAGS $LDSTATIC $CC -std=c99 $CFLAGS -o cmd/link cmd/link.c $LDFLAGS $LDSTATIC $CC -std=c99 $CFLAGS -o cmd/logname cmd/logname.c $LDFLAGS $LDSTATIC $CC -std=c99 $CFLAGS -o cmd/mkdir cmd/mkdir.c lib/mode.c $LDFLAGS $LDSTATIC +$CC -std=c99 $CFLAGS -o cmd/mknod cmd/mknod.c lib/mode.c $LDFLAGS $LDSTATIC $CC -std=c99 $CFLAGS -o cmd/nice cmd/nice.c $LDFLAGS $LDSTATIC $CC -std=c99 $CFLAGS -o cmd/nohup cmd/nohup.c $LDFLAGS $LDSTATIC $CC -std=c99 $CFLAGS -o cmd/nproc cmd/nproc.c $LDFLAGS $LDSTATIC