micro-utils/coreutils/mknod.c
2023-11-02 12:51:20 +03:00

80 lines
1.5 KiB
C

#ifdef __linux__
#include <sys/sysmacros.h>
#endif
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include "parse_mode.h"
long parse_int(const char *str) {
char *ptr = NULL;
long value = strtol(str, &ptr, 10);
if (*ptr) {
fprintf(stderr, "mknod: not a number: %s\n", str);
exit(1);
}
else if (value < 1) {
fprintf(stderr, "mknod: number is negative: %s\n", str);
exit(1);
}
return value;
}
int main(const int argc, const char **argv) {
mode_t mode = 0666;
int i;
for (i = 1; i < argc; i++) {
if (argv[i][0] != '-')
break;
else if (!strncmp("-m=", argv[i], 3))
mode = mu_parse_mode(argv[i] + 3, 0);
}
long major = 0;
long minor = 0;
dev_t dev = 0;
if (argc - i >= 2 && argc - i != 3) {
if (argc - i == 4) {
major = parse_int(argv[i + 2]);
minor = parse_int(argv[i + 3]);
dev = makedev(major, minor);
}
if (!strncmp("b", argv[i + 1], 1))
mode |= S_IFBLK;
else if (!strncmp("c", argv[i + 1], 1) || !strncmp("u", argv[i + 1], 1))
mode |= S_IFCHR;
else if (!strncmp("p", argv[i + 1], 1))
mode |= S_IFIFO;
else if (!strncmp("s", argv[i + 1], 1))
mode |= S_IFSOCK;
if (mknod(argv[i], mode, dev) < 0) {
fprintf(stderr, "mknod: %s\n", strerror(errno));
return 1;
}
}
else {
printf("mknod [-m=mode] [NAME] [TYPE] [MAJOR MINOR]\n");
printf("Types:\n b - block device\n c or u - character device\n p - named pipe/fifo (MAJOR MINOR must be omitted)\n s - socket\n");
return 0;
}
return 0;
}