From tetsuya@secom-sis.co.jp  Thu Aug  7 01:25:46 1997
Received: from secom-sis.co.jp (spiral.secom-sis.co.jp [202.218.246.72])
          by hub.freebsd.org (8.8.5/8.8.5) with ESMTP id BAA27145
          for <FreeBSD-gnats-submit@FreeBSD.ORG>; Thu, 7 Aug 1997 01:25:45 -0700 (PDT)
Received: from secom-sis.co.jp ([172.27.9.50]) by spiral.secom-sis.co.jp with ESMTP id <35716-1>; Thu, 7 Aug 1997 17:25:23 +0900
Received: from juria.secom-sis.co.jp (juria.secom-sis.co.jp [172.27.2.16]) by secom-sis.co.jp (8.8.4/3.5Wpl1) with ESMTP id RAA19385 for <FreeBSD-gnats-submit@freebsd.org>; Thu, 7 Aug 1997 17:30:04 +0900 (JST)
Received: (from tetsuya@localhost) by juria.secom-sis.co.jp (8.8.6/3.5Wpl7-19970626s) id RAA10674; Thu, 7 Aug 1997 17:25:16 +0900 (JST)
Message-Id: <199708070825.RAA10674@juria.secom-sis.co.jp>
Date: Thu, 7 Aug 1997 17:25:16 +0900
From: tetsuya@secom-sis.co.jp
Reply-To: tetsuya@secom-sis.co.jp
To: FreeBSD-gnats-submit@FreeBSD.ORG
Subject: file locking doesn't work for pipe
X-Send-Pr-Version: 3.2

>Number:         4243
>Category:       kern
>Synopsis:       file locking doesn't work for pipe
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Aug  7 01:30:01 PDT 1997
>Closed-Date:    Sun Jun 02 04:28:35 PDT 2002
>Last-Modified:  Sun Jun 02 04:28:35 PDT 2002
>Originator:     Tetsuya Furukawa
>Release:        FreeBSD 2.2-STABLE i386
>Organization:
Secom Information System Co.,Ltd.
>Environment:
FreeBSD 2.2-STABLE i386 on July 11, 1997

>Description:
In flock() in /sys/kern/kern_descrip.c, the following statement:

    f (fp->f_type != DTYPE_VNODE)
	    return (EOPNOTSUPP);

rejects the file descriptor if fp->f_type == DTYPE_PIPE.
F_SETLK and F_GETLK of fcntl() have also the similar statements.

"Program rewriting map" (RewriteMap mapname prg:filename) of
the URL rewriting module (mod_rewrite) of the Apache HTTP server
uses file locking for pipe, so FreeBSD users cannot use the fine
feature of "program rewriting map".

>How-To-Repeat:
The following program prints "flock: Operation not supported".

--------
#include <sys/file.h>
#include <stdio.h>
#include <unistd.h>

int
main()
{
    int fds[2];
    char c;

    pipe(fds);
    if (flock(fds[1], LOCK_EX) == -1)
	perror("flock");
    write(fds[1], "a", 1);
    read(fds[0], &c, 1);
    return 0;
}
--------

>Fix:
Maybe, modify the three lines like

    if (fp->f_type != DTYPE_VNODE)

into

    if (fp->f_type != DTYPE_VNODE && fp->f_type != DTYPE_PIPE)

I have not tried it, and I'm not convinced that it is safe and right
for I don't know detail of the kernel.

>Release-Note:
>Audit-Trail:

From: David Greenman <dg@root.com>
To: tetsuya@secom-sis.co.jp
Cc: FreeBSD-gnats-submit@FreeBSD.ORG
Subject: Re: kern/4243: file locking doesn't work for pipe 
Date: Thu, 07 Aug 1997 05:22:17 -0700

 >In flock() in /sys/kern/kern_descrip.c, the following statement:
 >
 >    f (fp->f_type != DTYPE_VNODE)
 >	    return (EOPNOTSUPP);
 >
 >rejects the file descriptor if fp->f_type == DTYPE_PIPE.
 >F_SETLK and F_GETLK of fcntl() have also the similar statements.
 >
 >"Program rewriting map" (RewriteMap mapname prg:filename) of
 >the URL rewriting module (mod_rewrite) of the Apache HTTP server
 >uses file locking for pipe, so FreeBSD users cannot use the fine
 >feature of "program rewriting map".
 
    Hmmm. Maybe I'm missing something obvious, but I can't think of a reason
 why one would want to do file locking on a pipe (which is not a shared
 resource). This sounds like a bug in Apache to me...
 
 -DG
 
 David Greenman
 Core-team/Principal Architect, The FreeBSD Project

