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