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, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
29 The GNU General Public License is contained in the file COPYING.
32 #include "pub_core_basics.h"
33 #include "pub_core_vki.h"
34 #include "pub_core_vkiscnums.h"
35 #include "pub_core_debuglog.h"
36 #include "pub_core_libcbase.h"
37 #include "pub_core_libcassert.h"
38 #include "pub_core_libcfile.h"
39 #include "pub_core_libcprint.h" // VG_(sprintf)
40 #include "pub_core_libcproc.h" // VG_(getpid), VG_(getppid)
41 #include "pub_core_clientstate.h" // VG_(fd_hard_limit)
42 #include "pub_core_mallocfree.h" // VG_(realloc)
43 #include "pub_core_syscall.h"
45 /* IMPORTANT: on Darwin it is essential to use the _nocancel versions
46 of syscalls rather than the vanilla version, if a _nocancel version
47 is available. See docs/internals/Darwin-notes.txt for the reason
50 /* ---------------------------------------------------------------------
52 ------------------------------------------------------------------ */
54 /* Move an fd into the Valgrind-safe range */
55 Int
VG_(safe_fd
)(Int oldfd
)
59 vg_assert(VG_(fd_hard_limit
) != -1);
61 newfd
= VG_(fcntl
)(oldfd
, VKI_F_DUPFD
, VG_(fd_hard_limit
));
65 /* Set the close-on-exec flag for this fd. */
66 VG_(fcntl
)(newfd
, VKI_F_SETFD
, VKI_FD_CLOEXEC
);
68 vg_assert(newfd
>= VG_(fd_hard_limit
));
72 /* Given a file descriptor, attempt to deduce its filename. To do
73 this, we use /proc/self/fd/<FD>. If this doesn't point to a file,
74 or if it doesn't exist, we return False.
75 Upon successful completion *result contains the filename. The
76 filename will be overwritten with the next invocation so callers
77 need to copy the filename if needed. *result is NULL if the filename
79 Bool
VG_(resolve_filename
) ( Int fd
, const HChar
** result
)
81 # if defined(VGO_linux) || defined(VGO_solaris)
82 static HChar
*buf
= NULL
;
83 static SizeT bufsiz
= 0;
85 if (buf
== NULL
) { // first time
87 buf
= VG_(malloc
)("resolve_filename", bufsiz
);
90 HChar tmp
[64]; // large enough
92 # if defined(VGO_linux)
93 VG_(sprintf
)(tmp
, "/proc/self/fd/%d", fd
);
94 # elif defined(VGO_solaris)
95 VG_(sprintf
)(tmp
, "/proc/self/path/%d", fd
);
100 SSizeT res
= VG_(readlink
)(tmp
, buf
, bufsiz
);
102 if (res
== bufsiz
) { // buffer too small; increase and retry
104 buf
= VG_(realloc
)("resolve_filename", buf
, bufsiz
);
107 vg_assert(bufsiz
> res
); // paranoia
108 if (buf
[0] != '/') break;
118 # elif defined(VGO_darwin)
119 HChar tmp
[VKI_MAXPATHLEN
+1];
120 if (0 == VG_(fcntl
)(fd
, VKI_F_GETPATH
, (UWord
)tmp
)) {
121 static HChar
*buf
= NULL
;
124 buf
= VG_(malloc
)("resolve_filename", VKI_MAXPATHLEN
+1);
125 VG_(strcpy
)( buf
, tmp
);
128 if (buf
[0] == '/') return True
;
139 SysRes
VG_(mknod
) ( const HChar
* pathname
, Int mode
, UWord dev
)
141 # if defined(VGP_arm64_linux)
142 /* ARM64 wants to use __NR_mknodat rather than __NR_mknod. */
143 SysRes res
= VG_(do_syscall4
)(__NR_mknodat
,
144 VKI_AT_FDCWD
, (UWord
)pathname
, mode
, dev
);
145 # elif defined(VGO_linux) || defined(VGO_darwin)
146 SysRes res
= VG_(do_syscall3
)(__NR_mknod
,
147 (UWord
)pathname
, mode
, dev
);
148 # elif defined(VGO_solaris)
149 SysRes res
= VG_(do_syscall4
)(__NR_mknodat
,
150 VKI_AT_FDCWD
, (UWord
)pathname
, mode
, dev
);
157 SysRes
VG_(open
) ( const HChar
* pathname
, Int flags
, Int mode
)
159 # if defined(VGP_arm64_linux)
160 /* ARM64 wants to use __NR_openat rather than __NR_open. */
161 SysRes res
= VG_(do_syscall4
)(__NR_openat
,
162 VKI_AT_FDCWD
, (UWord
)pathname
, flags
, mode
);
163 # elif defined(VGO_linux)
164 SysRes res
= VG_(do_syscall3
)(__NR_open
,
165 (UWord
)pathname
, flags
, mode
);
166 # elif defined(VGO_darwin)
167 SysRes res
= VG_(do_syscall3
)(__NR_open_nocancel
,
168 (UWord
)pathname
, flags
, mode
);
169 # elif defined(VGO_solaris)
170 SysRes res
= VG_(do_syscall4
)(__NR_openat
,
171 VKI_AT_FDCWD
, (UWord
)pathname
, flags
, mode
);
178 Int
VG_(fd_open
) (const HChar
* pathname
, Int flags
, Int mode
)
181 sr
= VG_(open
) (pathname
, flags
, mode
);
188 void VG_(close
) ( Int fd
)
190 /* Hmm. Return value is not checked. That's uncool. */
191 # if defined(VGO_linux) || defined(VGO_solaris)
192 (void)VG_(do_syscall1
)(__NR_close
, fd
);
193 # elif defined(VGO_darwin)
194 (void)VG_(do_syscall1
)(__NR_close_nocancel
, fd
);
200 Int
VG_(read
) ( Int fd
, void* buf
, Int count
)
203 # if defined(VGO_linux) || defined(VGO_solaris)
204 SysRes res
= VG_(do_syscall3
)(__NR_read
, fd
, (UWord
)buf
, count
);
205 # elif defined(VGO_darwin)
206 SysRes res
= VG_(do_syscall3
)(__NR_read_nocancel
, fd
, (UWord
)buf
, count
);
210 if (sr_isError(res
)) {
211 ret
= - (Int
)(Word
)sr_Err(res
);
214 ret
= (Int
)(Word
)sr_Res(res
);
220 Int
VG_(write
) ( Int fd
, const void* buf
, Int count
)
223 # if defined(VGO_linux) || defined(VGO_solaris)
224 SysRes res
= VG_(do_syscall3
)(__NR_write
, fd
, (UWord
)buf
, count
);
225 # elif defined(VGO_darwin)
226 SysRes res
= VG_(do_syscall3
)(__NR_write_nocancel
, fd
, (UWord
)buf
, count
);
230 if (sr_isError(res
)) {
231 ret
= - (Int
)(Word
)sr_Err(res
);
234 ret
= (Int
)(Word
)sr_Res(res
);
241 Int
VG_(pipe
) ( Int fd
[2] )
243 # if defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
244 /* __NR_pipe has a strange return convention on mips32-linux. */
245 SysRes res
= VG_(do_syscall1
)(__NR_pipe
, (UWord
)fd
);
246 if (!sr_isError(res
)) {
247 fd
[0] = (Int
)sr_Res(res
);
248 fd
[1] = (Int
)sr_ResEx(res
);
253 # elif defined(VGP_arm64_linux)
254 SysRes res
= VG_(do_syscall2
)(__NR_pipe2
, (UWord
)fd
, 0);
255 return sr_isError(res
) ? -1 : 0;
256 # elif defined(VGO_linux)
257 SysRes res
= VG_(do_syscall1
)(__NR_pipe
, (UWord
)fd
);
258 return sr_isError(res
) ? -1 : 0;
259 # elif defined(VGO_darwin)
260 /* __NR_pipe is UX64, so produces a double-word result */
261 SysRes res
= VG_(do_syscall0
)(__NR_pipe
);
262 if (!sr_isError(res
)) {
263 fd
[0] = (Int
)sr_Res(res
);
264 fd
[1] = (Int
)sr_ResHI(res
);
266 return sr_isError(res
) ? -1 : 0;
267 # elif defined(VGO_solaris)
268 # if defined(SOLARIS_NEW_PIPE_SYSCALL)
269 SysRes res
= VG_(do_syscall2
)(__NR_pipe
, (UWord
)fd
, 0);
270 return sr_isError(res
) ? -1 : 0;
272 SysRes res
= VG_(do_syscall0
)(__NR_pipe
);
273 if (!sr_isError(res
)) {
274 fd
[0] = (Int
)sr_Res(res
);
275 fd
[1] = (Int
)sr_ResHI(res
);
277 return sr_isError(res
) ? -1 : 0;
284 Off64T
VG_(lseek
) ( Int fd
, Off64T offset
, Int whence
)
286 # if defined(VGO_linux) || defined(VGP_amd64_darwin)
287 # if defined(__NR__llseek)
289 SysRes res
= VG_(do_syscall5
)(__NR__llseek
, fd
,
290 offset
>> 32, offset
& 0xffffffff,
291 (UWord
)&result
, whence
);
292 return sr_isError(res
) ? (-1) : result
;
294 SysRes res
= VG_(do_syscall3
)(__NR_lseek
, fd
, offset
, whence
);
295 vg_assert(sizeof(Off64T
) == sizeof(Word
));
296 return sr_isError(res
) ? (-1) : sr_Res(res
);
298 # elif defined(VGP_x86_darwin)
299 SysRes res
= VG_(do_syscall4
)(__NR_lseek
, fd
,
300 offset
& 0xffffffff, offset
>> 32, whence
);
301 return sr_isError(res
) ? (-1) : sr_Res(res
);
302 # elif defined(VGP_x86_solaris)
303 SysRes res
= VG_(do_syscall4
)(__NR_llseek
, fd
,
304 offset
& 0xffffffff, offset
>> 32, whence
);
305 return sr_isError(res
) ? (-1) : ((ULong
)sr_ResHI(res
) << 32 | sr_Res(res
));
306 # elif defined(VGP_amd64_solaris)
307 SysRes res
= VG_(do_syscall3
)(__NR_lseek
, fd
, offset
, whence
);
308 vg_assert(sizeof(Off64T
) == sizeof(Word
));
309 return sr_isError(res
) ? (-1) : sr_Res(res
);
311 # error "Unknown plat"
313 /* if you change the error-reporting conventions of this, also
314 change all usage points. */
318 /* stat/fstat support. It's uggerly. We have impedance-match into a
319 'struct vg_stat' in order to have a single structure that callers
320 can use consistently on all platforms. */
322 #define TRANSLATE_TO_vg_stat(_p_vgstat, _p_vkistat) \
324 (_p_vgstat)->dev = (ULong)( (_p_vkistat)->st_dev ); \
325 (_p_vgstat)->ino = (ULong)( (_p_vkistat)->st_ino ); \
326 (_p_vgstat)->nlink = (ULong)( (_p_vkistat)->st_nlink ); \
327 (_p_vgstat)->mode = (UInt) ( (_p_vkistat)->st_mode ); \
328 (_p_vgstat)->uid = (UInt) ( (_p_vkistat)->st_uid ); \
329 (_p_vgstat)->gid = (UInt) ( (_p_vkistat)->st_gid ); \
330 (_p_vgstat)->rdev = (ULong)( (_p_vkistat)->st_rdev ); \
331 (_p_vgstat)->size = (Long) ( (_p_vkistat)->st_size ); \
332 (_p_vgstat)->blksize = (ULong)( (_p_vkistat)->st_blksize ); \
333 (_p_vgstat)->blocks = (ULong)( (_p_vkistat)->st_blocks ); \
334 (_p_vgstat)->atime = (ULong)( (_p_vkistat)->st_atime ); \
335 (_p_vgstat)->atime_nsec = (ULong)( (_p_vkistat)->st_atime_nsec ); \
336 (_p_vgstat)->mtime = (ULong)( (_p_vkistat)->st_mtime ); \
337 (_p_vgstat)->mtime_nsec = (ULong)( (_p_vkistat)->st_mtime_nsec ); \
338 (_p_vgstat)->ctime = (ULong)( (_p_vkistat)->st_ctime ); \
339 (_p_vgstat)->ctime_nsec = (ULong)( (_p_vkistat)->st_ctime_nsec ); \
342 SysRes
VG_(stat
) ( const HChar
* file_name
, struct vg_stat
* vgbuf
)
345 VG_(memset
)(vgbuf
, 0, sizeof(*vgbuf
));
347 # if defined(VGO_linux) || defined(VGO_darwin)
348 /* First try with stat64. If that doesn't work out, fall back to
349 the vanilla version. */
350 # if defined(__NR_stat64)
351 { struct vki_stat64 buf64
;
352 res
= VG_(do_syscall2
)(__NR_stat64
, (UWord
)file_name
, (UWord
)&buf64
);
353 if (!(sr_isError(res
) && sr_Err(res
) == VKI_ENOSYS
)) {
354 /* Success, or any failure except ENOSYS */
355 if (!sr_isError(res
))
356 TRANSLATE_TO_vg_stat(vgbuf
, &buf64
);
360 # endif /* defined(__NR_stat64) */
361 /* This is the fallback ("vanilla version"). */
362 { struct vki_stat buf
;
363 # if defined(VGP_arm64_linux)
364 res
= VG_(do_syscall3
)(__NR3264_fstatat
, VKI_AT_FDCWD
,
365 (UWord
)file_name
, (UWord
)&buf
);
367 res
= VG_(do_syscall2
)(__NR_stat
, (UWord
)file_name
, (UWord
)&buf
);
369 if (!sr_isError(res
))
370 TRANSLATE_TO_vg_stat(vgbuf
, &buf
);
373 # elif defined(VGO_solaris)
375 # if defined(VGP_x86_solaris)
376 struct vki_stat64 buf64
;
377 res
= VG_(do_syscall4
)(__NR_fstatat64
, VKI_AT_FDCWD
, (UWord
)file_name
,
379 # elif defined(VGP_amd64_solaris)
380 struct vki_stat buf64
;
381 res
= VG_(do_syscall4
)(__NR_fstatat
, VKI_AT_FDCWD
, (UWord
)file_name
,
384 # error "Unknown platform"
386 if (!sr_isError(res
))
387 TRANSLATE_TO_vg_stat(vgbuf
, &buf64
);
395 Int
VG_(fstat
) ( Int fd
, struct vg_stat
* vgbuf
)
398 VG_(memset
)(vgbuf
, 0, sizeof(*vgbuf
));
400 # if defined(VGO_linux) || defined(VGO_darwin)
401 /* First try with fstat64. If that doesn't work out, fall back to
402 the vanilla version. */
403 # if defined(__NR_fstat64)
404 { struct vki_stat64 buf64
;
405 res
= VG_(do_syscall2
)(__NR_fstat64
, (UWord
)fd
, (UWord
)&buf64
);
406 if (!(sr_isError(res
) && sr_Err(res
) == VKI_ENOSYS
)) {
407 /* Success, or any failure except ENOSYS */
408 if (!sr_isError(res
))
409 TRANSLATE_TO_vg_stat(vgbuf
, &buf64
);
410 return sr_isError(res
) ? (-1) : 0;
413 # endif /* if defined(__NR_fstat64) */
414 { struct vki_stat buf
;
415 res
= VG_(do_syscall2
)(__NR_fstat
, (UWord
)fd
, (UWord
)&buf
);
416 if (!sr_isError(res
))
417 TRANSLATE_TO_vg_stat(vgbuf
, &buf
);
418 return sr_isError(res
) ? (-1) : 0;
420 # elif defined(VGO_solaris)
422 # if defined(VGP_x86_solaris)
423 struct vki_stat64 buf64
;
424 res
= VG_(do_syscall4
)(__NR_fstatat64
, (UWord
)fd
, 0, (UWord
)&buf64
, 0);
425 # elif defined(VGP_amd64_solaris)
426 struct vki_stat buf64
;
427 res
= VG_(do_syscall4
)(__NR_fstatat
, (UWord
)fd
, 0, (UWord
)&buf64
, 0);
429 # error "Unknown platform"
431 if (!sr_isError(res
))
432 TRANSLATE_TO_vg_stat(vgbuf
, &buf64
);
433 return sr_isError(res
) ? (-1) : 0;
440 #undef TRANSLATE_TO_vg_stat
443 Long
VG_(fsize
) ( Int fd
)
446 Int res
= VG_(fstat
)( fd
, &buf
);
447 return (res
== -1) ? (-1LL) : buf
.size
;
450 SysRes
VG_(getxattr
) ( const HChar
* file_name
, const HChar
* attr_name
, Addr attr_value
, SizeT attr_value_len
)
453 #if defined(VGO_linux)
454 res
= VG_(do_syscall4
)(__NR_getxattr
, (UWord
)file_name
, (UWord
)attr_name
,
455 attr_value
, attr_value_len
);
457 res
= VG_(mk_SysRes_Error
)(VKI_ENOSYS
);
462 Bool
VG_(is_dir
) ( const HChar
* f
)
465 SysRes res
= VG_(stat
)(f
, &buf
);
466 return sr_isError(res
) ? False
467 : VKI_S_ISDIR(buf
.mode
) ? True
: False
;
470 SysRes
VG_(dup
) ( Int oldfd
)
472 # if defined(VGO_linux) || defined(VGO_darwin)
473 return VG_(do_syscall1
)(__NR_dup
, oldfd
);
474 # elif defined(VGO_solaris)
475 return VG_(do_syscall3
)(__NR_fcntl
, oldfd
, F_DUPFD
, 0);
481 SysRes
VG_(dup2
) ( Int oldfd
, Int newfd
)
483 # if defined(VGP_arm64_linux)
484 /* We only have dup3, that means we have to mimic dup2.
485 The only real difference is when oldfd == newfd.
486 dup3 always returns an error, but dup2 returns only an
487 error if the fd is invalid, otherwise it returns newfd. */
488 if (oldfd
== newfd
) {
489 if (VG_(fcntl
)(oldfd
, VKI_F_GETFL
, 0) == -1)
490 return VG_(mk_SysRes_Error
)(VKI_EBADF
);
491 return VG_(mk_SysRes_Success
)(newfd
);
493 return VG_(do_syscall3
)(__NR_dup3
, oldfd
, newfd
, 0);
494 # elif defined(VGO_linux) || defined(VGO_darwin)
495 return VG_(do_syscall2
)(__NR_dup2
, oldfd
, newfd
);
496 # elif defined(VGO_solaris)
497 return VG_(do_syscall3
)(__NR_fcntl
, oldfd
, F_DUP2FD
, newfd
);
503 /* Returns -1 on error. */
504 Int
VG_(fcntl
) ( Int fd
, Int cmd
, Addr arg
)
506 # if defined(VGO_linux) || defined(VGO_solaris)
507 SysRes res
= VG_(do_syscall3
)(__NR_fcntl
, fd
, cmd
, arg
);
508 # elif defined(VGO_darwin)
509 SysRes res
= VG_(do_syscall3
)(__NR_fcntl_nocancel
, fd
, cmd
, arg
);
513 return sr_isError(res
) ? -1 : sr_Res(res
);
516 Int
VG_(rename
) ( const HChar
* old_name
, const HChar
* new_name
)
518 # if defined(VGO_solaris) || defined(VGP_arm64_linux)
519 SysRes res
= VG_(do_syscall4
)(__NR_renameat
, VKI_AT_FDCWD
, (UWord
)old_name
,
520 VKI_AT_FDCWD
, (UWord
)new_name
);
521 # elif defined(VGO_linux) || defined(VGO_darwin)
522 SysRes res
= VG_(do_syscall2
)(__NR_rename
, (UWord
)old_name
, (UWord
)new_name
);
526 return sr_isError(res
) ? (-1) : 0;
529 Int
VG_(unlink
) ( const HChar
* file_name
)
531 # if defined(VGP_arm64_linux)
532 SysRes res
= VG_(do_syscall2
)(__NR_unlinkat
, VKI_AT_FDCWD
,
534 # elif defined(VGO_linux) || defined(VGO_darwin)
535 SysRes res
= VG_(do_syscall1
)(__NR_unlink
, (UWord
)file_name
);
536 # elif defined(VGO_solaris)
537 SysRes res
= VG_(do_syscall3
)(__NR_unlinkat
, VKI_AT_FDCWD
,
538 (UWord
)file_name
, 0);
542 return sr_isError(res
) ? (-1) : 0;
545 /* The working directory at startup.
546 All that is really needed is to note the cwd at process startup.
547 Hence VG_(record_startup_wd) notes it (in a platform dependent way)
548 and VG_(get_startup_wd) produces the noted value. */
549 static HChar
*startup_wd
;
551 /* Record the process' working directory at startup. Is intended to
552 be called exactly once, at startup, before the working directory
554 void VG_(record_startup_wd
) ( void )
556 # if defined(VGO_linux) || defined(VGO_solaris)
557 /* Simple: just ask the kernel */
562 startup_wd
= VG_(realloc
)("startup_wd", startup_wd
, szB
);
563 VG_(memset
)(startup_wd
, 0, szB
);
564 res
= VG_(do_syscall2
)(__NR_getcwd
, (UWord
)startup_wd
, szB
-1);
565 } while (sr_isError(res
) && sr_Err(res
) == VKI_ERANGE
);
567 if (sr_isError(res
)) {
568 VG_(free
)(startup_wd
);
573 vg_assert(startup_wd
[szB
-1] == 0);
575 # elif defined(VGO_darwin)
576 /* We can't ask the kernel, so instead rely on launcher-*.c to
577 tell us the startup path. Note the env var is keyed to the
578 parent's PID, not ours, since our parent is the launcher
580 { HChar envvar
[100]; // large enough
582 VG_(memset
)(envvar
, 0, sizeof(envvar
));
583 VG_(sprintf
)(envvar
, "VALGRIND_STARTUP_PWD_%d_XYZZY",
584 (Int
)VG_(getppid
)());
585 wd
= VG_(getenv
)( envvar
);
588 SizeT need
= VG_(strlen
)(wd
) + 1;
589 startup_wd
= VG_(malloc
)("startup_wd", need
);
590 VG_(strcpy
)(startup_wd
, wd
);
597 /* Return the previously acquired startup_wd or NULL. */
598 const HChar
*VG_(get_startup_wd
) ( void )
603 SysRes
VG_(poll
) (struct vki_pollfd
*fds
, Int nfds
, Int timeout
)
606 # if defined(VGP_arm64_linux)
607 /* ARM64 wants to use __NR_ppoll rather than __NR_poll. */
608 struct vki_timespec timeout_ts
;
610 timeout_ts
.tv_sec
= timeout
/ 1000;
611 timeout_ts
.tv_nsec
= ((long)timeout
% 1000) * 1000000;
613 res
= VG_(do_syscall4
)(__NR_ppoll
,
615 (UWord
)(timeout
>= 0 ? &timeout_ts
: NULL
),
617 # elif defined(VGO_linux)
618 res
= VG_(do_syscall3
)(__NR_poll
, (UWord
)fds
, nfds
, timeout
);
619 # elif defined(VGO_darwin)
620 res
= VG_(do_syscall3
)(__NR_poll_nocancel
, (UWord
)fds
, nfds
, timeout
);
621 # elif defined(VGO_solaris)
622 struct vki_timespec ts
;
623 struct vki_timespec
*tsp
;
628 ts
.tv_sec
= timeout
/ 1000;
629 ts
.tv_nsec
= (timeout
% 1000) * 1000000;
633 res
= VG_(do_syscall4
)(__NR_pollsys
, (UWord
)fds
, nfds
, (UWord
)tsp
, 0);
641 /* Performs the readlink operation and puts the result into 'buf'.
642 Note, that the string in 'buf' is *not* null-terminated. The function
643 returns the number of characters put into 'buf' or -1 if an error
645 SSizeT
VG_(readlink
) (const HChar
* path
, HChar
* buf
, SizeT bufsiz
)
648 /* res = readlink( path, buf, bufsiz ); */
649 # if defined(VGP_arm64_linux)
650 res
= VG_(do_syscall4
)(__NR_readlinkat
, VKI_AT_FDCWD
,
651 (UWord
)path
, (UWord
)buf
, bufsiz
);
652 # elif defined(VGO_linux) || defined(VGO_darwin)
653 res
= VG_(do_syscall3
)(__NR_readlink
, (UWord
)path
, (UWord
)buf
, bufsiz
);
654 # elif defined(VGO_solaris)
655 res
= VG_(do_syscall4
)(__NR_readlinkat
, VKI_AT_FDCWD
, (UWord
)path
,
660 return sr_isError(res
) ? -1 : sr_Res(res
);
663 #if defined(VGO_linux) || defined(VGO_solaris)
664 Int
VG_(getdents64
) (Int fd
, struct vki_dirent64
*dirp
, UInt count
)
667 /* res = getdents( fd, dirp, count ); */
668 # if defined(VGP_amd64_solaris)
669 /* This silently assumes that dirent64 and dirent on amd64 are same, which
670 they should always be. */
671 res
= VG_(do_syscall3
)(__NR_getdents
, fd
, (UWord
)dirp
, count
);
673 res
= VG_(do_syscall3
)(__NR_getdents64
, fd
, (UWord
)dirp
, count
);
674 # if defined(VGA_mips64)
675 /* The MIPS64 getdents64() system call is only present in 3.10+ kernels.
676 If the getdents64() system call is not available fall back to using
677 getdents() and modify the result to be compatible with getdents64(). */
678 if (sr_isError(res
) && (sr_Err(res
) == VKI_ENOSYS
)) {
680 res
= VG_(do_syscall3
)(__NR_getdents
, fd
, (UWord
)dirp
, count
);
687 struct vki_dirent64 d
;
691 u
= (union dirents
*)p
;
692 /* This should not happen, but just in case... */
693 if (p
+ u
->m
.d_reclen
> (char *)dirp
+ r
)
695 /* shuffle the dirent */
696 type
= *(p
+ u
->m
.d_reclen
- 1);
697 VG_(memmove
)(u
->d
.d_name
, u
->m
.d_name
,
699 - offsetof(struct vki_dirent
, d_name
) + 1);
702 } while (p
< (char *)dirp
+ r
);
707 return sr_isError(res
) ? -1 : sr_Res(res
);
711 /* Check accessibility of a file. Returns zero for access granted,
712 nonzero otherwise. */
713 Int
VG_(access
) ( const HChar
* path
, Bool irusr
, Bool iwusr
, Bool ixusr
)
715 # if defined(VGO_linux)
716 /* Very annoyingly, I cannot find any definition for R_OK et al in
717 the kernel interfaces. Therefore I reluctantly resort to
718 hardwiring in these magic numbers that I determined by
725 UWord w
= (irusr
? VKI_R_OK
: 0)
726 | (iwusr
? VKI_W_OK
: 0)
727 | (ixusr
? VKI_X_OK
: 0);
728 # if defined(VGP_arm64_linux)
729 SysRes res
= VG_(do_syscall3
)(__NR_faccessat
, VKI_AT_FDCWD
, (UWord
)path
, w
);
730 # elif defined(VGO_linux) || defined(VGO_darwin)
731 SysRes res
= VG_(do_syscall2
)(__NR_access
, (UWord
)path
, w
);
732 # elif defined(VGO_solaris)
733 SysRes res
= VG_(do_syscall4
)(__NR_faccessat
, VKI_AT_FDCWD
, (UWord
)path
,
738 return sr_isError(res
) ? 1 : 0;
740 # if defined(VGO_linux)
748 Emulate the normal Unix permissions checking algorithm.
750 If owner matches, then use the owner permissions, else
751 if group matches, then use the group permissions, else
752 use other permissions.
754 Note that we can't deal properly with SUID/SGID. By default
755 (allow_setuid == False), we refuse to run them (otherwise the
756 executable may misbehave if it doesn't have the permissions it
757 thinks it does). However, the caller may indicate that setuid
758 executables are allowed, for example if we are going to exec them
759 but not trace into them (iow, client sys_execve when
760 clo_trace_children == False).
762 If VKI_EACCES is returned (iow, permission was refused), then
763 *is_setuid is set to True iff permission was refused because the
764 executable is setuid.
766 /* returns: 0 = success, non-0 is failure */
767 Int
VG_(check_executable
)(/*OUT*/Bool
* is_setuid
,
768 const HChar
* f
, Bool allow_setuid
)
771 SysRes res
= VG_(stat
)(f
, &st
);
776 if (sr_isError(res
)) {
780 if ( VKI_S_ISDIR (st
.mode
) ) {
784 if ( (st
.mode
& (VKI_S_ISUID
| VKI_S_ISGID
)) && !allow_setuid
) {
790 res
= VG_(getxattr
)(f
, "security.capability", (Addr
)0, 0);
791 if (!sr_isError(res
) && !allow_setuid
) {
797 if (VG_(geteuid
)() == st
.uid
) {
798 if (!(st
.mode
& VKI_S_IXUSR
))
803 if (VG_(getegid
)() == st
.gid
)
809 /* Find out # groups, allocate large enough array and fetch groups */
810 ngrp
= VG_(getgroups
)(0, NULL
);
812 groups
= VG_(malloc
)("check_executable", ngrp
* sizeof *groups
);
813 ngrp
= VG_(getgroups
)(ngrp
, groups
);
817 /* ngrp will be -1 if VG_(getgroups) failed. */
818 for (i
= 0; i
< ngrp
; i
++) {
819 if (groups
[i
] == st
.gid
) {
828 if (!(st
.mode
& VKI_S_IXGRP
)) {
831 } else if (!(st
.mode
& VKI_S_IXOTH
)) {
839 SysRes
VG_(pread
) ( Int fd
, void* buf
, Int count
, OffT offset
)
842 // on 32 bits platforms, we receive a 32 bits OffT but
843 // we must extend it to pass a long long 64 bits.
844 # if defined(VGP_x86_linux)
845 vg_assert(sizeof(OffT
) == 4);
846 res
= VG_(do_syscall5
)(__NR_pread64
, fd
, (UWord
)buf
, count
,
847 offset
, 0); // Little endian long long
849 # elif defined(VGP_arm_linux)
850 vg_assert(sizeof(OffT
) == 4);
851 res
= VG_(do_syscall5
)(__NR_pread64
, fd
, (UWord
)buf
, count
,
852 0, offset
); // Big endian long long
854 # elif defined(VGP_ppc32_linux)
855 vg_assert(sizeof(OffT
) == 4);
856 res
= VG_(do_syscall6
)(__NR_pread64
, fd
, (UWord
)buf
, count
,
857 0, // Padding needed on PPC32
858 0, offset
); // Big endian long long
860 # elif defined(VGP_mips32_linux) && (VKI_LITTLE_ENDIAN)
861 vg_assert(sizeof(OffT
) == 4);
862 res
= VG_(do_syscall6
)(__NR_pread64
, fd
, (UWord
)buf
, count
,
865 # elif defined(VGP_mips32_linux) && (VKI_BIG_ENDIAN)
866 vg_assert(sizeof(OffT
) == 4);
867 res
= VG_(do_syscall6
)(__NR_pread64
, fd
, (UWord
)buf
, count
,
870 # elif defined(VGP_amd64_linux) || defined(VGP_s390x_linux) \
871 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
872 || defined(VGP_mips64_linux) || defined(VGP_arm64_linux)
873 res
= VG_(do_syscall4
)(__NR_pread64
, fd
, (UWord
)buf
, count
, offset
);
875 # elif defined(VGP_amd64_darwin)
876 vg_assert(sizeof(OffT
) == 8);
877 res
= VG_(do_syscall4
)(__NR_pread_nocancel
, fd
, (UWord
)buf
, count
, offset
);
879 # elif defined(VGP_x86_darwin)
880 vg_assert(sizeof(OffT
) == 8);
881 res
= VG_(do_syscall5
)(__NR_pread_nocancel
, fd
, (UWord
)buf
, count
,
882 offset
& 0xffffffff, offset
>> 32);
884 # elif defined(VGP_x86_solaris)
885 vg_assert(sizeof(OffT
) == 4);
886 res
= VG_(do_syscall4
)(__NR_pread
, fd
, (UWord
)buf
, count
, offset
);
888 # elif defined(VGP_amd64_solaris)
889 vg_assert(sizeof(OffT
) == 8);
890 res
= VG_(do_syscall4
)(__NR_pread
, fd
, (UWord
)buf
, count
, offset
);
893 # error "Unknown platform"
897 /* Return the name of a directory for temporary files. */
898 const HChar
*VG_(tmpdir
)(void)
902 tmpdir
= VG_(getenv
)("TMPDIR");
903 if (tmpdir
== NULL
|| *tmpdir
== '\0') tmpdir
= VG_TMPDIR
;
904 if (tmpdir
== NULL
|| *tmpdir
== '\0') tmpdir
= "/tmp"; /* fallback */
909 static const HChar mkstemp_format
[] = "%s/valgrind_%s_%08x";
911 SizeT
VG_(mkstemp_fullname_bufsz
) ( SizeT part_of_name_len
)
913 return VG_(strlen
)(mkstemp_format
)
914 + VG_(strlen
)(VG_(tmpdir
)()) - 2 // %s tmpdir
915 + part_of_name_len
- 2 // %s part_of_name
921 Int
VG_(mkstemp
) ( const HChar
* part_of_name
, /*OUT*/HChar
* fullname
)
928 vg_assert(part_of_name
);
930 n
= VG_(strlen
)(part_of_name
);
931 vg_assert(n
> 0 && n
< 100);
933 seed
= (VG_(getpid
)() << 9) ^ VG_(getppid
)();
935 /* Determine sensible location for temporary files */
936 tmpdir
= VG_(tmpdir
)();
942 VG_(sprintf
)( fullname
, mkstemp_format
,
943 tmpdir
, part_of_name
, VG_(random
)( &seed
));
945 VG_(printf
)("VG_(mkstemp): trying: %s\n", fullname
);
947 sres
= VG_(open
)(fullname
,
948 VKI_O_CREAT
|VKI_O_RDWR
|VKI_O_EXCL
|VKI_O_TRUNC
,
949 VKI_S_IRUSR
|VKI_S_IWUSR
);
950 if (sr_isError(sres
)) {
951 VG_(umsg
)("VG_(mkstemp): failed to create temp file: %s\n", fullname
);
954 /* VG_(safe_fd) doesn't return if it fails. */
955 return VG_(safe_fd
)( sr_Res(sres
) );
961 /* ---------------------------------------------------------------------
962 Socket-related stuff.
963 ------------------------------------------------------------------ */
966 Int
parse_inet_addr_and_port ( const HChar
* str
, UInt
* ip_addr
, UShort
* port
);
969 Int
my_connect ( Int sockfd
, struct vki_sockaddr_in
* serv_addr
, Int addrlen
);
971 UInt
VG_(htonl
) ( UInt x
)
973 # if defined(VG_BIGENDIAN)
977 (((x
>> 24) & 0xFF) << 0) | (((x
>> 16) & 0xFF) << 8)
978 | (((x
>> 8) & 0xFF) << 16) | (((x
>> 0) & 0xFF) << 24);
982 UInt
VG_(ntohl
) ( UInt x
)
984 # if defined(VG_BIGENDIAN)
988 (((x
>> 24) & 0xFF) << 0) | (((x
>> 16) & 0xFF) << 8)
989 | (((x
>> 8) & 0xFF) << 16) | (((x
>> 0) & 0xFF) << 24);
993 UShort
VG_(htons
) ( UShort x
)
995 # if defined(VG_BIGENDIAN)
999 (((x
>> 8) & 0xFF) << 0) | (((x
>> 0) & 0xFF) << 8);
1003 UShort
VG_(ntohs
) ( UShort x
)
1005 # if defined(VG_BIGENDIAN)
1009 (((x
>> 8) & 0xFF) << 0) | (((x
>> 0) & 0xFF) << 8);
1014 /* The main function.
1016 Supplied string contains either an ip address "192.168.0.1" or
1017 an ip address and port pair, "192.168.0.1:1500". Parse these,
1019 -1 if there is a parse error
1020 -2 if no parse error, but specified host:port cannot be opened
1021 the relevant file (socket) descriptor, otherwise.
1024 Int
VG_(connect_via_socket
)( const HChar
* str
)
1026 # if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris)
1028 struct vki_sockaddr_in servAddr
;
1030 UShort port
= VG_CLO_DEFAULT_LOGPORT
;
1031 Bool ok
= parse_inet_addr_and_port(str
, &ip
, &port
);
1036 // VG_(printf)("ip = %d.%d.%d.%d, port %d\n",
1037 // (ip >> 24) & 0xFF, (ip >> 16) & 0xFF,
1038 // (ip >> 8) & 0xFF, ip & 0xFF,
1041 servAddr
.sin_family
= VKI_AF_INET
;
1042 servAddr
.sin_addr
.s_addr
= VG_(htonl
)(ip
);
1043 servAddr
.sin_port
= VG_(htons
)(port
);
1046 sd
= VG_(socket
)(VKI_AF_INET
, VKI_SOCK_STREAM
, 0 /* IPPROTO_IP ? */);
1048 /* this shouldn't happen ... nevertheless */
1052 /* connect to server */
1053 res
= my_connect(sd
, &servAddr
, sizeof(servAddr
));
1055 /* connection failed */
1062 # error "Unknown OS"
1067 /* Let d = one or more digits. Accept either:
1068 d.d.d.d or d.d.d.d:d
1070 static Int
parse_inet_addr_and_port ( const HChar
* str
, UInt
* ip_addr
, UShort
* port
)
1072 # define GET_CH ((*str) ? (*str++) : 0)
1073 UInt ipa
, i
, j
, c
, any
;
1075 for (i
= 0; i
< 4; i
++) {
1080 if (c
< '0' || c
> '9') break;
1081 j
= 10 * j
+ (int)(c
- '0');
1084 if (any
== 0 || j
> 255) goto syntaxerr
;
1085 ipa
= (ipa
<< 8) + j
;
1086 if (i
<= 2 && c
!= '.') goto syntaxerr
;
1088 if (c
== 0 || c
== ':')
1090 if (c
== 0) goto ok
;
1091 if (c
!= ':') goto syntaxerr
;
1096 if (c
< '0' || c
> '9') break;
1097 j
= j
* 10 + (int)(c
- '0');
1099 if (j
> 65535) goto syntaxerr
;
1101 if (any
== 0 || c
!= 0) goto syntaxerr
;
1102 if (j
< 1024) goto syntaxerr
;
1111 // GrP fixme safe_fd?
1112 Int
VG_(socket
) ( Int domain
, Int type
, Int protocol
)
1114 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1115 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1116 || defined(VGP_s390x_linux)
1122 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_SOCKET
, (UWord
)&args
);
1123 return sr_isError(res
) ? -1 : sr_Res(res
);
1125 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1126 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
1127 || defined(VGP_arm64_linux)
1129 res
= VG_(do_syscall3
)(__NR_socket
, domain
, type
, protocol
);
1130 return sr_isError(res
) ? -1 : sr_Res(res
);
1132 # elif defined(VGO_darwin)
1134 res
= VG_(do_syscall3
)(__NR_socket
, domain
, type
, protocol
);
1135 if (!sr_isError(res
)) {
1136 // Set SO_NOSIGPIPE so write() returns EPIPE instead of raising SIGPIPE
1139 res2
= VG_(do_syscall5
)(__NR_setsockopt
, sr_Res(res
), VKI_SOL_SOCKET
,
1140 VKI_SO_NOSIGPIPE
, (UWord
)&optval
,
1142 // ignore setsockopt() error
1144 return sr_isError(res
) ? -1 : sr_Res(res
);
1146 # elif defined(VGO_solaris)
1147 /* XXX There doesn't seem to be an easy way to convince the send syscall to
1148 only return EPIPE instead of raising SIGPIPE. EPIPE is only returned if
1149 SM_KERNEL is set on the socket. Without serious hackery it looks we
1150 can't set this flag.
1152 Should we wrap the send syscall below into sigprocmask calls to block
1156 res
= VG_(do_syscall5
)(__NR_so_socket
, domain
, type
, protocol
,
1157 0 /*devpath*/, VKI_SOV_DEFAULT
/*version*/);
1158 return sr_isError(res
) ? -1 : sr_Res(res
);
1161 # error "Unknown arch"
1167 Int
my_connect ( Int sockfd
, struct vki_sockaddr_in
* serv_addr
, Int addrlen
)
1169 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1170 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1171 || defined(VGP_s390x_linux)
1175 args
[1] = (UWord
)serv_addr
;
1177 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_CONNECT
, (UWord
)&args
);
1178 return sr_isError(res
) ? -1 : sr_Res(res
);
1180 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1181 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
1182 || defined(VGP_arm64_linux)
1184 res
= VG_(do_syscall3
)(__NR_connect
, sockfd
, (UWord
)serv_addr
, addrlen
);
1185 return sr_isError(res
) ? -1 : sr_Res(res
);
1187 # elif defined(VGO_darwin)
1189 res
= VG_(do_syscall3
)(__NR_connect_nocancel
,
1190 sockfd
, (UWord
)serv_addr
, addrlen
);
1191 return sr_isError(res
) ? -1 : sr_Res(res
);
1193 # elif defined(VGO_solaris)
1195 res
= VG_(do_syscall4
)(__NR_connect
, sockfd
, (UWord
)serv_addr
, addrlen
,
1196 VKI_SOV_DEFAULT
/*version*/);
1197 return sr_isError(res
) ? -1 : sr_Res(res
);
1200 # error "Unknown arch"
1204 Int
VG_(write_socket
)( Int sd
, const void *msg
, Int count
)
1206 /* This is actually send(). */
1208 /* For Linux, VKI_MSG_NOSIGNAL is a request not to send SIGPIPE on
1209 errors on stream oriented sockets when the other end breaks the
1210 connection. The EPIPE error is still returned.
1212 For Darwin, VG_(socket)() sets SO_NOSIGPIPE to get EPIPE instead of
1215 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1216 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1217 || defined(VGP_s390x_linux)
1221 args
[1] = (UWord
)msg
;
1223 args
[3] = VKI_MSG_NOSIGNAL
;
1224 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_SEND
, (UWord
)&args
);
1225 return sr_isError(res
) ? -1 : sr_Res(res
);
1227 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1228 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
1229 || defined(VGP_arm64_linux)
1231 res
= VG_(do_syscall6
)(__NR_sendto
, sd
, (UWord
)msg
,
1232 count
, VKI_MSG_NOSIGNAL
, 0,0);
1233 return sr_isError(res
) ? -1 : sr_Res(res
);
1235 # elif defined(VGP_x86_darwin) || defined(VGP_amd64_darwin)
1237 res
= VG_(do_syscall3
)(__NR_write_nocancel
, sd
, (UWord
)msg
, count
);
1238 return sr_isError(res
) ? -1 : sr_Res(res
);
1240 # elif defined(VGO_solaris)
1242 res
= VG_(do_syscall4
)(__NR_send
, sd
, (UWord
)msg
, count
, 0 /*flags*/);
1243 return sr_isError(res
) ? -1 : sr_Res(res
);
1246 # error "Unknown platform"
1250 Int
VG_(getsockname
) ( Int sd
, struct vki_sockaddr
*name
, Int
*namelen
)
1252 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1253 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1254 || defined(VGP_s390x_linux) \
1255 || defined(VGP_mips32_linux)
1259 args
[1] = (UWord
)name
;
1260 args
[2] = (UWord
)namelen
;
1261 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_GETSOCKNAME
, (UWord
)&args
);
1262 return sr_isError(res
) ? -1 : sr_Res(res
);
1264 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1265 || defined(VGP_mips64_linux) || defined(VGP_arm64_linux)
1267 res
= VG_(do_syscall3
)( __NR_getsockname
,
1268 (UWord
)sd
, (UWord
)name
, (UWord
)namelen
);
1269 return sr_isError(res
) ? -1 : sr_Res(res
);
1271 # elif defined(VGO_darwin)
1273 res
= VG_(do_syscall3
)( __NR_getsockname
,
1274 (UWord
)sd
, (UWord
)name
, (UWord
)namelen
);
1275 return sr_isError(res
) ? -1 : sr_Res(res
);
1277 # elif defined(VGO_solaris)
1279 res
= VG_(do_syscall4
)(__NR_getsockname
, sd
, (UWord
)name
, (UWord
)namelen
,
1280 VKI_SOV_DEFAULT
/*version*/);
1281 return sr_isError(res
) ? -1 : sr_Res(res
);
1284 # error "Unknown platform"
1288 Int
VG_(getpeername
) ( Int sd
, struct vki_sockaddr
*name
, Int
*namelen
)
1290 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1291 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1292 || defined(VGP_s390x_linux) \
1293 || defined(VGP_mips32_linux)
1297 args
[1] = (UWord
)name
;
1298 args
[2] = (UWord
)namelen
;
1299 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_GETPEERNAME
, (UWord
)&args
);
1300 return sr_isError(res
) ? -1 : sr_Res(res
);
1302 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1303 || defined(VGP_mips64_linux) || defined(VGP_arm64_linux)
1305 res
= VG_(do_syscall3
)( __NR_getpeername
,
1306 (UWord
)sd
, (UWord
)name
, (UWord
)namelen
);
1307 return sr_isError(res
) ? -1 : sr_Res(res
);
1309 # elif defined(VGO_darwin)
1311 res
= VG_(do_syscall3
)( __NR_getpeername
,
1312 (UWord
)sd
, (UWord
)name
, (UWord
)namelen
);
1313 return sr_isError(res
) ? -1 : sr_Res(res
);
1315 # elif defined(VGO_solaris)
1317 res
= VG_(do_syscall4
)(__NR_getpeername
, sd
, (UWord
)name
, (UWord
)namelen
,
1318 VKI_SOV_DEFAULT
/*version*/);
1319 return sr_isError(res
) ? -1 : sr_Res(res
);
1322 # error "Unknown platform"
1326 Int
VG_(getsockopt
) ( Int sd
, Int level
, Int optname
, void *optval
,
1329 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1330 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1331 || defined(VGP_s390x_linux)
1337 args
[3] = (UWord
)optval
;
1338 args
[4] = (UWord
)optlen
;
1339 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_GETSOCKOPT
, (UWord
)&args
);
1340 return sr_isError(res
) ? -1 : sr_Res(res
);
1342 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1343 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
1344 || defined(VGP_arm64_linux)
1346 res
= VG_(do_syscall5
)( __NR_getsockopt
,
1347 (UWord
)sd
, (UWord
)level
, (UWord
)optname
,
1348 (UWord
)optval
, (UWord
)optlen
);
1349 return sr_isError(res
) ? -1 : sr_Res(res
);
1351 # elif defined(VGO_darwin)
1353 res
= VG_(do_syscall5
)( __NR_getsockopt
,
1354 (UWord
)sd
, (UWord
)level
, (UWord
)optname
,
1355 (UWord
)optval
, (UWord
)optlen
);
1356 return sr_isError(res
) ? -1 : sr_Res(res
);
1358 # elif defined(VGO_solaris)
1360 res
= VG_(do_syscall6
)(__NR_getsockopt
, sd
, level
, optname
, (UWord
)optval
,
1361 (UWord
)optlen
, VKI_SOV_DEFAULT
/*version*/);
1362 return sr_isError(res
) ? -1 : sr_Res(res
);
1365 # error "Unknown platform"
1370 Int
VG_(setsockopt
) ( Int sd
, Int level
, Int optname
, void *optval
,
1373 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1374 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1375 || defined(VGP_s390x_linux)
1381 args
[3] = (UWord
)optval
;
1382 args
[4] = (UWord
)optlen
;
1383 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_SETSOCKOPT
, (UWord
)&args
);
1384 return sr_isError(res
) ? -1 : sr_Res(res
);
1386 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1387 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
1388 || defined(VGP_arm64_linux)
1390 res
= VG_(do_syscall5
)( __NR_setsockopt
,
1391 (UWord
)sd
, (UWord
)level
, (UWord
)optname
,
1392 (UWord
)optval
, (UWord
)optlen
);
1393 return sr_isError(res
) ? -1 : sr_Res(res
);
1395 # elif defined(VGO_darwin)
1397 res
= VG_(do_syscall5
)( __NR_setsockopt
,
1398 (UWord
)sd
, (UWord
)level
, (UWord
)optname
,
1399 (UWord
)optval
, (UWord
)optlen
);
1400 return sr_isError(res
) ? -1 : sr_Res(res
);
1402 # elif defined(VGO_solaris)
1404 res
= VG_(do_syscall6
)( __NR_setsockopt
,
1405 (UWord
)sd
, (UWord
)level
, (UWord
)optname
,
1406 (UWord
)optval
, (UWord
)optlen
,
1407 VKI_SOV_DEFAULT
/*version*/ );
1408 return sr_isError(res
) ? -1 : sr_Res(res
);
1411 # error "Unknown platform"
1416 const HChar
*VG_(basename
)(const HChar
*path
)
1418 static HChar
*buf
= NULL
;
1419 static SizeT buf_len
= 0;
1420 const HChar
*p
, *end
;
1423 0 == VG_(strcmp
)(path
, ""))
1428 p
= path
+ VG_(strlen
)(path
);
1429 while (p
> path
&& *p
== '/') {
1430 // skip all trailing '/'
1434 if (p
== path
&& *p
== '/') return "/"; // all slashes
1438 while (p
> path
&& *p
!= '/') {
1445 SizeT need
= end
-p
+1 + 1;
1446 if (need
> buf_len
) {
1447 buf_len
= (buf_len
== 0) ? 500 : need
;
1448 buf
= VG_(realloc
)("basename", buf
, buf_len
);
1450 VG_(strncpy
)(buf
, p
, end
-p
+1);
1451 buf
[end
-p
+1] = '\0';
1457 const HChar
*VG_(dirname
)(const HChar
*path
)
1459 static HChar
*buf
= NULL
;
1460 static SizeT buf_len
= 0;
1465 0 == VG_(strcmp
)(path
, "") ||
1466 0 == VG_(strcmp
)(path
, "/"))
1471 p
= path
+ VG_(strlen
)(path
);
1472 while (p
> path
&& *p
== '/') {
1473 // skip all trailing '/'
1477 while (p
> path
&& *p
!= '/') {
1483 if (*p
== '/') return "/"; // all slashes
1484 else return "."; // no slashes
1487 while (p
> path
&& *p
== '/') {
1492 SizeT need
= p
-path
+1 + 1;
1493 if (need
> buf_len
) {
1494 buf_len
= (buf_len
== 0) ? 500 : need
;
1495 buf
= VG_(realloc
)("dirname", buf
, buf_len
);
1497 VG_(strncpy
)(buf
, path
, p
-path
+1);
1498 buf
[p
-path
+1] = '\0';
1504 /*--------------------------------------------------------------------*/
1506 /*--------------------------------------------------------------------*/