From: "Mark E." To: djgpp-workers AT delorie DOT com Date: Sat, 24 Mar 2001 23:43:12 -0500 MIME-Version: 1.0 Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7BIT 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 ! #include 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 ! #include ! #include ! #include ! #include ! #include + /* 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 + #include + + /* 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