Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , 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" To: Subject: FIFO patch Date: Fri, 9 Aug 2002 13:33:39 +0800 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_014D_01C23FA9.5F318920" 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 #include #include #include #include #include #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 #include 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/ */=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--