diff options
| author | Jeremy Allison <jra@samba.org> | 2002-09-30 21:17:18 +0000 | 
|---|---|---|
| committer | Jeremy Allison <jra@samba.org> | 2002-09-30 21:17:18 +0000 | 
| commit | 4d2d5c4ace09a74420b74f1b9fbee04ecf5fa08b (patch) | |
| tree | b8b5daebebae565074a3f561615e39e51b26dd6f | |
| parent | e5323386143ad9950581b88cc0779ce36dceb6bd (diff) | |
| download | samba-4d2d5c4ace09a74420b74f1b9fbee04ecf5fa08b.tar.gz samba-4d2d5c4ace09a74420b74f1b9fbee04ecf5fa08b.tar.bz2 samba-4d2d5c4ace09a74420b74f1b9fbee04ecf5fa08b.zip  | |
Added Solaris sendfile patch + configure tests from Pierre Belanger <belanger@yahoo.com>.
Jeremy.
(This used to be commit 9c17faefa5cb0ed450578ae5bbcca44e3058bc9b)
| -rw-r--r-- | source3/acconfig.h | 3 | ||||
| -rwxr-xr-x | source3/configure | 158 | ||||
| -rw-r--r-- | source3/configure.in | 66 | ||||
| -rw-r--r-- | source3/include/config.h.in | 3 | ||||
| -rw-r--r-- | source3/lib/sendfile.c | 87 | 
5 files changed, 300 insertions, 17 deletions
diff --git a/source3/acconfig.h b/source3/acconfig.h index 45d6366935..0d0da44887 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 538f44621c..4e7b81d1ca 100755 --- a/source3/configure +++ b/source3/configure @@ -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 @@ -14328,20 +14458,20 @@ fi  #		[#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 @@ -14366,20 +14496,20 @@ fi  #		[#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)' @@ -14507,16 +14637,16 @@ fi  # 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 diff --git a/source3/configure.in b/source3/configure.in index 5221b8ec2b..cd9c8ecbaf 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -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  	;;  	*) diff --git a/source3/include/config.h.in b/source3/include/config.h.in index 770af1a6b5..f1fab36d87 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)  | 
