[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: C/C++ programming on Linux/Unix
Hi Vlady and all the others
I wrote few years ago such thing as part of a library.
the code is attached.
Replys are welcomed, the source is GPL I'll write help
if needed.
Try it and use it.
Maybe we should write a HOWTO for translating code from
MS / Borland to Linux with a set of functions.
Erez
BTW: no flames for using the list for the answer
As I think the subject might be of interes for
some other readers.
On Sun, 7 Dec 1997 rutman@handlin.pet.ac.il wrote:
> Hi.
> I have a big question.How can I get the functions like getch() and
> getche() for Linux/Unix C programs ,or possibly to develop them by
> any language (may be Assembler)?
> Has anybody have an answer or solution?
>
> Mail me:
> rutman@handlin.pet.ac.il
> Vlady
>
/* ____________________________________________________________________________
*
* $Header: /home/erez/cvs-main/tlib/ukbhit.h,v 1.2 1994/08/04 13:31:37 erez Exp $
* ukbhit.h
* Unix kbhit emulation functions interface. This file gives the prototype
* of a set of functions that emulate the operation of the DOS kbhit, getch
* and getche functions.
* The library works and tested on SunOs4.1.3 and Solaris2.3
*
* Written by Erez Strauss. 1994.
*
* $Log: ukbhit.h,v $
* Revision 1.2 1994/08/04 13:31:37 erez
* (1)(N) The non user function are static, (2)(N) There are new user
* functions kbhit_on, kbhit_off.
*
* Revision 1.1.1.1 1994/07/06 15:44:51 erez
* Library.
*
* ____________________________________________________________________________
*/
# ifndef __UKBHIT_H__
# define __UKBHIT_H__
# if defined ( __GNUC__ ) && ! defined ( NO_IDENT )
# ident "@(#)$Id: ukbhit.h,v 1.2 1994/08/04 13:31:37 erez Exp $"
# else /* __GNUC__ */
static const char _ukbhit_h_id[] = "@(#)$Id: ukbhit.h,v 1.2 1994/08/04 13:31:37 erez Exp $";
# endif /* __GNUC__ */
/* User usable Functions */
extern void kbhit_on (void);
extern void kbhit_off (void);
extern int kbhit (void);
extern void kbwait (void);
extern char getch (void);
extern char getche (void);
# endif /* __UKBHIT_H__ */
/* End of file: ukbhit.h ___________________________________________________ */
/* ____________________________________________________________________________
*
* $Header: /home/erez/cvs-main/tlib/ukbhit.c,v 1.4 1994/12/28 12:27:05 erez Exp $
* Unix emulation of the PC non waiting input/output.
*
* Written by Erez Strauss. 1994.
*
* $Log: ukbhit.c,v $
* Revision 1.4 1994/12/28 12:27:05 erez
* (1)(N) UKBHIT_TYPE, compile time flag choose which system call to use
* the select or the poll.
*
* Revision 1.3 1994/08/04 13:30:47 erez
* (1)(N) The non user function are static, (2)(N) There are new user
* functions kbhit_on, kbhit_off. (3)(BGFX) the kbhit_end was calling the
* termio set function with null argument in cat the end was called before.
*
* Revision 1.2 1994/07/31 08:09:13 erez
* (1)(U) The conditions of the Identification was updated.
*
* Revision 1.1.1.1 1994/07/06 15:44:51 erez
* Library.
*
* ____________________________________________________________________________
*/
# if ! defined ( NO_IDENT )
# if defined ( __GNUC__ )
# ident "@(#)$Id: ukbhit.c,v 1.4 1994/12/28 12:27:05 erez Exp $"
# else /* __GNUC__ */
static const char file_id[] = "@(#)$Id: ukbhit.c,v 1.4 1994/12/28 12:27:05 erez Exp $";
# endif/* __GNUC__ */
# endif /* NO_IDENT */
# include <stdio.h>
# include <stdlib.h>
# include <memory.h>
# include <unistd.h>
# include <signal.h>
# include <sys/termios.h>
# include <sys/types.h>
# include <sys/time.h>
# define UKBHIT_SELECT 1
# define UKBHIT_POLL 2
# include "ukbhit.h"
# ifndef UKBHIT_TYPE
# define UKBHIT_TYPE UKBHIT_SELECT
# endif /* UKBHIT_TYPE */
# if ( UKBHIT_TYPE == UKBHIT_POLL )
# include <poll.h>
# endif /* UKBHIT_TYPE */
static void kbhit_init (void);
static void kbhit_end (void);
/*
* The ukbhit library will provide the following user accessable functions:
* kbhit_on
* kbhit_off
* kbwait
* kbhit
* getch
* getche
* The other functions in this file are static and will be used only localy.
*/
/* first - code that doesn't depend on the select / poll */
void
kbhit_on (void)
{
kbhit_init ();
}
void
kbhit_off (void)
{
kbhit_end ();
}
char
getch (void)
{
char ch = 0;
kbwait ();
read (0, &ch, 1);
return ch;
}
char
getche ()
{
char ch = getch ();
fwrite (&ch, 1, 1, stdout);
fflush (stdout);
return ch;
}
/* poll code */
# if ( UKBHIT_TYPE == UKBHIT_POLL )
int
kbhit (void) /* with poll - just check input */
{
int i = 0;
struct pollfd ifd;
ifd.fd = 0;
ifd.events = POLLIN;
ifd.revents = 0;
kbhit_init ();
if (poll (&ifd, 1, 0) && (ifd.revents & POLLIN))
{
i = 1;
}
return i;
}
void
kbwait (void) /* with poll - just check input */
{
struct pollfd ifd;
ifd.fd = 0;
ifd.events = POLLIN;
ifd.revents = 0;
fflush (stdout);
kbhit_init ();
poll (&ifd, 1, -1); /* Wait without timeout */
}
# elif ( UKBHIT_TYPE == UKBHIT_SELECT ) /* UKBHIT_TYPE */
int
kbhit (void) /* with select - just check input */
{
int i = 0;
fd_set fds;
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO (&fds);
FD_SET (0, &fds);
kbhit_init ();
if (select (1, &fds, 0, 0, &tv))
{
i = 1;
}
return i;
}
void
kbwait (void) /* with select */
{
fd_set fds;
FD_ZERO (&fds);
FD_SET (0, &fds);
fflush (stdout);
kbhit_init ();
select (1, &fds, 0, 0, 0);
}
# else
# error ***** Error What about UKBHIT_TYPE, (UKBHIT_SELECT / UKBHIT_POLL)
# endif /* UKBHIT_TYPE */
static struct termios* trm_init_mode = 0;
static struct termios* trm_direct_mode = 0;
# ifdef UKBHIT_DEBUG
static void termios_dump (struct termios* p, FILE* fp);
static void
termios_dump (struct termios* p, FILE* fp)
{
fprintf (fp,
"p: 0x%lX\n"
"c_iflag:\t0x%08lX\n"
"c_oflag:\t0x%08lX\n"
"c_cflag:\t0x%08lX\n"
"c_lflag:\t0x%08lX\n"
"c_cc[0]:\t0x%02lX\n",
(long)p,
(long)p->c_iflag,
(long)p->c_oflag,
(long)p->c_cflag,
(long)p->c_lflag,
(long)p->c_cc[0]);
}
# endif /* UKBHIT_DEBUG */
static void
kbhit_init (void)
{
int status;
static int set_at_exit = 0;
if (!trm_init_mode || !trm_direct_mode)
{
if (!trm_init_mode)
{
trm_init_mode = (struct termios*)malloc (sizeof (struct termios));
}
if (!trm_direct_mode)
{
trm_direct_mode = (struct termios*)malloc (sizeof (struct termios));
}
if (!trm_init_mode || !trm_direct_mode)
{
fprintf (stderr, "kbhit_init: can't malloc !\n");
exit (1);
}
status = tcgetattr (0, trm_init_mode);
*trm_direct_mode = *trm_init_mode;
/* change trm_direct_mode */
trm_direct_mode->c_iflag &= ~BRKINT ;
trm_direct_mode->c_oflag |= 0;
trm_direct_mode->c_cflag |= 0;
trm_direct_mode->c_lflag &= ~(ISIG | ICANON | ECHO | ECHOE | ECHOK
| ECHONL | ECHOCTL);
/* trm_direct_mode->c_line |= 0; */
trm_direct_mode->c_cc[0] |= 0;
trm_direct_mode->c_cc[VMIN] = 0;
trm_direct_mode->c_cc[VTIME] = 0;
status = tcsetattr (0, TCSANOW, trm_direct_mode);
/* set atexit() function so at the end of the program the
* mode will return to normal.
*/
# if defined ( __GNUC__ ) && !defined ( __svr4__ )
/* SunOS 4.1.3 doesn't have the atexit() function. */
# define atexit(FNC) on_exit((FNC),0)
# endif/* __GNUC__ */
if (!set_at_exit)
{
set_at_exit = 1;
atexit (kbhit_end);
}
}
}
static void
kbhit_end (void)
{
/*
* We set the attributes without cleaning the input buffer.
*/
if (trm_init_mode)
{
tcsetattr (0, TCSANOW, trm_init_mode);
}
if (trm_direct_mode)
{
free (trm_direct_mode);
trm_direct_mode = 0;
}
if (trm_init_mode)
{
free (trm_init_mode);
trm_init_mode = 0;
}
}
# ifdef STAND_ALONE
int
main (int argc, char** argv)
{
int i = 0;
char buff[32];
while (!kbhit ()) /* busy wait */
{
if (!(i++ % 1000))
printf (".\n");
}
kbhit_off ();
fprintf (stderr, "\nEnter a string: ");
scanf ("%[^\n]", buff);
fprintf (stderr, "the buff: '%s'\n", buff);
return 0;
}
# endif /* STAND_ALONE */
/* End of file: ukbhit.c ___________________________________________________ */