aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt33
-rw-r--r--client.c30
-rw-r--r--configure.ac12
3 files changed, 60 insertions, 15 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 37185b2..eaaf6b0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,14 +1,29 @@
-CMAKE_MINIMUM_REQUIRED (VERSION 2.6)
-PROJECT (FileSender)
+CMAKE_MINIMUM_REQUIRED(VERSION 3.0)
+PROJECT(FileSender)
-INCLUDE (CheckIncludeFiles)
-CHECK_INCLUDE_FILES (sys/sendfile.h HAVE_SYS_SENDFILE_H)
+INCLUDE(CheckIncludeFiles)
+CHECK_INCLUDE_FILES(sys/sendfile.h HAVE_SYS_SENDFILE_H)
-INCLUDE (CheckFunctionExists)
-CHECK_FUNCTION_EXISTS (socket HAVE_SOCKET)
+IF(HAVE_SYS_SENDFILE_H)
+ ADD_COMPILE_DEFINITIONS(HAVE_SYS_SENDFILE_H)
+ENDIF(HAVE_SYS_SENDFILE_H)
+
+INCLUDE(CheckFunctionExists)
+CHECK_FUNCTION_EXISTS(sendfile HAVE_SENDFILE)
+IF(HAVE_SENDFILE)
+ ADD_COMPILE_DEFINITIONS(HAVE_SENDFILE)
+ENDIF(HAVE_SENDFILE)
+
+CHECK_FUNCTION_EXISTS(socket HAVE_SOCKET)
IF(NOT HAVE_SOCKET)
- CHECK_LIBRARY_EXISTS (socket socket "" HAVE_SOCKET)
+ CHECK_LIBRARY_EXISTS(socket socket "" HAVE_SOCKET)
ENDIF(NOT HAVE_SOCKET)
-ADD_EXECUTABLE (server server.c utils.c utils.h)
-ADD_EXECUTABLE (client client.c utils.c utils.h)
+INCLUDE(CheckStructHasMember)
+CHECK_STRUCT_HAS_MEMBER("struct sf_hdtr" hdr_cnt sys/socket.h HAVE_STRUCT_SF_HDTR_HDR_CNT)
+IF(HAVE_STRUCT_SF_HDTR_HDR_CNT)
+ ADD_COMPILE_DEFINITIONS(HAVE_STRUCT_SF_HDTR_HDR_CNT)
+ENDIF(HAVE_STRUCT_SF_HDTR_HDR_CNT)
+
+ADD_EXECUTABLE(server server.c utils.c utils.h)
+ADD_EXECUTABLE(client client.c utils.c utils.h)
diff --git a/client.c b/client.c
index 9d04966..2cf94f3 100644
--- a/client.c
+++ b/client.c
@@ -10,12 +10,15 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <sys/sendfile.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
+#ifdef HAVE_SYS_SENDFILE_H
+#include <sys/sendfile.h>
+#endif
+
#include "utils.h"
const char *progname = NULL;
@@ -29,10 +32,31 @@ usage ()
printf ("Default port is %s\n", port);
}
+static ssize_t
+transmit (int fd, int sfd, size_t size)
+{
+#if HAVE_SENDFILE
+#if HAVE_STRUCT_SF_HDTR_HDR_CNT
+ int rc;
+ off_t sbytes;
+ rc = sendfile (sfd, fd, 0, size, (struct sf_hdtr *) NULL, &sbytes, 0);
+ if (rc < 0)
+ return rc;
+ return sbytes;
+#else
+ int rc;
+ off_t dummy = 0; /* specially for Solaris (it crashes if sendfile's 3rd arg is NULL). */
+ rc = sendfile (fd, sfd, &dummy, size);
+ return rc;
+#endif
+#else /* no HAVE_SENDFILE */
+#error need sendfile()
+#endif
+}
+
static void
send_file (int fd, const char *filename)
{
- off_t dummy = 0; /* specially for Solaris (it crashes if sendfile's 3rd arg is NULL). */
int sfd = open (filename, O_RDONLY);
if (sfd < 0)
fatal ("cannot read `%s'", filename);
@@ -47,7 +71,7 @@ send_file (int fd, const char *filename)
rc = write (fd, name, filename_len); /* filename\0payload */
if (rc != filename_len)
fatal ("failed to write filename");
- rc = sendfile (fd, sfd, &dummy, st.st_size);
+ rc = transmit (fd, sfd, st.st_size);
if (rc < 0)
fatal ("failed to send file `%s'", filename);
else if (rc != st.st_size)
diff --git a/configure.ac b/configure.ac
index f3b9ee5..ef819ea 100644
--- a/configure.ac
+++ b/configure.ac
@@ -19,13 +19,19 @@ AC_CHECK_HEADERS([fcntl.h netinet/in.h stddef.h stdlib.h string.h sys/socket.h u
# Checks for typedefs, structures, and compiler characteristics.
AC_TYPE_SIZE_T
AC_TYPE_SSIZE_T
-AC_CHECK_TYPES([ptrdiff_t])
+AC_CHECK_MEMBERS([struct sf_hdtr.hdr_cnt], [], [],
+[
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+])
# Checks for library functions.
AC_FUNC_MALLOC
-AC_CHECK_FUNCS([memset strerror])
+AC_CHECK_FUNCS([memset sendfile strerror])
AC_SEARCH_LIBS([socket], [socket])
AC_SEARCH_LIBS([sendfile], [sendfile])
-AC_OUTPUT([Makefile])
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT()