BPicture: Fix archive constructor.
[haiku.git] / src / add-ons / kernel / drivers / tty / driver.cpp
bloba8b61a46dea94a7c65484a372dc0774a849b1671
1 /*
2 * Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3 * Distributed under the terms of the Haiku License.
4 */
6 #include <new>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
12 #include <lock.h>
14 #include "tty_private.h"
17 //#define TTY_TRACE
18 #ifdef TTY_TRACE
19 # define TRACE(x) dprintf x
20 #else
21 # define TRACE(x)
22 #endif
24 #define DRIVER_NAME "tty"
26 static const int kMaxCachedSemaphores = 8;
28 int32 api_version = B_CUR_DRIVER_API_VERSION;
30 char *gDeviceNames[kNumTTYs * 2 + 3];
31 // reserve space for "pt/" and "tt/" entries, "ptmx", "tty", and the
32 // terminating NULL
34 static mutex sTTYLocks[kNumTTYs];
36 struct mutex gGlobalTTYLock;
37 struct mutex gTTYCookieLock;
38 struct recursive_lock gTTYRequestLock;
41 status_t
42 init_hardware(void)
44 TRACE((DRIVER_NAME ": init_hardware()\n"));
45 return B_OK;
49 status_t
50 init_driver(void)
52 TRACE((DRIVER_NAME ": init_driver()\n"));
54 memset(gDeviceNames, 0, sizeof(gDeviceNames));
56 // create the request mutex
57 recursive_lock_init(&gTTYRequestLock, "tty requests");
59 // create the global mutex
60 mutex_init(&gGlobalTTYLock, "tty global");
62 // create the cookie mutex
63 mutex_init(&gTTYCookieLock, "tty cookies");
65 // create driver name array and initialize basic TTY structures
67 char letter = 'p';
68 int8 digit = 0;
70 for (uint32 i = 0; i < kNumTTYs; i++) {
71 // For compatibility, we have to create the same mess in /dev/pt and
72 // /dev/tt as BeOS does: we publish devices p0, p1, ..., pf, r1, ...,
73 // sf. It would be nice if we could drop compatibility and create
74 // something better. In fact we already don't need the master devices
75 // anymore, since "/dev/ptmx" does the job. The slaves entries could
76 // be published on the fly when a master is opened (e.g via
77 // vfs_create_special_node()).
78 char buffer[64];
80 snprintf(buffer, sizeof(buffer), "pt/%c%x", letter, digit);
81 gDeviceNames[i] = strdup(buffer);
83 snprintf(buffer, sizeof(buffer), "tt/%c%x", letter, digit);
84 gDeviceNames[i + kNumTTYs] = strdup(buffer);
86 if (++digit > 15)
87 digit = 0, letter++;
89 mutex_init(&sTTYLocks[i], "tty lock");
90 reset_tty(&gMasterTTYs[i], i, &sTTYLocks[i], true);
91 reset_tty(&gSlaveTTYs[i], i, &sTTYLocks[i], false);
92 reset_tty_settings(&gTTYSettings[i], i);
94 if (!gDeviceNames[i] || !gDeviceNames[i + kNumTTYs]) {
95 uninit_driver();
96 return B_NO_MEMORY;
100 gDeviceNames[2 * kNumTTYs] = (char *)"ptmx";
101 gDeviceNames[2 * kNumTTYs + 1] = (char *)"tty";
103 tty_add_debugger_commands();
105 return B_OK;
109 void
110 uninit_driver(void)
112 TRACE((DRIVER_NAME ": uninit_driver()\n"));
114 tty_remove_debugger_commands();
116 for (int32 i = 0; i < (int32)kNumTTYs * 2; i++)
117 free(gDeviceNames[i]);
119 for (int32 i = 0; i < (int32)kNumTTYs; i++)
120 mutex_destroy(&sTTYLocks[i]);
122 recursive_lock_destroy(&gTTYRequestLock);
123 mutex_destroy(&gTTYCookieLock);
124 mutex_destroy(&gGlobalTTYLock);
128 const char **
129 publish_devices(void)
131 TRACE((DRIVER_NAME ": publish_devices()\n"));
132 return const_cast<const char **>(gDeviceNames);
136 device_hooks *
137 find_device(const char *name)
139 TRACE((DRIVER_NAME ": find_device(\"%s\")\n", name));
141 for (uint32 i = 0; gDeviceNames[i] != NULL; i++)
142 if (!strcmp(name, gDeviceNames[i])) {
143 return i < kNumTTYs || i == (2 * kNumTTYs)
144 ? &gMasterTTYHooks : &gSlaveTTYHooks;
147 return NULL;