Added Solaris sendfile patch + configure tests from Pierre Belanger <belanger@yahoo...
authorJeremy Allison <jra@samba.org>
Mon, 30 Sep 2002 21:14:46 +0000 (21:14 +0000)
committerJeremy Allison <jra@samba.org>
Mon, 30 Sep 2002 21:14:46 +0000 (21:14 +0000)
Jeremy.
(This used to be commit 8db4d46dc983ce37814fb375d61951b6220a4c61)

source3/acconfig.h
source3/configure
source3/configure.in
source3/include/config.h.in
source3/lib/sendfile.c

index a5bf16279cfed96f0e9ca8801f0eaca8c8cb6a6d..e1bceb1edf756c4aaaf8dd0387de0352764528d8 100644 (file)
 #undef FREEBSD_SENDFILE_API
 #undef HPUX_SENDFILE_API
 #undef WITH_ADS
+#undef HAVE_SENDFILEV
+#undef HAVE_SENDFILEV64
+#undef SOLARIS_SENDFILE_API
index d0753f20275cb527aad00e7dfcbc074c816b61bf..ae8640f945da2ce055638034885c03b964030f9e 100755 (executable)
@@ -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
 
 #              [#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
 #              [#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)'
 # 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
index faa7a2d6fa9ab6019f9e449832e9ee0bc41cab19..f19a8ed18c7495807dd3309a464fd7ba1aab007e 100644 (file)
@@ -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
        ;;
 
        *)
index 617cf0c5faf1e8d941a0b86494be22cff3626e7b..824c054991a10ab0da44471389603e4ddf2e83b3 100644 (file)
 #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
index 5d1cf2f10bc1b465a6c6ab183f6d9a39b3a6c13c..d2ecf3f94ac4d3845728e9754a026697e021526d 100644 (file)
@@ -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)