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