diff options
Diffstat (limited to '')
-rw-r--r-- | usr/utils/mknod.c | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/usr/utils/mknod.c b/usr/utils/mknod.c new file mode 100644 index 0000000..fa7ac7a --- /dev/null +++ b/usr/utils/mknod.c @@ -0,0 +1,84 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> + +char *progname; + +static __noreturn usage(void) +{ + fprintf(stderr, "Usage: %s [-m mode] name {b|c|p} major minor\n", + progname); + exit(1); +} + +int main(int argc, char *argv[]) +{ + char *name, *type, typec, *endp; + unsigned int major_num, minor_num; + mode_t mode, mode_set = 0; + dev_t dev; + + progname = *argv++; + if (argc == 1) + usage(); + + if (argv[0][0] == '-' && argv[0][1] == 'm' && !argv[0][2]) { + mode_set = strtoul(argv[1], &endp, 8); + argv += 2; + } + + name = *argv++; + if (!name) + usage(); + + type = *argv++; + if (!type || !type[0] || type[1]) + usage(); + typec = type[0]; + + mode = 0; + switch (typec) { + case 'c': + mode = S_IFCHR; + break; + case 'b': + mode = S_IFBLK; + break; + case 'p': + mode = S_IFIFO; + break; + default: + usage(); + } + + if (mode == S_IFIFO) { + dev = 0; + } else { + if (!argv[0] || !argv[1]) + usage(); + + major_num = strtol(*argv++, &endp, 0); + if (*endp != '\0') + usage(); + minor_num = strtol(*argv++, &endp, 0); + if (*endp != '\0') + usage(); + dev = makedev(major_num, minor_num); + } + + if (*argv) + usage(); + + if (mknod(name, mode|0666, dev) == -1) { + perror("mknod"); + exit(1); + } + + if (mode_set && chmod(name, mode_set)) { + perror("chmod"); + exit(1); + } + + exit(0); +} |