[core] consolidate duplicated read-to-close code
[lighttpd.git] / src / network_backends.h
blob9537663cc67587b9ddda6ee5d03d81420f7cabd4
1 #ifndef _NETWORK_BACKENDS_H_
2 #define _NETWORK_BACKENDS_H_
3 #include "first.h"
5 #include "settings.h"
7 #include <sys/types.h>
9 /* on linux 2.4.x you get either sendfile or LFS */
10 #if defined HAVE_SYS_SENDFILE_H && defined HAVE_SENDFILE && (!defined _LARGEFILE_SOURCE || defined HAVE_SENDFILE64) && defined(__linux__) && !defined HAVE_SENDFILE_BROKEN
11 # ifdef USE_SENDFILE
12 # error "can't have more than one sendfile implementation"
13 # endif
14 # define USE_SENDFILE "linux-sendfile"
15 # define USE_LINUX_SENDFILE
16 #endif
18 #if defined HAVE_SENDFILE && (defined(__FreeBSD__) || defined(__DragonFly__))
19 # ifdef USE_SENDFILE
20 # error "can't have more than one sendfile implementation"
21 # endif
22 # define USE_SENDFILE "freebsd-sendfile"
23 # define USE_FREEBSD_SENDFILE
24 #endif
26 #if defined HAVE_SENDFILE && defined(__APPLE__)
27 # ifdef USE_SENDFILE
28 # error "can't have more than one sendfile implementation"
29 # endif
30 # define USE_SENDFILE "darwin-sendfile"
31 # define USE_DARWIN_SENDFILE
32 #endif
34 #if defined HAVE_SYS_SENDFILE_H && defined HAVE_SENDFILEV && defined(__sun)
35 # ifdef USE_SENDFILE
36 # error "can't have more than one sendfile implementation"
37 # endif
38 # define USE_SENDFILE "solaris-sendfilev"
39 # define USE_SOLARIS_SENDFILEV
40 #endif
42 /* not supported so far
43 #if defined HAVE_SEND_FILE && defined(__aix)
44 # ifdef USE_SENDFILE
45 # error "can't have more than one sendfile implementation"
46 # endif
47 # define USE_SENDFILE "aix-sendfile"
48 # define USE_AIX_SENDFILE
49 #endif
52 #if defined HAVE_SYS_UIO_H && defined HAVE_WRITEV
53 # define USE_WRITEV
54 #endif
56 #if defined HAVE_SYS_MMAN_H && defined HAVE_MMAP && defined ENABLE_MMAP
57 # define USE_MMAP
58 #endif
60 #include "base.h"
62 /* return values:
63 * >= 0 : no error
64 * -1 : error (on our side)
65 * -2 : remote close
68 int network_write_chunkqueue_write(server *srv, connection *con, int fd, chunkqueue *cq, off_t max_bytes);
70 #if defined(USE_WRITEV)
71 int network_write_chunkqueue_writev(server *srv, connection *con, int fd, chunkqueue *cq, off_t max_bytes); /* fallback to write */
72 #endif
74 #if defined(USE_SENDFILE)
75 int network_write_chunkqueue_sendfile(server *srv, connection *con, int fd, chunkqueue *cq, off_t max_bytes); /* fallback to write */
76 #endif
78 #if defined(USE_OPENSSL)
79 int network_write_chunkqueue_openssl(server *srv, connection *con, SSL *ssl, chunkqueue *cq, off_t max_bytes);
80 #endif
82 /* write next chunk(s); finished chunks are removed afterwards after successful writes.
83 * return values: similar as backends (0 succes, -1 error, -2 remote close, -3 try again later (EINTR/EAGAIN)) */
84 /* next chunk must be MEM_CHUNK. use write()/send() */
85 int network_write_mem_chunk(server *srv, connection *con, int fd, chunkqueue *cq, off_t *p_max_bytes);
87 #if defined(USE_WRITEV)
88 /* next chunk must be MEM_CHUNK. send multiple mem chunks using writev() */
89 int network_writev_mem_chunks(server *srv, connection *con, int fd, chunkqueue *cq, off_t *p_max_bytes);
90 #else
91 /* fallback to write()/send() */
92 static inline int network_writev_mem_chunks(server *srv, connection *con, int fd, chunkqueue *cq, off_t *p_max_bytes) {
93 return network_write_mem_chunk(srv, con, fd, cq, p_max_bytes);
95 #endif
97 /* next chunk must be FILE_CHUNK. use temporary buffer (srv->tmp_buf) to read into, then write()/send() it */
98 int network_write_file_chunk_no_mmap(server *srv, connection *con, int fd, chunkqueue *cq, off_t *p_max_bytes);
100 off_t mmap_align_offset(off_t start);
101 #if defined(USE_MMAP)
102 /* next chunk must be FILE_CHUNK. send mmap()ed file with write() */
103 int network_write_file_chunk_mmap(server *srv, connection *con, int fd, chunkqueue *cq, off_t *p_max_bytes);
104 #else
105 /* fallback to no_mmap */
106 static inline int network_write_file_chunk_mmap(server *srv, connection *con, int fd, chunkqueue *cq, off_t *p_max_bytes) {
107 return network_write_file_chunk_no_mmap(srv, con, fd, cq, p_max_bytes);
109 #endif
111 #if defined(USE_SENDFILE)
112 int network_write_file_chunk_sendfile(server *srv, connection *con, int fd, chunkqueue *cq, off_t *p_max_bytes);
113 #else
114 /* fallback to mmap */
115 static inline int network_write_file_chunk_sendfile(server *srv, connection *con, int fd, chunkqueue *cq, off_t *p_max_bytes) {
116 return network_write_file_chunk_mmap(srv, con, fd, cq, p_max_bytes);
118 #endif
120 /* next chunk must be FILE_CHUNK. return values: 0 success (=> -1 != cq->first->file.fd), -1 error */
121 int network_open_file_chunk(server *srv, connection *con, chunkqueue *cq);
123 #endif