PARROT_EXPORT PARROT_WARN_UNUSED_RESULT PARROT_CANNOT_RETURN_NULL PMC * Parrot_io_fdopen(PARROT_INTERP, ARGIN(PMC *pmc), PIOHANDLE fd, ARGIN(STRING *sflags)) { ASSERT_ARGS(Parrot_io_fdopen) PMC *new_filehandle; const INTVAL flags = Parrot_io_parse_open_flags(interp, sflags); if (!flags) return PMCNULL; new_filehandle = Parrot_io_fdopen_flags(interp, pmc, fd, flags); if (Parrot_io_get_flags(interp, new_filehandle) & PIO_F_CONSOLE) Parrot_io_setlinebuf(interp, new_filehandle); else Parrot_io_setbuf(interp, new_filehandle, PIO_UNBOUND); return new_filehandle; }
PARROT_EXPORT PARROT_WARN_UNUSED_RESULT PARROT_CANNOT_RETURN_NULL PMC * Parrot_io_open_handle(PARROT_INTERP, ARGIN(PMC *pmc), ARGIN(STRING *path), ARGIN(STRING *mode)) { ASSERT_ARGS(Parrot_io_open_handle) PMC *filehandle; const INTVAL typenum = Parrot_hll_get_ctx_HLL_type(interp, Parrot_PMC_typenum(interp, "FileHandle")); if (PMC_IS_NULL(pmc)) { filehandle = Parrot_pmc_new(interp, typenum); } else filehandle = pmc; if (STRING_IS_NULL(path)) Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR, "Cannot open filehandle, no path"); if (filehandle->vtable->base_type == typenum) { INTVAL flags = Parrot_io_parse_open_flags(interp, mode); PIOHANDLE os_handle; /* TODO: a filehandle shouldn't allow a NULL path. */ PARROT_ASSERT(filehandle->vtable->base_type == typenum); if (flags & PIO_F_PIPE) { const int f_read = (flags & PIO_F_READ) != 0; const int f_write = (flags & PIO_F_WRITE) != 0; INTVAL pid; if (f_read == f_write) Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR, "Invalid pipe mode: %X", flags); os_handle = PIO_OPEN_PIPE(interp, path, flags, &pid); /* Save the pid of the child, we'll wait for it when closing */ VTABLE_set_integer_keyed_int(interp, filehandle, 0, pid); } else { 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"); os_handle = PIO_OPEN(interp, path, flags); if (os_handle == PIO_INVALID_HANDLE) Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR, "Unable to open filehandle from path '%Ss'", path); flags |= PIO_F_FILE; /* Set generic flag here if is a terminal then * FileHandle can know how to setup buffering. * STDIN, STDOUT, STDERR would be in this case * so we would setup linebuffering. */ if (PIO_IS_TTY(interp, os_handle)) flags |= PIO_F_CONSOLE; } if (STRING_IS_NULL(mode)) mode = CONST_STRING(interp, "r"); else if (STRING_index(interp, mode, CONST_STRING(interp, "b"), 0) >= 0) SETATTR_FileHandle_encoding(interp, filehandle, CONST_STRING(interp, "binary")); SETATTR_FileHandle_os_handle(interp, filehandle, os_handle); SETATTR_FileHandle_flags(interp, filehandle, flags); SETATTR_FileHandle_filename(interp, filehandle, path); SETATTR_FileHandle_mode(interp, filehandle, mode); Parrot_io_setbuf(interp, filehandle, PIO_UNBOUND); } else Parrot_pcc_invoke_method_from_c_args(interp, filehandle, CONST_STRING(interp, "open"), "SS->P", path, mode, &filehandle); return filehandle; }