From: Peter Wemm <peter@spinner.dialix.com.au>
To: David Greenman <dg@root.com>
Cc: tetsuya@secom-sis.co.jp, FreeBSD-gnats-submit@FreeBSD.ORG
Subject: Re: kern/4243: file locking doesn't work for pipe 
Date: Thu, 07 Aug 1997 22:12:12 +0800

 David Greenman wrote:
 >  >In flock() in /sys/kern/kern_descrip.c, the following statement:
 >  >
 >  >    f (fp->f_type != DTYPE_VNODE)
 >  >	    return (EOPNOTSUPP);
 >  >
 >  >rejects the file descriptor if fp->f_type == DTYPE_PIPE.
 >  >F_SETLK and F_GETLK of fcntl() have also the similar statements.
 >  >
 >  >"Program rewriting map" (RewriteMap mapname prg:filename) of
 >  >the URL rewriting module (mod_rewrite) of the Apache HTTP server
 >  >uses file locking for pipe, so FreeBSD users cannot use the fine
 >  >feature of "program rewriting map".
 >  
 >     Hmmm. Maybe I'm missing something obvious, but I can't think of a reason
 >  why one would want to do file locking on a pipe (which is not a shared
 >  resource). This sounds like a bug in Apache to me...
 
 It's been around for a while..  I've also seen it used to syncronise 
 multiple listeners on the same socket on systems where it's not safe to 
 listen on a socket, fork N children and have them all do an accept().  I 
 don't remember where I saw that first, but I'm pretty sure I've seen it in 
 use on one of the http daemons, possibly the NCSA one or early apache code.
 
 Yeah, it's kinda nonsensical, but useful in certain situations where the 
 same fd is shared between processes. If we could support it without too 
 much effort it'd be kinda handy.
 
 >  -DG
 >  
 >  David Greenman
 >  Core-team/Principal Architect, The FreeBSD Project
 > 
 
 Cheers,
 -Peter
 
 

From: Marc Slemko <marcs@znep.com>
To: David Greenman <dg@root.com>
Cc: freebsd-gnats-submit@freebsd.org
Subject: Re: kern/4243: file locking doesn't work for pipe 
Date: Thu, 7 Aug 1997 05:22:34 -0600 (MDT)

 On Thu, 7 Aug 1997, David Greenman wrote:
 
 >     Hmmm. Maybe I'm missing something obvious, but I can't think of a reason
 >  why one would want to do file locking on a pipe (which is not a shared
 >  resource). This sounds like a bug in Apache to me...
 
 The specific reason why it is done in this case is as follows:
 
 	- it is possible to use a program to rewrite URLs using 
 	  mod_rewrite in Apache.
 	- when that is done, the implementation creates one process
 	  to do the rewrite before the child processes are forked.
 	  Each child has access to the input and output descriptors
 	  of the one process.
 	- when a child wants to use the program for a rewrite map,
 	  it has to be sure it has exclusive access.
 
 There are a lot of ways to solve the above problem and many other 
 ways to implement a solution.  This particular one locks the 
 descriptor to ensure only one child accesses the program at a time.
 
 -- 
      Marc Slemko     | Apache team member
      marcs@znep.com  | marc@apache.org
 
 

