OSDN Git Service

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