-/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc.
+/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002, 2003, 2004 Free Software Foundation, Inc.
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this software; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307 USA
- *
- * As a special exception, the Free Software Foundation gives permission
- * for additional uses of the text contained in its release of GUILE.
- *
- * The exception is that, if you link the GUILE library with other files
- * to produce an executable, this does not by itself cause the
- * resulting executable to be covered by the GNU General Public License.
- * Your use of that executable is in no way restricted on account of
- * linking the GUILE library code into it.
- *
- * This exception does not however invalidate any other reasons why
- * the executable file might be covered by the GNU General Public License.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * This exception applies only to the code released by the
- * Free Software Foundation under the name GUILE. If you copy
- * code from other Free Software Foundation releases into a copy of
- * GUILE, as the General Public License permits, the exception does
- * not apply to the code that you add in this way. To avoid misleading
- * anyone as to the status of such modified files, you must delete
- * this exception notice from them.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * If you write modifications of your own for GUILE, it is your choice
- * whether to permit this exception to apply to your modifications.
- * If you do not wish that, delete this exception notice. */
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
\f
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
#include <stdio.h>
#include <fcntl.h>
#include "libguile/strings.h"
#include "libguile/validate.h"
#include "libguile/gc.h"
+#include "libguile/dynwind.h"
#include "libguile/fports.h"
#else
size_t fwrite ();
#endif
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
#include <sys/stat.h>
#endif
#include <errno.h>
#include "libguile/iselect.h"
-/* Some defines for Windows. */
+
+/* Some defines for Windows (native port, not Cygwin). */
#ifdef __MINGW32__
# include <sys/stat.h>
# include <winsock2.h>
scm_fport_buffer_add (SCM port, long read_size, int write_size)
#define FUNC_NAME "scm_fport_buffer_add"
{
- scm_t_fport *fp = SCM_FSTREAM (port);
scm_t_port *pt = SCM_PTAB_ENTRY (port);
if (read_size == -1 || write_size == -1)
size_t default_size;
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
struct stat st;
+ scm_t_fport *fp = SCM_FSTREAM (port);
default_size = (fstat (fp->fdes, &st) == -1) ? default_buffer_size
: st.st_blksize;
if (SCM_INPUT_PORT_P (port) && read_size > 0)
{
- pt->read_buf = scm_must_malloc (read_size, FUNC_NAME);
+ pt->read_buf = scm_gc_malloc (read_size, "port buffer");
pt->read_pos = pt->read_end = pt->read_buf;
pt->read_buf_size = read_size;
}
if (SCM_OUTPUT_PORT_P (port) && write_size > 0)
{
- pt->write_buf = scm_must_malloc (write_size, FUNC_NAME);
+ pt->write_buf = scm_gc_malloc (write_size, "port buffer");
pt->write_pos = pt->write_buf;
pt->write_buf_size = write_size;
}
port = SCM_COERCE_OUTPORT (port);
SCM_VALIDATE_OPFPORT (1,port);
- SCM_VALIDATE_INUM_COPY (2,mode,cmode);
+ cmode = scm_to_int (mode);
if (cmode != _IONBF && cmode != _IOFBF && cmode != _IOLBF)
scm_out_of_range (FUNC_NAME, mode);
}
else
{
- SCM_VALIDATE_INUM_COPY (3,size,csize);
+ csize = scm_to_int (size);
if (csize < 0 || (cmode == _IONBF && csize > 0))
scm_out_of_range (FUNC_NAME, size);
}
pt = SCM_PTAB_ENTRY (port);
- /* silently discards buffered chars. */
+ /* silently discards buffered and put-back chars. */
+ if (pt->read_buf == pt->putback_buf)
+ {
+ pt->read_buf = pt->saved_read_buf;
+ pt->read_pos = pt->saved_read_pos;
+ pt->read_end = pt->saved_read_end;
+ pt->read_buf_size = pt->saved_read_buf_size;
+ }
if (pt->read_buf != &pt->shortbuf)
- scm_must_free (pt->read_buf);
+ scm_gc_free (pt->read_buf, pt->read_buf_size, "port buffer");
if (pt->write_buf != &pt->shortbuf)
- scm_must_free (pt->write_buf);
+ scm_gc_free (pt->write_buf, pt->write_buf_size, "port buffer");
scm_fport_buffer_add (port, csize, csize);
return SCM_UNSPECIFIED;
#undef FUNC_NAME
/* Move ports with the specified file descriptor to new descriptors,
- * reseting the revealed count to 0.
+ * resetting the revealed count to 0.
*/
void
{
long i;
- for (i = 0; i < scm_port_table_size; i++)
+ scm_mutex_lock (&scm_i_port_table_mutex);
+
+ for (i = 0; i < scm_i_port_table_size; i++)
{
- SCM port = scm_port_table[i]->port;
+ SCM port = scm_i_port_table[i]->port;
if (SCM_FPORTP (port))
{
fp->fdes = dup (fd);
if (fp->fdes == -1)
scm_syserror ("scm_evict_ports");
- scm_set_port_revealed_x (port, SCM_MAKINUM (0));
+ scm_set_port_revealed_x (port, scm_from_int (0));
}
}
}
+
+ scm_mutex_unlock (&scm_i_port_table_mutex);
}
"Determine whether @var{obj} is a port that is related to a file.")
#define FUNC_NAME s_scm_file_port_p
{
- return SCM_BOOL (SCM_FPORTP (obj));
+ return scm_from_bool (SCM_FPORTP (obj));
}
#undef FUNC_NAME
char *md;
char *ptr;
- SCM_VALIDATE_STRING (1, filename);
- SCM_VALIDATE_STRING (2, mode);
+ scm_frame_begin (0);
+
+ file = scm_to_locale_string (filename);
+ scm_frame_free (file);
- file = SCM_STRING_CHARS (filename);
- md = SCM_STRING_CHARS (mode);
+ md = scm_to_locale_string (mode);
+ scm_frame_free (md);
switch (*md)
{
int en = errno;
SCM_SYSERROR_MSG ("~A: ~S",
- scm_cons (scm_makfrom0str (strerror (en)),
+ scm_cons (scm_strerror (scm_from_int (en)),
scm_cons (filename, SCM_EOL)), en);
}
port = scm_fdes_to_port (fdes, md, filename);
+
+ scm_frame_end ();
+
return port;
}
#undef FUNC_NAME
else
{
/* Or an anonymous pipe handle ? */
- if (buf.st_mode & 0x1000 /* _O_SHORT_LIVED */)
- flags = O_RDWR;
+ if (buf.st_mode & _S_IFIFO)
+ flags = PeekNamedPipe ((HANDLE) _get_osfhandle (fdes), NULL, 0,
+ NULL, NULL, NULL) ? O_RDONLY : O_WRONLY;
/* stdin ? */
- else if (fdes == 0 && isatty (fdes))
+ else if (fdes == fileno (stdin) && isatty (fdes))
flags = O_RDONLY;
/* stdout / stderr ? */
- else if ((fdes == 1 || fdes == 2) && isatty (fdes))
+ else if ((fdes == fileno (stdout) || fdes == fileno (stderr)) &&
+ isatty (fdes))
flags = O_WRONLY;
else
flags = buf.st_mode;
SCM_MISC_ERROR ("requested file mode not available on fdes", SCM_EOL);
}
- SCM_NEWCELL (port);
- SCM_DEFER_INTS;
- pt = scm_add_to_port_table (port);
- SCM_SETPTAB_ENTRY (port, pt);
- SCM_SET_CELL_TYPE (port, (scm_tc16_fport | mode_bits));
+ scm_mutex_lock (&scm_i_port_table_mutex);
+ port = scm_new_port_table_entry (scm_tc16_fport);
+ SCM_SET_CELL_TYPE(port, scm_tc16_fport | mode_bits);
+ pt = SCM_PTAB_ENTRY(port);
{
scm_t_fport *fp
- = (scm_t_fport *) scm_must_malloc (sizeof (scm_t_fport),
- FUNC_NAME);
+ = (scm_t_fport *) scm_gc_malloc (sizeof (scm_t_fport), "file port");
fp->fdes = fdes;
pt->rw_random = SCM_FDES_RANDOM_P (fdes);
scm_fport_buffer_add (port, -1, -1);
}
SCM_SET_FILENAME (port, name);
- SCM_ALLOW_INTS;
+ scm_mutex_unlock (&scm_i_port_table_mutex);
return port;
}
#undef FUNC_NAME
{
int fdes;
SCM name = SCM_FILENAME (exp);
- if (SCM_STRINGP (name) || SCM_SYMBOLP (name))
+ if (scm_is_string (name) || SCM_SYMBOLP (name))
scm_display (name, port);
else
scm_puts (SCM_PTOBNAME (SCM_PTOBNUM (exp)), port);
return 1;
}
-#ifdef GUILE_ISELECT
+#ifndef __MINGW32__
/* thread-local block for input on fport's fdes. */
static void
fport_wait_for_input (SCM port)
while (n == -1 && errno == EINTR);
}
}
-#endif
+#endif /* !__MINGW32__ */
static void fport_flush (SCM port);
scm_t_port *pt = SCM_PTAB_ENTRY (port);
scm_t_fport *fp = SCM_FSTREAM (port);
-#ifdef GUILE_ISELECT
+#ifndef __MINGW32__
fport_wait_for_input (port);
-#endif
+#endif /* !__MINGW32__ */
SCM_SYSCALL (count = read (fp->fdes, pt->read_buf, pt->read_buf_size));
if (count == -1)
scm_syserror ("fport_fill_input");
/* becomes 1 when process is exiting: normal exception handling won't
work by this time. */
-extern int terminating;
+extern int scm_i_terminating;
static void
fport_flush (SCM port)
}
pt->write_pos = pt->write_buf + remaining;
}
- if (terminating)
+ if (scm_i_terminating)
{
const char *msg = "Error: could not flush file-descriptor ";
char buf[11];
if (pt->read_buf == pt->putback_buf)
pt->read_buf = pt->saved_read_buf;
if (pt->read_buf != &pt->shortbuf)
- scm_must_free (pt->read_buf);
+ scm_gc_free (pt->read_buf, pt->read_buf_size, "port buffer");
if (pt->write_buf != &pt->shortbuf)
- scm_must_free (pt->write_buf);
- scm_must_free ((char *) fp);
+ scm_gc_free (pt->write_buf, pt->write_buf_size, "port buffer");
+ scm_gc_free (fp, sizeof (*fp), "file port");
return rv;
}
{
scm_tc16_fport = scm_make_fptob ();
- scm_c_define ("_IOFBF", SCM_MAKINUM (_IOFBF));
- scm_c_define ("_IOLBF", SCM_MAKINUM (_IOLBF));
- scm_c_define ("_IONBF", SCM_MAKINUM (_IONBF));
+ scm_c_define ("_IOFBF", scm_from_int (_IOFBF));
+ scm_c_define ("_IOLBF", scm_from_int (_IOLBF));
+ scm_c_define ("_IONBF", scm_from_int (_IONBF));
-#ifndef SCM_MAGIC_SNARFER
#include "libguile/fports.x"
-#endif
}
/*