The UNIX and Linux Forums  

Go Back   The UNIX and Linux Forums > Top Forums > High Level Programming
Google UNIX.COM



View Single Post in UNIX Forums - Click on the Thread or Permalink to View Entire Thread -->
  #8 (permalink)  
Old 04-10-2008
stewartw stewartw is offline
Registered User
 

Join Date: Apr 2008
Posts: 5
Ramen Noodle,

You are correct. When I supply the return it terminates. But this is the real story. Below is the original program that had this problem. It uses the NCurses library. I simplified it for the post. This program puts the terminal into cbreak mode and does not require the newline character -- it is using non-blocking I/O. And you will discover that typign newline after the 'q' does not solve it.

But I would be grateful to know what does. Here it is:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <curses.h>
#include <signal.h>
#include <sys/time.h>
#include <fcntl.h>
#include <time.h>
#include "timers.h"

/*****************************************************************************/
/* Global Constants */
/*****************************************************************************/

#define INITIAL_SPEED 30
#define RIGHT 1
#define LEFT -1
#define ROW 12
#define MESSAGE "ooooooo=>"
#define REVMSSGE "<=ooooooo"
#define BLANK " "

int row; // current row
int col; // current column
int dir; // Global variable to store direction of movement
int speed; // Current speed in chars/second
volatile sig_atomic_t finished;

/*****************************************************************************/
/* Signal Handler Prototypes */
/*****************************************************************************/
void on_alarm(int); /* handler for alarm */
void on_input(int); /* handler for keybd */

/*****************************************************************************/
/* Utility Function Prototype */
/*****************************************************************************/

void enable_kbd_signals();

/*****************************************************************************/
/* Main */
/*****************************************************************************/
int main( int argc, char * argv[])
{
struct sigaction newhandler; // for installing handlers
sigset_t blocked; // to set mask for handler


// Set up signal handling
newhandler.sa_handler = on_input; // name of handler
newhandler.sa_flags = SA_RESTART; // flag is just RESTART
sigemptyset(&blocked); // clear all bits of blocked set
//sigaddset(&blocked, SIGALRM);
newhandler.sa_mask = blocked; // set this empty set to be the mask
if ( sigaction(SIGIO, &newhandler, NULL) == -1 ) {
perror("sigaction");
return (1);
}

sigemptyset(&blocked); // clear all bits of blocked set
//sigaddset(&blocked, SIGIO);
newhandler.sa_mask = blocked; // set this empty set to be the mask
newhandler.sa_handler = on_alarm; // SIGALRM handler function
if ( sigaction(SIGALRM, &newhandler, NULL) == -1 ){ // try to install
perror("sigaction");
return (1);
}

// Prepare the terminal for the animation
initscr(); // initialize the library and screen
cbreak(); // put terminal into non-blocking input mode
noecho(); // turn off echo
clear(); // clear the screen
curs_set(0); // hide the cursor

// Initialize the parameters of the program
row = ROW;
col = 0;
dir = RIGHT;
finished = 0;
speed = INITIAL_SPEED ;

// Turn on keyboard signals
enable_kbd_signals();

// Start the real time interval timer with delay interval size
set_timer( ITIMER_REAL, 1000/speed, 1000/speed );


// mvaddstr(LINES-1, 0, "Current speed:");
//refresh();

// Put the message into the first position and start
mvaddstr(row, col, MESSAGE);


while( !finished ) {
pause();
}
endwin();
return 0;
}

/*****************************************************************************/

void on_input(int signum)
{
int c;

c = getch();

switch (c) {

case 'Q':

case 'q':

finished = 1;
}
}



/*****************************************************************************/

void on_alarm(int signum)
{

mvaddstr( row, col, BLANK ); // erase old string
col += dir; // advance one column
move( row, col ); // move to new locataion
if ( RIGHT == dir ) {
addstr( MESSAGE ); // add forward string
if ( col+strlen(MESSAGE) >= COLS-1 )
dir = LEFT; // reverse if hitting edge
}
else {
addstr( REVMSSGE ); // add reverse string
if ( col <= 0 )
dir = RIGHT; // reverse if hitting edge
}
refresh();
}

/*****************************************************************************/
/*
* install a handler, tell kernel who to notify on input, enable signals
*/
void enable_kbd_signals()
{
int fd_flags;

fcntl(0, F_SETOWN, getpid());
fd_flags = fcntl(0, F_GETFL);
fcntl(0, F_SETFL, (fd_flags|O_ASYNC));
}
Reply With Quote