#include <stdlib.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/signal.h>
#include <sys/queue.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <sys/aio.h>
#include <pthread.h>
static void *_aio_thr_start(void *);
static void
_aio_notify(struct sigevent *sigevp)
{
#if 0
int sig;
union sigval sv;
pid_t pid;
#endif
pthread_t thr;
switch (sigevp->sigev_notify) {
case SIGEV_NONE:
return;
case SIGEV_THREAD:
pthread_create(&thr,
sigevp->sigev_notify_attributes,
_aio_thr_start,
sigevp);
break;
case SIGEV_SIGNAL:
#if 0
pid = getpid();
sig = sigevp->sigev_signo;
sv = sigevp->sigev_value;
sigqueue(pid, sig, sv);
#endif
break;
case SIGEV_KEVENT:
break;
}
}
static void *
_aio_thr_start(void *vsigevp)
{
struct sigevent *sigevp = vsigevp;
sigevp->sigev_notify_function(sigevp->sigev_value);
return (NULL);
}
int
aio_read(struct aiocb *ap)
{
#if 0
if ((ap->aio_sigevent.sigev_notify != SIGEV_NONE) &&
(ap->aio_sigevent.sigev_notify != SIGEV_THREAD))
return (ENOSYS);
#endif
ap->_aio_val = pread(ap->aio_fildes,
(void *) ap->aio_buf,
ap->aio_nbytes,
ap->aio_offset);
ap->_aio_err = errno;
_aio_notify(&ap->aio_sigevent);
return (0);
}
int
aio_write(struct aiocb *ap)
{
#if 0
if ((ap->aio_sigevent.sigev_notify != SIGEV_NONE) &&
(ap->aio_sigevent.sigev_notify != SIGEV_THREAD))
return (ENOSYS);
#endif
ap->_aio_val = pwrite(ap->aio_fildes,
(void *) ap->aio_buf,
ap->aio_nbytes,
ap->aio_offset);
ap->_aio_err = errno;
_aio_notify(&ap->aio_sigevent);
return (0);
}
int
aio_fsync(int op, struct aiocb *ap)
{
#if 0
if ((ap->aio_sigevent.sigev_notify != SIGEV_NONE) &&
(ap->aio_sigevent.sigev_notify != SIGEV_THREAD))
return (ENOSYS);
#endif
ap->_aio_val = fsync(ap->aio_fildes);
ap->_aio_err = errno;
_aio_notify(&ap->aio_sigevent);
return(0);
}
int
lio_listio(int mode, struct aiocb * __restrict const apv[__restrict_arr],
int nent, struct sigevent * __restrict sigevp)
{
int i;
#if 0
if (sigevp &&
(sigevp->sigev_notify != SIGEV_NONE) &&
(sigevp->sigev_notify != SIGEV_THREAD))
return (ENOSYS);
#endif
for (i = 0; i < nent; i++)
switch (apv[i]->aio_lio_opcode) {
case LIO_READ:
aio_read(apv[i]);
break;
case LIO_WRITE:
aio_write(apv[i]);
break;
case LIO_NOP:
break;
}
if (sigevp &&
(mode == LIO_NOWAIT)
) {
_aio_notify(sigevp);
}
return (0);
}
int
aio_error(const struct aiocb *ap)
{
return (ap->_aio_err);
}
ssize_t
aio_return(struct aiocb *ap)
{
return (ap->_aio_val);
}
int
aio_cancel(int fildes, struct aiocb *aiocbp)
{
struct stat sb;
if (fstat(fildes, &sb)) {
errno = EBADF;
return -1;
}
return (AIO_ALLDONE);
}
int
aio_suspend(const struct aiocb *const list[], int nent, const struct timespec *timo)
{
return (0);
}