blob: 2d2eeadd464debd0a78dd4bc3bdcf12315778e2f [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#pragma once
#include <stdint.h>
#include <threads.h>
#include <ddk/device.h>
#include <zircon/compiler.h>
#include <zircon/listnode.h>
__BEGIN_CDECLS;
typedef struct pty_server pty_server_t;
typedef struct pty_client pty_client_t;
struct pty_server {
zx_device_t* mxdev;
// lock covers server and all its clients
mtx_t lock;
// track server lifetime
int32_t refcount;
// pending OOB events
uint32_t events;
// list of all clients
list_node_t clients;
// active client receives inbound data
pty_client_t* active;
// control client receives events
pty_client_t* control;
// called when data is written by active client
// pty_server's lock is held across this call
// (it is not legal to call back into any pty_server_*() functions)
zx_status_t (*recv)(pty_server_t* ps, const void* data, size_t len, size_t* actual);
// if non-null, called for unhandled client ioctl ops
// no lock is held across this call
zx_status_t (*ioctl)(pty_server_t* ps, uint32_t op,
const void* cmd, size_t cmdlen,
void* out, size_t outlen, size_t* out_actual);
// called when pty_server_t should be deleted
// if NULL, free(ps) is called instead
void (*release)(pty_server_t* ps);
// window size in character cells
uint32_t width;
uint32_t height;
};
// this initializes everything *except* the embedded zx_device_t
void pty_server_init(pty_server_t* ps);
// write data through to active client
// if atomic is true, the send will be all-or-nothing
// if atomic is true ^c, etc processing is not done
zx_status_t pty_server_send(pty_server_t* ps, const void* data, size_t len, bool atomic, size_t* actual);
// If the recv callback returns ZX_ERR_SHOULD_WAIT, pty_server_resume()
// must be called when it is possible to call it successfully again.
// ps->lock must be held.
void pty_server_resume_locked(pty_server_t* ps);
void pty_server_set_window_size(pty_server_t* ps, uint32_t w, uint32_t h);
// device ops for pty_server
// the zx_device_t here must be the one embedded in pty_server_t
zx_status_t pty_server_openat(void* ctx, zx_device_t** out, const char* path, uint32_t flags);
void pty_server_release(void* ctx);
__END_CDECLS;