Skip to content

Instantly share code, notes, and snippets.

@tamird
Forked from manuels/crashing_code.rs
Created April 21, 2015 15:19
Show Gist options
  • Save tamird/819a5774c66d4a28113b to your computer and use it in GitHub Desktop.
Save tamird/819a5774c66d4a28113b to your computer and use it in GitHub Desktop.
extern crate libc;
extern crate native;
use libc::{c_short, c_int};
mod linux {
use native::io::file::FileDesc;
use libc::c_int;
pub fn socketpair(domain: int, type_: int, protocol: int) -> Result<(FileDesc, FileDesc), int> {
unsafe {
let sv: [c_int, ..2] = [0, 0];
let res = internal::socketpair(domain as c_int, type_ as c_int, protocol as c_int, sv.as_ptr());
if res == 0 {
assert!(sv[0] >= 0);
assert!(sv[1] >= 0);
let SOCK_CLOEXEC = 02000000;
let close_on_exec = (type_ & SOCK_CLOEXEC) > 0;
let left = FileDesc::new(sv[0], close_on_exec);
let right = FileDesc::new(sv[1], close_on_exec);
let pair = (left, right);
return Ok(pair)
} else {
return Err(res as int)
}
}
}
mod internal {
use native::io::file::fd_t;
use libc::c_int;
extern {
pub fn socketpair(domain: c_int, type_: c_int, protocol: c_int, sv: *const fd_t) -> c_int;
}
}
}
mod libevent {
use native::io::file::{FileDesc, fd_t};
use libc::{c_short, c_int};
use std::ptr::null;
pub struct Base {
ptr: *const c_int,
}
impl Base {
pub fn new() -> Base {
unsafe {
let ptr = event_init();
assert!(!ptr.is_null());
return Base {
ptr: ptr,
}
}
}
pub fn dispatch(&self) -> int {
unsafe {
return event_base_dispatch(self.ptr) as int
}
}
extern "C"
fn c_watch_fd_callback(ev:*const c_int, type_:c_short, cb: watch_fd_callback_t) {
cb(ev, type_)
}
pub fn watch_fd(&self, fd: FileDesc, cb: watch_fd_callback_t) {
unsafe {
let EV_READ:c_short = 0x02;
let ev = event_new(self.ptr, fd.fd(), EV_READ, Base::c_watch_fd_callback, cb);
assert!(!ev.is_null());
let res = event_add(ev, null());
assert!(res == 0);
}
}
}
impl Drop for Base {
fn drop(&mut self) {
unsafe {
event_base_free(self.ptr)
}
}
}
type watch_fd_callback_t = fn(*const c_int, c_short);
type c_watch_fd_callback_t = extern fn(*const c_int, c_short, watch_fd_callback_t);
#[link(name="event")]
extern {
fn event_init() -> *const c_int;
fn event_base_dispatch(ptr: *const c_int) -> c_int;
fn event_base_loop(ptr: *const c_int, flags: c_int) -> c_int;
fn event_base_free(ptr: *const c_int);
fn event_new(base: *const c_int, fd: fd_t, events: c_short, cb: c_watch_fd_callback_t, args: watch_fd_callback_t) -> *const c_int;
fn event_add(ev: *const c_int, timeout: *const c_int) -> c_int;
}
}
fn printme(ev: *const c_int, flags: i16) {
println!("hello");
}
fn main() {
use linux::socketpair;
use libc::consts::os::bsd44::{AF_UNIX, SOCK_DGRAM};
let AF_UNSPEC = 0 as int;
let domain = AF_UNIX as int;
let type_ = SOCK_DGRAM as int;
let protocol = AF_UNSPEC as int;
let (mut fd1, fd2) = socketpair(domain, type_, protocol).ok().expect("socketpair failed!");
println!("{}, {}", fd1.fd(), fd2.fd());
spawn(proc() {
let ev = libevent::Base::new();
ev.watch_fd(fd2, printme);
println!("waiting...");
ev.dispatch();
println!("waiting done");
});
let buf:[u8, ..1] = [0];
match fd1.inner_write(buf) {
Err(x) => { println!("write() err: {}", x.detail.expect("Unknown error")) },
_ => {},
}
println!("wrote!");
}
70c70,75
< pub fn watch_fd(&self, fd: FileDesc, cb: extern fn(*const c_int, c_short, *const c_int)) {
---
> extern "C"
> fn c_watch_fd_callback(ev:*const c_int, type_:c_short, cb: watch_fd_callback_t) {
> cb(ev, type_)
> }
>
> pub fn watch_fd(&self, fd: FileDesc, cb: watch_fd_callback_t) {
73c78
< let ev = event_new(self.ptr, fd.fd(), EV_READ, cb, null());
---
> let ev = event_new(self.ptr, fd.fd(), EV_READ, Base::c_watch_fd_callback, cb);
89a95,97
> type watch_fd_callback_t = fn(*const c_int, c_short);
> type c_watch_fd_callback_t = extern fn(*const c_int, c_short, watch_fd_callback_t);
>
97c105
< fn event_new(base: *const c_int, fd: fd_t, events: c_short, cb: extern fn(*const c_int, c_short, *const c_int), args: *const c_int) -> *const c_int;
---
> fn event_new(base: *const c_int, fd: fd_t, events: c_short, cb: c_watch_fd_callback_t, args: watch_fd_callback_t) -> *const c_int;
102,103c110
< extern "C"
< fn printme(ev: *const c_int, flags: c_short, args: *const c_int) {
---
> fn printme(ev: *const c_int, flags: i16) {
extern crate libc;
extern crate native;
use libc::{c_short, c_int};
mod linux {
use native::io::file::FileDesc;
use libc::c_int;
pub fn socketpair(domain: int, type_: int, protocol: int) -> Result<(FileDesc, FileDesc), int> {
unsafe {
let sv: [c_int, ..2] = [0, 0];
let res = internal::socketpair(domain as c_int, type_ as c_int, protocol as c_int, sv.as_ptr());
if res == 0 {
assert!(sv[0] >= 0);
assert!(sv[1] >= 0);
let SOCK_CLOEXEC = 02000000;
let close_on_exec = (type_ & SOCK_CLOEXEC) > 0;
let left = FileDesc::new(sv[0], close_on_exec);
let right = FileDesc::new(sv[1], close_on_exec);
let pair = (left, right);
return Ok(pair)
} else {
return Err(res as int)
}
}
}
mod internal {
use native::io::file::fd_t;
use libc::c_int;
extern {
pub fn socketpair(domain: c_int, type_: c_int, protocol: c_int, sv: *const fd_t) -> c_int;
}
}
}
mod libevent {
use native::io::file::{FileDesc, fd_t};
use libc::{c_short, c_int};
use std::ptr::null;
pub struct Base {
ptr: *const c_int,
}
impl Base {
pub fn new() -> Base {
unsafe {
let ptr = event_init();
assert!(!ptr.is_null());
return Base {
ptr: ptr,
}
}
}
pub fn dispatch(&self) -> int {
unsafe {
return event_base_dispatch(self.ptr) as int
}
}
pub fn watch_fd(&self, fd: FileDesc, cb: extern fn(*const c_int, c_short, *const c_int)) {
unsafe {
let EV_READ:c_short = 0x02;
let ev = event_new(self.ptr, fd.fd(), EV_READ, cb, null());
assert!(!ev.is_null());
let res = event_add(ev, null());
assert!(res == 0);
}
}
}
impl Drop for Base {
fn drop(&mut self) {
unsafe {
event_base_free(self.ptr)
}
}
}
#[link(name="event")]
extern {
fn event_init() -> *const c_int;
fn event_base_dispatch(ptr: *const c_int) -> c_int;
fn event_base_loop(ptr: *const c_int, flags: c_int) -> c_int;
fn event_base_free(ptr: *const c_int);
fn event_new(base: *const c_int, fd: fd_t, events: c_short, cb: extern fn(*const c_int, c_short, *const c_int), args: *const c_int) -> *const c_int;
fn event_add(ev: *const c_int, timeout: *const c_int) -> c_int;
}
}
extern "C"
fn printme(ev: *const c_int, flags: c_short, args: *const c_int) {
println!("hello");
}
fn main() {
use linux::socketpair;
use libc::consts::os::bsd44::{AF_UNIX, SOCK_DGRAM};
let AF_UNSPEC = 0 as int;
let domain = AF_UNIX as int;
let type_ = SOCK_DGRAM as int;
let protocol = AF_UNSPEC as int;
let (mut fd1, fd2) = socketpair(domain, type_, protocol).ok().expect("socketpair failed!");
println!("{}, {}", fd1.fd(), fd2.fd());
spawn(proc() {
let ev = libevent::Base::new();
ev.watch_fd(fd2, printme);
println!("waiting...");
ev.dispatch();
println!("waiting done");
});
let buf:[u8, ..1] = [0];
match fd1.inner_write(buf) {
Err(x) => { println!("write() err: {}", x.detail.expect("Unknown error")) },
_ => {},
}
println!("wrote!");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment