⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 seterm.c

📁 功能丰富的串口通讯程序
💻 C
字号:
/* * This file is part of the Seyon, Copyright (c) 1992-1993 by Muhammad M. * Saggaf. All rights reserved. * * See the file COPYING (1-COPYING) or the manual page seyon(1) for a full * statement of rights and permissions for this program. *//* * This file contains routines for Seyon's terminal. The main routine is * terminal(), which reads characters from the terminal and sends them to the * port. That routine also forks a child process that reads characters from * the port and writes them to the temrinal. Once the parent receives SIGTERM * (which should be sent by the grand parent), it kills the child and exits. */#include <stdio.h>#include <unistd.h>#include <signal.h>#include <sys/types.h>#include <sys/wait.h>#include <X11/Intrinsic.h>#include "seyon.h"#include "SeDecl.h"extern char     TtyReadChar();extern int      MdmReadStr();extern FILE    *tfp,            /* terminal pointer */               *cfp;            /* capture file pointer */extern Boolean  capture;        /* are we capturing or not ? */extern int      tfd,            /* terminal descriptor */                mainToTermPipe[];extern pid_t    mainPid;void            send_tbyte(),                toggle(),                cleanup();pid_t           readProcPid = 0; /* pid of child process *//*---------------------------------------------------------------------------+| DoNothingHandler - handler for doing nothing.+---------------------------------------------------------------------------*/voidDoNothingHandler(sigNum)     int       sigNum;{#ifdef DEBUG  showf(">>> in DoNothingHandler, pid = %d, sig = %d", getpid(), sigNum);#endif  /* Reinstall the signal handler */  signal(sigNum, DoNothingHandler);}/*---------------------------------------------------------------------------+| TerminalKillHandler - handler for the terminal kill (SIGTERM).+---------------------------------------------------------------------------*/voidTerminalKillHandler(dummy)     int             dummy;{  signal(SIGTERM, SIG_IGN);  /* Kill the child process and wait for it to die, sounds vicious,      doesn't it? The child process is the read process from the port */  if (readProcPid && kill(readProcPid, SIGTERM) == 0)     while(wait((int*)0) < 0);    fflush(tfp);  exit(0);}/*---------------------------------------------------------------------------+| TerminalSuspendHandler - handler for the terminal suspension (SIGUSR1).+---------------------------------------------------------------------------*/voidTerminalSuspendHandler(sigNum)     int             sigNum;{  /* Don't deliver or stack (as pending) any more instances of the signal     until we've woken up (below) */  signal(sigNum, SIG_IGN);  if (readProcPid) kill(readProcPid, sigNum);  pause();#ifdef DEBUG  showf(">>> Terminal %d woke up - good", getpid());#endif  /* After waking up */  if (readProcPid) kill(readProcPid, SIGCONT);  /* Reinstall the signal handler */  signal(sigNum, TerminalSuspendHandler);}/*---------------------------------------------------------------------------+| TerminalRefreshParametersHandler - handler for the terminal to get the |                                    current session parameters (SIGUSR2).+---------------------------------------------------------------------------*/voidTerminalRefreshParametersHandler(sigNum)     int       sigNum;{  int        PutParameters();  void       GetParameters();  /* Don't deliver or stack (as pending) any more instances of the signal     until we're finished with the work at hand */  signal(sigNum, SIG_IGN);  GetParameters(NULL, mainToTermPipe);  if (readProcPid && (PutParameters(mainToTermPipe) < 0 ||                       kill(readProcPid, sigNum) != 0))    SePError("Could not pipe parameters");  /* Reinstall the signal handler */  signal(sigNum, TerminalRefreshParametersHandler);}/* * Terminal: main routine. Has two processes, one to read from terminal  *           and send to the port and the other to do the oppsite. */voidTerminal(){  char            c;  /* Tell the program where to go when signals are received */  signal(SIGTERM, TerminalKillHandler);  signal(SIGUSR1, TerminalSuspendHandler);  signal(SIGUSR2, TerminalRefreshParametersHandler);  signal(SIGCONT, DoNothingHandler);  signal(SIGCHLD, SIG_DFL);  /* Split into read and write processes */  /* Child, read proc: read from port and write to tty */  if ((readProcPid = SeFork()) == 0)    PortToTty();  /* Parent, write proc: read from tty and write to port */  while (1)    if (TtyReadChar(tfd, &c) >= 0) send_tbyte(c);    else {      SeError("TTY read error. Terminal process exiting");      if (readProcPid && kill(readProcPid, SIGTERM) == 0)         while(wait((int*)0) < 0);      ProcRequest(POPUP_ERROR, "TTY Read Error", "errReadError");      exit(1);    }  /*NOT REACHED*/}/* * Read from the port and write to the tty */voidPortToTty(){  static char           zmSig[] = "**\030B00";  static char          *zmSigPtr = zmSig;  char                  buf[BUFSIZ], c;  int                   n, i;  signal(SIGTERM, TerminalKillHandler);  /* Let the main process know we're all set */  kill(mainPid, SIGCONT);  while (1) {    /* Read incoming charaters and exit the process if a read error       is encountered */    if ((n = MdmReadStr(buf)) < 0) {      SeError("Modem read error. Terminal process exiting");      ProcRequest(POPUP_ERROR, "Modem Read Error", "errReadError");      ProcRequest(KILL_TERM, "", "");      exit(1);    }    /* Write incoming characters to the tty */    fwrite(buf, sizeof(char), n, tfp);     fflush(tfp);    for(i = 0; i < n; i++) {      c = buf[i];            /* Write to capture file if capture is enabled */      if (capture) fputc(c, cfp);      /* Look for Zmodem signature */      if (c != *zmSigPtr)        zmSigPtr = zmSig;      else if (*++zmSigPtr == '\0' && qres.autoZmodem)         ProcRequest(DISPATCH_ACTION, "Zmodem Auto-Download", 					qres.autoZmodemAction);    } /* for... */  } /* while(1)... */  /*NOT REACHED*/}/* * send a translated character to the modem */voidsend_tbyte(c)     int             c;{  switch (c) {    /*Translate new line to carriage return if newline translation mode is      in effect*/  case '\n':    switch (newlineTrMode) {    case 2:      c = '\r';      break;    case 3:      sendbyte('\r');    default:      break;    }    break;    /*Translate backspace to delete if del translation mode is in effect*/  case 0x08:    if (qres.backspaceTranslation)      c = 0x7f;    break;  default:    break;  }  /*Send ESC before the character if meta key is pressed with the  character    and the meta key translation mode is on*/  if (qres.metaKeyTranslation && (c & 0x80)) {    sendbyte('\033');    sendbyte(c);  }  /*Send the character to the port*/  else    sendbyte(c);}/*---------------------------------------------------------------------------+| Routines to manipulate the terminal process. +---------------------------------------------------------------------------*/pid_t           termProcPid = 0; /* pid of the terminal process *//*---------------------------------------------------------------------------+| StartTerminal - starts the terminal process.+---------------------------------------------------------------------------*/voidStartTerminal(){  /* Child Process */  if ((termProcPid = SeFork()) == 0) 	{Terminal(); exit(1);}}/*---------------------------------------------------------------------------+| KillTerminal - kills the terminal process.+---------------------------------------------------------------------------*/voidKillTerminal(){  void     (*oldSigHandler)();  if (termProcPid == 0) return;  /* Make sure it's not suspended so that it can react to SIGTERM *//*  if (SuspContTerminal(TERM_CONTINUE) == 0) return;*/  oldSigHandler = signal(SIGCHLD, SIG_DFL);  /* Kill the child and wait for it to die */  if (termProcPid && kill(termProcPid, SIGTERM) == 0)     {while(wait((int*)0) < 0); termProcPid = 0;}  signal(SIGCHLD, oldSigHandler);}/*---------------------------------------------------------------------------+| SuspContTerminal - suspends or resumes the terminal process.+---------------------------------------------------------------------------*/intSuspContTerminal(state)     int state;{  /* This variable keeps track of whether      the terminal is active or suspended */  static int termSuspended = 0;    if (termProcPid == 0) return 0;  if (state == TERM_CONTINUE) {    if (termProcPid && kill(termProcPid, SIGCONT) == 0)       termSuspended = 0;    return 1;  }  if (termSuspended) return 0;  if (termProcPid && kill(termProcPid, SIGUSR1) == 0)     {termSuspended = 1; return 1;}  else    return 0;}intTerminalRefreshParameters(){  int    PutParameters();  if (termProcPid && (PutParameters(mainToTermPipe) < 0 ||                       kill(termProcPid, SIGUSR2) != 0))    return -1;  else return 0;}/* * Restart the terminal process (refresh) by killing it and starting a new * one */voidRestartTerminal(){  KillTerminal();  StartTerminal();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -