00001
00002
00003 #include "ttyintf.hh"
00004
00005 #include <stdio.h>
00006 #include <stdlib.h>
00007
00008 #ifdef UNIX_LIKE_PLAT
00009 #ifndef UNIX
00010 #define UNIX 1
00011 #endif
00012 #endif
00013
00014 #ifdef UNIX
00015 #include <errno.h>
00016 #include <string.h>
00017 #include <sys/types.h>
00018 #include <sys/stat.h>
00019 #include <fcntl.h>
00020 #include <unistd.h>
00021 #include <termios.h>
00022 #endif
00023
00024 #ifdef WIN32
00025 #include <windows.h>
00026 #endif
00027
00028 #include "rcs_prnt.hh"
00029 #include "linklist.hh"
00030
00031 #ifdef UNIX
00032 typedef int RCS_SERIAL_PORT_HANDLE;
00033 #endif
00034 #ifdef WIN32
00035 typedef HANDLE RCS_SERIAL_PORT_HANDLE;
00036 #endif
00037
00038
00039 struct HANDLE_INFO
00040 {
00041 RCS_SERIAL_PORT_HANDLE handle;
00042 char name[256];
00043 int refcount;
00044 };
00045
00046 RCS_LINKED_LIST *handles_list;
00047
00048
00049 HANDLE_INFO *
00050 findHandle (const char *name)
00051 {
00052 HANDLE_INFO *hi;
00053 if (NULL == handles_list)
00054 {
00055 return NULL;
00056 }
00057 hi = (HANDLE_INFO *) handles_list->get_head ();
00058 while (NULL != hi)
00059 {
00060 if (!strncmp (hi->name, name, 256))
00061 {
00062 return hi;
00063 }
00064 }
00065 return NULL;
00066 }
00067
00068 void
00069 addHandle (const char *name, RCS_SERIAL_PORT_HANDLE _handle)
00070 {
00071 if (NULL == handles_list)
00072 {
00073 handles_list = new RCS_LINKED_LIST ();
00074 }
00075 HANDLE_INFO hi;
00076 strncpy (hi.name, name, 256);
00077 hi.refcount = 1;
00078 hi.handle = _handle;
00079 handles_list->store_at_tail (&hi, sizeof (HANDLE_INFO), 1);
00080 }
00081
00082
00083 int
00084 removeHandle (RCS_SERIAL_PORT_HANDLE _handle)
00085 {
00086 int refcount = 0;
00087 HANDLE_INFO *hi;
00088 if (NULL == handles_list)
00089 {
00090 return -1;
00091 }
00092 hi = (HANDLE_INFO *) handles_list->get_head ();
00093 while (NULL != hi)
00094 {
00095 if (hi->handle == _handle)
00096 {
00097 hi->refcount--;
00098 if (hi->refcount <= 0)
00099 {
00100 handles_list->delete_current_node ();
00101 }
00102 refcount = hi->refcount;
00103 break;
00104 }
00105 }
00106 if (handles_list->list_size <= 0)
00107 {
00108 delete handles_list;
00109 handles_list = NULL;
00110 }
00111 return refcount;
00112 }
00113 static char clean_string_buf[256];
00114
00115 char *
00116 clean_string (char *string, int len)
00117 {
00118 int i = 0;
00119 char *cptr = string;
00120 char c = *cptr;
00121 if (len > 256)
00122 {
00123 len = 256;
00124 }
00125 while (i < len
00126 && (c == ' ' || c == '\t' || c == '=' || c == '\r' || c == '\n')
00127 && c != 0)
00128 {
00129 cptr++;
00130 c = *cptr;
00131 i++;
00132 }
00133 memset (clean_string_buf, 0, 256);
00134 if (c == 0 || i > len)
00135 {
00136 return clean_string_buf;
00137 }
00138 c = *cptr;
00139 char *dptr = clean_string_buf;
00140 while (i < len && c != 0 && c != ' ' && c != '\t' && c != '\r' && c != '\n')
00141 {
00142 *dptr = *cptr;
00143 cptr++;
00144 dptr++;
00145 i++;
00146 c = *cptr;
00147 }
00148 return clean_string_buf;
00149 }
00150
00151
00152 int
00153 print_serial_port_configuration (RCS_SERIAL_PORT_HANDLE _handle)
00154 {
00155 #ifdef UNIX
00156 int ttyFileFd = _handle;
00157 struct termios ttysettings;
00158 rcs_print ("tcgetattr returned %d\n", tcgetattr (ttyFileFd, &ttysettings));
00159 rcs_print ("c_iflag: %x ", ttysettings.c_iflag);
00160 if (ttysettings.c_iflag & BRKINT)
00161 rcs_print ("BRKINT ");
00162 if (ttysettings.c_iflag & ICRNL)
00163 rcs_print ("ICRNL ");
00164 if (ttysettings.c_iflag & IGNBRK)
00165 rcs_print ("IGNBRK ");
00166 if (ttysettings.c_iflag & IGNCR)
00167 rcs_print ("IGNCR ");
00168 if (ttysettings.c_iflag & IMAXBEL)
00169 rcs_print ("IMAXBEL ");
00170 if (ttysettings.c_iflag & INLCR)
00171 rcs_print ("INLCR ");
00172 if (ttysettings.c_iflag & INPCK)
00173 rcs_print ("INPCK ");
00174 if (ttysettings.c_iflag & IUCLC)
00175 rcs_print ("IUCLC ");
00176 if (ttysettings.c_iflag & IXANY)
00177 rcs_print ("IXANY ");
00178 if (ttysettings.c_iflag & IXOFF)
00179 rcs_print ("IXOFF ");
00180 if (ttysettings.c_iflag & IXON)
00181 rcs_print ("IXON ");
00182 if (ttysettings.c_iflag & PARMRK)
00183 rcs_print ("PARMRK ");
00184 rcs_print ("\n");
00185 rcs_print ("c_oflag: %x ", ttysettings.c_oflag);
00186 if (ttysettings.c_oflag & BSDLY)
00187 rcs_print ("BSDLY ");
00188 if (ttysettings.c_oflag & CRDLY)
00189 rcs_print ("CRDLY ");
00190 if (ttysettings.c_oflag & FFDLY)
00191 rcs_print ("FFDLY ");
00192 if (ttysettings.c_oflag & NLDLY)
00193 rcs_print ("NLDLY ");
00194 if (ttysettings.c_oflag & OCRNL)
00195 rcs_print ("OCRNL ");
00196 if (ttysettings.c_oflag & OFDEL)
00197 rcs_print ("OFDEL ");
00198 if (ttysettings.c_oflag & OFILL)
00199 rcs_print ("OFILL ");
00200 if (ttysettings.c_oflag & OLCUC)
00201 rcs_print ("OLCUC ");
00202 if (ttysettings.c_oflag & ONLCR)
00203 rcs_print ("ONLCR ");
00204 if (ttysettings.c_oflag & ONLRET)
00205 rcs_print ("ONLRET ");
00206 if (ttysettings.c_oflag & ONOCR)
00207 rcs_print ("ONOCR ");
00208 #ifdef ONEOT
00209 if (ttysettings.c_oflag & ONOEOT)
00210 rcs_print ("ONEOT ");
00211 #endif
00212 if (ttysettings.c_oflag & OPOST)
00213 rcs_print ("OPOST ");
00214 #ifdef OXTABS
00215 if (ttysettings.c_oflag & OXTABS)
00216 rcs_print ("OXTABS ");
00217 #endif
00218 if (ttysettings.c_oflag & TABDLY)
00219 rcs_print ("TABDLY ");
00220 if (ttysettings.c_oflag & VTDLY)
00221 rcs_print ("VTDLY ");
00222 rcs_print ("\n");
00223 rcs_print ("c_cflag: %x ", ttysettings.c_cflag);
00224 #ifdef CCTS_OFLOW
00225 if (ttysettings.c_cflag & CCTS_OFLOW)
00226 rcs_print ("CCTS_OFLOW ");
00227 #endif
00228
00229 #ifdef CIGNORE
00230 if (ttysettings.c_cflag & CIGNORE)
00231 rcs_print ("CIGNORE ");
00232 #endif
00233
00234 if (ttysettings.c_cflag & CLOCAL)
00235 rcs_print ("CLOCAL ");
00236 if (ttysettings.c_cflag & CREAD)
00237 rcs_print ("CREAD ");
00238 #ifdef CRTS_IFLOW
00239 if (ttysettings.c_cflag & CRTS_IFLOW)
00240 rcs_print ("CRTS_IFLOW ");
00241 #endif
00242 if ((ttysettings.c_cflag & CSIZE) == CS5)
00243 rcs_print ("CS5 ");
00244 if ((ttysettings.c_cflag & CSIZE) == CS6)
00245 rcs_print ("CS6 ");
00246 if ((ttysettings.c_cflag & CSIZE) == CS7)
00247 rcs_print ("CS7 ");
00248 if ((ttysettings.c_cflag & CSIZE) == CS8)
00249 rcs_print ("CS8 ");
00250 if (ttysettings.c_cflag & CSTOPB)
00251 rcs_print ("CSTOPB ");
00252 if (ttysettings.c_cflag & HUPCL)
00253 rcs_print ("HUPCL ");
00254 #ifdef MDMBUF
00255 if (ttysettings.c_cflag & MDMBUF)
00256 rcs_print ("MDMBUF ");
00257 #endif
00258 if (ttysettings.c_cflag & PARENB)
00259 rcs_print ("PARENB ");
00260 if (ttysettings.c_cflag & PARODD)
00261 rcs_print ("PARODD ");
00262 rcs_print ("\n");
00263 rcs_print ("c_lflag: %x ", ttysettings.c_lflag);
00264 #ifdef ALTWERASE
00265 if (ttysettings.c_cflag & ALTWERASE)
00266 rcs_print ("ALTWERASE ");
00267 #endif
00268 if (ttysettings.c_cflag & ECHO)
00269 rcs_print ("ECHO ");
00270 if (ttysettings.c_cflag & ECHOCTL)
00271 rcs_print ("ECHOCTL ");
00272 if (ttysettings.c_cflag & ECHOE)
00273 rcs_print ("ECHOE ");
00274 if (ttysettings.c_cflag & ECHOK)
00275 rcs_print ("ECHOK ");
00276 if (ttysettings.c_cflag & ECHOKE)
00277 rcs_print ("ECHOKE ");
00278 if (ttysettings.c_cflag & ECHONL)
00279 rcs_print ("ECHONL ");
00280 if (ttysettings.c_cflag & ECHOPRT)
00281 rcs_print ("ECHOPRT ");
00282 if (ttysettings.c_cflag & FLUSHO)
00283 rcs_print ("FLUSHO ");
00284 if (ttysettings.c_cflag & ICANON)
00285 rcs_print ("ICANON ");
00286 if (ttysettings.c_cflag & IEXTEN)
00287 rcs_print ("IEXTEN ");
00288 if (ttysettings.c_cflag & ISIG)
00289 rcs_print ("ISIG ");
00290 if (ttysettings.c_cflag & NOFLSH)
00291 rcs_print ("NOFLSH ");
00292 #ifdef NOKERNINFO
00293 if (ttysettings.c_cflag & NOKERNINFO)
00294 rcs_print ("NOKERNINFO ");
00295 #endif
00296 if (ttysettings.c_cflag & PENDIN)
00297 rcs_print ("PENDIN ");
00298 if (ttysettings.c_cflag & TOSTOP)
00299 rcs_print ("TOSTOP ");
00300 if (ttysettings.c_cflag & XCASE)
00301 rcs_print ("XCASE ");
00302 rcs_print ("\n");
00303 #endif
00304
00305 #ifdef WIN32
00306 DCB dcb;
00307 if (!GetCommState (_handle, &dcb))
00308 {
00309 return -1;
00310 }
00311 rcs_print ("DCBlength=%d\n", dcb.DCBlength);
00312 rcs_print ("BaudRate=%d\n", dcb.BaudRate);
00313 rcs_print ("fBinary=%d\n", dcb.fBinary);
00314 rcs_print ("fParity=%d\n", dcb.fParity);
00315 rcs_print ("fOutxCtsFlow=%d\n", dcb.fOutxCtsFlow);
00316 rcs_print ("fOutxDsrFlow=%d\n", dcb.fOutxDsrFlow);
00317 rcs_print ("fDtrControl=%d\n", dcb.fDsrSensitivity);
00318 rcs_print ("fDsrSensitivity=%d\n", dcb.fDsrSensitivity);
00319 rcs_print ("fTXContinueOnXoff=%d\n", dcb.fTXContinueOnXoff);
00320 rcs_print ("fOutX=%d\n", dcb.fOutX);
00321 rcs_print ("fInX=%d\n", dcb.fInX);
00322 rcs_print ("fErrorChar=%d\n", dcb.fErrorChar);
00323 rcs_print ("fNull=%d\n", dcb.fNull);
00324 rcs_print ("fRtsControl=%d\n", dcb.fRtsControl);
00325 rcs_print ("fAbortOnError=%d\n", dcb.fAbortOnError);
00326 rcs_print ("XonLim=%d\n", dcb.XonLim);
00327 rcs_print ("XoffLim=%d\n", dcb.XoffLim);
00328 rcs_print ("ByteSize=%d\n", dcb.ByteSize);
00329 rcs_print ("Parity=%d\n", dcb.Parity);
00330 rcs_print ("StopBits=%d\n", dcb.StopBits);
00331 rcs_print ("XonChar=%x %c\n", dcb.XoffChar, dcb.XoffChar);
00332 rcs_print ("XoffChar=%x %c\n", dcb.XoffChar, dcb.XoffChar);
00333 rcs_print ("ErrorChar=%x %c\n", dcb.ErrorChar, dcb.ErrorChar);
00334 rcs_print ("EofChar=%x %c\n", dcb.EofChar, dcb.EofChar);
00335 rcs_print ("EvtChar=%x %c\n", dcb.EvtChar, dcb.EvtChar);
00336 #endif
00337 return 0;
00338 }
00339
00340 int
00341 set_serial_port_configuration (RCS_SERIAL_PORT_HANDLE _handle,
00342 rcs_serial_port_setting * _settings)
00343 {
00344 #ifdef UNIX
00345 struct termios ttysettings;
00346 int ttyFileFd = _handle;
00347 if (tcgetattr (ttyFileFd, &ttysettings) < 0)
00348 {
00349 return -1;
00350 }
00351 ttysettings.c_iflag = 0;
00352 ttysettings.c_oflag = 0;
00353 ttysettings.c_cflag = CLOCAL | CREAD;
00354 if (NULL != _settings)
00355 {
00356 if (_settings->data_bits == 8)
00357 {
00358 ttysettings.c_cflag |= CS8;
00359 }
00360 else if (_settings->data_bits == 7)
00361 {
00362 ttysettings.c_cflag |= CS7;
00363 }
00364 if (_settings->use_parity)
00365 {
00366 ttysettings.c_cflag |= PARENB;
00367 if (!_settings->even_parity)
00368 {
00369 ttysettings.c_cflag |= PARODD;
00370 }
00371 }
00372 }
00373 ttysettings.c_lflag = 0;
00374 ttysettings.c_cc[VMIN] = 0;
00375 ttysettings.c_cc[VTIME] = 0;
00376 int cfsetting = B9600;
00377 if (NULL != _settings)
00378 {
00379 switch (_settings->baud_rate)
00380 {
00381 #ifdef B50
00382 case 50:
00383 cfsetting = B50;
00384 break;
00385 #endif
00386
00387 #ifdef B75
00388 case 75:
00389 cfsetting = B75;
00390 break;
00391 #endif
00392
00393 #ifdef B110
00394 case 110:
00395 cfsetting = B110;
00396 break;
00397 #endif
00398
00399 #ifdef B150
00400 case 150:
00401 cfsetting = B150;
00402 break;
00403 #endif
00404
00405 #ifdef B200
00406 case 200:
00407 cfsetting = B200;
00408 break;
00409 #endif
00410
00411 #ifdef B300
00412 case 300:
00413 cfsetting = B300;
00414 break;
00415 #endif
00416
00417 #ifdef B600
00418 case 600:
00419 cfsetting = B600;
00420 break;
00421 #endif
00422
00423 #ifdef B1200
00424 case 1200:
00425 cfsetting = B1200;
00426 break;
00427 #endif
00428
00429 #ifdef B1800
00430 case 1800:
00431 cfsetting = B1800;
00432 break;
00433 #endif
00434
00435 #ifdef B2400
00436 case 2400:
00437 cfsetting = B2400;
00438 break;
00439 #endif
00440
00441 #ifdef B4800
00442 case 4800:
00443 cfsetting = B4800;
00444 break;
00445 #endif
00446
00447 #ifdef B9600
00448 case 9600:
00449 cfsetting = B9600;
00450 break;
00451 #endif
00452
00453
00454 #ifdef B19200
00455 case 19200:
00456 cfsetting = B19200;
00457 break;
00458 #endif
00459
00460
00461 #ifdef B38400
00462 case 38400:
00463 cfsetting = B38400;
00464 break;
00465 #endif
00466
00467
00468 #ifdef B57600
00469 case 57600:
00470 cfsetting = B57600;
00471 break;
00472 #endif
00473
00474
00475 #ifdef B76800
00476 case 76800:
00477 cfsetting = B76800;
00478 break;
00479 #endif
00480
00481
00482 #ifdef B115200
00483 case 115200:
00484 cfsetting = B115200;
00485 break;
00486 #endif
00487
00488
00489 #ifdef B153600
00490 case 153600:
00491 cfsetting = B153600;
00492 break;
00493 #endif
00494
00495
00496 #ifdef B230400
00497 case 230400:
00498 cfsetting = B230400;
00499 break;
00500 #endif
00501
00502
00503 #ifdef B307200
00504 case 307200:
00505 cfsetting = B307200;
00506 break;
00507 #endif
00508
00509 #ifdef B460800
00510 case 460800:
00511 cfsetting = B460800;
00512 break;
00513 #endif
00514
00515 default:
00516 rcs_print_error ("Invalid baud rate for serial port. (%d)\n",
00517 _settings->baud_rate);
00518 }
00519 }
00520 if (cfsetospeed (&ttysettings, cfsetting) < 0)
00521 {
00522 rcs_print_error
00523 ("Can't set baud rate. cfsetospeed(*,%d): errno = %d %s\n", cfsetting,
00524 errno, strerror (errno));
00525 return -1;
00526 }
00527 if (cfsetispeed (&ttysettings, cfsetting) < 0)
00528 {
00529 rcs_print_error
00530 ("Can't set baud rate. cfsetospeed(*,%d): errno = %d %s\n", cfsetting,
00531 errno, strerror (errno));
00532 return -1;
00533 }
00534 if (tcsetattr (ttyFileFd, TCSANOW, &ttysettings) < 0)
00535 {
00536 rcs_print_error
00537 ("Can't set serial port attributes. tcsetattr: errno = %d %s\n",
00538 errno, strerror (errno));
00539 return -1;
00540 }
00541 #endif
00542 #ifdef WIN32
00543 DCB dcb;
00544 if (!GetCommState (_handle, &dcb))
00545 {
00546 rcs_print_sys_error (GETLASTERROR_ERROR_SOURCE,
00547 "Can't GetCommState for a serial communications port.\n");
00548 return -1;
00549 }
00550
00551 dcb.BaudRate = CBR_9600;
00552 if (NULL != _settings)
00553 {
00554 dcb.BaudRate = _settings->baud_rate;
00555 }
00556 dcb.fBinary = FALSE;
00557 dcb.fParity = NOPARITY;
00558 dcb.fOutxCtsFlow = FALSE;
00559 dcb.fOutxDsrFlow = FALSE;
00560 dcb.fDtrControl = DTR_CONTROL_DISABLE;
00561 dcb.fDsrSensitivity = FALSE;
00562 dcb.fTXContinueOnXoff = TRUE;
00563 dcb.fOutX = FALSE;
00564 dcb.fInX = FALSE;
00565 dcb.fErrorChar = FALSE;
00566 dcb.fNull = FALSE;
00567 dcb.fRtsControl = RTS_CONTROL_DISABLE;
00568 dcb.ByteSize = 8;
00569 dcb.Parity = NOPARITY;
00570 dcb.StopBits = ONESTOPBIT;
00571 if (NULL != _settings)
00572 {
00573 dcb.ByteSize = _settings->data_bits;
00574 if (!_settings->use_parity)
00575 {
00576 dcb.Parity = NOPARITY;
00577 }
00578 else
00579 {
00580 if (!_settings->even_parity)
00581 {
00582 dcb.Parity = ODDPARITY;
00583 }
00584 else
00585 {
00586 dcb.Parity = EVENPARITY;
00587 }
00588 dcb.fParity = TRUE;
00589 }
00590 if (_settings->stop_bits == 2)
00591 {
00592 dcb.StopBits = TWOSTOPBITS;
00593 }
00594 }
00595 if (!SetCommState (_handle, &dcb))
00596 {
00597 rcs_print_sys_error (GETLASTERROR_ERROR_SOURCE,
00598 "Can't SetCommState for a serial communications port.\n");
00599 return -1;
00600 }
00601 #endif
00602 return 0;
00603 }
00604
00605
00606 RCS_SERIAL_PORT_HANDLE
00607 open_serial_communications_port (const char *name)
00608 {
00609 RCS_SERIAL_PORT_HANDLE rcs_handle;
00610 HANDLE_INFO *hi = findHandle (name);
00611 if (NULL != hi)
00612 {
00613 hi->refcount++;
00614 return hi->handle;
00615 }
00616 #ifdef UNIX
00617 int ttyFileFd = open (name, O_RDWR | O_NDELAY);
00618 if (ttyFileFd < 0)
00619 {
00620 rcs_print_error
00621 ("Can't open %s as a serial communications port. : %d %s\n", name,
00622 errno, strerror (errno));
00623 return ((RCS_SERIAL_PORT_HANDLE) - 1);
00624 }
00625 rcs_handle = ttyFileFd;
00626 #endif
00627 #ifdef WIN32
00628 HANDLE handle =
00629 CreateFile (name, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
00630 FILE_FLAG_NO_BUFFERING, NULL);
00631 if (handle == INVALID_HANDLE_VALUE)
00632 {
00633 rcs_print_sys_error (GETLASTERROR_ERROR_SOURCE,
00634 "Can't open %s as a serial communications port.\n",
00635 name);
00636 return ((RCS_SERIAL_PORT_HANDLE) - 1);
00637 }
00638 rcs_handle = handle;
00639 #endif
00640 if (((int) rcs_handle) > 0)
00641 {
00642 addHandle (name, rcs_handle);
00643 }
00644 return rcs_handle;
00645 }
00646
00647
00648 int
00649 close_serial_communications_port (RCS_SERIAL_PORT_HANDLE _handle)
00650 {
00651 if (removeHandle (_handle))
00652 {
00653 return 0;
00654 }
00655 #ifdef UNIX
00656 return close (_handle);
00657 #endif
00658 #ifdef WIN32
00659 return CloseHandle (_handle);
00660 #endif
00661 }
00662
00663
00664 int
00665 read_serial_communications_port (RCS_SERIAL_PORT_HANDLE _handle, char *buf,
00666 int maxlen)
00667 {
00668 #ifdef UNIX
00669 int ttyFileFd = _handle;
00670 int bytes_read = read (ttyFileFd, buf, maxlen);
00671 return bytes_read;
00672 #endif
00673 #ifdef WIN32
00674 unsigned long bytes_read = 0;
00675 if (!ReadFile (_handle, buf, maxlen, &bytes_read, NULL))
00676 {
00677 rcs_print_sys_error (GETLASTERROR_ERROR_SOURCE,
00678 "Can't read from a serial communications port.\n");
00679 return -1;
00680 }
00681 return bytes_read;
00682 #endif
00683 }
00684
00685
00686 int
00687 readn_serial_communications_port (RCS_SERIAL_PORT_HANDLE _handle, char *buf,
00688 int len)
00689 {
00690 int bytes_read = 0;
00691 while (bytes_read < len)
00692 {
00693 int rval = read_serial_communications_port (_handle, buf + bytes_read,
00694 len - bytes_read);
00695 if (rval < 0)
00696 {
00697 return rval;
00698 }
00699 bytes_read += rval;
00700 }
00701 return bytes_read;
00702 }
00703
00704 int
00705 write_serial_communications_port (RCS_SERIAL_PORT_HANDLE _handle, char *buf,
00706 int maxlen)
00707 {
00708 #ifdef UNIX
00709 int ttyFileFd = _handle;
00710 return write (ttyFileFd, buf, maxlen);
00711 #endif
00712 #ifdef WIN32
00713 unsigned long bytes_written = 0;
00714 if (!WriteFile (_handle, buf, maxlen, &bytes_written, NULL))
00715 {
00716 rcs_print_sys_error (GETLASTERROR_ERROR_SOURCE,
00717 "Can't write to a serial communications port.\n");
00718 return -1;
00719 }
00720 return bytes_written;
00721 #endif
00722 }