sysdep1.c
上传用户:tianjinjs
上传日期:2007-01-05
资源大小:309k
文件大小:10k
源码类别:

Modem编程

开发平台:

Unix_Linux

  1. /*
  2.  * sysdep1.c system dependant routines.
  3.  *
  4.  *  $Id: sysdep1.c,v 1.2 1999/09/03 12:25:24 walker Exp $
  5.  *
  6.  * m_dtrtoggle - dropt dtr and raise it again
  7.  * m_break - send BREAK signal
  8.  * m_getdcd - get modem dcd status
  9.  * m_setdcd - set modem dcd status
  10.  * m_savestate - save modem state
  11.  * m_restorestate - restore saved modem state
  12.  * m_nohang - tell driver not to hang up at DTR drop
  13.  * m_hupcl - set hangup on close on/off
  14.  * m_setparms - set baudrate, parity and number of bits.
  15.  * m_readchk - see if there is input waiting.
  16.  * m_wait - wait for child to finish. Sysdep. too.
  17.  *
  18.  * If it's possible, Posix termios are preferred.
  19.  *
  20.  * This file is part of the minicom communications package,
  21.  * Copyright 1991-1995 Miquel van Smoorenburg.
  22.  *
  23.  * This program is free software; you can redistribute it and/or
  24.  * modify it under the terms of the GNU General Public License
  25.  * as published by the Free Software Foundation; either version
  26.  * 2 of the License, or (at your option) any later version.
  27.  *
  28.  *   jl  23.06.97  adjustable DTR downtime
  29.  */
  30. #include "sysdep.h"
  31. /* Set hardware flow control. */
  32. void m_sethwf(fd, on)
  33. int fd, on;
  34. {
  35. #ifdef _DGUX_SOURCE
  36.   struct termiox x;
  37. #endif
  38. #ifdef _POSIX
  39.   struct termios tty;
  40.   tcgetattr(fd, &tty);
  41.   if (on)
  42. tty.c_cflag |= CRTSCTS;
  43.   else
  44. tty.c_cflag &= ~CRTSCTS;
  45.   tcsetattr(fd, TCSANOW, &tty);
  46. #endif
  47. #ifdef _DGUX_SOURCE
  48.   if (ioctl(fd, TCGETX, &x) < 0) {
  49. fprintf(stderr, "can't get termiox attr.n");
  50. return;
  51.   }
  52.   x.x_hflag = on ? RTSXOFF|CTSXON : 0;
  53.   if (ioctl(fd, TCSETX, &x) < 0) {
  54. fprintf(stderr, "can't set termiox attr.n");
  55. return;
  56.   }
  57. #endif
  58. }
  59. /* Set RTS line. Sometimes dropped. Linux specific? */
  60. void m_setrts(fd)
  61. int fd;
  62. {
  63. #if defined(TIOCM_RTS) && defined(TIOCMODG)
  64.   int mcs;
  65.   ioctl(fd, TIOCMODG, &mcs);
  66.   mcs |= TIOCM_RTS;
  67.   ioctl(fd, TIOCMODS, &mcs);
  68. #endif
  69. #ifdef _COHERENT
  70.   ioctl(fd, TIOCSRTS, 0);
  71. #endif
  72. }
  73. /*
  74.  * Drop DTR line and raise it again.
  75.  */
  76. void m_dtrtoggle(fd,sec) 
  77. int fd;
  78. int sec;
  79. {
  80. #ifdef TIOCSDTR
  81.   /* Use the ioctls meant for this type of thing. */
  82.   ioctl(fd, TIOCCDTR, 0);
  83.   if (sec>0) {
  84.     sleep(sec);
  85.     ioctl(fd, TIOCSDTR, 0);
  86.   }
  87. #else /* TIOCSDTR */
  88. #  if defined (_POSIX) && !defined(_HPUX_SOURCE)
  89.   /* Posix - set baudrate to 0 and back */
  90.   struct termios tty, old;
  91.   tcgetattr(fd, &tty);
  92.   tcgetattr(fd, &old);
  93.   cfsetospeed(&tty, B0);
  94.   cfsetispeed(&tty, B0);
  95.   tcsetattr(fd, TCSANOW, &tty);
  96.   if (sec>0) {
  97.     sleep(sec);
  98.     tcsetattr(fd, TCSANOW, &old);
  99.   }
  100. #  else /* POSIX */
  101. #    ifdef _V7
  102.   /* Just drop speed to 0 and back to normal again */
  103.   struct sgttyb sg, ng;
  104.   
  105.   ioctl(fd, TIOCGETP, &sg);
  106.   ioctl(fd, TIOCGETP, &ng);
  107.   
  108.   ng.sg_ispeed = ng.sg_ospeed = 0;
  109.   ioctl(fd, TIOCSETP, &ng);
  110.   if (sec>0) {
  111.     sleep(sec);
  112.     ioctl(fd, TIOCSETP, &sg);
  113.   }
  114. #    endif /* _V7 */
  115. #    ifdef _HPUX_SOURCE
  116.   unsigned long mflag = 0L;
  117.   ioctl(fd, MCSETAF, &mflag);
  118.   ioctl(fd, MCGETA, &mflag);
  119.   mflag = MRTS | MDTR;
  120.   if (sec>0) {
  121.     sleep(sec);
  122.     ioctl(fd, MCSETAF, &mflag);
  123.   }
  124. #    endif /* _HPUX_SOURCE */
  125. #  endif /* POSIX */
  126. #endif /* TIOCSDTR */
  127. }
  128. /*
  129.  * Send a break
  130.  */
  131. void m_break(fd)
  132. int fd;
  133. #ifdef _POSIX
  134.   tcsendbreak(fd, 0);
  135. #else
  136. #  ifdef _V7
  137. #    ifndef TIOCSBRK
  138.   struct sgttyb sg, ng;
  139.   ioctl(fd, TIOCGETP, &sg);
  140.   ioctl(fd, TIOCGETP, &ng);
  141.   ng.sg_ispeed = ng.sg_ospeed = B110;
  142.   ng.sg_flags = BITS8 | RAW;
  143.   ioctl(fd, TIOCSETP, &ng);
  144.   write(fd, "", 10);
  145.   ioctl(fd, TIOCSETP, &sg);
  146. #    else
  147.   ioctl(fd, TIOCSBRK, 0);
  148.   sleep(1);
  149.   ioctl(fd, TIOCCBRK, 0);
  150. #    endif
  151. #  endif
  152. #endif
  153. }
  154. /*
  155.  * Get the dcd status
  156.  */
  157. int m_getdcd(fd)
  158. int fd;
  159. {
  160. #ifdef TIOCMODG
  161.   int mcs;
  162.    
  163.   ioctl(fd, TIOCMODG, &mcs);
  164.   return(mcs & TIOCM_CAR ? 1 : 0);
  165. #else
  166.   (void)fd;
  167.   return(0); /* Impossible!! (eg. Coherent) */
  168. #endif
  169. }
  170. /* Variables to save states in */
  171. #ifdef _POSIX
  172. static struct termios savetty;
  173. static int m_word;
  174. #else
  175. #  if defined (_BSD43) || defined (_V7)
  176. static struct sgttyb sg;
  177. static struct tchars tch;
  178. static int lsw;
  179. static int m_word;
  180. #  endif
  181. #endif
  182. /*
  183.  * Save the state of a port
  184.  */
  185. void m_savestate(fd)
  186. int fd;
  187. {
  188. #ifdef _POSIX
  189.   tcgetattr(fd, &savetty);
  190. #else
  191. #  if defined(_BSD43) || defined(_V7)
  192.   ioctl(fd, TIOCGETP, &sg);
  193.   ioctl(fd, TIOCGETC, &tch);
  194. #  endif
  195. #  ifdef _BSD43
  196.   ioctl(fd, TIOCLGET, &lsw);
  197. #  endif
  198. #endif
  199. #ifdef TIOCMODG
  200.   ioctl(fd, TIOCMODG, &m_word);
  201. #endif
  202. }
  203. /*
  204.  * Restore the state of a port
  205.  */
  206. void m_restorestate(fd)
  207. int fd;
  208. {
  209. #ifdef _POSIX
  210.   tcsetattr(fd, TCSANOW, &savetty);
  211. #else
  212. #  if defined(_BSD43) || defined(_V7)
  213.   ioctl(fd, TIOCSETP, &sg);
  214.   ioctl(fd, TIOCSETC, &tch);
  215. #  endif
  216. #  ifdef _BSD43  
  217.   ioctl(fd, TIOCLSET, &lsw);
  218. #  endif
  219. #endif
  220. #ifdef TIOCMODS
  221.   ioctl(fd, TIOCMODS, &m_word);
  222. #endif
  223. }
  224. /*
  225.  * Set the line status so that it will not kill our process
  226.  * if the line hangs up.
  227.  */
  228. /*ARGSUSED*/ 
  229. void m_nohang(fd)
  230. int fd;
  231. {
  232. #ifdef _POSIX
  233.   struct termios sgg;
  234.   
  235.   tcgetattr(fd, &sgg);
  236.   sgg.c_cflag |= CLOCAL;
  237.   tcsetattr(fd, TCSANOW, &sgg);
  238. #else
  239. #  if defined (_BSD43) && defined(LNOHANG)
  240.   int lsw;
  241.   
  242.   ioctl(fd, TIOCLGET, &lsw);
  243.   lsw |= LNOHANG;
  244.   ioctl(fd, TIOCLSET, &lsw);
  245. #  endif
  246. #  ifdef _COHERENT
  247.   /* Doesn't know about this either, me thinks. */
  248. #  endif
  249. #endif
  250. }
  251. /*
  252.  * Set hangup on close on/off.
  253.  */
  254. void m_hupcl(fd, on)
  255. int fd;
  256. int on;
  257. {
  258.   /* Eh, I don't know how to do this under BSD (yet..) */
  259. #ifdef _POSIX
  260.   struct termios sgg;
  261.   
  262.   tcgetattr(fd, &sgg);
  263.   if (on)
  264.    sgg.c_cflag |= HUPCL;
  265.   else
  266. sgg.c_cflag &= ~HUPCL;
  267.   tcsetattr(fd, TCSANOW, &sgg);
  268. #endif
  269. }
  270. /*
  271.  * Flush the buffers
  272.  */
  273. void m_flush(fd)
  274. int fd;
  275. {
  276. /* Should I Posixify this, or not? */
  277. #ifdef TCFLSH
  278.   ioctl(fd, TCFLSH, 2);
  279. #endif
  280. #ifdef TIOCFLUSH
  281. #ifdef _COHERENT
  282.   ioctl(fd, TIOCFLUSH, 0);
  283. #else
  284.   ioctl(fd, TIOCFLUSH, (void *)0);
  285. #endif
  286. #endif
  287. }
  288. /*
  289.  * See if there is input waiting.
  290.  * returns: 0=nothing, >0=something, -1=can't.
  291.  */
  292. int m_readchk(fd)
  293. int fd;
  294. {
  295. #ifdef FIONREAD
  296.   long i = -1;
  297.   (void) ioctl(fd, FIONREAD, &i);
  298.   return((int)i);
  299. #else
  300. #  if defined(F_GETFL) && defined(O_NDELAY)
  301.   int i, old;
  302.   char c;
  303.   old = fcntl(fd, F_GETFL, 0);
  304.   (void) fcntl(fd, F_SETFL, old | O_NDELAY);
  305.   i = read(fd, &c, 1);
  306.   (void) fcntl(fd, F_SETFL, old);
  307.   return(i);
  308. #  else
  309.   return(-1);
  310. #  endif
  311. #endif
  312. }
  313. /*
  314.  * Get maximum speed.
  315.  * Returns maximum speed / 100. (192-1152)
  316.  */
  317. int m_getmaxspd()
  318. {
  319. #ifdef B230400
  320.   return(2304);
  321. #elif defined(B115200)
  322.   return(1152);
  323. #elif defined(B57600)
  324.   return(576);
  325. #elif defined(B38400)
  326.   return(384);
  327. #elif defined(EXTB)
  328.   return(384);
  329. #elif defined(B19200)
  330.   return(192);
  331. #elif defined(EXTA)
  332.   return(192);
  333. #else
  334.   return(96);
  335. #endif
  336. }
  337. /*
  338.  * Set baudrate, parity and number of bits.
  339.  */
  340. void m_setparms(fd, baudr, par, bits, hwf, swf)
  341. int fd;
  342. char *baudr;
  343. char *par;
  344. char *bits;
  345. int hwf;
  346. int swf;
  347. {
  348.   int spd = -1;
  349.   int newbaud;
  350.   int bit = bits[0];
  351. #ifdef _POSIX
  352.   struct termios tty;
  353.   tcgetattr(fd, &tty);
  354. #else /* _POSIX */
  355.   struct sgttyb tty;
  356.   ioctl(fd, TIOCGETP, &tty);
  357. #endif /* _POSIX */
  358.   /* We generate mark and space parity ourself. */
  359.   if (bit == '7' && (par[0] == 'M' || par[0] == 'S'))
  360. bit = '8';
  361.   /* Check if 'baudr' is really a number */
  362.   if ((newbaud = (atol(baudr) / 100)) == 0 && baudr[0] != '0') newbaud = -1;
  363.   switch(newbaud) {
  364.    case 0:
  365. #ifdef B0
  366. spd = B0; break;
  367. #else
  368. spd = 0; break;
  369. #endif
  370.    case 3: spd = B300; break;
  371.    case 6: spd = B600; break;
  372.    case 12: spd = B1200; break;
  373.    case 24: spd = B2400; break;
  374.    case 48: spd = B4800; break;
  375.    case 96: spd = B9600; break;
  376. #ifdef B19200
  377.    case 192: spd = B19200; break;
  378. #else /* B19200 */
  379. #  ifdef EXTA
  380. case 192: spd = EXTA; break;
  381. #   else /* EXTA */
  382. case 192: spd = B9600; break;
  383. #   endif /* EXTA */
  384. #endif  /* B19200 */
  385. #ifdef B38400
  386.    case 384: spd = B38400; break;
  387. #else /* B38400 */
  388. #  ifdef EXTB
  389. case 384: spd = EXTB; break;
  390. #   else /* EXTB */
  391. case 384: spd = B9600; break;
  392. #   endif /* EXTB */
  393. #endif  /* B38400 */
  394. #ifdef B57600
  395. case 576: spd = B57600; break;
  396. #endif
  397. #ifdef B115200
  398. case 1152: spd = B115200; break;
  399. #endif
  400. #ifdef B230400
  401. case 2304: spd = B230400; break;
  402. #endif
  403.   }
  404.   
  405. #if defined (_BSD43) && !defined(_POSIX)
  406.   if (spd != -1) tty.sg_ispeed = tty.sg_ospeed = spd;
  407.   /* Number of bits is ignored */
  408.   tty.sg_flags = RAW | TANDEM;
  409.   if (par[0] == 'E')
  410. tty.sg_flags |= EVENP;
  411.   else if (par[0] == 'O')
  412. tty.sg_flags |= ODDP;
  413.   else
  414.    tty.sg_flags |= PASS8 | ANYP;
  415.   ioctl(fd, TIOCSETP, &tty);
  416. #  ifdef TIOCSDTR
  417.   /* FIXME: huh? - MvS */
  418.   ioctl(fd, TIOCSDTR, 0);
  419. #  endif
  420. #endif /* _BSD43 && !_POSIX */
  421. #if defined (_V7) && !defined(_POSIX)
  422.   if (spd != -1) tty.sg_ispeed = tty.sg_ospeed = spd;
  423.   tty.sg_flags = RAW;
  424.   if (par[0] == 'E')
  425. tty.sg_flags |= EVENP;
  426.   else if (par[0] == 'O')
  427. tty.sg_flags |= ODDP;
  428.   ioctl(fd, TIOCSETP, &tty);
  429. #endif /* _V7 && !POSIX */
  430. #ifdef _POSIX
  431.   if (spd != -1) {
  432. cfsetospeed(&tty, (speed_t)spd);
  433. cfsetispeed(&tty, (speed_t)spd);
  434.   }
  435.   switch (bit) {
  436.    case '5':
  437.    tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS5;
  438.    break;
  439.    case '6':
  440.    tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS6;
  441.    break;
  442.    case '7':
  443.    tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS7;
  444.    break;
  445.    case '8':
  446. default:
  447.    tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8;
  448.    break;
  449.   }
  450.   /* Set into raw, no echo mode */
  451.   tty.c_iflag =  IGNBRK;
  452.   tty.c_lflag = 0;
  453.   tty.c_oflag = 0;
  454.   tty.c_cflag |= CLOCAL | CREAD;
  455. #ifdef _DCDFLOW
  456.   tty.c_cflag &= ~CRTSCTS;
  457. #endif
  458.   tty.c_cc[VMIN] = 1;
  459.   tty.c_cc[VTIME] = 5;
  460.   if (swf)
  461. tty.c_iflag |= IXON | IXOFF;
  462.   else
  463. tty.c_iflag &= ~(IXON|IXOFF|IXANY);
  464.   tty.c_cflag &= ~(PARENB | PARODD);
  465.   if (par[0] == 'E')
  466. tty.c_cflag |= PARENB;
  467.   else if (par[0] == 'O')
  468. tty.c_cflag |= (PARENB | PARODD);
  469.   tcsetattr(fd, TCSANOW, &tty);
  470.   m_setrts(fd);
  471. #endif /* _POSIX */
  472. #ifndef _DCDFLOW
  473.   m_sethwf(fd, hwf);
  474. #endif
  475. }
  476. /*
  477.  * Wait for child and return pid + status
  478.  */
  479. int m_wait(stt)
  480. int *stt;
  481. {
  482. #if defined (_BSD43) && !defined(_POSIX)
  483.   int pid;
  484.   union wait st1;
  485.   
  486.   pid = wait((void *)&st1);
  487.   *stt = (unsigned)st1.w_retcode + 256 * (unsigned)st1.w_termsig;
  488.   return(pid);
  489. #else
  490.   int pid;
  491.   int st1;
  492.   
  493.   pid = wait(&st1);
  494.   *stt = (unsigned)WEXITSTATUS(st1) + 256 * (unsigned)WTERMSIG(st1);
  495.   return(pid);
  496. #endif
  497. }