delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2002/08/09/01:34:06

Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sources.redhat.com/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sources.redhat.com/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com
Message-ID: <015001c23f66$5146be40$7065a8c0@wgjmpc>
From: "vcc" <vcc AT selab DOT org>
To: <cygwin AT cygwin DOT com>
Subject: FIFO patch
Date: Fri, 9 Aug 2002 13:33:39 +0800
MIME-Version: 1.0
X-Priority: 3
X-MSMail-Priority: Normal
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2600.0000
Note-from-DJ: This may be spam

------=_NextPart_000_014D_01C23FA9.5F318920
Content-Type: text/plain;
	charset="Windows-1252"
Content-Transfer-Encoding: 7bit

Hi,
I modify and test Robert Collins's FIFO patch on cygwin current cvs version
, I chang make FIFO to symlink a file on /fifo/* . It will be faster.
Will it go into cygwin dist? I need it.
patch see attachment.

vcc

------=_NextPart_000_014D_01C23FA9.5F318920
Content-Type: application/octet-stream;
	name="fhandler_fifo.cc"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="fhandler_fifo.cc"

/* fhandler.cc.  See console.cc for fhandler_console functions.

   Copyright 1996, 1997, 1998, 1999, 2000, 2001 Cygnus Solutions.

This file is part of Cygwin.

This software is a copyrighted work licensed under the terms of the
Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
details. */

#include "winsup.h"
#include <sys/fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/cygwin.h>
#include <signal.h>
#include "cygerrno.h"
#include "perprocess.h"
#include "security.h"
#include "cygwin/version.h"
#include "fhandler.h"
#include "path.h"
#include "dtable.h"
#include "cygheap.h"
#include "shared_info.h"
#include "sigproc.h"
#include "pinfo.h"
#include <assert.h>
#include <stdio.h>


static char fhandler_fifo_dummy_name[] =3D "some fifo";

/**********************************************************************/
/* fhandler_fifo */

/* Observed behaviour of fifo's on un*x.
 *
 * First reader or writer blocks.
 * pipe reads return EOF when last writer quits
 * pipe writes return -1 and error EPIPE when the last reader quits.
 */

fhandler_fifo::fhandler_fifo (const char *name):
fhandler_base (FH_FIFO, (uint) name)
{
  set_need_fork_fixup ();
  unix_path_name =3D NULL;
  win32_path_name =3D NULL;
}

int
fhandler_fifo::open (const char *path, int flags, mode_t mode)
{
  syscall_printf ("(%s, %p)", path, flags);

  /* O_NOSYMLINK is an internal flag for implementing lstat, nothing =
more. */
  path_conv real_path (path, (flags & O_NOSYMLINK) ?
		       PC_SYM_NOFOLLOW : PC_SYM_FOLLOW);

  if (real_path.error &&
      (flags & O_NOSYMLINK || real_path.error !=3D ENOENT
       || !(flags & O_CREAT)))
    {
      set_errno (real_path.error);
      syscall_printf ("0 =3D fhandler_fifo::open (%s, %p)", path, =
flags);
      return 0;
    }
=20
  return open (real_path, flags, mode);
}

