llvm/openmp/runtime/src/kmp_io.cpp

/*
 * kmp_io.cpp -- RTL IO
 */

//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef __ABSOFT_WIN
#include <sys/types.h>
#endif

#include "kmp.h" // KMP_GTID_DNE, __kmp_debug_buf, etc
#include "kmp_io.h"
#include "kmp_lock.h"
#include "kmp_os.h"
#include "kmp_str.h"

#if KMP_OS_WINDOWS
#if KMP_MSVC_COMPAT
#pragma warning(push)
#pragma warning(disable : 271 310)
#endif
#include <windows.h>
#if KMP_MSVC_COMPAT
#pragma warning(pop)
#endif
#endif

/* ------------------------------------------------------------------------ */

kmp_bootstrap_lock_t __kmp_stdio_lock =; /* Control stdio functions */
kmp_bootstrap_lock_t __kmp_console_lock =; /* Control console initialization */

#if KMP_OS_WINDOWS

static HANDLE __kmp_stdout = NULL;
static HANDLE __kmp_stderr = NULL;
static int __kmp_console_exists = FALSE;
static kmp_str_buf_t __kmp_console_buf;

void __kmp_close_console(void) {
  /* wait until user presses return before closing window */
  /* TODO only close if a window was opened */
  if (__kmp_console_exists) {
    __kmp_stdout = NULL;
    __kmp_stderr = NULL;
    __kmp_str_buf_free(&__kmp_console_buf);
    __kmp_console_exists = FALSE;
  }
}

/* For windows, call this before stdout, stderr, or stdin are used.
   It opens a console window and starts processing */
static void __kmp_redirect_output(void) {
  __kmp_acquire_bootstrap_lock(&__kmp_console_lock);

  if (!__kmp_console_exists) {
    HANDLE ho;
    HANDLE he;

    __kmp_str_buf_init(&__kmp_console_buf);

    AllocConsole();
    // We do not check the result of AllocConsole because
    //  1. the call is harmless
    //  2. it is not clear how to communicate failue
    //  3. we will detect failure later when we get handle(s)

    ho = GetStdHandle(STD_OUTPUT_HANDLE);
    if (ho == INVALID_HANDLE_VALUE || ho == NULL) {

      DWORD err = GetLastError();
      // TODO: output error somehow (maybe message box)
      (void)err;
      __kmp_stdout = NULL;

    } else {

      __kmp_stdout = ho; // temporary code, need new global for ho
    }
    he = GetStdHandle(STD_ERROR_HANDLE);
    if (he == INVALID_HANDLE_VALUE || he == NULL) {

      DWORD err = GetLastError();
      // TODO: output error somehow (maybe message box)
      (void)err;
      __kmp_stderr = NULL;

    } else {

      __kmp_stderr = he; // temporary code, need new global
    }
    __kmp_console_exists = TRUE;
  }
  __kmp_release_bootstrap_lock(&__kmp_console_lock);
}

#else
#define __kmp_stderr
#define __kmp_stdout
#endif /* KMP_OS_WINDOWS */

void __kmp_vprintf(enum kmp_io out_stream, char const *format, va_list ap) {}

void __kmp_printf(char const *format, ...) {}

void __kmp_printf_no_lock(char const *format, ...) {}

void __kmp_fprintf(enum kmp_io stream, char const *format, ...) {}