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-2017 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, see <http://www.gnu.org/licenses/>.
27 The GNU General Public License is contained in the file COPYING.
30 #include "pub_core_basics.h"
31 #include "pub_core_vki.h"
32 #include "pub_core_vkiscnums.h"
33 #include "pub_core_debuglog.h"
34 #include "pub_core_libcbase.h"
35 #include "pub_core_libcassert.h"
36 #include "pub_core_libcfile.h"
37 #include "pub_core_libcprint.h" // VG_(sprintf)
38 #include "pub_core_libcproc.h" // VG_(getpid), VG_(getppid)
39 #include "pub_core_clientstate.h" // VG_(fd_hard_limit)
40 #include "pub_core_mallocfree.h" // VG_(realloc)
41 #include "pub_core_syscall.h"
43 /* IMPORTANT: on Darwin it is essential to use the _nocancel versions
44 of syscalls rather than the vanilla version, if a _nocancel version
45 is available. See docs/internals/Darwin-notes.txt for the reason
48 /* ---------------------------------------------------------------------
50 ------------------------------------------------------------------ */
52 /* Move an fd into the Valgrind-safe range */
53 Int
VG_(safe_fd
)(Int oldfd
)
57 vg_assert(VG_(fd_hard_limit
) != -1);
59 newfd
= VG_(fcntl
)(oldfd
, VKI_F_DUPFD
, VG_(fd_hard_limit
));
62 VG_(debugLog
)(0, "libcfile", "Valgrind: FATAL: "
63 "Private file creation failed.\n"
64 " The current file descriptor limit is %d.\n"
65 " If you are running in Docker please consider\n"
66 " lowering this limit with the shell built-in limit command.\n",
68 VG_(debugLog
)(0, "libcfile", "Exiting now.\n");
72 vg_assert(newfd
>= VG_(fd_hard_limit
));
76 /* Set the close-on-exec flag for this fd. */
77 VG_(fcntl
)(newfd
, VKI_F_SETFD
, VKI_FD_CLOEXEC
);
82 #if defined(VGO_freebsd)
83 #define M_FILEDESC_BUF 1000000
84 static Char filedesc_buf
[M_FILEDESC_BUF
];
87 /* Given a file descriptor, attempt to deduce its filename. To do
88 this, we use /proc/self/fd/<FD>. If this doesn't point to a file,
89 or if it doesn't exist, we return False.
90 Upon successful completion *result contains the filename. The
91 filename will be overwritten with the next invocation so callers
92 need to copy the filename if needed. *result is NULL if the filename
94 Bool
VG_(resolve_filename
) ( Int fd
, const HChar
** result
)
96 # if defined(VGO_linux) || defined(VGO_solaris)
97 static HChar
*buf
= NULL
;
98 static SizeT bufsiz
= 0;
100 if (buf
== NULL
) { // first time
102 buf
= VG_(malloc
)("resolve_filename", bufsiz
);
105 HChar tmp
[64]; // large enough
107 # if defined(VGO_linux)
108 VG_(sprintf
)(tmp
, "/proc/self/fd/%d", fd
);
109 # elif defined(VGO_solaris)
110 VG_(sprintf
)(tmp
, "/proc/self/path/%d", fd
);
115 SSizeT res
= VG_(readlink
)(tmp
, buf
, bufsiz
);
117 if (res
== bufsiz
) { // buffer too small; increase and retry
119 buf
= VG_(realloc
)("resolve_filename", buf
, bufsiz
);
122 vg_assert(bufsiz
> res
); // paranoia
123 if (buf
[0] != '/') break;
133 #elif defined(VGO_freebsd)
141 struct vki_kinfo_file
*kf
;
142 static HChar
*buf
= NULL
;
143 static SizeT bufsiz
= 0;
145 if (buf
== NULL
) { // first time
147 buf
= VG_(malloc
)("resolve_filename", bufsiz
);
150 mib
[0] = VKI_CTL_KERN
;
151 mib
[1] = VKI_KERN_PROC
;
152 mib
[2] = VKI_KERN_PROC_FILEDESC
;
153 mib
[3] = sr_Res(VG_(do_syscall0
)(__NR_getpid
));
154 len
= sizeof(filedesc_buf
);
155 sres
= VG_(do_syscall6
)(__NR___sysctl
, (UWord
)mib
, 4, (UWord
)filedesc_buf
,
157 if (sr_isError(sres
)) {
158 VG_(debugLog
)(0, "sysctl(kern.proc.filedesc)", "%s\n", VG_(strerror
)(sr_Err(sres
)));
161 /* Walk though the list. */
163 eb
= filedesc_buf
+ len
;
165 kf
= (struct vki_kinfo_file
*)bp
;
166 if (kf
->vki_kf_fd
== fd
) {
169 bp
+= kf
->vki_kf_structsize
;
171 if (bp
>= eb
|| *kf
->vki_kf_path
== '\0') {
172 VG_(strncpy
)( buf
, "[unknown]", bufsiz
);
174 VG_(strncpy
)( buf
, kf
->vki_kf_path
, bufsiz
);
179 // PJF it will be a relief to get rid of the above bit of ugliness
180 // however it does not seem to have the same functionality
181 // regarding pipes where it profuces just an empty string
182 struct vki_kinfo_file kinfo_file
;
183 kinfo_file
.vki_kf_structsize
= VKI_KINFO_FILE_SIZE
;
184 if (0 == VG_(fcntl
) ( fd
, VKI_F_KINFO
, (Addr
)&kinfo_file
)) {
185 static HChar
*buf
= NULL
;
188 buf
= VG_(malloc
)("resolve_filename", VKI_PATH_MAX
);
191 VG_(strcpy
)( buf
, kinfo_file
.vki_kf_path
);
192 if (buf
[0] == '/') return True
;
198 # elif defined(VGO_darwin)
199 HChar tmp
[VKI_MAXPATHLEN
+1];
200 if (0 == VG_(fcntl
)(fd
, VKI_F_GETPATH
, (UWord
)tmp
)) {
201 static HChar
*buf
= NULL
;
204 buf
= VG_(malloc
)("resolve_filename", VKI_MAXPATHLEN
+1);
205 VG_(strcpy
)( buf
, tmp
);
208 if (buf
[0] == '/') return True
;
219 #if defined(VGO_freebsd)
223 /* This should only be called after a successful call to
224 * Bool VG_(resolve_filename) ( Int fd, const HChar** result )
225 * so that filedesc_buf is still valid for fd */
226 Bool
VG_(resolve_filemode
) ( Int fd
, Int
* result
)
230 struct vki_kinfo_file
*kf
;
232 /* Walk though the list. */
234 eb
= filedesc_buf
+ sizeof(filedesc_buf
);
236 kf
= (struct vki_kinfo_file
*)bp
;
237 if (kf
->vki_kf_fd
== fd
) {
240 bp
+= kf
->vki_kf_structsize
;
245 *result
= kf
->vki_kf_flags
;
250 /* less ugly version, no dependency on resolve_filename */
251 Bool
VG_(resolve_filemode
) ( Int fd
, Int
* result
)
253 struct vki_kinfo_file kinfo_file
;
254 kinfo_file
.vki_kf_structsize
= VKI_KINFO_FILE_SIZE
;
255 if (0 == VG_(fcntl
) ( fd
, VKI_F_KINFO
, (Addr
)&kinfo_file
)) {
256 *result
= kinfo_file
.vki_kf_flags
;
265 SysRes
VG_(mknod
) ( const HChar
* pathname
, Int mode
, UWord dev
)
267 # if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
268 /* ARM64 wants to use __NR_mknodat rather than __NR_mknod. */
269 SysRes res
= VG_(do_syscall4
)(__NR_mknodat
,
270 VKI_AT_FDCWD
, (UWord
)pathname
, mode
, dev
);
271 # elif defined(VGO_linux) || defined(VGO_darwin)
272 SysRes res
= VG_(do_syscall3
)(__NR_mknod
,
273 (UWord
)pathname
, mode
, dev
);
274 # elif defined(VGO_freebsd)
275 #if (FREEBSD_VERS < FREEBSD_12)
276 SysRes res
= VG_(do_syscall3
)(__NR_freebsd11_mknod
,
277 (UWord
)pathname
, mode
, dev
);
279 SysRes res
= VG_(do_syscall4
)(__NR_mknodat
, VKI_AT_FDCWD
,
280 (UWord
)pathname
, mode
, dev
);
282 # elif defined(VGO_solaris)
283 SysRes res
= VG_(do_syscall4
)(__NR_mknodat
,
284 VKI_AT_FDCWD
, (UWord
)pathname
, mode
, dev
);
291 SysRes
VG_(open
) ( const HChar
* pathname
, Int flags
, Int mode
)
293 # if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
294 /* ARM64 wants to use __NR_openat rather than __NR_open. */
295 SysRes res
= VG_(do_syscall4
)(__NR_openat
,
296 VKI_AT_FDCWD
, (UWord
)pathname
, flags
, mode
);
297 # elif defined(VGO_linux) || defined(VGO_freebsd)
298 SysRes res
= VG_(do_syscall3
)(__NR_open
,
299 (UWord
)pathname
, flags
, mode
);
300 # elif defined(VGO_darwin)
301 SysRes res
= VG_(do_syscall3
)(__NR_open_nocancel
,
302 (UWord
)pathname
, flags
, mode
);
303 # elif defined(VGO_solaris)
304 SysRes res
= VG_(do_syscall4
)(__NR_openat
,
305 VKI_AT_FDCWD
, (UWord
)pathname
, flags
, mode
);
312 Int
VG_(fd_open
) (const HChar
* pathname
, Int flags
, Int mode
)
315 sr
= VG_(open
) (pathname
, flags
, mode
);
322 void VG_(close
) ( Int fd
)
324 /* Hmm. Return value is not checked. That's uncool. */
325 # if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd)
326 (void)VG_(do_syscall1
)(__NR_close
, fd
);
327 # elif defined(VGO_darwin)
328 (void)VG_(do_syscall1
)(__NR_close_nocancel
, fd
);
334 Int
VG_(read
) ( Int fd
, void* buf
, Int count
)
337 # if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd)
338 SysRes res
= VG_(do_syscall3
)(__NR_read
, fd
, (UWord
)buf
, count
);
339 # elif defined(VGO_darwin)
340 SysRes res
= VG_(do_syscall3
)(__NR_read_nocancel
, fd
, (UWord
)buf
, count
);
344 if (sr_isError(res
)) {
345 ret
= - (Int
)(Word
)sr_Err(res
);
348 ret
= (Int
)(Word
)sr_Res(res
);
354 Int
VG_(write
) ( Int fd
, const void* buf
, Int count
)
357 # if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd)
358 SysRes res
= VG_(do_syscall3
)(__NR_write
, fd
, (UWord
)buf
, count
);
359 # elif defined(VGO_darwin)
360 SysRes res
= VG_(do_syscall3
)(__NR_write_nocancel
, fd
, (UWord
)buf
, count
);
364 if (sr_isError(res
)) {
365 ret
= - (Int
)(Word
)sr_Err(res
);
368 ret
= (Int
)(Word
)sr_Res(res
);
375 Int
VG_(pipe
) ( Int fd
[2] )
377 # if defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
378 /* __NR_pipe has a strange return convention on mips32-linux. */
379 SysRes res
= VG_(do_syscall1
)(__NR_pipe
, (UWord
)fd
);
380 if (!sr_isError(res
)) {
381 fd
[0] = (Int
)sr_Res(res
);
382 fd
[1] = (Int
)sr_ResEx(res
);
387 # elif defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
388 SysRes res
= VG_(do_syscall2
)(__NR_pipe2
, (UWord
)fd
, 0);
389 return sr_isError(res
) ? -1 : 0;
390 # elif defined(VGO_linux)
391 SysRes res
= VG_(do_syscall1
)(__NR_pipe
, (UWord
)fd
);
392 return sr_isError(res
) ? -1 : 0;
393 # elif defined(VGO_freebsd)
394 #if defined(__NR_pipe2)
395 SysRes res
= VG_(do_syscall2
)(__NR_pipe2
, (UWord
)fd
, 0);
397 SysRes res
= VG_(do_syscall0
)(__NR_freebsd10_pipe
);
398 if (!sr_isError(res
)) {
400 fd
[1] = sr_ResHI(res
);
403 return sr_isError(res
) ? -1 : 0;
404 # elif defined(VGO_darwin)
405 /* __NR_pipe is UX64, so produces a double-word result */
406 SysRes res
= VG_(do_syscall0
)(__NR_pipe
);
407 if (!sr_isError(res
)) {
408 fd
[0] = (Int
)sr_Res(res
);
409 fd
[1] = (Int
)sr_ResHI(res
);
411 return sr_isError(res
) ? -1 : 0;
412 # elif defined(VGO_solaris)
413 # if defined(SOLARIS_NEW_PIPE_SYSCALL)
414 SysRes res
= VG_(do_syscall2
)(__NR_pipe
, (UWord
)fd
, 0);
415 return sr_isError(res
) ? -1 : 0;
417 SysRes res
= VG_(do_syscall0
)(__NR_pipe
);
418 if (!sr_isError(res
)) {
419 fd
[0] = (Int
)sr_Res(res
);
420 fd
[1] = (Int
)sr_ResHI(res
);
422 return sr_isError(res
) ? -1 : 0;
429 Off64T
VG_(lseek
) ( Int fd
, Off64T offset
, Int whence
)
431 # if defined(VGO_linux) || defined(VGP_amd64_darwin) || defined(VGP_amd64_freebsd) || defined(VGP_arm64_freebsd)
432 # if defined(__NR__llseek)
434 SysRes res
= VG_(do_syscall5
)(__NR__llseek
, fd
,
435 offset
>> 32, offset
& 0xffffffff,
436 (UWord
)&result
, whence
);
437 return sr_isError(res
) ? (-1) : result
;
439 SysRes res
= VG_(do_syscall3
)(__NR_lseek
, fd
, offset
, whence
);
440 vg_assert(sizeof(Off64T
) == sizeof(sr_Res(res
)));
441 return sr_isError(res
) ? (-1) : sr_Res(res
);
443 # elif defined(VGP_x86_darwin) || defined(VGP_x86_freebsd)
444 SysRes res
= VG_(do_syscall4
)(__NR_lseek
, fd
,
445 offset
& 0xffffffff, offset
>> 32, whence
);
446 return sr_isError(res
) ? (-1) : sr_Res(res
);
447 # elif defined(VGP_x86_solaris)
448 SysRes res
= VG_(do_syscall4
)(__NR_llseek
, fd
,
449 offset
& 0xffffffff, offset
>> 32, whence
);
450 return sr_isError(res
) ? (-1) : ((ULong
)sr_ResHI(res
) << 32 | sr_Res(res
));
451 # elif defined(VGP_amd64_solaris)
452 SysRes res
= VG_(do_syscall3
)(__NR_lseek
, fd
, offset
, whence
);
453 vg_assert(sizeof(Off64T
) == sizeof(Word
));
454 return sr_isError(res
) ? (-1) : sr_Res(res
);
456 # error "Unknown plat"
458 /* if you change the error-reporting conventions of this, also
459 change all usage points. */
463 /* stat/fstat support. It's uggerly. We have impedance-match into a
464 'struct vg_stat' in order to have a single structure that callers
465 can use consistently on all platforms. */
467 #define TRANSLATE_TO_vg_stat(_p_vgstat, _p_vkistat) \
469 (_p_vgstat)->dev = (ULong)( (_p_vkistat)->st_dev ); \
470 (_p_vgstat)->ino = (ULong)( (_p_vkistat)->st_ino ); \
471 (_p_vgstat)->nlink = (ULong)( (_p_vkistat)->st_nlink ); \
472 (_p_vgstat)->mode = (UInt) ( (_p_vkistat)->st_mode ); \
473 (_p_vgstat)->uid = (UInt) ( (_p_vkistat)->st_uid ); \
474 (_p_vgstat)->gid = (UInt) ( (_p_vkistat)->st_gid ); \
475 (_p_vgstat)->rdev = (ULong)( (_p_vkistat)->st_rdev ); \
476 (_p_vgstat)->size = (Long) ( (_p_vkistat)->st_size ); \
477 (_p_vgstat)->blksize = (ULong)( (_p_vkistat)->st_blksize ); \
478 (_p_vgstat)->blocks = (ULong)( (_p_vkistat)->st_blocks ); \
479 (_p_vgstat)->atime = (ULong)( (_p_vkistat)->st_atime ); \
480 (_p_vgstat)->atime_nsec = (ULong)( (_p_vkistat)->st_atime_nsec ); \
481 (_p_vgstat)->mtime = (ULong)( (_p_vkistat)->st_mtime ); \
482 (_p_vgstat)->mtime_nsec = (ULong)( (_p_vkistat)->st_mtime_nsec ); \
483 (_p_vgstat)->ctime = (ULong)( (_p_vkistat)->st_ctime ); \
484 (_p_vgstat)->ctime_nsec = (ULong)( (_p_vkistat)->st_ctime_nsec ); \
487 #define TRANSLATE_statx_TO_vg_stat(_p_vgstat, _p_vkistat) \
489 (_p_vgstat)->dev = VG_MAKEDEV( (_p_vkistat)->stx_dev_major, \
490 (_p_vkistat)->stx_dev_minor ); \
491 (_p_vgstat)->ino = (ULong)( (_p_vkistat)->stx_ino ); \
492 (_p_vgstat)->nlink = (ULong)( (_p_vkistat)->stx_nlink ); \
493 (_p_vgstat)->mode = (UInt) ( (_p_vkistat)->stx_mode ); \
494 (_p_vgstat)->uid = (UInt) ( (_p_vkistat)->stx_uid ); \
495 (_p_vgstat)->gid = (UInt) ( (_p_vkistat)->stx_gid ); \
496 (_p_vgstat)->rdev = VG_MAKEDEV( (_p_vkistat)->stx_rdev_major, \
497 (_p_vkistat)->stx_rdev_minor ); \
498 (_p_vgstat)->size = (Long) ( (_p_vkistat)->stx_size ); \
499 (_p_vgstat)->blksize = (ULong)( (_p_vkistat)->stx_blksize ); \
500 (_p_vgstat)->blocks = (ULong)( (_p_vkistat)->stx_blocks ); \
501 (_p_vgstat)->atime = (ULong)( (_p_vkistat)->stx_atime.tv_sec ); \
502 (_p_vgstat)->atime_nsec = (ULong)( (_p_vkistat)->stx_atime.tv_nsec ); \
503 (_p_vgstat)->mtime = (ULong)( (_p_vkistat)->stx_mtime.tv_sec ); \
504 (_p_vgstat)->mtime_nsec = (ULong)( (_p_vkistat)->stx_mtime.tv_nsec ); \
505 (_p_vgstat)->ctime = (ULong)( (_p_vkistat)->stx_ctime.tv_sec ); \
506 (_p_vgstat)->ctime_nsec = (ULong)( (_p_vkistat)->stx_ctime.tv_nsec ); \
509 SysRes
VG_(stat
) ( const HChar
* file_name
, struct vg_stat
* vgbuf
)
512 VG_(memset
)(vgbuf
, 0, sizeof(*vgbuf
));
514 # if defined(VGO_linux)
515 /* On Linux, first try with statx. If that doesn't work out, fall back to
516 the stat64 or vanilla version. */
517 { struct vki_statx buf
;
518 res
= VG_(do_syscall5
)(__NR_statx
, VKI_AT_FDCWD
, (UWord
)file_name
, 0,
519 VKI_STATX_ALL
, (UWord
)&buf
);
520 if (!(sr_isError(res
) && sr_Err(res
) == VKI_ENOSYS
)) {
521 /* Success, or any failure except ENOSYS */
522 if (!sr_isError(res
))
523 TRANSLATE_statx_TO_vg_stat(vgbuf
, &buf
);
528 # if defined(VGO_linux) || defined(VGO_darwin)
529 /* Try with stat64. This is the second candidate on Linux, and the first
530 one on Darwin. If that doesn't work out, fall back to vanilla version.
532 # if defined(__NR_stat64)
533 { struct vki_stat64 buf64
;
534 res
= VG_(do_syscall2
)(__NR_stat64
, (UWord
)file_name
, (UWord
)&buf64
);
535 if (!(sr_isError(res
) && sr_Err(res
) == VKI_ENOSYS
)) {
536 /* Success, or any failure except ENOSYS */
537 if (!sr_isError(res
))
538 TRANSLATE_TO_vg_stat(vgbuf
, &buf64
);
542 # endif /* defined(__NR_stat64) */
543 # if defined(__NR_stat) || defined(VGP_arm64_linux)
544 /* This is the fallback ("vanilla version"). */
545 { struct vki_stat buf
;
546 # if defined(VGP_arm64_linux)
547 res
= VG_(do_syscall3
)(__NR3264_fstatat
, VKI_AT_FDCWD
,
548 (UWord
)file_name
, (UWord
)&buf
);
550 res
= VG_(do_syscall2
)(__NR_stat
, (UWord
)file_name
, (UWord
)&buf
);
552 if (!sr_isError(res
))
553 TRANSLATE_TO_vg_stat(vgbuf
, &buf
);
557 # elif defined(VGO_solaris)
559 # if defined(VGP_x86_solaris)
560 struct vki_stat64 buf64
;
561 res
= VG_(do_syscall4
)(__NR_fstatat64
, VKI_AT_FDCWD
, (UWord
)file_name
,
563 # elif defined(VGP_amd64_solaris)
564 struct vki_stat buf64
;
565 res
= VG_(do_syscall4
)(__NR_fstatat
, VKI_AT_FDCWD
, (UWord
)file_name
,
568 # error "Unknown platform"
570 if (!sr_isError(res
))
571 TRANSLATE_TO_vg_stat(vgbuf
, &buf64
);
574 # elif defined(VGO_freebsd)
576 #if (FREEBSD_VERS < FREEBSD_12)
577 struct vki_freebsd11_stat buf
;
578 res
= VG_(do_syscall2
)(__NR_stat
, (UWord
)file_name
, (UWord
)&buf
);
581 res
= VG_(do_syscall4
)(__NR_fstatat
, VKI_AT_FDCWD
, (UWord
)file_name
, (UWord
)&buf
, 0);
583 if (!sr_isError(res
)) {
584 TRANSLATE_TO_vg_stat(vgbuf
, &buf
);
593 Int
VG_(fstat
) ( Int fd
, struct vg_stat
* vgbuf
)
596 VG_(memset
)(vgbuf
, 0, sizeof(*vgbuf
));
598 # if defined(VGO_linux)
599 /* On Linux, first try with statx. If that doesn't work out, fall back to
600 the fstat64 or vanilla version. */
601 { struct vki_statx buf
;
602 const char* file_name
= "";
603 res
= VG_(do_syscall5
)(__NR_statx
, fd
, (RegWord
)file_name
,
604 VKI_AT_EMPTY_PATH
, VKI_STATX_ALL
, (RegWord
)&buf
);
605 if (!(sr_isError(res
) && sr_Err(res
) == VKI_ENOSYS
)) {
606 /* Success, or any failure except ENOSYS */
607 if (!sr_isError(res
))
608 TRANSLATE_statx_TO_vg_stat(vgbuf
, &buf
);
609 return sr_isError(res
) ? (-1) : 0;
613 # if defined(VGO_linux) || defined(VGO_darwin)
614 /* Try with fstat64. This is the second candidate on Linux, and the first
615 one on Darwin. If that doesn't work out, fall back to vanilla version.
617 # if defined(__NR_fstat64)
618 { struct vki_stat64 buf64
;
619 res
= VG_(do_syscall2
)(__NR_fstat64
, (UWord
)fd
, (UWord
)&buf64
);
620 if (!(sr_isError(res
) && sr_Err(res
) == VKI_ENOSYS
)) {
621 /* Success, or any failure except ENOSYS */
622 if (!sr_isError(res
))
623 TRANSLATE_TO_vg_stat(vgbuf
, &buf64
);
624 return sr_isError(res
) ? (-1) : 0;
627 # endif /* defined(__NR_fstat64) */
628 # if defined(__NR_fstat)
629 { struct vki_stat buf
;
630 res
= VG_(do_syscall2
)(__NR_fstat
, (RegWord
)fd
, (RegWord
)(Addr
)&buf
);
631 if (!sr_isError(res
))
632 TRANSLATE_TO_vg_stat(vgbuf
, &buf
);
633 return sr_isError(res
) ? (-1) : 0;
636 # elif defined(VGO_solaris)
638 # if defined(VGP_x86_solaris)
639 struct vki_stat64 buf64
;
640 res
= VG_(do_syscall4
)(__NR_fstatat64
, (UWord
)fd
, 0, (UWord
)&buf64
, 0);
641 # elif defined(VGP_amd64_solaris)
642 struct vki_stat buf64
;
643 res
= VG_(do_syscall4
)(__NR_fstatat
, (UWord
)fd
, 0, (UWord
)&buf64
, 0);
645 # error "Unknown platform"
647 if (!sr_isError(res
))
648 TRANSLATE_TO_vg_stat(vgbuf
, &buf64
);
649 return sr_isError(res
) ? (-1) : 0;
651 # elif defined(VGO_freebsd)
653 #if (FREEBSD_VERS < FREEBSD_12)
654 struct vki_freebsd11_stat buf
;
655 res
= VG_(do_syscall2
)(__NR_fstat
, (RegWord
)fd
, (RegWord
)(Addr
)&buf
);
658 res
= VG_(do_syscall2
)(__NR_fstat
, (RegWord
)fd
, (RegWord
)(Addr
)&buf
);
660 if (!sr_isError(res
)) {
661 TRANSLATE_TO_vg_stat(vgbuf
, &buf
);
663 return sr_isError(res
) ? (-1) : 0;
670 #if defined(VGO_freebsd)
671 /* extend this to other OSes as and when needed */
672 SysRes
VG_(lstat
) ( const HChar
* file_name
, struct vg_stat
* vgbuf
)
675 VG_(memset
)(vgbuf
, 0, sizeof(*vgbuf
));
677 #if (FREEBSD_VERS < FREEBSD_12)
678 struct vki_freebsd11_stat buf
;
679 res
= VG_(do_syscall2
)(__NR_lstat
, (UWord
)file_name
, (UWord
)&buf
);
682 res
= VG_(do_syscall4
)(__NR_fstatat
, VKI_AT_FDCWD
, (UWord
)file_name
, (UWord
)&buf
, VKI_AT_SYMLINK_NOFOLLOW
);
684 if (!sr_isError(res
)) {
685 TRANSLATE_TO_vg_stat(vgbuf
, &buf
);
691 #undef TRANSLATE_TO_vg_stat
692 #undef TRANSLATE_statx_TO_vg_stat
694 Long
VG_(fsize
) ( Int fd
)
697 Int res
= VG_(fstat
)( fd
, &buf
);
698 return (res
== -1) ? (-1LL) : buf
.size
;
701 SysRes
VG_(getxattr
) ( const HChar
* file_name
, const HChar
* attr_name
, Addr attr_value
, SizeT attr_value_len
)
704 #if defined(VGO_linux)
705 res
= VG_(do_syscall4
)(__NR_getxattr
, (UWord
)file_name
, (UWord
)attr_name
,
706 attr_value
, attr_value_len
);
708 res
= VG_(mk_SysRes_Error
)(VKI_ENOSYS
);
713 Bool
VG_(is_dir
) ( const HChar
* f
)
716 SysRes res
= VG_(stat
)(f
, &buf
);
717 return sr_isError(res
) ? False
718 : VKI_S_ISDIR(buf
.mode
) ? True
: False
;
721 SysRes
VG_(dup
) ( Int oldfd
)
723 # if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_freebsd)
724 return VG_(do_syscall1
)(__NR_dup
, oldfd
);
725 # elif defined(VGO_solaris)
726 return VG_(do_syscall3
)(__NR_fcntl
, oldfd
, F_DUPFD
, 0);
732 SysRes
VG_(dup2
) ( Int oldfd
, Int newfd
)
734 # if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
735 /* We only have dup3, that means we have to mimic dup2.
736 The only real difference is when oldfd == newfd.
737 dup3 always returns an error, but dup2 returns only an
738 error if the fd is invalid, otherwise it returns newfd. */
739 if (oldfd
== newfd
) {
740 if (VG_(fcntl
)(oldfd
, VKI_F_GETFL
, 0) == -1)
741 return VG_(mk_SysRes_Error
)(VKI_EBADF
);
742 return VG_(mk_SysRes_Success
)(newfd
);
744 return VG_(do_syscall3
)(__NR_dup3
, oldfd
, newfd
, 0);
745 # elif defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_freebsd)
746 return VG_(do_syscall2
)(__NR_dup2
, oldfd
, newfd
);
747 # elif defined(VGO_solaris)
748 return VG_(do_syscall3
)(__NR_fcntl
, oldfd
, F_DUP2FD
, newfd
);
754 /* Returns -1 on error. */
755 Int
VG_(fcntl
) ( Int fd
, Int cmd
, Addr arg
)
757 # if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd)
758 # if defined(VGP_nanomips_linux)
759 SysRes res
= VG_(do_syscall3
)(__NR_fcntl64
, fd
, cmd
, arg
);
761 SysRes res
= VG_(do_syscall3
)(__NR_fcntl
, fd
, cmd
, arg
);
763 # elif defined(VGO_darwin)
764 SysRes res
= VG_(do_syscall3
)(__NR_fcntl_nocancel
, fd
, cmd
, arg
);
768 if (sr_isError(res
)) {
769 VG_(debugLog
)(1, "VG_(fcntl)", "fcntl error %lu %s\n", sr_Err(res
), VG_(strerror
)(sr_Err(res
)));
772 return (Int
)sr_Res(res
);
775 Int
VG_(rename
) ( const HChar
* old_name
, const HChar
* new_name
)
777 # if defined(VGO_solaris) || defined(VGP_arm64_linux)
778 SysRes res
= VG_(do_syscall4
)(__NR_renameat
, VKI_AT_FDCWD
, (UWord
)old_name
,
779 VKI_AT_FDCWD
, (UWord
)new_name
);
780 # elif defined(VGP_nanomips_linux)
781 SysRes res
= VG_(do_syscall5
)(__NR_renameat2
, VKI_AT_FDCWD
, (UWord
)old_name
,
782 VKI_AT_FDCWD
, (UWord
)new_name
, 0);
784 # elif defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_freebsd)
785 SysRes res
= VG_(do_syscall2
)(__NR_rename
, (UWord
)old_name
, (UWord
)new_name
);
789 return sr_isError(res
) ? (-1) : 0;
792 Int
VG_(unlink
) ( const HChar
* file_name
)
794 # if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
795 SysRes res
= VG_(do_syscall2
)(__NR_unlinkat
, VKI_AT_FDCWD
,
797 # elif defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_freebsd)
798 SysRes res
= VG_(do_syscall1
)(__NR_unlink
, (UWord
)file_name
);
799 # elif defined(VGO_solaris)
800 SysRes res
= VG_(do_syscall3
)(__NR_unlinkat
, VKI_AT_FDCWD
,
801 (UWord
)file_name
, 0);
805 return sr_isError(res
) ? (-1) : 0;
808 /* The working directory at startup.
809 All that is really needed is to note the cwd at process startup.
810 Hence VG_(record_startup_wd) notes it (in a platform dependent way)
811 and VG_(get_startup_wd) produces the noted value. */
812 static HChar
*startup_wd
;
814 /* Record the process' working directory at startup. Is intended to
815 be called exactly once, at startup, before the working directory
817 void VG_(record_startup_wd
) ( void )
819 # if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd)
820 /* Simple: just ask the kernel */
825 startup_wd
= VG_(realloc
)("startup_wd", startup_wd
, szB
);
826 VG_(memset
)(startup_wd
, 0, szB
);
827 # if defined(VGO_linux) || defined(VGO_solaris)
828 res
= VG_(do_syscall2
)(__NR_getcwd
, (UWord
)startup_wd
, szB
-1);
829 # elif defined(VGO_freebsd)
830 res
= VG_(do_syscall2
)(__NR___getcwd
, (UWord
)startup_wd
, szB
-1);
832 } while (sr_isError(res
) && sr_Err(res
) == VKI_ERANGE
);
834 if (sr_isError(res
)) {
835 VG_(free
)(startup_wd
);
840 vg_assert(startup_wd
[szB
-1] == 0);
842 # elif defined(VGO_darwin)
843 /* We can't ask the kernel, so instead rely on launcher-*.c to
844 tell us the startup path. Note the env var is keyed to the
845 parent's PID, not ours, since our parent is the launcher
847 { HChar envvar
[100]; // large enough
849 VG_(memset
)(envvar
, 0, sizeof(envvar
));
850 VG_(sprintf
)(envvar
, "VALGRIND_STARTUP_PWD_%d_XYZZY",
851 (Int
)VG_(getppid
)());
852 wd
= VG_(getenv
)( envvar
);
855 SizeT need
= VG_(strlen
)(wd
) + 1;
856 startup_wd
= VG_(malloc
)("startup_wd", need
);
857 VG_(strcpy
)(startup_wd
, wd
);
864 /* Return the previously acquired startup_wd or NULL. */
865 const HChar
*VG_(get_startup_wd
) ( void )
870 SysRes
VG_(poll
) (struct vki_pollfd
*fds
, Int nfds
, Int timeout
)
873 # if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
874 /* ARM64 wants to use __NR_ppoll rather than __NR_poll. */
875 struct vki_timespec timeout_ts
;
877 timeout_ts
.tv_sec
= timeout
/ 1000;
878 timeout_ts
.tv_nsec
= ((long)timeout
% 1000) * 1000000;
880 res
= VG_(do_syscall4
)(__NR_ppoll
,
882 (UWord
)(timeout
>= 0 ? &timeout_ts
: NULL
),
884 # elif defined(VGO_linux)
885 res
= VG_(do_syscall3
)(__NR_poll
, (UWord
)fds
, nfds
, timeout
);
886 # elif defined(VGO_freebsd)
887 res
= VG_(do_syscall3
)(__NR_poll
, (UWord
)fds
, nfds
, timeout
);
888 # elif defined(VGO_darwin)
889 res
= VG_(do_syscall3
)(__NR_poll_nocancel
, (UWord
)fds
, nfds
, timeout
);
890 # elif defined(VGO_solaris)
891 struct vki_timespec ts
;
892 struct vki_timespec
*tsp
;
897 ts
.tv_sec
= timeout
/ 1000;
898 ts
.tv_nsec
= (timeout
% 1000) * 1000000;
902 res
= VG_(do_syscall4
)(__NR_pollsys
, (UWord
)fds
, nfds
, (UWord
)tsp
, 0);
910 /* Performs the readlink operation and puts the result into 'buf'.
911 Note, that the string in 'buf' is *not* null-terminated. The function
912 returns the number of characters put into 'buf' or -1 if an error
914 SSizeT
VG_(readlink
) (const HChar
* path
, HChar
* buf
, SizeT bufsiz
)
917 /* res = readlink( path, buf, bufsiz ); */
918 # if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
919 res
= VG_(do_syscall4
)(__NR_readlinkat
, VKI_AT_FDCWD
,
920 (UWord
)path
, (UWord
)buf
, bufsiz
);
921 # elif defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_freebsd)
922 res
= VG_(do_syscall3
)(__NR_readlink
, (UWord
)path
, (UWord
)buf
, bufsiz
);
923 # elif defined(VGO_solaris)
924 res
= VG_(do_syscall4
)(__NR_readlinkat
, VKI_AT_FDCWD
, (UWord
)path
,
929 return sr_isError(res
) ? -1 : sr_Res(res
);
932 #if defined(VGO_linux) || defined(VGO_solaris)
933 Int
VG_(getdents64
) (Int fd
, struct vki_dirent64
*dirp
, UInt count
)
936 /* res = getdents( fd, dirp, count ); */
937 # if defined(VGP_amd64_solaris)
938 /* This silently assumes that dirent64 and dirent on amd64 are same, which
939 they should always be. */
940 res
= VG_(do_syscall3
)(__NR_getdents
, fd
, (UWord
)dirp
, count
);
942 res
= VG_(do_syscall3
)(__NR_getdents64
, fd
, (UWord
)dirp
, count
);
943 # if defined(VGA_mips64)
944 /* The MIPS64 getdents64() system call is only present in 3.10+ kernels.
945 If the getdents64() system call is not available fall back to using
946 getdents() and modify the result to be compatible with getdents64(). */
947 if (sr_isError(res
) && (sr_Err(res
) == VKI_ENOSYS
)) {
949 res
= VG_(do_syscall3
)(__NR_getdents
, fd
, (UWord
)dirp
, count
);
956 struct vki_dirent64 d
;
960 u
= (union dirents
*)p
;
961 /* This should not happen, but just in case... */
962 if (p
+ u
->m
.d_reclen
> (char *)dirp
+ r
)
964 /* shuffle the dirent */
965 type
= *(p
+ u
->m
.d_reclen
- 1);
966 VG_(memmove
)(u
->d
.d_name
, u
->m
.d_name
,
968 - offsetof(struct vki_dirent
, d_name
) + 1);
971 } while (p
< (char *)dirp
+ r
);
976 return sr_isError(res
) ? -1 : sr_Res(res
);
980 /* Check accessibility of a file. Returns zero for access granted,
981 nonzero otherwise. */
982 Int
VG_(access
) ( const HChar
* path
, Bool irusr
, Bool iwusr
, Bool ixusr
)
984 # if defined(VGO_linux)
985 /* Very annoyingly, I cannot find any definition for R_OK et al in
986 the kernel interfaces. Therefore I reluctantly resort to
987 hardwiring in these magic numbers that I determined by
994 UWord w
= (irusr
? VKI_R_OK
: 0)
995 | (iwusr
? VKI_W_OK
: 0)
996 | (ixusr
? VKI_X_OK
: 0);
997 # if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
998 SysRes res
= VG_(do_syscall3
)(__NR_faccessat
, VKI_AT_FDCWD
, (UWord
)path
, w
);
999 # elif defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_freebsd)
1000 SysRes res
= VG_(do_syscall2
)(__NR_access
, (UWord
)path
, w
);
1001 # elif defined(VGO_solaris)
1002 SysRes res
= VG_(do_syscall4
)(__NR_faccessat
, VKI_AT_FDCWD
, (UWord
)path
,
1005 # error "Unknown OS"
1007 return sr_isError(res
) ? 1 : 0;
1009 # if defined(VGO_linux)
1017 Emulate the normal Unix permissions checking algorithm.
1019 If owner matches, then use the owner permissions, else
1020 if group matches, then use the group permissions, else
1021 use other permissions.
1023 Note that we can't deal properly with SUID/SGID. By default
1024 (allow_setuid == False), we refuse to run them (otherwise the
1025 executable may misbehave if it doesn't have the permissions it
1026 thinks it does). However, the caller may indicate that setuid
1027 executables are allowed, for example if we are going to exec them
1028 but not trace into them (iow, client sys_execve when
1029 clo_trace_children == False).
1031 If VKI_EACCES is returned (iow, permission was refused), then
1032 *is_setuid is set to True iff permission was refused because the
1033 executable is setuid.
1035 /* returns: 0 = success, non-0 is failure */
1036 Int
VG_(check_executable
)(/*OUT*/Bool
* is_setuid
,
1037 const HChar
* f
, Bool allow_setuid
)
1040 SysRes res
= VG_(stat
)(f
, &st
);
1045 if (sr_isError(res
)) {
1049 if ( VKI_S_ISDIR (st
.mode
) ) {
1053 if ( (st
.mode
& (VKI_S_ISUID
| VKI_S_ISGID
)) && !allow_setuid
) {
1059 res
= VG_(getxattr
)(f
, "security.capability", (Addr
)0, 0);
1060 if (!sr_isError(res
) && !allow_setuid
) {
1066 if (VG_(geteuid
)() == st
.uid
) {
1067 if (!(st
.mode
& VKI_S_IXUSR
))
1072 if (VG_(getegid
)() == st
.gid
)
1075 UInt
*groups
= NULL
;
1078 /* Find out # groups, allocate large enough array and fetch groups */
1079 ngrp
= VG_(getgroups
)(0, NULL
);
1081 groups
= VG_(malloc
)("check_executable", ngrp
* sizeof *groups
);
1082 ngrp
= VG_(getgroups
)(ngrp
, groups
);
1086 /* ngrp will be -1 if VG_(getgroups) failed. */
1087 for (i
= 0; i
< ngrp
; i
++) {
1088 if (groups
[i
] == st
.gid
) {
1097 if (!(st
.mode
& VKI_S_IXGRP
)) {
1100 } else if (!(st
.mode
& VKI_S_IXOTH
)) {
1108 SysRes
VG_(pread
) ( Int fd
, void* buf
, Int count
, OffT offset
)
1111 // on 32 bits platforms, we receive a 32 bits OffT but
1112 // we must extend it to pass a long long 64 bits.
1113 # if defined(VGP_x86_linux)
1114 vg_assert(sizeof(OffT
) == 4);
1115 res
= VG_(do_syscall5
)(__NR_pread64
, fd
, (UWord
)buf
, count
,
1116 offset
, 0); // Little endian long long
1118 # elif defined(VGP_arm_linux)
1119 vg_assert(sizeof(OffT
) == 4);
1120 res
= VG_(do_syscall5
)(__NR_pread64
, fd
, (UWord
)buf
, count
,
1121 0, offset
); // Big endian long long
1123 # elif defined(VGP_ppc32_linux)
1124 vg_assert(sizeof(OffT
) == 4);
1125 res
= VG_(do_syscall6
)(__NR_pread64
, fd
, (UWord
)buf
, count
,
1126 0, // Padding needed on PPC32
1127 0, offset
); // Big endian long long
1129 # elif (defined(VGP_mips32_linux) || defined(VGP_nanomips_linux)) \
1130 && (VKI_LITTLE_ENDIAN)
1131 vg_assert(sizeof(OffT
) == 4);
1132 res
= VG_(do_syscall6
)(__NR_pread64
, fd
, (UWord
)buf
, count
,
1135 # elif (defined(VGP_mips32_linux) || defined(VGP_nanomips_linux)) \
1137 vg_assert(sizeof(OffT
) == 4);
1138 res
= VG_(do_syscall6
)(__NR_pread64
, fd
, (UWord
)buf
, count
,
1141 # elif defined(VGP_amd64_linux) || defined(VGP_s390x_linux) \
1142 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1143 || defined(VGP_mips64_linux) || defined(VGP_arm64_linux)
1144 res
= VG_(do_syscall4
)(__NR_pread64
, fd
, (UWord
)buf
, count
, offset
);
1146 # elif defined(VGP_amd64_freebsd) || defined(VGP_arm64_freebsd)
1147 vg_assert(sizeof(OffT
) == 8);
1148 res
= VG_(do_syscall4
)(__NR_pread
, fd
, (UWord
)buf
, count
, offset
);
1150 # elif defined(VGP_x86_freebsd)
1151 vg_assert(sizeof(OffT
) == 8);
1152 res
= VG_(do_syscall5
)(__NR_pread
, fd
, (UWord
)buf
, count
,
1153 offset
& 0xffffffff, offset
>> 32);
1155 # elif defined(VGP_amd64_darwin)
1156 vg_assert(sizeof(OffT
) == 8);
1157 res
= VG_(do_syscall4
)(__NR_pread_nocancel
, fd
, (UWord
)buf
, count
, offset
);
1159 # elif defined(VGP_x86_darwin)
1160 vg_assert(sizeof(OffT
) == 8);
1161 res
= VG_(do_syscall5
)(__NR_pread_nocancel
, fd
, (UWord
)buf
, count
,
1162 offset
& 0xffffffff, offset
>> 32);
1164 # elif defined(VGP_x86_solaris)
1165 vg_assert(sizeof(OffT
) == 4);
1166 res
= VG_(do_syscall4
)(__NR_pread
, fd
, (UWord
)buf
, count
, offset
);
1168 # elif defined(VGP_amd64_solaris)
1169 vg_assert(sizeof(OffT
) == 8);
1170 res
= VG_(do_syscall4
)(__NR_pread
, fd
, (UWord
)buf
, count
, offset
);
1173 # error "Unknown platform"
1177 /* Return the name of a directory for temporary files. */
1178 const HChar
*VG_(tmpdir
)(void)
1180 const HChar
*tmpdir
;
1182 tmpdir
= VG_(getenv
)("TMPDIR");
1183 if (tmpdir
== NULL
|| *tmpdir
== '\0') tmpdir
= VG_TMPDIR
;
1184 if (tmpdir
== NULL
|| *tmpdir
== '\0') tmpdir
= "/tmp"; /* fallback */
1189 static const HChar mkstemp_format
[] = "%s/valgrind_%s_%08x";
1191 SizeT
VG_(mkstemp_fullname_bufsz
) ( SizeT part_of_name_len
)
1193 return VG_(strlen
)(mkstemp_format
)
1194 + VG_(strlen
)(VG_(tmpdir
)()) - 2 // %s tmpdir
1195 + part_of_name_len
- 2 // %s part_of_name
1201 Int
VG_(mkstemp
) ( const HChar
* part_of_name
, /*OUT*/HChar
* fullname
)
1206 const HChar
*tmpdir
;
1208 vg_assert(part_of_name
);
1209 vg_assert(fullname
);
1210 n
= VG_(strlen
)(part_of_name
);
1211 vg_assert(n
> 0 && n
< 100);
1213 seed
= (VG_(getpid
)() << 9) ^ VG_(getppid
)();
1215 /* Determine sensible location for temporary files */
1216 tmpdir
= VG_(tmpdir
)();
1222 VG_(sprintf
)( fullname
, mkstemp_format
,
1223 tmpdir
, part_of_name
, VG_(random
)( &seed
));
1225 VG_(printf
)("VG_(mkstemp): trying: %s\n", fullname
);
1227 sres
= VG_(open
)(fullname
,
1228 VKI_O_CREAT
|VKI_O_RDWR
|VKI_O_EXCL
|VKI_O_TRUNC
,
1229 VKI_S_IRUSR
|VKI_S_IWUSR
);
1230 if (sr_isError(sres
)) {
1231 VG_(umsg
)("VG_(mkstemp): failed to create temp file: %s\n", fullname
);
1234 /* VG_(safe_fd) doesn't return if it fails. */
1235 return VG_(safe_fd
)( sr_Res(sres
) );
1241 /* ---------------------------------------------------------------------
1242 Socket-related stuff.
1243 ------------------------------------------------------------------ */
1246 Int
parse_inet_addr_and_port ( const HChar
* str
, UInt
* ip_addr
, UShort
* port
);
1249 Int
my_connect ( Int sockfd
, struct vki_sockaddr_in
* serv_addr
, Int addrlen
);
1251 UInt
VG_(htonl
) ( UInt x
)
1253 # if defined(VG_BIGENDIAN)
1257 (((x
>> 24) & 0xFF) << 0) | (((x
>> 16) & 0xFF) << 8)
1258 | (((x
>> 8) & 0xFF) << 16) | (((x
>> 0) & 0xFF) << 24);
1262 UInt
VG_(ntohl
) ( UInt x
)
1264 # if defined(VG_BIGENDIAN)
1268 (((x
>> 24) & 0xFF) << 0) | (((x
>> 16) & 0xFF) << 8)
1269 | (((x
>> 8) & 0xFF) << 16) | (((x
>> 0) & 0xFF) << 24);
1273 UShort
VG_(htons
) ( UShort x
)
1275 # if defined(VG_BIGENDIAN)
1279 (((x
>> 8) & 0xFF) << 0) | (((x
>> 0) & 0xFF) << 8);
1283 UShort
VG_(ntohs
) ( UShort x
)
1285 # if defined(VG_BIGENDIAN)
1289 (((x
>> 8) & 0xFF) << 0) | (((x
>> 0) & 0xFF) << 8);
1294 /* The main function.
1296 Supplied string contains either an ip address "192.168.0.1" or
1297 an ip address and port pair, "192.168.0.1:1500". Parse these,
1299 -1 if there is a parse error
1300 -2 if no parse error, but specified host:port cannot be opened
1301 the relevant file (socket) descriptor, otherwise.
1304 Int
VG_(connect_via_socket
)( const HChar
* str
)
1306 # if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) || defined(VGO_freebsd)
1308 struct vki_sockaddr_in servAddr
;
1310 UShort port
= VG_CLO_DEFAULT_LOGPORT
;
1311 Bool ok
= parse_inet_addr_and_port(str
, &ip
, &port
);
1316 // VG_(printf)("ip = %d.%d.%d.%d, port %d\n",
1317 // (ip >> 24) & 0xFF, (ip >> 16) & 0xFF,
1318 // (ip >> 8) & 0xFF, ip & 0xFF,
1321 servAddr
.sin_family
= VKI_AF_INET
;
1322 servAddr
.sin_addr
.s_addr
= VG_(htonl
)(ip
);
1323 servAddr
.sin_port
= VG_(htons
)(port
);
1326 sd
= VG_(socket
)(VKI_AF_INET
, VKI_SOCK_STREAM
, 0 /* IPPROTO_IP ? */);
1328 /* this shouldn't happen ... nevertheless */
1332 /* connect to server */
1333 res
= my_connect(sd
, &servAddr
, sizeof(servAddr
));
1335 /* connection failed */
1343 # error "Unknown OS"
1348 /* Let d = one or more digits. Accept either:
1349 d.d.d.d or d.d.d.d:d
1351 static Int
parse_inet_addr_and_port ( const HChar
* str
, UInt
* ip_addr
, UShort
* port
)
1353 # define GET_CH ((*str) ? (*str++) : 0)
1354 UInt ipa
, i
, j
, c
, any
;
1356 for (i
= 0; i
< 4; i
++) {
1361 if (c
< '0' || c
> '9') break;
1362 j
= 10 * j
+ (int)(c
- '0');
1365 if (any
== 0 || j
> 255) goto syntaxerr
;
1366 ipa
= (ipa
<< 8) + j
;
1367 if (i
<= 2 && c
!= '.') goto syntaxerr
;
1369 if (c
== 0 || c
== ':')
1371 if (c
== 0) goto ok
;
1372 if (c
!= ':') goto syntaxerr
;
1377 if (c
< '0' || c
> '9') break;
1378 j
= j
* 10 + (int)(c
- '0');
1380 if (j
> 65535) goto syntaxerr
;
1382 if (any
== 0 || c
!= 0) goto syntaxerr
;
1383 if (j
< 1024) goto syntaxerr
;
1392 // GrP fixme safe_fd?
1393 Int
VG_(socket
) ( Int domain
, Int type
, Int protocol
)
1395 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1396 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1397 || defined(VGP_s390x_linux)
1403 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_SOCKET
, (UWord
)&args
);
1404 return sr_isError(res
) ? -1 : sr_Res(res
);
1406 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1407 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
1408 || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) || defined(VGO_freebsd)
1410 res
= VG_(do_syscall3
)(__NR_socket
, domain
, type
, protocol
);
1411 return sr_isError(res
) ? -1 : sr_Res(res
);
1413 # elif defined(VGO_darwin)
1415 res
= VG_(do_syscall3
)(__NR_socket
, domain
, type
, protocol
);
1416 if (!sr_isError(res
)) {
1417 // Set SO_NOSIGPIPE so write() returns EPIPE instead of raising SIGPIPE
1420 res2
= VG_(do_syscall5
)(__NR_setsockopt
, sr_Res(res
), VKI_SOL_SOCKET
,
1421 VKI_SO_NOSIGPIPE
, (UWord
)&optval
,
1423 // ignore setsockopt() error
1425 return sr_isError(res
) ? -1 : sr_Res(res
);
1427 # elif defined(VGO_solaris)
1428 /* XXX There doesn't seem to be an easy way to convince the send syscall to
1429 only return EPIPE instead of raising SIGPIPE. EPIPE is only returned if
1430 SM_KERNEL is set on the socket. Without serious hackery it looks we
1431 can't set this flag.
1433 Should we wrap the send syscall below into sigprocmask calls to block
1437 res
= VG_(do_syscall5
)(__NR_so_socket
, domain
, type
, protocol
,
1438 0 /*devpath*/, VKI_SOV_DEFAULT
/*version*/);
1439 return sr_isError(res
) ? -1 : sr_Res(res
);
1442 # error "Unknown arch"
1448 Int
my_connect ( Int sockfd
, struct vki_sockaddr_in
* serv_addr
, Int addrlen
)
1450 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1451 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1452 || defined(VGP_s390x_linux)
1456 args
[1] = (UWord
)serv_addr
;
1458 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_CONNECT
, (UWord
)&args
);
1459 return sr_isError(res
) ? -1 : sr_Res(res
);
1461 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1462 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
1463 || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) || defined(VGO_freebsd)
1465 res
= VG_(do_syscall3
)(__NR_connect
, sockfd
, (UWord
)serv_addr
, addrlen
);
1466 return sr_isError(res
) ? -1 : sr_Res(res
);
1468 # elif defined(VGO_darwin)
1470 res
= VG_(do_syscall3
)(__NR_connect_nocancel
,
1471 sockfd
, (UWord
)serv_addr
, addrlen
);
1472 return sr_isError(res
) ? -1 : sr_Res(res
);
1474 # elif defined(VGO_solaris)
1476 res
= VG_(do_syscall4
)(__NR_connect
, sockfd
, (UWord
)serv_addr
, addrlen
,
1477 VKI_SOV_DEFAULT
/*version*/);
1478 return sr_isError(res
) ? -1 : sr_Res(res
);
1481 # error "Unknown arch"
1485 Int
VG_(write_socket
)( Int sd
, const void *msg
, Int count
)
1487 /* This is actually send(). */
1489 /* For Linux, VKI_MSG_NOSIGNAL is a request not to send SIGPIPE on
1490 errors on stream oriented sockets when the other end breaks the
1491 connection. The EPIPE error is still returned.
1493 For Darwin, VG_(socket)() sets SO_NOSIGPIPE to get EPIPE instead of
1496 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1497 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1498 || defined(VGP_s390x_linux)
1502 args
[1] = (UWord
)msg
;
1504 args
[3] = VKI_MSG_NOSIGNAL
;
1505 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_SEND
, (UWord
)&args
);
1506 return sr_isError(res
) ? -1 : sr_Res(res
);
1508 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1509 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
1510 || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) || defined(VGO_freebsd)
1512 res
= VG_(do_syscall6
)(__NR_sendto
, sd
, (UWord
)msg
,
1513 count
, VKI_MSG_NOSIGNAL
, 0,0);
1514 return sr_isError(res
) ? -1 : sr_Res(res
);
1516 # elif defined(VGP_x86_darwin) || defined(VGP_amd64_darwin)
1518 res
= VG_(do_syscall3
)(__NR_write_nocancel
, sd
, (UWord
)msg
, count
);
1519 return sr_isError(res
) ? -1 : sr_Res(res
);
1521 # elif defined(VGO_solaris)
1523 res
= VG_(do_syscall4
)(__NR_send
, sd
, (UWord
)msg
, count
, 0 /*flags*/);
1524 return sr_isError(res
) ? -1 : sr_Res(res
);
1527 # error "Unknown platform"
1531 Int
VG_(getsockname
) ( Int sd
, struct vki_sockaddr
*name
, Int
*namelen
)
1533 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1534 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1535 || defined(VGP_s390x_linux) \
1536 || defined(VGP_mips32_linux)
1540 args
[1] = (UWord
)name
;
1541 args
[2] = (UWord
)namelen
;
1542 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_GETSOCKNAME
, (UWord
)&args
);
1543 return sr_isError(res
) ? -1 : sr_Res(res
);
1545 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1546 || defined(VGP_mips64_linux) || defined(VGP_arm64_linux) \
1547 || defined(VGP_nanomips_linux) || defined(VGO_freebsd) \
1548 || defined(VGP_mips64_linux) || defined(VGP_arm64_linux)
1550 res
= VG_(do_syscall3
)( __NR_getsockname
,
1551 (UWord
)sd
, (UWord
)name
, (UWord
)namelen
);
1552 return sr_isError(res
) ? -1 : sr_Res(res
);
1554 # elif defined(VGO_darwin)
1556 res
= VG_(do_syscall3
)( __NR_getsockname
,
1557 (UWord
)sd
, (UWord
)name
, (UWord
)namelen
);
1558 return sr_isError(res
) ? -1 : sr_Res(res
);
1560 # elif defined(VGO_solaris)
1562 res
= VG_(do_syscall4
)(__NR_getsockname
, sd
, (UWord
)name
, (UWord
)namelen
,
1563 VKI_SOV_DEFAULT
/*version*/);
1564 return sr_isError(res
) ? -1 : sr_Res(res
);
1567 # error "Unknown platform"
1571 Int
VG_(getpeername
) ( Int sd
, struct vki_sockaddr
*name
, Int
*namelen
)
1573 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1574 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1575 || defined(VGP_s390x_linux) \
1576 || defined(VGP_mips32_linux)
1580 args
[1] = (UWord
)name
;
1581 args
[2] = (UWord
)namelen
;
1582 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_GETPEERNAME
, (UWord
)&args
);
1583 return sr_isError(res
) ? -1 : sr_Res(res
);
1585 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1586 || defined(VGP_mips64_linux) || defined(VGP_arm64_linux) \
1587 || defined(VGP_nanomips_linux) || defined(VGO_freebsd)
1589 res
= VG_(do_syscall3
)( __NR_getpeername
,
1590 (UWord
)sd
, (UWord
)name
, (UWord
)namelen
);
1591 return sr_isError(res
) ? -1 : sr_Res(res
);
1593 # elif defined(VGO_darwin)
1595 res
= VG_(do_syscall3
)( __NR_getpeername
,
1596 (UWord
)sd
, (UWord
)name
, (UWord
)namelen
);
1597 return sr_isError(res
) ? -1 : sr_Res(res
);
1599 # elif defined(VGO_solaris)
1601 res
= VG_(do_syscall4
)(__NR_getpeername
, sd
, (UWord
)name
, (UWord
)namelen
,
1602 VKI_SOV_DEFAULT
/*version*/);
1603 return sr_isError(res
) ? -1 : sr_Res(res
);
1606 # error "Unknown platform"
1610 Int
VG_(getsockopt
) ( Int sd
, Int level
, Int optname
, void *optval
,
1613 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1614 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1615 || defined(VGP_s390x_linux)
1621 args
[3] = (UWord
)optval
;
1622 args
[4] = (UWord
)optlen
;
1623 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_GETSOCKOPT
, (UWord
)&args
);
1624 return sr_isError(res
) ? -1 : sr_Res(res
);
1626 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1627 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
1628 || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) \
1629 || defined(VGO_freebsd)
1631 res
= VG_(do_syscall5
)( __NR_getsockopt
,
1632 (UWord
)sd
, (UWord
)level
, (UWord
)optname
,
1633 (UWord
)optval
, (UWord
)optlen
);
1634 return sr_isError(res
) ? -1 : sr_Res(res
);
1636 # elif defined(VGO_darwin)
1638 res
= VG_(do_syscall5
)( __NR_getsockopt
,
1639 (UWord
)sd
, (UWord
)level
, (UWord
)optname
,
1640 (UWord
)optval
, (UWord
)optlen
);
1641 return sr_isError(res
) ? -1 : sr_Res(res
);
1643 # elif defined(VGO_solaris)
1645 res
= VG_(do_syscall6
)(__NR_getsockopt
, sd
, level
, optname
, (UWord
)optval
,
1646 (UWord
)optlen
, VKI_SOV_DEFAULT
/*version*/);
1647 return sr_isError(res
) ? -1 : sr_Res(res
);
1650 # error "Unknown platform"
1655 Int
VG_(setsockopt
) ( Int sd
, Int level
, Int optname
, void *optval
,
1658 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1659 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1660 || defined(VGP_s390x_linux)
1666 args
[3] = (UWord
)optval
;
1667 args
[4] = (UWord
)optlen
;
1668 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_SETSOCKOPT
, (UWord
)&args
);
1669 return sr_isError(res
) ? -1 : sr_Res(res
);
1671 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1672 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
1673 || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
1675 res
= VG_(do_syscall5
)( __NR_setsockopt
,
1676 (UWord
)sd
, (UWord
)level
, (UWord
)optname
,
1677 (UWord
)optval
, (UWord
)optlen
);
1678 return sr_isError(res
) ? -1 : sr_Res(res
);
1680 # elif defined(VGO_darwin) || defined(VGO_freebsd)
1682 res
= VG_(do_syscall5
)( __NR_setsockopt
,
1683 (UWord
)sd
, (UWord
)level
, (UWord
)optname
,
1684 (UWord
)optval
, (UWord
)optlen
);
1685 return sr_isError(res
) ? -1 : sr_Res(res
);
1687 # elif defined(VGO_solaris)
1689 res
= VG_(do_syscall6
)( __NR_setsockopt
,
1690 (UWord
)sd
, (UWord
)level
, (UWord
)optname
,
1691 (UWord
)optval
, (UWord
)optlen
,
1692 VKI_SOV_DEFAULT
/*version*/ );
1693 return sr_isError(res
) ? -1 : sr_Res(res
);
1696 # error "Unknown platform"
1701 const HChar
*VG_(basename
)(const HChar
*path
)
1703 static HChar
*buf
= NULL
;
1704 static SizeT buf_len
= 0;
1705 const HChar
*p
, *end
;
1708 0 == VG_(strcmp
)(path
, ""))
1713 p
= path
+ VG_(strlen
)(path
);
1714 while (p
> path
&& *p
== '/') {
1715 // skip all trailing '/'
1719 if (p
== path
&& *p
== '/') return "/"; // all slashes
1723 while (p
> path
&& *p
!= '/') {
1730 SizeT need
= end
-p
+1 + 1;
1731 if (need
> buf_len
) {
1732 buf_len
= (buf_len
== 0) ? 500 : need
;
1733 buf
= VG_(realloc
)("basename", buf
, buf_len
);
1735 VG_(strncpy
)(buf
, p
, end
-p
+1);
1736 buf
[end
-p
+1] = '\0';
1742 const HChar
*VG_(dirname
)(const HChar
*path
)
1744 static HChar
*buf
= NULL
;
1745 static SizeT buf_len
= 0;
1750 0 == VG_(strcmp
)(path
, "") ||
1751 0 == VG_(strcmp
)(path
, "/"))
1756 p
= path
+ VG_(strlen
)(path
);
1757 while (p
> path
&& *p
== '/') {
1758 // skip all trailing '/'
1762 while (p
> path
&& *p
!= '/') {
1768 if (*p
== '/') return "/"; // all slashes
1769 else return "."; // no slashes
1772 while (p
> path
&& *p
== '/') {
1777 SizeT need
= p
-path
+1 + 1;
1778 if (need
> buf_len
) {
1779 buf_len
= (buf_len
== 0) ? 500 : need
;
1780 buf
= VG_(realloc
)("dirname", buf
, buf_len
);
1782 VG_(strncpy
)(buf
, path
, p
-path
+1);
1783 buf
[p
-path
+1] = '\0';
1788 #if defined(VGO_freebsd)
1790 * I did look at nicking this from FreeBSD, it's fairly easy to port
1791 * but I was put off by the copyright and 3-clause licence
1792 * Then I looked at nicking it from glibc but that is full of
1793 * macros private functions and conditions for Windows.
1794 * So I gave up as it is only for FreeBSD 11 and 12.
1796 * It is somewhat hard-coded for sysctl_kern_proc_pathname
1797 * and PRE(sys___sysctl) assuming resolved has
1798 * VKI_PATH_MAX space.
1800 Bool
VG_(realpath
)(const HChar
*path
, HChar
*resolved
)
1803 vg_assert(resolved
);
1804 #if (FREEBSD_VERS >= FREEBSD_13_0)
1805 return !sr_isError(VG_(do_syscall5
)(__NR___realpathat
, VKI_AT_FDCWD
, (RegWord
)path
, (RegWord
)resolved
, VKI_PATH_MAX
, 0));
1807 // poor man's realpath
1808 const HChar
*resolved_name
;
1809 HChar tmp
[VKI_PATH_MAX
];
1811 struct vg_stat statbuf
;
1812 SysRes res
= VG_(lstat
)(path
, &statbuf
);
1814 if (sr_isError(res
)) {
1818 if (VKI_S_ISLNK(statbuf
.mode
)) {
1819 SizeT link_len
= VG_(readlink
)(path
, tmp
, VKI_PATH_MAX
);
1820 tmp
[link_len
] = '\0';
1821 resolved_name
= tmp
;
1824 resolved_name
= path
;
1827 if (resolved_name
[0] != '/') {
1829 if (resolved_name
[0] == '.' && resolved_name
[1] == '/') {
1832 VG_(snprintf
)(resolved
, VKI_PATH_MAX
, "%s/%s", VG_(get_startup_wd
)(), resolved_name
);
1834 VG_(snprintf
)(resolved
, VKI_PATH_MAX
, "%s", resolved_name
);
1843 /*--------------------------------------------------------------------*/
1845 /*--------------------------------------------------------------------*/