#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include "libproc.h"
typedef union {
offset_t full;
uint32_t half[2];
} offsets_t;
off_t
pr_lseek(struct ps_prochandle *Pr, int filedes, off_t offset, int whence)
{
int syscall;
int nargs;
offsets_t off;
sysret_t rval;
argdes_t argd[4];
argdes_t *adp;
int error;
if (Pr == NULL)
return (lseek(filedes, offset, whence));
adp = &argd[0];
adp->arg_value = filedes;
adp->arg_object = NULL;
adp->arg_type = AT_BYVAL;
adp->arg_inout = AI_INPUT;
adp->arg_size = 0;
adp++;
if (Pstatus(Pr)->pr_dmodel == PR_MODEL_NATIVE) {
syscall = SYS_lseek;
nargs = 3;
adp->arg_value = offset;
adp->arg_object = NULL;
adp->arg_type = AT_BYVAL;
adp->arg_inout = AI_INPUT;
adp->arg_size = 0;
} else {
syscall = SYS_llseek;
nargs = 4;
off.full = offset;
adp->arg_value = off.half[0];
adp->arg_object = NULL;
adp->arg_type = AT_BYVAL;
adp->arg_inout = AI_INPUT;
adp->arg_size = 0;
adp++;
adp->arg_value = off.half[1];
adp->arg_object = NULL;
adp->arg_type = AT_BYVAL;
adp->arg_inout = AI_INPUT;
adp->arg_size = 0;
}
adp++;
adp->arg_value = whence;
adp->arg_object = NULL;
adp->arg_type = AT_BYVAL;
adp->arg_inout = AI_INPUT;
adp->arg_size = 0;
error = Psyscall(Pr, &rval, syscall, nargs, &argd[0]);
if (error) {
errno = (error > 0)? error : ENOSYS;
return ((off_t)(-1));
}
if (Pstatus(Pr)->pr_dmodel == PR_MODEL_NATIVE)
offset = rval.sys_rval1;
else {
off.half[0] = (uint32_t)rval.sys_rval1;
off.half[1] = (uint32_t)rval.sys_rval2;
offset = (off_t)off.full;
}
return (offset);
}
offset_t
pr_llseek(struct ps_prochandle *Pr, int filedes, offset_t offset, int whence)
{
int syscall;
int nargs;
offsets_t off;
sysret_t rval;
argdes_t argd[4];
argdes_t *adp;
int error;
if (Pr == NULL)
return (llseek(filedes, offset, whence));
adp = &argd[0];
adp->arg_value = filedes;
adp->arg_object = NULL;
adp->arg_type = AT_BYVAL;
adp->arg_inout = AI_INPUT;
adp->arg_size = 0;
adp++;
if (Pstatus(Pr)->pr_dmodel == PR_MODEL_LP64) {
syscall = SYS_lseek;
nargs = 3;
adp->arg_value = offset;
adp->arg_object = NULL;
adp->arg_type = AT_BYVAL;
adp->arg_inout = AI_INPUT;
adp->arg_size = 0;
} else {
syscall = SYS_llseek;
nargs = 4;
off.full = offset;
adp->arg_value = off.half[0];
adp->arg_object = NULL;
adp->arg_type = AT_BYVAL;
adp->arg_inout = AI_INPUT;
adp->arg_size = 0;
adp++;
adp->arg_value = off.half[1];
adp->arg_object = NULL;
adp->arg_type = AT_BYVAL;
adp->arg_inout = AI_INPUT;
adp->arg_size = 0;
}
adp++;
adp->arg_value = whence;
adp->arg_object = NULL;
adp->arg_type = AT_BYVAL;
adp->arg_inout = AI_INPUT;
adp->arg_size = 0;
error = Psyscall(Pr, &rval, syscall, nargs, &argd[0]);
if (error) {
errno = (error > 0)? error : ENOSYS;
return ((offset_t)(-1));
}
if (Pstatus(Pr)->pr_dmodel == PR_MODEL_LP64)
offset = rval.sys_rval1;
else {
off.half[0] = (uint32_t)rval.sys_rval1;
off.half[1] = (uint32_t)rval.sys_rval2;
offset = off.full;
}
return (offset);
}