int
fhandler_fifo::open (path_conv * preal_path, int flags, mode_t mode)
{
  path_conv& real_path =3D *preal_path;
 =20
  win32_path_name =3D cstrdup(real_path.get_win32 ());

  unix_path_name =3D real_path.return_and_clear_normalized_path();
   =20
  set_has_acls (real_path.has_acls ());

  if (real_path.file_attributes () !=3D (DWORD) - 1
      && (real_path.file_attributes () & FILE_ATTRIBUTE_DIRECTORY))
    {
      set_errno (EPIPE);
      syscall_printf
	("fhandler_fifo::open attempt to open a directory as a FIFO\n");
    }

  system_printf ("FIFO opening : %s\n", real_path.get_win32 ());
  const char *path =3D get_name ();

  /* insert OS test here  - build security descriptor for NT */
  /* and GLOBAL\ prefix for terminal serices */

  if ((flags & (O_RDONLY | O_WRONLY | O_RDWR)) =3D=3D O_RDONLY)
    {
//    fifoaccess =3D FILE_MAP_READ;
      reader =3D 1;
      writer =3D 0;
    }
  else if ((flags & (O_RDONLY | O_WRONLY | O_RDWR)) =3D=3D O_WRONLY)
    {
//    fifoaccess =3D FILE_MAP_WRITE;
      reader =3D 0;
      writer =3D 1;
    }
  else
    {
//  fifoaccess =3D FILE_MAP_WRITE;
      reader =3D 1;
      writer =3D 1;
    }

  set_flags(flags);
  unsigned int created =3D 0;
  SYSTEM_INFO sysinfo;
  size_t buffer_offset;

// todo enter the FIFO global mutex

// if os=3Dnt4 ts or win2k or above add "Global\" as a prefix.

// setup our names
  snprintf (filemapname, MAX_PATH, "FIFOFM%s", path);
  snprintf (rrname, MAX_PATH, "FIFORR%s", path);
  snprintf (rmname, MAX_PATH, "FIFORM%s", path);
  snprintf (wmname, MAX_PATH, "FIFOWM%s", path);
  snprintf (dmname, MAX_PATH, "FIFODM%s", path);
  snprintf (wdname, MAX_PATH, "FIFOWD%s", path);
  snprintf (rsname, MAX_PATH, "FIFORS%s", path);
  snprintf (wsname, MAX_PATH, "FIFOWS%s", path);

  GetSystemInfo (&sysinfo);
  if (sysinfo.dwAllocationGranularity >=3D sizeof (class fifoshared))
    buffer_offset =3D sysinfo.dwAllocationGranularity;
  else
    buffer_offset =3D
      sysinfo.dwAllocationGranularity * (1 +
					 sizeof (class fifoshared) /
					 sysinfo.dwAllocationGranularity);

// FIXME: we need two file map objects. One for the header (r/w for =
every allowed user
// and one for data transfer (access only r or w as per file access =
rights
  filemap =3D CreateFileMapping (INVALID_HANDLE_VALUE,	// system =
pagefile.
/* default security - FIXME set allowed access from file permissions */
			       &sec_none,
			       // and set this appropriately.
			       PAGE_READWRITE,	// protection
			       0x00000000, 0x00100000 + buffer_offset,	// 1 Mb data,=20
			       filemapname	// object name
    );

/* This is not quite what we need to test the file access permissions, =
but it's a=20
 * starting point.*/
#if 0
  HANDLE thehandle;
  thehandle =3D CreateFile (win32_path_name_, access_,
			  FILE_SHARE_READ | FILE_SHARE_WRITE,
			  &sec_all_nih, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
			  NULL);

  is_open =3D 1;

  return 1;			/*success */
#endif

  if (filemap =3D=3D NULL)
    {
      system_printf ("failed to open mapping: %d\n", GetLastError ());
    }
  else
    {
      if (GetLastError () !=3D ERROR_ALREADY_EXISTS)
	created =3D 1;
/* FIXME: FOR all the create routines: use the security descriptor =
created above */
      readreadyevent =3D CreateEvent (&sec_none,	// SD=20
				    FALSE,	// reset type
				    FALSE,	// initial state
				    rrname	// object name
	);

      if (readreadyevent =3D=3D NULL)
	{
	  system_printf ("failed to open event : %d\n", GetLastError ());
	  //close the filemap
	}

      writingmutex =3D CreateMutex (&sec_none,	// SD
				  FALSE,	// initial owner
				  wmname	// object name
	);

      if (writingmutex =3D=3D NULL)
	{
	  system_printf ("failed to open write mutex : %d\n",
			 GetLastError ());
	  //close the event and the filemap
	}

      readmutex =3D CreateMutex (&sec_none,	// SD
			       FALSE,	// initial owner
			       rmname	// object name
	);

      if (readmutex =3D=3D NULL)
	{
	  system_printf ("failed to open read mutex : %d\n", GetLastError ());
	  //close the event and the filemap  andt eh write mutex
	}

      datamutex =3D CreateMutex (&sec_none,	// SD
			       FALSE,	// initial owner
			       dmname	// object name
	);

      if (datamutex =3D=3D NULL)
	{
	  system_printf ("failed to open read mutex : %d\n", GetLastError ());
	  //close the event and the filemap  andt eh write mutex
	}

      writedoneevent =3D CreateEvent (&sec_none,	// SD=20
				    FALSE,	// reset type
				    FALSE,	// initial state
				    wdname	// object name
	);

      if (readreadyevent =3D=3D NULL)
	{
	  system_printf ("failed to open event : %d\n", GetLastError ());
	  //close the event and the filemap  and both mutexs
	}

      guts =3D
	(class fifoshared *) MapViewOfFile (filemap, FILE_MAP_WRITE, 0, 0, 0);

      if (guts =3D=3D NULL)
	{
	  system_printf ("failed to map fifo file to memory: %d\n",
			 GetLastError ());
	  //close both event and the filemap  and both mutexs
	}

      // FIXME: SEH for read and writes?

      if (created)
	{
	  if (reader)
	    guts->readers =3D 1;
	  else
	    guts->readers =3D 0;
	  if (writer)
	    guts->writers =3D 1;
	  else
	    guts->writers =3D 0;
	  guts->buffer_offset =3D buffer_offset;
	  guts->buffer_length =3D 0x00100000;	//1 Mb
	  guts->data_length =3D 0;	// how much data is ready to be read (starts =
at
	  guts->data_offset =3D 0;	// data_offset
	  guts->pipeactive =3D 0;	// 0 =3D pipe waiting for an open
	}
      else
	{
	  if (guts->buffer_offset !=3D buffer_offset)
	    {
	      system_printf
		("incorrect data offset - check for multiple cygwin dll's \n");
	      //close both event and the filemap  and both mutexs and free the =
mapped view
	    }
	  if (reader)
	    guts->readers++;
	  if (writer)
	    guts->writers++;
	}

      // FIX ME set the file map read/write to the requested access.
      filedata =3D
	MapViewOfFile (filemap, FILE_MAP_WRITE, 0, guts->buffer_offset,
		       guts->buffer_length);

      if (filedata =3D=3D NULL)
	{
	  system_printf ("failed to map fifo data file to memory: %d\n",
			 GetLastError ());
	  //close both event and the filemap  and both mutexs and the first =
file view
	}


    }

  system_printf("FIFO opened\n");
// FIXME free the FIFO mutex;
  return 1;


#if 0
  /* We don't care about the _actual_ file. Maybe we should for locking =
purposes? */
  int res =3D this->fhandler_base::open (flags, mode);

  if (!res)
    goto out;

  /* This is for file systems known for having a buggy CreateFile call
     which might return a valid HANDLE without having actually opened
     the file.
     The only known file system to date is the SUN NFS Solstice Client =
3.1
     which returns a valid handle when trying to open a file in a non
     existant directory. */
  if (real_path.has_buggy_open ()
      && GetFileAttributes (win32_path_name_) =3D=3D (DWORD) - 1)
    {
      debug_printf ("Buggy open detected.");
      close ();
      set_errno (ENOENT);
      return 0;
    }

  extern BOOL allow_ntea;

  if (real_path.isdisk ()
      && (real_path.exec_state () =3D=3D dont_know_if_executable)
      && !allow_ntea && (!allow_ntsec || !real_path.has_acls ()))
    {
      DWORD done;
      char magic[3];
      /* FIXME should we use /etc/magic ? */
      magic[0] =3D magic[1] =3D magic[2] =3D '\0';
      ReadFile (get_handle (), magic, 3, &done, 0);
      if (has_exec_chars (magic, done))
	real_path.set_exec ();
      if (!(flags & O_APPEND))
	SetFilePointer (get_handle (), 0, 0, FILE_BEGIN);
    }

  if (flags & O_APPEND)
    SetFilePointer (get_handle (), 0, 0, FILE_END);

  set_symlink_p (real_path.issymlink ());
  set_execable_p (real_path.exec_state ());
  set_socket_p (real_path.issocket ());

out:
  syscall_printf ("%d =3D fhandler_fifo::open (%s, %p)", res,
		  get_win32_name (), flags);
  return res;
#endif
}


