diff --git a/Makefile.in b/Makefile.in index c232946..e3113c6 100644 --- a/Makefile.in +++ b/Makefile.in @@ -80,11 +80,11 @@ host_triplet = @host@ subdir = . DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/configure $(am__configure_deps) \ - $(top_srcdir)/config/mkinstalldirs INSTALL config/compile \ - config/config.guess config/config.sub config/depcomp \ - config/install-sh config/missing config/mkinstalldirs \ - config/ltmain.sh $(top_srcdir)/config/compile \ - $(top_srcdir)/config/config.guess \ + $(top_srcdir)/config/mkinstalldirs $(srcdir)/iperf3.spec.in \ + INSTALL config/compile config/config.guess config/config.sub \ + config/depcomp config/install-sh config/missing \ + config/mkinstalldirs config/ltmain.sh \ + $(top_srcdir)/config/compile $(top_srcdir)/config/config.guess \ $(top_srcdir)/config/config.sub \ $(top_srcdir)/config/install-sh $(top_srcdir)/config/ltmain.sh \ $(top_srcdir)/config/missing @@ -96,7 +96,7 @@ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs CONFIG_HEADER = $(top_builddir)/src/iperf_config.h -CONFIG_CLEAN_FILES = +CONFIG_CLEAN_FILES = iperf3.spec CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) @@ -349,6 +349,8 @@ $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): +iperf3.spec: $(top_builddir)/config.status $(srcdir)/iperf3.spec.in + cd $(top_builddir) && $(SHELL) ./config.status $@ mostlyclean-libtool: -rm -f *.lo diff --git a/configure b/configure index 54e8083..9a6d125 100755 --- a/configure +++ b/configure @@ -11809,6 +11809,132 @@ exit 1 fi +# On illumos we need -lsocket +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing socket" >&5 +$as_echo_n "checking for library containing socket... " >&6; } +if ${ac_cv_search_socket+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char socket (); +int +main () +{ +return socket (); + ; + return 0; +} +_ACEOF +for ac_lib in '' socket; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_socket=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_socket+:} false; then : + break +fi +done +if ${ac_cv_search_socket+:} false; then : + +else + ac_cv_search_socket=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_socket" >&5 +$as_echo "$ac_cv_search_socket" >&6; } +ac_res=$ac_cv_search_socket +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else + +echo "socket()" +exit 1 + +fi + + +# On illumos inet_ntop in in -lnsl +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing inet_ntop" >&5 +$as_echo_n "checking for library containing inet_ntop... " >&6; } +if ${ac_cv_search_inet_ntop+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char inet_ntop (); +int +main () +{ +return inet_ntop (); + ; + return 0; +} +_ACEOF +for ac_lib in '' nsl; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_inet_ntop=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_inet_ntop+:} false; then : + break +fi +done +if ${ac_cv_search_inet_ntop+:} false; then : + +else + ac_cv_search_inet_ntop=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_inet_ntop" >&5 +$as_echo "$ac_cv_search_inet_ntop" >&6; } +ac_res=$ac_cv_search_inet_ntop +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else + +echo "inet_ntop()" +exit 1 + +fi + + # Checks for typedefs, structures, and compiler characteristics. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } @@ -11893,9 +12019,25 @@ fi # Check for SCTP support +for ac_header in sys/socket.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "sys/socket.h" "ac_cv_header_sys_socket_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_socket_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SYS_SOCKET_H 1 +_ACEOF + +fi + +done + for ac_header in netinet/sctp.h do : - ac_fn_c_check_header_mongrel "$LINENO" "netinet/sctp.h" "ac_cv_header_netinet_sctp_h" "$ac_includes_default" + ac_fn_c_check_header_compile "$LINENO" "netinet/sctp.h" "ac_cv_header_netinet_sctp_h" "#ifdef HAVE_SYS_SOCKET_H +#include +#endif + +" if test "x$ac_cv_header_netinet_sctp_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_NETINET_SCTP_H 1 @@ -12009,7 +12151,7 @@ fi done -ac_config_files="$ac_config_files Makefile src/Makefile src/version.h examples/Makefile" +ac_config_files="$ac_config_files Makefile src/Makefile src/version.h examples/Makefile iperf3.spec" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -13024,6 +13166,7 @@ do "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "src/version.h") CONFIG_FILES="$CONFIG_FILES src/version.h" ;; "examples/Makefile") CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;; + "iperf3.spec") CONFIG_FILES="$CONFIG_FILES iperf3.spec" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac diff --git a/configure.ac b/configure.ac index 3f7f413..50b4819 100644 --- a/configure.ac +++ b/configure.ac @@ -68,14 +68,32 @@ echo "nanosleep() required for timing operations." exit 1 ]) +# On illumos we need -lsocket +AC_SEARCH_LIBS(socket, [socket], [], [ +echo "socket()" +exit 1 +]) + +# On illumos inet_ntop in in -lnsl +AC_SEARCH_LIBS(inet_ntop, [nsl], [], [ +echo "inet_ntop()" +exit 1 +]) + # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST # Check for SCTP support +AC_CHECK_HEADERS([sys/socket.h]) AC_CHECK_HEADERS([netinet/sctp.h], - AC_DEFINE([HAVE_SCTP], [1], [Have SCTP support.])) + AC_DEFINE([HAVE_SCTP], [1], [Have SCTP support.]), + [], + [#ifdef HAVE_SYS_SOCKET_H +#include +#endif +]) -# Check for TCP_CONGESTION sockopt (believed to be Linux only) +# Check for TCP_CONGESTION sockopt (believed to be Linux and FreeBSD only) AC_CACHE_CHECK([TCP_CONGESTION socket option], [iperf3_cv_header_tcp_congestion], AC_EGREP_CPP(yes, @@ -119,4 +137,4 @@ AC_CHECK_FUNCS([cpuset_setaffinity sched_setaffinity], # it needs and what arguments it expects. AC_CHECK_FUNCS([sendfile]) -AC_OUTPUT([Makefile src/Makefile src/version.h examples/Makefile]) +AC_OUTPUT([Makefile src/Makefile src/version.h examples/Makefile iperf3.spec]) diff --git a/docs/conf.py b/docs/conf.py index 2032233..37182f1 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -52,9 +52,9 @@ copyright = u'2014, ESnet' # built documents. # # The short X.Y version. -version = '3.0.7' +version = '3.0.9' # The full version, including alpha/beta/rc tags. -release = '3.0.7' +release = '3.0.9' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/docs/dev.rst b/docs/dev.rst index 22347b9..edf9ea6 100644 --- a/docs/dev.rst +++ b/docs/dev.rst @@ -182,7 +182,7 @@ Release Engineering Checklist 8. Plug the SHA256 checksum into the release announcement. -9. PGP-sign the release announcement text using ``pgp --clearsign``. +9. PGP-sign the release announcement text using ``gpg --clearsign``. The signed announcement will be sent out in a subsequent emails, but could also be archived. Decoupling the signing from emailing allows a signed release announcement to be resent via email or sent diff --git a/docs/index.rst b/docs/index.rst index e74ee49..a4b2225 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -27,7 +27,7 @@ supported platforms, however there have been some reports of success with OpenBSD, Android, and other Linux distributions. iperf3 is principally developed by `ESnet `_ / -`Lawrence Berkleley National Laboratory `_. It +`Lawrence Berkeley National Laboratory `_. It is released under a three-clause BSD license. Links for the Impatient diff --git a/docs/news.rst b/docs/news.rst index dc3c4ed..8652004 100644 --- a/docs/news.rst +++ b/docs/news.rst @@ -1,6 +1,29 @@ iperf3 Project News =================== +2014-10-14: iperf-3.0.9 released +--------------------------------- + +| URL: http://downloads.es.net/pub/iperf/iperf-3.0.9.tar.gz +| SHA256: ``40249a2b30d26b937350b969bcb19f88e1beb356f886ed31422b554bac692459 iperf-3.0.9.tar.gz`` + +This maintenance release fixes an issue for a situation in which +attempting a UDP test with pathologically large (and illegal) packet +sizes could put the iperf3 server in a state where it would stop +accepting connections from clients, thus causing the clients to crash +when interrupted. + + +2014-09-30: iperf-3.0.8 released +--------------------------------- + +| URL: http://downloads.es.net/pub/iperf/iperf-3.0.8.tar.gz +| SHA256: ``81b8d91159862896c57f9b90a006e8b5dc22bd94175d97bd0db50b0ae2c1a78e iperf-3.0.8.tar.gz`` + +This maintenance release is functionally identical to 3.0.7. It +incorporates updated license verbage and a minor compilation fix. + + 2014-08-28: iperf-3.0.7 released --------------------------------- diff --git a/iperf3.spec.in b/iperf3.spec.in new file mode 100644 index 0000000..7276a44 --- /dev/null +++ b/iperf3.spec.in @@ -0,0 +1,105 @@ +Name: iperf3 +Version: @VERSION@ +Release: 1%{?dist} +Summary: Measurement tool for TCP/UDP bandwidth performance + +Group: Applications/Internet +License: BSD +URL: http://github.com/esnet/iperf +Source0: http://stats.es.net/software/iperf-%{version}.tar.gz +BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) + +%if 0%{?el5} +BuildRequires: e2fsprogs-devel +%else +BuildRequires: libuuid-devel +%endif + +%description +Iperf is a tool to measure maximum TCP bandwidth, allowing the tuning of +various parameters and UDP characteristics. Iperf reports bandwidth, delay +jitter, data-gram loss. + +%package devel +Summary: Development files for %{name} +Group: Development/Libraries + +%description devel +The %{name}-devel package contains libraries and header files for +developing applications that use %{name}. + +%prep +%setup -q -n iperf-%{version} + +%build +%configure +make %{?_smp_mflags} + +%install +rm -rf $RPM_BUILD_ROOT +%makeinstall -C src INSTALL_DIR="%{buildroot}%{_bindir}" +mkdir -p %{buildroot}%{_mandir}/man1 + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%defattr(-,root,root,-) +%doc AUTHORS INSTALL +%{_mandir}/man1/iperf3.1.gz +%{_mandir}/man3/libiperf.3.gz +%{_bindir}/iperf3 +%{_libdir}/*.so.* + +%files devel +%defattr(-,root,root,-) +%{_includedir}/iperf_api.h +%{_libdir}/libiperf.a +%{_libdir}/libiperf.la +%{_libdir}/*.so +%{_libdir}/*.so.* + +%changelog +* Fri Aug 29 2014 Aaron Brown 3.0.7-1 +- Update to 3.0.7 + +* Tue Jul 29 2014 Aaron Brown 3.0.6-1 +- Update to 3.0.6 + +* Mon Jun 16 2014 Aaron Brown 3.0.5-1 +- Update to 3.0.5 + +* Wed Apr 2 2014 Susant Sahani 3.0.3-2 +- Moved static library to devel section only . + +* Sun Mar 30 2014 Susant Sahani 3.0.3-1 +- Update to 3.0.3 and added devel rpm support + +* Tue Mar 11 2014 Susant Sahani 3.0.2-1 +- Update to 3.0.2 + +* Tue Jan 14 2014 Susant Sahani 3.0.1-1 +- Update to 3.0.1 + +* Fri Oct 25 2013 Steven Roberts 3.0-1 +- Update to 3.0 + +* Sat May 04 2013 Kevin Fenzi 3.0-0.4.b5 +- Update to 3.0b5 + +* Thu Feb 14 2013 Fedora Release Engineering - 3.0-0.3.b4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Thu Jul 19 2012 Fedora Release Engineering - 3.0-0.2.b4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Fri Jan 13 2012 Fedora Release Engineering - 3.0-0.1.b4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Wed Apr 06 2011 G.Balaji 3.0b4-2 +- Changed the Spec name, removed static libs generation and devel +- package. + +* Sat Mar 26 2011 G.Balaji 3.0b4-1 +- Initial Version + diff --git a/src/iperf.h b/src/iperf.h index b1ff1e8..7d5c1e3 100644 --- a/src/iperf.h +++ b/src/iperf.h @@ -294,6 +294,8 @@ struct iperf_test #define MB (1024 * 1024) #define MAX_TCP_BUFFER (512 * MB) #define MAX_BLOCKSIZE MB +/* Maximum size UDP send is (64K - 1) - IP and UDP header sizes */ +#define MAX_UDP_BLOCKSIZE (65535 - 8 - 20) #define MIN_INTERVAL 0.1 #define MAX_INTERVAL 60.0 #define MAX_TIME 86400 diff --git a/src/iperf_api.c b/src/iperf_api.c index b8f7891..7833ee7 100644 --- a/src/iperf_api.c +++ b/src/iperf_api.c @@ -913,6 +913,11 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv) i_errno = IEBLOCKSIZE; return -1; } + if (test->protocol->id == Pudp && + blksize > MAX_UDP_BLOCKSIZE) { + i_errno = IEUDPBLOCKSIZE; + return -1; + } test->settings->blksize = blksize; if (!rate_flag) @@ -2103,6 +2108,8 @@ iperf_print_intermediate(struct iperf_test *test) /* next build string with sum of all streams */ if (test->num_streams > 1 || test->json_output) { sp = SLIST_FIRST(&test->streams); /* reset back to 1st stream */ + /* Only do this of course if there was a first stream */ + if (sp) { irp = TAILQ_LAST(&sp->result->interval_results, irlisthead); /* use 1st stream for timing info */ unit_snprintf(ubuf, UNIT_LEN, (double) bytes, 'A'); @@ -2141,6 +2148,7 @@ iperf_print_intermediate(struct iperf_test *test) iprintf(test, report_sum_bw_udp_format, start_time, end_time, ubuf, nbuf, avg_jitter * 1000.0, lost_packets, total_packets, lost_percent, test->omitting?report_omitted:""); } } + } } } @@ -2187,6 +2195,13 @@ iperf_print_results(struct iperf_test *test) start_time = 0.; sp = SLIST_FIRST(&test->streams); + /* + * If there is at least one stream, then figure out the length of time + * we were running the tests and print out some statistics about + * the streams. It's possible to not have any streams at all + * if the client got interrupted before it got to do anything. + */ + if (sp) { end_time = timeval_diff(&sp->result->start_time, &sp->result->end_time); SLIST_FOREACH(sp, &test->streams, streams) { if (test->json_output) { @@ -2263,10 +2278,17 @@ iperf_print_results(struct iperf_test *test) iprintf(test, report_bw_format, sp->socket, start_time, end_time, ubuf, nbuf, report_receiver); } } + } if (test->num_streams > 1 || test->json_output) { unit_snprintf(ubuf, UNIT_LEN, (double) total_sent, 'A'); - bandwidth = (double) total_sent / (double) end_time; + /* If no tests were run, arbitrariliy set bandwidth to 0. */ + if (end_time > 0.0) { + bandwidth = (double) total_sent / (double) end_time; + } + else { + bandwidth = 0.0; + } unit_snprintf(nbuf, UNIT_LEN, bandwidth, test->settings->unit_format); if (test->protocol->id == Ptcp || test->protocol->id == Psctp) { if (test->sender_has_retransmits) { @@ -2283,7 +2305,13 @@ iperf_print_results(struct iperf_test *test) iprintf(test, report_sum_bw_format, start_time, end_time, ubuf, nbuf, report_sender); } unit_snprintf(ubuf, UNIT_LEN, (double) total_received, 'A'); - bandwidth = (double) total_received / (double) end_time; + /* If no tests were run, set received bandwidth to 0 */ + if (end_time > 0.0) { + bandwidth = (double) total_received / (double) end_time; + } + else { + bandwidth = 0.0; + } unit_snprintf(nbuf, UNIT_LEN, bandwidth, test->settings->unit_format); if (test->json_output) cJSON_AddItemToObject(test->json_end, "sum_received", iperf_json_printf("start: %f end: %f seconds: %f bytes: %d bits_per_second: %f", (double) start_time, (double) end_time, (double) end_time, (int64_t) total_received, bandwidth * 8)); @@ -2292,7 +2320,13 @@ iperf_print_results(struct iperf_test *test) } else { /* Summary sum, UDP. */ avg_jitter /= test->num_streams; - lost_percent = 100.0 * lost_packets / total_packets; + /* If no packets were sent, arbitrarily set loss percentage to 100. */ + if (total_packets > 0) { + lost_percent = 100.0 * lost_packets / total_packets; + } + else { + lost_percent = 100.0; + } if (test->json_output) cJSON_AddItemToObject(test->json_end, "sum", iperf_json_printf("start: %f end: %f seconds: %f bytes: %d bits_per_second: %f jitter_ms: %f lost_packets: %d packets: %d lost_percent: %f", (double) start_time, (double) end_time, (double) end_time, (int64_t) total_sent, bandwidth * 8, (double) avg_jitter * 1000.0, (int64_t) lost_packets, (int64_t) total_packets, (double) lost_percent)); else diff --git a/src/iperf_api.h b/src/iperf_api.h index 0fe85b8..d958581 100644 --- a/src/iperf_api.h +++ b/src/iperf_api.h @@ -282,6 +282,7 @@ enum { IELOGFILE = 17, // Can't open log file IENOSCTP = 18, // No SCTP support available IEBIND = 19, // Local port specified with no local bind option + IEUDPBLOCKSIZE = 20, // Block size too large. Maximum value = %dMAX_UDP_BLOCKSIZE /* Test errors */ IENEWTEST = 100, // Unable to create a new test (check perror) IEINITTEST = 101, // Test initialization failed (check perror) diff --git a/src/iperf_config.h.in b/src/iperf_config.h.in index c3d81b0..2187e7e 100644 --- a/src/iperf_config.h.in +++ b/src/iperf_config.h.in @@ -42,6 +42,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKET_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H diff --git a/src/iperf_error.c b/src/iperf_error.c index a14f261..6587022 100644 --- a/src/iperf_error.c +++ b/src/iperf_error.c @@ -124,6 +124,9 @@ iperf_strerror(int i_errno) case IEBIND: snprintf(errstr, len, "--bind must be specified to use --cport"); break; + case IEUDPBLOCKSIZE: + snprintf(errstr, len, "block size too large (maximum = %d bytes)", MAX_UDP_BLOCKSIZE); + break; case IEMSS: snprintf(errstr, len, "TCP MSS too large (maximum = %d bytes)", MAX_MSS); break; @@ -341,7 +344,7 @@ iperf_strerror(int i_errno) perr = 1; break; case IESETSCTPDISABLEFRAG: - snprintf(errstr, len, "unable to set SCTP_DISABLE_FRAG"); + snprintf(errstr, len, "unable to set SCTP_DISABLE_FRAGMENTS"); perr = 1; break; } diff --git a/src/iperf_server_api.c b/src/iperf_server_api.c index 31b642e..5d3e3c2 100644 --- a/src/iperf_server_api.c +++ b/src/iperf_server_api.c @@ -534,8 +534,14 @@ iperf_run_server(struct iperf_test *test) FD_SET(s, &test->read_set); if (s > test->max_fd) test->max_fd = s; - // If the protocol isn't UDP, set nonblocking sockets - if (test->protocol->id != Pudp) { + /* + * If the protocol isn't UDP, or even if it is but + * we're the receiver, set nonblocking sockets. + * We need this to allow a server receiver to + * maintain interactivity with the control channel. + */ + if (test->protocol->id != Pudp || + !test->sender) { setnonblocking(s, 1); } diff --git a/src/iperf_udp.c b/src/iperf_udp.c index edc1721..5bb8afe 100644 --- a/src/iperf_udp.c +++ b/src/iperf_udp.c @@ -63,7 +63,12 @@ iperf_udp_recv(struct iperf_stream *sp) r = Nread(sp->socket, sp->buffer, size, Pudp); - if (r < 0) + /* + * If we got an error in the read, or if we didn't read anything + * because the underlying read(2) got a EAGAIN, then skip packet + * processing. + */ + if (r <= 0) return r; sp->result->bytes_received += r; diff --git a/src/portable_endian.h b/src/portable_endian.h index 520c79a..c7cb852 100644 --- a/src/portable_endian.h +++ b/src/portable_endian.h @@ -55,7 +55,7 @@ # include -#elif defined(__SunOS) +#elif defined(__sun) && defined(__SVR4) # include # include