Home | History | Annotate | Download | only in coregrind
      1 /* -*- mode: C; c-basic-offset: 3; -*- */
      2 
      3 /*--------------------------------------------------------------------*/
      4 /*--- File- and socket-related libc stuff.            m_libcfile.c ---*/
      5 /*--------------------------------------------------------------------*/
      6 
      7 /*
      8    This file is part of Valgrind, a dynamic binary instrumentation
      9    framework.
     10 
     11    Copyright (C) 2000-2015 Julian Seward
     12       jseward (at) acm.org
     13 
     14    This program is free software; you can redistribute it and/or
     15    modify it under the terms of the GNU General Public License as
     16    published by the Free Software Foundation; either version 2 of the
     17    License, or (at your option) any later version.
     18 
     19    This program is distributed in the hope that it will be useful, but
     20    WITHOUT ANY WARRANTY; without even the implied warranty of
     21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     22    General Public License for more details.
     23 
     24    You should have received a copy of the GNU General Public License
     25    along with this program; if not, write to the Free Software
     26    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     27    02111-1307, USA.
     28 
     29    The GNU General Public License is contained in the file COPYING.
     30 */
     31 
     32 #include "pub_core_basics.h"
     33 #include "pub_core_vki.h"
     34 #include "pub_core_vkiscnums.h"
     35 #include "pub_core_debuglog.h"
     36 #include "pub_core_libcbase.h"
     37 #include "pub_core_libcassert.h"
     38 #include "pub_core_libcfile.h"
     39 #include "pub_core_libcprint.h"     // VG_(sprintf)
     40 #include "pub_core_libcproc.h"      // VG_(getpid), VG_(getppid)
     41 #include "pub_core_clientstate.h"   // VG_(fd_hard_limit)
     42 #include "pub_core_mallocfree.h"    // VG_(realloc)
     43 #include "pub_core_syscall.h"
     44 
     45 /* IMPORTANT: on Darwin it is essential to use the _nocancel versions
     46    of syscalls rather than the vanilla version, if a _nocancel version
     47    is available.  See docs/internals/Darwin-notes.txt for the reason
     48    why. */
     49 
     50 /* ---------------------------------------------------------------------
     51    File stuff
     52    ------------------------------------------------------------------ */
     53 
     54 /* Move an fd into the Valgrind-safe range */
     55 Int VG_(safe_fd)(Int oldfd)
     56 {
     57    Int newfd;
     58 
     59    vg_assert(VG_(fd_hard_limit) != -1);
     60 
     61    newfd = VG_(fcntl)(oldfd, VKI_F_DUPFD, VG_(fd_hard_limit));
     62    if (newfd != -1)
     63       VG_(close)(oldfd);
     64 
     65    /* Set the close-on-exec flag for this fd. */
     66    VG_(fcntl)(newfd, VKI_F_SETFD, VKI_FD_CLOEXEC);
     67 
     68    vg_assert(newfd >= VG_(fd_hard_limit));
     69    return newfd;
     70 }
     71 
     72 /* Given a file descriptor, attempt to deduce its filename.  To do
     73    this, we use /proc/self/fd/<FD>.  If this doesn't point to a file,
     74    or if it doesn't exist, we return False.
     75    Upon successful completion *result contains the filename. The
     76    filename will be overwritten with the next invocation so callers
     77    need to copy the filename if needed. *result is NULL if the filename
     78    cannot be deduced. */
     79 Bool VG_(resolve_filename) ( Int fd, const HChar** result )
     80 {
     81 #  if defined(VGO_linux) || defined(VGO_solaris)
     82    static HChar *buf = NULL;
     83    static SizeT  bufsiz = 0;
     84 
     85    if (buf == NULL) {   // first time
     86       bufsiz = 500;
     87       buf = VG_(malloc)("resolve_filename", bufsiz);
     88    }
     89 
     90    HChar tmp[64];   // large enough
     91    {
     92 #     if defined(VGO_linux)
     93       VG_(sprintf)(tmp, "/proc/self/fd/%d", fd);
     94 #     elif defined(VGO_solaris)
     95       VG_(sprintf)(tmp, "/proc/self/path/%d", fd);
     96 #     endif
     97    }
     98 
     99    while (42) {
    100       SSizeT res = VG_(readlink)(tmp, buf, bufsiz);
    101       if (res < 0) break;
    102       if (res == bufsiz) {  // buffer too small; increase and retry
    103          bufsiz += 500;
    104          buf = VG_(realloc)("resolve_filename", buf, bufsiz);
    105          continue;
    106       }
    107       vg_assert(bufsiz > res);  // paranoia
    108       if (buf[0] != '/') break;
    109 
    110       buf[res] = '\0';
    111       *result = buf;
    112       return True;
    113    }
    114    // Failure
    115    *result = NULL;
    116    return False;
    117 
    118 #  elif defined(VGO_darwin)
    119    HChar tmp[VKI_MAXPATHLEN+1];
    120    if (0 == VG_(fcntl)(fd, VKI_F_GETPATH, (UWord)tmp)) {
    121       static HChar *buf = NULL;
    122 
    123       if (buf == NULL)
    124          buf = VG_(malloc)("resolve_filename", VKI_MAXPATHLEN+1);
    125       VG_(strcpy)( buf, tmp );
    126 
    127       *result = buf;
    128       if (buf[0] == '/') return True;
    129    }
    130    // Failure
    131    *result = NULL;
    132    return False;
    133 
    134 #  else
    135 #     error Unknown OS
    136 #  endif
    137 }
    138 
    139 SysRes VG_(mknod) ( const HChar* pathname, Int mode, UWord dev )
    140 {
    141 #  if defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
    142    /* ARM64 wants to use __NR_mknodat rather than __NR_mknod. */
    143    SysRes res = VG_(do_syscall4)(__NR_mknodat,
    144                                  VKI_AT_FDCWD, (UWord)pathname, mode, dev);
    145 #  elif defined(VGO_linux) || defined(VGO_darwin)
    146    SysRes res = VG_(do_syscall3)(__NR_mknod,
    147                                  (UWord)pathname, mode, dev);
    148 #  elif defined(VGO_solaris)
    149    SysRes res = VG_(do_syscall4)(__NR_mknodat,
    150                                  VKI_AT_FDCWD, (UWord)pathname, mode, dev);
    151 #  else
    152 #    error Unknown OS
    153 #  endif
    154    return res;
    155 }
    156 
    157 SysRes VG_(open) ( const HChar* pathname, Int flags, Int mode )
    158 {
    159 #  if defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
    160    /* ARM64 wants to use __NR_openat rather than __NR_open. */
    161    SysRes res = VG_(do_syscall4)(__NR_openat,
    162                                  VKI_AT_FDCWD, (UWord)pathname, flags, mode);
    163 #  elif defined(VGO_linux)
    164    SysRes res = VG_(do_syscall3)(__NR_open,
    165                                  (UWord)pathname, flags, mode);
    166 #  elif defined(VGO_darwin)
    167    SysRes res = VG_(do_syscall3)(__NR_open_nocancel,
    168                                  (UWord)pathname, flags, mode);
    169 #  elif defined(VGO_solaris)
    170    SysRes res = VG_(do_syscall4)(__NR_openat,
    171                                  VKI_AT_FDCWD, (UWord)pathname, flags, mode);
    172 #  else
    173 #    error Unknown OS
    174 #  endif
    175    return res;
    176 }
    177 
    178 Int VG_(fd_open) (const HChar* pathname, Int flags, Int mode)
    179 {
    180    SysRes sr;
    181    sr = VG_(open) (pathname, flags, mode);
    182    if (sr_isError (sr))
    183       return -1;
    184    else
    185       return sr_Res (sr);
    186 }
    187 
    188 void VG_(close) ( Int fd )
    189 {
    190    /* Hmm.  Return value is not checked.  That's uncool. */
    191 #  if defined(VGO_linux) || defined(VGO_solaris)
    192    (void)VG_(do_syscall1)(__NR_close, fd);
    193 #  elif defined(VGO_darwin)
    194    (void)VG_(do_syscall1)(__NR_close_nocancel, fd);
    195 #  else
    196 #    error Unknown OS
    197 #  endif
    198 }
    199 
    200 Int VG_(read) ( Int fd, void* buf, Int count)
    201 {
    202    Int    ret;
    203 #  if defined(VGO_linux) || defined(VGO_solaris)
    204    SysRes res = VG_(do_syscall3)(__NR_read, fd, (UWord)buf, count);
    205 #  elif defined(VGO_darwin)
    206    SysRes res = VG_(do_syscall3)(__NR_read_nocancel, fd, (UWord)buf, count);
    207 #  else
    208 #    error Unknown OS
    209 #  endif
    210    if (sr_isError(res)) {
    211       ret = - (Int)(Word)sr_Err(res);
    212       vg_assert(ret < 0);
    213    } else {
    214       ret = (Int)(Word)sr_Res(res);
    215       vg_assert(ret >= 0);
    216    }
    217    return ret;
    218 }
    219 
    220 Int VG_(write) ( Int fd, const void* buf, Int count)
    221 {
    222    Int    ret;
    223 #  if defined(VGO_linux) || defined(VGO_solaris)
    224    SysRes res = VG_(do_syscall3)(__NR_write, fd, (UWord)buf, count);
    225 #  elif defined(VGO_darwin)
    226    SysRes res = VG_(do_syscall3)(__NR_write_nocancel, fd, (UWord)buf, count);
    227 #  else
    228 #    error "Unknown OS"
    229 #  endif
    230    if (sr_isError(res)) {
    231       ret = - (Int)(Word)sr_Err(res);
    232       vg_assert(ret < 0);
    233    } else {
    234       ret = (Int)(Word)sr_Res(res);
    235       vg_assert(ret >= 0);
    236    }
    237    return ret;
    238 }
    239 
    240 
    241 Int VG_(pipe) ( Int fd[2] )
    242 {
    243 #  if defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
    244    /* __NR_pipe has a strange return convention on mips32-linux. */
    245    SysRes res = VG_(do_syscall1)(__NR_pipe, (UWord)fd);
    246    if (!sr_isError(res)) {
    247       fd[0] = (Int)sr_Res(res);
    248       fd[1] = (Int)sr_ResEx(res);
    249       return 0;
    250    } else {
    251       return -1;
    252    }
    253 #  elif defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
    254    SysRes res = VG_(do_syscall2)(__NR_pipe2, (UWord)fd, 0);
    255    return sr_isError(res) ? -1 : 0;
    256 #  elif defined(VGO_linux)
    257    SysRes res = VG_(do_syscall1)(__NR_pipe, (UWord)fd);
    258    return sr_isError(res) ? -1 : 0;
    259 #  elif defined(VGO_darwin)
    260    /* __NR_pipe is UX64, so produces a double-word result */
    261    SysRes res = VG_(do_syscall0)(__NR_pipe);
    262    if (!sr_isError(res)) {
    263       fd[0] = (Int)sr_Res(res);
    264       fd[1] = (Int)sr_ResHI(res);
    265    }
    266    return sr_isError(res) ? -1 : 0;
    267 #  elif defined(VGO_solaris)
    268 #  if defined(SOLARIS_NEW_PIPE_SYSCALL)
    269    SysRes res = VG_(do_syscall2)(__NR_pipe, (UWord)fd, 0);
    270    return sr_isError(res) ? -1 : 0;
    271 #  else
    272    SysRes res = VG_(do_syscall0)(__NR_pipe);
    273    if (!sr_isError(res)) {
    274       fd[0] = (Int)sr_Res(res);
    275       fd[1] = (Int)sr_ResHI(res);
    276    }
    277    return sr_isError(res) ? -1 : 0;
    278 #  endif
    279 #  else
    280 #    error "Unknown OS"
    281 #  endif
    282 }
    283 
    284 Off64T VG_(lseek) ( Int fd, Off64T offset, Int whence )
    285 {
    286 #  if defined(VGO_linux) || defined(VGP_amd64_darwin)
    287 #  if defined(__NR__llseek)
    288    Off64T result;
    289    SysRes res = VG_(do_syscall5)(__NR__llseek, fd,
    290                                  offset >> 32, offset & 0xffffffff,
    291                                  (UWord)&result, whence);
    292    return sr_isError(res) ? (-1) : result;
    293 #  else
    294    SysRes res = VG_(do_syscall3)(__NR_lseek, fd, offset, whence);
    295    vg_assert(sizeof(Off64T) == sizeof(Word));
    296    return sr_isError(res) ? (-1) : sr_Res(res);
    297 #  endif
    298 #  elif defined(VGP_x86_darwin)
    299    SysRes res = VG_(do_syscall4)(__NR_lseek, fd,
    300                                  offset & 0xffffffff, offset >> 32, whence);
    301    return sr_isError(res) ? (-1) : sr_Res(res);
    302 #  elif defined(VGP_x86_solaris)
    303    SysRes res = VG_(do_syscall4)(__NR_llseek, fd,
    304                                  offset & 0xffffffff, offset >> 32, whence);
    305    return sr_isError(res) ? (-1) : ((ULong)sr_ResHI(res) << 32 | sr_Res(res));
    306 #  elif defined(VGP_amd64_solaris)
    307    SysRes res = VG_(do_syscall3)(__NR_lseek, fd, offset, whence);
    308    vg_assert(sizeof(Off64T) == sizeof(Word));
    309    return sr_isError(res) ? (-1) : sr_Res(res);
    310 #  else
    311 #    error "Unknown plat"
    312 #  endif
    313    /* if you change the error-reporting conventions of this, also
    314       change all usage points. */
    315 }
    316 
    317 
    318 /* stat/fstat support.  It's uggerly.  We have impedance-match into a
    319    'struct vg_stat' in order to have a single structure that callers
    320    can use consistently on all platforms. */
    321 
    322 #define TRANSLATE_TO_vg_stat(_p_vgstat, _p_vkistat) \
    323    do { \
    324       (_p_vgstat)->dev        = (ULong)( (_p_vkistat)->st_dev ); \
    325       (_p_vgstat)->ino        = (ULong)( (_p_vkistat)->st_ino ); \
    326       (_p_vgstat)->nlink      = (ULong)( (_p_vkistat)->st_nlink ); \
    327       (_p_vgstat)->mode       = (UInt) ( (_p_vkistat)->st_mode ); \
    328       (_p_vgstat)->uid        = (UInt) ( (_p_vkistat)->st_uid ); \
    329       (_p_vgstat)->gid        = (UInt) ( (_p_vkistat)->st_gid ); \
    330       (_p_vgstat)->rdev       = (ULong)( (_p_vkistat)->st_rdev ); \
    331       (_p_vgstat)->size       = (Long) ( (_p_vkistat)->st_size ); \
    332       (_p_vgstat)->blksize    = (ULong)( (_p_vkistat)->st_blksize ); \
    333       (_p_vgstat)->blocks     = (ULong)( (_p_vkistat)->st_blocks ); \
    334       (_p_vgstat)->atime      = (ULong)( (_p_vkistat)->st_atime ); \
    335       (_p_vgstat)->atime_nsec = (ULong)( (_p_vkistat)->st_atime_nsec ); \
    336       (_p_vgstat)->mtime      = (ULong)( (_p_vkistat)->st_mtime ); \
    337       (_p_vgstat)->mtime_nsec = (ULong)( (_p_vkistat)->st_mtime_nsec ); \
    338       (_p_vgstat)->ctime      = (ULong)( (_p_vkistat)->st_ctime ); \
    339       (_p_vgstat)->ctime_nsec = (ULong)( (_p_vkistat)->st_ctime_nsec ); \
    340    } while (0)
    341 
    342 SysRes VG_(stat) ( const HChar* file_name, struct vg_stat* vgbuf )
    343 {
    344    SysRes res;
    345    VG_(memset)(vgbuf, 0, sizeof(*vgbuf));
    346 
    347 #  if defined(VGO_linux) || defined(VGO_darwin)
    348    /* First try with stat64.  If that doesn't work out, fall back to
    349       the vanilla version. */
    350 #  if defined(__NR_stat64)
    351    { struct vki_stat64 buf64;
    352      res = VG_(do_syscall2)(__NR_stat64, (UWord)file_name, (UWord)&buf64);
    353      if (!(sr_isError(res) && sr_Err(res) == VKI_ENOSYS)) {
    354         /* Success, or any failure except ENOSYS */
    355         if (!sr_isError(res))
    356            TRANSLATE_TO_vg_stat(vgbuf, &buf64);
    357         return res;
    358      }
    359    }
    360 #  endif /* defined(__NR_stat64) */
    361    /* This is the fallback ("vanilla version"). */
    362    { struct vki_stat buf;
    363 #    if defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
    364      res = VG_(do_syscall3)(__NR3264_fstatat, VKI_AT_FDCWD,
    365                                               (UWord)file_name, (UWord)&buf);
    366 #    else
    367      res = VG_(do_syscall2)(__NR_stat, (UWord)file_name, (UWord)&buf);
    368 #    endif
    369      if (!sr_isError(res))
    370         TRANSLATE_TO_vg_stat(vgbuf, &buf);
    371      return res;
    372    }
    373 #  elif defined(VGO_solaris)
    374    {
    375 #     if defined(VGP_x86_solaris)
    376       struct vki_stat64 buf64;
    377       res = VG_(do_syscall4)(__NR_fstatat64, VKI_AT_FDCWD, (UWord)file_name,
    378                              (UWord)&buf64, 0);
    379 #     elif defined(VGP_amd64_solaris)
    380       struct vki_stat buf64;
    381       res = VG_(do_syscall4)(__NR_fstatat, VKI_AT_FDCWD, (UWord)file_name,
    382                              (UWord)&buf64, 0);
    383 #     else
    384 #        error "Unknown platform"
    385 #     endif
    386       if (!sr_isError(res))
    387          TRANSLATE_TO_vg_stat(vgbuf, &buf64);
    388       return res;
    389    }
    390 #  else
    391 #    error Unknown OS
    392 #  endif
    393 }
    394 
    395 Int VG_(fstat) ( Int fd, struct vg_stat* vgbuf )
    396 {
    397    SysRes res;
    398    VG_(memset)(vgbuf, 0, sizeof(*vgbuf));
    399 
    400 #  if defined(VGO_linux) || defined(VGO_darwin)
    401    /* First try with fstat64.  If that doesn't work out, fall back to
    402       the vanilla version. */
    403 #  if defined(__NR_fstat64)
    404    { struct vki_stat64 buf64;
    405      res = VG_(do_syscall2)(__NR_fstat64, (UWord)fd, (UWord)&buf64);
    406      if (!(sr_isError(res) && sr_Err(res) == VKI_ENOSYS)) {
    407         /* Success, or any failure except ENOSYS */
    408         if (!sr_isError(res))
    409            TRANSLATE_TO_vg_stat(vgbuf, &buf64);
    410         return sr_isError(res) ? (-1) : 0;
    411      }
    412    }
    413 #  endif /* if defined(__NR_fstat64) */
    414    { struct vki_stat buf;
    415      res = VG_(do_syscall2)(__NR_fstat, (UWord)fd, (UWord)&buf);
    416      if (!sr_isError(res))
    417         TRANSLATE_TO_vg_stat(vgbuf, &buf);
    418      return sr_isError(res) ? (-1) : 0;
    419    }
    420 #  elif defined(VGO_solaris)
    421    {
    422 #     if defined(VGP_x86_solaris)
    423       struct vki_stat64 buf64;
    424       res = VG_(do_syscall4)(__NR_fstatat64, (UWord)fd, 0, (UWord)&buf64, 0);
    425 #     elif defined(VGP_amd64_solaris)
    426       struct vki_stat buf64;
    427       res = VG_(do_syscall4)(__NR_fstatat, (UWord)fd, 0, (UWord)&buf64, 0);
    428 #     else
    429 #        error "Unknown platform"
    430 #     endif
    431       if (!sr_isError(res))
    432          TRANSLATE_TO_vg_stat(vgbuf, &buf64);
    433       return sr_isError(res) ? (-1) : 0;
    434    }
    435 #  else
    436 #    error Unknown OS
    437 #  endif
    438 }
    439 
    440 #undef TRANSLATE_TO_vg_stat
    441 
    442 
    443 Long VG_(fsize) ( Int fd )
    444 {
    445    struct vg_stat buf;
    446    Int res = VG_(fstat)( fd, &buf );
    447    return (res == -1) ? (-1LL) : buf.size;
    448 }
    449 
    450 SysRes VG_(getxattr) ( const HChar* file_name, const HChar* attr_name, Addr attr_value, SizeT attr_value_len )
    451 {
    452    SysRes res;
    453 #if defined(VGO_linux)
    454    res = VG_(do_syscall4)(__NR_getxattr, (UWord)file_name, (UWord)attr_name,
    455                           attr_value, attr_value_len);
    456 #else
    457    res = VG_(mk_SysRes_Error)(VKI_ENOSYS);
    458 #endif
    459    return res;
    460 }
    461 
    462 Bool VG_(is_dir) ( const HChar* f )
    463 {
    464    struct vg_stat buf;
    465    SysRes res = VG_(stat)(f, &buf);
    466    return sr_isError(res) ? False
    467                       : VKI_S_ISDIR(buf.mode) ? True : False;
    468 }
    469 
    470 SysRes VG_(dup) ( Int oldfd )
    471 {
    472 #  if defined(VGO_linux) || defined(VGO_darwin)
    473    return VG_(do_syscall1)(__NR_dup, oldfd);
    474 #  elif defined(VGO_solaris)
    475    return VG_(do_syscall3)(__NR_fcntl, oldfd, F_DUPFD, 0);
    476 #  else
    477 #    error Unknown OS
    478 #  endif
    479 }
    480 
    481 SysRes VG_(dup2) ( Int oldfd, Int newfd )
    482 {
    483 #  if defined(VGO_linux) || defined(VGO_darwin)
    484    return VG_(do_syscall2)(__NR_dup2, oldfd, newfd);
    485 #  elif defined(VGO_solaris)
    486    return VG_(do_syscall3)(__NR_fcntl, oldfd, F_DUP2FD, newfd);
    487 #  else
    488 #    error Unknown OS
    489 #  endif
    490 }
    491 
    492 /* Returns -1 on error. */
    493 Int VG_(fcntl) ( Int fd, Int cmd, Addr arg )
    494 {
    495 #  if defined(VGO_linux) || defined(VGO_solaris)
    496    SysRes res = VG_(do_syscall3)(__NR_fcntl, fd, cmd, arg);
    497 #  elif defined(VGO_darwin)
    498    SysRes res = VG_(do_syscall3)(__NR_fcntl_nocancel, fd, cmd, arg);
    499 #  else
    500 #    error "Unknown OS"
    501 #  endif
    502    return sr_isError(res) ? -1 : sr_Res(res);
    503 }
    504 
    505 Int VG_(rename) ( const HChar* old_name, const HChar* new_name )
    506 {
    507 #  if defined(VGP_tilegx_linux)
    508    SysRes res = VG_(do_syscall3)(__NR_renameat, VKI_AT_FDCWD,
    509                                  (UWord)old_name, (UWord)new_name);
    510 #  elif defined(VGO_linux) || defined(VGO_darwin)
    511    SysRes res = VG_(do_syscall2)(__NR_rename, (UWord)old_name, (UWord)new_name);
    512 #  elif defined(VGO_solaris)
    513    SysRes res = VG_(do_syscall4)(__NR_renameat, VKI_AT_FDCWD, (UWord)old_name,
    514                                  VKI_AT_FDCWD, (UWord)new_name);
    515 #  else
    516 #    error "Unknown OS"
    517 #  endif
    518    return sr_isError(res) ? (-1) : 0;
    519 }
    520 
    521 Int VG_(unlink) ( const HChar* file_name )
    522 {
    523 #  if defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
    524    SysRes res = VG_(do_syscall2)(__NR_unlinkat, VKI_AT_FDCWD,
    525                                                 (UWord)file_name);
    526 #  elif defined(VGO_linux) || defined(VGO_darwin)
    527    SysRes res = VG_(do_syscall1)(__NR_unlink, (UWord)file_name);
    528 #  elif defined(VGO_solaris)
    529    SysRes res = VG_(do_syscall3)(__NR_unlinkat, VKI_AT_FDCWD,
    530                                  (UWord)file_name, 0);
    531 #  else
    532 #    error "Unknown OS"
    533 #  endif
    534    return sr_isError(res) ? (-1) : 0;
    535 }
    536 
    537 /* The working directory at startup.
    538    All that is really needed is to note the cwd at process startup.
    539    Hence VG_(record_startup_wd) notes it (in a platform dependent way)
    540    and VG_(get_startup_wd) produces the noted value. */
    541 static HChar *startup_wd;
    542 static Bool   startup_wd_acquired = False;
    543 
    544 /* Record the process' working directory at startup.  Is intended to
    545    be called exactly once, at startup, before the working directory
    546    changes.  Return True for success, False for failure, so that the
    547    caller can bomb out suitably without creating module cycles if
    548    there is a problem. */
    549 Bool VG_(record_startup_wd) ( void )
    550 {
    551    vg_assert(!startup_wd_acquired);
    552 #  if defined(VGO_linux) || defined(VGO_solaris)
    553    /* Simple: just ask the kernel */
    554    SysRes res;
    555    SizeT szB = 0;
    556    do {
    557       szB += 500;
    558       startup_wd = VG_(realloc)("startup_wd", startup_wd, szB);
    559       VG_(memset)(startup_wd, 0, szB);
    560       res = VG_(do_syscall2)(__NR_getcwd, (UWord)startup_wd, szB-1);
    561    } while (sr_isError(res));
    562 
    563    vg_assert(startup_wd[szB-1] == 0);
    564    startup_wd_acquired = True;
    565    return True;
    566 
    567 #  elif defined(VGO_darwin)
    568    /* We can't ask the kernel, so instead rely on launcher-*.c to
    569       tell us the startup path.  Note the env var is keyed to the
    570       parent's PID, not ours, since our parent is the launcher
    571       process. */
    572    { HChar  envvar[100];   // large enough
    573      HChar* wd;
    574      VG_(memset)(envvar, 0, sizeof(envvar));
    575      VG_(sprintf)(envvar, "VALGRIND_STARTUP_PWD_%d_XYZZY",
    576                           (Int)VG_(getppid)());
    577      wd = VG_(getenv)( envvar );
    578      if (wd == NULL)
    579         return False;
    580      SizeT need = VG_(strlen)(wd) + 1;
    581      startup_wd = VG_(malloc)("startup_wd", need);
    582      VG_(strcpy)(startup_wd, wd);
    583      startup_wd_acquired = True;
    584      return True;
    585    }
    586 #  else
    587 #    error Unknown OS
    588 #  endif
    589 }
    590 
    591 /* Return the previously acquired startup_wd. */
    592 const HChar *VG_(get_startup_wd) ( void )
    593 {
    594    vg_assert(startup_wd_acquired);
    595 
    596    return startup_wd;
    597 }
    598 
    599 SysRes VG_(poll) (struct vki_pollfd *fds, Int nfds, Int timeout)
    600 {
    601    SysRes res;
    602 #  if defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
    603    /* ARM64 wants to use __NR_ppoll rather than __NR_poll. */
    604    struct vki_timespec timeout_ts;
    605    if (timeout >= 0) {
    606       timeout_ts.tv_sec = timeout / 1000;
    607       timeout_ts.tv_nsec = ((long)timeout % 1000) * 1000000;
    608    }
    609    res = VG_(do_syscall4)(__NR_ppoll,
    610                           (UWord)fds, nfds,
    611                           (UWord)(timeout >= 0 ? &timeout_ts : NULL),
    612                           (UWord)NULL);
    613 #  elif defined(VGO_linux)
    614    res = VG_(do_syscall3)(__NR_poll, (UWord)fds, nfds, timeout);
    615 #  elif defined(VGO_darwin)
    616    res = VG_(do_syscall3)(__NR_poll_nocancel, (UWord)fds, nfds, timeout);
    617 #  elif defined(VGO_solaris)
    618    struct vki_timespec ts;
    619    struct vki_timespec *tsp;
    620 
    621    if (timeout < 0)
    622       tsp = NULL;
    623    else {
    624       ts.tv_sec = timeout / 1000;
    625       ts.tv_nsec = (timeout % 1000) * 1000000;
    626       tsp = &ts;
    627    }
    628 
    629    res = VG_(do_syscall4)(__NR_pollsys, (UWord)fds, nfds, (UWord)tsp, 0);
    630 #  else
    631 #    error "Unknown OS"
    632 #  endif
    633    return res;
    634 }
    635 
    636 
    637 /* Performs the readlink operation and puts the result into 'buf'.
    638    Note, that the string in 'buf' is *not* null-terminated. The function
    639    returns the number of characters put into 'buf' or -1 if an error
    640    occurred. */
    641 SSizeT VG_(readlink) (const HChar* path, HChar* buf, SizeT bufsiz)
    642 {
    643    SysRes res;
    644    /* res = readlink( path, buf, bufsiz ); */
    645 #  if defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
    646    res = VG_(do_syscall4)(__NR_readlinkat, VKI_AT_FDCWD,
    647                                            (UWord)path, (UWord)buf, bufsiz);
    648 #  elif defined(VGO_linux) || defined(VGO_darwin)
    649    res = VG_(do_syscall3)(__NR_readlink, (UWord)path, (UWord)buf, bufsiz);
    650 #  elif defined(VGO_solaris)
    651    res = VG_(do_syscall4)(__NR_readlinkat, VKI_AT_FDCWD, (UWord)path,
    652                           (UWord)buf, bufsiz);
    653 #  else
    654 #    error "Unknown OS"
    655 #  endif
    656    return sr_isError(res) ? -1 : sr_Res(res);
    657 }
    658 
    659 #if defined(VGO_linux) || defined(VGO_solaris)
    660 Int VG_(getdents64) (Int fd, struct vki_dirent64 *dirp, UInt count)
    661 {
    662    SysRes res;
    663    /* res = getdents( fd, dirp, count ); */
    664 #  if defined(VGP_amd64_solaris)
    665    /* This silently assumes that dirent64 and dirent on amd64 are same, which
    666       they should always be. */
    667    res = VG_(do_syscall3)(__NR_getdents, fd, (UWord)dirp, count);
    668 #  else
    669    res = VG_(do_syscall3)(__NR_getdents64, fd, (UWord)dirp, count);
    670 #  endif
    671    return sr_isError(res) ? -1 : sr_Res(res);
    672 }
    673 #endif
    674 
    675 /* Check accessibility of a file.  Returns zero for access granted,
    676    nonzero otherwise. */
    677 Int VG_(access) ( const HChar* path, Bool irusr, Bool iwusr, Bool ixusr )
    678 {
    679 #  if defined(VGO_linux)
    680    /* Very annoyingly, I cannot find any definition for R_OK et al in
    681       the kernel interfaces.  Therefore I reluctantly resort to
    682       hardwiring in these magic numbers that I determined by
    683       experimentation. */
    684 #  define VKI_R_OK 4
    685 #  define VKI_W_OK 2
    686 #  define VKI_X_OK 1
    687 #  endif
    688 
    689    UWord w = (irusr ? VKI_R_OK : 0)
    690              | (iwusr ? VKI_W_OK : 0)
    691              | (ixusr ? VKI_X_OK : 0);
    692 #  if defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
    693    SysRes res = VG_(do_syscall3)(__NR_faccessat, VKI_AT_FDCWD, (UWord)path, w);
    694 #  elif defined(VGO_linux) || defined(VGO_darwin)
    695    SysRes res = VG_(do_syscall2)(__NR_access, (UWord)path, w);
    696 #  elif defined(VGO_solaris)
    697    SysRes res = VG_(do_syscall4)(__NR_faccessat, VKI_AT_FDCWD, (UWord)path,
    698                                  w, 0);
    699 #  else
    700 #    error "Unknown OS"
    701 #  endif
    702    return sr_isError(res) ? 1 : 0;
    703 
    704 #  if defined(VGO_linux)
    705 #  undef VKI_R_OK
    706 #  undef VKI_W_OK
    707 #  undef VKI_X_OK
    708 #  endif
    709 }
    710 
    711 /*
    712    Emulate the normal Unix permissions checking algorithm.
    713 
    714    If owner matches, then use the owner permissions, else
    715    if group matches, then use the group permissions, else
    716    use other permissions.
    717 
    718    Note that we can't deal properly with SUID/SGID.  By default
    719    (allow_setuid == False), we refuse to run them (otherwise the
    720    executable may misbehave if it doesn't have the permissions it
    721    thinks it does).  However, the caller may indicate that setuid
    722    executables are allowed, for example if we are going to exec them
    723    but not trace into them (iow, client sys_execve when
    724    clo_trace_children == False).
    725 
    726    If VKI_EACCES is returned (iow, permission was refused), then
    727    *is_setuid is set to True iff permission was refused because the
    728    executable is setuid.
    729 */
    730 /* returns: 0 = success, non-0 is failure */
    731 Int VG_(check_executable)(/*OUT*/Bool* is_setuid,
    732                           const HChar* f, Bool allow_setuid)
    733 {
    734    struct vg_stat st;
    735    SysRes res = VG_(stat)(f, &st);
    736 
    737    if (is_setuid)
    738       *is_setuid = False;
    739 
    740    if (sr_isError(res)) {
    741       return sr_Err(res);
    742    }
    743 
    744    if ( VKI_S_ISDIR (st.mode) ) {
    745       return VKI_EACCES;
    746    }
    747 
    748    if ( (st.mode & (VKI_S_ISUID | VKI_S_ISGID)) && !allow_setuid ) {
    749       if (is_setuid)
    750          *is_setuid = True;
    751       return VKI_EACCES;
    752    }
    753 
    754    res = VG_(getxattr)(f, "security.capability", (Addr)0, 0);
    755    if (!sr_isError(res) && !allow_setuid) {
    756       if (is_setuid)
    757          *is_setuid = True;
    758       return VKI_EACCES;
    759    }
    760 
    761    if (VG_(geteuid)() == st.uid) {
    762       if (!(st.mode & VKI_S_IXUSR))
    763          return VKI_EACCES;
    764    } else {
    765       Int grpmatch = 0;
    766 
    767       if (VG_(getegid)() == st.gid)
    768 	 grpmatch = 1;
    769       else {
    770          UInt *groups = NULL;
    771          Int   ngrp;
    772 
    773          /* Find out # groups, allocate large enough array and fetch groups */
    774          ngrp = VG_(getgroups)(0, NULL);
    775          if (ngrp != -1) {
    776             groups = VG_(malloc)("check_executable", ngrp * sizeof *groups);
    777             ngrp   = VG_(getgroups)(ngrp, groups);
    778          }
    779 
    780          Int i;
    781          /* ngrp will be -1 if VG_(getgroups) failed. */
    782          for (i = 0; i < ngrp; i++) {
    783 	    if (groups[i] == st.gid) {
    784 	       grpmatch = 1;
    785 	       break;
    786 	    }
    787          }
    788          VG_(free)(groups);
    789       }
    790 
    791       if (grpmatch) {
    792 	 if (!(st.mode & VKI_S_IXGRP)) {
    793             return VKI_EACCES;
    794          }
    795       } else if (!(st.mode & VKI_S_IXOTH)) {
    796          return VKI_EACCES;
    797       }
    798    }
    799 
    800    return 0;
    801 }
    802 
    803 SysRes VG_(pread) ( Int fd, void* buf, Int count, OffT offset )
    804 {
    805    SysRes res;
    806    // on 32 bits platforms, we receive a 32 bits OffT but
    807    // we must extend it to pass a long long 64 bits.
    808 #  if defined(VGP_x86_linux)
    809    vg_assert(sizeof(OffT) == 4);
    810    res = VG_(do_syscall5)(__NR_pread64, fd, (UWord)buf, count,
    811                           offset, 0); // Little endian long long
    812    return res;
    813 #  elif defined(VGP_arm_linux)
    814    vg_assert(sizeof(OffT) == 4);
    815    res = VG_(do_syscall5)(__NR_pread64, fd, (UWord)buf, count,
    816                           0, offset); // Big endian long long
    817    return res;
    818 #  elif defined(VGP_ppc32_linux)
    819    vg_assert(sizeof(OffT) == 4);
    820    res = VG_(do_syscall6)(__NR_pread64, fd, (UWord)buf, count,
    821                           0, // Padding needed on PPC32
    822                           0, offset); // Big endian long long
    823    return res;
    824 #  elif defined(VGP_mips32_linux) && (VKI_LITTLE_ENDIAN)
    825    vg_assert(sizeof(OffT) == 4);
    826    res = VG_(do_syscall6)(__NR_pread64, fd, (UWord)buf, count,
    827                           0, offset, 0);
    828    return res;
    829 #  elif defined(VGP_mips32_linux) && (VKI_BIG_ENDIAN)
    830    vg_assert(sizeof(OffT) == 4);
    831    res = VG_(do_syscall6)(__NR_pread64, fd, (UWord)buf, count,
    832                           0, 0, offset);
    833    return res;
    834 #  elif defined(VGP_amd64_linux) || defined(VGP_s390x_linux) \
    835       || defined(VGP_ppc64be_linux)  || defined(VGP_ppc64le_linux) \
    836       || defined(VGP_mips64_linux) \
    837   || defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
    838    res = VG_(do_syscall4)(__NR_pread64, fd, (UWord)buf, count, offset);
    839    return res;
    840 #  elif defined(VGP_amd64_darwin)
    841    vg_assert(sizeof(OffT) == 8);
    842    res = VG_(do_syscall4)(__NR_pread_nocancel, fd, (UWord)buf, count, offset);
    843    return res;
    844 #  elif defined(VGP_x86_darwin)
    845    vg_assert(sizeof(OffT) == 8);
    846    res = VG_(do_syscall5)(__NR_pread_nocancel, fd, (UWord)buf, count,
    847                           offset & 0xffffffff, offset >> 32);
    848    return res;
    849 #  elif defined(VGP_x86_solaris)
    850    vg_assert(sizeof(OffT) == 4);
    851    res = VG_(do_syscall4)(__NR_pread, fd, (UWord)buf, count, offset);
    852    return res;
    853 #  elif defined(VGP_amd64_solaris)
    854    vg_assert(sizeof(OffT) == 8);
    855    res = VG_(do_syscall4)(__NR_pread, fd, (UWord)buf, count, offset);
    856    return res;
    857 #  else
    858 #    error "Unknown platform"
    859 #  endif
    860 }
    861 
    862 /* Return the name of a directory for temporary files. */
    863 const HChar *VG_(tmpdir)(void)
    864 {
    865    const HChar *tmpdir;
    866 
    867    tmpdir = VG_(getenv)("TMPDIR");
    868    if (tmpdir == NULL || *tmpdir == '\0') tmpdir = VG_TMPDIR;
    869    if (tmpdir == NULL || *tmpdir == '\0') tmpdir = "/tmp";    /* fallback */
    870 
    871    return tmpdir;
    872 }
    873 
    874 static const HChar mkstemp_format[] = "%s/valgrind_%s_%08x";
    875 
    876 SizeT VG_(mkstemp_fullname_bufsz) ( SizeT part_of_name_len )
    877 {
    878    return VG_(strlen)(mkstemp_format)
    879       + VG_(strlen)(VG_(tmpdir)()) - 2 // %s tmpdir
    880       + part_of_name_len - 2           // %s part_of_name
    881       + 8 - 4                          // %08x
    882       + 1;                             // trailing 0
    883 }
    884 
    885 
    886 Int VG_(mkstemp) ( const HChar* part_of_name, /*OUT*/HChar* fullname )
    887 {
    888    Int    n, tries;
    889    UInt   seed;
    890    SysRes sres;
    891    const HChar *tmpdir;
    892 
    893    vg_assert(part_of_name);
    894    vg_assert(fullname);
    895    n = VG_(strlen)(part_of_name);
    896    vg_assert(n > 0 && n < 100);
    897 
    898    seed = (VG_(getpid)() << 9) ^ VG_(getppid)();
    899 
    900    /* Determine sensible location for temporary files */
    901    tmpdir = VG_(tmpdir)();
    902 
    903    tries = 0;
    904    while (True) {
    905       if (tries++ > 10)
    906          return -1;
    907       VG_(sprintf)( fullname, mkstemp_format,
    908                     tmpdir, part_of_name, VG_(random)( &seed ));
    909       if (0)
    910          VG_(printf)("VG_(mkstemp): trying: %s\n", fullname);
    911 
    912       sres = VG_(open)(fullname,
    913                        VKI_O_CREAT|VKI_O_RDWR|VKI_O_EXCL|VKI_O_TRUNC,
    914                        VKI_S_IRUSR|VKI_S_IWUSR);
    915       if (sr_isError(sres)) {
    916          VG_(umsg)("VG_(mkstemp): failed to create temp file: %s\n", fullname);
    917          continue;
    918       }
    919       /* VG_(safe_fd) doesn't return if it fails. */
    920       return VG_(safe_fd)( sr_Res(sres) );
    921    }
    922    /* NOTREACHED */
    923 }
    924 
    925 
    926 /* ---------------------------------------------------------------------
    927    Socket-related stuff.
    928    ------------------------------------------------------------------ */
    929 
    930 static
    931 Int parse_inet_addr_and_port ( const HChar* str, UInt* ip_addr, UShort* port );
    932 
    933 static
    934 Int my_connect ( Int sockfd, struct vki_sockaddr_in* serv_addr, Int addrlen );
    935 
    936 UInt VG_(htonl) ( UInt x )
    937 {
    938 #  if defined(VG_BIGENDIAN)
    939    return x;
    940 #  else
    941    return
    942       (((x >> 24) & 0xFF) << 0) | (((x >> 16) & 0xFF) << 8)
    943       | (((x >> 8) & 0xFF) << 16) | (((x >> 0) & 0xFF) << 24);
    944 #  endif
    945 }
    946 
    947 UInt VG_(ntohl) ( UInt x )
    948 {
    949 #  if defined(VG_BIGENDIAN)
    950    return x;
    951 #  else
    952    return
    953       (((x >> 24) & 0xFF) << 0) | (((x >> 16) & 0xFF) << 8)
    954       | (((x >> 8) & 0xFF) << 16) | (((x >> 0) & 0xFF) << 24);
    955 #  endif
    956 }
    957 
    958 UShort VG_(htons) ( UShort x )
    959 {
    960 #  if defined(VG_BIGENDIAN)
    961    return x;
    962 #  else
    963    return
    964       (((x >> 8) & 0xFF) << 0) | (((x >> 0) & 0xFF) << 8);
    965 #  endif
    966 }
    967 
    968 UShort VG_(ntohs) ( UShort x )
    969 {
    970 #  if defined(VG_BIGENDIAN)
    971    return x;
    972 #  else
    973    return
    974       (((x >> 8) & 0xFF) << 0) | (((x >> 0) & 0xFF) << 8);
    975 #  endif
    976 }
    977 
    978 
    979 /* The main function.
    980 
    981    Supplied string contains either an ip address "192.168.0.1" or
    982    an ip address and port pair, "192.168.0.1:1500".  Parse these,
    983    and return:
    984      -1 if there is a parse error
    985      -2 if no parse error, but specified host:port cannot be opened
    986      the relevant file (socket) descriptor, otherwise.
    987  is used.
    988 */
    989 Int VG_(connect_via_socket)( const HChar* str )
    990 {
    991 #  if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris)
    992    Int sd, res;
    993    struct vki_sockaddr_in servAddr;
    994    UInt   ip   = 0;
    995    UShort port = VG_CLO_DEFAULT_LOGPORT;
    996    Bool   ok   = parse_inet_addr_and_port(str, &ip, &port);
    997    if (!ok)
    998       return -1;
    999 
   1000    //if (0)
   1001    //   VG_(printf)("ip = %d.%d.%d.%d, port %d\n",
   1002    //               (ip >> 24) & 0xFF, (ip >> 16) & 0xFF,
   1003    //               (ip >> 8) & 0xFF, ip & 0xFF,
   1004    //               (UInt)port );
   1005 
   1006    servAddr.sin_family = VKI_AF_INET;
   1007    servAddr.sin_addr.s_addr = VG_(htonl)(ip);
   1008    servAddr.sin_port = VG_(htons)(port);
   1009 
   1010    /* create socket */
   1011    sd = VG_(socket)(VKI_AF_INET, VKI_SOCK_STREAM, 0 /* IPPROTO_IP ? */);
   1012    if (sd < 0) {
   1013       /* this shouldn't happen ... nevertheless */
   1014       return -2;
   1015    }
   1016 
   1017    /* connect to server */
   1018    res = my_connect(sd, &servAddr, sizeof(servAddr));
   1019    if (res < 0) {
   1020       /* connection failed */
   1021       return -2;
   1022    }
   1023 
   1024    return sd;
   1025 
   1026 #  else
   1027 #    error "Unknown OS"
   1028 #  endif
   1029 }
   1030 
   1031 
   1032 /* Let d = one or more digits.  Accept either:
   1033    d.d.d.d  or  d.d.d.d:d
   1034 */
   1035 static Int parse_inet_addr_and_port ( const HChar* str, UInt* ip_addr, UShort* port )
   1036 {
   1037 #  define GET_CH ((*str) ? (*str++) : 0)
   1038    UInt ipa, i, j, c, any;
   1039    ipa = 0;
   1040    for (i = 0; i < 4; i++) {
   1041       j = 0;
   1042       any = 0;
   1043       while (1) {
   1044          c = GET_CH;
   1045          if (c < '0' || c > '9') break;
   1046          j = 10 * j + (int)(c - '0');
   1047          any = 1;
   1048       }
   1049       if (any == 0 || j > 255) goto syntaxerr;
   1050       ipa = (ipa << 8) + j;
   1051       if (i <= 2 && c != '.') goto syntaxerr;
   1052    }
   1053    if (c == 0 || c == ':')
   1054       *ip_addr = ipa;
   1055    if (c == 0) goto ok;
   1056    if (c != ':') goto syntaxerr;
   1057    j = 0;
   1058    any = 0;
   1059    while (1) {
   1060       c = GET_CH;
   1061       if (c < '0' || c > '9') break;
   1062       j = j * 10 + (int)(c - '0');
   1063       any = 1;
   1064       if (j > 65535) goto syntaxerr;
   1065    }
   1066    if (any == 0 || c != 0) goto syntaxerr;
   1067    if (j < 1024) goto syntaxerr;
   1068    *port = (UShort)j;
   1069  ok:
   1070    return 1;
   1071  syntaxerr:
   1072    return 0;
   1073 #  undef GET_CH
   1074 }
   1075 
   1076 // GrP fixme safe_fd?
   1077 Int VG_(socket) ( Int domain, Int type, Int protocol )
   1078 {
   1079 #  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
   1080       || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
   1081       || defined(VGP_s390x_linux)
   1082    SysRes res;
   1083    UWord  args[3];
   1084    args[0] = domain;
   1085    args[1] = type;
   1086    args[2] = protocol;
   1087    res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_SOCKET, (UWord)&args);
   1088    return sr_isError(res) ? -1 : sr_Res(res);
   1089 
   1090 #  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
   1091         || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
   1092         || defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
   1093    SysRes res;
   1094    res = VG_(do_syscall3)(__NR_socket, domain, type, protocol );
   1095    return sr_isError(res) ? -1 : sr_Res(res);
   1096 
   1097 #  elif defined(VGO_darwin)
   1098    SysRes res;
   1099    res = VG_(do_syscall3)(__NR_socket, domain, type, protocol);
   1100    if (!sr_isError(res)) {
   1101        // Set SO_NOSIGPIPE so write() returns EPIPE instead of raising SIGPIPE
   1102        Int optval = 1;
   1103        SysRes res2;
   1104        res2 = VG_(do_syscall5)(__NR_setsockopt, sr_Res(res), VKI_SOL_SOCKET,
   1105                                VKI_SO_NOSIGPIPE, (UWord)&optval,
   1106                                sizeof(optval));
   1107        // ignore setsockopt() error
   1108    }
   1109    return sr_isError(res) ? -1 : sr_Res(res);
   1110 
   1111 #  elif defined(VGO_solaris)
   1112    /* XXX There doesn't seem to be an easy way to convince the send syscall to
   1113       only return EPIPE instead of raising SIGPIPE. EPIPE is only returned if
   1114       SM_KERNEL is set on the socket. Without serious hackery it looks we
   1115       can't set this flag.
   1116 
   1117       Should we wrap the send syscall below into sigprocmask calls to block
   1118       SIGPIPE?
   1119     */
   1120    SysRes res;
   1121    res = VG_(do_syscall5)(__NR_so_socket, domain, type, protocol,
   1122                           0 /*devpath*/, VKI_SOV_DEFAULT /*version*/);
   1123    return sr_isError(res) ? -1 : sr_Res(res);
   1124 
   1125 #  else
   1126 #    error "Unknown arch"
   1127 #  endif
   1128 }
   1129 
   1130 
   1131 static
   1132 Int my_connect ( Int sockfd, struct vki_sockaddr_in* serv_addr, Int addrlen )
   1133 {
   1134 #  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
   1135       || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
   1136       || defined(VGP_s390x_linux)
   1137    SysRes res;
   1138    UWord  args[3];
   1139    args[0] = sockfd;
   1140    args[1] = (UWord)serv_addr;
   1141    args[2] = addrlen;
   1142    res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_CONNECT, (UWord)&args);
   1143    return sr_isError(res) ? -1 : sr_Res(res);
   1144 
   1145 #  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
   1146         || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
   1147         || defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
   1148    SysRes res;
   1149    res = VG_(do_syscall3)(__NR_connect, sockfd, (UWord)serv_addr, addrlen);
   1150    return sr_isError(res) ? -1 : sr_Res(res);
   1151 
   1152 #  elif defined(VGO_darwin)
   1153    SysRes res;
   1154    res = VG_(do_syscall3)(__NR_connect_nocancel,
   1155                           sockfd, (UWord)serv_addr, addrlen);
   1156    return sr_isError(res) ? -1 : sr_Res(res);
   1157 
   1158 #  elif defined(VGO_solaris)
   1159    SysRes res;
   1160    res = VG_(do_syscall4)(__NR_connect, sockfd, (UWord)serv_addr, addrlen,
   1161                           VKI_SOV_DEFAULT /*version*/);
   1162    return sr_isError(res) ? -1 : sr_Res(res);
   1163 
   1164 #  else
   1165 #    error "Unknown arch"
   1166 #  endif
   1167 }
   1168 
   1169 Int VG_(write_socket)( Int sd, const void *msg, Int count )
   1170 {
   1171    /* This is actually send(). */
   1172 
   1173    /* For Linux, VKI_MSG_NOSIGNAL is a request not to send SIGPIPE on
   1174       errors on stream oriented sockets when the other end breaks the
   1175       connection. The EPIPE error is still returned.
   1176 
   1177       For Darwin, VG_(socket)() sets SO_NOSIGPIPE to get EPIPE instead of
   1178       SIGPIPE */
   1179 
   1180 #  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
   1181       || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
   1182       || defined(VGP_s390x_linux)
   1183    SysRes res;
   1184    UWord  args[4];
   1185    args[0] = sd;
   1186    args[1] = (UWord)msg;
   1187    args[2] = count;
   1188    args[3] = VKI_MSG_NOSIGNAL;
   1189    res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_SEND, (UWord)&args);
   1190    return sr_isError(res) ? -1 : sr_Res(res);
   1191 
   1192 #  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
   1193         || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
   1194         || defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
   1195    SysRes res;
   1196    res = VG_(do_syscall6)(__NR_sendto, sd, (UWord)msg,
   1197                                        count, VKI_MSG_NOSIGNAL, 0,0);
   1198    return sr_isError(res) ? -1 : sr_Res(res);
   1199 
   1200 #  elif defined(VGP_x86_darwin) || defined(VGP_amd64_darwin)
   1201    SysRes res;
   1202    res = VG_(do_syscall3)(__NR_write_nocancel, sd, (UWord)msg, count);
   1203    return sr_isError(res) ? -1 : sr_Res(res);
   1204 
   1205 #  elif defined(VGO_solaris)
   1206    SysRes res;
   1207    res = VG_(do_syscall4)(__NR_send, sd, (UWord)msg, count, 0 /*flags*/);
   1208    return sr_isError(res) ? -1 : sr_Res(res);
   1209 
   1210 #  else
   1211 #    error "Unknown platform"
   1212 #  endif
   1213 }
   1214 
   1215 Int VG_(getsockname) ( Int sd, struct vki_sockaddr *name, Int *namelen)
   1216 {
   1217 #  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
   1218       || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
   1219       || defined(VGP_s390x_linux) \
   1220       || defined(VGP_mips32_linux)
   1221    SysRes res;
   1222    UWord  args[3];
   1223    args[0] = sd;
   1224    args[1] = (UWord)name;
   1225    args[2] = (UWord)namelen;
   1226    res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETSOCKNAME, (UWord)&args);
   1227    return sr_isError(res) ? -1 : sr_Res(res);
   1228 
   1229 #  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
   1230         || defined(VGP_mips64_linux) || defined(VGP_arm64_linux) \
   1231         || defined(VGP_tilegx_linux)
   1232    SysRes res;
   1233    res = VG_(do_syscall3)( __NR_getsockname,
   1234                            (UWord)sd, (UWord)name, (UWord)namelen );
   1235    return sr_isError(res) ? -1 : sr_Res(res);
   1236 
   1237 #  elif defined(VGO_darwin)
   1238    SysRes res;
   1239    res = VG_(do_syscall3)( __NR_getsockname,
   1240                            (UWord)sd, (UWord)name, (UWord)namelen );
   1241    return sr_isError(res) ? -1 : sr_Res(res);
   1242 
   1243 #  elif defined(VGO_solaris)
   1244    SysRes res;
   1245    res = VG_(do_syscall4)(__NR_getsockname, sd, (UWord)name, (UWord)namelen,
   1246                           VKI_SOV_DEFAULT /*version*/);
   1247    return sr_isError(res) ? -1 : sr_Res(res);
   1248 
   1249 #  else
   1250 #    error "Unknown platform"
   1251 #  endif
   1252 }
   1253 
   1254 Int VG_(getpeername) ( Int sd, struct vki_sockaddr *name, Int *namelen)
   1255 {
   1256 #  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
   1257       || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
   1258       || defined(VGP_s390x_linux) \
   1259       || defined(VGP_mips32_linux)
   1260    SysRes res;
   1261    UWord  args[3];
   1262    args[0] = sd;
   1263    args[1] = (UWord)name;
   1264    args[2] = (UWord)namelen;
   1265    res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETPEERNAME, (UWord)&args);
   1266    return sr_isError(res) ? -1 : sr_Res(res);
   1267 
   1268 #  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
   1269         || defined(VGP_mips64_linux) || defined(VGP_arm64_linux) \
   1270         || defined(VGP_tilegx_linux)
   1271    SysRes res;
   1272    res = VG_(do_syscall3)( __NR_getpeername,
   1273                            (UWord)sd, (UWord)name, (UWord)namelen );
   1274    return sr_isError(res) ? -1 : sr_Res(res);
   1275 
   1276 #  elif defined(VGO_darwin)
   1277    SysRes res;
   1278    res = VG_(do_syscall3)( __NR_getpeername,
   1279                            (UWord)sd, (UWord)name, (UWord)namelen );
   1280    return sr_isError(res) ? -1 : sr_Res(res);
   1281 
   1282 #  elif defined(VGO_solaris)
   1283    SysRes res;
   1284    res = VG_(do_syscall4)(__NR_getpeername, sd, (UWord)name, (UWord)namelen,
   1285                           VKI_SOV_DEFAULT /*version*/);
   1286    return sr_isError(res) ? -1 : sr_Res(res);
   1287 
   1288 #  else
   1289 #    error "Unknown platform"
   1290 #  endif
   1291 }
   1292 
   1293 Int VG_(getsockopt) ( Int sd, Int level, Int optname, void *optval,
   1294                       Int *optlen)
   1295 {
   1296 #  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
   1297       || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
   1298       || defined(VGP_s390x_linux)
   1299    SysRes res;
   1300    UWord  args[5];
   1301    args[0] = sd;
   1302    args[1] = level;
   1303    args[2] = optname;
   1304    args[3] = (UWord)optval;
   1305    args[4] = (UWord)optlen;
   1306    res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETSOCKOPT, (UWord)&args);
   1307    return sr_isError(res) ? -1 : sr_Res(res);
   1308 
   1309 #  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
   1310         || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
   1311         || defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
   1312    SysRes res;
   1313    res = VG_(do_syscall5)( __NR_getsockopt,
   1314                            (UWord)sd, (UWord)level, (UWord)optname,
   1315                            (UWord)optval, (UWord)optlen );
   1316    return sr_isError(res) ? -1 : sr_Res(res);
   1317 
   1318 #  elif defined(VGO_darwin)
   1319    SysRes res;
   1320    res = VG_(do_syscall5)( __NR_getsockopt,
   1321                            (UWord)sd, (UWord)level, (UWord)optname,
   1322                            (UWord)optval, (UWord)optlen );
   1323    return sr_isError(res) ? -1 : sr_Res(res);
   1324 
   1325 #  elif defined(VGO_solaris)
   1326    SysRes res;
   1327    res = VG_(do_syscall6)(__NR_getsockopt, sd, level, optname, (UWord)optval,
   1328                           (UWord)optlen, VKI_SOV_DEFAULT /*version*/);
   1329    return sr_isError(res) ? -1 : sr_Res(res);
   1330 
   1331 #  else
   1332 #    error "Unknown platform"
   1333 #  endif
   1334 }
   1335 
   1336 
   1337 Int VG_(setsockopt) ( Int sd, Int level, Int optname, void *optval,
   1338                       Int optlen)
   1339 {
   1340 #  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
   1341       || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
   1342       || defined(VGP_s390x_linux)
   1343    SysRes res;
   1344    UWord  args[5];
   1345    args[0] = sd;
   1346    args[1] = level;
   1347    args[2] = optname;
   1348    args[3] = (UWord)optval;
   1349    args[4] = (UWord)optlen;
   1350    res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_SETSOCKOPT, (UWord)&args);
   1351    return sr_isError(res) ? -1 : sr_Res(res);
   1352 
   1353 #  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
   1354         || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
   1355         || defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
   1356    SysRes res;
   1357    res = VG_(do_syscall5)( __NR_setsockopt,
   1358                            (UWord)sd, (UWord)level, (UWord)optname,
   1359                            (UWord)optval, (UWord)optlen );
   1360    return sr_isError(res) ? -1 : sr_Res(res);
   1361 
   1362 #  elif defined(VGO_darwin)
   1363    SysRes res;
   1364    res = VG_(do_syscall5)( __NR_setsockopt,
   1365                            (UWord)sd, (UWord)level, (UWord)optname,
   1366                            (UWord)optval, (UWord)optlen );
   1367    return sr_isError(res) ? -1 : sr_Res(res);
   1368 
   1369 #  elif defined(VGO_solaris)
   1370    SysRes res;
   1371    res = VG_(do_syscall6)( __NR_setsockopt,
   1372                            (UWord)sd, (UWord)level, (UWord)optname,
   1373                            (UWord)optval, (UWord)optlen,
   1374                            VKI_SOV_DEFAULT /*version*/ );
   1375    return sr_isError(res) ? -1 : sr_Res(res);
   1376 
   1377 #  else
   1378 #    error "Unknown platform"
   1379 #  endif
   1380 }
   1381 
   1382 
   1383 const HChar *VG_(basename)(const HChar *path)
   1384 {
   1385    static HChar *buf = NULL;
   1386    static SizeT  buf_len = 0;
   1387    const HChar *p, *end;
   1388 
   1389    if (path == NULL  ||
   1390        0 == VG_(strcmp)(path, ""))
   1391    {
   1392       return ".";
   1393    }
   1394 
   1395    p = path + VG_(strlen)(path);
   1396    while (p > path  &&  *p == '/') {
   1397       // skip all trailing '/'
   1398       p--;
   1399    }
   1400 
   1401    if (p == path  &&  *p == '/') return "/"; // all slashes
   1402 
   1403    end = p;
   1404 
   1405    while (p > path  &&  *p != '/') {
   1406       // now skip non '/'
   1407       p--;
   1408    }
   1409 
   1410    if (*p == '/') p++;
   1411 
   1412    SizeT need = end-p+1 + 1;
   1413    if (need > buf_len) {
   1414       buf_len = (buf_len == 0) ? 500 : need;
   1415       buf = VG_(realloc)("basename", buf, buf_len);
   1416    }
   1417    VG_(strncpy)(buf, p, end-p+1);
   1418    buf[end-p+1] = '\0';
   1419 
   1420    return buf;
   1421 }
   1422 
   1423 
   1424 const HChar *VG_(dirname)(const HChar *path)
   1425 {
   1426    static HChar *buf = NULL;
   1427    static SizeT  buf_len = 0;
   1428 
   1429    const HChar *p;
   1430 
   1431    if (path == NULL  ||
   1432        0 == VG_(strcmp)(path, "")  ||
   1433        0 == VG_(strcmp)(path, "/"))
   1434    {
   1435       return ".";
   1436    }
   1437 
   1438    p = path + VG_(strlen)(path);
   1439    while (p > path  &&  *p == '/') {
   1440       // skip all trailing '/'
   1441       p--;
   1442    }
   1443 
   1444    while (p > path  &&  *p != '/') {
   1445       // now skip non '/'
   1446       p--;
   1447    }
   1448 
   1449    if (p == path) {
   1450       if (*p == '/') return "/"; // all slashes
   1451       else return "."; // no slashes
   1452    }
   1453 
   1454    while (p > path  &&  *p == '/') {
   1455       // skip '/' again
   1456       p--;
   1457    }
   1458 
   1459    SizeT need = p-path+1 + 1;
   1460    if (need > buf_len) {
   1461       buf_len = (buf_len == 0) ? 500 : need;
   1462       buf = VG_(realloc)("dirname", buf, buf_len);
   1463    }
   1464    VG_(strncpy)(buf, path, p-path+1);
   1465    buf[p-path+1] = '\0';
   1466 
   1467    return buf;
   1468 }
   1469 
   1470 
   1471 /*--------------------------------------------------------------------*/
   1472 /*--- end                                                          ---*/
   1473 /*--------------------------------------------------------------------*/
   1474