1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-12 23:00:22 +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" "@item _IOFBF\n"
"block buffered, using a newly allocated buffer of @var{size} bytes.\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" "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" "@end table\n"
"") )
#define FUNC_NAME s_scm_setvbuf #define FUNC_NAME s_scm_setvbuf
{ {
int cmode, csize; 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 - 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. that fdes won't be closed when the port object is GC'd.
- catch exceptions: allow Guile to be able to start up even - catch exceptions: allow Guile to be able to start up even
if it has been handed bogus stdin/stdout/stderr. In this case if it has been handed bogus stdin/stdout/stderr. replace the
try to open a new stream on /dev/null. */ bad ports with void ports. */
static SCM static SCM
scm_standard_stream_to_port (int fdes, char *mode, char *name) 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, port = scm_internal_catch (SCM_BOOL_T, stream_body, &body_data,
stream_handler, NULL); stream_handler, NULL);
if (SCM_FALSEP (port)) if (SCM_FALSEP (port))
{ port = scm_void_port (mode);
/* 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. */
}
return port; return port;
} }

View file

@ -102,9 +102,15 @@ scm_markstream (SCM ptr)
* type constructor, and optional fields set by setters. * type constructor, and optional fields set by setters.
*/ */
static void flush_void_port (SCM port); static void
static void end_input_void_port (SCM port, int offset); flush_port_default (SCM port)
static void write_void_port (SCM port, const void *data, size_t size); {
}
static void
end_input_default (SCM port, int offset)
{
}
long long
scm_make_port_type (char *name, 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].close = 0;
scm_ptobs[scm_numptob].write = write; 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].fill_input = fill_input;
scm_ptobs[scm_numptob].input_waiting = 0; scm_ptobs[scm_numptob].input_waiting = 0;
@ -484,6 +490,14 @@ SCM_DEFINE (scm_pt_member, "pt-member", 1, 0, 0,
#undef FUNC_NAME #undef FUNC_NAME
#endif #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. */ /* Revealed counts --- an oddity inherited from SCSH. */
@ -1302,14 +1316,9 @@ scm_ports_prehistory ()
long scm_tc16_void_port = 0; long scm_tc16_void_port = 0;
static void static int fill_input_void_port (SCM port)
flush_void_port (SCM port)
{
}
static void
end_input_void_port (SCM port, int offset)
{ {
return EOF;
} }
static void static void
@ -1328,6 +1337,7 @@ scm_void_port (char *mode_str)
SCM_DEFER_INTS; SCM_DEFER_INTS;
mode_bits = scm_mode_bits (mode_str); mode_bits = scm_mode_bits (mode_str);
pt = scm_add_to_port_table (answer); pt = scm_add_to_port_table (answer);
scm_port_non_buffer (pt);
SCM_SETPTAB_ENTRY (answer, pt); SCM_SETPTAB_ENTRY (answer, pt);
SCM_SETSTREAM (answer, 0); SCM_SETSTREAM (answer, 0);
SCM_SETCAR (answer, scm_tc16_void_port | mode_bits); SCM_SETCAR (answer, scm_tc16_void_port | mode_bits);
@ -1335,11 +1345,11 @@ scm_void_port (char *mode_str)
return answer; return answer;
} }
SCM_DEFINE (scm_sys_make_void_port, "%make-void-port", 1, 0, 0, SCM_DEFINE (scm_sys_make_void_port, "%make-void-port", 1, 0, 0,
(SCM mode), (SCM mode),
"Create and return a new void port. The @var{mode} argument describes\n" "Create and return a new void port. A void port acts like\n"
"the input/output modes for this port; for a description, see the\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}.") "documentation for @code{open-file} in @ref{File Ports}.")
#define FUNC_NAME s_scm_sys_make_void_port #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_CUR", SCM_MAKINUM (SEEK_CUR));
scm_sysintern ("SEEK_END", SCM_MAKINUM (SEEK_END)); 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" #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 void scm_grow_port_cbuf (SCM port, size_t requested);
extern SCM scm_pt_size (void); extern SCM scm_pt_size (void);
extern SCM scm_pt_member (SCM member); extern SCM scm_pt_member (SCM member);
extern void scm_port_non_buffer (scm_port *pt);
extern int scm_revealed_count (SCM port); extern int scm_revealed_count (SCM port);
extern SCM scm_port_revealed (SCM port); extern SCM scm_port_revealed (SCM port);
extern SCM scm_set_port_revealed_x (SCM port, SCM rcount); 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_NEWCELL (z);
SCM_DEFER_INTS; SCM_DEFER_INTS;
pt = scm_add_to_port_table (z); 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_SETCAR (z, scm_tc16_sfport | scm_mode_bits (SCM_ROCHARS (modes)));
SCM_SETPTAB_ENTRY (z, pt); SCM_SETPTAB_ENTRY (z, pt);
SCM_SETSTREAM (z, pv); 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; SCM_ALLOW_INTS;
return z; return z;
} }