IO-AIO
view release on metacpan or search on metacpan
eio_set_idle_timeout (seconds);
void
max_outstanding (unsigned int maxreqs)
PROTOTYPE: $
CODE:
max_outstanding = maxreqs;
void
aio_wd (SV8 *pathname, SV *callback = &PL_sv_undef)
PPCODE:
{
dREQ;
req->type = EIO_WD_OPEN;
req_set_path1 (req, pathname);
REQ_SEND;
}
void
aio_open (SV8 *pathname, int flags, int mode, SV *callback = &PL_sv_undef)
PPCODE:
{
dREQ;
req->type = EIO_OPEN;
req_set_path1 (req, pathname);
req->int1 = flags;
req->int2 = mode;
REQ_SEND;
}
void
aio_fsync (SV *fh, SV *callback = &PL_sv_undef)
ALIAS:
aio_fsync = EIO_FSYNC
aio_fdatasync = EIO_FDATASYNC
aio_syncfs = EIO_SYNCFS
PPCODE:
{
int fd = s_fileno_croak (fh, 0);
dREQ;
req->type = ix;
req->sv1 = newSVsv (fh);
req->int1 = fd;
REQ_SEND;
}
void
aio_sync_file_range (SV *fh, off_t offset, size_t nbytes, UV flags, SV *callback = &PL_sv_undef)
PPCODE:
{
int fd = s_fileno_croak (fh, 0);
dREQ;
req->type = EIO_SYNC_FILE_RANGE;
req->sv1 = newSVsv (fh);
req->int1 = fd;
req->offs = offset;
req->size = nbytes;
req->int2 = flags;
REQ_SEND;
}
void
aio_allocate (SV *fh, int mode, off_t offset, size_t len, SV *callback = &PL_sv_undef)
PPCODE:
{
int fd = s_fileno_croak (fh, 0);
dREQ;
req->type = EIO_FALLOCATE;
req->sv1 = newSVsv (fh);
req->int1 = fd;
req->int2 = mode;
req->offs = offset;
req->size = len;
REQ_SEND;
}
void
aio_close (SV *fh, SV *callback = &PL_sv_undef)
PPCODE:
{
int fd = s_fileno_croak (fh, 0);
dREQ;
#if 0
/* partially duplicate logic in s_fileno */
SvGETMAGIC (fh);
if (SvROK (fh))
{
fh = SvRV (fh);
req->int1 = close_fd;
req->sv2 = newSVsv (fh);
req->int2 = fd;
}
REQ_SEND;
}
void
aio_seek (SV *fh, SV *offset, int whence, SV *callback = &PL_sv_undef)
PPCODE:
{
int fd = s_fileno_croak (fh, 0);
dREQ;
req->type = EIO_SEEK;
req->sv1 = newSVsv (fh);
req->int1 = fd;
req->offs = SvVAL64 (offset);
req->int2 = whence;
REQ_SEND;
}
void
aio_read (SV *fh, SV *offset, SV *length, SV8 *data, IV dataoffset, SV *callback = &PL_sv_undef)
ALIAS:
aio_read = EIO_READ
aio_write = EIO_WRITE
PPCODE:
{
STRLEN svlen;
int fd = s_fileno_croak (fh, ix == EIO_WRITE);
char *svptr = SvPVbyte (data, svlen);
UV len = SvUV (length);
if (dataoffset < 0)
dataoffset += svlen;
if (dataoffset < 0 || dataoffset > svlen)
REQ_SEND;
}
}
void
aio_ioctl (SV *fh, unsigned long request, SV8 *arg, SV *callback = &PL_sv_undef)
ALIAS:
aio_ioctl = EIO_IOCTL
aio_fcntl = EIO_FCNTL
PPCODE:
{
int fd = s_fileno_croak (fh, 0);
char *svptr;
if (SvPOK (arg) || !SvNIOK (arg))
{
STRLEN svlen;
/* perl uses IOCPARM_LEN for fcntl, so we do, too */
#ifdef IOCPARM_LEN
STRLEN need = IOCPARM_LEN (request);
REQ_SEND;
}
}
void
aio_readlink (SV8 *pathname, SV *callback = &PL_sv_undef)
ALIAS:
aio_readlink = EIO_READLINK
aio_realpath = EIO_REALPATH
PPCODE:
{
dREQ;
req->type = ix;
req_set_path1 (req, pathname);
REQ_SEND;
}
void
aio_sendfile (SV *out_fh, SV *in_fh, off_t in_offset, size_t length, SV *callback = &PL_sv_undef)
PPCODE:
{
int ifd = s_fileno_croak (in_fh , 0);
int ofd = s_fileno_croak (out_fh, 1);
dREQ;
req->type = EIO_SENDFILE;
req->sv1 = newSVsv (out_fh);
req->int1 = ofd;
req->sv2 = newSVsv (in_fh);
req->int2 = ifd;
req->offs = in_offset;
req->size = length;
REQ_SEND;
}
void
aio_readahead (SV *fh, off_t offset, size_t length, SV *callback = &PL_sv_undef)
PPCODE:
{
int fd = s_fileno_croak (fh, 0);
dREQ;
req->type = EIO_READAHEAD;
req->sv1 = newSVsv (fh);
req->int1 = fd;
req->offs = offset;
req->size = length;
REQ_SEND;
}
void
aio_stat (SV8 *fh_or_path, SV *callback = &PL_sv_undef)
ALIAS:
aio_stat = EIO_STAT
aio_lstat = EIO_LSTAT
aio_statvfs = EIO_STATVFS
PPCODE:
{
dREQ;
req_set_fh_or_path (req, ix, ix == EIO_STATVFS ? EIO_FSTATVFS : EIO_FSTAT, fh_or_path);
REQ_SEND;
}
void
st_xtime ()
ALIAS:
st_atime = 0x01
st_mtime = 0x02
st_ctime = 0x04
st_btime = 0x08
st_xtime = 0x0f
PPCODE:
EXTEND (SP, 4);
if (ix & 0x01) PUSHs (newSVnv (PL_statcache.st_atime + 1e-9 * ATIMENSEC));
if (ix & 0x02) PUSHs (newSVnv (PL_statcache.st_mtime + 1e-9 * MTIMENSEC));
if (ix & 0x04) PUSHs (newSVnv (PL_statcache.st_ctime + 1e-9 * CTIMENSEC));
if (ix & 0x08) PUSHs (newSVnv (BTIMESEC + 1e-9 * BTIMENSEC));
void
st_xtimensec ()
ALIAS:
st_atimensec = 0x01
st_mtimensec = 0x02
st_ctimensec = 0x04
st_btimensec = 0x08
st_xtimensec = 0x0f
st_btimesec = 0x10
st_gen = 0x20
PPCODE:
EXTEND (SP, 4);
if (ix & 0x01) PUSHs (newSViv (ATIMENSEC));
if (ix & 0x02) PUSHs (newSViv (MTIMENSEC));
if (ix & 0x04) PUSHs (newSViv (CTIMENSEC));
if (ix & 0x08) PUSHs (newSViv (BTIMENSEC));
if (ix & 0x10) PUSHs (newSVuv (BTIMESEC));
if (ix & 0x20) PUSHs (newSVuv (ST_GEN));
UV
major (UV dev)
UV
makedev (UV maj, UV min)
CODE:
RETVAL = makedev (maj, min);
OUTPUT:
RETVAL
void
aio_utime (SV8 *fh_or_path, SV *atime, SV *mtime, SV *callback = &PL_sv_undef)
PPCODE:
{
dREQ;
req->nv1 = SvOK (atime) ? SvNV (atime) : -1.;
req->nv2 = SvOK (mtime) ? SvNV (mtime) : -1.;
req_set_fh_or_path (req, EIO_UTIME, EIO_FUTIME, fh_or_path);
REQ_SEND;
}
void
aio_truncate (SV8 *fh_or_path, SV *offset, SV *callback = &PL_sv_undef)
PPCODE:
{
dREQ;
req->offs = SvOK (offset) ? SvVAL64 (offset) : -1;
req_set_fh_or_path (req, EIO_TRUNCATE, EIO_FTRUNCATE, fh_or_path);
REQ_SEND;
}
void
aio_chmod (SV8 *fh_or_path, int mode, SV *callback = &PL_sv_undef)
PPCODE:
{
dREQ;
req->int2 = mode;
req_set_fh_or_path (req, EIO_CHMOD, EIO_FCHMOD, fh_or_path);
REQ_SEND;
}
void
aio_chown (SV8 *fh_or_path, SV *uid, SV *gid, SV *callback = &PL_sv_undef)
PPCODE:
{
dREQ;
req->int2 = SvOK (uid) ? SvIV (uid) : -1;
req->int3 = SvOK (gid) ? SvIV (gid) : -1;
req_set_fh_or_path (req, EIO_CHOWN, EIO_FCHOWN, fh_or_path);
REQ_SEND;
}
void
aio_readdirx (SV8 *pathname, IV flags, SV *callback = &PL_sv_undef)
PPCODE:
{
dREQ;
req->type = EIO_READDIR;
req->int1 = flags | EIO_READDIR_DENTS | EIO_READDIR_CUSTOM1;
if (flags & EIO_READDIR_DENTS)
req->int1 |= EIO_READDIR_CUSTOM2;
req_set_path1 (req, pathname);
REQ_SEND;
}
void
aio_mkdir (SV8 *pathname, int mode, SV *callback = &PL_sv_undef)
PPCODE:
{
dREQ;
req->type = EIO_MKDIR;
req->int2 = mode;
req_set_path1 (req, pathname);
REQ_SEND;
}
void
aio_unlink (SV8 *pathname, SV *callback = &PL_sv_undef)
ALIAS:
aio_unlink = EIO_UNLINK
aio_rmdir = EIO_RMDIR
aio_readdir = EIO_READDIR
PPCODE:
{
dREQ;
req->type = ix;
req_set_path1 (req, pathname);
REQ_SEND;
}
void
aio_link (SV8 *oldpath, SV8 *newpath, SV *callback = &PL_sv_undef)
ALIAS:
aio_link = EIO_LINK
aio_symlink = EIO_SYMLINK
aio_rename = EIO_RENAME
PPCODE:
{
eio_wd wd2 = 0;
dREQ;
req->type = ix;
req_set_path1 (req, oldpath);
req_set_path (newpath, &req->sv2, &req->sv4, &wd2, &req->ptr2);
req->int3 = (long)wd2;
REQ_SEND;
}
void
aio_rename2 (SV8 *oldpath, SV8 *newpath, int flags = 0, SV *callback = &PL_sv_undef)
PPCODE:
{
eio_wd wd2 = 0;
dREQ;
req->type = EIO_RENAME;
req_set_path1 (req, oldpath);
req_set_path (newpath, &req->sv2, &req->sv4, &wd2, &req->ptr2);
req->int2 = flags;
req->int3 = (long)wd2;
REQ_SEND;
}
void
aio_mknod (SV8 *pathname, int mode, UV dev, SV *callback = &PL_sv_undef)
PPCODE:
{
dREQ;
req->type = EIO_MKNOD;
req->int2 = (mode_t)mode;
req->offs = dev;
req_set_path1 (req, pathname);
REQ_SEND;
}
void
aio_mtouch (SV8 *data, IV offset = 0, SV *length = &PL_sv_undef, int flags = -1, SV *callback = &PL_sv_undef)
ALIAS:
aio_mtouch = EIO_MTOUCH
aio_msync = EIO_MSYNC
PPCODE:
{
STRLEN svlen;
char *svptr = SvPVbyte (data, svlen);
UV len = SvUV (length);
if (flags < 0)
flags = ix == EIO_MSYNC ? EIO_MS_SYNC : 0;
if (offset < 0)
offset += svlen;
req->ptr2 = (char *)svptr + offset;
req->size = len;
req->int1 = flags;
REQ_SEND;
}
}
void
aio_mlock (SV8 *data, IV offset = 0, SV *length = &PL_sv_undef, SV *callback = &PL_sv_undef)
PPCODE:
{
STRLEN svlen;
char *svptr = SvPVbyte (data, svlen);
UV len = SvUV (length);
if (offset < 0)
offset += svlen;
if (offset < 0 || offset > svlen)
croak ("offset outside of scalar");
req->sv2 = SvREFCNT_inc (data);
req->ptr2 = (char *)svptr + offset;
req->size = len;
REQ_SEND;
}
}
void
aio_mlockall (IV flags, SV *callback = &PL_sv_undef)
PPCODE:
{
dREQ;
req->type = EIO_MLOCKALL;
req->int1 = flags;
REQ_SEND;
}
void
aio_fiemap (SV *fh, off_t start, SV *length, U32 flags, SV *count, SV *callback = &PL_sv_undef)
PPCODE:
{
int fd = s_fileno_croak (fh, 0);
dREQ;
req->type = EIO_CUSTOM;
req->sv1 = newSVsv (fh);
req->int1 = fd;
req->feed = fiemap;
#if HAVE_FIEMAP
req->size = SvOK (length) ? SvVAL64 (length) : ~0ULL;
req->int2 = flags;
req->int3 = SvOK (count) ? SvIV (count) : -1;
#endif
REQ_SEND;
}
void
aio_slurp (SV *pathname, off_t offset, UV length, SV8 *data, SV *callback = &PL_sv_undef)
PPCODE:
{
char *svptr = 0;
sv_clear_foreign (data);
if (length) /* known length, directly read into scalar */
{
if (!SvPOK (data) || SvLEN (data) >= SvCUR (data))
svptr = sv_grow (data, length + 1);
else if (SvCUR (data) < length)
SvREADONLY_on (data);
req->flags |= FLAG_SV2_RO_OFF;
}
REQ_SEND;
}
}
void
aio_busy (double delay, SV *callback = &PL_sv_undef)
PPCODE:
{
dREQ;
req->type = EIO_BUSY;
req->nv1 = delay < 0. ? 0. : delay;
REQ_SEND;
}
void
aio_group (SV *callback = &PL_sv_undef)
PPCODE:
{
dREQ;
req->type = EIO_GROUP;
PUTBACK;
req_submit (req);
SPAGAIN;
XPUSHs (req_sv (req, aio_grp_stash));
}
void
aio_nop (SV *callback = &PL_sv_undef)
ALIAS:
aio_nop = EIO_NOP
aio_sync = EIO_SYNC
PPCODE:
{
dREQ;
req->type = ix;
REQ_SEND;
}
int
aioreq_pri (int pri = NO_INIT)
IV
sendfile (aio_wfd ofh, aio_rfd ifh, off_t offset, size_t count)
CODE:
RETVAL = eio_sendfile_sync (ofh, ifh, offset, count);
OUTPUT:
RETVAL
void
mmap (SV *scalar, STRLEN length, int prot, int flags, SV *fh = &PL_sv_undef, off_t offset = 0)
PPCODE:
sv_clear_foreign (scalar);
{
int fd = SvOK (fh) ? s_fileno_croak (fh, flags & PROT_WRITE) : -1;
void *addr = (void *)mmap (0, length, prot, flags, fd, offset);
if (addr == (void *)-1)
XSRETURN_NO;
sv_set_foreign (scalar, &mmap_vtbl, addr, length);
if (!(prot & PROT_WRITE))
struct statx_timestamp *ts = (struct statx_timestamp *)((char *)&stx + ix);
RETVAL = ts->tv_nsec;
#else
RETVAL = 0;
#endif
OUTPUT:
RETVAL
void
accept4 (aio_rfd rfh, SV *sockaddr, int salen, int flags)
PPCODE:
{
SV *retval;
#if HAVE_ACCEPT4
socklen_t salen_ = salen ? salen + 1 : 0;
if (salen)
{
sv_upgrade (sockaddr, SVt_PV);
sv_grow (sockaddr, salen_);
}
#else
errno = ENOSYS;
RETVAL = -1;
#endif
OUTPUT:
RETVAL
void
pipe2 (int flags = 0)
PROTOTYPE: ;$
PPCODE:
{
int fd[2];
int res;
if (flags)
#if HAVE_PIPE2
res = pipe2 (fd, flags);
#else
res = (errno = ENOSYS, -1);
#endif
if (!res)
{
EXTEND (SP, 2);
PUSHs (newmortalFH (fd[0], O_RDONLY));
PUSHs (newmortalFH (fd[1], O_WRONLY));
}
}
void
pidfd_open (int pid, unsigned int flags = 0)
PPCODE:
{
/*GENDEF0_SYSCALL(pidfd_open,434)*/
int fd = syscall (SYS_pidfd_open, pid, flags);
XPUSHs (newmortalFH (fd, O_RDWR));
}
int
pidfd_send_signal (SV *pidfh, int sig, SV *siginfo = &PL_sv_undef, unsigned int flags = 0)
PPCODE:
{
int res;
#if HAVE_SIGINFO_T
siginfo_t si = { 0 };
if (SvOK (siginfo))
{
HV *hv;
SV **svp;
res = syscall (SYS_pidfd_send_signal, s_fileno_croak (pidfh, 0), sig, SvOK (siginfo) ? &si : 0, flags);
#else
res = (errno = ENOSYS, -1);
#endif
XPUSHs (sv_2mortal (newSViv (res)));
}
void
pidfd_getfd (SV *pidfh, int targetfd, unsigned int flags = 0)
PPCODE:
{
/*GENDEF0_SYSCALL(pidfd_getfd,438)*/
int fd = syscall (SYS_pidfd_getfd, s_fileno_croak (pidfh, 0), targetfd, flags);
XPUSHs (newmortalFH (fd, O_RDWR));
}
void
eventfd (unsigned int initval = 0, int flags = 0)
PPCODE:
{
int fd;
#if HAVE_EVENTFD
fd = eventfd (initval, flags);
#else
fd = (errno = ENOSYS, -1);
#endif
XPUSHs (newmortalFH (fd, O_RDWR));
}
void
timerfd_create (int clockid, int flags = 0)
PPCODE:
{
int fd;
#if HAVE_TIMERFD
fd = timerfd_create (clockid, flags);
#else
fd = (errno = ENOSYS, -1);
#endif
XPUSHs (newmortalFH (fd, O_RDWR));
}
void
timerfd_settime (SV *fh, int flags, NV interval, NV value)
PPCODE:
{
int fd = s_fileno_croak (fh, 0);
#if HAVE_TIMERFD
int res;
struct itimerspec its, ots;
ts_set (&its.it_interval, interval);
ts_set (&its.it_value , value);
res = timerfd_settime (fd, flags, &its, &ots);
PUSHs (newSVnv (ts_get (&ots.it_interval)));
PUSHs (newSVnv (ts_get (&ots.it_value)));
}
#else
errno = ENOSYS;
#endif
}
void
timerfd_gettime (SV *fh)
PPCODE:
{
int fd = s_fileno_croak (fh, 0);
#if HAVE_TIMERFD
int res;
struct itimerspec ots;
res = timerfd_gettime (fd, &ots);
if (!res)
{
EXTEND (SP, 2);
PUSHs (newSVnv (ts_get (&ots.it_interval)));
PUSHs (newSVnv (ts_get (&ots.it_value)));
}
#else
errno = ENOSYS;
#endif
}
void
memfd_create (octet_string pathname, int flags = 0)
PPCODE:
{
int fd;
#if HAVE_MEMFD_CREATE
fd = memfd_create (pathname, flags);
#else
fd = (errno = ENOSYS, -1);
#endif
XPUSHs (newmortalFH (fd, O_RDWR));
}
MODULE = IO::AIO PACKAGE = IO::AIO::REQ
void
cancel (aio_req_ornot req)
CODE:
eio_cancel (req);
void
cb (aio_req_ornot req, SV *callback = NO_INIT)
PPCODE:
{
if (GIMME_V != G_VOID)
XPUSHs (req->callback ? sv_2mortal (newRV_inc (req->callback)) : &PL_sv_undef);
if (items > 1)
{
SV *cb_cv = get_cb (callback);
SvREFCNT_dec (req->callback);
req->callback = SvREFCNT_inc (cb_cv);
}
}
MODULE = IO::AIO PACKAGE = IO::AIO::GRP
void
add (aio_req grp, ...)
PPCODE:
{
int i;
if (grp->int1 == 2)
croak ("cannot add requests to IO::AIO::GRP after the group finished");
for (i = 1; i < items; ++i )
{
aio_req req;
( run in 1.059 second using v1.01-cache-2.11-cpan-5511b514fd6 )