2 ** Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3 ** Distributed under the terms of the Haiku License.
7 #include "tty_private.h"
11 #include <util/AutoLock.h>
14 //#define MASTER_TRACE
16 # define TRACE(x) dprintf x
22 struct master_cookie
: tty_cookie
{
26 struct tty gMasterTTYs
[kNumTTYs
];
30 master_service(struct tty
*tty
, uint32 op
)
38 create_master_cookie(master_cookie
*&cookie
, struct tty
*master
,
39 struct tty
*slave
, uint32 openMode
)
41 cookie
= (master_cookie
*)malloc(sizeof(struct master_cookie
));
45 status_t error
= init_tty_cookie(cookie
, master
, slave
, openMode
);
59 master_open(const char *name
, uint32 flags
, void **_cookie
)
61 bool findUnusedTTY
= strcmp(name
, "ptmx") == 0;
65 index
= get_tty_index(name
);
66 if (index
>= (int32
)kNumTTYs
)
70 TRACE(("master_open: TTY index = %ld (name = %s)\n", index
, name
));
72 MutexLocker
globalLocker(gGlobalTTYLock
);
75 for (index
= 0; index
< (int32
)kNumTTYs
; index
++) {
76 if (gMasterTTYs
[index
].ref_count
== 0)
79 if (index
>= (int32
)kNumTTYs
)
81 } else if (gMasterTTYs
[index
].ref_count
> 0) {
82 // we're already open!
86 status_t status
= tty_open(&gMasterTTYs
[index
], &master_service
);
88 // initializing TTY failed
92 master_cookie
*cookie
;
93 status
= create_master_cookie(cookie
, &gMasterTTYs
[index
],
94 &gSlaveTTYs
[index
], flags
);
96 tty_close(&gMasterTTYs
[index
]);
100 add_tty_cookie(cookie
);
109 master_close(void *_cookie
)
111 master_cookie
*cookie
= (master_cookie
*)_cookie
;
113 TRACE(("master_close: cookie %p\n", _cookie
));
115 MutexLocker
globalLocker(gGlobalTTYLock
);
117 // close all connected slave cookies first
118 while (tty_cookie
*slave
= cookie
->other_tty
->cookies
.Head())
119 tty_close_cookie(slave
);
121 // close the client cookie
122 tty_close_cookie(cookie
);
129 master_free_cookie(void *_cookie
)
131 // The TTY is already closed. We only have to free the cookie.
132 master_cookie
*cookie
= (master_cookie
*)_cookie
;
134 MutexLocker
globalLocker(gGlobalTTYLock
);
135 uninit_tty_cookie(cookie
);
136 globalLocker
.Unlock();
145 master_ioctl(void *_cookie
, uint32 op
, void *buffer
, size_t length
)
147 master_cookie
*cookie
= (master_cookie
*)_cookie
;
149 TRACE(("master_ioctl: cookie %p, op %lu, buffer %p, length %lu\n", _cookie
, op
, buffer
, length
));
151 return tty_ioctl(cookie
, op
, buffer
, length
);
156 master_read(void *_cookie
, off_t offset
, void *buffer
, size_t *_length
)
158 master_cookie
*cookie
= (master_cookie
*)_cookie
;
160 TRACE(("master_read: cookie %p, offset %Ld, buffer %p, length %lu\n",
161 _cookie
, offset
, buffer
, *_length
));
163 status_t result
= tty_input_read(cookie
, buffer
, _length
);
165 TRACE(("master_read done: cookie %p, result: %lx, length %lu\n", _cookie
,
173 master_write(void *_cookie
, off_t offset
, const void *buffer
, size_t *_length
)
175 master_cookie
*cookie
= (master_cookie
*)_cookie
;
177 TRACE(("master_write: cookie %p, offset %Ld, buffer %p, length %lu\n",
178 _cookie
, offset
, buffer
, *_length
));
180 status_t result
= tty_write_to_tty_master(cookie
, buffer
, _length
);
182 TRACE(("master_write done: cookie %p, result: %lx, length %lu\n", _cookie
,
190 master_select(void *_cookie
, uint8 event
, uint32 ref
, selectsync
*sync
)
192 master_cookie
*cookie
= (master_cookie
*)_cookie
;
194 return tty_select(cookie
, event
, ref
, sync
);
199 master_deselect(void *_cookie
, uint8 event
, selectsync
*sync
)
201 master_cookie
*cookie
= (master_cookie
*)_cookie
;
203 return tty_deselect(cookie
, event
, sync
);
207 device_hooks gMasterTTYHooks
= {
216 NULL
, // read_pages()
217 NULL
// write_pages()