summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2002-09-30 21:14:46 +0000
committerJeremy Allison <jra@samba.org>2002-09-30 21:14:46 +0000
commit7dc8aa0854b50242d7ac96c674f5c73111b59e29 (patch)
tree5e005590b61402e31efc5563595609a72956ebb2
parent834b89cc49dc0be1a7f2b8ed4c6f070cc223896e (diff)
downloadsamba-7dc8aa0854b50242d7ac96c674f5c73111b59e29.tar.gz
samba-7dc8aa0854b50242d7ac96c674f5c73111b59e29.tar.bz2
samba-7dc8aa0854b50242d7ac96c674f5c73111b59e29.zip
Added Solaris sendfile patch + configure tests from Pierre Belanger <belanger@yahoo.com>.
Jeremy. (This used to be commit 8db4d46dc983ce37814fb375d61951b6220a4c61)
-rw-r--r--source3/acconfig.h3
-rwxr-xr-xsource3/configure158
-rw-r--r--source3/configure.in66
-rw-r--r--source3/include/config.h.in3
-rw-r--r--source3/lib/sendfile.c87
5 files changed, 300 insertions, 17 deletions
diff --git a/source3/acconfig.h b/source3/acconfig.h
index a5bf16279c..e1bceb1edf 100644
--- a/source3/acconfig.h
+++ b/source3/acconfig.h
@@ -230,3 +230,6 @@
#undef FREEBSD_SENDFILE_API
#undef HPUX_SENDFILE_API
#undef WITH_ADS
+#undef HAVE_SENDFILEV
+#undef HAVE_SENDFILEV64
+#undef SOLARIS_SENDFILE_API
diff --git a/source3/configure b/source3/configure
index d0753f2027..ae8640f945 100755
--- a/source3/configure
+++ b/source3/configure
@@ -14235,7 +14235,137 @@ EOF
else
echo "$ac_t""no" 1>&6;
fi
+ ;;
+ *solaris*)
+ LIBS="$LIBS -lsendfile"
+ echo $ac_n "checking for solaris sendfilev64 support""... $ac_c" 1>&6
+echo "configure:14244: checking for solaris sendfilev64 support" >&5
+if eval "test \"`echo '$''{'samba_cv_HAVE_SENDFILEV64'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+ cat > conftest.$ac_ext <<EOF
+#line 14250 "configure"
+#include "confdefs.h"
+\
+#include <sys/sendfile.h>
+int main() {
+\
+ int sfvcnt;
+ size_t xferred;
+ struct sendfilevec vec[2];
+ ssize_t nwritten;
+
+ sfvcnt = 2;
+
+ vec[0].sfv_fd = SFV_FD_SELF;
+ vec[0].sfv_flag = 0;
+ vec[0].sfv_off = 0;
+ vec[0].sfv_len = 0;
+
+ vec[1].sfv_fd = 0;
+ vec[1].sfv_flag = 0;
+ vec[1].sfv_off = 0;
+ vec[1].sfv_len = 0;
+ nwritten = sendfilev64(tofd, vec, sfvcnt, &xferred);
+
+; return 0; }
+EOF
+if { (eval echo configure:14276: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ samba_cv_HAVE_SENDFILEV64=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ samba_cv_HAVE_SENDFILEV64=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$samba_cv_HAVE_SENDFILEV64" 1>&6
+
+ if test x"$samba_cv_HAVE_SENDFILEV64" = x"yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_SENDFILEV64 1
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define SOLARIS_SENDFILE_API 1
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define WITH_SENDFILE 1
+EOF
+
+ else
+ echo "$ac_t""no" 1>&6;
+ fi
+
+ echo $ac_n "checking for solaris sendfilev support""... $ac_c" 1>&6
+echo "configure:14308: checking for solaris sendfilev support" >&5
+if eval "test \"`echo '$''{'samba_cv_HAVE_SENDFILEV'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+ cat > conftest.$ac_ext <<EOF
+#line 14314 "configure"
+#include "confdefs.h"
+\
+#include <sys/sendfile.h>
+int main() {
+\
+ int sfvcnt;
+ size_t xferred;
+ struct sendfilevec vec[2];
+ ssize_t nwritten;
+
+ sfvcnt = 2;
+
+ vec[0].sfv_fd = SFV_FD_SELF;
+ vec[0].sfv_flag = 0;
+ vec[0].sfv_off = 0;
+ vec[0].sfv_len = 0;
+
+ vec[1].sfv_fd = 0;
+ vec[1].sfv_flag = 0;
+ vec[1].sfv_off = 0;
+ vec[1].sfv_len = 0;
+ nwritten = sendfilev(tofd, vec, sfvcnt, &xferred);
+
+; return 0; }
+EOF
+if { (eval echo configure:14340: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ samba_cv_HAVE_SENDFILEV=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ samba_cv_HAVE_SENDFILEV=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$samba_cv_HAVE_SENDFILEV" 1>&6
+
+ if test x"$samba_cv_HAVE_SENDFILEV" = x"yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_SENDFILEV 1
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define SOLARIS_SENDFILE_API 1
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define WITH_SENDFILE 1
+EOF
+
+ else
+ echo "$ac_t""no" 1>&6;
+ fi
;;
*)
@@ -14259,7 +14389,7 @@ fi
# (WINBIND_STARGETS) and shared libraries (WINBIND_LTARGETS).
echo $ac_n "checking whether to build winbind""... $ac_c" 1>&6
-echo "configure:14263: checking whether to build winbind" >&5
+echo "configure:14393: checking whether to build winbind" >&5
# Initially, the value of $host_os decides whether winbind is supported
@@ -14355,20 +14485,20 @@ fi
# [#include <pwd.h>])
echo $ac_n "checking whether struct passwd has pw_comment""... $ac_c" 1>&6
-echo "configure:14359: checking whether struct passwd has pw_comment" >&5
+echo "configure:14489: checking whether struct passwd has pw_comment" >&5
if eval "test \"`echo '$''{'samba_cv_passwd_pw_comment'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 14365 "configure"
+#line 14495 "configure"
#include "confdefs.h"
#include <pwd.h>
int main() {
struct passwd p; p.pw_comment;
; return 0; }
EOF
-if { (eval echo configure:14372: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:14502: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_passwd_pw_comment=yes
else
@@ -14393,20 +14523,20 @@ fi
# [#include <pwd.h>])
echo $ac_n "checking whether struct passwd has pw_age""... $ac_c" 1>&6
-echo "configure:14397: checking whether struct passwd has pw_age" >&5
+echo "configure:14527: checking whether struct passwd has pw_age" >&5
if eval "test \"`echo '$''{'samba_cv_passwd_pw_age'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 14403 "configure"
+#line 14533 "configure"
#include "confdefs.h"
#include <pwd.h>
int main() {
struct passwd p; p.pw_age;
; return 0; }
EOF
-if { (eval echo configure:14410: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:14540: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_passwd_pw_age=yes
else
@@ -14445,7 +14575,7 @@ fi
if test x"$INCLUDED_POPT" != x"yes"; then
echo $ac_n "checking for poptGetContext in -lpopt""... $ac_c" 1>&6
-echo "configure:14449: checking for poptGetContext in -lpopt" >&5
+echo "configure:14579: checking for poptGetContext in -lpopt" >&5
ac_lib_var=`echo popt'_'poptGetContext | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -14453,7 +14583,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lpopt $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 14457 "configure"
+#line 14587 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -14464,7 +14594,7 @@ int main() {
poptGetContext()
; return 0; }
EOF
-if { (eval echo configure:14468: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:14598: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -14488,7 +14618,7 @@ fi
fi
echo $ac_n "checking whether to use included popt""... $ac_c" 1>&6
-echo "configure:14492: checking whether to use included popt" >&5
+echo "configure:14622: checking whether to use included popt" >&5
if test x"$INCLUDED_POPT" = x"yes"; then
echo "$ac_t""yes" 1>&6
BUILD_POPT='$(POPT_OBJS)'
@@ -14534,16 +14664,16 @@ fi
# final configure stuff
echo $ac_n "checking configure summary""... $ac_c" 1>&6
-echo "configure:14538: checking configure summary" >&5
+echo "configure:14668: checking configure summary" >&5
if test "$cross_compiling" = yes; then
echo "configure: warning: cannot run when cross-compiling" 1>&2
else
cat > conftest.$ac_ext <<EOF
-#line 14543 "configure"
+#line 14673 "configure"
#include "confdefs.h"
#include "${srcdir-.}/tests/summary.c"
EOF
-if { (eval echo configure:14547: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:14677: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
echo "$ac_t""yes" 1>&6
else
diff --git a/source3/configure.in b/source3/configure.in
index faa7a2d6fa..f19a8ed18c 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -2872,7 +2872,73 @@ samba_cv_HAVE_SENDFILE=yes,samba_cv_HAVE_SENDFILE=no)])
else
AC_MSG_RESULT(no);
fi
+ ;;
+
+ *solaris*)
+ LIBS="$LIBS -lsendfile"
+ AC_CACHE_CHECK([for solaris sendfilev64 support],samba_cv_HAVE_SENDFILEV64,[
+ AC_TRY_LINK([\
+#include <sys/sendfile.h>],
+[\
+ int sfvcnt;
+ size_t xferred;
+ struct sendfilevec vec[2];
+ ssize_t nwritten;
+
+ sfvcnt = 2;
+ vec[0].sfv_fd = SFV_FD_SELF;
+ vec[0].sfv_flag = 0;
+ vec[0].sfv_off = 0;
+ vec[0].sfv_len = 0;
+
+ vec[1].sfv_fd = 0;
+ vec[1].sfv_flag = 0;
+ vec[1].sfv_off = 0;
+ vec[1].sfv_len = 0;
+ nwritten = sendfilev64(tofd, vec, sfvcnt, &xferred);
+],
+samba_cv_HAVE_SENDFILEV64=yes,samba_cv_HAVE_SENDFILEV64=no)])
+
+ if test x"$samba_cv_HAVE_SENDFILEV64" = x"yes"; then
+ AC_DEFINE(HAVE_SENDFILEV64)
+ AC_DEFINE(SOLARIS_SENDFILE_API)
+ AC_DEFINE(WITH_SENDFILE)
+ else
+ AC_MSG_RESULT(no);
+ fi
+
+ AC_CACHE_CHECK([for solaris sendfilev support],samba_cv_HAVE_SENDFILEV,[
+ AC_TRY_LINK([\
+#include <sys/sendfile.h>],
+[\
+ int sfvcnt;
+ size_t xferred;
+ struct sendfilevec vec[2];
+ ssize_t nwritten;
+
+ sfvcnt = 2;
+
+ vec[0].sfv_fd = SFV_FD_SELF;
+ vec[0].sfv_flag = 0;
+ vec[0].sfv_off = 0;
+ vec[0].sfv_len = 0;
+
+ vec[1].sfv_fd = 0;
+ vec[1].sfv_flag = 0;
+ vec[1].sfv_off = 0;
+ vec[1].sfv_len = 0;
+ nwritten = sendfilev(tofd, vec, sfvcnt, &xferred);
+],
+samba_cv_HAVE_SENDFILEV=yes,samba_cv_HAVE_SENDFILEV=no)])
+
+ if test x"$samba_cv_HAVE_SENDFILEV" = x"yes"; then
+ AC_DEFINE(HAVE_SENDFILEV)
+ AC_DEFINE(SOLARIS_SENDFILE_API)
+ AC_DEFINE(WITH_SENDFILE)
+ else
+ AC_MSG_RESULT(no);
+ fi
;;
*)
diff --git a/source3/include/config.h.in b/source3/include/config.h.in
index 617cf0c5fa..824c054991 100644
--- a/source3/include/config.h.in
+++ b/source3/include/config.h.in
@@ -296,6 +296,9 @@
#undef FREEBSD_SENDFILE_API
#undef HPUX_SENDFILE_API
#undef WITH_ADS
+#undef HAVE_SENDFILEV
+#undef HAVE_SENDFILEV64
+#undef SOLARIS_SENDFILE_API
/* The number of bytes in a int. */
#undef SIZEOF_INT
diff --git a/source3/lib/sendfile.c b/source3/lib/sendfile.c
index 5d1cf2f10b..d2ecf3f94a 100644
--- a/source3/lib/sendfile.c
+++ b/source3/lib/sendfile.c
@@ -143,11 +143,92 @@ ssize_t sys_sendfile(int tofd, int fromfd, const DATA_BLOB *header, SMB_OFF_T of
#elif defined(SOLARIS_SENDFILE_API)
-/* Hmmm. Can't find Solaris sendfile API docs.... Where is it ? */
+/*
+ * Solaris sendfile code written by Pierre Belanger <belanger@yahoo.com>.
+ */
+
+#include <sys/sendfile.h>
+
ssize_t sys_sendfile(int tofd, int fromfd, const DATA_BLOB *header, SMB_OFF_T offset, size_t count)
{
- errno = ENOSYS;
- return -1;
+ int sfvcnt;
+ size_t total, xferred;
+ struct sendfilevec vec[2];
+ ssize_t hdr_len = 0;
+
+ if (header) {
+ sfvcnt = 2;
+
+ vec[0].sfv_fd = SFV_FD_SELF;
+ vec[0].sfv_flag = 0;
+ vec[0].sfv_off = header->data;
+ vec[0].sfv_len = header->length;
+
+ vec[1].sfv_fd = fromfd;
+ vec[1].sfv_flag = 0;
+ vec[1].sfv_off = offset;
+ vec[1].sfv_len = count;
+
+ hdr_len = header->length;
+ } else {
+ sfvcnt = 1;
+
+ vec[0].sfv_fd = fromfd;
+ vec[0].sfv_flag = 0;
+ vec[0].sfv_off = offset;
+ vec[0].sfv_len = count;
+ }
+
+ total = count + hdr_len;
+
+ while (total) {
+ ssize_t nwritten;
+
+ /*
+ * Although not listed in the API error returns, this is almost certainly
+ * a slow system call and will be interrupted by a signal with EINTR. JRA.
+ */
+
+ xferred = 0;
+
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_SENDFILEV64)
+ nwritten = sendfilev64(tofd, vec, sfvcnt, &xferred);
+#else
+ nwritten = sendfilev(tofd, vec, sfvcnt, &xferred);
+#endif
+ if (nwritten == -1 && errno == EINTR) {
+ if (xferred == 0)
+ continue; /* Nothing written yet. */
+ else
+ nwritten = xferred;
+ }
+
+ if (nwritten == -1)
+ return -1;
+ if (nwritten == 0)
+ return -1; /* I think we're at EOF here... */
+
+ /*
+ * If this was a short (signal interrupted) write we may need
+ * to subtract it from the header data, or null out the header
+ * data altogether if we wrote more than vec[0].sfv_len bytes.
+ * We move vec[1].* to vec[0].* and set sfvcnt to 1
+ */
+
+ if (sfvcnt == 2 && nwritten >= vec[0].sfv_len) {
+ vec[1].sfv_off += nwritten - vec[0].sfv_len;
+ vec[1].sfv_len -= nwritten - vec[0].sfv_len;
+
+ /* Move vec[1].* to vec[0].* and set sfvcnt to 1 */
+ vec[0] = vec[1];
+ sfvcnt = 1;
+ } else {
+ vec[0].sfv_off += nwritten;
+ vec[0].sfv_len -= nwritten;
+ }
+ total -= nwritten;
+ }
+ return count + hdr_len;
}
#elif defined(HPUX_SENDFILE_API)