00001
00002 #define _INCLUDE_XOPEN_SOURCE
00003
00004 #include "std/config.H"
00005 #include "tty.H"
00006
00007 #ifdef sgi
00008 #include <bstring.h>
00009 #endif
00010
00011 #ifdef sun
00012 #include <strings.h>
00013 #endif
00014
00015 #ifndef aix
00016 #define TRUE 1
00017 #endif
00018
00019 #define BIT(N, INT) ((1 << N) & ((int)(INT)))
00020 #define brcase break; case
00021 #define brdefault break; default
00022
00023 int TTYdebug = 0;
00024 typedef unsigned char byte;
00025
00026 #ifndef WIN32
00027 extern "C" int (*SELECT)(int, fd_set *, fd_set *, fd_set *, timeval *) = select;
00028
00029 extern "C" int Select(int maxfds, fd_set *reads, fd_set *writes, fd_set *errors,
00030 struct timeval *timeout)
00031 {
00032 struct timezone tz;
00033 struct timeval Timer1, Timer2;
00034 struct timeval timetogo;
00035 static fd_set readcopy;
00036 static fd_set writecopy;
00037 static fd_set errcopy;
00038 int rc;
00039 double worktime;
00040 double remaining;
00041
00042
00043 if (reads) bcopy(reads,&readcopy,sizeof(fd_set));
00044 if (writes) bcopy(writes,&writecopy,sizeof(fd_set));
00045 if (errors) bcopy(errors,&errcopy,sizeof(fd_set));
00046
00047
00048
00049
00050
00051 if (timeout == NULL) {
00052 while (TRUE) {
00053 rc = select(maxfds,reads,writes,errors,NULL);
00054 if ((rc == -1) && (errno == EINTR)) {
00055 if (reads) bcopy(&readcopy,reads,sizeof(fd_set));
00056 if (writes) bcopy(&writecopy,writes,sizeof(fd_set));
00057 if (errors) bcopy(&errcopy,errors,sizeof(fd_set));
00058 continue;
00059 }
00060 else return(rc);
00061 }
00062 }
00063 else {
00064 timetogo.tv_sec = timeout->tv_sec;
00065 timetogo.tv_usec = timeout->tv_usec;
00066 remaining = timetogo.tv_sec + timetogo.tv_usec/1000000.;
00067
00068
00069
00070
00071 gettimeofday(&Timer2, &tz);
00072 while (TRUE) {
00073 Timer1.tv_sec = Timer2.tv_sec;
00074 Timer1.tv_usec = Timer2.tv_usec;
00075 rc = select(maxfds,reads,writes,errors,&timetogo);
00076 if ((rc == -1) && (errno == EINTR)) {
00077 gettimeofday(&Timer2, &tz);
00078
00079 worktime = (Timer2.tv_sec - Timer1.tv_sec) +
00080 (Timer2.tv_usec - Timer1.tv_usec)/1000000.;
00081 remaining = remaining - worktime;
00082 timetogo.tv_sec = (int) remaining;
00083 timetogo.tv_usec = (int) ((remaining - timetogo.tv_sec)*
00084 1000000.);
00085
00086 if (reads) bcopy(&readcopy,reads,sizeof(fd_set));
00087 if (writes) bcopy(&writecopy,writes,sizeof(fd_set));
00088 if (errors) bcopy(&errcopy,errors,sizeof(fd_set));
00089 continue;
00090 }
00091 else return(rc);
00092 }
00093 }
00094 }
00095 #endif
00096
00097 FD_MANAGER *FD_MANAGER::_mgr = 0;
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 #define VMIN_CHARACTERS 0
00111 #define VTIME_LENGTH 0
00112 #define MILLISEC_TO_TIME(PTR, MSEC, TIME) \
00113 if ((MSEC) != -1) { \
00114 (TIME).tv_sec = (MSEC)/1000; \
00115 (TIME).tv_usec = ((MSEC)%1000)*1000; \
00116 PTR = &TIME; \
00117 } else \
00118 PTR = NULL
00119
00120
00121
00122 #if !defined(sun) && !defined(hpux) && !defined(sgi)
00123 int TTYfd::_timeout = 0;
00124 #else
00125 # ifdef hp
00126 int TTYfd::_timeout = 120;
00127 # else
00128 int TTYfd::_timeout = 30;
00129 # endif
00130 #endif
00131
00132
00133
00134
00135
00136
00137
00138
00139 int TTYfd::not_configured( int MIN, int TIME)
00140 {
00141 #ifndef WIN32
00142 return (_ios_current.c_cc[VMIN] != MIN ||
00143 _ios_current.c_cc[VTIME] != TIME);
00144 #else
00145
00146 return (_ct_current.ReadTotalTimeoutConstant != (unsigned)TIME);
00147 #endif
00148 }
00149
00150
00151
00152
00153
00154
00155 int TTYfd::get_flags()
00156 {
00157 #ifndef WIN32
00158 if (tcgetattr(_fd, &_ios_current) == -1) {
00159 perror("TTYfd::get_flags [ioctl TCGETA]");
00160 return -1;
00161 }
00162 #else
00163 if (!GetCommState((HANDLE)_fd, &_dcb_current) ||
00164 !GetCommTimeouts((HANDLE)_fd, &_ct_current)) {
00165 perror("TTYfd::get_flags [GetCommState]");
00166 return -1;
00167 }
00168 #endif
00169
00170 return 0;
00171 }
00172
00173
00174
00175
00176
00177
00178 int TTYfd::set_flags()
00179 {
00180 #ifndef WIN32
00181 return tcsetattr(_fd, TCSADRAIN, &_ios_current);
00182 #else
00183 return (SetCommState((HANDLE)_fd, &_dcb_current) &&
00184 SetCommTimeouts((HANDLE)_fd, &_ct_current));
00185 #endif
00186 }
00187
00188
00189
00190
00191
00192
00193
00194
00195 int TTYfd::clear()
00196 {
00197 #ifndef WIN32
00198 return tcflush(_fd, TCIOFLUSH);
00199 #else
00200 return PurgeComm((HANDLE)_fd, PURGE_TXCLEAR | PURGE_RXCLEAR);
00201 #endif
00202 }
00203
00204
00205
00206
00207
00208
00209
00210
00211 int TTYfd::send_break(
00212 int duration
00213 )
00214 {
00215 #ifndef WIN32
00216 if (tcsendbreak(_fd, duration) == -1) {
00217 perror("TTYbreak [ioctl TCSBRK]");
00218 return -1;
00219 }
00220 #else
00221 if (SetCommBreak((HANDLE)_fd) == FALSE) {
00222 perror("TTYbreak [EscapeCommFunction BRK]");
00223 return -1;
00224 }
00225 #endif
00226
00227 return 0;
00228 }
00229
00230 static void cspeed(speed_t sp, char *buf)
00231 {
00232 switch(sp) {
00233 case B0: strcat(buf, "0");
00234 brcase B50: strcat(buf, "50");
00235 brcase B75: strcat(buf, "75");
00236 brcase B110: strcat(buf, "110");
00237 brcase B134: strcat(buf, "134");
00238 brcase B150: strcat(buf, "150");
00239 brcase B200: strcat(buf, "200");
00240 brcase B300: strcat(buf, "300");
00241 brcase B600: strcat(buf, "600");
00242 brcase B1200: strcat(buf, "1200");
00243 brcase B1800: strcat(buf, "1800");
00244 brcase B2400: strcat(buf, "2400");
00245 brcase B4800: strcat(buf, "4800");
00246 brcase B9600: strcat(buf, "9600");
00247 brcase B19200: strcat(buf, "19200");
00248 brcase B38400: strcat(buf, "38400");
00249 brdefault: strcat(buf, "unknown");
00250 }
00251 }
00252
00253
00254
00255
00256 void TTYfd::print_flags()
00257 {
00258 char buf[1024];
00259 speed_t speed;
00260
00261 buf[0] = '\0';
00262 if (get_flags())
00263 return;
00264
00265 #ifndef WIN32
00266 switch(_ios_current.c_cflag & CSIZE) {
00267 case CS5: strcat(buf, "5");
00268 brcase CS6: strcat(buf, "6");
00269 brcase CS7: strcat(buf, "7");
00270 brcase CS8: strcat(buf, "8");
00271 }
00272 strcat(buf, " char bits\t");
00273
00274 speed = cfgetispeed(&_ios_current);
00275 cspeed(speed, buf);
00276 strcat(buf, " baud input\t");
00277 speed = cfgetospeed(&_ios_current);
00278 cspeed(speed, buf);
00279 strcat(buf, " baud output\t");
00280
00281 if (!(_ios_current.c_cflag & PARENB))
00282 strcat(buf, "no parity\t");
00283 else if (_ios_current.c_cflag & PARODD)
00284 strcat(buf, "odd parity\t");
00285 else
00286 strcat(buf, "even parity\t");
00287
00288 if (_ios_current.c_cflag & CSTOPB)
00289 strcat(buf, "2 stop bits.");
00290 else
00291 strcat(buf, "1 stop bit.");
00292
00293 #else
00294
00295 switch(_dcb_current.ByteSize) {
00296 case CS5: strcat(buf, "5");
00297 brcase CS6: strcat(buf, "6");
00298 brcase CS7: strcat(buf, "7");
00299 brcase CS8: strcat(buf, "8");
00300 }
00301 strcat(buf, " char bits\t");
00302
00303 speed = _dcb_current.BaudRate;
00304 cspeed(speed, buf);
00305 strcat(buf, " baud input\t");
00306
00307 cspeed(speed, buf);
00308 strcat(buf, " baud output\t");
00309
00310 switch (_dcb_current.Parity) {
00311 case NOPARITY: strcat(buf, "no parity\t");
00312 brcase EVENPARITY: strcat(buf, "even parity\t");
00313 brcase ODDPARITY: strcat(buf, "odd parity\t");
00314 brcase MARKPARITY: strcat(buf, "mark parity\t");
00315 brcase SPACEPARITY: strcat(buf, "space parity\t");
00316 }
00317
00318 if (_dcb_current.StopBits == TWOSTOPBITS)
00319 strcat(buf, "2 stop bits.");
00320 else
00321 strcat(buf, "1 stop bit.");
00322 #endif
00323
00324 cerr << buf << endl;
00325 }
00326
00327
00328
00329
00330
00331
00332 int TTYfd::set_speed(
00333 long speed
00334 )
00335 {
00336 if (get_flags() < 0)
00337 return -1;
00338
00339 #ifndef WIN32
00340 cfsetospeed(&_ios_current, speed);
00341 cfsetispeed(&_ios_current, speed);
00342 #else
00343 _dcb_current.BaudRate =speed;
00344 #endif
00345
00346 return set_flags();
00347 }
00348
00349
00350
00351
00352
00353
00354
00355 int TTYfd::set_stopbits(
00356 int num
00357 )
00358 {
00359 if (num != 1 && num != 2) {
00360 cerr << "TTYfd::set_stopbits: must be 1 or 2: " << num << endl;
00361 return -1;
00362 }
00363
00364 if (get_flags() < 0)
00365 return -1;
00366
00367 #ifndef WIN32
00368 _ios_current.c_cflag &= num == 1 ? ~0 : ~CSTOPB;
00369 _ios_current.c_cflag |= num == 1 ? 0 : CSTOPB;
00370 #else
00371 _dcb_current.StopBits = (num == 1) ? ONESTOPBIT : TWOSTOPBITS;
00372 #endif
00373
00374 return set_flags();
00375 }
00376
00377
00378
00379
00380
00381 int TTYfd::set_charsize(
00382 short size
00383 )
00384 {
00385 if (get_flags() < 0)
00386 return -1;
00387
00388 #ifndef WIN32
00389 _ios_current.c_cflag &= ~CSIZE;
00390 _ios_current.c_cflag |= CSIZE & size;
00391 #else
00392 _dcb_current.ByteSize = (unsigned int)size;
00393 #endif
00394
00395 return set_flags();
00396 }
00397
00398
00399
00400
00401
00402 int TTYfd::set_parity(
00403 TTYparity parity
00404 )
00405 {
00406 if (get_flags() < 0)
00407 return -1;
00408
00409 #ifndef WIN32
00410 switch (parity) {
00411 case TTY_ODD:
00412 _ios_current.c_cflag |= PARENB;
00413 _ios_current.c_cflag |= PARODD;
00414 brcase TTY_EVEN:
00415 _ios_current.c_cflag |= PARENB;
00416 _ios_current.c_cflag &= ~PARODD;
00417 brcase TTY_NONE:
00418 _ios_current.c_cflag &= ~PARENB;
00419 }
00420 #else
00421 switch (parity) {
00422 case TTY_ODD:
00423 _dcb_current.Parity = ODDPARITY;
00424 brcase TTY_EVEN:
00425 _dcb_current.Parity = EVENPARITY;
00426 brcase TTY_NONE:
00427 _dcb_current.Parity = NOPARITY;
00428 }
00429 #endif
00430
00431 return set_flags();
00432 }
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443 int TTYfd::set_min_and_time(
00444 int minimum,
00445 int time
00446 )
00447 {
00448 get_flags();
00449
00450 if (not_configured(minimum, time)) {
00451 #ifndef WIN32
00452 _ios_current.c_cc[VMIN] = minimum;
00453 _ios_current.c_cc[VTIME] = time;
00454 #else
00455 _ct_current.ReadTotalTimeoutConstant = time;
00456 if (minimum != 0)
00457 cerr << "TTYfd::set_min_and_time (minimum!=0)" << endl;
00458
00459 #endif
00460
00461 return set_flags();
00462 }
00463
00464 return 0;
00465 }
00466
00467
00468
00469
00470
00471
00472
00473
00474 int TTYfd::read_all(
00475 char *buf,
00476 int maxbytes
00477 )
00478 {
00479 int i, num;
00480
00481 if (not_configured(0, 0) && set_min_and_time(0, 0) == -1) {
00482 cerr << "TTYfd::read_all: TTYfd::set_min_and_time failed" << endl;
00483 return -1;
00484 }
00485
00486 #ifndef WIN32
00487 if ((num = read(_fd, buf, maxbytes)) < 0) {
00488 if (errno != EWOULDBLOCK) {
00489 perror("TTYread_all [read failed]");
00490 return -1;
00491 } else
00492 return 0;
00493 }
00494 #else
00495 COMSTAT stat;
00496 DWORD eflags;
00497 ClearCommError((HANDLE)_fd, &eflags, &stat);
00498 if (stat.cbInQue >= (unsigned int)maxbytes)
00499 stat.cbInQue = maxbytes;
00500 if (stat.cbInQue > 0) {
00501 unsigned long bytes;
00502 int error = ReadFile((HANDLE)_fd, buf, stat.cbInQue, &bytes, NULL);
00503 num = bytes;
00504 if (error==FALSE)
00505 return -1;
00506 } else
00507 return 0;
00508 #endif
00509
00510 if (TTYdebug) {
00511 for (i=0; i < num; i++)
00512 printf("[0x%x]%s", (byte)buf[i], i == num-1 ? ".\n":"");
00513 cerr << "TTYread_all: done.\n";
00514 }
00515
00516 return num;
00517 }
00518
00519
00520
00521
00522
00523
00524
00525
00526 int TTYfd::nread(
00527 char *buf,
00528 int readnum,
00529 int timeoutval
00530 )
00531 {
00532 register int i, num = 0, howmany = 0;
00533 char *buf_save = buf;
00534
00535 if (not_configured (VMIN_CHARACTERS, VTIME_LENGTH) &&
00536 set_min_and_time(VMIN_CHARACTERS, VTIME_LENGTH) == -1) {
00537 cerr << "TTYfd::nread: TTYfd::set_min_and_time failed" << endl;
00538 return -1;
00539 }
00540
00541 #ifndef WIN32
00542 struct timeval timeout, *toptr;
00543 fd_set readfds;
00544 MILLISEC_TO_TIME(toptr, timeoutval, timeout);
00545
00546 FD_ZERO(&readfds);
00547 FD_SET(_fd, &readfds);
00548 for (buf += num; num < readnum; buf += howmany, num += howmany)
00549 if ((i = SELECT(FD_SETSIZE, &readfds, 0, 0, toptr)) == 0) {
00550 if (TTYdebug)
00551 cerr << "Timeout expired" << endl;
00552 return num;
00553 } else if (i < 0) {
00554 perror("TTYnread [select failed]");
00555 return -1;
00556 } else if ((howmany = read(_fd, buf, (readnum - num))) < 1) {
00557 char pbuf[256]; sprintf(pbuf, "TTYfd::nread [read failed] %d", _fd);
00558 perror(pbuf);
00559 break;
00560 }
00561 #else
00562 unsigned long bytes;
00563 for (buf +=num; num<readnum; buf+=howmany, num+=howmany) {
00564 int error = ReadFile((HANDLE)_fd, buf, readnum-num, &bytes, NULL);
00565 if (bytes==0) {
00566 if (TTYdebug)
00567 cerr << "Timeout expired" << endl;
00568 return num;
00569 }
00570 howmany = bytes;
00571 }
00572 #endif
00573
00574 if (TTYdebug) {
00575 for (i = 0, buf = buf_save; i < num; i++, buf++)
00576 printf("[0x%x]%s", (byte)(*buf), (i == num-1) ? ".\n" : "");
00577 cerr << "TTYnread: done" << endl;
00578 }
00579
00580 return num;
00581 }
00582
00583 int
00584 TTYfd::read_synchronized(
00585 char sentinel,
00586 int record_size,
00587 char *buf
00588 )
00589 {
00590 return read_synchronized(sentinel, 0, 0, record_size, buf);
00591 }
00592
00593 int
00594 TTYfd::read_synchronized(
00595 int sentinel_bit,
00596 int record_size,
00597 char *buf
00598 )
00599 {
00600 return read_synchronized('\0', sentinel_bit, 1, record_size, buf);
00601 }
00602
00603 int
00604 TTYfd::read_synchronized(
00605 char sentinel,
00606 int sentinel_bit,
00607 int which_sentinel,
00608 int record_size,
00609 char *buf
00610 )
00611 {
00612 if (record_size > MAX_REC_SIZE) {
00613 cerr << "TTYfd::read_synchronized() : record size of "
00614 << record_size << " bigger than max size of "
00615 << MAX_REC_SIZE << endl;
00616 return 0;
00617 }
00618
00619 if (_synch_pos == 0) {
00620 int retries = 0;
00621 do {
00622 if (nread(_synch_buf, 1, _timeout) != 1 ||
00623 ((which_sentinel == 1 && !BIT(sentinel_bit, _synch_buf[0])) ||
00624 (which_sentinel == 0 && _synch_buf[0] != sentinel))
00625 )
00626 retries++;
00627 else
00628 _synch_pos ++;
00629 } while (retries < record_size && !_synch_pos);
00630
00631 if (retries == record_size) {
00632 clear();
00633 cerr << "TTYfd::read_synchronized(): no sentinel after trying "
00634 << retries << " times" << endl;
00635 return 0;
00636 }
00637 }
00638
00639
00640 int nr, need = record_size - _synch_pos;
00641 if ((nr = nread(&_synch_buf[_synch_pos], need, _timeout)) != -1) {
00642 _synch_pos = (_synch_pos + nr) % record_size;
00643 if (nr == need) {
00644 for (int i = 0; i < record_size; i++)
00645 buf[i] = _synch_buf[i];
00646 return 1;
00647 }
00648 }
00649
00650 return 0;
00651 }
00652
00653
00654
00655
00656
00657
00658
00659
00660 int TTYfd::drain()
00661 {
00662 #ifndef WIN32
00663 return tcdrain(_fd);
00664 #else
00665 return PurgeComm((HANDLE)_fd, PURGE_TXCLEAR);
00666 #endif
00667 }
00668
00669
00670
00671
00672
00673 int TTYfd::write(
00674 const char *buf,
00675 int writenum,
00676 int timeoutval
00677 )
00678 {
00679 struct timeval timeout, *toptr;
00680 int num = 0, i;
00681
00682 if (TTYdebug) {
00683 cerr << "TTYfd::write: writing..." << endl;
00684
00685 for (i=0; i<writenum; i++)
00686 printf("[0x%x]%s", (byte)buf[i], (i==writenum-1) ? ".\n":"");
00687 }
00688
00689 MILLISEC_TO_TIME(toptr, timeoutval, timeout);
00690
00691 #ifndef WIN32
00692 int howmany;
00693 fd_set writefds;
00694 if ((num = ::write(_fd, buf, writenum)) < 0) {
00695 perror("TTYfd::write [write failed]");
00696 return -1;
00697 }
00698
00699 FD_ZERO(&writefds);
00700 FD_SET(_fd, &writefds);
00701 for (; num < writenum; num += howmany, buf += howmany) {
00702 if (SELECT(FD_SETSIZE, 0, &writefds, 0, toptr) <= 0) {
00703 perror("TTYfd::write [select failed]");
00704 break;
00705 }
00706 if ((howmany = ::write(_fd, buf, writenum-num)) != 1) {
00707 perror("TTYfd::write [write failed]");
00708 break;
00709 }
00710 }
00711 #else
00712 unsigned long bytes;
00713 if (WriteFile((HANDLE)_fd, buf, writenum, &bytes, NULL) == FALSE)
00714 perror("TTYfd::write [WriteFile failed]");
00715 num = bytes;
00716 #endif
00717
00718 if (TTYdebug)
00719 cerr << "TTYwrite: done" << endl;
00720
00721 return num;
00722 }
00723
00724
00725
00726
00727
00728
00729
00730
00731 int TTYfd::setup()
00732 {
00733 get_flags();
00734
00735
00736
00737 #ifndef WIN32
00738 _ios_current.c_cc[VMIN] = VMIN_CHARACTERS;
00739 _ios_current.c_cc[VTIME] = VTIME_LENGTH;
00740 #ifndef macosx
00741 _ios_current.c_iflag &= ~(PARMRK|INPCK|ISTRIP|INLCR|IGNCR|ICRNL|IUCLC|
00742 IXON|IXANY|IXOFF
00743 #ifdef IMAXBEL
00744 |IMAXBEL
00745 #endif
00746 );
00747 #endif
00748 _ios_current.c_iflag |= IGNBRK;
00749 _ios_current.c_oflag &= ~(OPOST);
00750 cfsetispeed(&_ios_current, B9600);
00751 cfsetospeed(&_ios_current, B9600);
00752 _ios_current.c_cflag &= ~(CSIZE|CSTOPB|PARENB);
00753 _ios_current.c_cflag |= CS8|CREAD|CLOCAL;
00754 _ios_current.c_lflag &= ~(ISIG|ICANON|ECHO|ECHOE|ECHOK|ECHONL|TOSTOP|IEXTEN
00755 #ifdef ECHOCTL
00756 |ECHOCTL
00757 #endif
00758 #ifdef ECHOKE
00759 |ECHOKE
00760 #endif
00761 #ifdef PENDIN
00762 |PENDIN
00763 #endif
00764 );
00765 #else
00766 _ct_current.ReadIntervalTimeout = MAXDWORD;
00767 _ct_current.ReadTotalTimeoutMultiplier = MAXDWORD;
00768 _ct_current.ReadTotalTimeoutConstant = VTIME_LENGTH;
00769 _ct_current.WriteTotalTimeoutMultiplier = 0;
00770 _ct_current.WriteTotalTimeoutConstant = 0;
00771 _dcb_current.fParity = FALSE;
00772 _dcb_current.fBinary = TRUE;
00773 _dcb_current.fInX = FALSE;
00774 _dcb_current.BaudRate = CBR_9600;
00775 _dcb_current.ByteSize = 8;
00776 _dcb_current.Parity = NOPARITY;
00777 _dcb_current.StopBits = ONESTOPBIT;
00778 #endif
00779 set_flags();
00780
00781
00782
00783
00784
00785
00786
00787
00788 #ifdef sol
00789 int xxx = TIOCM_DTR|TIOCM_RTS;
00790 ioctl(_fd, TIOCMBIC, &xxx);
00791 ioctl(_fd, TCIOMBIS, &xxx);
00792 #endif
00793
00794 return _fd;
00795 }
00796
00797
00798
00799
00800
00801 int TTYfd::close()
00802 {
00803 #ifndef WIN32
00804 _ios_current = _ios_saved;
00805 #else
00806 _ct_current = _ct_saved;
00807 _dcb_current = _dcb_saved;
00808 #endif
00809
00810 set_flags();
00811
00812 #ifndef WIN32
00813 if (::close(_fd)) {
00814 #else
00815 if (CloseHandle((HANDLE)_fd) == FALSE) {
00816 #endif
00817 char buf[256]; sprintf(buf, "TTYfd::close - failed on : %d", _fd);
00818 perror(buf);
00819 return -1;
00820 }
00821
00822 _fd = -1;
00823
00824 return 0;
00825 }
00826
00827
00828
00829
00830
00831
00832 int TTYfd::open()
00833 {
00834 if (_fd == -1) {
00835 #ifdef sun
00836 if ((_fd = ::open(_dev, O_RDWR|O_NDELAY |O_NOCTTY, 0)) < 0) {
00837 #elif WIN32
00838 if ((HANDLE)(_fd = (int)CreateFile(_dev, GENERIC_READ|GENERIC_WRITE, 0, NULL,
00839 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) ==
00840 INVALID_HANDLE_VALUE) {
00841 #else
00842 if ((_fd = ::open(_dev, O_RDWR|O_NONBLOCK|O_NOCTTY, 0)) < 0) {
00843 #endif
00844 char buf[256]; sprintf(buf, "TTYfd::open - failed on : %s", _dev);
00845 perror(buf);
00846 return -1;
00847 }
00848
00849 get_flags();
00850
00851 #ifndef WIN32
00852 _ios_saved = _ios_current;
00853 #else
00854 _ct_saved = _ct_current;
00855 _dcb_saved = _dcb_current;
00856 #endif
00857
00858 #ifdef hp
00859 mflag dtr_set = MDTR | MRTS;
00860 ioctl(_fd, MCSETA, &dtr_set);
00861 #endif
00862 }
00863
00864 return 1;
00865 }
00866
00867 int
00868 TTYfd::activate()
00869 {
00870 if (open() < 0) {
00871 cerr << "Couldn't open the serial port:" << _dev << endl;
00872 return 0;
00873 }
00874 setup();
00875 clear();
00876
00877 if (_manager)
00878 _manager->add(this);
00879
00880 return 1;
00881 }
00882
00883 int
00884 TTYfd::deactivate()
00885 {
00886 if (_fd != -1)
00887 close();
00888 if (_manager)
00889 _manager->rem(this);
00890
00891 return 1;
00892 }
00893
00894 TTYfd::TTYfd(
00895 FD_MANAGER *manager,
00896 const char *dev,
00897 const char *name
00898 ):_synch_pos(0), _manager(manager)
00899 {
00900 if (dev != NULL)
00901 {
00902 strcpy(_dev, dev);
00903 }
00904 else
00905 {
00906 str_ptr name_var = Config::get_var_str(name,NULL_STR,false);
00907 if (name_var != NULL_STR)
00908 {
00909 strcpy(_dev, **name_var);
00910 }
00911 else
00912 {
00913 _dev[0] = '\0';
00914 }
00915 }
00916
00917
00918
00919 int timeout = Config::get_var_int("TTY_TIMEOUT",-1,true);
00920 if (timeout>=0) _timeout = timeout;
00921 }
00922
00923
00924