PageRenderTime 50ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/src/lib.rs

http://github.com/erickt/rust-zmq
Rust | 1350 lines | 902 code | 142 blank | 306 comment | 44 complexity | db3dfc22f733616e35bfd3cf9e0112ff MD5 | raw file
Possible License(s): Apache-2.0, MIT
  1. //! Module: zmq
  2. #![allow(trivial_numeric_casts)]
  3. use bitflags::bitflags;
  4. use libc::{c_int, c_long, c_short};
  5. use std::ffi;
  6. use std::fmt;
  7. use std::marker::PhantomData;
  8. use std::os::raw::c_void;
  9. #[cfg(unix)]
  10. use std::os::unix::io::{AsRawFd, RawFd as UnixRawFd};
  11. #[cfg(windows)]
  12. use std::os::windows::io::{AsRawSocket, RawSocket};
  13. use std::result;
  14. use std::string::FromUtf8Error;
  15. use std::sync::Arc;
  16. use std::{mem, ptr, str};
  17. use zmq_sys::{errno, RawFd};
  18. macro_rules! zmq_try {
  19. ($($tt:tt)*) => {{
  20. let rc = $($tt)*;
  21. if rc == -1 {
  22. return Err(crate::errno_to_error());
  23. }
  24. rc
  25. }}
  26. }
  27. mod message;
  28. mod sockopt;
  29. use crate::message::msg_ptr;
  30. pub use crate::message::Message;
  31. pub use crate::SocketType::*;
  32. /// `zmq`-specific Result type.
  33. pub type Result<T> = result::Result<T, Error>;
  34. /// Socket types
  35. #[allow(non_camel_case_types)]
  36. #[derive(Clone, Copy, Debug, PartialEq)]
  37. pub enum SocketType {
  38. PAIR,
  39. PUB,
  40. SUB,
  41. REQ,
  42. REP,
  43. DEALER,
  44. ROUTER,
  45. PULL,
  46. PUSH,
  47. XPUB,
  48. XSUB,
  49. STREAM,
  50. }
  51. impl SocketType {
  52. fn to_raw(self) -> c_int {
  53. let raw = match self {
  54. PAIR => zmq_sys::ZMQ_PAIR,
  55. PUB => zmq_sys::ZMQ_PUB,
  56. SUB => zmq_sys::ZMQ_SUB,
  57. REQ => zmq_sys::ZMQ_REQ,
  58. REP => zmq_sys::ZMQ_REP,
  59. DEALER => zmq_sys::ZMQ_DEALER,
  60. ROUTER => zmq_sys::ZMQ_ROUTER,
  61. PULL => zmq_sys::ZMQ_PULL,
  62. PUSH => zmq_sys::ZMQ_PUSH,
  63. XPUB => zmq_sys::ZMQ_XPUB,
  64. XSUB => zmq_sys::ZMQ_XSUB,
  65. STREAM => zmq_sys::ZMQ_STREAM,
  66. };
  67. raw as c_int
  68. }
  69. fn from_raw(raw: c_int) -> SocketType {
  70. match raw as u32 {
  71. zmq_sys::ZMQ_PAIR => PAIR,
  72. zmq_sys::ZMQ_PUB => PUB,
  73. zmq_sys::ZMQ_SUB => SUB,
  74. zmq_sys::ZMQ_REQ => REQ,
  75. zmq_sys::ZMQ_REP => REP,
  76. zmq_sys::ZMQ_DEALER => DEALER,
  77. zmq_sys::ZMQ_ROUTER => ROUTER,
  78. zmq_sys::ZMQ_PULL => PULL,
  79. zmq_sys::ZMQ_PUSH => PUSH,
  80. zmq_sys::ZMQ_XPUB => XPUB,
  81. zmq_sys::ZMQ_XSUB => XSUB,
  82. zmq_sys::ZMQ_STREAM => STREAM,
  83. _ => panic!("socket type is out of range!"),
  84. }
  85. }
  86. }
  87. /// Socket Events
  88. #[allow(non_camel_case_types)]
  89. #[derive(Clone, Copy, Debug, PartialEq)]
  90. pub enum SocketEvent {
  91. // TODO: This should become a proper enum, including the data.
  92. CONNECTED = zmq_sys::ZMQ_EVENT_CONNECTED as isize,
  93. CONNECT_DELAYED = zmq_sys::ZMQ_EVENT_CONNECT_DELAYED as isize,
  94. CONNECT_RETRIED = zmq_sys::ZMQ_EVENT_CONNECT_RETRIED as isize,
  95. LISTENING = zmq_sys::ZMQ_EVENT_LISTENING as isize,
  96. BIND_FAILED = zmq_sys::ZMQ_EVENT_BIND_FAILED as isize,
  97. ACCEPTED = zmq_sys::ZMQ_EVENT_ACCEPTED as isize,
  98. ACCEPT_FAILED = zmq_sys::ZMQ_EVENT_ACCEPT_FAILED as isize,
  99. CLOSED = zmq_sys::ZMQ_EVENT_CLOSED as isize,
  100. CLOSE_FAILED = zmq_sys::ZMQ_EVENT_CLOSE_FAILED as isize,
  101. DISCONNECTED = zmq_sys::ZMQ_EVENT_DISCONNECTED as isize,
  102. MONITOR_STOPPED = zmq_sys::ZMQ_EVENT_MONITOR_STOPPED as isize,
  103. HANDSHAKE_FAILED_NO_DETAIL = zmq_sys::ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL as isize,
  104. HANDSHAKE_SUCCEEDED = zmq_sys::ZMQ_EVENT_HANDSHAKE_SUCCEEDED as isize,
  105. HANDSHAKE_FAILED_PROTOCOL = zmq_sys::ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL as isize,
  106. HANDSHAKE_FAILED_AUTH = zmq_sys::ZMQ_EVENT_HANDSHAKE_FAILED_AUTH as isize,
  107. ALL = zmq_sys::ZMQ_EVENT_ALL as isize,
  108. }
  109. impl SocketEvent {
  110. pub fn to_raw(self) -> u16 {
  111. self as u16
  112. }
  113. // TODO: this should not need to be public
  114. pub fn from_raw(raw: u16) -> SocketEvent {
  115. use SocketEvent::*;
  116. match u32::from(raw) {
  117. zmq_sys::ZMQ_EVENT_CONNECTED => CONNECTED,
  118. zmq_sys::ZMQ_EVENT_CONNECT_DELAYED => CONNECT_DELAYED,
  119. zmq_sys::ZMQ_EVENT_CONNECT_RETRIED => CONNECT_RETRIED,
  120. zmq_sys::ZMQ_EVENT_LISTENING => LISTENING,
  121. zmq_sys::ZMQ_EVENT_BIND_FAILED => BIND_FAILED,
  122. zmq_sys::ZMQ_EVENT_ACCEPTED => ACCEPTED,
  123. zmq_sys::ZMQ_EVENT_ACCEPT_FAILED => ACCEPT_FAILED,
  124. zmq_sys::ZMQ_EVENT_CLOSED => CLOSED,
  125. zmq_sys::ZMQ_EVENT_CLOSE_FAILED => CLOSE_FAILED,
  126. zmq_sys::ZMQ_EVENT_DISCONNECTED => DISCONNECTED,
  127. zmq_sys::ZMQ_EVENT_MONITOR_STOPPED => MONITOR_STOPPED,
  128. zmq_sys::ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL => HANDSHAKE_FAILED_NO_DETAIL,
  129. zmq_sys::ZMQ_EVENT_HANDSHAKE_SUCCEEDED => HANDSHAKE_SUCCEEDED,
  130. zmq_sys::ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL => HANDSHAKE_FAILED_PROTOCOL,
  131. zmq_sys::ZMQ_EVENT_HANDSHAKE_FAILED_AUTH => HANDSHAKE_FAILED_AUTH,
  132. zmq_sys::ZMQ_EVENT_ALL => ALL,
  133. x => panic!("unknown event type {}", x),
  134. }
  135. }
  136. }
  137. /// Flag for socket `send` methods that specifies non-blocking mode.
  138. pub static DONTWAIT: i32 = zmq_sys::ZMQ_DONTWAIT as i32;
  139. /// Flag for socket `send` methods that specifies that more frames of a
  140. /// multipart message will follow.
  141. pub static SNDMORE: i32 = zmq_sys::ZMQ_SNDMORE as i32;
  142. /// Security Mechanism
  143. #[allow(non_camel_case_types)]
  144. #[derive(Clone, Copy, Debug, PartialEq)]
  145. pub enum Mechanism {
  146. // TODO: Fix the naming
  147. ZMQ_NULL,
  148. ZMQ_PLAIN,
  149. ZMQ_CURVE,
  150. ZMQ_GSSAPI,
  151. }
  152. /// An error returned by a 0MQ API function.
  153. #[derive(Clone, Copy, Eq, PartialEq)]
  154. pub enum Error {
  155. EACCES,
  156. EADDRINUSE,
  157. EAGAIN,
  158. EBUSY,
  159. ECONNREFUSED,
  160. EFAULT,
  161. EINTR,
  162. EHOSTUNREACH,
  163. EINPROGRESS,
  164. EINVAL,
  165. EMFILE,
  166. EMSGSIZE,
  167. ENAMETOOLONG,
  168. ENODEV,
  169. ENOENT,
  170. ENOMEM,
  171. ENOTCONN,
  172. ENOTSOCK,
  173. EPROTO,
  174. EPROTONOSUPPORT,
  175. ENOTSUP,
  176. ENOBUFS,
  177. ENETDOWN,
  178. EADDRNOTAVAIL,
  179. // native zmq error codes
  180. EFSM,
  181. ENOCOMPATPROTO,
  182. ETERM,
  183. EMTHREAD,
  184. }
  185. impl Error {
  186. pub fn to_raw(self) -> i32 {
  187. match self {
  188. Error::EACCES => errno::EACCES,
  189. Error::EADDRINUSE => errno::EADDRINUSE,
  190. Error::EAGAIN => errno::EAGAIN,
  191. Error::EBUSY => errno::EBUSY,
  192. Error::ECONNREFUSED => errno::ECONNREFUSED,
  193. Error::EFAULT => errno::EFAULT,
  194. Error::EINTR => errno::EINTR,
  195. Error::EHOSTUNREACH => errno::EHOSTUNREACH,
  196. Error::EINPROGRESS => errno::EINPROGRESS,
  197. Error::EINVAL => errno::EINVAL,
  198. Error::EMFILE => errno::EMFILE,
  199. Error::EMSGSIZE => errno::EMSGSIZE,
  200. Error::ENAMETOOLONG => errno::ENAMETOOLONG,
  201. Error::ENODEV => errno::ENODEV,
  202. Error::ENOENT => errno::ENOENT,
  203. Error::ENOMEM => errno::ENOMEM,
  204. Error::ENOTCONN => errno::ENOTCONN,
  205. Error::ENOTSOCK => errno::ENOTSOCK,
  206. Error::EPROTO => errno::EPROTO,
  207. Error::EPROTONOSUPPORT => errno::EPROTONOSUPPORT,
  208. Error::ENOTSUP => errno::ENOTSUP,
  209. Error::ENOBUFS => errno::ENOBUFS,
  210. Error::ENETDOWN => errno::ENETDOWN,
  211. Error::EADDRNOTAVAIL => errno::EADDRNOTAVAIL,
  212. Error::EFSM => errno::EFSM,
  213. Error::ENOCOMPATPROTO => errno::ENOCOMPATPROTO,
  214. Error::ETERM => errno::ETERM,
  215. Error::EMTHREAD => errno::EMTHREAD,
  216. }
  217. }
  218. pub fn from_raw(raw: i32) -> Error {
  219. match raw {
  220. errno::EACCES => Error::EACCES,
  221. errno::EADDRINUSE => Error::EADDRINUSE,
  222. errno::EAGAIN => Error::EAGAIN,
  223. errno::EBUSY => Error::EBUSY,
  224. errno::ECONNREFUSED => Error::ECONNREFUSED,
  225. errno::EFAULT => Error::EFAULT,
  226. errno::EHOSTUNREACH => Error::EHOSTUNREACH,
  227. errno::EINPROGRESS => Error::EINPROGRESS,
  228. errno::EINVAL => Error::EINVAL,
  229. errno::EMFILE => Error::EMFILE,
  230. errno::EMSGSIZE => Error::EMSGSIZE,
  231. errno::ENAMETOOLONG => Error::ENAMETOOLONG,
  232. errno::ENODEV => Error::ENODEV,
  233. errno::ENOENT => Error::ENOENT,
  234. errno::ENOMEM => Error::ENOMEM,
  235. errno::ENOTCONN => Error::ENOTCONN,
  236. errno::ENOTSOCK => Error::ENOTSOCK,
  237. errno::EPROTO => Error::EPROTO,
  238. errno::EPROTONOSUPPORT => Error::EPROTONOSUPPORT,
  239. errno::ENOTSUP => Error::ENOTSUP,
  240. errno::ENOBUFS => Error::ENOBUFS,
  241. errno::ENETDOWN => Error::ENETDOWN,
  242. errno::EADDRNOTAVAIL => Error::EADDRNOTAVAIL,
  243. errno::EINTR => Error::EINTR,
  244. // These may turn up on platforms that don't support these
  245. // errno codes natively (Windows)
  246. errno::ENOTSUP_ALT => Error::ENOTSUP,
  247. errno::EPROTONOSUPPORT_ALT => Error::EPROTONOSUPPORT,
  248. errno::ENOBUFS_ALT => Error::ENOBUFS,
  249. errno::ENETDOWN_ALT => Error::ENETDOWN,
  250. errno::EADDRINUSE_ALT => Error::EADDRINUSE,
  251. errno::EADDRNOTAVAIL_ALT => Error::EADDRNOTAVAIL,
  252. errno::ECONNREFUSED_ALT => Error::ECONNREFUSED,
  253. errno::EINPROGRESS_ALT => Error::EINPROGRESS,
  254. errno::ENOTSOCK_ALT => Error::ENOTSOCK,
  255. errno::EMSGSIZE_ALT => Error::EMSGSIZE,
  256. // TODO: these are present in `zmq-sys`, but not handled, as that
  257. // would break backwards-compatibility for the `Error` enum.
  258. // errno::EAFNOSUPPORT_ALT => Error::EAFNOSUPPORT,
  259. // errno::ENETUNREACH_ALT => Error::ENETUNREACH,
  260. // errno::ECONNABORTED_ALT => Error::ECONNABORTED,
  261. // errno::ECONNRESET_ALT => Error::ECONNRESET,
  262. // errno::ENOTCONN_ALT => Error::ENOTCONN,
  263. // errno::ETIMEDOUT_ALT => Error::ETIMEDOUT,
  264. // errno::EHOSTUNREACH_ALT => Error::EHOSTUNREACH,
  265. // errno::ENETRESET_ALT => Error::ENETRESET,
  266. // 0MQ native error codes
  267. errno::EFSM => Error::EFSM,
  268. errno::ENOCOMPATPROTO => Error::ENOCOMPATPROTO,
  269. errno::ETERM => Error::ETERM,
  270. errno::EMTHREAD => Error::EMTHREAD,
  271. x => unsafe {
  272. let s = zmq_sys::zmq_strerror(x);
  273. panic!(
  274. "unknown error [{}]: {}",
  275. x,
  276. str::from_utf8(ffi::CStr::from_ptr(s).to_bytes()).unwrap()
  277. )
  278. },
  279. }
  280. }
  281. /// Returns the error message provided by 0MQ.
  282. pub fn message(self) -> &'static str {
  283. unsafe {
  284. let s = zmq_sys::zmq_strerror(self.to_raw());
  285. let v: &'static [u8] = mem::transmute(ffi::CStr::from_ptr(s).to_bytes());
  286. str::from_utf8(v).unwrap()
  287. }
  288. }
  289. }
  290. impl std::error::Error for Error {
  291. fn description(&self) -> &str {
  292. self.message()
  293. }
  294. }
  295. impl std::fmt::Display for Error {
  296. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  297. write!(f, "{}", self.message())
  298. }
  299. }
  300. impl fmt::Debug for Error {
  301. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  302. // FIXME: An unquoted string is not a good `Debug` output.
  303. write!(f, "{}", self.message())
  304. }
  305. }
  306. impl From<Error> for std::io::Error {
  307. fn from(error: Error) -> Self {
  308. use std::io::ErrorKind;
  309. let kind = match error {
  310. Error::ENOENT => ErrorKind::NotFound,
  311. Error::EACCES => ErrorKind::PermissionDenied,
  312. Error::ECONNREFUSED => ErrorKind::ConnectionRefused,
  313. Error::ENOTCONN => ErrorKind::NotConnected,
  314. Error::EADDRINUSE => ErrorKind::AddrInUse,
  315. Error::EADDRNOTAVAIL => ErrorKind::AddrNotAvailable,
  316. Error::EAGAIN => ErrorKind::WouldBlock,
  317. Error::EINVAL => ErrorKind::InvalidInput,
  318. Error::EINTR => ErrorKind::Interrupted,
  319. _ => ErrorKind::Other,
  320. };
  321. // TODO: With rust 1.14 and up there is an optimization
  322. // opportunity using `std::io::Error: From<ErrorKind>` when
  323. // `kind != Other`. We should do that once 1.14 has been
  324. // stable for a bit.
  325. std::io::Error::new(kind, error)
  326. }
  327. }
  328. fn errno_to_error() -> Error {
  329. Error::from_raw(unsafe { zmq_sys::zmq_errno() })
  330. }
  331. /// Return the current zeromq version, as `(major, minor, patch)`.
  332. pub fn version() -> (i32, i32, i32) {
  333. let mut major = 0;
  334. let mut minor = 0;
  335. let mut patch = 0;
  336. unsafe {
  337. zmq_sys::zmq_version(&mut major, &mut minor, &mut patch);
  338. }
  339. (major as i32, minor as i32, patch as i32)
  340. }
  341. struct RawContext {
  342. ctx: *mut c_void,
  343. }
  344. impl RawContext {
  345. fn term(&self) -> Result<()> {
  346. zmq_try!(unsafe { zmq_sys::zmq_ctx_term(self.ctx) });
  347. Ok(())
  348. }
  349. }
  350. unsafe impl Send for RawContext {}
  351. unsafe impl Sync for RawContext {}
  352. impl Drop for RawContext {
  353. fn drop(&mut self) {
  354. let mut e = self.term();
  355. while e == Err(Error::EINTR) {
  356. e = self.term();
  357. }
  358. }
  359. }
  360. /// Handle for a 0MQ context, used to create sockets.
  361. ///
  362. /// It is thread safe, and can be safely cloned and shared. Each clone
  363. /// references the same underlying C context. Internally, an `Arc` is
  364. /// used to implement this in a threadsafe way.
  365. ///
  366. /// Also note that this binding deviates from the C API in that each
  367. /// socket created from a context initially owns a clone of that
  368. /// context. This reference is kept to avoid a potential deadlock
  369. /// situation that would otherwise occur:
  370. ///
  371. /// Destroying the underlying C context is an operation which
  372. /// blocks waiting for all sockets created from it to be closed
  373. /// first. If one of the sockets belongs to thread issuing the
  374. /// destroy operation, you have established a deadlock.
  375. ///
  376. /// You can still deadlock yourself (or intentionally close sockets in
  377. /// other threads, see `zmq_ctx_destroy`(3)) by explicitly calling
  378. /// `Context::destroy`.
  379. ///
  380. #[derive(Clone)]
  381. pub struct Context {
  382. raw: Arc<RawContext>,
  383. }
  384. impl Context {
  385. /// Create a new reference-counted context handle.
  386. pub fn new() -> Context {
  387. Context {
  388. raw: Arc::new(RawContext {
  389. ctx: unsafe { zmq_sys::zmq_ctx_new() },
  390. }),
  391. }
  392. }
  393. /// Get the size of the ØMQ thread pool to handle I/O operations.
  394. pub fn get_io_threads(&self) -> Result<i32> {
  395. let rc =
  396. zmq_try!(unsafe { zmq_sys::zmq_ctx_get(self.raw.ctx, zmq_sys::ZMQ_IO_THREADS as _) });
  397. Ok(rc as i32)
  398. }
  399. /// Set the size of the ØMQ thread pool to handle I/O operations.
  400. pub fn set_io_threads(&self, value: i32) -> Result<()> {
  401. zmq_try!(unsafe {
  402. zmq_sys::zmq_ctx_set(self.raw.ctx, zmq_sys::ZMQ_IO_THREADS as _, value as i32)
  403. });
  404. Ok(())
  405. }
  406. /// Create a new socket.
  407. ///
  408. /// Note that the returned socket keeps a an `Arc` reference to
  409. /// the context it was created from, and will keep that context
  410. /// from being dropped while being live.
  411. pub fn socket(&self, socket_type: SocketType) -> Result<Socket> {
  412. let sock = unsafe { zmq_sys::zmq_socket(self.raw.ctx, socket_type.to_raw()) };
  413. if sock.is_null() {
  414. return Err(errno_to_error());
  415. }
  416. Ok(Socket {
  417. sock,
  418. context: Some(self.clone()),
  419. owned: true,
  420. })
  421. }
  422. /// Try to destroy the context. This is different than the destructor; the
  423. /// destructor will loop when zmq_ctx_term returns EINTR.
  424. pub fn destroy(&mut self) -> Result<()> {
  425. self.raw.term()
  426. }
  427. }
  428. impl Default for Context {
  429. fn default() -> Self {
  430. Context::new()
  431. }
  432. }
  433. /// A socket, the central object in 0MQ.
  434. pub struct Socket {
  435. sock: *mut c_void,
  436. // The `context` field is never accessed, but implicitly does
  437. // reference counting via the `Drop` trait.
  438. #[allow(dead_code)]
  439. context: Option<Context>,
  440. owned: bool,
  441. }
  442. unsafe impl Send for Socket {}
  443. impl Drop for Socket {
  444. fn drop(&mut self) {
  445. if self.owned && unsafe { zmq_sys::zmq_close(self.sock) } == -1 {
  446. panic!(errno_to_error());
  447. }
  448. }
  449. }
  450. #[cfg(unix)]
  451. impl AsRawFd for Socket {
  452. fn as_raw_fd(&self) -> UnixRawFd {
  453. self.get_fd().unwrap() as UnixRawFd
  454. }
  455. }
  456. #[cfg(windows)]
  457. impl AsRawSocket for Socket {
  458. fn as_raw_socket(&self) -> RawSocket {
  459. self.get_fd().unwrap() as RawSocket
  460. }
  461. }
  462. macro_rules! sockopt_getter {
  463. ( $(#[$meta:meta])*
  464. pub $getter:ident => $constant_name:ident as $ty:ty
  465. ) => {
  466. $(#[$meta])*
  467. pub fn $getter(&self) -> Result<$ty> {
  468. <$ty as sockopt::Getter>::get(self.sock, zmq_sys::$constant_name as c_int)
  469. }
  470. };
  471. }
  472. macro_rules! sockopt_setter {
  473. ( $(#[$meta:meta])*
  474. pub $setter:ident => $constant_name:ident as $ty:ty
  475. ) => {
  476. $(#[$meta])*
  477. pub fn $setter(&self, value: $ty) -> Result<()> {
  478. <$ty as sockopt::Setter>::set(self.sock, zmq_sys::$constant_name as c_int, value)
  479. }
  480. };
  481. }
  482. macro_rules! sockopt_seq {
  483. ( META { $($meta:meta)* }, ) => ();
  484. ( META { $($meta:meta)* }, $(#[$item_meta:meta])* (_, $setter:ident) => $constant_name:ident as $ty:ty,
  485. $($rest:tt)*
  486. ) => {
  487. sockopt_setter! {
  488. $(#[$meta])* $(#[$item_meta])*
  489. pub $setter => $constant_name as $ty
  490. }
  491. sockopt_seq!(META { $($meta)* }, $($rest)*);
  492. };
  493. ( META { $($meta:meta)* }, $(#[$item_meta:meta])* ($getter:ident) => $constant_name:ident as $ty:ty,
  494. $($rest:tt)*
  495. ) => {
  496. sockopt_getter! {
  497. $(#[$meta])* $(#[$item_meta])*
  498. pub $getter => $constant_name as $ty
  499. }
  500. sockopt_seq!(META { $($meta)* }, $($rest)*);
  501. };
  502. ( META { $($meta:meta)* }, $(#[$item_meta:meta])* ($getter:ident, $setter:ident) => $constant_name:ident as $ty:ty,
  503. $($rest:tt)*
  504. ) => {
  505. sockopt_getter! {
  506. $(#[$meta])* $(#[$item_meta])*
  507. pub $getter => $constant_name as $ty
  508. }
  509. sockopt_setter! {
  510. $(#[$meta])* $(#[$item_meta])*
  511. pub $setter => $constant_name as $ty
  512. }
  513. sockopt_seq!(META { $($meta)* }, $($rest)*);
  514. };
  515. }
  516. macro_rules! sockopts {
  517. () => ();
  518. ( $($rest:tt)* ) => {
  519. sockopt_seq!(META {}, $($rest)*);
  520. };
  521. }
  522. /// Sendable over a `Socket`.
  523. ///
  524. /// A type can implement this trait there is an especially efficient
  525. /// implementation for sending it as a message over a zmq socket.
  526. ///
  527. /// If the type needs to be directly passed to `Socket::send()`, but
  528. /// the overhead of allocating a `Message` instance is not an issue,
  529. /// `Into<Message>` should be implemented instead.
  530. ///
  531. pub trait Sendable {
  532. fn send(self, socket: &Socket, flags: i32) -> Result<()>;
  533. }
  534. impl<T> Sendable for T
  535. where
  536. T: Into<Message>,
  537. {
  538. fn send(self, socket: &Socket, flags: i32) -> Result<()> {
  539. let mut msg = self.into();
  540. zmq_try!(unsafe { zmq_sys::zmq_msg_send(msg_ptr(&mut msg), socket.sock, flags as c_int) });
  541. Ok(())
  542. }
  543. }
  544. impl Socket {
  545. /// Consume the Socket and return the raw socket pointer.
  546. ///
  547. /// Failure to close the raw socket manually or call `from_raw`
  548. /// will lead to a memory leak. Also note that is function
  549. /// relinquishes the reference on the context is was created from.
  550. pub fn into_raw(mut self) -> *mut c_void {
  551. self.owned = false;
  552. self.sock
  553. }
  554. /// Create a Socket from a raw socket pointer.
  555. ///
  556. /// The Socket assumes ownership of the pointer and will close the socket
  557. /// when it is dropped. The returned socket will not reference any context.
  558. ///
  559. /// # Safety
  560. ///
  561. /// The socket pointer must be a socket created via the `into_raw`
  562. /// method. The ownership of the socket is transferred the returned Socket,
  563. /// so any other pointers to the same socket may only be used until it is
  564. /// dropped.
  565. pub unsafe fn from_raw(sock: *mut c_void) -> Socket {
  566. Socket {
  567. sock,
  568. context: None,
  569. owned: true,
  570. }
  571. }
  572. /// Return the inner pointer to this Socket.
  573. ///
  574. /// **WARNING**:
  575. /// It is your responsibility to make sure that the underlying
  576. /// memory is not freed too early.
  577. pub fn as_mut_ptr(&mut self) -> *mut c_void {
  578. self.sock
  579. }
  580. /// Accept connections on a socket.
  581. pub fn bind(&self, endpoint: &str) -> Result<()> {
  582. let c_str = ffi::CString::new(endpoint.as_bytes()).unwrap();
  583. zmq_try!(unsafe { zmq_sys::zmq_bind(self.sock, c_str.as_ptr()) });
  584. Ok(())
  585. }
  586. /// Stop accepting connections on a socket
  587. pub fn unbind(&self, endpoint: &str) -> Result<()> {
  588. let c_str = ffi::CString::new(endpoint.as_bytes()).unwrap();
  589. zmq_try!(unsafe { zmq_sys::zmq_unbind(self.sock, c_str.as_ptr()) });
  590. Ok(())
  591. }
  592. /// Connect a socket.
  593. pub fn connect(&self, endpoint: &str) -> Result<()> {
  594. let c_str = ffi::CString::new(endpoint.as_bytes()).unwrap();
  595. zmq_try!(unsafe { zmq_sys::zmq_connect(self.sock, c_str.as_ptr()) });
  596. Ok(())
  597. }
  598. /// Disconnect a previously connected socket
  599. pub fn disconnect(&self, endpoint: &str) -> Result<()> {
  600. let c_str = ffi::CString::new(endpoint.as_bytes()).unwrap();
  601. zmq_try!(unsafe { zmq_sys::zmq_disconnect(self.sock, c_str.as_ptr()) });
  602. Ok(())
  603. }
  604. /// Configure the socket for monitoring
  605. pub fn monitor(&self, monitor_endpoint: &str, events: i32) -> Result<()> {
  606. let c_str = ffi::CString::new(monitor_endpoint.as_bytes()).unwrap();
  607. zmq_try!(unsafe {
  608. zmq_sys::zmq_socket_monitor(self.sock, c_str.as_ptr(), events as c_int)
  609. });
  610. Ok(())
  611. }
  612. /// Send a message.
  613. ///
  614. /// Due to the provided `From` implementations, this works for
  615. /// `&[u8]`, `Vec<u8>` and `&str` `Message` itself.
  616. pub fn send<T>(&self, data: T, flags: i32) -> Result<()>
  617. where
  618. T: Sendable,
  619. {
  620. data.send(self, flags)
  621. }
  622. /// Send a `Message` message.
  623. #[deprecated(since = "0.9.0", note = "Use `send` instead")]
  624. pub fn send_msg(&self, msg: Message, flags: i32) -> Result<()> {
  625. self.send(msg, flags)
  626. }
  627. #[deprecated(since = "0.9.0", note = "Use `send` instead")]
  628. pub fn send_str(&self, data: &str, flags: i32) -> Result<()> {
  629. self.send(data, flags)
  630. }
  631. pub fn send_multipart<I, T>(&self, iter: I, flags: i32) -> Result<()>
  632. where
  633. I: IntoIterator<Item = T>,
  634. T: Into<Message>,
  635. {
  636. let mut last_part: Option<T> = None;
  637. for part in iter {
  638. let maybe_last = last_part.take();
  639. if let Some(last) = maybe_last {
  640. self.send(last.into(), flags | SNDMORE)?;
  641. }
  642. last_part = Some(part);
  643. }
  644. if let Some(last) = last_part {
  645. self.send(last.into(), flags)
  646. } else {
  647. Ok(())
  648. }
  649. }
  650. /// Receive a message into a `Message`. The length passed to zmq_msg_recv
  651. /// is the length of the buffer.
  652. pub fn recv(&self, msg: &mut Message, flags: i32) -> Result<()> {
  653. zmq_try!(unsafe { zmq_sys::zmq_msg_recv(msg_ptr(msg), self.sock, flags as c_int) });
  654. Ok(())
  655. }
  656. /// Receive bytes into a slice. The length passed to `zmq_recv` is the length of the slice. The
  657. /// return value is the number of bytes in the message, which may be larger than the length of
  658. /// the slice, indicating truncation.
  659. pub fn recv_into(&self, bytes: &mut [u8], flags: i32) -> Result<usize> {
  660. let bytes_ptr = bytes.as_mut_ptr() as *mut c_void;
  661. let rc = zmq_try!(unsafe {
  662. zmq_sys::zmq_recv(self.sock, bytes_ptr, bytes.len(), flags as c_int)
  663. });
  664. Ok(rc as usize)
  665. }
  666. /// Receive a message into a fresh `Message`.
  667. pub fn recv_msg(&self, flags: i32) -> Result<Message> {
  668. let mut msg = Message::new();
  669. self.recv(&mut msg, flags).map(|_| msg)
  670. }
  671. /// Receive a message as a byte vector.
  672. pub fn recv_bytes(&self, flags: i32) -> Result<Vec<u8>> {
  673. self.recv_msg(flags).map(|msg| msg.to_vec())
  674. }
  675. /// Receive a `String` from the socket.
  676. ///
  677. /// If the received message is not valid UTF-8, it is returned as the original
  678. /// Vec in the `Err` part of the inner result.
  679. pub fn recv_string(&self, flags: i32) -> Result<result::Result<String, Vec<u8>>> {
  680. self.recv_bytes(flags)
  681. .map(|bytes| String::from_utf8(bytes).map_err(FromUtf8Error::into_bytes))
  682. }
  683. /// Receive a multipart message from the socket.
  684. ///
  685. /// Note that this will allocate a new vector for each message part; for
  686. /// many applications it will be possible to process the different parts
  687. /// sequentially and reuse allocations that way.
  688. pub fn recv_multipart(&self, flags: i32) -> Result<Vec<Vec<u8>>> {
  689. let mut parts: Vec<Vec<u8>> = vec![];
  690. loop {
  691. let part = self.recv_bytes(flags)?;
  692. parts.push(part);
  693. let more_parts = self.get_rcvmore()?;
  694. if !more_parts {
  695. break;
  696. }
  697. }
  698. Ok(parts)
  699. }
  700. sockopts! {
  701. /// Accessor for the `ZMQ_IPV6` option.
  702. (is_ipv6, set_ipv6) => ZMQ_IPV6 as bool,
  703. /// Accessor for the `ZMQ_IMMEDIATE` option.
  704. (is_immediate, set_immediate) => ZMQ_IMMEDIATE as bool,
  705. /// Accessor for the `ZMQ_PLAIN_SERVER` option.
  706. (is_plain_server, set_plain_server) => ZMQ_PLAIN_SERVER as bool,
  707. /// Accessor for the `ZMQ_CONFLATE` option.
  708. (is_conflate, set_conflate) => ZMQ_CONFLATE as bool,
  709. (is_probe_router, set_probe_router) => ZMQ_PROBE_ROUTER as bool,
  710. (is_router_mandatory, set_router_mandatory) => ZMQ_ROUTER_MANDATORY as bool,
  711. (is_router_handover, set_router_handover) => ZMQ_ROUTER_HANDOVER as bool,
  712. (is_curve_server, set_curve_server) => ZMQ_CURVE_SERVER as bool,
  713. (is_gssapi_server, set_gssapi_server) => ZMQ_GSSAPI_SERVER as bool,
  714. (is_gssapi_plaintext, set_gssapi_plaintext) => ZMQ_GSSAPI_PLAINTEXT as bool,
  715. (_, set_req_relaxed) => ZMQ_REQ_RELAXED as bool,
  716. (_, set_req_correlate) => ZMQ_REQ_CORRELATE as bool,
  717. }
  718. /// Return the type of this socket.
  719. pub fn get_socket_type(&self) -> Result<SocketType> {
  720. sockopt::get(self.sock, zmq_sys::ZMQ_TYPE as c_int).map(SocketType::from_raw)
  721. }
  722. /// Return true if there are more frames of a multipart message to receive.
  723. pub fn get_rcvmore(&self) -> Result<bool> {
  724. sockopt::get(self.sock, zmq_sys::ZMQ_RCVMORE as c_int).map(|o: i64| o == 1i64)
  725. }
  726. sockopts! {
  727. (get_maxmsgsize, set_maxmsgsize) => ZMQ_MAXMSGSIZE as i64,
  728. (get_sndhwm, set_sndhwm) => ZMQ_SNDHWM as i32,
  729. (get_rcvhwm, set_rcvhwm) => ZMQ_RCVHWM as i32,
  730. (get_affinity, set_affinity) => ZMQ_AFFINITY as u64,
  731. (get_rate, set_rate) => ZMQ_RATE as i32,
  732. (get_recovery_ivl, set_recovery_ivl) => ZMQ_RECOVERY_IVL as i32,
  733. (get_sndbuf, set_sndbuf) => ZMQ_SNDBUF as i32,
  734. (get_rcvbuf, set_rcvbuf) => ZMQ_RCVBUF as i32,
  735. (get_tos, set_tos) => ZMQ_TOS as i32,
  736. (get_linger, set_linger) => ZMQ_LINGER as i32,
  737. (get_reconnect_ivl, set_reconnect_ivl) => ZMQ_RECONNECT_IVL as i32,
  738. (get_reconnect_ivl_max, set_reconnect_ivl_max) => ZMQ_RECONNECT_IVL_MAX as i32,
  739. (get_backlog, set_backlog) => ZMQ_BACKLOG as i32,
  740. /// Get the event notification file descriptor.
  741. ///
  742. /// Getter for the `ZMQ_FD` option. Note that the returned
  743. /// type is platform-specific; it aliases either
  744. /// `std::os::unix::io::RawFd` and or
  745. /// `std::os::windows::io::RawSocket`.
  746. ///
  747. /// Note that the returned file desciptor has special
  748. /// semantics: it should only used with an operating system
  749. /// facility like Unix `poll()` to check its readability.
  750. (get_fd) => ZMQ_FD as RawFd,
  751. /// Get the currently pending events.
  752. ///
  753. /// Note that the result of this function can also change due
  754. /// to receiving or sending a message on the socket, without
  755. /// the signalling FD (see `Socket::get_fd()`).
  756. ///
  757. /// # Examples
  758. ///
  759. /// ```
  760. /// use zmq;
  761. /// let ctx = zmq::Context::new();
  762. /// let socket = ctx.socket(zmq::REQ).unwrap();
  763. /// let events = socket.get_events().unwrap();
  764. /// if events.contains(zmq::POLLIN) {
  765. /// println!("socket readable")
  766. /// }
  767. /// drop(socket);
  768. /// ```
  769. ///
  770. /// # Compatibility
  771. ///
  772. /// This function currently returns the bitmask as an `i32`
  773. /// for backwards compatibility; in effect it should have been
  774. /// using the same type as `PollItem::get_revents()` all
  775. /// along.
  776. ///
  777. /// In the `0.9` series, this will be rectified.
  778. (get_events) => ZMQ_EVENTS as PollEvents,
  779. (get_multicast_hops, set_multicast_hops) => ZMQ_MULTICAST_HOPS as i32,
  780. (get_rcvtimeo, set_rcvtimeo) => ZMQ_RCVTIMEO as i32,
  781. (get_sndtimeo, set_sndtimeo) => ZMQ_SNDTIMEO as i32,
  782. (get_tcp_keepalive, set_tcp_keepalive) => ZMQ_TCP_KEEPALIVE as i32,
  783. (get_tcp_keepalive_cnt, set_tcp_keepalive_cnt) => ZMQ_TCP_KEEPALIVE_CNT as i32,
  784. (get_tcp_keepalive_idle, set_tcp_keepalive_idle) => ZMQ_TCP_KEEPALIVE_IDLE as i32,
  785. (get_tcp_keepalive_intvl, set_tcp_keepalive_intvl) => ZMQ_TCP_KEEPALIVE_INTVL as i32,
  786. (get_handshake_ivl, set_handshake_ivl) => ZMQ_HANDSHAKE_IVL as i32,
  787. // TODO: deprecate to align with ZMQ's preferred naming
  788. (_, set_identity) => ZMQ_ROUTING_ID as &[u8],
  789. (_, set_subscribe) => ZMQ_SUBSCRIBE as &[u8],
  790. (_, set_unsubscribe) => ZMQ_UNSUBSCRIBE as &[u8],
  791. (get_heartbeat_ivl, set_heartbeat_ivl) => ZMQ_HEARTBEAT_IVL as i32,
  792. (get_heartbeat_ttl, set_heartbeat_ttl) => ZMQ_HEARTBEAT_TTL as i32,
  793. (get_heartbeat_timeout, set_heartbeat_timeout) => ZMQ_HEARTBEAT_TIMEOUT as i32,
  794. (get_connect_timeout, set_connect_timeout) => ZMQ_CONNECT_TIMEOUT as i32,
  795. }
  796. // TODO: deprecate to align with ZMQ's preferred naming
  797. pub fn get_identity(&self) -> Result<Vec<u8>> {
  798. // 255 = identity max length
  799. sockopt::get_bytes(self.sock, zmq_sys::ZMQ_ROUTING_ID as c_int, 255)
  800. }
  801. pub fn get_socks_proxy(&self) -> Result<result::Result<String, Vec<u8>>> {
  802. // 255 = longest allowable domain name is 253 so this should
  803. // be a reasonable size.
  804. sockopt::get_string(self.sock, zmq_sys::ZMQ_SOCKS_PROXY as c_int, 255, true)
  805. }
  806. pub fn get_mechanism(&self) -> Result<Mechanism> {
  807. sockopt::get(self.sock, zmq_sys::ZMQ_MECHANISM as c_int).map(|mech| match mech {
  808. zmq_sys::ZMQ_NULL => Mechanism::ZMQ_NULL,
  809. zmq_sys::ZMQ_PLAIN => Mechanism::ZMQ_PLAIN,
  810. zmq_sys::ZMQ_CURVE => Mechanism::ZMQ_CURVE,
  811. zmq_sys::ZMQ_GSSAPI => Mechanism::ZMQ_GSSAPI,
  812. _ => panic!("Mechanism is out of range!"),
  813. })
  814. }
  815. pub fn get_plain_username(&self) -> Result<result::Result<String, Vec<u8>>> {
  816. // 255 = arbitrary size
  817. sockopt::get_string(self.sock, zmq_sys::ZMQ_PLAIN_USERNAME as c_int, 255, true)
  818. }
  819. pub fn get_plain_password(&self) -> Result<result::Result<String, Vec<u8>>> {
  820. // 256 = arbitrary size based on std crypto key size
  821. sockopt::get_string(self.sock, zmq_sys::ZMQ_PLAIN_PASSWORD as c_int, 256, true)
  822. }
  823. pub fn get_zap_domain(&self) -> Result<result::Result<String, Vec<u8>>> {
  824. // 255 = arbitrary size
  825. sockopt::get_string(self.sock, zmq_sys::ZMQ_ZAP_DOMAIN as c_int, 255, true)
  826. }
  827. /// Return the address of the last endpoint this socket was bound to.
  828. ///
  829. /// Note that the returned address is not guaranteed to be the
  830. /// same as the one used with `bind`, and might also not be
  831. /// directly usable with `connect`. In particular, when `bind` is
  832. /// used with the wildcard address (`"*"`), in the address
  833. /// returned, the wildcard will be expanded into the any address
  834. /// (i.e. `0.0.0.0` with IPv4).
  835. pub fn get_last_endpoint(&self) -> Result<result::Result<String, Vec<u8>>> {
  836. // 256 + 9 + 1 = maximum inproc name size (= 256) + "inproc://".len() (= 9), plus null byte
  837. sockopt::get_string(
  838. self.sock,
  839. zmq_sys::ZMQ_LAST_ENDPOINT as c_int,
  840. 256 + 9 + 1,
  841. true,
  842. )
  843. }
  844. /// Set the `ZMQ_CURVE_PUBLICKEY` option value.
  845. ///
  846. /// The key is returned as raw bytes. Use `z85_encode` on the
  847. /// resulting data to get the Z85-encoded string representation of
  848. /// the key.
  849. pub fn get_curve_publickey(&self) -> Result<Vec<u8>> {
  850. sockopt::get_bytes(self.sock, zmq_sys::ZMQ_CURVE_PUBLICKEY as c_int, 32)
  851. }
  852. /// Get the `ZMQ_CURVE_SECRETKEY` option value.
  853. ///
  854. /// The key is returned as raw bytes. Use `z85_encode` on the
  855. /// resulting data to get the Z85-encoded string representation of
  856. /// the key.
  857. pub fn get_curve_secretkey(&self) -> Result<Vec<u8>> {
  858. sockopt::get_bytes(self.sock, zmq_sys::ZMQ_CURVE_SECRETKEY as c_int, 32)
  859. }
  860. /// Get `ZMQ_CURVE_SERVERKEY` option value.
  861. ///
  862. /// Note that the key is returned as raw bytes, as a 32-byte
  863. /// vector. Use `z85_encode()` explicitly to obtain the
  864. /// Z85-encoded string variant.
  865. pub fn get_curve_serverkey(&self) -> Result<Vec<u8>> {
  866. // 41 = Z85 encoded keysize + 1 for null byte
  867. sockopt::get_bytes(self.sock, zmq_sys::ZMQ_CURVE_SERVERKEY as c_int, 32)
  868. }
  869. pub fn get_gssapi_principal(&self) -> Result<result::Result<String, Vec<u8>>> {
  870. // 260 = best guess of max length based on docs.
  871. sockopt::get_string(self.sock, zmq_sys::ZMQ_GSSAPI_PRINCIPAL as c_int, 260, true)
  872. }
  873. pub fn get_gssapi_service_principal(&self) -> Result<result::Result<String, Vec<u8>>> {
  874. // 260 = best guess of max length based on docs.
  875. sockopt::get_string(
  876. self.sock,
  877. zmq_sys::ZMQ_GSSAPI_SERVICE_PRINCIPAL as c_int,
  878. 260,
  879. true,
  880. )
  881. }
  882. sockopts! {
  883. (_, set_socks_proxy) => ZMQ_SOCKS_PROXY as Option<&str>,
  884. (_, set_plain_username) => ZMQ_PLAIN_USERNAME as Option<&str>,
  885. (_, set_plain_password) => ZMQ_PLAIN_PASSWORD as Option<&str>,
  886. (_, set_zap_domain) => ZMQ_ZAP_DOMAIN as &str,
  887. (_, set_xpub_welcome_msg) => ZMQ_XPUB_WELCOME_MSG as Option<&str>,
  888. (_, set_xpub_verbose) => ZMQ_XPUB_VERBOSE as bool,
  889. (_, set_curve_publickey) => ZMQ_CURVE_PUBLICKEY as &[u8],
  890. (_, set_curve_secretkey) => ZMQ_CURVE_SECRETKEY as &[u8],
  891. (_, set_curve_serverkey) => ZMQ_CURVE_SERVERKEY as &[u8],
  892. (_, set_gssapi_principal) => ZMQ_GSSAPI_PRINCIPAL as &str,
  893. (_, set_gssapi_service_principal) => ZMQ_GSSAPI_SERVICE_PRINCIPAL as &str,
  894. }
  895. /// Create a `PollItem` from the socket.
  896. pub fn as_poll_item(&self, events: PollEvents) -> PollItem {
  897. PollItem {
  898. socket: self.sock,
  899. fd: 0,
  900. events: events.bits(),
  901. revents: 0,
  902. marker: PhantomData,
  903. }
  904. }
  905. /// Do a call to `zmq_poll` with only this socket.
  906. ///
  907. /// The return value on success will be either zero (no event) or one (some
  908. /// event was signaled).
  909. pub fn poll(&self, events: PollEvents, timeout_ms: i64) -> Result<i32> {
  910. poll(&mut [self.as_poll_item(events)], timeout_ms)
  911. }
  912. }
  913. // TODO: Duplicating the values inside the bitflags struct and on the top level
  914. // is unfortunate.
  915. bitflags! {
  916. /// Type representing pending socket events.
  917. pub struct PollEvents: i16 {
  918. /// For `poll()`, specifies to signal when a message/some data
  919. /// can be read from a socket.
  920. const POLLIN = zmq_sys::ZMQ_POLLIN as i16;
  921. /// For `poll()`, specifies to signal when a message/some data
  922. /// can be written to a socket.
  923. const POLLOUT = zmq_sys::ZMQ_POLLOUT as i16;
  924. /// For `poll()`, specifies to signal when an error condition
  925. /// is present on a socket. This only applies to non-0MQ
  926. /// sockets.
  927. const POLLERR = zmq_sys::ZMQ_POLLERR as i16;
  928. }
  929. }
  930. /// For `poll()`, specifies to signal when a message/some data can be
  931. /// read from a socket.
  932. pub const POLLIN: PollEvents = PollEvents::POLLIN;
  933. /// For `poll()`, specifies to signal when a message/some data can be
  934. /// written to a socket.
  935. pub const POLLOUT: PollEvents = PollEvents::POLLOUT;
  936. /// For `poll()`, specifies to signal when an error condition is
  937. /// present on a socket. This only applies to non-0MQ sockets.
  938. pub const POLLERR: PollEvents = PollEvents::POLLERR;
  939. /// Represents a handle that can be `poll()`ed.
  940. ///
  941. /// This is either a reference to a 0MQ socket, or a standard socket.
  942. /// Apart from that it contains the requested event mask, and is updated
  943. /// with the occurred events after `poll()` finishes.
  944. #[repr(C)]
  945. pub struct PollItem<'a> {
  946. socket: *mut c_void,
  947. fd: RawFd,
  948. events: c_short,
  949. revents: c_short,
  950. marker: PhantomData<&'a Socket>,
  951. }
  952. impl<'a> PollItem<'a> {
  953. /// Construct a PollItem from a non-0MQ socket, given by its file
  954. /// descriptor and the events that should be polled.
  955. pub fn from_fd(fd: RawFd, events: PollEvents) -> PollItem<'a> {
  956. PollItem {
  957. socket: ptr::null_mut(),
  958. fd,
  959. events: events.bits(),
  960. revents: 0,
  961. marker: PhantomData,
  962. }
  963. }
  964. /// Change the events to wait for.
  965. pub fn set_events(&mut self, events: PollEvents) {
  966. self.events = events.bits();
  967. }
  968. /// Retrieve the events that occurred for this handle.
  969. pub fn get_revents(&self) -> PollEvents {
  970. PollEvents::from_bits_truncate(self.revents)
  971. }
  972. /// Returns true if the polled socket has messages ready to receive.
  973. pub fn is_readable(&self) -> bool {
  974. (self.revents & POLLIN.bits()) != 0
  975. }
  976. /// Returns true if the polled socket can accept messages to be sent
  977. /// without blocking.
  978. pub fn is_writable(&self) -> bool {
  979. (self.revents & POLLOUT.bits()) != 0
  980. }
  981. /// Returns true if the polled socket encountered an error condition.
  982. pub fn is_error(&self) -> bool {
  983. (self.revents & POLLERR.bits()) != 0
  984. }
  985. /// Returns true if the polled socket is the given 0MQ socket.
  986. pub fn has_socket(&self, socket: &Socket) -> bool {
  987. self.socket == socket.sock
  988. }
  989. /// Returns true if the polled socket is the given file descriptor.
  990. pub fn has_fd(&self, fd: RawFd) -> bool {
  991. self.socket.is_null() && self.fd == fd
  992. }
  993. }
  994. /// Poll for events on multiple sockets.
  995. ///
  996. /// For every poll item given, the events given in the `events` bitmask are
  997. /// monitored, and signaled in `revents` when they occur. Any number of poll
  998. /// items can have events signaled when the function returns.
  999. ///
  1000. /// The given timeout is in milliseconds and can be zero. A timeout of `-1`
  1001. /// indicates to block indefinitely until an event has occurred.
  1002. ///
  1003. /// The result, if not `Err`, indicates the number of poll items that have
  1004. /// events signaled.
  1005. pub fn poll(items: &mut [PollItem], timeout: i64) -> Result<i32> {
  1006. let rc = zmq_try!(unsafe {
  1007. zmq_sys::zmq_poll(
  1008. items.as_mut_ptr() as *mut zmq_sys::zmq_pollitem_t,
  1009. items.len() as c_int,
  1010. timeout as c_long,
  1011. )
  1012. });
  1013. Ok(rc as i32)
  1014. }
  1015. /// Start a 0MQ proxy in the current thread.
  1016. ///
  1017. /// A proxy connects a frontend socket with a backend socket, where the exact
  1018. /// behavior depends on the type of both sockets.
  1019. ///
  1020. /// This function only returns (always with an `Err`) when the sockets' context
  1021. /// has been closed.
  1022. pub fn proxy(frontend: &Socket, backend: &Socket) -> Result<()> {
  1023. zmq_try!(unsafe { zmq_sys::zmq_proxy(frontend.sock, backend.sock, ptr::null_mut()) });
  1024. Ok(())
  1025. }
  1026. /// Start a 0MQ proxy in the current thread, with a capture socket.
  1027. ///
  1028. /// The capture socket is sent all messages received on the frontend and backend
  1029. /// sockets.
  1030. pub fn proxy_with_capture(
  1031. frontend: &mut Socket,
  1032. backend: &mut Socket,
  1033. capture: &mut Socket,
  1034. ) -> Result<()> {
  1035. zmq_try!(unsafe { zmq_sys::zmq_proxy(frontend.sock, backend.sock, capture.sock) });
  1036. Ok(())
  1037. }
  1038. /// Start a 0MQ proxy in the current thread, with a control socket.
  1039. ///
  1040. /// If PAUSE is received on the control socket, the proxy suspends its activities. If RESUME is received,
  1041. /// it goes on. If TERMINATE is received, it terminates smoothly. At start, the proxy runs normally
  1042. /// as if `proxy` was used.
  1043. pub fn proxy_steerable(
  1044. frontend: &mut Socket,
  1045. backend: &mut Socket,
  1046. control: &mut Socket,
  1047. ) -> Result<()> {
  1048. zmq_try!(unsafe {
  1049. zmq_sys::zmq_proxy_steerable(frontend.sock, backend.sock, ptr::null_mut(), control.sock)
  1050. });
  1051. Ok(())
  1052. }
  1053. /// Start a 0MQ proxy in the current thread, with capture and control sockets.
  1054. ///
  1055. /// Provides a steerable proxy with a capture socket. See `proxy_with_capture`
  1056. pub fn proxy_steerable_with_capture(
  1057. frontend: &mut Socket,
  1058. backend: &mut Socket,
  1059. capture: &mut Socket,
  1060. control: &mut Socket,
  1061. ) -> Result<()> {
  1062. zmq_try!(unsafe {
  1063. zmq_sys::zmq_proxy_steerable(frontend.sock, backend.sock, capture.sock, control.sock)
  1064. });
  1065. Ok(())
  1066. }
  1067. /// Return true if the used 0MQ library has the given capability.
  1068. ///
  1069. /// The return value is always the `Some` variant; it used to return
  1070. /// `None` for older, now unsupported versions of 0MQ that didn't have
  1071. /// the wrapped `zmq_has` function. Thus, for code that requires `zmq`
  1072. /// version 0.9.0 or newer, you can safely call `unwrap` on the return
  1073. /// value.
  1074. ///
  1075. /// For a list of capabilities, please consult the `zmq_has` manual
  1076. /// page.
  1077. ///
  1078. /// # Compatibility
  1079. ///
  1080. /// In the `zmq` 0.10.0, this function will simply return `bool`.
  1081. ///
  1082. pub fn has(capability: &str) -> Option<bool> {
  1083. let c_str = ffi::CString::new(capability).unwrap();
  1084. unsafe { Some(zmq_sys::zmq_has(c_str.as_ptr()) == 1) }
  1085. }
  1086. /// A CURVE key pair generated by 0MQ.
  1087. ///
  1088. /// Note that for API consistency reasons, since version 0.9, the key
  1089. /// pair is represented in the binary form. This is in contrast to
  1090. /// libzmq, which returns the z85-encoded representation.
  1091. #[derive(Debug)]
  1092. pub struct CurveKeyPair {
  1093. pub public_key: [u8; 32],
  1094. pub secret_key: [u8; 32],
  1095. }
  1096. impl CurveKeyPair {
  1097. /// Create a new key pair.
  1098. pub fn new() -> Result<CurveKeyPair> {
  1099. // Curve keypairs are currently 40 bytes long, plus terminating NULL.
  1100. let mut ffi_public_key = [0u8; 41];
  1101. let mut ffi_secret_key = [0u8; 41];
  1102. zmq_try!(unsafe {
  1103. zmq_sys::zmq_curve_keypair(
  1104. ffi_public_key.as_mut_ptr() as *mut libc::c_char,
  1105. ffi_secret_key.as_mut_ptr() as *mut libc::c_char,
  1106. )
  1107. });
  1108. let mut pair = CurveKeyPair {
  1109. public_key: [0; 32],
  1110. secret_key: [0; 32],
  1111. };
  1112. unsafe {
  1113. // No need to check return code here, as zmq_curve_keypair
  1114. // is supposed to generate valid z85-encoded keys
  1115. zmq_sys::zmq_z85_decode(
  1116. pair.public_key.as_mut_ptr(),
  1117. ffi_public_key.as_ptr() as *mut libc::c_char,
  1118. );
  1119. zmq_sys::zmq_z85_decode(
  1120. pair.secret_key.as_mut_ptr(),
  1121. ffi_secret_key.as_ptr() as *mut libc::c_char,
  1122. );
  1123. }
  1124. Ok(pair)
  1125. }
  1126. }
  1127. /// Errors that can occur while encoding Z85.
  1128. #[derive(Debug)]
  1129. pub enum EncodeError {
  1130. BadLength,
  1131. FromUtf8Error(FromUtf8Error),
  1132. }
  1133. impl From<FromUtf8Error> for EncodeError {
  1134. fn from(err: FromUtf8Error) -> Self {
  1135. EncodeError::FromUtf8Error(err)
  1136. }
  1137. }
  1138. impl fmt::Display for EncodeError {
  1139. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  1140. match *self {
  1141. EncodeError::BadLength => write!(f, "Invalid data length. Should be multiple of 4."),
  1142. EncodeError::FromUtf8Error(ref e) => write!(f, "UTF8 conversion error: {}", e),
  1143. }
  1144. }
  1145. }
  1146. impl std::error::Error for EncodeError {}
  1147. /// Encode a binary key as Z85 printable text.
  1148. ///
  1149. /// Z85 is an encoding similar to Base64, but operates on 4-byte chunks,
  1150. /// which are encoded into 5-byte sequences.
  1151. ///
  1152. /// The input slice *must* have a length divisible by 4.
  1153. pub fn z85_encode(data: &[u8]) -> result::Result<String, EncodeError> {
  1154. if data.len() % 4 != 0 {
  1155. return Err(EncodeError::BadLength);
  1156. }
  1157. let len = data.len() * 5 / 4 + 1;
  1158. let mut dest = vec![0u8; len];
  1159. unsafe {
  1160. zmq_sys::zmq_z85_encode(
  1161. dest.as_mut_ptr() as *mut libc::c_char,
  1162. data.as_ptr(),
  1163. data.len(),
  1164. );
  1165. }
  1166. dest.truncate(len - 1);
  1167. String::from_utf8(dest).map_err(EncodeError::FromUtf8Error)
  1168. }
  1169. /// Errors that can occur while decoding Z85.
  1170. #[derive(Debug)]
  1171. pub enum DecodeError {
  1172. /// The input string slice's length was not a multiple of 5.
  1173. BadLength,
  1174. /// The input string slice had embedded NUL bytes.
  1175. NulError(ffi::NulError),
  1176. }
  1177. impl From<ffi::NulError> for DecodeError {
  1178. fn from(err: ffi::NulError) -> Self {
  1179. DecodeError::NulError(err)
  1180. }
  1181. }
  1182. impl fmt::Display for DecodeError {
  1183. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  1184. match *self {
  1185. DecodeError::BadLength => write!(f, "Invalid data length. Should be multiple of 5."),
  1186. DecodeError::NulError(ref e) => write!(f, "Nul byte error: {}", e),
  1187. }
  1188. }
  1189. }
  1190. impl std::error::Error for DecodeError {}
  1191. /// Decode a binary key from Z85-encoded text.
  1192. ///
  1193. /// The input string must have a length divisible by 5.
  1194. ///
  1195. /// Note that 0MQ silently accepts characters outside the range defined for
  1196. /// the Z85 encoding.
  1197. pub fn z85_decode(data: &str) -> result::Result<Vec<u8>, DecodeError> {
  1198. if data.len() % 5 != 0 {
  1199. return Err(DecodeError::BadLength);
  1200. }
  1201. let len = data.len() * 4 / 5;
  1202. let mut dest = vec![0u8; len];
  1203. let c_str = ffi::CString::new(data)?;
  1204. unsafe {
  1205. zmq_sys::zmq_z85_decode(dest.as_mut_ptr(), c_str.into_raw());
  1206. }
  1207. Ok(dest)
  1208. }