1 /* -*- mode: C; c-basic-offset: 3; -*- */
3 /*--------------------------------------------------------------------*/
4 /*--- File- and socket-related libc stuff. m_libcfile.c ---*/
5 /*--------------------------------------------------------------------*/
8 This file is part of Valgrind, a dynamic binary instrumentation
11 Copyright (C) 2000-2013 Julian Seward
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation; either version 2 of the
17 License, or (at your option) any later version.
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
29 The GNU General Public License is contained in the file COPYING.
32 #include "pub_core_basics.h"
33 #include "pub_core_vki.h"
34 #include "pub_core_vkiscnums.h"
35 #include "pub_core_debuglog.h"
36 #include "pub_core_libcbase.h"
37 #include "pub_core_libcassert.h"
38 #include "pub_core_libcfile.h"
39 #include "pub_core_libcprint.h" // VG_(sprintf)
40 #include "pub_core_libcproc.h" // VG_(getpid), VG_(getppid)
41 #include "pub_core_clientstate.h" // VG_(fd_hard_limit)
42 #include "pub_core_mallocfree.h" // VG_(realloc)
43 #include "pub_core_syscall.h"
45 /* IMPORTANT: on Darwin it is essential to use the _nocancel versions
46 of syscalls rather than the vanilla version, if a _nocancel version
47 is available. See docs/internals/Darwin-notes.txt for the reason
50 /* ---------------------------------------------------------------------
52 ------------------------------------------------------------------ */
54 /* Move an fd into the Valgrind-safe range */
55 Int
VG_(safe_fd
)(Int oldfd
)
59 vg_assert(VG_(fd_hard_limit
) != -1);
61 newfd
= VG_(fcntl
)(oldfd
, VKI_F_DUPFD
, VG_(fd_hard_limit
));
65 /* Set the close-on-exec flag for this fd. */
66 VG_(fcntl
)(newfd
, VKI_F_SETFD
, VKI_FD_CLOEXEC
);
68 vg_assert(newfd
>= VG_(fd_hard_limit
));
72 /* Given a file descriptor, attempt to deduce its filename. To do
73 this, we use /proc/self/fd/<FD>. If this doesn't point to a file,
74 or if it doesn't exist, we return False.
75 Upon successful completion *result contains the filename. The
76 filename will be overwritten with the next invocation so callers
77 need to copy the filename if needed. *result is NULL if the filename
79 Bool
VG_(resolve_filename
) ( Int fd
, const HChar
** result
)
81 # if defined(VGO_linux)
82 static HChar
*buf
= NULL
;
83 static SizeT bufsiz
= 0;
85 if (buf
== NULL
) { // first time
87 buf
= VG_(malloc
)("resolve_filename", bufsiz
);
90 HChar tmp
[64]; // large enough
91 VG_(sprintf
)(tmp
, "/proc/self/fd/%d", fd
);
94 SSizeT res
= VG_(readlink
)(tmp
, buf
, bufsiz
);
96 if (res
== bufsiz
) { // buffer too small; increase and retry
98 buf
= VG_(realloc
)("resolve_filename", buf
, bufsiz
);
101 vg_assert(bufsiz
> res
); // paranoia
102 if (buf
[0] != '/') break;
112 # elif defined(VGO_darwin)
113 HChar tmp
[VKI_MAXPATHLEN
+1];
114 if (0 == VG_(fcntl
)(fd
, VKI_F_GETPATH
, (UWord
)tmp
)) {
115 static HChar
*buf
= NULL
;
118 buf
= VG_(malloc
)("resolve_filename", VKI_MAXPATHLEN
+1);
119 VG_(strcpy
)( buf
, tmp
);
122 if (buf
[0] == '/') return True
;
133 SysRes
VG_(mknod
) ( const HChar
* pathname
, Int mode
, UWord dev
)
135 # if defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
136 /* ARM64 wants to use __NR_mknodat rather than __NR_mknod. */
137 SysRes res
= VG_(do_syscall4
)(__NR_mknodat
,
138 VKI_AT_FDCWD
, (UWord
)pathname
, mode
, dev
);
139 # elif defined(VGO_linux) || defined(VGO_darwin)
140 SysRes res
= VG_(do_syscall3
)(__NR_mknod
,
141 (UWord
)pathname
, mode
, dev
);
148 SysRes
VG_(open
) ( const HChar
* pathname
, Int flags
, Int mode
)
150 # if defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
151 /* ARM64 wants to use __NR_openat rather than __NR_open. */
152 SysRes res
= VG_(do_syscall4
)(__NR_openat
,
153 VKI_AT_FDCWD
, (UWord
)pathname
, flags
, mode
);
154 # elif defined(VGO_linux)
155 SysRes res
= VG_(do_syscall3
)(__NR_open
,
156 (UWord
)pathname
, flags
, mode
);
157 # elif defined(VGO_darwin)
158 SysRes res
= VG_(do_syscall3
)(__NR_open_nocancel
,
159 (UWord
)pathname
, flags
, mode
);
166 Int
VG_(fd_open
) (const HChar
* pathname
, Int flags
, Int mode
)
169 sr
= VG_(open
) (pathname
, flags
, mode
);
176 void VG_(close
) ( Int fd
)
178 /* Hmm. Return value is not checked. That's uncool. */
179 # if defined(VGO_linux)
180 (void)VG_(do_syscall1
)(__NR_close
, fd
);
181 # elif defined(VGO_darwin)
182 (void)VG_(do_syscall1
)(__NR_close_nocancel
, fd
);
188 Int
VG_(read
) ( Int fd
, void* buf
, Int count
)
191 # if defined(VGO_linux)
192 SysRes res
= VG_(do_syscall3
)(__NR_read
, fd
, (UWord
)buf
, count
);
193 # elif defined(VGO_darwin)
194 SysRes res
= VG_(do_syscall3
)(__NR_read_nocancel
, fd
, (UWord
)buf
, count
);
198 if (sr_isError(res
)) {
199 ret
= - (Int
)(Word
)sr_Err(res
);
202 ret
= (Int
)(Word
)sr_Res(res
);
208 Int
VG_(write
) ( Int fd
, const void* buf
, Int count
)
211 # if defined(VGO_linux)
212 SysRes res
= VG_(do_syscall3
)(__NR_write
, fd
, (UWord
)buf
, count
);
213 # elif defined(VGO_darwin)
214 SysRes res
= VG_(do_syscall3
)(__NR_write_nocancel
, fd
, (UWord
)buf
, count
);
218 if (sr_isError(res
)) {
219 ret
= - (Int
)(Word
)sr_Err(res
);
222 ret
= (Int
)(Word
)sr_Res(res
);
229 Int
VG_(pipe
) ( Int fd
[2] )
231 # if defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
232 /* __NR_pipe has a strange return convention on mips32-linux. */
233 SysRes res
= VG_(do_syscall1
)(__NR_pipe
, (UWord
)fd
);
234 if (!sr_isError(res
)) {
235 fd
[0] = (Int
)sr_Res(res
);
236 fd
[1] = (Int
)sr_ResEx(res
);
241 # elif defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
242 SysRes res
= VG_(do_syscall2
)(__NR_pipe2
, (UWord
)fd
, 0);
243 return sr_isError(res
) ? -1 : 0;
244 # elif defined(VGO_linux)
245 SysRes res
= VG_(do_syscall1
)(__NR_pipe
, (UWord
)fd
);
246 return sr_isError(res
) ? -1 : 0;
247 # elif defined(VGO_darwin)
248 /* __NR_pipe is UX64, so produces a double-word result */
249 SysRes res
= VG_(do_syscall0
)(__NR_pipe
);
250 if (!sr_isError(res
)) {
251 fd
[0] = (Int
)sr_Res(res
);
252 fd
[1] = (Int
)sr_ResHI(res
);
254 return sr_isError(res
) ? -1 : 0;
260 Off64T
VG_(lseek
) ( Int fd
, Off64T offset
, Int whence
)
262 # if defined(VGO_linux) || defined(VGP_amd64_darwin)
263 # if defined(__NR__llseek)
265 SysRes res
= VG_(do_syscall5
)(__NR__llseek
, fd
,
266 offset
>> 32, offset
& 0xffffffff,
267 (UWord
)&result
, whence
);
268 return sr_isError(res
) ? (-1) : result
;
270 SysRes res
= VG_(do_syscall3
)(__NR_lseek
, fd
, offset
, whence
);
271 vg_assert(sizeof(Off64T
) == sizeof(Word
));
272 return sr_isError(res
) ? (-1) : sr_Res(res
);
274 # elif defined(VGP_x86_darwin)
275 SysRes res
= VG_(do_syscall4
)(__NR_lseek
, fd
,
276 offset
& 0xffffffff, offset
>> 32, whence
);
277 return sr_isError(res
) ? (-1) : sr_Res(res
);
279 # error "Unknown plat"
281 /* if you change the error-reporting conventions of this, also
282 change all usage points. */
286 /* stat/fstat support. It's uggerly. We have impedance-match into a
287 'struct vg_stat' in order to have a single structure that callers
288 can use consistently on all platforms. */
290 #define TRANSLATE_TO_vg_stat(_p_vgstat, _p_vkistat) \
292 (_p_vgstat)->dev = (ULong)( (_p_vkistat)->st_dev ); \
293 (_p_vgstat)->ino = (ULong)( (_p_vkistat)->st_ino ); \
294 (_p_vgstat)->nlink = (ULong)( (_p_vkistat)->st_nlink ); \
295 (_p_vgstat)->mode = (UInt) ( (_p_vkistat)->st_mode ); \
296 (_p_vgstat)->uid = (UInt) ( (_p_vkistat)->st_uid ); \
297 (_p_vgstat)->gid = (UInt) ( (_p_vkistat)->st_gid ); \
298 (_p_vgstat)->rdev = (ULong)( (_p_vkistat)->st_rdev ); \
299 (_p_vgstat)->size = (Long) ( (_p_vkistat)->st_size ); \
300 (_p_vgstat)->blksize = (ULong)( (_p_vkistat)->st_blksize ); \
301 (_p_vgstat)->blocks = (ULong)( (_p_vkistat)->st_blocks ); \
302 (_p_vgstat)->atime = (ULong)( (_p_vkistat)->st_atime ); \
303 (_p_vgstat)->atime_nsec = (ULong)( (_p_vkistat)->st_atime_nsec ); \
304 (_p_vgstat)->mtime = (ULong)( (_p_vkistat)->st_mtime ); \
305 (_p_vgstat)->mtime_nsec = (ULong)( (_p_vkistat)->st_mtime_nsec ); \
306 (_p_vgstat)->ctime = (ULong)( (_p_vkistat)->st_ctime ); \
307 (_p_vgstat)->ctime_nsec = (ULong)( (_p_vkistat)->st_ctime_nsec ); \
310 SysRes
VG_(stat
) ( const HChar
* file_name
, struct vg_stat
* vgbuf
)
313 VG_(memset
)(vgbuf
, 0, sizeof(*vgbuf
));
315 # if defined(VGO_linux) || defined(VGO_darwin)
316 /* First try with stat64. If that doesn't work out, fall back to
317 the vanilla version. */
318 # if defined(__NR_stat64)
319 { struct vki_stat64 buf64
;
320 res
= VG_(do_syscall2
)(__NR_stat64
, (UWord
)file_name
, (UWord
)&buf64
);
321 if (!(sr_isError(res
) && sr_Err(res
) == VKI_ENOSYS
)) {
322 /* Success, or any failure except ENOSYS */
323 if (!sr_isError(res
))
324 TRANSLATE_TO_vg_stat(vgbuf
, &buf64
);
328 # endif /* defined(__NR_stat64) */
329 /* This is the fallback ("vanilla version"). */
330 { struct vki_stat buf
;
331 # if defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
332 res
= VG_(do_syscall3
)(__NR3264_fstatat
, VKI_AT_FDCWD
,
333 (UWord
)file_name
, (UWord
)&buf
);
335 res
= VG_(do_syscall2
)(__NR_stat
, (UWord
)file_name
, (UWord
)&buf
);
337 if (!sr_isError(res
))
338 TRANSLATE_TO_vg_stat(vgbuf
, &buf
);
347 Int
VG_(fstat
) ( Int fd
, struct vg_stat
* vgbuf
)
350 VG_(memset
)(vgbuf
, 0, sizeof(*vgbuf
));
352 # if defined(VGO_linux) || defined(VGO_darwin)
353 /* First try with fstat64. If that doesn't work out, fall back to
354 the vanilla version. */
355 # if defined(__NR_fstat64)
356 { struct vki_stat64 buf64
;
357 res
= VG_(do_syscall2
)(__NR_fstat64
, (UWord
)fd
, (UWord
)&buf64
);
358 if (!(sr_isError(res
) && sr_Err(res
) == VKI_ENOSYS
)) {
359 /* Success, or any failure except ENOSYS */
360 if (!sr_isError(res
))
361 TRANSLATE_TO_vg_stat(vgbuf
, &buf64
);
362 return sr_isError(res
) ? (-1) : 0;
365 # endif /* if defined(__NR_fstat64) */
366 { struct vki_stat buf
;
367 res
= VG_(do_syscall2
)(__NR_fstat
, (UWord
)fd
, (UWord
)&buf
);
368 if (!sr_isError(res
))
369 TRANSLATE_TO_vg_stat(vgbuf
, &buf
);
370 return sr_isError(res
) ? (-1) : 0;
378 #undef TRANSLATE_TO_vg_stat
381 Long
VG_(fsize
) ( Int fd
)
384 Int res
= VG_(fstat
)( fd
, &buf
);
385 return (res
== -1) ? (-1LL) : buf
.size
;
388 SysRes
VG_(getxattr
) ( const HChar
* file_name
, const HChar
* attr_name
, Addr attr_value
, SizeT attr_value_len
)
391 #if defined(VGO_linux)
392 res
= VG_(do_syscall4
)(__NR_getxattr
, (UWord
)file_name
, (UWord
)attr_name
,
393 attr_value
, attr_value_len
);
395 res
= VG_(mk_SysRes_Error
)(VKI_ENOSYS
);
400 Bool
VG_(is_dir
) ( const HChar
* f
)
403 SysRes res
= VG_(stat
)(f
, &buf
);
404 return sr_isError(res
) ? False
405 : VKI_S_ISDIR(buf
.mode
) ? True
: False
;
408 SysRes
VG_(dup
) ( Int oldfd
)
410 return VG_(do_syscall1
)(__NR_dup
, oldfd
);
413 SysRes
VG_(dup2
) ( Int oldfd
, Int newfd
)
415 # if defined(VGO_linux) || defined(VGO_darwin)
416 return VG_(do_syscall2
)(__NR_dup2
, oldfd
, newfd
);
422 /* Returns -1 on error. */
423 Int
VG_(fcntl
) ( Int fd
, Int cmd
, Addr arg
)
425 # if defined(VGO_linux)
426 SysRes res
= VG_(do_syscall3
)(__NR_fcntl
, fd
, cmd
, arg
);
427 # elif defined(VGO_darwin)
428 SysRes res
= VG_(do_syscall3
)(__NR_fcntl_nocancel
, fd
, cmd
, arg
);
432 return sr_isError(res
) ? -1 : sr_Res(res
);
435 Int
VG_(rename
) ( const HChar
* old_name
, const HChar
* new_name
)
437 # if defined(VGP_tilegx_linux)
438 SysRes res
= VG_(do_syscall3
)(__NR_renameat
, VKI_AT_FDCWD
,
439 (UWord
)old_name
, (UWord
)new_name
);
441 SysRes res
= VG_(do_syscall2
)(__NR_rename
, (UWord
)old_name
, (UWord
)new_name
);
443 return sr_isError(res
) ? (-1) : 0;
446 Int
VG_(unlink
) ( const HChar
* file_name
)
448 # if defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
449 SysRes res
= VG_(do_syscall2
)(__NR_unlinkat
, VKI_AT_FDCWD
,
452 SysRes res
= VG_(do_syscall1
)(__NR_unlink
, (UWord
)file_name
);
454 return sr_isError(res
) ? (-1) : 0;
457 /* The working directory at startup.
458 All that is really needed is to note the cwd at process startup.
459 Hence VG_(record_startup_wd) notes it (in a platform dependent way)
460 and VG_(get_startup_wd) produces the noted value. */
461 static HChar
*startup_wd
;
462 static Bool startup_wd_acquired
= False
;
464 /* Record the process' working directory at startup. Is intended to
465 be called exactly once, at startup, before the working directory
466 changes. Return True for success, False for failure, so that the
467 caller can bomb out suitably without creating module cycles if
468 there is a problem. */
469 Bool
VG_(record_startup_wd
) ( void )
471 vg_assert(!startup_wd_acquired
);
473 # if defined(VGO_linux)
474 /* Simple: just ask the kernel */
479 startup_wd
= VG_(realloc
)("startup_wd", startup_wd
, szB
);
480 VG_(memset
)(startup_wd
, 0, szB
);
481 res
= VG_(do_syscall2
)(__NR_getcwd
, (UWord
)startup_wd
, szB
-1);
482 } while (sr_isError(res
));
484 vg_assert(startup_wd
[szB
-1] == 0);
485 startup_wd_acquired
= True
;
488 # elif defined(VGO_darwin)
489 /* We can't ask the kernel, so instead rely on launcher-*.c to
490 tell us the startup path. Note the env var is keyed to the
491 parent's PID, not ours, since our parent is the launcher
493 { HChar envvar
[100]; // large enough
495 VG_(memset
)(envvar
, 0, sizeof(envvar
));
496 VG_(sprintf
)(envvar
, "VALGRIND_STARTUP_PWD_%d_XYZZY",
497 (Int
)VG_(getppid
)());
498 wd
= VG_(getenv
)( envvar
);
501 SizeT need
= VG_(strlen
)(wd
) + 1;
502 startup_wd
= VG_(malloc
)("startup_wd", need
);
503 VG_(strcpy
)(startup_wd
, wd
);
504 startup_wd_acquired
= True
;
512 /* Return the previously acquired startup_wd. */
513 const HChar
*VG_(get_startup_wd
) ( void )
515 vg_assert(startup_wd_acquired
);
520 SysRes
VG_(poll
) (struct vki_pollfd
*fds
, Int nfds
, Int timeout
)
523 # if defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
524 /* ARM64 wants to use __NR_ppoll rather than __NR_poll. */
525 struct vki_timespec timeout_ts
;
527 timeout_ts
.tv_sec
= timeout
/ 1000;
528 timeout_ts
.tv_nsec
= ((long)timeout
% 1000) * 1000000;
530 res
= VG_(do_syscall4
)(__NR_ppoll
,
532 (UWord
)(timeout
>= 0 ? &timeout_ts
: NULL
),
534 # elif defined(VGO_linux)
535 res
= VG_(do_syscall3
)(__NR_poll
, (UWord
)fds
, nfds
, timeout
);
536 # elif defined(VGO_darwin)
537 res
= VG_(do_syscall3
)(__NR_poll_nocancel
, (UWord
)fds
, nfds
, timeout
);
545 /* Performs the readlink operation and puts the result into 'buf'.
546 Note, that the string in 'buf' is *not* null-terminated. The function
547 returns the number of characters put into 'buf' or -1 if an error
549 SSizeT
VG_(readlink
) (const HChar
* path
, HChar
* buf
, SizeT bufsiz
)
552 /* res = readlink( path, buf, bufsiz ); */
553 # if defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
554 res
= VG_(do_syscall4
)(__NR_readlinkat
, VKI_AT_FDCWD
,
555 (UWord
)path
, (UWord
)buf
, bufsiz
);
557 res
= VG_(do_syscall3
)(__NR_readlink
, (UWord
)path
, (UWord
)buf
, bufsiz
);
559 return sr_isError(res
) ? -1 : sr_Res(res
);
562 #if defined(VGO_linux)
563 Int
VG_(getdents64
) (Int fd
, struct vki_dirent64
*dirp
, UInt count
)
566 /* res = getdents( fd, dirp, count ); */
567 res
= VG_(do_syscall3
)(__NR_getdents64
, fd
, (UWord
)dirp
, count
);
568 return sr_isError(res
) ? -1 : sr_Res(res
);
572 /* Check accessibility of a file. Returns zero for access granted,
573 nonzero otherwise. */
574 Int
VG_(access
) ( const HChar
* path
, Bool irusr
, Bool iwusr
, Bool ixusr
)
576 # if defined(VGO_linux)
577 /* Very annoyingly, I cannot find any definition for R_OK et al in
578 the kernel interfaces. Therefore I reluctantly resort to
579 hardwiring in these magic numbers that I determined by
586 UWord w
= (irusr
? VKI_R_OK
: 0)
587 | (iwusr
? VKI_W_OK
: 0)
588 | (ixusr
? VKI_X_OK
: 0);
589 # if defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
590 SysRes res
= VG_(do_syscall3
)(__NR_faccessat
, VKI_AT_FDCWD
, (UWord
)path
, w
);
592 SysRes res
= VG_(do_syscall2
)(__NR_access
, (UWord
)path
, w
);
594 return sr_isError(res
) ? 1 : 0;
596 # if defined(VGO_linux)
604 Emulate the normal Unix permissions checking algorithm.
606 If owner matches, then use the owner permissions, else
607 if group matches, then use the group permissions, else
608 use other permissions.
610 Note that we can't deal properly with SUID/SGID. By default
611 (allow_setuid == False), we refuse to run them (otherwise the
612 executable may misbehave if it doesn't have the permissions it
613 thinks it does). However, the caller may indicate that setuid
614 executables are allowed, for example if we are going to exec them
615 but not trace into them (iow, client sys_execve when
616 clo_trace_children == False).
618 If VKI_EACCES is returned (iow, permission was refused), then
619 *is_setuid is set to True iff permission was refused because the
620 executable is setuid.
622 /* returns: 0 = success, non-0 is failure */
623 Int
VG_(check_executable
)(/*OUT*/Bool
* is_setuid
,
624 const HChar
* f
, Bool allow_setuid
)
627 SysRes res
= VG_(stat
)(f
, &st
);
632 if (sr_isError(res
)) {
636 if ( VKI_S_ISDIR (st
.mode
) ) {
640 if ( (st
.mode
& (VKI_S_ISUID
| VKI_S_ISGID
)) && !allow_setuid
) {
646 res
= VG_(getxattr
)(f
, "security.capability", (Addr
)0, 0);
647 if (!sr_isError(res
) && !allow_setuid
) {
653 if (VG_(geteuid
)() == st
.uid
) {
654 if (!(st
.mode
& VKI_S_IXUSR
))
659 if (VG_(getegid
)() == st
.gid
)
665 /* Find out # groups, allocate large enough array and fetch groups */
666 ngrp
= VG_(getgroups
)(0, NULL
);
668 groups
= VG_(malloc
)("check_executable", ngrp
* sizeof *groups
);
669 ngrp
= VG_(getgroups
)(ngrp
, groups
);
673 /* ngrp will be -1 if VG_(getgroups) failed. */
674 for (i
= 0; i
< ngrp
; i
++) {
675 if (groups
[i
] == st
.gid
) {
684 if (!(st
.mode
& VKI_S_IXGRP
)) {
687 } else if (!(st
.mode
& VKI_S_IXOTH
)) {
695 SysRes
VG_(pread
) ( Int fd
, void* buf
, Int count
, OffT offset
)
698 // on 32 bits platforms, we receive a 32 bits OffT but
699 // we must extend it to pass a long long 64 bits.
700 # if defined(VGP_x86_linux)
701 vg_assert(sizeof(OffT
) == 4);
702 res
= VG_(do_syscall5
)(__NR_pread64
, fd
, (UWord
)buf
, count
,
703 offset
, 0); // Little endian long long
705 # elif defined(VGP_arm_linux)
706 vg_assert(sizeof(OffT
) == 4);
707 res
= VG_(do_syscall5
)(__NR_pread64
, fd
, (UWord
)buf
, count
,
708 0, offset
); // Big endian long long
710 # elif defined(VGP_ppc32_linux)
711 vg_assert(sizeof(OffT
) == 4);
712 res
= VG_(do_syscall6
)(__NR_pread64
, fd
, (UWord
)buf
, count
,
713 0, // Padding needed on PPC32
714 0, offset
); // Big endian long long
716 # elif defined(VGP_mips32_linux) && (VKI_LITTLE_ENDIAN)
717 vg_assert(sizeof(OffT
) == 4);
718 res
= VG_(do_syscall6
)(__NR_pread64
, fd
, (UWord
)buf
, count
,
721 # elif defined(VGP_mips32_linux) && (VKI_BIG_ENDIAN)
722 vg_assert(sizeof(OffT
) == 4);
723 res
= VG_(do_syscall6
)(__NR_pread64
, fd
, (UWord
)buf
, count
,
726 # elif defined(VGP_amd64_linux) || defined(VGP_s390x_linux) \
727 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
728 || defined(VGP_mips64_linux) \
729 || defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
730 res
= VG_(do_syscall4
)(__NR_pread64
, fd
, (UWord
)buf
, count
, offset
);
732 # elif defined(VGP_amd64_darwin)
733 vg_assert(sizeof(OffT
) == 8);
734 res
= VG_(do_syscall4
)(__NR_pread_nocancel
, fd
, (UWord
)buf
, count
, offset
);
736 # elif defined(VGP_x86_darwin)
737 vg_assert(sizeof(OffT
) == 8);
738 res
= VG_(do_syscall5
)(__NR_pread_nocancel
, fd
, (UWord
)buf
, count
,
739 offset
& 0xffffffff, offset
>> 32);
742 # error "Unknown platform"
746 /* Return the name of a directory for temporary files. */
747 const HChar
*VG_(tmpdir
)(void)
751 tmpdir
= VG_(getenv
)("TMPDIR");
752 if (tmpdir
== NULL
|| *tmpdir
== '\0') tmpdir
= VG_TMPDIR
;
753 if (tmpdir
== NULL
|| *tmpdir
== '\0') tmpdir
= "/tmp"; /* fallback */
758 static const HChar mkstemp_format
[] = "%s/valgrind_%s_%08x";
760 SizeT
VG_(mkstemp_fullname_bufsz
) ( SizeT part_of_name_len
)
762 return VG_(strlen
)(mkstemp_format
)
763 + VG_(strlen
)(VG_(tmpdir
)()) - 2 // %s tmpdir
764 + part_of_name_len
- 2 // %s part_of_name
770 Int
VG_(mkstemp
) ( const HChar
* part_of_name
, /*OUT*/HChar
* fullname
)
777 vg_assert(part_of_name
);
779 n
= VG_(strlen
)(part_of_name
);
780 vg_assert(n
> 0 && n
< 100);
782 seed
= (VG_(getpid
)() << 9) ^ VG_(getppid
)();
784 /* Determine sensible location for temporary files */
785 tmpdir
= VG_(tmpdir
)();
791 VG_(sprintf
)( fullname
, mkstemp_format
,
792 tmpdir
, part_of_name
, VG_(random
)( &seed
));
794 VG_(printf
)("VG_(mkstemp): trying: %s\n", fullname
);
796 sres
= VG_(open
)(fullname
,
797 VKI_O_CREAT
|VKI_O_RDWR
|VKI_O_EXCL
|VKI_O_TRUNC
,
798 VKI_S_IRUSR
|VKI_S_IWUSR
);
799 if (sr_isError(sres
)) {
800 VG_(umsg
)("VG_(mkstemp): failed to create temp file: %s\n", fullname
);
803 /* VG_(safe_fd) doesn't return if it fails. */
804 return VG_(safe_fd
)( sr_Res(sres
) );
810 /* ---------------------------------------------------------------------
811 Socket-related stuff.
812 ------------------------------------------------------------------ */
815 Int
parse_inet_addr_and_port ( const HChar
* str
, UInt
* ip_addr
, UShort
* port
);
818 Int
my_connect ( Int sockfd
, struct vki_sockaddr_in
* serv_addr
, Int addrlen
);
820 UInt
VG_(htonl
) ( UInt x
)
822 # if defined(VG_BIGENDIAN)
826 (((x
>> 24) & 0xFF) << 0) | (((x
>> 16) & 0xFF) << 8)
827 | (((x
>> 8) & 0xFF) << 16) | (((x
>> 0) & 0xFF) << 24);
831 UInt
VG_(ntohl
) ( UInt x
)
833 # if defined(VG_BIGENDIAN)
837 (((x
>> 24) & 0xFF) << 0) | (((x
>> 16) & 0xFF) << 8)
838 | (((x
>> 8) & 0xFF) << 16) | (((x
>> 0) & 0xFF) << 24);
842 UShort
VG_(htons
) ( UShort x
)
844 # if defined(VG_BIGENDIAN)
848 (((x
>> 8) & 0xFF) << 0) | (((x
>> 0) & 0xFF) << 8);
852 UShort
VG_(ntohs
) ( UShort x
)
854 # if defined(VG_BIGENDIAN)
858 (((x
>> 8) & 0xFF) << 0) | (((x
>> 0) & 0xFF) << 8);
863 /* The main function.
865 Supplied string contains either an ip address "192.168.0.1" or
866 an ip address and port pair, "192.168.0.1:1500". Parse these,
868 -1 if there is a parse error
869 -2 if no parse error, but specified host:port cannot be opened
870 the relevant file (socket) descriptor, otherwise.
873 Int
VG_(connect_via_socket
)( const HChar
* str
)
875 # if defined(VGO_linux) || defined(VGO_darwin)
877 struct vki_sockaddr_in servAddr
;
879 UShort port
= VG_CLO_DEFAULT_LOGPORT
;
880 Bool ok
= parse_inet_addr_and_port(str
, &ip
, &port
);
885 // VG_(printf)("ip = %d.%d.%d.%d, port %d\n",
886 // (ip >> 24) & 0xFF, (ip >> 16) & 0xFF,
887 // (ip >> 8) & 0xFF, ip & 0xFF,
890 servAddr
.sin_family
= VKI_AF_INET
;
891 servAddr
.sin_addr
.s_addr
= VG_(htonl
)(ip
);
892 servAddr
.sin_port
= VG_(htons
)(port
);
895 sd
= VG_(socket
)(VKI_AF_INET
, VKI_SOCK_STREAM
, 0 /* IPPROTO_IP ? */);
897 /* this shouldn't happen ... nevertheless */
901 /* connect to server */
902 res
= my_connect(sd
, &servAddr
, sizeof(servAddr
));
904 /* connection failed */
916 /* Let d = one or more digits. Accept either:
919 static Int
parse_inet_addr_and_port ( const HChar
* str
, UInt
* ip_addr
, UShort
* port
)
921 # define GET_CH ((*str) ? (*str++) : 0)
922 UInt ipa
, i
, j
, c
, any
;
924 for (i
= 0; i
< 4; i
++) {
929 if (c
< '0' || c
> '9') break;
930 j
= 10 * j
+ (int)(c
- '0');
933 if (any
== 0 || j
> 255) goto syntaxerr
;
934 ipa
= (ipa
<< 8) + j
;
935 if (i
<= 2 && c
!= '.') goto syntaxerr
;
937 if (c
== 0 || c
== ':')
940 if (c
!= ':') goto syntaxerr
;
945 if (c
< '0' || c
> '9') break;
946 j
= j
* 10 + (int)(c
- '0');
948 if (j
> 65535) goto syntaxerr
;
950 if (any
== 0 || c
!= 0) goto syntaxerr
;
951 if (j
< 1024) goto syntaxerr
;
960 // GrP fixme safe_fd?
961 Int
VG_(socket
) ( Int domain
, Int type
, Int protocol
)
963 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
964 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
965 || defined(VGP_s390x_linux)
971 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_SOCKET
, (UWord
)&args
);
972 return sr_isError(res
) ? -1 : sr_Res(res
);
974 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
975 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
976 || defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
978 res
= VG_(do_syscall3
)(__NR_socket
, domain
, type
, protocol
);
979 return sr_isError(res
) ? -1 : sr_Res(res
);
981 # elif defined(VGO_darwin)
983 res
= VG_(do_syscall3
)(__NR_socket
, domain
, type
, protocol
);
984 if (!sr_isError(res
)) {
985 // Set SO_NOSIGPIPE so write() returns EPIPE instead of raising SIGPIPE
988 res2
= VG_(do_syscall5
)(__NR_setsockopt
, sr_Res(res
), VKI_SOL_SOCKET
,
989 VKI_SO_NOSIGPIPE
, (UWord
)&optval
,
991 // ignore setsockopt() error
993 return sr_isError(res
) ? -1 : sr_Res(res
);
996 # error "Unknown arch"
1002 Int
my_connect ( Int sockfd
, struct vki_sockaddr_in
* serv_addr
, Int addrlen
)
1004 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1005 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1006 || defined(VGP_s390x_linux)
1010 args
[1] = (UWord
)serv_addr
;
1012 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_CONNECT
, (UWord
)&args
);
1013 return sr_isError(res
) ? -1 : sr_Res(res
);
1015 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1016 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
1017 || defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
1019 res
= VG_(do_syscall3
)(__NR_connect
, sockfd
, (UWord
)serv_addr
, addrlen
);
1020 return sr_isError(res
) ? -1 : sr_Res(res
);
1022 # elif defined(VGO_darwin)
1024 res
= VG_(do_syscall3
)(__NR_connect_nocancel
,
1025 sockfd
, (UWord
)serv_addr
, addrlen
);
1026 return sr_isError(res
) ? -1 : sr_Res(res
);
1029 # error "Unknown arch"
1033 Int
VG_(write_socket
)( Int sd
, const void *msg
, Int count
)
1035 /* This is actually send(). */
1037 /* For Linux, VKI_MSG_NOSIGNAL is a request not to send SIGPIPE on
1038 errors on stream oriented sockets when the other end breaks the
1039 connection. The EPIPE error is still returned.
1041 For Darwin, VG_(socket)() sets SO_NOSIGPIPE to get EPIPE instead of
1044 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1045 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1046 || defined(VGP_s390x_linux)
1050 args
[1] = (UWord
)msg
;
1052 args
[3] = VKI_MSG_NOSIGNAL
;
1053 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_SEND
, (UWord
)&args
);
1054 return sr_isError(res
) ? -1 : sr_Res(res
);
1056 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1057 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
1058 || defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
1060 res
= VG_(do_syscall6
)(__NR_sendto
, sd
, (UWord
)msg
,
1061 count
, VKI_MSG_NOSIGNAL
, 0,0);
1062 return sr_isError(res
) ? -1 : sr_Res(res
);
1064 # elif defined(VGP_x86_darwin) || defined(VGP_amd64_darwin)
1066 res
= VG_(do_syscall3
)(__NR_write_nocancel
, sd
, (UWord
)msg
, count
);
1067 return sr_isError(res
) ? -1 : sr_Res(res
);
1070 # error "Unknown platform"
1074 Int
VG_(getsockname
) ( Int sd
, struct vki_sockaddr
*name
, Int
*namelen
)
1076 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1077 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1078 || defined(VGP_s390x_linux) \
1079 || defined(VGP_mips32_linux)
1083 args
[1] = (UWord
)name
;
1084 args
[2] = (UWord
)namelen
;
1085 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_GETSOCKNAME
, (UWord
)&args
);
1086 return sr_isError(res
) ? -1 : sr_Res(res
);
1088 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1089 || defined(VGP_mips64_linux) || defined(VGP_arm64_linux) \
1090 || defined(VGP_tilegx_linux)
1092 res
= VG_(do_syscall3
)( __NR_getsockname
,
1093 (UWord
)sd
, (UWord
)name
, (UWord
)namelen
);
1094 return sr_isError(res
) ? -1 : sr_Res(res
);
1096 # elif defined(VGO_darwin)
1098 res
= VG_(do_syscall3
)( __NR_getsockname
,
1099 (UWord
)sd
, (UWord
)name
, (UWord
)namelen
);
1100 return sr_isError(res
) ? -1 : sr_Res(res
);
1103 # error "Unknown platform"
1107 Int
VG_(getpeername
) ( Int sd
, struct vki_sockaddr
*name
, Int
*namelen
)
1109 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1110 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1111 || defined(VGP_s390x_linux) \
1112 || defined(VGP_mips32_linux)
1116 args
[1] = (UWord
)name
;
1117 args
[2] = (UWord
)namelen
;
1118 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_GETPEERNAME
, (UWord
)&args
);
1119 return sr_isError(res
) ? -1 : sr_Res(res
);
1121 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1122 || defined(VGP_mips64_linux) || defined(VGP_arm64_linux) \
1123 || defined(VGP_tilegx_linux)
1125 res
= VG_(do_syscall3
)( __NR_getpeername
,
1126 (UWord
)sd
, (UWord
)name
, (UWord
)namelen
);
1127 return sr_isError(res
) ? -1 : sr_Res(res
);
1129 # elif defined(VGO_darwin)
1131 res
= VG_(do_syscall3
)( __NR_getpeername
,
1132 (UWord
)sd
, (UWord
)name
, (UWord
)namelen
);
1133 return sr_isError(res
) ? -1 : sr_Res(res
);
1136 # error "Unknown platform"
1140 Int
VG_(getsockopt
) ( Int sd
, Int level
, Int optname
, void *optval
,
1143 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1144 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1145 || defined(VGP_s390x_linux)
1151 args
[3] = (UWord
)optval
;
1152 args
[4] = (UWord
)optlen
;
1153 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_GETSOCKOPT
, (UWord
)&args
);
1154 return sr_isError(res
) ? -1 : sr_Res(res
);
1156 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1157 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
1158 || defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
1160 res
= VG_(do_syscall5
)( __NR_getsockopt
,
1161 (UWord
)sd
, (UWord
)level
, (UWord
)optname
,
1162 (UWord
)optval
, (UWord
)optlen
);
1163 return sr_isError(res
) ? -1 : sr_Res(res
);
1165 # elif defined(VGO_darwin)
1167 res
= VG_(do_syscall5
)( __NR_getsockopt
,
1168 (UWord
)sd
, (UWord
)level
, (UWord
)optname
,
1169 (UWord
)optval
, (UWord
)optlen
);
1170 return sr_isError(res
) ? -1 : sr_Res(res
);
1173 # error "Unknown platform"
1178 Int
VG_(setsockopt
) ( Int sd
, Int level
, Int optname
, void *optval
,
1181 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1182 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1183 || defined(VGP_s390x_linux)
1189 args
[3] = (UWord
)optval
;
1190 args
[4] = (UWord
)optlen
;
1191 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_SETSOCKOPT
, (UWord
)&args
);
1192 return sr_isError(res
) ? -1 : sr_Res(res
);
1194 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1195 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
1196 || defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
1198 res
= VG_(do_syscall5
)( __NR_setsockopt
,
1199 (UWord
)sd
, (UWord
)level
, (UWord
)optname
,
1200 (UWord
)optval
, (UWord
)optlen
);
1201 return sr_isError(res
) ? -1 : sr_Res(res
);
1203 # elif defined(VGO_darwin)
1205 res
= VG_(do_syscall5
)( __NR_setsockopt
,
1206 (UWord
)sd
, (UWord
)level
, (UWord
)optname
,
1207 (UWord
)optval
, (UWord
)optlen
);
1208 return sr_isError(res
) ? -1 : sr_Res(res
);
1211 # error "Unknown platform"
1216 const HChar
*VG_(basename
)(const HChar
*path
)
1218 static HChar
*buf
= NULL
;
1219 static SizeT buf_len
= 0;
1220 const HChar
*p
, *end
;
1223 0 == VG_(strcmp
)(path
, ""))
1228 p
= path
+ VG_(strlen
)(path
);
1229 while (p
> path
&& *p
== '/') {
1230 // skip all trailing '/'
1234 if (p
== path
&& *p
== '/') return "/"; // all slashes
1238 while (p
> path
&& *p
!= '/') {
1245 SizeT need
= end
-p
+1 + 1;
1246 if (need
> buf_len
) {
1247 buf_len
= (buf_len
== 0) ? 500 : need
;
1248 buf
= VG_(realloc
)("basename", buf
, buf_len
);
1250 VG_(strncpy
)(buf
, p
, end
-p
+1);
1251 buf
[end
-p
+1] = '\0';
1257 const HChar
*VG_(dirname
)(const HChar
*path
)
1259 static HChar
*buf
= NULL
;
1260 static SizeT buf_len
= 0;
1265 0 == VG_(strcmp
)(path
, "") ||
1266 0 == VG_(strcmp
)(path
, "/"))
1271 p
= path
+ VG_(strlen
)(path
);
1272 while (p
> path
&& *p
== '/') {
1273 // skip all trailing '/'
1277 while (p
> path
&& *p
!= '/') {
1283 if (*p
== '/') return "/"; // all slashes
1284 else return "."; // no slashes
1287 while (p
> path
&& *p
== '/') {
1292 SizeT need
= p
-path
+1 + 1;
1293 if (need
> buf_len
) {
1294 buf_len
= (buf_len
== 0) ? 500 : need
;
1295 buf
= VG_(realloc
)("dirname", buf
, buf_len
);
1297 VG_(strncpy
)(buf
, path
, p
-path
+1);
1298 buf
[p
-path
+1] = '\0';
1304 /*--------------------------------------------------------------------*/
1306 /*--------------------------------------------------------------------*/