OSDN Git Service

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