]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Merge r6130:
authorJulian Seward <jseward@acm.org>
Tue, 17 Oct 2006 01:38:13 +0000 (01:38 +0000)
committerJulian Seward <jseward@acm.org>
Tue, 17 Oct 2006 01:38:13 +0000 (01:38 +0000)
- 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

coregrind/m_libcfile.c
coregrind/pub_core_libcfile.h
include/pub_tool_libcfile.h

index 37bdb0777972524a881bc4b9dde8728ed25fbcd4..fb08569916680fe68b7181a43da6472c493d53be 100644 (file)
@@ -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
index 34bfd5fdeaaec326877e60123afade4c1cd2eee1..d63e895e18c7056174dbfd66b6e03a3351ec583a 100644 (file)
@@ -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"
index eb824fe8f972f5c0a282991f6a276df9ee448d4f..bb371b9f1904d6f1bc3b7b0220f7a5552432a82d 100644 (file)
@@ -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);