IO-AIO
view release on metacpan or search on metacpan
|| fcntl (pipefd [0], F_SETFD, FD_CLOEXEC) < 0
#endif
|| close (pipefd [1]) < 0
)
croak ("IO::AIO: unable to create dummy pipe for aio_close");
close_fd = pipefd [0];
}
reinit ();
}
void
reinit ()
PROTOTYPE:
void
max_poll_reqs (unsigned int nreqs)
PROTOTYPE: $
CODE:
eio_set_max_poll_reqs (nreqs);
void
max_poll_time (double nseconds)
PROTOTYPE: $
CODE:
eio_set_max_poll_time (nseconds);
void
min_parallel (unsigned int nthreads)
PROTOTYPE: $
CODE:
eio_set_min_parallel (nthreads);
void
max_parallel (unsigned int nthreads)
PROTOTYPE: $
CODE:
eio_set_max_parallel (nthreads);
void
max_idle (unsigned int nthreads)
PROTOTYPE: $
CODE:
eio_set_max_idle (nthreads);
void
idle_timeout (unsigned int seconds)
PROTOTYPE: $
CODE:
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);
SvGETMAGIC (fh);
}
if (SvTYPE (fh) == SVt_PVGV)
{
/* perl filehandle */
PerlIOUnix_refcnt_inc (fd);
do_close ((GV *)fh, 1);
req->type = EIO_CLOSE;
req->int1 = fd;
/*req->sv2 = newSVsv (fh);*/ /* since we stole the fd, no need to keep the fh */
}
else
#endif
{
/* fd number */
req->type = EIO_DUP2;
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)
croak ("dataoffset outside of data scalar");
if (ix == EIO_WRITE)
{
/* write: check length and adjust. */
if (!SvOK (length) || len + dataoffset > svlen)
len = svlen - dataoffset;
}
else
{
/* read: check type and grow scalar as necessary */
if (!SvPOK (data) || SvLEN (data) >= SvCUR (data))
svptr = sv_grow (data, len + dataoffset + 1);
else if (SvCUR (data) < len + dataoffset)
croak ("length + dataoffset outside of scalar, and cannot grow");
}
{
dREQ;
req->type = ix;
req->sv1 = newSVsv (fh);
req->int1 = fd;
req->offs = SvOK (offset) ? SvVAL64 (offset) : -1;
req->size = len;
req->sv2 = SvREFCNT_inc (data);
req->ptr2 = (char *)svptr + dataoffset;
req->stroffset = dataoffset;
if (!SvREADONLY (data))
{
SvREADONLY_on (data);
req->flags |= FLAG_SV2_RO_OFF;
}
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);
#else
STRLEN need = 256;
#endif
if (svlen < need)
svptr = SvGROW (arg, need);
}
else
svptr = (char *)SvIV (arg);
{
dREQ;
req->type = ix;
req->sv1 = newSVsv (fh);
req->int1 = fd;
req->int2 = (long)request;
req->sv2 = SvREFCNT_inc (arg);
req->ptr2 = svptr;
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)
ALIAS:
minor = 1
CODE:
RETVAL = ix ? minor (dev) : major (dev);
OUTPUT:
RETVAL
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;
if (offset < 0 || offset > svlen)
croak ("offset outside of scalar");
if (!SvOK (length) || len + offset > svlen)
len = svlen - offset;
{
dREQ;
req->type = ix;
req->sv2 = SvREFCNT_inc (data);
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");
if (!SvOK (length) || len + offset > svlen)
len = svlen - offset;
{
dREQ;
req->type = EIO_MLOCK;
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
/* keep our fingers crossed that the next two types are 64 bit */
req->offs = start;
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)
croak ("length outside of scalar, and cannot grow");
else
svptr = SvPVbyte_nolen (data);
}
{
dREQ;
req->type = EIO_SLURP;
req_set_path1 (req, pathname);
req->offs = offset;
req->size = length;
req->sv2 = SvREFCNT_inc (data);
req->ptr2 = svptr;
if (!SvREADONLY (data))
{
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)
CODE:
RETVAL = next_pri;
if (items > 0)
{
if (pri < EIO_PRI_MIN) pri = EIO_PRI_MIN;
if (pri > EIO_PRI_MAX) pri = EIO_PRI_MAX;
next_pri = pri;
}
OUTPUT:
RETVAL
void
aioreq_nice (int nice = 0)
CODE:
nice = next_pri - nice;
if (nice < EIO_PRI_MIN) nice = EIO_PRI_MIN;
if (nice > EIO_PRI_MAX) nice = EIO_PRI_MAX;
next_pri = nice;
void
flush ()
CODE:
while (eio_nreqs ())
{
poll_wait ();
poll_cb ();
}
int
poll ()
CODE:
poll_wait ();
RETVAL = poll_cb ();
OUTPUT:
RETVAL
int
poll_fileno ()
CODE:
RETVAL = s_epipe_fd (&respipe);
OUTPUT:
RETVAL
int
poll_cb (...)
PROTOTYPE:
CODE:
RETVAL = poll_cb ();
OUTPUT:
RETVAL
void
poll_wait ()
CODE:
poll_wait ();
int
nreqs ()
CODE:
RETVAL = eio_nreqs ();
OUTPUT:
RETVAL
int
nready ()
CODE:
RETVAL = eio_nready ();
OUTPUT:
RETVAL
int
npending ()
CODE:
RETVAL = eio_npending ();
OUTPUT:
RETVAL
int
nthreads ()
CODE:
RETVAL = eio_nthreads ();
OUTPUT:
RETVAL
int
fadvise (aio_rfd fh, off_t offset, off_t length, IV advice)
CODE:
RETVAL = posix_fadvise (fh, offset, length, advice);
OUTPUT:
RETVAL
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))
SvREADONLY_on (scalar);
XSRETURN_YES;
}
void
munmap (SV *scalar)
CODE:
sv_clear_foreign (scalar);
SV *
mremap (SV *scalar, STRLEN new_length, int flags = MREMAP_MAYMOVE, IV new_address = 0)
CODE:
{
MAGIC *mg = mg_findext (scalar, FOREIGN_MAGIC, &mmap_vtbl);
void *new;
if (!mg || SvPVX (scalar) != mg->mg_ptr)
croak ("IO::AIO::mremap: scalar not mapped by IO::AIO::mmap or improperly modified");
new = mremap (mg->mg_ptr, (size_t)mg->mg_obj, new_length, flags, (void *)new_address);
RETVAL = &PL_sv_no;
if (new != (void *)-1)
{
RETVAL = new == (void *)mg->mg_ptr
? newSVpvn ("0 but true", 10)
: &PL_sv_yes;
mg->mg_ptr = (char *)new;
mg->mg_obj = (SV *)new_length;
SvPVX (scalar) = mg->mg_ptr;
SvCUR_set (scalar, new_length);
}
}
OUTPUT:
RETVAL
int
madvise (SV *scalar, IV offset = 0, SV *length = &PL_sv_undef, IV advice_or_prot)
ALIAS:
mprotect = 1
CODE:
{
STRLEN svlen;
void *addr = SvPVbyte (scalar, svlen);
STRLEN len = SvUV (length);
#endif
OUTPUT:
RETVAL
NV
stx_atime ()
PROTOTYPE:
ALIAS:
stx_atime = STATX_OFFSET_atime
stx_btime = STATX_OFFSET_btime
stx_ctime = STATX_OFFSET_ctime
stx_mtime = STATX_OFFSET_mtime
CODE:
#if HAVE_STATX
struct statx_timestamp *ts = (struct statx_timestamp *)((char *)&stx + ix);
RETVAL = ts->tv_sec + ts->tv_nsec * 1e-9;
#else
XSRETURN_UNDEF;
#endif
OUTPUT:
RETVAL
VAL64
stx_atimesec ()
PROTOTYPE:
ALIAS:
stx_atimesec = STATX_OFFSET_atime
stx_btimesec = STATX_OFFSET_btime
stx_ctimesec = STATX_OFFSET_ctime
stx_mtimesec = STATX_OFFSET_mtime
CODE:
#if HAVE_STATX
struct statx_timestamp *ts = (struct statx_timestamp *)((char *)&stx + ix);
RETVAL = ts->tv_sec;
#else
XSRETURN_UNDEF;
#endif
OUTPUT:
RETVAL
U32
stx_atimensec ()
PROTOTYPE:
ALIAS:
stx_atimensec = STATX_OFFSET_atime
stx_btimensec = STATX_OFFSET_btime
stx_ctimensec = STATX_OFFSET_ctime
stx_mtimensec = STATX_OFFSET_mtime
CODE:
#if HAVE_STATX
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_);
}
int res = accept4 (rfh, salen ? (struct sockaddr *)SvPVX (sockaddr) : 0, salen ? &salen_ : 0, flags);
retval = newmortalFH (res, O_RDWR);
if (res >= 0 && salen > 0)
{
if (salen_ > salen + 1)
salen_ = salen + 1;
SvPOK_only (sockaddr);
SvCUR_set (sockaddr, salen_);
}
#else
errno = ENOSYS;
retval = &PL_sv_undef;
#endif
XPUSHs (retval);
}
ssize_t
splice (aio_rfd rfh, SV *off_in, aio_wfd wfh, SV *off_out, size_t length, unsigned int flags)
CODE:
{
#if HAVE_LINUX_SPLICE
loff_t off_in_, off_out_;
RETVAL = splice (
rfh, SvOK (off_in ) ? (off_in_ = SvVAL64 (off_in )), &off_in_ : 0,
wfh, SvOK (off_out) ? (off_out_ = SvVAL64 (off_out)), &off_out_ : 0,
length, flags
);
#else
RETVAL = EIO_ENOSYS ();
#endif
}
OUTPUT:
RETVAL
ssize_t
tee (aio_rfd rfh, aio_wfd wfh, size_t length, unsigned int flags)
CODE:
#if HAVE_LINUX_SPLICE
RETVAL = tee (rfh, wfh, length, flags);
#else
RETVAL = EIO_ENOSYS ();
#endif
OUTPUT:
RETVAL
int
pipesize (aio_rfd rfh, int new_size = -1)
PROTOTYPE: $;$
CODE:
#if defined(F_SETPIPE_SZ) && defined(F_GETPIPE_SZ)
if (new_size >= 0)
RETVAL = fcntl (rfh, F_SETPIPE_SZ, new_size);
else
RETVAL = fcntl (rfh, F_GETPIPE_SZ);
#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
else
res = pipe (fd);
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;
if (!SvROK (siginfo) || SvTYPE (SvRV (siginfo)) != SVt_PVHV)
croak ("siginfo argument must be a hashref with 'code', 'pid', 'uid' and 'value_int' or 'value_ptr' members, caught");
hv = (HV *)SvRV (siginfo);
if ((svp = hv_fetchs (hv, "code" , 0))) si.si_code = SvIV (*svp);
if ((svp = hv_fetchs (hv, "pid" , 0))) si.si_pid = SvIV (*svp);
if ((svp = hv_fetchs (hv, "uid" , 0))) si.si_uid = SvIV (*svp);
if ((svp = hv_fetchs (hv, "value_int", 0))) si.si_value.sival_int = SvIV (*svp);
if ((svp = hv_fetchs (hv, "value_ptr", 0))) si.si_value.sival_ptr = (void *)SvIV (*svp);
}
/*GENDEF0_SYSCALL(pidfd_send_signal,424)*/
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);
if (!res)
{
EXTEND (SP, 2);
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));
}
int
fexecve (SV *fh, SV *args, SV *envs = &PL_sv_undef)
CODE:
{
int fd = PerlIO_fileno (IoIFP (sv_2io (fh)));
char **envp, **argv;
argv = extract_stringvec (args, "IO::AIO::fexecve: args must be an array of strings");
if (!SvOK (envs))
{
extern char **environ;
envp = environ;
}
else
envp = extract_stringvec (envs, "IO::AIO::fexecve: envs must be an array of strings");
#if HAVE_FEXECVE
RETVAL = fexecve (fd, argv, envp);
#else
RETVAL = (errno = ENOSYS, -1);
#endif
}
OUTPUT: RETVAL
int
mount (octet_string special, octet_string path, octet_string fstype, UV flags = 0, octet_string_ornull data = 0)
CODE:
#if HAVE_MOUNT
RETVAL = mount (special, path, fstype, flags, data);
#else
RETVAL = (errno = ENOSYS, -1);
#endif
OUTPUT: RETVAL
int
umount (octet_string path, int flags = 0)
CODE:
if (flags)
#if HAVE_UMOUNT2
RETVAL = umount2 (path, flags);
#else
RETVAL = (errno = ENOSYS, -1);
#endif
else
#if HAVE_UMOUNT
RETVAL = umount (path);
#else
RETVAL = (errno = ENOSYS, -1);
#endif
OUTPUT: RETVAL
rl.rlim_max &= ~bit; /* too high, remove bit again */
}
/* now, raise the soft limit to the max permitted */
if (0 == getrlimit (RLIMIT_NOFILE, &rl))
{
rl.rlim_cur = rl.rlim_max;
if (0 == setrlimit (RLIMIT_NOFILE, &rl))
errno = EPERM;
}
}
#endif
fail:
XSRETURN_UNDEF;
}
void _on_next_submit (SV *cb)
CODE:
SvREFCNT_dec (on_next_submit);
on_next_submit = SvOK (cb) ? newSVsv (cb) : 0;
PROTOTYPES: DISABLE
MODULE = IO::AIO PACKAGE = IO::AIO::WD
BOOT:
{
newCONSTSUB (aio_stash, "CWD" , newSVaio_wd (EIO_CWD ));
newCONSTSUB (aio_stash, "INVALID_WD", newSVaio_wd (EIO_INVALID_WD));
}
void
DESTROY (SV *self)
CODE:
{
aio_wd wd = SvAIO_WD (self);
#if HAVE_AT
{
SV *callback = &PL_sv_undef;
dREQ; /* clobbers next_pri :/ */
next_pri = req->pri; /* restore next_pri */
req->pri = EIO_PRI_MAX; /* better use max. priority to conserve fds */
req->type = EIO_WD_CLOSE;
req->wd = wd;
REQ_SEND;
}
#else
eio_wd_close_sync (wd);
#endif
}
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;
if (GIMME_V != G_VOID)
XPUSHs (sv_2mortal (newSVsv (ST (i))));
req = SvAIO_REQ (ST (i));
if (req)
eio_grp_add (grp, req);
}
}
void
cancel_subs (aio_req_ornot req)
CODE:
req_cancel_subs (req);
void
result (aio_req grp, ...)
CODE:
{
int i;
AV *av;
grp->errorno = errno;
av = newAV ();
av_extend (av, items - 1);
for (i = 1; i < items; ++i )
av_push (av, newSVsv (ST (i)));
SvREFCNT_dec (grp->sv1);
grp->sv1 = (SV *)av;
}
void
errno (aio_req grp, int errorno = errno)
CODE:
grp->errorno = errorno;
void
limit (aio_req grp, int limit)
CODE:
eio_grp_limit (grp, limit);
void
feed (aio_req grp, SV *callback = &PL_sv_undef)
CODE:
{
SvREFCNT_dec (grp->sv2);
grp->sv2 = newSVsv (callback);
( run in 1.371 second using v1.01-cache-2.11-cpan-71847e10f99 )