m_libcfile.c revision f0cb39bc6abe181a0abdd1f6c778521ae8497277
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
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_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
111SysRes 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
125void 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
137Int 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
157Int 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
178Int 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
196OffT 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
212extern 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
245SysRes 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
295Int 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
332Long 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
339Bool 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
347SysRes VG_(dup) ( Int oldfd )
348{
349   return VG_(do_syscall1)(__NR_dup, oldfd);
350}
351
352SysRes 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. */
364Int 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
376Int 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
382Int 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: */
394static HChar startup_wd[VKI_PATH_MAX];
395static 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. */
402Bool 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. */
445Bool 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
455Int 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
463Int 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. */
479Int 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 */
524Int 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()?) */
580SysRes 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
608Int 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)
650struct vki_sockaddr_in;
651#endif
652
653static
654Int parse_inet_addr_and_port ( UChar* str, UInt* ip_addr, UShort* port );
655
656static
657Int my_connect ( Int sockfd, struct vki_sockaddr_in* serv_addr, Int addrlen );
658
659UInt 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
670UInt 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
681UShort 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
691UShort 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*/
712Int 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*/
761static 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?
803Int 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
843static
844Int 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
875Int 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
916Int 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
948Int 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
980Int 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
1018Char *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
1054Char *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