source: zzuf/trunk/src/fd.c @ 1671

Last change on this file since 1671 was 1671, checked in by Sam Hocevar, 16 years ago
  • Oops, ratio should be a double, not a float.
  • Property svn:keywords set to Id
File size: 5.2 KB
Line 
1/*
2 *  zzuf - general purpose fuzzer
3 *  Copyright (c) 2006 Sam Hocevar <sam@zoy.org>
4 *                All Rights Reserved
5 *
6 *  $Id: fd.c 1671 2007-01-14 20:47:18Z sam $
7 *
8 *  This program is free software. It comes without any warranty, to
9 *  the extent permitted by applicable law. You can redistribute it
10 *  and/or modify it under the terms of the Do What The Fuck You Want
11 *  To Public License, Version 2, as published by Sam Hocevar. See
12 *  http://sam.zoy.org/wtfpl/COPYING for more details.
13 */
14
15/*
16 *  libzzuf.c: preloaded wrapper library
17 */
18
19#include "config.h"
20#define _GNU_SOURCE
21
22#if defined HAVE_STDINT_H
23#   include <stdint.h>
24#elif defined HAVE_INTTYPES_H
25#   include <inttypes.h>
26#endif
27#include <stdlib.h>
28#include <regex.h>
29#include <string.h>
30
31#include "debug.h"
32#include "libzzuf.h"
33#include "fd.h"
34
35/* Regex stuff */
36static regex_t re_include, re_exclude;
37static int has_include = 0, has_exclude = 0;
38
39/* File descriptor stuff. When program is launched, we use the static array of
40 * 32 structures, which ought to be enough for most programs. If it happens
41 * not to be the case, ie. if the process opens more than 32 file descriptors
42 * at the same time, a bigger array is malloc()ed and replaces the static one.
43 */
44#define STATIC_FILES 32
45static struct files
46{
47    int managed;
48    uint64_t pos;
49    /* Public stuff */
50    struct fuzz fuzz;
51}
52*files, static_files[STATIC_FILES];
53static int *fds, static_fds[STATIC_FILES];
54static int maxfd, nfiles;
55
56static int32_t seed = DEFAULT_SEED;
57static double  ratio = DEFAULT_RATIO;
58static int     autoinc = 0;
59
60void _zz_include(char const *regex)
61{
62    if(regcomp(&re_include, regex, REG_EXTENDED) == 0)
63        has_include = 1;
64}
65
66void _zz_exclude(char const *regex)
67{
68    if(regcomp(&re_exclude, regex, REG_EXTENDED) == 0)
69        has_exclude = 1;
70}
71
72void _zz_setseed(int32_t s)
73{
74    seed = s;
75}
76
77void _zz_setratio(double r)
78{
79    if(r < MIN_RATIO)
80        r = MIN_RATIO;
81    else if(r > MAX_RATIO)
82        r = MAX_RATIO;
83    ratio = r;
84}
85
86void _zz_setautoinc(void)
87{
88    autoinc = 1;
89}
90
91void _zz_fd_init(void)
92{
93    /* We start with 32 file descriptors. This is to reduce the number of
94     * calls to malloc() that we do, so we get better chances that memory
95     * corruption errors are reproducible */
96    files = static_files;
97    for(nfiles = 0; nfiles < 32; nfiles++)
98        files[nfiles].managed = 0;
99
100    fds = static_fds;
101    for(maxfd = 0; maxfd < 32; maxfd++)
102        fds[maxfd] = -1;
103}
104
105void _zz_fd_fini(void)
106{
107    int i;
108
109    for(i = 0; i < maxfd; i++)
110    {
111        if(!files[fds[i]].managed)
112            continue;
113
114        /* XXX: What are we supposed to do? If filedescriptors weren't
115         * closed properly, there's a leak, but it's not our problem. */
116    }
117
118    if(files != static_files)
119       free(files);
120    if(fds != static_fds)
121        free(fds);
122}
123
124int _zz_mustwatch(char const *file)
125{
126    if(has_include && regexec(&re_include, file, 0, NULL, 0) == REG_NOMATCH)
127        return 0; /* not included: ignore */
128
129    if(has_exclude && regexec(&re_exclude, file, 0, NULL, 0) != REG_NOMATCH)
130        return 0; /* excluded: ignore */
131
132    return 1; /* default */
133}
134
135int _zz_iswatched(int fd)
136{
137    if(fd < 0 || fd >= maxfd || fds[fd] == -1)
138        return 0;
139
140    return 1;
141}
142
143void _zz_register(int fd)
144{
145    int i;
146
147    if(fd < 0 || fd > 65535 || (fd < maxfd && fds[fd] != -1))
148        return;
149
150#if 0
151    if(autoinc)
152        debug("using seed %li", (long int)seed);
153#endif
154
155    /* If filedescriptor is outside our bounds */
156    while(fd >= maxfd)
157    {
158        if(fds == static_fds)
159        {
160            fds = malloc(2 * maxfd * sizeof(*fds));
161            memcpy(fds, static_fds, maxfd * sizeof(*fds));
162        }
163        else
164            fds = realloc(fds, 2 * maxfd * sizeof(*fds));
165        for(i = maxfd; i < maxfd * 2; i++)
166            fds[i] = -1;
167        maxfd *= 2;
168    }
169           
170    /* Find an empty slot */
171    for(i = 0; i < nfiles; i++)
172        if(files[i].managed == 0)
173            break;
174
175    /* No slot found, allocate memory */
176    if(i == nfiles)
177    {
178        nfiles++;
179        if(files == static_files)
180        {
181            files = malloc(nfiles * sizeof(*files));
182            memcpy(files, static_files, nfiles * sizeof(*files));
183        }
184        else
185            files = realloc(files, nfiles * sizeof(*files));
186    }
187
188    files[i].managed = 1;
189    files[i].pos = 0;
190    files[i].fuzz.seed = seed;
191    files[i].fuzz.ratio = ratio;
192    files[i].fuzz.cur = -1;
193#ifdef HAVE_FGETLN
194    files[i].fuzz.tmp = NULL;
195#endif
196
197    if(autoinc)
198        seed++;
199
200    fds[fd] = i;
201}
202
203void _zz_unregister(int fd)
204{
205    if(fd < 0 || fd >= maxfd || fds[fd] == -1)
206        return;
207
208    files[fds[fd]].managed = 0;
209#ifdef HAVE_FGETLN
210    if(files[fds[fd]].fuzz.tmp)
211        free(files[fds[fd]].fuzz.tmp);
212#endif
213
214    fds[fd] = -1;
215}
216
217long int _zz_getpos(int fd)
218{
219    if(fd < 0 || fd >= maxfd || fds[fd] == -1)
220        return 0;
221
222    return files[fds[fd]].pos;
223}
224
225void _zz_setpos(int fd, long int pos)
226{
227    if(fd < 0 || fd >= maxfd || fds[fd] == -1)
228        return;
229
230    files[fds[fd]].pos = pos;
231}
232
233void _zz_addpos(int fd, long int off)
234{
235    if(fd < 0 || fd >= maxfd || fds[fd] == -1)
236        return;
237
238    files[fds[fd]].pos += off;
239}
240
241struct fuzz *_zz_getfuzz(int fd)
242{
243    if(fd < 0 || fd >= maxfd || fds[fd] == -1)
244        return NULL;
245
246    return &files[fds[fd]].fuzz;
247}
248
Note: See TracBrowser for help on using the repository browser.