delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2001/03/24/23:43:04

From: "Mark E." <snowball3 AT bigfoot DOT com>
To: djgpp-workers AT delorie DOT com
Date: Sat, 24 Mar 2001 23:43:12 -0500
MIME-Version: 1.0
Subject: new pipe patch
Message-ID: <3ABD3110.20018.23D9EC@localhost>
X-mailer: Pegasus Mail for Win32 (v3.12c)
Reply-To: djgpp-workers AT delorie DOT com

This version adds a pipe property so lseek can detect a file descriptor with 
this property and set ESPIPE accordingly.

Index: include/libc/fd_props.h
===================================================================
RCS file: /cvs/djgpp/djgpp/include/libc/fd_props.h,v
retrieving revision 1.2
diff -c -p -r1.2 fd_props.h
*** fd_props.h	2001/03/20 04:45:26	1.2
--- fd_props.h	2001/03/25 04:37:42
*************** extern "C" {
*** 22,27 ****
--- 22,30 ----
  /* Set when there can't be an EOF gap or it should be left alone.  */
  #define FILE_DESC_DONT_FILL_EOF_GAP 0x04
  
+ /* Set when the descriptor is used for pipe emulation.  */
+ #define FILE_DESC_PIPE              0x08
+ 
  typedef struct fd_properties fd_properties;
  
  struct fd_properties
Index: src/libc/posix/unistd/lseek.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/unistd/lseek.c,v
retrieving revision 1.3
diff -c -p -r1.3 lseek.c
*** lseek.c	2001/03/20 04:50:59	1.3
--- lseek.c	2001/03/25 04:37:54
*************** lseek(int handle, off_t offset, int when
*** 37,42 ****
--- 37,50 ----
    }
  
    has_props = __has_fd_properties(handle);
+ 
+   /* POSIX doesn't allow seek on a pipe.  */
+   if (has_props && (__fd_properties[handle]->flags & FILE_DESC_PIPE))
+   {
+     errno = ESPIPE;
+     return -1;
+   }
+ 
    if (!has_props ||
        (__fd_properties[handle]->flags & FILE_DESC_DONT_FILL_EOF_GAP) == 0)
    {
Index: src/libc/compat/unistd/llseek.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/compat/unistd/llseek.c,v
retrieving revision 1.3
diff -c -p -r1.3 llseek.c
*** llseek.c	2001/03/25 04:36:59	1.3
--- llseek.c	2001/03/25 04:38:03
*************** llseek( int handle, offset_t offset, int
*** 46,51 ****
--- 46,59 ----
    }
  
    has_props = __has_fd_properties(handle);
+ 
+   /* POSIX doesn't allow seek on a pipe.  */
+   if (has_props && (__fd_properties[handle]->flags & FILE_DESC_PIPE))
+   {
+     errno = ESPIPE;
+     return -1;
+   }
+ 
    if (!has_props ||
        (__fd_properties[handle]->flags & FILE_DESC_DONT_FILL_EOF_GAP) == 0)
    {
Index: src/libc/posix/unistd/pipe.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/unistd/pipe.c,v
retrieving revision 1.1
diff -c -p -r1.1 pipe.c
*** pipe.c	1995/04/01 23:49:02	1.1
--- pipe.c	2001/03/25 04:38:13
***************
*** 1,10 ****
  /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  #include <unistd.h>
! #include <errno.h>
  
  int
! pipe(int _fildes[2])
  {
!   errno = EACCES;
!   return -1;
  }
--- 1,43 ----
+ /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  #include <unistd.h>
! #include <stdlib.h>
! #include <fcntl.h>
! #include <stdio.h>
! #include <sys/stat.h>
! #include <libc/fd_props.h>
  
+ /* Emulate a pipe using a temporary file.  */
  int
! pipe(int fildes[2])
  {
!   int ifd, ofd;
!   char temp_name[FILENAME_MAX + 1];
!   char *tname;
! 
!   tname = tmpnam(temp_name);
!   if (tname == NULL)
!     return -1;
!     
!   ofd = open(tname, O_WRONLY | O_CREAT | O_TRUNC | O_APPEND | O_TEMPORARY,
!              S_IWUSR);
!   if (ofd < 0)
!     return -1;
!     
!   ifd = open(tname, O_RDONLY | O_TEMPORARY);
!   if (ifd < 0)
!   {
!     close(ofd);
!     return -1;
!   }
! 
!   if (__has_fd_properties(ofd))
!     __set_fd_flags(ofd, FILE_DESC_PIPE);
!   if (__has_fd_properties(ifd))
!     __set_fd_flags(ifd, FILE_DESC_PIPE);
! 
!   fildes[0] = ifd;
!   fildes[1] = ofd;
!     
!   return 0;
  }
Index: src/libc/posix/unistd/pipe.txh
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/unistd/pipe.txh,v
retrieving revision 1.2
diff -c -p -r1.2 pipe.txh
*** pipe.txh	1998/09/27 15:22:26	1.2
--- pipe.txh	2001/03/25 04:38:28
*************** int pipe(int fildes[2]);
*** 9,19 ****
  
  @subheading Description
  
! This function is provided only to assist in porting from Unix.  It
! always returns an error condition. 
  
  
  @subheading Portability
  
  @portability !ansi, posix
  
--- 9,79 ----
  
  @subheading Description
  
! This function creates a pipe and places a file descriptor for the read end
! of the pipe in @code{fildes[0]}, and another for the write end in
! @code{fildes[1]}.  Data written to @code{fildes[1]} will be read from
! @code{fildes[0]} on a first-in first-out (FIFO) basis.
  
+ Note this pipe implementation won't help port instances of
+ @code{fork}/@code{exec} or any other methods that require support for
+ multitasking.
  
+ @subheading Return Value
+ 
+ Zero for success, otherwise -1 is returned and @var{errno} is set to indicate
+ the error.
+ 
  @subheading Portability
  
  @portability !ansi, posix
  
+ @subheading Example
+ 
+ @example
+ 
+ #include <unistd.h>
+ #include <process.h>
+ 
+ /* Pipe the output of program to the input of another. */
+ 
+ int main()
+ @{
+   int pipe_fds[2];
+   int stdin_save, stdout_save;
+   
+   if (pipe(pipe_fds) < 0)
+     return -1;
+ 
+   /* Duplicate stdin and stdout so we can restore them later. */
+   stdin_save = dup(STDIN_FILENO);
+   stdout_save = dup(STDOUT_FILENO);
+ 
+   /* Make the write end of the pipe stdout. */
+   dup2(pipe_fds[1], STDOUT_FILENO);
+ 
+   /* Run the program. Its output will be written to the pipe. */
+   spawnl(P_WAIT, "/dev/env/DJDIR/bin/ls.exe", "ls.exe", NULL);
+ 
+   /* Close the write end of the pipe. */
+   close(pipe_fds[1]);
+ 
+   /* Restore stdout. */
+   dup2(stdout_save, STDOUT_FILENO);
+ 
+   /* Make the read end of the pipe stdin. */
+   dup2(pipe_fds[0], STDIN_FILENO);
+ 
+   /* Run another program. Its input will come from the output of the
+      first program. */
+   spawnl(P_WAIT, "/dev/env/DJDIR/bin/less.exe", "less.exe", "-E", NULL);
+ 
+   /* Close the read end of the pipe. */
+   close(pipe_fds[0]);
+ 
+   /* Restore stdin. */
+   dup2(stdin_save, STDIN_FILENO);
+   
+   return 0;
+ @}
+ 
+ @end example

- Raw text -


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