Bug 13365

Summary: Patch to mkfifo(1) for Unix 98 compliance
Product: Base System Reporter: howardjp <howardjp>
Component: binAssignee: Sheldon Hearn <sheldonh>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 3.2-STABLE   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
file.diff none

Description howardjp 1999-08-25 03:50:01 UTC
Unix 98 requires that mkfifo(1) take an argument -m.  If this
argument is given, it is followed by a string which specifies
the mode which the FIFO will be set to.  The behaviour is 
identical to the -m argument to mkdir(1).  Consquently, the 
changes to mkfifo were derived from mkdir.  Apply the diff 
below to /usr/src/usr.bin/mkfifo to update mkfifo.c and 
mkfifo.1.

How-To-Repeat: 
mkfifo -m gives an illegal option error
Comment 1 Sheldon Hearn freebsd_committer freebsd_triage 1999-08-26 10:41:45 UTC
Responsible Changed
From-To: freebsd-bugs->sheldonh

I'll take this one. I've passed a simpler solution on to James 
to have a look at and I'm waiting for his feedback. 

Comment 2 Sheldon Hearn 1999-08-26 12:49:49 UTC
This is the patch I intend to apply. I'm waiting for feedback from
freebsd-hackers on whether executable/sticky bits on pipes mean anything
special in FreeBSD.

Ciao,
Sheldon.

Index: mkfifo.1
===================================================================
RCS file: /home/ncvs/src/usr.bin/mkfifo/mkfifo.1,v
retrieving revision 1.4
diff -u -d -r1.4 mkfifo.1
--- mkfifo.1	1997/04/27 08:45:45	1.4
+++ mkfifo.1	1999/08/26 10:29:57
@@ -43,13 +43,33 @@
 .Nd make fifos
 .Sh SYNOPSIS
 .Nm
+.Op Fl m Ar mode
 .Ar fifo_name  ...
 .Sh DESCRIPTION
 The
 .Nm
 command creates the fifos requested, in the order specified,
-using mode
-.Li \&0777 .
+using a default mode
+.Li \&0666
+modified by the current
+.Xr umask 2 .
+.Pp
+The options are as follows:
+.Bl -tag -width indent
+.It Fl m
+Set the file permission bits of the created fifos to the
+specified mode.
+The mode argument takes any format that can be specified to the
+.Xr chmod 1
+command.
+If a symbolic mode is specified, the op symbols
+.Dq +
+(plus) and
+.Dq -
+(hyphen) are interpreted relative to an assumed initial mode of
+.Dq a=rw
+(read and write permissions for all). 
+.El
 .Pp
 The
 .Nm
Index: mkfifo.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/mkfifo/mkfifo.c,v
retrieving revision 1.3
diff -u -d -r1.3 mkfifo.c
--- mkfifo.c	1997/07/24 07:02:55	1.3
+++ mkfifo.c	1999/08/26 11:13:16
@@ -49,22 +49,33 @@
 #include <sys/stat.h>
 
 #include <err.h>
+#include <errno.h>
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
 
 static void usage __P((void));
 
+static int f_mode;
+static const mode_t basemode = (S_IRWXU & ~S_IXUSR | S_IRWXG & ~S_IXGRP |
+				S_IRWXO & ~S_IXOTH);
+
 int
 main(argc, argv)
 	int argc;
 	char *argv[];
 {
-	extern int optind;
 	int ch, exitval;
+	char *modestr;
+	void *mode;
+	mode_t creatmode;
 
-	while ((ch = getopt(argc, argv, "")) != -1)
+	while ((ch = getopt(argc, argv, "m:")) != -1)
 		switch(ch) {
+		case 'm':
+			f_mode = 1;
+			modestr = optarg;
+			break;
 		case '?':
 		default:
 			usage();
@@ -74,8 +85,21 @@
 	if (argv[0] == NULL)
 		usage();
 
+	if (f_mode) {
+		errno = 0;
+		if ((mode = setmode(modestr)) == NULL) {
+			if (errno)
+				err(1, NULL);
+			else
+				errx(1, "invalid file mode: %s", modestr);
+		}
+		creatmode = getmode(mode, basemode);
+	} else {
+		creatmode = basemode;
+	}
+
 	for (exitval = 0; *argv != NULL; ++argv)
-		if (mkfifo(*argv, S_IRWXU | S_IRWXG | S_IRWXO) < 0) {
+		if (mkfifo(*argv, creatmode) < 0) {
 			warn("%s", *argv);
 			exitval = 1;
 		}
@@ -85,6 +109,6 @@
 static void
 usage()
 {
-	(void)fprintf(stderr, "usage: mkfifo fifoname ...\n");
+	(void)fprintf(stderr, "usage: mkfifo [-m mode] fifoname ...\n");
 	exit(1);
 }
Comment 3 Sheldon Hearn 1999-08-26 16:57:21 UTC
On Thu, 26 Aug 1999 11:32:39 -0400, James Howard wrote:

> The other option is to set the umask to zero before calling mkfifo.  But
> mangling umasks amd permissions in a utility seems even uglier.

We're already mangling permissions. That ugliness seems to be mandated
by the Single UNIX spec. Since the -m option is required to ignore the
umask(2) and our mkfifo(2) syscall does _not_ ignore the umask(2),
mangling the umask(2) is necessary.

Here's the patch with a call to umask(2) added and the manpage's
description of the -m flag updated appropriately.

Ciao,
Sheldon.

Index: mkfifo.1
===================================================================
RCS file: /home/ncvs/src/usr.bin/mkfifo/mkfifo.1,v
retrieving revision 1.4
diff -u -d -r1.4 mkfifo.1
--- mkfifo.1	1997/04/27 08:45:45	1.4
+++ mkfifo.1	1999/08/26 15:54:19
@@ -43,14 +43,39 @@
 .Nd make fifos
 .Sh SYNOPSIS
 .Nm
+.Op Fl m Ar mode
 .Ar fifo_name  ...
 .Sh DESCRIPTION
 The
 .Nm
-command creates the fifos requested, in the order specified,
-using mode
-.Li \&0777 .
+command creates the fifos requested, in the order specified.
 .Pp
+The options are as follows:
+.Bl -tag -width indent
+.It Fl m
+Set the file permission bits of the created fifos to the
+specified mode, ignoring the
+.Xr umask 2
+of the calling process.
+The mode argument takes any format that can be specified to the
+.Xr chmod 1
+command.
+If a symbolic mode is specified, the op symbols
+.Dq +
+(plus) and
+.Dq -
+(hyphen) are interpreted relative to an assumed initial mode of
+.Dq a=rw
+(read and write permissions for all). 
+.El
+.Pp
+If the
+.Fl m
+option is not specified, fifos are created with mode
+.Li \&0666
+modified by the
+.Xr umask 2
+of the calling process.
 The
 .Nm
 command requires write permission in the parent directory.
Index: mkfifo.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/mkfifo/mkfifo.c,v
retrieving revision 1.3
diff -u -d -r1.3 mkfifo.c
--- mkfifo.c	1997/07/24 07:02:55	1.3
+++ mkfifo.c	1999/08/26 15:47:48
@@ -49,22 +49,33 @@
 #include <sys/stat.h>
 
 #include <err.h>
+#include <errno.h>
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
 
 static void usage __P((void));
 
+static int f_mode;
+static const mode_t basemode = (S_IRWXU & ~S_IXUSR | S_IRWXG & ~S_IXGRP |
+				S_IRWXO & ~S_IXOTH);
+
 int
 main(argc, argv)
 	int argc;
 	char *argv[];
 {
-	extern int optind;
 	int ch, exitval;
+	char *modestr;
+	void *mode;
+	mode_t creatmode;
 
-	while ((ch = getopt(argc, argv, "")) != -1)
+	while ((ch = getopt(argc, argv, "m:")) != -1)
 		switch(ch) {
+		case 'm':
+			f_mode = 1;
+			modestr = optarg;
+			break;
 		case '?':
 		default:
 			usage();
@@ -74,8 +85,22 @@
 	if (argv[0] == NULL)
 		usage();
 
+	if (f_mode) {
+		umask(0);
+		errno = 0;
+		if ((mode = setmode(modestr)) == NULL) {
+			if (errno)
+				err(1, NULL);
+			else
+				errx(1, "invalid file mode: %s", modestr);
+		}
+		creatmode = getmode(mode, basemode);
+	} else {
+		creatmode = basemode;
+	}
+
 	for (exitval = 0; *argv != NULL; ++argv)
-		if (mkfifo(*argv, S_IRWXU | S_IRWXG | S_IRWXO) < 0) {
+		if (mkfifo(*argv, creatmode) < 0) {
 			warn("%s", *argv);
 			exitval = 1;
 		}
@@ -85,6 +110,6 @@
 static void
 usage()
 {
-	(void)fprintf(stderr, "usage: mkfifo fifoname ...\n");
+	(void)fprintf(stderr, "usage: mkfifo [-m mode] fifoname ...\n");
 	exit(1);
 }
Comment 4 howardjp 1999-08-27 03:35:18 UTC
On Thu, 26 Aug 1999, Sheldon Hearn wrote:

> Here's the patch with a call to umask(2) added and the manpage's
> description of the -m flag updated appropriately.
> 
> ...

Yes, I beleive this is correct.  :)

Jamie
Comment 5 Sheldon Hearn freebsd_committer freebsd_triage 1999-08-27 11:52:55 UTC
State Changed
From-To: open->analyzed

Committed to CURRENT, left in this state for MFC later. 
Comment 6 Sheldon Hearn freebsd_committer freebsd_triage 1999-12-20 16:40:47 UTC
State Changed
From-To: analyzed->closed

Damn, I left this in the wrong state for MFC.  Since it missed 
3.4-RELEASE, and since there isn't going to be another release 
thereafter on the RELENG_3 line, an MFC now  would be silly.