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