* 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:
Ingo Weinhold 2008-04-24 21:26:35 +00:00
parent 719f971dea
commit 06b7c7ffe2
6 changed files with 92 additions and 26 deletions

View 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

View File

@ -1,6 +1,7 @@
SubDir HAIKU_TOP src add-ons kernel drivers tty ;
UsePrivateKernelHeaders ;
UsePrivateHeaders drivers ;
KernelAddon <driver>tty :
driver.cpp

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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));

View File

@ -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];