1 /* 2 * Copyright 2004-2006, Axel Dörfler, axeld@pinc-software.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 #ifndef TTY_PRIVATE_H 6 #define TTY_PRIVATE_H 7 8 #include <termios.h> 9 10 #include <Drivers.h> 11 #include <KernelExport.h> 12 #include <tty/tty_module.h> 13 14 #include <condition_variable.h> 15 #include <fs/select_sync_pool.h> 16 #include <lock.h> 17 #include <util/DoublyLinkedList.h> 18 19 #include "line_buffer.h" 20 21 22 #define TTY_BUFFER_SIZE 4096 23 24 // The only nice Rico'ism :) 25 #define CTRL(c) ((c) - 0100) 26 27 28 class RequestOwner; 29 class Semaphore; 30 struct tty; 31 struct tty_cookie; 32 33 class Request : public DoublyLinkedListLinkImpl<Request> { 34 public: 35 Request(); 36 37 void Init(RequestOwner *owner, tty_cookie *cookie, size_t bytesNeeded); 38 TTYCookie()39 tty_cookie *TTYCookie() const { return fCookie; } 40 41 void Notify(size_t bytesAvailable); 42 void NotifyError(status_t error); 43 WasNotified()44 bool WasNotified() const { return fNotified; } HasError()45 bool HasError() const { return fError; } 46 47 void Dump(const char* prefix); 48 49 private: 50 RequestOwner *fOwner; 51 tty_cookie *fCookie; 52 size_t fBytesNeeded; 53 bool fNotified; 54 bool fError; 55 }; 56 57 class RequestQueue { 58 public: 59 RequestQueue(); ~RequestQueue()60 ~RequestQueue() {} 61 62 void Add(Request *request); 63 void Remove(Request *request); 64 First()65 Request *First() const { return fRequests.First(); } IsEmpty()66 bool IsEmpty() const { return fRequests.IsEmpty(); } 67 68 void NotifyFirst(size_t bytesAvailable); 69 void NotifyError(status_t error); 70 void NotifyError(tty_cookie *cookie, status_t error); 71 72 void Dump(const char* prefix); 73 74 private: 75 typedef DoublyLinkedList<Request> RequestList; 76 77 RequestList fRequests; 78 }; 79 80 class RequestOwner { 81 public: 82 RequestOwner(); 83 84 void Enqueue(tty_cookie *cookie, RequestQueue *queue1, 85 RequestQueue *queue2 = NULL); 86 void Dequeue(); 87 88 void SetBytesNeeded(size_t bytesNeeded); BytesNeeded()89 size_t BytesNeeded() const { return fBytesNeeded; } 90 91 status_t Wait(bool interruptable, bigtime_t timeout = B_INFINITE_TIMEOUT); 92 93 bool IsFirstInQueues(); 94 95 void Notify(Request *request); 96 void NotifyError(Request *request, status_t error); 97 Error()98 status_t Error() const { return fError; } 99 100 private: 101 ConditionVariable* fConditionVariable; 102 tty_cookie* fCookie; 103 status_t fError; 104 RequestQueue* fRequestQueues[2]; 105 Request fRequests[2]; 106 size_t fBytesNeeded; 107 }; 108 109 110 struct tty_cookie : DoublyLinkedListLinkImpl<tty_cookie> { 111 struct tty *tty; 112 struct tty *other_tty; 113 uint32 open_mode; 114 int32 thread_count; 115 sem_id blocking_semaphore; 116 bool closed; 117 }; 118 119 typedef DoublyLinkedList<tty_cookie> TTYCookieList; 120 121 struct tty_settings { 122 pid_t pgrp_id; 123 pid_t session_id; 124 struct termios termios; 125 struct winsize window_size; 126 }; 127 128 struct tty { 129 int32 ref_count; // referenced by cookies 130 int32 open_count; 131 int32 opened_count; 132 select_sync_pool* select_pool; 133 RequestQueue reader_queue; 134 RequestQueue writer_queue; 135 TTYCookieList cookies; 136 line_buffer input_buffer; 137 tty_service_func service_func; 138 uint32 pending_eof; 139 bool is_master; 140 recursive_lock* lock; 141 tty_settings* settings; 142 uint8 hardware_bits; 143 bool is_exclusive; 144 }; 145 146 147 extern struct mutex gTTYCookieLock; 148 extern struct recursive_lock gTTYRequestLock; 149 150 extern status_t tty_create(tty_service_func func, struct tty *masterTTY, 151 struct tty **tty); 152 extern void tty_destroy(struct tty *tty); 153 154 extern status_t tty_create_cookie(struct tty *tty, struct tty *otherTTY, 155 uint32 openMode, struct tty_cookie **cookie); 156 extern void tty_destroy_cookie(tty_cookie *cookie); 157 extern void tty_close_cookie(tty_cookie *cookie); 158 159 extern status_t tty_read(tty_cookie *cookie, void *buffer, size_t *_length); 160 extern status_t tty_write(tty_cookie *sourceCookie, const void *buffer, 161 size_t *_length); 162 extern status_t tty_control(tty_cookie *cookie, uint32 op, void *buffer, 163 size_t length); 164 extern status_t tty_select(tty_cookie *cookie, uint8 event, uint32 ref, 165 selectsync *sync); 166 extern status_t tty_deselect(tty_cookie *cookie, uint8 event, selectsync *sync); 167 168 extern status_t tty_input_lock(tty_cookie* cookie, bool lock); 169 extern status_t tty_hardware_signal(tty_cookie* cookie, int signal, bool); 170 171 #endif /* TTY_PRIVATE_H */ 172