Ignore:
Timestamp:
Jul 11, 2012, 3:01:20 PM (9 years ago)
Author:
wisk
Message:

on win32, use a named pipe and IOCP to read stdout, stderr and debugfd correctly.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • zzuf/trunk/src/zzuf.c

    r4683 r4827  
    113113    ((fd >= 0) && (FD_ISSET(fd, p_fdset)))
    114114
     115#if defined _WIN32
     116#   include <Windows.h>
     117static CRITICAL_SECTION _zz_pipe_cs;
     118#endif
     119
    115120int main(int argc, char *argv[])
    116121{
     
    123128    int debug = 0, network = 0;
    124129    int i;
     130
     131#if defined _WIN32
     132    InitializeCriticalSection(&_zz_pipe_cs);
     133#endif
    125134
    126135    _zz_opts_init(opts);
     
    537546    _zz_opts_fini(opts);
    538547
     548#if defined _WIN32
     549    DeleteCriticalSection(&_zz_pipe_cs);
     550#endif
     551
    539552    return opts->crashes ? EXIT_FAILURE : EXIT_SUCCESS;
    540553}
     
    915928}
    916929
     930#ifdef _WIN32
     931
     932/* This structure contains useful information about data sent from fuzzed applications */
     933struct child_overlapped
     934{
     935    OVERLAPPED overlapped;
     936    char buf[BUFSIZ];
     937    struct opts * opts;
     938    int child_no;
     939    int fd_no;
     940};
     941
     942/* This callback is called when fuzzed applications write in fd out, err or debug */
     943static void _stdcall read_child(DWORD err_code, DWORD nbr_of_bytes_transfered, LPOVERLAPPED overlapped)
     944{
     945    struct child_overlapped * co = (struct child_overlapped *)overlapped;
     946
     947    /* TODO: handle more cases like ERROR_MORE_DATA */
     948    if (err_code != ERROR_SUCCESS) return;
     949
     950    EnterCriticalSection(&_zz_pipe_cs);
     951    switch (co->fd_no)
     952    {
     953    case 0: /* debug fd */
     954        write(1, "dbg: ", 4);
     955    case 1: /* out */
     956        write(1, co->buf, nbr_of_bytes_transfered); break;
     957    case 2: /* err */
     958        write(2, co->buf, nbr_of_bytes_transfered); break;
     959    default: break;
     960    }
     961    LeaveCriticalSection(&_zz_pipe_cs);
     962
     963    if(co->fd_no != 0) /* either out or err fd */
     964        co->opts->child[co->child_no].bytes += nbr_of_bytes_transfered;
     965
     966    if(co->opts->md5 && co->fd_no == 2)
     967        _zz_md5_add(co->opts->child[co->child_no].ctx, co->buf, nbr_of_bytes_transfered);
     968
     969    free(co); /* clean up allocated data */
     970}
     971
     972/* Since on windows select doesn't support file HANDLE, we use IOCP */
     973static void read_children(struct opts *opts)
     974{
     975    size_t i, j;
     976    HANDLE *children_handle, * cur_child_handle;
     977    size_t fd_number = opts->maxchild * 3;
     978
     979    cur_child_handle = children_handle = malloc(sizeof(*children_handle) * fd_number);
     980
     981    for(i = 0; i < fd_number; i++)
     982        children_handle[i] = INVALID_HANDLE_VALUE;
     983
     984    /* XXX: cute (i, j) iterating hack */
     985    for(i = 0, j = 0; i < (size_t)opts->maxchild; i += (j == 2), j = (j + 1) % 3)
     986    {
     987        struct child_overlapped * co;
     988        HANDLE h;
     989
     990        if(opts->child[i].status != STATUS_RUNNING)
     991            continue;
     992
     993        co = malloc(sizeof(*co));
     994        ZeroMemory(co, sizeof(*co));
     995        *cur_child_handle = co->overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
     996        co->child_no = i;
     997        co->fd_no    = j;
     998        co->opts     = opts;
     999
     1000        h = (HANDLE)_get_osfhandle(opts->child[i].fd[j]);
     1001
     1002        /* FIXME: handle error */
     1003        ReadFileEx(h, co->buf, sizeof(co->buf), (LPOVERLAPPED)co, read_child);
     1004        cur_child_handle++;
     1005    }
     1006
     1007    /* FIXME: handle error */
     1008    WaitForMultipleObjectsEx(fd_number, children_handle, FALSE, INFINITE, TRUE);
     1009}
     1010
     1011#else
    9171012static void read_children(struct opts *opts)
    9181013{
     
    9341029    tv.tv_usec = 1000;
    9351030
    936 #if !defined _WIN32
    937     /* Win32 does not support select() on non-sockets */
    9381031    errno = 0;
    9391032    ret = select(maxfd + 1, &fdset, NULL, NULL, &tv);
     
    9421035    if(ret <= 0)
    9431036        return;
    944 #endif
    9451037
    9461038    /* XXX: cute (i, j) iterating hack */
     
    9521044            continue;
    9531045
    954 #if !defined _WIN32
    9551046        if(!ZZUF_FD_ISSET(opts->child[i].fd[j], &fdset))
    9561047            continue;
    957 #endif
    9581048
    9591049        ret = read(opts->child[i].fd[j], buf, BUFSIZ - 1);
     
    9691059                write((j < 2) ? STDERR_FILENO : STDOUT_FILENO, buf, ret);
    9701060        }
    971 #if !defined _WIN32
    9721061        else if(ret == 0)
    9731062        {
     
    9811070                opts->child[i].status = STATUS_EOF;
    9821071        }
    983 #endif
    984     }
    985 }
     1072    }
     1073}
     1074#endif
    9861075
    9871076#if !defined HAVE_SETENV
Note: See TracChangeset for help on using the changeset viewer.