mf-heuristics.c: Fix whitespace at end of line.
[gcc.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
588 /* An auxiliary data structure for tracking the hand-made stdio
589 buffers we generate during the fopen/fopen64 hooks. In a civilized
590 language, this would be a simple dynamically sized FILE*->char*
591 lookup table, but this is C and we get to do it by hand. */
592 struct mf_filebuffer
593 {
594 FILE *file;
595 char *buffer;
596 struct mf_filebuffer *next;
597 };
598 static struct mf_filebuffer *mf_filebuffers = NULL;
599
600 static void
601 mkbuffer (FILE *f)
602 {
603 /* Reset any buffer automatically provided by libc, since this may
604 have been done via mechanisms that libmudflap couldn't
605 intercept. */
606 int rc;
607 size_t bufsize = BUFSIZ;
608 int bufmode;
609 char *buffer = malloc (bufsize);
610 struct mf_filebuffer *b = malloc (sizeof (struct mf_filebuffer));
611 assert ((buffer != NULL) && (b != NULL));
612
613 /* Link it into list. */
614 b->file = f;
615 b->buffer = buffer;
616 b->next = mf_filebuffers;
617 mf_filebuffers = b;
618
619 /* Determine how the file is supposed to be buffered at the moment. */
620 bufmode = fileno (f) == 2 ? _IONBF : (isatty (fileno (f)) ? _IOLBF : _IOFBF);
621
622 rc = setvbuf (f, buffer, bufmode, bufsize);
623 assert (rc == 0);
624 }
625
626 static void
627 unmkbuffer (FILE *f)
628 {
629 struct mf_filebuffer *b = mf_filebuffers;
630 struct mf_filebuffer **pb = & mf_filebuffers;
631 while (b != NULL)
632 {
633 if (b->file == f)
634 {
635 *pb = b->next;
636 free (b->buffer);
637 free (b);
638 return;
639 }
640 pb = & b->next;
641 b = b->next;
642 }
643 }
644
645
646
647 WRAPPER2(FILE *, fopen, const char *path, const char *mode)
648 {
649 size_t n;
650 FILE *p;
651 TRACE ("%s\n", __PRETTY_FUNCTION__);
652
653 n = strlen (path);
654 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "fopen path");
655
656 n = strlen (mode);
657 MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "fopen mode");
658
659 p = fopen (path, mode);
660 if (NULL != p) {
661 #ifdef MF_REGISTER_fopen
662 __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "fopen result");
663 #endif
664 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "fopen result");
665
666 mkbuffer (p);
667 }
668
669 return p;
670 }
671
672
673 WRAPPER2(int, setvbuf, FILE *stream, char *buf, int mode, size_t size)
674 {
675 int rc = 0;
676 TRACE ("%s\n", __PRETTY_FUNCTION__);
677
678 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, "setvbuf stream");
679
680 unmkbuffer (stream);
681
682 if (buf != NULL)
683 MF_VALIDATE_EXTENT (buf, size, __MF_CHECK_WRITE, "setvbuf buffer");
684
685 /* Override the user only if it's an auto-allocated buffer request. Otherwise
686 assume that the supplied buffer is already known to libmudflap. */
687 if ((buf == NULL) && ((mode == _IOFBF) || (mode == _IOLBF)))
688 mkbuffer (stream);
689 else
690 rc = setvbuf (stream, buf, mode, size);
691
692 return rc;
693 }
694
695
696 #ifdef HAVE_SETBUF
697 WRAPPER2(int, setbuf, FILE* stream, char *buf)
698 {
699 return __mfwrap_setvbuf (stream, buf, buf ? _IOFBF : _IONBF, BUFSIZ);
700 }
701 #endif
702
703 #ifdef HAVE_SETBUFFER
704 WRAPPER2(int, setbuffer, FILE* stream, char *buf, size_t sz)
705 {
706 return __mfwrap_setvbuf (stream, buf, buf ? _IOFBF : _IONBF, sz);
707 }
708 #endif
709
710 #ifdef HAVE_SETLINEBUF
711 WRAPPER2(int, setlinebuf, FILE* stream)
712 {
713 return __mfwrap_setvbuf(stream, NULL, _IOLBF, 0);
714 }
715 #endif
716
717
718
719 WRAPPER2(FILE *, fdopen, int fd, const char *mode)
720 {
721 size_t n;
722 FILE *p;
723 TRACE ("%s\n", __PRETTY_FUNCTION__);
724
725 n = strlen (mode);
726 MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "fdopen mode");
727
728 p = fdopen (fd, mode);
729 if (NULL != p) {
730 #ifdef MF_REGISTER_fopen
731 __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "fdopen result");
732 #endif
733 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "fdopen result");
734
735 mkbuffer (p);
736 }
737
738 return p;
739 }
740
741
742 WRAPPER2(FILE *, freopen, const char *path, const char *mode, FILE *s)
743 {
744 size_t n;
745 FILE *p;
746 TRACE ("%s\n", __PRETTY_FUNCTION__);
747
748 n = strlen (path);
749 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "freopen path");
750
751 MF_VALIDATE_EXTENT (s, (sizeof (*s)), __MF_CHECK_WRITE, "freopen stream");
752 unmkbuffer (s);
753
754 n = strlen (mode);
755 MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "freopen mode");
756
757 p = freopen (path, mode, s);
758 if (NULL != p) {
759 #ifdef MF_REGISTER_fopen
760 __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "freopen result");
761 #endif
762 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "freopen result");
763
764 mkbuffer (p);
765 }
766
767 return p;
768 }
769
770
771 #ifdef HAVE_FOPEN64
772 WRAPPER2(FILE *, fopen64, const char *path, const char *mode)
773 {
774 size_t n;
775 FILE *p;
776 TRACE ("%s\n", __PRETTY_FUNCTION__);
777
778 n = strlen (path);
779 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "fopen64 path");
780
781 n = strlen (mode);
782 MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "fopen64 mode");
783
784 p = fopen64 (path, mode);
785 if (NULL != p) {
786 #ifdef MF_REGISTER_fopen
787 __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "fopen64 result");
788 #endif
789 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "fopen64 result");
790
791 mkbuffer (p);
792 }
793
794 return p;
795 }
796 #endif
797
798
799 #ifdef HAVE_FREOPEN64
800 WRAPPER2(FILE *, freopen64, const char *path, const char *mode, FILE *s)
801 {
802 size_t n;
803 FILE *p;
804 TRACE ("%s\n", __PRETTY_FUNCTION__);
805
806 n = strlen (path);
807 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "freopen64 path");
808
809 MF_VALIDATE_EXTENT (s, (sizeof (*s)), __MF_CHECK_WRITE, "freopen64 stream");
810 unmkbuffer (s);
811
812 n = strlen (mode);
813 MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "freopen64 mode");
814
815 p = freopen (path, mode, s);
816 if (NULL != p) {
817 #ifdef MF_REGISTER_fopen
818 __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "freopen64 result");
819 #endif
820 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "freopen64 result");
821
822 mkbuffer (p);
823 }
824
825 return p;
826 }
827 #endif
828
829
830 WRAPPER2(int, fclose, FILE *stream)
831 {
832 int resp;
833 TRACE ("%s\n", __PRETTY_FUNCTION__);
834 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
835 "fclose stream");
836 resp = fclose (stream);
837 #ifdef MF_REGISTER_fopen
838 __mf_unregister (stream, sizeof (*stream), MF_REGISTER_fopen);
839 #endif
840 unmkbuffer (stream);
841
842 return resp;
843 }
844
845
846 WRAPPER2(size_t, fread, void *ptr, size_t size, size_t nmemb, FILE *stream)
847 {
848 TRACE ("%s\n", __PRETTY_FUNCTION__);
849 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
850 "fread stream");
851 MF_VALIDATE_EXTENT (ptr, size * nmemb, __MF_CHECK_WRITE, "fread buffer");
852 return fread (ptr, size, nmemb, stream);
853 }
854
855
856 WRAPPER2(size_t, fwrite, const void *ptr, size_t size, size_t nmemb,
857 FILE *stream)
858 {
859 TRACE ("%s\n", __PRETTY_FUNCTION__);
860 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
861 "fwrite stream");
862 MF_VALIDATE_EXTENT (ptr, size * nmemb, __MF_CHECK_READ, "fwrite buffer");
863 return fwrite (ptr, size, nmemb, stream);
864 }
865
866
867 WRAPPER2(int, fgetc, FILE *stream)
868 {
869 TRACE ("%s\n", __PRETTY_FUNCTION__);
870 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
871 "fgetc stream");
872 return fgetc (stream);
873 }
874
875
876 WRAPPER2(char *, fgets, char *s, int size, FILE *stream)
877 {
878 TRACE ("%s\n", __PRETTY_FUNCTION__);
879 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
880 "fgets stream");
881 MF_VALIDATE_EXTENT (s, size, __MF_CHECK_WRITE, "fgets buffer");
882 return fgets (s, size, stream);
883 }
884
885
886 WRAPPER2(int, getc, FILE *stream)
887 {
888 TRACE ("%s\n", __PRETTY_FUNCTION__);
889 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
890 "getc stream");
891 return getc (stream);
892 }
893
894
895 WRAPPER2(char *, gets, char *s)
896 {
897 TRACE ("%s\n", __PRETTY_FUNCTION__);
898 MF_VALIDATE_EXTENT (s, 1, __MF_CHECK_WRITE, "gets buffer");
899 /* Avoid link-time warning... */
900 s = fgets (s, INT_MAX, stdin);
901 if (NULL != s) { /* better late than never */
902 size_t n = strlen (s);
903 MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_WRITE, "gets buffer");
904 }
905 return s;
906 }
907
908
909 WRAPPER2(int, ungetc, int c, FILE *stream)
910 {
911 TRACE ("%s\n", __PRETTY_FUNCTION__);
912 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
913 "ungetc stream");
914 return ungetc (c, stream);
915 }
916
917
918 WRAPPER2(int, fputc, int c, FILE *stream)
919 {
920 TRACE ("%s\n", __PRETTY_FUNCTION__);
921 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
922 "fputc stream");
923 return fputc (c, stream);
924 }
925
926
927 WRAPPER2(int, fputs, const char *s, FILE *stream)
928 {
929 size_t n;
930 TRACE ("%s\n", __PRETTY_FUNCTION__);
931 n = strlen (s);
932 MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "fputs buffer");
933 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
934 "fputs stream");
935 return fputs (s, stream);
936 }
937
938
939 WRAPPER2(int, putc, int c, FILE *stream)
940 {
941 TRACE ("%s\n", __PRETTY_FUNCTION__);
942 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
943 "putc stream");
944 return putc (c, stream);
945 }
946
947
948 WRAPPER2(int, puts, const char *s)
949 {
950 size_t n;
951 TRACE ("%s\n", __PRETTY_FUNCTION__);
952 n = strlen (s);
953 MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "puts buffer");
954 return puts (s);
955 }
956
957
958 WRAPPER2(void, clearerr, FILE *stream)
959 {
960 TRACE ("%s\n", __PRETTY_FUNCTION__);
961 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
962 "clearerr stream");
963 clearerr (stream);
964 }
965
966
967 WRAPPER2(int, feof, FILE *stream)
968 {
969 TRACE ("%s\n", __PRETTY_FUNCTION__);
970 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
971 "feof stream");
972 return feof (stream);
973 }
974
975
976 WRAPPER2(int, ferror, FILE *stream)
977 {
978 TRACE ("%s\n", __PRETTY_FUNCTION__);
979 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
980 "ferror stream");
981 return ferror (stream);
982 }
983
984
985 WRAPPER2(int, fileno, FILE *stream)
986 {
987 TRACE ("%s\n", __PRETTY_FUNCTION__);
988 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
989 "fileno stream");
990 return fileno (stream);
991 }
992
993
994 WRAPPER2(int, printf, const char *format, ...)
995 {
996 size_t n;
997 va_list ap;
998 int result;
999 TRACE ("%s\n", __PRETTY_FUNCTION__);
1000 n = strlen (format);
1001 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
1002 "printf format");
1003 va_start (ap, format);
1004 result = vprintf (format, ap);
1005 va_end (ap);
1006 return result;
1007 }
1008
1009
1010 WRAPPER2(int, fprintf, FILE *stream, const char *format, ...)
1011 {
1012 size_t n;
1013 va_list ap;
1014 int result;
1015 TRACE ("%s\n", __PRETTY_FUNCTION__);
1016 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1017 "fprintf stream");
1018 n = strlen (format);
1019 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
1020 "fprintf format");
1021 va_start (ap, format);
1022 result = vfprintf (stream, format, ap);
1023 va_end (ap);
1024 return result;
1025 }
1026
1027
1028 WRAPPER2(int, sprintf, char *str, const char *format, ...)
1029 {
1030 size_t n;
1031 va_list ap;
1032 int result;
1033 TRACE ("%s\n", __PRETTY_FUNCTION__);
1034 MF_VALIDATE_EXTENT (str, 1, __MF_CHECK_WRITE, "sprintf str");
1035 n = strlen (format);
1036 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
1037 "sprintf format");
1038 va_start (ap, format);
1039 result = vsprintf (str, format, ap);
1040 va_end (ap);
1041 n = strlen (str);
1042 MF_VALIDATE_EXTENT (str, CLAMPADD(n, 1), __MF_CHECK_WRITE, "sprintf str");
1043 return result;
1044 }
1045
1046
1047 WRAPPER2(int, snprintf, char *str, size_t size, const char *format, ...)
1048 {
1049 size_t n;
1050 va_list ap;
1051 int result;
1052 TRACE ("%s\n", __PRETTY_FUNCTION__);
1053 MF_VALIDATE_EXTENT (str, size, __MF_CHECK_WRITE, "snprintf str");
1054 n = strlen (format);
1055 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
1056 "snprintf format");
1057 va_start (ap, format);
1058 result = vsnprintf (str, size, format, ap);
1059 va_end (ap);
1060 return result;
1061 }
1062
1063
1064 WRAPPER2(int, vprintf, const char *format, va_list ap)
1065 {
1066 size_t n;
1067 TRACE ("%s\n", __PRETTY_FUNCTION__);
1068 n = strlen (format);
1069 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
1070 "vprintf format");
1071 return vprintf (format, ap);
1072 }
1073
1074
1075 WRAPPER2(int, vfprintf, FILE *stream, const char *format, va_list ap)
1076 {
1077 size_t n;
1078 TRACE ("%s\n", __PRETTY_FUNCTION__);
1079 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1080 "vfprintf stream");
1081 n = strlen (format);
1082 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
1083 "vfprintf format");
1084 return vfprintf (stream, format, ap);
1085 }
1086
1087
1088 WRAPPER2(int, vsprintf, char *str, const char *format, va_list ap)
1089 {
1090 size_t n;
1091 int result;
1092 TRACE ("%s\n", __PRETTY_FUNCTION__);
1093 MF_VALIDATE_EXTENT (str, 1, __MF_CHECK_WRITE, "vsprintf str");
1094 n = strlen (format);
1095 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
1096 "vsprintf format");
1097 result = vsprintf (str, format, ap);
1098 n = strlen (str);
1099 MF_VALIDATE_EXTENT (str, CLAMPADD(n, 1), __MF_CHECK_WRITE, "vsprintf str");
1100 return result;
1101 }
1102
1103
1104 WRAPPER2(int, vsnprintf, char *str, size_t size, const char *format,
1105 va_list ap)
1106 {
1107 size_t n;
1108 TRACE ("%s\n", __PRETTY_FUNCTION__);
1109 MF_VALIDATE_EXTENT (str, size, __MF_CHECK_WRITE, "vsnprintf str");
1110 n = strlen (format);
1111 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
1112 "vsnprintf format");
1113 return vsnprintf (str, size, format, ap);
1114 }
1115
1116
1117 WRAPPER2(int , access, const char *path, int mode)
1118 {
1119 size_t n;
1120 TRACE ("%s\n", __PRETTY_FUNCTION__);
1121 n = strlen (path);
1122 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "access path");
1123 return access (path, mode);
1124 }
1125
1126
1127 WRAPPER2(int , remove, const char *path)
1128 {
1129 size_t n;
1130 TRACE ("%s\n", __PRETTY_FUNCTION__);
1131 n = strlen (path);
1132 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "remove path");
1133 return remove (path);
1134 }
1135
1136
1137 WRAPPER2(int, fflush, FILE *stream)
1138 {
1139 TRACE ("%s\n", __PRETTY_FUNCTION__);
1140 if (stream != NULL)
1141 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1142 "fflush stream");
1143 return fflush (stream);
1144 }
1145
1146
1147 WRAPPER2(int, fseek, FILE *stream, long offset, int whence)
1148 {
1149 TRACE ("%s\n", __PRETTY_FUNCTION__);
1150 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1151 "fseek stream");
1152 return fseek (stream, offset, whence);
1153 }
1154
1155
1156 #ifdef HAVE_FSEEKO64
1157 WRAPPER2(int, fseeko64, FILE *stream, off64_t offset, int whence)
1158 {
1159 TRACE ("%s\n", __PRETTY_FUNCTION__);
1160 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1161 "fseeko64 stream");
1162 return fseeko64 (stream, offset, whence);
1163 }
1164 #endif
1165
1166
1167 WRAPPER2(long, ftell, FILE *stream)
1168 {
1169 TRACE ("%s\n", __PRETTY_FUNCTION__);
1170 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1171 "ftell stream");
1172 return ftell (stream);
1173 }
1174
1175
1176 #ifdef HAVE_FTELLO64
1177 WRAPPER2(off64_t, ftello64, FILE *stream)
1178 {
1179 TRACE ("%s\n", __PRETTY_FUNCTION__);
1180 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1181 "ftello64 stream");
1182 return ftello64 (stream);
1183 }
1184 #endif
1185
1186
1187 WRAPPER2(void, rewind, FILE *stream)
1188 {
1189 TRACE ("%s\n", __PRETTY_FUNCTION__);
1190 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1191 "rewind stream");
1192 rewind (stream);
1193 }
1194
1195
1196 WRAPPER2(int, fgetpos, FILE *stream, fpos_t *pos)
1197 {
1198 TRACE ("%s\n", __PRETTY_FUNCTION__);
1199 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1200 "fgetpos stream");
1201 MF_VALIDATE_EXTENT (pos, sizeof (*pos), __MF_CHECK_WRITE, "fgetpos pos");
1202 return fgetpos (stream, pos);
1203 }
1204
1205
1206 WRAPPER2(int, fsetpos, FILE *stream, fpos_t *pos)
1207 {
1208 TRACE ("%s\n", __PRETTY_FUNCTION__);
1209 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1210 "fsetpos stream");
1211 MF_VALIDATE_EXTENT (pos, sizeof (*pos), __MF_CHECK_READ, "fsetpos pos");
1212 return fsetpos (stream, pos);
1213 }
1214
1215
1216 WRAPPER2(int , stat, const char *path, struct stat *buf)
1217 {
1218 size_t n;
1219 TRACE ("%s\n", __PRETTY_FUNCTION__);
1220 n = strlen (path);
1221 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "stat path");
1222 MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ, "stat buf");
1223 return stat (path, buf);
1224 }
1225
1226
1227 #ifdef HAVE_STAT64
1228 WRAPPER2(int , stat64, const char *path, struct stat64 *buf)
1229 {
1230 size_t n;
1231 TRACE ("%s\n", __PRETTY_FUNCTION__);
1232 n = strlen (path);
1233 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "stat64 path");
1234 MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ, "stat64 buf");
1235 return stat64 (path, buf);
1236 }
1237 #endif
1238
1239
1240 WRAPPER2(int , fstat, int filedes, struct stat *buf)
1241 {
1242 TRACE ("%s\n", __PRETTY_FUNCTION__);
1243 MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ, "fstat buf");
1244 return fstat (filedes, buf);
1245 }
1246
1247
1248 WRAPPER2(int , lstat, const char *path, struct stat *buf)
1249 {
1250 size_t n;
1251 TRACE ("%s\n", __PRETTY_FUNCTION__);
1252 n = strlen (path);
1253 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "lstat path");
1254 MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ, "lstat buf");
1255 return lstat (path, buf);
1256 }
1257
1258
1259 WRAPPER2(int , mkfifo, const char *path, mode_t mode)
1260 {
1261 size_t n;
1262 TRACE ("%s\n", __PRETTY_FUNCTION__);
1263 n = strlen (path);
1264 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "mkfifo path");
1265 return mkfifo (path, mode);
1266 }
1267
1268
1269 #ifdef HAVE_DIRENT_H
1270 WRAPPER2(DIR *, opendir, const char *path)
1271 {
1272 DIR *p;
1273 size_t n;
1274 TRACE ("%s\n", __PRETTY_FUNCTION__);
1275 n = strlen (path);
1276 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "opendir path");
1277
1278 p = opendir (path);
1279 if (NULL != p) {
1280 #ifdef MF_REGISTER_opendir
1281 __mf_register (p, MF_RESULT_SIZE_opendir, MF_REGISTER_opendir,
1282 "opendir result");
1283 #endif
1284 MF_VALIDATE_EXTENT (p, MF_RESULT_SIZE_opendir, __MF_CHECK_WRITE,
1285 "opendir result");
1286 }
1287 return p;
1288 }
1289
1290
1291 WRAPPER2(int, closedir, DIR *dir)
1292 {
1293 TRACE ("%s\n", __PRETTY_FUNCTION__);
1294 MF_VALIDATE_EXTENT (dir, 0, __MF_CHECK_WRITE, "closedir dir");
1295 #ifdef MF_REGISTER_opendir
1296 __mf_unregister (dir, MF_RESULT_SIZE_opendir, MF_REGISTER_opendir);
1297 #endif
1298 return closedir (dir);
1299 }
1300
1301
1302 WRAPPER2(struct dirent *, readdir, DIR *dir)
1303 {
1304 struct dirent *p;
1305 TRACE ("%s\n", __PRETTY_FUNCTION__);
1306 MF_VALIDATE_EXTENT (dir, 0, __MF_CHECK_READ, "readdir dir");
1307 p = readdir (dir);
1308 if (NULL != p) {
1309 #ifdef MF_REGISTER_readdir
1310 __mf_register (p, sizeof (*p), MF_REGISTER_readdir, "readdir result");
1311 #endif
1312 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "readdir result");
1313 }
1314 return p;
1315 }
1316 #endif
1317
1318
1319 #ifdef HAVE_SYS_SOCKET_H
1320
1321 WRAPPER2(int, recv, int s, void *buf, size_t len, int flags)
1322 {
1323 TRACE ("%s\n", __PRETTY_FUNCTION__);
1324 MF_VALIDATE_EXTENT (buf, len, __MF_CHECK_WRITE, "recv buf");
1325 return recv (s, buf, len, flags);
1326 }
1327
1328
1329 WRAPPER2(int, recvfrom, int s, void *buf, size_t len, int flags,
1330 struct sockaddr *from, socklen_t *fromlen)
1331 {
1332 TRACE ("%s\n", __PRETTY_FUNCTION__);
1333 MF_VALIDATE_EXTENT (buf, len, __MF_CHECK_WRITE, "recvfrom buf");
1334 MF_VALIDATE_EXTENT (from, (size_t)*fromlen, __MF_CHECK_WRITE,
1335 "recvfrom from");
1336 return recvfrom (s, buf, len, flags, from, fromlen);
1337 }
1338
1339
1340 WRAPPER2(int, recvmsg, int s, struct msghdr *msg, int flags)
1341 {
1342 TRACE ("%s\n", __PRETTY_FUNCTION__);
1343 MF_VALIDATE_EXTENT (msg, sizeof (*msg), __MF_CHECK_WRITE, "recvmsg msg");
1344 return recvmsg (s, msg, flags);
1345 }
1346
1347
1348 WRAPPER2(int, send, int s, const void *msg, size_t len, int flags)
1349 {
1350 TRACE ("%s\n", __PRETTY_FUNCTION__);
1351 MF_VALIDATE_EXTENT (msg, len, __MF_CHECK_READ, "send msg");
1352 return send (s, msg, len, flags);
1353 }
1354
1355
1356 WRAPPER2(int, sendto, int s, const void *msg, size_t len, int flags,
1357 const struct sockaddr *to, socklen_t tolen)
1358 {
1359 TRACE ("%s\n", __PRETTY_FUNCTION__);
1360 MF_VALIDATE_EXTENT (msg, len, __MF_CHECK_READ, "sendto msg");
1361 MF_VALIDATE_EXTENT (to, (size_t)tolen, __MF_CHECK_WRITE, "sendto to");
1362 return sendto (s, msg, len, flags, to, tolen);
1363 }
1364
1365
1366 WRAPPER2(int, sendmsg, int s, const void *msg, int flags)
1367 {
1368 TRACE ("%s\n", __PRETTY_FUNCTION__);
1369 MF_VALIDATE_EXTENT (msg, sizeof (*msg), __MF_CHECK_READ, "sendmsg msg");
1370 return sendmsg (s, msg, flags);
1371 }
1372
1373
1374 WRAPPER2(int, setsockopt, int s, int level, int optname, const void *optval,
1375 socklen_t optlen)
1376 {
1377 TRACE ("%s\n", __PRETTY_FUNCTION__);
1378 MF_VALIDATE_EXTENT (optval, (size_t)optlen, __MF_CHECK_READ,
1379 "setsockopt optval");
1380 return setsockopt (s, level, optname, optval, optlen);
1381 }
1382
1383
1384 WRAPPER2(int, getsockopt, int s, int level, int optname, void *optval,
1385 socklen_t *optlen)
1386 {
1387 TRACE ("%s\n", __PRETTY_FUNCTION__);
1388 MF_VALIDATE_EXTENT (optval, (size_t)*optlen, __MF_CHECK_WRITE,
1389 "getsockopt optval");
1390 return getsockopt (s, level, optname, optval, optlen);
1391 }
1392
1393
1394 WRAPPER2(int, accept, int s, struct sockaddr *addr, socklen_t *addrlen)
1395 {
1396 TRACE ("%s\n", __PRETTY_FUNCTION__);
1397 MF_VALIDATE_EXTENT (addr, (size_t)*addrlen, __MF_CHECK_WRITE, "accept addr");
1398 return accept (s, addr, addrlen);
1399 }
1400
1401
1402 WRAPPER2(int, bind, int sockfd, struct sockaddr *addr, socklen_t addrlen)
1403 {
1404 TRACE ("%s\n", __PRETTY_FUNCTION__);
1405 MF_VALIDATE_EXTENT (addr, (size_t)addrlen, __MF_CHECK_WRITE, "bind addr");
1406 return bind (sockfd, addr, addrlen);
1407 }
1408
1409
1410 WRAPPER2(int, connect, int sockfd, const struct sockaddr *addr,
1411 socklen_t addrlen)
1412 {
1413 TRACE ("%s\n", __PRETTY_FUNCTION__);
1414 MF_VALIDATE_EXTENT (addr, (size_t)addrlen, __MF_CHECK_READ,
1415 "connect addr");
1416 return connect (sockfd, addr, addrlen);
1417 }
1418
1419 #endif /* HAVE_SYS_SOCKET_H */
1420
1421
1422 WRAPPER2(int, gethostname, char *name, size_t len)
1423 {
1424 TRACE ("%s\n", __PRETTY_FUNCTION__);
1425 MF_VALIDATE_EXTENT (name, len, __MF_CHECK_WRITE, "gethostname name");
1426 return gethostname (name, len);
1427 }
1428
1429
1430 #ifdef HAVE_SETHOSTNAME
1431 WRAPPER2(int, sethostname, const char *name, size_t len)
1432 {
1433 TRACE ("%s\n", __PRETTY_FUNCTION__);
1434 MF_VALIDATE_EXTENT (name, len, __MF_CHECK_READ, "sethostname name");
1435 return sethostname (name, len);
1436 }
1437 #endif
1438
1439
1440 #ifdef HAVE_NETDB_H
1441
1442 WRAPPER2(struct hostent *, gethostbyname, const char *name)
1443 {
1444 struct hostent *p;
1445 char **ss;
1446 char *s;
1447 size_t n;
1448 int nreg;
1449 TRACE ("%s\n", __PRETTY_FUNCTION__);
1450 n = strlen (name);
1451 MF_VALIDATE_EXTENT (name, CLAMPADD(n, 1), __MF_CHECK_READ,
1452 "gethostbyname name");
1453 p = gethostbyname (name);
1454 if (NULL != p) {
1455 #ifdef MF_REGISTER_gethostbyname
1456 __mf_register (p, sizeof (*p), MF_REGISTER_gethostbyname,
1457 "gethostbyname result");
1458 #endif
1459 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE,
1460 "gethostbyname result");
1461 if (NULL != (s = p->h_name)) {
1462 n = strlen (s);
1463 n = CLAMPADD(n, 1);
1464 #ifdef MF_REGISTER_gethostbyname_items
1465 __mf_register (s, n, MF_REGISTER_gethostbyname_items,
1466 "gethostbyname result->h_name");
1467 #endif
1468 MF_VALIDATE_EXTENT (s, n, __MF_CHECK_WRITE,
1469 "gethostbyname result->h_name");
1470 }
1471
1472 if (NULL != (ss = p->h_aliases)) {
1473 for (nreg = 1;; ++nreg) {
1474 s = *ss++;
1475 if (NULL == s)
1476 break;
1477 n = strlen (s);
1478 n = CLAMPADD(n, 1);
1479 #ifdef MF_REGISTER_gethostbyname_items
1480 __mf_register (s, n, MF_REGISTER_gethostbyname_items,
1481 "gethostbyname result->h_aliases[]");
1482 #endif
1483 MF_VALIDATE_EXTENT (s, n, __MF_CHECK_WRITE,
1484 "gethostbyname result->h_aliases[]");
1485 }
1486 nreg *= sizeof (*p->h_aliases);
1487 #ifdef MF_REGISTER_gethostbyname_items
1488 __mf_register (p->h_aliases, nreg, MF_REGISTER_gethostbyname_items,
1489 "gethostbyname result->h_aliases");
1490 #endif
1491 MF_VALIDATE_EXTENT (p->h_aliases, nreg, __MF_CHECK_WRITE,
1492 "gethostbyname result->h_aliases");
1493 }
1494
1495 if (NULL != (ss = p->h_addr_list)) {
1496 for (nreg = 1;; ++nreg) {
1497 s = *ss++;
1498 if (NULL == s)
1499 break;
1500 #ifdef MF_REGISTER_gethostbyname_items
1501 __mf_register (s, p->h_length, MF_REGISTER_gethostbyname_items,
1502 "gethostbyname result->h_addr_list[]");
1503 #endif
1504 MF_VALIDATE_EXTENT (s, p->h_length, __MF_CHECK_WRITE,
1505 "gethostbyname result->h_addr_list[]");
1506 }
1507 nreg *= sizeof (*p->h_addr_list);
1508 #ifdef MF_REGISTER_gethostbyname_items
1509 __mf_register (p->h_addr_list, nreg, MF_REGISTER_gethostbyname_items,
1510 "gethostbyname result->h_addr_list");
1511 #endif
1512 MF_VALIDATE_EXTENT (p->h_addr_list, nreg, __MF_CHECK_WRITE,
1513 "gethostbyname result->h_addr_list");
1514 }
1515 }
1516 return p;
1517 }
1518
1519 #endif /* HAVE_NETDB_H */
1520
1521
1522 #ifdef HAVE_SYS_WAIT_H
1523
1524 WRAPPER2(pid_t, wait, int *status)
1525 {
1526 TRACE ("%s\n", __PRETTY_FUNCTION__);
1527 if (NULL != status)
1528 MF_VALIDATE_EXTENT (status, sizeof (*status), __MF_CHECK_WRITE,
1529 "wait status");
1530 return wait (status);
1531 }
1532
1533
1534 WRAPPER2(pid_t, waitpid, pid_t pid, int *status, int options)
1535 {
1536 TRACE ("%s\n", __PRETTY_FUNCTION__);
1537 if (NULL != status)
1538 MF_VALIDATE_EXTENT (status, sizeof (*status), __MF_CHECK_WRITE,
1539 "waitpid status");
1540 return waitpid (pid, status, options);
1541 }
1542
1543 #endif /* HAVE_SYS_WAIT_H */
1544
1545
1546 WRAPPER2(FILE *, popen, const char *command, const char *mode)
1547 {
1548 size_t n;
1549 FILE *p;
1550 TRACE ("%s\n", __PRETTY_FUNCTION__);
1551
1552 n = strlen (command);
1553 MF_VALIDATE_EXTENT (command, CLAMPADD(n, 1), __MF_CHECK_READ, "popen path");
1554
1555 n = strlen (mode);
1556 MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "popen mode");
1557
1558 p = popen (command, mode);
1559 if (NULL != p) {
1560 #ifdef MF_REGISTER_fopen
1561 __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "popen result");
1562 #endif
1563 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "popen result");
1564 }
1565 return p;
1566 }
1567
1568
1569 WRAPPER2(int, pclose, FILE *stream)
1570 {
1571 int resp;
1572 TRACE ("%s\n", __PRETTY_FUNCTION__);
1573 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1574 "pclose stream");
1575 resp = pclose (stream);
1576 #ifdef MF_REGISTER_fopen
1577 __mf_unregister (stream, sizeof (*stream), MF_REGISTER_fopen);
1578 #endif
1579 return resp;
1580 }
1581
1582
1583 WRAPPER2(int, execve, const char *path, char *const argv [],
1584 char *const envp[])
1585 {
1586 size_t n;
1587 char *const *p;
1588 const char *s;
1589 TRACE ("%s\n", __PRETTY_FUNCTION__);
1590
1591 n = strlen (path);
1592 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "execve path");
1593
1594 for (p = argv;;) {
1595 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_READ, "execve *argv");
1596 s = *p++;
1597 if (NULL == s)
1598 break;
1599 n = strlen (s);
1600 MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "execve **argv");
1601 }
1602
1603 for (p = envp;;) {
1604 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_READ, "execve *envp");
1605 s = *p++;
1606 if (NULL == s)
1607 break;
1608 n = strlen (s);
1609 MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "execve **envp");
1610 }
1611 return execve (path, argv, envp);
1612 }
1613
1614
1615 WRAPPER2(int, execv, const char *path, char *const argv [])
1616 {
1617 size_t n;
1618 char *const *p;
1619 const char *s;
1620 TRACE ("%s\n", __PRETTY_FUNCTION__);
1621
1622 n = strlen (path);
1623 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "execv path");
1624
1625 for (p = argv;;) {
1626 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_READ, "execv *argv");
1627 s = *p++;
1628 if (NULL == s)
1629 break;
1630 n = strlen (s);
1631 MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "execv **argv");
1632 }
1633 return execv (path, argv);
1634 }
1635
1636
1637 WRAPPER2(int, execvp, const char *path, char *const argv [])
1638 {
1639 size_t n;
1640 char *const *p;
1641 const char *s;
1642 TRACE ("%s\n", __PRETTY_FUNCTION__);
1643
1644 n = strlen (path);
1645 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "execvp path");
1646
1647 for (p = argv;;) {
1648 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_READ, "execvp *argv");
1649 s = *p++;
1650 if (NULL == s)
1651 break;
1652 n = strlen (s);
1653 MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "execvp **argv");
1654 }
1655 return execvp (path, argv);
1656 }
1657
1658
1659 WRAPPER2(int, system, const char *string)
1660 {
1661 size_t n;
1662 TRACE ("%s\n", __PRETTY_FUNCTION__);
1663 n = strlen (string);
1664 MF_VALIDATE_EXTENT (string, CLAMPADD(n, 1), __MF_CHECK_READ,
1665 "system string");
1666 return system (string);
1667 }
1668
1669
1670 WRAPPER2(void *, dlopen, const char *path, int flags)
1671 {
1672 void *p;
1673 size_t n;
1674 TRACE ("%s\n", __PRETTY_FUNCTION__);
1675 n = strlen (path);
1676 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "dlopen path");
1677 p = dlopen (path, flags);
1678 if (NULL != p) {
1679 #ifdef MF_REGISTER_dlopen
1680 __mf_register (p, 0, MF_REGISTER_dlopen, "dlopen result");
1681 #endif
1682 MF_VALIDATE_EXTENT (p, 0, __MF_CHECK_WRITE, "dlopen result");
1683 }
1684 return p;
1685 }
1686
1687
1688 WRAPPER2(int, dlclose, void *handle)
1689 {
1690 int resp;
1691 TRACE ("%s\n", __PRETTY_FUNCTION__);
1692 MF_VALIDATE_EXTENT (handle, 0, __MF_CHECK_READ, "dlclose handle");
1693 resp = dlclose (handle);
1694 #ifdef MF_REGISTER_dlopen
1695 __mf_unregister (handle, 0, MF_REGISTER_dlopen);
1696 #endif
1697 return resp;
1698 }
1699
1700
1701 WRAPPER2(char *, dlerror)
1702 {
1703 char *p;
1704 TRACE ("%s\n", __PRETTY_FUNCTION__);
1705 p = dlerror ();
1706 if (NULL != p) {
1707 size_t n;
1708 n = strlen (p);
1709 n = CLAMPADD(n, 1);
1710 #ifdef MF_REGISTER_dlerror
1711 __mf_register (p, n, MF_REGISTER_dlerror, "dlerror result");
1712 #endif
1713 MF_VALIDATE_EXTENT (p, n, __MF_CHECK_WRITE, "dlerror result");
1714 }
1715 return p;
1716 }
1717
1718
1719 WRAPPER2(void *, dlsym, void *handle, char *symbol)
1720 {
1721 size_t n;
1722 void *p;
1723 TRACE ("%s\n", __PRETTY_FUNCTION__);
1724 MF_VALIDATE_EXTENT (handle, 0, __MF_CHECK_READ, "dlsym handle");
1725 n = strlen (symbol);
1726 MF_VALIDATE_EXTENT (symbol, CLAMPADD(n, 1), __MF_CHECK_READ, "dlsym symbol");
1727 p = dlsym (handle, symbol);
1728 if (NULL != p) {
1729 #ifdef MF_REGISTER_dlsym
1730 __mf_register (p, 0, MF_REGISTER_dlsym, "dlsym result");
1731 #endif
1732 MF_VALIDATE_EXTENT (p, 0, __MF_CHECK_WRITE, "dlsym result");
1733 }
1734 return p;
1735 }
1736
1737
1738 #if defined (HAVE_SYS_IPC_H) && defined (HAVE_SYS_SEM_H) && defined (HAVE_SYS_SHM_H)
1739
1740 WRAPPER2(int, semop, int semid, struct sembuf *sops, unsigned nsops)
1741 {
1742 TRACE ("%s\n", __PRETTY_FUNCTION__);
1743 MF_VALIDATE_EXTENT (sops, sizeof (*sops) * nsops, __MF_CHECK_READ,
1744 "semop sops");
1745 return semop (semid, sops, nsops);
1746 }
1747
1748
1749 #ifndef HAVE_UNION_SEMUN
1750 union semun {
1751 int val; /* value for SETVAL */
1752 struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */
1753 unsigned short int *array; /* array for GETALL, SETALL */
1754 struct seminfo *__buf; /* buffer for IPC_INFO */
1755 };
1756 #endif
1757 WRAPPER2(int, semctl, int semid, int semnum, int cmd, union semun arg)
1758 {
1759 TRACE ("%s\n", __PRETTY_FUNCTION__);
1760 switch (cmd) {
1761 case IPC_STAT:
1762 MF_VALIDATE_EXTENT (arg.buf, sizeof (*arg.buf), __MF_CHECK_WRITE,
1763 "semctl buf");
1764 break;
1765 case IPC_SET:
1766 MF_VALIDATE_EXTENT (arg.buf, sizeof (*arg.buf), __MF_CHECK_READ,
1767 "semctl buf");
1768 break;
1769 case GETALL:
1770 MF_VALIDATE_EXTENT (arg.array, sizeof (*arg.array), __MF_CHECK_WRITE,
1771 "semctl array");
1772 case SETALL:
1773 MF_VALIDATE_EXTENT (arg.array, sizeof (*arg.array), __MF_CHECK_READ,
1774 "semctl array");
1775 break;
1776 #ifdef IPC_INFO
1777 /* FreeBSD 5.1 And Cygwin headers include IPC_INFO but not the __buf field. */
1778 #if !defined(__FreeBSD__) && !defined(__CYGWIN__)
1779 case IPC_INFO:
1780 MF_VALIDATE_EXTENT (arg.__buf, sizeof (*arg.__buf), __MF_CHECK_WRITE,
1781 "semctl __buf");
1782 break;
1783 #endif
1784 #endif
1785 default:
1786 break;
1787 }
1788 return semctl (semid, semnum, cmd, arg);
1789 }
1790
1791
1792 WRAPPER2(int, shmctl, int shmid, int cmd, struct shmid_ds *buf)
1793 {
1794 TRACE ("%s\n", __PRETTY_FUNCTION__);
1795 switch (cmd) {
1796 case IPC_STAT:
1797 MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_WRITE,
1798 "shmctl buf");
1799 break;
1800 case IPC_SET:
1801 MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ,
1802 "shmctl buf");
1803 break;
1804 default:
1805 break;
1806 }
1807 return shmctl (shmid, cmd, buf);
1808 }
1809
1810
1811 WRAPPER2(void *, shmat, int shmid, const void *shmaddr, int shmflg)
1812 {
1813 void *p;
1814 TRACE ("%s\n", __PRETTY_FUNCTION__);
1815 p = shmat (shmid, shmaddr, shmflg);
1816 #ifdef MF_REGISTER_shmat
1817 if (NULL != p) {
1818 struct shmid_ds buf;
1819 __mf_register (p, shmctl (shmid, IPC_STAT, &buf) ? 0 : buf.shm_segsz,
1820 MF_REGISTER_shmat, "shmat result");
1821 }
1822 #endif
1823 return p;
1824 }
1825
1826
1827 WRAPPER2(int, shmdt, const void *shmaddr)
1828 {
1829 int resp;
1830 TRACE ("%s\n", __PRETTY_FUNCTION__);
1831 resp = shmdt (shmaddr);
1832 #ifdef MF_REGISTER_shmat
1833 __mf_unregister ((void *)shmaddr, 0, MF_REGISTER_shmat);
1834 #endif
1835 return resp;
1836 }
1837
1838
1839 #endif /* HAVE_SYS_IPC/SEM/SHM_H */
1840
1841
1842
1843 /* ctype stuff. This is host-specific by necessity, as the arrays
1844 that is used by most is*()/to*() macros are implementation-defined. */
1845
1846 /* GLIBC 2.3 */
1847 #ifdef HAVE___CTYPE_B_LOC
1848 WRAPPER2(unsigned short **, __ctype_b_loc, void)
1849 {
1850 static unsigned short * last_buf = (void *) 0;
1851 static unsigned short ** last_ptr = (void *) 0;
1852 unsigned short ** ptr = (unsigned short **) __ctype_b_loc ();
1853 unsigned short * buf = * ptr;
1854 if (ptr != last_ptr)
1855 {
1856 /* XXX: unregister last_ptr? */
1857 last_ptr = ptr;
1858 __mf_register (last_ptr, sizeof(last_ptr), __MF_TYPE_STATIC, "ctype_b_loc **");
1859 }
1860 if (buf != last_buf)
1861 {
1862 last_buf = buf;
1863 __mf_register ((void *) (last_buf - 128), 384 * sizeof(unsigned short), __MF_TYPE_STATIC,
1864 "ctype_b_loc []");
1865 }
1866 return ptr;
1867 }
1868 #endif
1869
1870 #ifdef HAVE___CTYPE_TOUPPER_LOC
1871 WRAPPER2(int **, __ctype_toupper_loc, void)
1872 {
1873 static int * last_buf = (void *) 0;
1874 static int ** last_ptr = (void *) 0;
1875 int ** ptr = (int **) __ctype_toupper_loc ();
1876 int * buf = * ptr;
1877 if (ptr != last_ptr)
1878 {
1879 /* XXX: unregister last_ptr? */
1880 last_ptr = ptr;
1881 __mf_register (last_ptr, sizeof(last_ptr), __MF_TYPE_STATIC, "ctype_toupper_loc **");
1882 }
1883 if (buf != last_buf)
1884 {
1885 last_buf = buf;
1886 __mf_register ((void *) (last_buf - 128), 384 * sizeof(int), __MF_TYPE_STATIC,
1887 "ctype_toupper_loc []");
1888 }
1889 return ptr;
1890 }
1891 #endif
1892
1893 #ifdef HAVE___CTYPE_TOLOWER_LOC
1894 WRAPPER2(int **, __ctype_tolower_loc, void)
1895 {
1896 static int * last_buf = (void *) 0;
1897 static int ** last_ptr = (void *) 0;
1898 int ** ptr = (int **) __ctype_tolower_loc ();
1899 int * buf = * ptr;
1900 if (ptr != last_ptr)
1901 {
1902 /* XXX: unregister last_ptr? */
1903 last_ptr = ptr;
1904 __mf_register (last_ptr, sizeof(last_ptr), __MF_TYPE_STATIC, "ctype_tolower_loc **");
1905 }
1906 if (buf != last_buf)
1907 {
1908 last_buf = buf;
1909 __mf_register ((void *) (last_buf - 128), 384 * sizeof(int), __MF_TYPE_STATIC,
1910 "ctype_tolower_loc []");
1911 }
1912 return ptr;
1913 }
1914 #endif
1915
1916
1917 /* passwd/group related functions. These register every (static) pointer value returned,
1918 and rely on libmudflap's quiet toleration of duplicate static registrations. */
1919
1920 #ifdef HAVE_GETLOGIN
1921 WRAPPER2(char *, getlogin, void)
1922 {
1923 char *buf = getlogin ();
1924 if (buf != NULL)
1925 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
1926 "getlogin() return");
1927 return buf;
1928 }
1929 #endif
1930
1931
1932 #ifdef HAVE_CUSERID
1933 WRAPPER2(char *, cuserid, char * buf)
1934 {
1935 if (buf != NULL)
1936 {
1937 MF_VALIDATE_EXTENT(buf, L_cuserid, __MF_CHECK_WRITE,
1938 "cuserid destination");
1939 return cuserid (buf);
1940 }
1941 buf = cuserid (NULL);
1942 if (buf != NULL)
1943 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
1944 "getcuserid() return");
1945 return buf;
1946 }
1947 #endif
1948
1949
1950 #ifdef HAVE_GETPWNAM
1951 WRAPPER2(struct passwd *, getpwnam, const char *name)
1952 {
1953 struct passwd *buf;
1954 MF_VALIDATE_EXTENT(name, strlen(name)+1, __MF_CHECK_READ,
1955 "getpwnam name");
1956 buf = getpwnam (name);
1957 if (buf != NULL)
1958 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
1959 "getpw*() return");
1960 return buf;
1961 }
1962 #endif
1963
1964
1965 #ifdef HAVE_GETPWUID
1966 WRAPPER2(struct passwd *, getpwuid, uid_t uid)
1967 {
1968 struct passwd *buf;
1969 buf = getpwuid (uid);
1970 if (buf != NULL)
1971 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
1972 "getpw*() return");
1973 return buf;
1974 }
1975 #endif
1976
1977
1978 #ifdef HAVE_GETGRNAM
1979 WRAPPER2(struct group *, getgrnam, const char *name)
1980 {
1981 struct group *buf;
1982 MF_VALIDATE_EXTENT(name, strlen(name)+1, __MF_CHECK_READ,
1983 "getgrnam name");
1984 buf = getgrnam (name);
1985 if (buf != NULL)
1986 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
1987 "getgr*() return");
1988 return buf;
1989 }
1990 #endif
1991
1992
1993 #ifdef HAVE_GETGRGID
1994 WRAPPER2(struct group *, getgrgid, uid_t uid)
1995 {
1996 struct group *buf;
1997 buf = getgrgid (uid);
1998 if (buf != NULL)
1999 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
2000 "getgr*() return");
2001 return buf;
2002 }
2003 #endif
2004
2005
2006 #ifdef HAVE_GETSERVENT
2007 WRAPPER2(struct servent *, getservent, void)
2008 {
2009 struct servent *buf;
2010 buf = getservent ();
2011 if (buf != NULL)
2012 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
2013 "getserv*() return");
2014 return buf;
2015 }
2016 #endif
2017
2018
2019 #ifdef HAVE_GETSERVBYNAME
2020 WRAPPER2(struct servent *, getservbyname, const char *name, const char *proto)
2021 {
2022 struct servent *buf;
2023 MF_VALIDATE_EXTENT(name, strlen(name)+1, __MF_CHECK_READ,
2024 "getservbyname name");
2025 MF_VALIDATE_EXTENT(proto, strlen(proto)+1, __MF_CHECK_READ,
2026 "getservbyname proto");
2027 buf = getservbyname (name, proto);
2028 if (buf != NULL)
2029 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
2030 "getserv*() return");
2031 return buf;
2032 }
2033 #endif
2034
2035
2036 #ifdef HAVE_GETSERVBYPORT
2037 WRAPPER2(struct servent *, getservbyport, int port, const char *proto)
2038 {
2039 struct servent *buf;
2040 MF_VALIDATE_EXTENT(proto, strlen(proto)+1, __MF_CHECK_READ,
2041 "getservbyport proto");
2042 buf = getservbyport (port, proto);
2043 if (buf != NULL)
2044 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
2045 "getserv*() return");
2046 return buf;
2047 }
2048 #endif
2049
2050
2051 #ifdef HAVE_GAI_STRERROR
2052 WRAPPER2(const char *, gai_strerror, int errcode)
2053 {
2054 const char *buf;
2055 buf = gai_strerror (errcode);
2056 if (buf != NULL)
2057 __mf_register ((void *) buf, strlen(buf)+1, __MF_TYPE_STATIC,
2058 "gai_strerror() return");
2059 return buf;
2060 }
2061 #endif
2062
2063
2064 #ifdef HAVE_GETMNTENT
2065 WRAPPER2(struct mntent *, getmntent, FILE *filep)
2066 {
2067 struct mntent *m;
2068 static struct mntent *last = NULL;
2069
2070 MF_VALIDATE_EXTENT (filep, sizeof (*filep), __MF_CHECK_WRITE,
2071 "getmntent stream");
2072 #define UR(field) __mf_unregister(last->field, strlen (last->field)+1, __MF_TYPE_STATIC)
2073 if (last)
2074 {
2075 UR (mnt_fsname);
2076 UR (mnt_dir);
2077 UR (mnt_type);
2078 UR (mnt_opts);
2079 __mf_unregister (last, sizeof (*last), __MF_TYPE_STATIC);
2080 }
2081 #undef UR
2082
2083 m = getmntent (filep);
2084 last = m;
2085
2086 #define R(field) __mf_register(last->field, strlen (last->field)+1, __MF_TYPE_STATIC, "mntent " #field)
2087 if (m)
2088 {
2089 R (mnt_fsname);
2090 R (mnt_dir);
2091 R (mnt_type);
2092 R (mnt_opts);
2093 __mf_register (last, sizeof (*last), __MF_TYPE_STATIC, "getmntent result");
2094 }
2095 #undef R
2096
2097 return m;
2098 }
2099 #endif
2100
2101
2102 #ifdef HAVE_INET_NTOA
2103 WRAPPER2(char *, inet_ntoa, struct in_addr in)
2104 {
2105 static char *last_buf = NULL;
2106 char *buf;
2107 if (last_buf)
2108 __mf_unregister (last_buf, strlen (last_buf)+1, __MF_TYPE_STATIC);
2109 buf = inet_ntoa (in);
2110 last_buf = buf;
2111 if (buf)
2112 __mf_register (last_buf, strlen (last_buf)+1, __MF_TYPE_STATIC, "inet_ntoa result");
2113 return buf;
2114 }
2115 #endif
2116
2117
2118 #ifdef HAVE_GETPROTOENT
2119 WRAPPER2(struct protoent *, getprotoent, void)
2120 {
2121 struct protoent *buf;
2122 buf = getprotoent ();
2123 if (buf != NULL)
2124 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC, "getproto*() return");
2125 return buf;
2126 }
2127 #endif
2128
2129
2130 #ifdef HAVE_GETPROTOBYNAME
2131 WRAPPER2(struct protoent *, getprotobyname, const char *name)
2132 {
2133 struct protoent *buf;
2134 MF_VALIDATE_EXTENT(name, strlen(name)+1, __MF_CHECK_READ,
2135 "getprotobyname name");
2136 buf = getprotobyname (name);
2137 if (buf != NULL)
2138 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
2139 "getproto*() return");
2140 return buf;
2141 }
2142 #endif
2143
2144
2145 #ifdef HAVE_GETPROTOBYNUMBER
2146 WRAPPER2(struct protoent *, getprotobynumber, int port)
2147 {
2148 struct protoent *buf;
2149 buf = getprotobynumber (port);
2150 if (buf != NULL)
2151 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC,
2152 "getproto*() return");
2153 return buf;
2154 }
2155 #endif