Mail Archives: djgpp-workers/2001/03/24/23:43:04
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 -