1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-11 14:21:10 +02:00

* ports.c (flush_void_port): renamed to flush_port_default.

(end_input_void_port): renamed to end_input_default.

	* init.c (scm_standard_stream_to_port): create a void port instead
	of opening /dev/null if the standard file descriptors are bad.
	advantages: no portability problems, doesn't waste a file descriptor,
	simplifies the code (thanks to Marius for the idea).

	* vports.c (s_scm_make_soft_port): call scm_port_non_buffer.

	* void ports: make reading from a void port give EOF instead of
	segv:
	* ports.c (s_scm_sys_make_void_port): modified docstring.
	(fill_input_void_port): new proc.
	(scm_init_ports): set up fill_input_void_port.
	* ports.c (scm_port_non_buffer): new proc.
	(scm_void_port): call scm_port_non_buffer.

	* fports.c (scm_setvbuf): docstring: remove the fcntl documentation
	which was incorrectly appended.
This commit is contained in:
Gary Houston 2000-03-13 22:21:21 +00:00
parent 26fba92291
commit 70df8af662
5 changed files with 33 additions and 65 deletions

View file

@ -142,32 +142,8 @@ SCM_DEFINE (scm_setvbuf, "setvbuf", 2, 1, 0,
"@item _IOFBF\n"
"block buffered, using a newly allocated buffer of @var{size} bytes.\n"
"If @var{size} is omitted, a default size will be used.\n"
"@end table\n\n\n"
"@deffn primitive fcntl fd/port command [value]\n"
"Apply @var{command} to the specified file descriptor or the underlying\n"
"file descriptor of the specified port. @var{value} is an optional\n"
"integer argument.\n\n"
"Values for @var{command} are:\n\n"
"@table @code\n"
"@item F_DUPFD\n"
"Duplicate a file descriptor\n"
"@item F_GETFD\n"
"Get flags associated with the file descriptor.\n"
"@item F_SETFD\n"
"Set flags associated with the file descriptor to @var{value}.\n"
"@item F_GETFL\n"
"Get flags associated with the open file.\n"
"@item F_SETFL\n"
"Set flags associated with the open file to @var{value}\n"
"@item F_GETOWN\n"
"Get the process ID of a socket's owner, for @code{SIGIO} signals.\n"
"@item F_SETOWN\n"
"Set the process that owns a socket to @var{value}, for @code{SIGIO} signals.\n"
"@item FD_CLOEXEC\n"
"The value used to indicate the \"close on exec\" flag with @code{F_GETFL} or\n"
"@code{F_SETFL}.\n"
"@end table\n"
"")
)
#define FUNC_NAME s_scm_setvbuf
{
int cmode, csize;

View file

@ -279,8 +279,8 @@ stream_handler (void *data, SCM tag, SCM throw_args)
- set the revealed count for FILE's file descriptor to 1, so
that fdes won't be closed when the port object is GC'd.
- catch exceptions: allow Guile to be able to start up even
if it has been handed bogus stdin/stdout/stderr. In this case
try to open a new stream on /dev/null. */
if it has been handed bogus stdin/stdout/stderr. replace the
bad ports with void ports. */
static SCM
scm_standard_stream_to_port (int fdes, char *mode, char *name)
{
@ -293,23 +293,7 @@ scm_standard_stream_to_port (int fdes, char *mode, char *name)
port = scm_internal_catch (SCM_BOOL_T, stream_body, &body_data,
stream_handler, NULL);
if (SCM_FALSEP (port))
{
/* FIXME: /dev/null portability. there's also *null-device* in
r4rs.scm. */
int null_fdes = open ("/dev/null",
(mode[0] == 'r') ? O_RDONLY : O_WRONLY);
body_data.fdes = null_fdes;
port = (null_fdes == -1) ? SCM_BOOL_F
: scm_internal_catch (SCM_BOOL_T, stream_body, &body_data,
stream_handler, NULL);
/* if the standard fdes was not allocated, reset the revealed count
on the grounds that the user doesn't know what it is. */
if (SCM_NFALSEP (port) && null_fdes != fdes)
SCM_REVEALED (port) = 0;
/* if port is still #f, we'll just leave it like that and
an error will be raised on the first attempt to use it. */
}
port = scm_void_port (mode);
return port;
}

View file

@ -102,9 +102,15 @@ scm_markstream (SCM ptr)
* type constructor, and optional fields set by setters.
*/
static void flush_void_port (SCM port);
static void end_input_void_port (SCM port, int offset);
static void write_void_port (SCM port, const void *data, size_t size);
static void
flush_port_default (SCM port)
{
}
static void
end_input_default (SCM port, int offset)
{
}
long
scm_make_port_type (char *name,
@ -130,9 +136,9 @@ scm_make_port_type (char *name,
scm_ptobs[scm_numptob].close = 0;
scm_ptobs[scm_numptob].write = write;
scm_ptobs[scm_numptob].flush = flush_void_port;
scm_ptobs[scm_numptob].flush = flush_port_default;
scm_ptobs[scm_numptob].end_input = end_input_void_port;
scm_ptobs[scm_numptob].end_input = end_input_default;
scm_ptobs[scm_numptob].fill_input = fill_input;
scm_ptobs[scm_numptob].input_waiting = 0;
@ -484,6 +490,14 @@ SCM_DEFINE (scm_pt_member, "pt-member", 1, 0, 0,
#undef FUNC_NAME
#endif
void
scm_port_non_buffer (scm_port *pt)
{
pt->read_pos = pt->read_buf = pt->read_end = &pt->shortbuf;
pt->write_buf = pt->write_pos = &pt->shortbuf;
pt->read_buf_size = pt->write_buf_size = 1;
pt->write_end = pt->write_buf + pt->write_buf_size;
}
/* Revealed counts --- an oddity inherited from SCSH. */
@ -1302,14 +1316,9 @@ scm_ports_prehistory ()
long scm_tc16_void_port = 0;
static void
flush_void_port (SCM port)
{
}
static void
end_input_void_port (SCM port, int offset)
static int fill_input_void_port (SCM port)
{
return EOF;
}
static void
@ -1328,6 +1337,7 @@ scm_void_port (char *mode_str)
SCM_DEFER_INTS;
mode_bits = scm_mode_bits (mode_str);
pt = scm_add_to_port_table (answer);
scm_port_non_buffer (pt);
SCM_SETPTAB_ENTRY (answer, pt);
SCM_SETSTREAM (answer, 0);
SCM_SETCAR (answer, scm_tc16_void_port | mode_bits);
@ -1335,11 +1345,11 @@ scm_void_port (char *mode_str)
return answer;
}
SCM_DEFINE (scm_sys_make_void_port, "%make-void-port", 1, 0, 0,
(SCM mode),
"Create and return a new void port. The @var{mode} argument describes\n"
"the input/output modes for this port; for a description, see the\n"
"Create and return a new void port. A void port acts like\n"
"/dev/null. The @var{mode} argument\n"
"specifies the input/output modes for this port: see the\n"
"documentation for @code{open-file} in @ref{File Ports}.")
#define FUNC_NAME s_scm_sys_make_void_port
{
@ -1360,6 +1370,7 @@ scm_init_ports ()
scm_sysintern ("SEEK_CUR", SCM_MAKINUM (SEEK_CUR));
scm_sysintern ("SEEK_END", SCM_MAKINUM (SEEK_END));
scm_tc16_void_port = scm_make_port_type ("void", 0, write_void_port);
scm_tc16_void_port = scm_make_port_type ("void", fill_input_void_port,
write_void_port);
#include "ports.x"
}

View file

@ -253,6 +253,7 @@ extern void scm_remove_from_port_table (SCM port);
extern void scm_grow_port_cbuf (SCM port, size_t requested);
extern SCM scm_pt_size (void);
extern SCM scm_pt_member (SCM member);
extern void scm_port_non_buffer (scm_port *pt);
extern int scm_revealed_count (SCM port);
extern SCM scm_port_revealed (SCM port);
extern SCM scm_set_port_revealed_x (SCM port, SCM rcount);

View file

@ -184,14 +184,10 @@ SCM_DEFINE (scm_make_soft_port, "make-soft-port", 2, 0, 0,
SCM_NEWCELL (z);
SCM_DEFER_INTS;
pt = scm_add_to_port_table (z);
scm_port_non_buffer (pt);
SCM_SETCAR (z, scm_tc16_sfport | scm_mode_bits (SCM_ROCHARS (modes)));
SCM_SETPTAB_ENTRY (z, pt);
SCM_SETSTREAM (z, pv);
pt->read_pos = pt->read_buf = pt->read_end = &pt->shortbuf;
pt->write_buf = pt->write_pos = &pt->shortbuf;
pt->read_buf_size = pt->write_buf_size = 1;
pt->write_end = pt->write_buf + pt->write_buf_size;
pt->rw_random = 0;
SCM_ALLOW_INTS;
return z;
}