Unix IO Interface.
For Julia programs that need to interact with Unix-specific IO interfaces.
e.g. Character devices, Terminals, Unix domain sockets, Block devices etc.
using UnixIO
using UnixIO: C
UnixIO.read(`curl https://julialang.org`, String; timeout=5)
io = UnixIO.open("/dev/ttyUSB0", C.O_RDWR | C.O_NOCTTY)
UnixIO.tcsetattr(io) do attr
attr.speed=9600
attr.c_lflag |= C.ICANON
end
readline(io; timeout=5)
fd = C.open("file.txt", C.O_CREAT | C.O_WRONLY, 0o644)
C.write(fd, pointer("Hello!"), 7)
C.close(fd)
io = UnixIO.open("file.txt", C.O_CREAT | C.O_WRONLY)
write(io, "Hello!")
close(io)
Blocking IO is multiplexed by running poll(2) under a task started by Threads.@spawn. See src/poll.jl
If ENV["JULIA_IO_EVENT_SOURCE"] is set to epoll the Linux epoll(7) API is used instead.
If ENV["JULIA_IO_EVENT_SOURCE"] is set to sleep IO polling is done by a dumb loop with a 10ms delay. This may be more efficient for small systems with simple IO requirements. (e.g. communicating with a few serial ports and sub-processes on a Raspberry Pi).
UnixIO.open([FDType], pathname, [flags = C.O_RDWR],
[mode = 0o644]];
[timeout=Inf],
[tcattr=nothing]) -> UnixIO{FDType}
Open the file specified by pathname.
Use Base.close to close the file.
The IO returned by UnixIO.open can be used with
UnixIO.read and UnixIO.write. It can also be used with
the standard Base.IO functions
(Base.read, Base.write, Base.readbytes!, Base.close etc).
See open(2)
open returns UnixFD{FDType}, where FDType is one of:
FDType
├─ File
│ ├─ S_IFBLK
│ └─ S_IFREG
├─ MetaFile
│ ├─ S_IFDIR
│ └─ S_IFLNK
├─ PidFD
└─ Stream
├─ S_IFCHR
│ ├─ CanonicalMode
│ └─ Pseudoterminal
├─ S_IFIFO
└─ S_IFSOCK
If the FDType argument is provided then open guarantees to return
UnixIO{FDType} (or throw an ArgumentError if FDType is not applicable
to pathname.
Note: C.O_NONBLOCK is always added to flags to ensure compatibility with
poll(2).
A RawFD can be opened in blocking mode by calling C.open directly.
UnixIO.set_timeout(fd::UnixFD, timeout)
Configure fd to limit IO operations to timeout seconds.
UnixIO.tcgetattr(tty) -> C.termios_m
Get terminal device options. See tcgetattr(3).
UnixIO.tcsetattr(tty, attr::C.termios_m)
UnixIO.tcsetattr(tty) do attr
[attr.c_iflag = ...]
[attr.c_oflag = ...]
[attr.c_cflag = ...]
[attr.c_lflag = ...]
[attr.speed = ...]
end
Set terminal device options.
e.g.
io = UnixIO.open("/dev/ttyUSB0", C.O_RDWR | C.O_NOCTTY)
UnixIO.tcsetattr(io) do attr
setraw(attr)
attr.speed=9600
attr.c_lflag |= C.ICANON
end
If raw is true the attributes are initialised to:
attr.c_iflag = 0
attr.c_oflag = 0
attr.c_cflag = C.CS8
attr.c_lflag = 0
See tcsetattr(3) for flag descriptions.
tcflush(tty, flags)
See tcflush(3p)
tiocgwinsz(tty) -> C.winsize
See tty_ioctl(4)
UnixIO.shutdown(sockfd, how)
Shut down part of a full-duplex connection.
how is one of C.SHUT_RD, C.SHUT_WR or C.SHUT_RDWR.
See shutdown(2)
UnixIO.read(fd, buf, [count=length(buf)];
[timeout=Inf] ) -> number of bytes read
Attempt to read up to count bytes from file descriptor fd
into the buffer starting at buf.
See read(2)
UnixIO.println(x...)
UnixIO.printerr(x...)
Write directly to STDOUT or STDERR.
Does not yield control from the current task.
UnixIO.socketpair() -> fd1, fd2
Create a pair of connected Unix Domain Sockets (AF_UNIX, SOCK_STREAM).
See socketpair(2)
UnixIO.openpt([flags = C._NOCTTY | C.O_RDWR]) -> ptfd::UnixFD, "/dev/pts/X"
Open an unused pseudoterminal device, returning: a file descriptor that can be used to refer to that device, and the path of the pseudoterminal device.
See posix_openpt(3) and prsname(3).
sh"shell command"
String containing result of shell command. e.g.
julia> println("Machine is ", sh"uname -m")
Machine is x86_64
julia> println("V: ", sh"grep version Project.toml | awk '{print$3}'")
V: "0.1.0"
UnixIO.system(command) -> exit status
See system(3)
e.g.
julia> UnixIO.system("uname -srm")
Darwin 20.3.0 x86_64
UnixIO.open(f, cmd::Cmd; [check_status=true, capture_stderr=false])
Run cmd using posix_spawn.
Call f(cmdin, cmdout)
with (STDIN, STDOUT) of cmd connected to (cmdin, cmdout).
If capture_stderr is true STDERR of cmd is merged into cmdout.
If check_status is true an exception is thrown on non-zero exit status.
e.g.
julia> UnixIO.open(`hexdump -C`) do cmdin, cmdout
write(cmdin, "Hello World!")
close(cmdin)
read(cmdout, String)
end |> println
00000000 48 65 6c 6c 6f 20 57 6f 72 6c 64 21 |Hello World!|
0000000c
UnixIO.ptopen(f, cmd::Cmd; [env=ENV, check_status=true])
Run cmd using posix_spawn.
Call f(cmdin, cmdout) with (STDIN, STDOUT and STDERR) of cmd
connected to (cmdin, cmdout) via a pseudoterminal.
If check_status is true an exception is thrown on non-zero exit status.
Run cmd using posix_spawn.
read(cmd::Cmd; [timeout=Inf,
check_status=true,
capture_stderr=false]) -> Vector{UInt8}
read(cmd::Cmd, String; kw...) -> String
Run cmd using fork and execv.
Return byes written to stdout by cmd.
e.g.
julia> UnixIO.read(`uname -srm`, String)
"Darwin 20.3.0 x86_64
"
UnixIO.waitpid(pid) -> status
See waitpid(3)