Home | History | Annotate | Download | only in coregrind
      1 
      2 /*--------------------------------------------------------------------*/
      3 /*--- File- and socket-related libc stuff.            m_libcfile.c ---*/
      4 /*--------------------------------------------------------------------*/
      5 
      6 /*
      7    This file is part of Valgrind, a dynamic binary instrumentation
      8    framework.
      9 
     10    Copyright (C) 2000-2011 Julian Seward
     11       jseward (at) acm.org
     12 
     13    This program is free software; you can redistribute it and/or
     14    modify it under the terms of the GNU General Public License as
     15    published by the Free Software Foundation; either version 2 of the
     16    License, or (at your option) any later version.
     17 
     18    This program is distributed in the hope that it will be useful, but
     19    WITHOUT ANY WARRANTY; without even the implied warranty of
     20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     21    General Public License for more details.
     22 
     23    You should have received a copy of the GNU General Public License
     24    along with this program; if not, write to the Free Software
     25    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     26    02111-1307, USA.
     27 
     28    The GNU General Public License is contained in the file COPYING.
     29 */
     30 
     31 #include "pub_core_basics.h"
     32 #include "pub_core_vki.h"
     33 #include "pub_core_vkiscnums.h"
     34 #include "pub_core_debuglog.h"
     35 #include "pub_core_libcbase.h"
     36 #include "pub_core_libcassert.h"
     37 #include "pub_core_libcfile.h"
     38 #include "pub_core_libcprint.h"     // VG_(sprintf)
     39 #include "pub_core_libcproc.h"      // VG_(getpid), VG_(getppid)
     40 #include "pub_core_xarray.h"
     41 #include "pub_core_clientstate.h"   // VG_(fd_hard_limit)
     42 #include "pub_core_syscall.h"
     43 
     44 /* IMPORTANT: on Darwin it is essential to use the _nocancel versions
     45    of syscalls rather than the vanilla version, if a _nocancel version
     46    is available.  See docs/internals/Darwin-notes.txt for the reason
     47    why. */
     48 
     49 /* ---------------------------------------------------------------------
     50    File stuff
     51    ------------------------------------------------------------------ */
     52 
     53 static inline Bool fd_exists(Int fd)
     54 {
     55    struct vg_stat st;
     56    return VG_(fstat)(fd, &st) == 0;
     57 }
     58 
     59 /* Move an fd into the Valgrind-safe range */
     60 Int VG_(safe_fd)(Int oldfd)
     61 {
     62    Int newfd;
     63 
     64    vg_assert(VG_(fd_hard_limit) != -1);
     65 
     66    newfd = VG_(fcntl)(oldfd, VKI_F_DUPFD, VG_(fd_hard_limit));
     67    if (newfd != -1)
     68       VG_(close)(oldfd);
     69 
     70    /* Set the close-on-exec flag for this fd. */
     71    VG_(fcntl)(newfd, VKI_F_SETFD, VKI_FD_CLOEXEC);
     72 
     73    vg_assert(newfd >= VG_(fd_hard_limit));
     74    return newfd;
     75 }
     76 
     77 /* Given a file descriptor, attempt to deduce its filename.  To do
     78    this, we use /proc/self/fd/<FD>.  If this doesn't point to a file,
     79    or if it doesn't exist, we return False. */
     80 Bool VG_(resolve_filename) ( Int fd, HChar* buf, Int n_buf )
     81 {
     82 #  if defined(VGO_linux)
     83    HChar tmp[64];
     84    VG_(sprintf)(tmp, "/proc/self/fd/%d", fd);
     85    VG_(memset)(buf, 0, n_buf);
     86    if (VG_(readlink)(tmp, buf, n_buf) > 0 && buf[0] == '/')
     87       return True;
     88    else
     89       return False;
     90 
     91 #  elif defined(VGO_darwin)
     92    HChar tmp[VKI_MAXPATHLEN+1];
     93    if (0 == VG_(fcntl)(fd, VKI_F_GETPATH, (UWord)tmp)) {
     94       if (n_buf > 0) {
     95          VG_(strncpy)( buf, tmp, n_buf < sizeof(tmp) ? n_buf : sizeof(tmp) );
     96          buf[n_buf-1] = 0;
     97       }
     98       if (tmp[0] == '/') return True;
     99    }
    100    return False;
    101 
    102 #  else
    103 #     error Unknown OS
    104 #  endif
    105 }
    106 
    107 SysRes VG_(mknod) ( const Char* pathname, Int mode, UWord dev )
    108 {
    109 #  if defined(VGO_linux) || defined(VGO_darwin)
    110    SysRes res = VG_(do_syscall3)(__NR_mknod,
    111                                  (UWord)pathname, mode, dev);
    112 #  else
    113 #    error Unknown OS
    114 #  endif
    115    return res;
    116 }
    117 
    118 SysRes VG_(open) ( const Char* pathname, Int flags, Int mode )
    119 {
    120 #  if defined(VGO_linux)
    121    SysRes res = VG_(do_syscall3)(__NR_open,
    122                                  (UWord)pathname, flags, mode);
    123 #  elif defined(VGO_darwin)
    124    SysRes res = VG_(do_syscall3)(__NR_open_nocancel,
    125                                  (UWord)pathname, flags, mode);
    126 #  else
    127 #    error Unknown OS
    128 #  endif
    129    return res;
    130 }
    131 
    132 Int VG_(fd_open) (const Char* pathname, Int flags, Int mode)
    133 {
    134    SysRes sr;
    135    sr = VG_(open) (pathname, flags, mode);
    136    if (sr_isError (sr))
    137       return -1;
    138    else
    139       return sr_Res (sr);
    140 }
    141 
    142 void VG_(close) ( Int fd )
    143 {
    144    /* Hmm.  Return value is not checked.  That's uncool. */
    145 #  if defined(VGO_linux)
    146    (void)VG_(do_syscall1)(__NR_close, fd);
    147 #  elif defined(VGO_darwin)
    148    (void)VG_(do_syscall1)(__NR_close_nocancel, fd);
    149 #  else
    150 #    error Unknown OS
    151 #  endif
    152 }
    153 
    154 Int VG_(read) ( Int fd, void* buf, Int count)
    155 {
    156    Int    ret;
    157 #  if defined(VGO_linux)
    158    SysRes res = VG_(do_syscall3)(__NR_read, fd, (UWord)buf, count);
    159 #  elif defined(VGO_darwin)
    160    SysRes res = VG_(do_syscall3)(__NR_read_nocancel, fd, (UWord)buf, count);
    161 #  else
    162 #    error Unknown OS
    163 #  endif
    164    if (sr_isError(res)) {
    165       ret = - (Int)(Word)sr_Err(res);
    166       vg_assert(ret < 0);
    167    } else {
    168       ret = (Int)(Word)sr_Res(res);
    169       vg_assert(ret >= 0);
    170    }
    171    return ret;
    172 }
    173 
    174 Int VG_(write) ( Int fd, const void* buf, Int count)
    175 {
    176    Int    ret;
    177 #  if defined(VGO_linux)
    178    SysRes res = VG_(do_syscall3)(__NR_write, fd, (UWord)buf, count);
    179 #  elif defined(VGO_darwin)
    180    SysRes res = VG_(do_syscall3)(__NR_write_nocancel, fd, (UWord)buf, count);
    181 #  else
    182 #    error "Unknown OS"
    183 #  endif
    184    if (sr_isError(res)) {
    185       ret = - (Int)(Word)sr_Err(res);
    186       vg_assert(ret < 0);
    187    } else {
    188       ret = (Int)(Word)sr_Res(res);
    189       vg_assert(ret >= 0);
    190    }
    191    return ret;
    192 }
    193 
    194 
    195 Int VG_(pipe) ( Int fd[2] )
    196 {
    197 #  if defined(VGO_linux)
    198    SysRes res = VG_(do_syscall1)(__NR_pipe, (UWord)fd);
    199    return sr_isError(res) ? -1 : 0;
    200 #  elif defined(VGO_darwin)
    201    /* __NR_pipe is UX64, so produces a double-word result */
    202    SysRes res = VG_(do_syscall0)(__NR_pipe);
    203    if (!sr_isError(res)) {
    204       fd[0] = (Int)sr_Res(res);
    205       fd[1] = (Int)sr_ResHI(res);
    206    }
    207    return sr_isError(res) ? -1 : 0;
    208 #  else
    209 #    error "Unknown OS"
    210 #  endif
    211 }
    212 
    213 Off64T VG_(lseek) ( Int fd, Off64T offset, Int whence )
    214 {
    215 #  if defined(VGO_linux) || defined(VGP_amd64_darwin)
    216 #  if defined(__NR__llseek)
    217    Off64T result;
    218    SysRes res = VG_(do_syscall5)(__NR__llseek, fd,
    219                                  offset >> 32, offset & 0xffffffff,
    220                                  (UWord)&result, whence);
    221    return sr_isError(res) ? (-1) : result;
    222 #  else
    223    SysRes res = VG_(do_syscall3)(__NR_lseek, fd, offset, whence);
    224    vg_assert(sizeof(Off64T) == sizeof(Word));
    225    return sr_isError(res) ? (-1) : sr_Res(res);
    226 #  endif
    227 #  elif defined(VGP_x86_darwin)
    228    SysRes res = VG_(do_syscall4)(__NR_lseek, fd,
    229                                  offset & 0xffffffff, offset >> 32, whence);
    230    return sr_isError(res) ? (-1) : sr_Res(res);
    231 #  else
    232 #    error "Unknown plat"
    233 #  endif
    234    /* if you change the error-reporting conventions of this, also
    235       change VG_(pread) and all other usage points. */
    236 }
    237 
    238 extern Int VG_(ftruncate) ( Int fd, OffT length ) {
    239 #if defined (VGO_linux)
    240    SysRes res = VG_(do_syscall2)(__NR_ftruncate, fd, length);
    241    return sr_isError(res) ? (-1) : sr_Res(res);
    242 #else
    243    return -1;  /*UNIMPLEMENTED*/
    244 #endif
    245 }
    246 
    247 /* stat/fstat support.  It's uggerly.  We have impedance-match into a
    248    'struct vg_stat' in order to have a single structure that callers
    249    can use consistently on all platforms. */
    250 
    251 #define TRANSLATE_TO_vg_stat(_p_vgstat, _p_vkistat) \
    252    do { \
    253       (_p_vgstat)->dev        = (ULong)( (_p_vkistat)->st_dev ); \
    254       (_p_vgstat)->ino        = (ULong)( (_p_vkistat)->st_ino ); \
    255       (_p_vgstat)->nlink      = (ULong)( (_p_vkistat)->st_nlink ); \
    256       (_p_vgstat)->mode       = (UInt) ( (_p_vkistat)->st_mode ); \
    257       (_p_vgstat)->uid        = (UInt) ( (_p_vkistat)->st_uid ); \
    258       (_p_vgstat)->gid        = (UInt) ( (_p_vkistat)->st_gid ); \
    259       (_p_vgstat)->rdev       = (ULong)( (_p_vkistat)->st_rdev ); \
    260       (_p_vgstat)->size       = (Long) ( (_p_vkistat)->st_size ); \
    261       (_p_vgstat)->blksize    = (ULong)( (_p_vkistat)->st_blksize ); \
    262       (_p_vgstat)->blocks     = (ULong)( (_p_vkistat)->st_blocks ); \
    263       (_p_vgstat)->atime      = (ULong)( (_p_vkistat)->st_atime ); \
    264       (_p_vgstat)->atime_nsec = (ULong)( (_p_vkistat)->st_atime_nsec ); \
    265       (_p_vgstat)->mtime      = (ULong)( (_p_vkistat)->st_mtime ); \
    266       (_p_vgstat)->mtime_nsec = (ULong)( (_p_vkistat)->st_mtime_nsec ); \
    267       (_p_vgstat)->ctime      = (ULong)( (_p_vkistat)->st_ctime ); \
    268       (_p_vgstat)->ctime_nsec = (ULong)( (_p_vkistat)->st_ctime_nsec ); \
    269    } while (0)
    270 
    271 SysRes VG_(stat) ( const Char* file_name, struct vg_stat* vgbuf )
    272 {
    273    SysRes res;
    274    VG_(memset)(vgbuf, 0, sizeof(*vgbuf));
    275 
    276 #  if defined(VGO_linux) || defined(VGO_darwin)
    277    /* First try with stat64.  If that doesn't work out, fall back to
    278       the vanilla version. */
    279 #  if defined(__NR_stat64)
    280    { struct vki_stat64 buf64;
    281      res = VG_(do_syscall2)(__NR_stat64, (UWord)file_name, (UWord)&buf64);
    282      if (!(sr_isError(res) && sr_Err(res) == VKI_ENOSYS)) {
    283         /* Success, or any failure except ENOSYS */
    284         if (!sr_isError(res))
    285            TRANSLATE_TO_vg_stat(vgbuf, &buf64);
    286         return res;
    287      }
    288    }
    289 #  endif /* defined(__NR_stat64) */
    290    { struct vki_stat buf;
    291      res = VG_(do_syscall2)(__NR_stat, (UWord)file_name, (UWord)&buf);
    292      if (!sr_isError(res))
    293         TRANSLATE_TO_vg_stat(vgbuf, &buf);
    294      return res;
    295    }
    296 
    297 #  else
    298 #    error Unknown OS
    299 #  endif
    300 }
    301 
    302 Int VG_(fstat) ( Int fd, struct vg_stat* vgbuf )
    303 {
    304    SysRes res;
    305    VG_(memset)(vgbuf, 0, sizeof(*vgbuf));
    306 
    307 #  if defined(VGO_linux)  ||  defined(VGO_darwin)
    308    /* First try with fstat64.  If that doesn't work out, fall back to
    309       the vanilla version. */
    310 #  if defined(__NR_fstat64)
    311    { struct vki_stat64 buf64;
    312      res = VG_(do_syscall2)(__NR_fstat64, (UWord)fd, (UWord)&buf64);
    313      if (!(sr_isError(res) && sr_Err(res) == VKI_ENOSYS)) {
    314         /* Success, or any failure except ENOSYS */
    315         if (!sr_isError(res))
    316            TRANSLATE_TO_vg_stat(vgbuf, &buf64);
    317         return sr_isError(res) ? (-1) : 0;
    318      }
    319    }
    320 #  endif /* if defined(__NR_fstat64) */
    321    { struct vki_stat buf;
    322      res = VG_(do_syscall2)(__NR_fstat, (UWord)fd, (UWord)&buf);
    323      if (!sr_isError(res))
    324         TRANSLATE_TO_vg_stat(vgbuf, &buf);
    325      return sr_isError(res) ? (-1) : 0;
    326    }
    327 
    328 #  else
    329 #    error Unknown OS
    330 #  endif
    331 }
    332 
    333 #undef TRANSLATE_TO_vg_stat
    334 
    335 
    336 Long VG_(fsize) ( Int fd )
    337 {
    338    struct vg_stat buf;
    339    Int res = VG_(fstat)( fd, &buf );
    340    return (res == -1) ? (-1LL) : buf.size;
    341 }
    342 
    343 Bool VG_(is_dir) ( const HChar* f )
    344 {
    345    struct vg_stat buf;
    346    SysRes res = VG_(stat)(f, &buf);
    347    return sr_isError(res) ? False
    348                       : VKI_S_ISDIR(buf.mode) ? True : False;
    349 }
    350 
    351 SysRes VG_(dup) ( Int oldfd )
    352 {
    353    return VG_(do_syscall1)(__NR_dup, oldfd);
    354 }
    355 
    356 SysRes VG_(dup2) ( Int oldfd, Int newfd )
    357 {
    358 #  if defined(VGO_linux) || defined(VGO_darwin)
    359    return VG_(do_syscall2)(__NR_dup2, oldfd, newfd);
    360 #  else
    361 #    error Unknown OS
    362 #  endif
    363 }
    364 
    365 /* Returns -1 on error. */
    366 Int VG_(fcntl) ( Int fd, Int cmd, Addr arg )
    367 {
    368 #  if defined(VGO_linux)
    369    SysRes res = VG_(do_syscall3)(__NR_fcntl, fd, cmd, arg);
    370 #  elif defined(VGO_darwin)
    371    SysRes res = VG_(do_syscall3)(__NR_fcntl_nocancel, fd, cmd, arg);
    372 #  else
    373 #    error "Unknown OS"
    374 #  endif
    375    return sr_isError(res) ? -1 : sr_Res(res);
    376 }
    377 
    378 Int VG_(rename) ( const Char* old_name, const Char* new_name )
    379 {
    380    SysRes res = VG_(do_syscall2)(__NR_rename, (UWord)old_name, (UWord)new_name);
    381    return sr_isError(res) ? (-1) : 0;
    382 }
    383 
    384 Int VG_(unlink) ( const Char* file_name )
    385 {
    386    SysRes res = VG_(do_syscall1)(__NR_unlink, (UWord)file_name);
    387    return sr_isError(res) ? (-1) : 0;
    388 }
    389 
    390 /* The working directory at startup.  AIX doesn't provide an easy
    391    system call to do getcwd, but fortunately we don't need arbitrary
    392    getcwd support.  All that is really needed is to note the cwd at
    393    process startup.  Hence VG_(record_startup_wd) notes it (in a
    394    platform dependent way) and VG_(get_startup_wd) produces the noted
    395    value.  Hence: */
    396 static HChar startup_wd[VKI_PATH_MAX];
    397 static Bool  startup_wd_acquired = False;
    398 
    399 /* Record the process' working directory at startup.  Is intended to
    400    be called exactly once, at startup, before the working directory
    401    changes.  Return True for success, False for failure, so that the
    402    caller can bomb out suitably without creating module cycles if
    403    there is a problem. */
    404 Bool VG_(record_startup_wd) ( void )
    405 {
    406    const Int szB = sizeof(startup_wd);
    407    vg_assert(!startup_wd_acquired);
    408    vg_assert(szB >= 512 && szB <= 16384/*let's say*/); /* stay sane */
    409    VG_(memset)(startup_wd, 0, szB);
    410 #  if defined(VGO_linux)
    411    /* Simple: just ask the kernel */
    412    { SysRes res
    413         = VG_(do_syscall2)(__NR_getcwd, (UWord)startup_wd, szB-1);
    414      vg_assert(startup_wd[szB-1] == 0);
    415      if (sr_isError(res)) {
    416         return False;
    417      } else {
    418         startup_wd_acquired = True;
    419         return True;
    420      }
    421    }
    422 #  elif defined(VGO_darwin)
    423    /* We can't ask the kernel, so instead rely on launcher-*.c to
    424       tell us the startup path.  Note the env var is keyed to the
    425       parent's PID, not ours, since our parent is the launcher
    426       process. */
    427    { Char  envvar[100];
    428      Char* wd = NULL;
    429      VG_(memset)(envvar, 0, sizeof(envvar));
    430      VG_(sprintf)(envvar, "VALGRIND_STARTUP_PWD_%d_XYZZY",
    431                           (Int)VG_(getppid)());
    432      wd = VG_(getenv)( envvar );
    433      if (wd == NULL || (1+VG_(strlen)(wd) >= szB))
    434         return False;
    435      VG_(strncpy_safely)(startup_wd, wd, szB);
    436      vg_assert(startup_wd[szB-1] == 0);
    437      startup_wd_acquired = True;
    438      return True;
    439    }
    440 #  else
    441 #    error Unknown OS
    442 #  endif
    443 }
    444 
    445 /* Copy the previously acquired startup_wd into buf[0 .. size-1],
    446    or return False if buf isn't big enough. */
    447 Bool VG_(get_startup_wd) ( Char* buf, SizeT size )
    448 {
    449    vg_assert(startup_wd_acquired);
    450    vg_assert(startup_wd[ sizeof(startup_wd)-1 ] == 0);
    451    if (1+VG_(strlen)(startup_wd) >= size)
    452       return False;
    453    VG_(strncpy_safely)(buf, startup_wd, size);
    454    return True;
    455 }
    456 
    457 Int    VG_(poll) (struct vki_pollfd *fds, Int nfds, Int timeout)
    458 {
    459    SysRes res;
    460    res = VG_(do_syscall3)(__NR_poll, (UWord)fds, nfds, timeout);
    461    return sr_isError(res) ? -1 : sr_Res(res);
    462 }
    463 
    464 
    465 Int VG_(readlink) (const Char* path, Char* buf, UInt bufsiz)
    466 {
    467    SysRes res;
    468    /* res = readlink( path, buf, bufsiz ); */
    469    res = VG_(do_syscall3)(__NR_readlink, (UWord)path, (UWord)buf, bufsiz);
    470    return sr_isError(res) ? -1 : sr_Res(res);
    471 }
    472 
    473 Int VG_(getdents) (Int fd, struct vki_dirent *dirp, UInt count)
    474 {
    475 #  if defined(VGO_linux)
    476    SysRes res;
    477    /* res = getdents( fd, dirp, count ); */
    478    res = VG_(do_syscall3)(__NR_getdents, fd, (UWord)dirp, count);
    479    return sr_isError(res) ? -1 : sr_Res(res);
    480 #  elif defined(VGO_darwin)
    481    I_die_here;
    482 #  else
    483 #    error "Unknown OS"
    484 #  endif
    485 }
    486 
    487 /* Check accessibility of a file.  Returns zero for access granted,
    488    nonzero otherwise. */
    489 Int VG_(access) ( const HChar* path, Bool irusr, Bool iwusr, Bool ixusr )
    490 {
    491 #  if defined(VGO_linux)
    492    /* Very annoyingly, I cannot find any definition for R_OK et al in
    493       the kernel interfaces.  Therefore I reluctantly resort to
    494       hardwiring in these magic numbers that I determined by
    495       experimentation. */
    496 #  define VKI_R_OK 4
    497 #  define VKI_W_OK 2
    498 #  define VKI_X_OK 1
    499 #  endif
    500 
    501    UWord w = (irusr ? VKI_R_OK : 0)
    502              | (iwusr ? VKI_W_OK : 0)
    503              | (ixusr ? VKI_X_OK : 0);
    504    SysRes res = VG_(do_syscall2)(__NR_access, (UWord)path, w);
    505    return sr_isError(res) ? 1 : 0;
    506 
    507 #  if defined(VGO_linux)
    508 #  undef VKI_R_OK
    509 #  undef VKI_W_OK
    510 #  undef VKI_X_OK
    511 #  endif
    512 }
    513 
    514 /*
    515    Emulate the normal Unix permissions checking algorithm.
    516 
    517    If owner matches, then use the owner permissions, else
    518    if group matches, then use the group permissions, else
    519    use other permissions.
    520 
    521    Note that we can't deal properly with SUID/SGID.  By default
    522    (allow_setuid == False), we refuse to run them (otherwise the
    523    executable may misbehave if it doesn't have the permissions it
    524    thinks it does).  However, the caller may indicate that setuid
    525    executables are allowed, for example if we are going to exec them
    526    but not trace into them (iow, client sys_execve when
    527    clo_trace_children == False).
    528 
    529    If VKI_EACCES is returned (iow, permission was refused), then
    530    *is_setuid is set to True iff permission was refused because the
    531    executable is setuid.
    532 */
    533 /* returns: 0 = success, non-0 is failure */
    534 Int VG_(check_executable)(/*OUT*/Bool* is_setuid,
    535                           const HChar* f, Bool allow_setuid)
    536 {
    537    struct vg_stat st;
    538    SysRes res = VG_(stat)(f, &st);
    539 
    540    if (is_setuid)
    541       *is_setuid = False;
    542 
    543    if (sr_isError(res)) {
    544       return sr_Err(res);
    545    }
    546 
    547    if ( (st.mode & (VKI_S_ISUID | VKI_S_ISGID)) && !allow_setuid ) {
    548       if (is_setuid)
    549          *is_setuid = True;
    550       return VKI_EACCES;
    551    }
    552 
    553    if (VG_(geteuid)() == st.uid) {
    554       if (!(st.mode & VKI_S_IXUSR))
    555          return VKI_EACCES;
    556    } else {
    557       Int grpmatch = 0;
    558 
    559       if (VG_(getegid)() == st.gid)
    560 	 grpmatch = 1;
    561       else {
    562 	 UInt groups[32];
    563 	 Int ngrp = VG_(getgroups)(32, groups);
    564 	 Int i;
    565          /* ngrp will be -1 if VG_(getgroups) failed. */
    566          for (i = 0; i < ngrp; i++) {
    567 	    if (groups[i] == st.gid) {
    568 	       grpmatch = 1;
    569 	       break;
    570 	    }
    571          }
    572       }
    573 
    574       if (grpmatch) {
    575 	 if (!(st.mode & VKI_S_IXGRP)) {
    576             return VKI_EACCES;
    577          }
    578       } else if (!(st.mode & VKI_S_IXOTH)) {
    579          return VKI_EACCES;
    580       }
    581    }
    582 
    583    return 0;
    584 }
    585 
    586 /* DDD: Note this moves (or at least, is believed to move) the file
    587    pointer on Linux but doesn't on Darwin.  This inconsistency should
    588    be fixed.  (In other words, why isn't the Linux version implemented
    589    in terms of pread()?) */
    590 SysRes VG_(pread) ( Int fd, void* buf, Int count, OffT offset )
    591 {
    592    SysRes res;
    593 #  if defined(VGO_linux)
    594    OffT off = VG_(lseek)( fd, offset, VKI_SEEK_SET);
    595    if (off < 0)
    596       return VG_(mk_SysRes_Error)( VKI_EINVAL );
    597    res = VG_(do_syscall3)(__NR_read, fd, (UWord)buf, count );
    598    return res;
    599 #  elif defined(VGP_amd64_darwin)
    600    res = VG_(do_syscall4)(__NR_pread_nocancel, fd, (UWord)buf, count, offset);
    601    return res;
    602 #  elif defined(VGP_x86_darwin)
    603    /* ppc32-darwin is the same, but with the args inverted */
    604    res = VG_(do_syscall5)(__NR_pread_nocancel, fd, (UWord)buf, count,
    605                           offset & 0xffffffff, offset >> 32);
    606    return res;
    607 #  else
    608 #    error "Unknown platform"
    609 #  endif
    610 }
    611 
    612 /* Return the name of a directory for temporary files. */
    613 const HChar *VG_(tmpdir)(void)
    614 {
    615    const HChar *tmpdir;
    616 
    617    tmpdir = VG_(getenv)("TMPDIR");
    618    if (tmpdir == NULL || *tmpdir == '\0') tmpdir = VG_TMPDIR;
    619    if (tmpdir == NULL || *tmpdir == '\0') tmpdir = "/tmp";    /* fallback */
    620 
    621    return tmpdir;
    622 }
    623 
    624 /* Create and open (-rw------) a tmp file name incorporating said arg.
    625    Returns -1 on failure, else the fd of the file.  If fullname is
    626    non-NULL, the file's name is written into it.  The number of bytes
    627    written is guaranteed not to exceed 64+strlen(part_of_name). */
    628 
    629 Int VG_(mkstemp) ( HChar* part_of_name, /*OUT*/HChar* fullname )
    630 {
    631    HChar  buf[200];
    632    Int    n, tries, fd;
    633    UInt   seed;
    634    SysRes sres;
    635    const HChar *tmpdir;
    636 
    637    vg_assert(part_of_name);
    638    n = VG_(strlen)(part_of_name);
    639    vg_assert(n > 0 && n < 100);
    640 
    641    seed = (VG_(getpid)() << 9) ^ VG_(getppid)();
    642 
    643    /* Determine sensible location for temporary files */
    644    tmpdir = VG_(tmpdir)();
    645 
    646    tries = 0;
    647    while (True) {
    648       if (tries++ > 10)
    649          return -1;
    650       VG_(sprintf)( buf, "%s/valgrind_%s_%08x",
    651                     tmpdir, part_of_name, VG_(random)( &seed ));
    652       if (0)
    653          VG_(printf)("VG_(mkstemp): trying: %s\n", buf);
    654 
    655       sres = VG_(open)(buf,
    656                        VKI_O_CREAT|VKI_O_RDWR|VKI_O_EXCL|VKI_O_TRUNC,
    657                        VKI_S_IRUSR|VKI_S_IWUSR);
    658       if (sr_isError(sres)) {
    659          VG_(umsg)("VG_(mkstemp): failed to create temp file: %s\n", buf);
    660          continue;
    661       }
    662       /* VG_(safe_fd) doesn't return if it fails. */
    663       fd = VG_(safe_fd)( sr_Res(sres) );
    664       if (fullname)
    665          VG_(strcpy)( fullname, buf );
    666       return fd;
    667    }
    668    /* NOTREACHED */
    669 }
    670 
    671 
    672 /* ---------------------------------------------------------------------
    673    Socket-related stuff.
    674    ------------------------------------------------------------------ */
    675 
    676 static
    677 Int parse_inet_addr_and_port ( UChar* str, UInt* ip_addr, UShort* port );
    678 
    679 static
    680 Int my_connect ( Int sockfd, struct vki_sockaddr_in* serv_addr, Int addrlen );
    681 
    682 UInt VG_(htonl) ( UInt x )
    683 {
    684 #  if defined(VG_BIGENDIAN)
    685    return x;
    686 #  else
    687    return
    688       (((x >> 24) & 0xFF) << 0) | (((x >> 16) & 0xFF) << 8)
    689       | (((x >> 8) & 0xFF) << 16) | (((x >> 0) & 0xFF) << 24);
    690 #  endif
    691 }
    692 
    693 UInt VG_(ntohl) ( UInt x )
    694 {
    695 #  if defined(VG_BIGENDIAN)
    696    return x;
    697 #  else
    698    return
    699       (((x >> 24) & 0xFF) << 0) | (((x >> 16) & 0xFF) << 8)
    700       | (((x >> 8) & 0xFF) << 16) | (((x >> 0) & 0xFF) << 24);
    701 #  endif
    702 }
    703 
    704 UShort VG_(htons) ( UShort x )
    705 {
    706 #  if defined(VG_BIGENDIAN)
    707    return x;
    708 #  else
    709    return
    710       (((x >> 8) & 0xFF) << 0) | (((x >> 0) & 0xFF) << 8);
    711 #  endif
    712 }
    713 
    714 UShort VG_(ntohs) ( UShort x )
    715 {
    716 #  if defined(VG_BIGENDIAN)
    717    return x;
    718 #  else
    719    return
    720       (((x >> 8) & 0xFF) << 0) | (((x >> 0) & 0xFF) << 8);
    721 #  endif
    722 }
    723 
    724 
    725 /* The main function.
    726 
    727    Supplied string contains either an ip address "192.168.0.1" or
    728    an ip address and port pair, "192.168.0.1:1500".  Parse these,
    729    and return:
    730      -1 if there is a parse error
    731      -2 if no parse error, but specified host:port cannot be opened
    732      the relevant file (socket) descriptor, otherwise.
    733  is used.
    734 */
    735 Int VG_(connect_via_socket)( UChar* str )
    736 {
    737 #  if defined(VGO_linux) || defined(VGO_darwin)
    738    Int sd, res;
    739    struct vki_sockaddr_in servAddr;
    740    UInt   ip   = 0;
    741    UShort port = VG_CLO_DEFAULT_LOGPORT;
    742    Bool   ok   = parse_inet_addr_and_port(str, &ip, &port);
    743    if (!ok)
    744       return -1;
    745 
    746    //if (0)
    747    //   VG_(printf)("ip = %d.%d.%d.%d, port %d\n",
    748    //               (ip >> 24) & 0xFF, (ip >> 16) & 0xFF,
    749    //               (ip >> 8) & 0xFF, ip & 0xFF,
    750    //               (UInt)port );
    751 
    752    servAddr.sin_family = VKI_AF_INET;
    753    servAddr.sin_addr.s_addr = VG_(htonl)(ip);
    754    servAddr.sin_port = VG_(htons)(port);
    755 
    756    /* create socket */
    757    sd = VG_(socket)(VKI_AF_INET, VKI_SOCK_STREAM, 0 /* IPPROTO_IP ? */);
    758    if (sd < 0) {
    759       /* this shouldn't happen ... nevertheless */
    760       return -2;
    761    }
    762 
    763    /* connect to server */
    764    res = my_connect(sd, &servAddr, sizeof(servAddr));
    765    if (res < 0) {
    766       /* connection failed */
    767       return -2;
    768    }
    769 
    770    return sd;
    771 
    772 #  else
    773 #    error "Unknown OS"
    774 #  endif
    775 }
    776 
    777 
    778 /* Let d = one or more digits.  Accept either:
    779    d.d.d.d  or  d.d.d.d:d
    780 */
    781 static Int parse_inet_addr_and_port ( UChar* str, UInt* ip_addr, UShort* port )
    782 {
    783 #  define GET_CH ((*str) ? (*str++) : 0)
    784    UInt ipa, i, j, c, any;
    785    ipa = 0;
    786    for (i = 0; i < 4; i++) {
    787       j = 0;
    788       any = 0;
    789       while (1) {
    790          c = GET_CH;
    791          if (c < '0' || c > '9') break;
    792          j = 10 * j + (int)(c - '0');
    793          any = 1;
    794       }
    795       if (any == 0 || j > 255) goto syntaxerr;
    796       ipa = (ipa << 8) + j;
    797       if (i <= 2 && c != '.') goto syntaxerr;
    798    }
    799    if (c == 0 || c == ':')
    800       *ip_addr = ipa;
    801    if (c == 0) goto ok;
    802    if (c != ':') goto syntaxerr;
    803    j = 0;
    804    any = 0;
    805    while (1) {
    806       c = GET_CH;
    807       if (c < '0' || c > '9') break;
    808       j = j * 10 + (int)(c - '0');
    809       any = 1;
    810       if (j > 65535) goto syntaxerr;
    811    }
    812    if (any == 0 || c != 0) goto syntaxerr;
    813    if (j < 1024) goto syntaxerr;
    814    *port = (UShort)j;
    815  ok:
    816    return 1;
    817  syntaxerr:
    818    return 0;
    819 #  undef GET_CH
    820 }
    821 
    822 // GrP fixme safe_fd?
    823 Int VG_(socket) ( Int domain, Int type, Int protocol )
    824 {
    825 #  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
    826       || defined(VGP_ppc64_linux) || defined(VGP_s390x_linux)
    827    SysRes res;
    828    UWord  args[3];
    829    args[0] = domain;
    830    args[1] = type;
    831    args[2] = protocol;
    832    res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_SOCKET, (UWord)&args);
    833    return sr_isError(res) ? -1 : sr_Res(res);
    834 
    835 #  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux)
    836    SysRes res;
    837    res = VG_(do_syscall3)(__NR_socket, domain, type, protocol );
    838    return sr_isError(res) ? -1 : sr_Res(res);
    839 
    840 #  elif defined(VGO_darwin)
    841    SysRes res;
    842    res = VG_(do_syscall3)(__NR_socket, domain, type, protocol);
    843    if (!sr_isError(res)) {
    844        // Set SO_NOSIGPIPE so write() returns EPIPE instead of raising SIGPIPE
    845        Int optval = 1;
    846        SysRes res2;
    847        res2 = VG_(do_syscall5)(__NR_setsockopt, sr_Res(res), VKI_SOL_SOCKET,
    848                                VKI_SO_NOSIGPIPE, (UWord)&optval,
    849                                sizeof(optval));
    850        // ignore setsockopt() error
    851    }
    852    return sr_isError(res) ? -1 : sr_Res(res);
    853 
    854 #  else
    855 #    error "Unknown arch"
    856 #  endif
    857 }
    858 
    859 
    860 static
    861 Int my_connect ( Int sockfd, struct vki_sockaddr_in* serv_addr, Int addrlen )
    862 {
    863 #  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
    864       || defined(VGP_ppc64_linux) || defined(VGP_s390x_linux)
    865    SysRes res;
    866    UWord  args[3];
    867    args[0] = sockfd;
    868    args[1] = (UWord)serv_addr;
    869    args[2] = addrlen;
    870    res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_CONNECT, (UWord)&args);
    871    return sr_isError(res) ? -1 : sr_Res(res);
    872 
    873 #  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux)
    874    SysRes res;
    875    res = VG_(do_syscall3)(__NR_connect, sockfd, (UWord)serv_addr, addrlen);
    876    return sr_isError(res) ? -1 : sr_Res(res);
    877 
    878 #  elif defined(VGO_darwin)
    879    SysRes res;
    880    res = VG_(do_syscall3)(__NR_connect_nocancel,
    881                           sockfd, (UWord)serv_addr, addrlen);
    882    return sr_isError(res) ? -1 : sr_Res(res);
    883 
    884 #  else
    885 #    error "Unknown arch"
    886 #  endif
    887 }
    888 
    889 Int VG_(write_socket)( Int sd, void *msg, Int count )
    890 {
    891    /* This is actually send(). */
    892 
    893    /* For Linux, VKI_MSG_NOSIGNAL is a request not to send SIGPIPE on
    894       errors on stream oriented sockets when the other end breaks the
    895       connection. The EPIPE error is still returned.
    896 
    897       For Darwin, VG_(socket)() sets SO_NOSIGPIPE to get EPIPE instead of
    898       SIGPIPE */
    899 
    900 #  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
    901       || defined(VGP_ppc64_linux) || defined(VGP_s390x_linux)
    902    SysRes res;
    903    UWord  args[4];
    904    args[0] = sd;
    905    args[1] = (UWord)msg;
    906    args[2] = count;
    907    args[3] = VKI_MSG_NOSIGNAL;
    908    res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_SEND, (UWord)&args);
    909    return sr_isError(res) ? -1 : sr_Res(res);
    910 
    911 #  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux)
    912    SysRes res;
    913    res = VG_(do_syscall6)(__NR_sendto, sd, (UWord)msg,
    914                                        count, VKI_MSG_NOSIGNAL, 0,0);
    915    return sr_isError(res) ? -1 : sr_Res(res);
    916 
    917 #  elif defined(VGP_x86_darwin) || defined(VGP_amd64_darwin)
    918    SysRes res;
    919    res = VG_(do_syscall3)(__NR_write_nocancel, sd, (UWord)msg, count);
    920    return sr_isError(res) ? -1 : sr_Res(res);
    921 
    922 #  else
    923 #    error "Unknown platform"
    924 #  endif
    925 }
    926 
    927 Int VG_(getsockname) ( Int sd, struct vki_sockaddr *name, Int *namelen)
    928 {
    929 #  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
    930       || defined(VGP_ppc64_linux) || defined(VGP_s390x_linux)
    931    SysRes res;
    932    UWord  args[3];
    933    args[0] = sd;
    934    args[1] = (UWord)name;
    935    args[2] = (UWord)namelen;
    936    res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETSOCKNAME, (UWord)&args);
    937    return sr_isError(res) ? -1 : sr_Res(res);
    938 
    939 #  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux)
    940    SysRes res;
    941    res = VG_(do_syscall3)( __NR_getsockname,
    942                            (UWord)sd, (UWord)name, (UWord)namelen );
    943    return sr_isError(res) ? -1 : sr_Res(res);
    944 
    945 #  elif defined(VGO_darwin)
    946    SysRes res;
    947    res = VG_(do_syscall3)( __NR_getsockname,
    948                            (UWord)sd, (UWord)name, (UWord)namelen );
    949    return sr_isError(res) ? -1 : sr_Res(res);
    950 
    951 #  else
    952 #    error "Unknown platform"
    953 #  endif
    954 }
    955 
    956 Int VG_(getpeername) ( Int sd, struct vki_sockaddr *name, Int *namelen)
    957 {
    958 #  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
    959       || defined(VGP_ppc64_linux) || defined(VGP_s390x_linux)
    960    SysRes res;
    961    UWord  args[3];
    962    args[0] = sd;
    963    args[1] = (UWord)name;
    964    args[2] = (UWord)namelen;
    965    res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETPEERNAME, (UWord)&args);
    966    return sr_isError(res) ? -1 : sr_Res(res);
    967 
    968 #  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux)
    969    SysRes res;
    970    res = VG_(do_syscall3)( __NR_getpeername,
    971                            (UWord)sd, (UWord)name, (UWord)namelen );
    972    return sr_isError(res) ? -1 : sr_Res(res);
    973 
    974 #  elif defined(VGO_darwin)
    975    SysRes res;
    976    res = VG_(do_syscall3)( __NR_getpeername,
    977                            (UWord)sd, (UWord)name, (UWord)namelen );
    978    return sr_isError(res) ? -1 : sr_Res(res);
    979 
    980 #  else
    981 #    error "Unknown platform"
    982 #  endif
    983 }
    984 
    985 Int VG_(getsockopt) ( Int sd, Int level, Int optname, void *optval,
    986                       Int *optlen)
    987 {
    988 #  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
    989       || defined(VGP_ppc64_linux) || defined(VGP_s390x_linux)
    990    SysRes res;
    991    UWord  args[5];
    992    args[0] = sd;
    993    args[1] = level;
    994    args[2] = optname;
    995    args[3] = (UWord)optval;
    996    args[4] = (UWord)optlen;
    997    res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETSOCKOPT, (UWord)&args);
    998    return sr_isError(res) ? -1 : sr_Res(res);
    999 
   1000 #  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux)
   1001    SysRes res;
   1002    res = VG_(do_syscall5)( __NR_getsockopt,
   1003                            (UWord)sd, (UWord)level, (UWord)optname,
   1004                            (UWord)optval, (UWord)optlen );
   1005    return sr_isError(res) ? -1 : sr_Res(res);
   1006 
   1007 #  elif defined(VGO_darwin)
   1008    SysRes res;
   1009    res = VG_(do_syscall5)( __NR_getsockopt,
   1010                            (UWord)sd, (UWord)level, (UWord)optname,
   1011                            (UWord)optval, (UWord)optlen );
   1012    return sr_isError(res) ? -1 : sr_Res(res);
   1013 
   1014 #  else
   1015 #    error "Unknown platform"
   1016 #  endif
   1017 }
   1018 
   1019 
   1020 Char *VG_(basename)(const Char *path)
   1021 {
   1022    static Char buf[VKI_PATH_MAX];
   1023 
   1024    const Char *p, *end;
   1025 
   1026    if (path == NULL  ||
   1027        0 == VG_(strcmp)(path, ""))
   1028    {
   1029       return ".";
   1030    }
   1031 
   1032    p = path + VG_(strlen)(path);
   1033    while (p > path  &&  *p == '/') {
   1034       // skip all trailing '/'
   1035       p--;
   1036    }
   1037 
   1038    if (p == path  &&  *p == '/') return "/"; // all slashes
   1039 
   1040    end = p;
   1041 
   1042    while (p > path  &&  *p != '/') {
   1043       // now skip non '/'
   1044       p--;
   1045    }
   1046 
   1047    if (*p == '/') p++;
   1048 
   1049    VG_(strncpy)(buf, p, end-p+1);
   1050    buf[end-p+1] = '\0';
   1051 
   1052    return buf;
   1053 }
   1054 
   1055 
   1056 Char *VG_(dirname)(const Char *path)
   1057 {
   1058    static Char buf[VKI_PATH_MAX];
   1059 
   1060    const Char *p;
   1061 
   1062    if (path == NULL  ||
   1063        0 == VG_(strcmp)(path, "")  ||
   1064        0 == VG_(strcmp)(path, "/"))
   1065    {
   1066       return ".";
   1067    }
   1068 
   1069    p = path + VG_(strlen)(path);
   1070    while (p > path  &&  *p == '/') {
   1071       // skip all trailing '/'
   1072       p--;
   1073    }
   1074 
   1075    while (p > path  &&  *p != '/') {
   1076       // now skip non '/'
   1077       p--;
   1078    }
   1079 
   1080    if (p == path) {
   1081       if (*p == '/') return "/"; // all slashes
   1082       else return "."; // no slashes
   1083    }
   1084 
   1085    while (p > path  &&  *p == '/') {
   1086       // skip '/' again
   1087       p--;
   1088    }
   1089 
   1090    VG_(strncpy)(buf, path, p-path+1);
   1091    buf[p-path+1] = '\0';
   1092 
   1093    return buf;
   1094 }
   1095 
   1096 
   1097 /*--------------------------------------------------------------------*/
   1098 /*--- end                                                          ---*/
   1099 /*--------------------------------------------------------------------*/
   1100