[GNU Manual] [No POSIX requirement] [Linux man] [FreeBSD man]
Summary
mknod - make block or character special files
Lines of code: 276
Principal syscall: mknod(), mkfifo() (BSD)
Support syscalls: fchmodat() via lchmod()
for links
Options: 6 (2 short, 4 long)
Descended from mknod introduced in Version 6 UNIX (1975)
Added to Fileutils in October 1992 [First version]
Number of revisions: 143 [Code Evolution]
The mknod utility wraps the syscall of the same name. It may parse major/minor numbers and handle the security context.
Helpers:- None
defaultcon()
- Gets the security context label of the inputdie()
- Exit with mandatory non-zero error and message to stderrerror()
- Outputs error message to standard error with possible process terminationmakedev()
- Produces a device ID from a major and minor numbersetfscreatecon()
- Sets the context for a new filesystem objectsmack_set_label_for_self()
- Sets security label for the current process
Setup
mknod initializes local variables in main()
, including:
newmode
- A file mode in UGO format*specified_mode
- A file mode as input by the userexit_status
- Utility exit status (EXIT_*)optc
- The next option to process*scontext
- The user specified security contextset_security_context
- Flag to check security context labels in SELinux
Parsing
Parsing mknod performs a bit more work than a typical utility because the user provides a more input than options and targets. This requires a more robust sanity checking phase than simply verifying options and boundaries. First, parsing collects options to answer questions, including:
- What access mode is the named pipe?
- Are there security considerations? (SELinux / Smack)
Parsing failures
These failure cases are explicitly checked:
- Permission type is invalid
- The operand counts must make sense:
- Including a major and minor device number for a fifo
- Not including a major and minor device number for a special file
This failure result in a short error message followed by the usage instructions.
Execution
The utility has some work to do to properly parse the input arguments in to a form usable by the mknod()
syscall. The syscall has this prototype:
int mknod(const char *path, mode_t mode, dev_t dev);
While the user passes this to the utility:
mknod [option]… name type [major minor]
You can see the relationship between 'name', and the path. Combine that with the type and we can derive the mode (permissions). Finally the 'major' and 'minor' components lead to a 'dev'.
The mknod
utility execution sequence looks like this:
- If the user specified a security context, attempt to set the next context
- For block and character devices:
- Parse the major and minor numbers
- Call
makedev()
(alias forgnu_dev_makedev()
in libc) for a device_id - Set the security context
- Call
mknod()
using the target, mode, and device
- For Pipes/FIFOs:
- Set the security context
- Call
mkfifo()
using the target and mode
- Return exit status (any failure forces EXIT_FAILURE)
mknod execution may fail in several cases:
- Invalid major and minor numbers
- Invalid device specified
makedev()
ormknod()
fails- Unable to set permissions
- System specified special files not supported
- Unable to set security context