OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [libmudflap/] [mf-hooks2.c] - Blame information for rev 856

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.