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-2012 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(VGP_mips32_linux)
    198    /* __NR_pipe has a strange return convention on mips32-linux. */
    199    SysRes res = VG_(do_syscall0)(__NR_pipe);
    200    if (!sr_isError(res)) {
    201       fd[0] = (Int)sr_Res(res);
    202       fd[1] = (Int)sr_ResEx(res);
    203       return 0;
    204    } else {
    205       return -1;
    206    }
    207 #  elif defined(VGO_linux)
    208    SysRes res = VG_(do_syscall1)(__NR_pipe, (UWord)fd);
    209    return sr_isError(res) ? -1 : 0;
    210 #  elif defined(VGO_darwin)
    211    /* __NR_pipe is UX64, so produces a double-word result */
    212    SysRes res = VG_(do_syscall0)(__NR_pipe);
    213    if (!sr_isError(res)) {
    214       fd[0] = (Int)sr_Res(res);
    215       fd[1] = (Int)sr_ResHI(res);
    216    }
    217    return sr_isError(res) ? -1 : 0;
    218 #  else
    219 #    error "Unknown OS"
    220 #  endif
    221 }
    222 
    223 Off64T VG_(lseek) ( Int fd, Off64T offset, Int whence )
    224 {
    225 #  if defined(VGO_linux) || defined(VGP_amd64_darwin)
    226 #  if defined(__NR__llseek)
    227    Off64T result;
    228    SysRes res = VG_(do_syscall5)(__NR__llseek, fd,
    229                                  offset >> 32, offset & 0xffffffff,
    230                                  (UWord)&result, whence);
    231    return sr_isError(res) ? (-1) : result;
    232 #  else
    233    SysRes res = VG_(do_syscall3)(__NR_lseek, fd, offset, whence);
    234    vg_assert(sizeof(Off64T) == sizeof(Word));
    235    return sr_isError(res) ? (-1) : sr_Res(res);
    236 #  endif
    237 #  elif defined(VGP_x86_darwin)
    238    SysRes res = VG_(do_syscall4)(__NR_lseek, fd,
    239                                  offset & 0xffffffff, offset >> 32, whence);
    240    return sr_isError(res) ? (-1) : sr_Res(res);
    241 #  else
    242 #    error "Unknown plat"
    243 #  endif
    244    /* if you change the error-reporting conventions of this, also
    245       change all usage points. */
    246 }
    247 
    248 
    249 /* stat/fstat support.  It's uggerly.  We have impedance-match into a
    250    'struct vg_stat' in order to have a single structure that callers
    251    can use consistently on all platforms. */
    252 
    253 #define TRANSLATE_TO_vg_stat(_p_vgstat, _p_vkistat) \
    254    do { \
    255       (_p_vgstat)->dev        = (ULong)( (_p_vkistat)->st_dev ); \
    256       (_p_vgstat)->ino        = (ULong)( (_p_vkistat)->st_ino ); \
    257       (_p_vgstat)->nlink      = (ULong)( (_p_vkistat)->st_nlink ); \
    258       (_p_vgstat)->mode       = (UInt) ( (_p_vkistat)->st_mode ); \
    259       (_p_vgstat)->uid        = (UInt) ( (_p_vkistat)->st_uid ); \
    260       (_p_vgstat)->gid        = (UInt) ( (_p_vkistat)->st_gid ); \
    261       (_p_vgstat)->rdev       = (ULong)( (_p_vkistat)->st_rdev ); \
    262       (_p_vgstat)->size       = (Long) ( (_p_vkistat)->st_size ); \
    263       (_p_vgstat)->blksize    = (ULong)( (_p_vkistat)->st_blksize ); \
    264       (_p_vgstat)->blocks     = (ULong)( (_p_vkistat)->st_blocks ); \
    265       (_p_vgstat)->atime      = (ULong)( (_p_vkistat)->st_atime ); \
    266       (_p_vgstat)->atime_nsec = (ULong)( (_p_vkistat)->st_atime_nsec ); \
    267       (_p_vgstat)->mtime      = (ULong)( (_p_vkistat)->st_mtime ); \
    268       (_p_vgstat)->mtime_nsec = (ULong)( (_p_vkistat)->st_mtime_nsec ); \
    269       (_p_vgstat)->ctime      = (ULong)( (_p_vkistat)->st_ctime ); \
    270       (_p_vgstat)->ctime_nsec = (ULong)( (_p_vkistat)->st_ctime_nsec ); \
    271    } while (0)
    272 
    273 SysRes VG_(stat) ( const Char* file_name, struct vg_stat* vgbuf )
    274 {
    275    SysRes res;
    276    VG_(memset)(vgbuf, 0, sizeof(*vgbuf));
    277 
    278 #  if defined(VGO_linux) || defined(VGO_darwin)
    279    /* First try with stat64.  If that doesn't work out, fall back to
    280       the vanilla version. */
    281 #  if defined(__NR_stat64)
    282    { struct vki_stat64 buf64;
    283      res = VG_(do_syscall2)(__NR_stat64, (UWord)file_name, (UWord)&buf64);
    284      if (!(sr_isError(res) && sr_Err(res) == VKI_ENOSYS)) {
    285         /* Success, or any failure except ENOSYS */
    286         if (!sr_isError(res))
    287            TRANSLATE_TO_vg_stat(vgbuf, &buf64);
    288         return res;
    289      }
    290    }
    291 #  endif /* defined(__NR_stat64) */
    292    { struct vki_stat buf;
    293      res = VG_(do_syscall2)(__NR_stat, (UWord)file_name, (UWord)&buf);
    294      if (!sr_isError(res))
    295         TRANSLATE_TO_vg_stat(vgbuf, &buf);
    296      return res;
    297    }
    298 
    299 #  else
    300 #    error Unknown OS
    301 #  endif
    302 }
    303 
    304 Int VG_(fstat) ( Int fd, struct vg_stat* vgbuf )
    305 {
    306    SysRes res;
    307    VG_(memset)(vgbuf, 0, sizeof(*vgbuf));
    308 
    309 #  if defined(VGO_linux)  ||  defined(VGO_darwin)
    310    /* First try with fstat64.  If that doesn't work out, fall back to
    311       the vanilla version. */
    312 #  if defined(__NR_fstat64)
    313    { struct vki_stat64 buf64;
    314      res = VG_(do_syscall2)(__NR_fstat64, (UWord)fd, (UWord)&buf64);
    315      if (!(sr_isError(res) && sr_Err(res) == VKI_ENOSYS)) {
    316         /* Success, or any failure except ENOSYS */
    317         if (!sr_isError(res))
    318            TRANSLATE_TO_vg_stat(vgbuf, &buf64);
    319         return sr_isError(res) ? (-1) : 0;
    320      }
    321    }
    322 #  endif /* if defined(__NR_fstat64) */
    323    { struct vki_stat buf;
    324      res = VG_(do_syscall2)(__NR_fstat, (UWord)fd, (UWord)&buf);
    325      if (!sr_isError(res))
    326         TRANSLATE_TO_vg_stat(vgbuf, &buf);
    327      return sr_isError(res) ? (-1) : 0;
    328    }
    329 
    330 #  else
    331 #    error Unknown OS
    332 #  endif
    333 }
    334 
    335 #undef TRANSLATE_TO_vg_stat
    336 
    337 
    338 Long VG_(fsize) ( Int fd )
    339 {
    340    struct vg_stat buf;
    341    Int res = VG_(fstat)( fd, &buf );
    342    return (res == -1) ? (-1LL) : buf.size;
    343 }
    344 
    345 Bool VG_(is_dir) ( const HChar* f )
    346 {
    347    struct vg_stat buf;
    348    SysRes res = VG_(stat)(f, &buf);
    349    return sr_isError(res) ? False
    350                       : VKI_S_ISDIR(buf.mode) ? True : False;
    351 }
    352 
    353 SysRes VG_(dup) ( Int oldfd )
    354 {
    355    return VG_(do_syscall1)(__NR_dup, oldfd);
    356 }
    357 
    358 SysRes VG_(dup2) ( Int oldfd, Int newfd )
    359 {
    360 #  if defined(VGO_linux) || defined(VGO_darwin)
    361    return VG_(do_syscall2)(__NR_dup2, oldfd, newfd);
    362 #  else
    363 #    error Unknown OS
    364 #  endif
    365 }
    366 
    367 /* Returns -1 on error. */
    368 Int VG_(fcntl) ( Int fd, Int cmd, Addr arg )
    369 {
    370 #  if defined(VGO_linux)
    371    SysRes res = VG_(do_syscall3)(__NR_fcntl, fd, cmd, arg);
    372 #  elif defined(VGO_darwin)
    373    SysRes res = VG_(do_syscall3)(__NR_fcntl_nocancel, fd, cmd, arg);
    374 #  else
    375 #    error "Unknown OS"
    376 #  endif
    377    return sr_isError(res) ? -1 : sr_Res(res);
    378 }
    379 
    380 Int VG_(rename) ( const Char* old_name, const Char* new_name )
    381 {
    382    SysRes res = VG_(do_syscall2)(__NR_rename, (UWord)old_name, (UWord)new_name);
    383    return sr_isError(res) ? (-1) : 0;
    384 }
    385 
    386 Int VG_(unlink) ( const Char* file_name )
    387 {
    388    SysRes res = VG_(do_syscall1)(__NR_unlink, (UWord)file_name);
    389    return sr_isError(res) ? (-1) : 0;
    390 }
    391 
    392 /* The working directory at startup.  AIX doesn't provide an easy
    393    system call to do getcwd, but fortunately we don't need arbitrary
    394    getcwd support.  All that is really needed is to note the cwd at
    395    process startup.  Hence VG_(record_startup_wd) notes it (in a
    396    platform dependent way) and VG_(get_startup_wd) produces the noted
    397    value.  Hence: */
    398 static HChar startup_wd[VKI_PATH_MAX];
    399 static Bool  startup_wd_acquired = False;
    400 
    401 /* Record the process' working directory at startup.  Is intended to
    402    be called exactly once, at startup, before the working directory
    403    changes.  Return True for success, False for failure, so that the
    404    caller can bomb out suitably without creating module cycles if
    405    there is a problem. */
    406 Bool VG_(record_startup_wd) ( void )
    407 {
    408    const Int szB = sizeof(startup_wd);
    409    vg_assert(!startup_wd_acquired);
    410    vg_assert(szB >= 512 && szB <= 16384/*let's say*/); /* stay sane */
    411    VG_(memset)(startup_wd, 0, szB);
    412 #  if defined(VGO_linux)
    413    /* Simple: just ask the kernel */
    414    { SysRes res
    415         = VG_(do_syscall2)(__NR_getcwd, (UWord)startup_wd, szB-1);
    416      vg_assert(startup_wd[szB-1] == 0);
    417      if (sr_isError(res)) {
    418         return False;
    419      } else {
    420         startup_wd_acquired = True;
    421         return True;
    422      }
    423    }
    424 #  elif defined(VGO_darwin)
    425    /* We can't ask the kernel, so instead rely on launcher-*.c to
    426       tell us the startup path.  Note the env var is keyed to the
    427       parent's PID, not ours, since our parent is the launcher
    428       process. */
    429    { Char  envvar[100];
    430      Char* wd = NULL;
    431      VG_(memset)(envvar, 0, sizeof(envvar));
    432      VG_(sprintf)(envvar, "VALGRIND_STARTUP_PWD_%d_XYZZY",
    433                           (Int)VG_(getppid)());
    434      wd = VG_(getenv)( envvar );
    435      if (wd == NULL || (1+VG_(strlen)(wd) >= szB))
    436         return False;
    437      VG_(strncpy_safely)(startup_wd, wd, szB);
    438      vg_assert(startup_wd[szB-1] == 0);
    439      startup_wd_acquired = True;
    440      return True;
    441    }
    442 #  else
    443 #    error Unknown OS
    444 #  endif
    445 }
    446 
    447 /* Copy the previously acquired startup_wd into buf[0 .. size-1],
    448    or return False if buf isn't big enough. */
    449 Bool VG_(get_startup_wd) ( Char* buf, SizeT size )
    450 {
    451    vg_assert(startup_wd_acquired);
    452    vg_assert(startup_wd[ sizeof(startup_wd)-1 ] == 0);
    453    if (1+VG_(strlen)(startup_wd) >= size)
    454       return False;
    455    VG_(strncpy_safely)(buf, startup_wd, size);
    456    return True;
    457 }
    458 
    459 Int VG_(poll) (struct vki_pollfd *fds, Int nfds, Int timeout)
    460 {
    461    SysRes res;
    462 #  if defined(VGO_linux)
    463    res = VG_(do_syscall3)(__NR_poll, (UWord)fds, nfds, timeout);
    464 #  elif defined(VGO_darwin)
    465    res = VG_(do_syscall3)(__NR_poll_nocancel, (UWord)fds, nfds, timeout);
    466 #  else
    467 #    error "Unknown OS"
    468 #  endif
    469    return sr_isError(res) ? -1 : sr_Res(res);
    470 }
    471 
    472 
    473 Int VG_(readlink) (const Char* path, Char* buf, UInt bufsiz)
    474 {
    475    SysRes res;
    476    /* res = readlink( path, buf, bufsiz ); */
    477    res = VG_(do_syscall3)(__NR_readlink, (UWord)path, (UWord)buf, bufsiz);
    478    return sr_isError(res) ? -1 : sr_Res(res);
    479 }
    480 
    481 Int VG_(getdents) (Int fd, struct vki_dirent *dirp, UInt count)
    482 {
    483 #  if defined(VGO_linux)
    484    SysRes res;
    485    /* res = getdents( fd, dirp, count ); */
    486    res = VG_(do_syscall3)(__NR_getdents, fd, (UWord)dirp, count);
    487    return sr_isError(res) ? -1 : sr_Res(res);
    488 #  elif defined(VGO_darwin)
    489    I_die_here;
    490 #  else
    491 #    error "Unknown OS"
    492 #  endif
    493 }
    494 
    495 /* Check accessibility of a file.  Returns zero for access granted,
    496    nonzero otherwise. */
    497 Int VG_(access) ( const HChar* path, Bool irusr, Bool iwusr, Bool ixusr )
    498 {
    499 #  if defined(VGO_linux)
    500    /* Very annoyingly, I cannot find any definition for R_OK et al in
    501       the kernel interfaces.  Therefore I reluctantly resort to
    502       hardwiring in these magic numbers that I determined by
    503       experimentation. */
    504 #  define VKI_R_OK 4
    505 #  define VKI_W_OK 2
    506 #  define VKI_X_OK 1
    507 #  endif
    508 
    509    UWord w = (irusr ? VKI_R_OK : 0)
    510              | (iwusr ? VKI_W_OK : 0)
    511              | (ixusr ? VKI_X_OK : 0);
    512    SysRes res = VG_(do_syscall2)(__NR_access, (UWord)path, w);
    513    return sr_isError(res) ? 1 : 0;
    514 
    515 #  if defined(VGO_linux)
    516 #  undef VKI_R_OK
    517 #  undef VKI_W_OK
    518 #  undef VKI_X_OK
    519 #  endif
    520 }
    521 
    522 /*
    523    Emulate the normal Unix permissions checking algorithm.
    524 
    525    If owner matches, then use the owner permissions, else
    526    if group matches, then use the group permissions, else
    527    use other permissions.
    528 
    529    Note that we can't deal properly with SUID/SGID.  By default
    530    (allow_setuid == False), we refuse to run them (otherwise the
    531    executable may misbehave if it doesn't have the permissions it
    532    thinks it does).  However, the caller may indicate that setuid
    533    executables are allowed, for example if we are going to exec them
    534    but not trace into them (iow, client sys_execve when
    535    clo_trace_children == False).
    536 
    537    If VKI_EACCES is returned (iow, permission was refused), then
    538    *is_setuid is set to True iff permission was refused because the
    539    executable is setuid.
    540 */
    541 /* returns: 0 = success, non-0 is failure */
    542 Int VG_(check_executable)(/*OUT*/Bool* is_setuid,
    543                           const HChar* f, Bool allow_setuid)
    544 {
    545    struct vg_stat st;
    546    SysRes res = VG_(stat)(f, &st);
    547 
    548    if (is_setuid)
    549       *is_setuid = False;
    550 
    551    if (sr_isError(res)) {
    552       return sr_Err(res);
    553    }
    554 
    555    if ( (st.mode & (VKI_S_ISUID | VKI_S_ISGID)) && !allow_setuid ) {
    556       if (is_setuid)
    557          *is_setuid = True;
    558       return VKI_EACCES;
    559    }
    560 
    561    if (VG_(geteuid)() == st.uid) {
    562       if (!(st.mode & VKI_S_IXUSR))
    563          return VKI_EACCES;
    564    } else {
    565       Int grpmatch = 0;
    566 
    567       if (VG_(getegid)() == st.gid)
    568 	 grpmatch = 1;
    569       else {
    570 	 UInt groups[32];
    571 	 Int ngrp = VG_(getgroups)(32, groups);
    572 	 Int i;
    573          /* ngrp will be -1 if VG_(getgroups) failed. */
    574          for (i = 0; i < ngrp; i++) {
    575 	    if (groups[i] == st.gid) {
    576 	       grpmatch = 1;
    577 	       break;
    578 	    }
    579          }
    580       }
    581 
    582       if (grpmatch) {
    583 	 if (!(st.mode & VKI_S_IXGRP)) {
    584             return VKI_EACCES;
    585          }
    586       } else if (!(st.mode & VKI_S_IXOTH)) {
    587          return VKI_EACCES;
    588       }
    589    }
    590 
    591    return 0;
    592 }
    593 
    594 SysRes VG_(pread) ( Int fd, void* buf, Int count, OffT offset )
    595 {
    596    SysRes res;
    597    // on 32 bits platforms, we receive a 32 bits OffT but
    598    // we must extend it to pass a long long 64 bits.
    599 #  if defined(VGP_x86_linux)
    600    vg_assert(sizeof(OffT) == 4);
    601    res = VG_(do_syscall5)(__NR_pread64, fd, (UWord)buf, count,
    602                           offset, 0); // Little endian long long
    603    return res;
    604 #  elif defined(VGP_arm_linux)
    605    vg_assert(sizeof(OffT) == 4);
    606    res = VG_(do_syscall5)(__NR_pread64, fd, (UWord)buf, count,
    607                           0, offset); // Big endian long long
    608    return res;
    609 #  elif defined(VGP_ppc32_linux)
    610    vg_assert(sizeof(OffT) == 4);
    611    res = VG_(do_syscall6)(__NR_pread64, fd, (UWord)buf, count,
    612                           0, // Padding needed on PPC32
    613                           0, offset); // Big endian long long
    614    return res;
    615 #  elif defined(VGP_mips32_linux) && VKI_LITTLE_ENDIAN
    616    vg_assert(sizeof(OffT) == 4);
    617    res = VG_(do_syscall6)(__NR_pread64, fd, (UWord)buf, count,
    618                           0, offset, 0);
    619    return res;
    620 #  elif defined(VGP_mips32_linux) && VKI_BIG_ENDIAN
    621    vg_assert(sizeof(OffT) == 4);
    622    res = VG_(do_syscall6)(__NR_pread64, fd, (UWord)buf, count,
    623                           0, 0, offset);
    624    return res;
    625 #  elif defined(VGP_amd64_linux) \
    626       || defined(VGP_ppc64_linux) || defined(VGP_s390x_linux)
    627    res = VG_(do_syscall4)(__NR_pread64, fd, (UWord)buf, count, offset);
    628    return res;
    629 #  elif defined(VGP_amd64_darwin)
    630    vg_assert(sizeof(OffT) == 8);
    631    res = VG_(do_syscall4)(__NR_pread_nocancel, fd, (UWord)buf, count, offset);
    632    return res;
    633 #  elif defined(VGP_x86_darwin)
    634    vg_assert(sizeof(OffT) == 8);
    635    res = VG_(do_syscall5)(__NR_pread_nocancel, fd, (UWord)buf, count,
    636                           offset & 0xffffffff, offset >> 32);
    637    return res;
    638 #  else
    639 #    error "Unknown platform"
    640 #  endif
    641 }
    642 
    643 /* Return the name of a directory for temporary files. */
    644 const HChar *VG_(tmpdir)(void)
    645 {
    646    const HChar *tmpdir;
    647 
    648    tmpdir = VG_(getenv)("TMPDIR");
    649    if (tmpdir == NULL || *tmpdir == '\0') tmpdir = VG_TMPDIR;
    650    if (tmpdir == NULL || *tmpdir == '\0') tmpdir = "/tmp";    /* fallback */
    651 
    652    return tmpdir;
    653 }
    654 
    655 /* Create and open (-rw------) a tmp file name incorporating said arg.
    656    Returns -1 on failure, else the fd of the file.  If fullname is
    657    non-NULL, the file's name is written into it.  The number of bytes
    658    written is guaranteed not to exceed 64+strlen(part_of_name). */
    659 
    660 Int VG_(mkstemp) ( HChar* part_of_name, /*OUT*/HChar* fullname )
    661 {
    662    HChar  buf[200];
    663    Int    n, tries, fd;
    664    UInt   seed;
    665    SysRes sres;
    666    const HChar *tmpdir;
    667 
    668    vg_assert(part_of_name);
    669    n = VG_(strlen)(part_of_name);
    670    vg_assert(n > 0 && n < 100);
    671 
    672    seed = (VG_(getpid)() << 9) ^ VG_(getppid)();
    673 
    674    /* Determine sensible location for temporary files */
    675    tmpdir = VG_(tmpdir)();
    676 
    677    tries = 0;
    678    while (True) {
    679       if (tries++ > 10)
    680          return -1;
    681       VG_(sprintf)( buf, "%s/valgrind_%s_%08x",
    682                     tmpdir, part_of_name, VG_(random)( &seed ));
    683       if (0)
    684          VG_(printf)("VG_(mkstemp): trying: %s\n", buf);
    685 
    686       sres = VG_(open)(buf,
    687                        VKI_O_CREAT|VKI_O_RDWR|VKI_O_EXCL|VKI_O_TRUNC,
    688                        VKI_S_IRUSR|VKI_S_IWUSR);
    689       if (sr_isError(sres)) {
    690          VG_(umsg)("VG_(mkstemp): failed to create temp file: %s\n", buf);
    691          continue;
    692       }
    693       /* VG_(safe_fd) doesn't return if it fails. */
    694       fd = VG_(safe_fd)( sr_Res(sres) );
    695       if (fullname)
    696          VG_(strcpy)( fullname, buf );
    697       return fd;
    698    }
    699    /* NOTREACHED */
    700 }
    701 
    702 
    703 /* ---------------------------------------------------------------------
    704    Socket-related stuff.
    705    ------------------------------------------------------------------ */
    706 
    707 static
    708 Int parse_inet_addr_and_port ( UChar* str, UInt* ip_addr, UShort* port );
    709 
    710 static
    711 Int my_connect ( Int sockfd, struct vki_sockaddr_in* serv_addr, Int addrlen );
    712 
    713 UInt VG_(htonl) ( UInt x )
    714 {
    715 #  if defined(VG_BIGENDIAN)
    716    return x;
    717 #  else
    718    return
    719       (((x >> 24) & 0xFF) << 0) | (((x >> 16) & 0xFF) << 8)
    720       | (((x >> 8) & 0xFF) << 16) | (((x >> 0) & 0xFF) << 24);
    721 #  endif
    722 }
    723 
    724 UInt VG_(ntohl) ( UInt x )
    725 {
    726 #  if defined(VG_BIGENDIAN)
    727    return x;
    728 #  else
    729    return
    730       (((x >> 24) & 0xFF) << 0) | (((x >> 16) & 0xFF) << 8)
    731       | (((x >> 8) & 0xFF) << 16) | (((x >> 0) & 0xFF) << 24);
    732 #  endif
    733 }
    734 
    735 UShort VG_(htons) ( UShort x )
    736 {
    737 #  if defined(VG_BIGENDIAN)
    738    return x;
    739 #  else
    740    return
    741       (((x >> 8) & 0xFF) << 0) | (((x >> 0) & 0xFF) << 8);
    742 #  endif
    743 }
    744 
    745 UShort VG_(ntohs) ( UShort x )
    746 {
    747 #  if defined(VG_BIGENDIAN)
    748    return x;
    749 #  else
    750    return
    751       (((x >> 8) & 0xFF) << 0) | (((x >> 0) & 0xFF) << 8);
    752 #  endif
    753 }
    754 
    755 
    756 /* The main function.
    757 
    758    Supplied string contains either an ip address "192.168.0.1" or
    759    an ip address and port pair, "192.168.0.1:1500".  Parse these,
    760    and return:
    761      -1 if there is a parse error
    762      -2 if no parse error, but specified host:port cannot be opened
    763      the relevant file (socket) descriptor, otherwise.
    764  is used.
    765 */
    766 Int VG_(connect_via_socket)( UChar* str )
    767 {
    768 #  if defined(VGO_linux) || defined(VGO_darwin)
    769    Int sd, res;
    770    struct vki_sockaddr_in servAddr;
    771    UInt   ip   = 0;
    772    UShort port = VG_CLO_DEFAULT_LOGPORT;
    773    Bool   ok   = parse_inet_addr_and_port(str, &ip, &port);
    774    if (!ok)
    775       return -1;
    776 
    777    //if (0)
    778    //   VG_(printf)("ip = %d.%d.%d.%d, port %d\n",
    779    //               (ip >> 24) & 0xFF, (ip >> 16) & 0xFF,
    780    //               (ip >> 8) & 0xFF, ip & 0xFF,
    781    //               (UInt)port );
    782 
    783    servAddr.sin_family = VKI_AF_INET;
    784    servAddr.sin_addr.s_addr = VG_(htonl)(ip);
    785    servAddr.sin_port = VG_(htons)(port);
    786 
    787    /* create socket */
    788    sd = VG_(socket)(VKI_AF_INET, VKI_SOCK_STREAM, 0 /* IPPROTO_IP ? */);
    789    if (sd < 0) {
    790       /* this shouldn't happen ... nevertheless */
    791       return -2;
    792    }
    793 
    794    /* connect to server */
    795    res = my_connect(sd, &servAddr, sizeof(servAddr));
    796    if (res < 0) {
    797       /* connection failed */
    798       return -2;
    799    }
    800 
    801    return sd;
    802 
    803 #  else
    804 #    error "Unknown OS"
    805 #  endif
    806 }
    807 
    808 
    809 /* Let d = one or more digits.  Accept either:
    810    d.d.d.d  or  d.d.d.d:d
    811 */
    812 static Int parse_inet_addr_and_port ( UChar* str, UInt* ip_addr, UShort* port )
    813 {
    814 #  define GET_CH ((*str) ? (*str++) : 0)
    815    UInt ipa, i, j, c, any;
    816    ipa = 0;
    817    for (i = 0; i < 4; i++) {
    818       j = 0;
    819       any = 0;
    820       while (1) {
    821          c = GET_CH;
    822          if (c < '0' || c > '9') break;
    823          j = 10 * j + (int)(c - '0');
    824          any = 1;
    825       }
    826       if (any == 0 || j > 255) goto syntaxerr;
    827       ipa = (ipa << 8) + j;
    828       if (i <= 2 && c != '.') goto syntaxerr;
    829    }
    830    if (c == 0 || c == ':')
    831       *ip_addr = ipa;
    832    if (c == 0) goto ok;
    833    if (c != ':') goto syntaxerr;
    834    j = 0;
    835    any = 0;
    836    while (1) {
    837       c = GET_CH;
    838       if (c < '0' || c > '9') break;
    839       j = j * 10 + (int)(c - '0');
    840       any = 1;
    841       if (j > 65535) goto syntaxerr;
    842    }
    843    if (any == 0 || c != 0) goto syntaxerr;
    844    if (j < 1024) goto syntaxerr;
    845    *port = (UShort)j;
    846  ok:
    847    return 1;
    848  syntaxerr:
    849    return 0;
    850 #  undef GET_CH
    851 }
    852 
    853 // GrP fixme safe_fd?
    854 Int VG_(socket) ( Int domain, Int type, Int protocol )
    855 {
    856 #  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
    857       || defined(VGP_ppc64_linux) || defined(VGP_s390x_linux)
    858    SysRes res;
    859    UWord  args[3];
    860    args[0] = domain;
    861    args[1] = type;
    862    args[2] = protocol;
    863    res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_SOCKET, (UWord)&args);
    864    return sr_isError(res) ? -1 : sr_Res(res);
    865 
    866 #  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
    867         || defined(VGP_mips32_linux)
    868    SysRes res;
    869    res = VG_(do_syscall3)(__NR_socket, domain, type, protocol );
    870    return sr_isError(res) ? -1 : sr_Res(res);
    871 
    872 #  elif defined(VGO_darwin)
    873    SysRes res;
    874    res = VG_(do_syscall3)(__NR_socket, domain, type, protocol);
    875    if (!sr_isError(res)) {
    876        // Set SO_NOSIGPIPE so write() returns EPIPE instead of raising SIGPIPE
    877        Int optval = 1;
    878        SysRes res2;
    879        res2 = VG_(do_syscall5)(__NR_setsockopt, sr_Res(res), VKI_SOL_SOCKET,
    880                                VKI_SO_NOSIGPIPE, (UWord)&optval,
    881                                sizeof(optval));
    882        // ignore setsockopt() error
    883    }
    884    return sr_isError(res) ? -1 : sr_Res(res);
    885 
    886 #  else
    887 #    error "Unknown arch"
    888 #  endif
    889 }
    890 
    891 
    892 static
    893 Int my_connect ( Int sockfd, struct vki_sockaddr_in* serv_addr, Int addrlen )
    894 {
    895 #  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
    896       || defined(VGP_ppc64_linux) || defined(VGP_s390x_linux)
    897    SysRes res;
    898    UWord  args[3];
    899    args[0] = sockfd;
    900    args[1] = (UWord)serv_addr;
    901    args[2] = addrlen;
    902    res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_CONNECT, (UWord)&args);
    903    return sr_isError(res) ? -1 : sr_Res(res);
    904 
    905 #  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
    906         || defined(VGP_mips32_linux)
    907    SysRes res;
    908    res = VG_(do_syscall3)(__NR_connect, sockfd, (UWord)serv_addr, addrlen);
    909    return sr_isError(res) ? -1 : sr_Res(res);
    910 
    911 #  elif defined(VGO_darwin)
    912    SysRes res;
    913    res = VG_(do_syscall3)(__NR_connect_nocancel,
    914                           sockfd, (UWord)serv_addr, addrlen);
    915    return sr_isError(res) ? -1 : sr_Res(res);
    916 
    917 #  else
    918 #    error "Unknown arch"
    919 #  endif
    920 }
    921 
    922 Int VG_(write_socket)( Int sd, void *msg, Int count )
    923 {
    924    /* This is actually send(). */
    925 
    926    /* For Linux, VKI_MSG_NOSIGNAL is a request not to send SIGPIPE on
    927       errors on stream oriented sockets when the other end breaks the
    928       connection. The EPIPE error is still returned.
    929 
    930       For Darwin, VG_(socket)() sets SO_NOSIGPIPE to get EPIPE instead of
    931       SIGPIPE */
    932 
    933 #  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
    934       || defined(VGP_ppc64_linux) || defined(VGP_s390x_linux)
    935    SysRes res;
    936    UWord  args[4];
    937    args[0] = sd;
    938    args[1] = (UWord)msg;
    939    args[2] = count;
    940    args[3] = VKI_MSG_NOSIGNAL;
    941    res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_SEND, (UWord)&args);
    942    return sr_isError(res) ? -1 : sr_Res(res);
    943 
    944 #  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
    945         || defined(VGP_mips32_linux)
    946    SysRes res;
    947    res = VG_(do_syscall6)(__NR_sendto, sd, (UWord)msg,
    948                                        count, VKI_MSG_NOSIGNAL, 0,0);
    949    return sr_isError(res) ? -1 : sr_Res(res);
    950 
    951 #  elif defined(VGP_x86_darwin) || defined(VGP_amd64_darwin)
    952    SysRes res;
    953    res = VG_(do_syscall3)(__NR_write_nocancel, sd, (UWord)msg, count);
    954    return sr_isError(res) ? -1 : sr_Res(res);
    955 
    956 #  else
    957 #    error "Unknown platform"
    958 #  endif
    959 }
    960 
    961 Int VG_(getsockname) ( Int sd, struct vki_sockaddr *name, Int *namelen)
    962 {
    963 #  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
    964       || defined(VGP_ppc64_linux) || defined(VGP_s390x_linux) \
    965       || defined(VGP_mips32_linux)
    966    SysRes res;
    967    UWord  args[3];
    968    args[0] = sd;
    969    args[1] = (UWord)name;
    970    args[2] = (UWord)namelen;
    971    res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETSOCKNAME, (UWord)&args);
    972    return sr_isError(res) ? -1 : sr_Res(res);
    973 
    974 #  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux)
    975    SysRes res;
    976    res = VG_(do_syscall3)( __NR_getsockname,
    977                            (UWord)sd, (UWord)name, (UWord)namelen );
    978    return sr_isError(res) ? -1 : sr_Res(res);
    979 
    980 #  elif defined(VGO_darwin)
    981    SysRes res;
    982    res = VG_(do_syscall3)( __NR_getsockname,
    983                            (UWord)sd, (UWord)name, (UWord)namelen );
    984    return sr_isError(res) ? -1 : sr_Res(res);
    985 
    986 #  else
    987 #    error "Unknown platform"
    988 #  endif
    989 }
    990 
    991 Int VG_(getpeername) ( Int sd, struct vki_sockaddr *name, Int *namelen)
    992 {
    993 #  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
    994       || defined(VGP_ppc64_linux) || defined(VGP_s390x_linux) \
    995       || defined(VGP_mips32_linux)
    996    SysRes res;
    997    UWord  args[3];
    998    args[0] = sd;
    999    args[1] = (UWord)name;
   1000    args[2] = (UWord)namelen;
   1001    res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETPEERNAME, (UWord)&args);
   1002    return sr_isError(res) ? -1 : sr_Res(res);
   1003 
   1004 #  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux)
   1005    SysRes res;
   1006    res = VG_(do_syscall3)( __NR_getpeername,
   1007                            (UWord)sd, (UWord)name, (UWord)namelen );
   1008    return sr_isError(res) ? -1 : sr_Res(res);
   1009 
   1010 #  elif defined(VGO_darwin)
   1011    SysRes res;
   1012    res = VG_(do_syscall3)( __NR_getpeername,
   1013                            (UWord)sd, (UWord)name, (UWord)namelen );
   1014    return sr_isError(res) ? -1 : sr_Res(res);
   1015 
   1016 #  else
   1017 #    error "Unknown platform"
   1018 #  endif
   1019 }
   1020 
   1021 Int VG_(getsockopt) ( Int sd, Int level, Int optname, void *optval,
   1022                       Int *optlen)
   1023 {
   1024 #  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
   1025       || defined(VGP_ppc64_linux) || defined(VGP_s390x_linux)
   1026    SysRes res;
   1027    UWord  args[5];
   1028    args[0] = sd;
   1029    args[1] = level;
   1030    args[2] = optname;
   1031    args[3] = (UWord)optval;
   1032    args[4] = (UWord)optlen;
   1033    res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETSOCKOPT, (UWord)&args);
   1034    return sr_isError(res) ? -1 : sr_Res(res);
   1035 
   1036 #  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
   1037         || defined(VGP_mips32_linux)
   1038    SysRes res;
   1039    res = VG_(do_syscall5)( __NR_getsockopt,
   1040                            (UWord)sd, (UWord)level, (UWord)optname,
   1041                            (UWord)optval, (UWord)optlen );
   1042    return sr_isError(res) ? -1 : sr_Res(res);
   1043 
   1044 #  elif defined(VGO_darwin)
   1045    SysRes res;
   1046    res = VG_(do_syscall5)( __NR_getsockopt,
   1047                            (UWord)sd, (UWord)level, (UWord)optname,
   1048                            (UWord)optval, (UWord)optlen );
   1049    return sr_isError(res) ? -1 : sr_Res(res);
   1050 
   1051 #  else
   1052 #    error "Unknown platform"
   1053 #  endif
   1054 }
   1055 
   1056 
   1057 Char *VG_(basename)(const Char *path)
   1058 {
   1059    static Char buf[VKI_PATH_MAX];
   1060 
   1061    const Char *p, *end;
   1062 
   1063    if (path == NULL  ||
   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    if (p == path  &&  *p == '/') return "/"; // all slashes
   1076 
   1077    end = p;
   1078 
   1079    while (p > path  &&  *p != '/') {
   1080       // now skip non '/'
   1081       p--;
   1082    }
   1083 
   1084    if (*p == '/') p++;
   1085 
   1086    VG_(strncpy)(buf, p, end-p+1);
   1087    buf[end-p+1] = '\0';
   1088 
   1089    return buf;
   1090 }
   1091 
   1092 
   1093 Char *VG_(dirname)(const Char *path)
   1094 {
   1095    static Char buf[VKI_PATH_MAX];
   1096 
   1097    const Char *p;
   1098 
   1099    if (path == NULL  ||
   1100        0 == VG_(strcmp)(path, "")  ||
   1101        0 == VG_(strcmp)(path, "/"))
   1102    {
   1103       return ".";
   1104    }
   1105 
   1106    p = path + VG_(strlen)(path);
   1107    while (p > path  &&  *p == '/') {
   1108       // skip all trailing '/'
   1109       p--;
   1110    }
   1111 
   1112    while (p > path  &&  *p != '/') {
   1113       // now skip non '/'
   1114       p--;
   1115    }
   1116 
   1117    if (p == path) {
   1118       if (*p == '/') return "/"; // all slashes
   1119       else return "."; // no slashes
   1120    }
   1121 
   1122    while (p > path  &&  *p == '/') {
   1123       // skip '/' again
   1124       p--;
   1125    }
   1126 
   1127    VG_(strncpy)(buf, path, p-path+1);
   1128    buf[p-path+1] = '\0';
   1129 
   1130    return buf;
   1131 }
   1132 
   1133 
   1134 /*--------------------------------------------------------------------*/
   1135 /*--- end                                                          ---*/
   1136 /*--------------------------------------------------------------------*/
   1137