readline.c 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /* include readline1 */
  2. #include "unpthread.h"
  3. static pthread_key_t rl_key;
  4. static pthread_once_t rl_once = PTHREAD_ONCE_INIT;
  5. static void
  6. readline_destructor(void *ptr)
  7. {
  8. free(ptr);
  9. }
  10. static void
  11. readline_once(void)
  12. {
  13. Pthread_key_create(&rl_key, readline_destructor);
  14. }
  15. typedef struct {
  16. int rl_cnt; /* initialize to 0 */
  17. char *rl_bufptr; /* initialize to rl_buf */
  18. char rl_buf[MAXLINE];
  19. } Rline;
  20. /* end readline1 */
  21. /* include readline2 */
  22. static ssize_t
  23. my_read(Rline *tsd, int fd, char *ptr)
  24. {
  25. if (tsd->rl_cnt <= 0) {
  26. again:
  27. if ( (tsd->rl_cnt = read(fd, tsd->rl_buf, MAXLINE)) < 0) {
  28. if (errno == EINTR)
  29. goto again;
  30. return(-1);
  31. } else if (tsd->rl_cnt == 0)
  32. return(0);
  33. tsd->rl_bufptr = tsd->rl_buf;
  34. }
  35. tsd->rl_cnt--;
  36. *ptr = *tsd->rl_bufptr++;
  37. return(1);
  38. }
  39. ssize_t
  40. readline(int fd, void *vptr, size_t maxlen)
  41. {
  42. size_t n, rc;
  43. char c, *ptr;
  44. Rline *tsd;
  45. Pthread_once(&rl_once, readline_once);
  46. if ( (tsd = pthread_getspecific(rl_key)) == NULL) {
  47. tsd = Calloc(1, sizeof(Rline)); /* init to 0 */
  48. Pthread_setspecific(rl_key, tsd);
  49. }
  50. ptr = vptr;
  51. for (n = 1; n < maxlen; n++) {
  52. if ( (rc = my_read(tsd, fd, &c)) == 1) {
  53. *ptr++ = c;
  54. if (c == '\n')
  55. break;
  56. } else if (rc == 0) {
  57. *ptr = 0;
  58. return(n - 1); /* EOF, n - 1 bytes read */
  59. } else
  60. return(-1); /* error, errno set by read() */
  61. }
  62. *ptr = 0;
  63. return(n);
  64. }
  65. /* end readline2 */
  66. ssize_t
  67. Readline(int fd, void *ptr, size_t maxlen)
  68. {
  69. ssize_t n;
  70. if ( (n = readline(fd, ptr, maxlen)) < 0)
  71. err_sys("readline error");
  72. return(n);
  73. }