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