# IO
📦 std
Load the core IO modules — `IO::Handle`, `IO::File`, `IO::Seekable`, `IO::Pipe`, `IO::Socket`, `IO::Dir` — in one `use`.
This is the bootstrap module that `IO::Handle`, `IO::File`, `IO::Seekable`,
`IO::Dir`, `IO::Socket`, `IO::Pipe` all depend on. Without it, `require IO`
fails with «dynamic loading not available».
Functions are registered in their respective packages (IO::Seekable::,
IO::File::, IO::Handle::, IO::Socket::) — NOT in IO:: itself.
The BOOT section installs numeric constants into IO::Poll:: and
IO::Handle:: stashes via newCONSTSUB.
## Functions
### Other Functions
#### `io_import`
`IO.xs`: MODULE = IO — import is a no-op at the XS level. The Perl-level `IO.pm` does `eval "require IO::$_"` for each arg.
#### `fgetpos`
`IO.xs:149-173` fgetpos(handle) PerlIO path: RETVAL = newSV(0); PerlIO_getpos(handle, RETVAL) On failure or null handle: returns &PL_sv_undef.
#### `fsetpos`
`IO.xs:176-201` fsetpos(handle, pos) Returns 0 on success, -1 on failure.
#### `new_tmpfile`
`IO.xs:205-230` new_tmpfile(packname = «`IO::File`») Creates a PerlIO tmpfile, wraps in a new GV, do_open with «+>&», blesses the RV into packname. Returns blessed ref or undef.
#### `io_blocking`
`IO.xs:267-281` io_blocking(handle, blk=-1) XS wrapper: calls io_blocking_impl, returns IV or undef.
#### `ungetc`
`IO.xs:286-325` ungetc(handle, c) Simplified: we handle the PerlIO path only (no stdio fallback). skipped: UTF-8 multi-byte ungetc path (`UVCHR_IS_INVARIANT` / Perl_PerlIO_isutf8 / uvchr_to_utf8_flags) — would need full UTF-8 encoding machinery. For now we handle the single-byte invariant case which covers ASCII and the non-utf8-handle path.
#### `ferror`
`IO.xs:327-346` ferror(handle) Returns Perl_PerlIO_error(in) || (out && in != out && Perl_PerlIO_error(out)).
#### `clearerr`
`IO.xs:348-373` clearerr(handle) Clears error on both input and output streams. Returns 0 or -1.
#### `untaint`
`IO.xs:375-394` untaint(handle) No-op in our runtime (taint not supported). Returns 0 if handle valid, -1 otherwise. `IO.xs` sets IoFLAGS(io) |= IOf_UNTAINT — we just return 0.
#### `fflush`
`IO.xs:396-411` fflush(handle) Returns 0 on success, -1 on error.
#### `setbuf`
`IO.xs:413-426` setbuf(handle, …) Non-`PERLIO_IS_STDIO` path: not_here(»`IO::Handle::setbuf`») With PerlIO (our case): if buf is undef, call Perl_PerlIO_setlinebuf. `IO.xs` only implements this for `PERLIO_IS_STDIO`; for PerlIO it calls not_here. We implement the Perl_PerlIO_setlinebuf path when buf is undef (common usage), and croak for the `PERLIO_IS_STDIO` setbuf case.
#### `setvbuf`
`IO.xs:428-458` setvbuf(handle, buf, type, size) Only available under `PERLIO_IS_STDIO` && \_IOFBF && `HAS_SETVBUF`. We are PerlIO (not `PERLIO_IS_STDIO`), so this croaks.
#### `fsync`
`IO.xs:462-492` fsync(arg) Calls fsync(Perl_PerlIO_fileno(handle)).
#### [`getlines`](IO/getlines.md)
`IO.xs:520-565` getlines(…) / getline / gets These call pp_readline internally. For our implementation: getlines (ix=0): reads all lines in list context, croaks in scalar context. getline/gets (ix=1,2): reads one line in scalar context.
#### [`getlines_common`](IO/getlines_common.md)
Common implementation for getlines/getline/gets. ix=0 → getlines (list context, croak if scalar) ix=1 → getline/gets (scalar context)
#### `sockatmark`
`IO.xs:567-602` sockatmark(sock) Uses SIOCATMARK ioctl on Linux (`HAS_SOCKATMARK` path uses sockatmark(3), but ioctl is the fallback and what Linux actually does).