diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-05-03 22:59:58 +0200 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-05-03 22:59:58 +0200 |
commit | 8b249bd09bc63ad3a9aa99cc268299f0239b2f7d (patch) | |
tree | 345d460dd10fdbb34bc6e6cc283fe51a33095391 /Userland/mknod.cpp | |
parent | abb5c890e0960fa00cb566a9905e13cba078972b (diff) | |
download | serenity-8b249bd09bc63ad3a9aa99cc268299f0239b2f7d.zip |
Kernel+Userland: Implement mknod() syscall and add a /bin/mknod program.
Diffstat (limited to 'Userland/mknod.cpp')
-rw-r--r-- | Userland/mknod.cpp | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/Userland/mknod.cpp b/Userland/mknod.cpp new file mode 100644 index 0000000000..dc1221b51d --- /dev/null +++ b/Userland/mknod.cpp @@ -0,0 +1,50 @@ +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/stat.h> + +inline constexpr unsigned encoded_device(unsigned major, unsigned minor) +{ + return (minor & 0xff) | (major << 8) | ((minor & ~0xff) << 12); +} + +static int usage() +{ + printf("usage: mknod <name> <c|b|p> <major> <minor>\n"); + return 0; +} + +int main(int argc, char** argv) +{ + // FIXME: When invoked with type "p", no need for major/minor numbers. + // FIXME: Add some kind of option for specifying the file permissions. + if (argc != 5) + return usage(); + + const char* name = argv[1]; + mode_t mode = 0666; + switch (argv[2][0]) { + case 'c': + case 'u': + mode |= S_IFCHR; + break; + case 'b': + mode |= S_IFBLK; + break; + case 'p': + mode |= S_IFIFO; + break; + default: + return usage(); + } + + int major = atoi(argv[3]); + int minor = atoi(argv[4]); + + int rc = mknod(name, mode, encoded_device(major, minor)); + if (rc < 0) { + perror("mknod"); + return 1; + } + return 0; +} |