23#include <aquila/errno.h>
26MALLOC_DEFINE(M_PTY,
"pseudo-terminal",
"pseudo-terminal structure");
89 while (written < size) {
90 written += ringbuf_write(
pty->
out, size - written, (
char *) buf + written);
92 if (written != size) {
97 return written ? (
ssize_t) written : err;
120 while (written < size) {
121 written += ringbuf_write(
pty->
in, size - written, (
char *) buf + written);
123 if (written != size) {
128 return written ? (
ssize_t) written : err;
141 while (ringbuf_read(
pty->
in, 1, &c))
156 if (ptm ==
NULL)
return -ENOMEM;
175 if (!
pty)
return -ENXIO;
188 if (!
pty)
return -ENXIO;
198 if (!
pty)
return -ENXIO;
202 return copyout(argp, &
pty->
id,
sizeof(
int));
206 return copyin(&lock, argp,
sizeof(lock));
256 if (!
pty)
return -ENXIO;
283 if (!
pty)
return -ENXIO;
323 return !
pty || ringbuf_available(
pty->
out);
362 int err = 0,
id = -1;
369 if (!
pty)
goto e_nomem;
408 ringbuf_free(
pty->
in);
447 ringbuf_free(
pty->
in);
508 for (
devid_t i = 136; i < 144; ++i)
527 .can_write = __vfs_can_always,
547 .can_write = __vfs_can_always,
548 .eof = __vfs_eof_never,
int vfs_close(struct vnode *vnode)
Drops a reference to a vnode.
#define DEV(major, minor)
struct vnode * devpts_root
ssize_t tty_slave_write(struct tty *tty, size_t size, void *_buf)
Takes what programs write to the terminal, and sends it to the device through output processing (OPOS...
int tty_ioctl(struct tty *tty, int request, void *argp)
Handles a terminal's ioctl()s: its modes (TCGETS, TCSETS, ...), flushing, its session and foreground ...
int tty_free(struct tty *tty)
Ends a terminal: it is hung up, and freed.
ssize_t tty_write_iobuf(struct tty *tty, struct iobuf *io, ttyio write)
Writes to a terminal from an iobuf (user memory), to either side: a piece at a time through a kernel ...
int tty_new(struct proc *proc, size_t buf_size, ttyio master, ttyio slave, void *p, struct tty **ref)
Makes a new terminal, with the default modes (canonical, echo, signals, ICRNL, IXON,...
ssize_t tty_master_write(struct tty *tty, size_t size, void *buf)
Takes input from the terminal's device (the keyboard, a UART, or a pseudo-terminal's master),...
int tty_can_read(struct tty *tty, size_t buffered)
Says whether the terminal is readable, for select() and poll(): there is input, or an end-of-file.
int tty_eof(struct tty *tty)
Says whether a read that found nothing to return should return 0 at once: at an end-of-file (VEOF at ...
int tty_background(struct tty *tty, int sig)
Stops a background process that reads the terminal, writes it or changes it: if the current process i...
uint64_t tty_read_timeout(struct tty *tty)
Says how long a read waits for input: VTIME tenths of a second with VMIN 0 in non-canonical mode,...
void tty_open(struct tty *tty, struct file *file)
Handles a terminal device being opened: it becomes the controlling terminal of a session leader that ...
void kdev_chrdev_register(devid_t major, struct dev *dev)
Registers a driver as the character device of a major number.
#define MALLOC_DEFINE(type, _name, _desc)
void * kmalloc(size_t size, struct malloc_type *type, int flags)
Allocates memory for one of the kernel's structures.
void kfree(void *)
Frees an object that kmalloc() gave.
void * memset(void *dst, int c, size_t n)
Sets n bytes to c.
#define MODULE_INIT(name, i, f)
int posix_file_open(struct file *file)
Finishes opening a file: with O_TRUNC, a regular file is truncated to 0 bytes.
int posix_file_ioctl(struct file *file, int request, void *argp)
Passes an ioctl() request on to the file's vnode (a device's, or its filesystem's).
ssize_t posix_file_read(struct file *file, struct iobuf *io)
Reads from an open file at its offset, and moves the offset past what was read.
ssize_t posix_file_write(struct file *file, struct iobuf *io)
Writes to an open file at its offset, and moves the offset past what was written.
static int ptm_can_read(struct file *file, size_t size)
Returns whether the master can be read: the terminal output something.
int pty_init()
Registers the pseudo-terminals' devices: the masters (major 2) and the slaves (majors 136 to 143).
static uint64_t pts_read_timeout(struct file *file)
Returns how long a read of the slave may wait, from the terminal's mode (VTIME), or 0 for no limit.
static char pty_ids[PTY_MAX]
static struct pty * ptys[PTY_MAX]
static int pty_ioctl(struct devid *dd, int request, void *argp)
Handles a pseudo-terminal's ioctl()s: its number (TIOCGPTN), its lock (TIOCSPTLCK),...
ssize_t pty_master_write(struct tty *tty, size_t size, void *buf)
Takes the terminal's output, for the master to read.
static struct pty * pty_get(struct devid *dd)
Returns the pseudo-terminal of a master (major 2) or slave (major 136) device, or NULL if there is no...
int pty_new(struct proc *proc, struct vnode **master)
Makes a new pseudo-terminal: its rings, its terminal, its master and its slave, /dev/pts/N.
static ssize_t ptm_write(struct devid *dd, off_t offset, struct iobuf *io)
Writes to the terminal, as typed input.
static int ptm_new(struct pty *pty, struct vnode **ref)
Makes the master's vnode: an anonymous file, in no filesystem.
static ssize_t ptm_read(struct devid *dd, off_t offset, struct iobuf *io)
Reads the terminal's output, and wakes up the writers waiting for room.
static int pts_eof(struct file *file)
Returns whether a read of the slave that found no data is at the end of the file (the terminal says,...
ssize_t pts_read(struct devid *dd, off_t offset, struct iobuf *io)
Reads the slave's input.
static void pty_free(struct pty *pty)
Ends a pseudo-terminal, once its master is closed: the terminal, its /dev/pts node and its number go.
static int pty_id_get(void)
Takes the first free pseudo-terminal number.
int ptmx_open(struct file *file)
Opens /dev/ptmx: a new pseudo-terminal is made, and the file is its master instead.
ssize_t pts_write(struct devid *dd, off_t offset, struct iobuf *io)
Writes to the slave: the terminal's output.
ssize_t pty_slave_write(struct tty *tty, size_t size, void *buf)
Takes the terminal's input, after its line editing, for the slave to read.
int pts_can_read(struct file *file, size_t size)
Says whether a read of the slave wouldn't have to wait.
static int pts_open(struct file *file)
Opens the slave, which may become the process's controlling terminal.
static int pts_new(struct pty *pty, struct vnode **ref)
Makes the slave's node, /dev/pts/N, owned by the process that opened the master.
static int ptm_close(struct file *file)
Closes the master.
static void pty_input_flush(struct tty *tty)
Drops the input that the slave hasn't read (tcflush()).
int snprintf(char *s, size_t n, const char *fmt,...)
Formats a string into a buffer.
unsigned long long int uint64_t
A device driver: its operations, any of which may be NULL.
Which device: its kind (S_IFCHR or S_IFBLK) and numbers.
An open file (POSIX's "open file description", fs/file.c).
struct ringbuf * in
what the master writes, after line editing, for the slave to read
struct ringbuf * out
what the slave writes, after output processing, for the master to read
struct waitq pts_read_queue
where the slave's readers sleep, and the writers waiting for room in either ring (pty_slave_write(),...
struct waitq pts_write_queue
where the slave's writers and the master's readers sleep
A terminal, and its line discipline's state.
struct dev * dev
the terminal's device
void * p
the device's own data
struct vnode * vnode
the device's vnode, which /dev/tty opens in its place
void(*) input_flush(struct tty *tty)
discards the input that readers haven't read yet
Who does a filesystem operation: where its paths start, and its credentials and umask.
A file in memory (a vnode): what its inode says, and the kernel's own state.
struct waitq * write_queue
size_t ref
how many references there are to it
struct waitq * read_queue
where its readers and writers sleep
void * p
the filesystem's own data
int vfs_vunlink(struct vnode *dir, const char *fn, struct uio *uio)
Removes a name from a directory.
int vfs_vmknod(struct vnode *dir, const char *name, mode_t mode, dev_t dev, struct uio *uio, struct vnode **ref)
Makes a node in a directory.
void waitq_wakeup(struct waitq *waitq)
Wakes up every thread sleeping on a wait queue, and every thread polling it.
int waitq_sleep(struct waitq *waitq)
Puts the current thread to sleep on a wait queue until it is woken up.