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.

228 lines
6.5 KiB

18 years ago
18 years ago
18 years ago
14 years ago
15 years ago
  1. /* this header file comes from libowfat, http://www.fefe.de/libowfat/ */
  2. #ifndef IO_H
  3. #define IO_H
  4. #ifdef __MINGW32__
  5. #include_next <io.h>
  6. #endif
  7. /* http://cr.yp.to/lib/io.html */
  8. #include <libowfat/uint64.h>
  9. #include <libowfat/taia.h>
  10. #include <libowfat/compiler.h>
  11. #ifdef __cplusplus
  12. extern "C" {
  13. #endif
  14. /* like open(s,O_RDONLY) */
  15. /* return 1 if ok, 0 on error */
  16. att_read(2)
  17. att_write(1)
  18. int io_readfile(int64* d,const char* filename);
  19. /* like open(s,O_WRONLY|O_CREAT|O_TRUNC,0600) */
  20. /* return 1 if ok, 0 on error */
  21. att_read(2)
  22. att_write(1)
  23. int io_createfile(int64* d,const char* filename);
  24. /* like open(s,O_RDWR) */
  25. /* return 1 if ok, 0 on error */
  26. att_read(2)
  27. att_write(1)
  28. int io_readwritefile(int64* d,const char* filename);
  29. /* like open(s,O_WRONLY|O_APPEND|O_CREAT,0600) */
  30. /* return 1 if ok, 0 on error */
  31. att_read(2)
  32. att_write(1)
  33. int io_appendfile(int64* d,const char* filename);
  34. /* like pipe(d) */
  35. /* return 1 if ok, 0 on error */
  36. att_write(1)
  37. int io_pipe(int64* d);
  38. /* like socketpair() */
  39. /* return 1 if ok, 0 on error */
  40. att_write(1)
  41. int io_socketpair(int64* d);
  42. /* non-blocking read(), -1 for EAGAIN and -3+errno for other errors */
  43. att_writen(2, 3)
  44. int64 io_tryread(int64 d,char* buf,int64 len);
  45. /* blocking read(), with -3 instead of -1 for errors */
  46. att_writen(2, 3)
  47. int64 io_waitread(int64 d,char* buf,int64 len);
  48. /* non-blocking write(), -1 for EAGAIN and -3+errno for other errors */
  49. att_readn(2, 3)
  50. int64 io_trywrite(int64 d,const char* buf,int64 len);
  51. /* blocking write(), with -3 instead of -1 for errors */
  52. att_readn(2, 3)
  53. int64 io_waitwrite(int64 d,const char* buf,int64 len);
  54. /* modify timeout attribute of file descriptor */
  55. void io_timeout(int64 d,tai6464 t);
  56. /* like io_tryread but will return -2,errno=ETIMEDOUT if d has a timeout
  57. * associated and it is passed without input being there */
  58. att_writen(2, 3)
  59. int64 io_tryreadtimeout(int64 d,char* buf,int64 len);
  60. /* like io_trywrite but will return -2,errno=ETIMEDOUT if d has a timeout
  61. * associated and it is passed without being able to write */
  62. att_readn(2, 3)
  63. int64 io_trywritetimeout(int64 d,const char* buf,int64 len);
  64. void io_wantread(int64 d);
  65. void io_wantwrite(int64 d);
  66. void io_dontwantread(int64 d);
  67. void io_dontwantwrite(int64 d);
  68. void io_wait();
  69. void io_waituntil(tai6464 t);
  70. int64 io_waituntil2(int64 milliseconds);
  71. void io_check();
  72. /* signal that read/accept/whatever returned EAGAIN */
  73. /* needed for SIGIO and epoll */
  74. void io_eagain(int64 d); /* do not use, API was a bad idea */
  75. #define HAVE_EAGAIN_READWRITE
  76. void io_eagain_read(int64 d); /* use these ones */
  77. void io_eagain_write(int64 d);
  78. /* return next descriptor from io_wait that can be read from */
  79. int64 io_canread();
  80. /* return next descriptor from io_wait that can be written to */
  81. int64 io_canwrite();
  82. /* return next descriptor with expired timeout */
  83. int64 io_timeouted();
  84. /* is this fd over its timeout? */
  85. int io_timedout(int64 d);
  86. /* 1 means: have IO_FD_CANWRITE, IO_FD_BLOCK and IO_FD_NONBLOCK,
  87. * will be incremented if API is extended in the future */
  88. #define HAVE_IO_FD_FLAGS 1
  89. enum io_fd_flags {
  90. IO_FD_CANWRITE=1, /* new TCP connection, we know it's writable */
  91. IO_FD_BLOCK=2, /* skip the fcntl, assume fd is set to blocking */
  92. IO_FD_NONBLOCK=4, /* skip the fcntl, assume fd is set to non-blocking */
  93. };
  94. /* put d on internal data structure, return 1 on success, 0 on error */
  95. int io_fd(int64 d); /* use this for sockets before you called connect() or accept() */
  96. int io_fd_canwrite(int64 d); /* use this for connected sockets (assumes socket is writable) */
  97. int io_fd_flags(int64 d,int flags); /* can be used to tell io_fd to skip one syscall */
  98. att_write(2)
  99. void io_setcookie(int64 d,void* cookie);
  100. void* io_getcookie(int64 d);
  101. /* put descriptor in non-blocking mode */
  102. void io_nonblock(int64 d);
  103. /* put descriptor in blocking mode */
  104. void io_block(int64 d);
  105. /* put descriptor in close-on-exec mode */
  106. void io_closeonexec(int64 d);
  107. void io_close(int64 d);
  108. /* Free the internal data structures from libio.
  109. * This only makes sense if you run your program in a malloc checker and
  110. * these produce false alarms. Your OS will free these automatically on
  111. * process termination. */
  112. void io_finishandshutdown(void);
  113. /* send n bytes from file fd starting at offset off to socket s */
  114. /* return number of bytes written */
  115. int64 io_sendfile(int64 s,int64 fd,uint64 off,uint64 n);
  116. /* Pass fd over sock (must be a unix domain socket) to other process.
  117. * Return 0 if ok, -1 on error, setting errno. */
  118. int io_passfd(int64 sock,int64 fd);
  119. /* Receive fd over sock (must be a unix domain socket) from other
  120. * process. Return sock if ok, -1 on error, setting errno. */
  121. int64 io_receivefd(int64 sock);
  122. int io_starteventloopthread(unsigned int threads);
  123. #define HAVE_IO_QUEUEFORREAD
  124. /* Artificially queue a file descriptor as readable.
  125. * The next call to io_canread will return this descriptor. */
  126. int io_queueforread(int64 d);
  127. /* Artificially queue a file descriptor as writable.
  128. * The next call to io_canread will return this descriptor. */
  129. int io_queueforwrite(int64 d);
  130. typedef int64 (*io_write_callback)(int64 s,const void* buf,uint64 n);
  131. /* used internally, but hey, who knows */
  132. int64 io_mmapwritefile(int64 out,int64 in,uint64 off,uint64 bytes,io_write_callback writecb);
  133. /* only needed for debugging, will print some stats into the buffer to
  134. * aid in debugging the state machine if a descriptor loops or so */
  135. unsigned int io_debugstring(int64 s,char* buf,unsigned int bufsize);
  136. #ifdef __MINGW32__
  137. #include <mcfgthread/c11thread.h>
  138. #elif defined(__dietlibc__)
  139. #include <threads.h>
  140. #else
  141. #include <pthread.h>
  142. #include <semaphore.h>
  143. #endif
  144. enum { SLOTS=128 };
  145. typedef struct iomux {
  146. int ctx;
  147. int working; /* used to synchronize who is filling the queue */
  148. unsigned int h,l; /* high, low */
  149. struct {
  150. int fd, events;
  151. } q[SLOTS];
  152. #if defined(__MINGW32__) || defined(__dietlibc__)
  153. mtx_t mtx;
  154. cnd_t sem;
  155. #else
  156. sem_t sem;
  157. #endif
  158. } iomux_t;
  159. /* Init master context */
  160. int iom_init(iomux_t* c);
  161. /* Add socket to iomux */
  162. enum {
  163. IOM_READ=1,
  164. IOM_WRITE=2,
  165. IOM_ERROR=4
  166. };
  167. /* return -1 if error, events can be IOM_READ or IOM_WRITE */
  168. int iom_add(iomux_t* c,int64 s,unsigned int events);
  169. /* Blocking wait for single event, timeout in milliseconds */
  170. /* return -1 if error, 0 if ok; s set to fd, revents set to known events on that fd */
  171. /* when done with the fd, call iom_add on it again! */
  172. /* This can be called by multiple threads in parallel */
  173. int iom_wait(iomux_t* c,int64* s,unsigned int* revents,unsigned long timeout);
  174. /* Call this to terminate all threads waiting in iom_wait */
  175. int iom_abort(iomux_t* c);
  176. #ifdef __cplusplus
  177. }
  178. #endif
  179. #endif