X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=libmudflap%2Fmf-hooks2.c;h=87cb270b8fd59411ad2c5c6f94f6497a69043630;hp=ccd9931be86c10ba0eca8b5da9128d5956db3368;hb=285db2ce80c0185ca89282b7038990ec616698e3;hpb=8981aed2e88666a3668271f54391f9266c4c80bb diff --git a/libmudflap/mf-hooks2.c b/libmudflap/mf-hooks2.c index ccd9931be86..87cb270b8fd 100644 --- a/libmudflap/mf-hooks2.c +++ b/libmudflap/mf-hooks2.c @@ -41,7 +41,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #if !defined(__FreeBSD__) && !defined(__APPLE__) #define _POSIX_SOURCE #endif /* Some BSDs break if this is defined. */ -#define _GNU_SOURCE +#define _GNU_SOURCE #define _XOPEN_SOURCE #define _BSD_TYPES #define __EXTENSIONS__ @@ -52,7 +52,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include #include -#include #include #include #include @@ -63,7 +62,13 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include #include #include +#include +#ifdef HAVE_DLFCN_H +#include +#endif +#ifdef HAVE_DIRENT_H #include +#endif #ifdef HAVE_SYS_SOCKET_H #include #endif @@ -82,7 +87,24 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #ifdef HAVE_SYS_SHM_H #include #endif - +#ifdef HAVE_PWD_H +#include +#endif +#ifdef HAVE_GRP_H +#include +#endif +#ifdef HAVE_MNTENT_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif #include "mf-runtime.h" #include "mf-impl.h" @@ -170,7 +192,7 @@ WRAPPER2(char *, strcpy, char *dest, const char *src) size_t n = strlen (src); TRACE ("%s\n", __PRETTY_FUNCTION__); - MF_VALIDATE_EXTENT(src, CLAMPADD(n, 1), __MF_CHECK_READ, "strcpy src"); + MF_VALIDATE_EXTENT(src, CLAMPADD(n, 1), __MF_CHECK_READ, "strcpy src"); MF_VALIDATE_EXTENT(dest, CLAMPADD(n, 1), __MF_CHECK_WRITE, "strcpy dest"); return strcpy (dest, src); } @@ -194,7 +216,7 @@ WRAPPER2(char *, strcat, char *dest, const char *src) size_t src_sz; TRACE ("%s\n", __PRETTY_FUNCTION__); dest_sz = strlen (dest); - src_sz = strlen (src); + src_sz = strlen (src); MF_VALIDATE_EXTENT(src, CLAMPADD(src_sz, 1), __MF_CHECK_READ, "strcat src"); MF_VALIDATE_EXTENT(dest, CLAMPADD(dest_sz, CLAMPADD(src_sz, 1)), __MF_CHECK_WRITE, "strcat dest"); @@ -206,15 +228,15 @@ WRAPPER2(char *, strncat, char *dest, const char *src, size_t n) { /* nb: validating the extents (s,n) might be a mistake for two reasons. - - (1) the string s might be shorter than n chars, and n is just a + + (1) the string s might be shorter than n chars, and n is just a poor choice by the programmer. this is not a "true" error in the sense that the call to strncat would still be ok. - + (2) we could try to compensate for case (1) by calling strlen(s) and using that as a bound for the extent to verify, but strlen might fall off the end of a non-terminated string, leading to a false positive. - + so we will call strnlen(s,n) and use that as a bound. if strnlen returns a length beyond the end of the registered extent @@ -243,7 +265,7 @@ WRAPPER2(int, strcmp, const char *s1, const char *s2) size_t s2_sz; TRACE ("%s\n", __PRETTY_FUNCTION__); s1_sz = strlen (s1); - s2_sz = strlen (s2); + s2_sz = strlen (s2); MF_VALIDATE_EXTENT(s1, CLAMPADD(s1_sz, 1), __MF_CHECK_READ, "strcmp 1st arg"); MF_VALIDATE_EXTENT(s2, CLAMPADD(s2_sz, 1), __MF_CHECK_WRITE, "strcmp 2nd arg"); return strcmp (s1, s2); @@ -256,7 +278,7 @@ WRAPPER2(int, strcasecmp, const char *s1, const char *s2) size_t s2_sz; TRACE ("%s\n", __PRETTY_FUNCTION__); s1_sz = strlen (s1); - s2_sz = strlen (s2); + s2_sz = strlen (s2); MF_VALIDATE_EXTENT(s1, CLAMPADD(s1_sz, 1), __MF_CHECK_READ, "strcasecmp 1st arg"); MF_VALIDATE_EXTENT(s2, CLAMPADD(s2_sz, 1), __MF_CHECK_READ, "strcasecmp 2nd arg"); return strcasecmp (s1, s2); @@ -296,7 +318,7 @@ WRAPPER2(char *, strdup, const char *s) size_t n = strlen (s); TRACE ("%s\n", __PRETTY_FUNCTION__); MF_VALIDATE_EXTENT(s, CLAMPADD(n,1), __MF_CHECK_READ, "strdup region"); - result = (char *)CALL_REAL(malloc, + result = (char *)CALL_REAL(malloc, CLAMPADD(CLAMPADD(n,1), CLAMPADD(__mf_opts.crumple_zone, __mf_opts.crumple_zone))); @@ -321,11 +343,11 @@ WRAPPER2(char *, strndup, const char *s, size_t n) MF_VALIDATE_EXTENT(s, sz, __MF_CHECK_READ, "strndup region"); /* nb: strNdup */ /* note: strndup still adds a \0, even with the N limit! */ - result = (char *)CALL_REAL(malloc, + result = (char *)CALL_REAL(malloc, CLAMPADD(CLAMPADD(n,1), CLAMPADD(__mf_opts.crumple_zone, __mf_opts.crumple_zone))); - + if (UNLIKELY(! result)) return result; result += __mf_opts.crumple_zone; @@ -371,7 +393,7 @@ WRAPPER2(char *, strstr, const char *haystack, const char *needle) #ifdef HAVE_MEMMEM -WRAPPER2(void *, memmem, +WRAPPER2(void *, memmem, const void *haystack, size_t haystacklen, const void *needle, size_t needlelen) { @@ -522,7 +544,6 @@ WRAPPER2(struct tm*, gmtime, const time_t *timep) /* The following indicate if the result of the corresponding function * should be explicitly un/registered by the wrapper */ -#define MF_REGISTER_strerror __MF_TYPE_STATIC #undef MF_REGISTER_fopen #define MF_RESULT_SIZE_fopen (sizeof (FILE)) #undef MF_REGISTER_opendir @@ -550,21 +571,79 @@ WRAPPER2(time_t, time, time_t *timep) WRAPPER2(char *, strerror, int errnum) { char *p; - size_t n; + static char * last_strerror = NULL; + TRACE ("%s\n", __PRETTY_FUNCTION__); p = strerror (errnum); - if (NULL != p) { - n = strlen (p); - n = CLAMPADD(n, 1); -#ifdef MF_REGISTER_strerror - __mf_register (p, n, MF_REGISTER_strerror, "strerror result"); -#endif - MF_VALIDATE_EXTENT (p, n, __MF_CHECK_WRITE, "strerror result"); - } + if (last_strerror != NULL) + __mf_unregister (last_strerror, 0, __MF_TYPE_STATIC); + if (NULL != p) + __mf_register (p, strlen (p) + 1, __MF_TYPE_STATIC, "strerror result"); + last_strerror = p; return p; } + +/* An auxiliary data structure for tracking the hand-made stdio + buffers we generate during the fopen/fopen64 hooks. In a civilized + language, this would be a simple dynamically sized FILE*->char* + lookup table, but this is C and we get to do it by hand. */ +struct mf_filebuffer +{ + FILE *file; + char *buffer; + struct mf_filebuffer *next; +}; +static struct mf_filebuffer *mf_filebuffers = NULL; + +static void +mkbuffer (FILE *f) +{ + /* Reset any buffer automatically provided by libc, since this may + have been done via mechanisms that libmudflap couldn't + intercept. */ + int rc; + size_t bufsize = BUFSIZ; + int bufmode; + char *buffer = malloc (bufsize); + struct mf_filebuffer *b = malloc (sizeof (struct mf_filebuffer)); + assert ((buffer != NULL) && (b != NULL)); + + /* Link it into list. */ + b->file = f; + b->buffer = buffer; + b->next = mf_filebuffers; + mf_filebuffers = b; + + /* Determine how the file is supposed to be buffered at the moment. */ + bufmode = fileno (f) == 2 ? _IONBF : (isatty (fileno (f)) ? _IOLBF : _IOFBF); + + rc = setvbuf (f, buffer, bufmode, bufsize); + assert (rc == 0); +} + +static void +unmkbuffer (FILE *f) +{ + struct mf_filebuffer *b = mf_filebuffers; + struct mf_filebuffer **pb = & mf_filebuffers; + while (b != NULL) + { + if (b->file == f) + { + *pb = b->next; + free (b->buffer); + free (b); + return; + } + pb = & b->next; + b = b->next; + } +} + + + WRAPPER2(FILE *, fopen, const char *path, const char *mode) { size_t n; @@ -583,6 +662,106 @@ WRAPPER2(FILE *, fopen, const char *path, const char *mode) __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "fopen result"); #endif MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "fopen result"); + + mkbuffer (p); + } + + return p; +} + + +WRAPPER2(int, setvbuf, FILE *stream, char *buf, int mode, size_t size) +{ + int rc = 0; + TRACE ("%s\n", __PRETTY_FUNCTION__); + + MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, "setvbuf stream"); + + unmkbuffer (stream); + + if (buf != NULL) + MF_VALIDATE_EXTENT (buf, size, __MF_CHECK_WRITE, "setvbuf buffer"); + + /* Override the user only if it's an auto-allocated buffer request. Otherwise + assume that the supplied buffer is already known to libmudflap. */ + if ((buf == NULL) && ((mode == _IOFBF) || (mode == _IOLBF))) + mkbuffer (stream); + else + rc = setvbuf (stream, buf, mode, size); + + return rc; +} + + +#ifdef HAVE_SETBUF +WRAPPER2(int, setbuf, FILE* stream, char *buf) +{ + return __mfwrap_setvbuf (stream, buf, buf ? _IOFBF : _IONBF, BUFSIZ); +} +#endif + +#ifdef HAVE_SETBUFFER +WRAPPER2(int, setbuffer, FILE* stream, char *buf, size_t sz) +{ + return __mfwrap_setvbuf (stream, buf, buf ? _IOFBF : _IONBF, sz); +} +#endif + +#ifdef HAVE_SETLINEBUF +WRAPPER2(int, setlinebuf, FILE* stream) +{ + return __mfwrap_setvbuf(stream, NULL, _IOLBF, 0); +} +#endif + + + +WRAPPER2(FILE *, fdopen, int fd, const char *mode) +{ + size_t n; + FILE *p; + TRACE ("%s\n", __PRETTY_FUNCTION__); + + n = strlen (mode); + MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "fdopen mode"); + + p = fdopen (fd, mode); + if (NULL != p) { +#ifdef MF_REGISTER_fopen + __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "fdopen result"); +#endif + MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "fdopen result"); + + mkbuffer (p); + } + + return p; +} + + +WRAPPER2(FILE *, freopen, const char *path, const char *mode, FILE *s) +{ + size_t n; + FILE *p; + TRACE ("%s\n", __PRETTY_FUNCTION__); + + n = strlen (path); + MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "freopen path"); + + MF_VALIDATE_EXTENT (s, (sizeof (*s)), __MF_CHECK_WRITE, "freopen stream"); + unmkbuffer (s); + + n = strlen (mode); + MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "freopen mode"); + + p = freopen (path, mode, s); + if (NULL != p) { +#ifdef MF_REGISTER_fopen + __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "freopen result"); +#endif + MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "freopen result"); + + mkbuffer (p); } return p; @@ -608,6 +787,39 @@ WRAPPER2(FILE *, fopen64, const char *path, const char *mode) __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "fopen64 result"); #endif MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "fopen64 result"); + + mkbuffer (p); + } + + return p; +} +#endif + + +#ifdef HAVE_FREOPEN64 +WRAPPER2(FILE *, freopen64, const char *path, const char *mode, FILE *s) +{ + size_t n; + FILE *p; + TRACE ("%s\n", __PRETTY_FUNCTION__); + + n = strlen (path); + MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "freopen64 path"); + + MF_VALIDATE_EXTENT (s, (sizeof (*s)), __MF_CHECK_WRITE, "freopen64 stream"); + unmkbuffer (s); + + n = strlen (mode); + MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "freopen64 mode"); + + p = freopen (path, mode, s); + if (NULL != p) { +#ifdef MF_REGISTER_fopen + __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "freopen64 result"); +#endif + MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "freopen64 result"); + + mkbuffer (p); } return p; @@ -623,8 +835,9 @@ WRAPPER2(int, fclose, FILE *stream) "fclose stream"); resp = fclose (stream); #ifdef MF_REGISTER_fopen - __mf_unregister (stream, sizeof (*stream)); + __mf_unregister (stream, sizeof (*stream), MF_REGISTER_fopen); #endif + unmkbuffer (stream); return resp; } @@ -924,8 +1137,9 @@ WRAPPER2(int , remove, const char *path) WRAPPER2(int, fflush, FILE *stream) { TRACE ("%s\n", __PRETTY_FUNCTION__); - MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, - "fflush stream"); + if (stream != NULL) + MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, + "fflush stream"); return fflush (stream); } @@ -1052,28 +1266,7 @@ WRAPPER2(int , mkfifo, const char *path, mode_t mode) } -WRAPPER2(int, setvbuf, FILE *stream, char *buf, int mode , size_t size) -{ - TRACE ("%s\n", __PRETTY_FUNCTION__); - MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, - "setvbuf stream"); - if (NULL != buf) - MF_VALIDATE_EXTENT (buf, size, __MF_CHECK_READ, "setvbuf buf"); - return setvbuf (stream, buf, mode, size); -} - - -WRAPPER2(void, setbuf, FILE *stream, char *buf) -{ - TRACE ("%s\n", __PRETTY_FUNCTION__); - MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, - "setbuf stream"); - if (NULL != buf) - MF_VALIDATE_EXTENT (buf, BUFSIZ, __MF_CHECK_READ, "setbuf buf"); - setbuf (stream, buf); -} - - +#ifdef HAVE_DIRENT_H WRAPPER2(DIR *, opendir, const char *path) { DIR *p; @@ -1100,7 +1293,7 @@ WRAPPER2(int, closedir, DIR *dir) TRACE ("%s\n", __PRETTY_FUNCTION__); MF_VALIDATE_EXTENT (dir, 0, __MF_CHECK_WRITE, "closedir dir"); #ifdef MF_REGISTER_opendir - __mf_unregister (dir, MF_RESULT_SIZE_opendir); + __mf_unregister (dir, MF_RESULT_SIZE_opendir, MF_REGISTER_opendir); #endif return closedir (dir); } @@ -1120,6 +1313,7 @@ WRAPPER2(struct dirent *, readdir, DIR *dir) } return p; } +#endif #ifdef HAVE_SYS_SOCKET_H @@ -1380,7 +1574,7 @@ WRAPPER2(int, pclose, FILE *stream) "pclose stream"); resp = pclose (stream); #ifdef MF_REGISTER_fopen - __mf_unregister (stream, sizeof (*stream)); + __mf_unregister (stream, sizeof (*stream), MF_REGISTER_fopen); #endif return resp; } @@ -1498,7 +1692,7 @@ WRAPPER2(int, dlclose, void *handle) MF_VALIDATE_EXTENT (handle, 0, __MF_CHECK_READ, "dlclose handle"); resp = dlclose (handle); #ifdef MF_REGISTER_dlopen - __mf_unregister (handle, 0); + __mf_unregister (handle, 0, MF_REGISTER_dlopen); #endif return resp; } @@ -1580,8 +1774,8 @@ WRAPPER2(int, semctl, int semid, int semnum, int cmd, union semun arg) "semctl array"); break; #ifdef IPC_INFO - /* FreeBSD 5.1 headers include IPC_INFO but not the __buf field. */ -#if !defined(__FreeBSD__) + /* FreeBSD 5.1 And Cygwin headers include IPC_INFO but not the __buf field. */ +#if !defined(__FreeBSD__) && !defined(__CYGWIN__) case IPC_INFO: MF_VALIDATE_EXTENT (arg.__buf, sizeof (*arg.__buf), __MF_CHECK_WRITE, "semctl __buf"); @@ -1636,10 +1830,326 @@ WRAPPER2(int, shmdt, const void *shmaddr) TRACE ("%s\n", __PRETTY_FUNCTION__); resp = shmdt (shmaddr); #ifdef MF_REGISTER_shmat - __mf_unregister ((void *)shmaddr, 0); + __mf_unregister ((void *)shmaddr, 0, MF_REGISTER_shmat); #endif return resp; } #endif /* HAVE_SYS_IPC/SEM/SHM_H */ + + + +/* ctype stuff. This is host-specific by necessity, as the arrays + that is used by most is*()/to*() macros are implementation-defined. */ + +/* GLIBC 2.3 */ +#ifdef HAVE___CTYPE_B_LOC +WRAPPER2(unsigned short **, __ctype_b_loc, void) +{ + static unsigned short * last_buf = (void *) 0; + static unsigned short ** last_ptr = (void *) 0; + unsigned short ** ptr = (unsigned short **) __ctype_b_loc (); + unsigned short * buf = * ptr; + if (ptr != last_ptr) + { + /* XXX: unregister last_ptr? */ + last_ptr = ptr; + __mf_register (last_ptr, sizeof(last_ptr), __MF_TYPE_STATIC, "ctype_b_loc **"); + } + if (buf != last_buf) + { + last_buf = buf; + __mf_register ((void *) (last_buf - 128), 384 * sizeof(unsigned short), __MF_TYPE_STATIC, + "ctype_b_loc []"); + } + return ptr; +} +#endif + +#ifdef HAVE___CTYPE_TOUPPER_LOC +WRAPPER2(int **, __ctype_toupper_loc, void) +{ + static int * last_buf = (void *) 0; + static int ** last_ptr = (void *) 0; + int ** ptr = (int **) __ctype_toupper_loc (); + int * buf = * ptr; + if (ptr != last_ptr) + { + /* XXX: unregister last_ptr? */ + last_ptr = ptr; + __mf_register (last_ptr, sizeof(last_ptr), __MF_TYPE_STATIC, "ctype_toupper_loc **"); + } + if (buf != last_buf) + { + last_buf = buf; + __mf_register ((void *) (last_buf - 128), 384 * sizeof(int), __MF_TYPE_STATIC, + "ctype_toupper_loc []"); + } + return ptr; +} +#endif + +#ifdef HAVE___CTYPE_TOLOWER_LOC +WRAPPER2(int **, __ctype_tolower_loc, void) +{ + static int * last_buf = (void *) 0; + static int ** last_ptr = (void *) 0; + int ** ptr = (int **) __ctype_tolower_loc (); + int * buf = * ptr; + if (ptr != last_ptr) + { + /* XXX: unregister last_ptr? */ + last_ptr = ptr; + __mf_register (last_ptr, sizeof(last_ptr), __MF_TYPE_STATIC, "ctype_tolower_loc **"); + } + if (buf != last_buf) + { + last_buf = buf; + __mf_register ((void *) (last_buf - 128), 384 * sizeof(int), __MF_TYPE_STATIC, + "ctype_tolower_loc []"); + } + return ptr; +} +#endif + + +/* passwd/group related functions. These register every (static) pointer value returned, + and rely on libmudflap's quiet toleration of duplicate static registrations. */ + +#ifdef HAVE_GETLOGIN +WRAPPER2(char *, getlogin, void) +{ + char *buf = getlogin (); + if (buf != NULL) + __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC, + "getlogin() return"); + return buf; +} +#endif + + +#ifdef HAVE_CUSERID +WRAPPER2(char *, cuserid, char * buf) +{ + if (buf != NULL) + { + MF_VALIDATE_EXTENT(buf, L_cuserid, __MF_CHECK_WRITE, + "cuserid destination"); + return cuserid (buf); + } + buf = cuserid (NULL); + if (buf != NULL) + __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC, + "getcuserid() return"); + return buf; +} +#endif + + +#ifdef HAVE_GETPWNAM +WRAPPER2(struct passwd *, getpwnam, const char *name) +{ + struct passwd *buf; + MF_VALIDATE_EXTENT(name, strlen(name)+1, __MF_CHECK_READ, + "getpwnam name"); + buf = getpwnam (name); + if (buf != NULL) + __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC, + "getpw*() return"); + return buf; +} +#endif + + +#ifdef HAVE_GETPWUID +WRAPPER2(struct passwd *, getpwuid, uid_t uid) +{ + struct passwd *buf; + buf = getpwuid (uid); + if (buf != NULL) + __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC, + "getpw*() return"); + return buf; +} +#endif + + +#ifdef HAVE_GETGRNAM +WRAPPER2(struct group *, getgrnam, const char *name) +{ + struct group *buf; + MF_VALIDATE_EXTENT(name, strlen(name)+1, __MF_CHECK_READ, + "getgrnam name"); + buf = getgrnam (name); + if (buf != NULL) + __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC, + "getgr*() return"); + return buf; +} +#endif + + +#ifdef HAVE_GETGRGID +WRAPPER2(struct group *, getgrgid, uid_t uid) +{ + struct group *buf; + buf = getgrgid (uid); + if (buf != NULL) + __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC, + "getgr*() return"); + return buf; +} +#endif + + +#ifdef HAVE_GETSERVENT +WRAPPER2(struct servent *, getservent, void) +{ + struct servent *buf; + buf = getservent (); + if (buf != NULL) + __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC, + "getserv*() return"); + return buf; +} +#endif + + +#ifdef HAVE_GETSERVBYNAME +WRAPPER2(struct servent *, getservbyname, const char *name, const char *proto) +{ + struct servent *buf; + MF_VALIDATE_EXTENT(name, strlen(name)+1, __MF_CHECK_READ, + "getservbyname name"); + MF_VALIDATE_EXTENT(proto, strlen(proto)+1, __MF_CHECK_READ, + "getservbyname proto"); + buf = getservbyname (name, proto); + if (buf != NULL) + __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC, + "getserv*() return"); + return buf; +} +#endif + + +#ifdef HAVE_GETSERVBYPORT +WRAPPER2(struct servent *, getservbyport, int port, const char *proto) +{ + struct servent *buf; + MF_VALIDATE_EXTENT(proto, strlen(proto)+1, __MF_CHECK_READ, + "getservbyport proto"); + buf = getservbyport (port, proto); + if (buf != NULL) + __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC, + "getserv*() return"); + return buf; +} +#endif + + +#ifdef HAVE_GAI_STRERROR +WRAPPER2(const char *, gai_strerror, int errcode) +{ + const char *buf; + buf = gai_strerror (errcode); + if (buf != NULL) + __mf_register ((void *) buf, strlen(buf)+1, __MF_TYPE_STATIC, + "gai_strerror() return"); + return buf; +} +#endif + + +#ifdef HAVE_GETMNTENT +WRAPPER2(struct mntent *, getmntent, FILE *filep) +{ + struct mntent *m; + static struct mntent *last = NULL; + + MF_VALIDATE_EXTENT (filep, sizeof (*filep), __MF_CHECK_WRITE, + "getmntent stream"); +#define UR(field) __mf_unregister(last->field, strlen (last->field)+1, __MF_TYPE_STATIC) + if (last) + { + UR (mnt_fsname); + UR (mnt_dir); + UR (mnt_type); + UR (mnt_opts); + __mf_unregister (last, sizeof (*last), __MF_TYPE_STATIC); + } +#undef UR + + m = getmntent (filep); + last = m; + +#define R(field) __mf_register(last->field, strlen (last->field)+1, __MF_TYPE_STATIC, "mntent " #field) + if (m) + { + R (mnt_fsname); + R (mnt_dir); + R (mnt_type); + R (mnt_opts); + __mf_register (last, sizeof (*last), __MF_TYPE_STATIC, "getmntent result"); + } +#undef R + + return m; +} +#endif + + +#ifdef HAVE_INET_NTOA +WRAPPER2(char *, inet_ntoa, struct in_addr in) +{ + static char *last_buf = NULL; + char *buf; + if (last_buf) + __mf_unregister (last_buf, strlen (last_buf)+1, __MF_TYPE_STATIC); + buf = inet_ntoa (in); + last_buf = buf; + if (buf) + __mf_register (last_buf, strlen (last_buf)+1, __MF_TYPE_STATIC, "inet_ntoa result"); + return buf; +} +#endif + + +#ifdef HAVE_GETPROTOENT +WRAPPER2(struct protoent *, getprotoent, void) +{ + struct protoent *buf; + buf = getprotoent (); + if (buf != NULL) + __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC, "getproto*() return"); + return buf; +} +#endif + + +#ifdef HAVE_GETPROTOBYNAME +WRAPPER2(struct protoent *, getprotobyname, const char *name) +{ + struct protoent *buf; + MF_VALIDATE_EXTENT(name, strlen(name)+1, __MF_CHECK_READ, + "getprotobyname name"); + buf = getprotobyname (name); + if (buf != NULL) + __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC, + "getproto*() return"); + return buf; +} +#endif + + +#ifdef HAVE_GETPROTOBYNUMBER +WRAPPER2(struct protoent *, getprotobynumber, int port) +{ + struct protoent *buf; + buf = getprotobynumber (port); + if (buf != NULL) + __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC, + "getproto*() return"); + return buf; +} +#endif