Added Solaris sendfile patch + configure tests from Pierre Belanger <belanger@yahoo...
authorJeremy Allison <jra@samba.org>
Mon, 30 Sep 2002 21:17:18 +0000 (21:17 +0000)
committerJeremy Allison <jra@samba.org>
Mon, 30 Sep 2002 21:17:18 +0000 (21:17 +0000)
Jeremy.

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

index 45d63669354d077e2cb8ba7a34ccfc16af7c8354..0d0da4488706e4962a25662c1bf2b244f1537c8b 100644 (file)
 #undef FREEBSD_SENDFILE_API
 #undef HPUX_SENDFILE_API
 #undef WITH_ADS
+#undef HAVE_SENDFILEV
+#undef HAVE_SENDFILEV64
+#undef SOLARIS_SENDFILE_API
index 538f44621c85a3fbbf283113136808825a33dd2e..4e7b81d1ca2bbf7d704b955570d50aa5a95fb48d 100755 (executable)
@@ -14208,7 +14208,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:14217: 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 14223 "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:14249: \"$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:14281: 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 14287 "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:14313: \"$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
        ;;
 
        *)
@@ -14232,7 +14362,7 @@ fi
 # (WINBIND_STARGETS) and shared libraries (WINBIND_LTARGETS).
 
 echo $ac_n "checking whether to build winbind""... $ac_c" 1>&6
-echo "configure:14236: checking whether to build winbind" >&5
+echo "configure:14366: 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:14332: checking whether struct passwd has pw_comment" >&5
+echo "configure:14462: 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 14338 "configure"
+#line 14468 "configure"
 #include "confdefs.h"
 #include <pwd.h>
 int main() {
 struct passwd p; p.pw_comment;
 ; return 0; }
 EOF
-if { (eval echo configure:14345: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:14475: \"$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:14370: checking whether struct passwd has pw_age" >&5
+echo "configure:14500: 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 14376 "configure"
+#line 14506 "configure"
 #include "confdefs.h"
 #include <pwd.h>
 int main() {
 struct passwd p; p.pw_age;
 ; return 0; }
 EOF
-if { (eval echo configure:14383: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:14513: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   samba_cv_passwd_pw_age=yes
 else
@@ -14418,7 +14548,7 @@ fi
 
 if test x"$INCLUDED_POPT" != x"yes"; then
     echo $ac_n "checking for poptGetContext in -lpopt""... $ac_c" 1>&6
-echo "configure:14422: checking for poptGetContext in -lpopt" >&5
+echo "configure:14552: 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
@@ -14426,7 +14556,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lpopt  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 14430 "configure"
+#line 14560 "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
@@ -14437,7 +14567,7 @@ int main() {
 poptGetContext()
 ; return 0; }
 EOF
-if { (eval echo configure:14441: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:14571: \"$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
@@ -14461,7 +14591,7 @@ fi
 fi
 
 echo $ac_n "checking whether to use included popt""... $ac_c" 1>&6
-echo "configure:14465: checking whether to use included popt" >&5
+echo "configure:14595: 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:14511: checking configure summary" >&5
+echo "configure:14641: 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 14516 "configure"
+#line 14646 "configure"
 #include "confdefs.h"
 #include "${srcdir-.}/tests/summary.c"
 EOF
-if { (eval echo configure:14520: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:14650: \"$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 5221b8ec2b4279ef91d5ed6f384d160ec9372e4f..cd9c8ecbaf68ae7364be5ae53a3eaac6d0ac9194 100644 (file)
@@ -2855,7 +2855,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 770af1a6b562e42ef4cb7aa592e47f4c324f6b98..f1fab36d877f4a062a584343c2155e71c3f0f115 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)