This is the mail archive of the guile@cygnus.com mailing list for the guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

PATCH: ports.c and fports.c


This is a change to move checks of errno to below the scm_ptobs interface,
which seems to me to be where they belong. 

The only difficulty this change causes is that when raising a system error
exception below the ptobs interface we have to guess the name of the
primitive procedure that's calling us. This is easy to do if we know that
only one top-level primitive calls this ptobs function, but impossible if
any ptobs functions are shared between primitives. Perhaps if/when the
ptobs interface gets an overhaul we can add a `caller' argument to all the
port functions.

I also found that scm_ptobs[].fclose and scm_syserr were being called
within SCM_DEFER_INTS so this moves them outside. Can someone please check
that I've done this correctly and that I haven't exposed anything
vulnerable to interrupts. 

Ian

Subject: PATCH: libguile/ports.c libguile/fports.c

This is a change to move checks of errno to below the scm_ptobs
interface, which seems to me to be where they belong.

The only difficulty this causes is that when raising a system error
exception below the ptobs interface we have to guess the name of the
primitive procedure that's calling us. This is easy to do if we know
that only one top-level primitive calls this ptobs function, but
impossible if any are shared. Perhaps if/when the ptobs interface gets
an overhaul we can add a caller argument to all the port functions.

I also found that scm_ptobs[].fclose and scm_syserr were being called
within SCM_DEFER_INTS so this moves them outside.

Can someone please check that I've done this correctly and that
I haven't exposed anything vulnerable to interrupts.

Ian

1999-01-29  Ian Grant <I.A.N.Grant@damtp.cam.ac.uk>

        * ports.c: Moved tests for system errors to below
        the scm_ptobs interface. Necessary because not all ports
        are over system calls now. Also changed scm_close_port so
        that scm_ptobs[].fclose isn't called inside SCM_DEFER_INTS.

        * fports.c: Changed local_[fp]close to check errno and
        do what was previously done after scm_ptobs[].fclose
        returned. Changed the scm_ptobs[].free functions to just
        close the file/pipe, as they used to.

*** guile-core.orig/libguile/fports.c	Fri Jan 29 14:38:12 1999
--- guile-core/libguile/fports.c	Sat Jan 30 21:57:12 1999
***************
*** 502,508 ****
  local_fclose (SCM port)
  {
    FILE *fp = (FILE *) SCM_STREAM (port);
  
!   return fclose (fp);
  }
  
--- 502,513 ----
  local_fclose (SCM port)
  {
+   int rv;
    FILE *fp = (FILE *) SCM_STREAM (port);
  
!   SCM_SYSCALL (rv = fclose (fp));
!   /* ports with a closed file descriptor can be reclosed without error.  */
!   if (rv < 0 && errno != EBADF)
!     scm_syserror ("close-port"); /* We have to guess who called us. */
!   return rv;
  }
  
***************
*** 511,516 ****
  {
    FILE *fp = (FILE *) SCM_STREAM (port);
!   return fflush (fp);
    FPORT_ALL_OKAY (port);
  }
  
--- 516,526 ----
  {
    FILE *fp = (FILE *) SCM_STREAM (port);
!   int rv;
! 
!   SCM_SYSCALL (rv = fflush (fp));
! 
    FPORT_ALL_OKAY (port);
+ 
+   return rv;
  }
  
***************
*** 553,558 ****
--- 563,587 ----
  local_pclose (SCM port)
  {
+   int rv;
    FILE *fp = (FILE *) SCM_STREAM (port);
  
+   SCM_SYSCALL (rv = pclose (fp));
+   /* ports with a closed file descriptor can be reclosed without error.  */
+   if (rv < 0 && errno != EBADF)
+     scm_syserror ("close-port"); /* We have to guess who called us. */
+   return rv;
+ }
+ 
+ static int
+ local_free_fport (SCM port)
+ {
+   FILE *fp = (FILE *) SCM_STREAM (port);
+   return fclose (fp);
+ }
+ 
+ static int
+ local_free_pport (SCM port)
+ {
+   FILE *fp = (FILE *) SCM_STREAM (port);
    return pclose (fp);
  }
***************
*** 564,568 ****
  {
    0,
!   local_fclose,
    prinfport,
    0,
--- 593,597 ----
  {
    0,
!   local_free_fport,
    prinfport,
    0,
***************
*** 580,584 ****
  {
    0,
!   local_pclose,  
    print_pipe_port,
    0,
--- 609,613 ----
  {
    0,
!   local_free_pport,  
    print_pipe_port,
    0,
diff -r -C 2 guile-core.orig/libguile/ports.c guile-core/libguile/ports.c
*** guile-core.orig/libguile/ports.c	Fri Jan 29 14:39:00 1999
--- guile-core/libguile/ports.c	Sat Jan 30 21:57:00 1999
***************
*** 446,449 ****
--- 446,450 ----
    scm_sizet i;
    int rv;
+   int (*pfclose)(SCM);
  
    port = SCM_COERCE_OUTPORT (port);
***************
*** 454,467 ****
      return SCM_BOOL_F;
    i = SCM_PTOBNUM (port);
!   SCM_DEFER_INTS;
!   if (scm_ptobs[i].fclose)
!     {
!       SCM_SYSCALL (rv = (scm_ptobs[i].fclose) (port));
!       /* ports with a closed file descriptor can be reclosed without error.  */
!       if (rv < 0 && errno != EBADF)
! 	scm_syserror (s_close_port);
!     }
    else
      rv = 0;
    scm_remove_from_port_table (port);
    SCM_SETAND_CAR (port, ~SCM_OPN);
--- 455,464 ----
      return SCM_BOOL_F;
    i = SCM_PTOBNUM (port);
!   pfclose = scm_ptobs[i].fclose;
!   if (pfclose != NULL)
!     rv = (*pfclose) (port);
    else
      rv = 0;
+   SCM_DEFER_INTS;
    scm_remove_from_port_table (port);
    SCM_SETAND_CAR (port, ~SCM_OPN);
***************
*** 556,560 ****
    {
      scm_sizet i = SCM_PTOBNUM (port);
!     SCM_SYSCALL ((scm_ptobs[i].fflush) (port));
      return SCM_UNSPECIFIED;
    }
--- 553,557 ----
    {
      scm_sizet i = SCM_PTOBNUM (port);
!     (scm_ptobs[i].fflush) (port);
      return SCM_UNSPECIFIED;
    }