1 /* -*-C-*-
2 
3 Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
4     1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
5     2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Massachusetts
6     Institute of Technology
7 
8 This file is part of MIT/GNU Scheme.
9 
10 MIT/GNU Scheme is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or (at
13 your option) any later version.
14 
15 MIT/GNU Scheme is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 General Public License for more details.
19 
20 You should have received a copy of the GNU General Public License
21 along with MIT/GNU Scheme; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,
23 USA.
24 
25 */
26 
27 #include "os2.h"
28 
29 static msg_t * input_pipe_reader (LHANDLE, qid_t, msg_t *, int *);
30 static void input_pipe_operator
31   (Tchannel, chop_t, choparg_t, choparg_t, choparg_t);
32 
33 void
OS_make_pipe(Tchannel * readerp,Tchannel * writerp)34 OS_make_pipe (Tchannel * readerp, Tchannel * writerp)
35 {
36   HFILE hread;
37   HFILE hwrite;
38   STD_API_CALL (dos_create_pipe, ((&hread), (&hwrite), 4096));
39   transaction_begin ();
40   OS2_handle_close_on_abort (hwrite);
41   (*readerp) = (OS2_make_channel (hread, CHANNEL_READ));
42   transaction_commit ();
43   transaction_begin ();
44   OS_channel_close_on_abort (*readerp);
45   (*writerp) = (OS2_make_channel (hwrite, CHANNEL_WRITE));
46   transaction_commit ();
47 }
48 
49 void
OS2_initialize_pipe_channel(Tchannel channel)50 OS2_initialize_pipe_channel (Tchannel channel)
51 {
52   if (CHANNEL_INPUTP (channel))
53     OS2_start_channel_thread (channel,
54 			      input_pipe_reader,
55 			      input_pipe_operator);
56 }
57 
58 static msg_t *
input_pipe_reader(LHANDLE handle,qid_t qid,msg_t * message,int * eofp)59 input_pipe_reader (LHANDLE handle, qid_t qid, msg_t * message, int * eofp)
60 {
61   ULONG nread;
62   APIRET rc
63     = (dos_read (handle,
64 		 (SM_READAHEAD_DATA (message)),
65 		 (sizeof (SM_READAHEAD_DATA (message))),
66 		 (& nread)));
67   if (rc == NO_ERROR)
68     {
69       (SM_READAHEAD_SIZE (message)) = nread;
70       (*eofp) = (nread == 0);
71       return (message);
72     }
73   OS2_destroy_message (message);
74   if (rc == ERROR_INVALID_HANDLE)
75     /* Handle was closed on us -- no need to do anything else.  */
76     return (0);
77   (*eofp) = (rc == ERROR_BROKEN_PIPE);
78   return (OS2_make_syscall_error (rc, syscall_dos_read));
79 }
80 
81 static void
input_pipe_operator(Tchannel channel,chop_t operation,choparg_t arg1,choparg_t arg2,choparg_t arg3)82 input_pipe_operator (Tchannel channel, chop_t operation,
83 		     choparg_t arg1, choparg_t arg2, choparg_t arg3)
84 {
85   switch (operation)
86     {
87     case chop_read:
88       OS2_channel_thread_read_op (channel, arg1, arg2, arg3);
89       break;
90     case chop_close:
91       OS2_channel_thread_close (channel);
92       STD_API_CALL (dos_close, (CHANNEL_HANDLE (channel)));
93       break;
94     default:
95       OS2_logic_error ("Unknown operation for input pipe.");
96       break;
97     }
98 }
99