• 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-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 
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_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 
VG_(mknod)107 SysRes VG_(mknod) ( const Char* pathname, Int mode, UWord dev )
108 {
109 #  if defined(VGO_linux) || defined(VGO_darwin)
110    SysRes res = VG_(do_syscall3)(__NR_mknod,
111                                  (UWord)pathname, mode, dev);
112 #  else
113 #    error Unknown OS
114 #  endif
115    return res;
116 }
117 
VG_(open)118 SysRes VG_(open) ( const Char* pathname, Int flags, Int mode )
119 {
120 #  if defined(VGO_linux)
121    SysRes res = VG_(do_syscall3)(__NR_open,
122                                  (UWord)pathname, flags, mode);
123 #  elif defined(VGO_darwin)
124    SysRes res = VG_(do_syscall3)(__NR_open_nocancel,
125                                  (UWord)pathname, flags, mode);
126 #  else
127 #    error Unknown OS
128 #  endif
129    return res;
130 }
131 
VG_(fd_open)132 Int VG_(fd_open) (const Char* pathname, Int flags, Int mode)
133 {
134    SysRes sr;
135    sr = VG_(open) (pathname, flags, mode);
136    if (sr_isError (sr))
137       return -1;
138    else
139       return sr_Res (sr);
140 }
141 
VG_(close)142 void VG_(close) ( Int fd )
143 {
144    /* Hmm.  Return value is not checked.  That's uncool. */
145 #  if defined(VGO_linux)
146    (void)VG_(do_syscall1)(__NR_close, fd);
147 #  elif defined(VGO_darwin)
148    (void)VG_(do_syscall1)(__NR_close_nocancel, fd);
149 #  else
150 #    error Unknown OS
151 #  endif
152 }
153 
VG_(read)154 Int VG_(read) ( Int fd, void* buf, Int count)
155 {
156    Int    ret;
157 #  if defined(VGO_linux)
158    SysRes res = VG_(do_syscall3)(__NR_read, fd, (UWord)buf, count);
159 #  elif defined(VGO_darwin)
160    SysRes res = VG_(do_syscall3)(__NR_read_nocancel, fd, (UWord)buf, count);
161 #  else
162 #    error Unknown OS
163 #  endif
164    if (sr_isError(res)) {
165       ret = - (Int)(Word)sr_Err(res);
166       vg_assert(ret < 0);
167    } else {
168       ret = (Int)(Word)sr_Res(res);
169       vg_assert(ret >= 0);
170    }
171    return ret;
172 }
173 
VG_(write)174 Int VG_(write) ( Int fd, const void* buf, Int count)
175 {
176    Int    ret;
177 #  if defined(VGO_linux)
178    SysRes res = VG_(do_syscall3)(__NR_write, fd, (UWord)buf, count);
179 #  elif defined(VGO_darwin)
180    SysRes res = VG_(do_syscall3)(__NR_write_nocancel, fd, (UWord)buf, count);
181 #  else
182 #    error "Unknown OS"
183 #  endif
184    if (sr_isError(res)) {
185       ret = - (Int)(Word)sr_Err(res);
186       vg_assert(ret < 0);
187    } else {
188       ret = (Int)(Word)sr_Res(res);
189       vg_assert(ret >= 0);
190    }
191    return ret;
192 }
193 
194 
VG_(pipe)195 Int 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 
VG_(lseek)213 Off64T 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 
VG_(ftruncate)238 extern 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 
VG_(stat)271 SysRes 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 
VG_(fstat)302 Int 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 
VG_(fsize)336 Long 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 
VG_(is_dir)343 Bool 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 
VG_(dup)351 SysRes VG_(dup) ( Int oldfd )
352 {
353    return VG_(do_syscall1)(__NR_dup, oldfd);
354 }
355 
VG_(dup2)356 SysRes 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. */
VG_(fcntl)366 Int 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 
VG_(rename)378 Int 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 
VG_(unlink)384 Int 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: */
396 static HChar startup_wd[VKI_PATH_MAX];
397 static 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. */
VG_(record_startup_wd)404 Bool 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. */
VG_(get_startup_wd)447 Bool 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 
VG_(poll)457 Int    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 
VG_(readlink)465 Int 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 
VG_(getdents)473 Int 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. */
VG_(access)489 Int 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 */
VG_(check_executable)534 Int 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()?) */
VG_(pread)590 SysRes 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. */
VG_(tmpdir)613 const 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 
VG_(mkstemp)629 Int 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 
676 static
677 Int parse_inet_addr_and_port ( UChar* str, UInt* ip_addr, UShort* port );
678 
679 static
680 Int my_connect ( Int sockfd, struct vki_sockaddr_in* serv_addr, Int addrlen );
681 
VG_(htonl)682 UInt 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 
VG_(ntohl)693 UInt 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 
VG_(htons)704 UShort 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 
VG_(ntohs)714 UShort 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 */
VG_(connect_via_socket)735 Int 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 */
parse_inet_addr_and_port(UChar * str,UInt * ip_addr,UShort * port)781 static 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?
VG_(socket)823 Int 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 
860 static
my_connect(Int sockfd,struct vki_sockaddr_in * serv_addr,Int addrlen)861 Int 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 
VG_(write_socket)889 Int 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 
VG_(getsockname)927 Int 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 
VG_(getpeername)956 Int 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 
VG_(getsockopt)985 Int 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 
VG_(basename)1020 Char *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 
VG_(dirname)1056 Char *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