1 /* mknod -- make special files
2 Copyright (C) 90, 91, 1995-1999 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18 /* Usage: mknod [-m mode] [--mode=mode] path {bcu} major minor
19 make a block or character device node
20 mknod [-m mode] [--mode=mode] path p
21 make a FIFO (named pipe)
24 -m, --mode=mode Set the mode of created nodes to MODE, which is
25 symbolic as in chmod and uses the umask as a point of
28 David MacKenzie <djm@ai.mit.edu> */
33 #include <sys/types.h>
38 #include "long-options.h"
39 #include "modechange.h"
42 /* The name this program was run with. */
45 static struct option const longopts[] =
47 {"mode", required_argument, NULL, 'm'},
55 fprintf (stderr, _("Try `%s --help' for more information.\n"),
59 printf (_("Usage: %s [OPTION]... NAME TYPE [MAJOR MINOR]\n"), program_name);
61 Create the special file NAME of the given TYPE.\n\
63 -m, --mode=MODE set permission mode (as in chmod), not 0666 - umask\n\
64 --help display this help and exit\n\
65 --version output version information and exit\n\
67 MAJOR MINOR are forbidden for TYPE p, mandatory otherwise. TYPE may be:\n\
69 b create a block (buffered) special file\n\
70 c, u create a character (unbuffered) special file\n\
73 puts (_("\nReport bugs to <bug-fileutils@gnu.org>."));
80 main (int argc, char **argv)
82 unsigned short newmode;
83 struct mode_change *change;
87 long int tmp_major, tmp_minor;
90 program_name = argv[0];
91 setlocale (LC_ALL, "");
92 bindtextdomain (PACKAGE, LOCALEDIR);
95 parse_long_options (argc, argv, "mknod", GNU_PACKAGE, VERSION,
96 "David MacKenzie", usage);
100 while ((optc = getopt_long (argc, argv, "m:", longopts, NULL)) != -1)
107 symbolic_mode = optarg;
114 newmode = 0666 & ~umask (0);
117 change = mode_compile (symbolic_mode, 0);
118 if (change == MODE_INVALID)
119 error (1, 0, _("invalid mode"));
120 else if (change == MODE_MEMORY_EXHAUSTED)
121 error (1, 0, _("virtual memory exhausted"));
122 newmode = mode_adjust (newmode, change);
125 if (argc - optind != 2 && argc - optind != 4)
128 if (argc - optind < 2)
129 msg = _("too few arguments");
130 else if (argc - optind > 4)
131 msg = _("too many arguments");
133 msg = _("wrong number of arguments");
138 /* Only check the first character, to allow mnemonic usage like
139 `mknod /dev/rst0 character 18 0'. */
141 switch (argv[optind + 1][0])
143 case 'b': /* `block' or `buffered' */
145 error (4, 0, _("block special files not supported"));
147 if (argc - optind != 4)
150 when creating block special files, major and minor device\n\
151 numbers must be specified"));
155 s = argv[optind + 2];
156 if (xstrtol (s, NULL, 0, &tmp_major, NULL) != LONGINT_OK)
157 error (1, 0, _("invalid major device number `%s'"), s);
159 s = argv[optind + 3];
160 if (xstrtol (s, NULL, 0, &tmp_minor, NULL) != LONGINT_OK)
161 error (1, 0, _("invalid minor device number `%s'"), s);
163 i_major = (int) tmp_major;
164 i_minor = (int) tmp_minor;
166 if (mknod (argv[optind], newmode | S_IFBLK, makedev (i_major, i_minor)))
167 error (1, errno, "%s", argv[optind]);
171 case 'c': /* `character' */
172 case 'u': /* `unbuffered' */
174 error (4, 0, _("character special files not supported"));
176 if (argc - optind != 4)
179 when creating character special files, major and minor device\n\
180 numbers must be specified"));
184 s = argv[optind + 2];
185 if (xstrtol (s, NULL, 0, &tmp_major, NULL) != LONGINT_OK)
186 error (1, 0, _("invalid major device number `%s'"), s);
188 s = argv[optind + 3];
189 if (xstrtol (s, NULL, 0, &tmp_minor, NULL) != LONGINT_OK)
190 error (1, 0, _("invalid minor device number `%s'"), s);
192 i_major = (int) tmp_major;
193 i_minor = (int) tmp_minor;
195 if (mknod (argv[optind], newmode | S_IFCHR, makedev (i_major, i_minor)))
196 error (1, errno, "%s", argv[optind]);
200 case 'p': /* `pipe' */
202 error (4, 0, _("fifo files not supported"));
204 if (argc - optind != 2)
207 major and minor device numbers may not be specified for fifo files"));
210 if (mkfifo (argv[optind], newmode))
211 error (1, errno, "%s", argv[optind]);