From: tetsuya@secom-sis.co.jp (Tetsuya Furukawa)
To: peter@spinner.dialix.com.au
Cc: dg@root.com, FreeBSD-gnats-submit@FreeBSD.ORG
Subject: Re: kern/4243: file locking doesn't work for pipe 
Date: Fri, 8 Aug 1997 15:58:26 +0900

 Peter Wemm wrote:
 >Yeah, it's kinda nonsensical, but useful in certain situations where the 
 >same fd is shared between processes.
 
 The purpose that Apache's URL rewriting module locks a pipe is
 exactly that.
 
 The latest version of the module says:
 ----
     /* The locking support for the RewriteMap programs:
        Locking a pipe to the child works fine under most
        Unix derivates, but braindead SunOS 4.1.x has 
        problems with this approach... */
 #define USE_PIPE_LOCKING 1
 #ifdef SUNOS4
 #undef USE_PIPE_LOCKING
 #endif
 ----
 <URL:http://www.engelschall.com/sw/mod_rewrite/distrib/mod_rewrite-SNAP/src/mod_rewrite.h>
 
 I made a simple program to check whether flock() works for a pipe.
 ----
 #include <sys/file.h>
 #include <sys/errno.h>
 #include <errno.h>
 #include <stdio.h>
 #include <unistd.h>
 
 int
 main()
 {
     int fds[2];
     char c;
 
     pipe(fds);
     if (fork() == 0) {
 	/* child */
 	flock(fds[1], LOCK_EX);
 	sleep(2);
 	exit(0);
     }
 
     /* parent */
     sleep(1);
     if (flock(fds[1], LOCK_EX | LOCK_NB) == -1) {
 	if (errno == EWOULDBLOCK)
 	    printf("flock works fine.\n");
 	else
 	    printf("flock fails: %s\n", strerror(errno));
     } else
 	printf("flock is discarded.\n");
     return 0;
 }
 ----
 
 Results:
     FreeBSD 2.2-STABLE i386       flock fails: Operation not supported
     FreeBSD 2.1.7.1-RELEASE i386  flock fails: Operation not supported
     Linux 2.0.29 i686             flock is discarded.
     Solaris 2.5.1 sparc           flock works fine.
 
 Linux is really braindead.  :-(
 
 I will send the results to the developer of the Apache's module
 and request to use the other locking method.
 
 --
 Tetsuya FURUKAWA  in Tokyo, Japan
 PGP Key fingerprint = C2 86 A6 7C 72 A0 A1 94  F4 4C 83 9D D1 E3 47 BD

From: tetsuya@secom-sis.co.jp (Tetsuya Furukawa)
To: tetsuya@secom-sis.co.jp
Cc: peter@spinner.dialix.com.au, dg@root.com, FreeBSD-gnats-submit@FreeBSD.ORG
Subject: Re: kern/4243: file locking doesn't work for pipe 
Date: Fri, 8 Aug 1997 16:38:32 +0900

 I'm sorry I had forgot the BSD flock's mechanism,
 so the following program I wrote is useless for BSD.
 
 >----
 >#include <sys/file.h>
 >#include <sys/errno.h>
 >#include <errno.h>
 >#include <stdio.h>
 >#include <unistd.h>
 >
 >int
 >main()
 >{
 >    int fds[2];
 >    char c;
 >
 >    pipe(fds);
 >    if (fork() == 0) {
 >	/* child */
 >	flock(fds[1], LOCK_EX);
 >	sleep(2);
 >	exit(0);
 >    }
 >
 >    /* parent */
 >    sleep(1);
 >    if (flock(fds[1], LOCK_EX | LOCK_NB) == -1) {
 >	if (errno == EWOULDBLOCK)
 >	    printf("flock works fine.\n");
 >	else
 >	    printf("flock fails: %s\n", strerror(errno));
 >    } else
 >	printf("flock is discarded.\n");
 >    return 0;
 >}
 >----
 >
 >Results:
 >    FreeBSD 2.2-STABLE i386       flock fails: Operation not supported
 >    FreeBSD 2.1.7.1-RELEASE i386  flock fails: Operation not supported
 >    Linux 2.0.29 i686             flock is discarded.
 >    Solaris 2.5.1 sparc           flock works fine.
 >
 >Linux is really braindead.  :-(
 
 Solaris's behavier is compatible with SYSV.
 Linux's may be compatible with BSD.
 
 --
 Tetsuya FURUKAWA  in Tokyo, Japan
 PGP Key fingerprint = C2 86 A6 7C 72 A0 A1 94  F4 4C 83 9D D1 E3 47 BD

From: tetsuya@secom-sis.co.jp (Tetsuya Furukawa)
To: peter@spinner.dialix.com.au
Cc: dg@root.com, FreeBSD-gnats-submit@FreeBSD.ORG
Subject: Re: kern/4243: file locking doesn't work for pipe 
Date: Fri, 8 Aug 1997 18:58:53 +0900

 Since I remembered the proper specification of flock(), I also think
 that flock() for a file descriptor shared among different processes
 is obviously useless.
 
 But fcntl() for a shared file descriptor may be useful because
 fcntl() has the other specification.
 In fact, the following program prints "fcntl works fine." on
 FreeBSD 2.2-STABLE i386.
 ----
 #include <sys/file.h>
 #include <sys/errno.h>
 #include <errno.h>
 #include <stdio.h>
 #include <unistd.h>
 #include <fcntl.h>
 
 int
 main()
 {
     int fd;
     struct flock flbuf;
     char c;
     flbuf.l_start = 0;
     flbuf.l_len = 0;
     flbuf.l_type = F_WRLCK;
     flbuf.l_whence = SEEK_SET;
 
     fd = open("lockfile", O_WRONLY | O_CREAT, 0666);
     if (fork() == 0) {
 	/* child */
 	fcntl(fd, F_SETLKW, &flbuf);
 	sleep(2);
 	exit(0);
     }
 
     /* parent */
     sleep(1);
     if (fcntl(fd, F_SETLK, &flbuf) == -1) {
 	if (errno == EAGAIN)
 	    printf("fcntl works fine.\n");
 	else
 	    printf("fcntl fails: %s\n", strerror(errno));
     } else
 	printf("fcntl is discarded.\n");
     return 0;
 }
 ----
 
 File locking for a pipe by fcntl() fails on FreeBSD.
 I think the priority of supporting it is low.
 
 To the developer of the Apache's module, I suggested to do fcntl()
 for a temporary file. 
 
 --
 Tetsuya FURUKAWA  in Tokyo, Japan
 PGP Key fingerprint = C2 86 A6 7C 72 A0 A1 94  F4 4C 83 9D D1 E3 47 BD
State-Changed-From-To: open->feedback 
State-Changed-By: iedowse 
State-Changed-When: Sat Jan 19 13:23:36 PST 2002 
State-Changed-Why:  

Can this be closed? 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=4243 
State-Changed-From-To: feedback->closed 
State-Changed-By: iedowse 
State-Changed-When: Sun Jun 2 04:28:15 PDT 2002 
State-Changed-Why:  

Feedback timeout. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=4243 
>Unformatted:
