* ports.c (scm_flush_all_ports): SCM_PROC incorrectly allowed an
[bpt/guile.git] / libguile / fports.c
CommitLineData
3d8d56df 1/* Copyright (C) 1995,1996,1997 Free Software Foundation, Inc.
0f2d19dd
JB
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2, or (at your option)
6 * any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; see the file COPYING. If not, write to
82892bed
JB
15 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
16 * Boston, MA 02111-1307 USA
0f2d19dd
JB
17 *
18 * As a special exception, the Free Software Foundation gives permission
19 * for additional uses of the text contained in its release of GUILE.
20 *
21 * The exception is that, if you link the GUILE library with other files
22 * to produce an executable, this does not by itself cause the
23 * resulting executable to be covered by the GNU General Public License.
24 * Your use of that executable is in no way restricted on account of
25 * linking the GUILE library code into it.
26 *
27 * This exception does not however invalidate any other reasons why
28 * the executable file might be covered by the GNU General Public License.
29 *
30 * This exception applies only to the code released by the
31 * Free Software Foundation under the name GUILE. If you copy
32 * code from other Free Software Foundation releases into a copy of
33 * GUILE, as the General Public License permits, the exception does
34 * not apply to the code that you add in this way. To avoid misleading
35 * anyone as to the status of such modified files, you must delete
36 * this exception notice from them.
37 *
38 * If you write modifications of your own for GUILE, it is your choice
39 * whether to permit this exception to apply to your modifications.
82892bed 40 * If you do not wish that, delete this exception notice. */
0f2d19dd
JB
41\f
42
43#include <stdio.h>
44#include "_scm.h"
20e6290e
JB
45#include "markers.h"
46
47#include "fports.h"
95b88819
GH
48
49#ifdef HAVE_STRING_H
50#include <string.h>
51#endif
0f2d19dd
JB
52#ifdef HAVE_UNISTD_H
53#include <unistd.h>
54#else
0f2d19dd
JB
55scm_sizet fwrite ();
56#endif
0f2d19dd
JB
57
58
59#ifdef __IBMC__
60#include <io.h>
61#include <direct.h>
0f2d19dd
JB
62#else
63#ifndef MSDOS
64#ifndef ultrix
65#ifndef vms
66#ifdef _DCC
67#include <ioctl.h>
68#define setbuf(stream, buf) setvbuf(stream, buf, _IONBF, 0)
69#else
70#ifdef MWC
71#include <sys/io.h>
72#else
73#ifndef THINK_C
74#ifndef ARM_ULIB
75#include <sys/ioctl.h>
76#endif
77#endif
78#endif
79#endif
80#endif
81#endif
82#endif
83#endif
84\f
85
86/* {Ports - file ports}
87 *
88 */
89
90/* should be called with SCM_DEFER_INTS active */
1717856b 91
0f2d19dd
JB
92SCM
93scm_setbuf0 (port)
94 SCM port;
0f2d19dd
JB
95{
96#ifndef NOSETBUF
97#ifndef MSDOS
0f2d19dd
JB
98#ifndef ultrix
99 SCM_SYSCALL (setbuf ((FILE *)SCM_STREAM (port), 0););
100#endif
101#endif
0f2d19dd
JB
102#endif
103 return SCM_UNSPECIFIED;
104}
105
106/* Return the flags that characterize a port based on the mode
107 * string used to open a file for that port.
108 *
109 * See PORT FLAGS in scm.h
110 */
1717856b 111
0f2d19dd
JB
112long
113scm_mode_bits (modes)
114 char *modes;
0f2d19dd
JB
115{
116 return (SCM_OPN
117 | (strchr (modes, 'r') || strchr (modes, '+') ? SCM_RDNG : 0)
118 | ( strchr (modes, 'w')
119 || strchr (modes, 'a')
120 || strchr (modes, '+') ? SCM_WRTNG : 0)
121 | (strchr (modes, '0') ? SCM_BUF0 : 0));
122}
123
124
125/* scm_open_file
126 * Return a new port open on a given file.
127 *
128 * The mode string must match the pattern: [rwa+]** which
129 * is interpreted in the usual unix way.
130 *
131 * Return the new port.
132 */
19639113 133SCM_PROC(s_open_file, "open-file", 2, 0, 0, scm_open_file);
1717856b 134
0f2d19dd 135SCM
19639113
GH
136scm_open_file (filename, modes)
137 SCM filename;
138 SCM modes;
0f2d19dd 139{
19639113 140 SCM port;
0f2d19dd 141 FILE *f;
19639113
GH
142 char *file;
143 char *mode;
144
145 SCM_ASSERT (SCM_NIMP (filename) && SCM_ROSTRINGP (filename), filename, SCM_ARG1, s_open_file);
146 SCM_ASSERT (SCM_NIMP (modes) && SCM_ROSTRINGP (modes), modes, SCM_ARG2, s_open_file);
147 if (SCM_SUBSTRP (filename))
148 filename = scm_makfromstr (SCM_ROCHARS (filename), SCM_ROLENGTH (filename), 0);
149 if (SCM_SUBSTRP (modes))
150 modes = scm_makfromstr (SCM_ROCHARS (modes), SCM_ROLENGTH (modes), 0);
151
152 file = SCM_ROCHARS (filename);
153 mode = SCM_ROCHARS (modes);
154
0f2d19dd
JB
155 SCM_NEWCELL (port);
156 SCM_DEFER_INTS;
19639113 157 SCM_SYSCALL (f = fopen (file, mode));
0f2d19dd
JB
158 if (!f)
159 {
3d8d56df
GH
160 int en = errno;
161
f5bf2977 162 scm_syserror_msg (s_open_file, "%s: %S",
19639113
GH
163 scm_listify (scm_makfrom0str (strerror (errno)),
164 filename,
3d8d56df
GH
165 SCM_UNDEFINED),
166 en);
0f2d19dd
JB
167 }
168 else
169 {
170 struct scm_port_table * pt;
19639113 171
0f2d19dd
JB
172 pt = scm_add_to_port_table (port);
173 SCM_SETPTAB_ENTRY (port, pt);
a6c64c3c 174 SCM_SETCAR (port, scm_tc16_fport | scm_mode_bits (mode));
7471fb03 175 SCM_SETSTREAM (port, (SCM) f);
a6c64c3c 176 if (SCM_BUF0 & SCM_CAR (port))
0f2d19dd 177 scm_setbuf0 (port);
96937708 178 SCM_PTAB_ENTRY (port)->file_name = filename;
0f2d19dd 179 }
19639113 180 SCM_ALLOW_INTS;
0f2d19dd
JB
181 return port;
182}
183
a089567e
JB
184
185/* Build a Scheme port from an open stdio port, FILE.
186 MODE indicates whether FILE is open for reading or writing; it uses
187 the same notation as open-file's second argument.
188 If NAME is non-zero, use it as the port's filename.
189
190 scm_stdio_to_port sets the revealed count for FILE's file
191 descriptor to 1, so that FILE won't be closed when the port object
192 is GC'd. */
193SCM
194scm_stdio_to_port (file, mode, name)
195 FILE *file;
196 char *mode;
197 char *name;
198{
199 long mode_bits = scm_mode_bits (mode);
200 SCM port;
201 struct scm_port_table * pt;
202
203 SCM_NEWCELL (port);
204 SCM_DEFER_INTS;
205 {
206 pt = scm_add_to_port_table (port);
207 SCM_SETPTAB_ENTRY (port, pt);
208 SCM_SETCAR (port, (scm_tc16_fport | mode_bits));
7471fb03 209 SCM_SETSTREAM (port, (SCM) file);
a089567e
JB
210 if (SCM_BUF0 & SCM_CAR (port))
211 scm_setbuf0 (port);
a089567e
JB
212 SCM_PTAB_ENTRY (port)->file_name = scm_makfrom0str (name);
213 }
214 SCM_ALLOW_INTS;
215 scm_set_port_revealed_x (port, SCM_MAKINUM (1));
216 return port;
217}
218
219
0f2d19dd
JB
220/* Return the mode flags from an open port.
221 * Some modes such as "append" are only used when opening
a089567e 222 * a file and are not returned here. */
0f2d19dd
JB
223
224SCM_PROC(s_port_mode, "port-mode", 1, 0, 0, scm_port_mode);
1717856b 225
0f2d19dd
JB
226SCM
227scm_port_mode (port)
228 SCM port;
0f2d19dd
JB
229{
230 char modes[3];
231 modes[0] = '\0';
232 SCM_ASSERT (SCM_NIMP (port) && SCM_OPPORTP (port), port, SCM_ARG1, s_port_mode);
233 if (SCM_CAR (port) & SCM_RDNG) {
234 if (SCM_CAR (port) & SCM_WRTNG)
235 strcpy (modes, "r+");
236 else
237 strcpy (modes, "r");
238 }
239 else if (SCM_CAR (port) & SCM_WRTNG)
240 strcpy (modes, "w");
241 if (SCM_CAR (port) & SCM_BUF0)
242 strcat (modes, "0");
243 return scm_makfromstr (modes, strlen (modes), 0);
244}
245
246
1717856b
JB
247
248static int prinfport SCM_P ((SCM exp, SCM port, scm_print_state *pstate));
249
0f2d19dd 250static int
1717856b 251prinfport (exp, port, pstate)
0f2d19dd
JB
252 SCM exp;
253 SCM port;
1717856b 254 scm_print_state *pstate;
0f2d19dd
JB
255{
256 SCM name;
257 char * c;
258 if (SCM_CLOSEDP (exp))
259 {
260 c = "file";
261 }
262 else
263 {
264 name = SCM_PTAB_ENTRY (exp)->file_name;
265 if (SCM_NIMP (name) && SCM_ROSTRINGP (name))
266 c = SCM_ROCHARS (name);
267 else
268 c = "file";
269 }
19639113 270
0f2d19dd
JB
271 scm_prinport (exp, port, c);
272 return !0;
273}
274
275
1717856b
JB
276
277static int scm_fgetc SCM_P ((FILE * s));
278
0f2d19dd
JB
279static int
280scm_fgetc (s)
281 FILE * s;
0f2d19dd
JB
282{
283 if (feof (s))
284 return EOF;
285 else
286 return fgetc (s);
287}
288
289#ifdef vms
1717856b
JB
290
291static scm_sizet pwrite SCM_P ((char *ptr, scm_sizet size, nitems, FILE *port));
292
0f2d19dd
JB
293static scm_sizet
294pwrite (ptr, size, nitems, port)
295 char *ptr;
296 scm_sizet size, nitems;
297 FILE *port;
0f2d19dd
JB
298{
299 scm_sizet len = size * nitems;
300 scm_sizet i = 0;
301 for (; i < len; i++)
302 putc (ptr[i], port);
303 return len;
304}
305
306#define ffwrite pwrite
307#else
308#define ffwrite fwrite
309#endif
310
311\f
312/* This otherwise pointless code helps some poor
313 * crippled C compilers cope with life.
314 */
1717856b
JB
315
316static int local_fclose SCM_P ((FILE *fp));
317
0f2d19dd
JB
318static int
319local_fclose (fp)
320 FILE * fp;
321{
322 return fclose (fp);
323}
324
1717856b
JB
325static int local_fflush SCM_P ((FILE *fp));
326
0f2d19dd
JB
327static int
328local_fflush (fp)
329 FILE * fp;
330{
331 return fflush (fp);
332}
333
1717856b
JB
334static int local_fputc SCM_P ((int c, FILE *fp));
335
0f2d19dd
JB
336static int
337local_fputc (c, fp)
338 int c;
339 FILE * fp;
340{
341 return fputc (c, fp);
342}
343
1717856b
JB
344static int local_fputs SCM_P ((char *s, FILE *fp));
345
0f2d19dd
JB
346static int
347local_fputs (s, fp)
348 char * s;
349 FILE * fp;
350{
351 return fputs (s, fp);
352}
353
1717856b
JB
354static scm_sizet local_ffwrite SCM_P ((void *ptr, int size, int nitems, FILE *fp));
355
0f2d19dd
JB
356static scm_sizet
357local_ffwrite (ptr, size, nitems, fp)
358 void * ptr;
359 int size;
360 int nitems;
361 FILE * fp;
362{
363 return ffwrite (ptr, size, nitems, fp);
364}
365
8f29fbd0
JB
366static int
367print_pipe_port (SCM exp, SCM port, scm_print_state *pstate)
368{
369 scm_prinport (exp, port, "pipe");
370 return 1;
371}
372
373
374
6a2c4c81
JB
375/* On SunOS, there's no declaration for pclose in the headers, so
376 putting it directly in the initializer for scm_pipob doesn't really
377 fly. We could add an extern declaration for it, but then it'll
378 mismatch on some systems that do have a declaration. So we just
379 wrap it up this way. */
380static int
381local_pclose (fp)
382 FILE * fp;
383{
384 return pclose (fp);
385}
386
0f2d19dd
JB
387\f
388scm_ptobfuns scm_fptob =
389{
390 scm_mark0,
1717856b 391 (int (*) SCM_P ((SCM))) local_fclose,
0f2d19dd
JB
392 prinfport,
393 0,
1717856b
JB
394 (int (*) SCM_P ((int, SCM))) local_fputc,
395 (int (*) SCM_P ((char *, SCM))) local_fputs,
396 (scm_sizet (*) SCM_P ((char *, scm_sizet, scm_sizet, SCM))) local_ffwrite,
397 (int (*) SCM_P ((SCM))) local_fflush,
398 (int (*) SCM_P ((SCM))) scm_fgetc,
399 (int (*) SCM_P ((SCM))) local_fclose
0f2d19dd
JB
400};
401
6a2c4c81 402/* {Pipe ports} */
0f2d19dd
JB
403scm_ptobfuns scm_pipob =
404{
405 scm_mark0,
6a2c4c81 406 (int (*) SCM_P ((SCM))) local_pclose,
8f29fbd0 407 print_pipe_port,
0f2d19dd 408 0,
1717856b
JB
409 (int (*) SCM_P ((int, SCM))) local_fputc,
410 (int (*) SCM_P ((char *, SCM))) local_fputs,
411 (scm_sizet (*) SCM_P ((char *, scm_sizet, scm_sizet, SCM))) local_ffwrite,
412 (int (*) SCM_P ((SCM))) local_fflush,
413 (int (*) SCM_P ((SCM))) scm_fgetc,
6a2c4c81 414 (int (*) SCM_P ((SCM))) local_pclose
19468eff 415};
0f2d19dd 416
0f2d19dd
JB
417void
418scm_init_fports ()
0f2d19dd
JB
419{
420#include "fports.x"
421}