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 /* Given a file descriptor, attempt to deduce its filename. To do
71 this, we use /proc/self/fd/<FD>. If this doesn't point to a file,
72 or if it doesn't exist, we return False.
73 Upon successful completion *result contains the filename. The
74 filename will be overwritten with the next invocation so callers
75 need to copy the filename if needed. *result is NULL if the filename
77 Bool
VG_(resolve_filename
) ( Int fd
, const HChar
** result
)
79 # if defined(VGO_linux) || defined(VGO_solaris)
80 static HChar
*buf
= NULL
;
81 static SizeT bufsiz
= 0;
83 if (buf
== NULL
) { // first time
85 buf
= VG_(malloc
)("resolve_filename", bufsiz
);
88 HChar tmp
[64]; // large enough
90 # if defined(VGO_linux)
91 VG_(sprintf
)(tmp
, "/proc/self/fd/%d", fd
);
92 # elif defined(VGO_solaris)
93 VG_(sprintf
)(tmp
, "/proc/self/path/%d", fd
);
98 SSizeT res
= VG_(readlink
)(tmp
, buf
, bufsiz
);
100 if (res
== bufsiz
) { // buffer too small; increase and retry
102 buf
= VG_(realloc
)("resolve_filename", buf
, bufsiz
);
105 vg_assert(bufsiz
> res
); // paranoia
106 if (buf
[0] != '/') break;
116 # elif defined(VGO_darwin)
117 HChar tmp
[VKI_MAXPATHLEN
+1];
118 if (0 == VG_(fcntl
)(fd
, VKI_F_GETPATH
, (UWord
)tmp
)) {
119 static HChar
*buf
= NULL
;
122 buf
= VG_(malloc
)("resolve_filename", VKI_MAXPATHLEN
+1);
123 VG_(strcpy
)( buf
, tmp
);
126 if (buf
[0] == '/') return True
;
137 SysRes
VG_(mknod
) ( const HChar
* pathname
, Int mode
, UWord dev
)
139 # if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
140 /* ARM64 wants to use __NR_mknodat rather than __NR_mknod. */
141 SysRes res
= VG_(do_syscall4
)(__NR_mknodat
,
142 VKI_AT_FDCWD
, (UWord
)pathname
, mode
, dev
);
143 # elif defined(VGO_linux) || defined(VGO_darwin)
144 SysRes res
= VG_(do_syscall3
)(__NR_mknod
,
145 (UWord
)pathname
, mode
, dev
);
146 # elif defined(VGO_solaris)
147 SysRes res
= VG_(do_syscall4
)(__NR_mknodat
,
148 VKI_AT_FDCWD
, (UWord
)pathname
, mode
, dev
);
155 SysRes
VG_(open
) ( const HChar
* pathname
, Int flags
, Int mode
)
157 # if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
158 /* ARM64 wants to use __NR_openat rather than __NR_open. */
159 SysRes res
= VG_(do_syscall4
)(__NR_openat
,
160 VKI_AT_FDCWD
, (UWord
)pathname
, flags
, mode
);
161 # elif defined(VGO_linux)
162 SysRes res
= VG_(do_syscall3
)(__NR_open
,
163 (UWord
)pathname
, flags
, mode
);
164 # elif defined(VGO_darwin)
165 SysRes res
= VG_(do_syscall3
)(__NR_open_nocancel
,
166 (UWord
)pathname
, flags
, mode
);
167 # elif defined(VGO_solaris)
168 SysRes res
= VG_(do_syscall4
)(__NR_openat
,
169 VKI_AT_FDCWD
, (UWord
)pathname
, flags
, mode
);
176 Int
VG_(fd_open
) (const HChar
* pathname
, Int flags
, Int mode
)
179 sr
= VG_(open
) (pathname
, flags
, mode
);
186 void VG_(close
) ( Int fd
)
188 /* Hmm. Return value is not checked. That's uncool. */
189 # if defined(VGO_linux) || defined(VGO_solaris)
190 (void)VG_(do_syscall1
)(__NR_close
, fd
);
191 # elif defined(VGO_darwin)
192 (void)VG_(do_syscall1
)(__NR_close_nocancel
, fd
);
198 Int
VG_(read
) ( Int fd
, void* buf
, Int count
)
201 # if defined(VGO_linux) || defined(VGO_solaris)
202 SysRes res
= VG_(do_syscall3
)(__NR_read
, fd
, (UWord
)buf
, count
);
203 # elif defined(VGO_darwin)
204 SysRes res
= VG_(do_syscall3
)(__NR_read_nocancel
, fd
, (UWord
)buf
, count
);
208 if (sr_isError(res
)) {
209 ret
= - (Int
)(Word
)sr_Err(res
);
212 ret
= (Int
)(Word
)sr_Res(res
);
218 Int
VG_(write
) ( Int fd
, const void* buf
, Int count
)
221 # if defined(VGO_linux) || defined(VGO_solaris)
222 SysRes res
= VG_(do_syscall3
)(__NR_write
, fd
, (UWord
)buf
, count
);
223 # elif defined(VGO_darwin)
224 SysRes res
= VG_(do_syscall3
)(__NR_write_nocancel
, fd
, (UWord
)buf
, count
);
228 if (sr_isError(res
)) {
229 ret
= - (Int
)(Word
)sr_Err(res
);
232 ret
= (Int
)(Word
)sr_Res(res
);
239 Int
VG_(pipe
) ( Int fd
[2] )
241 # if defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
242 /* __NR_pipe has a strange return convention on mips32-linux. */
243 SysRes res
= VG_(do_syscall1
)(__NR_pipe
, (UWord
)fd
);
244 if (!sr_isError(res
)) {
245 fd
[0] = (Int
)sr_Res(res
);
246 fd
[1] = (Int
)sr_ResEx(res
);
251 # elif defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
252 SysRes res
= VG_(do_syscall2
)(__NR_pipe2
, (UWord
)fd
, 0);
253 return sr_isError(res
) ? -1 : 0;
254 # elif defined(VGO_linux)
255 SysRes res
= VG_(do_syscall1
)(__NR_pipe
, (UWord
)fd
);
256 return sr_isError(res
) ? -1 : 0;
257 # elif defined(VGO_darwin)
258 /* __NR_pipe is UX64, so produces a double-word result */
259 SysRes res
= VG_(do_syscall0
)(__NR_pipe
);
260 if (!sr_isError(res
)) {
261 fd
[0] = (Int
)sr_Res(res
);
262 fd
[1] = (Int
)sr_ResHI(res
);
264 return sr_isError(res
) ? -1 : 0;
265 # elif defined(VGO_solaris)
266 # if defined(SOLARIS_NEW_PIPE_SYSCALL)
267 SysRes res
= VG_(do_syscall2
)(__NR_pipe
, (UWord
)fd
, 0);
268 return sr_isError(res
) ? -1 : 0;
270 SysRes res
= VG_(do_syscall0
)(__NR_pipe
);
271 if (!sr_isError(res
)) {
272 fd
[0] = (Int
)sr_Res(res
);
273 fd
[1] = (Int
)sr_ResHI(res
);
275 return sr_isError(res
) ? -1 : 0;
282 Off64T
VG_(lseek
) ( Int fd
, Off64T offset
, Int whence
)
284 # if defined(VGO_linux) || defined(VGP_amd64_darwin)
285 # if defined(__NR__llseek)
287 SysRes res
= VG_(do_syscall5
)(__NR__llseek
, fd
,
288 offset
>> 32, offset
& 0xffffffff,
289 (UWord
)&result
, whence
);
290 return sr_isError(res
) ? (-1) : result
;
292 SysRes res
= VG_(do_syscall3
)(__NR_lseek
, fd
, offset
, whence
);
293 vg_assert(sizeof(Off64T
) == sizeof(sr_Res(res
)));
294 return sr_isError(res
) ? (-1) : sr_Res(res
);
296 # elif defined(VGP_x86_darwin)
297 SysRes res
= VG_(do_syscall4
)(__NR_lseek
, fd
,
298 offset
& 0xffffffff, offset
>> 32, whence
);
299 return sr_isError(res
) ? (-1) : sr_Res(res
);
300 # elif defined(VGP_x86_solaris)
301 SysRes res
= VG_(do_syscall4
)(__NR_llseek
, fd
,
302 offset
& 0xffffffff, offset
>> 32, whence
);
303 return sr_isError(res
) ? (-1) : ((ULong
)sr_ResHI(res
) << 32 | sr_Res(res
));
304 # elif defined(VGP_amd64_solaris)
305 SysRes res
= VG_(do_syscall3
)(__NR_lseek
, fd
, offset
, whence
);
306 vg_assert(sizeof(Off64T
) == sizeof(Word
));
307 return sr_isError(res
) ? (-1) : sr_Res(res
);
309 # error "Unknown plat"
311 /* if you change the error-reporting conventions of this, also
312 change all usage points. */
316 /* stat/fstat support. It's uggerly. We have impedance-match into a
317 'struct vg_stat' in order to have a single structure that callers
318 can use consistently on all platforms. */
320 #define TRANSLATE_TO_vg_stat(_p_vgstat, _p_vkistat) \
322 (_p_vgstat)->dev = (ULong)( (_p_vkistat)->st_dev ); \
323 (_p_vgstat)->ino = (ULong)( (_p_vkistat)->st_ino ); \
324 (_p_vgstat)->nlink = (ULong)( (_p_vkistat)->st_nlink ); \
325 (_p_vgstat)->mode = (UInt) ( (_p_vkistat)->st_mode ); \
326 (_p_vgstat)->uid = (UInt) ( (_p_vkistat)->st_uid ); \
327 (_p_vgstat)->gid = (UInt) ( (_p_vkistat)->st_gid ); \
328 (_p_vgstat)->rdev = (ULong)( (_p_vkistat)->st_rdev ); \
329 (_p_vgstat)->size = (Long) ( (_p_vkistat)->st_size ); \
330 (_p_vgstat)->blksize = (ULong)( (_p_vkistat)->st_blksize ); \
331 (_p_vgstat)->blocks = (ULong)( (_p_vkistat)->st_blocks ); \
332 (_p_vgstat)->atime = (ULong)( (_p_vkistat)->st_atime ); \
333 (_p_vgstat)->atime_nsec = (ULong)( (_p_vkistat)->st_atime_nsec ); \
334 (_p_vgstat)->mtime = (ULong)( (_p_vkistat)->st_mtime ); \
335 (_p_vgstat)->mtime_nsec = (ULong)( (_p_vkistat)->st_mtime_nsec ); \
336 (_p_vgstat)->ctime = (ULong)( (_p_vkistat)->st_ctime ); \
337 (_p_vgstat)->ctime_nsec = (ULong)( (_p_vkistat)->st_ctime_nsec ); \
340 #define TRANSLATE_statx_TO_vg_stat(_p_vgstat, _p_vkistat) \
342 (_p_vgstat)->dev = VG_MAKEDEV( (_p_vkistat)->stx_dev_major, \
343 (_p_vkistat)->stx_dev_minor ); \
344 (_p_vgstat)->ino = (ULong)( (_p_vkistat)->stx_ino ); \
345 (_p_vgstat)->nlink = (ULong)( (_p_vkistat)->stx_nlink ); \
346 (_p_vgstat)->mode = (UInt) ( (_p_vkistat)->stx_mode ); \
347 (_p_vgstat)->uid = (UInt) ( (_p_vkistat)->stx_uid ); \
348 (_p_vgstat)->gid = (UInt) ( (_p_vkistat)->stx_gid ); \
349 (_p_vgstat)->rdev = VG_MAKEDEV( (_p_vkistat)->stx_rdev_major, \
350 (_p_vkistat)->stx_rdev_minor ); \
351 (_p_vgstat)->size = (Long) ( (_p_vkistat)->stx_size ); \
352 (_p_vgstat)->blksize = (ULong)( (_p_vkistat)->stx_blksize ); \
353 (_p_vgstat)->blocks = (ULong)( (_p_vkistat)->stx_blocks ); \
354 (_p_vgstat)->atime = (ULong)( (_p_vkistat)->stx_atime.tv_sec ); \
355 (_p_vgstat)->atime_nsec = (ULong)( (_p_vkistat)->stx_atime.tv_nsec ); \
356 (_p_vgstat)->mtime = (ULong)( (_p_vkistat)->stx_mtime.tv_sec ); \
357 (_p_vgstat)->mtime_nsec = (ULong)( (_p_vkistat)->stx_mtime.tv_nsec ); \
358 (_p_vgstat)->ctime = (ULong)( (_p_vkistat)->stx_ctime.tv_sec ); \
359 (_p_vgstat)->ctime_nsec = (ULong)( (_p_vkistat)->stx_ctime.tv_nsec ); \
362 SysRes
VG_(stat
) ( const HChar
* file_name
, struct vg_stat
* vgbuf
)
365 VG_(memset
)(vgbuf
, 0, sizeof(*vgbuf
));
367 # if defined(VGO_linux)
368 /* On Linux, first try with statx. If that doesn't work out, fall back to
369 the stat64 or vanilla version. */
370 { struct vki_statx buf
;
371 res
= VG_(do_syscall5
)(__NR_statx
, VKI_AT_FDCWD
, (UWord
)file_name
, 0,
372 VKI_STATX_ALL
, (UWord
)&buf
);
373 if (!(sr_isError(res
) && sr_Err(res
) == VKI_ENOSYS
)) {
374 /* Success, or any failure except ENOSYS */
375 if (!sr_isError(res
))
376 TRANSLATE_statx_TO_vg_stat(vgbuf
, &buf
);
381 # if defined(VGO_linux) || defined(VGO_darwin)
382 /* Try with stat64. This is the second candidate on Linux, and the first
383 one on Darwin. If that doesn't work out, fall back to vanilla version.
385 # if defined(__NR_stat64)
386 { struct vki_stat64 buf64
;
387 res
= VG_(do_syscall2
)(__NR_stat64
, (UWord
)file_name
, (UWord
)&buf64
);
388 if (!(sr_isError(res
) && sr_Err(res
) == VKI_ENOSYS
)) {
389 /* Success, or any failure except ENOSYS */
390 if (!sr_isError(res
))
391 TRANSLATE_TO_vg_stat(vgbuf
, &buf64
);
395 # endif /* defined(__NR_stat64) */
396 # if defined(__NR_stat) || defined(VGP_arm64_linux)
397 /* This is the fallback ("vanilla version"). */
398 { struct vki_stat buf
;
399 # if defined(VGP_arm64_linux)
400 res
= VG_(do_syscall3
)(__NR3264_fstatat
, VKI_AT_FDCWD
,
401 (UWord
)file_name
, (UWord
)&buf
);
403 res
= VG_(do_syscall2
)(__NR_stat
, (UWord
)file_name
, (UWord
)&buf
);
405 if (!sr_isError(res
))
406 TRANSLATE_TO_vg_stat(vgbuf
, &buf
);
410 # elif defined(VGO_solaris)
412 # if defined(VGP_x86_solaris)
413 struct vki_stat64 buf64
;
414 res
= VG_(do_syscall4
)(__NR_fstatat64
, VKI_AT_FDCWD
, (UWord
)file_name
,
416 # elif defined(VGP_amd64_solaris)
417 struct vki_stat buf64
;
418 res
= VG_(do_syscall4
)(__NR_fstatat
, VKI_AT_FDCWD
, (UWord
)file_name
,
421 # error "Unknown platform"
423 if (!sr_isError(res
))
424 TRANSLATE_TO_vg_stat(vgbuf
, &buf64
);
432 Int
VG_(fstat
) ( Int fd
, struct vg_stat
* vgbuf
)
435 VG_(memset
)(vgbuf
, 0, sizeof(*vgbuf
));
437 # if defined(VGO_linux)
438 /* On Linux, first try with statx. If that doesn't work out, fall back to
439 the fstat64 or vanilla version. */
440 { struct vki_statx buf
;
441 const char* file_name
= "";
442 res
= VG_(do_syscall5
)(__NR_statx
, fd
, (RegWord
)file_name
,
443 VKI_AT_EMPTY_PATH
, VKI_STATX_ALL
, (RegWord
)&buf
);
444 if (!(sr_isError(res
) && sr_Err(res
) == VKI_ENOSYS
)) {
445 /* Success, or any failure except ENOSYS */
446 if (!sr_isError(res
))
447 TRANSLATE_statx_TO_vg_stat(vgbuf
, &buf
);
448 return sr_isError(res
) ? (-1) : 0;
452 # if defined(VGO_linux) || defined(VGO_darwin)
453 /* Try with fstat64. This is the second candidate on Linux, and the first
454 one on Darwin. If that doesn't work out, fall back to vanilla version.
456 # if defined(__NR_fstat64)
457 { struct vki_stat64 buf64
;
458 res
= VG_(do_syscall2
)(__NR_fstat64
, (UWord
)fd
, (UWord
)&buf64
);
459 if (!(sr_isError(res
) && sr_Err(res
) == VKI_ENOSYS
)) {
460 /* Success, or any failure except ENOSYS */
461 if (!sr_isError(res
))
462 TRANSLATE_TO_vg_stat(vgbuf
, &buf64
);
463 return sr_isError(res
) ? (-1) : 0;
466 # endif /* defined(__NR_fstat64) */
467 # if defined(__NR_fstat)
468 { struct vki_stat buf
;
469 res
= VG_(do_syscall2
)(__NR_fstat
, (RegWord
)fd
, (RegWord
)(Addr
)&buf
);
470 if (!sr_isError(res
))
471 TRANSLATE_TO_vg_stat(vgbuf
, &buf
);
472 return sr_isError(res
) ? (-1) : 0;
475 # elif defined(VGO_solaris)
477 # if defined(VGP_x86_solaris)
478 struct vki_stat64 buf64
;
479 res
= VG_(do_syscall4
)(__NR_fstatat64
, (UWord
)fd
, 0, (UWord
)&buf64
, 0);
480 # elif defined(VGP_amd64_solaris)
481 struct vki_stat buf64
;
482 res
= VG_(do_syscall4
)(__NR_fstatat
, (UWord
)fd
, 0, (UWord
)&buf64
, 0);
484 # error "Unknown platform"
486 if (!sr_isError(res
))
487 TRANSLATE_TO_vg_stat(vgbuf
, &buf64
);
488 return sr_isError(res
) ? (-1) : 0;
495 #undef TRANSLATE_TO_vg_stat
496 #undef TRANSLATE_statx_TO_vg_stat
498 Long
VG_(fsize
) ( Int fd
)
501 Int res
= VG_(fstat
)( fd
, &buf
);
502 return (res
== -1) ? (-1LL) : buf
.size
;
505 SysRes
VG_(getxattr
) ( const HChar
* file_name
, const HChar
* attr_name
, Addr attr_value
, SizeT attr_value_len
)
508 #if defined(VGO_linux)
509 res
= VG_(do_syscall4
)(__NR_getxattr
, (UWord
)file_name
, (UWord
)attr_name
,
510 attr_value
, attr_value_len
);
512 res
= VG_(mk_SysRes_Error
)(VKI_ENOSYS
);
517 Bool
VG_(is_dir
) ( const HChar
* f
)
520 SysRes res
= VG_(stat
)(f
, &buf
);
521 return sr_isError(res
) ? False
522 : VKI_S_ISDIR(buf
.mode
) ? True
: False
;
525 SysRes
VG_(dup
) ( Int oldfd
)
527 # if defined(VGO_linux) || defined(VGO_darwin)
528 return VG_(do_syscall1
)(__NR_dup
, oldfd
);
529 # elif defined(VGO_solaris)
530 return VG_(do_syscall3
)(__NR_fcntl
, oldfd
, F_DUPFD
, 0);
536 SysRes
VG_(dup2
) ( Int oldfd
, Int newfd
)
538 # if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
539 /* We only have dup3, that means we have to mimic dup2.
540 The only real difference is when oldfd == newfd.
541 dup3 always returns an error, but dup2 returns only an
542 error if the fd is invalid, otherwise it returns newfd. */
543 if (oldfd
== newfd
) {
544 if (VG_(fcntl
)(oldfd
, VKI_F_GETFL
, 0) == -1)
545 return VG_(mk_SysRes_Error
)(VKI_EBADF
);
546 return VG_(mk_SysRes_Success
)(newfd
);
548 return VG_(do_syscall3
)(__NR_dup3
, oldfd
, newfd
, 0);
549 # elif defined(VGO_linux) || defined(VGO_darwin)
550 return VG_(do_syscall2
)(__NR_dup2
, oldfd
, newfd
);
551 # elif defined(VGO_solaris)
552 return VG_(do_syscall3
)(__NR_fcntl
, oldfd
, F_DUP2FD
, newfd
);
558 /* Returns -1 on error. */
559 Int
VG_(fcntl
) ( Int fd
, Int cmd
, Addr arg
)
561 # if defined(VGO_linux) || defined(VGO_solaris)
562 # if defined(VGP_nanomips_linux)
563 SysRes res
= VG_(do_syscall3
)(__NR_fcntl64
, fd
, cmd
, arg
);
565 SysRes res
= VG_(do_syscall3
)(__NR_fcntl
, fd
, cmd
, arg
);
567 # elif defined(VGO_darwin)
568 SysRes res
= VG_(do_syscall3
)(__NR_fcntl_nocancel
, fd
, cmd
, arg
);
572 return sr_isError(res
) ? -1 : sr_Res(res
);
575 Int
VG_(rename
) ( const HChar
* old_name
, const HChar
* new_name
)
577 # if defined(VGO_solaris) || defined(VGP_arm64_linux)
578 SysRes res
= VG_(do_syscall4
)(__NR_renameat
, VKI_AT_FDCWD
, (UWord
)old_name
,
579 VKI_AT_FDCWD
, (UWord
)new_name
);
580 # elif defined(VGP_nanomips_linux)
581 SysRes res
= VG_(do_syscall5
)(__NR_renameat2
, VKI_AT_FDCWD
, (UWord
)old_name
,
582 VKI_AT_FDCWD
, (UWord
)new_name
, 0);
584 # elif defined(VGO_linux) || defined(VGO_darwin)
585 SysRes res
= VG_(do_syscall2
)(__NR_rename
, (UWord
)old_name
, (UWord
)new_name
);
589 return sr_isError(res
) ? (-1) : 0;
592 Int
VG_(unlink
) ( const HChar
* file_name
)
594 # if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
595 SysRes res
= VG_(do_syscall2
)(__NR_unlinkat
, VKI_AT_FDCWD
,
597 # elif defined(VGO_linux) || defined(VGO_darwin)
598 SysRes res
= VG_(do_syscall1
)(__NR_unlink
, (UWord
)file_name
);
599 # elif defined(VGO_solaris)
600 SysRes res
= VG_(do_syscall3
)(__NR_unlinkat
, VKI_AT_FDCWD
,
601 (UWord
)file_name
, 0);
605 return sr_isError(res
) ? (-1) : 0;
608 /* The working directory at startup.
609 All that is really needed is to note the cwd at process startup.
610 Hence VG_(record_startup_wd) notes it (in a platform dependent way)
611 and VG_(get_startup_wd) produces the noted value. */
612 static HChar
*startup_wd
;
614 /* Record the process' working directory at startup. Is intended to
615 be called exactly once, at startup, before the working directory
617 void VG_(record_startup_wd
) ( void )
619 # if defined(VGO_linux) || defined(VGO_solaris)
620 /* Simple: just ask the kernel */
625 startup_wd
= VG_(realloc
)("startup_wd", startup_wd
, szB
);
626 VG_(memset
)(startup_wd
, 0, szB
);
627 res
= VG_(do_syscall2
)(__NR_getcwd
, (UWord
)startup_wd
, szB
-1);
628 } while (sr_isError(res
) && sr_Err(res
) == VKI_ERANGE
);
630 if (sr_isError(res
)) {
631 VG_(free
)(startup_wd
);
636 vg_assert(startup_wd
[szB
-1] == 0);
638 # elif defined(VGO_darwin)
639 /* We can't ask the kernel, so instead rely on launcher-*.c to
640 tell us the startup path. Note the env var is keyed to the
641 parent's PID, not ours, since our parent is the launcher
643 { HChar envvar
[100]; // large enough
645 VG_(memset
)(envvar
, 0, sizeof(envvar
));
646 VG_(sprintf
)(envvar
, "VALGRIND_STARTUP_PWD_%d_XYZZY",
647 (Int
)VG_(getppid
)());
648 wd
= VG_(getenv
)( envvar
);
651 SizeT need
= VG_(strlen
)(wd
) + 1;
652 startup_wd
= VG_(malloc
)("startup_wd", need
);
653 VG_(strcpy
)(startup_wd
, wd
);
660 /* Return the previously acquired startup_wd or NULL. */
661 const HChar
*VG_(get_startup_wd
) ( void )
666 SysRes
VG_(poll
) (struct vki_pollfd
*fds
, Int nfds
, Int timeout
)
669 # if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
670 /* ARM64 wants to use __NR_ppoll rather than __NR_poll. */
671 struct vki_timespec timeout_ts
;
673 timeout_ts
.tv_sec
= timeout
/ 1000;
674 timeout_ts
.tv_nsec
= ((long)timeout
% 1000) * 1000000;
676 res
= VG_(do_syscall4
)(__NR_ppoll
,
678 (UWord
)(timeout
>= 0 ? &timeout_ts
: NULL
),
680 # elif defined(VGO_linux)
681 res
= VG_(do_syscall3
)(__NR_poll
, (UWord
)fds
, nfds
, timeout
);
682 # elif defined(VGO_darwin)
683 res
= VG_(do_syscall3
)(__NR_poll_nocancel
, (UWord
)fds
, nfds
, timeout
);
684 # elif defined(VGO_solaris)
685 struct vki_timespec ts
;
686 struct vki_timespec
*tsp
;
691 ts
.tv_sec
= timeout
/ 1000;
692 ts
.tv_nsec
= (timeout
% 1000) * 1000000;
696 res
= VG_(do_syscall4
)(__NR_pollsys
, (UWord
)fds
, nfds
, (UWord
)tsp
, 0);
704 /* Performs the readlink operation and puts the result into 'buf'.
705 Note, that the string in 'buf' is *not* null-terminated. The function
706 returns the number of characters put into 'buf' or -1 if an error
708 SSizeT
VG_(readlink
) (const HChar
* path
, HChar
* buf
, SizeT bufsiz
)
711 /* res = readlink( path, buf, bufsiz ); */
712 # if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
713 res
= VG_(do_syscall4
)(__NR_readlinkat
, VKI_AT_FDCWD
,
714 (UWord
)path
, (UWord
)buf
, bufsiz
);
715 # elif defined(VGO_linux) || defined(VGO_darwin)
716 res
= VG_(do_syscall3
)(__NR_readlink
, (UWord
)path
, (UWord
)buf
, bufsiz
);
717 # elif defined(VGO_solaris)
718 res
= VG_(do_syscall4
)(__NR_readlinkat
, VKI_AT_FDCWD
, (UWord
)path
,
723 return sr_isError(res
) ? -1 : sr_Res(res
);
726 #if defined(VGO_linux) || defined(VGO_solaris)
727 Int
VG_(getdents64
) (Int fd
, struct vki_dirent64
*dirp
, UInt count
)
730 /* res = getdents( fd, dirp, count ); */
731 # if defined(VGP_amd64_solaris)
732 /* This silently assumes that dirent64 and dirent on amd64 are same, which
733 they should always be. */
734 res
= VG_(do_syscall3
)(__NR_getdents
, fd
, (UWord
)dirp
, count
);
736 res
= VG_(do_syscall3
)(__NR_getdents64
, fd
, (UWord
)dirp
, count
);
737 # if defined(VGA_mips64)
738 /* The MIPS64 getdents64() system call is only present in 3.10+ kernels.
739 If the getdents64() system call is not available fall back to using
740 getdents() and modify the result to be compatible with getdents64(). */
741 if (sr_isError(res
) && (sr_Err(res
) == VKI_ENOSYS
)) {
743 res
= VG_(do_syscall3
)(__NR_getdents
, fd
, (UWord
)dirp
, count
);
750 struct vki_dirent64 d
;
754 u
= (union dirents
*)p
;
755 /* This should not happen, but just in case... */
756 if (p
+ u
->m
.d_reclen
> (char *)dirp
+ r
)
758 /* shuffle the dirent */
759 type
= *(p
+ u
->m
.d_reclen
- 1);
760 VG_(memmove
)(u
->d
.d_name
, u
->m
.d_name
,
762 - offsetof(struct vki_dirent
, d_name
) + 1);
765 } while (p
< (char *)dirp
+ r
);
770 return sr_isError(res
) ? -1 : sr_Res(res
);
774 /* Check accessibility of a file. Returns zero for access granted,
775 nonzero otherwise. */
776 Int
VG_(access
) ( const HChar
* path
, Bool irusr
, Bool iwusr
, Bool ixusr
)
778 # if defined(VGO_linux)
779 /* Very annoyingly, I cannot find any definition for R_OK et al in
780 the kernel interfaces. Therefore I reluctantly resort to
781 hardwiring in these magic numbers that I determined by
788 UWord w
= (irusr
? VKI_R_OK
: 0)
789 | (iwusr
? VKI_W_OK
: 0)
790 | (ixusr
? VKI_X_OK
: 0);
791 # if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
792 SysRes res
= VG_(do_syscall3
)(__NR_faccessat
, VKI_AT_FDCWD
, (UWord
)path
, w
);
793 # elif defined(VGO_linux) || defined(VGO_darwin)
794 SysRes res
= VG_(do_syscall2
)(__NR_access
, (UWord
)path
, w
);
795 # elif defined(VGO_solaris)
796 SysRes res
= VG_(do_syscall4
)(__NR_faccessat
, VKI_AT_FDCWD
, (UWord
)path
,
801 return sr_isError(res
) ? 1 : 0;
803 # if defined(VGO_linux)
811 Emulate the normal Unix permissions checking algorithm.
813 If owner matches, then use the owner permissions, else
814 if group matches, then use the group permissions, else
815 use other permissions.
817 Note that we can't deal properly with SUID/SGID. By default
818 (allow_setuid == False), we refuse to run them (otherwise the
819 executable may misbehave if it doesn't have the permissions it
820 thinks it does). However, the caller may indicate that setuid
821 executables are allowed, for example if we are going to exec them
822 but not trace into them (iow, client sys_execve when
823 clo_trace_children == False).
825 If VKI_EACCES is returned (iow, permission was refused), then
826 *is_setuid is set to True iff permission was refused because the
827 executable is setuid.
829 /* returns: 0 = success, non-0 is failure */
830 Int
VG_(check_executable
)(/*OUT*/Bool
* is_setuid
,
831 const HChar
* f
, Bool allow_setuid
)
834 SysRes res
= VG_(stat
)(f
, &st
);
839 if (sr_isError(res
)) {
843 if ( VKI_S_ISDIR (st
.mode
) ) {
847 if ( (st
.mode
& (VKI_S_ISUID
| VKI_S_ISGID
)) && !allow_setuid
) {
853 res
= VG_(getxattr
)(f
, "security.capability", (Addr
)0, 0);
854 if (!sr_isError(res
) && !allow_setuid
) {
860 if (VG_(geteuid
)() == st
.uid
) {
861 if (!(st
.mode
& VKI_S_IXUSR
))
866 if (VG_(getegid
)() == st
.gid
)
872 /* Find out # groups, allocate large enough array and fetch groups */
873 ngrp
= VG_(getgroups
)(0, NULL
);
875 groups
= VG_(malloc
)("check_executable", ngrp
* sizeof *groups
);
876 ngrp
= VG_(getgroups
)(ngrp
, groups
);
880 /* ngrp will be -1 if VG_(getgroups) failed. */
881 for (i
= 0; i
< ngrp
; i
++) {
882 if (groups
[i
] == st
.gid
) {
891 if (!(st
.mode
& VKI_S_IXGRP
)) {
894 } else if (!(st
.mode
& VKI_S_IXOTH
)) {
902 SysRes
VG_(pread
) ( Int fd
, void* buf
, Int count
, OffT offset
)
905 // on 32 bits platforms, we receive a 32 bits OffT but
906 // we must extend it to pass a long long 64 bits.
907 # if defined(VGP_x86_linux)
908 vg_assert(sizeof(OffT
) == 4);
909 res
= VG_(do_syscall5
)(__NR_pread64
, fd
, (UWord
)buf
, count
,
910 offset
, 0); // Little endian long long
912 # elif defined(VGP_arm_linux)
913 vg_assert(sizeof(OffT
) == 4);
914 res
= VG_(do_syscall5
)(__NR_pread64
, fd
, (UWord
)buf
, count
,
915 0, offset
); // Big endian long long
917 # elif defined(VGP_ppc32_linux)
918 vg_assert(sizeof(OffT
) == 4);
919 res
= VG_(do_syscall6
)(__NR_pread64
, fd
, (UWord
)buf
, count
,
920 0, // Padding needed on PPC32
921 0, offset
); // Big endian long long
923 # elif (defined(VGP_mips32_linux) || defined(VGP_nanomips_linux)) \
924 && (VKI_LITTLE_ENDIAN)
925 vg_assert(sizeof(OffT
) == 4);
926 res
= VG_(do_syscall6
)(__NR_pread64
, fd
, (UWord
)buf
, count
,
929 # elif (defined(VGP_mips32_linux) || defined(VGP_nanomips_linux)) \
931 vg_assert(sizeof(OffT
) == 4);
932 res
= VG_(do_syscall6
)(__NR_pread64
, fd
, (UWord
)buf
, count
,
935 # elif defined(VGP_amd64_linux) || defined(VGP_s390x_linux) \
936 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
937 || defined(VGP_mips64_linux) || defined(VGP_arm64_linux)
938 res
= VG_(do_syscall4
)(__NR_pread64
, fd
, (UWord
)buf
, count
, offset
);
940 # elif defined(VGP_amd64_darwin)
941 vg_assert(sizeof(OffT
) == 8);
942 res
= VG_(do_syscall4
)(__NR_pread_nocancel
, fd
, (UWord
)buf
, count
, offset
);
944 # elif defined(VGP_x86_darwin)
945 vg_assert(sizeof(OffT
) == 8);
946 res
= VG_(do_syscall5
)(__NR_pread_nocancel
, fd
, (UWord
)buf
, count
,
947 offset
& 0xffffffff, offset
>> 32);
949 # elif defined(VGP_x86_solaris)
950 vg_assert(sizeof(OffT
) == 4);
951 res
= VG_(do_syscall4
)(__NR_pread
, fd
, (UWord
)buf
, count
, offset
);
953 # elif defined(VGP_amd64_solaris)
954 vg_assert(sizeof(OffT
) == 8);
955 res
= VG_(do_syscall4
)(__NR_pread
, fd
, (UWord
)buf
, count
, offset
);
958 # error "Unknown platform"
962 /* Return the name of a directory for temporary files. */
963 const HChar
*VG_(tmpdir
)(void)
967 tmpdir
= VG_(getenv
)("TMPDIR");
968 if (tmpdir
== NULL
|| *tmpdir
== '\0') tmpdir
= VG_TMPDIR
;
969 if (tmpdir
== NULL
|| *tmpdir
== '\0') tmpdir
= "/tmp"; /* fallback */
974 static const HChar mkstemp_format
[] = "%s/valgrind_%s_%08x";
976 SizeT
VG_(mkstemp_fullname_bufsz
) ( SizeT part_of_name_len
)
978 return VG_(strlen
)(mkstemp_format
)
979 + VG_(strlen
)(VG_(tmpdir
)()) - 2 // %s tmpdir
980 + part_of_name_len
- 2 // %s part_of_name
986 Int
VG_(mkstemp
) ( const HChar
* part_of_name
, /*OUT*/HChar
* fullname
)
993 vg_assert(part_of_name
);
995 n
= VG_(strlen
)(part_of_name
);
996 vg_assert(n
> 0 && n
< 100);
998 seed
= (VG_(getpid
)() << 9) ^ VG_(getppid
)();
1000 /* Determine sensible location for temporary files */
1001 tmpdir
= VG_(tmpdir
)();
1007 VG_(sprintf
)( fullname
, mkstemp_format
,
1008 tmpdir
, part_of_name
, VG_(random
)( &seed
));
1010 VG_(printf
)("VG_(mkstemp): trying: %s\n", fullname
);
1012 sres
= VG_(open
)(fullname
,
1013 VKI_O_CREAT
|VKI_O_RDWR
|VKI_O_EXCL
|VKI_O_TRUNC
,
1014 VKI_S_IRUSR
|VKI_S_IWUSR
);
1015 if (sr_isError(sres
)) {
1016 VG_(umsg
)("VG_(mkstemp): failed to create temp file: %s\n", fullname
);
1019 /* VG_(safe_fd) doesn't return if it fails. */
1020 return VG_(safe_fd
)( sr_Res(sres
) );
1026 /* ---------------------------------------------------------------------
1027 Socket-related stuff.
1028 ------------------------------------------------------------------ */
1031 Int
parse_inet_addr_and_port ( const HChar
* str
, UInt
* ip_addr
, UShort
* port
);
1034 Int
my_connect ( Int sockfd
, struct vki_sockaddr_in
* serv_addr
, Int addrlen
);
1036 UInt
VG_(htonl
) ( UInt x
)
1038 # if defined(VG_BIGENDIAN)
1042 (((x
>> 24) & 0xFF) << 0) | (((x
>> 16) & 0xFF) << 8)
1043 | (((x
>> 8) & 0xFF) << 16) | (((x
>> 0) & 0xFF) << 24);
1047 UInt
VG_(ntohl
) ( UInt x
)
1049 # if defined(VG_BIGENDIAN)
1053 (((x
>> 24) & 0xFF) << 0) | (((x
>> 16) & 0xFF) << 8)
1054 | (((x
>> 8) & 0xFF) << 16) | (((x
>> 0) & 0xFF) << 24);
1058 UShort
VG_(htons
) ( UShort x
)
1060 # if defined(VG_BIGENDIAN)
1064 (((x
>> 8) & 0xFF) << 0) | (((x
>> 0) & 0xFF) << 8);
1068 UShort
VG_(ntohs
) ( UShort x
)
1070 # if defined(VG_BIGENDIAN)
1074 (((x
>> 8) & 0xFF) << 0) | (((x
>> 0) & 0xFF) << 8);
1079 /* The main function.
1081 Supplied string contains either an ip address "192.168.0.1" or
1082 an ip address and port pair, "192.168.0.1:1500". Parse these,
1084 -1 if there is a parse error
1085 -2 if no parse error, but specified host:port cannot be opened
1086 the relevant file (socket) descriptor, otherwise.
1089 Int
VG_(connect_via_socket
)( const HChar
* str
)
1091 # if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris)
1093 struct vki_sockaddr_in servAddr
;
1095 UShort port
= VG_CLO_DEFAULT_LOGPORT
;
1096 Bool ok
= parse_inet_addr_and_port(str
, &ip
, &port
);
1101 // VG_(printf)("ip = %d.%d.%d.%d, port %d\n",
1102 // (ip >> 24) & 0xFF, (ip >> 16) & 0xFF,
1103 // (ip >> 8) & 0xFF, ip & 0xFF,
1106 servAddr
.sin_family
= VKI_AF_INET
;
1107 servAddr
.sin_addr
.s_addr
= VG_(htonl
)(ip
);
1108 servAddr
.sin_port
= VG_(htons
)(port
);
1111 sd
= VG_(socket
)(VKI_AF_INET
, VKI_SOCK_STREAM
, 0 /* IPPROTO_IP ? */);
1113 /* this shouldn't happen ... nevertheless */
1117 /* connect to server */
1118 res
= my_connect(sd
, &servAddr
, sizeof(servAddr
));
1120 /* connection failed */
1127 # error "Unknown OS"
1132 /* Let d = one or more digits. Accept either:
1133 d.d.d.d or d.d.d.d:d
1135 static Int
parse_inet_addr_and_port ( const HChar
* str
, UInt
* ip_addr
, UShort
* port
)
1137 # define GET_CH ((*str) ? (*str++) : 0)
1138 UInt ipa
, i
, j
, c
, any
;
1140 for (i
= 0; i
< 4; i
++) {
1145 if (c
< '0' || c
> '9') break;
1146 j
= 10 * j
+ (int)(c
- '0');
1149 if (any
== 0 || j
> 255) goto syntaxerr
;
1150 ipa
= (ipa
<< 8) + j
;
1151 if (i
<= 2 && c
!= '.') goto syntaxerr
;
1153 if (c
== 0 || c
== ':')
1155 if (c
== 0) goto ok
;
1156 if (c
!= ':') goto syntaxerr
;
1161 if (c
< '0' || c
> '9') break;
1162 j
= j
* 10 + (int)(c
- '0');
1164 if (j
> 65535) goto syntaxerr
;
1166 if (any
== 0 || c
!= 0) goto syntaxerr
;
1167 if (j
< 1024) goto syntaxerr
;
1176 // GrP fixme safe_fd?
1177 Int
VG_(socket
) ( Int domain
, Int type
, Int protocol
)
1179 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1180 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1181 || defined(VGP_s390x_linux)
1187 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_SOCKET
, (UWord
)&args
);
1188 return sr_isError(res
) ? -1 : sr_Res(res
);
1190 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1191 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
1192 || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
1194 res
= VG_(do_syscall3
)(__NR_socket
, domain
, type
, protocol
);
1195 return sr_isError(res
) ? -1 : sr_Res(res
);
1197 # elif defined(VGO_darwin)
1199 res
= VG_(do_syscall3
)(__NR_socket
, domain
, type
, protocol
);
1200 if (!sr_isError(res
)) {
1201 // Set SO_NOSIGPIPE so write() returns EPIPE instead of raising SIGPIPE
1204 res2
= VG_(do_syscall5
)(__NR_setsockopt
, sr_Res(res
), VKI_SOL_SOCKET
,
1205 VKI_SO_NOSIGPIPE
, (UWord
)&optval
,
1207 // ignore setsockopt() error
1209 return sr_isError(res
) ? -1 : sr_Res(res
);
1211 # elif defined(VGO_solaris)
1212 /* XXX There doesn't seem to be an easy way to convince the send syscall to
1213 only return EPIPE instead of raising SIGPIPE. EPIPE is only returned if
1214 SM_KERNEL is set on the socket. Without serious hackery it looks we
1215 can't set this flag.
1217 Should we wrap the send syscall below into sigprocmask calls to block
1221 res
= VG_(do_syscall5
)(__NR_so_socket
, domain
, type
, protocol
,
1222 0 /*devpath*/, VKI_SOV_DEFAULT
/*version*/);
1223 return sr_isError(res
) ? -1 : sr_Res(res
);
1226 # error "Unknown arch"
1232 Int
my_connect ( Int sockfd
, struct vki_sockaddr_in
* serv_addr
, Int addrlen
)
1234 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1235 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1236 || defined(VGP_s390x_linux)
1240 args
[1] = (UWord
)serv_addr
;
1242 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_CONNECT
, (UWord
)&args
);
1243 return sr_isError(res
) ? -1 : sr_Res(res
);
1245 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1246 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
1247 || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
1249 res
= VG_(do_syscall3
)(__NR_connect
, sockfd
, (UWord
)serv_addr
, addrlen
);
1250 return sr_isError(res
) ? -1 : sr_Res(res
);
1252 # elif defined(VGO_darwin)
1254 res
= VG_(do_syscall3
)(__NR_connect_nocancel
,
1255 sockfd
, (UWord
)serv_addr
, addrlen
);
1256 return sr_isError(res
) ? -1 : sr_Res(res
);
1258 # elif defined(VGO_solaris)
1260 res
= VG_(do_syscall4
)(__NR_connect
, sockfd
, (UWord
)serv_addr
, addrlen
,
1261 VKI_SOV_DEFAULT
/*version*/);
1262 return sr_isError(res
) ? -1 : sr_Res(res
);
1265 # error "Unknown arch"
1269 Int
VG_(write_socket
)( Int sd
, const void *msg
, Int count
)
1271 /* This is actually send(). */
1273 /* For Linux, VKI_MSG_NOSIGNAL is a request not to send SIGPIPE on
1274 errors on stream oriented sockets when the other end breaks the
1275 connection. The EPIPE error is still returned.
1277 For Darwin, VG_(socket)() sets SO_NOSIGPIPE to get EPIPE instead of
1280 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1281 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1282 || defined(VGP_s390x_linux)
1286 args
[1] = (UWord
)msg
;
1288 args
[3] = VKI_MSG_NOSIGNAL
;
1289 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_SEND
, (UWord
)&args
);
1290 return sr_isError(res
) ? -1 : sr_Res(res
);
1292 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1293 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
1294 || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
1296 res
= VG_(do_syscall6
)(__NR_sendto
, sd
, (UWord
)msg
,
1297 count
, VKI_MSG_NOSIGNAL
, 0,0);
1298 return sr_isError(res
) ? -1 : sr_Res(res
);
1300 # elif defined(VGP_x86_darwin) || defined(VGP_amd64_darwin)
1302 res
= VG_(do_syscall3
)(__NR_write_nocancel
, sd
, (UWord
)msg
, count
);
1303 return sr_isError(res
) ? -1 : sr_Res(res
);
1305 # elif defined(VGO_solaris)
1307 res
= VG_(do_syscall4
)(__NR_send
, sd
, (UWord
)msg
, count
, 0 /*flags*/);
1308 return sr_isError(res
) ? -1 : sr_Res(res
);
1311 # error "Unknown platform"
1315 Int
VG_(getsockname
) ( Int sd
, struct vki_sockaddr
*name
, Int
*namelen
)
1317 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1318 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1319 || defined(VGP_s390x_linux) \
1320 || defined(VGP_mips32_linux)
1324 args
[1] = (UWord
)name
;
1325 args
[2] = (UWord
)namelen
;
1326 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_GETSOCKNAME
, (UWord
)&args
);
1327 return sr_isError(res
) ? -1 : sr_Res(res
);
1329 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1330 || defined(VGP_mips64_linux) || defined(VGP_arm64_linux) \
1331 || defined(VGP_nanomips_linux)
1333 res
= VG_(do_syscall3
)( __NR_getsockname
,
1334 (UWord
)sd
, (UWord
)name
, (UWord
)namelen
);
1335 return sr_isError(res
) ? -1 : sr_Res(res
);
1337 # elif defined(VGO_darwin)
1339 res
= VG_(do_syscall3
)( __NR_getsockname
,
1340 (UWord
)sd
, (UWord
)name
, (UWord
)namelen
);
1341 return sr_isError(res
) ? -1 : sr_Res(res
);
1343 # elif defined(VGO_solaris)
1345 res
= VG_(do_syscall4
)(__NR_getsockname
, sd
, (UWord
)name
, (UWord
)namelen
,
1346 VKI_SOV_DEFAULT
/*version*/);
1347 return sr_isError(res
) ? -1 : sr_Res(res
);
1350 # error "Unknown platform"
1354 Int
VG_(getpeername
) ( Int sd
, struct vki_sockaddr
*name
, Int
*namelen
)
1356 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1357 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1358 || defined(VGP_s390x_linux) \
1359 || defined(VGP_mips32_linux)
1363 args
[1] = (UWord
)name
;
1364 args
[2] = (UWord
)namelen
;
1365 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_GETPEERNAME
, (UWord
)&args
);
1366 return sr_isError(res
) ? -1 : sr_Res(res
);
1368 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1369 || defined(VGP_mips64_linux) || defined(VGP_arm64_linux) \
1370 || defined(VGP_nanomips_linux)
1372 res
= VG_(do_syscall3
)( __NR_getpeername
,
1373 (UWord
)sd
, (UWord
)name
, (UWord
)namelen
);
1374 return sr_isError(res
) ? -1 : sr_Res(res
);
1376 # elif defined(VGO_darwin)
1378 res
= VG_(do_syscall3
)( __NR_getpeername
,
1379 (UWord
)sd
, (UWord
)name
, (UWord
)namelen
);
1380 return sr_isError(res
) ? -1 : sr_Res(res
);
1382 # elif defined(VGO_solaris)
1384 res
= VG_(do_syscall4
)(__NR_getpeername
, sd
, (UWord
)name
, (UWord
)namelen
,
1385 VKI_SOV_DEFAULT
/*version*/);
1386 return sr_isError(res
) ? -1 : sr_Res(res
);
1389 # error "Unknown platform"
1393 Int
VG_(getsockopt
) ( Int sd
, Int level
, Int optname
, void *optval
,
1396 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1397 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1398 || defined(VGP_s390x_linux)
1404 args
[3] = (UWord
)optval
;
1405 args
[4] = (UWord
)optlen
;
1406 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_GETSOCKOPT
, (UWord
)&args
);
1407 return sr_isError(res
) ? -1 : sr_Res(res
);
1409 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1410 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
1411 || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
1413 res
= VG_(do_syscall5
)( __NR_getsockopt
,
1414 (UWord
)sd
, (UWord
)level
, (UWord
)optname
,
1415 (UWord
)optval
, (UWord
)optlen
);
1416 return sr_isError(res
) ? -1 : sr_Res(res
);
1418 # elif defined(VGO_darwin)
1420 res
= VG_(do_syscall5
)( __NR_getsockopt
,
1421 (UWord
)sd
, (UWord
)level
, (UWord
)optname
,
1422 (UWord
)optval
, (UWord
)optlen
);
1423 return sr_isError(res
) ? -1 : sr_Res(res
);
1425 # elif defined(VGO_solaris)
1427 res
= VG_(do_syscall6
)(__NR_getsockopt
, sd
, level
, optname
, (UWord
)optval
,
1428 (UWord
)optlen
, VKI_SOV_DEFAULT
/*version*/);
1429 return sr_isError(res
) ? -1 : sr_Res(res
);
1432 # error "Unknown platform"
1437 Int
VG_(setsockopt
) ( Int sd
, Int level
, Int optname
, void *optval
,
1440 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1441 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1442 || defined(VGP_s390x_linux)
1448 args
[3] = (UWord
)optval
;
1449 args
[4] = (UWord
)optlen
;
1450 res
= VG_(do_syscall2
)(__NR_socketcall
, VKI_SYS_SETSOCKOPT
, (UWord
)&args
);
1451 return sr_isError(res
) ? -1 : sr_Res(res
);
1453 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1454 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
1455 || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
1457 res
= VG_(do_syscall5
)( __NR_setsockopt
,
1458 (UWord
)sd
, (UWord
)level
, (UWord
)optname
,
1459 (UWord
)optval
, (UWord
)optlen
);
1460 return sr_isError(res
) ? -1 : sr_Res(res
);
1462 # elif defined(VGO_darwin)
1464 res
= VG_(do_syscall5
)( __NR_setsockopt
,
1465 (UWord
)sd
, (UWord
)level
, (UWord
)optname
,
1466 (UWord
)optval
, (UWord
)optlen
);
1467 return sr_isError(res
) ? -1 : sr_Res(res
);
1469 # elif defined(VGO_solaris)
1471 res
= VG_(do_syscall6
)( __NR_setsockopt
,
1472 (UWord
)sd
, (UWord
)level
, (UWord
)optname
,
1473 (UWord
)optval
, (UWord
)optlen
,
1474 VKI_SOV_DEFAULT
/*version*/ );
1475 return sr_isError(res
) ? -1 : sr_Res(res
);
1478 # error "Unknown platform"
1483 const HChar
*VG_(basename
)(const HChar
*path
)
1485 static HChar
*buf
= NULL
;
1486 static SizeT buf_len
= 0;
1487 const HChar
*p
, *end
;
1490 0 == VG_(strcmp
)(path
, ""))
1495 p
= path
+ VG_(strlen
)(path
);
1496 while (p
> path
&& *p
== '/') {
1497 // skip all trailing '/'
1501 if (p
== path
&& *p
== '/') return "/"; // all slashes
1505 while (p
> path
&& *p
!= '/') {
1512 SizeT need
= end
-p
+1 + 1;
1513 if (need
> buf_len
) {
1514 buf_len
= (buf_len
== 0) ? 500 : need
;
1515 buf
= VG_(realloc
)("basename", buf
, buf_len
);
1517 VG_(strncpy
)(buf
, p
, end
-p
+1);
1518 buf
[end
-p
+1] = '\0';
1524 const HChar
*VG_(dirname
)(const HChar
*path
)
1526 static HChar
*buf
= NULL
;
1527 static SizeT buf_len
= 0;
1532 0 == VG_(strcmp
)(path
, "") ||
1533 0 == VG_(strcmp
)(path
, "/"))
1538 p
= path
+ VG_(strlen
)(path
);
1539 while (p
> path
&& *p
== '/') {
1540 // skip all trailing '/'
1544 while (p
> path
&& *p
!= '/') {
1550 if (*p
== '/') return "/"; // all slashes
1551 else return "."; // no slashes
1554 while (p
> path
&& *p
== '/') {
1559 SizeT need
= p
-path
+1 + 1;
1560 if (need
> buf_len
) {
1561 buf_len
= (buf_len
== 0) ? 500 : need
;
1562 buf
= VG_(realloc
)("dirname", buf
, buf_len
);
1564 VG_(strncpy
)(buf
, path
, p
-path
+1);
1565 buf
[p
-path
+1] = '\0';
1571 /*--------------------------------------------------------------------*/
1573 /*--------------------------------------------------------------------*/