PageRenderTime 40ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/io/socket.rs

http://github.com/djehuty/ibis
Rust | 658 lines | 511 code | 119 blank | 28 comment | 29 complexity | 2b33f00f2f064412056ba02b157f1e40 MD5 | raw file
Possible License(s): CC0-1.0
  1. #[crate_id="io-socket#1.0"];
  2. #[feature(globs)];
  3. extern mod io_stream = "io-stream";
  4. extern mod io_console = "io-console";
  5. extern mod text_format = "text-format";
  6. #[cfg(target_os = "linux")]
  7. mod os {
  8. // TODO: 32 bit
  9. pub type size_t = u64;
  10. pub type ssize_t = i64;
  11. pub type socklen_t = u32;
  12. pub type c_long = i64;
  13. pub type c_ulong = u64;
  14. pub type time_t = i32;
  15. pub static NFDBITS:i32 = 64;
  16. pub struct timeval {
  17. tv_sec: c_long,
  18. tv_usec: c_long,
  19. }
  20. pub struct sockaddr {
  21. sa_family: u16,
  22. sa_data: [u8,..14],
  23. }
  24. pub struct fd_set {
  25. fds_bits: [c_long,..(1024/NFDBITS)],
  26. }
  27. pub struct addrinfo {
  28. ai_flags: i32, /* AI_PASSIVE, AI_CANONNAME */
  29. ai_family: i32, /* PF_xxx */
  30. ai_socktype: i32, /* SOCK_xxx */
  31. ai_protocol: i32, /* IPPROTO_xxx for IPv4 and IPv6 */
  32. ai_addrlen: socklen_t, /* length of ai_addr */
  33. ai_addr: *sockaddr, /* binary address */
  34. ai_canonname: *char, /* canonical name for host */
  35. ai_next: *addrinfo, /* next structure in linked list */
  36. }
  37. pub enum AddressFamily {
  38. AF_MAX = 34,
  39. AF_APPLETALK = 5,
  40. AF_INET6 = 10,
  41. AF_FILE = 1,
  42. AF_ROSE = 11,
  43. AF_NETROM = 6,
  44. AF_ATMPVC = 8,
  45. AF_WANPIPE = 25,
  46. AF_UNSPEC = 0,
  47. AF_BRIDGE = 7,
  48. AF_X25 = 9,
  49. AF_BLUETOOTH = 31,
  50. AF_ROUTE = 16,
  51. AF_SECURITY = 14,
  52. AF_RXRPC = 33,
  53. AF_AX25 = 3,
  54. AF_KEY = 15,
  55. AF_IUCV = 32,
  56. AF_ECONET = 19,
  57. AF_INET = 2,
  58. AF_ATMSVC = 20,
  59. AF_PPPOX = 24,
  60. AF_PACKET = 17,
  61. AF_IRDA = 23,
  62. AF_NETBEUI = 13,
  63. AF_SNA = 22,
  64. AF_ASH = 18,
  65. AF_DECnet = 12,
  66. AF_IPX = 4,
  67. }
  68. pub enum SocketType {
  69. SOCK_RAW = 3,
  70. SOCK_RDM = 4,
  71. SOCK_SEQPACKET = 5,
  72. SOCK_PACKET = 10,
  73. SOCK_DGRAM = 2,
  74. SOCK_STREAM = 1,
  75. }
  76. pub enum Protocol {
  77. IPPROTO_IP = 0,
  78. IPPROTO_ROUTING = 43,
  79. IPPROTO_EGP = 8,
  80. IPPROTO_PIM = 103,
  81. IPPROTO_ENCAP = 98,
  82. IPPROTO_ESP = 50,
  83. IPPROTO_PUP = 12,
  84. IPPROTO_IDP = 22,
  85. IPPROTO_IPIP = 4,
  86. IPPROTO_TCP = 6,
  87. IPPROTO_IPV6 = 41,
  88. IPPROTO_SCTP = 132,
  89. IPPROTO_AH = 51,
  90. IPPROTO_MTP = 92,
  91. IPPROTO_TP = 29,
  92. IPPROTO_UDP = 17,
  93. IPPROTO_RAW = 255,
  94. IPPROTO_ICMP = 1,
  95. IPPROTO_GGP = 3,
  96. IPPROTO_FRAGMENT = 44,
  97. IPPROTO_GRE = 47,
  98. IPPROTO_DSTOPTS = 60,
  99. IPPROTO_NONE = 59,
  100. IPPROTO_RSVP = 46,
  101. IPPROTO_IGMP = 2,
  102. IPPROTO_ICMPV6 = 58,
  103. IPPROTO_COMP = 108,
  104. }
  105. /*pub enum RecvOptions {
  106. MSG_PEEK = 0x2,
  107. MSG_DONTWAIT = 0x40,
  108. }*/
  109. pub enum FileControlCommands {
  110. F_GETFL = 6,
  111. F_SETFL = 7,
  112. }
  113. pub enum FileControlOptions {
  114. O_NONBLOCK = 128,
  115. }
  116. pub enum IoControl {
  117. FIONREAD = 0x541b,
  118. }
  119. /*
  120. pub enum SocketLevel {
  121. SOL_SOCKET = 1,
  122. }
  123. pub enum SocketOptions {
  124. SO_ERROR = 4,
  125. }
  126. */
  127. #[nolink]
  128. extern {
  129. //pub fn gai_strerror(ecode: i32) -> *u8;
  130. //pub fn gethostname(name: *u8, namelen: i32) -> i32;
  131. //pub fn getnameinfo(sa: *sockaddr, salen: socklen_t, node: *u8, nodelen: socklen_t, service: *u8, servicelen: socklen_t, flags: i32) -> i32;
  132. pub fn ioctl(d: i32, request: c_ulong, ...) -> i32;
  133. pub fn fcntl(fd: i32, cmd: i32, ...) -> i32;
  134. //pub fn getsockopt(sockfd: i32, level: i32, optname: i32, optval: *i32, optlen: *socklen_t) -> i32;
  135. pub fn getaddrinfo(nodename: *u8, servname: *u8, hints: *addrinfo, res: **addrinfo) -> i32;
  136. pub fn freeaddrinfo(ai: *addrinfo);
  137. pub fn socket(af: i32, socket_type: i32, protocol: i32) -> i32;
  138. pub fn connect(s: i32, name: *sockaddr, namelen: socklen_t) -> i32;
  139. pub fn shutdown(s: i32, how: i32) -> i32;
  140. pub fn close(fd: i32) -> i32;
  141. pub fn recv(s: i32, buf: *mut u8, len: size_t, flags: i32) -> ssize_t;
  142. pub fn send(s: i32, buf: *u8, len: size_t, flags: i32) -> ssize_t;
  143. pub fn select(nfds: i32, readfds: *mut fd_set, writefds: *mut fd_set,
  144. errorfds: *mut fd_set, timeout: *timeval) -> i32;
  145. }
  146. }
  147. pub mod io {
  148. pub mod socket {
  149. use std::vec;
  150. //use io_stream::io::stream::{Read, Write, ReadWrite, Executable, ReadExecutable, WriteExecutable, ReadWriteExecutable};
  151. pub struct Socket {
  152. descriptor: u64,
  153. connected: bool,
  154. hostname: ~str,
  155. port: u16,
  156. }
  157. pub enum Connection {
  158. Connected(~Socket),
  159. Error(u64)
  160. }
  161. pub fn connect(hostname: &str, port: u16) -> ~Connection {
  162. let ai = ::os::addrinfo {
  163. ai_flags: 0,
  164. ai_family: ::os::AF_UNSPEC as i32,
  165. ai_socktype: ::os::SOCK_STREAM as i32,
  166. ai_protocol: ::os::IPPROTO_TCP as i32,
  167. ai_addrlen: 0,
  168. ai_addr: 0 as *::os::sockaddr,
  169. ai_canonname: 0 as *char,
  170. ai_next: 0 as *::os::addrinfo,
  171. };
  172. let ai_result_ptr: *::os::addrinfo = 0 as *::os::addrinfo;
  173. let port_string = ::text_format::text::format::integer(port as i64, 10) + "\0";
  174. let error = unsafe {
  175. ::os::getaddrinfo(hostname.as_ptr(), port_string.as_ptr(), &ai as *::os::addrinfo, &ai_result_ptr as **::os::addrinfo)
  176. };
  177. if error != 0 {
  178. // Error connecting
  179. unsafe { ::os::freeaddrinfo(ai_result_ptr) };
  180. return ~Error(0);
  181. }
  182. let ai_result = unsafe { *ai_result_ptr };
  183. let fd = unsafe {
  184. ::os::socket(ai_result.ai_family, ai_result.ai_socktype, ai_result.ai_protocol)
  185. };
  186. if fd == -1 {
  187. unsafe { ::os::freeaddrinfo(ai_result_ptr) };
  188. ~Error(0)
  189. }
  190. else {
  191. unsafe {
  192. let mut flags = ::os::fcntl(fd, ::os::F_GETFL as i32);
  193. flags |= ::os::O_NONBLOCK as i32;
  194. ::os::fcntl(fd, ::os::F_SETFL as i32, flags);
  195. }
  196. let socket = ~Socket {
  197. descriptor: fd as u64,
  198. connected: true,
  199. hostname: hostname.to_owned(),
  200. port: port,
  201. };
  202. let result = unsafe {
  203. ::os::connect(fd, ai_result.ai_addr, ai_result.ai_addrlen as ::os::socklen_t)
  204. };
  205. unsafe { ::os::freeaddrinfo(ai_result_ptr) };
  206. if result == -1 {
  207. unsafe { ::os::close(fd); }
  208. ~Error(0)
  209. }
  210. else {
  211. ~Connected(socket)
  212. }
  213. }
  214. }
  215. impl Drop for Socket {
  216. fn drop(&mut self) {
  217. unsafe {
  218. ::os::shutdown(self.descriptor as i32, 2);
  219. ::os::close(self.descriptor as i32);
  220. }
  221. }
  222. }
  223. impl ::io_stream::io::stream::Readable for Socket {
  224. fn readInto(&mut self, buffer: &mut [u8]) -> bool {
  225. self.readInto(buffer)
  226. }
  227. fn readIntoPtr(&mut self, buf_p: *mut u8, amount: u64) -> bool {
  228. self.readIntoPtr(buf_p, amount)
  229. }
  230. fn read(&mut self, amount: u64) -> ~[u8] {
  231. self.read(amount)
  232. }
  233. fn readAll(&mut self) -> ~[u8] {
  234. self.readAll()
  235. }
  236. fn seekTo(&mut self, _: u64) {
  237. }
  238. fn seek(&mut self, _: i64) {
  239. }
  240. fn length(&self) -> u64 {
  241. 0
  242. }
  243. fn available(&self) -> u64 {
  244. 0
  245. }
  246. fn position(&self) -> u64 {
  247. 0
  248. }
  249. fn seekable(&self) -> bool {
  250. self.seekable()
  251. }
  252. fn persistent(&self) -> bool {
  253. self.persistent()
  254. }
  255. }
  256. impl ::io_stream::io::stream::Writable for Socket {
  257. fn write(&mut self, data: &[u8]) {
  258. self.write(data)
  259. }
  260. fn writeFromPtr(&mut self, buf_p: *u8, amount: u64) {
  261. self.writeFromPtr(buf_p, amount)
  262. }
  263. fn writeFromReader(&mut self, data: &mut ::io_stream::io::stream::Readable, amount: u64) {
  264. self.write(data.read(amount));
  265. }
  266. fn writeFromStream(&mut self, data: &mut ::io_stream::io::stream::Streamable, amount: u64) {
  267. self.write(data.read(amount));
  268. }
  269. fn append(&mut self, data: &[u8]) {
  270. self.append(data)
  271. }
  272. fn appendFromPtr(&mut self, buf_p: *u8, amount: u64) {
  273. self.appendFromPtr(buf_p, amount)
  274. }
  275. fn appendFromReader(&mut self, data: &mut ::io_stream::io::stream::Readable, amount: u64) {
  276. self.append(data.read(amount));
  277. }
  278. fn appendFromStream(&mut self, data: &mut ::io_stream::io::stream::Streamable, amount: u64) {
  279. self.append(data.read(amount));
  280. }
  281. fn seekTo(&mut self, _: u64) {
  282. }
  283. fn seek(&mut self, _: i64) {
  284. }
  285. fn length(&self) -> u64 {
  286. 0
  287. }
  288. fn available(&self) -> u64 {
  289. 0
  290. }
  291. fn position(&self) -> u64 {
  292. 0
  293. }
  294. fn seekable(&self) -> bool {
  295. self.seekable()
  296. }
  297. fn persistent(&self) -> bool {
  298. self.persistent()
  299. }
  300. }
  301. impl Socket {
  302. pub fn connected(&self) -> bool {
  303. self.connected
  304. }
  305. pub fn connect(&mut self) {
  306. let ai = ::os::addrinfo {
  307. ai_flags: 0,
  308. ai_family: ::os::AF_UNSPEC as i32,
  309. ai_socktype: ::os::SOCK_STREAM as i32,
  310. ai_protocol: ::os::IPPROTO_TCP as i32,
  311. ai_addrlen: 0,
  312. ai_addr: 0 as *::os::sockaddr,
  313. ai_canonname: 0 as *char,
  314. ai_next: 0 as *::os::addrinfo,
  315. };
  316. let ai_result_ptr: *::os::addrinfo = 0 as *::os::addrinfo;
  317. let port_string = ::text_format::text::format::integer(self.port as i64, 10) + "\0";
  318. let error = unsafe {
  319. ::os::getaddrinfo(self.hostname.as_ptr(), port_string.as_ptr(), &ai as *::os::addrinfo, &ai_result_ptr as **::os::addrinfo)
  320. };
  321. if error != 0 {
  322. // Error connecting
  323. unsafe { ::os::freeaddrinfo(ai_result_ptr) };
  324. }
  325. let ai_result = unsafe { *ai_result_ptr };
  326. let result = unsafe {
  327. ::os::connect(self.descriptor as i32, ai_result.ai_addr, ai_result.ai_addrlen as ::os::socklen_t)
  328. };
  329. unsafe { ::os::freeaddrinfo(ai_result_ptr) };
  330. if result == -1 {
  331. // TODO: is this good to do?
  332. unsafe { ::os::close(self.descriptor as i32); }
  333. }
  334. }
  335. pub fn stream(&self) -> ~::io_stream::io::stream::Streamable {
  336. ~Socket {
  337. descriptor: self.descriptor,
  338. connected: self.connected,
  339. port: self.port,
  340. hostname: self.hostname.clone(),
  341. } as ~::io_stream::io::stream::Streamable
  342. }
  343. pub fn reader(&self) -> ~::io_stream::io::stream::Readable {
  344. ~Socket {
  345. descriptor: self.descriptor,
  346. connected: self.connected,
  347. port: self.port,
  348. hostname: self.hostname.clone(),
  349. } as ~::io_stream::io::stream::Readable
  350. }
  351. pub fn writer(&self) -> ~::io_stream::io::stream::Writable {
  352. ~Socket {
  353. descriptor: self.descriptor,
  354. connected: self.connected,
  355. port: self.port,
  356. hostname: self.hostname.clone(),
  357. } as ~::io_stream::io::stream::Writable
  358. }
  359. pub fn readInto(&mut self, buffer: &mut [u8]) -> bool {
  360. let buf_p = buffer.as_mut_ptr();
  361. let buf_len = buffer.len();
  362. self.readIntoPtr(buf_p, buf_len as u64)
  363. }
  364. pub fn readIntoPtr(&mut self, buf_p: *mut u8, amount: u64) -> bool {
  365. if amount == 0 {
  366. // Check for disconnect using select and timeout of 0
  367. let mut set = ::os::fd_set {
  368. fds_bits: [0,..(1024/::os::NFDBITS)]
  369. };
  370. let tval = ::os::timeval {
  371. tv_sec: 0,
  372. tv_usec: 0,
  373. };
  374. set.fds_bits[(self.descriptor as i32) / ::os::NFDBITS] |= (1 << ((self.descriptor as i32) % ::os::NFDBITS));
  375. let selected =
  376. unsafe {
  377. ::os::select(self.descriptor as i32 + 1,
  378. &mut set as *mut ::os::fd_set,
  379. 0 as *mut ::os::fd_set,
  380. 0 as *mut ::os::fd_set,
  381. &tval as *::os::timeval)
  382. };
  383. if selected > 0 {
  384. // Descriptors found!
  385. if self.available() == 0 {
  386. self.connected = false
  387. }
  388. }
  389. return true;
  390. }
  391. let amount_read =
  392. unsafe {
  393. ::os::recv(self.descriptor as i32, buf_p, amount as ::os::size_t, 0)
  394. };
  395. if amount_read == 0 {
  396. // Connection closed
  397. self.connected = false;
  398. }
  399. true
  400. }
  401. pub fn read(&mut self, amount: u64) -> ~[u8] {
  402. let mut vector = vec::with_capacity(amount as uint);
  403. unsafe { vector.set_len(amount as uint); }
  404. self.readInto(vector);
  405. vector
  406. }
  407. pub fn readAll(&mut self) -> ~[u8] {
  408. let amount = self.available();
  409. if amount == 0 {
  410. // Check for disconnect using select and timeout of 0
  411. let mut set = ::os::fd_set {
  412. fds_bits: [0,..(1024/::os::NFDBITS)]
  413. };
  414. let tval = ::os::timeval {
  415. tv_sec: 0,
  416. tv_usec: 0,
  417. };
  418. set.fds_bits[(self.descriptor as i32) / ::os::NFDBITS] |= (1 << ((self.descriptor as i32) % ::os::NFDBITS));
  419. let selected =
  420. unsafe {
  421. ::os::select(self.descriptor as i32 + 1,
  422. &mut set as *mut ::os::fd_set,
  423. 0 as *mut ::os::fd_set,
  424. 0 as *mut ::os::fd_set,
  425. &tval as *::os::timeval)
  426. };
  427. if selected > 0 {
  428. // Descriptors found!
  429. if self.available() == 0 {
  430. self.connected = false
  431. }
  432. }
  433. ~[]
  434. }
  435. else {
  436. self.read(amount)
  437. }
  438. }
  439. pub fn seekTo(&mut self, _: u64) {
  440. }
  441. pub fn seek(&mut self, _: i64) {
  442. }
  443. pub fn length(&self) -> u64 {
  444. 0
  445. }
  446. pub fn available(&self) -> u64 {
  447. unsafe {
  448. let bytes_available:i32 = 0;
  449. ::os::ioctl(self.descriptor as i32, ::os::FIONREAD as ::os::c_ulong, &bytes_available);
  450. bytes_available as u64
  451. }
  452. }
  453. pub fn position(&self) -> u64 {
  454. 0
  455. }
  456. pub fn write(&mut self, data: &[u8]) {
  457. let vbuf = data.as_ptr();
  458. let len = data.len();
  459. self.writeFromPtr(vbuf, len as u64);
  460. }
  461. pub fn writeFromPtr(&mut self, buf_p: *u8, amount: u64) {
  462. // TODO: non-blocking
  463. unsafe {
  464. ::os::send(self.descriptor as i32, buf_p, amount as ::os::size_t, 0);
  465. }
  466. }
  467. pub fn append(&mut self, data: &[u8]) {
  468. self.write(data);
  469. }
  470. pub fn appendFromPtr(&mut self, buf_p: *u8, amount: u64) {
  471. self.writeFromPtr(buf_p, amount);
  472. }
  473. pub fn seekable(&self) -> bool {
  474. false
  475. }
  476. pub fn persistent(&self) -> bool {
  477. false
  478. }
  479. }
  480. impl ::io_stream::io::stream::Streamable for Socket {
  481. fn readInto(&mut self, buffer: &mut [u8]) -> bool {
  482. self.readInto(buffer)
  483. }
  484. fn readIntoPtr(&mut self, buf_p: *mut u8, amount: u64) -> bool {
  485. self.readIntoPtr(buf_p, amount)
  486. }
  487. fn read(&mut self, amount: u64) -> ~[u8] {
  488. self.read(amount)
  489. }
  490. fn readAll(&mut self) -> ~[u8] {
  491. self.readAll()
  492. }
  493. fn seekTo(&mut self, _: u64) {
  494. }
  495. fn seek(&mut self, _: i64) {
  496. }
  497. fn length(&self) -> u64 {
  498. 0
  499. }
  500. fn available(&self) -> u64 {
  501. 0
  502. }
  503. fn position(&self) -> u64 {
  504. 0
  505. }
  506. fn write(&mut self, data: &[u8]) {
  507. self.write(data)
  508. }
  509. fn writeFromReader(&mut self, data: &mut ::io_stream::io::stream::Readable, amount: u64) {
  510. self.write(data.read(amount));
  511. }
  512. fn writeFromStream(&mut self, data: &mut ::io_stream::io::stream::Streamable, amount: u64) {
  513. self.write(data.read(amount));
  514. }
  515. fn writeFromPtr(&mut self, buf_p: *u8, amount: u64) {
  516. self.writeFromPtr(buf_p, amount)
  517. }
  518. fn append(&mut self, data: &[u8]) {
  519. self.append(data)
  520. }
  521. fn appendFromPtr(&mut self, buf_p: *u8, amount: u64) {
  522. self.appendFromPtr(buf_p, amount)
  523. }
  524. fn appendFromReader(&mut self, data: &mut ::io_stream::io::stream::Readable, amount: u64) {
  525. self.append(data.read(amount));
  526. }
  527. fn appendFromStream(&mut self, data: &mut ::io_stream::io::stream::Streamable, amount: u64) {
  528. self.append(data.read(amount));
  529. }
  530. fn seekable(&self) -> bool {
  531. self.seekable()
  532. }
  533. fn persistent(&self) -> bool {
  534. self.persistent()
  535. }
  536. }
  537. }
  538. }