- Fix reference to PR (17285 -> 17835)
[official-gcc.git] / libmudflap / mf-hooks2.c
blob52ff3c1b4a877a1c7afa6e28e32f9041ada9b1f5
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_DLFCN_H
67 #include <dlfcn.h>
68 #endif
69 #ifdef HAVE_DIRENT_H
70 #include <dirent.h>
71 #endif
72 #ifdef HAVE_SYS_SOCKET_H
73 #include <sys/socket.h>
74 #endif
75 #ifdef HAVE_NETDB_H
76 #include <netdb.h>
77 #endif
78 #ifdef HAVE_SYS_WAIT_H
79 #include <sys/wait.h>
80 #endif
81 #ifdef HAVE_SYS_IPC_H
82 #include <sys/ipc.h>
83 #endif
84 #ifdef HAVE_SYS_SEM_H
85 #include <sys/sem.h>
86 #endif
87 #ifdef HAVE_SYS_SHM_H
88 #include <sys/shm.h>
89 #endif
90 #ifdef HAVE_PWD_H
91 #include <pwd.h>
92 #endif
93 #ifdef HAVE_GRP_H
94 #include <grp.h>
95 #endif
96 #ifdef HAVE_MNTENT_H
97 #include <mntent.h>
98 #endif
99 #ifdef HAVE_SYS_SOCKET_H
100 #include <sys/socket.h>
101 #endif
102 #ifdef HAVE_NETINET_IN_H
103 #include <netinet/in.h>
104 #endif
105 #ifdef HAVE_ARPA_INET_H
106 #include <arpa/inet.h>
107 #endif
109 #include "mf-runtime.h"
110 #include "mf-impl.h"
112 #ifdef _MUDFLAP
113 #error "Do not compile this file with -fmudflap!"
114 #endif
117 /* A bunch of independent stdlib/unistd hook functions, all
118 intercepted by mf-runtime.h macros. */
120 #ifndef HAVE_STRNLEN
121 static inline size_t (strnlen) (const char* str, size_t n)
123 const char *s;
125 for (s = str; n && *s; ++s, --n)
127 return (s - str);
129 #endif
132 /* str*,mem*,b* */
134 WRAPPER2(void *, memcpy, void *dest, const void *src, size_t n)
136 TRACE ("%s\n", __PRETTY_FUNCTION__);
137 MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "memcpy source");
138 MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "memcpy dest");
139 return memcpy (dest, src, n);
143 WRAPPER2(void *, memmove, void *dest, const void *src, size_t n)
145 TRACE ("%s\n", __PRETTY_FUNCTION__);
146 MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "memmove src");
147 MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "memmove dest");
148 return memmove (dest, src, n);
152 WRAPPER2(void *, memset, void *s, int c, size_t n)
154 TRACE ("%s\n", __PRETTY_FUNCTION__);
155 MF_VALIDATE_EXTENT(s, n, __MF_CHECK_WRITE, "memset dest");
156 return memset (s, c, n);
160 WRAPPER2(int, memcmp, const void *s1, const void *s2, size_t n)
162 TRACE ("%s\n", __PRETTY_FUNCTION__);
163 MF_VALIDATE_EXTENT(s1, n, __MF_CHECK_READ, "memcmp 1st arg");
164 MF_VALIDATE_EXTENT(s2, n, __MF_CHECK_READ, "memcmp 2nd arg");
165 return memcmp (s1, s2, n);
169 WRAPPER2(void *, memchr, const void *s, int c, size_t n)
171 TRACE ("%s\n", __PRETTY_FUNCTION__);
172 MF_VALIDATE_EXTENT(s, n, __MF_CHECK_READ, "memchr region");
173 return memchr (s, c, n);
177 #ifdef HAVE_MEMRCHR
178 WRAPPER2(void *, memrchr, const void *s, int c, size_t n)
180 TRACE ("%s\n", __PRETTY_FUNCTION__);
181 MF_VALIDATE_EXTENT(s, n, __MF_CHECK_READ, "memrchr region");
182 return memrchr (s, c, n);
184 #endif
187 WRAPPER2(char *, strcpy, char *dest, const char *src)
189 /* nb: just because strlen(src) == n doesn't mean (src + n) or (src + n +
190 1) are valid pointers. the allocated object might have size < n.
191 check anyways. */
193 size_t n = strlen (src);
194 TRACE ("%s\n", __PRETTY_FUNCTION__);
195 MF_VALIDATE_EXTENT(src, CLAMPADD(n, 1), __MF_CHECK_READ, "strcpy src");
196 MF_VALIDATE_EXTENT(dest, CLAMPADD(n, 1), __MF_CHECK_WRITE, "strcpy dest");
197 return strcpy (dest, src);
201 #ifdef HAVE_STRNCPY
202 WRAPPER2(char *, strncpy, char *dest, const char *src, size_t n)
204 size_t len = strnlen (src, n);
205 TRACE ("%s\n", __PRETTY_FUNCTION__);
206 MF_VALIDATE_EXTENT(src, len, __MF_CHECK_READ, "strncpy src");
207 MF_VALIDATE_EXTENT(dest, len, __MF_CHECK_WRITE, "strncpy dest"); /* nb: strNcpy */
208 return strncpy (dest, src, n);
210 #endif
213 WRAPPER2(char *, strcat, char *dest, const char *src)
215 size_t dest_sz;
216 size_t src_sz;
217 TRACE ("%s\n", __PRETTY_FUNCTION__);
218 dest_sz = strlen (dest);
219 src_sz = strlen (src);
220 MF_VALIDATE_EXTENT(src, CLAMPADD(src_sz, 1), __MF_CHECK_READ, "strcat src");
221 MF_VALIDATE_EXTENT(dest, CLAMPADD(dest_sz, CLAMPADD(src_sz, 1)),
222 __MF_CHECK_WRITE, "strcat dest");
223 return strcat (dest, src);
227 WRAPPER2(char *, strncat, char *dest, const char *src, size_t n)
230 /* nb: validating the extents (s,n) might be a mistake for two reasons.
232 (1) the string s might be shorter than n chars, and n is just a
233 poor choice by the programmer. this is not a "true" error in the
234 sense that the call to strncat would still be ok.
236 (2) we could try to compensate for case (1) by calling strlen(s) and
237 using that as a bound for the extent to verify, but strlen might fall off
238 the end of a non-terminated string, leading to a false positive.
240 so we will call strnlen(s,n) and use that as a bound.
242 if strnlen returns a length beyond the end of the registered extent
243 associated with s, there is an error: the programmer's estimate for n is
244 too large _AND_ the string s is unterminated, in which case they'd be
245 about to touch memory they don't own while calling strncat.
247 this same logic applies to further uses of strnlen later down in this
248 file. */
250 size_t src_sz;
251 size_t dest_sz;
252 TRACE ("%s\n", __PRETTY_FUNCTION__);
253 src_sz = strnlen (src, n);
254 dest_sz = strnlen (dest, n);
255 MF_VALIDATE_EXTENT(src, src_sz, __MF_CHECK_READ, "strncat src");
256 MF_VALIDATE_EXTENT(dest, (CLAMPADD(dest_sz, CLAMPADD(src_sz, 1))),
257 __MF_CHECK_WRITE, "strncat dest");
258 return strncat (dest, src, n);
262 WRAPPER2(int, strcmp, const char *s1, const char *s2)
264 size_t s1_sz;
265 size_t s2_sz;
266 TRACE ("%s\n", __PRETTY_FUNCTION__);
267 s1_sz = strlen (s1);
268 s2_sz = strlen (s2);
269 MF_VALIDATE_EXTENT(s1, CLAMPADD(s1_sz, 1), __MF_CHECK_READ, "strcmp 1st arg");
270 MF_VALIDATE_EXTENT(s2, CLAMPADD(s2_sz, 1), __MF_CHECK_WRITE, "strcmp 2nd arg");
271 return strcmp (s1, s2);
275 WRAPPER2(int, strcasecmp, const char *s1, const char *s2)
277 size_t s1_sz;
278 size_t s2_sz;
279 TRACE ("%s\n", __PRETTY_FUNCTION__);
280 s1_sz = strlen (s1);
281 s2_sz = strlen (s2);
282 MF_VALIDATE_EXTENT(s1, CLAMPADD(s1_sz, 1), __MF_CHECK_READ, "strcasecmp 1st arg");
283 MF_VALIDATE_EXTENT(s2, CLAMPADD(s2_sz, 1), __MF_CHECK_READ, "strcasecmp 2nd arg");
284 return strcasecmp (s1, s2);
288 WRAPPER2(int, strncmp, const char *s1, const char *s2, size_t n)
290 size_t s1_sz;
291 size_t s2_sz;
292 TRACE ("%s\n", __PRETTY_FUNCTION__);
293 s1_sz = strnlen (s1, n);
294 s2_sz = strnlen (s2, n);
295 MF_VALIDATE_EXTENT(s1, s1_sz, __MF_CHECK_READ, "strncmp 1st arg");
296 MF_VALIDATE_EXTENT(s2, s2_sz, __MF_CHECK_READ, "strncmp 2nd arg");
297 return strncmp (s1, s2, n);
301 WRAPPER2(int, strncasecmp, const char *s1, const char *s2, size_t n)
303 size_t s1_sz;
304 size_t s2_sz;
305 TRACE ("%s\n", __PRETTY_FUNCTION__);
306 s1_sz = strnlen (s1, n);
307 s2_sz = strnlen (s2, n);
308 MF_VALIDATE_EXTENT(s1, s1_sz, __MF_CHECK_READ, "strncasecmp 1st arg");
309 MF_VALIDATE_EXTENT(s2, s2_sz, __MF_CHECK_READ, "strncasecmp 2nd arg");
310 return strncasecmp (s1, s2, n);
314 WRAPPER2(char *, strdup, const char *s)
316 DECLARE(void *, malloc, size_t sz);
317 char *result;
318 size_t n = strlen (s);
319 TRACE ("%s\n", __PRETTY_FUNCTION__);
320 MF_VALIDATE_EXTENT(s, CLAMPADD(n,1), __MF_CHECK_READ, "strdup region");
321 result = (char *)CALL_REAL(malloc,
322 CLAMPADD(CLAMPADD(n,1),
323 CLAMPADD(__mf_opts.crumple_zone,
324 __mf_opts.crumple_zone)));
326 if (UNLIKELY(! result)) return result;
328 result += __mf_opts.crumple_zone;
329 memcpy (result, s, n);
330 result[n] = '\0';
332 __mf_register (result, CLAMPADD(n,1), __MF_TYPE_HEAP_I, "strdup region");
333 return result;
337 WRAPPER2(char *, strndup, const char *s, size_t n)
339 DECLARE(void *, malloc, size_t sz);
340 char *result;
341 size_t sz = strnlen (s, n);
342 TRACE ("%s\n", __PRETTY_FUNCTION__);
343 MF_VALIDATE_EXTENT(s, sz, __MF_CHECK_READ, "strndup region"); /* nb: strNdup */
345 /* note: strndup still adds a \0, even with the N limit! */
346 result = (char *)CALL_REAL(malloc,
347 CLAMPADD(CLAMPADD(n,1),
348 CLAMPADD(__mf_opts.crumple_zone,
349 __mf_opts.crumple_zone)));
351 if (UNLIKELY(! result)) return result;
353 result += __mf_opts.crumple_zone;
354 memcpy (result, s, n);
355 result[n] = '\0';
357 __mf_register (result, CLAMPADD(n,1), __MF_TYPE_HEAP_I, "strndup region");
358 return result;
362 WRAPPER2(char *, strchr, const char *s, int c)
364 size_t n;
365 TRACE ("%s\n", __PRETTY_FUNCTION__);
366 n = strlen (s);
367 MF_VALIDATE_EXTENT(s, CLAMPADD(n,1), __MF_CHECK_READ, "strchr region");
368 return strchr (s, c);
372 WRAPPER2(char *, strrchr, const char *s, int c)
374 size_t n;
375 TRACE ("%s\n", __PRETTY_FUNCTION__);
376 n = strlen (s);
377 MF_VALIDATE_EXTENT(s, CLAMPADD(n,1), __MF_CHECK_READ, "strrchr region");
378 return strrchr (s, c);
382 WRAPPER2(char *, strstr, const char *haystack, const char *needle)
384 size_t haystack_sz;
385 size_t needle_sz;
386 TRACE ("%s\n", __PRETTY_FUNCTION__);
387 haystack_sz = strlen (haystack);
388 needle_sz = strlen (needle);
389 MF_VALIDATE_EXTENT(haystack, CLAMPADD(haystack_sz, 1), __MF_CHECK_READ, "strstr haystack");
390 MF_VALIDATE_EXTENT(needle, CLAMPADD(needle_sz, 1), __MF_CHECK_READ, "strstr needle");
391 return strstr (haystack, needle);
395 #ifdef HAVE_MEMMEM
396 WRAPPER2(void *, memmem,
397 const void *haystack, size_t haystacklen,
398 const void *needle, size_t needlelen)
400 TRACE ("%s\n", __PRETTY_FUNCTION__);
401 MF_VALIDATE_EXTENT(haystack, haystacklen, __MF_CHECK_READ, "memmem haystack");
402 MF_VALIDATE_EXTENT(needle, needlelen, __MF_CHECK_READ, "memmem needle");
403 return memmem (haystack, haystacklen, needle, needlelen);
405 #endif
408 WRAPPER2(size_t, strlen, const char *s)
410 size_t result = strlen (s);
411 TRACE ("%s\n", __PRETTY_FUNCTION__);
412 MF_VALIDATE_EXTENT(s, CLAMPADD(result, 1), __MF_CHECK_READ, "strlen region");
413 return result;
417 WRAPPER2(size_t, strnlen, const char *s, size_t n)
419 size_t result = strnlen (s, n);
420 TRACE ("%s\n", __PRETTY_FUNCTION__);
421 MF_VALIDATE_EXTENT(s, result, __MF_CHECK_READ, "strnlen region");
422 return result;
426 WRAPPER2(void, bzero, void *s, size_t n)
428 TRACE ("%s\n", __PRETTY_FUNCTION__);
429 MF_VALIDATE_EXTENT(s, n, __MF_CHECK_WRITE, "bzero region");
430 bzero (s, n);
434 #undef bcopy
435 WRAPPER2(void, bcopy, const void *src, void *dest, size_t n)
437 TRACE ("%s\n", __PRETTY_FUNCTION__);
438 MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "bcopy src");
439 MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "bcopy dest");
440 bcopy (src, dest, n);
444 #undef bcmp
445 WRAPPER2(int, bcmp, const void *s1, const void *s2, size_t n)
447 TRACE ("%s\n", __PRETTY_FUNCTION__);
448 MF_VALIDATE_EXTENT(s1, n, __MF_CHECK_READ, "bcmp 1st arg");
449 MF_VALIDATE_EXTENT(s2, n, __MF_CHECK_READ, "bcmp 2nd arg");
450 return bcmp (s1, s2, n);
454 WRAPPER2(char *, index, const char *s, int c)
456 size_t n = strlen (s);
457 TRACE ("%s\n", __PRETTY_FUNCTION__);
458 MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "index region");
459 return index (s, c);
463 WRAPPER2(char *, rindex, const char *s, int c)
465 size_t n = strlen (s);
466 TRACE ("%s\n", __PRETTY_FUNCTION__);
467 MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "rindex region");
468 return rindex (s, c);
471 /* XXX: stpcpy, memccpy */
473 /* XXX: *printf,*scanf */
475 /* XXX: setjmp, longjmp */
477 WRAPPER2(char *, asctime, struct tm *tm)
479 static char *reg_result = NULL;
480 char *result;
481 TRACE ("%s\n", __PRETTY_FUNCTION__);
482 MF_VALIDATE_EXTENT(tm, sizeof (struct tm), __MF_CHECK_READ, "asctime tm");
483 result = asctime (tm);
484 if (reg_result == NULL)
486 __mf_register (result, strlen (result)+1, __MF_TYPE_STATIC, "asctime string");
487 reg_result = result;
489 return result;
493 WRAPPER2(char *, ctime, const time_t *timep)
495 static char *reg_result = NULL;
496 char *result;
497 TRACE ("%s\n", __PRETTY_FUNCTION__);
498 MF_VALIDATE_EXTENT(timep, sizeof (time_t), __MF_CHECK_READ, "ctime time");
499 result = ctime (timep);
500 if (reg_result == NULL)
502 /* XXX: what if asctime and ctime return the same static ptr? */
503 __mf_register (result, strlen (result)+1, __MF_TYPE_STATIC, "ctime string");
504 reg_result = result;
506 return result;
510 WRAPPER2(struct tm*, localtime, const time_t *timep)
512 static struct tm *reg_result = NULL;
513 struct tm *result;
514 TRACE ("%s\n", __PRETTY_FUNCTION__);
515 MF_VALIDATE_EXTENT(timep, sizeof (time_t), __MF_CHECK_READ, "localtime time");
516 result = localtime (timep);
517 if (reg_result == NULL)
519 __mf_register (result, sizeof (struct tm), __MF_TYPE_STATIC, "localtime tm");
520 reg_result = result;
522 return result;
526 WRAPPER2(struct tm*, gmtime, const time_t *timep)
528 static struct tm *reg_result = NULL;
529 struct tm *result;
530 TRACE ("%s\n", __PRETTY_FUNCTION__);
531 MF_VALIDATE_EXTENT(timep, sizeof (time_t), __MF_CHECK_READ, "gmtime time");
532 result = gmtime (timep);
533 if (reg_result == NULL)
535 __mf_register (result, sizeof (struct tm), __MF_TYPE_STATIC, "gmtime tm");
536 reg_result = result;
538 return result;
542 /* EL start */
544 /* The following indicate if the result of the corresponding function
545 * should be explicitly un/registered by the wrapper
547 #undef MF_REGISTER_fopen
548 #define MF_RESULT_SIZE_fopen (sizeof (FILE))
549 #undef MF_REGISTER_opendir
550 #define MF_RESULT_SIZE_opendir 0 /* (sizeof (DIR)) */
551 #undef MF_REGISTER_readdir
552 #define MF_REGISTER_gethostbyname __MF_TYPE_STATIC
553 #undef MF_REGISTER_gethostbyname_items
554 #undef MF_REGISTER_dlopen
555 #undef MF_REGISTER_dlerror
556 #undef MF_REGISTER_dlsym
557 #define MF_REGISTER_shmat __MF_TYPE_GUESS
560 #include <time.h>
561 WRAPPER2(time_t, time, time_t *timep)
563 TRACE ("%s\n", __PRETTY_FUNCTION__);
564 if (NULL != timep)
565 MF_VALIDATE_EXTENT (timep, sizeof (*timep), __MF_CHECK_WRITE,
566 "time timep");
567 return time (timep);
571 WRAPPER2(char *, strerror, int errnum)
573 char *p;
574 static char * last_strerror = NULL;
576 TRACE ("%s\n", __PRETTY_FUNCTION__);
577 p = strerror (errnum);
578 if (last_strerror != NULL)
579 __mf_unregister (last_strerror, 0, __MF_TYPE_STATIC);
580 if (NULL != p)
581 __mf_register (p, strlen (p) + 1, __MF_TYPE_STATIC, "strerror result");
582 last_strerror = p;
583 return p;
587 WRAPPER2(FILE *, fopen, const char *path, const char *mode)
589 size_t n;
590 FILE *p;
591 TRACE ("%s\n", __PRETTY_FUNCTION__);
593 n = strlen (path);
594 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "fopen path");
596 n = strlen (mode);
597 MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "fopen mode");
599 p = fopen (path, mode);
600 if (NULL != p) {
601 #ifdef MF_REGISTER_fopen
602 __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "fopen result");
603 #endif
604 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "fopen result");
607 return p;
611 #ifdef HAVE_FOPEN64
612 WRAPPER2(FILE *, fopen64, const char *path, const char *mode)
614 size_t n;
615 FILE *p;
616 TRACE ("%s\n", __PRETTY_FUNCTION__);
618 n = strlen (path);
619 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "fopen64 path");
621 n = strlen (mode);
622 MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "fopen64 mode");
624 p = fopen64 (path, mode);
625 if (NULL != p) {
626 #ifdef MF_REGISTER_fopen
627 __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "fopen64 result");
628 #endif
629 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "fopen64 result");
632 return p;
634 #endif
637 WRAPPER2(int, fclose, FILE *stream)
639 int resp;
640 TRACE ("%s\n", __PRETTY_FUNCTION__);
641 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
642 "fclose stream");
643 resp = fclose (stream);
644 #ifdef MF_REGISTER_fopen
645 __mf_unregister (stream, sizeof (*stream), MF_REGISTER_fopen);
646 #endif
648 return resp;
652 WRAPPER2(size_t, fread, void *ptr, size_t size, size_t nmemb, FILE *stream)
654 TRACE ("%s\n", __PRETTY_FUNCTION__);
655 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
656 "fread stream");
657 MF_VALIDATE_EXTENT (ptr, size * nmemb, __MF_CHECK_WRITE, "fread buffer");
658 return fread (ptr, size, nmemb, stream);
662 WRAPPER2(size_t, fwrite, const void *ptr, size_t size, size_t nmemb,
663 FILE *stream)
665 TRACE ("%s\n", __PRETTY_FUNCTION__);
666 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
667 "fwrite stream");
668 MF_VALIDATE_EXTENT (ptr, size * nmemb, __MF_CHECK_READ, "fwrite buffer");
669 return fwrite (ptr, size, nmemb, stream);
673 WRAPPER2(int, fgetc, FILE *stream)
675 TRACE ("%s\n", __PRETTY_FUNCTION__);
676 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
677 "fgetc stream");
678 return fgetc (stream);
682 WRAPPER2(char *, fgets, char *s, int size, FILE *stream)
684 TRACE ("%s\n", __PRETTY_FUNCTION__);
685 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
686 "fgets stream");
687 MF_VALIDATE_EXTENT (s, size, __MF_CHECK_WRITE, "fgets buffer");
688 return fgets (s, size, stream);
692 WRAPPER2(int, getc, FILE *stream)
694 TRACE ("%s\n", __PRETTY_FUNCTION__);
695 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
696 "getc stream");
697 return getc (stream);
701 WRAPPER2(char *, gets, char *s)
703 TRACE ("%s\n", __PRETTY_FUNCTION__);
704 MF_VALIDATE_EXTENT (s, 1, __MF_CHECK_WRITE, "gets buffer");
705 /* Avoid link-time warning... */
706 s = fgets (s, INT_MAX, stdin);
707 if (NULL != s) { /* better late than never */
708 size_t n = strlen (s);
709 MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_WRITE, "gets buffer");
711 return s;
715 WRAPPER2(int, ungetc, int c, FILE *stream)
717 TRACE ("%s\n", __PRETTY_FUNCTION__);
718 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
719 "ungetc stream");
720 return ungetc (c, stream);
724 WRAPPER2(int, fputc, int c, FILE *stream)
726 TRACE ("%s\n", __PRETTY_FUNCTION__);
727 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
728 "fputc stream");
729 return fputc (c, stream);
733 WRAPPER2(int, fputs, const char *s, FILE *stream)
735 size_t n;
736 TRACE ("%s\n", __PRETTY_FUNCTION__);
737 n = strlen (s);
738 MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "fputs buffer");
739 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
740 "fputs stream");
741 return fputs (s, stream);
745 WRAPPER2(int, putc, int c, FILE *stream)
747 TRACE ("%s\n", __PRETTY_FUNCTION__);
748 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
749 "putc stream");
750 return putc (c, stream);
754 WRAPPER2(int, puts, const char *s)
756 size_t n;
757 TRACE ("%s\n", __PRETTY_FUNCTION__);
758 n = strlen (s);
759 MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "puts buffer");
760 return puts (s);
764 WRAPPER2(void, clearerr, FILE *stream)
766 TRACE ("%s\n", __PRETTY_FUNCTION__);
767 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
768 "clearerr stream");
769 clearerr (stream);
773 WRAPPER2(int, feof, FILE *stream)
775 TRACE ("%s\n", __PRETTY_FUNCTION__);
776 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
777 "feof stream");
778 return feof (stream);
782 WRAPPER2(int, ferror, FILE *stream)
784 TRACE ("%s\n", __PRETTY_FUNCTION__);
785 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
786 "ferror stream");
787 return ferror (stream);
791 WRAPPER2(int, fileno, FILE *stream)
793 TRACE ("%s\n", __PRETTY_FUNCTION__);
794 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
795 "fileno stream");
796 return fileno (stream);
800 WRAPPER2(int, printf, const char *format, ...)
802 size_t n;
803 va_list ap;
804 int result;
805 TRACE ("%s\n", __PRETTY_FUNCTION__);
806 n = strlen (format);
807 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
808 "printf format");
809 va_start (ap, format);
810 result = vprintf (format, ap);
811 va_end (ap);
812 return result;
816 WRAPPER2(int, fprintf, FILE *stream, const char *format, ...)
818 size_t n;
819 va_list ap;
820 int result;
821 TRACE ("%s\n", __PRETTY_FUNCTION__);
822 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
823 "fprintf stream");
824 n = strlen (format);
825 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
826 "fprintf format");
827 va_start (ap, format);
828 result = vfprintf (stream, format, ap);
829 va_end (ap);
830 return result;
834 WRAPPER2(int, sprintf, char *str, const char *format, ...)
836 size_t n;
837 va_list ap;
838 int result;
839 TRACE ("%s\n", __PRETTY_FUNCTION__);
840 MF_VALIDATE_EXTENT (str, 1, __MF_CHECK_WRITE, "sprintf str");
841 n = strlen (format);
842 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
843 "sprintf format");
844 va_start (ap, format);
845 result = vsprintf (str, format, ap);
846 va_end (ap);
847 n = strlen (str);
848 MF_VALIDATE_EXTENT (str, CLAMPADD(n, 1), __MF_CHECK_WRITE, "sprintf str");
849 return result;
853 WRAPPER2(int, snprintf, char *str, size_t size, const char *format, ...)
855 size_t n;
856 va_list ap;
857 int result;
858 TRACE ("%s\n", __PRETTY_FUNCTION__);
859 MF_VALIDATE_EXTENT (str, size, __MF_CHECK_WRITE, "snprintf str");
860 n = strlen (format);
861 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
862 "snprintf format");
863 va_start (ap, format);
864 result = vsnprintf (str, size, format, ap);
865 va_end (ap);
866 return result;
870 WRAPPER2(int, vprintf, const char *format, va_list ap)
872 size_t n;
873 TRACE ("%s\n", __PRETTY_FUNCTION__);
874 n = strlen (format);
875 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
876 "vprintf format");
877 return vprintf (format, ap);
881 WRAPPER2(int, vfprintf, FILE *stream, const char *format, va_list ap)
883 size_t n;
884 TRACE ("%s\n", __PRETTY_FUNCTION__);
885 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
886 "vfprintf stream");
887 n = strlen (format);
888 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
889 "vfprintf format");
890 return vfprintf (stream, format, ap);
894 WRAPPER2(int, vsprintf, char *str, const char *format, va_list ap)
896 size_t n;
897 int result;
898 TRACE ("%s\n", __PRETTY_FUNCTION__);
899 MF_VALIDATE_EXTENT (str, 1, __MF_CHECK_WRITE, "vsprintf str");
900 n = strlen (format);
901 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
902 "vsprintf format");
903 result = vsprintf (str, format, ap);
904 n = strlen (str);
905 MF_VALIDATE_EXTENT (str, CLAMPADD(n, 1), __MF_CHECK_WRITE, "vsprintf str");
906 return result;
910 WRAPPER2(int, vsnprintf, char *str, size_t size, const char *format,
911 va_list ap)
913 size_t n;
914 TRACE ("%s\n", __PRETTY_FUNCTION__);
915 MF_VALIDATE_EXTENT (str, size, __MF_CHECK_WRITE, "vsnprintf str");
916 n = strlen (format);
917 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
918 "vsnprintf format");
919 return vsnprintf (str, size, format, ap);
923 WRAPPER2(int , access, const char *path, int mode)
925 size_t n;
926 TRACE ("%s\n", __PRETTY_FUNCTION__);
927 n = strlen (path);
928 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "access path");
929 return access (path, mode);
933 WRAPPER2(int , remove, const char *path)
935 size_t n;
936 TRACE ("%s\n", __PRETTY_FUNCTION__);
937 n = strlen (path);
938 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "remove path");
939 return remove (path);
943 WRAPPER2(int, fflush, FILE *stream)
945 TRACE ("%s\n", __PRETTY_FUNCTION__);
946 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
947 "fflush stream");
948 return fflush (stream);
952 WRAPPER2(int, fseek, FILE *stream, long offset, int whence)
954 TRACE ("%s\n", __PRETTY_FUNCTION__);
955 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
956 "fseek stream");
957 return fseek (stream, offset, whence);
961 #ifdef HAVE_FSEEKO64
962 WRAPPER2(int, fseeko64, FILE *stream, off64_t offset, int whence)
964 TRACE ("%s\n", __PRETTY_FUNCTION__);
965 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
966 "fseeko64 stream");
967 return fseeko64 (stream, offset, whence);
969 #endif
972 WRAPPER2(long, ftell, FILE *stream)
974 TRACE ("%s\n", __PRETTY_FUNCTION__);
975 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
976 "ftell stream");
977 return ftell (stream);
981 #ifdef HAVE_FTELLO64
982 WRAPPER2(off64_t, ftello64, FILE *stream)
984 TRACE ("%s\n", __PRETTY_FUNCTION__);
985 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
986 "ftello64 stream");
987 return ftello64 (stream);
989 #endif
992 WRAPPER2(void, rewind, FILE *stream)
994 TRACE ("%s\n", __PRETTY_FUNCTION__);
995 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
996 "rewind stream");
997 rewind (stream);
1001 WRAPPER2(int, fgetpos, FILE *stream, fpos_t *pos)
1003 TRACE ("%s\n", __PRETTY_FUNCTION__);
1004 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1005 "fgetpos stream");
1006 MF_VALIDATE_EXTENT (pos, sizeof (*pos), __MF_CHECK_WRITE, "fgetpos pos");
1007 return fgetpos (stream, pos);
1011 WRAPPER2(int, fsetpos, FILE *stream, fpos_t *pos)
1013 TRACE ("%s\n", __PRETTY_FUNCTION__);
1014 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1015 "fsetpos stream");
1016 MF_VALIDATE_EXTENT (pos, sizeof (*pos), __MF_CHECK_READ, "fsetpos pos");
1017 return fsetpos (stream, pos);
1021 WRAPPER2(int , stat, const char *path, struct stat *buf)
1023 size_t n;
1024 TRACE ("%s\n", __PRETTY_FUNCTION__);
1025 n = strlen (path);
1026 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "stat path");
1027 MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ, "stat buf");
1028 return stat (path, buf);
1032 #ifdef HAVE_STAT64
1033 WRAPPER2(int , stat64, const char *path, struct stat64 *buf)
1035 size_t n;
1036 TRACE ("%s\n", __PRETTY_FUNCTION__);
1037 n = strlen (path);
1038 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "stat64 path");
1039 MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ, "stat64 buf");
1040 return stat64 (path, buf);
1042 #endif
1045 WRAPPER2(int , fstat, int filedes, struct stat *buf)
1047 TRACE ("%s\n", __PRETTY_FUNCTION__);
1048 MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ, "fstat buf");
1049 return fstat (filedes, buf);
1053 WRAPPER2(int , lstat, const char *path, struct stat *buf)
1055 size_t n;
1056 TRACE ("%s\n", __PRETTY_FUNCTION__);
1057 n = strlen (path);
1058 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "lstat path");
1059 MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ, "lstat buf");
1060 return lstat (path, buf);
1064 WRAPPER2(int , mkfifo, const char *path, mode_t mode)
1066 size_t n;
1067 TRACE ("%s\n", __PRETTY_FUNCTION__);
1068 n = strlen (path);
1069 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "mkfifo path");
1070 return mkfifo (path, mode);
1074 WRAPPER2(int, setvbuf, FILE *stream, char *buf, int mode , size_t size)
1076 TRACE ("%s\n", __PRETTY_FUNCTION__);
1077 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1078 "setvbuf stream");
1079 if (NULL != buf)
1080 MF_VALIDATE_EXTENT (buf, size, __MF_CHECK_READ, "setvbuf buf");
1081 return setvbuf (stream, buf, mode, size);
1085 WRAPPER2(void, setbuf, FILE *stream, char *buf)
1087 TRACE ("%s\n", __PRETTY_FUNCTION__);
1088 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1089 "setbuf stream");
1090 if (NULL != buf)
1091 MF_VALIDATE_EXTENT (buf, BUFSIZ, __MF_CHECK_READ, "setbuf buf");
1092 setbuf (stream, buf);
1096 #ifdef HAVE_DIRENT_H
1097 WRAPPER2(DIR *, opendir, const char *path)
1099 DIR *p;
1100 size_t n;
1101 TRACE ("%s\n", __PRETTY_FUNCTION__);
1102 n = strlen (path);
1103 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "opendir path");
1105 p = opendir (path);
1106 if (NULL != p) {
1107 #ifdef MF_REGISTER_opendir
1108 __mf_register (p, MF_RESULT_SIZE_opendir, MF_REGISTER_opendir,
1109 "opendir result");
1110 #endif
1111 MF_VALIDATE_EXTENT (p, MF_RESULT_SIZE_opendir, __MF_CHECK_WRITE,
1112 "opendir result");
1114 return p;
1118 WRAPPER2(int, closedir, DIR *dir)
1120 TRACE ("%s\n", __PRETTY_FUNCTION__);
1121 MF_VALIDATE_EXTENT (dir, 0, __MF_CHECK_WRITE, "closedir dir");
1122 #ifdef MF_REGISTER_opendir
1123 __mf_unregister (dir, MF_RESULT_SIZE_opendir, MF_REGISTER_opendir);
1124 #endif
1125 return closedir (dir);
1129 WRAPPER2(struct dirent *, readdir, DIR *dir)
1131 struct dirent *p;
1132 TRACE ("%s\n", __PRETTY_FUNCTION__);
1133 MF_VALIDATE_EXTENT (dir, 0, __MF_CHECK_READ, "readdir dir");
1134 p = readdir (dir);
1135 if (NULL != p) {
1136 #ifdef MF_REGISTER_readdir
1137 __mf_register (p, sizeof (*p), MF_REGISTER_readdir, "readdir result");
1138 #endif
1139 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "readdir result");
1141 return p;
1143 #endif
1146 #ifdef HAVE_SYS_SOCKET_H
1148 WRAPPER2(int, recv, int s, void *buf, size_t len, int flags)
1150 TRACE ("%s\n", __PRETTY_FUNCTION__);
1151 MF_VALIDATE_EXTENT (buf, len, __MF_CHECK_WRITE, "recv buf");
1152 return recv (s, buf, len, flags);
1156 WRAPPER2(int, recvfrom, int s, void *buf, size_t len, int flags,
1157 struct sockaddr *from, socklen_t *fromlen)
1159 TRACE ("%s\n", __PRETTY_FUNCTION__);
1160 MF_VALIDATE_EXTENT (buf, len, __MF_CHECK_WRITE, "recvfrom buf");
1161 MF_VALIDATE_EXTENT (from, (size_t)*fromlen, __MF_CHECK_WRITE,
1162 "recvfrom from");
1163 return recvfrom (s, buf, len, flags, from, fromlen);
1167 WRAPPER2(int, recvmsg, int s, struct msghdr *msg, int flags)
1169 TRACE ("%s\n", __PRETTY_FUNCTION__);
1170 MF_VALIDATE_EXTENT (msg, sizeof (*msg), __MF_CHECK_WRITE, "recvmsg msg");
1171 return recvmsg (s, msg, flags);
1175 WRAPPER2(int, send, int s, const void *msg, size_t len, int flags)
1177 TRACE ("%s\n", __PRETTY_FUNCTION__);
1178 MF_VALIDATE_EXTENT (msg, len, __MF_CHECK_READ, "send msg");
1179 return send (s, msg, len, flags);
1183 WRAPPER2(int, sendto, int s, const void *msg, size_t len, int flags,
1184 const struct sockaddr *to, socklen_t tolen)
1186 TRACE ("%s\n", __PRETTY_FUNCTION__);
1187 MF_VALIDATE_EXTENT (msg, len, __MF_CHECK_READ, "sendto msg");
1188 MF_VALIDATE_EXTENT (to, (size_t)tolen, __MF_CHECK_WRITE, "sendto to");
1189 return sendto (s, msg, len, flags, to, tolen);
1193 WRAPPER2(int, sendmsg, int s, const void *msg, int flags)
1195 TRACE ("%s\n", __PRETTY_FUNCTION__);
1196 MF_VALIDATE_EXTENT (msg, sizeof (*msg), __MF_CHECK_READ, "sendmsg msg");
1197 return sendmsg (s, msg, flags);
1201 WRAPPER2(int, setsockopt, int s, int level, int optname, const void *optval,
1202 socklen_t optlen)
1204 TRACE ("%s\n", __PRETTY_FUNCTION__);
1205 MF_VALIDATE_EXTENT (optval, (size_t)optlen, __MF_CHECK_READ,
1206 "setsockopt optval");
1207 return setsockopt (s, level, optname, optval, optlen);
1211 WRAPPER2(int, getsockopt, int s, int level, int optname, void *optval,
1212 socklen_t *optlen)
1214 TRACE ("%s\n", __PRETTY_FUNCTION__);
1215 MF_VALIDATE_EXTENT (optval, (size_t)*optlen, __MF_CHECK_WRITE,
1216 "getsockopt optval");
1217 return getsockopt (s, level, optname, optval, optlen);
1221 WRAPPER2(int, accept, int s, struct sockaddr *addr, socklen_t *addrlen)
1223 TRACE ("%s\n", __PRETTY_FUNCTION__);
1224 MF_VALIDATE_EXTENT (addr, (size_t)*addrlen, __MF_CHECK_WRITE, "accept addr");
1225 return accept (s, addr, addrlen);
1229 WRAPPER2(int, bind, int sockfd, struct sockaddr *addr, socklen_t addrlen)
1231 TRACE ("%s\n", __PRETTY_FUNCTION__);
1232 MF_VALIDATE_EXTENT (addr, (size_t)addrlen, __MF_CHECK_WRITE, "bind addr");
1233 return bind (sockfd, addr, addrlen);
1237 WRAPPER2(int, connect, int sockfd, const struct sockaddr *addr,
1238 socklen_t addrlen)
1240 TRACE ("%s\n", __PRETTY_FUNCTION__);
1241 MF_VALIDATE_EXTENT (addr, (size_t)addrlen, __MF_CHECK_READ,
1242 "connect addr");
1243 return connect (sockfd, addr, addrlen);
1246 #endif /* HAVE_SYS_SOCKET_H */
1249 WRAPPER2(int, gethostname, char *name, size_t len)
1251 TRACE ("%s\n", __PRETTY_FUNCTION__);
1252 MF_VALIDATE_EXTENT (name, len, __MF_CHECK_WRITE, "gethostname name");
1253 return gethostname (name, len);
1257 #ifdef HAVE_SETHOSTNAME
1258 WRAPPER2(int, sethostname, const char *name, size_t len)
1260 TRACE ("%s\n", __PRETTY_FUNCTION__);
1261 MF_VALIDATE_EXTENT (name, len, __MF_CHECK_READ, "sethostname name");
1262 return sethostname (name, len);
1264 #endif
1267 #ifdef HAVE_NETDB_H
1269 WRAPPER2(struct hostent *, gethostbyname, const char *name)
1271 struct hostent *p;
1272 char **ss;
1273 char *s;
1274 size_t n;
1275 int nreg;
1276 TRACE ("%s\n", __PRETTY_FUNCTION__);
1277 n = strlen (name);
1278 MF_VALIDATE_EXTENT (name, CLAMPADD(n, 1), __MF_CHECK_READ,
1279 "gethostbyname name");
1280 p = gethostbyname (name);
1281 if (NULL != p) {
1282 #ifdef MF_REGISTER_gethostbyname
1283 __mf_register (p, sizeof (*p), MF_REGISTER_gethostbyname,
1284 "gethostbyname result");
1285 #endif
1286 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE,
1287 "gethostbyname result");
1288 if (NULL != (s = p->h_name)) {
1289 n = strlen (s);
1290 n = CLAMPADD(n, 1);
1291 #ifdef MF_REGISTER_gethostbyname_items
1292 __mf_register (s, n, MF_REGISTER_gethostbyname_items,
1293 "gethostbyname result->h_name");
1294 #endif
1295 MF_VALIDATE_EXTENT (s, n, __MF_CHECK_WRITE,
1296 "gethostbyname result->h_name");
1299 if (NULL != (ss = p->h_aliases)) {
1300 for (nreg = 1;; ++nreg) {
1301 s = *ss++;
1302 if (NULL == s)
1303 break;
1304 n = strlen (s);
1305 n = CLAMPADD(n, 1);
1306 #ifdef MF_REGISTER_gethostbyname_items
1307 __mf_register (s, n, MF_REGISTER_gethostbyname_items,
1308 "gethostbyname result->h_aliases[]");
1309 #endif
1310 MF_VALIDATE_EXTENT (s, n, __MF_CHECK_WRITE,
1311 "gethostbyname result->h_aliases[]");
1313 nreg *= sizeof (*p->h_aliases);
1314 #ifdef MF_REGISTER_gethostbyname_items
1315 __mf_register (p->h_aliases, nreg, MF_REGISTER_gethostbyname_items,
1316 "gethostbyname result->h_aliases");
1317 #endif
1318 MF_VALIDATE_EXTENT (p->h_aliases, nreg, __MF_CHECK_WRITE,
1319 "gethostbyname result->h_aliases");
1322 if (NULL != (ss = p->h_addr_list)) {
1323 for (nreg = 1;; ++nreg) {
1324 s = *ss++;
1325 if (NULL == s)
1326 break;
1327 #ifdef MF_REGISTER_gethostbyname_items
1328 __mf_register (s, p->h_length, MF_REGISTER_gethostbyname_items,
1329 "gethostbyname result->h_addr_list[]");
1330 #endif
1331 MF_VALIDATE_EXTENT (s, p->h_length, __MF_CHECK_WRITE,
1332 "gethostbyname result->h_addr_list[]");
1334 nreg *= sizeof (*p->h_addr_list);
1335 #ifdef MF_REGISTER_gethostbyname_items
1336 __mf_register (p->h_addr_list, nreg, MF_REGISTER_gethostbyname_items,
1337 "gethostbyname result->h_addr_list");
1338 #endif
1339 MF_VALIDATE_EXTENT (p->h_addr_list, nreg, __MF_CHECK_WRITE,
1340 "gethostbyname result->h_addr_list");
1343 return p;
1346 #endif /* HAVE_NETDB_H */
1349 #ifdef HAVE_SYS_WAIT_H
1351 WRAPPER2(pid_t, wait, int *status)
1353 TRACE ("%s\n", __PRETTY_FUNCTION__);
1354 if (NULL != status)
1355 MF_VALIDATE_EXTENT (status, sizeof (*status), __MF_CHECK_WRITE,
1356 "wait status");
1357 return wait (status);
1361 WRAPPER2(pid_t, waitpid, pid_t pid, int *status, int options)
1363 TRACE ("%s\n", __PRETTY_FUNCTION__);
1364 if (NULL != status)
1365 MF_VALIDATE_EXTENT (status, sizeof (*status), __MF_CHECK_WRITE,
1366 "waitpid status");
1367 return waitpid (pid, status, options);
1370 #endif /* HAVE_SYS_WAIT_H */
1373 WRAPPER2(FILE *, popen, const char *command, const char *mode)
1375 size_t n;
1376 FILE *p;
1377 TRACE ("%s\n", __PRETTY_FUNCTION__);
1379 n = strlen (command);
1380 MF_VALIDATE_EXTENT (command, CLAMPADD(n, 1), __MF_CHECK_READ, "popen path");
1382 n = strlen (mode);
1383 MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "popen mode");
1385 p = popen (command, mode);
1386 if (NULL != p) {
1387 #ifdef MF_REGISTER_fopen
1388 __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "popen result");
1389 #endif
1390 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "popen result");
1392 return p;
1396 WRAPPER2(int, pclose, FILE *stream)
1398 int resp;
1399 TRACE ("%s\n", __PRETTY_FUNCTION__);
1400 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1401 "pclose stream");
1402 resp = pclose (stream);
1403 #ifdef MF_REGISTER_fopen
1404 __mf_unregister (stream, sizeof (*stream), MF_REGISTER_fopen);
1405 #endif
1406 return resp;
1410 WRAPPER2(int, execve, const char *path, char *const argv [],
1411 char *const envp[])
1413 size_t n;
1414 char *const *p;
1415 const char *s;
1416 TRACE ("%s\n", __PRETTY_FUNCTION__);
1418 n = strlen (path);
1419 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "execve path");
1421 for (p = argv;;) {
1422 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_READ, "execve *argv");
1423 s = *p++;
1424 if (NULL == s)
1425 break;
1426 n = strlen (s);
1427 MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "execve **argv");
1430 for (p = envp;;) {
1431 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_READ, "execve *envp");
1432 s = *p++;
1433 if (NULL == s)
1434 break;
1435 n = strlen (s);
1436 MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "execve **envp");
1438 return execve (path, argv, envp);
1442 WRAPPER2(int, execv, const char *path, char *const argv [])
1444 size_t n;
1445 char *const *p;
1446 const char *s;
1447 TRACE ("%s\n", __PRETTY_FUNCTION__);
1449 n = strlen (path);
1450 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "execv path");
1452 for (p = argv;;) {
1453 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_READ, "execv *argv");
1454 s = *p++;
1455 if (NULL == s)
1456 break;
1457 n = strlen (s);
1458 MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "execv **argv");
1460 return execv (path, argv);
1464 WRAPPER2(int, execvp, const char *path, char *const argv [])
1466 size_t n;
1467 char *const *p;
1468 const char *s;
1469 TRACE ("%s\n", __PRETTY_FUNCTION__);
1471 n = strlen (path);
1472 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "execvp path");
1474 for (p = argv;;) {
1475 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_READ, "execvp *argv");
1476 s = *p++;
1477 if (NULL == s)
1478 break;
1479 n = strlen (s);
1480 MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "execvp **argv");
1482 return execvp (path, argv);
1486 WRAPPER2(int, system, const char *string)
1488 size_t n;
1489 TRACE ("%s\n", __PRETTY_FUNCTION__);
1490 n = strlen (string);
1491 MF_VALIDATE_EXTENT (string, CLAMPADD(n, 1), __MF_CHECK_READ,
1492 "system string");
1493 return system (string);
1497 WRAPPER2(void *, dlopen, const char *path, int flags)
1499 void *p;
1500 size_t n;
1501 TRACE ("%s\n", __PRETTY_FUNCTION__);
1502 n = strlen (path);
1503 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "dlopen path");
1504 p = dlopen (path, flags);
1505 if (NULL != p) {
1506 #ifdef MF_REGISTER_dlopen
1507 __mf_register (p, 0, MF_REGISTER_dlopen, "dlopen result");
1508 #endif
1509 MF_VALIDATE_EXTENT (p, 0, __MF_CHECK_WRITE, "dlopen result");
1511 return p;
1515 WRAPPER2(int, dlclose, void *handle)
1517 int resp;
1518 TRACE ("%s\n", __PRETTY_FUNCTION__);
1519 MF_VALIDATE_EXTENT (handle, 0, __MF_CHECK_READ, "dlclose handle");
1520 resp = dlclose (handle);
1521 #ifdef MF_REGISTER_dlopen
1522 __mf_unregister (handle, 0, MF_REGISTER_dlopen);
1523 #endif
1524 return resp;
1528 WRAPPER2(char *, dlerror)
1530 char *p;
1531 TRACE ("%s\n", __PRETTY_FUNCTION__);
1532 p = dlerror ();
1533 if (NULL != p) {
1534 size_t n;
1535 n = strlen (p);
1536 n = CLAMPADD(n, 1);
1537 #ifdef MF_REGISTER_dlerror
1538 __mf_register (p, n, MF_REGISTER_dlerror, "dlerror result");
1539 #endif
1540 MF_VALIDATE_EXTENT (p, n, __MF_CHECK_WRITE, "dlerror result");
1542 return p;
1546 WRAPPER2(void *, dlsym, void *handle, char *symbol)
1548 size_t n;
1549 void *p;
1550 TRACE ("%s\n", __PRETTY_FUNCTION__);
1551 MF_VALIDATE_EXTENT (handle, 0, __MF_CHECK_READ, "dlsym handle");
1552 n = strlen (symbol);
1553 MF_VALIDATE_EXTENT (symbol, CLAMPADD(n, 1), __MF_CHECK_READ, "dlsym symbol");
1554 p = dlsym (handle, symbol);
1555 if (NULL != p) {
1556 #ifdef MF_REGISTER_dlsym
1557 __mf_register (p, 0, MF_REGISTER_dlsym, "dlsym result");
1558 #endif
1559 MF_VALIDATE_EXTENT (p, 0, __MF_CHECK_WRITE, "dlsym result");
1561 return p;
1565 #if defined (HAVE_SYS_IPC_H) && defined (HAVE_SYS_SEM_H) && defined (HAVE_SYS_SHM_H)
1567 WRAPPER2(int, semop, int semid, struct sembuf *sops, unsigned nsops)
1569 TRACE ("%s\n", __PRETTY_FUNCTION__);
1570 MF_VALIDATE_EXTENT (sops, sizeof (*sops) * nsops, __MF_CHECK_READ,
1571 "semop sops");
1572 return semop (semid, sops, nsops);
1576 #ifndef HAVE_UNION_SEMUN
1577 union semun {
1578 int val; /* value for SETVAL */
1579 struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */
1580 unsigned short int *array; /* array for GETALL, SETALL */
1581 struct seminfo *__buf; /* buffer for IPC_INFO */
1583 #endif
1584 WRAPPER2(int, semctl, int semid, int semnum, int cmd, union semun arg)
1586 TRACE ("%s\n", __PRETTY_FUNCTION__);
1587 switch (cmd) {
1588 case IPC_STAT:
1589 MF_VALIDATE_EXTENT (arg.buf, sizeof (*arg.buf), __MF_CHECK_WRITE,
1590 "semctl buf");
1591 break;
1592 case IPC_SET:
1593 MF_VALIDATE_EXTENT (arg.buf, sizeof (*arg.buf), __MF_CHECK_READ,
1594 "semctl buf");
1595 break;
1596 case GETALL:
1597 MF_VALIDATE_EXTENT (arg.array, sizeof (*arg.array), __MF_CHECK_WRITE,
1598 "semctl array");
1599 case SETALL:
1600 MF_VALIDATE_EXTENT (arg.array, sizeof (*arg.array), __MF_CHECK_READ,
1601 "semctl array");
1602 break;
1603 #ifdef IPC_INFO
1604 /* FreeBSD 5.1 And Cygwin headers include IPC_INFO but not the __buf field. */
1605 #if !defined(__FreeBSD__) && !defined(__CYGWIN__)
1606 case IPC_INFO:
1607 MF_VALIDATE_EXTENT (arg.__buf, sizeof (*arg.__buf), __MF_CHECK_WRITE,
1608 "semctl __buf");
1609 break;
1610 #endif
1611 #endif
1612 default:
1613 break;
1615 return semctl (semid, semnum, cmd, arg);
1619 WRAPPER2(int, shmctl, int shmid, int cmd, struct shmid_ds *buf)
1621 TRACE ("%s\n", __PRETTY_FUNCTION__);
1622 switch (cmd) {
1623 case IPC_STAT:
1624 MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_WRITE,
1625 "shmctl buf");
1626 break;
1627 case IPC_SET:
1628 MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ,
1629 "shmctl buf");
1630 break;
1631 default:
1632 break;
1634 return shmctl (shmid, cmd, buf);
1638 WRAPPER2(void *, shmat, int shmid, const void *shmaddr, int shmflg)
1640 void *p;
1641 TRACE ("%s\n", __PRETTY_FUNCTION__);
1642 p = shmat (shmid, shmaddr, shmflg);
1643 #ifdef MF_REGISTER_shmat
1644 if (NULL != p) {
1645 struct shmid_ds buf;
1646 __mf_register (p, shmctl (shmid, IPC_STAT, &buf) ? 0 : buf.shm_segsz,
1647 MF_REGISTER_shmat, "shmat result");
1649 #endif
1650 return p;
1654 WRAPPER2(int, shmdt, const void *shmaddr)
1656 int resp;
1657 TRACE ("%s\n", __PRETTY_FUNCTION__);
1658 resp = shmdt (shmaddr);
1659 #ifdef MF_REGISTER_shmat
1660 __mf_unregister ((void *)shmaddr, 0, MF_REGISTER_shmat);
1661 #endif
1662 return resp;
1666 #endif /* HAVE_SYS_IPC/SEM/SHM_H */
1670 /* ctype stuff. This is host-specific by necessity, as the arrays
1671 that is used by most is*()/to*() macros are implementation-defined. */
1673 /* GLIBC 2.3 */
1674 #ifdef HAVE___CTYPE_B_LOC
1675 WRAPPER2(unsigned short **, __ctype_b_loc, void)
1677 static unsigned short * last_buf = (void *) 0;
1678 static unsigned short ** last_ptr = (void *) 0;
1679 unsigned short ** ptr = (unsigned short **) __ctype_b_loc ();
1680 unsigned short * buf = * ptr;
1681 if (ptr != last_ptr)
1683 /* XXX: unregister last_ptr? */
1684 last_ptr = ptr;
1685 __mf_register (last_ptr, sizeof(last_ptr), __MF_TYPE_STATIC, "ctype_b_loc **");
1687 if (buf != last_buf)
1689 last_buf = buf;
1690 __mf_register ((void *) (last_buf - 128), 384 * sizeof(unsigned short), __MF_TYPE_STATIC,
1691 "ctype_b_loc []");
1693 return ptr;
1695 #endif
1697 #ifdef HAVE___CTYPE_TOUPPER_LOC
1698 WRAPPER2(int **, __ctype_toupper_loc, void)
1700 static int * last_buf = (void *) 0;
1701 static int ** last_ptr = (void *) 0;
1702 int ** ptr = (int **) __ctype_toupper_loc ();
1703 int * buf = * ptr;
1704 if (ptr != last_ptr)
1706 /* XXX: unregister last_ptr? */
1707 last_ptr = ptr;
1708 __mf_register (last_ptr, sizeof(last_ptr), __MF_TYPE_STATIC, "ctype_toupper_loc **");
1710 if (buf != last_buf)
1712 last_buf = buf;
1713 __mf_register ((void *) (last_buf - 128), 384 * sizeof(int), __MF_TYPE_STATIC,
1714 "ctype_toupper_loc []");
1716 return ptr;
1718 #endif
1720 #ifdef HAVE___CTYPE_TOLOWER_LOC
1721 WRAPPER2(int **, __ctype_tolower_loc, void)
1723 static int * last_buf = (void *) 0;
1724 static int ** last_ptr = (void *) 0;
1725 int ** ptr = (int **) __ctype_tolower_loc ();
1726 int * buf = * ptr;
1727 if (ptr != last_ptr)
1729 /* XXX: unregister last_ptr? */
1730 last_ptr = ptr;
1731 __mf_register (last_ptr, sizeof(last_ptr), __MF_TYPE_STATIC, "ctype_tolower_loc **");
1733 if (buf != last_buf)
1735 last_buf = buf;
1736 __mf_register ((void *) (last_buf - 128), 384 * sizeof(int), __MF_TYPE_STATIC,
1737 "ctype_tolower_loc []");
1739 return ptr;
1741 #endif
1744 /* passwd/group related functions. These register every (static) pointer value returned,
1745 and rely on libmudflap's quiet toleration of duplicate static registrations. */
1747 #ifdef HAVE_GETLOGIN
1748 WRAPPER2(char *, getlogin, void)
1750 char *buf = getlogin ();
1751 if (buf != NULL)
1752 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
1753 "getlogin() return");
1754 return buf;
1756 #endif
1759 #ifdef HAVE_CUSERID
1760 WRAPPER2(char *, cuserid, char * buf)
1762 if (buf != NULL)
1764 MF_VALIDATE_EXTENT(buf, L_cuserid, __MF_CHECK_WRITE,
1765 "cuserid destination");
1766 return cuserid (buf);
1768 buf = cuserid (NULL);
1769 if (buf != NULL)
1770 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
1771 "getcuserid() return");
1772 return buf;
1774 #endif
1777 #ifdef HAVE_GETPWNAM
1778 WRAPPER2(struct passwd *, getpwnam, const char *name)
1780 struct passwd *buf;
1781 MF_VALIDATE_EXTENT(name, strlen(name)+1, __MF_CHECK_READ,
1782 "getpwnam name");
1783 buf = getpwnam (name);
1784 if (buf != NULL)
1785 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
1786 "getpw*() return");
1787 return buf;
1789 #endif
1792 #ifdef HAVE_GETPWUID
1793 WRAPPER2(struct passwd *, getpwuid, uid_t uid)
1795 struct passwd *buf;
1796 buf = getpwuid (uid);
1797 if (buf != NULL)
1798 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
1799 "getpw*() return");
1800 return buf;
1802 #endif
1805 #ifdef HAVE_GETGRNAM
1806 WRAPPER2(struct group *, getgrnam, const char *name)
1808 struct group *buf;
1809 MF_VALIDATE_EXTENT(name, strlen(name)+1, __MF_CHECK_READ,
1810 "getgrnam name");
1811 buf = getgrnam (name);
1812 if (buf != NULL)
1813 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
1814 "getgr*() return");
1815 return buf;
1817 #endif
1820 #ifdef HAVE_GETGRGID
1821 WRAPPER2(struct group *, getgrgid, uid_t uid)
1823 struct group *buf;
1824 buf = getgrgid (uid);
1825 if (buf != NULL)
1826 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
1827 "getgr*() return");
1828 return buf;
1830 #endif
1833 #ifdef HAVE_GETSERVENT
1834 WRAPPER2(struct servent *, getservent, void)
1836 struct servent *buf;
1837 buf = getservent ();
1838 if (buf != NULL)
1839 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
1840 "getserv*() return");
1841 return buf;
1843 #endif
1846 #ifdef HAVE_GETSERVBYNAME
1847 WRAPPER2(struct servent *, getservbyname, const char *name, const char *proto)
1849 struct servent *buf;
1850 MF_VALIDATE_EXTENT(name, strlen(name)+1, __MF_CHECK_READ,
1851 "getservbyname name");
1852 MF_VALIDATE_EXTENT(proto, strlen(proto)+1, __MF_CHECK_READ,
1853 "getservbyname proto");
1854 buf = getservbyname (name, proto);
1855 if (buf != NULL)
1856 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
1857 "getserv*() return");
1858 return buf;
1860 #endif
1863 #ifdef HAVE_GETSERVBYPORT
1864 WRAPPER2(struct servent *, getservbyport, int port, const char *proto)
1866 struct servent *buf;
1867 MF_VALIDATE_EXTENT(proto, strlen(proto)+1, __MF_CHECK_READ,
1868 "getservbyport proto");
1869 buf = getservbyport (port, proto);
1870 if (buf != NULL)
1871 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
1872 "getserv*() return");
1873 return buf;
1875 #endif
1878 #ifdef HAVE_GAI_STRERROR
1879 WRAPPER2(const char *, gai_strerror, int errcode)
1881 const char *buf;
1882 buf = gai_strerror (errcode);
1883 if (buf != NULL)
1884 __mf_register ((void *) buf, strlen(buf)+1, __MF_TYPE_STATIC,
1885 "gai_strerror() return");
1886 return buf;
1888 #endif
1891 #ifdef HAVE_GETMNTENT
1892 WRAPPER2(struct mntent *, getmntent, FILE *filep)
1894 struct mntent *m;
1895 static struct mntent *last = NULL;
1897 MF_VALIDATE_EXTENT (filep, sizeof (*filep), __MF_CHECK_WRITE,
1898 "getmntent stream");
1899 #define UR(field) __mf_unregister(last->field, strlen (last->field)+1, __MF_TYPE_STATIC)
1900 if (last)
1902 UR (mnt_fsname);
1903 UR (mnt_dir);
1904 UR (mnt_type);
1905 UR (mnt_opts);
1906 __mf_unregister (last, sizeof (*last), __MF_TYPE_STATIC);
1908 #undef UR
1910 m = getmntent (filep);
1911 last = m;
1913 #define R(field) __mf_register(last->field, strlen (last->field)+1, __MF_TYPE_STATIC, "mntent " #field)
1914 if (m)
1916 R (mnt_fsname);
1917 R (mnt_dir);
1918 R (mnt_type);
1919 R (mnt_opts);
1920 __mf_register (last, sizeof (*last), __MF_TYPE_STATIC, "getmntent result");
1922 #undef R
1924 return m;
1926 #endif
1929 #ifdef HAVE_INET_NTOA
1930 WRAPPER2(char *, inet_ntoa, struct in_addr in)
1932 static char *last_buf = NULL;
1933 char *buf;
1934 if (last_buf)
1935 __mf_unregister (last_buf, strlen (last_buf)+1, __MF_TYPE_STATIC);
1936 buf = inet_ntoa (in);
1937 last_buf = buf;
1938 if (buf)
1939 __mf_register (last_buf, strlen (last_buf)+1, __MF_TYPE_STATIC, "inet_ntoa result");
1940 return buf;
1942 #endif
1945 #ifdef HAVE_GETPROTOENT
1946 WRAPPER2(struct protoent *, getprotoent, void)
1948 struct protoent *buf;
1949 buf = getprotoent ();
1950 if (buf != NULL)
1951 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC, "getproto*() return");
1952 return buf;
1954 #endif
1957 #ifdef HAVE_GETPROTOBYNAME
1958 WRAPPER2(struct protoent *, getprotobyname, const char *name)
1960 struct protoent *buf;
1961 MF_VALIDATE_EXTENT(name, strlen(name)+1, __MF_CHECK_READ,
1962 "getprotobyname name");
1963 buf = getprotobyname (name);
1964 if (buf != NULL)
1965 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
1966 "getproto*() return");
1967 return buf;
1969 #endif
1972 #ifdef HAVE_GETPROTOBYNUMBER
1973 WRAPPER2(struct protoent *, getprotobynumber, int port)
1975 struct protoent *buf;
1976 buf = getprotobynumber (port);
1977 if (buf != NULL)
1978 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
1979 "getproto*() return");
1980 return buf;
1982 #endif