Commit aac917dc authored by Jeremy Soller's avatar Jeremy Soller

Add poll and improve select

parent e91cf4c4
......@@ -14,6 +14,7 @@ lib_a_CFLAGS = $(AM_CFLAGS)
rust_sources = \
src/lib.rs \
src/macros.rs \
src/event.rs \
src/process.rs \
src/file.rs \
src/time.rs \
......
......@@ -202,6 +202,7 @@ lib_a_CFLAGS = $(AM_CFLAGS)
rust_sources = \
src/lib.rs \
src/macros.rs \
src/event.rs \
src/process.rs \
src/file.rs \
src/time.rs \
......
#ifndef POLL_H
#define POLL_H
#define POLLIN 0x0001
#define POLLPRI 0x0002
#define POLLOUT 0x0004
#define POLLERR 0x0008
#define POLLHUP 0x0010
#define POLLNVAL 0x0020
typedef unsigned int nfds_t;
struct pollfd {
int fd;
short int events;
short int revents;
};
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
#endif
use core::slice;
use libc::{c_int, c_uint};
use syscall;
use syscall::error::{Error, EINVAL};
use types::{fd_set, pollfd, timeval, FD_SETSIZE, POLLIN, POLLOUT, NFDBITS};
libc_fn!(unsafe poll(fds: *mut pollfd, nfds: c_uint, timeout: c_int) -> Result<c_int> {
let fds = slice::from_raw_parts_mut(fds, nfds as usize);
let mut ret = 0;
for fd in fds.iter_mut() {
// always ready for read or write
fd.revents = fd.events & (POLLIN | POLLOUT);
if fd.revents != 0 {
ret += 1;
}
}
Ok(ret)
});
libc_fn!(unsafe select(nfds: c_int, readfds: *mut fd_set, writefds: *mut fd_set, errorfds: *mut fd_set, _timeout: *mut timeval) -> Result<c_int> {
if nfds < 0 || nfds > FD_SETSIZE as i32 {
return Err(Error::new(EINVAL));
}
let mut ret = 0;
for i in 0..nfds as usize {
if ! readfds.is_null() {
// always ready to read
if ((*readfds).fds_bits[i/NFDBITS] & (1 << (i % NFDBITS))) != 0 {
ret += 1;
}
}
if ! writefds.is_null() {
// always ready to write
if ((*writefds).fds_bits[i/NFDBITS] & (1 << (i % NFDBITS))) != 0 {
ret += 1;
}
}
if ! errorfds.is_null() {
// report no errors
if ((*errorfds).fds_bits[i/NFDBITS] & (1 << (i % NFDBITS))) != 0 {
(*errorfds).fds_bits[i/NFDBITS] &= !(1 << (i % NFDBITS));
}
}
}
Ok(ret)
});
......@@ -103,7 +103,7 @@ libc_fn!(unsafe chmod(path: *mut c_char, mode: mode_t) -> Result<c_int> {
libc_fn!(unsafe realpath(path: *const c_char, resolved_path: *mut c_char) -> Result<*mut c_char> {
let fd = ::RawFile::open(::cstr_to_slice(path), O_STAT)?;
let mut resolved_path = ::MallocNull::new(resolved_path, PATH_MAX);
let resolved_path = ::MallocNull::new(resolved_path, PATH_MAX);
let buf = slice::from_raw_parts_mut(resolved_path.as_mut_ptr() as *mut u8, PATH_MAX-1);
let length = syscall::fpath(*fd, buf)?;
buf[length] = b'\0';
......@@ -155,7 +155,7 @@ libc_fn!(unsafe utime(path: *mut c_char, times: *const utimbuf) -> Result<c_int>
TimeSpec { tv_sec: (*times).modtime, tv_nsec: 0 }]
};
let fd = ::RawFile::open(::cstr_to_slice(path), 0)?;
syscall::futimens(*fd, &times);
syscall::futimens(*fd, &times)?;
Ok(0)
});
......@@ -163,7 +163,7 @@ libc_fn!(unsafe utimes(path: *mut c_char, times: *const [timeval; 2]) -> Result<
let times = [TimeSpec { tv_sec: (*times)[0].tv_sec, tv_nsec: (*times)[0].tv_usec as i32 * 1000 },
TimeSpec { tv_sec: (*times)[1].tv_sec, tv_nsec: (*times)[0].tv_usec as i32 * 1000 }];
let fd = ::RawFile::open(::cstr_to_slice(path), 0)?;
syscall::futimens(*fd, &times);
syscall::futimens(*fd, &times)?;
Ok(0)
});
......
......@@ -7,7 +7,6 @@
const_fn,
const_ptr_null,
core_intrinsics,
drop_types_in_const,
global_allocator,
lang_items,
linkage,
......@@ -32,6 +31,7 @@ mod types;
mod dns;
mod mallocnull;
mod rawfile;
pub mod event;
pub mod process;
pub mod file;
pub mod folder;
......
......@@ -52,6 +52,10 @@ libc_fn!(unsafe _fork() -> Result<c_int> {
Ok(syscall::clone(0)? as c_int)
});
libc_fn!(unsafe vfork() -> Result<c_int> {
Ok(syscall::clone(syscall::CLONE_VFORK)? as c_int)
});
libc_fn!(unsafe getcwd(buf: *mut c_char, size: size_t) -> Result<*const c_char> {
let mut size = size;
if size == 0 {
......
......@@ -104,7 +104,7 @@ libc_fn!(unsafe bind(socket: c_int, address: *const sockaddr, _address_len: sock
Ok(0)
});
libc_fn!(unsafe listen(socket: c_int, backlog: c_int) -> Result<c_int> {
libc_fn!(unsafe listen(_socket: c_int, _backlog: c_int) -> Result<c_int> {
// TODO
Ok(0)
});
......@@ -128,7 +128,7 @@ libc_fn!(unsafe send(socket: c_int, buffer: *const c_void, length: size_t, flags
}
});
libc_fn!(unsafe recvfrom(socket: c_int, buffer: *mut c_void, length: size_t, flags: c_int, address: *const sockaddr, _address_len: *const socklen_t) -> Result<ssize_t> {
libc_fn!(unsafe recvfrom(socket: c_int, buffer: *mut c_void, length: size_t, flags: c_int, _address: *const sockaddr, _address_len: *const socklen_t) -> Result<ssize_t> {
let fd = syscall::dup(socket as usize, b"listen")?;
let mut path = [0; 4096];
syscall::fpath(socket as usize, &mut path)?;
......
......@@ -83,6 +83,20 @@ pub struct fd_set {
pub fds_bits: [fd_mask; (FD_SETSIZE + NFDBITS - 1) / NFDBITS]
}
pub const POLLIN: libc::c_short = 0x0001;
pub const POLLPRI: libc::c_short = 0x0002;
pub const POLLOUT: libc::c_short = 0x0004;
pub const POLLERR: libc::c_short = 0x0008;
pub const POLLHUP: libc::c_short = 0x0010;
pub const POLLNVAL: libc::c_short = 0x0020;
#[repr(C)]
pub struct pollfd {
pub fd: libc::c_int,
pub events: libc::c_short,
pub revents: libc::c_short,
}
#[repr(C)]
pub struct passwd {
pub pw_name: *const libc::c_char,
......
use syscall;
use libc::{c_uint, c_int, c_char, gid_t, uid_t, c_void, c_long, mode_t};
use ::types::{timeval, fd_set};
use syscall::error::{Error, EACCES, EPERM, EINVAL};
#[allow(non_camel_case_types)]
......@@ -54,10 +53,6 @@ libc_fn!(umask(_mode: mode_t) -> mode_t {
0o000
});
libc_fn!(unsafe vfork() -> c_int {
::process::_fork()
});
libc_fn!(ttyname(_fd: c_int) -> Result<*const c_char> {
UNIMPL!(ttyname, EINVAL)
});
......@@ -69,27 +64,3 @@ libc_fn!(fpathconf(_fildes: c_int, _name: c_int) -> Result<c_long> {
libc_fn!(getlogin() -> Result<*const c_char> {
UNIMPL!(getlogin, EINVAL)
});
libc_fn!(unsafe select(_nfds: c_int, readfds: *mut fd_set, writefds: *mut fd_set, errorfds: *mut fd_set, _timeout: *mut timeval) -> Result<c_int> {
use ::types::{FD_SETSIZE, NFDBITS};
let mut ret = 0;
syscall::write(2, b"unimplemented: select()\n").unwrap();
if !readfds.is_null() {
for i in 0..FD_SETSIZE {
if ((*readfds).fds_bits[i/NFDBITS] & (1 << (i % NFDBITS))) != 0 {
ret += 1;
}
}
}
if !writefds.is_null() {
for i in 0..FD_SETSIZE {
if ((*writefds).fds_bits[i/NFDBITS] & (1 << (i % NFDBITS))) != 0 {
ret += 1;
}
}
}
if !errorfds.is_null() {
(*errorfds).fds_bits = [0; (FD_SETSIZE + NFDBITS - 1) / NFDBITS];
}
Ok(ret)
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment