From howardjp@wam.umd.edu Tue Aug 24 19:45:13 1999
Return-Path: <howardjp@wam.umd.edu>
Received: from po4.wam.umd.edu (po4.wam.umd.edu [128.8.10.166])
	by hub.freebsd.org (Postfix) with ESMTP id A429115193
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 24 Aug 1999 19:45:12 -0700 (PDT)
	(envelope-from howardjp@wam.umd.edu)
Received: from rac9.wam.umd.edu (root@rac9.wam.umd.edu [128.8.10.149])
	by po4.wam.umd.edu (8.9.3/8.9.3) with ESMTP id WAA08767
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 24 Aug 1999 22:42:17 -0400 (EDT)
Received: from rac9.wam.umd.edu (sendmail@localhost [127.0.0.1])
	by rac9.wam.umd.edu (8.9.3/8.9.3) with SMTP id WAA07678
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 24 Aug 1999 22:42:17 -0400 (EDT)
Received: (from howardjp@localhost)
	by rac9.wam.umd.edu (8.9.3/8.9.3) id WAA07674
	for FreeBSD-gnats-submit@freebsd.org; Tue, 24 Aug 1999 22:42:16 -0400 (EDT)
Message-Id: <199908250242.WAA07674@rac9.wam.umd.edu>
Date: Tue, 24 Aug 1999 22:42:16 -0400 (EDT)
From: James Howard <howardjp@wam.umd.edu>
Reply-To: howardjp@wam.umd.edu
To: FreeBSD-gnats-submit@freebsd.org
Subject: Patch to mkfifo(1) for Unix 98 compliance
X-Send-Pr-Version: 3.2

>Number:         13365
>Category:       bin
>Synopsis:       Patch to mkfifo(1) for Unix 98 compliance
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    sheldonh
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Tue Aug 24 19:50:01 PDT 1999
>Closed-Date:    Mon Dec 20 08:40:47 PST 1999
>Last-Modified:  Mon Dec 20 08:41:46 PST 1999
>Originator:     James Howard
>Release:        FreeBSD 3.2-STABLE i386
>Organization:
University of Maryland
>Environment:

FreeBSD byzantine 3.2-STABLE FreeBSD 3.2-STABLE #5: Sat Aug  7 23:43:54 GMT 1999     root@byzantine:/usr/src/sys/compile/BYZANTINE  i386
	
>Description:

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

>Fix:
	
diff -c /usr/src/usr.bin/mkfifo/mkfifo.1 /usr/local/src/mkfifo/mkfifo.1
*** /usr/src/usr.bin/mkfifo/mkfifo.1	Sun Apr 27 08:45:45 1997
--- /usr/local/src/mkfifo/mkfifo.1	Tue Aug 24 18:53:24 1999
***************
*** 43,48 ****
--- 43,49 ----
  .Nd make fifos
  .Sh SYNOPSIS
  .Nm
+ .Op Fl m Ar mode
  .Ar fifo_name  ...
  .Sh DESCRIPTION
  The
***************
*** 54,59 ****
--- 55,77 ----
  The
  .Nm
  command requires write permission in the parent directory.
+ .Pp
+ The options are as follows
+ .Pp
+ .Bl -tag -width indent
+ .It Fl m
+ Set the file permission bits of the final created directory to
+ the specified mode.
+ The mode argument can be in any of the formats specified to the
+ .Xr chmod 1
+ command.
+ If a symbolic mode is specified, the operation characters
+ .Dq +
+ and
+ .Dq -
+ are interpreted relative to an initial mode of
+ .Dq a=rwx .
+ .El
  .Pp
  The
  .Nm
diff -c /usr/src/usr.bin/mkfifo/mkfifo.c /usr/local/src/mkfifo/mkfifo.c
*** /usr/src/usr.bin/mkfifo/mkfifo.c	Thu Jul 24 07:02:55 1997
--- /usr/local/src/mkfifo/mkfifo.c	Tue Aug 24 19:11:30 1999
***************
*** 50,55 ****
--- 50,56 ----
  
  #include <err.h>
  #include <stdio.h>
+ #include <stdlib.h>
  #include <string.h>
  #include <unistd.h>
  
