Commit for Victor Leikehman <lei@il.ibm.com>
[official-gcc.git] / libmudflap / mf-hooks2.c
blobe031b43f4c90c7c427867e2d787f73407d80a087
1 /* Mudflap: narrow-pointer bounds-checking by tree rewriting.
2 Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
3 Contributed by Frank Ch. Eigler <fche@redhat.com>
4 and Graydon Hoare <graydon@redhat.com>
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
11 version.
13 In addition to the permissions in the GNU General Public License, the
14 Free Software Foundation gives you unlimited permission to link the
15 compiled version of this file into combinations with other programs,
16 and to distribute those combinations without any restriction coming
17 from the use of this file. (The General Public License restrictions
18 do apply in other respects; for example, they cover modification of
19 the file, and distribution when not linked into a combine
20 executable.)
22 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
23 WARRANTY; without even the implied warranty of MERCHANTABILITY or
24 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25 for more details.
27 You should have received a copy of the GNU General Public License
28 along with GCC; see the file COPYING. If not, write to the Free
29 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
30 02111-1307, USA. */
33 #include "config.h"
35 #ifndef HAVE_SOCKLEN_T
36 #define socklen_t int
37 #endif
39 /* These attempt to coax various unix flavours to declare all our
40 needed tidbits in the system headers. */
41 #if !defined(__FreeBSD__) && !defined(__APPLE__)
42 #define _POSIX_SOURCE
43 #endif /* Some BSDs break <sys/socket.h> if this is defined. */
44 #define _GNU_SOURCE
45 #define _XOPEN_SOURCE
46 #define _BSD_TYPES
47 #define __EXTENSIONS__
48 #define _ALL_SOURCE
49 #define _LARGE_FILE_API
50 #define _LARGEFILE64_SOURCE
51 #define _XOPEN_SOURCE_EXTENDED 1
53 #include <string.h>
54 #include <stdarg.h>
55 #include <stdio.h>
56 #include <stdlib.h>
57 #include <sys/stat.h>
58 #include <sys/time.h>
59 #include <sys/types.h>
60 #include <unistd.h>
61 #include <assert.h>
62 #include <errno.h>
63 #include <limits.h>
64 #include <time.h>
65 #include <ctype.h>
66 #ifdef HAVE_DIRENT_H
67 #include <dirent.h>
68 #endif
69 #ifdef HAVE_SYS_SOCKET_H
70 #include <sys/socket.h>
71 #endif
72 #ifdef HAVE_NETDB_H
73 #include <netdb.h>
74 #endif
75 #ifdef HAVE_SYS_WAIT_H
76 #include <sys/wait.h>
77 #endif
78 #ifdef HAVE_SYS_IPC_H
79 #include <sys/ipc.h>
80 #endif
81 #ifdef HAVE_SYS_SEM_H
82 #include <sys/sem.h>
83 #endif
84 #ifdef HAVE_SYS_SHM_H
85 #include <sys/shm.h>
86 #endif
89 #include "mf-runtime.h"
90 #include "mf-impl.h"
92 #ifdef _MUDFLAP
93 #error "Do not compile this file with -fmudflap!"
94 #endif
97 /* A bunch of independent stdlib/unistd hook functions, all
98 intercepted by mf-runtime.h macros. */
100 #ifndef HAVE_STRNLEN
101 static inline size_t (strnlen) (const char* str, size_t n)
103 const char *s;
105 for (s = str; n && *s; ++s, --n)
107 return (s - str);
109 #endif
112 /* str*,mem*,b* */
114 WRAPPER2(void *, memcpy, void *dest, const void *src, size_t n)
116 TRACE ("%s\n", __PRETTY_FUNCTION__);
117 MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "memcpy source");
118 MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "memcpy dest");
119 return memcpy (dest, src, n);
123 WRAPPER2(void *, memmove, void *dest, const void *src, size_t n)
125 TRACE ("%s\n", __PRETTY_FUNCTION__);
126 MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "memmove src");
127 MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "memmove dest");
128 return memmove (dest, src, n);
132 WRAPPER2(void *, memset, void *s, int c, size_t n)
134 TRACE ("%s\n", __PRETTY_FUNCTION__);
135 MF_VALIDATE_EXTENT(s, n, __MF_CHECK_WRITE, "memset dest");
136 return memset (s, c, n);
140 WRAPPER2(int, memcmp, const void *s1, const void *s2, size_t n)
142 TRACE ("%s\n", __PRETTY_FUNCTION__);
143 MF_VALIDATE_EXTENT(s1, n, __MF_CHECK_READ, "memcmp 1st arg");
144 MF_VALIDATE_EXTENT(s2, n, __MF_CHECK_READ, "memcmp 2nd arg");
145 return memcmp (s1, s2, n);
149 WRAPPER2(void *, memchr, const void *s, int c, size_t n)
151 TRACE ("%s\n", __PRETTY_FUNCTION__);
152 MF_VALIDATE_EXTENT(s, n, __MF_CHECK_READ, "memchr region");
153 return memchr (s, c, n);
157 #ifdef HAVE_MEMRCHR
158 WRAPPER2(void *, memrchr, const void *s, int c, size_t n)
160 TRACE ("%s\n", __PRETTY_FUNCTION__);
161 MF_VALIDATE_EXTENT(s, n, __MF_CHECK_READ, "memrchr region");
162 return memrchr (s, c, n);
164 #endif
167 WRAPPER2(char *, strcpy, char *dest, const char *src)
169 /* nb: just because strlen(src) == n doesn't mean (src + n) or (src + n +
170 1) are valid pointers. the allocated object might have size < n.
171 check anyways. */
173 size_t n = strlen (src);
174 TRACE ("%s\n", __PRETTY_FUNCTION__);
175 MF_VALIDATE_EXTENT(src, CLAMPADD(n, 1), __MF_CHECK_READ, "strcpy src");
176 MF_VALIDATE_EXTENT(dest, CLAMPADD(n, 1), __MF_CHECK_WRITE, "strcpy dest");
177 return strcpy (dest, src);
181 #ifdef HAVE_STRNCPY
182 WRAPPER2(char *, strncpy, char *dest, const char *src, size_t n)
184 size_t len = strnlen (src, n);
185 TRACE ("%s\n", __PRETTY_FUNCTION__);
186 MF_VALIDATE_EXTENT(src, len, __MF_CHECK_READ, "strncpy src");
187 MF_VALIDATE_EXTENT(dest, len, __MF_CHECK_WRITE, "strncpy dest"); /* nb: strNcpy */
188 return strncpy (dest, src, n);
190 #endif
193 WRAPPER2(char *, strcat, char *dest, const char *src)
195 size_t dest_sz;
196 size_t src_sz;
197 TRACE ("%s\n", __PRETTY_FUNCTION__);
198 dest_sz = strlen (dest);
199 src_sz = strlen (src);
200 MF_VALIDATE_EXTENT(src, CLAMPADD(src_sz, 1), __MF_CHECK_READ, "strcat src");
201 MF_VALIDATE_EXTENT(dest, CLAMPADD(dest_sz, CLAMPADD(src_sz, 1)),
202 __MF_CHECK_WRITE, "strcat dest");
203 return strcat (dest, src);
207 WRAPPER2(char *, strncat, char *dest, const char *src, size_t n)
210 /* nb: validating the extents (s,n) might be a mistake for two reasons.
212 (1) the string s might be shorter than n chars, and n is just a
213 poor choice by the programmer. this is not a "true" error in the
214 sense that the call to strncat would still be ok.
216 (2) we could try to compensate for case (1) by calling strlen(s) and
217 using that as a bound for the extent to verify, but strlen might fall off
218 the end of a non-terminated string, leading to a false positive.
220 so we will call strnlen(s,n) and use that as a bound.
222 if strnlen returns a length beyond the end of the registered extent
223 associated with s, there is an error: the programmer's estimate for n is
224 too large _AND_ the string s is unterminated, in which case they'd be
225 about to touch memory they don't own while calling strncat.
227 this same logic applies to further uses of strnlen later down in this
228 file. */
230 size_t src_sz;
231 size_t dest_sz;
232 TRACE ("%s\n", __PRETTY_FUNCTION__);
233 src_sz = strnlen (src, n);
234 dest_sz = strnlen (dest, n);
235 MF_VALIDATE_EXTENT(src, src_sz, __MF_CHECK_READ, "strncat src");
236 MF_VALIDATE_EXTENT(dest, (CLAMPADD(dest_sz, CLAMPADD(src_sz, 1))),
237 __MF_CHECK_WRITE, "strncat dest");
238 return strncat (dest, src, n);
242 WRAPPER2(int, strcmp, const char *s1, const char *s2)
244 size_t s1_sz;
245 size_t s2_sz;
246 TRACE ("%s\n", __PRETTY_FUNCTION__);
247 s1_sz = strlen (s1);
248 s2_sz = strlen (s2);
249 MF_VALIDATE_EXTENT(s1, CLAMPADD(s1_sz, 1), __MF_CHECK_READ, "strcmp 1st arg");
250 MF_VALIDATE_EXTENT(s2, CLAMPADD(s2_sz, 1), __MF_CHECK_WRITE, "strcmp 2nd arg");
251 return strcmp (s1, s2);
255 WRAPPER2(int, strcasecmp, const char *s1, const char *s2)
257 size_t s1_sz;
258 size_t s2_sz;
259 TRACE ("%s\n", __PRETTY_FUNCTION__);
260 s1_sz = strlen (s1);
261 s2_sz = strlen (s2);
262 MF_VALIDATE_EXTENT(s1, CLAMPADD(s1_sz, 1), __MF_CHECK_READ, "strcasecmp 1st arg");
263 MF_VALIDATE_EXTENT(s2, CLAMPADD(s2_sz, 1), __MF_CHECK_READ, "strcasecmp 2nd arg");
264 return strcasecmp (s1, s2);
268 WRAPPER2(int, strncmp, const char *s1, const char *s2, size_t n)
270 size_t s1_sz;
271 size_t s2_sz;
272 TRACE ("%s\n", __PRETTY_FUNCTION__);
273 s1_sz = strnlen (s1, n);
274 s2_sz = strnlen (s2, n);
275 MF_VALIDATE_EXTENT(s1, s1_sz, __MF_CHECK_READ, "strncmp 1st arg");
276 MF_VALIDATE_EXTENT(s2, s2_sz, __MF_CHECK_READ, "strncmp 2nd arg");
277 return strncmp (s1, s2, n);
281 WRAPPER2(int, strncasecmp, const char *s1, const char *s2, size_t n)
283 size_t s1_sz;
284 size_t s2_sz;
285 TRACE ("%s\n", __PRETTY_FUNCTION__);
286 s1_sz = strnlen (s1, n);
287 s2_sz = strnlen (s2, n);
288 MF_VALIDATE_EXTENT(s1, s1_sz, __MF_CHECK_READ, "strncasecmp 1st arg");
289 MF_VALIDATE_EXTENT(s2, s2_sz, __MF_CHECK_READ, "strncasecmp 2nd arg");
290 return strncasecmp (s1, s2, n);
294 WRAPPER2(char *, strdup, const char *s)
296 DECLARE(void *, malloc, size_t sz);
297 char *result;
298 size_t n = strlen (s);
299 TRACE ("%s\n", __PRETTY_FUNCTION__);
300 MF_VALIDATE_EXTENT(s, CLAMPADD(n,1), __MF_CHECK_READ, "strdup region");
301 result = (char *)CALL_REAL(malloc,
302 CLAMPADD(CLAMPADD(n,1),
303 CLAMPADD(__mf_opts.crumple_zone,
304 __mf_opts.crumple_zone)));
306 if (UNLIKELY(! result)) return result;
308 result += __mf_opts.crumple_zone;
309 memcpy (result, s, n);
310 result[n] = '\0';
312 __mf_register (result, CLAMPADD(n,1), __MF_TYPE_HEAP_I, "strdup region");
313 return result;
317 WRAPPER2(char *, strndup, const char *s, size_t n)
319 DECLARE(void *, malloc, size_t sz);
320 char *result;
321 size_t sz = strnlen (s, n);
322 TRACE ("%s\n", __PRETTY_FUNCTION__);
323 MF_VALIDATE_EXTENT(s, sz, __MF_CHECK_READ, "strndup region"); /* nb: strNdup */
325 /* note: strndup still adds a \0, even with the N limit! */
326 result = (char *)CALL_REAL(malloc,
327 CLAMPADD(CLAMPADD(n,1),
328 CLAMPADD(__mf_opts.crumple_zone,
329 __mf_opts.crumple_zone)));
331 if (UNLIKELY(! result)) return result;
333 result += __mf_opts.crumple_zone;
334 memcpy (result, s, n);
335 result[n] = '\0';
337 __mf_register (result, CLAMPADD(n,1), __MF_TYPE_HEAP_I, "strndup region");
338 return result;
342 WRAPPER2(char *, strchr, const char *s, int c)
344 size_t n;
345 TRACE ("%s\n", __PRETTY_FUNCTION__);
346 n = strlen (s);
347 MF_VALIDATE_EXTENT(s, CLAMPADD(n,1), __MF_CHECK_READ, "strchr region");
348 return strchr (s, c);
352 WRAPPER2(char *, strrchr, const char *s, int c)
354 size_t n;
355 TRACE ("%s\n", __PRETTY_FUNCTION__);
356 n = strlen (s);
357 MF_VALIDATE_EXTENT(s, CLAMPADD(n,1), __MF_CHECK_READ, "strrchr region");
358 return strrchr (s, c);
362 WRAPPER2(char *, strstr, const char *haystack, const char *needle)
364 size_t haystack_sz;
365 size_t needle_sz;
366 TRACE ("%s\n", __PRETTY_FUNCTION__);
367 haystack_sz = strlen (haystack);
368 needle_sz = strlen (needle);
369 MF_VALIDATE_EXTENT(haystack, CLAMPADD(haystack_sz, 1), __MF_CHECK_READ, "strstr haystack");
370 MF_VALIDATE_EXTENT(needle, CLAMPADD(needle_sz, 1), __MF_CHECK_READ, "strstr needle");
371 return strstr (haystack, needle);
375 #ifdef HAVE_MEMMEM
376 WRAPPER2(void *, memmem,
377 const void *haystack, size_t haystacklen,
378 const void *needle, size_t needlelen)
380 TRACE ("%s\n", __PRETTY_FUNCTION__);
381 MF_VALIDATE_EXTENT(haystack, haystacklen, __MF_CHECK_READ, "memmem haystack");
382 MF_VALIDATE_EXTENT(needle, needlelen, __MF_CHECK_READ, "memmem needle");
383 return memmem (haystack, haystacklen, needle, needlelen);
385 #endif
388 WRAPPER2(size_t, strlen, const char *s)
390 size_t result = strlen (s);
391 TRACE ("%s\n", __PRETTY_FUNCTION__);
392 MF_VALIDATE_EXTENT(s, CLAMPADD(result, 1), __MF_CHECK_READ, "strlen region");
393 return result;
397 WRAPPER2(size_t, strnlen, const char *s, size_t n)
399 size_t result = strnlen (s, n);
400 TRACE ("%s\n", __PRETTY_FUNCTION__);
401 MF_VALIDATE_EXTENT(s, result, __MF_CHECK_READ, "strnlen region");
402 return result;
406 WRAPPER2(void, bzero, void *s, size_t n)
408 TRACE ("%s\n", __PRETTY_FUNCTION__);
409 MF_VALIDATE_EXTENT(s, n, __MF_CHECK_WRITE, "bzero region");
410 bzero (s, n);
414 #undef bcopy
415 WRAPPER2(void, bcopy, const void *src, void *dest, size_t n)
417 TRACE ("%s\n", __PRETTY_FUNCTION__);
418 MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "bcopy src");
419 MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "bcopy dest");
420 bcopy (src, dest, n);
424 #undef bcmp
425 WRAPPER2(int, bcmp, const void *s1, const void *s2, size_t n)
427 TRACE ("%s\n", __PRETTY_FUNCTION__);
428 MF_VALIDATE_EXTENT(s1, n, __MF_CHECK_READ, "bcmp 1st arg");
429 MF_VALIDATE_EXTENT(s2, n, __MF_CHECK_READ, "bcmp 2nd arg");
430 return bcmp (s1, s2, n);
434 WRAPPER2(char *, index, const char *s, int c)
436 size_t n = strlen (s);
437 TRACE ("%s\n", __PRETTY_FUNCTION__);
438 MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "index region");
439 return index (s, c);
443 WRAPPER2(char *, rindex, const char *s, int c)
445 size_t n = strlen (s);
446 TRACE ("%s\n", __PRETTY_FUNCTION__);
447 MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "rindex region");
448 return rindex (s, c);
451 /* XXX: stpcpy, memccpy */
453 /* XXX: *printf,*scanf */
455 /* XXX: setjmp, longjmp */
457 WRAPPER2(char *, asctime, struct tm *tm)
459 static char *reg_result = NULL;
460 char *result;
461 TRACE ("%s\n", __PRETTY_FUNCTION__);
462 MF_VALIDATE_EXTENT(tm, sizeof (struct tm), __MF_CHECK_READ, "asctime tm");
463 result = asctime (tm);
464 if (reg_result == NULL)
466 __mf_register (result, strlen (result)+1, __MF_TYPE_STATIC, "asctime string");
467 reg_result = result;
469 return result;
473 WRAPPER2(char *, ctime, const time_t *timep)
475 static char *reg_result = NULL;
476 char *result;
477 TRACE ("%s\n", __PRETTY_FUNCTION__);
478 MF_VALIDATE_EXTENT(timep, sizeof (time_t), __MF_CHECK_READ, "ctime time");
479 result = ctime (timep);
480 if (reg_result == NULL)
482 /* XXX: what if asctime and ctime return the same static ptr? */
483 __mf_register (result, strlen (result)+1, __MF_TYPE_STATIC, "ctime string");
484 reg_result = result;
486 return result;
490 WRAPPER2(struct tm*, localtime, const time_t *timep)
492 static struct tm *reg_result = NULL;
493 struct tm *result;
494 TRACE ("%s\n", __PRETTY_FUNCTION__);
495 MF_VALIDATE_EXTENT(timep, sizeof (time_t), __MF_CHECK_READ, "localtime time");
496 result = localtime (timep);
497 if (reg_result == NULL)
499 __mf_register (result, sizeof (struct tm), __MF_TYPE_STATIC, "localtime tm");
500 reg_result = result;
502 return result;
506 WRAPPER2(struct tm*, gmtime, const time_t *timep)
508 static struct tm *reg_result = NULL;
509 struct tm *result;
510 TRACE ("%s\n", __PRETTY_FUNCTION__);
511 MF_VALIDATE_EXTENT(timep, sizeof (time_t), __MF_CHECK_READ, "gmtime time");
512 result = gmtime (timep);
513 if (reg_result == NULL)
515 __mf_register (result, sizeof (struct tm), __MF_TYPE_STATIC, "gmtime tm");
516 reg_result = result;
518 return result;
522 /* EL start */
524 /* The following indicate if the result of the corresponding function
525 * should be explicitly un/registered by the wrapper
527 #define MF_REGISTER_strerror __MF_TYPE_STATIC
528 #undef MF_REGISTER_fopen
529 #define MF_RESULT_SIZE_fopen (sizeof (FILE))
530 #undef MF_REGISTER_opendir
531 #define MF_RESULT_SIZE_opendir 0 /* (sizeof (DIR)) */
532 #undef MF_REGISTER_readdir
533 #define MF_REGISTER_gethostbyname __MF_TYPE_STATIC
534 #undef MF_REGISTER_gethostbyname_items
535 #undef MF_REGISTER_dlopen
536 #undef MF_REGISTER_dlerror
537 #undef MF_REGISTER_dlsym
538 #define MF_REGISTER_shmat __MF_TYPE_GUESS
541 #include <time.h>
542 WRAPPER2(time_t, time, time_t *timep)
544 TRACE ("%s\n", __PRETTY_FUNCTION__);
545 if (NULL != timep)
546 MF_VALIDATE_EXTENT (timep, sizeof (*timep), __MF_CHECK_WRITE,
547 "time timep");
548 return time (timep);
552 WRAPPER2(char *, strerror, int errnum)
554 char *p;
555 size_t n;
556 TRACE ("%s\n", __PRETTY_FUNCTION__);
557 p = strerror (errnum);
558 if (NULL != p) {
559 n = strlen (p);
560 n = CLAMPADD(n, 1);
561 #ifdef MF_REGISTER_strerror
562 __mf_register (p, n, MF_REGISTER_strerror, "strerror result");
563 #endif
564 MF_VALIDATE_EXTENT (p, n, __MF_CHECK_WRITE, "strerror result");
566 return p;
570 WRAPPER2(FILE *, fopen, const char *path, const char *mode)
572 size_t n;
573 FILE *p;
574 TRACE ("%s\n", __PRETTY_FUNCTION__);
576 n = strlen (path);
577 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "fopen path");
579 n = strlen (mode);
580 MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "fopen mode");
582 p = fopen (path, mode);
583 if (NULL != p) {
584 #ifdef MF_REGISTER_fopen
585 __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "fopen result");
586 #endif
587 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "fopen result");
590 return p;
594 #ifdef HAVE_FOPEN64
595 WRAPPER2(FILE *, fopen64, const char *path, const char *mode)
597 size_t n;
598 FILE *p;
599 TRACE ("%s\n", __PRETTY_FUNCTION__);
601 n = strlen (path);
602 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "fopen64 path");
604 n = strlen (mode);
605 MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "fopen64 mode");
607 p = fopen64 (path, mode);
608 if (NULL != p) {
609 #ifdef MF_REGISTER_fopen
610 __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "fopen64 result");
611 #endif
612 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "fopen64 result");
615 return p;
617 #endif
620 WRAPPER2(int, fclose, FILE *stream)
622 int resp;
623 TRACE ("%s\n", __PRETTY_FUNCTION__);
624 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
625 "fclose stream");
626 resp = fclose (stream);
627 #ifdef MF_REGISTER_fopen
628 __mf_unregister (stream, sizeof (*stream), MF_REGISTER_fopen);
629 #endif
631 return resp;
635 WRAPPER2(size_t, fread, void *ptr, size_t size, size_t nmemb, FILE *stream)
637 TRACE ("%s\n", __PRETTY_FUNCTION__);
638 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
639 "fread stream");
640 MF_VALIDATE_EXTENT (ptr, size * nmemb, __MF_CHECK_WRITE, "fread buffer");
641 return fread (ptr, size, nmemb, stream);
645 WRAPPER2(size_t, fwrite, const void *ptr, size_t size, size_t nmemb,
646 FILE *stream)
648 TRACE ("%s\n", __PRETTY_FUNCTION__);
649 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
650 "fwrite stream");
651 MF_VALIDATE_EXTENT (ptr, size * nmemb, __MF_CHECK_READ, "fwrite buffer");
652 return fwrite (ptr, size, nmemb, stream);
656 WRAPPER2(int, fgetc, FILE *stream)
658 TRACE ("%s\n", __PRETTY_FUNCTION__);
659 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
660 "fgetc stream");
661 return fgetc (stream);
665 WRAPPER2(char *, fgets, char *s, int size, FILE *stream)
667 TRACE ("%s\n", __PRETTY_FUNCTION__);
668 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
669 "fgets stream");
670 MF_VALIDATE_EXTENT (s, size, __MF_CHECK_WRITE, "fgets buffer");
671 return fgets (s, size, stream);
675 WRAPPER2(int, getc, FILE *stream)
677 TRACE ("%s\n", __PRETTY_FUNCTION__);
678 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
679 "getc stream");
680 return getc (stream);
684 WRAPPER2(char *, gets, char *s)
686 TRACE ("%s\n", __PRETTY_FUNCTION__);
687 MF_VALIDATE_EXTENT (s, 1, __MF_CHECK_WRITE, "gets buffer");
688 /* Avoid link-time warning... */
689 s = fgets (s, INT_MAX, stdin);
690 if (NULL != s) { /* better late than never */
691 size_t n = strlen (s);
692 MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_WRITE, "gets buffer");
694 return s;
698 WRAPPER2(int, ungetc, int c, FILE *stream)
700 TRACE ("%s\n", __PRETTY_FUNCTION__);
701 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
702 "ungetc stream");
703 return ungetc (c, stream);
707 WRAPPER2(int, fputc, int c, FILE *stream)
709 TRACE ("%s\n", __PRETTY_FUNCTION__);
710 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
711 "fputc stream");
712 return fputc (c, stream);
716 WRAPPER2(int, fputs, const char *s, FILE *stream)
718 size_t n;
719 TRACE ("%s\n", __PRETTY_FUNCTION__);
720 n = strlen (s);
721 MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "fputs buffer");
722 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
723 "fputs stream");
724 return fputs (s, stream);
728 WRAPPER2(int, putc, int c, FILE *stream)
730 TRACE ("%s\n", __PRETTY_FUNCTION__);
731 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
732 "putc stream");
733 return putc (c, stream);
737 WRAPPER2(int, puts, const char *s)
739 size_t n;
740 TRACE ("%s\n", __PRETTY_FUNCTION__);
741 n = strlen (s);
742 MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "puts buffer");
743 return puts (s);
747 WRAPPER2(void, clearerr, FILE *stream)
749 TRACE ("%s\n", __PRETTY_FUNCTION__);
750 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
751 "clearerr stream");
752 clearerr (stream);
756 WRAPPER2(int, feof, FILE *stream)
758 TRACE ("%s\n", __PRETTY_FUNCTION__);
759 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
760 "feof stream");
761 return feof (stream);
765 WRAPPER2(int, ferror, FILE *stream)
767 TRACE ("%s\n", __PRETTY_FUNCTION__);
768 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
769 "ferror stream");
770 return ferror (stream);
774 WRAPPER2(int, fileno, FILE *stream)
776 TRACE ("%s\n", __PRETTY_FUNCTION__);
777 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
778 "fileno stream");
779 return fileno (stream);
783 WRAPPER2(int, printf, const char *format, ...)
785 size_t n;
786 va_list ap;
787 int result;
788 TRACE ("%s\n", __PRETTY_FUNCTION__);
789 n = strlen (format);
790 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
791 "printf format");
792 va_start (ap, format);
793 result = vprintf (format, ap);
794 va_end (ap);
795 return result;
799 WRAPPER2(int, fprintf, FILE *stream, const char *format, ...)
801 size_t n;
802 va_list ap;
803 int result;
804 TRACE ("%s\n", __PRETTY_FUNCTION__);
805 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
806 "fprintf stream");
807 n = strlen (format);
808 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
809 "fprintf format");
810 va_start (ap, format);
811 result = vfprintf (stream, format, ap);
812 va_end (ap);
813 return result;
817 WRAPPER2(int, sprintf, char *str, const char *format, ...)
819 size_t n;
820 va_list ap;
821 int result;
822 TRACE ("%s\n", __PRETTY_FUNCTION__);
823 MF_VALIDATE_EXTENT (str, 1, __MF_CHECK_WRITE, "sprintf str");
824 n = strlen (format);
825 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
826 "sprintf format");
827 va_start (ap, format);
828 result = vsprintf (str, format, ap);
829 va_end (ap);
830 n = strlen (str);
831 MF_VALIDATE_EXTENT (str, CLAMPADD(n, 1), __MF_CHECK_WRITE, "sprintf str");
832 return result;
836 WRAPPER2(int, snprintf, char *str, size_t size, const char *format, ...)
838 size_t n;
839 va_list ap;
840 int result;
841 TRACE ("%s\n", __PRETTY_FUNCTION__);
842 MF_VALIDATE_EXTENT (str, size, __MF_CHECK_WRITE, "snprintf str");
843 n = strlen (format);
844 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
845 "snprintf format");
846 va_start (ap, format);
847 result = vsnprintf (str, size, format, ap);
848 va_end (ap);
849 return result;
853 WRAPPER2(int, vprintf, const char *format, va_list ap)
855 size_t n;
856 TRACE ("%s\n", __PRETTY_FUNCTION__);
857 n = strlen (format);
858 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
859 "vprintf format");
860 return vprintf (format, ap);
864 WRAPPER2(int, vfprintf, FILE *stream, const char *format, va_list ap)
866 size_t n;
867 TRACE ("%s\n", __PRETTY_FUNCTION__);
868 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
869 "vfprintf stream");
870 n = strlen (format);
871 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
872 "vfprintf format");
873 return vfprintf (stream, format, ap);
877 WRAPPER2(int, vsprintf, char *str, const char *format, va_list ap)
879 size_t n;
880 int result;
881 TRACE ("%s\n", __PRETTY_FUNCTION__);
882 MF_VALIDATE_EXTENT (str, 1, __MF_CHECK_WRITE, "vsprintf str");
883 n = strlen (format);
884 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
885 "vsprintf format");
886 result = vsprintf (str, format, ap);
887 n = strlen (str);
888 MF_VALIDATE_EXTENT (str, CLAMPADD(n, 1), __MF_CHECK_WRITE, "vsprintf str");
889 return result;
893 WRAPPER2(int, vsnprintf, char *str, size_t size, const char *format,
894 va_list ap)
896 size_t n;
897 TRACE ("%s\n", __PRETTY_FUNCTION__);
898 MF_VALIDATE_EXTENT (str, size, __MF_CHECK_WRITE, "vsnprintf str");
899 n = strlen (format);
900 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
901 "vsnprintf format");
902 return vsnprintf (str, size, format, ap);
906 WRAPPER2(int , access, const char *path, int mode)
908 size_t n;
909 TRACE ("%s\n", __PRETTY_FUNCTION__);
910 n = strlen (path);
911 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "access path");
912 return access (path, mode);
916 WRAPPER2(int , remove, const char *path)
918 size_t n;
919 TRACE ("%s\n", __PRETTY_FUNCTION__);
920 n = strlen (path);
921 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "remove path");
922 return remove (path);
926 WRAPPER2(int, fflush, FILE *stream)
928 TRACE ("%s\n", __PRETTY_FUNCTION__);
929 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
930 "fflush stream");
931 return fflush (stream);
935 WRAPPER2(int, fseek, FILE *stream, long offset, int whence)
937 TRACE ("%s\n", __PRETTY_FUNCTION__);
938 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
939 "fseek stream");
940 return fseek (stream, offset, whence);
944 #ifdef HAVE_FSEEKO64
945 WRAPPER2(int, fseeko64, FILE *stream, off64_t offset, int whence)
947 TRACE ("%s\n", __PRETTY_FUNCTION__);
948 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
949 "fseeko64 stream");
950 return fseeko64 (stream, offset, whence);
952 #endif
955 WRAPPER2(long, ftell, FILE *stream)
957 TRACE ("%s\n", __PRETTY_FUNCTION__);
958 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
959 "ftell stream");
960 return ftell (stream);
964 #ifdef HAVE_FTELLO64
965 WRAPPER2(off64_t, ftello64, FILE *stream)
967 TRACE ("%s\n", __PRETTY_FUNCTION__);
968 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
969 "ftello64 stream");
970 return ftello64 (stream);
972 #endif
975 WRAPPER2(void, rewind, FILE *stream)
977 TRACE ("%s\n", __PRETTY_FUNCTION__);
978 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
979 "rewind stream");
980 rewind (stream);
984 WRAPPER2(int, fgetpos, FILE *stream, fpos_t *pos)
986 TRACE ("%s\n", __PRETTY_FUNCTION__);
987 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
988 "fgetpos stream");
989 MF_VALIDATE_EXTENT (pos, sizeof (*pos), __MF_CHECK_WRITE, "fgetpos pos");
990 return fgetpos (stream, pos);
994 WRAPPER2(int, fsetpos, FILE *stream, fpos_t *pos)
996 TRACE ("%s\n", __PRETTY_FUNCTION__);
997 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
998 "fsetpos stream");
999 MF_VALIDATE_EXTENT (pos, sizeof (*pos), __MF_CHECK_READ, "fsetpos pos");
1000 return fsetpos (stream, pos);
1004 WRAPPER2(int , stat, const char *path, struct stat *buf)
1006 size_t n;
1007 TRACE ("%s\n", __PRETTY_FUNCTION__);
1008 n = strlen (path);
1009 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "stat path");
1010 MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ, "stat buf");
1011 return stat (path, buf);
1015 #ifdef HAVE_STAT64
1016 WRAPPER2(int , stat64, const char *path, struct stat64 *buf)
1018 size_t n;
1019 TRACE ("%s\n", __PRETTY_FUNCTION__);
1020 n = strlen (path);
1021 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "stat64 path");
1022 MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ, "stat64 buf");
1023 return stat64 (path, buf);
1025 #endif
1028 WRAPPER2(int , fstat, int filedes, struct stat *buf)
1030 TRACE ("%s\n", __PRETTY_FUNCTION__);
1031 MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ, "fstat buf");
1032 return fstat (filedes, buf);
1036 WRAPPER2(int , lstat, const char *path, struct stat *buf)
1038 size_t n;
1039 TRACE ("%s\n", __PRETTY_FUNCTION__);
1040 n = strlen (path);
1041 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "lstat path");
1042 MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ, "lstat buf");
1043 return lstat (path, buf);
1047 WRAPPER2(int , mkfifo, const char *path, mode_t mode)
1049 size_t n;
1050 TRACE ("%s\n", __PRETTY_FUNCTION__);
1051 n = strlen (path);
1052 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "mkfifo path");
1053 return mkfifo (path, mode);
1057 WRAPPER2(int, setvbuf, FILE *stream, char *buf, int mode , size_t size)
1059 TRACE ("%s\n", __PRETTY_FUNCTION__);
1060 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1061 "setvbuf stream");
1062 if (NULL != buf)
1063 MF_VALIDATE_EXTENT (buf, size, __MF_CHECK_READ, "setvbuf buf");
1064 return setvbuf (stream, buf, mode, size);
1068 WRAPPER2(void, setbuf, FILE *stream, char *buf)
1070 TRACE ("%s\n", __PRETTY_FUNCTION__);
1071 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1072 "setbuf stream");
1073 if (NULL != buf)
1074 MF_VALIDATE_EXTENT (buf, BUFSIZ, __MF_CHECK_READ, "setbuf buf");
1075 setbuf (stream, buf);
1079 #ifdef HAVE_DIRENT_H
1080 WRAPPER2(DIR *, opendir, const char *path)
1082 DIR *p;
1083 size_t n;
1084 TRACE ("%s\n", __PRETTY_FUNCTION__);
1085 n = strlen (path);
1086 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "opendir path");
1088 p = opendir (path);
1089 if (NULL != p) {
1090 #ifdef MF_REGISTER_opendir
1091 __mf_register (p, MF_RESULT_SIZE_opendir, MF_REGISTER_opendir,
1092 "opendir result");
1093 #endif
1094 MF_VALIDATE_EXTENT (p, MF_RESULT_SIZE_opendir, __MF_CHECK_WRITE,
1095 "opendir result");
1097 return p;
1101 WRAPPER2(int, closedir, DIR *dir)
1103 TRACE ("%s\n", __PRETTY_FUNCTION__);
1104 MF_VALIDATE_EXTENT (dir, 0, __MF_CHECK_WRITE, "closedir dir");
1105 #ifdef MF_REGISTER_opendir
1106 __mf_unregister (dir, MF_RESULT_SIZE_opendir, MF_REGISTER_opendir);
1107 #endif
1108 return closedir (dir);
1112 WRAPPER2(struct dirent *, readdir, DIR *dir)
1114 struct dirent *p;
1115 TRACE ("%s\n", __PRETTY_FUNCTION__);
1116 MF_VALIDATE_EXTENT (dir, 0, __MF_CHECK_READ, "readdir dir");
1117 p = readdir (dir);
1118 if (NULL != p) {
1119 #ifdef MF_REGISTER_readdir
1120 __mf_register (p, sizeof (*p), MF_REGISTER_readdir, "readdir result");
1121 #endif
1122 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "readdir result");
1124 return p;
1126 #endif
1129 #ifdef HAVE_SYS_SOCKET_H
1131 WRAPPER2(int, recv, int s, void *buf, size_t len, int flags)
1133 TRACE ("%s\n", __PRETTY_FUNCTION__);
1134 MF_VALIDATE_EXTENT (buf, len, __MF_CHECK_WRITE, "recv buf");
1135 return recv (s, buf, len, flags);
1139 WRAPPER2(int, recvfrom, int s, void *buf, size_t len, int flags,
1140 struct sockaddr *from, socklen_t *fromlen)
1142 TRACE ("%s\n", __PRETTY_FUNCTION__);
1143 MF_VALIDATE_EXTENT (buf, len, __MF_CHECK_WRITE, "recvfrom buf");
1144 MF_VALIDATE_EXTENT (from, (size_t)*fromlen, __MF_CHECK_WRITE,
1145 "recvfrom from");
1146 return recvfrom (s, buf, len, flags, from, fromlen);
1150 WRAPPER2(int, recvmsg, int s, struct msghdr *msg, int flags)
1152 TRACE ("%s\n", __PRETTY_FUNCTION__);
1153 MF_VALIDATE_EXTENT (msg, sizeof (*msg), __MF_CHECK_WRITE, "recvmsg msg");
1154 return recvmsg (s, msg, flags);
1158 WRAPPER2(int, send, int s, const void *msg, size_t len, int flags)
1160 TRACE ("%s\n", __PRETTY_FUNCTION__);
1161 MF_VALIDATE_EXTENT (msg, len, __MF_CHECK_READ, "send msg");
1162 return send (s, msg, len, flags);
1166 WRAPPER2(int, sendto, int s, const void *msg, size_t len, int flags,
1167 const struct sockaddr *to, socklen_t tolen)
1169 TRACE ("%s\n", __PRETTY_FUNCTION__);
1170 MF_VALIDATE_EXTENT (msg, len, __MF_CHECK_READ, "sendto msg");
1171 MF_VALIDATE_EXTENT (to, (size_t)tolen, __MF_CHECK_WRITE, "sendto to");
1172 return sendto (s, msg, len, flags, to, tolen);
1176 WRAPPER2(int, sendmsg, int s, const void *msg, int flags)
1178 TRACE ("%s\n", __PRETTY_FUNCTION__);
1179 MF_VALIDATE_EXTENT (msg, sizeof (*msg), __MF_CHECK_READ, "sendmsg msg");
1180 return sendmsg (s, msg, flags);
1184 WRAPPER2(int, setsockopt, int s, int level, int optname, const void *optval,
1185 socklen_t optlen)
1187 TRACE ("%s\n", __PRETTY_FUNCTION__);
1188 MF_VALIDATE_EXTENT (optval, (size_t)optlen, __MF_CHECK_READ,
1189 "setsockopt optval");
1190 return setsockopt (s, level, optname, optval, optlen);
1194 WRAPPER2(int, getsockopt, int s, int level, int optname, void *optval,
1195 socklen_t *optlen)
1197 TRACE ("%s\n", __PRETTY_FUNCTION__);
1198 MF_VALIDATE_EXTENT (optval, (size_t)*optlen, __MF_CHECK_WRITE,
1199 "getsockopt optval");
1200 return getsockopt (s, level, optname, optval, optlen);
1204 WRAPPER2(int, accept, int s, struct sockaddr *addr, socklen_t *addrlen)
1206 TRACE ("%s\n", __PRETTY_FUNCTION__);
1207 MF_VALIDATE_EXTENT (addr, (size_t)*addrlen, __MF_CHECK_WRITE, "accept addr");
1208 return accept (s, addr, addrlen);
1212 WRAPPER2(int, bind, int sockfd, struct sockaddr *addr, socklen_t addrlen)
1214 TRACE ("%s\n", __PRETTY_FUNCTION__);
1215 MF_VALIDATE_EXTENT (addr, (size_t)addrlen, __MF_CHECK_WRITE, "bind addr");
1216 return bind (sockfd, addr, addrlen);
1220 WRAPPER2(int, connect, int sockfd, const struct sockaddr *addr,
1221 socklen_t addrlen)
1223 TRACE ("%s\n", __PRETTY_FUNCTION__);
1224 MF_VALIDATE_EXTENT (addr, (size_t)addrlen, __MF_CHECK_READ,
1225 "connect addr");
1226 return connect (sockfd, addr, addrlen);
1229 #endif /* HAVE_SYS_SOCKET_H */
1232 WRAPPER2(int, gethostname, char *name, size_t len)
1234 TRACE ("%s\n", __PRETTY_FUNCTION__);
1235 MF_VALIDATE_EXTENT (name, len, __MF_CHECK_WRITE, "gethostname name");
1236 return gethostname (name, len);
1240 #ifdef HAVE_SETHOSTNAME
1241 WRAPPER2(int, sethostname, const char *name, size_t len)
1243 TRACE ("%s\n", __PRETTY_FUNCTION__);
1244 MF_VALIDATE_EXTENT (name, len, __MF_CHECK_READ, "sethostname name");
1245 return sethostname (name, len);
1247 #endif
1250 #ifdef HAVE_NETDB_H
1252 WRAPPER2(struct hostent *, gethostbyname, const char *name)
1254 struct hostent *p;
1255 char **ss;
1256 char *s;
1257 size_t n;
1258 int nreg;
1259 TRACE ("%s\n", __PRETTY_FUNCTION__);
1260 n = strlen (name);
1261 MF_VALIDATE_EXTENT (name, CLAMPADD(n, 1), __MF_CHECK_READ,
1262 "gethostbyname name");
1263 p = gethostbyname (name);
1264 if (NULL != p) {
1265 #ifdef MF_REGISTER_gethostbyname
1266 __mf_register (p, sizeof (*p), MF_REGISTER_gethostbyname,
1267 "gethostbyname result");
1268 #endif
1269 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE,
1270 "gethostbyname result");
1271 if (NULL != (s = p->h_name)) {
1272 n = strlen (s);
1273 n = CLAMPADD(n, 1);
1274 #ifdef MF_REGISTER_gethostbyname_items
1275 __mf_register (s, n, MF_REGISTER_gethostbyname_items,
1276 "gethostbyname result->h_name");
1277 #endif
1278 MF_VALIDATE_EXTENT (s, n, __MF_CHECK_WRITE,
1279 "gethostbyname result->h_name");
1282 if (NULL != (ss = p->h_aliases)) {
1283 for (nreg = 1;; ++nreg) {
1284 s = *ss++;
1285 if (NULL == s)
1286 break;
1287 n = strlen (s);
1288 n = CLAMPADD(n, 1);
1289 #ifdef MF_REGISTER_gethostbyname_items
1290 __mf_register (s, n, MF_REGISTER_gethostbyname_items,
1291 "gethostbyname result->h_aliases[]");
1292 #endif
1293 MF_VALIDATE_EXTENT (s, n, __MF_CHECK_WRITE,
1294 "gethostbyname result->h_aliases[]");
1296 nreg *= sizeof (*p->h_aliases);
1297 #ifdef MF_REGISTER_gethostbyname_items
1298 __mf_register (p->h_aliases, nreg, MF_REGISTER_gethostbyname_items,
1299 "gethostbyname result->h_aliases");
1300 #endif
1301 MF_VALIDATE_EXTENT (p->h_aliases, nreg, __MF_CHECK_WRITE,
1302 "gethostbyname result->h_aliases");
1305 if (NULL != (ss = p->h_addr_list)) {
1306 for (nreg = 1;; ++nreg) {
1307 s = *ss++;
1308 if (NULL == s)
1309 break;
1310 #ifdef MF_REGISTER_gethostbyname_items
1311 __mf_register (s, p->h_length, MF_REGISTER_gethostbyname_items,
1312 "gethostbyname result->h_addr_list[]");
1313 #endif
1314 MF_VALIDATE_EXTENT (s, p->h_length, __MF_CHECK_WRITE,
1315 "gethostbyname result->h_addr_list[]");
1317 nreg *= sizeof (*p->h_addr_list);
1318 #ifdef MF_REGISTER_gethostbyname_items
1319 __mf_register (p->h_addr_list, nreg, MF_REGISTER_gethostbyname_items,
1320 "gethostbyname result->h_addr_list");
1321 #endif
1322 MF_VALIDATE_EXTENT (p->h_addr_list, nreg, __MF_CHECK_WRITE,
1323 "gethostbyname result->h_addr_list");
1326 return p;
1329 #endif /* HAVE_NETDB_H */
1332 #ifdef HAVE_SYS_WAIT_H
1334 WRAPPER2(pid_t, wait, int *status)
1336 TRACE ("%s\n", __PRETTY_FUNCTION__);
1337 if (NULL != status)
1338 MF_VALIDATE_EXTENT (status, sizeof (*status), __MF_CHECK_WRITE,
1339 "wait status");
1340 return wait (status);
1344 WRAPPER2(pid_t, waitpid, pid_t pid, int *status, int options)
1346 TRACE ("%s\n", __PRETTY_FUNCTION__);
1347 if (NULL != status)
1348 MF_VALIDATE_EXTENT (status, sizeof (*status), __MF_CHECK_WRITE,
1349 "waitpid status");
1350 return waitpid (pid, status, options);
1353 #endif /* HAVE_SYS_WAIT_H */
1356 WRAPPER2(FILE *, popen, const char *command, const char *mode)
1358 size_t n;
1359 FILE *p;
1360 TRACE ("%s\n", __PRETTY_FUNCTION__);
1362 n = strlen (command);
1363 MF_VALIDATE_EXTENT (command, CLAMPADD(n, 1), __MF_CHECK_READ, "popen path");
1365 n = strlen (mode);
1366 MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "popen mode");
1368 p = popen (command, mode);
1369 if (NULL != p) {
1370 #ifdef MF_REGISTER_fopen
1371 __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "popen result");
1372 #endif
1373 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "popen result");
1375 return p;
1379 WRAPPER2(int, pclose, FILE *stream)
1381 int resp;
1382 TRACE ("%s\n", __PRETTY_FUNCTION__);
1383 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1384 "pclose stream");
1385 resp = pclose (stream);
1386 #ifdef MF_REGISTER_fopen
1387 __mf_unregister (stream, sizeof (*stream), MF_REGISTER_fopen);
1388 #endif
1389 return resp;
1393 WRAPPER2(int, execve, const char *path, char *const argv [],
1394 char *const envp[])
1396 size_t n;
1397 char *const *p;
1398 const char *s;
1399 TRACE ("%s\n", __PRETTY_FUNCTION__);
1401 n = strlen (path);
1402 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "execve path");
1404 for (p = argv;;) {
1405 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_READ, "execve *argv");
1406 s = *p++;
1407 if (NULL == s)
1408 break;
1409 n = strlen (s);
1410 MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "execve **argv");
1413 for (p = envp;;) {
1414 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_READ, "execve *envp");
1415 s = *p++;
1416 if (NULL == s)
1417 break;
1418 n = strlen (s);
1419 MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "execve **envp");
1421 return execve (path, argv, envp);
1425 WRAPPER2(int, execv, const char *path, char *const argv [])
1427 size_t n;
1428 char *const *p;
1429 const char *s;
1430 TRACE ("%s\n", __PRETTY_FUNCTION__);
1432 n = strlen (path);
1433 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "execv path");
1435 for (p = argv;;) {
1436 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_READ, "execv *argv");
1437 s = *p++;
1438 if (NULL == s)
1439 break;
1440 n = strlen (s);
1441 MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "execv **argv");
1443 return execv (path, argv);
1447 WRAPPER2(int, execvp, const char *path, char *const argv [])
1449 size_t n;
1450 char *const *p;
1451 const char *s;
1452 TRACE ("%s\n", __PRETTY_FUNCTION__);
1454 n = strlen (path);
1455 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "execvp path");
1457 for (p = argv;;) {
1458 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_READ, "execvp *argv");
1459 s = *p++;
1460 if (NULL == s)
1461 break;
1462 n = strlen (s);
1463 MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "execvp **argv");
1465 return execvp (path, argv);
1469 WRAPPER2(int, system, const char *string)
1471 size_t n;
1472 TRACE ("%s\n", __PRETTY_FUNCTION__);
1473 n = strlen (string);
1474 MF_VALIDATE_EXTENT (string, CLAMPADD(n, 1), __MF_CHECK_READ,
1475 "system string");
1476 return system (string);
1480 WRAPPER2(void *, dlopen, const char *path, int flags)
1482 void *p;
1483 size_t n;
1484 TRACE ("%s\n", __PRETTY_FUNCTION__);
1485 n = strlen (path);
1486 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "dlopen path");
1487 p = dlopen (path, flags);
1488 if (NULL != p) {
1489 #ifdef MF_REGISTER_dlopen
1490 __mf_register (p, 0, MF_REGISTER_dlopen, "dlopen result");
1491 #endif
1492 MF_VALIDATE_EXTENT (p, 0, __MF_CHECK_WRITE, "dlopen result");
1494 return p;
1498 WRAPPER2(int, dlclose, void *handle)
1500 int resp;
1501 TRACE ("%s\n", __PRETTY_FUNCTION__);
1502 MF_VALIDATE_EXTENT (handle, 0, __MF_CHECK_READ, "dlclose handle");
1503 resp = dlclose (handle);
1504 #ifdef MF_REGISTER_dlopen
1505 __mf_unregister (handle, 0, MF_REGISTER_dlopen);
1506 #endif
1507 return resp;
1511 WRAPPER2(char *, dlerror)
1513 char *p;
1514 TRACE ("%s\n", __PRETTY_FUNCTION__);
1515 p = dlerror ();
1516 if (NULL != p) {
1517 size_t n;
1518 n = strlen (p);
1519 n = CLAMPADD(n, 1);
1520 #ifdef MF_REGISTER_dlerror
1521 __mf_register (p, n, MF_REGISTER_dlerror, "dlerror result");
1522 #endif
1523 MF_VALIDATE_EXTENT (p, n, __MF_CHECK_WRITE, "dlerror result");
1525 return p;
1529 WRAPPER2(void *, dlsym, void *handle, char *symbol)
1531 size_t n;
1532 void *p;
1533 TRACE ("%s\n", __PRETTY_FUNCTION__);
1534 MF_VALIDATE_EXTENT (handle, 0, __MF_CHECK_READ, "dlsym handle");
1535 n = strlen (symbol);
1536 MF_VALIDATE_EXTENT (symbol, CLAMPADD(n, 1), __MF_CHECK_READ, "dlsym symbol");
1537 p = dlsym (handle, symbol);
1538 if (NULL != p) {
1539 #ifdef MF_REGISTER_dlsym
1540 __mf_register (p, 0, MF_REGISTER_dlsym, "dlsym result");
1541 #endif
1542 MF_VALIDATE_EXTENT (p, 0, __MF_CHECK_WRITE, "dlsym result");
1544 return p;
1548 #if defined (HAVE_SYS_IPC_H) && defined (HAVE_SYS_SEM_H) && defined (HAVE_SYS_SHM_H)
1550 WRAPPER2(int, semop, int semid, struct sembuf *sops, unsigned nsops)
1552 TRACE ("%s\n", __PRETTY_FUNCTION__);
1553 MF_VALIDATE_EXTENT (sops, sizeof (*sops) * nsops, __MF_CHECK_READ,
1554 "semop sops");
1555 return semop (semid, sops, nsops);
1559 #ifndef HAVE_UNION_SEMUN
1560 union semun {
1561 int val; /* value for SETVAL */
1562 struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */
1563 unsigned short int *array; /* array for GETALL, SETALL */
1564 struct seminfo *__buf; /* buffer for IPC_INFO */
1566 #endif
1567 WRAPPER2(int, semctl, int semid, int semnum, int cmd, union semun arg)
1569 TRACE ("%s\n", __PRETTY_FUNCTION__);
1570 switch (cmd) {
1571 case IPC_STAT:
1572 MF_VALIDATE_EXTENT (arg.buf, sizeof (*arg.buf), __MF_CHECK_WRITE,
1573 "semctl buf");
1574 break;
1575 case IPC_SET:
1576 MF_VALIDATE_EXTENT (arg.buf, sizeof (*arg.buf), __MF_CHECK_READ,
1577 "semctl buf");
1578 break;
1579 case GETALL:
1580 MF_VALIDATE_EXTENT (arg.array, sizeof (*arg.array), __MF_CHECK_WRITE,
1581 "semctl array");
1582 case SETALL:
1583 MF_VALIDATE_EXTENT (arg.array, sizeof (*arg.array), __MF_CHECK_READ,
1584 "semctl array");
1585 break;
1586 #ifdef IPC_INFO
1587 /* FreeBSD 5.1 And Cygwin headers include IPC_INFO but not the __buf field. */
1588 #if !defined(__FreeBSD__) && !defined(__CYGWIN__)
1589 case IPC_INFO:
1590 MF_VALIDATE_EXTENT (arg.__buf, sizeof (*arg.__buf), __MF_CHECK_WRITE,
1591 "semctl __buf");
1592 break;
1593 #endif
1594 #endif
1595 default:
1596 break;
1598 return semctl (semid, semnum, cmd, arg);
1602 WRAPPER2(int, shmctl, int shmid, int cmd, struct shmid_ds *buf)
1604 TRACE ("%s\n", __PRETTY_FUNCTION__);
1605 switch (cmd) {
1606 case IPC_STAT:
1607 MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_WRITE,
1608 "shmctl buf");
1609 break;
1610 case IPC_SET:
1611 MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ,
1612 "shmctl buf");
1613 break;
1614 default:
1615 break;
1617 return shmctl (shmid, cmd, buf);
1621 WRAPPER2(void *, shmat, int shmid, const void *shmaddr, int shmflg)
1623 void *p;
1624 TRACE ("%s\n", __PRETTY_FUNCTION__);
1625 p = shmat (shmid, shmaddr, shmflg);
1626 #ifdef MF_REGISTER_shmat
1627 if (NULL != p) {
1628 struct shmid_ds buf;
1629 __mf_register (p, shmctl (shmid, IPC_STAT, &buf) ? 0 : buf.shm_segsz,
1630 MF_REGISTER_shmat, "shmat result");
1632 #endif
1633 return p;
1637 WRAPPER2(int, shmdt, const void *shmaddr)
1639 int resp;
1640 TRACE ("%s\n", __PRETTY_FUNCTION__);
1641 resp = shmdt (shmaddr);
1642 #ifdef MF_REGISTER_shmat
1643 __mf_unregister ((void *)shmaddr, 0, MF_REGISTER_shmat);
1644 #endif
1645 return resp;
1649 #endif /* HAVE_SYS_IPC/SEM/SHM_H */
1653 /* ctype stuff. This is host-specific by necessity, as the arrays
1654 that is used by most is*()/to*() macros are implementation-defined. */
1656 /* GLIBC 2.3 */
1657 #ifdef HAVE___CTYPE_B_LOC
1658 WRAPPER2(unsigned short **, __ctype_b_loc, void)
1660 static unsigned short * last_buf = (void *) 0;
1661 static unsigned short ** last_ptr = (void *) 0;
1662 unsigned short ** ptr = (unsigned short **) __ctype_b_loc ();
1663 unsigned short * buf = * ptr;
1664 if (ptr != last_ptr)
1666 /* XXX: unregister last_ptr? */
1667 last_ptr = ptr;
1668 __mf_register (last_ptr, sizeof(last_ptr), __MF_TYPE_STATIC, "ctype_b_loc **");
1670 if (buf != last_buf)
1672 last_buf = buf;
1673 __mf_register ((void *) (last_buf - 128), 384 * sizeof(unsigned short), __MF_TYPE_STATIC,
1674 "ctype_b_loc []");
1676 return ptr;
1678 #endif
1680 #ifdef HAVE___CTYPE_TOUPPER_LOC
1681 WRAPPER2(int **, __ctype_toupper_loc, void)
1683 static int * last_buf = (void *) 0;
1684 static int ** last_ptr = (void *) 0;
1685 int ** ptr = (int **) __ctype_toupper_loc ();
1686 int * buf = * ptr;
1687 if (ptr != last_ptr)
1689 /* XXX: unregister last_ptr? */
1690 last_ptr = ptr;
1691 __mf_register (last_ptr, sizeof(last_ptr), __MF_TYPE_STATIC, "ctype_toupper_loc **");
1693 if (buf != last_buf)
1695 last_buf = buf;
1696 __mf_register ((void *) (last_buf - 128), 384 * sizeof(int), __MF_TYPE_STATIC,
1697 "ctype_toupper_loc []");
1699 return ptr;
1701 #endif
1703 #ifdef HAVE___CTYPE_TOLOWER_LOC
1704 WRAPPER2(int **, __ctype_tolower_loc, void)
1706 static int * last_buf = (void *) 0;
1707 static int ** last_ptr = (void *) 0;
1708 int ** ptr = (int **) __ctype_tolower_loc ();
1709 int * buf = * ptr;
1710 if (ptr != last_ptr)
1712 /* XXX: unregister last_ptr? */
1713 last_ptr = ptr;
1714 __mf_register (last_ptr, sizeof(last_ptr), __MF_TYPE_STATIC, "ctype_tolower_loc **");
1716 if (buf != last_buf)
1718 last_buf = buf;
1719 __mf_register ((void *) (last_buf - 128), 384 * sizeof(int), __MF_TYPE_STATIC,
1720 "ctype_tolower_loc []");
1722 return ptr;
1724 #endif