e576bb | 2002-10-11 | Martin Nilsson | |
|
1b10db | 2002-10-08 | Martin Nilsson | |
|
fe749b | 2013-06-17 | Martin Nilsson | | |
c59250 | 2012-05-12 | Henrik Grubbström (Grubba) | | */
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | */
|
848dec | 1999-04-18 | Henrik Grubbström (Grubba) | |
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | #include "global.h"
|
b30f5a | 1999-04-20 | Henrik Grubbström (Grubba) | | #include "file_machine.h"
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | |
|
a1209a | 1999-04-20 | Henrik Grubbström (Grubba) | | #include "fdlib.h"
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | #include "fd_control.h"
#include "object.h"
#include "array.h"
#include "threads.h"
#include "interpret.h"
#include "svalue.h"
#include "callback.h"
#include "backend.h"
#include "module_support.h"
|
797857 | 2000-08-19 | Henrik Grubbström (Grubba) | | #include "bignum.h"
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | |
|
61e49f | 1999-04-20 | Henrik Grubbström (Grubba) | | #include "file.h"
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | #include <errno.h>
|
e5510f | 2000-03-13 | Henrik Grubbström (Grubba) | | #ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif /* HAVE_SYS_PARAM_H */
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | #ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif /* HAVE_SYS_TYPES_H */
|
a7d70a | 1999-04-20 | Henrik Grubbström (Grubba) | | #ifdef HAVE_UNISTD_H
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | #include <unistd.h>
|
a7d70a | 1999-04-20 | Henrik Grubbström (Grubba) | | #endif /* HAVE_UNISTD_H */
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | |
|
7e7456 | 1999-04-18 | Henrik Grubbström (Grubba) | | #include <sys/stat.h>
|
7acc90 | 1999-05-08 | Simon Coggins | | #ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif /* HAVE_SYS_SOCKET_H */
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | #ifdef HAVE_SYS_UIO_H
#include <sys/uio.h>
#endif /* HAVE_SYS_UIO_H */
|
053395 | 2004-03-30 | Henrik Grubbström (Grubba) | | #ifdef HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
#endif /* HAVE_NETINET_TCP_H */
|
c87081 | 2004-04-14 | Henrik Grubbström (Grubba) | | #ifdef HAVE_SYS_SENDFILE_H
|
5df5b4 | 2004-04-15 | Henrik Grubbström (Grubba) | | #ifndef HAVE_BROKEN_SYS_SENDFILE_H
|
c87081 | 2004-04-14 | Henrik Grubbström (Grubba) | | #include <sys/sendfile.h>
|
5df5b4 | 2004-04-15 | Henrik Grubbström (Grubba) | | #endif /* !HAVE_BROKEN_SYS_SENDFILE_H */
|
c87081 | 2004-04-14 | Henrik Grubbström (Grubba) | | #endif /* HAVE_SYS_SENDFILE_H */
|
af25a2 | 2000-08-12 | Per Hedbor | | #if 0
|
848dec | 1999-04-18 | Henrik Grubbström (Grubba) | | #ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#else /* !HAVE_SYS_MMAN_H */
#ifdef HAVE_LINUX_MMAN_H
#include <linux/mman.h>
#else /* !HAVE_LINUX_MMAN_H */
|
af25a2 | 2000-08-12 | Per Hedbor | | #ifdef HAVE_MMAP /* sys/mman.h is _probably_ there anyway. */
|
848dec | 1999-04-18 | Henrik Grubbström (Grubba) | | #include <sys/mman.h>
#endif /* HAVE_MMAP */
#endif /* HAVE_LINUX_MMAN_H */
#endif /* HAVE_SYS_MMAN_H */
|
af25a2 | 2000-08-12 | Per Hedbor | | #endif
|
848dec | 1999-04-18 | Henrik Grubbström (Grubba) | |
|
6ad237 | 2002-05-11 | Martin Nilsson | | #define sp Pike_sp
|
d41c4c | 2000-12-02 | Henrik Grubbström (Grubba) | |
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | |
#ifdef SF_DEBUG
#define SF_DFPRINTF(X) fprintf X
#else /* !SF_DEBUG */
#define SF_DFPRINTF(X)
#endif /* SF_DEBUG */
|
848dec | 1999-04-18 | Henrik Grubbström (Grubba) | | #define BUF_SIZE 0x00010000 /* 64K */
#define MMAP_SIZE 0x00100000 /* 1M */
#ifndef MAP_FAILED
#define MAP_FAILED ((void *)-1)
|
7e7456 | 1999-04-18 | Henrik Grubbström (Grubba) | | #endif /* !MAP_FAILED */
#ifndef MAP_FILE
#define MAP_FILE 0
#endif /* !MAP_FILE */
|
a7ba2f | 2014-10-17 | Henrik Grubbström (Grubba) | | #if !defined(SOL_TCP) && defined(IPPROTO_TCP)
|
bcd8e2 | 2014-10-17 | Henrik Grubbström (Grubba) | |
#define SOL_TCP IPPROTO_TCP
#endif
|
ea496f | 1999-04-14 | Henrik Grubbström (Grubba) | |
#ifdef _REENTRANT
|
ccbfdc | 1999-05-13 | David Hedbor | | #undef THIS
|
206c15 | 2000-07-07 | Henrik Grubbström (Grubba) | | #define THIS ((struct pike_sendfile *)(Pike_fp->current_storage))
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | |
|
053395 | 2004-03-30 | Henrik Grubbström (Grubba) | |
#if 0
|
e7ae8b | 2000-10-19 | Henrik Grubbström (Grubba) | | |
053395 | 2004-03-30 | Henrik Grubbström (Grubba) | | * /grubba 2000-10-19
|
e7ae8b | 2000-10-19 | Henrik Grubbström (Grubba) | | */
#ifndef HAVE_BROKEN_SENDFILE
#define HAVE_BROKEN_SENDFILE
#endif /* !HAVE_BROKEN_SENDFILE */
|
053395 | 2004-03-30 | Henrik Grubbström (Grubba) | | #endif /* 0 */
|
e7ae8b | 2000-10-19 | Henrik Grubbström (Grubba) | |
|
e5510f | 2000-03-13 | Henrik Grubbström (Grubba) | | |
4b776e | 2000-03-21 | Henrik Grubbström (Grubba) | | * Disable any use of sendfile(2) if HAVE_BROKEN_SENDFILE is defined.
|
e5510f | 2000-03-13 | Henrik Grubbström (Grubba) | | */
|
4b776e | 2000-03-21 | Henrik Grubbström (Grubba) | | #ifdef HAVE_BROKEN_SENDFILE
#undef HAVE_SENDFILE
|
e5510f | 2000-03-13 | Henrik Grubbström (Grubba) | | #undef HAVE_FREEBSD_SENDFILE
|
4b776e | 2000-03-21 | Henrik Grubbström (Grubba) | | #undef HAVE_HPUX_SENDFILE
|
da94d5 | 2008-07-10 | Henrik Grubbström (Grubba) | | #undef HAVE_MACOSX_SENDFILE
|
4b776e | 2000-03-21 | Henrik Grubbström (Grubba) | | #endif /* HAVE_BROKEN_SENDFILE */
|
e5510f | 2000-03-13 | Henrik Grubbström (Grubba) | |
|
ea496f | 1999-04-14 | Henrik Grubbström (Grubba) | |
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | static struct program *pike_sendfile_prog = NULL;
|
74dfe8 | 2012-12-30 | Jonas Walldén | | static void init_pike_sendfile(struct object *UNUSED(o))
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | {
|
21b12a | 2014-09-03 | Martin Nilsson | | memset(THIS, 0, sizeof(struct pike_sendfile));
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | |
|
b53c53 | 1999-10-06 | Fredrik Hübinette (Hubbe) | |
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | SET_SVAL(THIS->callback, T_INT, NUMBER_NUMBER, integer, 0);
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | }
|
74dfe8 | 2012-12-30 | Jonas Walldén | | static void exit_pike_sendfile(struct object *UNUSED(o))
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | {
|
525f1a | 1999-08-17 | Henrik Grubbström (Grubba) | | SF_DFPRINTF((stderr, "sendfile: Exiting...\n"));
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | if (THIS->iovs) {
free(THIS->iovs);
|
408112 | 2000-12-02 | Henrik Grubbström (Grubba) | | THIS->iovs = NULL;
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | }
|
ea496f | 1999-04-14 | Henrik Grubbström (Grubba) | | if (THIS->buffer) {
free(THIS->buffer);
|
408112 | 2000-12-02 | Henrik Grubbström (Grubba) | | THIS->buffer = NULL;
|
ea496f | 1999-04-14 | Henrik Grubbström (Grubba) | | }
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | if (THIS->headers) {
free_array(THIS->headers);
|
408112 | 2000-12-02 | Henrik Grubbström (Grubba) | | THIS->headers = NULL;
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | }
if (THIS->trailers) {
free_array(THIS->trailers);
|
408112 | 2000-12-02 | Henrik Grubbström (Grubba) | | THIS->trailers = NULL;
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | }
if (THIS->from_file) {
free_object(THIS->from_file);
|
408112 | 2000-12-02 | Henrik Grubbström (Grubba) | | THIS->from_file = NULL;
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | }
if (THIS->to_file) {
free_object(THIS->to_file);
|
408112 | 2000-12-02 | Henrik Grubbström (Grubba) | | THIS->to_file = NULL;
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | }
if (THIS->args) {
free_array(THIS->args);
|
408112 | 2000-12-02 | Henrik Grubbström (Grubba) | | THIS->args = NULL;
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | }
if (THIS->self) {
free_object(THIS->self);
THIS->self = NULL;
}
|
cce868 | 1999-10-14 | Henrik Grubbström (Grubba) | | |
b53c53 | 1999-10-06 | Fredrik Hübinette (Hubbe) | | * /Hubbe
|
cce868 | 1999-10-14 | Henrik Grubbström (Grubba) | | * But we do it anyway for paranoia reasons.
* /grubba 1999-10-14
|
b53c53 | 1999-10-06 | Fredrik Hübinette (Hubbe) | | */
|
408112 | 2000-12-02 | Henrik Grubbström (Grubba) | | free_svalue(&(THIS->callback));
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | SET_SVAL(THIS->callback, T_INT, NUMBER_NUMBER, integer, 0);
|
f33d08 | 2003-06-02 | Martin Stjernholm | | if (THIS->backend_callback) {
remove_callback (THIS->backend_callback);
THIS->backend_callback = NULL;
}
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | }
|
ea496f | 1999-04-14 | Henrik Grubbström (Grubba) | | * Fallback code
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | */
|
ea496f | 1999-04-14 | Henrik Grubbström (Grubba) | | #ifndef HAVE_WRITEV
#define writev my_writev
|
2204d2 | 2000-08-07 | Henrik Grubbström (Grubba) | | static size_t writev(int fd, struct iovec *iov, int n)
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | {
|
ea496f | 1999-04-14 | Henrik Grubbström (Grubba) | | if (n) {
|
ccbfdc | 1999-05-13 | David Hedbor | | return fd_write(fd, iov->iov_base, iov->iov_len);
|
ea496f | 1999-04-14 | Henrik Grubbström (Grubba) | | }
return 0;
}
#endif /* !HAVE_WRITEV */
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | |
|
ea496f | 1999-04-14 | Henrik Grubbström (Grubba) | |
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | |
|
023e68 | 2000-01-27 | Henrik Grubbström (Grubba) | | static void sf_call_callback(struct pike_sendfile *this)
|
ea496f | 1999-04-14 | Henrik Grubbström (Grubba) | | {
|
1a1166 | 2000-10-07 | Henrik Grubbström (Grubba) | | debug_malloc_touch(this->args);
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(this->callback) != T_INT) {
if (((TYPEOF(this->callback) == T_OBJECT) ||
((TYPEOF(this->callback) == T_FUNCTION) &&
(SUBTYPEOF(this->callback) != FUNCTION_BUILTIN))) &&
|
c4c5f1 | 2005-10-19 | Henrik Grubbström (Grubba) | | !this->callback.u.object->prog) {
free_array(this->args);
this->args = NULL;
} else {
int sz = this->args->size;
push_int64(this->sent);
push_array_items(this->args);
this->args = NULL;
apply_svalue(&this->callback, 1 + sz);
pop_stack();
}
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | |
free_svalue(&this->callback);
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | SET_SVAL(this->callback, T_INT, NUMBER_NUMBER, integer, 0);
|
ea496f | 1999-04-14 | Henrik Grubbström (Grubba) | | } else {
free_array(this->args);
this->args = NULL;
}
}
|
74dfe8 | 2012-12-30 | Jonas Walldén | | static void call_callback_and_free(struct callback *cb, void *this_, void *UNUSED(arg))
|
ea496f | 1999-04-14 | Henrik Grubbström (Grubba) | | {
struct pike_sendfile *this = this_;
SF_DFPRINTF((stderr, "sendfile: Calling callback...\n"));
remove_callback(cb);
|
f33d08 | 2003-06-02 | Martin Stjernholm | | this->backend_callback = NULL;
|
ea496f | 1999-04-14 | Henrik Grubbström (Grubba) | |
if (this->self) {
|
a4a172 | 2000-12-05 | Per Hedbor | |
|
ea496f | 1999-04-14 | Henrik Grubbström (Grubba) | | push_object(this->self);
this->self = NULL;
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | }
|
ea496f | 1999-04-14 | Henrik Grubbström (Grubba) | |
sf_call_callback(this);
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | |
pop_stack();
}
|
ea496f | 1999-04-14 | Henrik Grubbström (Grubba) | |
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | |
|
1330e1 | 2000-08-10 | Henrik Grubbström (Grubba) | | static ptrdiff_t send_iov(int fd, struct iovec *iov, int iovcnt)
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | {
|
1330e1 | 2000-08-10 | Henrik Grubbström (Grubba) | | ptrdiff_t sent = 0;
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | |
|
a335c0 | 2000-10-23 | Henrik Grubbström (Grubba) | | SF_DFPRINTF((stderr, "sendfile: send_iov(%d, %p, %d)...\n",
fd, iov, iovcnt));
#ifdef SF_DEBUG
{
int cnt;
for(cnt = 0; cnt < iovcnt; cnt++) {
|
408112 | 2000-12-02 | Henrik Grubbström (Grubba) | | SF_DFPRINTF((stderr, "sendfile: %4d: iov_base: %p, iov_len: %ld\n",
cnt, iov[cnt].iov_base,
DO_NOT_WARN((long)iov[cnt].iov_len)));
|
a335c0 | 2000-10-23 | Henrik Grubbström (Grubba) | | }
}
#endif /* SF_DEBUG */
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | while (iovcnt) {
|
1330e1 | 2000-08-10 | Henrik Grubbström (Grubba) | | ptrdiff_t bytes;
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | int cnt = iovcnt;
#ifdef IOV_MAX
if (cnt > IOV_MAX) cnt = IOV_MAX;
#endif
|
a335c0 | 2000-10-23 | Henrik Grubbström (Grubba) | | #ifdef DEF_IOV_MAX
if (cnt > DEF_IOV_MAX) cnt = DEF_IOV_MAX;
#endif
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | #ifdef MAX_IOVEC
if (cnt > MAX_IOVEC) cnt = MAX_IOVEC;
#endif
bytes = writev(fd, iov, cnt);
if ((bytes < 0) && (errno == EINTR)) {
continue;
|
fc66db | 2000-01-24 | Henrik Grubbström (Grubba) | | } else if (bytes < 0) {
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | |
|
a335c0 | 2000-10-23 | Henrik Grubbström (Grubba) | | SF_DFPRINTF((stderr, "sendfile: send_iov(): writev() failed with errno:%d.\n"
"sendfile: Sent %ld bytes so far.\n",
errno, DO_NOT_WARN((long)sent)));
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | return sent;
} else {
sent += bytes;
while (bytes) {
|
2204d2 | 2000-08-07 | Henrik Grubbström (Grubba) | | if ((size_t)bytes >= (size_t)iov->iov_len) {
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | bytes -= iov->iov_len;
iov++;
iovcnt--;
} else {
iov->iov_base = ((char *)iov->iov_base) + bytes;
iov->iov_len -= bytes;
break;
}
}
}
}
|
a335c0 | 2000-10-23 | Henrik Grubbström (Grubba) | | SF_DFPRINTF((stderr, "sendfile: send_iov(): Sent %d bytes\n",
sent));
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | return sent;
}
|
023e68 | 2000-01-27 | Henrik Grubbström (Grubba) | | void low_do_sendfile(struct pike_sendfile *this)
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | {
|
053395 | 2004-03-30 | Henrik Grubbström (Grubba) | | #if defined(SOL_TCP) && (defined(TCP_CORK) || defined(TCP_NODELAY))
int old_val = -1;
|
2d76f2 | 2005-05-20 | Martin Stjernholm | | socklen_t old_len = (socklen_t) sizeof(old_val);
|
053395 | 2004-03-30 | Henrik Grubbström (Grubba) | | #ifdef TCP_CORK
int new_val = 1;
#else /* !TCP_CORK */
int new_val = 0;
#endif /* TCP_CORK */
#endif /* SOL_TCP && (TCP_CORK || TCP_NODELAY) */
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | |
set_nonblocking(this->to_fd, 0);
|
053395 | 2004-03-30 | Henrik Grubbström (Grubba) | | #ifdef SOL_TCP
#ifdef TCP_CORK
while ((getsockopt(this->to_fd, SOL_TCP, TCP_CORK,
|
c87081 | 2004-04-14 | Henrik Grubbström (Grubba) | | &old_val, &old_len)<0) &&
|
053395 | 2004-03-30 | Henrik Grubbström (Grubba) | | (errno == EINTR))
;
if (!old_val) {
while ((setsockopt(this->to_fd, SOL_TCP, TCP_CORK,
&new_val, sizeof(new_val))<0) &&
(errno == EINTR))
;
}
#elif defined(TCP_NODELAY)
while ((getsockopt(this->to_fd, SOL_TCP, TCP_NODELAY,
|
c87081 | 2004-04-14 | Henrik Grubbström (Grubba) | | &old_val, &old_len)<0) &&
|
053395 | 2004-03-30 | Henrik Grubbström (Grubba) | | (errno == EINTR))
;
if (old_val == 1) {
while ((setsockopt(this->to_fd, SOL_TCP, TCP_NODELAY,
&new_val, sizeof(new_val))<0) &&
(errno == EINTR))
;
}
#endif /* TCP_CORK || TCP_NODELAY */
#endif /* SOL_TCP */
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | SF_DFPRINTF((stderr, "sendfile: Worker started\n"));
if ((this->from_file) && (this->len)) {
|
da94d5 | 2008-07-10 | Henrik Grubbström (Grubba) | | #if defined(HAVE_FREEBSD_SENDFILE) || defined(HAVE_HPUX_SENDFILE) || defined(HAVE_MACOSX_SENDFILE)
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | off_t sent = 0;
int len = this->len;
|
675f64 | 1999-06-23 | Henrik Grubbström (Grubba) | | int res;
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | |
|
da94d5 | 2008-07-10 | Henrik Grubbström (Grubba) | | #if defined(HAVE_FREEBSD_SENDFILE) || defined(HAVE_MACOSX_SENDFILE)
|
675f64 | 1999-06-23 | Henrik Grubbström (Grubba) | | struct sf_hdtr hdtr = { NULL, 0, NULL, 0 };
|
da94d5 | 2008-07-10 | Henrik Grubbström (Grubba) | | #ifdef HAVE_FREEBSD_SENDFILE
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | SF_DFPRINTF((stderr, "sendfile: Using FreeBSD-style sendfile()\n"));
|
da94d5 | 2008-07-10 | Henrik Grubbström (Grubba) | | #else
SF_DFPRINTF((stderr, "sendfile: Using MacOS X-style sendfile()\n"));
#endif
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | |
if (this->hd_cnt) {
hdtr.headers = this->hd_iov;
hdtr.hdr_cnt = this->hd_cnt;
}
if (this->tr_cnt) {
hdtr.trailers = this->tr_iov;
hdtr.trl_cnt = this->tr_cnt;
}
|
da94d5 | 2008-07-10 | Henrik Grubbström (Grubba) | | #else /* !(HAVE_FREEBSD_SENDFILE || HAVE_MACOSX_SENDFILE) */
|
2820c4 | 1999-10-15 | Henrik Grubbström (Grubba) | |
|
675f64 | 1999-06-23 | Henrik Grubbström (Grubba) | | struct iovec hdtr[2] = { NULL, 0, NULL, 0 };
SF_DFPRINTF((stderr, "sendfile: Using HP/UX-style sendfile()\n"));
if (this->hd_cnt) {
hdtr[0].iov_base = this->hd_iov->iov_base;
hdtr[0].iov_len = this->hd_iov->iov_len;
}
if (this->tr_cnt) {
hdtr[1].iov_base = this->tr_iov->iov_base;
hdtr[1].iov_len = this->tr_iov->iov_len;
}
#endif /* HAVE_FREEBSD_SENDFILE */
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | if (len < 0) {
|
2247be | 2008-02-20 | Henrik Grubbström (Grubba) | | |
da94d5 | 2008-07-10 | Henrik Grubbström (Grubba) | | *
* From HPUX:
* nbytes is the number of bytes to be sent from the file. If
* this parameter is set to zero, data from the offset to the
* end of the file will be sent.
*
* From MacOS X:
* The len argument is a value-result parameter, that
* specifies how many bytes of the file should be sent and/or
* how many bytes have been sent. Initially the value pointed
* to by the len argument specifies how many bytes should be
* sent with 0 having the special meaning to send until the
* end of file has been reached. On return the value pointed
* to by the len argument indicates how many bytes have been
* sent. The len pointer may not be NULL.
|
2247be | 2008-02-20 | Henrik Grubbström (Grubba) | | */
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | len = 0;
}
|
b78cc6 | 2008-12-17 | Henrik Grubbström (Grubba) | | #ifdef HAVE_SENDFILE_HEADER_LEN_PROBLEM
if (len) {
for (res = 0; res < this->hd_cnt; res ++) {
len += this->hd_iov[res].iov_len;
}
}
#endif
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | |
|
bb3fc9 | 2008-07-10 | Henrik Grubbström (Grubba) | | do {
|
675f64 | 1999-06-23 | Henrik Grubbström (Grubba) | | #ifdef HAVE_FREEBSD_SENDFILE
|
bb3fc9 | 2008-07-10 | Henrik Grubbström (Grubba) | | res = sendfile(this->from_fd, this->to_fd, this->offset, len,
&hdtr, &sent, 0);
|
675f64 | 1999-06-23 | Henrik Grubbström (Grubba) | | #else /* !HAVE_FREEBSD_SENDFILE */
|
da94d5 | 2008-07-10 | Henrik Grubbström (Grubba) | | #ifdef HAVE_MACOSX_SENDFILE
|
bb3fc9 | 2008-07-10 | Henrik Grubbström (Grubba) | | sent = len;
res = sendfile(this->from_fd, this->to_fd, this->offset, &sent,
&hdtr, 0);
|
da94d5 | 2008-07-10 | Henrik Grubbström (Grubba) | | #else
|
053395 | 2004-03-30 | Henrik Grubbström (Grubba) | |
|
bb3fc9 | 2008-07-10 | Henrik Grubbström (Grubba) | | res = sendfile(this->to_fd, this->from_fd, this->offset, len,
hdtr, 0);
|
da94d5 | 2008-07-10 | Henrik Grubbström (Grubba) | | #endif /* HAVE_MACOSX_SENDFILE */
|
675f64 | 1999-06-23 | Henrik Grubbström (Grubba) | | #endif /* HAVE_FREEBSD_SENDFILE */
|
bb3fc9 | 2008-07-10 | Henrik Grubbström (Grubba) | | SF_DFPRINTF((stderr, "sendfile: sendfile() returned %d\n", res));
} while ((res < 0) && (errno == EINTR));
|
2c6393 | 2000-03-13 | Kai Voigt | |
|
675f64 | 1999-06-23 | Henrik Grubbström (Grubba) | | if (res < 0) {
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | switch(errno) {
default:
case ENOTSOCK:
case EINVAL:
goto fallback;
break;
case EFAULT:
|
675f64 | 1999-06-23 | Henrik Grubbström (Grubba) | | #ifdef HAVE_FREEBSD_SENDFILE
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("FreeBSD style sendfile(): EFAULT\n");
|
675f64 | 1999-06-23 | Henrik Grubbström (Grubba) | | #else /* !HAVE_FREEBSD_SENDFILE */
|
053395 | 2004-03-30 | Henrik Grubbström (Grubba) | |
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("HP/UX style sendfile(): EFAULT\n");
|
675f64 | 1999-06-23 | Henrik Grubbström (Grubba) | | #endif /* HAVE_FREEBSD_SENDFILE */
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | break;
case EBADF:
|
7acc90 | 1999-05-08 | Simon Coggins | | case ENOTCONN:
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | case EPIPE:
case EIO:
case EAGAIN:
break;
}
|
da94d5 | 2008-07-10 | Henrik Grubbström (Grubba) | | #ifdef HAVE_HPUX_SENDFILE
|
053395 | 2004-03-30 | Henrik Grubbström (Grubba) | |
|
675f64 | 1999-06-23 | Henrik Grubbström (Grubba) | | } else {
sent = res;
|
da94d5 | 2008-07-10 | Henrik Grubbström (Grubba) | | #endif /* HAVE_HPUX_SENDFILE */
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | }
this->sent += sent;
goto done;
fallback:
|
da94d5 | 2008-07-10 | Henrik Grubbström (Grubba) | | #endif /* HAVE_FREEBSD_SENDFILE || HAVE_HPUX_SENDFILE || HAVE_MACOSX_SENDFILE */
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | |
SF_DFPRINTF((stderr, "sendfile: Sending headers\n"));
if (this->hd_cnt) {
this->sent += send_iov(this->to_fd, this->hd_iov, this->hd_cnt);
}
|
a335c0 | 2000-10-23 | Henrik Grubbström (Grubba) | |
SF_DFPRINTF((stderr, "sendfile: Sent %ld bytes so far.\n",
DO_NOT_WARN((long)this->sent)));
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | |
|
da94d5 | 2008-07-10 | Henrik Grubbström (Grubba) | | #if defined(HAVE_SENDFILE) && !defined(HAVE_FREEBSD_SENDFILE) && !defined(HAVE_HPUX_SENDFILE) && !defined(HAVE_MACOSX_SENDFILE)
|
87ab03 | 2008-07-10 | Henrik Grubbström (Grubba) | | SF_DFPRINTF((stderr,
"sendfile: Sending file with sendfile() Linux & Solaris.\n"));
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | {
|
87ab03 | 2008-07-10 | Henrik Grubbström (Grubba) | | int fail;
off_t offset = this->offset;
if (this->len < 0) {
PIKE_STAT_T st;
if (!fd_fstat(this->from_fd, &st) &&
S_ISREG(st.st_mode)) {
this->len = st.st_size - offset;
} else {
this->len = MAX_LONGEST;
}
}
while (this->len > 0) {
do {
fail = sendfile(this->to_fd, this->from_fd, &offset, this->len);
} while ((fail < 0) && (errno == EINTR));
this->offset = offset;
if (fail <= 0) {
if (!fail) break;
goto normal;
}
this->sent += fail;
this->len -= fail;
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | }
goto send_trailers;
}
normal:
|
da94d5 | 2008-07-10 | Henrik Grubbström (Grubba) | | #endif /* HAVE_SENDFILE && !HAVE_FREEBSD_SENDFILE && !HAVE_HPUX_SENDFILE && !HAVE_MACOSX_SENDFILE */
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | SF_DFPRINTF((stderr, "sendfile: Sending file by hand\n"));
|
af25a2 | 2000-08-12 | Per Hedbor | | #if 0 /* mmap is slower than read/write on most if not all systems */
|
848dec | 1999-04-18 | Henrik Grubbström (Grubba) | | #if defined(HAVE_MMAP) && defined(HAVE_MUNMAP)
{
|
40962a | 2003-03-27 | Martin Stjernholm | | PIKE_STAT_T st;
|
848dec | 1999-04-18 | Henrik Grubbström (Grubba) | |
|
a1209a | 1999-04-20 | Henrik Grubbström (Grubba) | | if (!fd_fstat(this->from_fd, &st) &&
|
848dec | 1999-04-18 | Henrik Grubbström (Grubba) | | S_ISREG(st.st_mode)) {
SF_DFPRINTF((stderr,
"sendfile: from is a regular file - trying mmap().\n"));
while (this->len) {
void *mem;
|
b96ca9 | 2000-08-19 | Henrik Grubbström (Grubba) | | ptrdiff_t len = st.st_size - this->offset;
|
848dec | 1999-04-18 | Henrik Grubbström (Grubba) | | char *buf;
int buflen;
if ((len > this->len) && (this->len >= 0)) {
len = this->len;
}
if (len > MMAP_SIZE) {
len = MMAP_SIZE;
}
|
9a02d3 | 1999-10-14 | Fredrik Hübinette (Hubbe) | |
|
2820c4 | 1999-10-15 | Henrik Grubbström (Grubba) | | if (!len) {
goto send_trailers;
}
|
9a02d3 | 1999-10-14 | Fredrik Hübinette (Hubbe) | |
|
848dec | 1999-04-18 | Henrik Grubbström (Grubba) | | mem = mmap(NULL, len, PROT_READ, MAP_FILE|MAP_SHARED,
this->from_fd, this->offset);
|
149227 | 1999-08-27 | Fredrik Hübinette (Hubbe) | | if (((long)mem) == ((long)MAP_FAILED)) {
|
848dec | 1999-04-18 | Henrik Grubbström (Grubba) | |
goto use_read_write;
}
|
2820c4 | 1999-10-15 | Henrik Grubbström (Grubba) | | #if defined(HAVE_MADVISE) && defined(MADV_SEQUENTIAL)
|
848dec | 1999-04-18 | Henrik Grubbström (Grubba) | | madvise(mem, len, MADV_SEQUENTIAL);
|
2820c4 | 1999-10-15 | Henrik Grubbström (Grubba) | | #endif /* HAVE_MADVISE && MADV_SEQUENTIAL */
|
848dec | 1999-04-18 | Henrik Grubbström (Grubba) | | buf = mem;
buflen = len;
while (buflen) {
|
a1209a | 1999-04-20 | Henrik Grubbström (Grubba) | | int wrlen = fd_write(this->to_fd, buf, buflen);
|
848dec | 1999-04-18 | Henrik Grubbström (Grubba) | |
if ((wrlen < 0) && (errno == EINTR)) {
continue;
|
fc66db | 2000-01-24 | Henrik Grubbström (Grubba) | | } else if (wrlen < 0) {
|
848dec | 1999-04-18 | Henrik Grubbström (Grubba) | | munmap(mem, len);
goto send_trailers;
}
buf += wrlen;
buflen -= wrlen;
this->sent += wrlen;
this->offset += wrlen;
if (this->len > 0) {
this->len -= wrlen;
}
}
munmap(mem, len);
}
|
9a02d3 | 1999-10-14 | Fredrik Hübinette (Hubbe) | |
|
2820c4 | 1999-10-15 | Henrik Grubbström (Grubba) | |
goto send_trailers;
|
848dec | 1999-04-18 | Henrik Grubbström (Grubba) | | }
}
use_read_write:
#endif /* HAVE_MMAP && HAVE_MUNMAP */
|
af25a2 | 2000-08-12 | Per Hedbor | | #endif
|
848dec | 1999-04-18 | Henrik Grubbström (Grubba) | | SF_DFPRINTF((stderr, "sendfile: Using read() and write().\n"));
|
d46092 | 2015-05-04 | Henrik Grubbström (Grubba) | | while ((fd_lseek(this->from_fd, this->offset, SEEK_SET) < 0) &&
(errno == EINTR))
;
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | {
|
b96ca9 | 2000-08-19 | Henrik Grubbström (Grubba) | | ptrdiff_t buflen;
|
097de9 | 2006-07-05 | Martin Stjernholm | | ptrdiff_t len;
if ((this->len > this->buf_size) || (this->len < 0)) {
|
2c6393 | 2000-03-13 | Kai Voigt | | len = this->buf_size;
|
ea496f | 1999-04-14 | Henrik Grubbström (Grubba) | | }
|
097de9 | 2006-07-05 | Martin Stjernholm | | else
len = DO_NOT_WARN ((ptrdiff_t) this->len);
|
a1209a | 1999-04-20 | Henrik Grubbström (Grubba) | | while ((buflen = fd_read(this->from_fd, this->buffer, len)) > 0) {
|
ea496f | 1999-04-14 | Henrik Grubbström (Grubba) | | char *buf = this->buffer;
this->len -= buflen;
this->offset += buflen;
while (buflen) {
|
b96ca9 | 2000-08-19 | Henrik Grubbström (Grubba) | | ptrdiff_t wrlen = fd_write(this->to_fd, buf, buflen);
|
ea496f | 1999-04-14 | Henrik Grubbström (Grubba) | | if ((wrlen < 0) && (errno == EINTR)) {
continue;
|
fc66db | 2000-01-24 | Henrik Grubbström (Grubba) | | } else if (wrlen < 0) {
|
ea496f | 1999-04-14 | Henrik Grubbström (Grubba) | | goto send_trailers;
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | }
|
ea496f | 1999-04-14 | Henrik Grubbström (Grubba) | | buf += wrlen;
buflen -= wrlen;
this->sent += wrlen;
}
|
097de9 | 2006-07-05 | Martin Stjernholm | | if ((this->len > this->buf_size) || (this->len < 0)) {
|
2c6393 | 2000-03-13 | Kai Voigt | | len = this->buf_size;
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | }
|
097de9 | 2006-07-05 | Martin Stjernholm | | else
len = DO_NOT_WARN ((ptrdiff_t) this->len);
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | }
}
send_trailers:
|
a335c0 | 2000-10-23 | Henrik Grubbström (Grubba) | | SF_DFPRINTF((stderr, "sendfile: Sent %ld bytes so far.\n",
DO_NOT_WARN((long)this->sent)));
|
ea496f | 1999-04-14 | Henrik Grubbström (Grubba) | |
free(this->buffer);
this->buffer = NULL;
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | SF_DFPRINTF((stderr, "sendfile: Sending trailers.\n"));
if (this->tr_cnt) {
this->sent += send_iov(this->to_fd, this->tr_iov, this->tr_cnt);
}
} else {
struct iovec *iov = this->hd_iov;
int iovcnt = this->hd_cnt;
SF_DFPRINTF((stderr, "sendfile: Only headers & trailers.\n"));
if (!iovcnt) {
iovcnt = this->tr_cnt;
iov = this->tr_iov;
} else if (this->tr_cnt) {
if (iov + this->hd_cnt != this->tr_iov) {
int i;
struct iovec *iov_tmp = iov + this->hd_cnt;
for (i=0; i < this->tr_cnt; i++) {
iov_tmp[i] = this->tr_iov[i];
}
}
iovcnt += this->tr_cnt;
}
this->sent += send_iov(this->to_fd, iov, iovcnt);
}
|
da94d5 | 2008-07-10 | Henrik Grubbström (Grubba) | | #if defined(HAVE_FREEBSD_SENDFILE) || defined(HAVE_HPUX_SENDFILE) || defined(HAVE_MACOSX_SENDFILE)
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | done:
|
da94d5 | 2008-07-10 | Henrik Grubbström (Grubba) | | #endif /* HAVE_FREEBSD_SENDFILE || HAVE_HPUX_SENDFILE || HAVE_MACOSX_SENDFILE */
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | |
|
053395 | 2004-03-30 | Henrik Grubbström (Grubba) | | #ifdef SOL_TCP
#ifdef TCP_CORK
if (!old_val) {
while((setsockopt(this->to_fd, SOL_TCP, TCP_CORK,
|
c87081 | 2004-04-14 | Henrik Grubbström (Grubba) | | &old_val, old_len)<0) && (errno == EINTR))
|
053395 | 2004-03-30 | Henrik Grubbström (Grubba) | | ;
}
#elif defined(TCP_NODELAY)
if (old_val == 1) {
while((setsockopt(this->to_fd, SOL_TCP, TCP_NODELAY,
|
c87081 | 2004-04-14 | Henrik Grubbström (Grubba) | | &old_val, old_len)<0) && (errno == EINTR))
|
053395 | 2004-03-30 | Henrik Grubbström (Grubba) | | ;
}
#endif /* TCP_CORK || TCP_NODELAY */
#endif /* SOL_TCP */
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | SF_DFPRINTF((stderr,
"sendfile: Done. Setting up callback\n"
"%d bytes sent\n", this->sent));
|
053395 | 2004-03-30 | Henrik Grubbström (Grubba) | |
|
023e68 | 2000-01-27 | Henrik Grubbström (Grubba) | | }
static void worker(void *this_)
{
struct pike_sendfile *this = this_;
|
9407d8 | 2007-05-26 | Henrik Grubbström (Grubba) | | struct Backend_struct *backend;
|
02428c | 2007-06-26 | Henrik Grubbström (Grubba) | | struct timeval tv;
|
023e68 | 2000-01-27 | Henrik Grubbström (Grubba) | |
low_do_sendfile(this);
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | |
|
5715cc | 2001-11-01 | Martin Stjernholm | | low_mt_lock_interpreter();
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | |
|
61e49f | 1999-04-20 | Henrik Grubbström (Grubba) | |
if (this->from) {
if (this->from_file->prog) {
this->from->flags &= ~FILE_LOCK_FD;
} else {
|
913669 | 2003-10-15 | Henrik Grubbström (Grubba) | | if (this->from_fd >= 0) {
fd_close(this->from_fd);
}
|
61e49f | 1999-04-20 | Henrik Grubbström (Grubba) | |
|
10dac8 | 2004-04-05 | Martin Stjernholm | | change_fd_for_box (&this->from->box, -1);
|
61e49f | 1999-04-20 | Henrik Grubbström (Grubba) | | }
}
if (this->to_file->prog) {
this->to->flags &= ~FILE_LOCK_FD;
} else {
|
7640ae | 2008-01-23 | Henrik Grubbström (Grubba) | | fd_close(this->to_fd);
|
61e49f | 1999-04-20 | Henrik Grubbström (Grubba) | |
|
10dac8 | 2004-04-05 | Martin Stjernholm | | change_fd_for_box (&this->to->box, -1);
|
61e49f | 1999-04-20 | Henrik Grubbström (Grubba) | | }
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | |
|
f33d08 | 2003-06-02 | Martin Stjernholm | | #ifdef PIKE_DEBUG
if (this->backend_callback)
Pike_fatal ("Didn't expect a backend callback to be installed already.\n");
#endif
|
9407d8 | 2007-05-26 | Henrik Grubbström (Grubba) | |
if (!(backend = this->to->box.backend)) {
backend = default_backend;
}
|
f33d08 | 2003-06-02 | Martin Stjernholm | | this->backend_callback =
|
9407d8 | 2007-05-26 | Henrik Grubbström (Grubba) | | backend_add_backend_callback(backend, call_callback_and_free, this, 0);
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | |
|
02428c | 2007-06-26 | Henrik Grubbström (Grubba) | | tv.tv_usec = 0;
tv.tv_sec = 0;
backend_lower_timeout(backend, &tv);
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | |
|
9407d8 | 2007-05-26 | Henrik Grubbström (Grubba) | | backend_wake_up_backend(backend);
|
be1311 | 1999-04-23 | Henrik Grubbström (Grubba) | |
num_threads--;
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | |
|
c91f89 | 2000-04-19 | Martin Stjernholm | | mt_unlock_interpreter();
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | |
|
b5ee86 | 1999-08-17 | Henrik Grubbström (Grubba) | | return;
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | }
|
ea496f | 1999-04-14 | Henrik Grubbström (Grubba) | | * Functions callable from Pike code
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | */
|
844cc1 | 2008-03-29 | Martin Bähr | | |
2247be | 2008-02-20 | Henrik Grubbström (Grubba) | | *! function callback, mixed ... args)
*!
*! Low-level implementation of @[Stdio.sendfile()].
*!
*! Sends @[headers] followed by @[len] bytes starting at @[offset]
*! from the file @[from] followed by @[trailers] to the file @[to].
*! When completed @[callback] will be called with the total number of
*! bytes sent as the first argument, followed by @[args].
*!
*! Any of @[headers], @[from] and @[trailers] may be left out
*! by setting them to @expr{0@}.
*!
*! Setting @[offset] to @expr{-1@} means send from the current position in
*! @[from].
*!
*! Setting @[len] to @expr{-1@} means send until @[from]'s end of file is
*! reached.
*!
*! @note
*! Don't use this class directly! Use @[Stdio.sendfile()] instead.
*!
*! In Pike 7.7 and later the @[callback] function will be called
*! from the backend associated with @[to].
*!
*! @seealso
*! @[Stdio.sendfile()]
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | */
static void sf_create(INT32 args)
{
struct pike_sendfile sf;
int iovcnt = 0;
struct svalue *cb = NULL;
|
7a4ca6 | 2003-12-08 | Henrik Grubbström (Grubba) | | LONGEST offset, len;
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | |
if (THIS->to_file) {
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("sendfile->create(): Called a second time!\n");
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | }
|
cce868 | 1999-10-14 | Henrik Grubbström (Grubba) | |
free_svalue(&(THIS->callback));
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | SET_SVAL(THIS->callback, T_INT, NUMBER_NUMBER, integer, 0);
|
cce868 | 1999-10-14 | Henrik Grubbström (Grubba) | |
|
21b12a | 2014-09-03 | Martin Nilsson | | memset(&sf, 0, sizeof(struct pike_sendfile));
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | SET_SVAL(sf.callback, T_INT, NUMBER_NUMBER, integer, 0);
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | |
|
7a4ca6 | 2003-12-08 | Henrik Grubbström (Grubba) | | get_all_args("sendfile", args, "%A%O%l%l%A%o%*",
|
a92ad6 | 2003-10-13 | Henrik Grubbström (Grubba) | | &(sf.headers), &(sf.from_file), &offset,
&len, &(sf.trailers), &(sf.to_file), &cb);
sf.offset = offset;
sf.len = len;
|
b53c53 | 1999-10-06 | Fredrik Hübinette (Hubbe) | |
|
cce868 | 1999-10-14 | Henrik Grubbström (Grubba) | |
sf.callback = *cb;
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | |
push_array(sf.args = aggregate_array(args-7));
args = 8;
|
300266 | 1999-04-17 | Henrik Grubbström (Grubba) | |
|
61e49f | 1999-04-20 | Henrik Grubbström (Grubba) | |
if (sf.to_file->prog == file_program) {
sf.to = (struct my_file *)(sf.to_file->storage);
|
76f746 | 2014-05-26 | Martin Nilsson | | } else if (!(sf.to = get_storage(sf.to_file, file_program))) {
|
cfb831 | 2011-09-12 | Henrik Grubbström (Grubba) | | struct svalue *sval;
|
13b5ed | 2014-05-26 | Per Hedbor | | if (!(sval = get_storage(sf.to_file, file_ref_program)) ||
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | (TYPEOF(*sval) != T_OBJECT) ||
|
13b5ed | 2014-05-26 | Per Hedbor | | !(sf.to = get_storage(sval->u.object, file_program))) {
|
61e49f | 1999-04-20 | Henrik Grubbström (Grubba) | | SIMPLE_BAD_ARG_ERROR("sendfile", 6, "object(Stdio.File)");
}
|
cfb831 | 2011-09-12 | Henrik Grubbström (Grubba) | | add_ref(sval->u.object);
|
61e49f | 1999-04-20 | Henrik Grubbström (Grubba) | | #ifdef PIKE_DEBUG
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if ((TYPEOF(sp[5-args]) != T_OBJECT) ||
|
61e49f | 1999-04-20 | Henrik Grubbström (Grubba) | | (sp[5-args].u.object != sf.to_file)) {
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("sendfile: Stack out of sync(1).\n");
|
61e49f | 1999-04-20 | Henrik Grubbström (Grubba) | | }
#endif /* PIKE_DEBUG */
|
cfb831 | 2011-09-12 | Henrik Grubbström (Grubba) | | sf.to_file = sval->u.object;
|
772741 | 1999-04-22 | Henrik Grubbström (Grubba) | | free_object(sp[5-args].u.object);
|
1e5acf | 1999-04-21 | Henrik Grubbström (Grubba) | | sp[5-args].u.object = sf.to_file;
|
61e49f | 1999-04-20 | Henrik Grubbström (Grubba) | | }
if ((sf.to->flags & FILE_LOCK_FD) ||
|
10dac8 | 2004-04-05 | Martin Stjernholm | | (sf.to->box.fd < 0)) {
|
61e49f | 1999-04-20 | Henrik Grubbström (Grubba) | | SIMPLE_BAD_ARG_ERROR("sendfile", 6, "object(Stdio.File)");
}
|
10dac8 | 2004-04-05 | Martin Stjernholm | | sf.to_fd = sf.to->box.fd;
|
61e49f | 1999-04-20 | Henrik Grubbström (Grubba) | |
if (sf.from_file && !sf.len) {
free_object(sf.from_file);
sf.from_file = NULL;
sf.from = NULL;
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | SET_SVAL(sp[1-args], T_INT, NUMBER_NUMBER, integer, 0);
|
61e49f | 1999-04-20 | Henrik Grubbström (Grubba) | | }
if (sf.from_file) {
if (sf.from_file->prog == file_program) {
sf.from = (struct my_file *)(sf.from_file->storage);
|
76f746 | 2014-05-26 | Martin Nilsson | | } else if (!(sf.from = get_storage(sf.from_file, file_program))) {
|
cfb831 | 2011-09-12 | Henrik Grubbström (Grubba) | | struct svalue *sval;
|
76f746 | 2014-05-26 | Martin Nilsson | | if (!(sval = get_storage(sf.from_file, file_ref_program)) ||
|
319faa | 2015-03-18 | Jonas Walldén | | (TYPEOF(*sval) != T_OBJECT) ||
|
13b5ed | 2014-05-26 | Per Hedbor | | !(sf.from = get_storage(sval->u.object, file_program))) {
|
0b66db | 1999-05-01 | Henrik Grubbström (Grubba) | | SIMPLE_BAD_ARG_ERROR("sendfile", 2, "object(Stdio.File)");
|
61e49f | 1999-04-20 | Henrik Grubbström (Grubba) | | }
|
cfb831 | 2011-09-12 | Henrik Grubbström (Grubba) | | add_ref(sval->u.object);
|
61e49f | 1999-04-20 | Henrik Grubbström (Grubba) | | #ifdef PIKE_DEBUG
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if ((TYPEOF(sp[1-args]) != T_OBJECT) ||
|
61e49f | 1999-04-20 | Henrik Grubbström (Grubba) | | (sp[1-args].u.object != sf.from_file)) {
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("sendfile: Stack out of sync(2).\n");
|
61e49f | 1999-04-20 | Henrik Grubbström (Grubba) | | }
#endif /* PIKE_DEBUG */
|
cfb831 | 2011-09-12 | Henrik Grubbström (Grubba) | | sf.from_file = sval->u.object;
|
1e5acf | 1999-04-21 | Henrik Grubbström (Grubba) | | free_object(sp[1-args].u.object);
sp[1-args].u.object = sf.from_file;
|
61e49f | 1999-04-20 | Henrik Grubbström (Grubba) | | }
if ((sf.from->flags & FILE_LOCK_FD) ||
|
10dac8 | 2004-04-05 | Martin Stjernholm | | (sf.from->box.fd < 0)) {
|
61e49f | 1999-04-20 | Henrik Grubbström (Grubba) | | SIMPLE_BAD_ARG_ERROR("sendfile", 2, "object(Stdio.File)");
}
|
10dac8 | 2004-04-05 | Martin Stjernholm | | sf.from_fd = sf.from->box.fd;
|
61e49f | 1999-04-20 | Henrik Grubbström (Grubba) | | }
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | |
sf.hd_cnt = 0;
if (sf.headers) {
struct array *a = sf.headers;
int i;
for (i=0; i < a->size; i++) {
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if ((TYPEOF(a->item[i]) != T_STRING) || (a->item[i].u.string->size_shift)) {
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | SIMPLE_BAD_ARG_ERROR("sendfile", 1, "array(string)");
}
}
iovcnt = a->size;
sf.hd_cnt = a->size;
}
sf.tr_cnt = 0;
if (sf.trailers) {
struct array *a = sf.trailers;
int i;
for (i=0; i < a->size; i++) {
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if ((TYPEOF(a->item[i]) != T_STRING) || (a->item[i].u.string->size_shift)) {
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | SIMPLE_BAD_ARG_ERROR("sendfile", 5, "array(string)");
}
}
iovcnt += a->size;
sf.tr_cnt = a->size;
}
if (iovcnt) {
|
675f64 | 1999-06-23 | Henrik Grubbström (Grubba) | | #ifdef HAVE_HPUX_SENDFILE
iovcnt = 2;
#endif /* HAVE_HPUX_SENDFILE */
|
dc8d02 | 2014-04-27 | Martin Nilsson | | sf.iovs = xalloc(sizeof(struct iovec) * iovcnt);
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | |
sf.hd_iov = sf.iovs;
|
675f64 | 1999-06-23 | Henrik Grubbström (Grubba) | | #ifdef HAVE_HPUX_SENDFILE
sf.tr_iov = sf.iovs + 1;
#else /* !HAVE_HPUX_SENDFILE */
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | sf.tr_iov = sf.iovs + sf.hd_cnt;
|
675f64 | 1999-06-23 | Henrik Grubbström (Grubba) | | #endif /* HAVE_HPUX_SENDFILE */
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | |
if (sf.headers) {
int i;
for (i = sf.hd_cnt; i--;) {
struct pike_string *s;
|
675f64 | 1999-06-23 | Henrik Grubbström (Grubba) | | #ifdef HAVE_HPUX_SENDFILE
ref_push_string(sf.headers->item[i].u.string);
#else /* !HAVE_HPUX_SENDFILE */
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | if ((s = sf.headers->item[i].u.string)->len) {
sf.hd_iov[i].iov_base = s->str;
sf.hd_iov[i].iov_len = s->len;
} else {
sf.hd_iov++;
sf.hd_cnt--;
}
|
675f64 | 1999-06-23 | Henrik Grubbström (Grubba) | | #endif /* HAVE_HPUX_SENDFILE */
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | }
|
675f64 | 1999-06-23 | Henrik Grubbström (Grubba) | | #ifdef HAVE_HPUX_SENDFILE
if (sf.hd_cnt) {
f_add(sf.hd_cnt);
|
b78cc6 | 2008-12-17 | Henrik Grubbström (Grubba) | | sf.hd_cnt = 1;
|
675f64 | 1999-06-23 | Henrik Grubbström (Grubba) | | free_string(sf.headers->item->u.string);
sf.headers->item->u.string = sp[-1].u.string;
sp--;
|
fc66db | 2000-01-24 | Henrik Grubbström (Grubba) | | dmalloc_touch_svalue(sp);
|
675f64 | 1999-06-23 | Henrik Grubbström (Grubba) | | sf.hd_iov->iov_base = sf.headers->item->u.string->str;
sf.hd_iov->iov_len = sf.headers->item->u.string->len;
} else {
sf.hd_iov->iov_base = NULL;
sf.hd_iov->iov_len = 0;
}
#endif /* HAVE_HPUX_SENDFILE */
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | }
if (sf.trailers) {
int i;
for (i = sf.tr_cnt; i--;) {
struct pike_string *s;
|
675f64 | 1999-06-23 | Henrik Grubbström (Grubba) | | #ifdef HAVE_HPUX_SENDFILE
ref_push_string(sf.trailers->item[i].u.string);
#else /* !HAVE_HPUX_SENDFILE */
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | if ((s = sf.trailers->item[i].u.string)->len) {
sf.tr_iov[i].iov_base = s->str;
sf.tr_iov[i].iov_len = s->len;
} else {
sf.tr_iov++;
sf.tr_cnt--;
}
|
675f64 | 1999-06-23 | Henrik Grubbström (Grubba) | | #endif /* HAVE_HPUX_SENDFILE */
}
#ifdef HAVE_HPUX_SENDFILE
if (sf.tr_cnt) {
f_add(sf.tr_cnt);
free_string(sf.trailers->item->u.string);
sf.trailers->item->u.string = sp[-1].u.string;
sp--;
|
fc66db | 2000-01-24 | Henrik Grubbström (Grubba) | | dmalloc_touch_svalue(sp);
|
675f64 | 1999-06-23 | Henrik Grubbström (Grubba) | | sf.tr_iov->iov_base = sf.trailers->item->u.string->str;
sf.tr_iov->iov_len = sf.trailers->item->u.string->len;
} else {
sf.tr_iov->iov_base = NULL;
sf.tr_iov->iov_len = 0;
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | }
|
675f64 | 1999-06-23 | Henrik Grubbström (Grubba) | | #endif /* HAVE_HPUX_SENDFILE */
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | }
}
if ((sf.headers) && (sf.headers->refs > 1)) {
struct array *a = copy_array(sf.headers);
|
60385b | 1999-04-21 | Henrik Grubbström (Grubba) | | #ifdef PIKE_DEBUG
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if ((TYPEOF(sp[-args]) != T_ARRAY) || (sp[-args].u.array != sf.headers)) {
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("sendfile: Stack out of sync(3).\n");
|
60385b | 1999-04-21 | Henrik Grubbström (Grubba) | | }
#endif /* PIKE_DEBUG */
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | free_array(sf.headers);
|
60385b | 1999-04-21 | Henrik Grubbström (Grubba) | | sp[-args].u.array = a;
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | sf.headers = a;
}
if ((sf.trailers) && (sf.trailers->refs > 1)) {
struct array *a = copy_array(sf.trailers);
|
60385b | 1999-04-21 | Henrik Grubbström (Grubba) | | #ifdef PIKE_DEBUG
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if ((TYPEOF(sp[4-args]) != T_ARRAY) || (sp[4-args].u.array != sf.trailers)) {
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("sendfile: Stack out of sync(4).\n");
|
60385b | 1999-04-21 | Henrik Grubbström (Grubba) | | }
#endif /* PIKE_DEBUG */
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | free_array(sf.trailers);
|
60385b | 1999-04-21 | Henrik Grubbström (Grubba) | | sp[4-args].u.array = a;
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | sf.trailers = a;
}
|
ea496f | 1999-04-14 | Henrik Grubbström (Grubba) | | if (sf.from_file) {
|
dc8d02 | 2014-04-27 | Martin Nilsson | | ONERROR tmp;
SET_ONERROR(tmp, free, sf.iovs);
sf.buffer = xalloc(BUF_SIZE);
UNSET_ONERROR(tmp);
|
2c6393 | 2000-03-13 | Kai Voigt | | sf.buf_size = BUF_SIZE;
|
ea496f | 1999-04-14 | Henrik Grubbström (Grubba) | | }
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | |
|
61e49f | 1999-04-20 | Henrik Grubbström (Grubba) | | {
|
ea496f | 1999-04-14 | Henrik Grubbström (Grubba) | |
|
300266 | 1999-04-17 | Henrik Grubbström (Grubba) | | if (sf.from_file) {
|
61e49f | 1999-04-20 | Henrik Grubbström (Grubba) | |
set_nonblocking(sf.from_fd, 0);
sf.from->open_mode &= ~FILE_NONBLOCKING;
|
31d582 | 1999-04-21 | Henrik Grubbström (Grubba) | |
if (sf.offset < 0) {
sf.offset = fd_lseek(sf.from_fd, 0, SEEK_CUR);
if (sf.offset < 0) {
sf.offset = 0;
}
}
|
ea496f | 1999-04-14 | Henrik Grubbström (Grubba) | | }
|
61e49f | 1999-04-20 | Henrik Grubbström (Grubba) | |
set_nonblocking(sf.to_fd, 0);
sf.to->open_mode &= ~FILE_NONBLOCKING;
|
cce868 | 1999-10-14 | Henrik Grubbström (Grubba) | |
|
300266 | 1999-04-17 | Henrik Grubbström (Grubba) | |
sp -= args;
*THIS = sf;
|
fc66db | 2000-01-24 | Henrik Grubbström (Grubba) | | DO_IF_DMALLOC(while(args--) dmalloc_touch_svalue(sp + args));
|
300266 | 1999-04-17 | Henrik Grubbström (Grubba) | | args = 0;
|
ea496f | 1999-04-14 | Henrik Grubbström (Grubba) | |
|
206c15 | 2000-07-07 | Henrik Grubbström (Grubba) | | add_ref(THIS->self = Pike_fp->current_object);
|
ea496f | 1999-04-14 | Henrik Grubbström (Grubba) | |
|
61e49f | 1999-04-20 | Henrik Grubbström (Grubba) | |
sf.to->flags |= FILE_LOCK_FD;
if (sf.from) {
sf.from->flags |= FILE_LOCK_FD;
}
|
9a02d3 | 1999-10-14 | Fredrik Hübinette (Hubbe) | |
num_threads++;
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | |
|
525f1a | 1999-08-17 | Henrik Grubbström (Grubba) | | th_farm(worker, THIS);
#if 0
{
|
be1311 | 1999-04-23 | Henrik Grubbström (Grubba) | |
sf.to->flags &= ~FILE_LOCK_FD;
if (sf.from) {
sf.from->flags &= ~FILE_LOCK_FD;
}
free_object(THIS->self);
resource_error("Stdio.sendfile", sp, 0, "threads", 1,
"Failed to create thread.\n");
}
|
525f1a | 1999-08-17 | Henrik Grubbström (Grubba) | | #endif /* 0 */
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | }
return;
}
|
c59250 | 2012-05-12 | Henrik Grubbström (Grubba) | |
|
ea496f | 1999-04-14 | Henrik Grubbström (Grubba) | | #endif /* _REENTRANT */
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | |
|
29f9a9 | 2013-06-11 | Martin Nilsson | | void init_stdio_sendfile(void)
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | {
|
ea496f | 1999-04-14 | Henrik Grubbström (Grubba) | | #ifdef _REENTRANT
|
48b97a | 2003-10-28 | Martin Stjernholm | | START_NEW_PROGRAM_ID (STDIO_SENDFILE);
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | ADD_STORAGE(struct pike_sendfile);
|
0032aa | 2005-01-23 | Martin Nilsson | | MAP_VARIABLE("_args", tArray, 0, OFFSETOF(pike_sendfile, args),
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | T_ARRAY);
|
0032aa | 2005-01-23 | Martin Nilsson | | MAP_VARIABLE("_callback", tFuncV(tInt,tMix,tVoid), 0,
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | OFFSETOF(pike_sendfile, callback), T_MIXED);
ADD_FUNCTION("create", sf_create,
tFuncV(tArr(tStr) tObj tInt tInt tArr(tStr) tObj
tFuncV(tInt, tMix, tVoid), tMix, tVoid), 0);
set_init_callback(init_pike_sendfile);
set_exit_callback(exit_pike_sendfile);
pike_sendfile_prog = end_program();
add_program_constant("sendfile", pike_sendfile_prog, 0);
|
ea496f | 1999-04-14 | Henrik Grubbström (Grubba) | | #endif /* _REENTRANT */
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | }
|
29f9a9 | 2013-06-11 | Martin Nilsson | | void exit_stdio_sendfile(void)
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | {
|
ea496f | 1999-04-14 | Henrik Grubbström (Grubba) | | #ifdef _REENTRANT
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | if (pike_sendfile_prog) {
free_program(pike_sendfile_prog);
pike_sendfile_prog = NULL;
}
|
ea496f | 1999-04-14 | Henrik Grubbström (Grubba) | | #endif /* _REENTRANT */
|
f439fc | 1999-04-03 | Henrik Grubbström (Grubba) | | }
|
c59250 | 2012-05-12 | Henrik Grubbström (Grubba) | |
|