* Copyright 2004-2006, Axel DΓΆrfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*/
#ifndef TTY_PRIVATE_H
#define TTY_PRIVATE_H
#include <termios.h>
#include <Drivers.h>
#include <KernelExport.h>
#include <tty/tty_module.h>
#include <condition_variable.h>
#include <fs/select_sync_pool.h>
#include <lock.h>
#include <util/DoublyLinkedList.h>
#include "line_buffer.h"
#define TTY_BUFFER_SIZE 4096
#define CTRL(c) ((c) - 0100)
class RequestOwner;
class Semaphore;
struct tty;
struct tty_cookie;
class Request : public DoublyLinkedListLinkImpl<Request> {
public:
Request();
void Init(RequestOwner *owner, tty_cookie *cookie, size_t bytesNeeded);
tty_cookie *TTYCookie() const { return fCookie; }
void Notify(size_t bytesAvailable);
void NotifyError(status_t error);
bool WasNotified() const { return fNotified; }
bool HasError() const { return fError; }
void Dump(const char* prefix);
private:
RequestOwner *fOwner;
tty_cookie *fCookie;
size_t fBytesNeeded;
bool fNotified;
bool fError;
};
class RequestQueue {
public:
RequestQueue();
~RequestQueue() {}
void Add(Request *request);
void Remove(Request *request);
Request *First() const { return fRequests.First(); }
bool IsEmpty() const { return fRequests.IsEmpty(); }
void NotifyFirst(size_t bytesAvailable);
void NotifyError(status_t error);
void NotifyError(tty_cookie *cookie, status_t error);
void Dump(const char* prefix);
private:
typedef DoublyLinkedList<Request> RequestList;
RequestList fRequests;
};
class RequestOwner {
public:
RequestOwner();
void Enqueue(tty_cookie *cookie, RequestQueue *queue1,
RequestQueue *queue2 = NULL);
void Dequeue();
void SetBytesNeeded(size_t bytesNeeded);
size_t BytesNeeded() const { return fBytesNeeded; }
status_t Wait(bool interruptable, bigtime_t timeout = B_INFINITE_TIMEOUT);
bool IsFirstInQueues();
void Notify(Request *request);
void NotifyError(Request *request, status_t error);
status_t Error() const { return fError; }
private:
ConditionVariable* fConditionVariable;
tty_cookie* fCookie;
status_t fError;
RequestQueue* fRequestQueues[2];
Request fRequests[2];
size_t fBytesNeeded;
};
struct tty_cookie : DoublyLinkedListLinkImpl<tty_cookie> {
struct tty *tty;
struct tty *other_tty;
uint32 open_mode;
int32 thread_count;
sem_id blocking_semaphore;
bool closed;
};
typedef DoublyLinkedList<tty_cookie> TTYCookieList;
struct tty_settings {
pid_t pgrp_id;
pid_t session_id;
struct termios termios;
struct winsize window_size;
};
struct tty {
int32 ref_count;
int32 open_count;
int32 opened_count;
select_sync_pool* select_pool;
RequestQueue reader_queue;
RequestQueue writer_queue;
TTYCookieList cookies;
line_buffer input_buffer;
tty_service_func service_func;
uint32 pending_eof;
bool is_master;
recursive_lock* lock;
tty_settings* settings;
uint8 hardware_bits;
bool is_exclusive;
};
extern struct mutex gTTYCookieLock;
extern struct recursive_lock gTTYRequestLock;
extern status_t tty_create(tty_service_func func, struct tty *masterTTY,
struct tty **tty);
extern void tty_destroy(struct tty *tty);
extern status_t tty_create_cookie(struct tty *tty, struct tty *otherTTY,
uint32 openMode, struct tty_cookie **cookie);
extern void tty_destroy_cookie(tty_cookie *cookie);
extern void tty_close_cookie(tty_cookie *cookie);
extern status_t tty_read(tty_cookie *cookie, void *buffer, size_t *_length);
extern status_t tty_write(tty_cookie *sourceCookie, const void *buffer,
size_t *_length);
extern status_t tty_control(tty_cookie *cookie, uint32 op, void *buffer,
size_t length);
extern status_t tty_select(tty_cookie *cookie, uint8 event, uint32 ref,
selectsync *sync);
extern status_t tty_deselect(tty_cookie *cookie, uint8 event, selectsync *sync);
extern status_t tty_input_lock(tty_cookie* cookie, bool lock);
extern status_t tty_hardware_signal(tty_cookie* cookie, int signal, bool);
#endif