Commit | Line | Data |
---|---|---|
cf908fd1 WJ |
1 | /* dg2ps.c - datagram-backed abstraction for PStreams */ |
2 | ||
3 | #ifndef lint | |
4 | static char *rcsid = "$Header: /f/osi/psap/RCS/dg2ps.c,v 7.3 91/02/22 09:35:36 mrose Interim $"; | |
5 | #endif | |
6 | ||
7 | /* | |
8 | * $Header: /f/osi/psap/RCS/dg2ps.c,v 7.3 91/02/22 09:35:36 mrose Interim $ | |
9 | * | |
10 | * | |
11 | * $Log: dg2ps.c,v $ | |
12 | * Revision 7.3 91/02/22 09:35:36 mrose | |
13 | * Interim 6.8 | |
14 | * | |
15 | * Revision 7.2 91/01/07 12:40:25 mrose | |
16 | * update | |
17 | * | |
18 | * Revision 7.1 90/08/08 14:02:31 mrose | |
19 | * stuff | |
20 | * | |
21 | * Revision 7.0 89/11/23 22:12:34 mrose | |
22 | * Release 6.0 | |
23 | * | |
24 | */ | |
25 | ||
26 | /* | |
27 | * NOTICE | |
28 | * | |
29 | * Acquisition, use, and distribution of this module and related | |
30 | * materials are subject to the restrictions of a license agreement. | |
31 | * Consult the Preface in the User's Manual for the full terms of | |
32 | * this agreement. | |
33 | * | |
34 | */ | |
35 | ||
36 | ||
37 | /* LINTLIBRARY */ | |
38 | ||
39 | #include <stdio.h> | |
40 | #include "psap.h" | |
41 | ||
42 | ||
43 | struct ps_dg { | |
44 | int ps_fd; | |
45 | int ps_maxsize; | |
46 | ||
47 | struct ps_inout { | |
48 | struct qbuf *pio_qb; | |
49 | char *pio_ptr; | |
50 | int pio_cnt; | |
51 | ||
52 | IFP pio_fnx; | |
53 | } ps_input, | |
54 | ps_output; | |
55 | ||
56 | IFP ps_check; | |
57 | }; | |
58 | ||
59 | ||
60 | extern IFP set_check_fd (); | |
61 | ||
62 | /* \f */ | |
63 | ||
64 | static int dg_prime (ps, waiting) | |
65 | register PS ps; | |
66 | int waiting; | |
67 | { | |
68 | struct qbuf *qb; | |
69 | register struct ps_dg *pt = (struct ps_dg *) ps -> ps_addr; | |
70 | register struct ps_inout *pi = &pt -> ps_input; | |
71 | ||
72 | switch (waiting) { | |
73 | case 0: | |
74 | if (pi -> pio_cnt > 0) | |
75 | return OK; | |
76 | break; | |
77 | ||
78 | case 1: | |
79 | default: | |
80 | return (pi -> pio_cnt > 0 ? DONE : OK); | |
81 | ||
82 | case -1: | |
83 | if (pi -> pio_cnt <= 0) | |
84 | return OK; | |
85 | break; | |
86 | } | |
87 | ||
88 | if (pi -> pio_qb != NULL) { | |
89 | qb_free (pi -> pio_qb); | |
90 | pi -> pio_qb = NULL; | |
91 | } | |
92 | pi -> pio_cnt = 0; | |
93 | ||
94 | if (waiting < 0) | |
95 | return ps_seterr (ps, PS_ERR_EXTRA, NOTOK); | |
96 | ||
97 | if ((*pi -> pio_fnx) (pt -> ps_fd, &qb) == NOTOK) | |
98 | return ps_seterr (ps, PS_ERR_IO, NOTOK); | |
99 | ||
100 | if (pi -> pio_qb = qb) | |
101 | pi -> pio_ptr = qb -> qb_data, pi -> pio_cnt = qb -> qb_len; | |
102 | else | |
103 | pi -> pio_ptr = NULL, pi -> pio_cnt = 0; | |
104 | ||
105 | return OK; | |
106 | } | |
107 | ||
108 | ||
109 | /* ARGSUSED */ | |
110 | ||
111 | static int dg_read (ps, data, n, in_line) | |
112 | register PS ps; | |
113 | PElementData data; | |
114 | PElementLen n; | |
115 | int in_line; | |
116 | { | |
117 | int cc; | |
118 | register struct ps_dg *pt = (struct ps_dg *) ps -> ps_addr; | |
119 | register struct ps_inout *pi = &pt -> ps_input; | |
120 | ||
121 | if ((cc = pi -> pio_cnt) <= 0) | |
122 | return 0; | |
123 | if (cc > n) | |
124 | cc = n; | |
125 | ||
126 | bcopy (pi -> pio_ptr, (char *) data, cc); | |
127 | pi -> pio_ptr += cc, pi -> pio_cnt -= cc; | |
128 | ||
129 | return cc; | |
130 | } | |
131 | ||
132 | ||
133 | /* ARGSUSED */ | |
134 | ||
135 | static int dg_write (ps, data, n, in_line) | |
136 | register PS ps; | |
137 | PElementData data; | |
138 | PElementLen n; | |
139 | int in_line; | |
140 | { | |
141 | register struct ps_dg *pt = (struct ps_dg *) ps -> ps_addr; | |
142 | register struct ps_inout *po = &pt -> ps_output; | |
143 | ||
144 | if (po -> pio_cnt < n) | |
145 | return 0; | |
146 | ||
147 | bcopy ((char *) data, po -> pio_ptr, n); | |
148 | po -> pio_ptr += n, po -> pio_cnt -= n; | |
149 | ||
150 | return n; | |
151 | } | |
152 | ||
153 | ||
154 | static int dg_flush (ps) | |
155 | register PS ps; | |
156 | { | |
157 | register struct ps_dg *pt = (struct ps_dg *) ps -> ps_addr; | |
158 | register struct ps_inout *po = &pt -> ps_output; | |
159 | register struct qbuf *qb = po -> pio_qb; | |
160 | ||
161 | qb -> qb_len = po -> pio_ptr - qb -> qb_data; | |
162 | if ((*po -> pio_fnx) (pt -> ps_fd, qb) != qb -> qb_len) | |
163 | return ps_seterr (ps, PS_ERR_IO, NOTOK); | |
164 | ||
165 | po -> pio_ptr = qb -> qb_data, po -> pio_cnt = pt -> ps_maxsize; | |
166 | ||
167 | return OK; | |
168 | } | |
169 | ||
170 | ||
171 | static int dg_close (ps) | |
172 | register PS ps; | |
173 | { | |
174 | register struct ps_dg *pt = (struct ps_dg *) ps -> ps_addr; | |
175 | ||
176 | if (pt == NULL) | |
177 | return OK; | |
178 | ||
179 | if (pt -> ps_input.pio_qb) | |
180 | qb_free (pt -> ps_input.pio_qb); | |
181 | if (pt -> ps_output.pio_qb) | |
182 | qb_free (pt -> ps_output.pio_qb); | |
183 | ||
184 | (void) set_check_fd (pt -> ps_fd, NULLIFP, NULLCP); | |
185 | ||
186 | free ((char *) pt); | |
187 | ||
188 | return OK; | |
189 | } | |
190 | ||
191 | ||
192 | static int dg_check (fd, data) | |
193 | int fd; | |
194 | caddr_t data; | |
195 | { | |
196 | int n; | |
197 | PS ps = (PS) data; | |
198 | register struct ps_dg *pt = (struct ps_dg *) ps -> ps_addr; | |
199 | ||
200 | if (pt -> ps_check && (n = (*pt -> ps_check) (fd))) | |
201 | return n; | |
202 | ||
203 | return (ps_prime (ps, 1) > 0 ? DONE : OK); | |
204 | } | |
205 | ||
206 | /* \f */ | |
207 | ||
208 | int dg_open (ps) | |
209 | register PS ps; | |
210 | { | |
211 | ps -> ps_primeP = dg_prime; | |
212 | ps -> ps_readP = dg_read; | |
213 | ps -> ps_writeP = dg_write; | |
214 | ps -> ps_flushP = dg_flush; | |
215 | ps -> ps_closeP = dg_close; | |
216 | ||
217 | return OK; | |
218 | } | |
219 | ||
220 | ||
221 | int dg_setup (ps, fd, size, rfx, wfx, cfx) | |
222 | register PS ps; | |
223 | int fd, | |
224 | size; | |
225 | IFP rfx, | |
226 | wfx, | |
227 | cfx; | |
228 | { | |
229 | register struct ps_dg *pt; | |
230 | register struct ps_inout *po; | |
231 | register struct qbuf *qb; | |
232 | ||
233 | if ((pt = (struct ps_dg *) calloc (1, sizeof *pt)) == NULL) | |
234 | return ps_seterr (ps, PS_ERR_NMEM, NOTOK); | |
235 | ps -> ps_addr = (caddr_t) pt; | |
236 | ||
237 | pt -> ps_fd = fd; | |
238 | pt -> ps_maxsize = size; | |
239 | ||
240 | if ((qb = (struct qbuf *) malloc (sizeof *qb | |
241 | + (unsigned) pt -> ps_maxsize)) | |
242 | == NULL) | |
243 | return ps_seterr (ps, PS_ERR_NMEM, NOTOK); | |
244 | qb -> qb_forw = qb -> qb_back = qb; | |
245 | qb -> qb_len = 0; | |
246 | qb -> qb_data = qb -> qb_base; | |
247 | ||
248 | po = &pt -> ps_output; | |
249 | po -> pio_qb = qb; | |
250 | po -> pio_ptr = qb -> qb_data, po -> pio_cnt = pt -> ps_maxsize; | |
251 | if ((pt -> ps_input.pio_fnx = rfx) == NULLIFP | |
252 | || (po -> pio_fnx = wfx) == NULLIFP) | |
253 | return ps_seterr (ps, PS_ERR_XXX, NOTOK); | |
254 | ||
255 | pt -> ps_check = cfx; | |
256 | (void) set_check_fd (fd, dg_check, (caddr_t) ps); | |
257 | ||
258 | return OK; | |
259 | } |