Logo Search packages:      
Sourcecode: jpnevulator version File versions  Download package

tty.c

/* jpnevulator - serial reader/writer
 * Copyright (C) 2006 Freddy Spierenburg
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program 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 program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

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

#include "options.h"
#include "jpnevulator.h"
#include "tty.h"
#include "list.h"

static int ttyOpen(char *name) {
      int fd;
      struct termios options;
      fd=open(name,O_RDWR);
      if(fd!=-1) {
            /* Make sure we send to a raw serial interface! */
            fcntl(fd,F_SETFL,0);
            tcgetattr(fd,&options);
            cfmakeraw(&options);
            tcsetattr(fd,TCSANOW,&options);
      }
      return(fd);
}

static void ttyClose(int fd) {
      close(fd);
}

void ttyInitialize(void) {
      listInitialize(&_jpnevulatorOptions.tty);
}

static int cmpr(void *p,void *q) {
      return(!strcasecmp(((struct tty *)p)->name,(char *)q));
}

enum ttyRtrn ttyAdd(char *name) {
      struct tty *tty;
      int charactersPrinted;
      char error[256];
      char *alias;
      if(listSearch(&_jpnevulatorOptions.tty,cmpr,(void *)name)!=NULL) {
            return(ttyRtrnDouble);
      }
      tty=(struct tty *)malloc(sizeof(struct tty));
      if(tty==NULL) {
            return(ttyRtrnMemory);
      }
      /* Did the user give us a alias for the tty name? */
      if((alias=strstr(name,_jpnevulatorOptions.aliasSeparator))!=NULL) {
            /* Yes, so split the alias from the name. */
            *alias='\0';
            /* Advance the alias to the real beginning of it. */
            alias+=strlen(_jpnevulatorOptions.aliasSeparator);
            /* And put it in our alias reference. */
            charactersPrinted=sprintf(tty->alias,"%.*s",(int)sizeof(tty->alias)-1,alias);
            if(charactersPrinted!=strlen(alias)) {
                  fprintf(stderr,"%s: tty alias %s truncated to %d chars -> %s\n",PROGRAM_NAME,alias,charactersPrinted,tty->alias);
            }
      } else {
            /* No, empty the alias. */
            strcpy(tty->alias,"");
      }
      charactersPrinted=sprintf(tty->name,"%.*s",(int)sizeof(tty->name)-1,name);
      if(charactersPrinted!=strlen(name)) {
            fprintf(stderr,"%s: tty %s truncated to %d chars -> %s\n",PROGRAM_NAME,name,charactersPrinted,tty->name);
      }
      tty->fd=ttyOpen(tty->name);
      if(tty->fd==-1) {
            sprintf(error,"%s: Unable to open tty %s",PROGRAM_NAME,tty->name);
            perror(error);
            return(ttyRtrnOpen);
      }
      /* Initialize the byte count. We have not received/send any bytes yet. */
      tty->byteCount=0UL;
      if(listAppend(&_jpnevulatorOptions.tty,(void *)tty)!=listRtrnOk) {
            fprintf(stderr,"%s: unable to add tty %s to the list of tty's!\n",PROGRAM_NAME,tty->name);
            return(ttyRtrnList);
      }
      /* Advance to this next position. so all tty devices will be inline with the
       * order the user gave us. */
      listNext(&_jpnevulatorOptions.tty);
      return(ttyRtrnOk);
}

static void garbageCollect(void *data) {
      struct tty *tty;
      tty=(struct tty *)data;
      ttyClose(tty->fd);
      free(tty);
}

void ttyDestroy(void) {
      listDestroy(&_jpnevulatorOptions.tty,garbageCollect);
}

Generated by  Doxygen 1.6.0   Back to index