[svn:parrot] r39741 - in branches/io_cleanups: include/parrot src/io src/pmc

whiteknight at svn.parrot.org whiteknight at svn.parrot.org
Tue Jun 23 14:19:38 UTC 2009


Author: whiteknight
Date: Tue Jun 23 14:19:35 2009
New Revision: 39741
URL: https://trac.parrot.org/parrot/changeset/39741

Log:
[io_cleanups]. Handle is now a separate delegate type that encapsulates the low-level file descriptor, and is included as an attribute (not inherited by) FileHandle, Socket, Pipe, etc. These IO PMCs are now that much closer to being properly subclassable from PIR. Parrot builds with this change but there are some test failures. Likely, these are caused by passing a FileHandle to low-level functions that now expect a Handle, or vice-versa. Need help testing on other platforms. Will post to ticket/wiki/mailinglist or something to discuss further steps necessary here

Modified:
   branches/io_cleanups/include/parrot/io.h
   branches/io_cleanups/include/parrot/io_portable.h
   branches/io_cleanups/include/parrot/io_unix.h
   branches/io_cleanups/include/parrot/io_win32.h
   branches/io_cleanups/src/io/api.c
   branches/io_cleanups/src/io/buffer.c
   branches/io_cleanups/src/io/filehandle.c
   branches/io_cleanups/src/io/portable.c
   branches/io_cleanups/src/io/socket_api.c
   branches/io_cleanups/src/io/socket_unix.c
   branches/io_cleanups/src/io/unix.c
   branches/io_cleanups/src/io/win32.c
   branches/io_cleanups/src/pmc/filehandle.pmc
   branches/io_cleanups/src/pmc/handle.pmc
   branches/io_cleanups/src/pmc/socket.pmc
   branches/io_cleanups/src/pmc/stringhandle.pmc

Modified: branches/io_cleanups/include/parrot/io.h
==============================================================================
--- branches/io_cleanups/include/parrot/io.h	Tue Jun 23 11:14:56 2009	(r39740)
+++ branches/io_cleanups/include/parrot/io.h	Tue Jun 23 14:19:35 2009	(r39741)
@@ -198,6 +198,17 @@
         FUNC_MODIFIES(*pmc);
 
 PARROT_EXPORT
+PIOHANDLE Parrot_io_get_os_handle(PARROT_INTERP, ARGIN(PMC * pmc))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+PMC * Parrot_io_get_os_handle_pmc(PARROT_INTERP, ARGIN(PMC * pmc))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
 PARROT_WARN_UNUSED_RESULT
 PIOHANDLE Parrot_io_getfd(PARROT_INTERP, ARGMOD(PMC *pmc))
         __attribute__nonnull__(1)
@@ -223,6 +234,11 @@
 PIOOFF_T Parrot_io_make_offset(INTVAL offset);
 
 PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+PMC * Parrot_io_make_os_handle_pmc(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+PARROT_EXPORT
 PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 PMC * Parrot_io_new_pmc(PARROT_INTERP, INTVAL flags)
@@ -299,6 +315,13 @@
         FUNC_MODIFIES(*pmc);
 
 PARROT_EXPORT
+void Parrot_io_set_os_handle(PARROT_INTERP,
+    ARGIN(PMC * pmc),
+    PIOHANDLE os_handle)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
 PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 PMC * Parrot_io_STDERR(PARROT_INTERP)
@@ -371,6 +394,12 @@
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(pmc) \
     || PARROT_ASSERT_ARG(s)
+#define ASSERT_ARGS_Parrot_io_get_os_handle __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(pmc)
+#define ASSERT_ARGS_Parrot_io_get_os_handle_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(pmc)
 #define ASSERT_ARGS_Parrot_io_getfd __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(pmc)
@@ -381,6 +410,8 @@
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(pmc)
 #define ASSERT_ARGS_Parrot_io_make_offset __attribute__unused__ int _ASSERT_ARGS_CHECK = 0
+#define ASSERT_ARGS_Parrot_io_make_os_handle_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_Parrot_io_new_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_Parrot_io_open __attribute__unused__ int _ASSERT_ARGS_CHECK = \
@@ -408,6 +439,9 @@
 #define ASSERT_ARGS_Parrot_io_seek __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(pmc)
+#define ASSERT_ARGS_Parrot_io_set_os_handle __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(pmc)
 #define ASSERT_ARGS_Parrot_io_STDERR __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_Parrot_io_stdhandle __attribute__unused__ int _ASSERT_ARGS_CHECK = \
@@ -439,10 +473,10 @@
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*filehandle);
 
-INTVAL Parrot_io_flush_buffer(PARROT_INTERP, ARGMOD(PMC *filehandle))
+INTVAL Parrot_io_flush_buffer(PARROT_INTERP, ARGMOD(PMC *handle))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
-        FUNC_MODIFIES(*filehandle);
+        FUNC_MODIFIES(*handle);
 
 INTVAL Parrot_io_init_buffer(PARROT_INTERP)
         __attribute__nonnull__(1);
@@ -506,7 +540,7 @@
     || PARROT_ASSERT_ARG(filehandle)
 #define ASSERT_ARGS_Parrot_io_flush_buffer __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(filehandle)
+    || PARROT_ASSERT_ARG(handle)
 #define ASSERT_ARGS_Parrot_io_init_buffer __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_Parrot_io_peek_buffer __attribute__unused__ int _ASSERT_ARGS_CHECK = \
@@ -588,23 +622,27 @@
 
 PARROT_EXPORT
 PARROT_CAN_RETURN_NULL
-unsigned char * Parrot_io_get_buffer_end(SHIM_INTERP,
-    ARGIN_NULLOK(PMC *filehandle));
+unsigned char * Parrot_io_get_buffer_end(PARROT_INTERP,
+    ARGIN_NULLOK(PMC *filehandle))
+        __attribute__nonnull__(1);
 
 PARROT_EXPORT
 PARROT_CAN_RETURN_NULL
