// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License..

use std::io::Error;
use libc::{self, c_int, pollfd, nfds_t, epoll_event};

#[no_mangle]
pub extern "C" fn u_poll_ocall(
    error: *mut c_int,
    fds: *mut pollfd,
    nfds: nfds_t,
    timeout: c_int,
) -> c_int {
    let mut errno = 0;
    let ret = unsafe { libc::poll(fds, nfds, timeout) };
    if ret < 0 {
        errno = Error::last_os_error().raw_os_error().unwrap_or(0);
    }
    if !error.is_null() {
        unsafe { *error = errno; }
    }
    ret
}

#[no_mangle]
pub extern "C" fn u_epoll_create1_ocall(error: *mut c_int, flags: c_int) -> c_int {
    let mut errno = 0;
    let ret = unsafe { libc::epoll_create1(flags) };
    if ret < 0 {
        errno = Error::last_os_error().raw_os_error().unwrap_or(0);
    }
    if !error.is_null() {
        unsafe { *error = errno; }
    }
    ret
}

#[no_mangle]
pub extern "C" fn u_epoll_ctl_ocall(
    error: *mut c_int,
    epfd: c_int,
    op: c_int,
    fd: c_int,
    event: *mut epoll_event,
) -> c_int {
    let mut errno = 0;
    let ret = unsafe { libc::epoll_ctl(epfd, op, fd, event) };
    if ret < 0 {
        errno = Error::last_os_error().raw_os_error().unwrap_or(0);
    }
    if !error.is_null() {
        unsafe { *error = errno; }
    }
    ret
}

#[no_mangle]
pub extern "C" fn u_epoll_wait_ocall(error: *mut c_int, epfd: c_int, events: *mut epoll_event, maxevents: c_int, timeout: c_int) -> c_int {
    let mut errno = 0;
    let ret = unsafe { libc::epoll_wait(epfd, events, maxevents, timeout) };
    if ret < 0 {
        errno = Error::last_os_error().raw_os_error().unwrap_or(0);
    }
    if !error.is_null() {
        unsafe { *error = errno; }
    }
    ret
}
