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
));
63 /* Set the close-on-exec flag for this fd. */
64 VG_(fcntl
)(newfd
, VKI_F_SETFD
, VKI_FD_CLOEXEC
);
66 vg_assert(newfd
>= VG_(fd_hard_limit
));
70 #if defined(VGO_freebsd)
71 #define M_FILEDESC_BUF 1000000
72 static Char filedesc_buf
[M_FILEDESC_BUF
];
75 /* Given a file descriptor, attempt to deduce its filename. To do
76 this, we use /proc/self/fd/<FD>. If this doesn't point to a file,
77 or if it doesn't exist, we return False.
78 Upon successful completion *result contains the filename. The
79 filename will be overwritten with the next invocation so callers
80 need to copy the filename if needed. *result is NULL if the filename
82 Bool
VG_(resolve_filename
) ( Int fd
, const HChar
** result
)
84 # if defined(VGO_linux) || defined(VGO_solaris)
85 static HChar
*buf
= NULL
;
86 static SizeT bufsiz
= 0;
88 if (buf
== NULL
) { // first time
90 buf
= VG_(malloc
)("resolve_filename", bufsiz
);
93 HChar tmp
[64]; // large enough
95 # if defined(VGO_linux)
96 VG_(sprintf
)(tmp
, "/proc/self/fd/%d", fd
);
97 # elif defined(VGO_solaris)
98 VG_(sprintf
)(tmp
, "/proc/self/path/%d", fd
);
103 SSizeT res
= VG_(readlink
)(tmp
, buf
, bufsiz
);
105 if (res
== bufsiz
) { // buffer too small; increase and retry
107 buf
= VG_(realloc
)("resolve_filename", buf
, bufsiz
);
110 vg_assert(bufsiz
> res
); // paranoia
111 if (buf
[0] != '/') break;
121 #elif defined(VGO_freebsd)
126 struct vki_kinfo_file
*kf
;
127 static HChar
*buf
= NULL
;
128 static SizeT bufsiz
= 0;
130 if (buf
== NULL
) { // first time
132 buf
= VG_(malloc
)("resolve_filename", bufsiz
);
135 mib
[0] = VKI_CTL_KERN
;
136 mib
[1] = VKI_KERN_PROC
;
137 mib
[2] = VKI_KERN_PROC_FILEDESC
;
138 mib
[3] = sr_Res(VG_(do_syscall0
)(__NR_getpid
));
139 len
= sizeof(filedesc_buf
);
140 sres
= VG_(do_syscall6
)(__NR___sysctl
, (UWord
)mib
, 4, (UWord
)filedesc_buf
,
142 if (sr_isError(sres
)) {
143 VG_(debugLog
)(0, "sysctl(kern.proc.filedesc)", "%s\n", VG_(strerror
)(sr_Err(sres
)));
146 /* Walk though the list. */
148 eb
= filedesc_buf
+ len
;
150 kf
= (struct vki_kinfo_file
*)bp
;
153 bp
+= kf
->kf_structsize
;
155 if (bp
>= eb
|| *kf
->kf_path
== '\0')
156 VG_(strncpy
)( buf
, "[unknown]", bufsiz
);
158 VG_(strncpy
)( buf
, kf
->kf_path
, bufsiz
);
161 # elif defined(VGO_darwin)
162 HChar tmp
[VKI_MAXPATHLEN
+1];
163 if (0 == VG_(fcntl
)(fd
, VKI_F_GETPATH
, (UWord
)tmp
)) {
164 static HChar
*buf
= NULL
;
167 buf
= VG_(malloc
)("resolve_filename", VKI_MAXPATHLEN
+1);
168 VG_(strcpy
)( buf
, tmp
);
171 if (buf
[0] == '/') return True
;
182 #if defined(VGO_freebsd)
184 /* This should only be called after a successful call to
185 * Bool VG_(resolve_filename) ( Int fd, const HChar** result )
186 * so that filedesc_buf is still valid for fd */
187 Bool
VG_(resolve_filemode
) ( Int fd
, Int
* result
)
190 struct vki_kinfo_file
*kf
;
192 /* Walk though the list. */
194 eb
= filedesc_buf
+ sizeof(filedesc_buf
);
196 kf
= (struct vki_kinfo_file
*)bp
;
199 bp
+= kf
->kf_structsize
;
204 *result
= kf
->kf_flags
;
210 SysRes
VG_(mknod
) ( const HChar
* pathname
, Int mode
, UWord dev
)
212 # if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
213 /* ARM64 wants to use __NR_mknodat rather than __NR_mknod. */
214 SysRes res
= VG_(do_syscall4
)(__NR_mknodat
,
215 VKI_AT_FDCWD
, (UWord
)pathname
, mode
, dev
);
216 # elif defined(VGO_linux) || defined(VGO_darwin)
217 SysRes res
= VG_(do_syscall3
)(__NR_mknod
,
218 (UWord
)pathname
, mode
, dev
);
219 # elif defined(VGO_freebsd)
220 SysRes res
= VG_(do_syscall3
)(__NR_freebsd11_mknod
,
221 (UWord
)pathname
, mode
, dev
);
222 # elif defined(VGO_solaris)
223 SysRes res
= VG_(do_syscall4
)(__NR_mknodat
,
224 VKI_AT_FDCWD
, (UWord
)pathname
, mode
, dev
);
231 SysRes
VG_(open
) ( const HChar
* pathname
, Int flags
, Int mode
)
233 # if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
234 /* ARM64 wants to use __NR_openat rather than __NR_open. */
235 SysRes res
= VG_(do_syscall4
)(__NR_openat
,
236 VKI_AT_FDCWD
, (UWord
)pathname
, flags
, mode
);
237 # elif defined(VGO_linux) || defined(VGO_freebsd)
238 SysRes res
= VG_(do_syscall3
)(__NR_open
,
239 (UWord
)pathname
, flags
, mode
);
240 # elif defined(VGO_darwin)
241 SysRes res
= VG_(do_syscall3
)(__NR_open_nocancel
,
242 (UWord
)pathname
, flags
, mode
);
243 # elif defined(VGO_solaris)
244 SysRes res
= VG_(do_syscall4
)(__NR_openat
,
245 VKI_AT_FDCWD
, (UWord
)pathname
, flags
, mode
);
252 Int
VG_(fd_open
) (const HChar
* pathname
, Int flags
, Int mode
)
255 sr
= VG_(open
) (pathname
, flags
, mode
);
262 void VG_(close
) ( Int fd
)
264 /* Hmm. Return value is not checked. That's uncool. */
265 # if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd)
266 (void)VG_(do_syscall1
)(__NR_close
, fd
);
267 # elif defined(VGO_darwin)
268 (void)VG_(do_syscall1
)(__NR_close_nocancel
, fd
);
274 Int
VG_(read
) ( Int fd
, void* buf
, Int count
)
277 # if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd)
278 SysRes res
= VG_(do_syscall3
)(__NR_read
, fd
, (UWord
)buf
, count
);
279 # elif defined(VGO_darwin)
280 SysRes res
= VG_(do_syscall3
)(__NR_read_nocancel
, fd
, (UWord
)buf
, count
);
284 if (sr_isError(res
)) {
285 ret
= - (Int
)(Word
)sr_Err(res
);
288 ret
= (Int
)(Word
)sr_Res(res
);
294 Int
VG_(write
) ( Int fd
, const void* buf
, Int count
)
297 # if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd)
298 SysRes res
= VG_(do_syscall3
)(__NR_write
, fd
, (UWord
)buf
, count
);
299 # elif defined(VGO_darwin)
300 SysRes res
= VG_(do_syscall3
)(__NR_write_nocancel
, fd
, (UWord
)buf
, count
);
304 if (sr_isError(res
)) {
305 ret
= - (Int
)(Word
)sr_Err(res
);
308 ret
= (Int
)(Word
)sr_Res(res
);
315 Int
VG_(pipe
) ( Int fd
[2] )
317 # if defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
318 /* __NR_pipe has a strange return convention on mips32-linux. */
319 SysRes res
= VG_(do_syscall1
)(__NR_pipe
, (UWord
)fd
);
320 if (!sr_isError(res
)) {
321 fd
[0] = (Int
)sr_Res(res
);
322 fd
[1] = (Int
)sr_ResEx(res
);
327 # elif defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
328 SysRes res
= VG_(do_syscall2
)(__NR_pipe2
, (UWord
)fd
, 0);
329 return sr_isError(res
) ? -1 : 0;
330 # elif defined(VGO_linux)
331 SysRes res
= VG_(do_syscall1
)(__NR_pipe
, (UWord
)fd
);
332 return sr_isError(res
) ? -1 : 0;
333 # elif defined(VGO_freebsd)
334 SysRes res
= VG_(do_syscall0
)(__NR_freebsd10_pipe
);
335 if (!sr_isError(res
)) {
337 fd
[1] = sr_ResHI(res
);
339 return sr_isError(res
) ? -1 : 0;
340 # elif defined(VGO_darwin)
341 /* __NR_pipe is UX64, so produces a double-word result */
342 SysRes res
= VG_(do_syscall0
)(__NR_pipe
);
343 if (!sr_isError(res
)) {
344 fd
[0] = (Int
)sr_Res(res
);
345 fd
[1] = (Int
)sr_ResHI(res
);
347 return sr_isError(res
) ? -1 : 0;
348 # elif defined(VGO_solaris)
349 # if defined(SOLARIS_NEW_PIPE_SYSCALL)
350 SysRes res
= VG_(do_syscall2
)(__NR_pipe
, (UWord
)fd
, 0);
351 return sr_isError(res
) ? -1 : 0;
353 SysRes res
= VG_(do_syscall0
)(__NR_pipe
);
354 if (!sr_isError(res
)) {
355 fd
[0] = (Int
)sr_Res(res
);
356 fd
[1] = (Int
)sr_ResHI(res
);
358 return sr_isError(res
) ? -1 : 0;
365 Off64T
VG_(lseek
) ( Int fd
, Off64T offset
, Int whence
)
367 # if defined(VGO_linux) || defined(VGP_amd64_darwin) || defined(VGP_amd64_freebsd)
368 # if defined(__NR__llseek)
370 SysRes res
= VG_(do_syscall5
)(__NR__llseek
, fd
,
371 offset
>> 32, offset
& 0xffffffff,
372 (UWord
)&result
, whence
);
373 return sr_isError(res
) ? (-1) : result
;
375 SysRes res
= VG_(do_syscall3
)(__NR_lseek
, fd
, offset
, whence
);
376 vg_assert(sizeof(Off64T
) == sizeof(sr_Res(res
)));
377 return sr_isError(res
) ? (-1) : sr_Res(res
);
379 # elif defined(VGP_x86_darwin) || defined(VGP_x86_freebsd)
380 SysRes res
= VG_(do_syscall4
)(__NR_lseek
, fd
,
381 offset
& 0xffffffff, offset
>> 32, whence
);
382 return sr_isError(res
) ? (-1) : sr_Res(res
);
383 # elif defined(VGP_x86_solaris)
384 SysRes res
= VG_(do_syscall4
)(__NR_llseek
, fd
,
385 offset
& 0xffffffff, offset
>> 32, whence
);
386 return sr_isError(res
) ? (-1) : ((ULong
)sr_ResHI(res
) << 32 | sr_Res(res
));
387 # elif defined(VGP_amd64_solaris)
388 SysRes res
= VG_(do_syscall3
)(__NR_lseek
, fd
, offset
, whence
);
389 vg_assert(sizeof(Off64T
) == sizeof(Word
));
390 return sr_isError(res
) ? (-1) : sr_Res(res
);
392 # error "Unknown plat"
394 /* if you change the error-reporting conventions of this, also
395 change all usage points. */
399 /* stat/fstat support. It's uggerly. We have impedance-match into a
400 'struct vg_stat' in order to have a single structure that callers
401 can use consistently on all platforms. */
403 #define TRANSLATE_TO_vg_stat(_p_vgstat, _p_vkistat) \
405 (_p_vgstat)->dev = (ULong)( (_p_vkistat)->st_dev ); \
406 (_p_vgstat)->ino = (ULong)( (_p_vkistat)->st_ino ); \
407 (_p_vgstat)->nlink = (ULong)( (_p_vkistat)->st_nlink ); \
408 (_p_vgstat)->mode = (UInt) ( (_p_vkistat)->st_mode ); \
409 (_p_vgstat)->uid = (UInt) ( (_p_vkistat)->st_uid ); \
410 (_p_vgstat)->gid = (UInt) ( (_p_vkistat)->st_gid ); \
411 (_p_vgstat)->rdev = (ULong)( (_p_vkistat)->st_rdev ); \
412 (_p_vgstat)->size = (Long) ( (_p_vkistat)->st_size ); \
413 (_p_vgstat)->blksize = (ULong)( (_p_vkistat)->st_blksize ); \
414 (_p_vgstat)->blocks = (ULong)( (_p_vkistat)->st_blocks ); \
415 (_p_vgstat)->atime = (ULong)( (_p_vkistat)->st_atime ); \
416 (_p_vgstat)->atime_nsec = (ULong)( (_p_vkistat)->st_atime_nsec ); \
417 (_p_vgstat)->mtime = (ULong)( (_p_vkistat)->st_mtime ); \
418 (_p_vgstat)->mtime_nsec = (ULong)( (_p_vkistat)->st_mtime_nsec ); \
419 (_p_vgstat)->ctime = (ULong)( (_p_vkistat)->st_ctime ); \
420 (_p_vgstat)->ctime_nsec = (ULong)( (_p_vkistat)->st_ctime_nsec ); \
423 #define TRANSLATE_statx_TO_vg_stat(_p_vgstat, _p_vkistat) \
425 (_p_vgstat)->dev = VG_MAKEDEV( (_p_vkistat)->stx_dev_major, \
426 (_p_vkistat)->stx_dev_minor ); \
427 (_p_vgstat)->ino = (ULong)( (_p_vkistat)->stx_ino ); \
428 (_p_vgstat)->nlink = (ULong)( (_p_vkistat)->stx_nlink ); \
429 (_p_vgstat)->mode = (UInt) ( (_p_vkistat)->stx_mode ); \
430 (_p_vgstat)->uid = (UInt) ( (_p_vkistat)->stx_uid ); \
431 (_p_vgstat)->gid = (UInt) ( (_p_vkistat)->stx_gid ); \
432 (_p_vgstat)->rdev = VG_MAKEDEV( (_p_vkistat)->stx_rdev_major, \
433 (_p_vkistat)->stx_rdev_minor ); \
434 (_p_vgstat)->size = (Long) ( (_p_vkistat)->stx_size ); \
435 (_p_vgstat)->blksize = (ULong)( (_p_vkistat)->stx_blksize ); \
436 (_p_vgstat)->blocks = (ULong)( (_p_vkistat)->stx_blocks ); \
437 (_p_vgstat)->atime = (ULong)( (_p_vkistat)->stx_atime.tv_sec ); \
438 (_p_vgstat)->atime_nsec = (ULong)( (_p_vkistat)->stx_atime.tv_nsec ); \
439 (_p_vgstat)->mtime = (ULong)( (_p_vkistat)->stx_mtime.tv_sec ); \
440 (_p_vgstat)->mtime_nsec = (ULong)( (_p_vkistat)->stx_mtime.tv_nsec ); \
441 (_p_vgstat)->ctime = (ULong)( (_p_vkistat)->stx_ctime.tv_sec ); \
442 (_p_vgstat)->ctime_nsec = (ULong)( (_p_vkistat)->stx_ctime.tv_nsec ); \
445 SysRes
VG_(stat
) ( const HChar
* file_name
, struct vg_stat
* vgbuf
)
448 VG_(memset
)(vgbuf
, 0, sizeof(*vgbuf
));
450 # if defined(VGO_linux)
451 /* On Linux, first try with statx. If that doesn't work out, fall back to
452 the stat64 or vanilla version. */
453 { struct vki_statx buf
;
454 res
= VG_(do_syscall5
)(__NR_statx
, VKI_AT_FDCWD
, (UWord
)file_name
, 0,
455 VKI_STATX_ALL
, (UWord
)&buf
);
456 if (!(sr_isError(res
) && sr_Err(res
) == VKI_ENOSYS
)) {
457 /* Success, or any failure except ENOSYS */
458 if (!sr_isError(res
))
459 TRANSLATE_statx_TO_vg_stat(vgbuf
, &buf
);
464 # if defined(VGO_linux) || defined(VGO_darwin)
465 /* Try with stat64. This is the second candidate on Linux, and the first
466 one on Darwin. If that doesn't work out, fall back to vanilla version.
468 # if defined(__NR_stat64)
469 { struct vki_stat64 buf64
;
470 res
= VG_(do_syscall2
)(__NR_stat64
, (UWord
)file_name
, (UWord
)&buf64
);
471 if (!(sr_isError(res
) && sr_Err(res
) == VKI_ENOSYS
)) {
472 /* Success, or any failure except ENOSYS */
473 if (!sr_isError(res
))
474 TRANSLATE_TO_vg_stat(vgbuf
, &buf64
);
478 # endif /* defined(__NR_stat64) */
479 # if defined(__NR_stat) || defined(VGP_arm64_linux)
480 /* This is the fallback ("vanilla version"). */
481 { struct vki_stat buf
;
482 # if defined(VGP_arm64_linux)
483 res
= VG_(do_syscall3
)(__NR3264_fstatat
, VKI_AT_FDCWD
,
484 (UWord
)file_name
, (UWord
)&buf
);
486 res
= VG_(do_syscall2
)(__NR_stat
, (UWord
)file_name
, (UWord
)&buf
);
488 if (!sr_isError(res
))
489 TRANSLATE_TO_vg_stat(vgbuf
, &buf
);
493 # elif defined(VGO_solaris)
495 # if defined(VGP_x86_solaris)
496 struct vki_stat64 buf64
;
497 res
= VG_(do_syscall4
)(__NR_fstatat64
, VKI_AT_FDCWD
, (UWord
)file_name
,
499 # elif defined(VGP_amd64_solaris)
500 struct vki_stat buf64
;
501 res
= VG_(do_syscall4
)(__NR_fstatat
, VKI_AT_FDCWD
, (UWord
)file_name
,
504 # error "Unknown platform"
506 if (!sr_isError(res
))
507 TRANSLATE_TO_vg_stat(vgbuf
, &buf64
);
510 # elif defined(VGO_freebsd)
512 struct vki_freebsd11_stat buf
;
513 #if (FREEBSD_VERS >= FREEBSD_12)
514 res
= VG_(do_syscall2
)(__NR_freebsd11_stat
, (UWord
)file_name
, (UWord
)&buf
);
516 res
= VG_(do_syscall2
)(__NR_stat
, (UWord
)file_name
, (UWord
)&buf
);
518 if (!sr_isError(res
))
519 TRANSLATE_TO_vg_stat(vgbuf
, &buf
);
527 Int
VG_(fstat
) ( Int fd
, struct vg_stat
* vgbuf
)
530 VG_(memset
)(vgbuf
, 0, sizeof(*vgbuf
));
532 # if defined(VGO_linux)
533 /* On Linux, first try with statx. If that doesn't work out, fall back to
534 the fstat64 or vanilla version. */
535 { struct vki_statx buf
;
536 const char* file_name
= "";
537 res
= VG_(do_syscall5
)(__NR_statx
, fd
, (RegWord
)file_name
,
538 VKI_AT_EMPTY_PATH
, VKI_STATX_ALL
, (RegWord
)&buf
);
539 if (!(sr_isError(res
) && sr_Err(res
) == VKI_ENOSYS
)) {
540 /* Success, or any failure except ENOSYS */
541 if (!sr_isError(res
))
542 TRANSLATE_statx_TO_vg_stat(vgbuf
, &buf
);
543 return sr_isError(res
) ? (-1) : 0;
547 # if defined(VGO_linux) || defined(VGO_darwin)
548 /* Try with fstat64. This is the second candidate on Linux, and the first
549 one on Darwin. If that doesn't work out, fall back to vanilla version.
551 # if defined(__NR_fstat64)
552 { struct vki_stat64 buf64
;
553 res
= VG_(do_syscall2
)(__NR_fstat64
, (UWord
)fd
, (UWord
)&buf64
);
554 if (!(sr_isError(res
) && sr_Err(res
) == VKI_ENOSYS
)) {
555 /* Success, or any failure except ENOSYS */
556 if (!sr_isError(res
))
557 TRANSLATE_TO_vg_stat(vgbuf
, &buf64
);
558 return sr_isError(res
) ? (-1) : 0;
561 # endif /* defined(__NR_fstat64) */
562 # if defined(__NR_fstat)
563 { struct vki_stat buf
;
564 res
= VG_(do_syscall2
)(__NR_fstat
, (RegWord
)fd
, (RegWord
)(Addr
)&buf
);
565 if (!sr_isError(res
))
566 TRANSLATE_TO_vg_stat(vgbuf
, &buf
);
567 return sr_isError(res
) ? (-1) : 0;
570 # elif defined(VGO_solaris)
572 # if defined(VGP_x86_solaris)
573 struct vki_stat64 buf64
;
574 res
= VG_(do_syscall4
)(__NR_fstatat64
, (UWord
)fd
, 0, (UWord
)&buf64
, 0);
575 # elif defined(VGP_amd64_solaris)
576 struct vki_stat buf64
;
577 res
= VG_(do_syscall4
)(__NR_fstatat
, (UWord
)fd
, 0, (UWord
)&buf64
, 0);
579 # error "Unknown platform"
581 if (!sr_isError(res
))
582 TRANSLATE_TO_vg_stat(vgbuf
, &buf64
);
583 return sr_isError(res
) ? (-1) : 0;
585 # elif defined(VGO_freebsd)
587 struct vki_freebsd11_stat buf
;
588 #if (FREEBSD_VERS >= FREEBSD_12)
589 res
= VG_(do_syscall2
)(__NR_freebsd11_fstat
, (RegWord
)fd
, (RegWord
)(Addr
)&buf
);
591 res
= VG_(do_syscall2
)(__NR_fstat
, (RegWord
)fd
, (RegWord
)(Addr
)&buf
);
593 if (!sr_isError(res
)) {
594 TRANSLATE_TO_vg_stat(vgbuf
, &buf
);
596 return sr_isError(res
) ? (-1) : 0;
603 #undef TRANSLATE_TO_vg_stat
604 #undef TRANSLATE_statx_TO_vg_stat
606 Long
VG_(fsize
) ( Int fd
)
609 Int res
= VG_(fstat
)( fd
, &buf
);
610 return (res
== -1) ? (-1LL) : buf
.size
;
613 SysRes
VG_(getxattr
) ( const HChar
* file_name
, const HChar
* attr_name
, Addr attr_value
, SizeT attr_value_len
)
616 #if defined(VGO_linux)
617 res
= VG_(do_syscall4
)(__NR_getxattr
, (UWord
)file_name
, (UWord
)attr_name
,
618 attr_value
, attr_value_len
);
620 res
= VG_(mk_SysRes_Error
)(VKI_ENOSYS
);
625 Bool
VG_(is_dir
) ( const HChar
* f
)
628 SysRes res
= VG_(stat
)(f
, &buf
);
629 return sr_isError(res
) ? False
630 : VKI_S_ISDIR(buf
.mode
) ? True
: False
;
633 SysRes
VG_(dup
) ( Int oldfd
)
635 # if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_freebsd)
636 return VG_(do_syscall1
)(__NR_dup
, oldfd
);
637 # elif defined(VGO_solaris)
638 return VG_(do_syscall3
)(__NR_fcntl
, oldfd
, F_DUPFD
, 0);
644 SysRes
VG_(dup2
) ( Int oldfd
, Int newfd
)
646 # if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
647 /* We only have dup3, that means we have to mimic dup2.
648 The only real difference is when oldfd == newfd.
649 dup3 always returns an error, but dup2 returns only an
650 error if the fd is invalid, otherwise it returns newfd. */
651 if (oldfd
== newfd
) {
652 if (VG_(fcntl
)(oldfd
, VKI_F_GETFL
, 0) == -1)
653 return VG_(mk_SysRes_Error
)(VKI_EBADF
);
654 return VG_(mk_SysRes_Success
)(newfd
);
656 return VG_(do_syscall3
)(__NR_dup3
, oldfd
, newfd
, 0);
657 # elif defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_freebsd)
658 return VG_(do_syscall2
)(__NR_dup2
, oldfd
, newfd
);
659 # elif defined(VGO_solaris)
660 return VG_(do_syscall3
)(__NR_fcntl
, oldfd
, F_DUP2FD
, newfd
);
666 /* Returns -1 on error. */
667 Int
VG_(fcntl
) ( Int fd
, Int cmd
, Addr arg
)
669 # if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd)
670 # if defined(VGP_nanomips_linux)
671 SysRes res
= VG_(do_syscall3
)(__NR_fcntl64
, fd
, cmd
, arg
);
673 SysRes res
= VG_(do_syscall3
)(__NR_fcntl
, fd
, cmd
, arg
);
675 # elif defined(VGO_darwin)
676 SysRes res
= VG_(do_syscall3
)(__NR_fcntl_nocancel
, fd
, cmd
, arg
);
680 return sr_isError(res
) ? -1 : sr_Res(res
);
683 Int
VG_(rename
) ( const HChar
* old_name
, const HChar
* new_name
)
685 # if defined(VGO_solaris) || defined(VGP_arm64_linux)
686 SysRes res
= VG_(do_syscall4
)(__NR_renameat
, VKI_AT_FDCWD
, (UWord
)old_name
,
687 VKI_AT_FDCWD
, (UWord
)new_name
);
688 # elif defined(VGP_nanomips_linux)
689 SysRes res
= VG_(do_syscall5
)(__NR_renameat2
, VKI_AT_FDCWD
, (UWord
)old_name
,
690 VKI_AT_FDCWD
, (UWord
)new_name
, 0);
692 # elif defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_freebsd)
693 SysRes res
= VG_(do_syscall2
)(__NR_rename
, (UWord
)old_name
, (UWord
)new_name
);
697 return sr_isError(res
) ? (-1) : 0;
700 Int
VG_(unlink
) ( const HChar
* file_name
)
702 # if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
703 SysRes res
= VG_(do_syscall2
)(__NR_unlinkat
, VKI_AT_FDCWD
,
705 # elif defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_freebsd)
706 SysRes res
= VG_(do_syscall1
)(__NR_unlink
, (UWord
)file_name
);
707 # elif defined(VGO_solaris)
708 SysRes res
= VG_(do_syscall3
)(__NR_unlinkat
, VKI_AT_FDCWD
,
709 (UWord
)file_name
, 0);
713 return sr_isError(res
) ? (-1) : 0;
716 /* The working directory at startup.
717 All that is really needed is to note the cwd at process startup.
718 Hence VG_(record_startup_wd) notes it (in a platform dependent way)
719 and VG_(get_startup_wd) produces the noted value. */
720 static HChar
*startup_wd
;
722 /* Record the process' working directory at startup. Is intended to
723 be called exactly once, at startup, before the working directory
725 void VG_(record_startup_wd
) ( void )
727 # if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd)
728 /* Simple: just ask the kernel */
733 startup_wd
= VG_(realloc
)("startup_wd", startup_wd
, szB
);
734 VG_(memset
)(startup_wd
, 0, szB
);
735 # if defined(VGO_linux) || defined(VGO_solaris)
736 res
= VG_(do_syscall2
)(__NR_getcwd
, (UWord
)startup_wd
, szB
-1);
737 # elif defined(VGO_freebsd)
738 res
= VG_(do_syscall2
)(__NR___getcwd
, (UWord
)startup_wd
, szB
-1);
740 } while (sr_isError(res
) && sr_Err(res
) == VKI_ERANGE
);
742 if (sr_isError(res
)) {
743 VG_(free
)(startup_wd
);
748 vg_assert(startup_wd
[szB
-1] == 0);
750 # elif defined(VGO_darwin)
751 /* We can't ask the kernel, so instead rely on launcher-*.c to
752 tell us the startup path. Note the env var is keyed to the
753 parent's PID, not ours, since our parent is the launcher
755 { HChar envvar
[100]; // large enough
757 VG_(memset
)(envvar
, 0, sizeof(envvar
));
758 VG_(sprintf
)(envvar
, "VALGRIND_STARTUP_PWD_%d_XYZZY",
759 (Int
)VG_(getppid
)());
760 wd
= VG_(getenv
)( envvar
);
763 SizeT need
= VG_(strlen
)(wd
) + 1;
764 startup_wd
= VG_(malloc
)("startup_wd", need
);
765 VG_(strcpy
)(startup_wd
, wd
);
772 /* Return the previously acquired startup_wd or NULL. */
773 const HChar
*VG_(get_startup_wd
) ( void )
778 SysRes
VG_(poll
) (struct vki_pollfd
*fds
, Int nfds
, Int timeout
)
781 # if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
782 /* ARM64 wants to use __NR_ppoll rather than __NR_poll. */
783 struct vki_timespec timeout_ts
;
785 timeout_ts
.tv_sec
= timeout
/ 1000;
786 timeout_ts
.tv_nsec
= ((long)timeout
% 1000) * 1000000;
788 res
= VG_(do_syscall4
)(__NR_ppoll
,
790 (UWord
)(timeout
>= 0 ? &timeout_ts
: NULL
),
792 # elif defined(VGO_linux)
793 res
= VG_(do_syscall3
)(__NR_poll
, (UWord
)fds
, nfds
, timeout
);
794 # elif defined(VGO_freebsd)
795 res
= VG_(do_syscall3
)(__NR_poll
, (UWord
)fds
, nfds
, timeout
);
796 # elif defined(VGO_darwin)
797 res
= VG_(do_syscall3
)(__NR_poll_nocancel
, (UWord
)fds
, nfds
, timeout
);
798 # elif defined(VGO_solaris)
799 struct vki_timespec ts
;
800 struct vki_timespec
*tsp
;
805 ts
.tv_sec
= timeout
/ 1000;
806 ts
.tv_nsec
= (timeout
% 1000) * 1000000;
810 res
= VG_(do_syscall4
)(__NR_pollsys
, (UWord
)fds
, nfds
, (UWord
)tsp
, 0);
818 /* Performs the readlink operation and puts the result into 'buf'.
819 Note, that the string in 'buf' is *not* null-terminated. The function
820 returns the number of characters put into 'buf' or -1 if an error
822 SSizeT
VG_(readlink
) (const HChar
* path
, HChar
* buf
, SizeT bufsiz
)
825 /* res = readlink( path, buf, bufsiz ); */
826 # if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
827 res
= VG_(do_syscall4
)(__NR_readlinkat
, VKI_AT_FDCWD
,
828 (UWord
)path
, (UWord
)buf
, bufsiz
);
829 # elif defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_freebsd)
830 res
= VG_(do_syscall3
)(__NR_readlink
, (UWord
)path
, (UWord
)buf
, bufsiz
);
831 # elif defined(VGO_solaris)
832 res
= VG_(do_syscall4
)(__NR_readlinkat
, VKI_AT_FDCWD
, (UWord
)path
,
837 return sr_isError(res
) ? -1 : sr_Res(res
);
840 #if defined(VGO_linux) || defined(VGO_solaris)
841 Int
VG_(getdents64
) (Int fd
, struct vki_dirent64
*dirp
, UInt count
)
844 /* res = getdents( fd, dirp, count ); */
845 # if defined(VGP_amd64_solaris)
846 /* This silently assumes that dirent64 and dirent on amd64 are same, which
847 they should always be. */
848 res
= VG_(do_syscall3
)(__NR_getdents
, fd
, (UWord
)dirp
, count
);
850 res
= VG_(do_syscall3
)(__NR_getdents64
, fd
, (UWord
)dirp
, count
);
851 # if defined(VGA_mips64)
852 /* The MIPS64 getdents64() system call is only present in 3.10+ kernels.
853 If the getdents64() system call is not available fall back to using
854 getdents() and modify the result to be compatible with getdents64(). */
855 if (sr_isError(res
) && (sr_Err(res
) == VKI_ENOSYS
)) {
857 res
= VG_(do_syscall3
)(__NR_getdents
, fd
, (UWord
)dirp
, count
);
864 struct vki_dirent64 d
;
868 u
= (union dirents
*)p
;
869 /* This should not happen, but just in case... */
870 if (p
+ u
->m
.d_reclen
> (char *)dirp
+ r
)
872 /* shuffle the dirent */
873 type
= *(p
+ u
->m
.d_reclen
- 1);
874 VG_(memmove
)(u
->d
.d_name
, u
->m
.d_name
,
876 - offsetof(struct vki_dirent
, d_name
) + 1);
879 } while (p
< (char *)dirp
+ r
);
884 return sr_isError(res
) ? -1 : sr_Res(res
);
888 /* Check accessibility of a file. Returns zero for access granted,
889 nonzero otherwise. */
890 Int
VG_(access
) ( const HChar
* path
, Bool irusr
, Bool iwusr
, Bool ixusr
)
892 # if defined(VGO_linux)
893 /* Very annoyingly, I cannot find any definition for R_OK et al in
894 the kernel interfaces. Therefore I reluctantly resort to
895 hardwiring in these magic numbers that I determined by
902 UWord w
= (irusr
? VKI_R_OK
: 0)
903 | (iwusr
? VKI_W_OK
: 0)
904 | (ixusr
? VKI_X_OK
: 0);
905 # if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
906 SysRes res
= VG_(do_syscall3
)(__NR_faccessat
, VKI_AT_FDCWD
, (UWord
)path
, w
);
907 # elif defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_freebsd)
908 SysRes res
= VG_(do_syscall2
)(__NR_access
, (UWord
)path
, w
);
909 # elif defined(VGO_solaris)
910 SysRes res
= VG_(do_syscall4
)(__NR_faccessat
, VKI_AT_FDCWD
, (UWord
)path
,
915 return sr_isError(res
) ? 1 : 0;
917 # if defined(VGO_linux)
925 Emulate the normal Unix permissions checking algorithm.
927 If owner matches, then use the owner permissions, else
928 if group matches, then use the group permissions, else
929 use other permissions.
931 Note that we can't deal properly with SUID/SGID. By default
932 (allow_setuid == False), we refuse to run them (otherwise the
933 executable may misbehave if it doesn't have the permissions it
934 thinks it does). However, the caller may indicate that setuid
935 executables are allowed, for example if we are going to exec them
936 but not trace into them (iow, client sys_execve when
937 clo_trace_children == False).
939 If VKI_EACCES is returned (iow, permission was refused), then
940 *is_setuid is set to True iff permission was refused because the
941 executable is setuid.
943 /* returns: 0 = success, non-0 is failure */
944 Int
VG_(check_executable
)(/*OUT*/Bool
* is_setuid
,
945 const HChar
* f
, Bool allow_setuid
)
948 SysRes res
= VG_(stat
)(f
, &st
);
953 if (sr_isError(res
)) {
957 if ( VKI_S_ISDIR (st
.mode
) ) {
961 if ( (st
.mode
& (VKI_S_ISUID
| VKI_S_ISGID
)) && !allow_setuid
) {
967 res
= VG_(getxattr
)(f
, "security.capability", (Addr
)0, 0);
968 if (!sr_isError(res
) && !allow_setuid
) {
974 if (VG_(geteuid
)() == st
.uid
) {
975 if (!(st
.mode
& VKI_S_IXUSR
))
980 if (VG_(getegid
)() == st
.gid
)
986 /* Find out # groups, allocate large enough array and fetch groups */
987 ngrp
= VG_(getgroups
)(0, NULL
);
989 groups
= VG_(malloc
)("check_executable", ngrp
* sizeof *groups
);
990 ngrp
= VG_(getgroups
)(ngrp
, groups
);
994 /* ngrp will be -1 if VG_(getgroups) failed. */
995 for (i
= 0; i
< ngrp
; i
++) {
996 if (groups
[i
] == st
.gid
) {
1005 if (!(st
.mode
& VKI_S_IXGRP
)) {
1008 } else if (!(st
.mode
& VKI_S_IXOTH
)) {
1016 SysRes
VG_(pread
) ( Int fd
, void* buf
, Int count
, OffT offset
)
1019 // on 32 bits platforms, we receive a 32 bits OffT but
1020 // we must extend it to pass a long long 64 bits.
1021 # if defined(VGP_x86_linux)
1022 vg_assert(sizeof(OffT
) == 4);
1023 res
= VG_(do_syscall5
)(__NR_pread64
, fd
, (UWord
)buf
, count
,
1024 offset
, 0); // Little endian long long
1026 # elif defined(VGP_arm_linux)
1027 vg_assert(sizeof(OffT
) == 4);
1028 res
= VG_(do_syscall5
)(__NR_pread64
, fd
, (UWord
)buf
, count
,
1029 0, offset
); // Big endian long long
1031 # elif defined(VGP_ppc32_linux)
1032 vg_assert(sizeof(OffT
) == 4);
1033 res
= VG_(do_syscall6
)(__NR_pread64
, fd
, (UWord
)buf
, count
,
1034 0, // Padding needed on PPC32
1035 0, offset
); // Big endian long long
1037 # elif (defined(VGP_mips32_linux) || defined(VGP_nanomips_linux)) \
1038 && (VKI_LITTLE_ENDIAN)
1039 vg_assert(sizeof(OffT
) == 4);
1040 res
= VG_(do_syscall6
)(__NR_pread64
, fd
, (UWord
)buf
, count
,
1043 # elif (defined(VGP_mips32_linux) || defined(VGP_nanomips_linux)) \
1045 vg_assert(sizeof(OffT
) == 4);
1046 res
= VG_(do_syscall6
)(__NR_pread64
, fd
, (UWord
)buf
, count
,
1049 # elif defined(VGP_amd64_linux) || defined(VGP_s390x_linux) \
1050 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1051 || defined(VGP_mips64_linux) || defined(VGP_arm64_linux)
1052 res
= VG_(do_syscall4
)(__NR_pread64
, fd
, (UWord
)buf
, count
, offset
);
1054 # elif defined(VGP_amd64_freebsd)
1055 vg_assert(sizeof(OffT
) == 8);
1056 res
= VG_(do_syscall4
)(__NR_pread
, fd
, (UWord
)buf
, count
, offset
);
1058 # elif defined(VGP_x86_freebsd)
1059 vg_assert(sizeof(OffT
) == 8);
1060 res
= VG_(do_syscall5
)(__NR_pread
, fd
, (UWord
)buf
, count
,
1061 offset
& 0xffffffff, offset
>> 32);
1063 # elif defined(VGP_amd64_darwin)
1064 vg_assert(sizeof(OffT
) == 8);
1065 res
= VG_(do_syscall4
)(__NR_pread_nocancel
, fd
, (UWord
)buf
, count
, offset
);
1067 # elif defined(VGP_x86_darwin)
1068 vg_assert(sizeof(OffT
) == 8);
1069 res
= VG_(do_syscall5
)(__NR_pread_nocancel
, fd
, (UWord
)buf
, count
,
1070 offset
& 0xffffffff, offset
>> 32);
1072 # elif defined(VGP_x86_solaris)
1073 vg_assert(sizeof(OffT
) == 4);
1074 res
= VG_(do_syscall4
)(__NR_pread
, fd
, (UWord
)buf
, count
, offset
);
1076 # elif defined(VGP_amd64_solaris)
1077 vg_assert(sizeof(OffT
) == 8);
1078 res
= VG_(do_syscall4
)(__NR_pread
, fd
, (UWord
)buf
, count
, offset
);
1081 # error "Unknown platform"
1085 /* Return the name of a directory for temporary files. */
1086 const HChar
*VG_(tmpdir
)(void)
1088 const HChar
*tmpdir
;
1090 tmpdir
= VG_(getenv
)("TMPDIR");
1091 if (tmpdir
== NULL
|| *tmpdir
== '\0') tmpdir
= VG_TMPDIR
;
1092 if (tmpdir
== NULL
|| *tmpdir
== '\0') tmpdir
= "/tmp"; /* fallback */
1097 static const HChar mkstemp_format
[] = "%s/valgrind_%s_%08x";
1099 SizeT
VG_(mkstemp_fullname_bufsz
) ( SizeT part_of_name_len
)
1101 return VG_(strlen
)(mkstemp_format
)
1102 + VG_(strlen
)(VG_(tmpdir
)()) - 2 // %s tmpdir
1103 + part_of_name_len
- 2 // %s part_of_name
1109 Int
VG_(mkstemp
) ( const HChar
* part_of_name
, /*OUT*/HChar
* fullname
)
1114 const HChar
*tmpdir
;
1116 vg_assert(part_of_name
);
1117 vg_assert(fullname
);
1118 n
= VG_(strlen
)(part_of_name
);
1119 vg_assert(n
> 0 && n
< 100);
1121 seed
= (VG_(getpid
)() << 9) ^ VG_(getppid
)();
1123 /* Determine sensible location for temporary files */
1124 tmpdir
= VG_(tmpdir
)();
1130 VG_(sprintf
)( fullname
, mkstemp_format
,
1131 tmpdir
, part_of_name
, VG_(random
)( &seed
));
1133 VG_(printf
)("VG_(mkstemp): trying: %s\n", fullname
);
1135 sres
= VG_(open
)(fullname
,
1136 VKI_O_CREAT
|VKI_O_RDWR
|VKI_O_EXCL
|VKI_O_TRUNC
,
1137 VKI_S_IRUSR
|VKI_S_IWUSR
);
1138 if (sr_isError(sres
)) {
1139 VG_(umsg
)("VG_(mkstemp): failed to create temp file: %s\n", fullname
);
1142 /* VG_(safe_fd) doesn't return if it fails. */
1143 return VG_(safe_fd
)( sr_Res(sres
) );
1149 /* ---------------------------------------------------------------------
1150 Socket-related stuff.
1151 ------------------------------------------------------------------ */
1154 Int
parse_inet_addr_and_port ( const HChar
* str
, UInt
* ip_addr
, UShort
* port
);
1157 Int
my_connect ( Int sockfd
, struct vki_sockaddr_in
* serv_addr
, Int addrlen
);
1159 UInt
VG_(htonl
) ( UInt x
)
1161 # if defined(VG_BIGENDIAN)
1165 (((x
>> 24) & 0xFF) << 0) | (((x
>> 16) & 0xFF) << 8)
1166 | (((x
>> 8) & 0xFF) << 16) | (((x
>> 0) & 0xFF) << 24);
1170 UInt
VG_(ntohl
) ( UInt x
)
1172 # if defined(VG_BIGENDIAN)
1176 (((x
>> 24) & 0xFF) << 0) | (((x
>> 16) & 0xFF) << 8)
1177 | (((x
>> 8) & 0xFF) << 16) | (((x
>> 0) & 0xFF) << 24);
1181 UShort
VG_(htons
) ( UShort x
)
1183 # if defined(VG_BIGENDIAN)
1187 (((x
>> 8) & 0xFF) << 0) | (((x
>> 0) & 0xFF) << 8);
1191 UShort
VG_(ntohs
) ( UShort x
)
1193 # if defined(VG_BIGENDIAN)
1197 (((x
>> 8) & 0xFF) << 0) | (((x
>> 0) & 0xFF) << 8);
1202 /* The main function.
1204 Supplied string contains either an ip address "192.168.0.1" or
1205 an ip address and port pair, "192.168.0.1:1500". Parse these,
1207 -1 if there is a parse error
1208 -2 if no parse error, but specified host:port cannot be opened
1209 the relevant file (socket) descriptor, otherwise.
1212 Int
VG_(connect_via_socket
)( const HChar
* str
)
1214 # if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) || defined(VGO_freebsd)
1216 struct vki_sockaddr_in servAddr
;
1218 UShort port
= VG_CLO_DEFAULT_LOGPORT
;
1219 Bool ok
= parse_inet_addr_and_port(str
, &ip
, &port
);
1224 // VG_(printf)("ip = %d.%d.%d.%d, port %d\n",
1225 // (ip >> 24) & 0xFF, (ip >> 16) & 0xFF,
1226 // (ip >> 8) & 0xFF, ip & 0xFF,
1229 servAddr
.sin_family
= VKI_AF_INET
;
1230 servAddr
.sin_addr
.s_addr
= VG_(htonl
)(ip
);
1231 servAddr
.sin_port
= VG_(htons
)(port
);
1234 sd
= VG_(socket
)(VKI_AF_INET
, VKI_SOCK_STREAM
, 0 /* IPPROTO_IP ? */);
1236 /* this shouldn't happen ... nevertheless */
1240 /* connect to server */
1241 res
= my_connect(sd
, &servAddr
, sizeof(servAddr
));
1243 /* connection failed */
1250 # error "Unknown OS"
1255 /* Let d = one or more digits. Accept either:
1256 d.d.d.d or d.d.d.d:d
1258 static Int
parse_inet_addr_and_port ( const HChar
* str
, UInt
* ip_addr
, UShort
* port
)
1260 # define GET_CH ((*str) ? (*str++) : 0)
1261 UInt ipa
, i
, j
, c
, any
;
1263 for (i
= 0; i
< 4; i
++) {
1268 if (c
< '0' || c
> '9') break;
1269 j
= 10 * j
+ (int)(c
- '0');
1272 if (any
== 0 || j
> 255) goto syntaxerr
;
1273 ipa
= (ipa
<< 8) + j
;
1274 if (i
<= 2 && c
!= '.') goto syntaxerr
;
1276 if (c
== 0 || c
== ':')
1278 if (c
== 0) goto ok
;
1279 if (c
!= ':') goto syntaxerr
;
1284 if (c
< '0' || c
> '9') break;
1285 j
= j
* 10 + (int)(c
- '0');
1287 if (j
> 65535) goto syntaxerr
;
1289 if (any
== 0 || c
!= 0) goto syntaxerr
;
1290 if (j
< 1024) goto syntaxerr
;
1299 // GrP fixme safe_fd?
1300 Int
VG_(socket
) ( Int domain
, Int type
, Int protocol
)
1302 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1303 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1304 || defined(VGP_s390x_linux)
1310 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_SOCKET
, (UWord
)&args
);
1311 return sr_isError(res
) ? -1 : sr_Res(res
);
1313 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1314 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
1315 || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) || defined(VGO_freebsd)
1317 res
= VG_(do_syscall3
)(__NR_socket
, domain
, type
, protocol
);
1318 return sr_isError(res
) ? -1 : sr_Res(res
);
1320 # elif defined(VGO_darwin)
1322 res
= VG_(do_syscall3
)(__NR_socket
, domain
, type
, protocol
);
1323 if (!sr_isError(res
)) {
1324 // Set SO_NOSIGPIPE so write() returns EPIPE instead of raising SIGPIPE
1327 res2
= VG_(do_syscall5
)(__NR_setsockopt
, sr_Res(res
), VKI_SOL_SOCKET
,
1328 VKI_SO_NOSIGPIPE
, (UWord
)&optval
,
1330 // ignore setsockopt() error
1332 return sr_isError(res
) ? -1 : sr_Res(res
);
1334 # elif defined(VGO_solaris)
1335 /* XXX There doesn't seem to be an easy way to convince the send syscall to
1336 only return EPIPE instead of raising SIGPIPE. EPIPE is only returned if
1337 SM_KERNEL is set on the socket. Without serious hackery it looks we
1338 can't set this flag.
1340 Should we wrap the send syscall below into sigprocmask calls to block
1344 res
= VG_(do_syscall5
)(__NR_so_socket
, domain
, type
, protocol
,
1345 0 /*devpath*/, VKI_SOV_DEFAULT
/*version*/);
1346 return sr_isError(res
) ? -1 : sr_Res(res
);
1349 # error "Unknown arch"
1355 Int
my_connect ( Int sockfd
, struct vki_sockaddr_in
* serv_addr
, Int addrlen
)
1357 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1358 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1359 || defined(VGP_s390x_linux)
1363 args
[1] = (UWord
)serv_addr
;
1365 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_CONNECT
, (UWord
)&args
);
1366 return sr_isError(res
) ? -1 : sr_Res(res
);
1368 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1369 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
1370 || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) || defined(VGO_freebsd)
1372 res
= VG_(do_syscall3
)(__NR_connect
, sockfd
, (UWord
)serv_addr
, addrlen
);
1373 return sr_isError(res
) ? -1 : sr_Res(res
);
1375 # elif defined(VGO_darwin)
1377 res
= VG_(do_syscall3
)(__NR_connect_nocancel
,
1378 sockfd
, (UWord
)serv_addr
, addrlen
);
1379 return sr_isError(res
) ? -1 : sr_Res(res
);
1381 # elif defined(VGO_solaris)
1383 res
= VG_(do_syscall4
)(__NR_connect
, sockfd
, (UWord
)serv_addr
, addrlen
,
1384 VKI_SOV_DEFAULT
/*version*/);
1385 return sr_isError(res
) ? -1 : sr_Res(res
);
1388 # error "Unknown arch"
1392 Int
VG_(write_socket
)( Int sd
, const void *msg
, Int count
)
1394 /* This is actually send(). */
1396 /* For Linux, VKI_MSG_NOSIGNAL is a request not to send SIGPIPE on
1397 errors on stream oriented sockets when the other end breaks the
1398 connection. The EPIPE error is still returned.
1400 For Darwin, VG_(socket)() sets SO_NOSIGPIPE to get EPIPE instead of
1403 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1404 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1405 || defined(VGP_s390x_linux)
1409 args
[1] = (UWord
)msg
;
1411 args
[3] = VKI_MSG_NOSIGNAL
;
1412 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_SEND
, (UWord
)&args
);
1413 return sr_isError(res
) ? -1 : sr_Res(res
);
1415 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1416 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
1417 || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) || defined(VGO_freebsd)
1419 res
= VG_(do_syscall6
)(__NR_sendto
, sd
, (UWord
)msg
,
1420 count
, VKI_MSG_NOSIGNAL
, 0,0);
1421 return sr_isError(res
) ? -1 : sr_Res(res
);
1423 # elif defined(VGP_x86_darwin) || defined(VGP_amd64_darwin)
1425 res
= VG_(do_syscall3
)(__NR_write_nocancel
, sd
, (UWord
)msg
, count
);
1426 return sr_isError(res
) ? -1 : sr_Res(res
);
1428 # elif defined(VGO_solaris)
1430 res
= VG_(do_syscall4
)(__NR_send
, sd
, (UWord
)msg
, count
, 0 /*flags*/);
1431 return sr_isError(res
) ? -1 : sr_Res(res
);
1434 # error "Unknown platform"
1438 Int
VG_(getsockname
) ( Int sd
, struct vki_sockaddr
*name
, Int
*namelen
)
1440 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1441 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1442 || defined(VGP_s390x_linux) \
1443 || defined(VGP_mips32_linux)
1447 args
[1] = (UWord
)name
;
1448 args
[2] = (UWord
)namelen
;
1449 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_GETSOCKNAME
, (UWord
)&args
);
1450 return sr_isError(res
) ? -1 : sr_Res(res
);
1452 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1453 || defined(VGP_mips64_linux) || defined(VGP_arm64_linux) \
1454 || defined(VGP_nanomips_linux) || defined(VGO_freebsd) \
1455 || defined(VGP_mips64_linux) || defined(VGP_arm64_linux)
1457 res
= VG_(do_syscall3
)( __NR_getsockname
,
1458 (UWord
)sd
, (UWord
)name
, (UWord
)namelen
);
1459 return sr_isError(res
) ? -1 : sr_Res(res
);
1461 # elif defined(VGO_darwin)
1463 res
= VG_(do_syscall3
)( __NR_getsockname
,
1464 (UWord
)sd
, (UWord
)name
, (UWord
)namelen
);
1465 return sr_isError(res
) ? -1 : sr_Res(res
);
1467 # elif defined(VGO_solaris)
1469 res
= VG_(do_syscall4
)(__NR_getsockname
, sd
, (UWord
)name
, (UWord
)namelen
,
1470 VKI_SOV_DEFAULT
/*version*/);
1471 return sr_isError(res
) ? -1 : sr_Res(res
);
1474 # error "Unknown platform"
1478 Int
VG_(getpeername
) ( Int sd
, struct vki_sockaddr
*name
, Int
*namelen
)
1480 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1481 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1482 || defined(VGP_s390x_linux) \
1483 || defined(VGP_mips32_linux)
1487 args
[1] = (UWord
)name
;
1488 args
[2] = (UWord
)namelen
;
1489 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_GETPEERNAME
, (UWord
)&args
);
1490 return sr_isError(res
) ? -1 : sr_Res(res
);
1492 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1493 || defined(VGP_mips64_linux) || defined(VGP_arm64_linux) \
1494 || defined(VGP_nanomips_linux) || defined(VGO_freebsd)
1496 res
= VG_(do_syscall3
)( __NR_getpeername
,
1497 (UWord
)sd
, (UWord
)name
, (UWord
)namelen
);
1498 return sr_isError(res
) ? -1 : sr_Res(res
);
1500 # elif defined(VGO_darwin)
1502 res
= VG_(do_syscall3
)( __NR_getpeername
,
1503 (UWord
)sd
, (UWord
)name
, (UWord
)namelen
);
1504 return sr_isError(res
) ? -1 : sr_Res(res
);
1506 # elif defined(VGO_solaris)
1508 res
= VG_(do_syscall4
)(__NR_getpeername
, sd
, (UWord
)name
, (UWord
)namelen
,
1509 VKI_SOV_DEFAULT
/*version*/);
1510 return sr_isError(res
) ? -1 : sr_Res(res
);
1513 # error "Unknown platform"
1517 Int
VG_(getsockopt
) ( Int sd
, Int level
, Int optname
, void *optval
,
1520 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1521 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1522 || defined(VGP_s390x_linux)
1528 args
[3] = (UWord
)optval
;
1529 args
[4] = (UWord
)optlen
;
1530 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_GETSOCKOPT
, (UWord
)&args
);
1531 return sr_isError(res
) ? -1 : sr_Res(res
);
1533 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1534 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
1535 || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) \
1536 || defined(VGO_freebsd)
1538 res
= VG_(do_syscall5
)( __NR_getsockopt
,
1539 (UWord
)sd
, (UWord
)level
, (UWord
)optname
,
1540 (UWord
)optval
, (UWord
)optlen
);
1541 return sr_isError(res
) ? -1 : sr_Res(res
);
1543 # elif defined(VGO_darwin)
1545 res
= VG_(do_syscall5
)( __NR_getsockopt
,
1546 (UWord
)sd
, (UWord
)level
, (UWord
)optname
,
1547 (UWord
)optval
, (UWord
)optlen
);
1548 return sr_isError(res
) ? -1 : sr_Res(res
);
1550 # elif defined(VGO_solaris)
1552 res
= VG_(do_syscall6
)(__NR_getsockopt
, sd
, level
, optname
, (UWord
)optval
,
1553 (UWord
)optlen
, VKI_SOV_DEFAULT
/*version*/);
1554 return sr_isError(res
) ? -1 : sr_Res(res
);
1557 # error "Unknown platform"
1562 Int
VG_(setsockopt
) ( Int sd
, Int level
, Int optname
, void *optval
,
1565 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1566 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1567 || defined(VGP_s390x_linux)
1573 args
[3] = (UWord
)optval
;
1574 args
[4] = (UWord
)optlen
;
1575 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_SETSOCKOPT
, (UWord
)&args
);
1576 return sr_isError(res
) ? -1 : sr_Res(res
);
1578 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1579 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
1580 || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
1582 res
= VG_(do_syscall5
)( __NR_setsockopt
,
1583 (UWord
)sd
, (UWord
)level
, (UWord
)optname
,
1584 (UWord
)optval
, (UWord
)optlen
);
1585 return sr_isError(res
) ? -1 : sr_Res(res
);
1587 # elif defined(VGO_darwin) || defined(VGO_freebsd)
1589 res
= VG_(do_syscall5
)( __NR_setsockopt
,
1590 (UWord
)sd
, (UWord
)level
, (UWord
)optname
,
1591 (UWord
)optval
, (UWord
)optlen
);
1592 return sr_isError(res
) ? -1 : sr_Res(res
);
1594 # elif defined(VGO_solaris)
1596 res
= VG_(do_syscall6
)( __NR_setsockopt
,
1597 (UWord
)sd
, (UWord
)level
, (UWord
)optname
,
1598 (UWord
)optval
, (UWord
)optlen
,
1599 VKI_SOV_DEFAULT
/*version*/ );
1600 return sr_isError(res
) ? -1 : sr_Res(res
);
1603 # error "Unknown platform"
1608 const HChar
*VG_(basename
)(const HChar
*path
)
1610 static HChar
*buf
= NULL
;
1611 static SizeT buf_len
= 0;
1612 const HChar
*p
, *end
;
1615 0 == VG_(strcmp
)(path
, ""))
1620 p
= path
+ VG_(strlen
)(path
);
1621 while (p
> path
&& *p
== '/') {
1622 // skip all trailing '/'
1626 if (p
== path
&& *p
== '/') return "/"; // all slashes
1630 while (p
> path
&& *p
!= '/') {
1637 SizeT need
= end
-p
+1 + 1;
1638 if (need
> buf_len
) {
1639 buf_len
= (buf_len
== 0) ? 500 : need
;
1640 buf
= VG_(realloc
)("basename", buf
, buf_len
);
1642 VG_(strncpy
)(buf
, p
, end
-p
+1);
1643 buf
[end
-p
+1] = '\0';
1649 const HChar
*VG_(dirname
)(const HChar
*path
)
1651 static HChar
*buf
= NULL
;
1652 static SizeT buf_len
= 0;
1657 0 == VG_(strcmp
)(path
, "") ||
1658 0 == VG_(strcmp
)(path
, "/"))
1663 p
= path
+ VG_(strlen
)(path
);
1664 while (p
> path
&& *p
== '/') {
1665 // skip all trailing '/'
1669 while (p
> path
&& *p
!= '/') {
1675 if (*p
== '/') return "/"; // all slashes
1676 else return "."; // no slashes
1679 while (p
> path
&& *p
== '/') {
1684 SizeT need
= p
-path
+1 + 1;
1685 if (need
> buf_len
) {
1686 buf_len
= (buf_len
== 0) ? 500 : need
;
1687 buf
= VG_(realloc
)("dirname", buf
, buf_len
);
1689 VG_(strncpy
)(buf
, path
, p
-path
+1);
1690 buf
[p
-path
+1] = '\0';
1696 /*--------------------------------------------------------------------*/
1698 /*--------------------------------------------------------------------*/