1 2 /*--------------------------------------------------------------------*/ 3 /*--- File- and socket-related libc stuff. m_libcfile.c ---*/ 4 /*--------------------------------------------------------------------*/ 5 6 /* 7 This file is part of Valgrind, a dynamic binary instrumentation 8 framework. 9 10 Copyright (C) 2000-2012 Julian Seward 11 jseward (at) acm.org 12 13 This program is free software; you can redistribute it and/or 14 modify it under the terms of the GNU General Public License as 15 published by the Free Software Foundation; either version 2 of the 16 License, or (at your option) any later version. 17 18 This program is distributed in the hope that it will be useful, but 19 WITHOUT ANY WARRANTY; without even the implied warranty of 20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 General Public License for more details. 22 23 You should have received a copy of the GNU General Public License 24 along with this program; if not, write to the Free Software 25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 26 02111-1307, USA. 27 28 The GNU General Public License is contained in the file COPYING. 29 */ 30 31 #include "pub_core_basics.h" 32 #include "pub_core_vki.h" 33 #include "pub_core_vkiscnums.h" 34 #include "pub_core_debuglog.h" 35 #include "pub_core_libcbase.h" 36 #include "pub_core_libcassert.h" 37 #include "pub_core_libcfile.h" 38 #include "pub_core_libcprint.h" // VG_(sprintf) 39 #include "pub_core_libcproc.h" // VG_(getpid), VG_(getppid) 40 #include "pub_core_xarray.h" 41 #include "pub_core_clientstate.h" // VG_(fd_hard_limit) 42 #include "pub_core_syscall.h" 43 44 /* IMPORTANT: on Darwin it is essential to use the _nocancel versions 45 of syscalls rather than the vanilla version, if a _nocancel version 46 is available. See docs/internals/Darwin-notes.txt for the reason 47 why. */ 48 49 /* --------------------------------------------------------------------- 50 File stuff 51 ------------------------------------------------------------------ */ 52 53 static inline Bool fd_exists(Int fd) 54 { 55 struct vg_stat st; 56 return VG_(fstat)(fd, &st) == 0; 57 } 58 59 /* Move an fd into the Valgrind-safe range */ 60 Int VG_(safe_fd)(Int oldfd) 61 { 62 Int newfd; 63 64 vg_assert(VG_(fd_hard_limit) != -1); 65 66 newfd = VG_(fcntl)(oldfd, VKI_F_DUPFD, VG_(fd_hard_limit)); 67 if (newfd != -1) 68 VG_(close)(oldfd); 69 70 /* Set the close-on-exec flag for this fd. */ 71 VG_(fcntl)(newfd, VKI_F_SETFD, VKI_FD_CLOEXEC); 72 73 vg_assert(newfd >= VG_(fd_hard_limit)); 74 return newfd; 75 } 76 77 /* Given a file descriptor, attempt to deduce its filename. To do 78 this, we use /proc/self/fd/<FD>. If this doesn't point to a file, 79 or if it doesn't exist, we return False. */ 80 Bool VG_(resolve_filename) ( Int fd, HChar* buf, Int n_buf ) 81 { 82 # if defined(VGO_linux) 83 HChar tmp[64]; 84 VG_(sprintf)(tmp, "/proc/self/fd/%d", fd); 85 VG_(memset)(buf, 0, n_buf); 86 if (VG_(readlink)(tmp, buf, n_buf) > 0 && buf[0] == '/') 87 return True; 88 else 89 return False; 90 91 # elif defined(VGO_darwin) 92 HChar tmp[VKI_MAXPATHLEN+1]; 93 if (0 == VG_(fcntl)(fd, VKI_F_GETPATH, (UWord)tmp)) { 94 if (n_buf > 0) { 95 VG_(strncpy)( buf, tmp, n_buf < sizeof(tmp) ? n_buf : sizeof(tmp) ); 96 buf[n_buf-1] = 0; 97 } 98 if (tmp[0] == '/') return True; 99 } 100 return False; 101 102 # else 103 # error Unknown OS 104 # endif 105 } 106 107 SysRes VG_(mknod) ( const Char* pathname, Int mode, UWord dev ) 108 { 109 # if defined(VGO_linux) || defined(VGO_darwin) 110 SysRes res = VG_(do_syscall3)(__NR_mknod, 111 (UWord)pathname, mode, dev); 112 # else 113 # error Unknown OS 114 # endif 115 return res; 116 } 117 118 SysRes VG_(open) ( const Char* pathname, Int flags, Int mode ) 119 { 120 # if defined(VGO_linux) 121 SysRes res = VG_(do_syscall3)(__NR_open, 122 (UWord)pathname, flags, mode); 123 # elif defined(VGO_darwin) 124 SysRes res = VG_(do_syscall3)(__NR_open_nocancel, 125 (UWord)pathname, flags, mode); 126 # else 127 # error Unknown OS 128 # endif 129 return res; 130 } 131 132 Int VG_(fd_open) (const Char* pathname, Int flags, Int mode) 133 { 134 SysRes sr; 135 sr = VG_(open) (pathname, flags, mode); 136 if (sr_isError (sr)) 137 return -1; 138 else 139 return sr_Res (sr); 140 } 141 142 void VG_(close) ( Int fd ) 143 { 144 /* Hmm. Return value is not checked. That's uncool. */ 145 # if defined(VGO_linux) 146 (void)VG_(do_syscall1)(__NR_close, fd); 147 # elif defined(VGO_darwin) 148 (void)VG_(do_syscall1)(__NR_close_nocancel, fd); 149 # else 150 # error Unknown OS 151 # endif 152 } 153 154 Int VG_(read) ( Int fd, void* buf, Int count) 155 { 156 Int ret; 157 # if defined(VGO_linux) 158 SysRes res = VG_(do_syscall3)(__NR_read, fd, (UWord)buf, count); 159 # elif defined(VGO_darwin) 160 SysRes res = VG_(do_syscall3)(__NR_read_nocancel, fd, (UWord)buf, count); 161 # else 162 # error Unknown OS 163 # endif 164 if (sr_isError(res)) { 165 ret = - (Int)(Word)sr_Err(res); 166 vg_assert(ret < 0); 167 } else { 168 ret = (Int)(Word)sr_Res(res); 169 vg_assert(ret >= 0); 170 } 171 return ret; 172 } 173 174 Int VG_(write) ( Int fd, const void* buf, Int count) 175 { 176 Int ret; 177 # if defined(VGO_linux) 178 SysRes res = VG_(do_syscall3)(__NR_write, fd, (UWord)buf, count); 179 # elif defined(VGO_darwin) 180 SysRes res = VG_(do_syscall3)(__NR_write_nocancel, fd, (UWord)buf, count); 181 # else 182 # error "Unknown OS" 183 # endif 184 if (sr_isError(res)) { 185 ret = - (Int)(Word)sr_Err(res); 186 vg_assert(ret < 0); 187 } else { 188 ret = (Int)(Word)sr_Res(res); 189 vg_assert(ret >= 0); 190 } 191 return ret; 192 } 193 194 195 Int VG_(pipe) ( Int fd[2] ) 196 { 197 # if defined(VGP_mips32_linux) 198 /* __NR_pipe has a strange return convention on mips32-linux. */ 199 SysRes res = VG_(do_syscall0)(__NR_pipe); 200 if (!sr_isError(res)) { 201 fd[0] = (Int)sr_Res(res); 202 fd[1] = (Int)sr_ResEx(res); 203 return 0; 204 } else { 205 return -1; 206 } 207 # elif defined(VGO_linux) 208 SysRes res = VG_(do_syscall1)(__NR_pipe, (UWord)fd); 209 return sr_isError(res) ? -1 : 0; 210 # elif defined(VGO_darwin) 211 /* __NR_pipe is UX64, so produces a double-word result */ 212 SysRes res = VG_(do_syscall0)(__NR_pipe); 213 if (!sr_isError(res)) { 214 fd[0] = (Int)sr_Res(res); 215 fd[1] = (Int)sr_ResHI(res); 216 } 217 return sr_isError(res) ? -1 : 0; 218 # else 219 # error "Unknown OS" 220 # endif 221 } 222 223 Off64T VG_(lseek) ( Int fd, Off64T offset, Int whence ) 224 { 225 # if defined(VGO_linux) || defined(VGP_amd64_darwin) 226 # if defined(__NR__llseek) 227 Off64T result; 228 SysRes res = VG_(do_syscall5)(__NR__llseek, fd, 229 offset >> 32, offset & 0xffffffff, 230 (UWord)&result, whence); 231 return sr_isError(res) ? (-1) : result; 232 # else 233 SysRes res = VG_(do_syscall3)(__NR_lseek, fd, offset, whence); 234 vg_assert(sizeof(Off64T) == sizeof(Word)); 235 return sr_isError(res) ? (-1) : sr_Res(res); 236 # endif 237 # elif defined(VGP_x86_darwin) 238 SysRes res = VG_(do_syscall4)(__NR_lseek, fd, 239 offset & 0xffffffff, offset >> 32, whence); 240 return sr_isError(res) ? (-1) : sr_Res(res); 241 # else 242 # error "Unknown plat" 243 # endif 244 /* if you change the error-reporting conventions of this, also 245 change all usage points. */ 246 } 247 248 249 /* stat/fstat support. It's uggerly. We have impedance-match into a 250 'struct vg_stat' in order to have a single structure that callers 251 can use consistently on all platforms. */ 252 253 #define TRANSLATE_TO_vg_stat(_p_vgstat, _p_vkistat) \ 254 do { \ 255 (_p_vgstat)->dev = (ULong)( (_p_vkistat)->st_dev ); \ 256 (_p_vgstat)->ino = (ULong)( (_p_vkistat)->st_ino ); \ 257 (_p_vgstat)->nlink = (ULong)( (_p_vkistat)->st_nlink ); \ 258 (_p_vgstat)->mode = (UInt) ( (_p_vkistat)->st_mode ); \ 259 (_p_vgstat)->uid = (UInt) ( (_p_vkistat)->st_uid ); \ 260 (_p_vgstat)->gid = (UInt) ( (_p_vkistat)->st_gid ); \ 261 (_p_vgstat)->rdev = (ULong)( (_p_vkistat)->st_rdev ); \ 262 (_p_vgstat)->size = (Long) ( (_p_vkistat)->st_size ); \ 263 (_p_vgstat)->blksize = (ULong)( (_p_vkistat)->st_blksize ); \ 264 (_p_vgstat)->blocks = (ULong)( (_p_vkistat)->st_blocks ); \ 265 (_p_vgstat)->atime = (ULong)( (_p_vkistat)->st_atime ); \ 266 (_p_vgstat)->atime_nsec = (ULong)( (_p_vkistat)->st_atime_nsec ); \ 267 (_p_vgstat)->mtime = (ULong)( (_p_vkistat)->st_mtime ); \ 268 (_p_vgstat)->mtime_nsec = (ULong)( (_p_vkistat)->st_mtime_nsec ); \ 269 (_p_vgstat)->ctime = (ULong)( (_p_vkistat)->st_ctime ); \ 270 (_p_vgstat)->ctime_nsec = (ULong)( (_p_vkistat)->st_ctime_nsec ); \ 271 } while (0) 272 273 SysRes VG_(stat) ( const Char* file_name, struct vg_stat* vgbuf ) 274 { 275 SysRes res; 276 VG_(memset)(vgbuf, 0, sizeof(*vgbuf)); 277 278 # if defined(VGO_linux) || defined(VGO_darwin) 279 /* First try with stat64. If that doesn't work out, fall back to 280 the vanilla version. */ 281 # if defined(__NR_stat64) 282 { struct vki_stat64 buf64; 283 res = VG_(do_syscall2)(__NR_stat64, (UWord)file_name, (UWord)&buf64); 284 if (!(sr_isError(res) && sr_Err(res) == VKI_ENOSYS)) { 285 /* Success, or any failure except ENOSYS */ 286 if (!sr_isError(res)) 287 TRANSLATE_TO_vg_stat(vgbuf, &buf64); 288 return res; 289 } 290 } 291 # endif /* defined(__NR_stat64) */ 292 { struct vki_stat buf; 293 res = VG_(do_syscall2)(__NR_stat, (UWord)file_name, (UWord)&buf); 294 if (!sr_isError(res)) 295 TRANSLATE_TO_vg_stat(vgbuf, &buf); 296 return res; 297 } 298 299 # else 300 # error Unknown OS 301 # endif 302 } 303 304 Int VG_(fstat) ( Int fd, struct vg_stat* vgbuf ) 305 { 306 SysRes res; 307 VG_(memset)(vgbuf, 0, sizeof(*vgbuf)); 308 309 # if defined(VGO_linux) || defined(VGO_darwin) 310 /* First try with fstat64. If that doesn't work out, fall back to 311 the vanilla version. */ 312 # if defined(__NR_fstat64) 313 { struct vki_stat64 buf64; 314 res = VG_(do_syscall2)(__NR_fstat64, (UWord)fd, (UWord)&buf64); 315 if (!(sr_isError(res) && sr_Err(res) == VKI_ENOSYS)) { 316 /* Success, or any failure except ENOSYS */ 317 if (!sr_isError(res)) 318 TRANSLATE_TO_vg_stat(vgbuf, &buf64); 319 return sr_isError(res) ? (-1) : 0; 320 } 321 } 322 # endif /* if defined(__NR_fstat64) */ 323 { struct vki_stat buf; 324 res = VG_(do_syscall2)(__NR_fstat, (UWord)fd, (UWord)&buf); 325 if (!sr_isError(res)) 326 TRANSLATE_TO_vg_stat(vgbuf, &buf); 327 return sr_isError(res) ? (-1) : 0; 328 } 329 330 # else 331 # error Unknown OS 332 # endif 333 } 334 335 #undef TRANSLATE_TO_vg_stat 336 337 338 Long VG_(fsize) ( Int fd ) 339 { 340 struct vg_stat buf; 341 Int res = VG_(fstat)( fd, &buf ); 342 return (res == -1) ? (-1LL) : buf.size; 343 } 344 345 Bool VG_(is_dir) ( const HChar* f ) 346 { 347 struct vg_stat buf; 348 SysRes res = VG_(stat)(f, &buf); 349 return sr_isError(res) ? False 350 : VKI_S_ISDIR(buf.mode) ? True : False; 351 } 352 353 SysRes VG_(dup) ( Int oldfd ) 354 { 355 return VG_(do_syscall1)(__NR_dup, oldfd); 356 } 357 358 SysRes VG_(dup2) ( Int oldfd, Int newfd ) 359 { 360 # if defined(VGO_linux) || defined(VGO_darwin) 361 return VG_(do_syscall2)(__NR_dup2, oldfd, newfd); 362 # else 363 # error Unknown OS 364 # endif 365 } 366 367 /* Returns -1 on error. */ 368 Int VG_(fcntl) ( Int fd, Int cmd, Addr arg ) 369 { 370 # if defined(VGO_linux) 371 SysRes res = VG_(do_syscall3)(__NR_fcntl, fd, cmd, arg); 372 # elif defined(VGO_darwin) 373 SysRes res = VG_(do_syscall3)(__NR_fcntl_nocancel, fd, cmd, arg); 374 # else 375 # error "Unknown OS" 376 # endif 377 return sr_isError(res) ? -1 : sr_Res(res); 378 } 379 380 Int VG_(rename) ( const Char* old_name, const Char* new_name ) 381 { 382 SysRes res = VG_(do_syscall2)(__NR_rename, (UWord)old_name, (UWord)new_name); 383 return sr_isError(res) ? (-1) : 0; 384 } 385 386 Int VG_(unlink) ( const Char* file_name ) 387 { 388 SysRes res = VG_(do_syscall1)(__NR_unlink, (UWord)file_name); 389 return sr_isError(res) ? (-1) : 0; 390 } 391 392 /* The working directory at startup. AIX doesn't provide an easy 393 system call to do getcwd, but fortunately we don't need arbitrary 394 getcwd support. All that is really needed is to note the cwd at 395 process startup. Hence VG_(record_startup_wd) notes it (in a 396 platform dependent way) and VG_(get_startup_wd) produces the noted 397 value. Hence: */ 398 static HChar startup_wd[VKI_PATH_MAX]; 399 static Bool startup_wd_acquired = False; 400 401 /* Record the process' working directory at startup. Is intended to 402 be called exactly once, at startup, before the working directory 403 changes. Return True for success, False for failure, so that the 404 caller can bomb out suitably without creating module cycles if 405 there is a problem. */ 406 Bool VG_(record_startup_wd) ( void ) 407 { 408 const Int szB = sizeof(startup_wd); 409 vg_assert(!startup_wd_acquired); 410 vg_assert(szB >= 512 && szB <= 16384/*let's say*/); /* stay sane */ 411 VG_(memset)(startup_wd, 0, szB); 412 # if defined(VGO_linux) 413 /* Simple: just ask the kernel */ 414 { SysRes res 415 = VG_(do_syscall2)(__NR_getcwd, (UWord)startup_wd, szB-1); 416 vg_assert(startup_wd[szB-1] == 0); 417 if (sr_isError(res)) { 418 return False; 419 } else { 420 startup_wd_acquired = True; 421 return True; 422 } 423 } 424 # elif defined(VGO_darwin) 425 /* We can't ask the kernel, so instead rely on launcher-*.c to 426 tell us the startup path. Note the env var is keyed to the 427 parent's PID, not ours, since our parent is the launcher 428 process. */ 429 { Char envvar[100]; 430 Char* wd = NULL; 431 VG_(memset)(envvar, 0, sizeof(envvar)); 432 VG_(sprintf)(envvar, "VALGRIND_STARTUP_PWD_%d_XYZZY", 433 (Int)VG_(getppid)()); 434 wd = VG_(getenv)( envvar ); 435 if (wd == NULL || (1+VG_(strlen)(wd) >= szB)) 436 return False; 437 VG_(strncpy_safely)(startup_wd, wd, szB); 438 vg_assert(startup_wd[szB-1] == 0); 439 startup_wd_acquired = True; 440 return True; 441 } 442 # else 443 # error Unknown OS 444 # endif 445 } 446 447 /* Copy the previously acquired startup_wd into buf[0 .. size-1], 448 or return False if buf isn't big enough. */ 449 Bool VG_(get_startup_wd) ( Char* buf, SizeT size ) 450 { 451 vg_assert(startup_wd_acquired); 452 vg_assert(startup_wd[ sizeof(startup_wd)-1 ] == 0); 453 if (1+VG_(strlen)(startup_wd) >= size) 454 return False; 455 VG_(strncpy_safely)(buf, startup_wd, size); 456 return True; 457 } 458 459 Int VG_(poll) (struct vki_pollfd *fds, Int nfds, Int timeout) 460 { 461 SysRes res; 462 # if defined(VGO_linux) 463 res = VG_(do_syscall3)(__NR_poll, (UWord)fds, nfds, timeout); 464 # elif defined(VGO_darwin) 465 res = VG_(do_syscall3)(__NR_poll_nocancel, (UWord)fds, nfds, timeout); 466 # else 467 # error "Unknown OS" 468 # endif 469 return sr_isError(res) ? -1 : sr_Res(res); 470 } 471 472 473 Int VG_(readlink) (const Char* path, Char* buf, UInt bufsiz) 474 { 475 SysRes res; 476 /* res = readlink( path, buf, bufsiz ); */ 477 res = VG_(do_syscall3)(__NR_readlink, (UWord)path, (UWord)buf, bufsiz); 478 return sr_isError(res) ? -1 : sr_Res(res); 479 } 480 481 Int VG_(getdents) (Int fd, struct vki_dirent *dirp, UInt count) 482 { 483 # if defined(VGO_linux) 484 SysRes res; 485 /* res = getdents( fd, dirp, count ); */ 486 res = VG_(do_syscall3)(__NR_getdents, fd, (UWord)dirp, count); 487 return sr_isError(res) ? -1 : sr_Res(res); 488 # elif defined(VGO_darwin) 489 I_die_here; 490 # else 491 # error "Unknown OS" 492 # endif 493 } 494 495 /* Check accessibility of a file. Returns zero for access granted, 496 nonzero otherwise. */ 497 Int VG_(access) ( const HChar* path, Bool irusr, Bool iwusr, Bool ixusr ) 498 { 499 # if defined(VGO_linux) 500 /* Very annoyingly, I cannot find any definition for R_OK et al in 501 the kernel interfaces. Therefore I reluctantly resort to 502 hardwiring in these magic numbers that I determined by 503 experimentation. */ 504 # define VKI_R_OK 4 505 # define VKI_W_OK 2 506 # define VKI_X_OK 1 507 # endif 508 509 UWord w = (irusr ? VKI_R_OK : 0) 510 | (iwusr ? VKI_W_OK : 0) 511 | (ixusr ? VKI_X_OK : 0); 512 SysRes res = VG_(do_syscall2)(__NR_access, (UWord)path, w); 513 return sr_isError(res) ? 1 : 0; 514 515 # if defined(VGO_linux) 516 # undef VKI_R_OK 517 # undef VKI_W_OK 518 # undef VKI_X_OK 519 # endif 520 } 521 522 /* 523 Emulate the normal Unix permissions checking algorithm. 524 525 If owner matches, then use the owner permissions, else 526 if group matches, then use the group permissions, else 527 use other permissions. 528 529 Note that we can't deal properly with SUID/SGID. By default 530 (allow_setuid == False), we refuse to run them (otherwise the 531 executable may misbehave if it doesn't have the permissions it 532 thinks it does). However, the caller may indicate that setuid 533 executables are allowed, for example if we are going to exec them 534 but not trace into them (iow, client sys_execve when 535 clo_trace_children == False). 536 537 If VKI_EACCES is returned (iow, permission was refused), then 538 *is_setuid is set to True iff permission was refused because the 539 executable is setuid. 540 */ 541 /* returns: 0 = success, non-0 is failure */ 542 Int VG_(check_executable)(/*OUT*/Bool* is_setuid, 543 const HChar* f, Bool allow_setuid) 544 { 545 struct vg_stat st; 546 SysRes res = VG_(stat)(f, &st); 547 548 if (is_setuid) 549 *is_setuid = False; 550 551 if (sr_isError(res)) { 552 return sr_Err(res); 553 } 554 555 if ( (st.mode & (VKI_S_ISUID | VKI_S_ISGID)) && !allow_setuid ) { 556 if (is_setuid) 557 *is_setuid = True; 558 return VKI_EACCES; 559 } 560 561 if (VG_(geteuid)() == st.uid) { 562 if (!(st.mode & VKI_S_IXUSR)) 563 return VKI_EACCES; 564 } else { 565 Int grpmatch = 0; 566 567 if (VG_(getegid)() == st.gid) 568 grpmatch = 1; 569 else { 570 UInt groups[32]; 571 Int ngrp = VG_(getgroups)(32, groups); 572 Int i; 573 /* ngrp will be -1 if VG_(getgroups) failed. */ 574 for (i = 0; i < ngrp; i++) { 575 if (groups[i] == st.gid) { 576 grpmatch = 1; 577 break; 578 } 579 } 580 } 581 582 if (grpmatch) { 583 if (!(st.mode & VKI_S_IXGRP)) { 584 return VKI_EACCES; 585 } 586 } else if (!(st.mode & VKI_S_IXOTH)) { 587 return VKI_EACCES; 588 } 589 } 590 591 return 0; 592 } 593 594 SysRes VG_(pread) ( Int fd, void* buf, Int count, OffT offset ) 595 { 596 SysRes res; 597 // on 32 bits platforms, we receive a 32 bits OffT but 598 // we must extend it to pass a long long 64 bits. 599 # if defined(VGP_x86_linux) 600 vg_assert(sizeof(OffT) == 4); 601 res = VG_(do_syscall5)(__NR_pread64, fd, (UWord)buf, count, 602 offset, 0); // Little endian long long 603 return res; 604 # elif defined(VGP_arm_linux) 605 vg_assert(sizeof(OffT) == 4); 606 res = VG_(do_syscall5)(__NR_pread64, fd, (UWord)buf, count, 607 0, offset); // Big endian long long 608 return res; 609 # elif defined(VGP_ppc32_linux) 610 vg_assert(sizeof(OffT) == 4); 611 res = VG_(do_syscall6)(__NR_pread64, fd, (UWord)buf, count, 612 0, // Padding needed on PPC32 613 0, offset); // Big endian long long 614 return res; 615 # elif defined(VGP_mips32_linux) && VKI_LITTLE_ENDIAN 616 vg_assert(sizeof(OffT) == 4); 617 res = VG_(do_syscall6)(__NR_pread64, fd, (UWord)buf, count, 618 0, offset, 0); 619 return res; 620 # elif defined(VGP_mips32_linux) && VKI_BIG_ENDIAN 621 vg_assert(sizeof(OffT) == 4); 622 res = VG_(do_syscall6)(__NR_pread64, fd, (UWord)buf, count, 623 0, 0, offset); 624 return res; 625 # elif defined(VGP_amd64_linux) \ 626 || defined(VGP_ppc64_linux) || defined(VGP_s390x_linux) 627 res = VG_(do_syscall4)(__NR_pread64, fd, (UWord)buf, count, offset); 628 return res; 629 # elif defined(VGP_amd64_darwin) 630 vg_assert(sizeof(OffT) == 8); 631 res = VG_(do_syscall4)(__NR_pread_nocancel, fd, (UWord)buf, count, offset); 632 return res; 633 # elif defined(VGP_x86_darwin) 634 vg_assert(sizeof(OffT) == 8); 635 res = VG_(do_syscall5)(__NR_pread_nocancel, fd, (UWord)buf, count, 636 offset & 0xffffffff, offset >> 32); 637 return res; 638 # else 639 # error "Unknown platform" 640 # endif 641 } 642 643 /* Return the name of a directory for temporary files. */ 644 const HChar *VG_(tmpdir)(void) 645 { 646 const HChar *tmpdir; 647 648 tmpdir = VG_(getenv)("TMPDIR"); 649 if (tmpdir == NULL || *tmpdir == '\0') tmpdir = VG_TMPDIR; 650 if (tmpdir == NULL || *tmpdir == '\0') tmpdir = "/tmp"; /* fallback */ 651 652 return tmpdir; 653 } 654 655 /* Create and open (-rw------) a tmp file name incorporating said arg. 656 Returns -1 on failure, else the fd of the file. If fullname is 657 non-NULL, the file's name is written into it. The number of bytes 658 written is guaranteed not to exceed 64+strlen(part_of_name). */ 659 660 Int VG_(mkstemp) ( HChar* part_of_name, /*OUT*/HChar* fullname ) 661 { 662 HChar buf[200]; 663 Int n, tries, fd; 664 UInt seed; 665 SysRes sres; 666 const HChar *tmpdir; 667 668 vg_assert(part_of_name); 669 n = VG_(strlen)(part_of_name); 670 vg_assert(n > 0 && n < 100); 671 672 seed = (VG_(getpid)() << 9) ^ VG_(getppid)(); 673 674 /* Determine sensible location for temporary files */ 675 tmpdir = VG_(tmpdir)(); 676 677 tries = 0; 678 while (True) { 679 if (tries++ > 10) 680 return -1; 681 VG_(sprintf)( buf, "%s/valgrind_%s_%08x", 682 tmpdir, part_of_name, VG_(random)( &seed )); 683 if (0) 684 VG_(printf)("VG_(mkstemp): trying: %s\n", buf); 685 686 sres = VG_(open)(buf, 687 VKI_O_CREAT|VKI_O_RDWR|VKI_O_EXCL|VKI_O_TRUNC, 688 VKI_S_IRUSR|VKI_S_IWUSR); 689 if (sr_isError(sres)) { 690 VG_(umsg)("VG_(mkstemp): failed to create temp file: %s\n", buf); 691 continue; 692 } 693 /* VG_(safe_fd) doesn't return if it fails. */ 694 fd = VG_(safe_fd)( sr_Res(sres) ); 695 if (fullname) 696 VG_(strcpy)( fullname, buf ); 697 return fd; 698 } 699 /* NOTREACHED */ 700 } 701 702 703 /* --------------------------------------------------------------------- 704 Socket-related stuff. 705 ------------------------------------------------------------------ */ 706 707 static 708 Int parse_inet_addr_and_port ( UChar* str, UInt* ip_addr, UShort* port ); 709 710 static 711 Int my_connect ( Int sockfd, struct vki_sockaddr_in* serv_addr, Int addrlen ); 712 713 UInt VG_(htonl) ( UInt x ) 714 { 715 # if defined(VG_BIGENDIAN) 716 return x; 717 # else 718 return 719 (((x >> 24) & 0xFF) << 0) | (((x >> 16) & 0xFF) << 8) 720 | (((x >> 8) & 0xFF) << 16) | (((x >> 0) & 0xFF) << 24); 721 # endif 722 } 723 724 UInt VG_(ntohl) ( UInt x ) 725 { 726 # if defined(VG_BIGENDIAN) 727 return x; 728 # else 729 return 730 (((x >> 24) & 0xFF) << 0) | (((x >> 16) & 0xFF) << 8) 731 | (((x >> 8) & 0xFF) << 16) | (((x >> 0) & 0xFF) << 24); 732 # endif 733 } 734 735 UShort VG_(htons) ( UShort x ) 736 { 737 # if defined(VG_BIGENDIAN) 738 return x; 739 # else 740 return 741 (((x >> 8) & 0xFF) << 0) | (((x >> 0) & 0xFF) << 8); 742 # endif 743 } 744 745 UShort VG_(ntohs) ( UShort x ) 746 { 747 # if defined(VG_BIGENDIAN) 748 return x; 749 # else 750 return 751 (((x >> 8) & 0xFF) << 0) | (((x >> 0) & 0xFF) << 8); 752 # endif 753 } 754 755 756 /* The main function. 757 758 Supplied string contains either an ip address "192.168.0.1" or 759 an ip address and port pair, "192.168.0.1:1500". Parse these, 760 and return: 761 -1 if there is a parse error 762 -2 if no parse error, but specified host:port cannot be opened 763 the relevant file (socket) descriptor, otherwise. 764 is used. 765 */ 766 Int VG_(connect_via_socket)( UChar* str ) 767 { 768 # if defined(VGO_linux) || defined(VGO_darwin) 769 Int sd, res; 770 struct vki_sockaddr_in servAddr; 771 UInt ip = 0; 772 UShort port = VG_CLO_DEFAULT_LOGPORT; 773 Bool ok = parse_inet_addr_and_port(str, &ip, &port); 774 if (!ok) 775 return -1; 776 777 //if (0) 778 // VG_(printf)("ip = %d.%d.%d.%d, port %d\n", 779 // (ip >> 24) & 0xFF, (ip >> 16) & 0xFF, 780 // (ip >> 8) & 0xFF, ip & 0xFF, 781 // (UInt)port ); 782 783 servAddr.sin_family = VKI_AF_INET; 784 servAddr.sin_addr.s_addr = VG_(htonl)(ip); 785 servAddr.sin_port = VG_(htons)(port); 786 787 /* create socket */ 788 sd = VG_(socket)(VKI_AF_INET, VKI_SOCK_STREAM, 0 /* IPPROTO_IP ? */); 789 if (sd < 0) { 790 /* this shouldn't happen ... nevertheless */ 791 return -2; 792 } 793 794 /* connect to server */ 795 res = my_connect(sd, &servAddr, sizeof(servAddr)); 796 if (res < 0) { 797 /* connection failed */ 798 return -2; 799 } 800 801 return sd; 802 803 # else 804 # error "Unknown OS" 805 # endif 806 } 807 808 809 /* Let d = one or more digits. Accept either: 810 d.d.d.d or d.d.d.d:d 811 */ 812 static Int parse_inet_addr_and_port ( UChar* str, UInt* ip_addr, UShort* port ) 813 { 814 # define GET_CH ((*str) ? (*str++) : 0) 815 UInt ipa, i, j, c, any; 816 ipa = 0; 817 for (i = 0; i < 4; i++) { 818 j = 0; 819 any = 0; 820 while (1) { 821 c = GET_CH; 822 if (c < '0' || c > '9') break; 823 j = 10 * j + (int)(c - '0'); 824 any = 1; 825 } 826 if (any == 0 || j > 255) goto syntaxerr; 827 ipa = (ipa << 8) + j; 828 if (i <= 2 && c != '.') goto syntaxerr; 829 } 830 if (c == 0 || c == ':') 831 *ip_addr = ipa; 832 if (c == 0) goto ok; 833 if (c != ':') goto syntaxerr; 834 j = 0; 835 any = 0; 836 while (1) { 837 c = GET_CH; 838 if (c < '0' || c > '9') break; 839 j = j * 10 + (int)(c - '0'); 840 any = 1; 841 if (j > 65535) goto syntaxerr; 842 } 843 if (any == 0 || c != 0) goto syntaxerr; 844 if (j < 1024) goto syntaxerr; 845 *port = (UShort)j; 846 ok: 847 return 1; 848 syntaxerr: 849 return 0; 850 # undef GET_CH 851 } 852 853 // GrP fixme safe_fd? 854 Int VG_(socket) ( Int domain, Int type, Int protocol ) 855 { 856 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \ 857 || defined(VGP_ppc64_linux) || defined(VGP_s390x_linux) 858 SysRes res; 859 UWord args[3]; 860 args[0] = domain; 861 args[1] = type; 862 args[2] = protocol; 863 res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_SOCKET, (UWord)&args); 864 return sr_isError(res) ? -1 : sr_Res(res); 865 866 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \ 867 || defined(VGP_mips32_linux) 868 SysRes res; 869 res = VG_(do_syscall3)(__NR_socket, domain, type, protocol ); 870 return sr_isError(res) ? -1 : sr_Res(res); 871 872 # elif defined(VGO_darwin) 873 SysRes res; 874 res = VG_(do_syscall3)(__NR_socket, domain, type, protocol); 875 if (!sr_isError(res)) { 876 // Set SO_NOSIGPIPE so write() returns EPIPE instead of raising SIGPIPE 877 Int optval = 1; 878 SysRes res2; 879 res2 = VG_(do_syscall5)(__NR_setsockopt, sr_Res(res), VKI_SOL_SOCKET, 880 VKI_SO_NOSIGPIPE, (UWord)&optval, 881 sizeof(optval)); 882 // ignore setsockopt() error 883 } 884 return sr_isError(res) ? -1 : sr_Res(res); 885 886 # else 887 # error "Unknown arch" 888 # endif 889 } 890 891 892 static 893 Int my_connect ( Int sockfd, struct vki_sockaddr_in* serv_addr, Int addrlen ) 894 { 895 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \ 896 || defined(VGP_ppc64_linux) || defined(VGP_s390x_linux) 897 SysRes res; 898 UWord args[3]; 899 args[0] = sockfd; 900 args[1] = (UWord)serv_addr; 901 args[2] = addrlen; 902 res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_CONNECT, (UWord)&args); 903 return sr_isError(res) ? -1 : sr_Res(res); 904 905 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \ 906 || defined(VGP_mips32_linux) 907 SysRes res; 908 res = VG_(do_syscall3)(__NR_connect, sockfd, (UWord)serv_addr, addrlen); 909 return sr_isError(res) ? -1 : sr_Res(res); 910 911 # elif defined(VGO_darwin) 912 SysRes res; 913 res = VG_(do_syscall3)(__NR_connect_nocancel, 914 sockfd, (UWord)serv_addr, addrlen); 915 return sr_isError(res) ? -1 : sr_Res(res); 916 917 # else 918 # error "Unknown arch" 919 # endif 920 } 921 922 Int VG_(write_socket)( Int sd, void *msg, Int count ) 923 { 924 /* This is actually send(). */ 925 926 /* For Linux, VKI_MSG_NOSIGNAL is a request not to send SIGPIPE on 927 errors on stream oriented sockets when the other end breaks the 928 connection. The EPIPE error is still returned. 929 930 For Darwin, VG_(socket)() sets SO_NOSIGPIPE to get EPIPE instead of 931 SIGPIPE */ 932 933 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \ 934 || defined(VGP_ppc64_linux) || defined(VGP_s390x_linux) 935 SysRes res; 936 UWord args[4]; 937 args[0] = sd; 938 args[1] = (UWord)msg; 939 args[2] = count; 940 args[3] = VKI_MSG_NOSIGNAL; 941 res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_SEND, (UWord)&args); 942 return sr_isError(res) ? -1 : sr_Res(res); 943 944 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \ 945 || defined(VGP_mips32_linux) 946 SysRes res; 947 res = VG_(do_syscall6)(__NR_sendto, sd, (UWord)msg, 948 count, VKI_MSG_NOSIGNAL, 0,0); 949 return sr_isError(res) ? -1 : sr_Res(res); 950 951 # elif defined(VGP_x86_darwin) || defined(VGP_amd64_darwin) 952 SysRes res; 953 res = VG_(do_syscall3)(__NR_write_nocancel, sd, (UWord)msg, count); 954 return sr_isError(res) ? -1 : sr_Res(res); 955 956 # else 957 # error "Unknown platform" 958 # endif 959 } 960 961 Int VG_(getsockname) ( Int sd, struct vki_sockaddr *name, Int *namelen) 962 { 963 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \ 964 || defined(VGP_ppc64_linux) || defined(VGP_s390x_linux) \ 965 || defined(VGP_mips32_linux) 966 SysRes res; 967 UWord args[3]; 968 args[0] = sd; 969 args[1] = (UWord)name; 970 args[2] = (UWord)namelen; 971 res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETSOCKNAME, (UWord)&args); 972 return sr_isError(res) ? -1 : sr_Res(res); 973 974 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) 975 SysRes res; 976 res = VG_(do_syscall3)( __NR_getsockname, 977 (UWord)sd, (UWord)name, (UWord)namelen ); 978 return sr_isError(res) ? -1 : sr_Res(res); 979 980 # elif defined(VGO_darwin) 981 SysRes res; 982 res = VG_(do_syscall3)( __NR_getsockname, 983 (UWord)sd, (UWord)name, (UWord)namelen ); 984 return sr_isError(res) ? -1 : sr_Res(res); 985 986 # else 987 # error "Unknown platform" 988 # endif 989 } 990 991 Int VG_(getpeername) ( Int sd, struct vki_sockaddr *name, Int *namelen) 992 { 993 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \ 994 || defined(VGP_ppc64_linux) || defined(VGP_s390x_linux) \ 995 || defined(VGP_mips32_linux) 996 SysRes res; 997 UWord args[3]; 998 args[0] = sd; 999 args[1] = (UWord)name; 1000 args[2] = (UWord)namelen; 1001 res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETPEERNAME, (UWord)&args); 1002 return sr_isError(res) ? -1 : sr_Res(res); 1003 1004 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) 1005 SysRes res; 1006 res = VG_(do_syscall3)( __NR_getpeername, 1007 (UWord)sd, (UWord)name, (UWord)namelen ); 1008 return sr_isError(res) ? -1 : sr_Res(res); 1009 1010 # elif defined(VGO_darwin) 1011 SysRes res; 1012 res = VG_(do_syscall3)( __NR_getpeername, 1013 (UWord)sd, (UWord)name, (UWord)namelen ); 1014 return sr_isError(res) ? -1 : sr_Res(res); 1015 1016 # else 1017 # error "Unknown platform" 1018 # endif 1019 } 1020 1021 Int VG_(getsockopt) ( Int sd, Int level, Int optname, void *optval, 1022 Int *optlen) 1023 { 1024 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \ 1025 || defined(VGP_ppc64_linux) || defined(VGP_s390x_linux) 1026 SysRes res; 1027 UWord args[5]; 1028 args[0] = sd; 1029 args[1] = level; 1030 args[2] = optname; 1031 args[3] = (UWord)optval; 1032 args[4] = (UWord)optlen; 1033 res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETSOCKOPT, (UWord)&args); 1034 return sr_isError(res) ? -1 : sr_Res(res); 1035 1036 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \ 1037 || defined(VGP_mips32_linux) 1038 SysRes res; 1039 res = VG_(do_syscall5)( __NR_getsockopt, 1040 (UWord)sd, (UWord)level, (UWord)optname, 1041 (UWord)optval, (UWord)optlen ); 1042 return sr_isError(res) ? -1 : sr_Res(res); 1043 1044 # elif defined(VGO_darwin) 1045 SysRes res; 1046 res = VG_(do_syscall5)( __NR_getsockopt, 1047 (UWord)sd, (UWord)level, (UWord)optname, 1048 (UWord)optval, (UWord)optlen ); 1049 return sr_isError(res) ? -1 : sr_Res(res); 1050 1051 # else 1052 # error "Unknown platform" 1053 # endif 1054 } 1055 1056 1057 Char *VG_(basename)(const Char *path) 1058 { 1059 static Char buf[VKI_PATH_MAX]; 1060 1061 const Char *p, *end; 1062 1063 if (path == NULL || 1064 0 == VG_(strcmp)(path, "")) 1065 { 1066 return "."; 1067 } 1068 1069 p = path + VG_(strlen)(path); 1070 while (p > path && *p == '/') { 1071 // skip all trailing '/' 1072 p--; 1073 } 1074 1075 if (p == path && *p == '/') return "/"; // all slashes 1076 1077 end = p; 1078 1079 while (p > path && *p != '/') { 1080 // now skip non '/' 1081 p--; 1082 } 1083 1084 if (*p == '/') p++; 1085 1086 VG_(strncpy)(buf, p, end-p+1); 1087 buf[end-p+1] = '\0'; 1088 1089 return buf; 1090 } 1091 1092 1093 Char *VG_(dirname)(const Char *path) 1094 { 1095 static Char buf[VKI_PATH_MAX]; 1096 1097 const Char *p; 1098 1099 if (path == NULL || 1100 0 == VG_(strcmp)(path, "") || 1101 0 == VG_(strcmp)(path, "/")) 1102 { 1103 return "."; 1104 } 1105 1106 p = path + VG_(strlen)(path); 1107 while (p > path && *p == '/') { 1108 // skip all trailing '/' 1109 p--; 1110 } 1111 1112 while (p > path && *p != '/') { 1113 // now skip non '/' 1114 p--; 1115 } 1116 1117 if (p == path) { 1118 if (*p == '/') return "/"; // all slashes 1119 else return "."; // no slashes 1120 } 1121 1122 while (p > path && *p == '/') { 1123 // skip '/' again 1124 p--; 1125 } 1126 1127 VG_(strncpy)(buf, path, p-path+1); 1128 buf[p-path+1] = '\0'; 1129 1130 return buf; 1131 } 1132 1133 1134 /*--------------------------------------------------------------------*/ 1135 /*--- end ---*/ 1136 /*--------------------------------------------------------------------*/ 1137