PR rtl-optimization/15187
[official-gcc.git] / libmudflap / mf-hooks2.c
blob640b78e6be8d2808e0a8cb81116b41671664435a
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
87 #ifdef HAVE_PWD_H
88 #include <pwd.h>
89 #endif
90 #ifdef HAVE_GRP_H
91 #include <grp.h>
92 #endif
94 #include "mf-runtime.h"
95 #include "mf-impl.h"
97 #ifdef _MUDFLAP
98 #error "Do not compile this file with -fmudflap!"
99 #endif
102 /* A bunch of independent stdlib/unistd hook functions, all
103 intercepted by mf-runtime.h macros. */
105 #ifndef HAVE_STRNLEN
106 static inline size_t (strnlen) (const char* str, size_t n)
108 const char *s;
110 for (s = str; n && *s; ++s, --n)
112 return (s - str);
114 #endif
117 /* str*,mem*,b* */
119 WRAPPER2(void *, memcpy, void *dest, const void *src, size_t n)
121 TRACE ("%s\n", __PRETTY_FUNCTION__);
122 MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "memcpy source");
123 MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "memcpy dest");
124 return memcpy (dest, src, n);
128 WRAPPER2(void *, memmove, void *dest, const void *src, size_t n)
130 TRACE ("%s\n", __PRETTY_FUNCTION__);
131 MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "memmove src");
132 MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "memmove dest");
133 return memmove (dest, src, n);
137 WRAPPER2(void *, memset, void *s, int c, size_t n)
139 TRACE ("%s\n", __PRETTY_FUNCTION__);
140 MF_VALIDATE_EXTENT(s, n, __MF_CHECK_WRITE, "memset dest");
141 return memset (s, c, n);
145 WRAPPER2(int, memcmp, const void *s1, const void *s2, size_t n)
147 TRACE ("%s\n", __PRETTY_FUNCTION__);
148 MF_VALIDATE_EXTENT(s1, n, __MF_CHECK_READ, "memcmp 1st arg");
149 MF_VALIDATE_EXTENT(s2, n, __MF_CHECK_READ, "memcmp 2nd arg");
150 return memcmp (s1, s2, n);
154 WRAPPER2(void *, memchr, const void *s, int c, size_t n)
156 TRACE ("%s\n", __PRETTY_FUNCTION__);
157 MF_VALIDATE_EXTENT(s, n, __MF_CHECK_READ, "memchr region");
158 return memchr (s, c, n);
162 #ifdef HAVE_MEMRCHR
163 WRAPPER2(void *, memrchr, const void *s, int c, size_t n)
165 TRACE ("%s\n", __PRETTY_FUNCTION__);
166 MF_VALIDATE_EXTENT(s, n, __MF_CHECK_READ, "memrchr region");
167 return memrchr (s, c, n);
169 #endif
172 WRAPPER2(char *, strcpy, char *dest, const char *src)
174 /* nb: just because strlen(src) == n doesn't mean (src + n) or (src + n +
175 1) are valid pointers. the allocated object might have size < n.
176 check anyways. */
178 size_t n = strlen (src);
179 TRACE ("%s\n", __PRETTY_FUNCTION__);
180 MF_VALIDATE_EXTENT(src, CLAMPADD(n, 1), __MF_CHECK_READ, "strcpy src");
181 MF_VALIDATE_EXTENT(dest, CLAMPADD(n, 1), __MF_CHECK_WRITE, "strcpy dest");
182 return strcpy (dest, src);
186 #ifdef HAVE_STRNCPY
187 WRAPPER2(char *, strncpy, char *dest, const char *src, size_t n)
189 size_t len = strnlen (src, n);
190 TRACE ("%s\n", __PRETTY_FUNCTION__);
191 MF_VALIDATE_EXTENT(src, len, __MF_CHECK_READ, "strncpy src");
192 MF_VALIDATE_EXTENT(dest, len, __MF_CHECK_WRITE, "strncpy dest"); /* nb: strNcpy */
193 return strncpy (dest, src, n);
195 #endif
198 WRAPPER2(char *, strcat, char *dest, const char *src)
200 size_t dest_sz;
201 size_t src_sz;
202 TRACE ("%s\n", __PRETTY_FUNCTION__);
203 dest_sz = strlen (dest);
204 src_sz = strlen (src);
205 MF_VALIDATE_EXTENT(src, CLAMPADD(src_sz, 1), __MF_CHECK_READ, "strcat src");
206 MF_VALIDATE_EXTENT(dest, CLAMPADD(dest_sz, CLAMPADD(src_sz, 1)),
207 __MF_CHECK_WRITE, "strcat dest");
208 return strcat (dest, src);
212 WRAPPER2(char *, strncat, char *dest, const char *src, size_t n)
215 /* nb: validating the extents (s,n) might be a mistake for two reasons.
217 (1) the string s might be shorter than n chars, and n is just a
218 poor choice by the programmer. this is not a "true" error in the
219 sense that the call to strncat would still be ok.
221 (2) we could try to compensate for case (1) by calling strlen(s) and
222 using that as a bound for the extent to verify, but strlen might fall off
223 the end of a non-terminated string, leading to a false positive.
225 so we will call strnlen(s,n) and use that as a bound.
227 if strnlen returns a length beyond the end of the registered extent
228 associated with s, there is an error: the programmer's estimate for n is
229 too large _AND_ the string s is unterminated, in which case they'd be
230 about to touch memory they don't own while calling strncat.
232 this same logic applies to further uses of strnlen later down in this
233 file. */
235 size_t src_sz;
236 size_t dest_sz;
237 TRACE ("%s\n", __PRETTY_FUNCTION__);
238 src_sz = strnlen (src, n);
239 dest_sz = strnlen (dest, n);
240 MF_VALIDATE_EXTENT(src, src_sz, __MF_CHECK_READ, "strncat src");
241 MF_VALIDATE_EXTENT(dest, (CLAMPADD(dest_sz, CLAMPADD(src_sz, 1))),
242 __MF_CHECK_WRITE, "strncat dest");
243 return strncat (dest, src, n);
247 WRAPPER2(int, strcmp, const char *s1, const char *s2)
249 size_t s1_sz;
250 size_t s2_sz;
251 TRACE ("%s\n", __PRETTY_FUNCTION__);
252 s1_sz = strlen (s1);
253 s2_sz = strlen (s2);
254 MF_VALIDATE_EXTENT(s1, CLAMPADD(s1_sz, 1), __MF_CHECK_READ, "strcmp 1st arg");
255 MF_VALIDATE_EXTENT(s2, CLAMPADD(s2_sz, 1), __MF_CHECK_WRITE, "strcmp 2nd arg");
256 return strcmp (s1, s2);
260 WRAPPER2(int, strcasecmp, const char *s1, const char *s2)
262 size_t s1_sz;
263 size_t s2_sz;
264 TRACE ("%s\n", __PRETTY_FUNCTION__);
265 s1_sz = strlen (s1);
266 s2_sz = strlen (s2);
267 MF_VALIDATE_EXTENT(s1, CLAMPADD(s1_sz, 1), __MF_CHECK_READ, "strcasecmp 1st arg");
268 MF_VALIDATE_EXTENT(s2, CLAMPADD(s2_sz, 1), __MF_CHECK_READ, "strcasecmp 2nd arg");
269 return strcasecmp (s1, s2);
273 WRAPPER2(int, strncmp, const char *s1, const char *s2, size_t n)
275 size_t s1_sz;
276 size_t s2_sz;
277 TRACE ("%s\n", __PRETTY_FUNCTION__);
278 s1_sz = strnlen (s1, n);
279 s2_sz = strnlen (s2, n);
280 MF_VALIDATE_EXTENT(s1, s1_sz, __MF_CHECK_READ, "strncmp 1st arg");
281 MF_VALIDATE_EXTENT(s2, s2_sz, __MF_CHECK_READ, "strncmp 2nd arg");
282 return strncmp (s1, s2, n);
286 WRAPPER2(int, strncasecmp, const char *s1, const char *s2, size_t n)
288 size_t s1_sz;
289 size_t s2_sz;
290 TRACE ("%s\n", __PRETTY_FUNCTION__);
291 s1_sz = strnlen (s1, n);
292 s2_sz = strnlen (s2, n);
293 MF_VALIDATE_EXTENT(s1, s1_sz, __MF_CHECK_READ, "strncasecmp 1st arg");
294 MF_VALIDATE_EXTENT(s2, s2_sz, __MF_CHECK_READ, "strncasecmp 2nd arg");
295 return strncasecmp (s1, s2, n);
299 WRAPPER2(char *, strdup, const char *s)
301 DECLARE(void *, malloc, size_t sz);
302 char *result;
303 size_t n = strlen (s);
304 TRACE ("%s\n", __PRETTY_FUNCTION__);
305 MF_VALIDATE_EXTENT(s, CLAMPADD(n,1), __MF_CHECK_READ, "strdup region");
306 result = (char *)CALL_REAL(malloc,
307 CLAMPADD(CLAMPADD(n,1),
308 CLAMPADD(__mf_opts.crumple_zone,
309 __mf_opts.crumple_zone)));
311 if (UNLIKELY(! result)) return result;
313 result += __mf_opts.crumple_zone;
314 memcpy (result, s, n);
315 result[n] = '\0';
317 __mf_register (result, CLAMPADD(n,1), __MF_TYPE_HEAP_I, "strdup region");
318 return result;
322 WRAPPER2(char *, strndup, const char *s, size_t n)
324 DECLARE(void *, malloc, size_t sz);
325 char *result;
326 size_t sz = strnlen (s, n);
327 TRACE ("%s\n", __PRETTY_FUNCTION__);
328 MF_VALIDATE_EXTENT(s, sz, __MF_CHECK_READ, "strndup region"); /* nb: strNdup */
330 /* note: strndup still adds a \0, even with the N limit! */
331 result = (char *)CALL_REAL(malloc,
332 CLAMPADD(CLAMPADD(n,1),
333 CLAMPADD(__mf_opts.crumple_zone,
334 __mf_opts.crumple_zone)));
336 if (UNLIKELY(! result)) return result;
338 result += __mf_opts.crumple_zone;
339 memcpy (result, s, n);
340 result[n] = '\0';
342 __mf_register (result, CLAMPADD(n,1), __MF_TYPE_HEAP_I, "strndup region");
343 return result;
347 WRAPPER2(char *, strchr, const char *s, int c)
349 size_t n;
350 TRACE ("%s\n", __PRETTY_FUNCTION__);
351 n = strlen (s);
352 MF_VALIDATE_EXTENT(s, CLAMPADD(n,1), __MF_CHECK_READ, "strchr region");
353 return strchr (s, c);
357 WRAPPER2(char *, strrchr, const char *s, int c)
359 size_t n;
360 TRACE ("%s\n", __PRETTY_FUNCTION__);
361 n = strlen (s);
362 MF_VALIDATE_EXTENT(s, CLAMPADD(n,1), __MF_CHECK_READ, "strrchr region");
363 return strrchr (s, c);
367 WRAPPER2(char *, strstr, const char *haystack, const char *needle)
369 size_t haystack_sz;
370 size_t needle_sz;
371 TRACE ("%s\n", __PRETTY_FUNCTION__);
372 haystack_sz = strlen (haystack);
373 needle_sz = strlen (needle);
374 MF_VALIDATE_EXTENT(haystack, CLAMPADD(haystack_sz, 1), __MF_CHECK_READ, "strstr haystack");
375 MF_VALIDATE_EXTENT(needle, CLAMPADD(needle_sz, 1), __MF_CHECK_READ, "strstr needle");
376 return strstr (haystack, needle);
380 #ifdef HAVE_MEMMEM
381 WRAPPER2(void *, memmem,
382 const void *haystack, size_t haystacklen,
383 const void *needle, size_t needlelen)
385 TRACE ("%s\n", __PRETTY_FUNCTION__);
386 MF_VALIDATE_EXTENT(haystack, haystacklen, __MF_CHECK_READ, "memmem haystack");
387 MF_VALIDATE_EXTENT(needle, needlelen, __MF_CHECK_READ, "memmem needle");
388 return memmem (haystack, haystacklen, needle, needlelen);
390 #endif
393 WRAPPER2(size_t, strlen, const char *s)
395 size_t result = strlen (s);
396 TRACE ("%s\n", __PRETTY_FUNCTION__);
397 MF_VALIDATE_EXTENT(s, CLAMPADD(result, 1), __MF_CHECK_READ, "strlen region");
398 return result;
402 WRAPPER2(size_t, strnlen, const char *s, size_t n)
404 size_t result = strnlen (s, n);
405 TRACE ("%s\n", __PRETTY_FUNCTION__);
406 MF_VALIDATE_EXTENT(s, result, __MF_CHECK_READ, "strnlen region");
407 return result;
411 WRAPPER2(void, bzero, void *s, size_t n)
413 TRACE ("%s\n", __PRETTY_FUNCTION__);
414 MF_VALIDATE_EXTENT(s, n, __MF_CHECK_WRITE, "bzero region");
415 bzero (s, n);
419 #undef bcopy
420 WRAPPER2(void, bcopy, const void *src, void *dest, size_t n)
422 TRACE ("%s\n", __PRETTY_FUNCTION__);
423 MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "bcopy src");
424 MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "bcopy dest");
425 bcopy (src, dest, n);
429 #undef bcmp
430 WRAPPER2(int, bcmp, const void *s1, const void *s2, size_t n)
432 TRACE ("%s\n", __PRETTY_FUNCTION__);
433 MF_VALIDATE_EXTENT(s1, n, __MF_CHECK_READ, "bcmp 1st arg");
434 MF_VALIDATE_EXTENT(s2, n, __MF_CHECK_READ, "bcmp 2nd arg");
435 return bcmp (s1, s2, n);
439 WRAPPER2(char *, index, const char *s, int c)
441 size_t n = strlen (s);
442 TRACE ("%s\n", __PRETTY_FUNCTION__);
443 MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "index region");
444 return index (s, c);
448 WRAPPER2(char *, rindex, const char *s, int c)
450 size_t n = strlen (s);
451 TRACE ("%s\n", __PRETTY_FUNCTION__);
452 MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "rindex region");
453 return rindex (s, c);
456 /* XXX: stpcpy, memccpy */
458 /* XXX: *printf,*scanf */
460 /* XXX: setjmp, longjmp */
462 WRAPPER2(char *, asctime, struct tm *tm)
464 static char *reg_result = NULL;
465 char *result;
466 TRACE ("%s\n", __PRETTY_FUNCTION__);
467 MF_VALIDATE_EXTENT(tm, sizeof (struct tm), __MF_CHECK_READ, "asctime tm");
468 result = asctime (tm);
469 if (reg_result == NULL)
471 __mf_register (result, strlen (result)+1, __MF_TYPE_STATIC, "asctime string");
472 reg_result = result;
474 return result;
478 WRAPPER2(char *, ctime, const time_t *timep)
480 static char *reg_result = NULL;
481 char *result;
482 TRACE ("%s\n", __PRETTY_FUNCTION__);
483 MF_VALIDATE_EXTENT(timep, sizeof (time_t), __MF_CHECK_READ, "ctime time");
484 result = ctime (timep);
485 if (reg_result == NULL)
487 /* XXX: what if asctime and ctime return the same static ptr? */
488 __mf_register (result, strlen (result)+1, __MF_TYPE_STATIC, "ctime string");
489 reg_result = result;
491 return result;
495 WRAPPER2(struct tm*, localtime, const time_t *timep)
497 static struct tm *reg_result = NULL;
498 struct tm *result;
499 TRACE ("%s\n", __PRETTY_FUNCTION__);
500 MF_VALIDATE_EXTENT(timep, sizeof (time_t), __MF_CHECK_READ, "localtime time");
501 result = localtime (timep);
502 if (reg_result == NULL)
504 __mf_register (result, sizeof (struct tm), __MF_TYPE_STATIC, "localtime tm");
505 reg_result = result;
507 return result;
511 WRAPPER2(struct tm*, gmtime, const time_t *timep)
513 static struct tm *reg_result = NULL;
514 struct tm *result;
515 TRACE ("%s\n", __PRETTY_FUNCTION__);
516 MF_VALIDATE_EXTENT(timep, sizeof (time_t), __MF_CHECK_READ, "gmtime time");
517 result = gmtime (timep);
518 if (reg_result == NULL)
520 __mf_register (result, sizeof (struct tm), __MF_TYPE_STATIC, "gmtime tm");
521 reg_result = result;
523 return result;
527 /* EL start */
529 /* The following indicate if the result of the corresponding function
530 * should be explicitly un/registered by the wrapper
532 #undef MF_REGISTER_fopen
533 #define MF_RESULT_SIZE_fopen (sizeof (FILE))
534 #undef MF_REGISTER_opendir
535 #define MF_RESULT_SIZE_opendir 0 /* (sizeof (DIR)) */
536 #undef MF_REGISTER_readdir
537 #define MF_REGISTER_gethostbyname __MF_TYPE_STATIC
538 #undef MF_REGISTER_gethostbyname_items
539 #undef MF_REGISTER_dlopen
540 #undef MF_REGISTER_dlerror
541 #undef MF_REGISTER_dlsym
542 #define MF_REGISTER_shmat __MF_TYPE_GUESS
545 #include <time.h>
546 WRAPPER2(time_t, time, time_t *timep)
548 TRACE ("%s\n", __PRETTY_FUNCTION__);
549 if (NULL != timep)
550 MF_VALIDATE_EXTENT (timep, sizeof (*timep), __MF_CHECK_WRITE,
551 "time timep");
552 return time (timep);
556 WRAPPER2(char *, strerror, int errnum)
558 char *p;
559 static char * last_strerror = NULL;
561 TRACE ("%s\n", __PRETTY_FUNCTION__);
562 p = strerror (errnum);
563 if (last_strerror != NULL)
564 __mf_unregister (last_strerror, 0, __MF_TYPE_STATIC);
565 if (NULL != p)
566 __mf_register (p, strlen (p) + 1, __MF_TYPE_STATIC, "strerror result");
567 last_strerror = p;
568 return p;
572 WRAPPER2(FILE *, fopen, const char *path, const char *mode)
574 size_t n;
575 FILE *p;
576 TRACE ("%s\n", __PRETTY_FUNCTION__);
578 n = strlen (path);
579 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "fopen path");
581 n = strlen (mode);
582 MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "fopen mode");
584 p = fopen (path, mode);
585 if (NULL != p) {
586 #ifdef MF_REGISTER_fopen
587 __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "fopen result");
588 #endif
589 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "fopen result");
592 return p;
596 #ifdef HAVE_FOPEN64
597 WRAPPER2(FILE *, fopen64, const char *path, const char *mode)
599 size_t n;
600 FILE *p;
601 TRACE ("%s\n", __PRETTY_FUNCTION__);
603 n = strlen (path);
604 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "fopen64 path");
606 n = strlen (mode);
607 MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "fopen64 mode");
609 p = fopen64 (path, mode);
610 if (NULL != p) {
611 #ifdef MF_REGISTER_fopen
612 __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "fopen64 result");
613 #endif
614 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "fopen64 result");
617 return p;
619 #endif
622 WRAPPER2(int, fclose, FILE *stream)
624 int resp;
625 TRACE ("%s\n", __PRETTY_FUNCTION__);
626 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
627 "fclose stream");
628 resp = fclose (stream);
629 #ifdef MF_REGISTER_fopen
630 __mf_unregister (stream, sizeof (*stream), MF_REGISTER_fopen);
631 #endif
633 return resp;
637 WRAPPER2(size_t, fread, void *ptr, size_t size, size_t nmemb, FILE *stream)
639 TRACE ("%s\n", __PRETTY_FUNCTION__);
640 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
641 "fread stream");
642 MF_VALIDATE_EXTENT (ptr, size * nmemb, __MF_CHECK_WRITE, "fread buffer");
643 return fread (ptr, size, nmemb, stream);
647 WRAPPER2(size_t, fwrite, const void *ptr, size_t size, size_t nmemb,
648 FILE *stream)
650 TRACE ("%s\n", __PRETTY_FUNCTION__);
651 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
652 "fwrite stream");
653 MF_VALIDATE_EXTENT (ptr, size * nmemb, __MF_CHECK_READ, "fwrite buffer");
654 return fwrite (ptr, size, nmemb, stream);
658 WRAPPER2(int, fgetc, FILE *stream)
660 TRACE ("%s\n", __PRETTY_FUNCTION__);
661 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
662 "fgetc stream");
663 return fgetc (stream);
667 WRAPPER2(char *, fgets, char *s, int size, FILE *stream)
669 TRACE ("%s\n", __PRETTY_FUNCTION__);
670 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
671 "fgets stream");
672 MF_VALIDATE_EXTENT (s, size, __MF_CHECK_WRITE, "fgets buffer");
673 return fgets (s, size, stream);
677 WRAPPER2(int, getc, FILE *stream)
679 TRACE ("%s\n", __PRETTY_FUNCTION__);
680 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
681 "getc stream");
682 return getc (stream);
686 WRAPPER2(char *, gets, char *s)
688 TRACE ("%s\n", __PRETTY_FUNCTION__);
689 MF_VALIDATE_EXTENT (s, 1, __MF_CHECK_WRITE, "gets buffer");
690 /* Avoid link-time warning... */
691 s = fgets (s, INT_MAX, stdin);
692 if (NULL != s) { /* better late than never */
693 size_t n = strlen (s);
694 MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_WRITE, "gets buffer");
696 return s;
700 WRAPPER2(int, ungetc, int c, FILE *stream)
702 TRACE ("%s\n", __PRETTY_FUNCTION__);
703 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
704 "ungetc stream");
705 return ungetc (c, stream);
709 WRAPPER2(int, fputc, int c, FILE *stream)
711 TRACE ("%s\n", __PRETTY_FUNCTION__);
712 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
713 "fputc stream");
714 return fputc (c, stream);
718 WRAPPER2(int, fputs, const char *s, FILE *stream)
720 size_t n;
721 TRACE ("%s\n", __PRETTY_FUNCTION__);
722 n = strlen (s);
723 MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "fputs buffer");
724 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
725 "fputs stream");
726 return fputs (s, stream);
730 WRAPPER2(int, putc, int c, FILE *stream)
732 TRACE ("%s\n", __PRETTY_FUNCTION__);
733 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
734 "putc stream");
735 return putc (c, stream);
739 WRAPPER2(int, puts, const char *s)
741 size_t n;
742 TRACE ("%s\n", __PRETTY_FUNCTION__);
743 n = strlen (s);
744 MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "puts buffer");
745 return puts (s);
749 WRAPPER2(void, clearerr, FILE *stream)
751 TRACE ("%s\n", __PRETTY_FUNCTION__);
752 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
753 "clearerr stream");
754 clearerr (stream);
758 WRAPPER2(int, feof, FILE *stream)
760 TRACE ("%s\n", __PRETTY_FUNCTION__);
761 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
762 "feof stream");
763 return feof (stream);
767 WRAPPER2(int, ferror, FILE *stream)
769 TRACE ("%s\n", __PRETTY_FUNCTION__);
770 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
771 "ferror stream");
772 return ferror (stream);
776 WRAPPER2(int, fileno, FILE *stream)
778 TRACE ("%s\n", __PRETTY_FUNCTION__);
779 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
780 "fileno stream");
781 return fileno (stream);
785 WRAPPER2(int, printf, const char *format, ...)
787 size_t n;
788 va_list ap;
789 int result;
790 TRACE ("%s\n", __PRETTY_FUNCTION__);
791 n = strlen (format);
792 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
793 "printf format");
794 va_start (ap, format);
795 result = vprintf (format, ap);
796 va_end (ap);
797 return result;
801 WRAPPER2(int, fprintf, FILE *stream, const char *format, ...)
803 size_t n;
804 va_list ap;
805 int result;
806 TRACE ("%s\n", __PRETTY_FUNCTION__);
807 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
808 "fprintf stream");
809 n = strlen (format);
810 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
811 "fprintf format");
812 va_start (ap, format);
813 result = vfprintf (stream, format, ap);
814 va_end (ap);
815 return result;
819 WRAPPER2(int, sprintf, char *str, const char *format, ...)
821 size_t n;
822 va_list ap;
823 int result;
824 TRACE ("%s\n", __PRETTY_FUNCTION__);
825 MF_VALIDATE_EXTENT (str, 1, __MF_CHECK_WRITE, "sprintf str");
826 n = strlen (format);
827 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
828 "sprintf format");
829 va_start (ap, format);
830 result = vsprintf (str, format, ap);
831 va_end (ap);
832 n = strlen (str);
833 MF_VALIDATE_EXTENT (str, CLAMPADD(n, 1), __MF_CHECK_WRITE, "sprintf str");
834 return result;
838 WRAPPER2(int, snprintf, char *str, size_t size, const char *format, ...)
840 size_t n;
841 va_list ap;
842 int result;
843 TRACE ("%s\n", __PRETTY_FUNCTION__);
844 MF_VALIDATE_EXTENT (str, size, __MF_CHECK_WRITE, "snprintf str");
845 n = strlen (format);
846 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
847 "snprintf format");
848 va_start (ap, format);
849 result = vsnprintf (str, size, format, ap);
850 va_end (ap);
851 return result;
855 WRAPPER2(int, vprintf, const char *format, va_list ap)
857 size_t n;
858 TRACE ("%s\n", __PRETTY_FUNCTION__);
859 n = strlen (format);
860 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
861 "vprintf format");
862 return vprintf (format, ap);
866 WRAPPER2(int, vfprintf, FILE *stream, const char *format, va_list ap)
868 size_t n;
869 TRACE ("%s\n", __PRETTY_FUNCTION__);
870 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
871 "vfprintf stream");
872 n = strlen (format);
873 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
874 "vfprintf format");
875 return vfprintf (stream, format, ap);
879 WRAPPER2(int, vsprintf, char *str, const char *format, va_list ap)
881 size_t n;
882 int result;
883 TRACE ("%s\n", __PRETTY_FUNCTION__);
884 MF_VALIDATE_EXTENT (str, 1, __MF_CHECK_WRITE, "vsprintf str");
885 n = strlen (format);
886 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
887 "vsprintf format");
888 result = vsprintf (str, format, ap);
889 n = strlen (str);
890 MF_VALIDATE_EXTENT (str, CLAMPADD(n, 1), __MF_CHECK_WRITE, "vsprintf str");
891 return result;
895 WRAPPER2(int, vsnprintf, char *str, size_t size, const char *format,
896 va_list ap)
898 size_t n;
899 TRACE ("%s\n", __PRETTY_FUNCTION__);
900 MF_VALIDATE_EXTENT (str, size, __MF_CHECK_WRITE, "vsnprintf str");
901 n = strlen (format);
902 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
903 "vsnprintf format");
904 return vsnprintf (str, size, format, ap);
908 WRAPPER2(int , access, const char *path, int mode)
910 size_t n;
911 TRACE ("%s\n", __PRETTY_FUNCTION__);
912 n = strlen (path);
913 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "access path");
914 return access (path, mode);
918 WRAPPER2(int , remove, const char *path)
920 size_t n;
921 TRACE ("%s\n", __PRETTY_FUNCTION__);
922 n = strlen (path);
923 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "remove path");
924 return remove (path);
928 WRAPPER2(int, fflush, FILE *stream)
930 TRACE ("%s\n", __PRETTY_FUNCTION__);
931 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
932 "fflush stream");
933 return fflush (stream);
937 WRAPPER2(int, fseek, FILE *stream, long offset, int whence)
939 TRACE ("%s\n", __PRETTY_FUNCTION__);
940 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
941 "fseek stream");
942 return fseek (stream, offset, whence);
946 #ifdef HAVE_FSEEKO64
947 WRAPPER2(int, fseeko64, FILE *stream, off64_t offset, int whence)
949 TRACE ("%s\n", __PRETTY_FUNCTION__);
950 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
951 "fseeko64 stream");
952 return fseeko64 (stream, offset, whence);
954 #endif
957 WRAPPER2(long, ftell, FILE *stream)
959 TRACE ("%s\n", __PRETTY_FUNCTION__);
960 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
961 "ftell stream");
962 return ftell (stream);
966 #ifdef HAVE_FTELLO64
967 WRAPPER2(off64_t, ftello64, FILE *stream)
969 TRACE ("%s\n", __PRETTY_FUNCTION__);
970 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
971 "ftello64 stream");
972 return ftello64 (stream);
974 #endif
977 WRAPPER2(void, rewind, FILE *stream)
979 TRACE ("%s\n", __PRETTY_FUNCTION__);
980 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
981 "rewind stream");
982 rewind (stream);
986 WRAPPER2(int, fgetpos, FILE *stream, fpos_t *pos)
988 TRACE ("%s\n", __PRETTY_FUNCTION__);
989 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
990 "fgetpos stream");
991 MF_VALIDATE_EXTENT (pos, sizeof (*pos), __MF_CHECK_WRITE, "fgetpos pos");
992 return fgetpos (stream, pos);
996 WRAPPER2(int, fsetpos, FILE *stream, fpos_t *pos)
998 TRACE ("%s\n", __PRETTY_FUNCTION__);
999 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1000 "fsetpos stream");
1001 MF_VALIDATE_EXTENT (pos, sizeof (*pos), __MF_CHECK_READ, "fsetpos pos");
1002 return fsetpos (stream, pos);
1006 WRAPPER2(int , stat, const char *path, struct stat *buf)
1008 size_t n;
1009 TRACE ("%s\n", __PRETTY_FUNCTION__);
1010 n = strlen (path);
1011 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "stat path");
1012 MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ, "stat buf");
1013 return stat (path, buf);
1017 #ifdef HAVE_STAT64
1018 WRAPPER2(int , stat64, const char *path, struct stat64 *buf)
1020 size_t n;
1021 TRACE ("%s\n", __PRETTY_FUNCTION__);
1022 n = strlen (path);
1023 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "stat64 path");
1024 MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ, "stat64 buf");
1025 return stat64 (path, buf);
1027 #endif
1030 WRAPPER2(int , fstat, int filedes, struct stat *buf)
1032 TRACE ("%s\n", __PRETTY_FUNCTION__);
1033 MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ, "fstat buf");
1034 return fstat (filedes, buf);
1038 WRAPPER2(int , lstat, const char *path, struct stat *buf)
1040 size_t n;
1041 TRACE ("%s\n", __PRETTY_FUNCTION__);
1042 n = strlen (path);
1043 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "lstat path");
1044 MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ, "lstat buf");
1045 return lstat (path, buf);
1049 WRAPPER2(int , mkfifo, const char *path, mode_t mode)
1051 size_t n;
1052 TRACE ("%s\n", __PRETTY_FUNCTION__);
1053 n = strlen (path);
1054 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "mkfifo path");
1055 return mkfifo (path, mode);
1059 WRAPPER2(int, setvbuf, FILE *stream, char *buf, int mode , size_t size)
1061 TRACE ("%s\n", __PRETTY_FUNCTION__);
1062 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1063 "setvbuf stream");
1064 if (NULL != buf)
1065 MF_VALIDATE_EXTENT (buf, size, __MF_CHECK_READ, "setvbuf buf");
1066 return setvbuf (stream, buf, mode, size);
1070 WRAPPER2(void, setbuf, FILE *stream, char *buf)
1072 TRACE ("%s\n", __PRETTY_FUNCTION__);
1073 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1074 "setbuf stream");
1075 if (NULL != buf)
1076 MF_VALIDATE_EXTENT (buf, BUFSIZ, __MF_CHECK_READ, "setbuf buf");
1077 setbuf (stream, buf);
1081 #ifdef HAVE_DIRENT_H
1082 WRAPPER2(DIR *, opendir, const char *path)
1084 DIR *p;
1085 size_t n;
1086 TRACE ("%s\n", __PRETTY_FUNCTION__);
1087 n = strlen (path);
1088 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "opendir path");
1090 p = opendir (path);
1091 if (NULL != p) {
1092 #ifdef MF_REGISTER_opendir
1093 __mf_register (p, MF_RESULT_SIZE_opendir, MF_REGISTER_opendir,
1094 "opendir result");
1095 #endif
1096 MF_VALIDATE_EXTENT (p, MF_RESULT_SIZE_opendir, __MF_CHECK_WRITE,
1097 "opendir result");
1099 return p;
1103 WRAPPER2(int, closedir, DIR *dir)
1105 TRACE ("%s\n", __PRETTY_FUNCTION__);
1106 MF_VALIDATE_EXTENT (dir, 0, __MF_CHECK_WRITE, "closedir dir");
1107 #ifdef MF_REGISTER_opendir
1108 __mf_unregister (dir, MF_RESULT_SIZE_opendir, MF_REGISTER_opendir);
1109 #endif
1110 return closedir (dir);
1114 WRAPPER2(struct dirent *, readdir, DIR *dir)
1116 struct dirent *p;
1117 TRACE ("%s\n", __PRETTY_FUNCTION__);
1118 MF_VALIDATE_EXTENT (dir, 0, __MF_CHECK_READ, "readdir dir");
1119 p = readdir (dir);
1120 if (NULL != p) {
1121 #ifdef MF_REGISTER_readdir
1122 __mf_register (p, sizeof (*p), MF_REGISTER_readdir, "readdir result");
1123 #endif
1124 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "readdir result");
1126 return p;
1128 #endif
1131 #ifdef HAVE_SYS_SOCKET_H
1133 WRAPPER2(int, recv, int s, void *buf, size_t len, int flags)
1135 TRACE ("%s\n", __PRETTY_FUNCTION__);
1136 MF_VALIDATE_EXTENT (buf, len, __MF_CHECK_WRITE, "recv buf");
1137 return recv (s, buf, len, flags);
1141 WRAPPER2(int, recvfrom, int s, void *buf, size_t len, int flags,
1142 struct sockaddr *from, socklen_t *fromlen)
1144 TRACE ("%s\n", __PRETTY_FUNCTION__);
1145 MF_VALIDATE_EXTENT (buf, len, __MF_CHECK_WRITE, "recvfrom buf");
1146 MF_VALIDATE_EXTENT (from, (size_t)*fromlen, __MF_CHECK_WRITE,
1147 "recvfrom from");
1148 return recvfrom (s, buf, len, flags, from, fromlen);
1152 WRAPPER2(int, recvmsg, int s, struct msghdr *msg, int flags)
1154 TRACE ("%s\n", __PRETTY_FUNCTION__);
1155 MF_VALIDATE_EXTENT (msg, sizeof (*msg), __MF_CHECK_WRITE, "recvmsg msg");
1156 return recvmsg (s, msg, flags);
1160 WRAPPER2(int, send, int s, const void *msg, size_t len, int flags)
1162 TRACE ("%s\n", __PRETTY_FUNCTION__);
1163 MF_VALIDATE_EXTENT (msg, len, __MF_CHECK_READ, "send msg");
1164 return send (s, msg, len, flags);
1168 WRAPPER2(int, sendto, int s, const void *msg, size_t len, int flags,
1169 const struct sockaddr *to, socklen_t tolen)
1171 TRACE ("%s\n", __PRETTY_FUNCTION__);
1172 MF_VALIDATE_EXTENT (msg, len, __MF_CHECK_READ, "sendto msg");
1173 MF_VALIDATE_EXTENT (to, (size_t)tolen, __MF_CHECK_WRITE, "sendto to");
1174 return sendto (s, msg, len, flags, to, tolen);
1178 WRAPPER2(int, sendmsg, int s, const void *msg, int flags)
1180 TRACE ("%s\n", __PRETTY_FUNCTION__);
1181 MF_VALIDATE_EXTENT (msg, sizeof (*msg), __MF_CHECK_READ, "sendmsg msg");
1182 return sendmsg (s, msg, flags);
1186 WRAPPER2(int, setsockopt, int s, int level, int optname, const void *optval,
1187 socklen_t optlen)
1189 TRACE ("%s\n", __PRETTY_FUNCTION__);
1190 MF_VALIDATE_EXTENT (optval, (size_t)optlen, __MF_CHECK_READ,
1191 "setsockopt optval");
1192 return setsockopt (s, level, optname, optval, optlen);
1196 WRAPPER2(int, getsockopt, int s, int level, int optname, void *optval,
1197 socklen_t *optlen)
1199 TRACE ("%s\n", __PRETTY_FUNCTION__);
1200 MF_VALIDATE_EXTENT (optval, (size_t)*optlen, __MF_CHECK_WRITE,
1201 "getsockopt optval");
1202 return getsockopt (s, level, optname, optval, optlen);
1206 WRAPPER2(int, accept, int s, struct sockaddr *addr, socklen_t *addrlen)
1208 TRACE ("%s\n", __PRETTY_FUNCTION__);
1209 MF_VALIDATE_EXTENT (addr, (size_t)*addrlen, __MF_CHECK_WRITE, "accept addr");
1210 return accept (s, addr, addrlen);
1214 WRAPPER2(int, bind, int sockfd, struct sockaddr *addr, socklen_t addrlen)
1216 TRACE ("%s\n", __PRETTY_FUNCTION__);
1217 MF_VALIDATE_EXTENT (addr, (size_t)addrlen, __MF_CHECK_WRITE, "bind addr");
1218 return bind (sockfd, addr, addrlen);
1222 WRAPPER2(int, connect, int sockfd, const struct sockaddr *addr,
1223 socklen_t addrlen)
1225 TRACE ("%s\n", __PRETTY_FUNCTION__);
1226 MF_VALIDATE_EXTENT (addr, (size_t)addrlen, __MF_CHECK_READ,
1227 "connect addr");
1228 return connect (sockfd, addr, addrlen);
1231 #endif /* HAVE_SYS_SOCKET_H */
1234 WRAPPER2(int, gethostname, char *name, size_t len)
1236 TRACE ("%s\n", __PRETTY_FUNCTION__);
1237 MF_VALIDATE_EXTENT (name, len, __MF_CHECK_WRITE, "gethostname name");
1238 return gethostname (name, len);
1242 #ifdef HAVE_SETHOSTNAME
1243 WRAPPER2(int, sethostname, const char *name, size_t len)
1245 TRACE ("%s\n", __PRETTY_FUNCTION__);
1246 MF_VALIDATE_EXTENT (name, len, __MF_CHECK_READ, "sethostname name");
1247 return sethostname (name, len);
1249 #endif
1252 #ifdef HAVE_NETDB_H
1254 WRAPPER2(struct hostent *, gethostbyname, const char *name)
1256 struct hostent *p;
1257 char **ss;
1258 char *s;
1259 size_t n;
1260 int nreg;
1261 TRACE ("%s\n", __PRETTY_FUNCTION__);
1262 n = strlen (name);
1263 MF_VALIDATE_EXTENT (name, CLAMPADD(n, 1), __MF_CHECK_READ,
1264 "gethostbyname name");
1265 p = gethostbyname (name);
1266 if (NULL != p) {
1267 #ifdef MF_REGISTER_gethostbyname
1268 __mf_register (p, sizeof (*p), MF_REGISTER_gethostbyname,
1269 "gethostbyname result");
1270 #endif
1271 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE,
1272 "gethostbyname result");
1273 if (NULL != (s = p->h_name)) {
1274 n = strlen (s);
1275 n = CLAMPADD(n, 1);
1276 #ifdef MF_REGISTER_gethostbyname_items
1277 __mf_register (s, n, MF_REGISTER_gethostbyname_items,
1278 "gethostbyname result->h_name");
1279 #endif
1280 MF_VALIDATE_EXTENT (s, n, __MF_CHECK_WRITE,
1281 "gethostbyname result->h_name");
1284 if (NULL != (ss = p->h_aliases)) {
1285 for (nreg = 1;; ++nreg) {
1286 s = *ss++;
1287 if (NULL == s)
1288 break;
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_aliases[]");
1294 #endif
1295 MF_VALIDATE_EXTENT (s, n, __MF_CHECK_WRITE,
1296 "gethostbyname result->h_aliases[]");
1298 nreg *= sizeof (*p->h_aliases);
1299 #ifdef MF_REGISTER_gethostbyname_items
1300 __mf_register (p->h_aliases, nreg, MF_REGISTER_gethostbyname_items,
1301 "gethostbyname result->h_aliases");
1302 #endif
1303 MF_VALIDATE_EXTENT (p->h_aliases, nreg, __MF_CHECK_WRITE,
1304 "gethostbyname result->h_aliases");
1307 if (NULL != (ss = p->h_addr_list)) {
1308 for (nreg = 1;; ++nreg) {
1309 s = *ss++;
1310 if (NULL == s)
1311 break;
1312 #ifdef MF_REGISTER_gethostbyname_items
1313 __mf_register (s, p->h_length, MF_REGISTER_gethostbyname_items,
1314 "gethostbyname result->h_addr_list[]");
1315 #endif
1316 MF_VALIDATE_EXTENT (s, p->h_length, __MF_CHECK_WRITE,
1317 "gethostbyname result->h_addr_list[]");
1319 nreg *= sizeof (*p->h_addr_list);
1320 #ifdef MF_REGISTER_gethostbyname_items
1321 __mf_register (p->h_addr_list, nreg, MF_REGISTER_gethostbyname_items,
1322 "gethostbyname result->h_addr_list");
1323 #endif
1324 MF_VALIDATE_EXTENT (p->h_addr_list, nreg, __MF_CHECK_WRITE,
1325 "gethostbyname result->h_addr_list");
1328 return p;
1331 #endif /* HAVE_NETDB_H */
1334 #ifdef HAVE_SYS_WAIT_H
1336 WRAPPER2(pid_t, wait, int *status)
1338 TRACE ("%s\n", __PRETTY_FUNCTION__);
1339 if (NULL != status)
1340 MF_VALIDATE_EXTENT (status, sizeof (*status), __MF_CHECK_WRITE,
1341 "wait status");
1342 return wait (status);
1346 WRAPPER2(pid_t, waitpid, pid_t pid, int *status, int options)
1348 TRACE ("%s\n", __PRETTY_FUNCTION__);
1349 if (NULL != status)
1350 MF_VALIDATE_EXTENT (status, sizeof (*status), __MF_CHECK_WRITE,
1351 "waitpid status");
1352 return waitpid (pid, status, options);
1355 #endif /* HAVE_SYS_WAIT_H */
1358 WRAPPER2(FILE *, popen, const char *command, const char *mode)
1360 size_t n;
1361 FILE *p;
1362 TRACE ("%s\n", __PRETTY_FUNCTION__);
1364 n = strlen (command);
1365 MF_VALIDATE_EXTENT (command, CLAMPADD(n, 1), __MF_CHECK_READ, "popen path");
1367 n = strlen (mode);
1368 MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "popen mode");
1370 p = popen (command, mode);
1371 if (NULL != p) {
1372 #ifdef MF_REGISTER_fopen
1373 __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "popen result");
1374 #endif
1375 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "popen result");
1377 return p;
1381 WRAPPER2(int, pclose, FILE *stream)
1383 int resp;
1384 TRACE ("%s\n", __PRETTY_FUNCTION__);
1385 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1386 "pclose stream");
1387 resp = pclose (stream);
1388 #ifdef MF_REGISTER_fopen
1389 __mf_unregister (stream, sizeof (*stream), MF_REGISTER_fopen);
1390 #endif
1391 return resp;
1395 WRAPPER2(int, execve, const char *path, char *const argv [],
1396 char *const envp[])
1398 size_t n;
1399 char *const *p;
1400 const char *s;
1401 TRACE ("%s\n", __PRETTY_FUNCTION__);
1403 n = strlen (path);
1404 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "execve path");
1406 for (p = argv;;) {
1407 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_READ, "execve *argv");
1408 s = *p++;
1409 if (NULL == s)
1410 break;
1411 n = strlen (s);
1412 MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "execve **argv");
1415 for (p = envp;;) {
1416 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_READ, "execve *envp");
1417 s = *p++;
1418 if (NULL == s)
1419 break;
1420 n = strlen (s);
1421 MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "execve **envp");
1423 return execve (path, argv, envp);
1427 WRAPPER2(int, execv, const char *path, char *const argv [])
1429 size_t n;
1430 char *const *p;
1431 const char *s;
1432 TRACE ("%s\n", __PRETTY_FUNCTION__);
1434 n = strlen (path);
1435 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "execv path");
1437 for (p = argv;;) {
1438 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_READ, "execv *argv");
1439 s = *p++;
1440 if (NULL == s)
1441 break;
1442 n = strlen (s);
1443 MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "execv **argv");
1445 return execv (path, argv);
1449 WRAPPER2(int, execvp, const char *path, char *const argv [])
1451 size_t n;
1452 char *const *p;
1453 const char *s;
1454 TRACE ("%s\n", __PRETTY_FUNCTION__);
1456 n = strlen (path);
1457 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "execvp path");
1459 for (p = argv;;) {
1460 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_READ, "execvp *argv");
1461 s = *p++;
1462 if (NULL == s)
1463 break;
1464 n = strlen (s);
1465 MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "execvp **argv");
1467 return execvp (path, argv);
1471 WRAPPER2(int, system, const char *string)
1473 size_t n;
1474 TRACE ("%s\n", __PRETTY_FUNCTION__);
1475 n = strlen (string);
1476 MF_VALIDATE_EXTENT (string, CLAMPADD(n, 1), __MF_CHECK_READ,
1477 "system string");
1478 return system (string);
1482 WRAPPER2(void *, dlopen, const char *path, int flags)
1484 void *p;
1485 size_t n;
1486 TRACE ("%s\n", __PRETTY_FUNCTION__);
1487 n = strlen (path);
1488 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "dlopen path");
1489 p = dlopen (path, flags);
1490 if (NULL != p) {
1491 #ifdef MF_REGISTER_dlopen
1492 __mf_register (p, 0, MF_REGISTER_dlopen, "dlopen result");
1493 #endif
1494 MF_VALIDATE_EXTENT (p, 0, __MF_CHECK_WRITE, "dlopen result");
1496 return p;
1500 WRAPPER2(int, dlclose, void *handle)
1502 int resp;
1503 TRACE ("%s\n", __PRETTY_FUNCTION__);
1504 MF_VALIDATE_EXTENT (handle, 0, __MF_CHECK_READ, "dlclose handle");
1505 resp = dlclose (handle);
1506 #ifdef MF_REGISTER_dlopen
1507 __mf_unregister (handle, 0, MF_REGISTER_dlopen);
1508 #endif
1509 return resp;
1513 WRAPPER2(char *, dlerror)
1515 char *p;
1516 TRACE ("%s\n", __PRETTY_FUNCTION__);
1517 p = dlerror ();
1518 if (NULL != p) {
1519 size_t n;
1520 n = strlen (p);
1521 n = CLAMPADD(n, 1);
1522 #ifdef MF_REGISTER_dlerror
1523 __mf_register (p, n, MF_REGISTER_dlerror, "dlerror result");
1524 #endif
1525 MF_VALIDATE_EXTENT (p, n, __MF_CHECK_WRITE, "dlerror result");
1527 return p;
1531 WRAPPER2(void *, dlsym, void *handle, char *symbol)
1533 size_t n;
1534 void *p;
1535 TRACE ("%s\n", __PRETTY_FUNCTION__);
1536 MF_VALIDATE_EXTENT (handle, 0, __MF_CHECK_READ, "dlsym handle");
1537 n = strlen (symbol);
1538 MF_VALIDATE_EXTENT (symbol, CLAMPADD(n, 1), __MF_CHECK_READ, "dlsym symbol");
1539 p = dlsym (handle, symbol);
1540 if (NULL != p) {
1541 #ifdef MF_REGISTER_dlsym
1542 __mf_register (p, 0, MF_REGISTER_dlsym, "dlsym result");
1543 #endif
1544 MF_VALIDATE_EXTENT (p, 0, __MF_CHECK_WRITE, "dlsym result");
1546 return p;
1550 #if defined (HAVE_SYS_IPC_H) && defined (HAVE_SYS_SEM_H) && defined (HAVE_SYS_SHM_H)
1552 WRAPPER2(int, semop, int semid, struct sembuf *sops, unsigned nsops)
1554 TRACE ("%s\n", __PRETTY_FUNCTION__);
1555 MF_VALIDATE_EXTENT (sops, sizeof (*sops) * nsops, __MF_CHECK_READ,
1556 "semop sops");
1557 return semop (semid, sops, nsops);
1561 #ifndef HAVE_UNION_SEMUN
1562 union semun {
1563 int val; /* value for SETVAL */
1564 struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */
1565 unsigned short int *array; /* array for GETALL, SETALL */
1566 struct seminfo *__buf; /* buffer for IPC_INFO */
1568 #endif
1569 WRAPPER2(int, semctl, int semid, int semnum, int cmd, union semun arg)
1571 TRACE ("%s\n", __PRETTY_FUNCTION__);
1572 switch (cmd) {
1573 case IPC_STAT:
1574 MF_VALIDATE_EXTENT (arg.buf, sizeof (*arg.buf), __MF_CHECK_WRITE,
1575 "semctl buf");
1576 break;
1577 case IPC_SET:
1578 MF_VALIDATE_EXTENT (arg.buf, sizeof (*arg.buf), __MF_CHECK_READ,
1579 "semctl buf");
1580 break;
1581 case GETALL:
1582 MF_VALIDATE_EXTENT (arg.array, sizeof (*arg.array), __MF_CHECK_WRITE,
1583 "semctl array");
1584 case SETALL:
1585 MF_VALIDATE_EXTENT (arg.array, sizeof (*arg.array), __MF_CHECK_READ,
1586 "semctl array");
1587 break;
1588 #ifdef IPC_INFO
1589 /* FreeBSD 5.1 And Cygwin headers include IPC_INFO but not the __buf field. */
1590 #if !defined(__FreeBSD__) && !defined(__CYGWIN__)
1591 case IPC_INFO:
1592 MF_VALIDATE_EXTENT (arg.__buf, sizeof (*arg.__buf), __MF_CHECK_WRITE,
1593 "semctl __buf");
1594 break;
1595 #endif
1596 #endif
1597 default:
1598 break;
1600 return semctl (semid, semnum, cmd, arg);
1604 WRAPPER2(int, shmctl, int shmid, int cmd, struct shmid_ds *buf)
1606 TRACE ("%s\n", __PRETTY_FUNCTION__);
1607 switch (cmd) {
1608 case IPC_STAT:
1609 MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_WRITE,
1610 "shmctl buf");
1611 break;
1612 case IPC_SET:
1613 MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ,
1614 "shmctl buf");
1615 break;
1616 default:
1617 break;
1619 return shmctl (shmid, cmd, buf);
1623 WRAPPER2(void *, shmat, int shmid, const void *shmaddr, int shmflg)
1625 void *p;
1626 TRACE ("%s\n", __PRETTY_FUNCTION__);
1627 p = shmat (shmid, shmaddr, shmflg);
1628 #ifdef MF_REGISTER_shmat
1629 if (NULL != p) {
1630 struct shmid_ds buf;
1631 __mf_register (p, shmctl (shmid, IPC_STAT, &buf) ? 0 : buf.shm_segsz,
1632 MF_REGISTER_shmat, "shmat result");
1634 #endif
1635 return p;
1639 WRAPPER2(int, shmdt, const void *shmaddr)
1641 int resp;
1642 TRACE ("%s\n", __PRETTY_FUNCTION__);
1643 resp = shmdt (shmaddr);
1644 #ifdef MF_REGISTER_shmat
1645 __mf_unregister ((void *)shmaddr, 0, MF_REGISTER_shmat);
1646 #endif
1647 return resp;
1651 #endif /* HAVE_SYS_IPC/SEM/SHM_H */
1655 /* ctype stuff. This is host-specific by necessity, as the arrays
1656 that is used by most is*()/to*() macros are implementation-defined. */
1658 /* GLIBC 2.3 */
1659 #ifdef HAVE___CTYPE_B_LOC
1660 WRAPPER2(unsigned short **, __ctype_b_loc, void)
1662 static unsigned short * last_buf = (void *) 0;
1663 static unsigned short ** last_ptr = (void *) 0;
1664 unsigned short ** ptr = (unsigned short **) __ctype_b_loc ();
1665 unsigned short * buf = * ptr;
1666 if (ptr != last_ptr)
1668 /* XXX: unregister last_ptr? */
1669 last_ptr = ptr;
1670 __mf_register (last_ptr, sizeof(last_ptr), __MF_TYPE_STATIC, "ctype_b_loc **");
1672 if (buf != last_buf)
1674 last_buf = buf;
1675 __mf_register ((void *) (last_buf - 128), 384 * sizeof(unsigned short), __MF_TYPE_STATIC,
1676 "ctype_b_loc []");
1678 return ptr;
1680 #endif
1682 #ifdef HAVE___CTYPE_TOUPPER_LOC
1683 WRAPPER2(int **, __ctype_toupper_loc, void)
1685 static int * last_buf = (void *) 0;
1686 static int ** last_ptr = (void *) 0;
1687 int ** ptr = (int **) __ctype_toupper_loc ();
1688 int * buf = * ptr;
1689 if (ptr != last_ptr)
1691 /* XXX: unregister last_ptr? */
1692 last_ptr = ptr;
1693 __mf_register (last_ptr, sizeof(last_ptr), __MF_TYPE_STATIC, "ctype_toupper_loc **");
1695 if (buf != last_buf)
1697 last_buf = buf;
1698 __mf_register ((void *) (last_buf - 128), 384 * sizeof(int), __MF_TYPE_STATIC,
1699 "ctype_toupper_loc []");
1701 return ptr;
1703 #endif
1705 #ifdef HAVE___CTYPE_TOLOWER_LOC
1706 WRAPPER2(int **, __ctype_tolower_loc, void)
1708 static int * last_buf = (void *) 0;
1709 static int ** last_ptr = (void *) 0;
1710 int ** ptr = (int **) __ctype_tolower_loc ();
1711 int * buf = * ptr;
1712 if (ptr != last_ptr)
1714 /* XXX: unregister last_ptr? */
1715 last_ptr = ptr;
1716 __mf_register (last_ptr, sizeof(last_ptr), __MF_TYPE_STATIC, "ctype_tolower_loc **");
1718 if (buf != last_buf)
1720 last_buf = buf;
1721 __mf_register ((void *) (last_buf - 128), 384 * sizeof(int), __MF_TYPE_STATIC,
1722 "ctype_tolower_loc []");
1724 return ptr;
1726 #endif
1729 /* passwd/group related functions. These register every (static) pointer value returned,
1730 and rely on libmudflap's quiet toleration of duplicate static registrations. */
1732 #ifdef HAVE_GETLOGIN
1733 WRAPPER2(char *, getlogin, void)
1735 char *buf = getlogin ();
1736 if (buf != NULL)
1737 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
1738 "getlogin() return");
1739 return buf;
1741 #endif
1744 #ifdef HAVE_CUSERID
1745 WRAPPER2(char *, cuserid, char * buf)
1747 if (buf != NULL)
1749 MF_VALIDATE_EXTENT(buf, L_cuserid, __MF_CHECK_WRITE,
1750 "cuserid destination");
1751 return cuserid (buf);
1753 buf = cuserid (NULL);
1754 if (buf != NULL)
1755 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
1756 "getcuserid() return");
1757 return buf;
1759 #endif
1762 #ifdef HAVE_GETPWNAM
1763 WRAPPER2(struct passwd *, getpwnam, const char *name)
1765 struct passwd *buf;
1766 MF_VALIDATE_EXTENT(name, strlen(name)+1, __MF_CHECK_READ,
1767 "getpwnam name");
1768 buf = getpwnam (name);
1769 if (buf != NULL)
1770 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
1771 "getpw*() return");
1772 return buf;
1774 #endif
1777 #ifdef HAVE_GETPWUID
1778 WRAPPER2(struct passwd *, getpwuid, uid_t uid)
1780 struct passwd *buf;
1781 buf = getpwuid (uid);
1782 if (buf != NULL)
1783 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
1784 "getpw*() return");
1785 return buf;
1787 #endif
1790 #ifdef HAVE_GETGRNAM
1791 WRAPPER2(struct group *, getgrnam, const char *name)
1793 struct group *buf;
1794 MF_VALIDATE_EXTENT(name, strlen(name)+1, __MF_CHECK_READ,
1795 "getgrnam name");
1796 buf = getgrnam (name);
1797 if (buf != NULL)
1798 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
1799 "getgr*() return");
1800 return buf;
1802 #endif
1805 #ifdef HAVE_GETGRGID
1806 WRAPPER2(struct group *, getgrgid, uid_t uid)
1808 struct group *buf;
1809 buf = getgrgid (uid);
1810 if (buf != NULL)
1811 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
1812 "getgr*() return");
1813 return buf;
1815 #endif
1818 #ifdef HAVE_GETSERVENT
1819 WRAPPER2(struct servent *, getservent, void)
1821 struct servent *buf;
1822 buf = getservent ();
1823 if (buf != NULL)
1824 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
1825 "getserv*() return");
1826 return buf;
1828 #endif
1831 #ifdef HAVE_GETSERVBYNAME
1832 WRAPPER2(struct servent *, getservbyname, const char *name, const char *proto)
1834 struct servent *buf;
1835 MF_VALIDATE_EXTENT(name, strlen(name)+1, __MF_CHECK_READ,
1836 "getservbyname name");
1837 MF_VALIDATE_EXTENT(proto, strlen(proto)+1, __MF_CHECK_READ,
1838 "getservbyname proto");
1839 buf = getservbyname (name, proto);
1840 if (buf != NULL)
1841 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
1842 "getserv*() return");
1843 return buf;
1845 #endif
1848 #ifdef HAVE_GETSERVBYPORT
1849 WRAPPER2(struct servent *, getservbyport, int port, const char *proto)
1851 struct servent *buf;
1852 MF_VALIDATE_EXTENT(proto, strlen(proto)+1, __MF_CHECK_READ,
1853 "getservbyport proto");
1854 buf = getservbyport (port, 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_GAI_STRERROR
1864 WRAPPER2(const char *, gai_strerror, int errcode)
1866 const char *buf;
1867 buf = gai_strerror (errcode);
1868 if (buf != NULL)
1869 __mf_register ((void *) buf, strlen(buf)+1, __MF_TYPE_STATIC,
1870 "gai_strerror() return");
1871 return buf;
1873 #endif