Mirror of :pserver:cvs@cvs.fefe.de:/cvs libowfat https://www.fefe.de/libowfat/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

132 lines
3.4 KiB

  1. #include <unistd.h>
  2. #include <sys/time.h>
  3. #ifdef __MINGW32__
  4. #include <windows.h>
  5. #else
  6. #include <poll.h>
  7. #endif
  8. #include <errno.h>
  9. #include "io_internal.h"
  10. #ifdef __MINGW32__
  11. #include <stdio.h>
  12. /* All the Unix trickery is unsupported on Windows. Instead, one is
  13. * supposed to do the whole write in overlapping mode and then get
  14. * notified via an I/O completion port when it's done. */
  15. /* So we assume io_trywrite is not used so much and do the overlapping
  16. * stuff on I/O batches. */
  17. int64 io_trywrite(int64 d,const char* buf,int64 len) {
  18. io_entry* e=iarray_get(&io_fds,d);
  19. int r;
  20. if (!e) { errno=EBADF; return -3; }
  21. if (!e->nonblock) {
  22. DWORD written;
  23. fprintf(stderr,"Socket is in blocking mode, just calling WriteFile...");
  24. if (WriteFile((HANDLE)d,buf,len,&written,0)) {
  25. fprintf(stderr," OK, got %u bytes.\n",written);
  26. return written;
  27. } else {
  28. fprintf(stderr," failed.\n",written);
  29. return winsock2errno(-3);
  30. }
  31. } else {
  32. if (e->writequeued && !e->canwrite) {
  33. fprintf(stderr,"io_trywrite: write already queued, returning EAGAIN\n");
  34. errno=EAGAIN;
  35. return -1;
  36. }
  37. if (e->canwrite) {
  38. e->canwrite=0;
  39. e->next_write=-1;
  40. if (e->errorcode) {
  41. fprintf(stderr,"io_trywrite: e->canwrite was set, returning error %d\n",e->errorcode);
  42. errno=winsock2errno(e->errorcode);
  43. return -3;
  44. }
  45. fprintf(stderr,"io_trywrite: e->canwrite was set, had written %u bytes\n",e->bytes_written);
  46. return e->bytes_written;
  47. } else {
  48. fprintf(stderr,"io_trywrite: queueing write...");
  49. if (WriteFile((HANDLE)d,buf,len,&e->errorcode,&e->ow)) {
  50. fprintf(stderr," worked unexpectedly, error %d\n",e->errorcode);
  51. return e->errorcode; /* should not happen */
  52. } else if (GetLastError()==ERROR_IO_PENDING) {
  53. fprintf(stderr," pending.\n");
  54. e->writequeued=1;
  55. errno=EAGAIN;
  56. e->errorcode=0;
  57. return -1;
  58. } else {
  59. fprintf(stderr," failed, error %d\n",e->errorcode);
  60. winsock2errno(-1);
  61. e->errorcode=errno;
  62. return -3;
  63. }
  64. }
  65. }
  66. }
  67. #else
  68. int64 io_trywrite(int64 d,const char* buf,int64 len) {
  69. long r;
  70. struct itimerval old,new;
  71. struct pollfd p;
  72. io_entry* e=iarray_get(&io_fds,d);
  73. io_sigpipe();
  74. if (!e) { errno=EBADF; return -3; }
  75. if (!e->nonblock) {
  76. p.fd=d;
  77. if (p.fd != d) { errno=EBADF; return -3; } /* catch overflow */
  78. p.events=POLLOUT;
  79. switch (poll(&p,1,0)) {
  80. case -1: return -3;
  81. case 0: errno=EAGAIN;
  82. e->canwrite=0;
  83. e->next_write=-1;
  84. return -1;
  85. }
  86. new.it_interval.tv_usec=10000;
  87. new.it_interval.tv_sec=0;
  88. new.it_value.tv_usec=10000;
  89. new.it_value.tv_sec=0;
  90. setitimer(ITIMER_REAL,&new,&old);
  91. }
  92. r=write(d,buf,len);
  93. if (!e->nonblock) {
  94. setitimer(ITIMER_REAL,&old,0);
  95. }
  96. if (r==-1 && errno==EAGAIN)
  97. io_eagain_write(d);
  98. if (r==-1) {
  99. if (errno==EINTR) errno=EAGAIN;
  100. if (errno!=EAGAIN)
  101. r=-3;
  102. }
  103. if (r!=len) {
  104. e->canwrite=0;
  105. io_eagain_write(d);
  106. #if defined(HAVE_SIGIO)
  107. if (d==alt_firstwrite) {
  108. #if 0
  109. debug_printf(("io_trywrite: dequeueing %ld from alt write queue (next is %ld)\n",d,e->next_write));
  110. alt_firstwrite=e->next_write;
  111. e->next_write=-1;
  112. #else
  113. if (d==alt_curwrite) alt_curwrite=-1;
  114. } else {
  115. debug_printf(("io_trywrite: enqueueing %ld into alt write queue (next is %ld)\n",d,alt_firstwrite));
  116. e->next_write=alt_firstwrite;
  117. alt_firstwrite=d;
  118. #endif
  119. }
  120. #endif
  121. }
  122. return r;
  123. }
  124. #endif