***************
*** 61,70 ****
  	char *argv[];
  {
  	extern int optind;
! 	int ch, exitval;
  
! 	while ((ch = getopt(argc, argv, "")) != -1)
  		switch(ch) {
  		case '?':
  		default:
  			usage();
--- 62,77 ----
  	char *argv[];
  {
  	extern int optind;
! 	int ch, exitval, omode, success;
! 	mode_t *set = (mode_t *)NULL;
! 	char *mode;
  
! 	mode = NULL;
! 	while ((ch = getopt(argc, argv, "m:")) != -1)
  		switch(ch) {
+ 		case 'm':
+ 			mode = optarg;
+ 			break;
  		case '?':
  		default:
  			usage();
***************
*** 74,84 ****
  	if (argv[0] == NULL)
  		usage();
  
! 	for (exitval = 0; *argv != NULL; ++argv)
! 		if (mkfifo(*argv, S_IRWXU | S_IRWXG | S_IRWXO) < 0) {
  			warn("%s", *argv);
! 			exitval = 1;
  		}
  	exit(exitval);
  }
  
--- 81,116 ----
  	if (argv[0] == NULL)
  		usage();
  
! 	if (mode == NULL) {
!                 omode = S_IRWXU | S_IRWXG | S_IRWXO;
!         } else {
!                 if ((set = setmode(mode)) == NULL)
!                         errx(1, "invalid file mode: %s", mode);
!                 omode = getmode(set, S_IRWXU | S_IRWXG | S_IRWXO);
!                 free(set);
!         }
! 
! 	for (exitval = 0; *argv != NULL; ++argv) {
! 		success = 1;
! 		if (mkfifo(*argv, omode) < 0) {
  			warn("%s", *argv);
! 			success = 0;
  		}
+ 		if (!success)
+ 			exitval = 1;
+ 		/*
+                  * The mkdir() and umask() calls both honor only the low
+                  * nine bits, so if you try to set a mode including the
+                  * sticky, setuid, setgid bits you lose them.  Don't do
+                  * this unless the user has specifically requested a mode,
+                  * as chmod will (obviously) ignore the umask.
+                  */
+                 if (success && mode != NULL && chmod(*argv, omode) == -1) {
+                         warn("%s", *argv);
+                         exitval = 1;
+                 }
+         }
+ 	
  	exit(exitval);
  }
  

>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->sheldonh 
Responsible-Changed-By: sheldonh 
Responsible-Changed-When: Thu Aug 26 02:41:45 PDT 1999 
Responsible-Changed-Why:  
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. 

From: Sheldon Hearn <sheldonh@uunet.co.za>
To: freebsd-gnats-submit@freebsd.org
Cc: freebsd-bugs@freebsd.org
Subject: Re: bin/13365: Patch to mkfifo(1) for Unix 98 compliance
Date: Thu, 26 Aug 1999 13:49:49 +0200

 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);
  }
 

From: Sheldon Hearn <sheldonh@uunet.co.za>
To: James Howard <howardjp@wam.umd.edu>
Cc: freebsd-gnats-submit@freebsd.org
Subject: Re: bin/13365: Patch to mkfifo(1) for Unix 98 compliance 
Date: Thu, 26 Aug 1999 17:57:21 +0200

 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);
  }
 

From: James Howard <howardjp@wam.umd.edu>
To: Sheldon Hearn <sheldonh@uunet.co.za>
Cc: freebsd-gnats-submit@freebsd.org
Subject: Re: bin/13365: Patch to mkfifo(1) for Unix 98 compliance 
Date: Thu, 26 Aug 1999 22:35:18 -0400 (EDT)

 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
 
 
State-Changed-From-To: open->analyzed 
State-Changed-By: sheldonh 
State-Changed-When: Fri Aug 27 03:52:55 PDT 1999 
State-Changed-Why:  
Committed to CURRENT, left in this state for MFC later. 
State-Changed-From-To: analyzed->closed 
State-Changed-By: sheldonh 
State-Changed-When: Mon Dec 20 08:40:47 PST 1999 
State-Changed-Why:  
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. 
>Unformatted:
