When transmitting file contents to a client with sendfile(), on
every platform other then Solaris (where we use sendfilev()), we
send the AFP the protocol header with an additional send with
MSG_MORE before calling sendfile().
FreeBSD sendfile() supports sending protocol header (and trailer)
data similarly to Solaris sendfilev().
* FIX: Permissions of ._ AppleDouble ressource fork after conversion
from v2 to ea.
Fixes bug #505.
* FIX: Permissions of ._ AppleDouble ressource fork after conversion
from v2 to ea.
Fixes bug #505.
+* UPD: Use FreeBSD sendfile() capability to send protocol header.
+ From FR #75.
Changes in 3.0.2
================
Changes in 3.0.2
================
"afp_read(fork: %" PRIu16 " [%s], off: %" PRIu64 ", len: %" PRIu64 ", size: %" PRIu64 ")",
ofork->of_refnum, (ofork->of_flags & AFPFORK_DATA) ? "data" : "reso", offset, reqcount, size);
"afp_read(fork: %" PRIu16 " [%s], off: %" PRIu64 ", len: %" PRIu64 ", size: %" PRIu64 ")",
ofork->of_refnum, (ofork->of_flags & AFPFORK_DATA) ? "data" : "reso", offset, reqcount, size);
err = AFPERR_EOF;
goto afp_read_err;
}
err = AFPERR_EOF;
goto afp_read_err;
}
int sfvcnt;
struct sendfilevec vec[2];
ssize_t nwritten;
int sfvcnt;
struct sendfilevec vec[2];
ssize_t nwritten;
+#elif defined(FREEBSD)
+ ssize_t nwritten;
+ void *hdrp;
+ struct sf_hdtr hdr;
+ struct iovec iovec;
+ hdr.headers = &iovec;
+ hdr.hdr_cnt = 1;
+ hdr.trailers = NULL;
+ hdr.trl_cnt = 0;
+ hdrp = &hdr;
#endif
LOG(log_maxdebug, logtype_dsi, "dsi_stream_read_file(off: %jd, len: %zu)", (intmax_t)offset, length);
#endif
LOG(log_maxdebug, logtype_dsi, "dsi_stream_read_file(off: %jd, len: %zu)", (intmax_t)offset, length);
vec[1].sfv_flag = 0;
vec[1].sfv_off = offset;
vec[1].sfv_len = length;
vec[1].sfv_flag = 0;
vec[1].sfv_off = offset;
vec[1].sfv_len = length;
+#elif defined(FREEBSD)
+ iovec.iov_base = block;
+ iovec.iov_len = DSI_BLOCKSIZ;
#else
dsi_stream_write(dsi, block, sizeof(block), DSI_MSG_MORE);
#endif
#else
dsi_stream_write(dsi, block, sizeof(block), DSI_MSG_MORE);
#endif
#ifdef HAVE_SENDFILEV
nwritten = 0;
len = sendfilev(dsi->socket, vec, sfvcnt, &nwritten);
#ifdef HAVE_SENDFILEV
nwritten = 0;
len = sendfilev(dsi->socket, vec, sfvcnt, &nwritten);
+#elif defined(FREEBSD)
+ len = sendfile(fromfd, dsi->socket, pos, total - written, hdrp, &nwritten, 0);
+ if (len == 0)
+ len = nwritten;
#else
len = sys_sendfile(dsi->socket, fromfd, &pos, total - written);
#endif
#else
len = sys_sendfile(dsi->socket, fromfd, &pos, total - written);
#endif
case EINTR:
case EAGAIN:
len = 0;
case EINTR:
case EAGAIN:
len = 0;
+#if defined(HAVE_SENDFILEV) || defined(FREEBSD)
-#else
-#if defined(SOLARIS) || defined(FREEBSD)
if (pos > offset) {
/* we actually have sent sth., adjust counters and keep trying */
len = pos - offset;
offset = pos;
}
if (pos > offset) {
/* we actually have sent sth., adjust counters and keep trying */
len = pos - offset;
offset = pos;
}
-#endif /* defined(SOLARIS) || defined(FREEBSD) */
#endif /* HAVE_SENDFILEV */
if (dsi_peek(dsi) != 0) {
#endif /* HAVE_SENDFILEV */
if (dsi_peek(dsi) != 0) {
vec[0].sfv_off += len;
vec[0].sfv_len -= len;
}
vec[0].sfv_off += len;
vec[0].sfv_len -= len;
}
+#elif defined(FREEBSD)
+ if (hdrp) {
+ if (len >= iovec.iov_len) {
+ hdrp = NULL;
+ len -= iovec.iov_len; /* len now contains how much sendfile() actually sent from the file */
+ } else {
+ iovec.iov_len -= len;
+ iovec.iov_base += len;
+ len = 0;
+ }
+ }
+ pos += len;
#endif /* HAVE_SENDFILEV */
LOG(log_maxdebug, logtype_dsi, "dsi_stream_read_file: wrote: %zd", len);
written += len;
#endif /* HAVE_SENDFILEV */
LOG(log_maxdebug, logtype_dsi, "dsi_stream_read_file: wrote: %zd", len);
written += len;