# New Ticket Created by  Jürgen Bömmels 
# Please include the string:  [perl #22864]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org/rt2/Ticket/Display.html?id=22864 >


Hello,

this is the first step of the IO-system away from the mem_sys_alloc/free
memory-managment system to a full-fledged PMC-based system.

In this patch only the ParrotIO structures are transformed to a
PMC. This is simply done by wrapping the ParrotIO in a PMC_data. For
easier access of the layer-pointer (this is the first thing that is
actually needed if a function is called) is stored in the
cache.struct_val. The rest of the patch is mostly to an update of
parrot to the new prototypes.

The filedescriptor-ops are not deleted in this patch, but use
a hack to always create a new temporary PMC from the filedescriptor.

The standard filedescriptors stdin, stdout and stderr are protected
from closing by the PMC_destroy function by marking them as
PIO_F_SHARED. Don't know if this is a right solution.



-- attachment  1 ------------------------------------------------------
url: http://rt.perl.org/rt2/attach/60093/44531/17a4cc/io7.diff

Index: embed.c
===================================================================
RCS file: /cvs/public/parrot/embed.c,v
retrieving revision 1.68
diff -u -r1.68 embed.c
--- embed.c	14 Jun 2003 17:48:31 -0000	1.68
+++ embed.c	30 Jun 2003 21:42:46 -0000
@@ -71,7 +71,7 @@
     off_t program_size, wanted;
     char *program_code;
     struct PackFile *pf;
-    ParrotIO * io = NULL;
+    PMC * io = NULL;
     INTVAL is_mapped = 0;
 
 #ifdef HAS_HEADER_SYSSTAT
@@ -84,7 +84,7 @@
 
     if (filename == NULL || strcmp(filename, "-") == 0) {
         /* read from STDIN */
-        io = PIO_STDIN(interpreter);
+        io = new_io_pmc(interpreter, PIO_STDIN(interpreter));
         /* read 1k at a time */
         program_size = 0;
     }
Index: io.ops
===================================================================
RCS file: /cvs/public/parrot/io.ops,v
retrieving revision 1.23
diff -u -r1.23 io.ops
--- io.ops	30 Jun 2003 07:47:32 -0000	1.23
+++ io.ops	30 Jun 2003 21:42:46 -0000
@@ -36,7 +36,7 @@
 =cut
 
 inline op close(in PMC) {
-	PIO_close(interpreter, (ParrotIO*)(PMC_data($1)));
+	PIO_close(interpreter, $1);
 	goto NEXT();
 }
 
@@ -58,20 +58,15 @@
   ParrotIO *io;
   mode = string_to_cstring(interpreter, $3);
 
-  io = PIO_fdopen(interpreter, $2, mode);
+  $1 = PIO_fdopen(interpreter, $2, mode);
+  if (!$1) {
+    $1 = pmc_new(interpreter, enum_class_PerlUndef);
+  }
   /* string_cstring_free(mode); */
   /* TODO all results from sring_to_cstring() need freeing
      but this generates ugly warnings WRT discarding the const
      qualifier -lt
    */
-  if (io) {
-    $1 = pmc_new_noinit(interpreter, enum_class_ParrotIO);
-    VTABLE_init(interpreter, $1);
-    PMC_data($1) = io;
-  }
-  else {
-    $1 = pmc_new(interpreter, enum_class_PerlUndef);
-  }
 #else
     $1 = pmc_new(interpreter, enum_class_PerlUndef);
 #endif
