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.

54 lines
1.4 KiB

6 years ago
  1. #ifndef __MINGW32__
  2. #include <sys/types.h>
  3. #include <sys/uio.h>
  4. #include <errno.h>
  5. #include <unistd.h>
  6. #endif
  7. #include "buffer.h"
  8. #ifndef __unlikely
  9. #ifdef __GNUC__
  10. #define __unlikely(x) __builtin_expect((x),0)
  11. #else
  12. #define __unlikely(x) (x)
  13. #endif
  14. #endif
  15. extern ssize_t buffer_stubborn(ssize_t (*op)(),int fd,const char* buf, size_t len,void* cookie);
  16. int buffer_putflush(buffer* b,const char* x,size_t len) {
  17. /* Since we know we are going to flush anyway, let's see if we can
  18. * optimize a bit */
  19. if (!b->p) /* if the buffer is empty, just call buffer_stubborn directly */
  20. return buffer_stubborn(b->op,b->fd,x,len,b);
  21. #ifndef __MINGW32__
  22. if (b->op==write && len>sizeof(struct iovec)*2) {
  23. struct iovec v[2];
  24. ssize_t w;
  25. size_t cl=b->p+len;
  26. v[0].iov_base=b->x;
  27. v[0].iov_len=b->p;
  28. v[1].iov_base=(char*)x;
  29. v[1].iov_len=len;
  30. while ((w=writev(b->fd,v,2))<0) {
  31. if (errno == EINTR) continue;
  32. return -1;
  33. }
  34. if (__unlikely((size_t)w!=cl)) {
  35. /* partial write. ugh. */
  36. if ((size_t)w<v[0].iov_len) {
  37. if (buffer_stubborn(b->op,b->fd,v[0].iov_base+w,v[0].iov_len-w,b) ||
  38. buffer_stubborn(b->op,b->fd,v[1].iov_base,v[0].iov_len,b)) return -1;
  39. } else {
  40. w-=v[0].iov_len;
  41. return buffer_stubborn(b->op,b->fd,v[1].iov_base+w,v[1].iov_len-w,b);
  42. }
  43. }
  44. b->p=0;
  45. return 0;
  46. }
  47. #endif
  48. if (buffer_put(b,x,len)<0) return -1;
  49. if (buffer_flush(b)<0) return -1;
  50. return 0;
  51. }