* Set reasonable terminal flag defaults. This makes telnetd fully usable
again. * Publish /dev/ptmx. Opening it will open a fresh pty master. In principle /dev/pt/ is obsolete now, but I guess we keep it around for compatibility with BeOS. Though there shouldn't be many applications opening a pty, that we might be interested in... * New ioctls B_IOCTL_GET_TTY_INDEX (returns the tty index) and B_IOCTL_GRANT_TTY (grants tty slave access rights). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25133 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
719f971dea
commit
06b7c7ffe2
14
headers/private/drivers/tty.h
Normal file
14
headers/private/drivers/tty.h
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _DRIVERS_TTY_H
|
||||
#define _DRIVERS_TTY_H
|
||||
|
||||
#include <termios.h>
|
||||
|
||||
#define B_IOCTL_GET_TTY_INDEX (TCGETA + 32) /* param is int32* */
|
||||
#define B_IOCTL_GRANT_TTY (TCGETA + 33) /* no param (cf. grantpt()) */
|
||||
|
||||
|
||||
#endif // _DRIVERS_TTY_H
|
@ -1,6 +1,7 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel drivers tty ;
|
||||
|
||||
UsePrivateKernelHeaders ;
|
||||
UsePrivateHeaders drivers ;
|
||||
|
||||
KernelAddon <driver>tty :
|
||||
driver.cpp
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
** Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
** Distributed under the terms of the Haiku License.
|
||||
*/
|
||||
* Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Distributed under the terms of the Haiku License.
|
||||
*/
|
||||
|
||||
#include <new>
|
||||
|
||||
@ -27,9 +27,9 @@ static const int kMaxCachedSemaphores = 8;
|
||||
|
||||
int32 api_version = B_CUR_DRIVER_API_VERSION;
|
||||
|
||||
static char *sDeviceNames[kNumTTYs * 2 + 2];
|
||||
// reserve space for "pt/" and "tt/" entries, "tty", and the terminating
|
||||
// NULL
|
||||
char *gDeviceNames[kNumTTYs * 2 + 3];
|
||||
// reserve space for "pt/" and "tt/" entries, "ptmx", "tty", and the
|
||||
// terminating NULL
|
||||
|
||||
struct mutex gGlobalTTYLock;
|
||||
struct mutex gTTYCookieLock;
|
||||
@ -49,7 +49,7 @@ init_driver(void)
|
||||
{
|
||||
TRACE((DRIVER_NAME ": init_driver()\n"));
|
||||
|
||||
memset(sDeviceNames, 0, sizeof(sDeviceNames));
|
||||
memset(gDeviceNames, 0, sizeof(gDeviceNames));
|
||||
|
||||
// create the global mutex
|
||||
status_t error = mutex_init(&gGlobalTTYLock, "tty global");
|
||||
@ -77,16 +77,20 @@ init_driver(void)
|
||||
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.
|
||||
// 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);
|
||||
sDeviceNames[i] = strdup(buffer);
|
||||
gDeviceNames[i] = strdup(buffer);
|
||||
|
||||
snprintf(buffer, sizeof(buffer), "tt/%c%x", letter, digit);
|
||||
sDeviceNames[i + kNumTTYs] = strdup(buffer);
|
||||
gDeviceNames[i + kNumTTYs] = strdup(buffer);
|
||||
|
||||
if (++digit > 15)
|
||||
digit = 0, letter++;
|
||||
@ -95,13 +99,14 @@ init_driver(void)
|
||||
reset_tty(&gSlaveTTYs[i], i, false);
|
||||
reset_tty_settings(&gTTYSettings[i], i);
|
||||
|
||||
if (!sDeviceNames[i] || !sDeviceNames[i + kNumTTYs]) {
|
||||
if (!gDeviceNames[i] || !gDeviceNames[i + kNumTTYs]) {
|
||||
uninit_driver();
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
sDeviceNames[2 * kNumTTYs] = "tty";
|
||||
gDeviceNames[2 * kNumTTYs] = "ptmx";
|
||||
gDeviceNames[2 * kNumTTYs + 1] = "tty";
|
||||
|
||||
tty_add_debugger_commands();
|
||||
|
||||
@ -117,7 +122,7 @@ uninit_driver(void)
|
||||
tty_remove_debugger_commands();
|
||||
|
||||
for (int32 i = 0; i < (int32)kNumTTYs * 2; i++)
|
||||
free(sDeviceNames[i]);
|
||||
free(gDeviceNames[i]);
|
||||
|
||||
recursive_lock_destroy(&gTTYRequestLock);
|
||||
mutex_destroy(&gTTYCookieLock);
|
||||
@ -129,7 +134,7 @@ const char **
|
||||
publish_devices(void)
|
||||
{
|
||||
TRACE((DRIVER_NAME ": publish_devices()\n"));
|
||||
return const_cast<const char **>(sDeviceNames);
|
||||
return const_cast<const char **>(gDeviceNames);
|
||||
}
|
||||
|
||||
|
||||
@ -138,9 +143,11 @@ find_device(const char *name)
|
||||
{
|
||||
TRACE((DRIVER_NAME ": find_device(\"%s\")\n", name));
|
||||
|
||||
for (uint32 i = 0; sDeviceNames[i] != NULL; i++)
|
||||
if (!strcmp(name, sDeviceNames[i]))
|
||||
return i < kNumTTYs ? &gMasterTTYHooks : &gSlaveTTYHooks;
|
||||
for (uint32 i = 0; gDeviceNames[i] != NULL; i++)
|
||||
if (!strcmp(name, gDeviceNames[i])) {
|
||||
return i < kNumTTYs || i == (2 * kNumTTYs)
|
||||
? &gMasterTTYHooks : &gSlaveTTYHooks;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -65,15 +65,27 @@ create_master_cookie(master_cookie *&cookie, struct tty *master,
|
||||
static status_t
|
||||
master_open(const char *name, uint32 flags, void **_cookie)
|
||||
{
|
||||
int32 index = get_tty_index(name);
|
||||
if (index >= (int32)kNumTTYs)
|
||||
return B_ERROR;
|
||||
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 = %ld (name = %s)\n", index, name));
|
||||
|
||||
MutexLocker globalLocker(gGlobalTTYLock);
|
||||
|
||||
if (gMasterTTYs[index].open_count > 0) {
|
||||
if (findUnusedTTY) {
|
||||
for (index = 0; index < (int32)kNumTTYs; index++) {
|
||||
if (gMasterTTYs[index].open_count == 0)
|
||||
break;
|
||||
}
|
||||
if (index >= (int32)kNumTTYs)
|
||||
return ENOENT;
|
||||
} else if (gMasterTTYs[index].open_count > 0) {
|
||||
// we're already open!
|
||||
return B_BUSY;
|
||||
}
|
||||
|
@ -10,8 +10,11 @@
|
||||
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <util/AutoLock.h>
|
||||
@ -19,6 +22,8 @@
|
||||
|
||||
#include <team.h>
|
||||
|
||||
#include <tty.h>
|
||||
|
||||
#include "tty_private.h"
|
||||
|
||||
|
||||
@ -765,11 +770,11 @@ reset_termios(struct termios &termios)
|
||||
{
|
||||
memset(&termios, 0, sizeof(struct termios));
|
||||
|
||||
termios.c_iflag = 0;
|
||||
termios.c_oflag = 0;
|
||||
termios.c_iflag = ICRNL;
|
||||
termios.c_oflag = OPOST | ONLCR;
|
||||
termios.c_cflag = B19200 | CS8 | CREAD | HUPCL;
|
||||
// enable receiver, hang up on last close
|
||||
termios.c_lflag = 0;
|
||||
termios.c_lflag = ECHO | ISIG | ICANON;
|
||||
|
||||
// control characters
|
||||
termios.c_cc[VINTR] = CTRL('C');
|
||||
@ -1390,6 +1395,31 @@ tty_ioctl(tty_cookie *cookie, uint32 op, void *buffer, size_t length)
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
case B_IOCTL_GET_TTY_INDEX:
|
||||
if (user_memcpy(buffer, &tty->index, sizeof(int32)) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
return B_OK;
|
||||
|
||||
case B_IOCTL_GRANT_TTY:
|
||||
{
|
||||
if (!tty->is_master)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get slave path
|
||||
char path[64];
|
||||
snprintf(path, sizeof(path), "/dev/%s",
|
||||
gDeviceNames[kNumTTYs + tty->index]);
|
||||
|
||||
// set owner and permissions respectively
|
||||
if (chown(path, getuid(), getgid()) != 0
|
||||
|| chmod(path, S_IRUSR | S_IWUSR | S_IWGRP) != 0) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
|
||||
TRACE(("tty: unsupported opcode %lu\n", op));
|
||||
|
@ -145,6 +145,8 @@ struct tty {
|
||||
|
||||
static const uint32 kNumTTYs = 64;
|
||||
|
||||
extern char *gDeviceNames[kNumTTYs * 2 + 3];
|
||||
|
||||
extern tty gMasterTTYs[kNumTTYs];
|
||||
extern tty gSlaveTTYs[kNumTTYs];
|
||||
extern tty_settings gTTYSettings[kNumTTYs];
|
||||
|
Loading…
Reference in New Issue
Block a user