OSDN Git Service

5649e1c58829b9c387e105b2998ce62d68f98742
[pf3gnuchains/gcc-fork.git] / libmudflap / mf-hooks2.c
1 /* Mudflap: narrow-pointer bounds-checking by tree rewriting.
2    Copyright (C) 2002, 2003, 2004, 2009 Free Software Foundation, Inc.
3    Contributed by Frank Ch. Eigler <fche@redhat.com>
4    and Graydon Hoare <graydon@redhat.com>
5
6 This file is part of GCC.
7
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 3, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 Under Section 7 of GPL version 3, you are granted additional
19 permissions described in the GCC Runtime Library Exception, version
20 3.1, as published by the Free Software Foundation.
21
22 You should have received a copy of the GNU General Public License and
23 a copy of the GCC Runtime Library Exception along with this program;
24 see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
25 <http://www.gnu.org/licenses/>.  */
26
27 #include "config.h"
28
29 #ifndef HAVE_SOCKLEN_T
30 #define socklen_t int
31 #endif
32
33 /* These attempt to coax various unix flavours to declare all our
34    needed tidbits in the system headers.  */
35 #if !defined(__FreeBSD__) && !defined(__APPLE__)
36 #define _POSIX_SOURCE
37 #endif /* Some BSDs break <sys/socket.h> if this is defined. */
38 #define _GNU_SOURCE
39 #define _XOPEN_SOURCE
40 #define _BSD_TYPES
41 #define __EXTENSIONS__
42 #define _ALL_SOURCE
43 #define _LARGE_FILE_API
44 #define _LARGEFILE64_SOURCE
45 #define _XOPEN_SOURCE_EXTENDED 1
46
47 #include <string.h>
48 #include <stdarg.h>
49 #include <stdio.h>
50 #include <stdlib.h>
51 #include <sys/stat.h>
52 #include <sys/time.h>
53 #include <sys/types.h>
54 #include <unistd.h>
55 #include <assert.h>
56 #include <errno.h>
57 #include <limits.h>
58 #include <time.h>
59 #include <ctype.h>
60 #ifdef HAVE_DLFCN_H
61 #include <dlfcn.h>
62 #endif
63 #ifdef HAVE_DIRENT_H
64 #include <dirent.h>
65 #endif
66 #ifdef HAVE_SYS_SOCKET_H
67 #include <sys/socket.h>
68 #endif
69 #ifdef HAVE_NETDB_H
70 #include <netdb.h>
71 #endif
72 #ifdef HAVE_SYS_WAIT_H
73 #include <sys/wait.h>
74 #endif
75 #ifdef HAVE_SYS_IPC_H
76 #include <sys/ipc.h>
77 #endif
78 #ifdef HAVE_SYS_SEM_H
79 #include <sys/sem.h>
80 #endif
81 #ifdef HAVE_SYS_SHM_H
82 #include <sys/shm.h>
83 #endif
84 #ifdef HAVE_PWD_H
85 #include <pwd.h>
86 #endif
87 #ifdef HAVE_GRP_H
88 #include <grp.h>
89 #endif
90 #ifdef HAVE_MNTENT_H
91 #include <mntent.h>
92 #endif
93 #ifdef HAVE_SYS_SOCKET_H
94 #include <sys/socket.h>
95 #endif
96 #ifdef HAVE_NETINET_IN_H
97 #include <netinet/in.h>
98 #endif
99 #ifdef HAVE_ARPA_INET_H
100 #include <arpa/inet.h>
101 #endif
102
103 #include "mf-runtime.h"
104 #include "mf-impl.h"
105
106 #ifdef _MUDFLAP
107 #error "Do not compile this file with -fmudflap!"
108 #endif
109
110
111 /* A bunch of independent stdlib/unistd hook functions, all
112    intercepted by mf-runtime.h macros.  */
113
114 #ifndef HAVE_STRNLEN
115 static inline size_t (strnlen) (const char* str, size_t n)
116 {
117   const char *s;
118
119   for (s = str; n && *s; ++s, --n)
120     ;
121   return (s - str);
122 }
123 #endif
124
125
126 /* str*,mem*,b* */
127
128 WRAPPER2(void *, memcpy, void *dest, const void *src, size_t n)
129 {
130   TRACE ("%s\n", __PRETTY_FUNCTION__);
131   MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "memcpy source");
132   MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "memcpy dest");
133   return memcpy (dest, src, n);
134 }
135
136
137 WRAPPER2(void *, memmove, void *dest, const void *src, size_t n)
138 {
139   TRACE ("%s\n", __PRETTY_FUNCTION__);
140   MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "memmove src");
141   MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "memmove dest");
142   return memmove (dest, src, n);
143 }
144
145
146 WRAPPER2(void *, memset, void *s, int c, size_t n)
147 {
148   TRACE ("%s\n", __PRETTY_FUNCTION__);
149   MF_VALIDATE_EXTENT(s, n, __MF_CHECK_WRITE, "memset dest");
150   return memset (s, c, n);
151 }
152
153
154 WRAPPER2(int, memcmp, const void *s1, const void *s2, size_t n)
155 {
156   TRACE ("%s\n", __PRETTY_FUNCTION__);
157   MF_VALIDATE_EXTENT(s1, n, __MF_CHECK_READ, "memcmp 1st arg");
158   MF_VALIDATE_EXTENT(s2, n, __MF_CHECK_READ, "memcmp 2nd arg");
159   return memcmp (s1, s2, n);
160 }
161
162
163 WRAPPER2(void *, memchr, const void *s, int c, size_t n)
164 {
165   TRACE ("%s\n", __PRETTY_FUNCTION__);
166   MF_VALIDATE_EXTENT(s, n, __MF_CHECK_READ, "memchr region");
167   return memchr (s, c, n);
168 }
169
170
171 #ifdef HAVE_MEMRCHR
172 WRAPPER2(void *, memrchr, const void *s, int c, size_t n)
173 {
174   TRACE ("%s\n", __PRETTY_FUNCTION__);
175   MF_VALIDATE_EXTENT(s, n, __MF_CHECK_READ, "memrchr region");
176   return memrchr (s, c, n);
177 }
178 #endif
179
180
181 WRAPPER2(char *, strcpy, char *dest, const char *src)
182 {
183   /* nb: just because strlen(src) == n doesn't mean (src + n) or (src + n +
184      1) are valid pointers. the allocated object might have size < n.
185      check anyways. */
186
187   size_t n = strlen (src);
188   TRACE ("%s\n", __PRETTY_FUNCTION__);
189   MF_VALIDATE_EXTENT(src, CLAMPADD(n, 1), __MF_CHECK_READ, "strcpy src");
190   MF_VALIDATE_EXTENT(dest, CLAMPADD(n, 1), __MF_CHECK_WRITE, "strcpy dest");
191   return strcpy (dest, src);
192 }
193
194
195 #ifdef HAVE_STRNCPY
196 WRAPPER2(char *, strncpy, char *dest, const char *src, size_t n)
197 {
198   size_t len = strnlen (src, n);
199   TRACE ("%s\n", __PRETTY_FUNCTION__);
200   MF_VALIDATE_EXTENT(src, len, __MF_CHECK_READ, "strncpy src");
201   MF_VALIDATE_EXTENT(dest, len, __MF_CHECK_WRITE, "strncpy dest"); /* nb: strNcpy */
202   return strncpy (dest, src, n);
203 }
204 #endif
205
206
207 WRAPPER2(char *, strcat, char *dest, const char *src)
208 {
209   size_t dest_sz;
210   size_t src_sz;
211   TRACE ("%s\n", __PRETTY_FUNCTION__);
212   dest_sz = strlen (dest);
213   src_sz = strlen (src);
214   MF_VALIDATE_EXTENT(src, CLAMPADD(src_sz, 1), __MF_CHECK_READ, "strcat src");
215   MF_VALIDATE_EXTENT(dest, CLAMPADD(dest_sz, CLAMPADD(src_sz, 1)),
216                      __MF_CHECK_WRITE, "strcat dest");
217   return strcat (dest, src);
218 }
219
220
221 WRAPPER2(char *, strncat, char *dest, const char *src, size_t n)
222 {
223
224   /* nb: validating the extents (s,n) might be a mistake for two reasons.
225
226   (1) the string s might be shorter than n chars, and n is just a
227   poor choice by the programmer. this is not a "true" error in the
228   sense that the call to strncat would still be ok.
229
230   (2) we could try to compensate for case (1) by calling strlen(s) and
231   using that as a bound for the extent to verify, but strlen might fall off
232   the end of a non-terminated string, leading to a false positive.
233
234   so we will call strnlen(s,n) and use that as a bound.
235
236   if strnlen returns a length beyond the end of the registered extent
237   associated with s, there is an error: the programmer's estimate for n is
238   too large _AND_ the string s is unterminated, in which case they'd be
239   about to touch memory they don't own while calling strncat.
240
241   this same logic applies to further uses of strnlen later down in this
242   file. */
243
244   size_t src_sz;
245   size_t dest_sz;
246   TRACE ("%s\n", __PRETTY_FUNCTION__);
247   src_sz = strnlen (src, n);
248   dest_sz = strnlen (dest, n);
249   MF_VALIDATE_EXTENT(src, src_sz, __MF_CHECK_READ, "strncat src");
250   MF_VALIDATE_EXTENT(dest, (CLAMPADD(dest_sz, CLAMPADD(src_sz, 1))),
251                      __MF_CHECK_WRITE, "strncat dest");
252   return strncat (dest, src, n);
253 }
254
255
256 WRAPPER2(int, strcmp, const char *s1, const char *s2)
257 {
258   size_t s1_sz;
259   size_t s2_sz;
260   TRACE ("%s\n", __PRETTY_FUNCTION__);
261   s1_sz = strlen (s1);
262   s2_sz = strlen (s2);
263   MF_VALIDATE_EXTENT(s1, CLAMPADD(s1_sz, 1), __MF_CHECK_READ, "strcmp 1st arg");
264   MF_VALIDATE_EXTENT(s2, CLAMPADD(s2_sz, 1), __MF_CHECK_WRITE, "strcmp 2nd arg");
265   return strcmp (s1, s2);
266 }
267
268
269 WRAPPER2(int, strcasecmp, const char *s1, const char *s2)
270 {
271   size_t s1_sz;
272   size_t s2_sz;
273   TRACE ("%s\n", __PRETTY_FUNCTION__);
274   s1_sz = strlen (s1);
275   s2_sz = strlen (s2);
276   MF_VALIDATE_EXTENT(s1, CLAMPADD(s1_sz, 1), __MF_CHECK_READ, "strcasecmp 1st arg");
277   MF_VALIDATE_EXTENT(s2, CLAMPADD(s2_sz, 1), __MF_CHECK_READ, "strcasecmp 2nd arg");
278   return strcasecmp (s1, s2);
279 }
280
281
282 WRAPPER2(int, strncmp, const char *s1, const char *s2, size_t n)
283 {
284   size_t s1_sz;
285   size_t s2_sz;
286   TRACE ("%s\n", __PRETTY_FUNCTION__);
287   s1_sz = strnlen (s1, n);
288   s2_sz = strnlen (s2, n);
289   MF_VALIDATE_EXTENT(s1, s1_sz, __MF_CHECK_READ, "strncmp 1st arg");
290   MF_VALIDATE_EXTENT(s2, s2_sz, __MF_CHECK_READ, "strncmp 2nd arg");
291   return strncmp (s1, s2, n);
292 }
293
294
295 WRAPPER2(int, strncasecmp, const char *s1, const char *s2, size_t n)
296 {
297   size_t s1_sz;
298   size_t s2_sz;
299   TRACE ("%s\n", __PRETTY_FUNCTION__);
300   s1_sz = strnlen (s1, n);
301   s2_sz = strnlen (s2, n);
302   MF_VALIDATE_EXTENT(s1, s1_sz, __MF_CHECK_READ, "strncasecmp 1st arg");
303   MF_VALIDATE_EXTENT(s2, s2_sz, __MF_CHECK_READ, "strncasecmp 2nd arg");
304   return strncasecmp (s1, s2, n);
305 }
306
307
308 WRAPPER2(char *, strdup, const char *s)
309 {
310   DECLARE(void *, malloc, size_t sz);
311   char *result;
312   size_t n = strlen (s);
313   TRACE ("%s\n", __PRETTY_FUNCTION__);
314   MF_VALIDATE_EXTENT(s, CLAMPADD(n,1), __MF_CHECK_READ, "strdup region");
315   result = (char *)CALL_REAL(malloc,
316                              CLAMPADD(CLAMPADD(n,1),
317                                       CLAMPADD(__mf_opts.crumple_zone,
318                                                __mf_opts.crumple_zone)));
319
320   if (UNLIKELY(! result)) return result;
321
322   result += __mf_opts.crumple_zone;
323   memcpy (result, s, n);
324   result[n] = '\0';
325
326   __mf_register (result, CLAMPADD(n,1), __MF_TYPE_HEAP_I, "strdup region");
327   return result;
328 }
329
330
331 WRAPPER2(char *, strndup, const char *s, size_t n)
332 {
333   DECLARE(void *, malloc, size_t sz);
334   char *result;
335   size_t sz = strnlen (s, n);
336   TRACE ("%s\n", __PRETTY_FUNCTION__);
337   MF_VALIDATE_EXTENT(s, sz, __MF_CHECK_READ, "strndup region"); /* nb: strNdup */
338
339   /* note: strndup still adds a \0, even with the N limit! */
340   result = (char *)CALL_REAL(malloc,
341                              CLAMPADD(CLAMPADD(n,1),
342                                       CLAMPADD(__mf_opts.crumple_zone,
343                                                __mf_opts.crumple_zone)));
344
345   if (UNLIKELY(! result)) return result;
346
347   result += __mf_opts.crumple_zone;
348   memcpy (result, s, n);
349   result[n] = '\0';
350
351   __mf_register (result, CLAMPADD(n,1), __MF_TYPE_HEAP_I, "strndup region");
352   return result;
353 }
354
355
356 WRAPPER2(char *, strchr, const char *s, int c)
357 {
358   size_t n;
359   TRACE ("%s\n", __PRETTY_FUNCTION__);
360   n = strlen (s);
361   MF_VALIDATE_EXTENT(s, CLAMPADD(n,1), __MF_CHECK_READ, "strchr region");
362   return strchr (s, c);
363 }
364
365
366 WRAPPER2(char *, strrchr, const char *s, int c)
367 {
368   size_t n;
369   TRACE ("%s\n", __PRETTY_FUNCTION__);
370   n = strlen (s);
371   MF_VALIDATE_EXTENT(s, CLAMPADD(n,1), __MF_CHECK_READ, "strrchr region");
372   return strrchr (s, c);
373 }
374
375
376 WRAPPER2(char *, strstr, const char *haystack, const char *needle)
377 {
378   size_t haystack_sz;
379   size_t needle_sz;
380   TRACE ("%s\n", __PRETTY_FUNCTION__);
381   haystack_sz = strlen (haystack);
382   needle_sz = strlen (needle);
383   MF_VALIDATE_EXTENT(haystack, CLAMPADD(haystack_sz, 1), __MF_CHECK_READ, "strstr haystack");
384   MF_VALIDATE_EXTENT(needle, CLAMPADD(needle_sz, 1), __MF_CHECK_READ, "strstr needle");
385   return strstr (haystack, needle);
386 }
387
388
389 #ifdef HAVE_MEMMEM
390 WRAPPER2(void *, memmem,
391         const void *haystack, size_t haystacklen,
392         const void *needle, size_t needlelen)
393 {
394   TRACE ("%s\n", __PRETTY_FUNCTION__);
395   MF_VALIDATE_EXTENT(haystack, haystacklen, __MF_CHECK_READ, "memmem haystack");
396   MF_VALIDATE_EXTENT(needle, needlelen, __MF_CHECK_READ, "memmem needle");
397   return memmem (haystack, haystacklen, needle, needlelen);
398 }
399 #endif
400
401
402 WRAPPER2(size_t, strlen, const char *s)
403 {
404   size_t result = strlen (s);
405   TRACE ("%s\n", __PRETTY_FUNCTION__);
406   MF_VALIDATE_EXTENT(s, CLAMPADD(result, 1), __MF_CHECK_READ, "strlen region");
407   return result;
408 }
409
410
411 WRAPPER2(size_t, strnlen, const char *s, size_t n)
412 {
413   size_t result = strnlen (s, n);
414   TRACE ("%s\n", __PRETTY_FUNCTION__);
415   MF_VALIDATE_EXTENT(s, result, __MF_CHECK_READ, "strnlen region");
416   return result;
417 }
418
419
420 WRAPPER2(void, bzero, void *s, size_t n)
421 {
422   TRACE ("%s\n", __PRETTY_FUNCTION__);
423   MF_VALIDATE_EXTENT(s, n, __MF_CHECK_WRITE, "bzero region");
424   bzero (s, n);
425 }
426
427
428 #undef bcopy
429 WRAPPER2(void, bcopy, const void *src, void *dest, size_t n)
430 {
431   TRACE ("%s\n", __PRETTY_FUNCTION__);
432   MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "bcopy src");
433   MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "bcopy dest");
434   bcopy (src, dest, n);
435 }
436
437
438 #undef bcmp
439 WRAPPER2(int, bcmp, const void *s1, const void *s2, size_t n)
440 {
441   TRACE ("%s\n", __PRETTY_FUNCTION__);
442   MF_VALIDATE_EXTENT(s1, n, __MF_CHECK_READ, "bcmp 1st arg");
443   MF_VALIDATE_EXTENT(s2, n, __MF_CHECK_READ, "bcmp 2nd arg");
444   return bcmp (s1, s2, n);
445 }
446
447
448 WRAPPER2(char *, index, const char *s, int c)
449 {
450   size_t n = strlen (s);
451   TRACE ("%s\n", __PRETTY_FUNCTION__);
452   MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "index region");
453   return index (s, c);
454 }
455
456
457 WRAPPER2(char *, rindex, const char *s, int c)
458 {
459   size_t n = strlen (s);
460   TRACE ("%s\n", __PRETTY_FUNCTION__);
461   MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "rindex region");
462   return rindex (s, c);
463 }
464
465 /* XXX:  stpcpy, memccpy */
466
467 /* XXX: *printf,*scanf */
468
469 /* XXX: setjmp, longjmp */
470
471 WRAPPER2(char *, asctime, struct tm *tm)
472 {
473   static char *reg_result = NULL;
474   char *result;
475   TRACE ("%s\n", __PRETTY_FUNCTION__);
476   MF_VALIDATE_EXTENT(tm, sizeof (struct tm), __MF_CHECK_READ, "asctime tm");
477   result = asctime (tm);
478   if (reg_result == NULL)
479     {
480       __mf_register (result, strlen (result)+1, __MF_TYPE_STATIC, "asctime string");
481       reg_result = result;
482     }
483   return result;
484 }
485
486
487 WRAPPER2(char *, ctime, const time_t *timep)
488 {
489   static char *reg_result = NULL;
490   char *result;
491   TRACE ("%s\n", __PRETTY_FUNCTION__);
492   MF_VALIDATE_EXTENT(timep, sizeof (time_t), __MF_CHECK_READ, "ctime time");
493   result = ctime (timep);
494   if (reg_result == NULL)
495     {
496       /* XXX: what if asctime and ctime return the same static ptr? */
497       __mf_register (result, strlen (result)+1, __MF_TYPE_STATIC, "ctime string");
498       reg_result = result;
499     }
500   return result;
501 }
502
503
504 WRAPPER2(struct tm*, localtime, const time_t *timep)
505 {
506   static struct tm *reg_result = NULL;
507   struct tm *result;
508   TRACE ("%s\n", __PRETTY_FUNCTION__);
509   MF_VALIDATE_EXTENT(timep, sizeof (time_t), __MF_CHECK_READ, "localtime time");
510   result = localtime (timep);
511   if (reg_result == NULL)
512     {
513       __mf_register (result, sizeof (struct tm), __MF_TYPE_STATIC, "localtime tm");
514       reg_result = result;
515     }
516   return result;
517 }
518
519
520 WRAPPER2(struct tm*, gmtime, const time_t *timep)
521 {
522   static struct tm *reg_result = NULL;
523   struct tm *result;
524   TRACE ("%s\n", __PRETTY_FUNCTION__);
525   MF_VALIDATE_EXTENT(timep, sizeof (time_t), __MF_CHECK_READ, "gmtime time");
526   result = gmtime (timep);
527   if (reg_result == NULL)
528     {
529       __mf_register (result, sizeof (struct tm), __MF_TYPE_STATIC, "gmtime tm");
530       reg_result = result;
531     }
532   return result;
533 }
534
535
536 /* EL start */
537
538 /* The following indicate if the result of the corresponding function
539  * should be explicitly un/registered by the wrapper
540 */
541
542 #ifdef __FreeBSD__
543 #define MF_REGISTER_fopen               __MF_TYPE_STATIC
544 #else
545 #undef  MF_REGISTER_fopen
546 #endif
547 #define MF_RESULT_SIZE_fopen            (sizeof (FILE))
548
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
558
559
560 #include <time.h>
561 WRAPPER2(time_t, time, time_t *timep)
562 {
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);
568 }
569
570
571 WRAPPER2(char *, strerror, int errnum)
572 {
573   char *p;
574   static char * last_strerror = NULL;
575
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;
584 }
585
586
587
588 /* An auxiliary data structure for tracking the hand-made stdio
589    buffers we generate during the fopen/fopen64 hooks.  In a civilized
590    language, this would be a simple dynamically sized FILE*->char*
591    lookup table, but this is C and we get to do it by hand.  */
592 struct mf_filebuffer
593 {
594   FILE *file;
595   char *buffer;
596   struct mf_filebuffer *next;
597 };
598 static struct mf_filebuffer *mf_filebuffers = NULL;
599
600 static void
601 mkbuffer (FILE *f)
602 {
603   /* Reset any buffer automatically provided by libc, since this may
604      have been done via mechanisms that libmudflap couldn't
605      intercept.  */
606   int rc;
607   size_t bufsize = BUFSIZ;
608   int bufmode;
609   char *buffer = malloc (bufsize);
610   struct mf_filebuffer *b = malloc (sizeof (struct mf_filebuffer));
611   assert ((buffer != NULL) && (b != NULL));
612
613   /* Link it into list.  */
614   b->file = f;
615   b->buffer = buffer;
616   b->next = mf_filebuffers;
617   mf_filebuffers = b;
618
619   /* Determine how the file is supposed to be buffered at the moment.  */
620   bufmode = fileno (f) == 2 ? _IONBF : (isatty (fileno (f)) ? _IOLBF : _IOFBF);
621
622   rc = setvbuf (f, buffer, bufmode, bufsize);
623   assert (rc == 0);
624 }
625
626 static void
627 unmkbuffer (FILE *f)
628 {
629   struct mf_filebuffer *b = mf_filebuffers;
630   struct mf_filebuffer **pb = & mf_filebuffers;
631   while (b != NULL)
632     {
633       if (b->file == f)
634         {
635           *pb = b->next;
636           free (b->buffer);
637           free (b);
638           return;
639         }
640       pb = & b->next;
641       b = b->next;
642     }
643 }
644
645
646
647 WRAPPER2(FILE *, fopen, const char *path, const char *mode)
648 {
649   size_t n;
650   FILE *p;
651   TRACE ("%s\n", __PRETTY_FUNCTION__);
652
653   n = strlen (path);
654   MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "fopen path");
655
656   n = strlen (mode);
657   MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "fopen mode");
658
659   p = fopen (path, mode);
660   if (NULL != p) {
661 #ifdef MF_REGISTER_fopen
662     __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "fopen result");
663 #endif
664     MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "fopen result");
665
666     mkbuffer (p);
667   }
668
669   return p;
670 }
671
672
673 WRAPPER2(int, setvbuf, FILE *stream, char *buf, int mode, size_t size)
674 {
675   int rc = 0;
676   TRACE ("%s\n", __PRETTY_FUNCTION__);
677
678   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, "setvbuf stream");
679
680   unmkbuffer (stream);
681
682   if (buf != NULL)
683     MF_VALIDATE_EXTENT (buf, size, __MF_CHECK_WRITE, "setvbuf buffer");
684
685   /* Override the user only if it's an auto-allocated buffer request.  Otherwise
686      assume that the supplied buffer is already known to libmudflap.  */
687   if ((buf == NULL) && ((mode == _IOFBF) || (mode == _IOLBF)))
688     mkbuffer (stream);
689   else
690     rc = setvbuf (stream, buf, mode, size);
691
692   return rc;
693 }
694
695
696 #ifdef HAVE_SETBUF
697 WRAPPER2(int, setbuf, FILE* stream, char *buf)
698 {
699   return __mfwrap_setvbuf (stream, buf, buf ? _IOFBF : _IONBF, BUFSIZ);
700 }
701 #endif
702
703 #ifdef HAVE_SETBUFFER
704 WRAPPER2(int, setbuffer, FILE* stream, char *buf, size_t sz)
705 {
706   return __mfwrap_setvbuf (stream, buf, buf ? _IOFBF : _IONBF, sz);
707 }
708 #endif
709
710 #ifdef HAVE_SETLINEBUF
711 WRAPPER2(int, setlinebuf, FILE* stream)
712 {
713   return __mfwrap_setvbuf(stream, NULL, _IOLBF, 0);
714 }
715 #endif
716
717
718
719 WRAPPER2(FILE *, fdopen, int fd, const char *mode)
720 {
721   size_t n;
722   FILE *p;
723   TRACE ("%s\n", __PRETTY_FUNCTION__);
724
725   n = strlen (mode);
726   MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "fdopen mode");
727
728   p = fdopen (fd, mode);
729   if (NULL != p) {
730 #ifdef MF_REGISTER_fopen
731     __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "fdopen result");
732 #endif
733     MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "fdopen result");
734
735     mkbuffer (p);
736   }
737
738   return p;
739 }
740
741
742 WRAPPER2(FILE *, freopen, const char *path, const char *mode, FILE *s)
743 {
744   size_t n;
745   FILE *p;
746   TRACE ("%s\n", __PRETTY_FUNCTION__);
747
748   n = strlen (path);
749   MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "freopen path");
750
751   MF_VALIDATE_EXTENT (s, (sizeof (*s)), __MF_CHECK_WRITE, "freopen stream");
752   unmkbuffer (s);
753
754   n = strlen (mode);
755   MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "freopen mode");
756
757   p = freopen (path, mode, s);
758   if (NULL != p) {
759 #ifdef MF_REGISTER_fopen
760     __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "freopen result");
761 #endif
762     MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "freopen result");
763
764     mkbuffer (p);
765   }
766
767   return p;
768 }
769
770
771 #ifdef HAVE_FOPEN64
772 WRAPPER2(FILE *, fopen64, const char *path, const char *mode)
773 {
774   size_t n;
775   FILE *p;
776   TRACE ("%s\n", __PRETTY_FUNCTION__);
777
778   n = strlen (path);
779   MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "fopen64 path");
780
781   n = strlen (mode);
782   MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "fopen64 mode");
783
784   p = fopen64 (path, mode);
785   if (NULL != p) {
786 #ifdef MF_REGISTER_fopen
787     __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "fopen64 result");
788 #endif
789     MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "fopen64 result");
790
791     mkbuffer (p);
792   }
793
794   return p;
795 }
796 #endif
797
798
799 #ifdef HAVE_FREOPEN64
800 WRAPPER2(FILE *, freopen64, const char *path, const char *mode, FILE *s)
801 {
802   size_t n;
803   FILE *p;
804   TRACE ("%s\n", __PRETTY_FUNCTION__);
805
806   n = strlen (path);
807   MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "freopen64 path");
808
809   MF_VALIDATE_EXTENT (s, (sizeof (*s)), __MF_CHECK_WRITE, "freopen64 stream");
810   unmkbuffer (s);
811
812   n = strlen (mode);
813   MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "freopen64 mode");
814
815   p = freopen (path, mode, s);
816   if (NULL != p) {
817 #ifdef MF_REGISTER_fopen
818     __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "freopen64 result");
819 #endif
820     MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "freopen64 result");
821
822     mkbuffer (p);
823   }
824
825   return p;
826 }
827 #endif
828
829
830 WRAPPER2(int, fclose, FILE *stream)
831 {
832   int resp;
833   TRACE ("%s\n", __PRETTY_FUNCTION__);
834   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
835     "fclose stream");
836   resp = fclose (stream);
837 #ifdef MF_REGISTER_fopen
838   __mf_unregister (stream, sizeof (*stream), MF_REGISTER_fopen);
839 #endif
840   unmkbuffer (stream);
841
842   return resp;
843 }
844
845
846 WRAPPER2(size_t, fread, void *ptr, size_t size, size_t nmemb, FILE *stream)
847 {
848   TRACE ("%s\n", __PRETTY_FUNCTION__);
849   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
850     "fread stream");
851   MF_VALIDATE_EXTENT (ptr, size * nmemb, __MF_CHECK_WRITE, "fread buffer");
852   return fread (ptr, size, nmemb, stream);
853 }
854
855
856 WRAPPER2(size_t, fwrite, const void *ptr, size_t size, size_t nmemb,
857         FILE *stream)
858 {
859   TRACE ("%s\n", __PRETTY_FUNCTION__);
860   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
861     "fwrite stream");
862   MF_VALIDATE_EXTENT (ptr, size * nmemb, __MF_CHECK_READ, "fwrite buffer");
863   return fwrite (ptr, size, nmemb, stream);
864 }
865
866
867 WRAPPER2(int, fgetc, FILE *stream)
868 {
869   TRACE ("%s\n", __PRETTY_FUNCTION__);
870   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
871     "fgetc stream");
872   return fgetc (stream);
873 }
874
875
876 WRAPPER2(char *, fgets, char *s, int size, FILE *stream)
877 {
878   TRACE ("%s\n", __PRETTY_FUNCTION__);
879   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
880     "fgets stream");
881   MF_VALIDATE_EXTENT (s, size, __MF_CHECK_WRITE, "fgets buffer");
882   return fgets (s, size, stream);
883 }
884
885
886 WRAPPER2(int, getc, FILE *stream)
887 {
888   TRACE ("%s\n", __PRETTY_FUNCTION__);
889   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
890     "getc stream");
891   return getc (stream);
892 }
893
894
895 WRAPPER2(char *, gets, char *s)
896 {
897   TRACE ("%s\n", __PRETTY_FUNCTION__);
898   MF_VALIDATE_EXTENT (s, 1, __MF_CHECK_WRITE, "gets buffer");
899   /* Avoid link-time warning... */
900   s = fgets (s, INT_MAX, stdin);
901   if (NULL != s) {      /* better late than never */
902     size_t n = strlen (s);
903     MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_WRITE, "gets buffer");
904   }
905   return s;
906 }
907
908
909 WRAPPER2(int, ungetc, int c, FILE *stream)
910 {
911   TRACE ("%s\n", __PRETTY_FUNCTION__);
912   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
913      "ungetc stream");
914   return ungetc (c, stream);
915 }
916
917
918 WRAPPER2(int, fputc, int c, FILE *stream)
919 {
920   TRACE ("%s\n", __PRETTY_FUNCTION__);
921   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
922     "fputc stream");
923   return fputc (c, stream);
924 }
925
926
927 WRAPPER2(int, fputs, const char *s, FILE *stream)
928 {
929   size_t n;
930   TRACE ("%s\n", __PRETTY_FUNCTION__);
931   n = strlen (s);
932   MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "fputs buffer");
933   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
934     "fputs stream");
935   return fputs (s, stream);
936 }
937
938
939 WRAPPER2(int, putc, int c, FILE *stream)
940 {
941   TRACE ("%s\n", __PRETTY_FUNCTION__);
942   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
943     "putc stream");
944   return putc (c, stream);
945 }
946
947
948 WRAPPER2(int, puts, const char *s)
949 {
950   size_t n;
951   TRACE ("%s\n", __PRETTY_FUNCTION__);
952   n = strlen (s);
953   MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "puts buffer");
954   return puts (s);
955 }
956
957
958 WRAPPER2(void, clearerr, FILE *stream)
959 {
960   TRACE ("%s\n", __PRETTY_FUNCTION__);
961   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
962     "clearerr stream");
963   clearerr (stream);
964 }
965
966
967 WRAPPER2(int, feof, FILE *stream)
968 {
969   TRACE ("%s\n", __PRETTY_FUNCTION__);
970   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
971     "feof stream");
972   return feof (stream);
973 }
974
975
976 WRAPPER2(int, ferror, FILE *stream)
977 {
978   TRACE ("%s\n", __PRETTY_FUNCTION__);
979   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
980     "ferror stream");
981   return ferror (stream);
982 }
983
984
985 WRAPPER2(int, fileno, FILE *stream)
986 {
987   TRACE ("%s\n", __PRETTY_FUNCTION__);
988   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
989     "fileno stream");
990   return fileno (stream);
991 }
992
993
994 WRAPPER2(int, printf, const char *format, ...)
995 {
996   size_t n;
997   va_list ap;
998   int result;
999   TRACE ("%s\n", __PRETTY_FUNCTION__);
1000   n = strlen (format);
1001   MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
1002     "printf format");
1003   va_start (ap, format);
1004   result = vprintf (format, ap);
1005   va_end (ap);
1006   return result;
1007 }
1008
1009
1010 WRAPPER2(int, fprintf, FILE *stream, const char *format, ...)
1011 {
1012   size_t n;
1013   va_list ap;
1014   int result;
1015   TRACE ("%s\n", __PRETTY_FUNCTION__);
1016   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1017     "fprintf stream");
1018   n = strlen (format);
1019   MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
1020     "fprintf format");
1021   va_start (ap, format);
1022   result = vfprintf (stream, format, ap);
1023   va_end (ap);
1024   return result;
1025 }
1026
1027
1028 WRAPPER2(int, sprintf, char *str, const char *format, ...)
1029 {
1030   size_t n;
1031   va_list ap;
1032   int result;
1033   TRACE ("%s\n", __PRETTY_FUNCTION__);
1034   MF_VALIDATE_EXTENT (str, 1, __MF_CHECK_WRITE, "sprintf str");
1035   n = strlen (format);
1036   MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
1037     "sprintf format");
1038   va_start (ap, format);
1039   result = vsprintf (str, format, ap);
1040   va_end (ap);
1041   n = strlen (str);
1042   MF_VALIDATE_EXTENT (str, CLAMPADD(n, 1), __MF_CHECK_WRITE, "sprintf str");
1043   return result;
1044 }
1045
1046
1047 WRAPPER2(int, snprintf, char *str, size_t size, const char *format, ...)
1048 {
1049   size_t n;
1050   va_list ap;
1051   int result;
1052   TRACE ("%s\n", __PRETTY_FUNCTION__);
1053   MF_VALIDATE_EXTENT (str, size, __MF_CHECK_WRITE, "snprintf str");
1054   n = strlen (format);
1055   MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
1056     "snprintf format");
1057   va_start (ap, format);
1058   result = vsnprintf (str, size, format, ap);
1059   va_end (ap);
1060   return result;
1061 }
1062
1063
1064 WRAPPER2(int, vprintf,  const char *format, va_list ap)
1065 {
1066   size_t n;
1067   TRACE ("%s\n", __PRETTY_FUNCTION__);
1068   n = strlen (format);
1069   MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
1070     "vprintf format");
1071   return vprintf (format, ap);
1072 }
1073
1074
1075 WRAPPER2(int, vfprintf, FILE *stream, const char *format, va_list ap)
1076 {
1077   size_t n;
1078   TRACE ("%s\n", __PRETTY_FUNCTION__);
1079   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1080     "vfprintf stream");
1081   n = strlen (format);
1082   MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
1083     "vfprintf format");
1084   return vfprintf (stream, format, ap);
1085 }
1086
1087
1088 WRAPPER2(int, vsprintf, char *str, const char *format, va_list ap)
1089 {
1090   size_t n;
1091   int result;
1092   TRACE ("%s\n", __PRETTY_FUNCTION__);
1093   MF_VALIDATE_EXTENT (str, 1, __MF_CHECK_WRITE, "vsprintf str");
1094   n = strlen (format);
1095   MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
1096     "vsprintf format");
1097   result = vsprintf (str, format, ap);
1098   n = strlen (str);
1099   MF_VALIDATE_EXTENT (str, CLAMPADD(n, 1), __MF_CHECK_WRITE, "vsprintf str");
1100   return result;
1101 }
1102
1103
1104 WRAPPER2(int, vsnprintf, char *str, size_t size, const char *format,
1105         va_list ap)
1106 {
1107   size_t n;
1108   TRACE ("%s\n", __PRETTY_FUNCTION__);
1109   MF_VALIDATE_EXTENT (str, size, __MF_CHECK_WRITE, "vsnprintf str");
1110   n = strlen (format);
1111   MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
1112     "vsnprintf format");
1113   return vsnprintf (str, size, format, ap);
1114 }
1115
1116
1117 WRAPPER2(int , access, const char *path, int mode)
1118 {
1119   size_t n;
1120   TRACE ("%s\n", __PRETTY_FUNCTION__);
1121   n = strlen (path);
1122   MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "access path");
1123   return access (path, mode);
1124 }
1125
1126
1127 WRAPPER2(int , remove, const char *path)
1128 {
1129   size_t n;
1130   TRACE ("%s\n", __PRETTY_FUNCTION__);
1131   n = strlen (path);
1132   MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "remove path");
1133   return remove (path);
1134 }
1135
1136
1137 WRAPPER2(int, fflush, FILE *stream)
1138 {
1139   TRACE ("%s\n", __PRETTY_FUNCTION__);
1140   if (stream != NULL)
1141     MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1142                         "fflush stream");
1143   return fflush (stream);
1144 }
1145
1146
1147 WRAPPER2(int, fseek, FILE *stream, long offset, int whence)
1148 {
1149   TRACE ("%s\n", __PRETTY_FUNCTION__);
1150   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1151     "fseek stream");
1152   return fseek (stream, offset, whence);
1153 }
1154
1155
1156 #ifdef HAVE_FSEEKO64
1157 WRAPPER2(int, fseeko64, FILE *stream, off64_t offset, int whence)
1158 {
1159   TRACE ("%s\n", __PRETTY_FUNCTION__);
1160   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1161     "fseeko64 stream");
1162   return fseeko64 (stream, offset, whence);
1163 }
1164 #endif
1165
1166
1167 WRAPPER2(long, ftell, FILE *stream)
1168 {
1169   TRACE ("%s\n", __PRETTY_FUNCTION__);
1170   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1171     "ftell stream");
1172   return ftell (stream);
1173 }
1174
1175
1176 #ifdef HAVE_FTELLO64
1177 WRAPPER2(off64_t, ftello64, FILE *stream)
1178 {
1179   TRACE ("%s\n", __PRETTY_FUNCTION__);
1180   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1181     "ftello64 stream");
1182   return ftello64 (stream);
1183 }
1184 #endif
1185
1186
1187 WRAPPER2(void, rewind, FILE *stream)
1188 {
1189   TRACE ("%s\n", __PRETTY_FUNCTION__);
1190   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1191     "rewind stream");
1192   rewind (stream);
1193 }
1194
1195
1196 WRAPPER2(int, fgetpos, FILE *stream, fpos_t *pos)
1197 {
1198   TRACE ("%s\n", __PRETTY_FUNCTION__);
1199   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1200     "fgetpos stream");
1201   MF_VALIDATE_EXTENT (pos, sizeof (*pos), __MF_CHECK_WRITE, "fgetpos pos");
1202   return fgetpos (stream, pos);
1203 }
1204
1205
1206 WRAPPER2(int, fsetpos, FILE *stream, fpos_t *pos)
1207 {
1208   TRACE ("%s\n", __PRETTY_FUNCTION__);
1209   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1210     "fsetpos stream");
1211   MF_VALIDATE_EXTENT (pos, sizeof (*pos), __MF_CHECK_READ, "fsetpos pos");
1212   return fsetpos (stream, pos);
1213 }
1214
1215
1216 WRAPPER2(int , stat, const char *path, struct stat *buf)
1217 {
1218   size_t n;
1219   TRACE ("%s\n", __PRETTY_FUNCTION__);
1220   n = strlen (path);
1221   MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "stat path");
1222   MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ, "stat buf");
1223   return stat (path, buf);
1224 }
1225
1226
1227 #ifdef HAVE_STAT64
1228 WRAPPER2(int , stat64, const char *path, struct stat64 *buf)
1229 {
1230   size_t n;
1231   TRACE ("%s\n", __PRETTY_FUNCTION__);
1232   n = strlen (path);
1233   MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "stat64 path");
1234   MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ, "stat64 buf");
1235   return stat64 (path, buf);
1236 }
1237 #endif
1238
1239
1240 WRAPPER2(int , fstat, int filedes, struct stat *buf)
1241 {
1242   TRACE ("%s\n", __PRETTY_FUNCTION__);
1243   MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ, "fstat buf");
1244   return fstat (filedes, buf);
1245 }
1246
1247
1248 WRAPPER2(int , lstat, const char *path, struct stat *buf)
1249 {
1250   size_t n;
1251   TRACE ("%s\n", __PRETTY_FUNCTION__);
1252   n = strlen (path);
1253   MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "lstat path");
1254   MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ, "lstat buf");
1255   return lstat (path, buf);
1256 }
1257
1258
1259 WRAPPER2(int , mkfifo, const char *path, mode_t mode)
1260 {
1261   size_t n;
1262   TRACE ("%s\n", __PRETTY_FUNCTION__);
1263   n = strlen (path);
1264   MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "mkfifo path");
1265   return mkfifo (path, mode);
1266 }
1267
1268
1269 #ifdef HAVE_DIRENT_H
1270 WRAPPER2(DIR *, opendir, const char *path)
1271 {
1272   DIR *p;
1273   size_t n;
1274   TRACE ("%s\n", __PRETTY_FUNCTION__);
1275   n = strlen (path);
1276   MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "opendir path");
1277
1278   p = opendir (path);
1279   if (NULL != p) {
1280 #ifdef MF_REGISTER_opendir
1281     __mf_register (p, MF_RESULT_SIZE_opendir, MF_REGISTER_opendir,
1282       "opendir result");
1283 #endif
1284     MF_VALIDATE_EXTENT (p, MF_RESULT_SIZE_opendir, __MF_CHECK_WRITE,
1285       "opendir result");
1286   }
1287   return p;
1288 }
1289
1290
1291 WRAPPER2(int, closedir, DIR *dir)
1292 {
1293   TRACE ("%s\n", __PRETTY_FUNCTION__);
1294   MF_VALIDATE_EXTENT (dir, 0, __MF_CHECK_WRITE, "closedir dir");
1295 #ifdef MF_REGISTER_opendir
1296   __mf_unregister (dir, MF_RESULT_SIZE_opendir, MF_REGISTER_opendir);
1297 #endif
1298   return closedir (dir);
1299 }
1300
1301
1302 WRAPPER2(struct dirent *, readdir, DIR *dir)
1303 {
1304   struct dirent *p;
1305   TRACE ("%s\n", __PRETTY_FUNCTION__);
1306   MF_VALIDATE_EXTENT (dir, 0, __MF_CHECK_READ, "readdir dir");
1307   p = readdir (dir);
1308   if (NULL != p) {
1309 #ifdef MF_REGISTER_readdir
1310     __mf_register (p, sizeof (*p), MF_REGISTER_readdir, "readdir result");
1311 #endif
1312     MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "readdir result");
1313   }
1314   return p;
1315 }
1316 #endif
1317
1318
1319 #ifdef HAVE_SYS_SOCKET_H
1320
1321 WRAPPER2(int, recv, int s, void *buf, size_t len, int flags)
1322 {
1323   TRACE ("%s\n", __PRETTY_FUNCTION__);
1324   MF_VALIDATE_EXTENT (buf, len, __MF_CHECK_WRITE, "recv buf");
1325   return recv (s, buf, len, flags);
1326 }
1327
1328
1329 WRAPPER2(int, recvfrom, int s, void *buf, size_t len, int flags,
1330                 struct sockaddr *from, socklen_t *fromlen)
1331 {
1332   TRACE ("%s\n", __PRETTY_FUNCTION__);
1333   MF_VALIDATE_EXTENT (buf, len, __MF_CHECK_WRITE, "recvfrom buf");
1334   MF_VALIDATE_EXTENT (from, (size_t)*fromlen, __MF_CHECK_WRITE,
1335     "recvfrom from");
1336   return recvfrom (s, buf, len, flags, from, fromlen);
1337 }
1338
1339
1340 WRAPPER2(int, recvmsg, int s, struct msghdr *msg, int flags)
1341 {
1342   TRACE ("%s\n", __PRETTY_FUNCTION__);
1343   MF_VALIDATE_EXTENT (msg, sizeof (*msg), __MF_CHECK_WRITE, "recvmsg msg");
1344   return recvmsg (s, msg, flags);
1345 }
1346
1347
1348 WRAPPER2(int, send, int s, const void *msg, size_t len, int flags)
1349 {
1350   TRACE ("%s\n", __PRETTY_FUNCTION__);
1351   MF_VALIDATE_EXTENT (msg, len, __MF_CHECK_READ, "send msg");
1352   return send (s, msg, len, flags);
1353 }
1354
1355
1356 WRAPPER2(int, sendto, int s, const void *msg, size_t len, int flags,
1357                 const struct sockaddr *to, socklen_t tolen)
1358 {
1359   TRACE ("%s\n", __PRETTY_FUNCTION__);
1360   MF_VALIDATE_EXTENT (msg, len, __MF_CHECK_READ, "sendto msg");
1361   MF_VALIDATE_EXTENT (to, (size_t)tolen, __MF_CHECK_WRITE, "sendto to");
1362   return sendto (s, msg, len, flags, to, tolen);
1363 }
1364
1365
1366 WRAPPER2(int, sendmsg, int s, const void *msg, int flags)
1367 {
1368   TRACE ("%s\n", __PRETTY_FUNCTION__);
1369   MF_VALIDATE_EXTENT (msg, sizeof (*msg), __MF_CHECK_READ, "sendmsg msg");
1370   return sendmsg (s, msg, flags);
1371 }
1372
1373
1374 WRAPPER2(int, setsockopt, int s, int level, int optname, const void *optval,
1375         socklen_t optlen)
1376 {
1377   TRACE ("%s\n", __PRETTY_FUNCTION__);
1378   MF_VALIDATE_EXTENT (optval, (size_t)optlen, __MF_CHECK_READ,
1379     "setsockopt optval");
1380   return setsockopt (s, level, optname, optval, optlen);
1381 }
1382
1383
1384 WRAPPER2(int, getsockopt, int s, int level, int optname, void *optval,
1385                 socklen_t *optlen)
1386 {
1387   TRACE ("%s\n", __PRETTY_FUNCTION__);
1388   MF_VALIDATE_EXTENT (optval, (size_t)*optlen, __MF_CHECK_WRITE,
1389     "getsockopt optval");
1390   return getsockopt (s, level, optname, optval, optlen);
1391 }
1392
1393
1394 WRAPPER2(int, accept, int s, struct  sockaddr *addr, socklen_t *addrlen)
1395 {
1396   TRACE ("%s\n", __PRETTY_FUNCTION__);
1397   if (addr != NULL)
1398     MF_VALIDATE_EXTENT (addr, (size_t)*addrlen, __MF_CHECK_WRITE, "accept addr");
1399   return accept (s, addr, addrlen);
1400 }
1401
1402
1403 WRAPPER2(int, bind, int sockfd, struct  sockaddr *addr, socklen_t addrlen)
1404 {
1405   TRACE ("%s\n", __PRETTY_FUNCTION__);
1406   MF_VALIDATE_EXTENT (addr, (size_t)addrlen, __MF_CHECK_WRITE, "bind addr");
1407   return bind (sockfd, addr, addrlen);
1408 }
1409
1410
1411 WRAPPER2(int, connect, int sockfd, const struct sockaddr  *addr,
1412         socklen_t addrlen)
1413 {
1414   TRACE ("%s\n", __PRETTY_FUNCTION__);
1415   MF_VALIDATE_EXTENT (addr, (size_t)addrlen, __MF_CHECK_READ,
1416     "connect addr");
1417   return connect (sockfd, addr, addrlen);
1418 }
1419
1420 #endif /* HAVE_SYS_SOCKET_H */
1421
1422
1423 WRAPPER2(int, gethostname, char *name, size_t len)
1424 {
1425   TRACE ("%s\n", __PRETTY_FUNCTION__);
1426   MF_VALIDATE_EXTENT (name, len, __MF_CHECK_WRITE, "gethostname name");
1427   return gethostname (name, len);
1428 }
1429
1430
1431 #ifdef HAVE_SETHOSTNAME
1432 WRAPPER2(int, sethostname, const char *name, size_t len)
1433 {
1434   TRACE ("%s\n", __PRETTY_FUNCTION__);
1435   MF_VALIDATE_EXTENT (name, len, __MF_CHECK_READ, "sethostname name");
1436   return sethostname (name, len);
1437 }
1438 #endif
1439
1440
1441 #ifdef HAVE_NETDB_H
1442
1443 WRAPPER2(struct hostent *, gethostbyname, const char *name)
1444 {
1445   struct hostent *p;
1446   char **ss;
1447   char *s;
1448   size_t n;
1449   int nreg;
1450   TRACE ("%s\n", __PRETTY_FUNCTION__);
1451   n = strlen (name);
1452   MF_VALIDATE_EXTENT (name, CLAMPADD(n, 1), __MF_CHECK_READ,
1453     "gethostbyname name");
1454   p = gethostbyname (name);
1455   if (NULL != p) {
1456 #ifdef MF_REGISTER_gethostbyname
1457     __mf_register (p, sizeof (*p), MF_REGISTER_gethostbyname,
1458       "gethostbyname result");
1459 #endif
1460     MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE,
1461       "gethostbyname result");
1462     if (NULL != (s = p->h_name)) {
1463       n = strlen (s);
1464       n = CLAMPADD(n, 1);
1465 #ifdef MF_REGISTER_gethostbyname_items
1466       __mf_register (s, n, MF_REGISTER_gethostbyname_items,
1467         "gethostbyname result->h_name");
1468 #endif
1469       MF_VALIDATE_EXTENT (s, n, __MF_CHECK_WRITE,
1470         "gethostbyname result->h_name");
1471     }
1472
1473     if (NULL != (ss = p->h_aliases)) {
1474       for (nreg = 1;; ++nreg) {
1475         s = *ss++;
1476         if (NULL == s)
1477           break;
1478         n = strlen (s);
1479         n = CLAMPADD(n, 1);
1480 #ifdef MF_REGISTER_gethostbyname_items
1481         __mf_register (s, n, MF_REGISTER_gethostbyname_items,
1482           "gethostbyname result->h_aliases[]");
1483 #endif
1484         MF_VALIDATE_EXTENT (s, n, __MF_CHECK_WRITE,
1485           "gethostbyname result->h_aliases[]");
1486       }
1487       nreg *= sizeof (*p->h_aliases);
1488 #ifdef MF_REGISTER_gethostbyname_items
1489       __mf_register (p->h_aliases, nreg, MF_REGISTER_gethostbyname_items,
1490         "gethostbyname result->h_aliases");
1491 #endif
1492       MF_VALIDATE_EXTENT (p->h_aliases, nreg, __MF_CHECK_WRITE,
1493         "gethostbyname result->h_aliases");
1494     }
1495
1496     if (NULL != (ss = p->h_addr_list)) {
1497       for (nreg = 1;; ++nreg) {
1498         s = *ss++;
1499         if (NULL == s)
1500           break;
1501 #ifdef MF_REGISTER_gethostbyname_items
1502         __mf_register (s, p->h_length, MF_REGISTER_gethostbyname_items,
1503           "gethostbyname result->h_addr_list[]");
1504 #endif
1505         MF_VALIDATE_EXTENT (s, p->h_length, __MF_CHECK_WRITE,
1506           "gethostbyname result->h_addr_list[]");
1507       }
1508       nreg *= sizeof (*p->h_addr_list);
1509 #ifdef MF_REGISTER_gethostbyname_items
1510       __mf_register (p->h_addr_list, nreg, MF_REGISTER_gethostbyname_items,
1511         "gethostbyname result->h_addr_list");
1512 #endif
1513       MF_VALIDATE_EXTENT (p->h_addr_list, nreg, __MF_CHECK_WRITE,
1514         "gethostbyname result->h_addr_list");
1515     }
1516   }
1517   return p;
1518 }
1519
1520 #endif /* HAVE_NETDB_H */
1521
1522
1523 #ifdef HAVE_SYS_WAIT_H
1524
1525 WRAPPER2(pid_t, wait, int *status)
1526 {
1527   TRACE ("%s\n", __PRETTY_FUNCTION__);
1528   if (NULL != status)
1529     MF_VALIDATE_EXTENT (status, sizeof (*status), __MF_CHECK_WRITE,
1530       "wait status");
1531   return wait (status);
1532 }
1533
1534
1535 WRAPPER2(pid_t, waitpid, pid_t pid, int *status, int options)
1536 {
1537   TRACE ("%s\n", __PRETTY_FUNCTION__);
1538   if (NULL != status)
1539     MF_VALIDATE_EXTENT (status, sizeof (*status), __MF_CHECK_WRITE,
1540       "waitpid status");
1541   return waitpid (pid, status, options);
1542 }
1543
1544 #endif /* HAVE_SYS_WAIT_H */
1545
1546
1547 WRAPPER2(FILE *, popen, const char *command, const char *mode)
1548 {
1549   size_t n;
1550   FILE *p;
1551   TRACE ("%s\n", __PRETTY_FUNCTION__);
1552
1553   n = strlen (command);
1554   MF_VALIDATE_EXTENT (command, CLAMPADD(n, 1), __MF_CHECK_READ, "popen path");
1555
1556   n = strlen (mode);
1557   MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "popen mode");
1558
1559   p = popen (command, mode);
1560   if (NULL != p) {
1561 #ifdef MF_REGISTER_fopen
1562     __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "popen result");
1563 #endif
1564     MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "popen result");
1565   }
1566   return p;
1567 }
1568
1569
1570 WRAPPER2(int, pclose, FILE *stream)
1571 {
1572   int resp;
1573   TRACE ("%s\n", __PRETTY_FUNCTION__);
1574   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1575     "pclose stream");
1576   resp = pclose (stream);
1577 #ifdef MF_REGISTER_fopen
1578   __mf_unregister (stream, sizeof (*stream), MF_REGISTER_fopen);
1579 #endif
1580   return resp;
1581 }
1582
1583
1584 WRAPPER2(int, execve, const char *path, char *const argv [],
1585         char *const envp[])
1586 {
1587   size_t n;
1588   char *const *p;
1589   const char *s;
1590   TRACE ("%s\n", __PRETTY_FUNCTION__);
1591
1592   n = strlen (path);
1593   MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "execve path");
1594
1595   for (p = argv;;) {
1596     MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_READ, "execve *argv");
1597     s = *p++;
1598     if (NULL == s)
1599       break;
1600     n = strlen (s);
1601     MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "execve **argv");
1602   }
1603
1604   for (p = envp;;) {
1605     MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_READ, "execve *envp");
1606     s = *p++;
1607     if (NULL == s)
1608       break;
1609     n = strlen (s);
1610     MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "execve **envp");
1611   }
1612   return execve (path, argv, envp);
1613 }
1614
1615
1616 WRAPPER2(int, execv, const char *path, char *const argv [])
1617 {
1618   size_t n;
1619   char *const *p;
1620   const char *s;
1621   TRACE ("%s\n", __PRETTY_FUNCTION__);
1622
1623   n = strlen (path);
1624   MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "execv path");
1625
1626   for (p = argv;;) {
1627     MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_READ, "execv *argv");
1628     s = *p++;
1629     if (NULL == s)
1630       break;
1631     n = strlen (s);
1632     MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "execv **argv");
1633   }
1634   return execv (path, argv);
1635 }
1636
1637
1638 WRAPPER2(int, execvp, const char *path, char *const argv [])
1639 {
1640   size_t n;
1641   char *const *p;
1642   const char *s;
1643   TRACE ("%s\n", __PRETTY_FUNCTION__);
1644
1645   n = strlen (path);
1646   MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "execvp path");
1647
1648   for (p = argv;;) {
1649     MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_READ, "execvp *argv");
1650     s = *p++;
1651     if (NULL == s)
1652       break;
1653     n = strlen (s);
1654     MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "execvp **argv");
1655   }
1656   return execvp (path, argv);
1657 }
1658
1659
1660 WRAPPER2(int, system, const char *string)
1661 {
1662   size_t n;
1663   TRACE ("%s\n", __PRETTY_FUNCTION__);
1664   n = strlen (string);
1665   MF_VALIDATE_EXTENT (string, CLAMPADD(n, 1), __MF_CHECK_READ,
1666     "system string");
1667   return system (string);
1668 }
1669
1670
1671 WRAPPER2(void *, dlopen, const char *path, int flags)
1672 {
1673   void *p;
1674   size_t n;
1675   TRACE ("%s\n", __PRETTY_FUNCTION__);
1676   n = strlen (path);
1677   MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "dlopen path");
1678   p = dlopen (path, flags);
1679   if (NULL != p) {
1680 #ifdef MF_REGISTER_dlopen
1681     __mf_register (p, 0, MF_REGISTER_dlopen, "dlopen result");
1682 #endif
1683     MF_VALIDATE_EXTENT (p, 0, __MF_CHECK_WRITE, "dlopen result");
1684   }
1685   return p;
1686 }
1687
1688
1689 WRAPPER2(int, dlclose, void *handle)
1690 {
1691   int resp;
1692   TRACE ("%s\n", __PRETTY_FUNCTION__);
1693   MF_VALIDATE_EXTENT (handle, 0, __MF_CHECK_READ, "dlclose handle");
1694   resp = dlclose (handle);
1695 #ifdef MF_REGISTER_dlopen
1696   __mf_unregister (handle, 0, MF_REGISTER_dlopen);
1697 #endif
1698   return resp;
1699 }
1700
1701
1702 WRAPPER2(char *, dlerror)
1703 {
1704   char *p;
1705   TRACE ("%s\n", __PRETTY_FUNCTION__);
1706   p = dlerror ();
1707   if (NULL != p) {
1708     size_t n;
1709     n = strlen (p);
1710     n = CLAMPADD(n, 1);
1711 #ifdef MF_REGISTER_dlerror
1712     __mf_register (p, n, MF_REGISTER_dlerror, "dlerror result");
1713 #endif
1714     MF_VALIDATE_EXTENT (p, n, __MF_CHECK_WRITE, "dlerror result");
1715   }
1716   return p;
1717 }
1718
1719
1720 WRAPPER2(void *, dlsym, void *handle, char *symbol)
1721 {
1722   size_t n;
1723   void *p;
1724   TRACE ("%s\n", __PRETTY_FUNCTION__);
1725   MF_VALIDATE_EXTENT (handle, 0, __MF_CHECK_READ, "dlsym handle");
1726   n = strlen (symbol);
1727   MF_VALIDATE_EXTENT (symbol, CLAMPADD(n, 1), __MF_CHECK_READ, "dlsym symbol");
1728   p = dlsym (handle, symbol);
1729   if (NULL != p) {
1730 #ifdef MF_REGISTER_dlsym
1731     __mf_register (p, 0, MF_REGISTER_dlsym, "dlsym result");
1732 #endif
1733     MF_VALIDATE_EXTENT (p, 0, __MF_CHECK_WRITE, "dlsym result");
1734   }
1735   return p;
1736 }
1737
1738
1739 #if defined (HAVE_SYS_IPC_H) && defined (HAVE_SYS_SEM_H) && defined (HAVE_SYS_SHM_H)
1740
1741 WRAPPER2(int, semop, int semid, struct sembuf *sops, unsigned nsops)
1742 {
1743   TRACE ("%s\n", __PRETTY_FUNCTION__);
1744   MF_VALIDATE_EXTENT (sops, sizeof (*sops) * nsops, __MF_CHECK_READ,
1745     "semop sops");
1746   return semop (semid, sops, nsops);
1747 }
1748
1749
1750 #ifndef HAVE_UNION_SEMUN
1751 union semun {
1752         int val;                        /* value for SETVAL */
1753         struct semid_ds *buf;           /* buffer for IPC_STAT, IPC_SET */
1754         unsigned short int *array;      /* array for GETALL, SETALL */
1755         struct seminfo *__buf;          /* buffer for IPC_INFO */
1756 };
1757 #endif
1758 WRAPPER2(int, semctl, int semid, int semnum, int cmd, union semun arg)
1759 {
1760   TRACE ("%s\n", __PRETTY_FUNCTION__);
1761   switch (cmd) {
1762   case IPC_STAT:
1763     MF_VALIDATE_EXTENT (arg.buf, sizeof (*arg.buf), __MF_CHECK_WRITE,
1764       "semctl buf");
1765     break;
1766   case IPC_SET:
1767     MF_VALIDATE_EXTENT (arg.buf, sizeof (*arg.buf), __MF_CHECK_READ,
1768       "semctl buf");
1769     break;
1770   case GETALL:
1771     MF_VALIDATE_EXTENT (arg.array, sizeof (*arg.array), __MF_CHECK_WRITE,
1772       "semctl array");
1773   case SETALL:
1774     MF_VALIDATE_EXTENT (arg.array, sizeof (*arg.array), __MF_CHECK_READ,
1775       "semctl array");
1776     break;
1777 #ifdef IPC_INFO
1778   /* FreeBSD 5.1 And Cygwin headers include IPC_INFO but not the __buf field.  */
1779 #if !defined(__FreeBSD__) && !defined(__CYGWIN__)
1780   case IPC_INFO:
1781     MF_VALIDATE_EXTENT (arg.__buf, sizeof (*arg.__buf), __MF_CHECK_WRITE,
1782       "semctl __buf");
1783     break;
1784 #endif
1785 #endif
1786   default:
1787     break;
1788   }
1789   return semctl (semid, semnum, cmd, arg);
1790 }
1791
1792
1793 WRAPPER2(int, shmctl, int shmid, int cmd, struct shmid_ds *buf)
1794 {
1795   TRACE ("%s\n", __PRETTY_FUNCTION__);
1796   switch (cmd) {
1797   case IPC_STAT:
1798     MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_WRITE,
1799       "shmctl buf");
1800     break;
1801   case IPC_SET:
1802     MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ,
1803       "shmctl buf");
1804     break;
1805   default:
1806     break;
1807   }
1808   return shmctl (shmid, cmd, buf);
1809 }
1810
1811
1812 WRAPPER2(void *, shmat, int shmid, const void *shmaddr, int shmflg)
1813 {
1814   void *p;
1815   TRACE ("%s\n", __PRETTY_FUNCTION__);
1816   p = shmat (shmid, shmaddr, shmflg);
1817 #ifdef MF_REGISTER_shmat
1818   if (NULL != p) {
1819     struct shmid_ds buf;
1820     __mf_register (p, shmctl (shmid, IPC_STAT, &buf) ? 0 : buf.shm_segsz,
1821       MF_REGISTER_shmat, "shmat result");
1822   }
1823 #endif
1824   return p;
1825 }
1826
1827
1828 WRAPPER2(int, shmdt, const void *shmaddr)
1829 {
1830   int resp;
1831   TRACE ("%s\n", __PRETTY_FUNCTION__);
1832   resp = shmdt (shmaddr);
1833 #ifdef MF_REGISTER_shmat
1834   __mf_unregister ((void *)shmaddr, 0, MF_REGISTER_shmat);
1835 #endif
1836   return resp;
1837 }
1838
1839
1840 #endif /* HAVE_SYS_IPC/SEM/SHM_H */
1841
1842
1843
1844 /* ctype stuff.  This is host-specific by necessity, as the arrays
1845    that is used by most is*()/to*() macros are implementation-defined.  */
1846
1847 /* GLIBC 2.3 */
1848 #ifdef HAVE___CTYPE_B_LOC
1849 WRAPPER2(unsigned short **, __ctype_b_loc, void)
1850 {
1851   static unsigned short * last_buf = (void *) 0;
1852   static unsigned short ** last_ptr = (void *) 0;
1853   unsigned short ** ptr = (unsigned short **) __ctype_b_loc ();
1854   unsigned short * buf = * ptr;
1855   if (ptr != last_ptr)
1856     {
1857       /* XXX: unregister last_ptr? */
1858       last_ptr = ptr;
1859       __mf_register (last_ptr, sizeof(last_ptr), __MF_TYPE_STATIC, "ctype_b_loc **");
1860     }
1861   if (buf != last_buf)
1862     {
1863       last_buf = buf;
1864       __mf_register ((void *) (last_buf - 128), 384 * sizeof(unsigned short), __MF_TYPE_STATIC,
1865                      "ctype_b_loc []");
1866     }
1867   return ptr;
1868 }
1869 #endif
1870
1871 #ifdef HAVE___CTYPE_TOUPPER_LOC
1872 WRAPPER2(int **, __ctype_toupper_loc, void)
1873 {
1874   static int * last_buf = (void *) 0;
1875   static int ** last_ptr = (void *) 0;
1876   int ** ptr = (int **) __ctype_toupper_loc ();
1877   int * buf = * ptr;
1878   if (ptr != last_ptr)
1879     {
1880       /* XXX: unregister last_ptr? */
1881       last_ptr = ptr;
1882       __mf_register (last_ptr, sizeof(last_ptr), __MF_TYPE_STATIC, "ctype_toupper_loc **");
1883     }
1884   if (buf != last_buf)
1885     {
1886       last_buf = buf;
1887       __mf_register ((void *) (last_buf - 128), 384 * sizeof(int), __MF_TYPE_STATIC,
1888                      "ctype_toupper_loc []");
1889     }
1890   return ptr;
1891 }
1892 #endif
1893
1894 #ifdef HAVE___CTYPE_TOLOWER_LOC
1895 WRAPPER2(int **, __ctype_tolower_loc, void)
1896 {
1897   static int * last_buf = (void *) 0;
1898   static int ** last_ptr = (void *) 0;
1899   int ** ptr = (int **) __ctype_tolower_loc ();
1900   int * buf = * ptr;
1901   if (ptr != last_ptr)
1902     {
1903       /* XXX: unregister last_ptr? */
1904       last_ptr = ptr;
1905       __mf_register (last_ptr, sizeof(last_ptr), __MF_TYPE_STATIC, "ctype_tolower_loc **");
1906     }
1907   if (buf != last_buf)
1908     {
1909       last_buf = buf;
1910       __mf_register ((void *) (last_buf - 128), 384 * sizeof(int), __MF_TYPE_STATIC,
1911                      "ctype_tolower_loc []");
1912     }
1913   return ptr;
1914 }
1915 #endif
1916
1917
1918 /* passwd/group related functions.  These register every (static) pointer value returned,
1919    and rely on libmudflap's quiet toleration of duplicate static registrations.  */
1920
1921 #ifdef HAVE_GETLOGIN
1922 WRAPPER2(char *, getlogin, void)
1923 {
1924   char *buf = getlogin ();
1925   if (buf != NULL)
1926     __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
1927                    "getlogin() return");
1928   return buf;
1929 }
1930 #endif
1931
1932
1933 #ifdef HAVE_CUSERID
1934 WRAPPER2(char *, cuserid, char * buf)
1935 {
1936   if (buf != NULL)
1937     {
1938       MF_VALIDATE_EXTENT(buf, L_cuserid, __MF_CHECK_WRITE,
1939                          "cuserid destination");
1940       return cuserid (buf);
1941     }
1942   buf = cuserid (NULL);
1943   if (buf != NULL)
1944     __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
1945                    "getcuserid() return");
1946   return buf;
1947 }
1948 #endif
1949
1950
1951 #ifdef HAVE_GETPWNAM
1952 WRAPPER2(struct passwd *, getpwnam, const char *name)
1953 {
1954   struct passwd *buf;
1955   MF_VALIDATE_EXTENT(name, strlen(name)+1, __MF_CHECK_READ,
1956                      "getpwnam name");
1957   buf = getpwnam (name);
1958   if (buf != NULL)
1959     __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
1960                    "getpw*() return");
1961   return buf;
1962 }
1963 #endif
1964
1965
1966 #ifdef HAVE_GETPWUID
1967 WRAPPER2(struct passwd *, getpwuid, uid_t uid)
1968 {
1969   struct passwd *buf;
1970   buf = getpwuid (uid);
1971   if (buf != NULL)
1972     __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
1973                    "getpw*() return");
1974   return buf;
1975 }
1976 #endif
1977
1978
1979 #ifdef HAVE_GETGRNAM
1980 WRAPPER2(struct group *, getgrnam, const char *name)
1981 {
1982   struct group *buf;
1983   MF_VALIDATE_EXTENT(name, strlen(name)+1, __MF_CHECK_READ,
1984                      "getgrnam name");
1985   buf = getgrnam (name);
1986   if (buf != NULL)
1987     __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
1988                    "getgr*() return");
1989   return buf;
1990 }
1991 #endif
1992
1993
1994 #ifdef HAVE_GETGRGID
1995 WRAPPER2(struct group *, getgrgid, uid_t uid)
1996 {
1997   struct group *buf;
1998   buf = getgrgid (uid);
1999   if (buf != NULL)
2000     __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
2001                    "getgr*() return");
2002   return buf;
2003 }
2004 #endif
2005
2006
2007 #ifdef HAVE_GETSERVENT
2008 WRAPPER2(struct servent *, getservent, void)
2009 {
2010   struct servent *buf;
2011   buf = getservent ();
2012   if (buf != NULL)
2013     __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
2014                    "getserv*() return");
2015   return buf;
2016 }
2017 #endif
2018
2019
2020 #ifdef HAVE_GETSERVBYNAME
2021 WRAPPER2(struct servent *, getservbyname, const char *name, const char *proto)
2022 {
2023   struct servent *buf;
2024   MF_VALIDATE_EXTENT(name, strlen(name)+1, __MF_CHECK_READ,
2025                      "getservbyname name");
2026   MF_VALIDATE_EXTENT(proto, strlen(proto)+1, __MF_CHECK_READ,
2027                      "getservbyname proto");
2028   buf = getservbyname (name, proto);
2029   if (buf != NULL)
2030     __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
2031                    "getserv*() return");
2032   return buf;
2033 }
2034 #endif
2035
2036
2037 #ifdef HAVE_GETSERVBYPORT
2038 WRAPPER2(struct servent *, getservbyport, int port, const char *proto)
2039 {
2040   struct servent *buf;
2041   MF_VALIDATE_EXTENT(proto, strlen(proto)+1, __MF_CHECK_READ,
2042                      "getservbyport proto");
2043   buf = getservbyport (port, proto);
2044   if (buf != NULL)
2045     __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
2046                    "getserv*() return");
2047   return buf;
2048 }
2049 #endif
2050
2051
2052 #ifdef HAVE_GAI_STRERROR
2053 WRAPPER2(const char *, gai_strerror, int errcode)
2054 {
2055   const char *buf;
2056   buf = gai_strerror (errcode);
2057   if (buf != NULL)
2058     __mf_register ((void *) buf, strlen(buf)+1, __MF_TYPE_STATIC,
2059                    "gai_strerror() return");
2060   return buf;
2061 }
2062 #endif
2063
2064
2065 #ifdef HAVE_GETMNTENT
2066 WRAPPER2(struct mntent *, getmntent, FILE *filep)
2067 {
2068   struct mntent *m;
2069   static struct mntent *last = NULL;
2070
2071   MF_VALIDATE_EXTENT (filep, sizeof (*filep), __MF_CHECK_WRITE,
2072     "getmntent stream");
2073 #define UR(field) __mf_unregister(last->field, strlen (last->field)+1, __MF_TYPE_STATIC)
2074   if (last)
2075     {
2076       UR (mnt_fsname);
2077       UR (mnt_dir);
2078       UR (mnt_type);
2079       UR (mnt_opts);
2080       __mf_unregister (last, sizeof (*last), __MF_TYPE_STATIC);
2081     }
2082 #undef UR
2083
2084   m = getmntent (filep);
2085   last = m;
2086
2087 #define R(field) __mf_register(last->field, strlen (last->field)+1, __MF_TYPE_STATIC, "mntent " #field)
2088   if (m)
2089     {
2090       R (mnt_fsname);
2091       R (mnt_dir);
2092       R (mnt_type);
2093       R (mnt_opts);
2094       __mf_register (last, sizeof (*last), __MF_TYPE_STATIC, "getmntent result");
2095     }
2096 #undef R
2097
2098   return m;
2099 }
2100 #endif
2101
2102
2103 #ifdef HAVE_INET_NTOA
2104 WRAPPER2(char *, inet_ntoa, struct in_addr in)
2105 {
2106   static char *last_buf = NULL;
2107   char *buf;
2108   if (last_buf)
2109     __mf_unregister (last_buf, strlen (last_buf)+1, __MF_TYPE_STATIC);
2110   buf = inet_ntoa (in);
2111   last_buf = buf;
2112   if (buf)
2113     __mf_register (last_buf, strlen (last_buf)+1, __MF_TYPE_STATIC, "inet_ntoa result");
2114   return buf;
2115 }
2116 #endif
2117
2118
2119 #ifdef HAVE_GETPROTOENT
2120 WRAPPER2(struct protoent *, getprotoent, void)
2121 {
2122   struct protoent *buf;
2123   buf = getprotoent ();
2124   if (buf != NULL)
2125     __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC, "getproto*() return");
2126   return buf;
2127 }
2128 #endif
2129
2130
2131 #ifdef HAVE_GETPROTOBYNAME
2132 WRAPPER2(struct protoent *, getprotobyname, const char *name)
2133 {
2134   struct protoent *buf;
2135   MF_VALIDATE_EXTENT(name, strlen(name)+1, __MF_CHECK_READ,
2136                      "getprotobyname name");
2137   buf = getprotobyname (name);
2138   if (buf != NULL)
2139     __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
2140                    "getproto*() return");
2141   return buf;
2142 }
2143 #endif
2144
2145
2146 #ifdef HAVE_GETPROTOBYNUMBER
2147 WRAPPER2(struct protoent *, getprotobynumber, int port)
2148 {
2149   struct protoent *buf;
2150   buf = getprotobynumber (port);
2151   if (buf != NULL)
2152     __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
2153                    "getproto*() return");
2154   return buf;
2155 }
2156 #endif