int
fhandler_fifo::close ()
{
  int rv =3D 0;
  // FIXME Get the FIFO mutex
  if (!filemap)
    return 0;	// what for already closed files?
  else
    {
      if (reader)
	guts->readers--;
      if (writer)
	guts->writers--;
	if (!(guts->readers) || !(guts->writers))
	  {
	    guts->pipeactive =3D 2;	// 2 =3D closed;
	    system_printf ("last reader or writer closed the pipe\n");
	    system_printf ("Telling the current blocked writers");
	    PulseEvent (readreadyevent);
	    system_printf ("... and readers\n");
	    PulseEvent (writedoneevent);
	  }
      system_printf ("on close: readers %d\n", guts->readers);
      system_printf ("on close: writers %d\n", guts->writers);
      if (!CloseHandle (filemap))
	rv =3D -1;		/* what error !?!?! */
 filemap=3DNULL;
      if (!CloseHandle (readreadyevent))
	rv =3D -1;		/* what error !?!?! */
readreadyevent=3DNULL;
      if (!CloseHandle (writingmutex))
	rv =3D -1;		/* what error !?!?! */
writingmutex=3DNULL;
      if (!CloseHandle (readmutex))
	rv =3D -1;		/* what error !?!?! */
readmutex=3DNULL;
      if (!CloseHandle (datamutex))
	rv =3D -1;		/* what error !?!?! */
datamutex=3DNULL;
      if (!CloseHandle (writedoneevent))
	rv =3D -1;		/* what error !?!?! */
writedoneevent=3DNULL;
      if (!UnmapViewOfFile (filedata))
	rv =3D -1;		/* what error !?!?! */
filedata=3DNULL;
      if (!UnmapViewOfFile (guts))
	rv =3D -1;		/* what error !?!?! */
guts=3DNULL;
    }

  // FIXME free the FIFO mutex.

#if 0
  int res;
  if ((res =3D this->fhandler_base::close ()) =3D=3D 0)
    cygwin_shared->delqueue.process_queue ();
  return res;
#endif
  return rv;			/* Success. Failure is -1 */
}


