/*************************************************************************** * Copyright (C) 2001 by Rick L. Vinyard, Jr. * * rvinyard@cs.nmsu.edu * * * * This file is part of the conexus library. * * * * The conexus library is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License version 3 * * as published by the Free Software Foundation. * * * * The conexus library is distributed in the hope that it will be * * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * * General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this software. If not see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #include <conexus.h> #include <iostream> #include <termios.h> #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <sys/signal.h> #include <stdlib.h> #include <sys/wait.h> #define BAUDRATE 4000000 #define ENDMINITERM 2 /* ctrl-b to quit miniterm */ #define _POSIX_SOURCE 1 /* POSIX compliant source */ using namespace std; volatile bool STOP = false; void child_handler( int s ) { STOP = true; } void print_data( const Conexus::Data d ); int main( int argc, char** argv ) { Conexus::init(); int c; Conexus::TTY::pointer tty = Conexus::TTY::create(); struct termios oldstdio, newstdio; struct sigaction sa; char default_device[] = "/dev/ttyS0"; char* device = default_device; if ( argc == 2 ) device = argv[ 1 ]; /* Open modem device for reading and writing and not as controlling tty because we don't want to get killed if linenoise sends CTRL-C. */ tty->open( device ); tty->set_speed( BAUDRATE ); /* Strange, but if you uncomment this command miniterm will not work even if you stop canonical mode for stdout. */ tcgetattr( 1, &oldstdio ); newstdio = tty->attributes(); tcsetattr( 1, TCSANOW, &newstdio ); /* stdout settings like modem settings */ /* terminal settings done, now handle in/ouput */ switch ( fork() ) { case 0: /* child */ /* user input */ close( 1 ); /* stdout not needed */ for ( c = getchar(); c != ENDMINITERM ; c = getchar() ) tty->write( &c, 1 ); tty->close(); tcsetattr( 1, TCSANOW, &oldstdio ); exit( 0 ); /* will send a SIGCHLD to the parent */ break; case - 1: perror( "fork" ); tty->close(); tcsetattr( 1, TCSANOW, &oldstdio ); exit( -1 ); default: /* parent */ close( 0 ); /* stdin not needed */ sa.sa_handler = child_handler; sa.sa_flags = 0; sigaction( SIGCHLD, &sa, NULL ); /* handle dying child */ tty->signal_data().connect( sigc::ptr_fun( &print_data ) ); tty->start(); while ( !STOP ) ; /* modem input handler */ tty->stop(); wait( NULL ); /* wait for child to die or it will become a zombie */ break; } return 0; } void print_data( const Conexus::Data d ) { for ( unsigned i = 0; i < d.size(); i++ ) cout << ( char ) ( d.data() [ i ] ); cout << flush; }