Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base: master
...
compare: whiteknight/pipe_pmc
Checking mergeability… Don’t worry, you can still create the pull request.
  • 8 commits
  • 18 files changed
  • 0 commit comments
  • 1 contributor
View
2  MANIFEST
@@ -1408,6 +1408,7 @@ src/pmc/packfilesegment.pmc []
src/pmc/packfileview.pmc []
src/pmc/parrotinterpreter.pmc []
src/pmc/parrotlibrary.pmc []
+src/pmc/pipe.pmc []
src/pmc/pmc.num []
src/pmc/pmclist.pmc []
src/pmc/pmcproxy.pmc []
@@ -1944,6 +1945,7 @@ t/pmc/parrotinterpreter.t [test]
t/pmc/parrotio.t [test]
t/pmc/parrotlibrary.t [test]
t/pmc/parrotobject.t [test]
+t/pmc/pipe.t [test]
t/pmc/pmc.t [test]
t/pmc/pmclist.t [test]
t/pmc/pmcproxy.t [test]
View
2  config/gen/makefiles/root.in
@@ -1069,7 +1069,7 @@ src/io/stringhandle$(O) : \
src/io/pipe$(O) : \
$(PARROT_H_HEADERS) \
src/io/io_private.h \
- $(INC_PMC_DIR)/pmc_filehandle.h \
+ $(INC_PMC_DIR)/pmc_pipe.h \
src/io/pipe.c
src/io/userhandle$(O) : \
View
1  include/parrot/io.h
@@ -46,7 +46,6 @@
#define PIO_F_APPEND 00000004 /* File is opened for append */
#define PIO_F_TRUNC 00000010
#define PIO_F_EOF 00000020 /* File is at EOF */
-#define PIO_F_PIPE 00000040 /* FileHandle is in pipe mode */
#define PIO_F_CONSOLE 00001000 /* A terminal */
#define PIO_F_READLINE 00002000 /* user interactive readline */
#define PIO_F_SOFT_SP 00040000 /* Python softspace */
View
4 runtime/parrot/library/ProfTest/PIRProfile.nqp
@@ -83,8 +83,8 @@ method build_pir_profile() {
my $cli := "\"$parrot_exe\" $hash_seed_opt --runcore profiling $tmp_pir";
- my $pipe := pir::new__p_sc('FileHandle');
- $pipe.open($cli, "rp");
+ my $pipe := pir::new__p_sc('Pipe');
+ $pipe.open($cli, "r");
$pipe.readall();
self<exit_status> := $pipe.exit_status();
View
4 runtime/parrot/library/TAP/Parser.pir
@@ -967,9 +967,9 @@ C<TAP;Parser> is designed to produce a proper parse of TAP output.
unless $P0 goto L1
cmd .= ' 2>&1'
L1:
- $P0 = new 'FileHandle'
+ $P0 = new 'Pipe'
push_eh _handler
- $P0.'open'(cmd, 'pr')
+ $P0.'open'(cmd, 'r')
pop_eh
$P0.'encoding'('utf8')
setattribute self, 'stream', $P0
View
8 runtime/parrot/library/distutils.pir
@@ -3950,8 +3950,8 @@ TEMPLATE
.end
.sub 'get_timestamp' :anon
- $P0 = new 'FileHandle'
- $P0.'open'('date --rfc-2822', 'rp')
+ $P0 = new 'Pipe'
+ $P0.'open'('date --rfc-2822', 'r')
$S0 = $P0.'readline'()
$P0.'close'()
$S0 = chopn $S0, 1
@@ -4816,8 +4816,8 @@ Return the whole config
system(cmd, verbose :named('verbose'), 1 :named('ignore_error'))
unlink(srcname, verbose :named('verbose'))
- $P0 = new 'FileHandle'
- $P0.'open'(exename, 'rp')
+ $P0 = new 'Pipe'
+ $P0.'open'(exename, 'r')
$S0 = $P0.'readall'()
$P0.'close'()
View
1  src/dynoplibs/io.ops
@@ -226,7 +226,6 @@ The mode consists of a string of characters specified in any order:
r : read
w : write
a : append (Note: you must specify "wa", not just "a")
- p : pipe
=item B<open>(out PMC, in STR)
View
145 src/io/filehandle.c
@@ -54,10 +54,20 @@ static const STR_VTABLE * io_filehandle_get_encoding(PARROT_INTERP,
__attribute__nonnull__(1)
__attribute__nonnull__(2);
+PARROT_WARN_UNUSED_RESULT
+static PIOOFF_T io_filehandle_get_file_position(PARROT_INTERP,
+ ARGIN(const PMC *filehandle))
+ __attribute__nonnull__(2);
+
static INTVAL io_filehandle_get_flags(PARROT_INTERP, ARGIN(PMC *handle))
__attribute__nonnull__(1)
__attribute__nonnull__(2);
+PARROT_WARN_UNUSED_RESULT
+static PIOHANDLE io_filehandle_get_os_handle(PARROT_INTERP,
+ ARGIN(const PMC *filehandle))
+ __attribute__nonnull__(2);
+
static PIOHANDLE io_filehandle_get_piohandle(PARROT_INTERP,
ARGIN(PMC *handle))
__attribute__nonnull__(1)
@@ -115,6 +125,12 @@ static void io_filehandle_set_eof(PARROT_INTERP,
__attribute__nonnull__(2)
FUNC_MODIFIES(*handle);
+static void io_filehandle_set_file_position(PARROT_INTERP,
+ ARGMOD(PMC *filehandle),
+ PIOOFF_T file_pos)
+ __attribute__nonnull__(2)
+ FUNC_MODIFIES(*filehandle);
+
static void io_filehandle_set_flags(PARROT_INTERP,
ARGIN(PMC *handle),
INTVAL flags)
@@ -158,9 +174,14 @@ static INTVAL io_filehandle_write_b(PARROT_INTERP,
#define ASSERT_ARGS_io_filehandle_get_encoding __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(handle))
+#define ASSERT_ARGS_io_filehandle_get_file_position \
+ __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(filehandle))
#define ASSERT_ARGS_io_filehandle_get_flags __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(handle))
+#define ASSERT_ARGS_io_filehandle_get_os_handle __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(filehandle))
#define ASSERT_ARGS_io_filehandle_get_piohandle __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(handle))
@@ -188,6 +209,9 @@ static INTVAL io_filehandle_write_b(PARROT_INTERP,
#define ASSERT_ARGS_io_filehandle_set_eof __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(handle))
+#define ASSERT_ARGS_io_filehandle_set_file_position \
+ __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(filehandle))
#define ASSERT_ARGS_io_filehandle_set_flags __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(handle))
@@ -453,13 +477,6 @@ io_filehandle_open(PARROT_INTERP, ARGMOD(PMC *handle), ARGIN(STRING *path), INTV
ASSERT_ARGS(io_filehandle_open)
PIOHANDLE os_handle;
- /* Hack! If we're opening in pipe mode, turn this FileHandle into a pipe
- and use that vtable instead. */
- if (flags & PIO_F_PIPE) {
- const IO_VTABLE * const vtable = io_filehandle_convert_to_pipe(interp, handle);
- return vtable->open(interp, handle, path, flags, mode);
- }
-
if ((flags & (PIO_F_WRITE | PIO_F_READ)) == 0)
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
"Invalid mode for file open");
@@ -637,42 +654,25 @@ io_filehandle_get_piohandle(PARROT_INTERP, ARGIN(PMC *handle))
return io_filehandle_get_os_handle(interp, handle);
}
-
-
/*
-=item C<void io_filehandle_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.
+=back
-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.
+=head2 Private Helper Functions
-Possibly, this function should reset some characteristics of the object (like
-buffer and file positions) to their default values.
+=over 4
=cut
*/
-void
-io_filehandle_set_os_handle(SHIM_INTERP, ARGMOD(PMC *filehandle), PIOHANDLE file_descriptor)
-{
- ASSERT_ARGS(io_filehandle_set_os_handle)
- PARROT_FILEHANDLE(filehandle)->os_handle = file_descriptor;
-}
-
/*
-=item C<PIOHANDLE io_filehandle_get_os_handle(PARROT_INTERP, const PMC
+=item C<static PIOOFF_T io_filehandle_get_file_position(PARROT_INTERP, const PMC
*filehandle)>
-Retrieve the C<os_handle> attribute of the FileHandle object, which stores the
-low-level filehandle for the OS.
+Get the C<file_pos> attribute of the FileHandle object, which stores
+the current file position of the filehandle.
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
@@ -684,32 +684,21 @@ it can be cleanly changed later.
*/
PARROT_WARN_UNUSED_RESULT
-PIOHANDLE
-io_filehandle_get_os_handle(SHIM_INTERP, ARGIN(const PMC *filehandle))
+static PIOOFF_T
+io_filehandle_get_file_position(SHIM_INTERP, ARGIN(const PMC *filehandle))
{
- ASSERT_ARGS(io_filehandle_get_os_handle)
- return PARROT_FILEHANDLE(filehandle)->os_handle;
+ ASSERT_ARGS(io_filehandle_get_file_position)
+ return PARROT_FILEHANDLE(filehandle)->file_pos;
}
/*
-=back
-
-=head2 Helper Functions
-
-=over 4
-
-=cut
-
-*/
-
-/*
-
-=item C<PIOOFF_T io_filehandle_get_file_position(PARROT_INTERP, const PMC
-*filehandle)>
+=item C<static void io_filehandle_set_file_position(PARROT_INTERP, PMC
+*filehandle, PIOOFF_T file_pos)>
-Get the C<file_pos> attribute of the FileHandle object, which stores
-the current file position of the filehandle.
+Get the C<file_pos> attribute of the FileHandle object, which stores the
+current file position of the filehandle. Also set the C<last_pos> attribute to
+the previous value of C<file_pos>.
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
@@ -720,65 +709,65 @@ it can be cleanly changed later.
*/
-PARROT_WARN_UNUSED_RESULT
-PIOOFF_T
-io_filehandle_get_file_position(SHIM_INTERP, ARGIN(const PMC *filehandle))
+static void
+io_filehandle_set_file_position(SHIM_INTERP, ARGMOD(PMC *filehandle), PIOOFF_T file_pos)
{
- ASSERT_ARGS(io_filehandle_get_file_position)
- return PARROT_FILEHANDLE(filehandle)->file_pos;
+ ASSERT_ARGS(io_filehandle_set_file_position)
+ Parrot_FileHandle_attributes * const handle_struct = PARROT_FILEHANDLE(filehandle);
+ handle_struct->last_pos = handle_struct->file_pos;
+ handle_struct->file_pos = file_pos;
}
/*
-=item C<void io_filehandle_set_file_position(PARROT_INTERP, PMC *filehandle,
-PIOOFF_T file_pos)>
+=item C<void io_filehandle_set_os_handle(PARROT_INTERP, PMC *filehandle,
+PIOHANDLE file_descriptor)>
-Get the C<file_pos> attribute of the FileHandle object, which stores the
-current file position of the filehandle. Also set the C<last_pos> attribute to
-the previous value of C<file_pos>.
+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
*/
void
-io_filehandle_set_file_position(SHIM_INTERP, ARGMOD(PMC *filehandle), PIOOFF_T file_pos)
+io_filehandle_set_os_handle(SHIM_INTERP, ARGMOD(PMC *filehandle), PIOHANDLE file_descriptor)
{
- ASSERT_ARGS(io_filehandle_set_file_position)
- Parrot_FileHandle_attributes * const handle_struct = PARROT_FILEHANDLE(filehandle);
- handle_struct->last_pos = handle_struct->file_pos;
- handle_struct->file_pos = file_pos;
+ ASSERT_ARGS(io_filehandle_set_os_handle)
+ PARROT_FILEHANDLE(filehandle)->os_handle = file_descriptor;
}
/*
-=item C<const IO_VTABLE * io_filehandle_convert_to_pipe(PARROT_INTERP, PMC
-*handle)>
+=item C<static PIOHANDLE io_filehandle_get_os_handle(PARROT_INTERP, const PMC
+*filehandle)>
-Convert FileHandle C<handle> from file mode to pipe mode by swapping vtables.
-Return the Pipe vtable.
+Retrieve the C<os_handle> attribute of the FileHandle object, which stores the
+low-level filehandle for the OS.
-Notice that this function may go away when FileHandle and Pipe are separate
-PMC types.
+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_CANNOT_RETURN_NULL
PARROT_WARN_UNUSED_RESULT
-const IO_VTABLE *
-io_filehandle_convert_to_pipe(PARROT_INTERP, ARGMOD(PMC *handle))
+static PIOHANDLE
+io_filehandle_get_os_handle(SHIM_INTERP, ARGIN(const PMC *filehandle))
{
- ASSERT_ARGS(io_filehandle_convert_to_pipe)
- const IO_VTABLE * const vtable = Parrot_io_get_vtable(interp, IO_VTABLE_PIPE, NULL);
- VTABLE_set_pointer_keyed_int(interp, handle, IO_PTR_IDX_VTABLE, (void *)vtable);
- return vtable;
+ ASSERT_ARGS(io_filehandle_get_os_handle)
+ return PARROT_FILEHANDLE(filehandle)->os_handle;
}
/*
View
49 src/io/io_private.h
@@ -362,30 +362,6 @@ STRING * io_verify_string_encoding(PARROT_INTERP,
/* HEADERIZER BEGIN: src/io/filehandle.c */
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
-PARROT_CANNOT_RETURN_NULL
-PARROT_WARN_UNUSED_RESULT
-const IO_VTABLE * io_filehandle_convert_to_pipe(PARROT_INTERP,
- ARGMOD(PMC *handle))
- __attribute__nonnull__(1)
- __attribute__nonnull__(2)
- FUNC_MODIFIES(*handle);
-
-PARROT_WARN_UNUSED_RESULT
-PIOOFF_T io_filehandle_get_file_position(PARROT_INTERP,
- ARGIN(const PMC *filehandle))
- __attribute__nonnull__(2);
-
-PARROT_WARN_UNUSED_RESULT
-PIOHANDLE io_filehandle_get_os_handle(PARROT_INTERP,
- ARGIN(const PMC *filehandle))
- __attribute__nonnull__(2);
-
-void io_filehandle_set_file_position(PARROT_INTERP,
- ARGMOD(PMC *filehandle),
- PIOOFF_T file_pos)
- __attribute__nonnull__(2)
- FUNC_MODIFIES(*filehandle);
-
void io_filehandle_set_os_handle(PARROT_INTERP,
ARGMOD(PMC *filehandle),
PIOHANDLE file_descriptor)
@@ -398,17 +374,6 @@ void io_filehandle_setup_vtable(PARROT_INTERP,
__attribute__nonnull__(1)
FUNC_MODIFIES(*vtable);
-#define ASSERT_ARGS_io_filehandle_convert_to_pipe __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
- PARROT_ASSERT_ARG(interp) \
- , PARROT_ASSERT_ARG(handle))
-#define ASSERT_ARGS_io_filehandle_get_file_position \
- __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
- PARROT_ASSERT_ARG(filehandle))
-#define ASSERT_ARGS_io_filehandle_get_os_handle __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
- PARROT_ASSERT_ARG(filehandle))
-#define ASSERT_ARGS_io_filehandle_set_file_position \
- __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
- PARROT_ASSERT_ARG(filehandle))
#define ASSERT_ARGS_io_filehandle_set_os_handle __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(filehandle))
#define ASSERT_ARGS_io_filehandle_setup_vtable __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
@@ -419,12 +384,26 @@ void io_filehandle_setup_vtable(PARROT_INTERP,
/* HEADERIZER BEGIN: src/io/pipe.c */
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
+PARROT_WARN_UNUSED_RESULT
+PIOHANDLE io_pipe_get_os_handle(PARROT_INTERP, ARGIN(const PMC *pipe))
+ __attribute__nonnull__(2);
+
+void io_pipe_set_os_handle(PARROT_INTERP,
+ ARGMOD(PMC *pipe),
+ PIOHANDLE pipe_descriptor)
+ __attribute__nonnull__(2)
+ FUNC_MODIFIES(*pipe);
+
void io_pipe_setup_vtable(PARROT_INTERP,
ARGMOD_NULLOK(IO_VTABLE *vtable),
INTVAL idx)
__attribute__nonnull__(1)
FUNC_MODIFIES(*vtable);
+#define ASSERT_ARGS_io_pipe_get_os_handle __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(pipe))
+#define ASSERT_ARGS_io_pipe_set_os_handle __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(pipe))
#define ASSERT_ARGS_io_pipe_setup_vtable __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp))
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
View
118 src/io/pipe.c
@@ -19,7 +19,7 @@ This file implements the IO_VTABLE for pipes and helper functions.
#include "parrot/parrot.h"
#include "io_private.h"
-#include "pmc/pmc_filehandle.h"
+#include "pmc/pmc_pipe.h"
/* HEADERIZER HFILE: src/io/io_private.h */
@@ -257,13 +257,13 @@ static INTVAL
io_pipe_read_b(PARROT_INTERP, ARGMOD(PMC *handle), ARGOUT(char *buffer), size_t byte_length)
{
ASSERT_ARGS(io_pipe_read_b)
- const PIOHANDLE os_handle = io_filehandle_get_os_handle(interp, handle);
+ const PIOHANDLE os_handle = io_pipe_get_os_handle(interp, handle);
const size_t bytes_read = Parrot_io_internal_read(interp, os_handle, buffer, byte_length);
if (bytes_read == 0) {
INTVAL flags;
- GETATTR_FileHandle_flags(interp, handle, flags);
+ GETATTR_Pipe_flags(interp, handle, flags);
flags |= PIO_F_EOF;
- SETATTR_FileHandle_flags(interp, handle, flags);
+ SETATTR_Pipe_flags(interp, handle, flags);
}
return bytes_read;
}
@@ -283,7 +283,7 @@ static INTVAL
io_pipe_write_b(PARROT_INTERP, ARGMOD(PMC *handle), ARGIN(char *buffer), size_t byte_length)
{
ASSERT_ARGS(io_pipe_write_b)
- const PIOHANDLE os_handle = io_filehandle_get_os_handle(interp, handle);
+ const PIOHANDLE os_handle = io_pipe_get_os_handle(interp, handle);
return Parrot_io_internal_write(interp, os_handle, buffer, byte_length);
}
@@ -302,7 +302,7 @@ io_pipe_flush(PARROT_INTERP, ARGMOD(PMC *handle))
{
ASSERT_ARGS(io_pipe_flush)
/* TODO: In read mode, don't do what this does. */
- PIOHANDLE os_handle = io_filehandle_get_os_handle(interp, handle);
+ PIOHANDLE os_handle = io_pipe_get_os_handle(interp, handle);
return Parrot_io_internal_flush(interp, os_handle);
}
@@ -325,7 +325,7 @@ io_pipe_is_eof(PARROT_INTERP, ARGMOD(PMC *handle))
{
ASSERT_ARGS(io_pipe_is_eof)
INTVAL flags;
- GETATTR_FileHandle_flags(interp, handle, flags);
+ GETATTR_Pipe_flags(interp, handle, flags);
if (flags & PIO_F_EOF)
return 1;
return 0;
@@ -336,9 +336,9 @@ io_pipe_set_eof(PARROT_INTERP, ARGMOD(PMC *handle), INTVAL is_set)
{
ASSERT_ARGS(io_pipe_set_eof)
if (is_set)
- PARROT_FILEHANDLE(handle)->flags |= PIO_F_EOF;
+ PARROT_PIPE(handle)->flags |= PIO_F_EOF;
else
- PARROT_FILEHANDLE(handle)->flags &= ~PIO_F_EOF;
+ PARROT_PIPE(handle)->flags &= ~PIO_F_EOF;
}
/*
@@ -399,7 +399,7 @@ io_pipe_adv_position(PARROT_INTERP, ARGMOD(PMC *handle), size_t offset)
ASSERT_ARGS(io_pipe_adv_position)
UNUSED(handle);
UNUSED(offset);
- /* Pipes don't keep track of file position internally. Ignore this. */
+ /* Pipes don't keep track of stream position internally. Ignore this. */
}
/*
@@ -419,7 +419,7 @@ io_pipe_set_position(PARROT_INTERP, ARGMOD(PMC *handle), PIOOFF_T pos)
ASSERT_ARGS(io_pipe_set_position)
UNUSED(handle);
UNUSED(pos);
- /* Pipes don't keep track of file position internally. Ignore. */
+ /* Pipes don't keep track of stream position internally. Ignore. */
}
/*
@@ -436,7 +436,7 @@ static PIOOFF_T
io_pipe_get_position(PARROT_INTERP, ARGMOD(PMC *handle))
{
ASSERT_ARGS(io_pipe_get_position)
- /* Pipes don't keep track of file position internally. Return 0 */
+ /* Pipes don't keep track of stream position internally. Return 0 */
return (PIOOFF_T)0;
}
@@ -462,14 +462,6 @@ io_pipe_open(PARROT_INTERP, ARGMOD(PMC *handle), ARGIN(STRING *path), INTVAL fla
INTVAL pid;
PIOHANDLE os_handle;
- /* Hack! If we're opening in file mode, turn this FileHandle into a file
- and use that vtable instead. */
- if ((flags & PIO_F_PIPE) == 0) {
- const IO_VTABLE * const vtable = Parrot_io_get_vtable(interp, IO_VTABLE_FILEHANDLE, NULL);
- VTABLE_set_pointer_keyed_int(interp, handle, IO_PTR_IDX_VTABLE, (void *)vtable);
- return vtable->open(interp, handle, path, flags, mode);
- }
-
if (f_read == f_write)
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
"Invalid pipe mode: %X", flags);
@@ -480,13 +472,12 @@ io_pipe_open(PARROT_INTERP, ARGMOD(PMC *handle), ARGIN(STRING *path), INTVAL fla
VTABLE_set_integer_keyed_int(interp, handle, 0, pid);
if (flags & PIO_F_BINARY)
- SETATTR_FileHandle_encoding(interp, handle, Parrot_str_new(interp, "binary", 0));
+ SETATTR_Pipe_encoding(interp, handle, Parrot_str_new(interp, "binary", 0));
- SETATTR_FileHandle_os_handle(interp, handle, os_handle);
- SETATTR_FileHandle_flags(interp, handle, flags);
- SETATTR_FileHandle_filename(interp, handle, path);
- SETATTR_FileHandle_mode(interp, handle, mode);
- SETATTR_FileHandle_file_pos(interp, handle, 0);
+ SETATTR_Pipe_os_handle(interp, handle, os_handle);
+ SETATTR_Pipe_flags(interp, handle, flags);
+ SETATTR_Pipe_procname(interp, handle, path);
+ SETATTR_Pipe_mode(interp, handle, mode);
return 1;
}
@@ -505,7 +496,7 @@ static INTVAL
io_pipe_is_open(PARROT_INTERP, ARGMOD(PMC *handle))
{
ASSERT_ARGS(io_pipe_is_open)
- const PIOHANDLE os_handle = io_filehandle_get_os_handle(interp, handle);
+ const PIOHANDLE os_handle = io_pipe_get_os_handle(interp, handle);
return os_handle != PIO_INVALID_HANDLE;
}
@@ -523,7 +514,7 @@ static INTVAL
io_pipe_close(PARROT_INTERP, ARGMOD(PMC *handle))
{
ASSERT_ARGS(io_pipe_close)
- const PIOHANDLE os_handle = io_filehandle_get_os_handle(interp, handle);
+ const PIOHANDLE os_handle = io_pipe_get_os_handle(interp, handle);
if (os_handle == PIO_INVALID_HANDLE)
return -1;
@@ -532,10 +523,10 @@ io_pipe_close(PARROT_INTERP, ARGMOD(PMC *handle))
INTVAL pid;
INTVAL status;
INTVAL result = Parrot_io_internal_close(interp, os_handle);
- io_filehandle_set_os_handle(interp, handle, PIO_INVALID_HANDLE);
- GETATTR_FileHandle_process_id(interp, handle, pid);
+ io_pipe_set_os_handle(interp, handle, PIO_INVALID_HANDLE);
+ GETATTR_Pipe_process_id(interp, handle, pid);
status = Parrot_proc_waitpid(interp, pid);
- SETATTR_FileHandle_exit_status(interp, handle, status);
+ SETATTR_Pipe_exit_status(interp, handle, status);
io_pipe_set_flags(interp, handle, 0);
return result;
}
@@ -561,7 +552,7 @@ io_pipe_get_encoding(PARROT_INTERP, ARGIN(PMC *handle))
STRING *encoding_str;
const STR_VTABLE *encoding;
- GETATTR_FileHandle_encoding(interp, handle, encoding_str);
+ GETATTR_Pipe_encoding(interp, handle, encoding_str);
if (!STRING_IS_NULL(encoding_str))
return Parrot_find_encoding_by_string(interp, encoding_str);
return NULL;
@@ -581,7 +572,7 @@ static void
io_pipe_set_flags(PARROT_INTERP, ARGIN(PMC *handle), INTVAL flags)
{
ASSERT_ARGS(io_pipe_set_flags)
- PARROT_FILEHANDLE(handle)->flags = flags;
+ PARROT_PIPE(handle)->flags = flags;
}
/*
@@ -598,7 +589,7 @@ static INTVAL
io_pipe_get_flags(PARROT_INTERP, ARGIN(PMC *handle))
{
ASSERT_ARGS(io_pipe_get_flags)
- return PARROT_FILEHANDLE(handle)->flags;
+ return PARROT_PIPE(handle)->flags;
}
/*
@@ -632,7 +623,64 @@ static PIOHANDLE
io_pipe_get_piohandle(PARROT_INTERP, ARGIN(PMC *handle))
{
ASSERT_ARGS(io_pipe_get_piohandle)
- return io_filehandle_get_os_handle(interp, handle);
+ return io_pipe_get_os_handle(interp, handle);
+}
+
+/*
+
+=back
+
+=head2 Private Helper Functions
+
+=over 4
+
+=item C<void io_pipe_set_os_handle(PARROT_INTERP, PMC *pipe, PIOHANDLE
+pipe_descriptor)>
+
+Sets the C<os_handle> attribute of the Pipe object, which stores the
+low-level pipe for the OS.
+
+Currently, this pokes directly into the C struct of the Pipe PMC. This
+needs to change to a general interface that can be used by all subclasses and
+polymorphic equivalents of Pipe. 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 position) to their default values.
+
+=cut
+
+*/
+
+void
+io_pipe_set_os_handle(SHIM_INTERP, ARGMOD(PMC *pipe), PIOHANDLE pipe_descriptor)
+{
+ ASSERT_ARGS(io_pipe_set_os_handle)
+ PARROT_PIPE(pipe)->os_handle = pipe_descriptor;
+}
+
+/*
+
+=item C<PIOHANDLE io_pipe_get_os_handle(PARROT_INTERP, const PMC *pipe)>
+
+Retrieve the C<os_handle> attribute of the pipe object, which stores the
+low-level pipe for the OS.
+
+Currently, this pokes directly into the C struct of the Pipe PMC. This
+needs to change to a general interface that can be used by all subclasses and
+polymorphic equivalents of Pipe. For now, hiding it behind a function, so
+it can be cleanly changed later.
+
+=cut
+
+*/
+
+PARROT_WARN_UNUSED_RESULT
+PIOHANDLE
+io_pipe_get_os_handle(SHIM_INTERP, ARGIN(const PMC *pipe))
+{
+ ASSERT_ARGS(io_pipe_get_os_handle)
+ return PARROT_PIPE(pipe)->os_handle;
}
/*
View
3  src/io/utilities.c
@@ -71,7 +71,8 @@ Parrot_io_parse_open_flags(PARROT_INTERP, ARGIN(const STRING *mode_str))
flags &= ~PIO_F_TRUNC;
break;
case 'p':
- flags |= PIO_F_PIPE;
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
+ "Open mode 'p' is no longer valid. Use a Pipe PMC instead.");
break;
case 'b':
flags |= PIO_F_BINARY;
View
76 src/pmc/filehandle.pmc
@@ -39,17 +39,9 @@ pmclass FileHandle extends Handle auto_attrs {
ATTR INTVAL flags; /* Filehandle flags */
ATTR STRING *filename; /* The opened path and filename */
ATTR STRING *mode; /* The mode string used in open */
- ATTR INTVAL process_id; /* Child process on pipes */
- ATTR INTVAL exit_status; /* Child exit status on pipes */
ATTR PIOOFF_T file_pos; /* Current real file pointer */
ATTR PIOOFF_T last_pos; /* Last file position */
-
-/*
- * Using INTVAL for process_id is a temporary solution.
- * We may need to define a custom type to store it in a platform dependant way.
- */
-
/*
=item C<void init()>
@@ -69,8 +61,6 @@ Initializes a newly created FileHandle object.
attrs->filename = STRINGNULL;
attrs->mode = STRINGNULL;
attrs->encoding = STRINGNULL;
- attrs->process_id = 0;
- attrs->exit_status = 0;
attrs->file_pos = piooffsetzero;
attrs->last_pos = piooffsetzero;
attrs->io_vtable = (IO_VTABLE *)Parrot_io_get_vtable(interp,
@@ -115,8 +105,6 @@ Create a copy of the filehandle.
/* Copy over some metadata */
new_attrs->flags = old_attrs->flags;
- new_attrs->process_id = old_attrs->process_id;
- new_attrs->exit_status = old_attrs->exit_status;
new_attrs->file_pos = old_attrs->file_pos;
new_attrs->last_pos = old_attrs->last_pos;
@@ -167,54 +155,6 @@ Free structures.
/* TODO: flush and free the buffers */
}
-
-/*
-
-=item C<INTVAL get_integer_keyed_int(INTVAL key)>
-
-Shortcut to get the value of some attributes.
-For internal usage only, subject to change without notice.
-
-=cut
-
-*/
-
- VTABLE INTVAL get_integer_keyed_int(INTVAL key) {
- INTVAL result;
- switch (key) {
- case 0:
- GET_ATTR_process_id(INTERP, SELF, result);
- break;
- default:
- result = 0;
- }
-
- return result;
- }
-
-
-/*
-
-=item C<void set_integer_keyed_int(INTVAL key, INTVAL value)>
-
-Shortcut to set the value of some attributes
-For internal usage only, subject to change without notice.
-
-=cut
-
-*/
-
- VTABLE void set_integer_keyed_int(INTVAL key, INTVAL value) {
- switch (key) {
- case 0:
- SET_ATTR_process_id(INTERP, SELF, value);
- break;
- default:
- break;
- }
- }
-
-
/*
=item C<INTVAL get_bool()>
@@ -565,22 +505,6 @@ Returns the INTVAL used by the OS to identify this filehandle.
/*
-=item C<METHOD exit_status()>
-
-If this is a pipe, return the exit status of the child process.
-
-=cut
-
-*/
- METHOD exit_status() {
- INTVAL exit_status;
- GET_ATTR_exit_status(INTERP, SELF, exit_status);
- RETURN(INTVAL exit_status);
- }
-
-
-/*
-
=item C<METHOD tell()>
Get the file position of the stream. 2 C<INTVAL>s are returned. The first is
View
623 src/pmc/pipe.pmc
@@ -0,0 +1,623 @@
+/*
+Copyright (C) 2008-2011, Parrot Foundation.
+
+=head1 NAME
+
+src/pmc/pipe.pmc - Pipe PMC
+
+=head1 DESCRIPTION
+
+The Pipe PMC spawns a child process and captures standard input or output.
+
+=head2 Vtable Functions
+
+=over 4
+
+=cut
+
+*/
+
+#include "../src/io/io_private.h"
+#include "pmc/pmc_bytebuffer.h"
+
+#ifdef PARROT_HAS_READLINE
+#ifdef __cplusplus
+extern "C" {
+#endif
+ char *readline(const char *);
+ void add_history(const char*);
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+/* HEADERIZER HFILE: none */
+/* HEADERIZER BEGIN: static */
+/* HEADERIZER END: static */
+
+pmclass Pipe extends Handle auto_attrs {
+ ATTR INTVAL flags; /* Pipe flags */
+ ATTR STRING *procname; /* The opened process name */
+ ATTR STRING *mode; /* The mode string used in open */
+ ATTR INTVAL process_id; /* Child process ID */
+ ATTR INTVAL exit_status; /* Child exit status on pipes */
+
+
+/*
+ * TODO: Using INTVAL for process_id is a temporary solution.
+ * We may need to define a custom type to store it in a platform dependant way.
+ */
+
+/*
+
+=item C<void init()>
+
+Initializes a newly created Pipe object.
+
+=cut
+
+*/
+
+ VTABLE void init() {
+ Parrot_Pipe_attributes * const attrs = PARROT_PIPE(SELF);
+
+ attrs->record_separator = CONST_STRING(interp, "\n");
+ attrs->flags = 0;
+ attrs->procname = STRINGNULL;
+ attrs->mode = STRINGNULL;
+ attrs->encoding = STRINGNULL;
+ attrs->process_id = 0;
+ attrs->exit_status = 0;
+ attrs->io_vtable = (IO_VTABLE *)Parrot_io_get_vtable(interp,
+ IO_VTABLE_PIPE, NULL);
+
+ /* Initialize the os_handle to the platform-specific value for closed */
+ attrs->os_handle = (PIOHANDLE) PIO_INVALID_HANDLE;
+ attrs->read_buffer = NULL;
+ attrs->write_buffer = NULL;
+
+ PObj_custom_mark_SET(SELF);
+ PObj_custom_destroy_SET(SELF);
+ }
+
+
+/*
+
+=item C<PMC *clone()>
+
+Create a copy of the pipe.
+
+=cut
+
+*/
+
+ VTABLE PMC *clone() {
+ PMC * const copy = Parrot_pmc_new(interp, enum_class_Pipe);
+ Parrot_Pipe_attributes * const old_attrs = PARROT_PIPE(SELF);
+ Parrot_Pipe_attributes * const new_attrs = PARROT_PIPE(copy);
+
+ /* Properly clone string data. */
+ new_attrs->procname = old_attrs->procname;
+ new_attrs->mode = old_attrs->mode;
+ new_attrs->encoding = old_attrs->encoding;
+
+ /* Prevent GC of the strings. */
+ Parrot_gc_mark_STRING_alive(INTERP, new_attrs->procname);
+ Parrot_gc_mark_STRING_alive(INTERP, new_attrs->mode);
+ Parrot_gc_mark_STRING_alive(INTERP, new_attrs->encoding);
+
+ /* Copy over some metadata */
+ new_attrs->flags = old_attrs->flags;
+ new_attrs->process_id = old_attrs->process_id;
+ new_attrs->exit_status = old_attrs->exit_status;
+
+ /* Duplicate the pipe handle. */
+ new_attrs->os_handle = Parrot_io_internal_dup(interp, old_attrs->os_handle);
+
+ /* TODO: Clone the buffers and copy flags/data */
+
+ return copy;
+ }
+
+
+/*
+
+=item C<void mark()>
+
+Mark active pipe data as live.
+
+=cut
+
+*/
+
+ VTABLE void mark() {
+ Parrot_Pipe_attributes * const attrs = PARROT_PIPE(SELF);
+
+ Parrot_gc_mark_STRING_alive(INTERP, attrs->mode);
+ Parrot_gc_mark_STRING_alive(INTERP, attrs->procname);
+ Parrot_gc_mark_STRING_alive(INTERP, attrs->encoding);
+ Parrot_gc_mark_STRING_alive(INTERP, attrs->record_separator);
+ Parrot_io_buffer_mark(interp, attrs->read_buffer);
+ Parrot_io_buffer_mark(interp, attrs->write_buffer);
+ }
+
+
+/*
+
+=item C<void destroy()>
+
+Free structures.
+
+=cut
+
+*/
+ VTABLE void destroy() {
+ Parrot_io_close(INTERP, SELF, 1);
+
+ /* TODO: flush and free the buffers */
+ }
+
+
+/*
+
+=item C<INTVAL get_integer_keyed_int(INTVAL key)>
+
+Shortcut to get the value of some attributes.
+For internal usage only, subject to change without notice.
+
+=cut
+
+*/
+
+ VTABLE INTVAL get_integer_keyed_int(INTVAL key) {
+ INTVAL result;
+ switch (key) {
+ case 0:
+ GET_ATTR_process_id(INTERP, SELF, result);
+ break;
+ default:
+ result = 0;
+ }
+
+ return result;
+ }
+
+
+/*
+
+=item C<void set_integer_keyed_int(INTVAL key, INTVAL value)>
+
+Shortcut to set the value of some attributes
+For internal usage only, subject to change without notice.
+
+=cut
+
+*/
+
+ VTABLE void set_integer_keyed_int(INTVAL key, INTVAL value) {
+ switch (key) {
+ case 0:
+ SET_ATTR_process_id(INTERP, SELF, value);
+ break;
+ default:
+ break;
+ }
+ }
+
+
+/*
+
+=item C<INTVAL get_bool()>
+
+Return true if the pipe is open and ready to make operations. False otherwise.
+
+=cut
+
+*/
+
+ VTABLE INTVAL get_bool() {
+ /* TODO: Make sure that this makes sense for pipes */
+ return !Parrot_io_is_closed(INTERP, SELF);
+ }
+
+
+/*
+
+=back
+
+=head2 Methods
+
+=over 4
+
+=item C<METHOD open(STRING *procname :optional, STRING *mode :optional)>
+
+Opens the pipe at the given procname (including path) with the given mode. The
+invocant is modified and becomes an open pipe. A copy of the invocant is
+also returned by the method (some subclasses may create this as the primary
+pipe, rather than modifying the invocant).
+
+=cut
+
+*/
+
+ METHOD open(STRING *procname :optional, INTVAL got_procname :opt_flag,
+ STRING *mode :optional, INTVAL got_mode :opt_flag) {
+ PMC *pipe;
+
+ if (!Parrot_io_is_closed(INTERP, SELF))
+ Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_PIO_ERROR,
+ "Cannot reopen already open pipe");
+
+ if (!got_mode || STRING_IS_NULL(mode))
+ GET_ATTR_mode(INTERP, SELF, mode);
+
+ if (!got_procname || STRING_IS_NULL(procname))
+ GET_ATTR_procname(INTERP, SELF, procname);
+
+ pipe = Parrot_io_open(INTERP, SELF, procname, mode);
+ RETURN(PMC *pipe);
+ }
+
+
+/*
+
+=item C<METHOD isatty()>
+
+Returns a boolean value indicating whether C<SELF> is a console/tty.
+
+=cut
+
+*/
+
+ METHOD isatty() {
+ const INTVAL isatty = Parrot_io_is_tty_handle(INTERP, SELF);
+ RETURN(INTVAL isatty);
+ }
+
+
+/*
+
+=item C<METHOD is_closed()>
+
+Test if the pipe is closed.
+
+=cut
+
+*/
+
+ METHOD is_closed() {
+ const INTVAL status = Parrot_io_is_closed(INTERP, SELF);
+ RETURN(INTVAL status);
+ }
+
+
+/*
+
+=item C<METHOD readline_interactive(STRING *prompt)>
+
+Read a line from the pipe and return it in a string.
+
+=cut
+
+*/
+
+ METHOD readline_interactive(STRING *prompt :optional,
+ INTVAL got_prompt :opt_flag) {
+ STRING *string_result = NULL;
+
+#ifdef PARROT_HAS_READLINE
+ /* 4-column indent to get c_indent.t to DTRT */
+ char * const prompt_cstring =
+ (got_prompt ? Parrot_str_to_cstring(INTERP, prompt) : NULL);
+ char * const r = readline(prompt_cstring);
+ Parrot_str_free_cstring(prompt_cstring);
+
+ if (r) {
+ STRING *encoding;
+ const STR_VTABLE *enc = NULL;
+ GET_ATTR_encoding(INTERP, SELF, encoding);
+ if (*r)
+ add_history(r);
+ if (!STRING_IS_NULL(encoding))
+ enc = Parrot_find_encoding_by_string(INTERP, encoding);
+ if (enc == NULL)
+ string_result = Parrot_str_new(INTERP, r, 0);
+ else
+ string_result = Parrot_str_new_init(INTERP, r, strlen(r), enc, 0);
+ free(r);
+ }
+#else
+ if (got_prompt) {
+ char * const prompt_cstring = Parrot_str_to_cstring(INTERP, prompt);
+ fprintf(stderr, "%s", prompt_cstring);
+ Parrot_str_free_cstring(prompt_cstring);
+ }
+
+ string_result = Parrot_io_readline(INTERP, SELF);
+
+ {
+ INTVAL len = STRING_length(string_result);
+
+ if (len == 0) {
+ string_result = NULL;
+ }
+ else {
+ while (len > 0) {
+ const INTVAL c = STRING_ord(interp, string_result, len - 1);
+
+ if (c != '\n' && c != '\r')
+ break;
+
+ --len;
+ }
+
+ string_result = STRING_substr(interp, string_result, 0, len);
+ }
+ }
+#endif
+
+ if (string_result)
+ RETURN(STRING *string_result);
+ else
+ RETURN(PMC *PMCNULL);
+ }
+
+/*
+
+=item METHOD readall(STRING *name);
+
+Read the entire contents of a pipe to process I<name> into a Parrot string.
+On a pipe object that isn't opened yet, the path to a pipe can be passed to
+C<readall> and it will open a pipe on that process, read in the contents,
+and close the pipe.
+
+ .local pmc pio
+ pio = new 'Pipe'
+ $S0 = pio.'readall'('proc_name')
+
+If the pipe is already open, then no process name should be passed. The
+C<readall> method will read the contents of the pipe, and will not close the
+pipe when finished.
+
+ pio = open 'proc', 'r'
+ $S0 = pio.'readall'()
+
+=cut
+
+*/
+
+ METHOD readall(STRING *name :optional, INTVAL got_name :opt_flag) {
+ STRING *result;
+
+ if (got_name) {
+ /* called as class method - open, slurp, close pipe */
+ PMC *pipe;
+ STRING *encoding;
+ size_t size;
+
+ GET_ATTR_encoding(INTERP, SELF, encoding);
+
+ if (!Parrot_io_is_closed(INTERP, SELF))
+ Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_PIO_ERROR,
+ "Cannot readall on a new pipe from an already open pipe");
+
+ pipe = Parrot_io_open(INTERP, PMCNULL, name, STRINGNULL);
+
+ SET_ATTR_encoding(INTERP, pipe, encoding);
+ result = Parrot_io_readall_s(INTERP, pipe);
+
+ Parrot_io_close(INTERP, pipe, 1);
+ }
+ else
+ result = Parrot_io_readall_s(INTERP, SELF);
+
+ RETURN(STRING *result);
+ }
+
+
+/*
+
+=item C<METHOD flush()>
+
+Flushes the pipe.
+
+=cut
+
+*/
+
+ METHOD flush() {
+ Parrot_io_flush(INTERP, SELF);
+ }
+
+/*
+
+=item C<METHOD print([INTVAL|FLOATVAL|STRING *|PMC*] value)>
+
+Print the passed in integer, number, string, or PMC to the pipe.
+(Integers, numbers, and strings are auto-boxed as PMCs.)
+
+=cut
+
+*/
+
+ METHOD print(PMC *to_print) {
+ STRING * const string_to_print = VTABLE_get_string(INTERP, to_print);
+
+ const INTVAL status = Parrot_io_write_s(INTERP, SELF, string_to_print);
+
+ RETURN(INTVAL status);
+ }
+
+/*
+
+=item C<METHOD buffer_type(STRING *new_type :optional)>
+
+Set or retrieve the buffering behavior for the pipe. The argument and
+return value are one of the following:
+
+=over
+
+=item C<unbuffered>
+
+Buffering disabled, bytes are sent as soon as possible.
+
+=item C<line-buffered>
+
+Line buffering, bytes are sent when a record separator is encountered.
+
+=item C<full-buffered>
+
+Full buffering, bytes are sent when the buffer is full.
+
+=cut
+
+*/
+
+ METHOD buffer_type(STRING *new_type :optional, INTVAL got_type :opt_flag) {
+ if (got_type)
+ Parrot_io_set_buffer_mode(INTERP, SELF, new_type);
+ else {
+ STRING * type_str = Parrot_io_get_buffer_mode(INTERP, SELF);
+ RETURN(STRING *type_str);
+ }
+ }
+
+
+/*
+
+=item C<METHOD buffer_size(INTVAL new_size :optional)>
+
+Set or retrieve the buffer size for the pipe.
+
+=cut
+
+*/
+
+ METHOD buffer_size(INTVAL new_size :optional, INTVAL got_size :opt_flag) {
+ INTVAL buffer_size = Parrot_io_buffer_size(INTERP, SELF, new_size, got_size);
+ RETURN(INTVAL buffer_size);
+ }
+
+
+/*
+
+=item C<METHOD mode()>
+
+Retrieve the read mode string for the pipe.
+
+=cut
+
+*/
+
+ METHOD mode() {
+ STRING *mode;
+ GET_ATTR_mode(INTERP, SELF, mode);
+ RETURN(STRING *mode);
+ }
+
+/*
+
+=item C<METHOD eof()>
+
+Return true if a previous read attempted to read past the end of the underlying
+pipe. Note that this method may return false even if there are no bytes
+remaining if the most recent read requested the exact number of bytes remaining
+in the pipe.
+
+=cut
+
+*/
+
+ METHOD eof() {
+ const INTVAL flags = Parrot_io_eof(INTERP, SELF);
+ RETURN(INTVAL flags);
+ }
+
+
+/*
+
+=item C<METHOD handle()>
+
+Returns the INTVAL used by the OS to identify this pipe.
+
+=cut
+
+*/
+
+ METHOD handle() {
+ INTVAL handle;
+ GET_ATTR_os_handle(INTERP, SELF, handle);
+ RETURN(INTVAL handle);
+ }
+
+/*
+
+=item C<METHOD exit_status()>
+
+If this is a pipe, return the exit status of the child process.
+
+=cut
+
+*/
+ METHOD exit_status() {
+ INTVAL exit_status;
+ GET_ATTR_exit_status(INTERP, SELF, exit_status);
+ RETURN(INTVAL exit_status);
+ }
+
+
+
+/*
+
+=item C<METHOD peek()>
+
+Returns the next byte from the stream, but does not remove it.
+
+=cut
+
+*/
+
+ METHOD peek() {
+ STRING * const s = Parrot_io_peek(INTERP, SELF);
+ RETURN(STRING* s);
+ }
+
+/*
+
+=item C<METHOD setasync()>
+
+=cut
+
+*/
+ METHOD setasync() {
+ /* Parrot_io_async(INTERP, SELF, 1); */
+ }
+
+/*
+
+=item C<METHOD setblocking()>
+
+=cut
+
+*/
+ METHOD setblocking() {
+ /* Parrot_io_async(INTERP, SELF, 0); */
+ }
+
+/*
+
+=back
+
+=cut
+
+*/
+
+
+} /* end pmclass */
+
+/*
+ * Local variables:
+ * c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4 cinoptions='\:2=2' :
+ */
View
84 t/dynoplibs/io.t
@@ -20,11 +20,10 @@ Tests various io opcodes.
.sub 'main' :main
.include 'test_more.pir'
- plan(59)
+ plan(57)
read_on_null()
test_bad_open()
- open_pipe_for_reading()
getfd_fdopen()
test_fdopen_p_i_sc()
test_fdopen_p_ic_s()
@@ -39,7 +38,6 @@ Tests various io opcodes.
stdout_tests()
# must come after (these don't use test_more)
- open_pipe_for_writing()
read_invalid_fh()
.end
@@ -99,86 +97,6 @@ CODE
.include 'iglobals.pasm'
-.sub 'open_pipe_for_reading'
- .local pmc interp
- interp = getinterp
-
- .local pmc conf
- conf = interp[.IGLOBALS_CONFIG_HASH]
-
- .local string command
- command = '"'
- $S0 = conf['build_dir']
- command .= $S0
-
- .local string aux
- aux = conf['slash']
- command .= aux
- aux = conf['test_prog']
- command .= aux
- aux = conf['exe']
- command .= aux
- command .= '" -V'
-
- .local pmc pipe
- pipe = open command, 'rp'
- unless pipe goto open_pipe_for_reading_failed
- .local string line
- line = readline pipe
- line = substr line, 0, 14
- is('This is Parrot', line, 'open pipe for reading')
- .return ()
-
- open_pipe_for_reading_failed:
- nok(1, 'open pipe for reading')
- .return ()
-.end
-
-.sub 'open_pipe_for_writing'
- $I0 = tt661_todo_test()
- if $I0 goto open_pipe_for_writing_todoed
- .local pmc interp
- interp = getinterp
-
- .local pmc conf
- conf = interp[.IGLOBALS_CONFIG_HASH]
-
- .local string command
- .local string aux
- command = '"'
- aux = conf['build_dir']
- command .= aux
-
- aux = conf['slash']
- command .= aux
- .local string filename
- filename .= command
- filename .= 'examples/pasm/cat.pasm'
- aux = conf['test_prog']
- command .= aux
- aux = conf['exe']
- command .= aux
- command .= '" '
- command .= filename
- command .= '"'
-
- .local pmc pipe
- pipe = open command, 'wp'
- unless pipe goto open_pipe_for_writing_failed
-
- ok(1, 'open pipe for writing')
- close pipe
- .return ()
-
- open_pipe_for_writing_failed:
- nok(1, 'open pipe for writing')
- .return ()
-
- open_pipe_for_writing_todoed:
- todo(0, 'Unimplemented in this platform, TT #661')
-
-.end
-
# GH #465
.sub 'getfd_fdopen'
getstdout $P0
View
48 t/pmc/filehandle.t
@@ -6,7 +6,7 @@ use warnings;
use lib qw( . lib ../lib ../../lib );
use Test::More;
-use Parrot::Test tests => 32;
+use Parrot::Test tests => 31;
use Parrot::Test::Util 'create_tempfile';
=head1 NAME
@@ -780,52 +780,6 @@ CODE
utf8
OUTPUT
-pir_output_is( <<'CODE', <<"OUTPUT", "exit status" );
-.include 'iglobals.pasm'
-.sub 'main' :main
- .local pmc pipe, conf, interp
- .local string cmd
-
- interp = getinterp
- conf = interp[.IGLOBALS_CONFIG_HASH]
-
- cmd = '"'
-
- .local string aux
- aux = conf['build_dir']
- cmd .= aux
- aux = conf['slash']
- cmd .= aux
- aux = conf['test_prog']
- cmd .= aux
- aux = conf['exe']
- cmd .= aux
- cmd .= '"'
-
- pipe = new ['FileHandle']
- pipe.'open'(cmd, "rp")
- pipe.'readall'()
- pipe.'close'()
- print "expect 0 exit status: "
- $I0 = pipe.'exit_status'()
- say $I0
-
- cmd .= ' --this_is_not_a_valid_option'
- pipe = new ['FileHandle']
- pipe.'open'(cmd, "rp")
- pipe.'readall'()
- pipe.'close'()
- print "expect 1 exit status: "
- $I0 = pipe.'exit_status'()
- $I0 = $I0 != 0
- say $I0
-
-.end
-CODE
-expect 0 exit status: 0
-expect 1 exit status: 1
-OUTPUT
-
SKIP: {
skip 'Timely destruction is deprecated. GH #278' => 1;
View
70 t/pmc/pipe.t
@@ -0,0 +1,70 @@
+#!perl
+# Copyright (C) 2006-2011, Parrot Foundation.
+
+use strict;
+use warnings;
+use lib qw( . lib ../lib ../../lib );
+
+use Test::More;
+use Parrot::Test tests => 1;
+use Parrot::Test::Util 'create_tempfile';
+
+=head1 NAME
+
+t/pmc/pipe.t - test the Pipe PMC
+
+=head1 SYNOPSIS
+
+ % prove t/pmc/pipe.t
+
+=head1 DESCRIPTION
+
+Tests the Pipe PMC.
+
+=cut
+
+pir_output_is( <<'CODE', <<"OUTPUT", "exit status" );
+.include 'iglobals.pasm'
+.sub 'main' :main
+ .local pmc pipe, conf, interp
+ .local string cmd
+
+ interp = getinterp
+ conf = interp[.IGLOBALS_CONFIG_HASH]
+
+ cmd = '"'
+
+ .local string aux
+ aux = conf['build_dir']
+ cmd .= aux
+ aux = conf['slash']
+ cmd .= aux
+ aux = conf['test_prog']
+ cmd .= aux
+ aux = conf['exe']
+ cmd .= aux
+ cmd .= '"'
+
+ pipe = new ['Pipe']
+ pipe.'open'(cmd, "r")
+ pipe.'readall'()
+ pipe.'close'()
+ print "expect 0 exit status: "
+ $I0 = pipe.'exit_status'()
+ say $I0
+
+ cmd .= ' --this_is_not_a_valid_option'
+ pipe = new ['Pipe']
+ pipe.'open'(cmd, "r")
+ pipe.'readall'()
+ pipe.'close'()
+ print "expect 1 exit status: "
+ $I0 = pipe.'exit_status'()
+ $I0 = $I0 != 0
+ say $I0
+
+.end
+CODE
+expect 0 exit status: 0
+expect 1 exit status: 1
+OUTPUT
View
4 t/pmc/socket.t
@@ -154,8 +154,8 @@ stack, so we don't need to check if this parrot is IPv6-aware.
command .= str
command .= '" t/pmc/testlib/test_server.pir'
- server = new 'FileHandle'
- server.'open'(command, 'rp')
+ server = new 'Pipe'
+ server.'open'(command, 'r')
str = server.'readline'()
part = substr str, 0, 34
is(part, 'Server started, listening on port ', 'Server process started')
View
4 t/pmc/socket_ipv6.t
@@ -135,8 +135,8 @@ IPv6-related tests for the Socket PMC.
command .= str
command .= '" t/pmc/testlib/test_server_ipv6.pir'
- server = new 'FileHandle'
- server.'open'(command, 'rp')
+ server = new 'Pipe'
+ server.'open'(command, 'r')
str = server.'readline'()
part = substr str, 0, 34
is(part, 'Server started, listening on port ', 'Server process started')

No commit comments for this range

Something went wrong with that request. Please try again.