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