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)
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)
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)
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)
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 SysRes res
= VG_(do_syscall2
)(__NR_rename
, (UWord
)old_name
, (UWord
)new_name
);
438 return sr_isError(res
) ? (-1) : 0;
441 Int
VG_(unlink
) ( const HChar
* file_name
)
443 # if defined(VGP_arm64_linux)
444 SysRes res
= VG_(do_syscall2
)(__NR_unlinkat
, VKI_AT_FDCWD
,
447 SysRes res
= VG_(do_syscall1
)(__NR_unlink
, (UWord
)file_name
);
449 return sr_isError(res
) ? (-1) : 0;
452 /* The working directory at startup.
453 All that is really needed is to note the cwd at process startup.
454 Hence VG_(record_startup_wd) notes it (in a platform dependent way)
455 and VG_(get_startup_wd) produces the noted value. */
456 static HChar
*startup_wd
;
457 static Bool startup_wd_acquired
= False
;
459 /* Record the process' working directory at startup. Is intended to
460 be called exactly once, at startup, before the working directory
461 changes. Return True for success, False for failure, so that the
462 caller can bomb out suitably without creating module cycles if
463 there is a problem. */
464 Bool
VG_(record_startup_wd
) ( void )
466 vg_assert(!startup_wd_acquired
);
468 # if defined(VGO_linux)
469 /* Simple: just ask the kernel */
474 startup_wd
= VG_(realloc
)("startup_wd", startup_wd
, szB
);
475 VG_(memset
)(startup_wd
, 0, szB
);
476 res
= VG_(do_syscall2
)(__NR_getcwd
, (UWord
)startup_wd
, szB
-1);
477 } while (sr_isError(res
));
479 vg_assert(startup_wd
[szB
-1] == 0);
480 startup_wd_acquired
= True
;
483 # elif defined(VGO_darwin)
484 /* We can't ask the kernel, so instead rely on launcher-*.c to
485 tell us the startup path. Note the env var is keyed to the
486 parent's PID, not ours, since our parent is the launcher
488 { HChar envvar
[100]; // large enough
490 VG_(memset
)(envvar
, 0, sizeof(envvar
));
491 VG_(sprintf
)(envvar
, "VALGRIND_STARTUP_PWD_%d_XYZZY",
492 (Int
)VG_(getppid
)());
493 wd
= VG_(getenv
)( envvar
);
496 SizeT need
= VG_(strlen
)(wd
) + 1;
497 startup_wd
= VG_(malloc
)("startup_wd", need
);
498 VG_(strcpy
)(startup_wd
, wd
);
499 startup_wd_acquired
= True
;
507 /* Return the previously acquired startup_wd. */
508 const HChar
*VG_(get_startup_wd
) ( void )
510 vg_assert(startup_wd_acquired
);
515 SysRes
VG_(poll
) (struct vki_pollfd
*fds
, Int nfds
, Int timeout
)
518 # if defined(VGP_arm64_linux)
519 /* ARM64 wants to use __NR_ppoll rather than __NR_poll. */
520 struct vki_timespec timeout_ts
;
522 timeout_ts
.tv_sec
= timeout
/ 1000;
523 timeout_ts
.tv_nsec
= ((long)timeout
% 1000) * 1000000;
525 res
= VG_(do_syscall4
)(__NR_ppoll
,
527 (UWord
)(timeout
>= 0 ? &timeout_ts
: NULL
),
529 # elif defined(VGO_linux)
530 res
= VG_(do_syscall3
)(__NR_poll
, (UWord
)fds
, nfds
, timeout
);
531 # elif defined(VGO_darwin)
532 res
= VG_(do_syscall3
)(__NR_poll_nocancel
, (UWord
)fds
, nfds
, timeout
);
540 /* Performs the readlink operation and puts the result into 'buf'.
541 Note, that the string in 'buf' is *not* null-terminated. The function
542 returns the number of characters put into 'buf' or -1 if an error
544 SSizeT
VG_(readlink
) (const HChar
* path
, HChar
* buf
, SizeT bufsiz
)
547 /* res = readlink( path, buf, bufsiz ); */
548 # if defined(VGP_arm64_linux)
549 res
= VG_(do_syscall4
)(__NR_readlinkat
, VKI_AT_FDCWD
,
550 (UWord
)path
, (UWord
)buf
, bufsiz
);
552 res
= VG_(do_syscall3
)(__NR_readlink
, (UWord
)path
, (UWord
)buf
, bufsiz
);
554 return sr_isError(res
) ? -1 : sr_Res(res
);
557 #if defined(VGO_linux)
558 Int
VG_(getdents64
) (Int fd
, struct vki_dirent64
*dirp
, UInt count
)
561 /* res = getdents( fd, dirp, count ); */
562 res
= VG_(do_syscall3
)(__NR_getdents64
, fd
, (UWord
)dirp
, count
);
563 return sr_isError(res
) ? -1 : sr_Res(res
);
567 /* Check accessibility of a file. Returns zero for access granted,
568 nonzero otherwise. */
569 Int
VG_(access
) ( const HChar
* path
, Bool irusr
, Bool iwusr
, Bool ixusr
)
571 # if defined(VGO_linux)
572 /* Very annoyingly, I cannot find any definition for R_OK et al in
573 the kernel interfaces. Therefore I reluctantly resort to
574 hardwiring in these magic numbers that I determined by
581 UWord w
= (irusr
? VKI_R_OK
: 0)
582 | (iwusr
? VKI_W_OK
: 0)
583 | (ixusr
? VKI_X_OK
: 0);
584 # if defined(VGP_arm64_linux)
585 SysRes res
= VG_(do_syscall3
)(__NR_faccessat
, VKI_AT_FDCWD
, (UWord
)path
, w
);
587 SysRes res
= VG_(do_syscall2
)(__NR_access
, (UWord
)path
, w
);
589 return sr_isError(res
) ? 1 : 0;
591 # if defined(VGO_linux)
599 Emulate the normal Unix permissions checking algorithm.
601 If owner matches, then use the owner permissions, else
602 if group matches, then use the group permissions, else
603 use other permissions.
605 Note that we can't deal properly with SUID/SGID. By default
606 (allow_setuid == False), we refuse to run them (otherwise the
607 executable may misbehave if it doesn't have the permissions it
608 thinks it does). However, the caller may indicate that setuid
609 executables are allowed, for example if we are going to exec them
610 but not trace into them (iow, client sys_execve when
611 clo_trace_children == False).
613 If VKI_EACCES is returned (iow, permission was refused), then
614 *is_setuid is set to True iff permission was refused because the
615 executable is setuid.
617 /* returns: 0 = success, non-0 is failure */
618 Int
VG_(check_executable
)(/*OUT*/Bool
* is_setuid
,
619 const HChar
* f
, Bool allow_setuid
)
622 SysRes res
= VG_(stat
)(f
, &st
);
627 if (sr_isError(res
)) {
631 if ( (st
.mode
& (VKI_S_ISUID
| VKI_S_ISGID
)) && !allow_setuid
) {
637 res
= VG_(getxattr
)(f
, "security.capability", (Addr
)0, 0);
638 if (!sr_isError(res
) && !allow_setuid
) {
644 if (VG_(geteuid
)() == st
.uid
) {
645 if (!(st
.mode
& VKI_S_IXUSR
))
650 if (VG_(getegid
)() == st
.gid
)
656 /* Find out # groups, allocate large enough array and fetch groups */
657 ngrp
= VG_(getgroups
)(0, NULL
);
659 groups
= VG_(malloc
)("check_executable", ngrp
* sizeof *groups
);
660 ngrp
= VG_(getgroups
)(ngrp
, groups
);
664 /* ngrp will be -1 if VG_(getgroups) failed. */
665 for (i
= 0; i
< ngrp
; i
++) {
666 if (groups
[i
] == st
.gid
) {
675 if (!(st
.mode
& VKI_S_IXGRP
)) {
678 } else if (!(st
.mode
& VKI_S_IXOTH
)) {
686 SysRes
VG_(pread
) ( Int fd
, void* buf
, Int count
, OffT offset
)
689 // on 32 bits platforms, we receive a 32 bits OffT but
690 // we must extend it to pass a long long 64 bits.
691 # if defined(VGP_x86_linux)
692 vg_assert(sizeof(OffT
) == 4);
693 res
= VG_(do_syscall5
)(__NR_pread64
, fd
, (UWord
)buf
, count
,
694 offset
, 0); // Little endian long long
696 # elif defined(VGP_arm_linux)
697 vg_assert(sizeof(OffT
) == 4);
698 res
= VG_(do_syscall5
)(__NR_pread64
, fd
, (UWord
)buf
, count
,
699 0, offset
); // Big endian long long
701 # elif defined(VGP_ppc32_linux)
702 vg_assert(sizeof(OffT
) == 4);
703 res
= VG_(do_syscall6
)(__NR_pread64
, fd
, (UWord
)buf
, count
,
704 0, // Padding needed on PPC32
705 0, offset
); // Big endian long long
707 # elif defined(VGP_mips32_linux) && (VKI_LITTLE_ENDIAN)
708 vg_assert(sizeof(OffT
) == 4);
709 res
= VG_(do_syscall6
)(__NR_pread64
, fd
, (UWord
)buf
, count
,
712 # elif defined(VGP_mips32_linux) && (VKI_BIG_ENDIAN)
713 vg_assert(sizeof(OffT
) == 4);
714 res
= VG_(do_syscall6
)(__NR_pread64
, fd
, (UWord
)buf
, count
,
717 # elif defined(VGP_amd64_linux) || defined(VGP_s390x_linux) \
718 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
719 || defined(VGP_mips64_linux) \
720 || defined(VGP_arm64_linux)
721 res
= VG_(do_syscall4
)(__NR_pread64
, fd
, (UWord
)buf
, count
, offset
);
723 # elif defined(VGP_amd64_darwin)
724 vg_assert(sizeof(OffT
) == 8);
725 res
= VG_(do_syscall4
)(__NR_pread_nocancel
, fd
, (UWord
)buf
, count
, offset
);
727 # elif defined(VGP_x86_darwin)
728 vg_assert(sizeof(OffT
) == 8);
729 res
= VG_(do_syscall5
)(__NR_pread_nocancel
, fd
, (UWord
)buf
, count
,
730 offset
& 0xffffffff, offset
>> 32);
733 # error "Unknown platform"
737 /* Return the name of a directory for temporary files. */
738 const HChar
*VG_(tmpdir
)(void)
742 tmpdir
= VG_(getenv
)("TMPDIR");
743 if (tmpdir
== NULL
|| *tmpdir
== '\0') tmpdir
= VG_TMPDIR
;
744 if (tmpdir
== NULL
|| *tmpdir
== '\0') tmpdir
= "/tmp"; /* fallback */
749 static const HChar mkstemp_format
[] = "%s/valgrind_%s_%08x";
751 SizeT
VG_(mkstemp_fullname_bufsz
) ( SizeT part_of_name_len
)
753 return VG_(strlen
)(mkstemp_format
)
754 + VG_(strlen
)(VG_(tmpdir
)()) - 2 // %s tmpdir
755 + part_of_name_len
- 2 // %s part_of_name
761 Int
VG_(mkstemp
) ( const HChar
* part_of_name
, /*OUT*/HChar
* fullname
)
768 vg_assert(part_of_name
);
770 n
= VG_(strlen
)(part_of_name
);
771 vg_assert(n
> 0 && n
< 100);
773 seed
= (VG_(getpid
)() << 9) ^ VG_(getppid
)();
775 /* Determine sensible location for temporary files */
776 tmpdir
= VG_(tmpdir
)();
782 VG_(sprintf
)( fullname
, mkstemp_format
,
783 tmpdir
, part_of_name
, VG_(random
)( &seed
));
785 VG_(printf
)("VG_(mkstemp): trying: %s\n", fullname
);
787 sres
= VG_(open
)(fullname
,
788 VKI_O_CREAT
|VKI_O_RDWR
|VKI_O_EXCL
|VKI_O_TRUNC
,
789 VKI_S_IRUSR
|VKI_S_IWUSR
);
790 if (sr_isError(sres
)) {
791 VG_(umsg
)("VG_(mkstemp): failed to create temp file: %s\n", fullname
);
794 /* VG_(safe_fd) doesn't return if it fails. */
795 return VG_(safe_fd
)( sr_Res(sres
) );
801 /* ---------------------------------------------------------------------
802 Socket-related stuff.
803 ------------------------------------------------------------------ */
806 Int
parse_inet_addr_and_port ( const HChar
* str
, UInt
* ip_addr
, UShort
* port
);
809 Int
my_connect ( Int sockfd
, struct vki_sockaddr_in
* serv_addr
, Int addrlen
);
811 UInt
VG_(htonl
) ( UInt x
)
813 # if defined(VG_BIGENDIAN)
817 (((x
>> 24) & 0xFF) << 0) | (((x
>> 16) & 0xFF) << 8)
818 | (((x
>> 8) & 0xFF) << 16) | (((x
>> 0) & 0xFF) << 24);
822 UInt
VG_(ntohl
) ( UInt x
)
824 # if defined(VG_BIGENDIAN)
828 (((x
>> 24) & 0xFF) << 0) | (((x
>> 16) & 0xFF) << 8)
829 | (((x
>> 8) & 0xFF) << 16) | (((x
>> 0) & 0xFF) << 24);
833 UShort
VG_(htons
) ( UShort x
)
835 # if defined(VG_BIGENDIAN)
839 (((x
>> 8) & 0xFF) << 0) | (((x
>> 0) & 0xFF) << 8);
843 UShort
VG_(ntohs
) ( UShort x
)
845 # if defined(VG_BIGENDIAN)
849 (((x
>> 8) & 0xFF) << 0) | (((x
>> 0) & 0xFF) << 8);
854 /* The main function.
856 Supplied string contains either an ip address "192.168.0.1" or
857 an ip address and port pair, "192.168.0.1:1500". Parse these,
859 -1 if there is a parse error
860 -2 if no parse error, but specified host:port cannot be opened
861 the relevant file (socket) descriptor, otherwise.
864 Int
VG_(connect_via_socket
)( const HChar
* str
)
866 # if defined(VGO_linux) || defined(VGO_darwin)
868 struct vki_sockaddr_in servAddr
;
870 UShort port
= VG_CLO_DEFAULT_LOGPORT
;
871 Bool ok
= parse_inet_addr_and_port(str
, &ip
, &port
);
876 // VG_(printf)("ip = %d.%d.%d.%d, port %d\n",
877 // (ip >> 24) & 0xFF, (ip >> 16) & 0xFF,
878 // (ip >> 8) & 0xFF, ip & 0xFF,
881 servAddr
.sin_family
= VKI_AF_INET
;
882 servAddr
.sin_addr
.s_addr
= VG_(htonl
)(ip
);
883 servAddr
.sin_port
= VG_(htons
)(port
);
886 sd
= VG_(socket
)(VKI_AF_INET
, VKI_SOCK_STREAM
, 0 /* IPPROTO_IP ? */);
888 /* this shouldn't happen ... nevertheless */
892 /* connect to server */
893 res
= my_connect(sd
, &servAddr
, sizeof(servAddr
));
895 /* connection failed */
907 /* Let d = one or more digits. Accept either:
910 static Int
parse_inet_addr_and_port ( const HChar
* str
, UInt
* ip_addr
, UShort
* port
)
912 # define GET_CH ((*str) ? (*str++) : 0)
913 UInt ipa
, i
, j
, c
, any
;
915 for (i
= 0; i
< 4; i
++) {
920 if (c
< '0' || c
> '9') break;
921 j
= 10 * j
+ (int)(c
- '0');
924 if (any
== 0 || j
> 255) goto syntaxerr
;
925 ipa
= (ipa
<< 8) + j
;
926 if (i
<= 2 && c
!= '.') goto syntaxerr
;
928 if (c
== 0 || c
== ':')
931 if (c
!= ':') goto syntaxerr
;
936 if (c
< '0' || c
> '9') break;
937 j
= j
* 10 + (int)(c
- '0');
939 if (j
> 65535) goto syntaxerr
;
941 if (any
== 0 || c
!= 0) goto syntaxerr
;
942 if (j
< 1024) goto syntaxerr
;
951 // GrP fixme safe_fd?
952 Int
VG_(socket
) ( Int domain
, Int type
, Int protocol
)
954 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
955 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
956 || defined(VGP_s390x_linux)
962 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_SOCKET
, (UWord
)&args
);
963 return sr_isError(res
) ? -1 : sr_Res(res
);
965 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
966 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
967 || defined(VGP_arm64_linux)
969 res
= VG_(do_syscall3
)(__NR_socket
, domain
, type
, protocol
);
970 return sr_isError(res
) ? -1 : sr_Res(res
);
972 # elif defined(VGO_darwin)
974 res
= VG_(do_syscall3
)(__NR_socket
, domain
, type
, protocol
);
975 if (!sr_isError(res
)) {
976 // Set SO_NOSIGPIPE so write() returns EPIPE instead of raising SIGPIPE
979 res2
= VG_(do_syscall5
)(__NR_setsockopt
, sr_Res(res
), VKI_SOL_SOCKET
,
980 VKI_SO_NOSIGPIPE
, (UWord
)&optval
,
982 // ignore setsockopt() error
984 return sr_isError(res
) ? -1 : sr_Res(res
);
987 # error "Unknown arch"
993 Int
my_connect ( Int sockfd
, struct vki_sockaddr_in
* serv_addr
, Int addrlen
)
995 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
996 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
997 || defined(VGP_s390x_linux)
1001 args
[1] = (UWord
)serv_addr
;
1003 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_CONNECT
, (UWord
)&args
);
1004 return sr_isError(res
) ? -1 : sr_Res(res
);
1006 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1007 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
1008 || defined(VGP_arm64_linux)
1010 res
= VG_(do_syscall3
)(__NR_connect
, sockfd
, (UWord
)serv_addr
, addrlen
);
1011 return sr_isError(res
) ? -1 : sr_Res(res
);
1013 # elif defined(VGO_darwin)
1015 res
= VG_(do_syscall3
)(__NR_connect_nocancel
,
1016 sockfd
, (UWord
)serv_addr
, addrlen
);
1017 return sr_isError(res
) ? -1 : sr_Res(res
);
1020 # error "Unknown arch"
1024 Int
VG_(write_socket
)( Int sd
, const void *msg
, Int count
)
1026 /* This is actually send(). */
1028 /* For Linux, VKI_MSG_NOSIGNAL is a request not to send SIGPIPE on
1029 errors on stream oriented sockets when the other end breaks the
1030 connection. The EPIPE error is still returned.
1032 For Darwin, VG_(socket)() sets SO_NOSIGPIPE to get EPIPE instead of
1035 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1036 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1037 || defined(VGP_s390x_linux)
1041 args
[1] = (UWord
)msg
;
1043 args
[3] = VKI_MSG_NOSIGNAL
;
1044 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_SEND
, (UWord
)&args
);
1045 return sr_isError(res
) ? -1 : sr_Res(res
);
1047 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1048 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
1049 || defined(VGP_arm64_linux)
1051 res
= VG_(do_syscall6
)(__NR_sendto
, sd
, (UWord
)msg
,
1052 count
, VKI_MSG_NOSIGNAL
, 0,0);
1053 return sr_isError(res
) ? -1 : sr_Res(res
);
1055 # elif defined(VGP_x86_darwin) || defined(VGP_amd64_darwin)
1057 res
= VG_(do_syscall3
)(__NR_write_nocancel
, sd
, (UWord
)msg
, count
);
1058 return sr_isError(res
) ? -1 : sr_Res(res
);
1061 # error "Unknown platform"
1065 Int
VG_(getsockname
) ( Int sd
, struct vki_sockaddr
*name
, Int
*namelen
)
1067 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1068 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1069 || defined(VGP_s390x_linux) \
1070 || defined(VGP_mips32_linux)
1074 args
[1] = (UWord
)name
;
1075 args
[2] = (UWord
)namelen
;
1076 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_GETSOCKNAME
, (UWord
)&args
);
1077 return sr_isError(res
) ? -1 : sr_Res(res
);
1079 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1080 || defined(VGP_mips64_linux) || defined(VGP_arm64_linux)
1082 res
= VG_(do_syscall3
)( __NR_getsockname
,
1083 (UWord
)sd
, (UWord
)name
, (UWord
)namelen
);
1084 return sr_isError(res
) ? -1 : sr_Res(res
);
1086 # elif defined(VGO_darwin)
1088 res
= VG_(do_syscall3
)( __NR_getsockname
,
1089 (UWord
)sd
, (UWord
)name
, (UWord
)namelen
);
1090 return sr_isError(res
) ? -1 : sr_Res(res
);
1093 # error "Unknown platform"
1097 Int
VG_(getpeername
) ( Int sd
, struct vki_sockaddr
*name
, Int
*namelen
)
1099 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1100 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1101 || defined(VGP_s390x_linux) \
1102 || defined(VGP_mips32_linux)
1106 args
[1] = (UWord
)name
;
1107 args
[2] = (UWord
)namelen
;
1108 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_GETPEERNAME
, (UWord
)&args
);
1109 return sr_isError(res
) ? -1 : sr_Res(res
);
1111 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1112 || defined(VGP_mips64_linux) || defined(VGP_arm64_linux)
1114 res
= VG_(do_syscall3
)( __NR_getpeername
,
1115 (UWord
)sd
, (UWord
)name
, (UWord
)namelen
);
1116 return sr_isError(res
) ? -1 : sr_Res(res
);
1118 # elif defined(VGO_darwin)
1120 res
= VG_(do_syscall3
)( __NR_getpeername
,
1121 (UWord
)sd
, (UWord
)name
, (UWord
)namelen
);
1122 return sr_isError(res
) ? -1 : sr_Res(res
);
1125 # error "Unknown platform"
1129 Int
VG_(getsockopt
) ( Int sd
, Int level
, Int optname
, void *optval
,
1132 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1133 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1134 || defined(VGP_s390x_linux)
1140 args
[3] = (UWord
)optval
;
1141 args
[4] = (UWord
)optlen
;
1142 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_GETSOCKOPT
, (UWord
)&args
);
1143 return sr_isError(res
) ? -1 : sr_Res(res
);
1145 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1146 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
1147 || defined(VGP_arm64_linux)
1149 res
= VG_(do_syscall5
)( __NR_getsockopt
,
1150 (UWord
)sd
, (UWord
)level
, (UWord
)optname
,
1151 (UWord
)optval
, (UWord
)optlen
);
1152 return sr_isError(res
) ? -1 : sr_Res(res
);
1154 # elif defined(VGO_darwin)
1156 res
= VG_(do_syscall5
)( __NR_getsockopt
,
1157 (UWord
)sd
, (UWord
)level
, (UWord
)optname
,
1158 (UWord
)optval
, (UWord
)optlen
);
1159 return sr_isError(res
) ? -1 : sr_Res(res
);
1162 # error "Unknown platform"
1167 Int
VG_(setsockopt
) ( Int sd
, Int level
, Int optname
, void *optval
,
1170 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1171 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1172 || defined(VGP_s390x_linux)
1178 args
[3] = (UWord
)optval
;
1179 args
[4] = (UWord
)optlen
;
1180 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_SETSOCKOPT
, (UWord
)&args
);
1181 return sr_isError(res
) ? -1 : sr_Res(res
);
1183 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1184 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
1185 || defined(VGP_arm64_linux)
1187 res
= VG_(do_syscall5
)( __NR_setsockopt
,
1188 (UWord
)sd
, (UWord
)level
, (UWord
)optname
,
1189 (UWord
)optval
, (UWord
)optlen
);
1190 return sr_isError(res
) ? -1 : sr_Res(res
);
1192 # elif defined(VGO_darwin)
1194 res
= VG_(do_syscall5
)( __NR_setsockopt
,
1195 (UWord
)sd
, (UWord
)level
, (UWord
)optname
,
1196 (UWord
)optval
, (UWord
)optlen
);
1197 return sr_isError(res
) ? -1 : sr_Res(res
);
1200 # error "Unknown platform"
1205 const HChar
*VG_(basename
)(const HChar
*path
)
1207 static HChar
*buf
= NULL
;
1208 static SizeT buf_len
= 0;
1209 const HChar
*p
, *end
;
1212 0 == VG_(strcmp
)(path
, ""))
1217 p
= path
+ VG_(strlen
)(path
);
1218 while (p
> path
&& *p
== '/') {
1219 // skip all trailing '/'
1223 if (p
== path
&& *p
== '/') return "/"; // all slashes
1227 while (p
> path
&& *p
!= '/') {
1234 SizeT need
= end
-p
+1 + 1;
1235 if (need
> buf_len
) {
1236 buf_len
= (buf_len
== 0) ? 500 : need
;
1237 buf
= VG_(realloc
)("basename", buf
, buf_len
);
1239 VG_(strncpy
)(buf
, p
, end
-p
+1);
1240 buf
[end
-p
+1] = '\0';
1246 const HChar
*VG_(dirname
)(const HChar
*path
)
1248 static HChar
*buf
= NULL
;
1249 static SizeT buf_len
= 0;
1254 0 == VG_(strcmp
)(path
, "") ||
1255 0 == VG_(strcmp
)(path
, "/"))
1260 p
= path
+ VG_(strlen
)(path
);
1261 while (p
> path
&& *p
== '/') {
1262 // skip all trailing '/'
1266 while (p
> path
&& *p
!= '/') {
1272 if (*p
== '/') return "/"; // all slashes
1273 else return "."; // no slashes
1276 while (p
> path
&& *p
== '/') {
1281 SizeT need
= p
-path
+1 + 1;
1282 if (need
> buf_len
) {
1283 buf_len
= (buf_len
== 0) ? 500 : need
;
1284 buf
= VG_(realloc
)("dirname", buf
, buf_len
);
1286 VG_(strncpy
)(buf
, path
, p
-path
+1);
1287 buf
[p
-path
+1] = '\0';
1293 /*--------------------------------------------------------------------*/
1295 /*--------------------------------------------------------------------*/