-unsigned char * Parrot_io_get_buffer_next(SHIM_INTERP,
+unsigned char * Parrot_io_get_buffer_next(PARROT_INTERP,
     ARGIN(PMC *filehandle))
+        __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
 PARROT_EXPORT
 PARROT_CAN_RETURN_NULL
-unsigned char * Parrot_io_get_buffer_start(SHIM_INTERP,
+unsigned char * Parrot_io_get_buffer_start(PARROT_INTERP,
     ARGIN(PMC *filehandle))
+        __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
 PARROT_EXPORT
-PIOOFF_T Parrot_io_get_file_position(SHIM_INTERP, ARGIN(PMC *filehandle))
+PIOOFF_T Parrot_io_get_file_position(PARROT_INTERP, ARGIN(PMC *filehandle))
+        __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
 PARROT_EXPORT
@@ -613,12 +651,9 @@
         __attribute__nonnull__(2);
 
 PARROT_EXPORT
-PIOOFF_T Parrot_io_get_last_file_position(SHIM_INTERP,
+PIOOFF_T Parrot_io_get_last_file_position(PARROT_INTERP,
     ARGIN(PMC *filehandle))
-        __attribute__nonnull__(2);
-
-PARROT_EXPORT
-PIOHANDLE Parrot_io_get_os_handle(SHIM_INTERP, ARGIN(PMC *filehandle))
+        __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
 PARROT_EXPORT
@@ -643,9 +678,10 @@
         __attribute__nonnull__(1);
 
 PARROT_EXPORT
-void Parrot_io_set_file_position(SHIM_INTERP,
+void Parrot_io_set_file_position(PARROT_INTERP,
     ARGIN(PMC *filehandle),
     PIOOFF_T file_pos)
+        __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
 PARROT_EXPORT
@@ -655,22 +691,19 @@
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
-PARROT_EXPORT
-void Parrot_io_set_os_handle(SHIM_INTERP,
-    ARGIN(PMC *filehandle),
-    PIOHANDLE file_descriptor)
-        __attribute__nonnull__(2);
-
 PARROT_CAN_RETURN_NULL
-void Parrot_io_clear_buffer(SHIM_INTERP, ARGIN(PMC *filehandle))
+void Parrot_io_clear_buffer(PARROT_INTERP, ARGIN(PMC *filehandle))
+        __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
 PARROT_CAN_RETURN_NULL
-INTVAL Parrot_io_get_buffer_flags(SHIM_INTERP, ARGIN(PMC *filehandle))
+INTVAL Parrot_io_get_buffer_flags(PARROT_INTERP, ARGIN(PMC *filehandle))
+        __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
 PARROT_CAN_RETURN_NULL
-size_t Parrot_io_get_buffer_size(SHIM_INTERP, ARGIN(PMC *filehandle))
+size_t Parrot_io_get_buffer_size(PARROT_INTERP, ARGIN(PMC *filehandle))
+        __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
 PARROT_WARN_UNUSED_RESULT
@@ -682,29 +715,34 @@
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*buf);
 
-void Parrot_io_set_buffer_end(SHIM_INTERP,
+void Parrot_io_set_buffer_end(PARROT_INTERP,
     ARGIN(PMC *filehandle),
     ARGIN_NULLOK(unsigned char *new_end))
+        __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
-void Parrot_io_set_buffer_flags(SHIM_INTERP,
+void Parrot_io_set_buffer_flags(PARROT_INTERP,
     ARGIN(PMC *filehandle),
     INTVAL new_flags)
+        __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
-void Parrot_io_set_buffer_next(SHIM_INTERP,
+void Parrot_io_set_buffer_next(PARROT_INTERP,
     ARGIN(PMC *filehandle),
     ARGIN_NULLOK(unsigned char *new_next))
+        __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
-void Parrot_io_set_buffer_size(SHIM_INTERP,
+void Parrot_io_set_buffer_size(PARROT_INTERP,
     ARGIN(PMC *filehandle),
     size_t new_size)
+        __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
-void Parrot_io_set_buffer_start(SHIM_INTERP,
+void Parrot_io_set_buffer_start(PARROT_INTERP,
     ARGIN(PMC *filehandle),
     ARGIN_NULLOK(unsigned char *new_start))
+        __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
 #define ASSERT_ARGS_Parrot_io_close_filehandle __attribute__unused__ int _ASSERT_ARGS_CHECK = \
@@ -713,21 +751,24 @@
 #define ASSERT_ARGS_Parrot_io_flush_filehandle __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(pmc)
-#define ASSERT_ARGS_Parrot_io_get_buffer_end __attribute__unused__ int _ASSERT_ARGS_CHECK = 0
+#define ASSERT_ARGS_Parrot_io_get_buffer_end __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_Parrot_io_get_buffer_next __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(filehandle)
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(filehandle)
 #define ASSERT_ARGS_Parrot_io_get_buffer_start __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(filehandle)
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(filehandle)
 #define ASSERT_ARGS_Parrot_io_get_file_position __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(filehandle)
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(filehandle)
 #define ASSERT_ARGS_Parrot_io_get_flags __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(filehandle)
 #define ASSERT_ARGS_Parrot_io_get_last_file_position \
      __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(filehandle)
-#define ASSERT_ARGS_Parrot_io_get_os_handle __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(filehandle)
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(filehandle)
 #define ASSERT_ARGS_Parrot_io_is_closed_filehandle \
      __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
@@ -739,31 +780,38 @@
 #define ASSERT_ARGS_Parrot_io_parse_open_flags __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_Parrot_io_set_file_position __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(filehandle)
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(filehandle)
 #define ASSERT_ARGS_Parrot_io_set_flags __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(filehandle)
-#define ASSERT_ARGS_Parrot_io_set_os_handle __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(filehandle)
 #define ASSERT_ARGS_Parrot_io_clear_buffer __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(filehandle)
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(filehandle)
 #define ASSERT_ARGS_Parrot_io_get_buffer_flags __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(filehandle)
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(filehandle)
 #define ASSERT_ARGS_Parrot_io_get_buffer_size __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(filehandle)
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(filehandle)
 #define ASSERT_ARGS_Parrot_io_make_string __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(buf)
 #define ASSERT_ARGS_Parrot_io_set_buffer_end __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(filehandle)
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(filehandle)
 #define ASSERT_ARGS_Parrot_io_set_buffer_flags __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(filehandle)
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(filehandle)
 #define ASSERT_ARGS_Parrot_io_set_buffer_next __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(filehandle)
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(filehandle)
 #define ASSERT_ARGS_Parrot_io_set_buffer_size __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(filehandle)
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(filehandle)
 #define ASSERT_ARGS_Parrot_io_set_buffer_start __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(filehandle)
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(filehandle)
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 /* HEADERIZER END: src/io/filehandle.c */
 

Modified: branches/io_cleanups/include/parrot/io_portable.h
==============================================================================
--- branches/io_cleanups/include/parrot/io_portable.h	Tue Jun 23 11:14:56 2009	(r39740)
+++ branches/io_cleanups/include/parrot/io_portable.h	Tue Jun 23 14:19:35 2009	(r39741)
@@ -36,11 +36,21 @@
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*filehandle);
 
+INTVAL Parrot_io_flush_handle_portable(PARROT_INTERP, ARGMOD(PMC * handle))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        FUNC_MODIFIES(* handle);
+
 INTVAL Parrot_io_flush_portable(SHIM_INTERP, SHIM(PMC *filehandle));
 INTVAL Parrot_io_getblksize_portable(PIOHANDLE fptr);
 INTVAL Parrot_io_init_portable(PARROT_INTERP)
         __attribute__nonnull__(1);
 
+INTVAL Parrot_io_is_closed_handle_portable(PARROT_INTERP,
+    ARGIN(PMC* handle))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
 INTVAL Parrot_io_is_closed_portable(PARROT_INTERP, ARGIN(PMC *filehandle))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
@@ -90,7 +100,7 @@
         __attribute__nonnull__(2);
 
 size_t Parrot_io_write_portable(PARROT_INTERP,
-    ARGIN(PMC *filehandle),
+    ARGIN(PMC *handle),
     ARGMOD(STRING *s))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
@@ -103,10 +113,18 @@
 #define ASSERT_ARGS_Parrot_io_fdopen_portable __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(filehandle)
+#define ASSERT_ARGS_Parrot_io_flush_handle_portable \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(handle)
 #define ASSERT_ARGS_Parrot_io_flush_portable __attribute__unused__ int _ASSERT_ARGS_CHECK = 0
 #define ASSERT_ARGS_Parrot_io_getblksize_portable __attribute__unused__ int _ASSERT_ARGS_CHECK = 0
 #define ASSERT_ARGS_Parrot_io_init_portable __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_io_is_closed_handle_portable \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(handle)
 #define ASSERT_ARGS_Parrot_io_is_closed_portable __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(filehandle)
@@ -131,7 +149,7 @@
     || PARROT_ASSERT_ARG(filehandle)
 #define ASSERT_ARGS_Parrot_io_write_portable __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(filehandle) \
+    || PARROT_ASSERT_ARG(handle) \
     || PARROT_ASSERT_ARG(s)
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 /* HEADERIZER END: src/io/portable.c */
@@ -145,6 +163,7 @@
     Parrot_io_open_pipe_portable((interp), (pmc), (file), (flags))
 #define PIO_CLOSE(interp, pmc) Parrot_io_close_portable((interp), (pmc))
 #define PIO_IS_CLOSED(interp, pmc) Parrot_io_is_closed_portable((interp), (pmc))
+#define PIO_IS_CLOSED_HANDLE(interp, pmc) Parrot_io_is_closed_handle_portable((interp), (pmc))
 #define PIO_READ(interp, pmc, buf) Parrot_io_read_portable((interp), (pmc), (buf))
 #define PIO_WRITE(interp, pmc, str) Parrot_io_write_portable((interp), (pmc), (str))
 #define PIO_SEEK(interp, pmc, offset, start) \
@@ -152,6 +171,7 @@
 #define PIO_TELL(interp, pmc) Parrot_io_tell_portable((interp), (pmc))
 #define PIO_PEEK(interp, pmc, buf) Parrot_io_peek_portable((interp), (pmc), (buf))
 #define PIO_FLUSH(interp, pmc) Parrot_io_flush_portable((interp), (pmc))
+#define PIO_FLUSH_HANDLE(interp, pmc) Parrot_io_flush_handle_portable((interp), (pmc))
 #define PIO_GETBLKSIZE(handle) Parrot_io_getblksize_portable((handle))
 
 #endif /* PARROT_IO_PORTABLE_H_GUARD */

Modified: branches/io_cleanups/include/parrot/io_unix.h
==============================================================================
--- branches/io_cleanups/include/parrot/io_unix.h	Tue Jun 23 11:14:56 2009	(r39740)
+++ branches/io_cleanups/include/parrot/io_unix.h	Tue Jun 23 14:19:35 2009	(r39741)
@@ -46,6 +46,11 @@
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*filehandle);
 
+INTVAL Parrot_io_flush_handle_unix(PARROT_INTERP, ARGMOD(PMC * handle))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        FUNC_MODIFIES(* handle);
+
 INTVAL Parrot_io_flush_unix(PARROT_INTERP, ARGMOD(PMC *filehandle))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
@@ -55,6 +60,10 @@
 INTVAL Parrot_io_init_unix(PARROT_INTERP)
         __attribute__nonnull__(1);
 
+INTVAL Parrot_io_is_closed_handle_unix(PARROT_INTERP, ARGIN(PMC* handle))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
 INTVAL Parrot_io_is_closed_unix(PARROT_INTERP, ARGIN(PMC *filehandle))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
@@ -117,7 +126,7 @@
         FUNC_MODIFIES(*filehandle);
 
 size_t Parrot_io_write_unix(PARROT_INTERP,
-    ARGIN(PMC *filehandle),
+    ARGIN(PMC *handle),
     ARGMOD(STRING *s))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
@@ -135,12 +144,19 @@
 #define ASSERT_ARGS_Parrot_io_fdopen_unix __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(filehandle)
+#define ASSERT_ARGS_Parrot_io_flush_handle_unix __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(handle)
 #define ASSERT_ARGS_Parrot_io_flush_unix __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(filehandle)
 #define ASSERT_ARGS_Parrot_io_getblksize_unix __attribute__unused__ int _ASSERT_ARGS_CHECK = 0
 #define ASSERT_ARGS_Parrot_io_init_unix __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_io_is_closed_handle_unix \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(handle)
 #define ASSERT_ARGS_Parrot_io_is_closed_unix __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(filehandle)
@@ -168,7 +184,7 @@
     || PARROT_ASSERT_ARG(filehandle)
 #define ASSERT_ARGS_Parrot_io_write_unix __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(filehandle) \
+    || PARROT_ASSERT_ARG(handle) \
     || PARROT_ASSERT_ARG(s)
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 /* HEADERIZER END: src/io/unix.c */
@@ -201,15 +217,17 @@
         __attribute__nonnull__(3)
         FUNC_MODIFIES(*socket);
 
-INTVAL Parrot_io_listen_unix(SHIM_INTERP, ARGMOD(PMC *socket), INTVAL sec)
+INTVAL Parrot_io_listen_unix(PARROT_INTERP, ARGMOD(PMC *socket), INTVAL sec)
+        __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*socket);
 
-INTVAL Parrot_io_poll_unix(SHIM_INTERP,
+INTVAL Parrot_io_poll_unix(PARROT_INTERP,
     ARGMOD(PMC *socket),
     int which,
     int sec,
     int usec)
+        __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*socket);
 
@@ -222,9 +240,10 @@
         FUNC_MODIFIES(*socket)
         FUNC_MODIFIES(*s);
 
-INTVAL Parrot_io_send_unix(SHIM_INTERP,
+INTVAL Parrot_io_send_unix(PARROT_INTERP,
     ARGMOD(PMC *socket),
     ARGMOD(STRING *s))
+        __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         __attribute__nonnull__(3)
         FUNC_MODIFIES(*socket)
@@ -258,15 +277,18 @@
     || PARROT_ASSERT_ARG(socket) \
     || PARROT_ASSERT_ARG(r)
 #define ASSERT_ARGS_Parrot_io_listen_unix __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(socket)
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(socket)
 #define ASSERT_ARGS_Parrot_io_poll_unix __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(socket)
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(socket)
 #define ASSERT_ARGS_Parrot_io_recv_unix __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(socket) \
     || PARROT_ASSERT_ARG(s)
 #define ASSERT_ARGS_Parrot_io_send_unix __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(socket) \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(socket) \
     || PARROT_ASSERT_ARG(s)
 #define ASSERT_ARGS_Parrot_io_sockaddr_in __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
@@ -289,6 +311,7 @@
 #define PIO_CLOSE(interp, pmc) Parrot_io_close_unix((interp), (pmc))
 #define PIO_CLOSE_PIOHANDLE(interp, handle) Parrot_io_close_piohandle_unix((interp), (handle))
 #define PIO_IS_CLOSED(interp, pmc) Parrot_io_is_closed_unix((interp), (pmc))
+#define PIO_IS_CLOSED_HANDLE(interp, pmc) Parrot_io_is_closed_handle_unix((interp), (pmc))
 #define PIO_READ(interp, pmc, buf) Parrot_io_read_unix((interp), (pmc), (buf))
 #define PIO_WRITE(interp, pmc, str) Parrot_io_write_unix((interp), (pmc), (str))
 #define PIO_SEEK(interp, pmc, offset, start) \
@@ -296,6 +319,7 @@
 #define PIO_TELL(interp, pmc) Parrot_io_tell_unix((interp), (pmc))
 #define PIO_PEEK(interp, pmc, buf) Parrot_io_peek_unix((interp), (pmc), (buf))
 #define PIO_FLUSH(interp, pmc) Parrot_io_flush_unix((interp), (pmc))
+#define PIO_FLUSH_HANDLE(interp, pmc) Parrot_io_flush_handle_unix((interp), (pmc))
 #define PIO_GETBLKSIZE(handle) Parrot_io_getblksize_unix((handle))
 
 #define PIO_POLL(interp, pmc, which, sec, usec) \

Modified: branches/io_cleanups/include/parrot/io_win32.h
==============================================================================
--- branches/io_cleanups/include/parrot/io_win32.h	Tue Jun 23 11:14:56 2009	(r39740)
+++ branches/io_cleanups/include/parrot/io_win32.h	Tue Jun 23 14:19:35 2009	(r39741)
@@ -38,6 +38,11 @@
         __attribute__nonnull__(1)
         FUNC_MODIFIES(*filehandle);
 
+INTVAL Parrot_io_flush_handle_win32(PARROT_INTERP, ARGMOD(PMC * handle))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        FUNC_MODIFIES(* handle);
+
 INTVAL Parrot_io_flush_win32(PARROT_INTERP, ARGMOD(PMC *filehandle))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
@@ -47,6 +52,10 @@
 INTVAL Parrot_io_init_win32(PARROT_INTERP)
         __attribute__nonnull__(1);
 
+INTVAL Parrot_io_is_closed_handle_win32(PARROT_INTERP, ARGIN(PMC* handle))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
 INTVAL Parrot_io_is_closed_win32(PARROT_INTERP, ARGIN(PMC *filehandle))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
@@ -109,7 +118,7 @@
         __attribute__nonnull__(2);
 
 size_t Parrot_io_write_win32(PARROT_INTERP,
-    ARGIN(PMC *filehandle),
+    ARGIN(PMC *handle),
     ARGIN(STRING *s))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
@@ -123,12 +132,19 @@
     || PARROT_ASSERT_ARG(filehandle)
 #define ASSERT_ARGS_Parrot_io_fdopen_win32 __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_io_flush_handle_win32 __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(handle)
 #define ASSERT_ARGS_Parrot_io_flush_win32 __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(filehandle)
 #define ASSERT_ARGS_Parrot_io_getblksize_win32 __attribute__unused__ int _ASSERT_ARGS_CHECK = 0
 #define ASSERT_ARGS_Parrot_io_init_win32 __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_io_is_closed_handle_win32 \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(handle)
 #define ASSERT_ARGS_Parrot_io_is_closed_win32 __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(filehandle)
@@ -157,7 +173,7 @@
     || PARROT_ASSERT_ARG(filehandle)
 #define ASSERT_ARGS_Parrot_io_write_win32 __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(filehandle) \
+    || PARROT_ASSERT_ARG(handle) \
     || PARROT_ASSERT_ARG(s)
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 /* HEADERIZER END: src/io/win32.c */
@@ -274,6 +290,7 @@
 #define PIO_CLOSE(interp, pmc) Parrot_io_close_win32((interp), (pmc))
 #define PIO_CLOSE_PIOHANDLE(interp, handle) Parrot_io_close_piohandle_win32((interp), (handle))
 #define PIO_IS_CLOSED(interp, pmc) Parrot_io_is_closed_win32((interp), (pmc))
+#define PIO_IS_CLOSED_HANDLE(interp, pmc) Parrot_io_is_closed_handle_win32((interp), (pmc))
 #define PIO_READ(interp, pmc, buf) Parrot_io_read_win32((interp), (pmc), (buf))
 #define PIO_WRITE(interp, pmc, str) Parrot_io_write_win32((interp), (pmc), (str))
 #define PIO_SEEK(interp, pmc, offset, start) \
@@ -281,6 +298,7 @@
 #define PIO_TELL(interp, pmc) Parrot_io_tell_win32((interp), (pmc))
 #define PIO_PEEK(interp, pmc, buf) Parrot_io_peek_win32((interp), (pmc), (buf))
 #define PIO_FLUSH(interp, pmc) Parrot_io_flush_win32((interp), (pmc))
+#define PIO_FLUSH_HANDLE(interp, pmc) Parrot_io_flush_handle_win32((interp), (pmc))
 #define PIO_GETBLKSIZE(handle) Parrot_io_getblksize_win32((handle))
 
 #define PIO_POLL(interp, pmc, which, sec, usec) \

Modified: branches/io_cleanups/src/io/api.c
==============================================================================
--- branches/io_cleanups/src/io/api.c	Tue Jun 23 11:14:56 2009	(r39740)
+++ branches/io_cleanups/src/io/api.c	Tue Jun 23 14:19:35 2009	(r39741)
@@ -19,10 +19,6 @@
 The C<FileHandle> PMC provides the class-based interface for filehandles that
 is used in Parrot ops.
 
-TODO: Where possible, extract some of the filehandle-related details into
-src/io/filehandle.c, and extract the stringhandle details into
-src/io/io_string.c.
-
 =cut
 
 */
@@ -33,6 +29,7 @@
 #include "../pmc/pmc_filehandle.h"
 #include "../pmc/pmc_stringhandle.h"
 #include "../pmc/pmc_socket.h"
+#include "../pmc/pmc_handle.h"
 
 #include <stdarg.h>
 
@@ -217,13 +214,11 @@
     }
     else if (pmc->vtable->base_type == enum_class_StringHandle)
         SETATTR_StringHandle_read_offset(interp, pmc, 0);
-    else if (pmc->vtable->base_type == enum_class_Socket)
-    {
-        PIOHANDLE os_handle;
-        GETATTR_Socket_os_handle(interp, pmc, os_handle);
+    else if (pmc->vtable->base_type == enum_class_Socket) {
+        const PIOHANDLE os_handle = Parrot_io_get_os_handle(interp, pmc);
         if (os_handle != PIO_INVALID_HANDLE)
             result = Parrot_io_close_piohandle(interp, os_handle);
-        SETATTR_Socket_os_handle(interp, pmc, PIO_INVALID_HANDLE);
+        Parrot_io_set_os_handle(interp, pmc, PIO_INVALID_HANDLE);
     }
     else
         Parrot_PCCINVOKE(interp, pmc, CONST_STRING(interp, "close"), "->I", &result);
@@ -309,9 +304,8 @@
 
     if (pmc->vtable->base_type == enum_class_FileHandle)
         Parrot_io_flush_filehandle(interp, pmc);
-    else if (pmc->vtable->base_type == enum_class_StringHandle) {
+    else if (pmc->vtable->base_type == enum_class_StringHandle)
         SETATTR_StringHandle_stringhandle(interp, pmc, NULL);
-    }
     else
         Parrot_PCCINVOKE(interp, pmc, CONST_STRING(interp, "flush"), "->");
 }
@@ -922,6 +916,93 @@
     return VTABLE_get_integer(interp, pmc);
 }
 
+/*
+
+=item C<PMC * Parrot_io_make_os_handle_pmc(PARROT_INTERP)>
+
+Initialize a new low-level handle type
+
+=cut
+
+*/
+
+PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+PMC *
+Parrot_io_make_os_handle_pmc(PARROT_INTERP)
+{
+    PMC * handle = pmc_new_noinit(interp, enum_class_Handle);
+    Parrot_Handle_attributes *ds = mem_allocate_typed(Parrot_Handle_attributes);
+    ds->os_handle = (PIOHANDLE) PIO_INVALID_HANDLE;
+    ds->buffer_size  = 0;
+    ds->buffer_flags = 0;
+    ds->buffer_start = NULL;
+    ds->buffer_next  = NULL;
+    ds->buffer_end   = NULL;
+    ds->file_pos     = piooffsetzero;
+    ds->last_pos     = piooffsetzero;
+    PMC_data(handle) = ds;
+    PObj_active_destroy_SET(handle);
+    return handle;
+}
+
+/*
+
+=item C<PMC * Parrot_io_get_os_handle_pmc(PARROT_INTERP, PMC * pmc)>
+
+Get the Handle PMC that encapsulates the low-level OS handle for the given
+IO PMC
+
+=item C<PIOHANDLE Parrot_io_get_os_handle(PARROT_INTERP, PMC * pmc)>
+
+Get the low-level OS handle from the given IO PMC
+
+=item C<void Parrot_io_set_os_handle(PARROT_INTERP, PMC * pmc, PIOHANDLE
+os_handle)>
+
+Set he low-level OS handle to the given IO PMC
+
+=cut
+
+*/
+
+PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+PMC *
+Parrot_io_get_os_handle_pmc(PARROT_INTERP, ARGIN(PMC * pmc))
+{
+    PMC * handle = PMCNULL;
+    switch (pmc->vtable->base_type) {
+        case enum_class_FileHandle:
+            GETATTR_FileHandle_os_handle(interp, pmc, handle);
+            break;
+        case enum_class_Socket:
+            GETATTR_Socket_os_handle(interp, pmc, handle);
+            break;
+    }
+    if (PMC_IS_NULL(handle))
+        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
+                "Could not obtain Handle from IO pmc");
+    return handle;
+}
+
+PARROT_EXPORT
+PIOHANDLE
+Parrot_io_get_os_handle(PARROT_INTERP, ARGIN(PMC * pmc))
+{
+    const PMC * const handle = Parrot_io_get_os_handle_pmc(interp, pmc);
+    /* TODO: If we don't have a valid handle at this point, throw a
+             meaningful exception */
+    return PARROT_HANDLE(handle)->os_handle;
+}
+
+PARROT_EXPORT
+void
+Parrot_io_set_os_handle(PARROT_INTERP, ARGIN(PMC * pmc), PIOHANDLE os_handle)
+{
+    PMC * const handle = Parrot_io_get_os_handle_pmc(interp, pmc);
+    PARROT_HANDLE(handle)->os_handle = os_handle;
+}
 
 /*
 

Modified: branches/io_cleanups/src/io/buffer.c
==============================================================================
--- branches/io_cleanups/src/io/buffer.c	Tue Jun 23 11:14:56 2009	(r39740)
+++ branches/io_cleanups/src/io/buffer.c	Tue Jun 23 14:19:35 2009	(r39741)
@@ -20,6 +20,7 @@
 
 #include "parrot/parrot.h"
 #include "io_private.h"
+#include "../pmc/pmc_handle.h"
 
 /* HEADERIZER HFILE: include/parrot/io.h */
 /* HEADERIZER BEGIN: static */
@@ -71,6 +72,7 @@
 Parrot_io_setbuf(PARROT_INTERP, ARGMOD(PMC *filehandle), size_t bufsize)
 {
     ASSERT_ARGS(Parrot_io_setbuf)
+    PMC * handle = Parrot_io_get_os_handle_pmc(interp, filehandle);
     INTVAL filehandle_flags = Parrot_io_get_flags(interp, filehandle);
     INTVAL         buffer_flags = Parrot_io_get_buffer_flags(interp, filehandle);
     unsigned char *buffer_start = Parrot_io_get_buffer_start(interp, filehandle);
@@ -79,7 +81,7 @@
 
     /* If there is already a buffer, make sure we flush before modifying it. */
     if (buffer_start)
-        Parrot_io_flush_buffer(interp, filehandle);
+        Parrot_io_flush_buffer(interp, handle);
 
     /* Choose an appropriate buffer size for caller */
     switch (bufsize) {
@@ -161,30 +163,33 @@
 
 /*
 
-=item C<INTVAL Parrot_io_flush_buffer(PARROT_INTERP, PMC *filehandle)>
+=item C<INTVAL Parrot_io_flush_buffer(PARROT_INTERP, PMC *handle)>
 
-Flush the I/O buffer for a given filehandle object.
+Flush the I/O buffer for a given Handle PMC
 
 =cut
 
 */
 
 INTVAL
-Parrot_io_flush_buffer(PARROT_INTERP, ARGMOD(PMC *filehandle))
+Parrot_io_flush_buffer(PARROT_INTERP, ARGMOD(PMC *handle))
 {
     ASSERT_ARGS(Parrot_io_flush_buffer)
     long wrote;
     size_t to_write;
     STRING fake;
-    unsigned char *buffer_start = Parrot_io_get_buffer_start(interp, filehandle);
-    unsigned char *buffer_next  = Parrot_io_get_buffer_next(interp, filehandle);
-    INTVAL         buffer_flags = Parrot_io_get_buffer_flags(interp, filehandle);
+    /* TODO: Encapsulate all this better */
+    Parrot_Handle_attributes *data_struct = PARROT_HANDLE(handle);
+    unsigned char *buffer_start = data_struct->buffer_start;
+    unsigned char *buffer_next  = data_struct->buffer_next;
+    INTVAL         buffer_flags = data_struct->buffer_flags;
+    INTVAL         flags        = data_struct->flags;
 
     /*
      * Either buffering is null, disabled, or empty.
      */
     if (!buffer_start
-        || (Parrot_io_get_flags(interp, filehandle) & (PIO_F_BLKBUF | PIO_F_LINEBUF)) == 0
+        || (flags & (PIO_F_BLKBUF | PIO_F_LINEBUF)) == 0
         || (buffer_flags & (PIO_BF_WRITEBUF | PIO_BF_READBUF)) == 0)
         return 0;
     /*
@@ -196,11 +201,11 @@
         /* Flush to next layer */
         fake.strstart = (char *)buffer_start;
         fake.bufused = to_write;
-        wrote = PIO_WRITE(interp, filehandle, &fake);
+        wrote = PIO_WRITE(interp, handle, &fake);
         if (wrote == (long)to_write) {
-            Parrot_io_set_buffer_next(interp, filehandle, buffer_start);
+            data_struct->buffer_start = buffer_start;
             /* Release buffer */
-            Parrot_io_set_buffer_flags(interp, filehandle, (buffer_flags & ~PIO_BF_WRITEBUF));
+            data_struct->buffer_flags = (buffer_flags & ~PIO_BF_WRITEBUF);
             return 0;
         }
         else {
@@ -212,9 +217,9 @@
      * Read flush
      */
     else if (buffer_flags & PIO_BF_READBUF) {
-        Parrot_io_set_buffer_next(interp, filehandle, buffer_start);
+        data_struct->buffer_next = buffer_start;
         /* Release buffer */
-        Parrot_io_set_buffer_flags(interp, filehandle, (buffer_flags & ~PIO_BF_READBUF));
+        data_struct->buffer_flags = (buffer_flags & ~PIO_BF_READBUF);
     }
     return -1;
 }
@@ -282,6 +287,7 @@
     STRING        *s;
     size_t         len;
     size_t         current      = 0;
+    PMC * handle = Parrot_io_get_os_handle_pmc(interp, filehandle);
     INTVAL         buffer_flags = Parrot_io_get_buffer_flags(interp, filehandle);
 
     /* write buffer flush */
@@ -412,11 +418,12 @@
     unsigned char *buffer_next;
     STRING * const s            = Parrot_io_make_string(interp, buf, 1);
     UINTVAL        len          = 1;
+    PMC * handle = Parrot_io_get_os_handle_pmc(interp, filehandle);
     INTVAL         buffer_flags = Parrot_io_get_buffer_flags(interp, filehandle);
 
     /* write buffer flush */
     if (buffer_flags & PIO_BF_WRITEBUF) {
-        Parrot_io_flush_buffer(interp, filehandle);
+        Parrot_io_flush_buffer(interp, handle);
         buffer_flags = Parrot_io_get_buffer_flags(interp, filehandle);
     }
 
@@ -572,6 +579,7 @@
 {
     ASSERT_ARGS(Parrot_io_write_buffer)
     void          * const buffer       = s->strstart;
+    PMC * handle = Parrot_io_get_os_handle_pmc(interp, filehandle);
     unsigned char * const buffer_start = Parrot_io_get_buffer_start(interp, filehandle);
     unsigned char *       buffer_next  = Parrot_io_get_buffer_next(interp, filehandle);
     const size_t          buffer_size  = Parrot_io_get_buffer_size(interp, filehandle);
@@ -623,8 +631,8 @@
         long wrote;
 
         /* Write through, skip buffer. */
-        Parrot_io_flush_buffer(interp, filehandle);
-        wrote = PIO_WRITE(interp, filehandle, s);
+        Parrot_io_flush_buffer(interp, handle);
+        wrote = PIO_WRITE(interp, handle, s);
 
         if (wrote == (long)len) {
             Parrot_io_set_file_position(interp, filehandle, (wrote +
@@ -658,7 +666,7 @@
         Parrot_io_set_buffer_next(interp, filehandle, buffer_next);
         Parrot_io_set_file_position(interp, filehandle, (avail +
                     Parrot_io_get_file_position(interp, filehandle)));
-        Parrot_io_flush_buffer(interp, filehandle);
+        Parrot_io_flush_buffer(interp, handle);
 
         buffer_flags |= PIO_BF_WRITEBUF;
         Parrot_io_set_buffer_flags(interp, filehandle, buffer_flags);
@@ -691,6 +699,7 @@
         PIOOFF_T offset, INTVAL whence)
 {
     ASSERT_ARGS(Parrot_io_seek_buffer)
+    PMC * handle = Parrot_io_get_os_handle_pmc(interp, filehandle);
     PIOOFF_T newpos;
     PIOOFF_T file_pos = Parrot_io_get_file_position(interp, filehandle);
     unsigned char *buffer_start = Parrot_io_get_buffer_start(interp, filehandle);
@@ -718,7 +727,7 @@
 
     if ((newpos < file_pos - (buffer_next - buffer_start))
         || (newpos >= file_pos + (buffer_end - buffer_next))) {
-        Parrot_io_flush_buffer(interp, filehandle);
+        Parrot_io_flush_buffer(interp, handle);
         newpos = PIO_SEEK(interp, filehandle, newpos, SEEK_SET);
     }
     else {

Modified: branches/io_cleanups/src/io/filehandle.c
==============================================================================
--- branches/io_cleanups/src/io/filehandle.c	Tue Jun 23 11:14:56 2009	(r39740)
+++ branches/io_cleanups/src/io/filehandle.c	Tue Jun 23 14:19:35 2009	(r39741)
@@ -18,6 +18,7 @@
 #include "parrot/parrot.h"
 #include "io_private.h"
 #include "../pmc/pmc_filehandle.h"
+#include "../pmc/pmc_handle.h"
 
 /* HEADERIZER HFILE: include/parrot/io.h */
 
@@ -131,59 +132,6 @@
     }
 }
 
-
-/*
-
-=item C<void Parrot_io_set_os_handle(PARROT_INTERP, PMC *filehandle, PIOHANDLE
-file_descriptor)>
-
-Sets the C<os_handle> attribute of the FileHandle object, which stores the
-low-level filehandle for the OS.
-
-Currently, this pokes directly into the C struct of the FileHandle PMC. This
-needs to change to a general interface that can be used by all subclasses and
-polymorphic equivalents of FileHandle. For now, hiding it behind a function, so
-it can be cleanly changed later.
-
-Possibly, this function should reset some characteristics of the object (like
-buffer and file positions) to their default values.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-void
-Parrot_io_set_os_handle(SHIM_INTERP, ARGIN(PMC *filehandle), PIOHANDLE file_descriptor)
-{
-    ASSERT_ARGS(Parrot_io_set_os_handle)
-    PARROT_FILEHANDLE(filehandle)->os_handle = file_descriptor;
-}
-
-/*
-
-=item C<PIOHANDLE Parrot_io_get_os_handle(PARROT_INTERP, PMC *filehandle)>
-
-Retrieve the C<os_handle> attribute of the FileHandle object, which stores the
-low-level filehandle for the OS.
-
-Currently, this pokes directly into the C struct of the FileHandle PMC. This
-needs to change to a general interface that can be used by all subclasses and
-polymorphic equivalents of FileHandle. For now, hiding it behind a function, so
-it can be cleanly changed later.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-PIOHANDLE
-Parrot_io_get_os_handle(SHIM_INTERP, ARGIN(PMC *filehandle))
-{
-    ASSERT_ARGS(Parrot_io_get_os_handle)
-    return PARROT_FILEHANDLE(filehandle)->os_handle;
-}
-
 /*
 
 =item C<void Parrot_io_set_flags(PARROT_INTERP, PMC *filehandle, INTVAL flags)>
@@ -205,7 +153,9 @@
 Parrot_io_set_flags(PARROT_INTERP, ARGIN(PMC *filehandle), INTVAL flags)
 {
     ASSERT_ARGS(Parrot_io_set_flags)
+    PMC * const handle = Parrot_io_get_os_handle_pmc(interp, filehandle);
     SETATTR_FileHandle_flags(interp, filehandle, flags);
+    SETATTR_Handle_flags(interp, handle, flags);
 }
 
 /*
@@ -252,11 +202,12 @@
 */
 
 void
-Parrot_io_set_buffer_start(SHIM_INTERP, ARGIN(PMC *filehandle),
+Parrot_io_set_buffer_start(PARROT_INTERP, ARGIN(PMC *filehandle),
         ARGIN_NULLOK(unsigned char *new_start))
 {
     ASSERT_ARGS(Parrot_io_set_buffer_start)
-    PARROT_FILEHANDLE(filehandle)->buffer_start = new_start;
+    PMC * const handle = Parrot_io_get_os_handle_pmc(interp, filehandle);
+    PARROT_HANDLE(handle)->buffer_start = new_start;
 }
 
 /*
@@ -279,10 +230,11 @@
 PARROT_EXPORT
 PARROT_CAN_RETURN_NULL
 unsigned char *
-Parrot_io_get_buffer_start(SHIM_INTERP, ARGIN(PMC *filehandle))
+Parrot_io_get_buffer_start(PARROT_INTERP, ARGIN(PMC *filehandle))
 {
     ASSERT_ARGS(Parrot_io_get_buffer_start)
-    return PARROT_FILEHANDLE(filehandle)->buffer_start;
+    PMC * handle = Parrot_io_get_os_handle_pmc(interp, filehandle);
+    return PARROT_HANDLE(handle)->buffer_start;
 }
 
 /*
@@ -305,10 +257,11 @@
 PARROT_EXPORT
 PARROT_CAN_RETURN_NULL
 unsigned char *
-Parrot_io_get_buffer_next(SHIM_INTERP, ARGIN(PMC *filehandle))
+Parrot_io_get_buffer_next(PARROT_INTERP, ARGIN(PMC *filehandle))
 {
     ASSERT_ARGS(Parrot_io_get_buffer_next)
-    return PARROT_FILEHANDLE(filehandle)->buffer_next;
+    PMC * const handle = Parrot_io_get_os_handle_pmc(interp, filehandle);
+    return PARROT_HANDLE(handle)->buffer_next;
 }
 
 /*
@@ -329,11 +282,12 @@
 */
 
 void
-Parrot_io_set_buffer_next(SHIM_INTERP, ARGIN(PMC *filehandle),
+Parrot_io_set_buffer_next(PARROT_INTERP, ARGIN(PMC *filehandle),
         ARGIN_NULLOK(unsigned char *new_next))
 {
     ASSERT_ARGS(Parrot_io_set_buffer_next)
-    PARROT_FILEHANDLE(filehandle)->buffer_next = new_next;
+    PMC * const handle = Parrot_io_get_os_handle_pmc(interp, filehandle);
+    PARROT_HANDLE(handle)->buffer_next = new_next;
 }
 
 /*
@@ -356,10 +310,11 @@
 PARROT_EXPORT
 PARROT_CAN_RETURN_NULL
 unsigned char *
-Parrot_io_get_buffer_end(SHIM_INTERP, ARGIN_NULLOK(PMC *filehandle))
+Parrot_io_get_buffer_end(PARROT_INTERP, ARGIN_NULLOK(PMC *filehandle))
 {
     ASSERT_ARGS(Parrot_io_get_buffer_end)
-    return PARROT_FILEHANDLE(filehandle)->buffer_end;
+    PMC * const handle = Parrot_io_get_os_handle_pmc(interp, filehandle);
+    return PARROT_HANDLE(handle)->buffer_end;
 }
 
 /*
@@ -380,11 +335,12 @@
 */
 
 void
-Parrot_io_set_buffer_end(SHIM_INTERP, ARGIN(PMC *filehandle),
+Parrot_io_set_buffer_end(PARROT_INTERP, ARGIN(PMC *filehandle),
         ARGIN_NULLOK(unsigned char *new_end))
 {
     ASSERT_ARGS(Parrot_io_set_buffer_end)
-    PARROT_FILEHANDLE(filehandle)->buffer_end = new_end;
+    PMC * const handle = Parrot_io_get_os_handle_pmc(interp, filehandle);
+    PARROT_HANDLE(handle)->buffer_end = new_end;
 }
 
 /*
@@ -405,10 +361,11 @@
 
 PARROT_CAN_RETURN_NULL
 INTVAL
-Parrot_io_get_buffer_flags(SHIM_INTERP, ARGIN(PMC *filehandle))
+Parrot_io_get_buffer_flags(PARROT_INTERP, ARGIN(PMC *filehandle))
 {
     ASSERT_ARGS(Parrot_io_get_buffer_flags)
-    return PARROT_FILEHANDLE(filehandle)->buffer_flags;
+    PMC * const handle = Parrot_io_get_os_handle_pmc(interp, filehandle);
+    return PARROT_HANDLE(handle)->buffer_flags;
 }
 
 /*
@@ -429,10 +386,11 @@
 */
 
 void
-Parrot_io_set_buffer_flags(SHIM_INTERP, ARGIN(PMC *filehandle), INTVAL new_flags)
+Parrot_io_set_buffer_flags(PARROT_INTERP, ARGIN(PMC *filehandle), INTVAL new_flags)
 {
     ASSERT_ARGS(Parrot_io_set_buffer_flags)
-    PARROT_FILEHANDLE(filehandle)->buffer_flags = new_flags;
+    PMC * const handle = Parrot_io_get_os_handle_pmc(interp, filehandle);
+    PARROT_HANDLE(handle)->buffer_flags = new_flags;
 }
 
 /*
@@ -453,10 +411,11 @@
 
 PARROT_CAN_RETURN_NULL
 size_t
-Parrot_io_get_buffer_size(SHIM_INTERP, ARGIN(PMC *filehandle))
+Parrot_io_get_buffer_size(PARROT_INTERP, ARGIN(PMC *filehandle))
 {
     ASSERT_ARGS(Parrot_io_get_buffer_size)
-    return PARROT_FILEHANDLE(filehandle)->buffer_size;
+    PMC * const handle = Parrot_io_get_os_handle_pmc(interp, filehandle);
+    return PARROT_HANDLE(handle)->buffer_size;
 }
 
 /*
@@ -477,10 +436,11 @@
 */
 
 void
-Parrot_io_set_buffer_size(SHIM_INTERP, ARGIN(PMC *filehandle), size_t new_size)
+Parrot_io_set_buffer_size(PARROT_INTERP, ARGIN(PMC *filehandle), size_t new_size)
 {
     ASSERT_ARGS(Parrot_io_set_buffer_size)
-    PARROT_FILEHANDLE(filehandle)->buffer_size = new_size;
+    PMC * const handle = Parrot_io_get_os_handle_pmc(interp, filehandle);
+    PARROT_HANDLE(handle)->buffer_size = new_size;
 }
 
 /*
@@ -500,11 +460,13 @@
 
 PARROT_CAN_RETURN_NULL
 void
-Parrot_io_clear_buffer(SHIM_INTERP, ARGIN(PMC *filehandle))
+Parrot_io_clear_buffer(PARROT_INTERP, ARGIN(PMC *filehandle))
 {
     ASSERT_ARGS(Parrot_io_clear_buffer)
-    Parrot_FileHandle_attributes *io = PARROT_FILEHANDLE(filehandle);
-    if (io->buffer_start && (io->flags & PIO_BF_MALLOC)) {
+    PMC * const handle = Parrot_io_get_os_handle_pmc(interp, filehandle);
+    const INTVAL flags = PARROT_FILEHANDLE(filehandle)->flags;
+    Parrot_Handle_attributes * io = PARROT_HANDLE(handle);
+    if (io->buffer_start && (flags & PIO_BF_MALLOC)) {
         mem_sys_free(io->buffer_start);
         io->buffer_start = NULL;
     }
@@ -528,10 +490,11 @@
 
 PARROT_EXPORT
 PIOOFF_T
-Parrot_io_get_file_position(SHIM_INTERP, ARGIN(PMC *filehandle))
+Parrot_io_get_file_position(PARROT_INTERP, ARGIN(PMC *filehandle))
 {
     ASSERT_ARGS(Parrot_io_get_file_position)
-    return PARROT_FILEHANDLE(filehandle)->file_pos;
+    PMC * const handle = Parrot_io_get_os_handle_pmc(interp, filehandle);
+    return PARROT_HANDLE(handle)->file_pos;
 }
 
 /*
@@ -553,10 +516,11 @@
 
 PARROT_EXPORT
 PIOOFF_T
-Parrot_io_get_last_file_position(SHIM_INTERP, ARGIN(PMC *filehandle))
+Parrot_io_get_last_file_position(PARROT_INTERP, ARGIN(PMC *filehandle))
 {
     ASSERT_ARGS(Parrot_io_get_last_file_position)
-    return PARROT_FILEHANDLE(filehandle)->last_pos;
+    PMC * const handle = Parrot_io_get_os_handle_pmc(interp, filehandle);
+    return PARROT_HANDLE(handle)->last_pos;
 }
 
 /*
@@ -579,10 +543,11 @@
 
 PARROT_EXPORT
 void
-Parrot_io_set_file_position(SHIM_INTERP, ARGIN(PMC *filehandle), PIOOFF_T file_pos)
+Parrot_io_set_file_position(PARROT_INTERP, ARGIN(PMC *filehandle), PIOOFF_T file_pos)
 {
     ASSERT_ARGS(Parrot_io_set_file_position)
-    Parrot_FileHandle_attributes *handle_struct = PARROT_FILEHANDLE(filehandle);
+    PMC * const handle = Parrot_io_get_os_handle_pmc(interp, filehandle);
+    Parrot_Handle_attributes *handle_struct = PARROT_HANDLE(handle);
     handle_struct->last_pos = handle_struct->file_pos;
     handle_struct->file_pos = file_pos;
 }
@@ -638,12 +603,13 @@
 {
     ASSERT_ARGS(Parrot_io_close_filehandle)
     INTVAL result;
+    PMC * handle = Parrot_io_get_os_handle_pmc(interp, pmc);
 
     if (Parrot_io_is_closed_filehandle(interp, pmc))
         return -1;
 
-    Parrot_io_flush_buffer(interp, pmc);
-    PIO_FLUSH(interp, pmc);
+    Parrot_io_flush_buffer(interp, handle);
+    PIO_FLUSH_HANDLE(interp, handle);
 
     result = PIO_CLOSE(interp, pmc);
     Parrot_io_clear_buffer(interp, pmc);
@@ -684,11 +650,12 @@
 Parrot_io_flush_filehandle(PARROT_INTERP, ARGMOD(PMC *pmc))
 {
     ASSERT_ARGS(Parrot_io_flush_filehandle)
+    PMC * handle = Parrot_io_get_os_handle_pmc(interp, pmc);
     if (Parrot_io_is_closed(interp, pmc))
         return;
 
-    Parrot_io_flush_buffer(interp, pmc);
-    PIO_FLUSH(interp, pmc);
+    Parrot_io_flush_buffer(interp, handle);
+    PIO_FLUSH_HANDLE(interp, handle);
 }
 
 /*

Modified: branches/io_cleanups/src/io/portable.c
==============================================================================
--- branches/io_cleanups/src/io/portable.c	Tue Jun 23 11:14:56 2009	(r39740)
+++ branches/io_cleanups/src/io/portable.c	Tue Jun 23 14:19:35 2009	(r39741)
@@ -25,6 +25,7 @@
 #include <stdio.h>
 #include "parrot/parrot.h"
 #include "io_private.h"
+#include "../pmc/pmc_handle.h"
 
 #ifdef PIO_OS_STDIO
 
@@ -246,6 +247,10 @@
 
 Tests whether the filehandle has been closed.
 
+=item C<INTVAL Parrot_io_is_closed_handle_portable(PARROT_INTERP, PMC* handle)>
+
+Tests whether the Handle has been closed.
+
 =cut
 
 */
@@ -260,6 +265,14 @@
     return 0;
 }
 
+INTVAL
+Parrot_io_is_closed_handle_portable(PARROT_INTERP, ARGIN(PMC* handle))
+{
+    ASSERT_ARGS(Parrot_io_is_closed_handle_portable)
+    if (PARROT_HANDLE(handle)->os_handle == (PIOHANDLE)NULL)
+        return 1;
+    return 0;
+}
 
 /*
 
@@ -344,6 +357,10 @@
 
 Flushes the underlying file descriptor of the given IO PMC.
 
+=item C<INTVAL Parrot_io_flush_handle_portable(PARROT_INTERP, PMC * handle)>
+
+Flushes the underlying file descriptor of the Handle PMC.
+
 =cut
 
 */
@@ -355,6 +372,15 @@
     return fflush((FILE *)Parrot_io_get_os_handle(interp, filehandle));
 }
 
+INTVAL
+Parrot_io_flush_handle_portable(PARROT_INTERP, ARGMOD(PMC * handle))
+{
+    ASSERT_ARGS(Parrot_io_flush_handle_unix)
+    PIOHANDLE fd = PARROT_HANDLE(handle)->os_handle;
+    return FlushFileBuffers(fd);
+}
+
+
 
 /*
 
@@ -393,8 +419,7 @@
 
 /*
 
-=item C<size_t Parrot_io_write_portable(PARROT_INTERP, PMC *filehandle, STRING
-*s)>
+=item C<size_t Parrot_io_write_portable(PARROT_INTERP, PMC *handle, STRING *s)>
 
 Writes the given STRING to the provided IO PMC.
 
@@ -403,12 +428,12 @@
 */
 
 size_t
-Parrot_io_write_portable(PARROT_INTERP, ARGIN(PMC *filehandle), ARGMOD(STRING *s))
+Parrot_io_write_portable(PARROT_INTERP, ARGIN(PMC *handle), ARGMOD(STRING *s))
 {
     ASSERT_ARGS(Parrot_io_write_portable)
     void * const buffer = s->strstart;
-    return fwrite(buffer, 1, s->bufused,
-                  (FILE *)Parrot_io_get_os_handle(interp, filehandle));
+    FILE * file = PARROT_HANDLE(handle)->os_handle;
+    return fwrite(buffer, 1, s->bufused, file);
 }
 
 

Modified: branches/io_cleanups/src/io/socket_api.c
==============================================================================
--- branches/io_cleanups/src/io/socket_api.c	Tue Jun 23 11:14:56 2009	(r39740)
+++ branches/io_cleanups/src/io/socket_api.c	Tue Jun 23 14:19:35 2009	(r39741)
@@ -113,8 +113,7 @@
 Parrot_io_socket_is_closed(PARROT_INTERP, ARGMOD(PMC *socket))
 {
     ASSERT_ARGS(Parrot_io_socket_is_closed)
-    PIOHANDLE os_handle;
-    GETATTR_Socket_os_handle(interp, socket, os_handle);
+    PIOHANDLE os_handle = Parrot_io_get_os_handle(interp, socket);
 #ifdef PIO_OS_WIN32
     return (os_handle == (PIOHANDLE)INVALID_HANDLE_VALUE);
 #endif

Modified: branches/io_cleanups/src/io/socket_unix.c
==============================================================================
--- branches/io_cleanups/src/io/socket_unix.c	Tue Jun 23 11:14:56 2009	(r39740)
+++ branches/io_cleanups/src/io/socket_unix.c	Tue Jun 23 14:19:35 2009	(r39741)
@@ -156,7 +156,7 @@
 Parrot_io_connect_unix(PARROT_INTERP, ARGMOD(PMC *socket), ARGIN(PMC *r))
 {
     ASSERT_ARGS(Parrot_io_connect_unix)
-    Parrot_Socket_attributes * io = PARROT_SOCKET(socket);
+    const PIOHANDLE os_handle = Parrot_io_get_os_handle(interp, socket);
 
     if (!r)
         return -1;
@@ -164,7 +164,7 @@
     PARROT_SOCKET(socket)->remote = r;
 
 AGAIN:
-    if ((connect(io->os_handle, (struct sockaddr *)SOCKADDR_REMOTE(socket),
+    if ((connect(os_handle, (struct sockaddr *)SOCKADDR_REMOTE(socket),
             sizeof (struct sockaddr_in))) != 0) {
         switch (errno) {
             case EINTR:
@@ -195,7 +195,7 @@
 Parrot_io_bind_unix(PARROT_INTERP, ARGMOD(PMC *socket), ARGMOD(PMC *sockaddr))
 {
     ASSERT_ARGS(Parrot_io_bind_unix)
-    Parrot_Socket_attributes * io = PARROT_SOCKET(socket);
+    const PIOHANDLE os_handle = Parrot_io_get_os_handle(interp, socket);
     struct sockaddr_in * saddr;
 
     if (!sockaddr)
@@ -205,7 +205,7 @@
 
     saddr = SOCKADDR_LOCAL(socket);
 
-    if ((bind(io->os_handle, (struct sockaddr *) saddr,
+    if ((bind(os_handle, (struct sockaddr *) saddr,
             sizeof (struct sockaddr_in))) == -1) {
         return -1;
     }
@@ -225,11 +225,11 @@
 */
 
 INTVAL
-Parrot_io_listen_unix(SHIM_INTERP, ARGMOD(PMC *socket), INTVAL sec)
+Parrot_io_listen_unix(PARROT_INTERP, ARGMOD(PMC *socket), INTVAL sec)
 {
     ASSERT_ARGS(Parrot_io_listen_unix)
-    Parrot_Socket_attributes * io = PARROT_SOCKET(socket);
-    if ((listen(io->os_handle, sec)) == -1) {
+    const PIOHANDLE os_handle = Parrot_io_get_os_handle(interp, socket);
+    if ((listen(os_handle, sec)) == -1) {
         return -1;
     }
     return 0;
@@ -251,7 +251,7 @@
 Parrot_io_accept_unix(PARROT_INTERP, ARGMOD(PMC *socket))
 {
     ASSERT_ARGS(Parrot_io_accept_unix)
-    Parrot_Socket_attributes * io = PARROT_SOCKET(socket);
+    const PIOHANDLE os_handle = Parrot_io_get_os_handle(interp, socket);
     PMC * newio   = Parrot_io_new_socket_pmc(interp,
             PIO_F_SOCKET | PIO_F_READ|PIO_F_WRITE);
     Parrot_Socklen_t    addrlen = sizeof (struct sockaddr_in);
@@ -262,13 +262,13 @@
     PARROT_SOCKET(newio)->remote = pmc_new(interp, enum_class_Sockaddr);
     saddr                        = SOCKADDR_REMOTE(newio);
 
-    newsock = accept(io->os_handle, (struct sockaddr *)saddr, &addrlen);
+    newsock = accept(os_handle, (struct sockaddr *)saddr, &addrlen);
 
     if (newsock == -1) {
         return PMCNULL;
     }
 
-    PARROT_SOCKET(newio)->os_handle = newsock;
+    Parrot_io_set_os_handle(interp, newio, newsock);
 
     /* XXX FIXME: Need to do a getsockname and getpeername here to
      * fill in the sockaddr_in structs for local and peer */
@@ -290,11 +290,11 @@
 */
 
 INTVAL
-Parrot_io_send_unix(SHIM_INTERP, ARGMOD(PMC *socket), ARGMOD(STRING *s))
+Parrot_io_send_unix(PARROT_INTERP, ARGMOD(PMC *socket), ARGMOD(STRING *s))
 {
     ASSERT_ARGS(Parrot_io_send_unix)
     int error, bytes, byteswrote;
-    Parrot_Socket_attributes * io = PARROT_SOCKET(socket);
+    const PIOHANDLE os_handle = Parrot_io_get_os_handle(interp, socket);
 
     bytes = s->bufused;
     byteswrote = 0;
@@ -302,7 +302,7 @@
     /*
      * Ignore encoding issues for now.
      */
-    if ((error = send(io->os_handle, (char *)s->strstart + byteswrote,
+    if ((error = send(os_handle, (char *)s->strstart + byteswrote,
                     bytes, 0)) >= 0) {
         byteswrote += error;
         bytes -= error;
@@ -324,7 +324,7 @@
 #    endif
             case EPIPE:
                 /* XXX why close it here and not below */
-                close(io->os_handle);
+                close(os_handle);
                 return -1;
             default:
                 return -1;
@@ -349,10 +349,10 @@
     int error;
     unsigned int bytesread = 0;
     char buf[2048];
-    Parrot_Socket_attributes * io = PARROT_SOCKET(socket);
+    const PIOHANDLE os_handle = Parrot_io_get_os_handle(interp, socket);
 
 AGAIN:
-    if ((error = recv(io->os_handle, buf, 2048, 0)) >= 0) {
+    if ((error = recv(os_handle, buf, 2048, 0)) >= 0) {
         bytesread += error;
         /* The charset should probably be 'binary', but right now httpd.pir
          * only works with 'ascii'
@@ -373,11 +373,11 @@
 #    endif
             case ECONNRESET:
                 /* XXX why close it on err return result is -1 anyway */
-                close(io->os_handle);
+                close(os_handle);
                 *s = Parrot_str_new_noinit(interp, enum_stringrep_one, 0);
                 return -1;
             default:
-                close(io->os_handle);
+                close(os_handle);
                 *s = Parrot_str_new_noinit(interp, enum_stringrep_one, 0);
                 return -1;
         }
@@ -406,27 +406,27 @@
 */
 
 INTVAL
-Parrot_io_poll_unix(SHIM_INTERP, ARGMOD(PMC *socket), int which, int sec,
+Parrot_io_poll_unix(PARROT_INTERP, ARGMOD(PMC *socket), int which, int sec,
     int usec)
 {
     ASSERT_ARGS(Parrot_io_poll_unix)
     fd_set r, w, e;
     struct timeval t;
-    Parrot_Socket_attributes * io = PARROT_SOCKET(socket);
+    const PIOHANDLE os_handle = Parrot_io_get_os_handle(interp, socket);
 
     t.tv_sec = sec;
     t.tv_usec = usec;
     FD_ZERO(&r); FD_ZERO(&w); FD_ZERO(&e);
     /* These should be defined in header */
-    if (which & 1) FD_SET(io->os_handle, &r);
-    if (which & 2) FD_SET(io->os_handle, &w);
-    if (which & 4) FD_SET(io->os_handle, &e);
+    if (which & 1) FD_SET(os_handle, &r);
+    if (which & 2) FD_SET(os_handle, &w);
+    if (which & 4) FD_SET(os_handle, &e);
 AGAIN:
-    if ((select(io->os_handle+1, &r, &w, &e, &t)) >= 0) {
+    if ((select(os_handle+1, &r, &w, &e, &t)) >= 0) {
         int n;
-        n = (FD_ISSET(io->os_handle, &r) ? 1 : 0);
-        n |= (FD_ISSET(io->os_handle, &w) ? 2 : 0);
-        n |= (FD_ISSET(io->os_handle, &e) ? 4 : 0);
+        n = (FD_ISSET(os_handle, &r) ? 1 : 0);
+        n |= (FD_ISSET(os_handle, &w) ? 2 : 0);
+        n |= (FD_ISSET(os_handle, &e) ? 4 : 0);
         return n;
     }
     else {

Modified: branches/io_cleanups/src/io/unix.c
==============================================================================
--- branches/io_cleanups/src/io/unix.c	Tue Jun 23 11:14:56 2009	(r39740)
+++ branches/io_cleanups/src/io/unix.c	Tue Jun 23 14:19:35 2009	(r39741)
@@ -30,6 +30,7 @@
 
 #include "parrot/parrot.h"
 #include "io_private.h"
+#include "../pmc/pmc_handle.h"
 
 #ifdef PIO_OS_UNIX
 
@@ -382,6 +383,10 @@
 
 Test whether the filehandle has been closed.
 
+=item C<INTVAL Parrot_io_is_closed_handle_unix(PARROT_INTERP, PMC* handle)>
+
+Test whether the Handle has been closed
+
 =cut
 
 */
@@ -396,6 +401,15 @@
     return 0;
 }
 
+INTVAL
+Parrot_io_is_closed_handle_unix(PARROT_INTERP, ARGIN(PMC* handle))
+{
+    ASSERT_ARGS(Parrot_io_is_closed_handle_unix)
+    if (PARROT_HANDLE(handle)->os_handle == -1)
+        return 1;
+    return 0;
+}
+
 /*
 
 =item C<static INTVAL io_is_tty_unix(PIOHANDLE fd)>
@@ -468,6 +482,10 @@
 
 XXX: Is it necessary to C<sync()> here?
 
+=item C<INTVAL Parrot_io_flush_handle_unix(PARROT_INTERP, PMC * handle)>
+
+Flush the Handle at the lowest level.
+
 =cut
 
 */
@@ -480,6 +498,14 @@
     return fsync(file_descriptor);
 }
 
+INTVAL
+Parrot_io_flush_handle_unix(PARROT_INTERP, ARGMOD(PMC * handle))
+{
+    ASSERT_ARGS(Parrot_io_flush_handle_unix)
+    PIOHANDLE fd = PARROT_HANDLE(handle)->os_handle;
+    return fsync(fd);
+}
+
 /*
 
 =item C<size_t Parrot_io_read_unix(PARROT_INTERP, PMC *filehandle, STRING
@@ -531,7 +557,7 @@
 
 /*
 
-=item C<size_t Parrot_io_write_unix(PARROT_INTERP, PMC *filehandle, STRING *s)>
+=item C<size_t Parrot_io_write_unix(PARROT_INTERP, PMC *handle, STRING *s)>
 
 Calls C<write()> to write C<len> bytes from the memory starting at
 C<buffer> to the file descriptor in C<*io>.
@@ -541,10 +567,10 @@
 */
 
 size_t
-Parrot_io_write_unix(PARROT_INTERP, ARGIN(PMC *filehandle), ARGMOD(STRING *s))
+Parrot_io_write_unix(PARROT_INTERP, ARGIN(PMC *handle), ARGMOD(STRING *s))
 {
     ASSERT_ARGS(Parrot_io_write_unix)
-    PIOHANDLE file_descriptor = Parrot_io_get_os_handle(interp, filehandle);
+    PIOHANDLE file_descriptor = PARROT_HANDLE(handle)->os_handle;
     const char * const buffer = s->strstart;
     const char * ptr          = buffer;
 

Modified: branches/io_cleanups/src/io/win32.c
==============================================================================
--- branches/io_cleanups/src/io/win32.c	Tue Jun 23 11:14:56 2009	(r39740)
+++ branches/io_cleanups/src/io/win32.c	Tue Jun 23 14:19:35 2009	(r39741)
@@ -28,6 +28,7 @@
 
 #include "parrot/parrot.h"
 #include "io_private.h"
+#include "../pmc/pmc_handle.h"
 
 #ifdef PIO_OS_WIN32
 
@@ -352,6 +353,10 @@
 
 Test whether the filehandle has been closed.
 
+=item C<INTVAL Parrot_io_is_closed_handle_win32(PARROT_INTERP, PMC* handle)>
+
+Test whether the Handle has been closed.
+
 =cut
 
 */
@@ -366,6 +371,15 @@
     return 0;
 }
 
+INTVAL
+Parrot_io_is_closed_handle_win32(PARROT_INTERP, ARGIN(PMC* handle))
+{
+    ASSERT_ARGS(Parrot_io_is_closed_handle_portable)
+    if (PARROT_HANDLE(handle)->os_handle = INVALID_HANDLE_VALUE)
+        return 1;
+    return 0;
+}
+
 /*
 
 =item C<static INTVAL io_is_tty_win32(PIOHANDLE fd)>
@@ -391,6 +405,10 @@
 
 Calls C<FlushFileBuffers()> to flush C<*io>'s file descriptor.
 
+=item C<INTVAL Parrot_io_flush_handle_win32(PARROT_INTERP, PMC * handle)>
+
+Flushes the low-level file descriptor from a Handle PMC.
+
 =cut
 
 */
@@ -414,6 +432,14 @@
     return FlushFileBuffers(Parrot_io_get_os_handle(interp, filehandle));
 }
 
+INTVAL
+Parrot_io_flush_handle_win32(PARROT_INTERP, ARGMOD(PMC * handle))
+{
+    ASSERT_ARGS(Parrot_io_flush_handle_unix)
+    PIOHANDLE fd = PARROT_HANDLE(handle)->os_handle;
+    return FlushFileBuffers(fd);
+}
+
 /*
 
 =item C<size_t Parrot_io_read_win32(PARROT_INTERP, PMC *filehandle, STRING
@@ -464,7 +490,7 @@
 
 /*
 
-=item C<size_t Parrot_io_write_win32(PARROT_INTERP, PMC *filehandle, STRING *s)>
+=item C<size_t Parrot_io_write_win32(PARROT_INTERP, PMC *handle, STRING *s)>
 
 Calls C<WriteFile()> to write C<len> bytes from the memory starting at
 C<buffer> to C<*io>'s file descriptor. Returns C<(size_t)-1> on
@@ -476,7 +502,7 @@
 
 size_t
 Parrot_io_write_win32(PARROT_INTERP,
-        ARGIN(PMC *filehandle),
+        ARGIN(PMC *handle),
         ARGIN(STRING *s))
 {
     ASSERT_ARGS(Parrot_io_write_win32)
@@ -484,15 +510,17 @@
     DWORD err;
     void * const buffer = s->strstart;
     DWORD len = (DWORD) s->bufused;
-    PIOHANDLE os_handle = Parrot_io_get_os_handle(interp, filehandle);
+    PIOHANDLE os_handle = PARROT_HANDLE(handle)->os_handle;
+    INTVAL flags = PARROT_HANDLE(handle)->flags;
 
     /* do it by hand, Win32 hasn't any specific flag */
-    if (Parrot_io_get_flags(interp, filehandle) & PIO_F_APPEND) {
+    if (flags & PIO_F_APPEND) {
         LARGE_INTEGER p;
         p.LowPart = 0;
         p.HighPart = 0;
         p.LowPart = SetFilePointer(os_handle, p.LowPart,
                                    &p.HighPart, FILE_END);
+        /* XXX: This doesn't look right. We set p.LowPart to 0 above */
         if (p.LowPart == 0xFFFFFFFF && (GetLastError() != NO_ERROR)) {
             /* Error - exception */
             return (size_t)-1;

Modified: branches/io_cleanups/src/pmc/filehandle.pmc
==============================================================================
--- branches/io_cleanups/src/pmc/filehandle.pmc	Tue Jun 23 11:14:56 2009	(r39740)
+++ branches/io_cleanups/src/pmc/filehandle.pmc	Tue Jun 23 14:19:35 2009	(r39741)
@@ -31,18 +31,12 @@
 #endif
 #endif
 
-pmclass FileHandle extends Handle {
+pmclass FileHandle {
+    ATTR PMC *os_handle;              /* encapsulated OS handle       */
     ATTR INTVAL flags;                /* Filehandle flags             */
     ATTR STRING *filename;            /* The opened path and filename */
     ATTR STRING *mode;                /* The mode string used in open */
     ATTR STRING *encoding;            /* The encoding for read/write  */
-    ATTR PIOOFF_T file_pos;           /* Current real file pointer    */
-    ATTR PIOOFF_T last_pos;           /* Last file position           */
-    ATTR size_t buffer_size;          /* Buffer size                  */
-    ATTR INTVAL buffer_flags;         /* Buffer flags                 */
-    ATTR unsigned char *buffer_start; /* Start of buffer              */
-    ATTR unsigned char *buffer_end;   /* End of buffer                */
-    ATTR unsigned char *buffer_next;  /* Current read/write pointer   */
 
 /*
 
@@ -63,16 +57,9 @@
         data_struct->filename      = NULL;
         data_struct->mode          = NULL;
         data_struct->encoding      = NULL;
-        data_struct->file_pos      = piooffsetzero;
-        data_struct->last_pos      = piooffsetzero;
-        data_struct->buffer_size   = 0;
-        data_struct->buffer_flags  = 0;
-        data_struct->buffer_start  = NULL;
-        data_struct->buffer_end    = NULL;
-        data_struct->buffer_next   = NULL;
 
-        /* Initialize the os_handle to the platform-specific value for closed. */
-        data_struct->os_handle     = (PIOHANDLE) PIO_INVALID_HANDLE;
+        /* Create the handle pmc */
+        data_struct->os_handle     = Parrot_io_make_os_handle_pmc(INTERP);
 
         PObj_custom_mark_SET(SELF);
         PObj_active_destroy_SET(SELF);
@@ -93,7 +80,7 @@
         PMC * const copy = Parrot_io_new_pmc(interp, old_struct->flags);
         Parrot_FileHandle_attributes * const data_struct = PARROT_FILEHANDLE(copy);
 
-        data_struct->os_handle    = Parrot_dup(old_struct->os_handle);
+        data_struct->os_handle = VTABLE_clone(INTERP, old_struct->os_handle);
 
         return copy;
     }
@@ -116,6 +103,8 @@
             Parrot_gc_mark_PObj_alive(interp, (PObj *)data_struct->filename);
         if (data_struct->encoding)
             Parrot_gc_mark_PObj_alive(interp, (PObj *)data_struct->encoding);
+        if (data_struct->os_handle)
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)data_struct->os_handle);
     }
 
 /*
@@ -131,16 +120,6 @@
         if (PARROT_FILEHANDLE(SELF)) {
             Parrot_FileHandle_attributes *data_struct = PARROT_FILEHANDLE(SELF);
 
-            if (!Parrot_io_is_closed_filehandle(INTERP, SELF)) {
-                if (data_struct->flags & PIO_F_SHARED)
-                    Parrot_io_flush_filehandle(INTERP, SELF);
-                else
-                    Parrot_io_close_filehandle(INTERP, SELF);
-            }
-
-            if (data_struct->buffer_start)
-                mem_sys_free(data_struct->buffer_start);
-
             mem_sys_free(PARROT_FILEHANDLE(SELF));
             PMC_data(SELF) = NULL;
         }
@@ -616,7 +595,7 @@
     METHOD get_fd() {
 #ifndef PIO_OS_STDIO
         INTVAL os_handle;
-        GET_ATTR_os_handle(INTERP, SELF, os_handle);
+        os_handle = Parrot_io_get_os_handle(INTERP, SELF);
         RETURN(INTVAL os_handle);
 #endif /*PIO_OS_STDIO*/
 

Modified: branches/io_cleanups/src/pmc/handle.pmc
==============================================================================
--- branches/io_cleanups/src/pmc/handle.pmc	Tue Jun 23 11:14:56 2009	(r39740)
+++ branches/io_cleanups/src/pmc/handle.pmc	Tue Jun 23 14:19:35 2009	(r39741)
@@ -25,18 +25,47 @@
 #include "parrot/parrot.h"
 #include "../src/io/io_private.h"
 
-pmclass Handle provides Handle {
-    /* TODO: Consider encapsulating PIOHANDLE as a PMC type, for subclassing */
+pmclass Handle {
     ATTR PIOHANDLE os_handle;         /* Low level OS descriptor      */
+    ATTR PIOOFF_T file_pos;           /* Current real file pointer    */
+    ATTR PIOOFF_T last_pos;           /* Last file position           */
+    ATTR INTVAL flags;                /* A copy of the flags          */
+    ATTR size_t buffer_size;          /* Buffer size                  */
+    ATTR INTVAL buffer_flags;         /* Buffer flags                 */
+    ATTR unsigned char *buffer_start; /* Start of buffer              */
+    ATTR unsigned char *buffer_end;   /* End of buffer                */
+    ATTR unsigned char *buffer_next;  /* Current read/write pointer   */
 
     VTABLE void init() {
         Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
-            "Handle cannot be instantiated directly.");
+            "Handle cannot be instantiated directly from PIR.");
     }
 
     VTABLE void init_pmc(PMC * init) {
         Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
-            "Handle cannot be instantiated directly.");
+            "Handle cannot be instantiated directly from PIR.");
+    }
+
+    VTABLE PMC* clone() {
+        PMC * const newhandle = Parrot_io_make_os_handle_pmc(INTERP);
+        PARROT_HANDLE(newhandle)->os_handle = Parrot_dup(PARROT_HANDLE(SELF)->os_handle);
+        return newhandle;
+    }
+
+    VTABLE void destroy() {
+        Parrot_Handle_attributes * data_struct = PARROT_HANDLE(SELF);
+        if (data_struct) {
+            if (!PIO_IS_CLOSED_HANDLE(INTERP, SELF)) {
+                Parrot_io_flush_buffer(INTERP, SELF);
+                PIO_FLUSH_HANDLE(INTERP, SELF);
+                if (!(data_struct->flags & PIO_F_SHARED))
+                    Parrot_io_close_piohandle(INTERP, data_struct->os_handle);
+            }
+
+            if (data_struct->buffer_start)
+                mem_sys_free(data_struct->buffer_start);
+            mem_sys_free(data_struct);
+        }
     }
 }
 

Modified: branches/io_cleanups/src/pmc/socket.pmc
==============================================================================
--- branches/io_cleanups/src/pmc/socket.pmc	Tue Jun 23 11:14:56 2009	(r39740)
+++ branches/io_cleanups/src/pmc/socket.pmc	Tue Jun 23 14:19:35 2009	(r39741)
@@ -20,9 +20,10 @@
 
 #include "../src/io/io_private.h"
 
-pmclass Socket extends Handle {
+pmclass Socket {
     ATTR PMC *local;           /* Local addr                   */
     ATTR PMC *remote;          /* Remote addr                  */
+    ATTR PMC *os_handle;       /* encapuslated handle type     */
 
 /*
 
@@ -41,6 +42,7 @@
         PMC_data(SELF)      = data_struct;
         data_struct->local  = PMCNULL;
         data_struct->remote = PMCNULL;
+        data_struct->os_handle = Parrot_io_make_os_handle_pmc(INTERP);
 
         PObj_custom_mark_destroy_SETALL(SELF);
     }
@@ -85,6 +87,9 @@
 
             if (data->remote)
                 Parrot_gc_mark_PObj_alive(interp, (PObj *)data->remote);
+
+            if (data->os_handle)
+                Parrot_gc_mark_PObj_alive(interp, (PObj *)data->os_handle);
         }
     }
 /*
@@ -97,13 +102,10 @@
 
 */
     VTABLE void destroy() {
-        if (PARROT_SOCKET(SELF)) {
-            Parrot_Socket_attributes *data_struct = PARROT_SOCKET(SELF);
-
-            if (data_struct->os_handle != PIO_INVALID_HANDLE)
-                Parrot_io_close_piohandle(interp, data_struct->os_handle);
-            data_struct->os_handle = PIO_INVALID_HANDLE;
-        }
+        const PIOHANDLE os_handle = Parrot_io_get_os_handle(INTERP, SELF);
+        if (os_handle != PIO_INVALID_HANDLE)
+            Parrot_io_close_piohandle(interp, os_handle);
+        Parrot_io_set_os_handle(INTERP, SELF, PIO_INVALID_HANDLE);
     }
 
 /*

Modified: branches/io_cleanups/src/pmc/stringhandle.pmc
==============================================================================
--- branches/io_cleanups/src/pmc/stringhandle.pmc	Tue Jun 23 11:14:56 2009	(r39740)
+++ branches/io_cleanups/src/pmc/stringhandle.pmc	Tue Jun 23 14:19:35 2009	(r39741)
@@ -46,7 +46,7 @@
         return Parrot_str_equal(interp, s, CONST_STRING(interp, "utf8"));
 }
 
-pmclass StringHandle extends Handle need_ext {
+pmclass StringHandle need_ext {
     ATTR INTVAL  flags;               /* Filehandle flags             */
     ATTR STRING *stringhandle;        /* The string data              */
     ATTR STRING *mode;                /* The mode string used in open */


More information about the parrot-commits mailing list