int
fhandler_fifo::dup (fhandler_base * child)
{
  fhandler_fifo *fhc =3D (fhandler_fifo *) child;

  if (!fhc->open (get_name (), get_flags (), 0))
    system_printf ("error opening fifo, %E");

#if 0
  fhandler_dev_clipboard *fhc =3D (fhandler_dev_clipboard *) child;

  if (!fhc->open (get_name (), get_flags (), 0))
    system_printf ("error opening clipboard, %E");

  fhc->membuffer =3D membuffer;
  fhc->pos =3D pos;
  fhc->msize =3D msize;
#endif
  return 0;
}

/* -1 =3D error. 0=3D EOF. + =3D bytes read */
int
fhandler_fifo::write (const void *buf, size_t len)
{
  unsigned int t;
  size_t current_length;
  size_t current_offset;
  // FIXME: did we open with write permissions?
  // FIXME: is the fd open? can it get this far if it's closed?
  // FIXME: is len > max_positive_int ?=20
  syscall_printf ("fhandler_fifo::write %x, %d\n",
		 buf,len);
  t =3D WaitForSingleObject (writingmutex, INFINITE	// time-out interval
    );
  if (t =3D=3D WAIT_OBJECT_0)
    {
      syscall_printf ("fhandler_fifo::write we have the write mutex %d =
\n", GetLastError ());
      current_length =3D 0;
      current_offset =3D 0;
      t =3D WaitForSingleObject (datamutex, INFINITE);
      if (t !=3D WAIT_OBJECT_0)
	{
	  /* an error of some sort */
	  system_printf
	    ("Error getting the datamutex - bad exit on the pipe...?? %d %d =
\n",
	     t, GetLastError ());
	}
      while (current_offset < len)
	{
	  syscall_printf ("fhandler_fifo::write is there any queued data ? ");
	  while (guts->data_length && guts->pipeactive < 2)
	    {
	      system_printf ("fhandler_fifo::write %d bytes still in the =
pipe\n",
			     guts->data_length);
	      if (guts->pipeactive > 1)
		{
		  syscall_printf ("fhandler_fifo::write and the pipe has been =
closed\n");
		  ReleaseMutex (datamutex);
		  ReleaseMutex (writingmutex);
		set_errno(EPIPE);
		  return -1;
		}
        if (get_flags() & O_NONBLOCK)
        {
	syscall_printf("fhandler_fifo::write returning due to O_NONBLOCK\n");
        set_errno(EAGAIN);
        ReleaseMutex (datamutex);
return -1;
}
	      t =3D
		SignalObjectAndWait (datamutex, readreadyevent,
				     INFINITE, FALSE);
	      if (t =3D=3D WAIT_OBJECT_0)
		{
//               system_printf (" // a read has occured rv %d lasterr =
%d\n", t,
//                        GetLastError ());
		}
	      else if (t =3D=3D WAIT_ABANDONED)
		{
		  system_printf ("********* wait timed out! | !?!\n");
		}
	      else if (t =3D=3D WAIT_FAILED)
		{
		  system_printf ("**********wait failed rv - %d lasterr %d\n",
				 t, GetLastError ());
		}
	      else
		{
		  system_printf
		    ("************unexpected return value - %d lasterr %d\n",
		     t, GetLastError ());
		}
	      t =3D WaitForSingleObject (datamutex, INFINITE);
	      if (t !=3D WAIT_OBJECT_0)
		{
		  system_printf
		    ("**************/* abandoned mutex - bad exit on the pipe...?? %d =
%d \n",
		     t, GetLastError ());
		}
	    }
	  syscall_printf ("fhandler_fifo::write  no data in the pipe.\n");
	  if (guts->pipeactive > 1)
	    {
//           system_printf
//              (" ****but the last reader has quit and the pipe has =
been closed\n");
	      ReleaseMutex (datamutex);
//           system_printf (" released the datamutex, rv %d, =
getlasterror %d\n", t,
//                    GetLastError ());
	      ReleaseMutex (writingmutex);
	      set_errno( EPIPE);
	      return -1;
	    }
	  syscall_printf
	    ("fhandler_fifo::write there are either readers waiting, or this is =
the first write. \n");
	  // send up to 1 Mb of data. - FIXME: return an error on nonblocking =
writes of more than 1 Mb

//	  system_printf ("writing\n");
	  current_length =3D len - current_offset;
	  if (current_length > 0x00100000)
	    current_length =3D 0x00100000;
	  memcpy (filedata, (char *) buf + current_offset, current_length);
	  guts->data_offset =3D 0;
	  guts->data_length =3D current_length;
	  current_offset +=3D current_length;
	  current_length =3D 0;
	  if (current_offset =3D=3D len)
	    guts->eow =3D 1;
	  else
	    guts->eow =3D 0;

	  syscall_printf
	    ("fhandler_fifo::write data written, telling any current reader, =
and waiting for a read to occur\n");
// for non blocking, don't wait for them to get the data
if (!(get_flags() & O_NONBLOCK))
{
	  t =3D ReleaseMutex (datamutex);
//	  system_printf (" released datamutex, rv %d, getlasterror %d\n", t,
//			 GetLastError ());
	  t =3D
	    SignalObjectAndWait (writedoneevent, readreadyevent, INFINITE, =
FALSE);
//	  system_printf (" we have the datamutex\n");
	  if (t !=3D WAIT_OBJECT_0)
	    {
	      system_printf ("error waiting on readreadyevent\n");
	    }
          t =3D WaitForSingleObject (datamutex, INFINITE);
              if (t !=3D WAIT_OBJECT_0)
                {
                  system_printf
                    ("**************/* abandoned mutex - bad exit on the =
pipe...?? %d %d \n",
                     t, GetLastError ());
                }=20
}
else=20
{
  syscall_printf("skippedwaiting for read confirmationdue to =
O_NONBLOCK\n");
  PulseEvent(writedoneevent);
}
	}
      t =3D ReleaseMutex (datamutex);
      system_printf (" released the datamutex, rv %d, getlasterror =
%d\n", t,
		     GetLastError ());
      system_printf ("releasing write mutex\n");
      ReleaseMutex (writingmutex);
      return current_offset;
    }
  else if (t =3D=3D WAIT_ABANDONED_0)
    {
      system_printf ("****  mutex was abandoned. \n");
      ReleaseMutex (writingmutex);
//      return fifowrite (data, buf, len);
    }
  else
    {
      system_printf ("*******/* we don't timeout */ rv=3D%d err=3D =
%d\n", t,
		     GetLastError ());
      return 0;
    }


  return 0;
}



int __stdcall
fhandler_fifo::read (void *ptr, size_t len)
{
  unsigned int t;
  size_t current_length, current_offset=3D0;
  if (!filemap)
  {
  set_errno(EBADF);
  return -1;
  }
  if (guts->pipeactive > 1)
    return 0;

  system_printf("reading a maximum of %d bytes, nonblocking =3D =
%d\n",len, get_flags() & O_NONBLOCK);

//  system_printf ("  /* wait for the read mutex */\n");
  t =3D WaitForSingleObject (readmutex,	// handle to object
			   INFINITE	// time-out interval
    );
#if 0
  if (guts->pipeactive > 1)
    {
      system_printf ("// the pipe has been closed\n");
      system_printf (" // current pipe status.  ml=3D%d dl=3D%d, =
eow=3D%d\n",
		     len, guts->data_length, guts->eow);
      //seterno EPIPE;
      ReleaseMutex (readmutex);
      return 0;
    }
#endif
  if (t =3D=3D WAIT_OBJECT_0)
    {
//      system_printf ("got the read mutex %d\n", t);
      current_length =3D 0;
      current_offset =3D 0;
      t =3D WaitForSingleObject (datamutex, INFINITE);
/*      system_printf (" // got the data mutex. co=3D%d ml=3D%d dl=3D%d, =
eow=3D%d\n",
		     current_offset, len, guts->data_length,
		     guts->eow); */
      while (current_offset < len
	     && !((guts->eow) && guts->data_length =3D=3D 0))
	{
//	  system_printf (" is there data waiting?");
	  while (!guts->data_length)
	    {
//	      system_printf ("..no..");
	      // there is no data in the pipe
	if (get_flags() & O_NONBLOCK)
	{
	set_errno(EAGAIN);
	system_printf ("NO data, not blocking\n");
ReleaseMutex (datamutex);
ReleaseMutex (readmutex);
	return -1;
	}
	      // is the pipe open?
	      if (guts->pipeactive > 1)
		{
		  system_printf ("amd the pipe has been closed\n");
		/* Note: the first writer blocks, so we _know_ that there was a =
writer.
 * EPIPE is not generated here - just EOF
 */
		  ReleaseMutex (datamutex);
		  ReleaseMutex (readmutex);
		  return current_offset;
		}
	      t =3D
		SignalObjectAndWait (datamutex, writedoneevent,
				     INFINITE, FALSE);
	      // a write has occured
	      t =3D WaitForSingleObject (datamutex, INFINITE);
	      if (t !=3D WAIT_OBJECT_0)
		{
		  system_printf
		    ("Error obtaining mutex - possibly an abandoned mutex - bad exit =
on the pipe... */\n");
		}
	    }

//	  system_printf ("..yes %d bytes of data waiting\n",
//			 guts->data_length);
//	  system_printf ("reading");
	  current_length =3D guts->data_length;
	  if (current_length + current_offset > len)
	    current_length =3D len - current_offset;

	  memcpy ((char *) ptr + current_offset,
		  (char *) filedata + guts->data_offset, current_length);

	  current_offset +=3D current_length;

	  if (!guts->pipeactive)
	    guts->pipeactive =3D 1;	// an io has completed
//	  system_printf
//	    ("...signalling acceptance of %d bytes of data...\n",
//	     current_length);
	  guts->data_length -=3D current_length;
	  guts->data_offset +=3D current_length;

	  PulseEvent (readreadyevent);
	}
      if (guts->data_length =3D=3D 0)
	guts->eow =3D 0;
      ReleaseMutex (datamutex);

      // read complete
      ReleaseMutex (readmutex);
    }
  else if (t =3D=3D WAIT_ABANDONED)
    {
      system_printf ("abandoned mutex found \n");
    }
  else
    {
      system_printf
	(" we don't have the mutex - should never ever happen (no timeout was =
set\n");
    }
  return current_offset;
}

off_t
fhandler_fifo::lseek (off_t offset, int whence)
{
  // for a pipe, you can't seek into the stream you can only rewind.
  // FIXME: should this be fixing the pipe for _every_ read and writer? =
or just us.
  if (!filemap)
  {
  set_errno(EBADF);
  return -1;
  }
  WaitForSingleObject (datamutex, INFINITE);
  guts->pipeactive=3D0;
  ReleaseMutex(datamutex);
  return 0;
}

void fhandler_fifo::fixup_after_fork (HANDLE parent)
{
  system_printf("fhandler_fifo::fixup_after_fork name =3D '%s', =
filemapname=3D'%s'\n",get_name(),filemapname);
  open(get_name(), get_flags(), 0);
}

------=_NextPart_000_014D_01C23FA9.5F318920
Content-Type: application/octet-stream;
	name="fifo.patch"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="fifo.patch"

Index: Makefile.in=0A=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A=
RCS file: /cvs/src/src/winsup/cygwin/Makefile.in,v=0A=
retrieving revision 1.98=0A=
diff -u -r1.98 Makefile.in=0A=
--- Makefile.in	1 Aug 2002 16:20:31 -0000	1.98=0A=
+++ Makefile.in	9 Aug 2002 05:05:57 -0000=0A=
@@ -135,7 +135,8 @@=0A=
 	select.o shared.o shm.o shortcut.o signal.o sigproc.o smallprint.o \=0A=
 	spawn.o strace.o strsep.o sync.o syscalls.o sysconf.o syslog.o \=0A=
 	termios.o thread.o times.o tty.o uinfo.o uname.o v8_regexp.o \=0A=
-	v8_regerror.o v8_regsub.o wait.o wincap.o window.o \=0A=
+	v8_regerror.o v8_regsub.o wait.o wincap.o window.o \=0A=
+	fhandler_fifo.o \=0A=
 	$(EXTRA_DLL_OFILES) $(EXTRA_OFILES) $(MALLOC_OFILES) $(MT_SAFE_OBJECTS)=0A=
 =0A=
 GMON_OFILES:=3Dgmon.o mcount.o profil.o=0A=
Index: dtable.cc=0A=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A=
RCS file: /cvs/src/src/winsup/cygwin/dtable.cc,v=0A=
retrieving revision 1.99=0A=
diff -u -r1.99 dtable.cc=0A=
--- dtable.cc	3 Jul 2002 18:02:53 -0000	1.99=0A=
+++ dtable.cc	9 Aug 2002 05:05:59 -0000=0A=
@@ -282,6 +282,16 @@=0A=
       set_errno (pc.error);=0A=
       return NULL;=0A=
     }=0A=
+    =0A=
+  /*  check fifo */=0A=
+  if (handle =3D=3D NULL && pc.exists() && !pc.isdir())=0A=
+    {=0A=
+     if (strncmp(pc.normalized_path,"/fifo/",6) =3D=3D 0) =0A=
+       {=0A=
+	  fhandler_base *fh =3D build_fhandler  (fd, FH_FIFO, =
name,pc,pc.get_unitn());=0A=
+	  return fh;=0A=
+       }=0A=
+    } /* NULL handle */=0A=
 =0A=
   if (!pc.exists () && handle)=0A=
     pc.fillin (handle);=0A=
@@ -372,6 +382,11 @@=0A=
       case FH_OSS_DSP:=0A=
 	fh =3D cnew (fhandler_dev_dsp) ();=0A=
 	break;=0A=
+	=0A=
+      case FH_FIFO:=0A=
+      	fh =3D cnew (fhandler_fifo) (NULL);=0A=
+      	break;=0A=
+	=0A=
       case FH_PROC:=0A=
 	fh =3D cnew (fhandler_proc) ();=0A=
 	break;=0A=
Index: fhandler.h=0A=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A=
RCS file: /cvs/src/src/winsup/cygwin/fhandler.h,v=0A=
retrieving revision 1.133=0A=
diff -u -r1.133 fhandler.h=0A=
--- fhandler.h	2 Aug 2002 02:10:24 -0000	1.133=0A=
+++ fhandler.h	9 Aug 2002 05:06:00 -0000=0A=
@@ -74,8 +74,10 @@=0A=
   FH_PROC    =3D 0x0000001a,      /* /proc */=0A=
   FH_REGISTRY =3D0x0000001b,      /* /proc/registry */=0A=
   FH_PROCESS =3D 0x0000001c,      /* /proc/<n> */=0A=
+  =0A=
+  FH_FIFO =3D 	 0x0000001d,=0A=
 =0A=
-  FH_NDEV    =3D 0x0000001d,      /* Maximum number of devices */=0A=
+  FH_NDEV    =3D 0x0000001e,      /* Maximum number of devices */=0A=
   FH_DEVMASK =3D 0x00000fff,	/* devices live here */=0A=
   FH_BAD     =3D 0xffffffff=0A=
 };=0A=
@@ -1227,5 +1229,73 @@=0A=
 };=0A=
 =0A=
 int __stdcall set_console_state_for_spawn ();=0A=
+=0A=
+=0A=
+class fifoshared=0A=
+{=0A=
+  public:=0A=
+  size_t data_offset;=0A=
+  unsigned int readers, writers;=0A=
+  /*set to 1 when the writer has written the last of it's buffer */=0A=
+  unsigned char eow;     =0A=
+  size_t buffer_length;=0A=
+  size_t buffer_offset;=0A=
+  size_t data_length;=0A=
+  unsigned int pipeactive;=0A=
+};=0A=
+=0A=
+class fhandler_fifo: public fhandler_base=0A=
+{=0A=
+private:=0A=
+  int is_open;=0A=
+  int reader, writer;=0A=
+=0A=
+  HANDLE filemap;=0A=
+  HANDLE readreadyevent;=0A=
+  HANDLE writingmutex;=0A=
+  HANDLE writedoneevent;=0A=
+  HANDLE readmutex;=0A=
+  HANDLE datamutex;=0A=
+  void *filedata;=0A=
+  unsigned int fifoaccess;=0A=
+  /* this may mean that multiple fifos at the max path length with =
similar prefixes =0A=
+   * collide. WIN32 limits us here, so the answer is don't do that! =
aka. Tough. */=0A=
+  char filemapname[MAX_PATH];=0A=
+  char rrname[MAX_PATH];=0A=
+  char rmname[MAX_PATH];=0A=
+  char wmname[MAX_PATH];=0A=
+  char wdname[MAX_PATH];=0A=
+  char rsname[MAX_PATH];=0A=
+  char wsname[MAX_PATH];=0A=
+  char dmname[MAX_PATH];=0A=
+  class fifoshared *guts;=0A=
+=0A=
+public:=0A=
+  fhandler_fifo (const char *name);=0A=
+=0A=
+  int open (const char *path, int flags, mode_t mode =3D 0);=0A=
+  virtual int open (path_conv* real_path, int flags, mode_t mode);=0A=
+  virtual int dup (fhandler_base *child);=0A=
+  virtual off_t lseek (off_t offset, int whence);=0A=
+  virtual int close ();=0A=
+=0A=
+  virtual int __stdcall read (void *ptr, size_t len) __attribute__ =
((regparm (3))); =0A=
+  virtual int write (const void *ptr, size_t len);=0A=
+=0A=
+//  virtual void fixup_before_fork_exec (DWORD);=0A=
+  void fixup_after_fork (HANDLE);=0A=
+  void fixup_after_exec (HANDLE parent) { fixup_after_fork (parent); }=0A=
+=0A=
+  // I need the fixup_after_fork stuff=0A=
+=0A=
+//  int lock (int, struct flock *);=0A=
+//  int fstat (struct stat *buf);=0A=
+=0A=
+//  HANDLE mmap (caddr_t *addr, size_t len, DWORD access, int flags, =
off_t off);=0A=
+//  int munmap (HANDLE h, caddr_t addr, size_t len);=0A=
+//  int msync (HANDLE h, caddr_t addr, size_t len, int flags);=0A=
+//  BOOL fixup_mmap_after_fork (HANDLE h, DWORD access, DWORD offset,=0A=
+//                              DWORD size, void *address);=0A=
+};=0A=
 =0A=
 #endif /* _FHANDLER_H_ */=0A=
Index: syscalls.cc=0A=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A=
RCS file: /cvs/src/src/winsup/cygwin/syscalls.cc,v=0A=
retrieving revision 1.223=0A=
diff -u -r1.223 syscalls.cc=0A=
--- syscalls.cc	2 Aug 2002 11:00:18 -0000	1.223=0A=
+++ syscalls.cc	9 Aug 2002 05:06:07 -0000=0A=
@@ -1931,6 +1931,35 @@=0A=
   return 0;=0A=
 }=0A=
 =0A=
+extern "C" int =0A=
+mkfifo ( const char *pathname, mode_t mode )=0A=
+{=0A=
+	/* create a file on /fifo/ and symlink to it */=0A=
+	FILE *tempfile;=0A=
+	int len =3D strlen(pathname);=0A=
+	char* str =3D (char*) malloc(len+7);=0A=
+	strcpy(str,"/fifo/");=0A=
+	strcat(str,pathname);=0A=
+	=0A=
+	for (int i =3D 6; i < len+6; i++) {=0A=
+		char c =3D str[i];=0A=
+		if (c =3D=3D '/')=0A=
+			str[i] =3D '_';=0A=
+	}=0A=
+	if ((tempfile=3Dfopen(str,"w"))=3D=3DNULL)=0A=
+     	{=0A=
+       		system_printf("error opening %s\n",str);=0A=
+       		set_errno (EIO);=0A=
+       		return -1;=0A=
+     	}=0A=
+     	fclose(tempfile);=0A=
+     	symlink(str,pathname);=0A=
+     	free(str);=0A=
+  return 0;=0A=
+=0A=
+}=0A=
+=0A=
+=0A=
 /* mknod was the call to create directories before the introduction=0A=
    of mkdir in 4.2BSD and SVR3.  Use of mknod required superuser privs=0A=
    so the mkdir command had to be setuid root.=0A=
@@ -1940,17 +1969,14 @@=0A=
 extern "C" int=0A=
 mknod (const char *_path, mode_t mode, dev_t dev)=0A=
 {=0A=
+  if (mode & S_IFIFO)=0A=
+  {=0A=
+    return mkfifo (_path, mode | (!S_IFIFO));=0A=
+  }=0A=
+  else=0A=
   set_errno (ENOSYS);=0A=
   return -1;=0A=
 }=0A=
-=0A=
-extern "C" int=0A=
-mkfifo (const char *_path, mode_t mode)=0A=
-{=0A=
-  set_errno (ENOSYS);=0A=
-  return -1;=0A=
-}=0A=
-=0A=
 /* seteuid: standards? */=0A=
 extern "C" int=0A=
 seteuid32 (__uid32_t uid)=0A=


------=_NextPart_000_014D_01C23FA9.5F318920
Content-Type: text/plain; charset=us-ascii

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/
------=_NextPart_000_014D_01C23FA9.5F318920--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019