Delete the old TTY driver.

No longer used or included in the build after the previous commit.
This commit is contained in:
Augustin Cavalier
2023-05-09 16:04:09 -04:00
parent 0c2a5bb5ea
commit bbb4db9276
7 changed files with 0 additions and 2798 deletions
-18
View File
@@ -1,18 +0,0 @@
SubDir HAIKU_TOP src add-ons kernel drivers tty ;
UsePrivateKernelHeaders ;
UsePrivateHeaders drivers ;
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel generic tty ] ;
KernelAddon <driver>tty :
driver.cpp
tty.cpp
line_buffer.cpp
master.cpp
slave.cpp
;
SEARCH on [ FGristFiles line_buffer.cpp ]
+= [ FDirName $(HAIKU_TOP) src add-ons kernel generic tty ] ;
-176
View File
@@ -1,176 +0,0 @@
/*
* Copyright 2004, Axel Dörfler, [email protected]. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#include <new>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <lock.h>
#include "tty_driver.h"
#include "tty_private.h"
//#define TTY_TRACE
#ifdef TTY_TRACE
# define TRACE(x) dprintf x
#else
# define TRACE(x)
#endif
#define DRIVER_NAME "tty"
static const int kMaxCachedSemaphores = 8;
int32 api_version = B_CUR_DRIVER_API_VERSION;
char *gDeviceNames[kNumTTYs * 2 + 3];
// reserve space for "pt/" and "tt/" entries, "ptmx", "tty", and the
// terminating NULL
static mutex sTTYLocks[kNumTTYs];
static tty_settings sTTYSettings[kNumTTYs];
struct mutex gGlobalTTYLock;
struct mutex gTTYCookieLock;
struct recursive_lock gTTYRequestLock;
status_t
init_hardware(void)
{
TRACE((DRIVER_NAME ": init_hardware()\n"));
return B_OK;
}
status_t
init_driver(void)
{
TRACE((DRIVER_NAME ": init_driver()\n"));
memset(gDeviceNames, 0, sizeof(gDeviceNames));
// create the request mutex
recursive_lock_init(&gTTYRequestLock, "tty requests");
// create the global mutex
mutex_init(&gGlobalTTYLock, "tty global");
// create the cookie mutex
mutex_init(&gTTYCookieLock, "tty cookies");
// create driver name array and initialize basic TTY structures
char letter = 'p';
int8 digit = 0;
for (uint32 i = 0; i < kNumTTYs; i++) {
// For compatibility, we have to create the same mess in /dev/pt and
// /dev/tt as BeOS does: we publish devices p0, p1, ..., pf, r1, ...,
// sf. It would be nice if we could drop compatibility and create
// something better. In fact we already don't need the master devices
// anymore, since "/dev/ptmx" does the job. The slaves entries could
// be published on the fly when a master is opened (e.g via
// vfs_create_special_node()).
char buffer[64];
snprintf(buffer, sizeof(buffer), "pt/%c%x", letter, digit);
gDeviceNames[i] = strdup(buffer);
snprintf(buffer, sizeof(buffer), "tt/%c%x", letter, digit);
gDeviceNames[i + kNumTTYs] = strdup(buffer);
if (++digit > 15)
digit = 0, letter++;
mutex_init(&sTTYLocks[i], "tty lock");
reset_tty(&gMasterTTYs[i], i, &sTTYLocks[i], true);
reset_tty(&gSlaveTTYs[i], i, &sTTYLocks[i], false);
reset_tty_settings(&sTTYSettings[i]);
if (!gDeviceNames[i] || !gDeviceNames[i + kNumTTYs]) {
uninit_driver();
return B_NO_MEMORY;
}
}
gDeviceNames[2 * kNumTTYs] = (char *)"ptmx";
gDeviceNames[2 * kNumTTYs + 1] = (char *)"tty";
return B_OK;
}
void
uninit_driver(void)
{
TRACE((DRIVER_NAME ": uninit_driver()\n"));
for (int32 i = 0; i < (int32)kNumTTYs * 2; i++)
free(gDeviceNames[i]);
for (int32 i = 0; i < (int32)kNumTTYs; i++)
mutex_destroy(&sTTYLocks[i]);
recursive_lock_destroy(&gTTYRequestLock);
mutex_destroy(&gTTYCookieLock);
mutex_destroy(&gGlobalTTYLock);
}
const char **
publish_devices(void)
{
TRACE((DRIVER_NAME ": publish_devices()\n"));
return const_cast<const char **>(gDeviceNames);
}
device_hooks *
find_device(const char *name)
{
TRACE((DRIVER_NAME ": find_device(\"%s\")\n", name));
for (uint32 i = 0; gDeviceNames[i] != NULL; i++)
if (!strcmp(name, gDeviceNames[i])) {
return i < kNumTTYs || i == (2 * kNumTTYs)
? &gMasterTTYHooks : &gSlaveTTYHooks;
}
return NULL;
}
int32
get_tty_index(const char* name)
{
// device names follow this form: "pt/%c%x"
int8 digit = name[4];
if (digit >= 'a') {
// hexadecimal digits
digit -= 'a' - 10;
} else
digit -= '0';
return (name[3] - 'p') * 16 + digit;
}
void
reset_tty(struct tty* tty, int32 index, mutex* lock, bool isMaster)
{
tty->ref_count = 0;
tty->open_count = 0;
tty->opened_count = 0;
tty->index = index;
tty->lock = lock;
tty->settings = &sTTYSettings[index];
tty->select_pool = NULL;
tty->is_master = isMaster;
tty->pending_eof = 0;
}
-221
View File
@@ -1,221 +0,0 @@
/*
** Copyright 2004, Axel Dörfler, [email protected]. All rights reserved.
** Distributed under the terms of the MIT License.
*/
#include "tty_driver.h"
#include "tty_private.h"
#include <stdlib.h>
#include <string.h>
#include <util/AutoLock.h>
//#define MASTER_TRACE
#ifdef MASTER_TRACE
# define TRACE(x) dprintf x
#else
# define TRACE(x) ;
#endif
struct master_cookie : tty_cookie {
};
struct tty gMasterTTYs[kNumTTYs];
static status_t
master_service(struct tty *tty, uint32 op)
{
// nothing here yet
return B_OK;
}
static status_t
create_master_cookie(master_cookie *&cookie, struct tty *master,
struct tty *slave, uint32 openMode)
{
cookie = (master_cookie*)malloc(sizeof(struct master_cookie));
if (cookie == NULL)
return B_NO_MEMORY;
status_t error = init_tty_cookie(cookie, master, slave, openMode);
if (error != B_OK) {
free(cookie);
return error;
}
return B_OK;
}
// #pragma mark -
static status_t
master_open(const char *name, uint32 flags, void **_cookie)
{
bool findUnusedTTY = strcmp(name, "ptmx") == 0;
int32 index = -1;
if (!findUnusedTTY) {
index = get_tty_index(name);
if (index >= (int32)kNumTTYs)
return B_ERROR;
}
TRACE(("master_open: TTY index = %" B_PRId32 " (name = %s)\n", index,
name));
MutexLocker globalLocker(gGlobalTTYLock);
if (findUnusedTTY) {
for (index = 0; index < (int32)kNumTTYs; index++) {
if (gMasterTTYs[index].ref_count == 0)
break;
}
if (index >= (int32)kNumTTYs)
return ENOENT;
} else if (gMasterTTYs[index].ref_count > 0) {
// we're already open!
return B_BUSY;
}
gMasterTTYs[index].opened_count = 0;
gSlaveTTYs[index].opened_count = 0;
status_t status = tty_open(&gMasterTTYs[index], &master_service);
if (status < B_OK) {
// initializing TTY failed
return status;
}
master_cookie *cookie;
status = create_master_cookie(cookie, &gMasterTTYs[index],
&gSlaveTTYs[index], flags);
if (status != B_OK) {
tty_close(&gMasterTTYs[index]);
return status;
}
*_cookie = cookie;
return B_OK;
}
static status_t
master_close(void *_cookie)
{
master_cookie *cookie = (master_cookie *)_cookie;
TRACE(("master_close: cookie %p\n", _cookie));
MutexLocker globalLocker(gGlobalTTYLock);
// close all connected slave cookies first
while (tty_cookie *slave = cookie->other_tty->cookies.Head())
tty_close_cookie(slave);
// close the client cookie
tty_close_cookie(cookie);
return B_OK;
}
static status_t
master_free_cookie(void *_cookie)
{
// The TTY is already closed. We only have to free the cookie.
master_cookie *cookie = (master_cookie *)_cookie;
MutexLocker globalLocker(gGlobalTTYLock);
uninit_tty_cookie(cookie);
globalLocker.Unlock();
free(cookie);
return B_OK;
}
static status_t
master_ioctl(void *_cookie, uint32 op, void *buffer, size_t length)
{
master_cookie *cookie = (master_cookie *)_cookie;
TRACE(("master_ioctl: cookie %p, op %" B_PRIu32 ", buffer %p, length %lu"
"\n", _cookie, op, buffer, length));
return tty_ioctl(cookie, op, buffer, length);
}
static status_t
master_read(void *_cookie, off_t offset, void *buffer, size_t *_length)
{
master_cookie *cookie = (master_cookie *)_cookie;
TRACE(("master_read: cookie %p, offset %" B_PRIdOFF ", buffer %p, length "
"%lu\n", _cookie, offset, buffer, *_length));
status_t result = tty_input_read(cookie, buffer, _length);
TRACE(("master_read done: cookie %p, result: %" B_PRIx32 ", length %lu\n",
_cookie, result, *_length));
return result;
}
static status_t
master_write(void *_cookie, off_t offset, const void *buffer, size_t *_length)
{
master_cookie *cookie = (master_cookie *)_cookie;
TRACE(("master_write: cookie %p, offset %" B_PRIdOFF ", buffer %p, length "
"%lu\n", _cookie, offset, buffer, *_length));
status_t result = tty_write_to_tty_master(cookie, buffer, _length);
TRACE(("master_write done: cookie %p, result: %" B_PRIx32 ", length %lu\n",
_cookie, result, *_length));
return result;
}
static status_t
master_select(void *_cookie, uint8 event, uint32 ref, selectsync *sync)
{
master_cookie *cookie = (master_cookie *)_cookie;
return tty_select(cookie, event, ref, sync);
}
static status_t
master_deselect(void *_cookie, uint8 event, selectsync *sync)
{
master_cookie *cookie = (master_cookie *)_cookie;
return tty_deselect(cookie, event, sync);
}
device_hooks gMasterTTYHooks = {
&master_open,
&master_close,
&master_free_cookie,
&master_ioctl,
&master_read,
&master_write,
&master_select,
&master_deselect,
NULL, // read_pages()
NULL // write_pages()
};
-232
View File
@@ -1,232 +0,0 @@
/*
** Copyright 2004, Axel Dörfler, [email protected]. All rights reserved.
** Distributed under the terms of the MIT License.
*/
#include <stdlib.h>
#include <string.h>
#include <util/AutoLock.h>
#include <team.h>
#include "tty_driver.h"
#include "tty_private.h"
//#define SLAVE_TRACE
#ifdef SLAVE_TRACE
# define TRACE(x) dprintf x
#else
# define TRACE(x)
#endif
struct slave_cookie : tty_cookie {
};
struct tty gSlaveTTYs[kNumTTYs];
static status_t
slave_open(const char *name, uint32 flags, void **_cookie)
{
// Get the tty index: Opening "/dev/tty" means opening the process'
// controlling tty.
int32 index = get_tty_index(name);
if (strcmp(name, "tty") == 0) {
index = team_get_controlling_tty();
if (index < 0)
return B_NOT_ALLOWED;
} else {
index = get_tty_index(name);
if (index >= (int32)kNumTTYs)
return B_ERROR;
}
TRACE(("slave_open: TTY index = %" B_PRId32 " (name = %s)\n", index,
name));
MutexLocker globalLocker(gGlobalTTYLock);
// we may only be used if our master has already been opened
if (gMasterTTYs[index].open_count == 0)
return B_IO_ERROR;
bool makeControllingTTY = (flags & O_NOCTTY) == 0;
pid_t processID = getpid();
pid_t sessionID = getsid(processID);
if (gSlaveTTYs[index].open_count == 0) {
// We only allow session leaders to open the tty initially.
if (makeControllingTTY && processID != sessionID)
return B_NOT_ALLOWED;
status_t status = tty_open(&gSlaveTTYs[index], NULL);
if (status < B_OK) {
// initializing TTY failed
return status;
}
} else if (makeControllingTTY) {
// If already open, we allow only processes from the same session
// to open the tty again while becoming controlling tty
pid_t ttySession = gSlaveTTYs[index].settings->session_id;
if (ttySession >= 0) {
makeControllingTTY = false;
} else {
// The tty is not associated with a session yet. The process needs
// to be a session leader.
if (makeControllingTTY && processID != sessionID)
return B_NOT_ALLOWED;
}
}
slave_cookie *cookie = (slave_cookie *)malloc(sizeof(struct slave_cookie));
if (cookie == NULL) {
if (gSlaveTTYs[index].open_count == 0)
tty_close(&gSlaveTTYs[index]);
return B_NO_MEMORY;
}
status_t status = init_tty_cookie(cookie, &gSlaveTTYs[index],
&gMasterTTYs[index], flags);
if (status != B_OK) {
free(cookie);
if (gSlaveTTYs[index].open_count == 0)
tty_close(&gSlaveTTYs[index]);
return status;
}
if (gSlaveTTYs[index].open_count == 0) {
gSlaveTTYs[index].lock = gMasterTTYs[index].lock;
gSlaveTTYs[index].settings->session_id = -1;
gSlaveTTYs[index].settings->pgrp_id = -1;
}
if (makeControllingTTY) {
gSlaveTTYs[index].settings->session_id = sessionID;
gSlaveTTYs[index].settings->pgrp_id = sessionID;
team_set_controlling_tty(gSlaveTTYs[index].index);
}
*_cookie = cookie;
return B_OK;
}
static status_t
slave_close(void *_cookie)
{
slave_cookie *cookie = (slave_cookie *)_cookie;
TRACE(("slave_close: cookie %p\n", _cookie));
MutexLocker globalLocker(gGlobalTTYLock);
// unblock and wait for all blocking operations
tty_close_cookie(cookie);
return B_OK;
}
static status_t
slave_free_cookie(void *_cookie)
{
// The TTY is already closed. We only have to free the cookie.
slave_cookie *cookie = (slave_cookie *)_cookie;
TRACE(("slave_free_cookie: cookie %p\n", _cookie));
MutexLocker globalLocker(gGlobalTTYLock);
uninit_tty_cookie(cookie);
globalLocker.Unlock();
free(cookie);
return B_OK;
}
static status_t
slave_ioctl(void *_cookie, uint32 op, void *buffer, size_t length)
{
slave_cookie *cookie = (slave_cookie *)_cookie;
TRACE(("slave_ioctl: cookie %p, op %" B_PRIu32 ", buffer %p, length %lu\n",
_cookie, op, buffer, length));
return tty_ioctl(cookie, op, buffer, length);
}
static status_t
slave_read(void *_cookie, off_t offset, void *buffer, size_t *_length)
{
slave_cookie *cookie = (slave_cookie *)_cookie;
TRACE(("slave_read: cookie %p, offset %" B_PRIdOFF ", buffer %p, length "
"%lu\n", _cookie, offset, buffer, *_length));
status_t result = tty_input_read(cookie, buffer, _length);
TRACE(("slave_read done: cookie %p, result %" B_PRIx32 ", length %lu\n",
_cookie, result, *_length));
return result;
}
static status_t
slave_write(void *_cookie, off_t offset, const void *buffer, size_t *_length)
{
slave_cookie *cookie = (slave_cookie *)_cookie;
TRACE(("slave_write: cookie %p, offset %" B_PRIdOFF", buffer %p, length "
"%lu\n", _cookie, offset, buffer, *_length));
status_t result = tty_write_to_tty_slave(cookie, buffer, _length);
TRACE(("slave_write done: cookie %p, result %" B_PRIx32 ", length %lu\n",
_cookie, result, *_length));
return result;
}
static status_t
slave_select(void *_cookie, uint8 event, uint32 ref, selectsync *sync)
{
slave_cookie *cookie = (slave_cookie *)_cookie;
return tty_select(cookie, event, ref, sync);
}
static status_t
slave_deselect(void *_cookie, uint8 event, selectsync *sync)
{
slave_cookie *cookie = (slave_cookie *)_cookie;
return tty_deselect(cookie, event, sync);
}
device_hooks gSlaveTTYHooks = {
&slave_open,
&slave_close,
&slave_free_cookie,
&slave_ioctl,
&slave_read,
&slave_write,
&slave_select,
&slave_deselect,
NULL, // read_pages()
NULL // write_pages()
};
File diff suppressed because it is too large Load Diff
@@ -1,25 +0,0 @@
/*
* Copyright 2004-2006, Axel Dörfler, [email protected]. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef TTY_DRIVER_H
#define TTY_DRIVER_H
#include "tty_private.h"
extern tty gMasterTTYs[kNumTTYs];
extern tty gSlaveTTYs[kNumTTYs];
extern device_hooks gMasterTTYHooks;
extern device_hooks gSlaveTTYHooks;
extern struct mutex gGlobalTTYLock;
extern int32 get_tty_index(const char *name);
extern void reset_tty(struct tty *tty, int32 index, mutex* lock, bool isMaster);
#endif /* !TTY_DRIVER_H */
@@ -1,178 +0,0 @@
/*
* Copyright 2004-2006, Axel Dörfler, [email protected].
* 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 <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
// The only nice Rico'ism :)
#define CTRL(c) ((c) - 0100)
typedef status_t (*tty_service_func)(struct tty *tty, uint32 op);
// not yet used...
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; // referenced by cookies
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;
struct mutex* lock;
tty_settings* settings;
int32 index;
};
static const uint32 kNumTTYs = 64;
extern char *gDeviceNames[kNumTTYs * 2 + 3];
extern struct mutex gTTYCookieLock;
extern struct recursive_lock gTTYRequestLock;
extern status_t tty_open(struct tty *tty, tty_service_func func);
extern status_t tty_close(struct tty *tty);
extern status_t init_tty_cookie(tty_cookie *cookie, struct tty *tty,
struct tty *otherTTY, uint32 openMode);
extern void uninit_tty_cookie(tty_cookie *cookie);
extern void tty_close_cookie(struct tty_cookie *cookie);
// functions available for master/slave TTYs
extern void reset_tty_settings(tty_settings *settings);
extern status_t tty_input_read(tty_cookie *cookie, void *buffer,
size_t *_length);
extern status_t tty_write_to_tty_master(tty_cookie *sourceCookie,
const void *buffer, size_t *_length);
extern status_t tty_write_to_tty_slave(tty_cookie *sourceCookie,
const void *buffer, size_t *_length);
extern status_t tty_ioctl(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);
#endif /* TTY_PRIVATE_H */