static int master(void)
{
    modem_t modem[10];
    char buf[1024];
    int len;
    int i;

    for (i = 0;  i < 10;  i++)
    {
        if (psuedo_terminal_create(&modem[i]))
        {
            printf("Failure\n");
            exit(2);
        }
        printf("%s %s\n", modem[i].devlink, modem[i].stty);
    }

    for (;;)
    {
        for (i = 0;  i < 10;  i++)
        {
            len = read(modem[i].master, buf, 4);
            if (len >= 0)
            {
                buf[len] = '\0';
                printf("%d %d '%s' %s\n", i, len, buf, strerror(errno));
            }
        }
    }

    for (i = 0;  i < 10;  i++)
    {
        if (psuedo_terminal_close(&modem[i]))
        {
            printf("Failure\n");
            exit(2);
        }
    }
    return 0;
}
int psuedo_terminal_create(modem_t *modem)
{
#if defined(WIN32)
    COMMTIMEOUTS timeouts = {0};
#endif

    memset(modem, 0, sizeof(*modem));

    span_log_init(&modem->logging, SPAN_LOG_NONE, NULL);
    span_log_set_protocol(&modem->logging, "PTY");

    span_log_set_level(&modem->logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
    span_log_set_tag(&modem->logging, "PTY");

    modem->master = -1;
    modem->slave = -1;

#if USE_OPENPTY
    if (openpty(&modem->master, &modem->slave, NULL, NULL, NULL))
    {
        span_log(&modem->logging, SPAN_LOG_ERROR, "Fatal error: failed to initialize pty\n");
        return -1;
    }
    modem->stty = ttyname(modem->slave);
#else
#if defined(WIN32)
    modem->slot = 4 + next_id++; /* need work here we start at COM4 for now*/
    snprintf(modem->devlink, sizeof(modem->devlink), "COM%d", modem->slot);

    modem->master = CreateFile(modem->devlink,
                               GENERIC_READ | GENERIC_WRITE,
                               0,
                               0,
                               OPEN_EXISTING,
                               FILE_FLAG_OVERLAPPED,
                               0);
    if (modem->master == INVALID_HANDLE_VALUE)
    {
        if (GetLastError() == ERROR_FILE_NOT_FOUND)
            span_log(&modem->logging, SPAN_LOG_ERROR, "Fatal error: Serial port does not exist\n");
        else
            span_log(&modem->logging, SPAN_LOG_ERROR, "Fatal error: Serial port open error\n");
        return -1;
    }
#elif !defined(HAVE_POSIX_OPENPT)
    modem->master = open("/dev/ptmx", O_RDWR);
#else
    modem->master = posix_openpt(O_RDWR | O_NOCTTY);
#endif

#if !defined(WIN32)
    if (modem->master < 0)
        span_log(&modem->logging, SPAN_LOG_ERROR, "Fatal error: failed to initialize UNIX98 master pty\n");

    if (grantpt(modem->master) < 0)
        span_log(&modem->logging, SPAN_LOG_ERROR, "Fatal error: failed to grant access to slave pty\n");

    if (unlockpt(modem->master) < 0)
        span_log(&modem->logging, SPAN_LOG_ERROR, "Fatal error: failed to unlock slave pty\n");

    if ((modem->stty = ptsname(modem->master)) == NULL)
        span_log(&modem->logging, SPAN_LOG_ERROR, "Fatal error: failed to obtain slave pty filename\n");

    if ((modem->slave = open(modem->stty, O_RDWR)) < 0)
        span_log(&modem->logging, SPAN_LOG_ERROR, "Fatal error: failed to open slave pty %s\n", modem->stty);
#endif

#if defined(SOLARIS)
    ioctl(modem->slave, I_PUSH, "ptem");
    ioctl(modem->slave, I_PUSH, "ldterm");
#endif
#endif

#if defined(WIN32)
    timeouts.ReadIntervalTimeout = 50;
    timeouts.ReadTotalTimeoutConstant = 50;
    timeouts.ReadTotalTimeoutMultiplier = 10;

    timeouts.WriteTotalTimeoutConstant = 50;
    timeouts.WriteTotalTimeoutMultiplier = 10;

    SetCommMask(modem->master, EV_RXCHAR);

    if (!SetCommTimeouts(modem->master, &timeouts))
    {
        span_log(&modem->logging, SPAN_LOG_ERROR, "Cannot set up non-blocking read on %s\n", modem->devlink);
        psuedo_terminal_close(modem);
        return -1;
    }
    modem->threadAbort = CreateEvent(NULL, true, false, NULL);
#else
    modem->slot = next_id++;
    snprintf(modem->devlink, sizeof(modem->devlink), "%s/%d", device_root_name, modem->slot);

    /* Remove any stale link which might be present */
    unlink(modem->devlink);

    if (symlink(modem->stty, modem->devlink))
    {
        span_log(&modem->logging, SPAN_LOG_ERROR, "Fatal error: failed to create %s symbolic link\n", modem->devlink);
        psuedo_terminal_close(modem);
        return -1;
    }

    if (fcntl(modem->master, F_SETFL, fcntl(modem->master, F_GETFL, 0) | O_NONBLOCK))
    {
        span_log(&modem->logging, SPAN_LOG_ERROR, "Cannot set up non-blocking read on %s\n", ttyname(modem->master));
        psuedo_terminal_close(modem);
        return -1;
    }
#endif
    return 0;
}
int main(int argc, char *argv[])
{
    int log_audio;
    int t38_mode;
    int test_sending;
    int use_ecm;
    int use_gui;
    int g1050_model_no;
    int g1050_speed_pattern_no;
    int opt;
#if !defined(WIN32)
    int tioflags;
#endif

    decode_test_file = NULL;
    log_audio = FALSE;
    test_sending = FALSE;
    t38_mode = FALSE;
    use_ecm = FALSE;
    use_gui = FALSE;
    g1050_model_no = 0;
    g1050_speed_pattern_no = 1;
    while ((opt = getopt(argc, argv, "d:eglM:rS:st")) != -1)
    {
        switch (opt)
        {
        case 'd':
            decode_test_file = optarg;
            break;
        case 'e':
            use_ecm = TRUE;
            break;
        case 'g':
#if defined(ENABLE_GUI)
            use_gui = TRUE;
#else
            fprintf(stderr, "Graphical monitoring not available\n");
            exit(2);
#endif
            break;
        case 'l':
            log_audio = TRUE;
            break;
        case 'M':
            g1050_model_no = optarg[0] - 'A' + 1;
            break;
        case 'r':
            test_sending = FALSE;
            break;
        case 'S':
            g1050_speed_pattern_no = atoi(optarg);
            break;
        case 's':
            test_sending = TRUE;
            break;
        case 't':
            t38_mode = TRUE;
            break;
        default:
            //usage();
            exit(2);
            break;
        }
    }

    if (psuedo_terminal_create(&modem[0]))
        printf("Failure\n");

#if !defined(WIN32)
    ioctl(modem[0].slave, TIOCMGET, &tioflags);
    tioflags |= TIOCM_RI;
    ioctl(modem[0].slave, TIOCMSET, &tioflags);
#endif

    t30_tests(t38_mode, use_ecm, use_gui, log_audio, test_sending, g1050_model_no, g1050_speed_pattern_no);
    if (psuedo_terminal_close(&modem[0]))
        printf("Failure\n");
    printf("Tests passed\n");
    return 0;
}