@@ -88,22 +83,16 @@
 =cut
 
 inline op open(out PMC, in STR, in STR) {
-  ParrotIO * io;
   /* These char * need to go away soon */
   const char * path, * mode;
 
   path = string_to_cstring(interpreter, $2);
   mode = string_to_cstring(interpreter, $3);
 
-  io = PIO_open(interpreter, path, mode);
+  $1 = PIO_open(interpreter, path, mode);
   /* string_cstring_free(mode); */
   /* string_cstring_free(path); */
-  if(io) {
-    $1 = pmc_new_noinit(interpreter, enum_class_ParrotIO);
-    VTABLE_init(interpreter, $1);
-    PMC_data($1) = io;
-  }
-  else {
+  if(!$1) {
     $1 = pmc_new(interpreter, enum_class_PerlUndef);
   }
   goto NEXT();
@@ -123,7 +112,7 @@
 
 op open(out INT, in STR) {
   char *path = string_to_cstring(interpreter, $2);
-  ParrotIO *io = PIO_open(interpreter, path, "+<");
+  PMC *io = PIO_open(interpreter, path, "+<");
   /* string_cstring_free(path); */
   if (io) {
     $1 = PIO_getfd(interpreter, io);
@@ -137,7 +126,7 @@
 op open(out INT, in STR, in STR) {
   char *path = string_to_cstring(interpreter, $2);
   char *mode = string_to_cstring(interpreter, $3);
-  ParrotIO *io = PIO_open(interpreter, path, mode);
+  PMC *io = PIO_open(interpreter, path, mode);
   /* string_cstring_free(mode); */
   /* string_cstring_free(path); */
   if (io) {
@@ -151,7 +140,7 @@
 
 ########################################
 
-=item B<close>(out INT)
+=item B<close>(inout INT)
 
 Close file opened on file descriptor $1.
 
@@ -165,7 +154,7 @@
     table = ((ParrotIOData*)interpreter->piodata)->table;
     io = table[$1];
     table[$1] = NULL;
-    PIO_close(interpreter, io);
+    PIO_close(interpreter, new_io_pmc(interpreter, io));
   }
   goto NEXT();
 }
@@ -208,16 +197,18 @@
 op print(in STR) {
   STRING *s = $1;
   if (s && string_length(s)) {
-    PIO_putps(interpreter, PIO_STDOUT(interpreter), s);
+    PIO_putps(interpreter, new_io_pmc(interpreter, PIO_STDOUT(interpreter)),
+              s);
   }
   goto NEXT();
 }
 
 op print(in PMC) {
   PMC *p = $1;
-  STRING *s = (p->vtable->get_string(interpreter, p));
+  STRING *s = (VTABLE_get_string(interpreter, p));
   if (s) {
-    PIO_putps(interpreter, PIO_STDOUT(interpreter), s);
+    PIO_putps(interpreter, new_io_pmc(interpreter, PIO_STDOUT(interpreter)),
+              s);
   }
   goto NEXT();
 }
@@ -226,14 +217,14 @@
 op print(in INT, in INT) {
   ParrotIO *io = ((ParrotIOData*)interpreter->piodata)->table[$1];
   STRING *s = Parrot_sprintf_c(interpreter, INTVAL_FMT, $2);
-  PIO_putps(interpreter, io, s);
+  PIO_putps(interpreter, new_io_pmc(interpreter, io), s);
   goto NEXT();
 }
 
 op print(in INT, in NUM) {
   ParrotIO *io = ((ParrotIOData*)interpreter->piodata)->table[$1];
   STRING *s = Parrot_sprintf_c(interpreter, "%f", (double)$2);
-  PIO_putps(interpreter, io, s);
+  PIO_putps(interpreter, new_io_pmc(interpreter, io), s);
   goto NEXT();
 }
 
@@ -241,7 +232,7 @@
   STRING *s = $2;
   ParrotIO *io = ((ParrotIOData*)interpreter->piodata)->table[$1];
   if (s && string_length(s)) {
-    PIO_putps(interpreter, io, s);
+    PIO_putps(interpreter, new_io_pmc(interpreter, io), s);
   }
   goto NEXT();
 }
@@ -251,14 +242,14 @@
   ParrotIO *io = ((ParrotIOData*)interpreter->piodata)->table[$1];
   STRING *s = (p->vtable->get_string(interpreter, p));
   if (s) {
-    PIO_putps(interpreter, io, s);
+    PIO_putps(interpreter, new_io_pmc(interpreter, io), s);
   }
   goto NEXT();
 }
 
 op flush(in INT) {
   ParrotIO *io = ((ParrotIOData*)interpreter->piodata)->table[$1];
-  PIO_flush(interpreter, io);
+  PIO_flush(interpreter, new_io_pmc(interpreter, io));
   goto NEXT();
 }
 
@@ -271,10 +262,8 @@
 =cut
 
 op print(in PMC, in STR) {
-  ParrotIO * io;
-  io = (ParrotIO*)(PMC_data($1));
-  if ($2 && io) {
-    PIO_write(interpreter, io, ($2)->strstart, string_length($2));
+  if ($2 && $1) {
+    PIO_write(interpreter, $1, ($2)->strstart, string_length($2));
   }
   goto NEXT();
 }
@@ -289,8 +278,8 @@
 
 op printerr(in STR) {
   if ($1) {
-    PIO_write(interpreter, PIO_STDERR(interpreter), ($1)->strstart,
-			string_length($1));
+    PIO_putps(interpreter, new_io_pmc(interpreter, PIO_STDERR(interpreter)),
+              $1);
   }
   goto NEXT();
 }
@@ -311,28 +300,22 @@
 =cut
 
 op puts(in STR) {
-  if (($1) && string_length($1)) {
-    PIO_write(interpreter, PIO_STDOUT(interpreter), ($1)->strstart,
-			string_length($1));
+  if ($1) {
+    PIO_putps(interpreter, new_io_pmc(interpreter, PIO_STDOUT(interpreter)),
+             $1);
   }
   goto NEXT();
 }
 
 op puts(in INT) {
   STRING * s = string_from_int(interpreter, $1);
-  if (string_length(s)) {
-    PIO_write(interpreter, PIO_STDOUT(interpreter), s->strstart,
-			string_length(s));
-  }
+  PIO_putps(interpreter, new_io_pmc(interpreter, PIO_STDOUT(interpreter)), s);
   goto NEXT();
 }
 
 op puts(in NUM) {
   STRING * s = Parrot_sprintf_c(interpreter, "%f", $1);
-  if (string_length(s)) {
-    PIO_write(interpreter, PIO_STDOUT(interpreter), s->strstart,
-			string_length(s));
-  }
+  PIO_putps(interpreter, new_io_pmc(interpreter, PIO_STDOUT(interpreter)), s);
   goto NEXT();
 }
 
@@ -363,7 +346,8 @@
     n = $2;
   $1 = string_make(interpreter, NULL, n, NULL, 0, NULL);
   memset(($1)->strstart, 0, n);
-  nr = PIO_read(interpreter, PIO_STDIN(interpreter), ($1)->strstart, (size_t)n);
+  nr = PIO_read(interpreter, new_io_pmc(interpreter, PIO_STDIN(interpreter)),
+                ($1)->strstart, (size_t)n);
   if(nr > 0)
     ($1)->strlen = ($1)->bufused = nr;
   else
@@ -380,8 +364,7 @@
     n = $3;
   $1 = string_make(interpreter, NULL, n, NULL, 0, NULL);
   memset(($1)->strstart, 0, n);
-  nr = PIO_read(interpreter, (ParrotIO*)(PMC_data($2)),
-    ($1)->strstart, (size_t)n);
+  nr = PIO_read(interpreter, $2, ($1)->strstart, (size_t)n);
   if(nr > 0)
     ($1)->strlen = ($1)->bufused = nr;
   else
@@ -405,9 +388,11 @@
   memset(($1)->strstart, 0, 65535);
 
   if ($2 >= 0) {
+    PMC *pmc;
     io = ((ParrotIOData*)interpreter->piodata)->table[$2];
-    PIO_setlinebuf(interpreter, io);
-    len = PIO_read(interpreter, io, ($1)->strstart, 65534);
+    pmc = new_io_pmc(interpreter, io);
+    PIO_setlinebuf(interpreter, pmc);
+    len = PIO_read(interpreter, pmc, ($1)->strstart, 65534);
     ($1)->strlen = ($1)->bufused = len;
   }
   goto NEXT();
@@ -430,19 +415,15 @@
 =cut
 
 op seek(out INT, in PMC, in INT, in INT) {
-  ParrotIO * io;
-  io = (ParrotIO*)(PMC_data($2));
-  if (io) {
-    $1 = (INTVAL)PIO_seek(interpreter, io, 0, $3, $4);
+  if ($2) {
+    $1 = (INTVAL)PIO_seek(interpreter, $2, 0, $3, $4);
   }
   goto NEXT();
 }
 
 op seek(out INT, in PMC, in INT, in INT, in INT) {
-  ParrotIO * io;
-  io = (ParrotIO*)(PMC_data($2));
-  if (io) {
-    $1 = (INTVAL)PIO_seek(interpreter, io, $3, $4, $5);
+  if ($2) {
+    $1 = (INTVAL)PIO_seek(interpreter, $2, $3, $4, $5);
   }
   goto NEXT();
 }
Index: classes/parrotio.pmc
===================================================================
RCS file: /cvs/public/parrot/classes/parrotio.pmc,v
retrieving revision 1.1
diff -u -r1.1 parrotio.pmc
--- classes/parrotio.pmc	23 Jun 2003 09:26:18 -0000	1.1
+++ classes/parrotio.pmc	30 Jun 2003 21:42:46 -0000
@@ -26,8 +26,8 @@
     }
 
     void destroy () {
-	if (PMC_data(SELF)) {
-	    PIO_close(interpreter, (ParrotIO*)(PMC_data(SELF)));
-	}
+	ParrotIO *io = PMC_data(SELF);
+        if (!(io->flags & PIO_F_SHARED))
+            PIO_close(interpreter, SELF); 
     }
 }
Index: include/parrot/io.h
===================================================================
RCS file: /cvs/public/parrot/include/parrot/io.h,v
retrieving revision 1.32
diff -u -r1.32 io.h
--- include/parrot/io.h	23 Jun 2003 09:26:25 -0000	1.32
+++ include/parrot/io.h	30 Jun 2003 21:42:47 -0000
@@ -293,42 +293,42 @@
 extern void PIO_finish(theINTERP);
 extern INTVAL PIO_init_stacks(theINTERP);
 extern void PIO_atexit(theINTERP);
-extern INTVAL PIO_push_layer(theINTERP, ParrotIOLayer *, ParrotIO *);
-extern ParrotIOLayer *PIO_pop_layer(theINTERP, ParrotIO *);
+extern INTVAL PIO_push_layer(theINTERP, ParrotIOLayer *, PMC *);
+extern ParrotIOLayer *PIO_pop_layer(theINTERP, PMC *);
 extern ParrotIOLayer *PIO_copy_stack(ParrotIOLayer *);
 
 
+extern struct PMC *new_io_pmc(struct Parrot_Interp *, ParrotIO *);
 extern void free_io_header(ParrotIO *);
 extern ParrotIOTable alloc_pio_array(int);
 extern int realloc_pio_array(ParrotIOTable *, int);
-extern ParrotIO *PIO_new(struct Parrot_Interp *, ParrotIO *,
-                         INTVAL, INTVAL, INTVAL);
-extern void PIO_destroy(theINTERP, ParrotIO *io);
+extern ParrotIO *PIO_new(struct Parrot_Interp *, INTVAL, INTVAL, INTVAL);
+extern void PIO_destroy(theINTERP, PMC *io);
 
 extern INTVAL PIO_base_init(theINTERP, ParrotIOLayer *proto);
 extern ParrotIOLayer *PIO_base_new_layer(ParrotIOLayer *proto);
 extern void PIO_base_delete_layer(ParrotIOLayer *proto);
 
 extern INTVAL PIO_parse_open_flags(const char *flagstr);
-extern ParrotIO *PIO_open(theINTERP, const char *, const char *);
-extern ParrotIO *PIO_fdopen(theINTERP, PIOHANDLE, const char *);
-extern INTVAL PIO_close(theINTERP, ParrotIO *);
-extern void PIO_flush(theINTERP, ParrotIO *);
-extern INTVAL PIO_read(theINTERP, ParrotIO *, void *, size_t);
-extern INTVAL PIO_write(theINTERP, ParrotIO *, void *, size_t);
-extern INTVAL PIO_setbuf(theINTERP, ParrotIO *, size_t);
-extern INTVAL PIO_setlinebuf(theINTERP, ParrotIO *);
-extern INTVAL PIO_puts(theINTERP, ParrotIO *, const char *);
-extern INTVAL PIO_seek(theINTERP, ParrotIO *, INTVAL hi,
+extern PMC *PIO_open(theINTERP, const char *, const char *);
+extern PMC *PIO_fdopen(theINTERP, PIOHANDLE, const char *);
+extern INTVAL PIO_close(theINTERP, PMC *);
+extern void PIO_flush(theINTERP, PMC *);
+extern INTVAL PIO_read(theINTERP, PMC *, void *, size_t);
+extern INTVAL PIO_write(theINTERP, PMC *, void *, size_t);
+extern INTVAL PIO_setbuf(theINTERP, PMC *, size_t);
+extern INTVAL PIO_setlinebuf(theINTERP, PMC *);
+extern INTVAL PIO_puts(theINTERP, PMC *, const char *);
+extern INTVAL PIO_seek(theINTERP, PMC *, INTVAL hi,
                        INTVAL lo, INTVAL whence);
-extern INTVAL PIO_eof(theINTERP, ParrotIO *);
+extern INTVAL PIO_eof(theINTERP, PMC *);
 
-extern INTVAL PIO_putps(theINTERP, ParrotIO *io, STRING *s);
-extern INTVAL PIO_fprintf(theINTERP, ParrotIO *io, const char *s, ...);
+extern INTVAL PIO_putps(theINTERP, PMC *io, STRING *s);
+extern INTVAL PIO_fprintf(theINTERP, PMC *io, const char *s, ...);
 extern INTVAL PIO_printf(theINTERP, const char *s, ...);
 extern INTVAL PIO_eprintf(theINTERP, const char *s, ...);
-extern INTVAL PIO_getfd(theINTERP, ParrotIO *io);
-extern PIOOFF_T PIO_tell(theINTERP, ParrotIO *io);
+extern INTVAL PIO_getfd(theINTERP, PMC *io);
+extern PIOOFF_T PIO_tell(theINTERP, PMC *io);
 
 /* Put platform specific macros here if you must */
 #ifdef PIO_OS_WIN32
Index: io/io.c
===================================================================
RCS file: /cvs/public/parrot/io/io.c,v
retrieving revision 1.39
diff -u -r1.39 io.c
--- io/io.c	30 Jun 2003 16:02:54 -0000	1.39
+++ io/io.c	30 Jun 2003 21:42:47 -0000
@@ -40,16 +40,15 @@
 
 PIOOFF_T piooffsetzero;
 
-#if 0
-void
-free_io_header(ParrotIO *io)
+PMC *
+new_io_pmc(theINTERP, ParrotIO *io)
 {
-    /* Free buffer if it was malloced */
-    if (io->b.startb && (io->b.flags & PIO_BF_MALLOC))
-        free(io->b.startb);
-    free(io);
+    PMC *new_pmc;
+    new_pmc = pmc_new(interpreter, enum_class_ParrotIO);
+    PMC_data(new_pmc) = io;
+    new_pmc->cache.struct_val = io->stack;
+    return new_pmc;
 }
-#endif
 
 ParrotIOTable
 alloc_pio_array(int numhandles)
@@ -69,18 +68,15 @@
 }
 
 /*
- * Create a new IO stream, optionally reusing old structure.
+ * Create a new IO stream,
  */
 ParrotIO *
-PIO_new(theINTERP, ParrotIO *old, INTVAL iotype, INTVAL flags, INTVAL mode)
+PIO_new(theINTERP, INTVAL iotype, INTVAL flags, INTVAL mode)
 {
     ParrotIO *new_io;
 
     UNUSED(iotype);
 
-    if (old) {
-        /* FIXME: Reuse old IO */
-    }
     new_io = (ParrotIO *)mem_sys_allocate(sizeof(ParrotIO));
     new_io->fpos = new_io->lpos = piooffsetzero;
     new_io->flags = flags;
@@ -98,8 +94,9 @@
  * Destroying the IO-Stream, at the moment only free memory
  */
 void
-PIO_destroy(theINTERP, ParrotIO *io)
+PIO_destroy(theINTERP, PMC *pmc)
 {
+    ParrotIO *io = PMC_data(pmc);
     UNUSED(interpreter);
 
     if (io->b.startb && (io->b.flags & PIO_BF_MALLOC))
@@ -137,7 +134,7 @@
     }
 
     if (Interp_flags_TEST(interpreter, PARROT_DEBUG_FLAG)) {
-        PIO_puts(interpreter, PIO_STDERR(interpreter),
+        PIO_puts(interpreter, new_io_pmc(interpreter, PIO_STDERR(interpreter)),
                  "PIO: IO system initialized.\n");
     }
 }
@@ -156,7 +153,7 @@
 
     for (i = 0 ; i < PIO_NR_OPEN; i++) {
         if ( (io = GET_INTERP_IOD(interpreter)->table[i]) ) {
-            PIO_close(interpreter, io);
+            PIO_close(interpreter, new_io_pmc(interpreter, io));
         }
     }
     for (p = GET_INTERP_IO(interpreter); p; ) {
@@ -275,12 +272,15 @@
  * Push a layer onto an IO object or the default stack
  */
 INTVAL
-PIO_push_layer(theINTERP, ParrotIOLayer *layer, ParrotIO *io)
+PIO_push_layer(theINTERP, ParrotIOLayer *layer, PMC *pmc)
 {
     ParrotIOLayer *t;
+
     if (layer == NULL)
         return -1;
-    if (io != NULL) {
+    if (pmc != NULL) {
+        ParrotIO *io = PMC_data(pmc);
+
         if (io->stack == NULL && (layer->flags & PIO_L_TERMINAL) == 0) {
             /* Error( 1st layer must be terminal) */
             return -1;
@@ -328,9 +328,11 @@
  * Pop a layer from an IO object or the default stack
  */
 ParrotIOLayer *
-PIO_pop_layer(theINTERP, ParrotIO *io)
+PIO_pop_layer(theINTERP, PMC *pmc)
 {
     ParrotIOLayer *layer;
+    ParrotIO *io = PMC_data(pmc);
+
     if (io) {
         layer = io->stack;
         if (layer) {
@@ -437,12 +439,14 @@
  * API for controlling buffering specifics on an IO stream
  */
 INTVAL
-PIO_setbuf(theINTERP, ParrotIO *io, size_t bufsize)
+PIO_setbuf(theINTERP, PMC *pmc, size_t bufsize)
 {
-    ParrotIOLayer *l = io->stack;
-    PIO_flush(interpreter, io);
+    ParrotIOLayer *l = pmc->cache.struct_val;
+
+    PIO_flush(interpreter, pmc);
     while (l) {
         if (l->api->SetBuf) {
+            ParrotIO *io = PMC_data(pmc);
             return (*l->api->SetBuf) (interpreter, l, io, bufsize);
         }
         l = PIO_DOWNLAYER(l);
@@ -453,12 +457,13 @@
 
 
 INTVAL
-PIO_setlinebuf(theINTERP, ParrotIO *io)
+PIO_setlinebuf(theINTERP, PMC *pmc)
 {
-    ParrotIOLayer *l = io->stack;
+    ParrotIOLayer *l = pmc->cache.struct_val;
 
     while (l) {
         if (l->api->SetLineBuf) {
+            ParrotIO *io = PMC_data(pmc);            
             return (*l->api->SetLineBuf) (interpreter, l, io);
         }
         l = PIO_DOWNLAYER(l);
@@ -468,18 +473,19 @@
 }
 
 
-ParrotIO *
+PMC *
 PIO_open(theINTERP, const char *spath, const char *sflags)
 {
     ParrotIO *io;
     ParrotIOLayer *l = GET_INTERP_IO(interpreter);
     INTVAL flags = PIO_parse_open_flags(sflags);
+
     while (l) {
         if (l->api->Open) {
             io = (*l->api->Open) (interpreter, l, spath, flags);
             if (io) {
                 io->stack = GET_INTERP_IO(interpreter);
-                return io;
+                return new_io_pmc(interpreter, io);
             }
             else {
                 return NULL;
@@ -496,18 +502,24 @@
  * This is particularly used to init Parrot Standard IO onto
  * the OS IO handles (0,1,2).
  */
-ParrotIO *
+PMC *
 PIO_fdopen(theINTERP, PIOHANDLE fd, const char *sflags)
 {
     ParrotIO *io;
     INTVAL flags;
     ParrotIOLayer *l = GET_INTERP_IO(interpreter);
+
     flags = PIO_parse_open_flags(sflags);
     while (l) {
         if (l->api->FDOpen) {
             io = (*l->api->FDOpen) (interpreter, l, fd, flags);
-            io->stack = GET_INTERP_IO(interpreter);
-            return io;
+            if (io) {
+                io->stack = GET_INTERP_IO(interpreter);
+                return new_io_pmc(interpreter, io);
+            }
+            else {
+                return NULL;
+            }
         }
         l = PIO_DOWNLAYER(l);
     }
@@ -516,37 +528,38 @@
 
 
 INTVAL
-PIO_close(theINTERP, ParrotIO *io)
+PIO_close(theINTERP, PMC *pmc)
 {
     INTVAL res;
-    if (io) {
-        ParrotIOLayer *l = io->stack;
-        while (l) {
-            if (l->api->Close) {
-                PIO_flush(interpreter, io);
-                res =  (*l->api->Close) (interpreter, l, io);
-                PIO_destroy(interpreter, io);
-                return res;
-            }
-            l = PIO_DOWNLAYER(l);
+    ParrotIOLayer *l = pmc->cache.struct_val;
+
+    while (l) {
+        if (l->api->Close) {
+            ParrotIO *io = PMC_data(pmc);
+            PIO_flush(interpreter, pmc);
+            res =  (*l->api->Close) (interpreter, l, io);
+            PIO_destroy(interpreter, pmc);
+            return res;
         }
+        l = PIO_DOWNLAYER(l);
     }
+
     return 0;
 }
 
 
 void
-PIO_flush(theINTERP, ParrotIO *io)
+PIO_flush(theINTERP, PMC *pmc)
 {
-    if (io) {
-        ParrotIOLayer *l = io->stack;
-        while (l) {
-            if (l->api->Flush) {
-                (*l->api->Flush) (interpreter, l, io);
-                return;
-            }
-            l = PIO_DOWNLAYER(l);
+    ParrotIOLayer *l = pmc->cache.struct_val;
+
+    while (l) {
+        if (l->api->Flush) {
+            ParrotIO *io = PMC_data(pmc);
+            (*l->api->Flush) (interpreter, l, io);
+            return;
         }
+        l = PIO_DOWNLAYER(l);
     }
 }
 
@@ -555,16 +568,16 @@
  * Iterate down the stack to the first layer implementing "Read" API
  */
 INTVAL
-PIO_read(theINTERP, ParrotIO *io, void *buffer, size_t len)
+PIO_read(theINTERP, PMC *pmc, void *buffer, size_t len)
 {
-    if (io) {
-        ParrotIOLayer *l = io->stack;
-        while (l) {
-            if (l->api->Read) {
-                return (*l->api->Read) (interpreter, l, io, buffer, len);
-            }
-            l = PIO_DOWNLAYER(l);
+    ParrotIOLayer *l = pmc->cache.struct_val;
+
+    while (l) {
+        if (l->api->Read) {
+            ParrotIO *io = PMC_data(pmc);
+            return (*l->api->Read) (interpreter, l, io, buffer, len);
         }
+        l = PIO_DOWNLAYER(l);
     }
 
     return 0;
@@ -575,16 +588,16 @@
  * Iterate down the stack to the first layer implementing "Write" API
  */
 INTVAL
-PIO_write(theINTERP, ParrotIO *io, void *buffer, size_t len)
+PIO_write(theINTERP, PMC *pmc, void *buffer, size_t len)
 {
-    if (io) {
-        ParrotIOLayer *l = io->stack;
-        while (l) {
-            if (l->api->Write) {
-                return (*l->api->Write) (interpreter, l, io, buffer, len);
-            }
-            l = PIO_DOWNLAYER(l);
+    ParrotIOLayer *l = pmc->cache.struct_val;
+
+    while (l) {
+        if (l->api->Write) {
+            ParrotIO *io = PMC_data(pmc);
+            return (*l->api->Write) (interpreter, l, io, buffer, len);
         }
+        l = PIO_DOWNLAYER(l);
     }
 
     return 0;
@@ -597,17 +610,18 @@
  * a 1 and 2 arg version of seek opcode.
  */
 INTVAL
-PIO_seek(theINTERP, ParrotIO *io, INTVAL hi, INTVAL lo, INTVAL w)
+PIO_seek(theINTERP, PMC *pmc, INTVAL hi, INTVAL lo, INTVAL w)
 {
-    if (io) {
-        ParrotIOLayer *l = io->stack;
-        while (l) {
-            if (l->api->Seek) {
-                return (*l->api->Seek) (interpreter, l, io, hi, lo, w);
-            }
-            l = PIO_DOWNLAYER(l);
+    ParrotIOLayer *l = pmc->cache.struct_val;
+
+    while (l) {
+        if (l->api->Seek) {
+            ParrotIO *io = PMC_data(pmc);
+            return (*l->api->Seek) (interpreter, l, io, hi, lo, w);
         }
+        l = PIO_DOWNLAYER(l);
     }
+
     return -1;
 }
 
@@ -616,16 +630,16 @@
  * Iterate down the stack to the first layer implementing "Tell" API
  */
 PIOOFF_T
-PIO_tell(theINTERP, ParrotIO *io)
+PIO_tell(theINTERP, PMC *pmc)
 {
-    if (io) {
-        ParrotIOLayer *l = io->stack;
-        while (l) {
-            if (l->api->Tell) {
-                return (*l->api->Tell) (interpreter, l, io);
-            }
-            l = PIO_DOWNLAYER(l);
+    ParrotIOLayer *l = pmc->cache.struct_val;
+
+    while (l) {
+        if (l->api->Tell) {
+            ParrotIO *io = PMC_data(pmc);
+            return (*l->api->Tell) (interpreter, l, io);
         }
+        l = PIO_DOWNLAYER(l);
     }
 
     return -1;
@@ -636,8 +650,10 @@
  * Iterate down the stack to the first layer implementing "Read" API
  */
 INTVAL
-PIO_eof(theINTERP, ParrotIO *io)
+PIO_eof(theINTERP, PMC *pmc)
 {
+    ParrotIO *io = PMC_data(pmc);
+
     if (io) {
         return (io->flags & (PIO_F_EOF)) != 0;
     }
@@ -649,38 +665,41 @@
  * PIO_putps is for.
  */
 INTVAL
-PIO_puts(theINTERP, ParrotIO *io, const char *s)
+PIO_puts(theINTERP, PMC *pmc, const char *s)
 {
-    if (io) {
-        ParrotIOLayer *l = io->stack;
-        while (l) {
-            if (l->api->PutS) {
-                return (*l->api->PutS) (interpreter, l, io, s);
-            }
-            l = PIO_DOWNLAYER(l);
+    ParrotIOLayer *l = pmc->cache.struct_val;
+
+    while (l) {
+        if (l->api->PutS) {
+            ParrotIO *io = PMC_data(pmc);
+            return (*l->api->PutS) (interpreter, l, io, s);
         }
+        l = PIO_DOWNLAYER(l);
     }
 
     return -1;
 }
 
 INTVAL
-PIO_putps(theINTERP, ParrotIO *io, STRING *s) {
+PIO_putps(theINTERP, PMC *pmc, STRING *s) 
+{
     INTVAL retVal;
+
     char *temp = string_to_cstring(interpreter, s);
-    retVal = PIO_puts(interpreter, io, temp);
+    retVal = PIO_puts(interpreter, pmc, temp);
     free(temp);
     return retVal;
 }
 
 INTVAL
-PIO_fprintf(theINTERP, ParrotIO *io, const char *s, ...) {
+PIO_fprintf(theINTERP, PMC *pmc, const char *s, ...)
+{
     va_list args;
     INTVAL ret=-1;
 
     va_start(args, s);
 
-    ret=PIO_putps(interpreter, io, Parrot_vsprintf_c(interpreter, s, args));
+    ret=PIO_putps(interpreter, pmc, Parrot_vsprintf_c(interpreter, s, args));
 
     va_end(args);
 
@@ -698,7 +717,8 @@
     str=Parrot_vsprintf_c(interpreter, s, args);
 
     if(interpreter) {
-        ret=PIO_putps(interpreter, PIO_STDOUT(interpreter), str);
+        ret=PIO_putps(interpreter, 
+                      new_io_pmc(interpreter, PIO_STDOUT(interpreter)), str);
     }
     else {
         /* Be nice about this...
@@ -725,7 +745,8 @@
     if(interpreter) {
         str=Parrot_vsprintf_c(interpreter, s, args);
 
-        ret=PIO_putps(interpreter, PIO_STDERR(interpreter), str);
+        ret=PIO_putps(interpreter, 
+                      new_io_pmc(interpreter, PIO_STDERR(interpreter)), str);
     }
     else {
         /* Be nice about this...
@@ -740,9 +761,11 @@
 }
 
 INTVAL
-PIO_getfd(theINTERP, ParrotIO *io)
+PIO_getfd(theINTERP, PMC *pmc)
 {
     INTVAL i;
+    ParrotIO *io = PMC_data(pmc);
+
     ParrotIOTable table = ((ParrotIOData*)interpreter->piodata)->table;
 
     for(i = 0; i < PIO_NR_OPEN; i++) {
Index: io/io_unix.c
===================================================================
RCS file: /cvs/public/parrot/io/io_unix.c,v
retrieving revision 1.24
diff -u -r1.24 io_unix.c
--- io/io_unix.c	24 Mar 2003 07:29:01 -0000	1.24
+++ io/io_unix.c	30 Jun 2003 21:42:48 -0000
@@ -89,13 +89,14 @@
     ParrotIOData *d = GET_INTERP_IOD(interpreter);
     if (d != NULL && d->table != NULL) {
         if ((PIO_STDIN(interpreter) =
-             PIO_unix_fdopen(interpreter, layer, STDIN_FILENO, PIO_F_READ))
+             PIO_unix_fdopen(interpreter, layer, STDIN_FILENO, 
+                             PIO_F_READ | PIO_F_SHARED))
             && (PIO_STDOUT(interpreter) =
                 PIO_unix_fdopen(interpreter, layer, STDOUT_FILENO,
-                                PIO_F_WRITE))
+                                PIO_F_WRITE | PIO_F_SHARED))
             && (PIO_STDERR(interpreter) =
                 PIO_unix_fdopen(interpreter, layer, STDERR_FILENO,
-                                PIO_F_WRITE))
+                                PIO_F_WRITE | PIO_F_SHARED))
             )
             return 0;
     }
@@ -178,7 +179,7 @@
          */
         if (PIO_unix_isatty(fd))
             flags |= PIO_F_CONSOLE;
-        io = PIO_new(interpreter, NULL, type, flags, mode);
+        io = PIO_new(interpreter, type, flags, mode);
         io->fd = fd;
         return io;
     }
@@ -215,7 +216,7 @@
 
     if (PIO_unix_isatty(fd))
         flags |= PIO_F_CONSOLE;
-    io = PIO_new(interpreter, NULL, PIO_F_FILE, flags, mode);
+    io = PIO_new(interpreter, PIO_F_FILE, flags, mode);
     io->fd = fd;
     return io;
 }

Reply via email to