POSIX-2008
view release on metacpan or search on metacpan
MODULE = POSIX::2008 PACKAGE = POSIX::2008
PROTOTYPES: ENABLE
INCLUDE: const-xs.inc
#ifdef PSX2008_HAS_ABORT
void
abort();
PPCODE:
/* Using PPCODE instead of an empty body avoids the (unnecessary)
* XSRETURN_EMPTY epilog and saves quite a few bytes. */
abort();
#endif
#ifdef PSX2008_HAS_SYNC
void
sync();
PPCODE:
sync();
#endif
#ifdef PSX2008_HAS_A64L
long
a64l(char *s);
#endif
clock();
#endif
#ifdef PSX2008_HAS_CLOCK_GETCPUCLOCKID
void
clock_getcpuclockid(pid_t pid=0);
INIT:
int rv;
clockid_t clock_id;
PPCODE:
rv = clock_getcpuclockid(pid, &clock_id);
if (LIKELY(rv == 0))
PUSH_INT_OR_PV(clock_id);
else {
SETERRNO(rv, rv);
PUSHs(&PL_sv_undef);
}
#endif
} STMT_END
#ifdef PSX2008_HAS_CLOCK_GETRES
void
clock_getres(clockid_t clock_id=CLOCK_REALTIME);
ALIAS:
clock_gettime = 1
INIT:
int rv;
struct timespec res;
PPCODE:
{
rv = (ix == 0)
? clock_getres(clock_id, &res)
: clock_gettime(clock_id, &res);
if (rv == 0)
PUSH_TIMESPEC(res);
}
#endif
} STMT_END
#ifdef PSX2008_HAS_CLOCK_NANOSLEEP
void
clock_nanosleep(clockid_t clock_id, int flags, SV *sec, long nsec=0);
PROTOTYPE: $$@
INIT:
int rv;
struct timespec request;
struct timespec remain = {0};
PPCODE:
{
SvGETMAGIC(sec);
if (items == 3 && LOOKS_LIKE_NV(sec))
TIMESPEC_FROM_NV_nomg(request, sec);
else
TIMESPEC_FROM_IV_nomg(request, sec, nsec);
rv = clock_nanosleep(clock_id, flags, &request, &remain);
if (rv == 0 || (errno = rv) == EINTR)
PUSH_TIMESPEC(remain);
}
#endif
#ifdef PSX2008_HAS_CLOCK_SETTIME
void
clock_settime(clockid_t clock_id, SV *sec, long nsec=0);
PROTOTYPE: $@
INIT:
struct timespec tp;
PPCODE:
{
SvGETMAGIC(sec);
if (items == 2 && LOOKS_LIKE_NV(sec))
TIMESPEC_FROM_NV_nomg(tp, sec);
else
TIMESPEC_FROM_IV_nomg(tp, sec, nsec);
if (clock_settime(clock_id, &tp) == 0)
mPUSHp("0 but true", 10);
else
PUSHs(&PL_sv_undef);
#endif
#ifdef PSX2008_HAS_NANOSLEEP
void
nanosleep(SV *sec, long nsec=0);
PROTOTYPE: @
INIT:
struct timespec request;
struct timespec remain = {0};
PPCODE:
{
SvGETMAGIC(sec);
if (items == 1 && LOOKS_LIKE_NV(sec))
TIMESPEC_FROM_NV_nomg(request, sec);
else
TIMESPEC_FROM_IV_nomg(request, sec, nsec);
if (nanosleep(&request, &remain) == 0 || errno == EINTR)
PUSH_TIMESPEC(remain);
}
OUTPUT:
RETVAL
#endif
#ifdef PSX2008_HAS_FNMATCH
void
fnmatch(const char *pattern, const char *string, int flags);
INIT:
int rv;
PPCODE:
rv = fnmatch(pattern, string, flags);
if (LIKELY(rv == 0 || rv == FNM_NOMATCH))
mPUSHs(newSViv(rv));
else
PUSHs(&PL_sv_undef);
#endif
#ifdef PSX2008_HAS_KILLPG
SysRetTrue
SysRetTrue
raise(int sig);
#endif
#ifdef PSX2008_HAS_GETDATE
void
getdate(const char *string);
INIT:
struct tm *tm = getdate(string);
PPCODE:
if (tm) {
EXTEND(SP, 9);
mPUSHs(newSViv(tm->tm_sec));
mPUSHs(newSViv(tm->tm_min));
mPUSHs(newSViv(tm->tm_hour));
mPUSHs(newSViv(tm->tm_mday));
mPUSHs(newSViv(tm->tm_mon));
mPUSHs(newSViv(tm->tm_year));
mPUSHs(newSViv(tm->tm_wday));
mPUSHs(newSViv(tm->tm_yday));
#define TM_COUNT_MAX 11
void
strptime(const char *s, const char *format, ...);
PROTOTYPE: $$@
INIT:
struct tm tm;
char *remainder;
Size_t i, tm_count;
AV *tm_av = NULL;
U8 gimme;
PPCODE:
{
if (items > 2) {
if (items > TM_COUNT_MAX + 2) {
DumpDarkSuckerjerk:
croak("%s::strptime: Too many arguments", PACKNAME);
}
SV *tm_arg = ST(2l);
SvGETMAGIC(tm_arg);
if (SvIsARRAY(tm_arg)) {
if (items == 3)
void
gethostname();
INIT:
#if defined(HOST_NAME_MAX) && HOST_NAME_MAX > 256
char name[HOST_NAME_MAX];
#elif defined(MAXHOSTNAMELEN) && MAXHOSTNAMELEN > 256
char name[MAXHOSTNAMELEN];
#else
char name[256];
#endif
PPCODE:
if (LIKELY(gethostname(name, sizeof(name)) == 0))
mPUSHp(name, _strnlen(name, sizeof(name)));
else
PUSHs(&PL_sv_undef);
#endif
#ifdef PSX2008_HAS_GETITIMER
void
getitimer(int which);
INIT:
struct itimerval value;
PPCODE:
if (getitimer(which, &value) == 0) {
EXTEND(SP, 2); /* Stack already has room for 2 items. */
mPUSHs(newSViv(value.it_interval.tv_sec));
mPUSHs(newSViv(value.it_interval.tv_usec));
mPUSHs(newSViv(value.it_value.tv_sec));
mPUSHs(newSViv(value.it_value.tv_usec));
}
#endif
#ifdef PSX2008_HAS_SETITIMER
void
setitimer(int which, \
time_t int_sec, long int_usec, \
time_t val_sec, long val_usec);
PROTOTYPE: $@
INIT:
struct itimerval value = { {int_sec, int_usec}, {val_sec, val_usec} };
struct itimerval ovalue;
PPCODE:
if (setitimer(which, &value, &ovalue) == 0) {
/* We already know the stack is long enough. */
mPUSHs(newSViv(ovalue.it_interval.tv_sec));
mPUSHs(newSViv(ovalue.it_interval.tv_usec));
mPUSHs(newSViv(ovalue.it_value.tv_sec));
mPUSHs(newSViv(ovalue.it_value.tv_usec));
}
#endif
#ifdef PSX2008_HAS_NICE
void
nice(int incr);
INIT:
SETERRNO(0, 0);
PPCODE:
{
int rv = nice(incr);
if (rv != -1 || errno == 0)
mPUSHs(newSViv(rv));
else
PUSHs(&PL_sv_undef);
}
#endif
#ifdef PSX2008_HAS_GETPRIORITY
void
getpriority(int which=PRIO_PROCESS, id_t who=0);
INIT:
SETERRNO(0, 0);
PPCODE:
{
int rv = getpriority(which, who);
if (rv != -1 || errno == 0)
mPUSHs(newSViv(rv));
else
PUSHs(&PL_sv_undef);
}
#endif
mPUSHs(newSViv(utxent->ut_pid)); \
mPUSHs(newSViv(utxent->ut_type)); \
mPUSHs(newSViv(utxent->ut_tv.tv_sec)); \
mPUSHs(newSViv(utxent->ut_tv.tv_usec)); \
} \
}
#ifdef PSX2008_HAS_ENDUTXENT
void
endutxent();
PPCODE:
endutxent();
#endif
#ifdef PSX2008_HAS_GETUTXENT
void
getutxent();
PPCODE:
{
struct utmpx *utxent = getutxent();
RETURN_UTXENT;
}
#endif
#ifdef PSX2008_HAS_GETUTXID
void
getutxid(short ut_type, SV *ut_id=NULL);
INIT:
struct utmpx *utxent;
struct utmpx utxent_req = {.ut_type=ut_type};
const Size_t ut_id_size = sizeof(utxent_req.ut_id);
PPCODE:
{
if (ut_id) {
STRLEN pvlen;
const char *pv = SvPV_const(ut_id, pvlen);
const STRLEN ut_id_len = ut_id_size < pvlen ? ut_id_size : pvlen;
Copy(pv, utxent_req.ut_id, ut_id_len, char);
}
utxent = getutxid(&utxent_req);
RETURN_UTXENT;
}
#endif
#ifdef PSX2008_HAS_GETUTXLINE
void
getutxline(SV *ut_line);
INIT:
struct utmpx *utxent;
struct utmpx utxent_req = {0};
const Size_t ut_line_size = sizeof(utxent_req.ut_line);
PPCODE:
{
STRLEN pvlen;
const char *pv = SvPV_const(ut_line, pvlen);
const STRLEN ut_line_len = ut_line_size < pvlen ? ut_line_size : pvlen;
Copy(pv, utxent_req.ut_line, ut_line_len, char);
utxent = getutxline(&utxent_req);
RETURN_UTXENT;
}
#endif
#ifdef PSX2008_HAS_SETUTXENT
void
setutxent();
PPCODE:
setutxent();
#endif
#ifdef PSX2008_HAS_DRAND48
NV
drand48();
#endif
#ifdef PSX2008_HAS_ERAND48
void
erand48(unsigned short X0, unsigned short X1, unsigned short X2);
INIT:
unsigned short xsubi[3] = { X0, X1, X2 };
double result = erand48(xsubi);
PPCODE:
/* We already know the stack is long enough. */
mPUSHs(newSVnv((NV)result));
mPUSHs(newSVuv(xsubi[0]));
mPUSHs(newSVuv(xsubi[1]));
mPUSHs(newSVuv(xsubi[2]));
#endif
#ifdef PSX2008_HAS_JRAND48
void
jrand48(unsigned short X0, unsigned short X1, unsigned short X2);
ALIAS:
nrand48 = 1
INIT:
unsigned short xsubi[3] = { X0, X1, X2 };
long result = (ix == 0) ? jrand48(xsubi) : nrand48(xsubi);
PPCODE:
/* We already know the stack is long enough. */
mPUSHs(newSViv((IV)result));
mPUSHs(newSVuv(xsubi[0]));
mPUSHs(newSVuv(xsubi[1]));
mPUSHs(newSVuv(xsubi[2]));
#endif
#ifdef PSX2008_HAS_LRAND48
long
mrand48();
#endif
#ifdef PSX2008_HAS_SEED48
void
seed48(unsigned short seed1, unsigned short seed2, unsigned short seed3);
INIT:
unsigned short seed16v[3] = { seed1, seed2, seed3 };
unsigned short *old = seed48(seed16v);
PPCODE:
/* We already know the stack is long enough. */
mPUSHs(newSVuv(old[0]));
mPUSHs(newSVuv(old[1]));
mPUSHs(newSVuv(old[2]));
#endif
#ifdef PSX2008_HAS_SRAND48
void
srand48(long seedval);
PPCODE:
srand48(seedval);
#endif
#ifdef PSX2008_HAS_RANDOM
long
random();
#endif
#ifdef PSX2008_HAS_SRANDOM
void
srandom(unsigned seed);
PPCODE:
srandom(seed);
#endif
#if defined(PSX2008_HAS_GETENTROPY)
# define _psx_getentropy(buf, len) getentropy(buf, len)
#elif defined(PSX2008_HAS_GETRANDOM)
# define _psx_getrandom(buf, len) getrandom(buf, len, 0)
#elif defined(PSX2008_HAS_GETRANDOM_SYS)
#if defined(_psx_getentropy) || defined(_psx_getrandom)
# ifdef _psx_cpu_rand_step_ok
# define _PSX_CPURAND_SIZE sizeof(_psx_cpu_rand_t)
# define _PSX_GETENTROPY_SVLEN_ROUNDUP(l) \
((l) + (_PSX_CPURAND_SIZE - ((l) % _PSX_CPURAND_SIZE)) % _PSX_CPURAND_SIZE)
# else
# define _PSX_GETENTROPY_SVLEN_ROUNDUP(l) (l)
# endif
void
getentropy(IV length);
PPCODE:
{
if (UNLIKELY(length < 0 || length > GETENTROPY_MAX)) {
SETERRNO(EINVAL, LIB_INVARG); /* Thus quoth POSIX. */
MakeUndefGreatAgain:
PUSHs(&PL_sv_undef);
}
else {
STRLEN sv_len = _PSX_GETENTROPY_SVLEN_ROUNDUP(length);
SV *bufsv = sv_2mortal(newSV(sv_len + !sv_len));
char *cbuf = SvPVX(bufsv);
#ifdef PSX2008_HAS_GETSID
pid_t
getsid(pid_t pid=0);
#endif
#ifdef PSX2008_HAS_GETRESGID
void
getresgid();
PPCODE:
{
gid_t rid, eid, sid;
int rv = getresgid(&rid, &eid, &sid);
if (LIKELY(rv == 0)) {
EXTEND(SP, 2); /* Stack already has room for 1 item. */
mPUSHs(newSVuv(rid));
mPUSHs(newSVuv(eid));
mPUSHs(newSVuv(sid));
}
}
#endif
#ifdef PSX2008_HAS_GETRESUID
void
getresuid();
PPCODE:
{
uid_t rid, eid, sid;
int rv = getresuid(&rid, &eid, &sid);
if (LIKELY(rv == 0)) {
EXTEND(SP, 2); /* Stack already has room for 1 item. */
mPUSHs(newSVuv(rid));
mPUSHs(newSVuv(eid));
mPUSHs(newSVuv(sid));
}
}
#ifdef PSX2008_HAS_SIGIGNORE
SysRetTrue
sigignore(int sig);
#endif
#ifdef PSX2008_HAS_SIGPAUSE
void
sigpause(int sig);
PPCODE:
(void)sigpause(sig);
PUSHs(&PL_sv_undef);
#endif
#ifdef PSX2008_HAS_SIGRELSE
SysRetTrue
sigrelse(int sig);
#endif
#ifdef PSX2008_HAS_PAUSE
void
pause();
PPCODE:
(void)pause();
PUSHs(&PL_sv_undef);
#endif
#ifdef PSX2008_HAS_PSIGNAL
void
psignal(int sig, const char *msg);
PPCODE:
psignal(sig, msg);
#endif
#ifdef PSX2008_HAS_STRSIGNAL
char*
strsignal(int sig);
#endif
timer_getoverrun(timer_t timerid);
#endif
#ifdef PSX2008_HAS_TIMER_GETTIME
void
timer_gettime(timer_t timerid);
PREINIT:
struct itimerspec curr_value;
int rv;
PPCODE:
{
rv = timer_gettime(timerid, &curr_value);
if (rv == 0) {
EXTEND(SP, 2);
mPUSHs(newSViv(curr_value.it_interval.tv_sec));
mPUSHs(newSViv(curr_value.it_interval.tv_nsec));
mPUSHs(newSViv(curr_value.it_value.tv_sec));
mPUSHs(newSViv(curr_value.it_value.tv_nsec));
}
}
#ifdef PSX2008_HAS_TIMER_SETTIME
void
timer_settime(timer_t timerid, int flags, \
time_t interval_sec, long interval_nsec, \
time_t initial_sec=-1, long initial_nsec=-1);
PROTOTYPE: $$@
PREINIT:
struct itimerspec new_value, old_value;
int rv;
PPCODE:
{
new_value.it_interval.tv_sec = interval_sec;
new_value.it_interval.tv_nsec = interval_nsec;
if (initial_sec < 0 || initial_nsec < 0)
new_value.it_value = new_value.it_interval;
else {
new_value.it_value.tv_sec = initial_sec;
new_value.it_value.tv_nsec = initial_nsec;
}
OUTPUT:
RETVAL
#endif
#ifdef PSX2008_HAS_CONFSTR
void
confstr(int name);
INIT:
SETERRNO(0, 0);
PPCODE:
{
Size_t len = confstr(name, NULL, 0);
if (!len && errno)
PUSHs(&PL_sv_undef);
else {
SV *bufsv = sv_2mortal(newSV(len + !len));
char *cbuf = SvPVX(bufsv);
(void)confstr(name, cbuf, len);
cbuf[len] = '\0';
SvTAINTED_on(bufsv);
PUSHs(bufsv);
}
}
#endif
#ifdef PSX2008_HAS_PATHCONF
void
pathconf(SV *what, int name);
PPCODE:
{
long rv = -1;
SvGETMAGIC(what);
SETERRNO(0, 0); /* SvGETMAGIC() might have set errno. */
if (UNLIKELY(!SvOK(what)))
SETERRNO(ENOENT, RMS_FNF);
else if (SvPOK(what)) {
const char *path = SvPV_nomg_const_nolen(what);
rv = pathconf(path, name);
}
PUSHs(&PL_sv_undef);
else
PUSH_INT_OR_PV(rv);
}
#endif
#ifdef PSX2008_HAS_SYSCONF
void
sysconf(int name);
PPCODE:
{
long rv;
SETERRNO(0, 0);
rv = sysconf(name);
if (rv < 0 && errno != 0)
PUSHs(&PL_sv_undef);
else
PUSH_INT_OR_PV(rv);
}
fsync(psx_fd_t fd);
#endif
#ifdef PSX2008_HAS_STAT
void
stat(SV *what);
INIT:
int rv = -1;
struct stat buf;
PPCODE:
SvGETMAGIC(what);
if (!SvOK(what))
SETERRNO(ENOENT, RMS_FNF);
else if (SvPOK(what)) {
const char *path = SvPV_nomg_const_nolen(what);
rv = stat(path, &buf);
}
else {
#ifdef PSX2008_HAS_FSTAT
int fd = _psx_fileno_nomg(aTHX_ what);
RETURN_STAT_BUF(rv, buf);
#endif
#ifdef PSX2008_HAS_LSTAT
void
lstat(const char *path);
INIT:
int rv;
struct stat buf;
PPCODE:
rv = lstat(path, &buf);
RETURN_STAT_BUF(rv, buf);
#endif
#ifdef PSX2008_HAS_STATVFS
void
statvfs(SV *what);
INIT:
int rv = -1;
struct statvfs buf;
PPCODE:
SvGETMAGIC(what);
if (!SvOK(what))
SETERRNO(ENOENT, RMS_FNF);
else if (SvPOK(what)) {
const char *path = SvPV_nomg_const_nolen(what);
rv = statvfs(path, &buf);
}
else {
#ifdef PSX2008_HAS_FSTATVFS
int fd = _psx_fileno_nomg(aTHX_ what);
#ifdef PSX2008_HAS_MKNOD
SysRetTrue
mknod(const char *path, mode_t mode, dev_t dev);
#endif
#ifdef PSX2008_HAS_MKDTEMP
void
mkdtemp(SV *template_sv);
PPCODE:
{
STRLEN len;
const char *ctmp = SvPV_const(template_sv, len);
/* Copy the original template to avoid overwriting it. */
SV *tmpsv = newSVpvn_flags(ctmp, len, SVs_TEMP);
char *dtemp = mkdtemp(SvPVX(tmpsv));
PUSHs(LIKELY(!!dtemp) ? tmpsv : &PL_sv_undef);
}
#endif
#ifdef PSX2008_HAS_MKSTEMP
void
mkstemp(SV *template_sv);
PPCODE:
{
STRLEN len;
const char *ctmp = SvPV_const(template_sv, len);
/* Copy the original template to avoid overwriting it. */
SV *tmpsv = newSVpvn_flags(ctmp, len, SVs_TEMP);
int fd = mkstemp(SvPVX(tmpsv));
if (LIKELY(fd >= 0)) {
mPUSHs(newSViv(fd));
PUSHs(tmpsv);
}
}
#endif
#ifdef PSX2008_HAS_MKOSTEMP
void
mkostemp(SV *template_sv, int flags);
PPCODE:
{
STRLEN len;
const char *ctmp = SvPV_const(template_sv, len);
/* Copy the original template to avoid overwriting it. */
SV *tmpsv = newSVpvn_flags(ctmp, len, SVs_TEMP);
int fd = mkostemp(SvPVX(tmpsv), flags);
if (LIKELY(fd >= 0)) {
mPUSHs(newSViv(fd));
PUSHs(tmpsv);
}
}
#endif
#if defined(PSX2008_HAS_FDOPEN)
void
fdopen(IV fd, const char *mode);
PPCODE:
{
SV *rv = NULL;
if (UNLIKELY(fd < 0 || fd > PERL_INT_MAX))
SETERRNO(EBADF, RMS_IFI);
else if (UNLIKELY(!mode || !*mode))
SETERRNO(EINVAL, LIB_INVARG);
else
rv = _psx_fd_to_handle(aTHX_ fd, mode);
PUSHs(rv ? rv : &PL_sv_undef);
}
#endif
#if defined(PSX2008_HAS_FDOPENDIR)
void
fdopendir(IV fd);
PPCODE:
{
SV *rv = NULL;
if (UNLIKELY(fd < 0 || fd > PERL_INT_MAX))
SETERRNO(EBADF, RMS_IFI);
else
rv = _psx_fd_to_handle(aTHX_ fd, NULL);
PUSHs(rv ? rv : &PL_sv_undef);
}
#endif
const char *path, uid_t owner, gid_t group, int flags=0);
#endif
#ifdef PSX2008_HAS_FSTATAT
void
fstatat(psx_fd_t dirfd, const char *path, int flags=0);
INIT:
int rv;
struct stat buf;
PPCODE:
rv = fstatat(dirfd, path, &buf, flags);
RETURN_STAT_BUF(rv, buf);
#endif
#ifdef PSX2008_HAS_LINKAT
SysRetTrue
linkat(psx_fd_t olddirfd, const char *oldpath, \
psx_fd_t newdirfd, const char *newpath, int flags=0);
#ifdef PSX2008_HAS_MKNODAT
SysRetTrue
mknodat(psx_fd_t dirfd, const char *path, mode_t mode, dev_t dev);
#endif
#ifdef PSX2008_HAS_OPENAT
void
openat(SV *dirfdsv, const char *path, int flags=O_RDONLY, mode_t mode=0666);
PPCODE:
{
SV *rv = _openat50c(aTHX_ dirfdsv, path, flags, mode, NULL);
PUSHs(rv ? rv : &PL_sv_undef);
}
#endif
#ifdef PSX2008_HAS_OPENAT2
void
openat2(SV *dirfdsv, const char *path, HV *how);
PPCODE:
{
SV *rv = _openat50c(aTHX_ dirfdsv, path, 0, 0, how);
PUSHs(rv ? rv : &PL_sv_undef);
}
#endif
#ifdef PSX2008_HAS_READLINK
void
readlink(const char *path);
PPCODE:
{
SV *rv = _readlink50c(aTHX_ path, NULL);
PUSHs(rv ? rv : &PL_sv_undef);
}
#endif
#ifdef PSX2008_HAS_READLINKAT
void
readlinkat(psx_fd_t dirfd, const char *path);
PPCODE:
{
SV *rv = _readlink50c(aTHX_ path, &dirfd);
PUSHs(rv ? rv : &PL_sv_undef);
}
#endif
#ifdef PSX2008_HAS_REALPATH
char *
realpath(const char *path);
#endif
#ifdef PSX2008_HAS_READ
void
read(psx_fd_t fd, SV *buf, SV *count);
PREINIT:
SSize_t rv;
Size_t nbytes;
char *cbuf;
PPCODE:
{
if (UNLIKELY(SvIsNEGATIVE(count))) /* Performs 'get' magic. */
croak("%s::read: Negative count: %" SVf_QUOTEDPREFIX,
PACKNAME, SVfARG(count));
nbytes = SvSTRLEN(count);
nbytes = (nbytes > SSIZE_MAX) ? SSIZE_MAX : nbytes;
if (UNLIKELY(SvTRULYREADONLY(buf))) {
if (nbytes)
croak("%s::read: Can't modify read-only buf", PACKNAME);
cbuf = NULL;
}
PUSH_INT_OR_PV(rv);
}
}
#endif
#ifdef PSX2008_HAS_WRITE
void
write(psx_fd_t fd, SV *buf, SV *count=NULL);
PPCODE:
{
if (UNLIKELY(SvIsNEGATIVE(count))) /* Performs 'get' magic. */
croak("%s::write: Negative count: %" SVf_QUOTEDPREFIX,
PACKNAME, SVfARG(count));
else {
SSize_t rv;
Size_t buflen;
const char *cbuf = SvPV_const(buf, buflen);
Size_t nbytes = buflen;
if (!SvIsUNDEF_onpurpose(count)) {
PUSH_INT_OR_PV(rv);
}
}
#endif
#ifdef PSX2008_HAS_READV
void
readv(psx_fd_t fd, SV *buffers, AV *sizes);
PROTOTYPE: $\[@$]$
PPCODE:
{
SSize_t rv = _readv50c(aTHX_ fd, buffers, sizes, NULL, NULL);
if (UNLIKELY(rv < 0))
PUSHs(&PL_sv_undef);
else
PUSH_INT_OR_PV(rv);
}
#endif
#ifdef PSX2008_HAS_PREADV
void
preadv(psx_fd_t fd, SV *buffers, AV *sizes, SV *offset=NULL);
PROTOTYPE: $\[@$]$;$
PPCODE:
{
SSize_t rv = _readv50c(aTHX_ fd, buffers, sizes, offset, NULL);
if (UNLIKELY(rv < 0))
PUSHs(&PL_sv_undef);
else
PUSH_INT_OR_PV(rv);
}
#endif
#ifdef PSX2008_HAS_PREADV2
void
preadv2(psx_fd_t fd, SV *buffers, AV *sizes, SV *offset=NULL, SV *flags=NULL);
PROTOTYPE: $\[@$]$;$$
PPCODE:
{
SSize_t rv = _readv50c(aTHX_ fd, buffers, sizes, offset, flags);
if (UNLIKELY(rv < 0))
PUSHs(&PL_sv_undef);
else
PUSH_INT_OR_PV(rv);
}
#endif
#ifdef PSX2008_HAS_WRITEV
void
writev(psx_fd_t fd, AV *buffers);
PPCODE:
{
struct iovec *iov;
int iovcnt = _psx_av2iov(aTHX_ buffers, &iov);
SSize_t rv = LIKELY(iovcnt >= 0) ? writev(fd, iov, iovcnt) : -1;
if (UNLIKELY(rv < 0))
PUSHs(&PL_sv_undef);
else
PUSH_INT_OR_PV(rv);
}
#endif
#ifdef PSX2008_HAS_PWRITEV
void
pwritev(psx_fd_t fd, AV *buffers, SV *offset=NULL);
PPCODE:
{
struct iovec *iov;
Off_t offs = SvIsUNDEF_onpurpose(offset) ? 0 : SvOFFt(offset);
int iovcnt = _psx_av2iov(aTHX_ buffers, &iov);
SSize_t rv = LIKELY(iovcnt >= 0) ? pwritev(fd, iov, iovcnt, offs) : -1;
if (UNLIKELY(rv < 0))
PUSHs(&PL_sv_undef);
else
PUSH_INT_OR_PV(rv);
}
#endif
#ifdef PSX2008_HAS_PWRITEV2
void
pwritev2(psx_fd_t fd, AV *buffers, SV *offset=NULL, SV *flags=NULL);
PPCODE:
{
struct iovec *iov;
Off_t offs = SvIsUNDEF_onpurpose(offset) ? 0 : SvOFFt(offset);
int i_flags = SvIsUNDEF_onpurpose(flags) ? 0 : (int)SvIV(flags);
int iovcnt = _psx_av2iov(aTHX_ buffers, &iov);
SSize_t rv =
LIKELY(iovcnt >= 0) ? pwritev2(fd, iov, iovcnt, offs, i_flags) : -1;
if (UNLIKELY(rv < 0))
PUSHs(&PL_sv_undef);
else
#endif
#ifdef PSX2008_HAS_PREAD
void
pread(psx_fd_t fd, SV *buf, SV *count, SV *offset=NULL, SV *buf_offset=NULL);
PREINIT:
char *cbuf;
Off_t f_offset;
Size_t b_offset, nbytes;
SSize_t rv;
PPCODE:
{
if (UNLIKELY(SvIsNEGATIVE(count))) /* Performs 'get' magic. */
croak("%s::pread: Negative count: %" SVf_QUOTEDPREFIX,
PACKNAME, SVfARG(count));
nbytes = SvSTRLEN(count);
if (nbytes > SSIZE_MAX)
nbytes = SSIZE_MAX;
if (UNLIKELY(SvTRULYREADONLY(buf))) {
#endif
#ifdef PSX2008_HAS_PWRITE
void
pwrite(psx_fd_t fd, SV *buf, \
SV *count=NULL, SV *offset=NULL, SV *buf_offset=NULL);
PREINIT:
Off_t f_offset;
Size_t b_offset;
SSize_t rv;
PPCODE:
{
STRLEN svpv_len;
const char *cbuf = SvPV_const(buf, svpv_len);
STRLEN nbytes = svpv_len;
/* Ensure buf_offset results in a valid string index. This is slightly
* different from pread() because we can't allow offsets beyond the buffer
* at all (zero is okay, though). */
if (SvIsUNDEF_onpurpose(buf_offset))
b_offset = 0;
PUSHs(&PL_sv_undef);
else
PUSH_INT_OR_PV(rv);
}
#endif
#ifdef PSX2008_HAS_POSIX_FADVISE
void
posix_fadvise(psx_fd_t fd, Off_t offset, Off_t len, int advice);
PPCODE:
{
int rv = posix_fadvise(fd, offset, len, advice);
if (LIKELY(rv == 0))
mPUSHp("0 but true", 10);
else {
SETERRNO(rv, rv);
PUSHs(&PL_sv_undef);
}
}
#endif
#ifdef PSX2008_HAS_POSIX_FALLOCATE
void
posix_fallocate(psx_fd_t fd, Off_t offset, Off_t len);
PPCODE:
{
int rv = posix_fallocate(fd, offset, len);
if (LIKELY(rv == 0))
mPUSHp("0 but true", 10);
else {
SETERRNO(rv, rv);
PUSHs(&PL_sv_undef);
}
}
#endif
#ifdef PSX2008_HAS_POSIX_OPENPT
void
posix_openpt(int flags=O_RDWR);
PPCODE:
{
const char *raw = _flags2raw(flags);
int fd = posix_openpt(flags);
SV *rv = LIKELY(fd >= 0) ? _psx_fd_to_handle(aTHX_ fd, raw) : NULL;
PUSHs(rv ? rv : &PL_sv_undef);
}
#endif
#ifdef PSX2008_HAS_GRANTPT
#ifdef PSX2008_HAS_UNLOCKPT
SysRetTrue
unlockpt(psx_fd_t fd);
#endif
#ifdef PSX2008_HAS_PTSNAME
void
ptsname(psx_fd_t fd);
PPCODE:
{
# ifdef PSX2008_HAS_PTSNAME_R
char name[MAXPATHLEN];
int rv = ptsname_r(fd, name, sizeof(name));
if (LIKELY(rv == 0))
mPUSHp(name, _strnlen(name, sizeof(name)));
else {
/* Some implementations return -1 on error and set errno. */
if (rv > 0) SETERRNO(rv, rv);
PUSHs(&PL_sv_undef);
else
PUSHs(&PL_sv_undef);
# endif
}
#endif
#ifdef PSX2008_HAS_TTYNAME
void
ttyname(psx_fd_t fd);
PPCODE:
{
# ifdef PSX2008_HAS_TTYNAME_R
char name[MAXPATHLEN];
int rv = ttyname_r(fd, name, sizeof(name));
if (LIKELY(rv == 0))
mPUSHp(name, _strnlen(name, sizeof(name)));
else {
SETERRNO(rv, rv);
PUSHs(&PL_sv_undef);
}
#elif !defined(_WIN32)
#define UNLINK_ISDIR_ERRNO (errno == EISDIR || errno == EPERM)
#else
#define UNLINK_ISDIR_ERRNO (errno == EISDIR || errno == EPERM || errno == EACCES)
#endif
#if !defined(PSX2008_HAS_REMOVE) || (defined(_WIN32) && !defined(__CYGWIN__))
# if defined(PSX2008_HAS_UNLINK) && defined(PSX2008_HAS_RMDIR)
void
remove(const char *path);
PPCODE:
if (unlink(path) == 0 || (UNLINK_ISDIR_ERRNO && rmdir(path) == 0))
mPUSHp("0 but true", 10);
else
PUSHs(&PL_sv_undef);
# else
# endif
#else
SysRetTrue
remove(const char *path);
#endif
#ifdef PSX2008_HAS_UNLINKAT
void
removeat(psx_fd_t dirfd, const char *path);
PPCODE:
if (unlinkat(dirfd, path, 0) == 0
|| (UNLINK_ISDIR_ERRNO && unlinkat(dirfd, path, AT_REMOVEDIR) == 0))
mPUSHp("0 but true", 10);
else
PUSHs(&PL_sv_undef);
#endif
#ifdef PSX2008_HAS_RENAME
SysRetTrue
RETVAL = futimens(fd, times);
OUTPUT:
RETVAL
#endif
#ifdef PSX2008_HAS_EXECVEAT
void
execveat(psx_fd_t dirfd, const char *path, \
AV *args, SV *env=NULL, int flags=0);
PPCODE:
{
_execve50c(aTHX_ dirfd, path, args, env, flags);
PUSHs(&PL_sv_undef);
}
#endif
#ifdef PSX2008_HAS_FEXECVE
void
fexecve(psx_fd_t fd, AV *args, SV *env=NULL);
PPCODE:
{
_execve50c(aTHX_ fd, NULL, args, env, 0);
PUSHs(&PL_sv_undef);
}
#endif
#ifdef PSX2008_HAS_POLL
void
poll(SV *pollfds, int timeout=-1);
PPCODE:
{
int rv = _poll50c(aTHX_ pollfds, timeout, NULL);
mPUSHs(newSViv(rv));
}
#endif
#ifdef PSX2008_HAS_PPOLL
void
ppoll(SV *pollfds, SV *timeout=NULL, SV *sigmask=NULL);
PREINIT:
int rv;
struct timespec tmo = {0};
struct psx_ppollspec ppspec = {0};
PPCODE:
{
/* See POSIX::sigprocmask(). Can't be wrong [TM]. */
if (sigmask && SvOK(sigmask)) {
if (sv_isa(sigmask, "POSIX::SigSet")) {
#if PERL_BCDVERSION >= 0x5016000
ppspec.sigmask = (sigset_t*)SvPV_nolen(SvRV(sigmask));
#else
IV tmp = SvIV((SV*)SvRV(sigmask));
ppspec.sigmask = INT2PTR(sigset_t*, tmp);
#endif
RETVAL = cosh(x);
# endif
OUTPUT:
RETVAL
#endif
#ifdef PSX2008_DIV
void
div(IV numer, IV denom);
PPCODE:
{
PSX2008_DIV_T result = PSX2008_DIV(numer, denom);
mPUSHs(newSViv(result.quot));
mPUSHs(newSViv(result.rem));
}
#endif
#ifdef PSX2008_HAS_ERF
NV
#ifdef PSX2008_HAS_FPCLASSIFY
int
fpclassify(NV x);
#endif
#ifdef PSX2008_HAS_FREXP
void
frexp(NV x);
PPCODE:
{
NV fr;
int exp;
# if defined(PSX2008_HAS_SQRTQ)
fr = frexpq(x, &exp);
# elif defined(PSX2008_HAS_SQRTL)
fr = frexpl(x, &exp);
# else
fr = frexp(x, &exp);
# endif
RETVAL = logb(x);
# endif
OUTPUT:
RETVAL
#endif
#ifdef PSX2008_HAS_LRINT
void
lrint(NV x);
PPCODE:
{
# if defined(PSX2008_HAS_LLRINTQ)
long long ret = llrintq(x);
# elif defined(PSX2008_HAS_LRINTQ)
long ret = lrintq(x);
# elif defined(PSX2008_HAS_LLRINTL)
long long ret = llrintl(x);
# elif defined(PSX2008_HAS_LRINTL)
long ret = lrintl(x);
# elif defined(PSX2008_HAS_LLRINT)
long ret = lrint(x);
# endif
PUSH_INT_OR_PV(ret);
}
#endif
#ifdef PSX2008_HAS_LROUND
void
lround(NV x);
PPCODE:
{
# if defined(PSX2008_HAS_LLROUNDQ)
long long ret = llroundq(x);
# elif defined(PSX2008_HAS_LROUNDQ)
long ret = lroundq(x);
# elif defined(PSX2008_HAS_LLROUNDL)
long long ret = llroundl(x);
# elif defined(PSX2008_HAS_LROUNDL)
long ret = lroundl(x);
# elif defined(PSX2008_HAS_LLROUND)
OUTPUT:
RETVAL
#endif
#ifdef PSX2008_HAS_REMAINDER
void
remainder(NV x, NV y);
INIT:
NV res;
PPCODE:
{
# if defined(PSX2008_HAS_SQRTQ)
res = remainderq(x, y);
# elif defined(PSX2008_HAS_SQRTL)
res = remainderl(x, y);
# else
res = remainder(x, y);
# endif
mPUSHs(newSVnv(res));
}
#endif
#ifdef PSX2008_HAS_REMQUO
void
remquo(NV x, NV y);
INIT:
int quo;
NV res;
PPCODE:
{
# if defined(PSX2008_HAS_SQRTQ)
res = remquoq(x, y, &quo);
# elif defined(PSX2008_HAS_SQRTL)
res = remquol(x, y, &quo);
# else
res = remquo(x, y, &quo);
# endif
mPUSHs(newSVnv(res));
mPUSHs(newSViv(quo));
#endif
#ifdef PSX2008_HAS_CPROJ
void
cproj(NV re, NV im);
INIT:
PSX2008_COMPLEX_T result;
PSX2008_COMPLEX_T z;
COMPLEX_FROM_RE_IM(z, re, im);
PPCODE:
# if defined(PSX2008_HAS_CSQRTQ)
result = cprojq(z);
# elif defined(PSX2008_HAS_CSQRTL)
result = cprojl(z);
# else
result = cproj(z);
# endif
RETURN_COMPLEX(result);
#endif
#endif
#ifdef PSX2008_HAS_CEXP
void
cexp(NV re, NV im);
INIT:
PSX2008_COMPLEX_T result;
PSX2008_COMPLEX_T z;
COMPLEX_FROM_RE_IM(z, re, im);
PPCODE:
# if defined(PSX2008_HAS_CSQRTQ)
result = cexpq(z);
# elif defined(PSX2008_HAS_CEXPL)
result = cexpl(z);
# else
result = cexp(z);
# endif
RETURN_COMPLEX(result);
#endif
#ifdef PSX2008_HAS_CLOG
void
clog(NV re, NV im);
INIT:
PSX2008_COMPLEX_T result;
PSX2008_COMPLEX_T z;
COMPLEX_FROM_RE_IM(z, re, im);
PPCODE:
# if defined(PSX2008_HAS_CSQRTQ)
result = clogq(z);
# elif defined(PSX2008_HAS_CLOGL)
result = clogl(z);
# else
result = clog(z);
# endif
RETURN_COMPLEX(result);
#endif
#ifdef PSX2008_HAS_CONJ
void
conj(NV re, NV im);
INIT:
PSX2008_COMPLEX_T result;
PSX2008_COMPLEX_T z;
COMPLEX_FROM_RE_IM(z, re, im);
PPCODE:
# if defined(PSX2008_HAS_CSQRTQ)
result = conjq(z);
# elif defined(PSX2008_HAS_CSQRTL)
result = conjl(z);
# else
result = conj(z);
# endif
RETURN_COMPLEX(result);
#endif
#ifdef PSX2008_HAS_CPOW
void
cpow(NV re_x, NV im_x, NV re_y, NV im_y);
INIT:
PSX2008_COMPLEX_T result;
PSX2008_COMPLEX_T x, y;
COMPLEX_FROM_RE_IM(x, re_x, im_x);
COMPLEX_FROM_RE_IM(y, re_y, im_y);
PPCODE:
# if defined(PSX2008_HAS_CSQRTQ)
result = cpowq(x, y);
# elif defined(PSX2008_HAS_CSQRTL)
result = cpowl(x, y);
# else
result = cpow(x, y);
# endif
RETURN_COMPLEX(result);
#endif
#ifdef PSX2008_HAS_CSQRT
void
csqrt(NV re, NV im);
INIT:
PSX2008_COMPLEX_T result;
PSX2008_COMPLEX_T z;
COMPLEX_FROM_RE_IM(z, re, im);
PPCODE:
# if defined(PSX2008_HAS_CSQRTQ)
result = csqrtq(z);
# elif defined(PSX2008_HAS_CSQRTL)
result = csqrtl(z);
# else
result = csqrt(z);
# endif
RETURN_COMPLEX(result);
#endif
#ifdef PSX2008_HAS_CACOS
void
cacos(NV re, NV im);
INIT:
PSX2008_COMPLEX_T result;
PSX2008_COMPLEX_T z;
COMPLEX_FROM_RE_IM(z, re, im);
PPCODE:
# if defined(PSX2008_HAS_CSQRTQ)
result = cacosq(z);
# elif defined(PSX2008_HAS_CSQRTL)
result = cacosl(z);
# else
result = cacos(z);
# endif
RETURN_COMPLEX(result);
#endif
#ifdef PSX2008_HAS_CACOSH
void
cacosh(NV re, NV im);
INIT:
PSX2008_COMPLEX_T result;
PSX2008_COMPLEX_T z;
COMPLEX_FROM_RE_IM(z, re, im);
PPCODE:
# if defined(PSX2008_HAS_CSQRTQ)
result = cacoshq(z);
# elif defined(PSX2008_HAS_CSQRTL)
result = cacoshl(z);
# else
result = cacosh(z);
# endif
RETURN_COMPLEX(result);
#endif
#ifdef PSX2008_HAS_CASIN
void
casin(NV re, NV im);
INIT:
PSX2008_COMPLEX_T result;
PSX2008_COMPLEX_T z;
COMPLEX_FROM_RE_IM(z, re, im);
PPCODE:
# if defined(PSX2008_HAS_CSQRTQ)
result = casinq(z);
# elif defined(PSX2008_HAS_CSQRTL)
result = casinl(z);
# else
result = casin(z);
# endif
RETURN_COMPLEX(result);
#endif
#ifdef PSX2008_HAS_CASINH
void
casinh(NV re, NV im);
INIT:
PSX2008_COMPLEX_T result;
PSX2008_COMPLEX_T z;
COMPLEX_FROM_RE_IM(z, re, im);
PPCODE:
# if defined(PSX2008_HAS_CSQRTQ)
result = casinhq(z);
# elif defined(PSX2008_HAS_CSQRTL)
result = casinhl(z);
# else
result = casinh(z);
# endif
RETURN_COMPLEX(result);
#endif
#ifdef PSX2008_HAS_CATAN
void
catan(NV re, NV im);
INIT:
PSX2008_COMPLEX_T result;
PSX2008_COMPLEX_T z;
COMPLEX_FROM_RE_IM(z, re, im);
PPCODE:
# if defined(PSX2008_HAS_CSQRTQ)
result = catanq(z);
# elif defined(PSX2008_HAS_CSQRTL)
result = catanl(z);
# else
result = catan(z);
# endif
RETURN_COMPLEX(result);
#endif
#ifdef PSX2008_HAS_CATANH
void
catanh(NV re, NV im);
INIT:
PSX2008_COMPLEX_T result;
PSX2008_COMPLEX_T z;
COMPLEX_FROM_RE_IM(z, re, im);
PPCODE:
# if defined(PSX2008_HAS_CSQRTQ)
result = catanhq(z);
# elif defined(PSX2008_HAS_CSQRTL)
result = catanhl(z);
# else
result = catanh(z);
# endif
RETURN_COMPLEX(result);
#endif
#ifdef PSX2008_HAS_CCOS
void
ccos(NV re, NV im);
INIT:
PSX2008_COMPLEX_T result;
PSX2008_COMPLEX_T z;
COMPLEX_FROM_RE_IM(z, re, im);
PPCODE:
# if defined(PSX2008_HAS_CSQRTQ)
result = ccosq(z);
# elif defined(PSX2008_HAS_CCOSL)
result = ccosl(z);
# else
result = ccos(z);
# endif
RETURN_COMPLEX(result);
#endif
#ifdef PSX2008_HAS_CCOSH
void
ccosh(NV re, NV im);
INIT:
PSX2008_COMPLEX_T result;
PSX2008_COMPLEX_T z;
COMPLEX_FROM_RE_IM(z, re, im);
PPCODE:
# if defined(PSX2008_HAS_CSQRTQ)
result = ccoshq(z);
# elif defined(PSX2008_HAS_CCOSHL)
result = ccoshl(z);
# else
result = ccosh(z);
# endif
RETURN_COMPLEX(result);
#endif
#ifdef PSX2008_HAS_CSIN
void
csin(NV re, NV im);
INIT:
PSX2008_COMPLEX_T result;
PSX2008_COMPLEX_T z;
COMPLEX_FROM_RE_IM(z, re, im);
PPCODE:
# if defined(PSX2008_HAS_CSQRTQ)
result = csinq(z);
# elif defined(PSX2008_HAS_CSINL)
result = csinl(z);
# else
result = csin(z);
# endif
RETURN_COMPLEX(result);
#endif
#ifdef PSX2008_HAS_CSINH
void
csinh(NV re, NV im);
INIT:
PSX2008_COMPLEX_T result;
PSX2008_COMPLEX_T z;
COMPLEX_FROM_RE_IM(z, re, im);
PPCODE:
# if defined(PSX2008_HAS_CSQRTQ)
result = csinhq(z);
# elif defined(PSX2008_HAS_CSINHL)
result = csinhl(z);
# else
result = csinh(z);
# endif
RETURN_COMPLEX(result);
#endif
#ifdef PSX2008_HAS_CTAN
void
ctan(NV re, NV im);
INIT:
PSX2008_COMPLEX_T result;
PSX2008_COMPLEX_T z;
COMPLEX_FROM_RE_IM(z, re, im);
PPCODE:
# if defined(PSX2008_HAS_CSQRTQ)
result = ctanq(z);
# elif defined(PSX2008_HAS_CTANL)
result = ctanl(z);
# else
result = ctan(z);
# endif
RETURN_COMPLEX(result);
#endif
#ifdef PSX2008_HAS_CTANH
void
ctanh(NV re, NV im);
INIT:
PSX2008_COMPLEX_T result;
PSX2008_COMPLEX_T z;
COMPLEX_FROM_RE_IM(z, re, im);
PPCODE:
# if defined(PSX2008_HAS_CSQRTQ)
result = ctanhq(z);
# elif defined(PSX2008_HAS_CTANHL)
result = ctanhl(z);
# else
result = ctanh(z);
# endif
RETURN_COMPLEX(result);
#endif
## DESTROY is called when a file handle we created (e.g. in openat)
## is cleaned up. This is just a dummy to silence AUTOLOAD. We leave
## it up to Perl to take the necessary steps.
void
DESTROY(...);
PPCODE:
BOOT:
{
}
( run in 0.943 second using v1.01-cache-2.11-cpan-4e7a2411597 )