#include "pub_core_basics.h"
#include "pub_core_vki.h"
+#include "pub_core_vkiscnums.h"
#include "pub_core_libcbase.h"
#include "pub_core_libcassert.h"
#include "pub_core_libcfile.h"
#include "pub_core_libcproc.h" // VG_(getpid), VG_(getppid)
#include "pub_core_clientstate.h" // VG_(fd_hard_limit)
#include "pub_core_syscall.h"
-#include "pub_core_vkiscnums.h"
/* ---------------------------------------------------------------------
File stuff
if (newfd != -1)
VG_(close)(oldfd);
+ /* Set the close-on-exec flag for this fd. */
VG_(fcntl)(newfd, VKI_F_SETFD, VKI_FD_CLOEXEC);
vg_assert(newfd >= VG_(fd_hard_limit));
Int VG_(read) ( Int fd, void* buf, Int count)
{
+ Int ret;
SysRes res = VG_(do_syscall3)(__NR_read, fd, (UWord)buf, count);
- return res.isError ? -1 : res.val;
+ if (res.isError) {
+ ret = - (Int)(Word)res.err;
+ vg_assert(ret < 0);
+ } else {
+ ret = (Int)(Word)res.res;
+ vg_assert(ret >= 0);
+ }
+ return ret;
}
Int VG_(write) ( Int fd, const void* buf, Int count)
{
+ Int ret;
SysRes res = VG_(do_syscall3)(__NR_write, fd, (UWord)buf, count);
- return res.isError ? -1 : res.val;
+ if (res.isError) {
+ ret = - (Int)(Word)res.err;
+ vg_assert(ret < 0);
+ } else {
+ ret = (Int)(Word)res.res;
+ vg_assert(ret >= 0);
+ }
+ return ret;
}
Int VG_(pipe) ( Int fd[2] )
OffT VG_(lseek) ( Int fd, OffT offset, Int whence )
{
SysRes res = VG_(do_syscall3)(__NR_lseek, fd, offset, whence);
- return res.isError ? (-1) : res.val;
+ return res.isError ? (-1) : res.res;
/* if you change the error-reporting conventions of this, also
change VG_(pread) and all other usage points. */
}
SysRes VG_(stat) ( Char* file_name, struct vki_stat* buf )
{
+# if defined(VGO_linux)
SysRes res = VG_(do_syscall2)(__NR_stat, (UWord)file_name, (UWord)buf);
return res;
+# elif defined(VGO_aix5)
+ SysRes res = VG_(do_syscall4)(__NR_AIX5_statx,
+ (UWord)file_name,
+ (UWord)buf,
+ sizeof(struct vki_stat),
+ VKI_STX_NORMAL);
+ return res;
+# else
+# error Unknown OS
+# endif
}
Int VG_(fstat) ( Int fd, struct vki_stat* buf )
{
+# if defined(VGO_linux)
SysRes res = VG_(do_syscall2)(__NR_fstat, fd, (UWord)buf);
return res.isError ? (-1) : 0;
+# elif defined(VGO_aix5)
+ I_die_here;
+# else
+# error Unknown OS
+# endif
}
Int VG_(fsize) ( Int fd )
{
-#ifdef __NR_fstat64
+# if defined(VGO_linux) && defined(__NR_fstat64)
struct vki_stat64 buf;
SysRes res = VG_(do_syscall2)(__NR_fstat64, fd, (UWord)&buf);
-#else
+ return res.isError ? (-1) : buf.st_size;
+# elif defined(VGO_linux) && !defined(__NR_fstat64)
struct vki_stat buf;
SysRes res = VG_(do_syscall2)(__NR_fstat, fd, (UWord)&buf);
-#endif
return res.isError ? (-1) : buf.st_size;
+# elif defined(VGO_aix5)
+ I_die_here;
+# else
+# error Unknown OS
+# endif
}
Bool VG_(is_dir) ( HChar* f )
{
struct vki_stat buf;
- SysRes res = VG_(do_syscall2)(__NR_stat, (UWord)f, (UWord)&buf);
+ SysRes res = VG_(stat)(f, &buf);
return res.isError ? False
: VKI_S_ISDIR(buf.st_mode) ? True : False;
}
Int VG_(fcntl) ( Int fd, Int cmd, Int arg )
{
SysRes res = VG_(do_syscall3)(__NR_fcntl, fd, cmd, arg);
- return res.isError ? -1 : res.val;
+ return res.isError ? -1 : res.res;
}
Int VG_(rename) ( Char* old_name, Char* new_name )
return res.isError ? (-1) : 0;
}
-/* Nb: we do not allow the Linux extension which malloc()s memory for the
- buffer if buf==NULL, because we don't want Linux calling malloc() */
Bool VG_(getcwd) ( Char* buf, SizeT size )
{
+# if defined(VGO_linux)
SysRes res;
vg_assert(buf != NULL);
res = VG_(do_syscall2)(__NR_getcwd, (UWord)buf, size);
return res.isError ? False : True;
+# elif defined(VGO_aix5)
+ static Int complaints = 3;
+ if (complaints-- > 0)
+ VG_(debugLog)(0, "libcfile",
+ "Warning: AIX5: m_libcfile.c: kludged 'getcwd'\n");
+ if (size < 2) return False;
+ buf[0] = '.';
+ buf[1] = 0;
+ return True;
+# else
+# error Unknown OS
+# endif
}
Int VG_(readlink) (Char* path, Char* buf, UInt bufsiz)
SysRes res;
/* res = readlink( path, buf, bufsiz ); */
res = VG_(do_syscall3)(__NR_readlink, (UWord)path, (UWord)buf, bufsiz);
- return res.isError ? -1 : res.val;
+ return res.isError ? -1 : res.res;
}
Int VG_(getdents) (UInt fd, struct vki_dirent *dirp, UInt count)
SysRes res;
/* res = getdents( fd, dirp, count ); */
res = VG_(do_syscall3)(__NR_getdents, fd, (UWord)dirp, count);
- return res.isError ? -1 : res.val;
+ return res.isError ? -1 : res.res;
}
/* Check accessibility of a file. Returns zero for access granted,
nonzero otherwise. */
Int VG_(access) ( HChar* path, Bool irusr, Bool iwusr, Bool ixusr )
{
-#if defined(VGO_linux)
+# if defined(VGO_linux)
/* Very annoyingly, I cannot find any definition for R_OK et al in
the kernel interfaces. Therefore I reluctantly resort to
hardwiring in these magic numbers that I determined by
| (iwusr ? 2/*W_OK*/ : 0)
| (ixusr ? 1/*X_OK*/ : 0);
SysRes res = VG_(do_syscall2)(__NR_access, (UWord)path, w);
- return res.isError ? 1 : res.val;
-#else
-# error "Don't know how to do VG_(access) on this OS"
-#endif
+ return res.isError ? 1 : 0;
+# elif defined(VGO_aix5)
+ UWord w = (irusr ? VKI_R_OK : 0)
+ | (iwusr ? VKI_W_OK : 0)
+ | (ixusr ? VKI_X_OK : 0);
+ SysRes res = VG_(do_syscall2)(__NR_access, (UWord)path, w);
+ return res.isError ? 1 : 0;
+# else
+# error "Don't know how to do VG_(access) on this OS"
+# endif
}
/*
#endif
if (res.isError) {
- return res.val;
+ return res.err;
}
if (st.st_mode & (VKI_S_ISUID | VKI_S_ISGID)) {
- //VG_(printf)("Can't execute suid/sgid executable %s\n", exe);
+ /* VG_(printf)("Can't execute suid/sgid executable %s\n", exe); */
return VKI_EACCES;
}
if (sres.isError)
continue;
/* VG_(safe_fd) doesn't return if it fails. */
- fd = VG_(safe_fd)( sres.val );
+ fd = VG_(safe_fd)( sres.res );
if (fullname)
VG_(strcpy)( fullname, buf );
return fd;
Int my_socket ( Int domain, Int type, Int protocol );
static
-Int my_connect ( Int sockfd, struct vki_sockaddr_in* serv_addr,
+Int my_connect ( Int sockfd,
+# if defined(VGO_linux)
+ struct vki_sockaddr_in* serv_addr,
+# else
+ void* serv_addr,
+# endif
Int addrlen );
UInt VG_(htonl) ( UInt x )
*/
Int VG_(connect_via_socket)( UChar* str )
{
+#if defined(VGO_aix5)
+ I_die_here;
+#else /* Yay, Linux */
Int sd, res;
struct vki_sockaddr_in servAddr;
UInt ip = 0;
}
return sd;
+#endif
}
/* Let d = one or more digits. Accept either:
d.d.d.d or d.d.d.d:d
*/
-Int parse_inet_addr_and_port ( UChar* str, UInt* ip_addr, UShort* port )
+static Int parse_inet_addr_and_port ( UChar* str, UInt* ip_addr, UShort* port )
{
# define GET_CH ((*str) ? (*str++) : 0)
UInt ipa, i, j, c, any;
args[1] = type;
args[2] = protocol;
res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_SOCKET, (UWord)&args);
- return res.isError ? -1 : res.val;
+ return res.isError ? -1 : res.res;
#elif defined(VGP_amd64_linux)
SysRes res;
res = VG_(do_syscall3)(__NR_socket, domain, type, protocol );
- return res.isError ? -1 : res.val;
+ return res.isError ? -1 : res.res;
+
+#elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+ I_die_here;
#else
# error Unknown arch
}
static
-Int my_connect ( Int sockfd, struct vki_sockaddr_in* serv_addr,
+Int my_connect ( Int sockfd,
+# if defined(VGO_linux)
+ struct vki_sockaddr_in* serv_addr,
+# else
+ void* serv_addr,
+# endif
Int addrlen )
{
#if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
args[1] = (UWord)serv_addr;
args[2] = addrlen;
res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_CONNECT, (UWord)&args);
- return res.isError ? -1 : res.val;
+ return res.isError ? -1 : res.res;
#elif defined(VGP_amd64_linux)
SysRes res;
res = VG_(do_syscall3)(__NR_connect, sockfd, (UWord)serv_addr, addrlen);
- return res.isError ? -1 : res.val;
+ return res.isError ? -1 : res.res;
+
+#elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+ I_die_here;
#else
# error Unknown arch
Int VG_(write_socket)( Int sd, void *msg, Int count )
{
/* This is actually send(). */
- /* Requests not to send SIGPIPE on errors on stream oriented
- sockets when the other end breaks the connection. The EPIPE
- error is still returned. */
- Int flags = VKI_MSG_NOSIGNAL;
+ /* For Linux, VKI_MSG_NOSIGNAL is a request not to send SIGPIPE on
+ errors on stream oriented sockets when the other end breaks the
+ connection. The EPIPE error is still returned. */
#if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
SysRes res;
args[0] = sd;
args[1] = (UWord)msg;
args[2] = count;
- args[3] = flags;
+ args[3] = VKI_MSG_NOSIGNAL;
res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_SEND, (UWord)&args);
- return res.isError ? -1 : res.val;
+ return res.isError ? -1 : res.res;
#elif defined(VGP_amd64_linux)
SysRes res;
- res = VG_(do_syscall6)(__NR_sendto, sd, (UWord)msg, count, flags, 0,0);
- return res.isError ? -1 : res.val;
+ res = VG_(do_syscall6)(__NR_sendto, sd, (UWord)msg,
+ count, VKI_MSG_NOSIGNAL, 0,0);
+ return res.isError ? -1 : res.res;
+
+#elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+ I_die_here;
#else
# error Unknown arch
Int VG_(getsockname) ( Int sd, struct vki_sockaddr *name, Int *namelen)
{
- SysRes res;
-
#if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
+ SysRes res;
UWord args[3];
args[0] = sd;
args[1] = (UWord)name;
args[2] = (UWord)namelen;
res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETSOCKNAME, (UWord)&args);
- return res.isError ? -1 : res.val;
+ return res.isError ? -1 : res.res;
#elif defined(VGP_amd64_linux)
+ SysRes res;
res = VG_(do_syscall3)( __NR_getsockname,
(UWord)sd, (UWord)name, (UWord)namelen );
- return res.isError ? -1 : res.val;
+ return res.isError ? -1 : res.res;
+
+#elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+ I_die_here;
#else
# error Unknown arch
Int VG_(getpeername) ( Int sd, struct vki_sockaddr *name, Int *namelen)
{
- SysRes res;
-
#if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
+ SysRes res;
UWord args[3];
args[0] = sd;
args[1] = (UWord)name;
args[2] = (UWord)namelen;
res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETPEERNAME, (UWord)&args);
- return res.isError ? -1 : res.val;
+ return res.isError ? -1 : res.res;
#elif defined(VGP_amd64_linux)
+ SysRes res;
res = VG_(do_syscall3)( __NR_getpeername,
(UWord)sd, (UWord)name, (UWord)namelen );
- return res.isError ? -1 : res.val;
+ return res.isError ? -1 : res.res;
+
+#elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+ I_die_here;
#else
-# error Unknown archx
+# error Unknown arch
#endif
}
Int VG_(getsockopt) ( Int sd, Int level, Int optname, void *optval,
Int *optlen)
{
- SysRes res;
-
#if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
+ SysRes res;
UWord args[5];
args[0] = sd;
args[1] = level;
args[3] = (UWord)optval;
args[4] = (UWord)optlen;
res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETSOCKOPT, (UWord)&args);
- return res.isError ? -1 : res.val;
+ return res.isError ? -1 : res.res;
#elif defined(VGP_amd64_linux)
+ SysRes res;
res = VG_(do_syscall5)( __NR_getsockopt,
(UWord)sd, (UWord)level, (UWord)optname,
(UWord)optval, (UWord)optlen );
- return res.isError ? -1 : res.val;
+ return res.isError ? -1 : res.res;
+
+#elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+ I_die_here;
#else
# error Unknown arch