Exemplo n.º 1
0
int ty_thread_create(ty_thread *thread, ty_thread_func *f, void *udata)
{
    struct thread_context ctx;
    int r;

    ctx.thread = thread;
    ctx.f = f;
    ctx.udata = udata;

    ctx.ev = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (!ctx.ev) {
        r = ty_error(TY_ERROR_SYSTEM, "CreateEvent() failed: %s", ty_win32_strerror(0));
        goto cleanup;
    }

    thread->h = (HANDLE)_beginthreadex(NULL, 0, thread_proc, &ctx, 0,
                                       (unsigned int *)&thread->thread_id);
    if (!thread->h) {
        r = ty_error(TY_ERROR_SYSTEM, "_beginthreadex() failed: %s", ty_win32_strerror(0));
        goto cleanup;
    }

    WaitForSingleObject(ctx.ev, INFINITE);

    r = 0;
cleanup:
    if (ctx.ev)
        CloseHandle(ctx.ev);
    return r;
}
Exemplo n.º 2
0
static int start_stdin_thread(void)
{
    input_available = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (!input_available)
        return ty_error(TY_ERROR_SYSTEM, "CreateEvent() failed: %s", ty_win32_strerror(0));

    input_processed = CreateEvent(NULL, TRUE, TRUE, NULL);
    if (!input_processed)
        return ty_error(TY_ERROR_SYSTEM, "CreateEvent() failed: %s", ty_win32_strerror(0));

    input_thread = (HANDLE)_beginthreadex(NULL, 0, stdin_thread, NULL, 0, NULL);
    if (!input_thread)
        return ty_error(TY_ERROR_SYSTEM, "_beginthreadex() failed: %s", ty_win32_strerror(0));

    return 0;
}
Exemplo n.º 3
0
int ty_terminal_setup(int flags)
{
    HANDLE handle;
    DWORD mode;
    BOOL r;

    handle = GetStdHandle(STD_INPUT_HANDLE);
    if (handle == INVALID_HANDLE_VALUE)
        return ty_error(TY_ERROR_SYSTEM, "GetStdHandle(STD_INPUT_HANDLE) failed");

    r = GetConsoleMode(handle, &mode);
    if (!r) {
        if (GetLastError() == ERROR_INVALID_HANDLE)
            return ty_error(TY_ERROR_UNSUPPORTED, "Not a terminal");
        return ty_error(TY_ERROR_SYSTEM, "GetConsoleMode(STD_INPUT_HANDLE) failed: %s",
                        ty_win32_strerror(0));
    }

    if (!saved_console_mode) {
        orig_console_mode = mode;
        saved_console_mode = true;

        atexit(ty_terminal_restore);
    }

    mode |= ENABLE_PROCESSED_INPUT;

    mode &= (DWORD)~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT);
    if (!(flags & TY_TERMINAL_RAW))
        mode |= ENABLE_LINE_INPUT;
    if (!(flags & TY_TERMINAL_SILENT))
        mode |= ENABLE_ECHO_INPUT;

    r = SetConsoleMode(handle, mode);
    if (!r)
        return ty_error(TY_ERROR_SYSTEM, "SetConsoleMode(STD_INPUT_HANDLE) failed: %s",
                        ty_win32_strerror(0));

    return 0;
}
Exemplo n.º 4
0
int ty_poll(const ty_descriptor_set *set, int timeout)
{
    assert(set);
    assert(set->count);
    assert(set->count <= 64);

    DWORD ret = WaitForMultipleObjects((DWORD)set->count, set->desc, FALSE,
                                       timeout < 0 ? INFINITE : (DWORD)timeout);
    switch (ret) {
    case WAIT_FAILED:
        return ty_error(TY_ERROR_SYSTEM, "WaitForMultipleObjects() failed: %s",
                        ty_win32_strerror(0));
    case WAIT_TIMEOUT:
        return 0;
    }

    return set->id[ret - WAIT_OBJECT_0];
}
Exemplo n.º 5
0
int ty_cond_init(ty_cond *cond)
{
    static bool init;
    static InitializeConditionVariable_func *InitializeConditionVariable_;

    if (!init) {
        HANDLE kernel32 = GetModuleHandle("kernel32.dll");

        // Condition Variables appeared on Vista, emulate them on Windows XP
        InitializeConditionVariable_ = (InitializeConditionVariable_func *)GetProcAddress(kernel32, "InitializeConditionVariable");
        if (InitializeConditionVariable_) {
            WakeConditionVariable_ = (WakeConditionVariable_func *)GetProcAddress(kernel32, "WakeConditionVariable");
            WakeAllConditionVariable_ = (WakeAllConditionVariable_func *)GetProcAddress(kernel32, "WakeAllConditionVariable");
            SleepConditionVariableCS_ = (SleepConditionVariableCS_func *)GetProcAddress(kernel32, "SleepConditionVariableCS");
        } else {
            WakeConditionVariable_ = WakeConditionVariable_fallback;
            WakeAllConditionVariable_ = WakeAllConditionVariable_fallback;
            SleepConditionVariableCS_ = SleepConditionVariableCS_fallback;
        }

        init = true;
    }

    if (InitializeConditionVariable_) {
        InitializeConditionVariable_((CONDITION_VARIABLE *)&cond->cv);
    } else {
        memset(cond, 0, sizeof(*cond));
        cond->xp.ev = CreateEvent(NULL, TRUE, FALSE, NULL);
        if (!cond->xp.ev)
            return ty_error(TY_ERROR_SYSTEM, "CreateEvent() failed: %s", ty_win32_strerror(0));
        InitializeCriticalSection((CRITICAL_SECTION *)&cond->xp.mutex);
    }
    cond->init = true;

    return 0;
}
Exemplo n.º 6
0
int ty_stat(const char *path, ty_file_info *info, bool follow)
{
    TY_UNUSED(follow);

    assert(path && path[0]);
    assert(info);

    HANDLE h;
    BY_HANDLE_FILE_INFORMATION attr;
    int r;

    // FIXME: check error handling
    h = CreateFile(path, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
    if (h == INVALID_HANDLE_VALUE) {
        switch (GetLastError()) {
        case ERROR_ACCESS_DENIED:
            return ty_error(TY_ERROR_ACCESS, "Permission denied for '%s'", path);
        case ERROR_NOT_READY:
            return ty_error(TY_ERROR_IO, "I/O error while stating '%s'", path);
        case ERROR_FILE_NOT_FOUND:
            return ty_error(TY_ERROR_NOT_FOUND, "Path '%s' does not exist", path);
        case ERROR_PATH_NOT_FOUND:
            return ty_error(TY_ERROR_NOT_FOUND, "Part of '%s' is not a directory", path);
        }
        // Let's lie a little, error will be clearer this way
        return ty_error(TY_ERROR_SYSTEM, "GetFileAttributesEx('%s') failed: %s", path, ty_win32_strerror(0));
    }

    r = GetFileInformationByHandle(h, &attr);
    if (!r)
        return ty_error(TY_ERROR_SYSTEM, "GetFileInformationByHandle('%s') failed: %s", path, ty_win32_strerror(0));

    if (attr.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
        info->type = TY_FILE_DIRECTORY;
    } else if (attr.dwFileAttributes & FILE_ATTRIBUTE_DEVICE) {
        info->type = TY_FILE_SPECIAL;
    } else {
        info->type = TY_FILE_REGULAR;
    }

    info->size = ((uint64_t)attr.nFileSizeHigh << 32) | attr.nFileSizeLow;
    info->mtime = filetime_to_unix_time(&attr.ftLastWriteTime);

    return 0;
}