1 use std::cell::RefCell; 2 use std::os::unix::io::{FromRawFd, RawFd}; 3 use std::sync::{Arc, Mutex}; 4 5 use nix::Result as NixResult; 6 7 use wayland_commons::map::{Object, ObjectMap, SERVER_ID_LIMIT}; 8 use wayland_commons::socket::{BufferedSocket, Socket}; 9 use wayland_commons::wire::{Argument, ArgumentType, Message, MessageParseError}; 10 11 use super::proxy::ObjectMeta; 12 use super::queues::QueueBuffer; 13 14 use crate::ProtocolError; 15 16 #[derive(Clone, Debug)] 17 pub(crate) enum Error { 18 Protocol(ProtocolError), 19 Parse(MessageParseError), 20 Nix(::nix::Error), 21 } 22 23 pub(crate) struct Connection { 24 pub(crate) socket: BufferedSocket, 25 pub(crate) map: Arc<Mutex<ObjectMap<ObjectMeta>>>, 26 pub(crate) last_error: Arc<Mutex<Option<Error>>>, 27 pub(crate) display_buffer: QueueBuffer, 28 } 29 30 impl Connection { new(fd: RawFd, display_object: Object<ObjectMeta>) -> Connection31 pub(crate) unsafe fn new(fd: RawFd, display_object: Object<ObjectMeta>) -> Connection { 32 let socket = BufferedSocket::new(Socket::from_raw_fd(fd)); 33 34 let mut map = ObjectMap::new(); 35 // Insert first pre-existing object 36 let display_buffer = display_object.meta.buffer.clone(); 37 map.insert_at(1, display_object).unwrap(); 38 39 Connection { 40 socket, 41 map: Arc::new(Mutex::new(map)), 42 last_error: Arc::new(Mutex::new(None)), 43 display_buffer, 44 } 45 } 46 write_message(&mut self, msg: &Message) -> NixResult<()>47 pub(crate) fn write_message(&mut self, msg: &Message) -> NixResult<()> { 48 self.socket.write_message(msg) 49 } 50 flush(&mut self) -> NixResult<()>51 pub(crate) fn flush(&mut self) -> NixResult<()> { 52 self.socket.flush() 53 } 54 read_events(&mut self) -> Result<usize, Error>55 pub(crate) fn read_events(&mut self) -> Result<usize, Error> { 56 if let Some(ref err) = *self.last_error.lock().unwrap() { 57 return Err(err.clone()); 58 } 59 // acquire the map lock, this means no objects can be created nor destroyed while we 60 // are reading events 61 let mut map = self.map.lock().unwrap(); 62 // wrap it in a RefCell for cheap sharing in the two closures below 63 let map = RefCell::new(&mut *map); 64 let mut last_error = self.last_error.lock().unwrap(); 65 // read messages 66 let ret = self.socket.read_messages( 67 |id, opcode| { 68 map.borrow() 69 .find(id) 70 .and_then(|o| o.events.get(opcode as usize)) 71 .map(|desc| desc.signature) 72 }, 73 |msg| { 74 // Early exit on protocol error 75 if msg.sender_id == 1 && msg.opcode == 0 { 76 if let [Argument::Object(faulty_id), Argument::Uint(error_code), Argument::Str(ref error_msg)] = &msg.args[..] { 77 let error_msg = error_msg.to_string_lossy().into_owned(); 78 let faulty_interface = map.borrow().find(*faulty_id).map(|obj| obj.interface).unwrap_or("unknown"); 79 // abort parsing, this is an unrecoverable error 80 *last_error = Some(Error::Protocol(ProtocolError { 81 code: *error_code, 82 object_id: *faulty_id, 83 object_interface: faulty_interface, 84 message: error_msg 85 })); 86 } else { 87 unreachable!(); 88 } 89 return false; 90 } 91 92 // dispatch the message to the proper object 93 let mut map = map.borrow_mut(); 94 let object = map.find(msg.sender_id); 95 96 // create a new object if applicable 97 if let Some((mut child, dead_parent)) = object 98 .as_ref() 99 .and_then(|o| o.event_child(msg.opcode).map(|c| (c, o.meta.client_destroyed))) 100 { 101 let new_id = msg 102 .args 103 .iter() 104 .flat_map(|a| if let Argument::NewId(nid) = *a { Some(nid) } else { None }) 105 .next() 106 .unwrap(); 107 let child_interface = child.interface; 108 // if this ID belonged to a now destroyed server object, we can replace it 109 if new_id >= SERVER_ID_LIMIT 110 && map.with(new_id, |obj| obj.meta.client_destroyed).unwrap_or(false) 111 { 112 map.remove(new_id) 113 } 114 // if the parent object is already destroyed, the user will never see this 115 // object, so we set it as client_destroyed to ignore all future messages to it 116 if dead_parent { 117 child.meta.client_destroyed = true; 118 } 119 if let Err(()) = map.insert_at(new_id, child) { 120 // abort parsing, this is an unrecoverable error 121 *last_error = Some(Error::Protocol(ProtocolError { 122 code: 0, 123 object_id: 0, 124 object_interface: "", 125 message: format!( 126 "Protocol error: server tried to create \ 127 an object \"{}\" with invalid id \"{}\".", 128 child_interface, new_id 129 ), 130 })); 131 return false; 132 } 133 } else { 134 // debug assert: if this opcode does not define a child, then there should be no 135 // NewId argument 136 debug_assert!(!msg.args.iter().any(|a| a.get_type() == ArgumentType::NewId)); 137 } 138 139 // send the message to the appropriate pending queue 140 match object { 141 Some(Object { meta: ObjectMeta { client_destroyed: true, .. }, .. }) | None => { 142 // this is a message sent to a destroyed object 143 // to avoid dying because of races, we just consume it into void 144 // closing any associated FDs 145 for a in msg.args { 146 if let Argument::Fd(fd) = a { 147 let _ = ::nix::unistd::close(fd); 148 } 149 } 150 } 151 Some(obj) => { 152 obj.meta.buffer.lock().unwrap().push_back(msg); 153 } 154 }; 155 156 // continue parsing 157 true 158 }, 159 ); 160 161 if let Some(ref e) = *last_error { 162 // a protocol error was generated, don't lose it, it is the source of any subsequent error 163 return Err(e.clone()); 164 } 165 166 match ret { 167 Ok(Ok(n)) => Ok(n), 168 Ok(Err(e)) => { 169 *last_error = Some(Error::Parse(e.clone())); 170 Err(Error::Parse(e)) 171 } 172 // non-fatal error 173 Err(e @ ::nix::Error::Sys(::nix::errno::Errno::EAGAIN)) => Err(Error::Nix(e)), 174 // fatal errors 175 Err(e) => { 176 *last_error = Some(Error::Nix(e)); 177 Err(Error::Nix(e)) 178 } 179 } 180 } 181 } 182