1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/* 
 * File:   myconio.h
 * Author: Christian Seiler http://forum.de.selfhtml.org/archiv/2006/10/t138258/
 *
 * Created on 7. Dezember 2008, 14:50
 */

#ifdef  WIN32
  #include <conio.h>
  #include <windows.h>
  #include <stdio.h>
  #include <stdlib.h>

// HACK: test if I'am in the windows CMD by trying to request the console mode
bool testCMD() 
{
  HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); 
  if (hStdin == INVALID_HANDLE_VALUE) {
    return false;
  }

  DWORD fdwSaveOldMode;
  if ( !GetConsoleMode(hStdin, &fdwSaveOldMode) ) {
    return false;
  }

  return true;
}

// HACK: test if it's a linux like console by trying to run stty
bool testTTY() {
  FILE *fp = _popen("stty -isig ","r");

  if(fp == NULL) {<--- Either the condition 'fp==NULL' is redundant or there is possible null pointer dereference: fp.
    false;
  }

  // skip the output
  char buffer[128];
  while(fgets(buffer, 128, fp)) {
    //printf(buffer);
  }

  // try to reset the console in any case 
  system("stty sane");

  // there was no problem running stty
  return _pclose(fp) == 0;
}

const bool imInCMD = testCMD();
const bool imInTTY = testTTY();

int mygetch()
{
  if(imInCMD) {
    return _getch();
  }

  if(imInTTY) {
    system("stty cbreak -echo");
    int r = getchar();
    system("stty -cbreak echo");
    return r;
  }

  // just use the standard getchar in line mode
  return getchar();
}

#else
#ifndef _MYCONIO_H
#define _MYCONIO_H

#ifdef  __cplusplus
extern "C"
{
#endif

#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <string.h>

// Nachimplementierung der getch()-Funktion aus DOS-conio.h
// fuer POSIX-Betriebsysteme
// Lizenz: Public domain

int mygetch()
{
  int ch;
  struct termios old_t, tmp_t;

  // alte Attribute holen
  if (tcgetattr(STDIN_FILENO, &old_t))
  {
    // moeglicherweise kein Terminal
    // moeglicherweise anderer Fehler
    return -1;
  }
  // struktur kopieren
  memcpy(&tmp_t, &old_t, sizeof (old_t));
  // Zeilenmodus sowie Spezialzeichen deaktivieren,
  // Bildschirmausgabe von eingegebenen Zeichen
  // deaktivieren
  tmp_t.c_lflag &= ~ICANON & ~ECHO;
  // Neue Flags setzen
  if (tcsetattr(STDIN_FILENO, TCSANOW, (const struct termios *) & tmp_t))
  {
    // moeglicherweise irgend ein Fehler
    return -1;
  }
  // zeichen einlesen (darauf verlassen,
  // STDIN_FILENO blockierend ist)
  ch = getchar();
  // Alte Flags zuruecksetzen
  // Rueckgabewert ignorieren, da das Terminal bei Fehler sowieso
  // nicht korrekt reagieren wird, wir dagegen aber nichts tun
  // koennen
  tcsetattr(STDIN_FILENO, TCSANOW, (const struct termios *) & old_t);
  // Zeichen zurueckgeben
  return ch;
}


#ifdef  __cplusplus
}
#endif

#endif  /* _MYCONIO_H */
#endif  /* WIN32 */