• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@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 
fd_exists(Int fd)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 */
VG_(safe_fd)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. */
VG_(resolve_filename)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 
VG_(open)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 
VG_(close)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 
VG_(read)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 
VG_(write)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 
VG_(pipe)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 
VG_(lseek)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 
VG_(ftruncate)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 
VG_(stat)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 
VG_(fstat)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 
VG_(fsize)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 
VG_(is_dir)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 
VG_(dup)347 SysRes VG_(dup) ( Int oldfd )
348 {
349    return VG_(do_syscall1)(__NR_dup, oldfd);
350 }
351 
VG_(dup2)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. */
VG_(fcntl)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 
VG_(rename)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 
VG_(unlink)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. */
VG_(record_startup_wd)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. */
VG_(get_startup_wd)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 
VG_(readlink)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 
VG_(getdents)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. */
VG_(access)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 */
VG_(check_executable)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()?) */
VG_(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 
VG_(mkstemp)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 
VG_(htonl)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 
VG_(ntohl)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 
VG_(htons)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 
VG_(ntohs)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 */
VG_(connect_via_socket)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 */
parse_inet_addr_and_port(UChar * str,UInt * ip_addr,UShort * port)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?
VG_(socket)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
my_connect(Int sockfd,struct vki_sockaddr_in * serv_addr,Int addrlen)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 
VG_(write_socket)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 
VG_(getsockname)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 
VG_(getpeername)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 
VG_(getsockopt)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 
VG_(basename)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 
VG_(dirname)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