master xplshn/aruu / cmd / xsi / mknod.c
 1/* See LICENSE file for copyright and license details. */
 2#include <sys/stat.h>
 3#include <sys/types.h>
 4
 5#include <stdio.h>
 6#include <stdlib.h>
 7#include <string.h>
 8#include <unistd.h>
 9
10#include "util.h"
11
12#ifndef makedev
13#include <sys/sysmacros.h>
14#endif
15
16static void
17usage(void)
18{
19  eprintf(
20      "usage: %s [-m mode] name b|c|u major minor\n"
21      "       %s [-m mode] name p\n",
22      argv0,
23      argv0
24  );
25}
26
27// ?man mknod: create special files
28// ?man arguments: name type [major minor]
29// ?man create a block special, character special, or fifo file
30int
31main(int argc, char *argv[])
32{
33  mode_t mode = 0666;
34  dev_t  dev;
35
36  ARGBEGIN
37  {
38    case 'm':
39      // ?man -m:mode: set the file mode bits of the created node
40      mode = parsemode(EARGF(usage()), mode, umask(0));
41      break;
42    default:
43      usage();
44  }
45  ARGEND
46
47  if (argc < 2)
48    usage();
49
50  if (strlen(argv[1]) != 1)
51    goto invalid;
52  switch (argv[1][0]) {
53    case 'b':
54      mode |= S_IFBLK;
55      break;
56    case 'u':
57    case 'c':
58      mode |= S_IFCHR;
59      break;
60    case 'p':
61      mode |= S_IFIFO;
62      break;
63    default:
64    invalid:
65      eprintf("invalid type '%s'\n", argv[1]);
66  }
67
68  if (S_ISFIFO(mode)) {
69    if (argc != 2)
70      usage();
71    dev = 0;
72  } else {
73    if (argc != 4)
74      usage();
75    dev = makedev(estrtonum(argv[2], 0, LLONG_MAX), estrtonum(argv[3], 0, LLONG_MAX));
76  }
77
78  if (mknod(argv[0], mode, dev) == -1)
79    eprintf("mknod %s:", argv[0]);
80  return 0;
81}