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