📄 ttyfuncs.c
字号:
/* * $Id: ttyfuncs.c,v 1.24 1998/02/17 09:52:24 mdejonge Exp $ * * $Source: /home/mdejonge/CVS/projects/modem/libtty/ttyfuncs.c,v $ * $Revision: 1.24 $ * Author: Merijn de Jonge * Email: mdejonge@wins.uva.nl * * * * This file is part of the modem communication package. * Copyright (C) 1996-1998 Merijn de Jonge * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * * *//* * Parts of this file are based on dip by Fred N. van Kempen. * * * dip A program for handling dialup IP connecions. * UNIX terminal I/O support functions. This file takes * care of opening, setting up and maintaining the line, * and it takes care of allocating the buffers and init- * ializing their control structures. * * * * Author: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> * Copyright 1988-1993 MicroWalt Corporation * Lock file stuff stolen from Taylor UUCP * Copyright (C) 1991, 1992 Ian Lance Taylor * * 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. */ #ifdef HAVE_CONFIG_H#include <config.h>#endif#include <signal.h>#include <stdlib.h>#include <unistd.h>#include <termios.h>#include <errno.h>#include <stdio.h>#include <fcntl.h>#include <pwd.h>#include <string.h>#include <ctype.h>#include <limits.h>#include <sys/types.h>#include <sys/ioctl.h>#include <sys/stat.h>#include <libport/libport.h>/* This might not be there */#ifndef CRTSCTS#define CRTSCTS 0#endif#include "ttyfuncs.h"/* * Datastructure used for terminals. * Currently only one terminal can be used at the same time * so the structure is not really needed */typedef struct{ int fd; char* dev; int locked; struct termios tty_saved; struct termios tty_current;} _ttyData;static struct { char *speed; int code;} tty_speeds[] = { /* table of usable baud rates */ { "0", B0 }, { "50", B50 }, { "75", B75 }, { "110", B110 }, { "300", B300 }, { "600", B600 }, { "1200", B1200 }, { "2400", B2400 }, { "4800", B4800 }, { "9600", B9600 },#ifdef B14400 { "14400", B14400 },#endif#ifdef B19200 { "19200", B19200 },#endif#ifdef B38400 { "38400", B38400 },#endif#ifdef B57600 { "57600", B57600 },#endif#ifdef B115200 { "115200", B115200 },#endif { NULL, 0 }};static _ttyData* ttyData = NULL;/* * return name of terminal in use */char* tty_device_name(){ if( ttyData == NULL ) return NULL; return ttyData->dev;}/* * Allocate new tty structure */static _ttyData* tty_alloc(){ _ttyData* tty = (_ttyData*)malloc( sizeof( _ttyData ) ); if( tty == NULL ) { FAIL( "malloc" ); exit( 1 ); } tty->fd = -1; tty->dev = NULL; tty->locked = 0; return tty;}/* * Free memeory used for tty structure */static void tty_free( _ttyData* tty ){ if( tty == NULL ) return; free( tty->dev ); free( tty );}/* * Is dev already locked */int tty_already_locked(char *dev) /* nam - complete path to lock file */{ int i = 0, pid = 0; FILE *fd = NULL; char* lock_file = lock_file_name( dev ); /* Does the lock file on our device exist? */ fd = fopen( lock_file, "r" ); if( fd == NULL ) return 0; /* Yes, the lock is there. Now let's make sure */ /* at least there's no active process that owns */ /* that lock. */ i = fscanf(fd, "%d", &pid); fclose(fd); if (i != 1) /* Lock file format's wrong! Kill't */ return 0; /* We got the pid, check if the process's alive */ if (kill(pid, 0) == 0) /* it found process */ return 1; /* Yup, it's running... */ /* Dead, we can proceed locking this device... */ return 0;}/* * Lock the tty */static inttty_lock( _ttyData* tty, int mode){ static char* lock_file; struct passwd *pw; pid_t ime; FILE *fd; #if HAVE_V2_LOCKFILES int cwrote;#endif /* HAVE_V2_LOCKFILES */ if( tty == NULL ) return -1; lock_file = lock_file_name( tty->dev ); if (mode == 1) { /* lock */ if (tty_already_locked( tty->dev ) == 1) { FAILn( "attempt to use already locked tty %s", lock_file ); exit( 1 ); } if ((fd = fopen(lock_file, "w")) == (FILE *)0) { FAIL1( "fopen", lock_file ); exit( 1 ); } ime = getpid();#ifdef HAVE_V2_LOCKFILES TEMP_FAILURE_RETRY( cwrote, write (fileno(fd), &ime, sizeof(ime)) );#else fprintf(fd, "%10d\n", (int)ime);#endif fclose(fd); /* Make sure UUCP owns the lockfile. Required by some packages. */ if ((pw = getpwnam( _UID_UUCP )) == NULL) { FAILn( "lock: UUCP user %s unknown!", _UID_UUCP); return 0; /* keep the lock anyway */ } chown(lock_file, pw->pw_uid, pw->pw_gid); tty->locked = 1; } else if (mode == 2) { /* re-acquire a lock after a fork() */ if (tty->locked != 1) { FAILn( "tty_lock reaquire: lock was not saved!", ""); exit( 1 ); } if ((fd = fopen(lock_file, "w")) == (FILE *)0) { FAIL1( "fopen", lock_file ); exit( 1 ); } ime = getpid();#ifdef HAVE_V2_LOCKFILES TEMP_FAILURE_RETRY( cwrote, write (fileno(fd), &ime, sizeof(ime)) );#else fprintf(fd, "%10d\n", (int)ime);#endif fclose(fd); chmod(lock_file, 0444); chown(lock_file, getuid(), getgid()); return 0; } else { /* unlock */ if ( tty->locked != 1) { FAILn( "tty_lock: lock was not saved?!", "" ); return 0; } if ((fd = fopen(lock_file, "w")) == NULL ) { FAIL1( "fopen", lock_file ); exit( 1 ); } if (unlink(lock_file) < 0) { FAIL1( "unlink", lock_file ); tty->locked = 0; exit( 1 ); } tty->locked = 0; } return 0;}/* Find a serial speed code in the table. */static inttty_find_speed(char *speed){ int i; i = 0; while (tty_speeds[i].speed != NULL) { if (! strcmp(tty_speeds[i].speed, speed)) { return(tty_speeds[i].code); } i++; } return -EINVAL;}/* Set the number of stop bits. */static inttty_set_stopbits(struct termios *tty, char *stopbits){ switch(*stopbits) { case '1': tty->c_cflag &= ~CSTOPB; break; case '2': tty->c_cflag |= CSTOPB; break; default: return -EINVAL; } return 0;}/* Set the number of data bits. */static inttty_set_databits(struct termios *tty, char *databits){ tty->c_cflag &= ~CSIZE; switch(*databits) { case '5': tty->c_cflag |= CS5; break; case '6': tty->c_cflag |= CS6; break; case '7': tty->c_cflag |= CS7; break; case '8': tty->c_cflag |= CS8; break; default: return -EINVAL; } return 0;} /* Set the type of parity encoding. */static inttty_set_parity(struct termios *tty, char *parity){ switch(toupper(*parity)) { case 'N': tty->c_cflag &= ~(PARENB | PARODD); break; case 'O': tty->c_cflag &= ~(PARENB | PARODD); tty->c_cflag |= (PARENB | PARODD); break; case 'E':
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -