From: Julian Seward Date: Tue, 17 Oct 2006 01:38:13 +0000 (+0000) Subject: Merge r6130: X-Git-Tag: svn/VALGRIND_3_3_0~609 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=49a9f8d4f96046042a8449102f61615b2f040e7a;p=thirdparty%2Fvalgrind.git Merge r6130: - AIX implementations of various stuff, nothing surprising. - For all platforms: make VG_(read) and VG_(write) return (negative) actual error values rather than producing -1 for all failures. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@6267 --- diff --git a/coregrind/m_libcfile.c b/coregrind/m_libcfile.c index 37bdb07779..fb08569916 100644 --- a/coregrind/m_libcfile.c +++ b/coregrind/m_libcfile.c @@ -30,6 +30,7 @@ #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" @@ -37,7 +38,6 @@ #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 @@ -61,6 +61,7 @@ Int VG_(safe_fd)(Int oldfd) 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)); @@ -96,14 +97,30 @@ void VG_(close) ( Int fd ) 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] ) @@ -115,39 +132,61 @@ 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; } @@ -161,7 +200,7 @@ SysRes VG_(dup) ( Int oldfd ) 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 ) @@ -176,14 +215,25 @@ Int VG_(unlink) ( Char* file_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) @@ -191,7 +241,7 @@ 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) @@ -199,14 +249,14 @@ 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 @@ -215,10 +265,16 @@ Int VG_(access) ( HChar* path, Bool irusr, Bool iwusr, Bool ixusr ) | (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 } /* @@ -244,11 +300,11 @@ Int VG_(check_executable)(HChar* f) #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; } @@ -326,7 +382,7 @@ Int VG_(mkstemp) ( HChar* part_of_name, /*OUT*/HChar* fullname ) 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; @@ -346,7 +402,12 @@ static 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 ) @@ -404,6 +465,9 @@ UShort VG_(ntohs) ( UShort 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; @@ -438,13 +502,14 @@ Int VG_(connect_via_socket)( UChar* str ) } 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; @@ -495,12 +560,15 @@ Int my_socket ( Int domain, Int type, Int protocol ) 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 @@ -508,7 +576,12 @@ 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 ) { #if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux) @@ -518,12 +591,15 @@ Int my_connect ( Int sockfd, struct vki_sockaddr_in* serv_addr, 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 @@ -533,10 +609,9 @@ Int my_connect ( Int sockfd, struct vki_sockaddr_in* serv_addr, 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; @@ -544,14 +619,18 @@ Int VG_(write_socket)( Int sd, void *msg, Int count ) 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 @@ -560,20 +639,23 @@ Int VG_(write_socket)( Int sd, void *msg, Int count ) 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 @@ -582,32 +664,34 @@ Int VG_(getsockname) ( Int sd, struct vki_sockaddr *name, Int *namelen) 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; @@ -615,13 +699,17 @@ Int VG_(getsockopt) ( Int sd, Int level, Int optname, void *optval, 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 diff --git a/coregrind/pub_core_libcfile.h b/coregrind/pub_core_libcfile.h index 34bfd5fdea..d63e895e18 100644 --- a/coregrind/pub_core_libcfile.h +++ b/coregrind/pub_core_libcfile.h @@ -34,6 +34,7 @@ //-------------------------------------------------------------------- // PURPOSE: This module contains all the libc code that relates to // files and sockets: opening, reading, writing, etc. +// To use, you must first include: pub_core_vki.h //-------------------------------------------------------------------- #include "pub_tool_libcfile.h" diff --git a/include/pub_tool_libcfile.h b/include/pub_tool_libcfile.h index eb824fe8f9..bb371b9f19 100644 --- a/include/pub_tool_libcfile.h +++ b/include/pub_tool_libcfile.h @@ -35,6 +35,8 @@ File-related functions. ------------------------------------------------------------------ */ +/* To use this file you must first include pub_tool_vki.h. */ + extern SysRes VG_(open) ( const Char* pathname, Int flags, Int mode ); extern void VG_(close) ( Int fd ); extern Int VG_(read) ( Int fd, void* buf, Int count);