kern/74242: Write to fifo with no reader fails in 6.0 current

Derek Tattersall dlt at mebtel.net
Mon Nov 22 15:00:57 GMT 2004


>Number:         74242
>Category:       kern
>Synopsis:       Write to fifo with no reader fails in 6.0 current
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Nov 22 15:00:54 GMT 2004
>Closed-Date:
>Last-Modified:
>Originator:     Derek Tattersall
>Release:        6.0 -  21 November 2004
>Organization:
>Environment:
FreeBSD lorne.arm.org 6.0-CURRENT FreeBSD 6.0-CURRENT #1: Sun Nov 21 12:00:32 EST 2004     root at lorne.arm.org:/usr/obj/usr/src/sys/LORNE  i386     
>Description:
  Problem: Writing to a fifo before a reader is present results in the
write returning -1 with errno 45 "operation not supported".  This
behavior is new with a system cvsup'ed yesterday.

($?=0)dlt at lorne 1021 dlt% uname -a
FreeBSD lorne.arm.org 6.0-CURRENT FreeBSD 6.0-CURRENT #1: Sun Nov 21
12:00:32 EST 2004     root at lorne.arm.org:/usr/obj/usr/src/sys/LORNE
i386

The following two programs, speak.c (writer) and tick.c (reader)
demonstrate the problem.  If speak is started before tick, the write
always fails.  If tick is started before speak, everything works as
expected.  This code is slightly modified from code on Beej's Unix IPC
site.

speak.c --------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#define FIFO_NAME "american_maid"

main()
{
  char s[300];
  int num, fd;

  /* don't forget to error check this stuff!! */
  /*mknod(FIFO_NAME, S_IFIFO | 0666, 0);*/
  mkfifo(FIFO_NAME, 0666);

  printf("waiting for readers...\n");
  fd = open(FIFO_NAME, O_WRONLY);
  printf("got a reader--type some stuff\n");

  while (gets(s), !feof(stdin)) {
    if ((num = write(fd, s, strlen(s))) == -1)
      perror("write");
    else
      printf("speak: wrote %d bytes\n", num);
  }
}
speak.c-------------------------------------------------------------
tick.c -------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#define FIFO_NAME "american_maid"

main()
{
  char s[300];
  int num, fd;

  /* don't forget to error check this stuff!! */
  mknod(FIFO_NAME, S_IFIFO | 0666, 0);

  printf("waiting for writers...\n");
  fd = open(FIFO_NAME, O_RDONLY);
  printf("got a writer:\n");

  do {
    if ((num = read(fd, s, 300)) == -1)
      perror("read");
    else {
      s[num] = '\0';
      printf("tick: read %d bytes: \"%s\"\n", num, s);
    }
  } while (num > 0);
}
tick.c-------------------------------------------------------------

Note:  On a 5.3 RELEASE system it does not matter which program is
started first.  In fact, this code has worked on current up through
11/10/2004.
    
>How-To-Repeat:
 Using speak, compiled with "cc -o speak speak.c" and tick compiled with "cc -o tick tick.c", start speak in an xterm or console, then start tick in another xterm or console.  Type in the speak window, mash newline, observe error message in speak window or console.  Note that starting tick first then speak, and typing in the speak window shows no error.
>Fix:
      
>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list