diff --git a/.azure/azure-pipelines-mac.yml b/.azure/azure-pipelines-mac.yml index 90be1439c..9fa1596f1 100644 --- a/.azure/azure-pipelines-mac.yml +++ b/.azure/azure-pipelines-mac.yml @@ -113,6 +113,16 @@ jobs: echo $? displayName: 'Consume from pkg-config' condition: and(succeeded(), contains(variables.CMakeFlags, 'Denable-framework=0')) + # regression test for #1266 + - script: | + set -e + rm -rf build + mkdir build && cd build + export PKG_CONFIG_PATH="$(brew --prefix libffi)/lib/pkgconfig" + cmake -G Xcode -Denable-sdl2=0 -Denable-readline=0 -Denable-dbus=0 .. + xcodebuild + displayName: 'Test CMake XCode Generator' + condition: and(succeeded(), not(contains(variables.CMakeFlags, 'Denable-framework=0'))) - job: macOS_ports diff --git a/.azure/azure-pipelines-vcpkg.yml b/.azure/azure-pipelines-vcpkg.yml index 3918115b5..52e3cafb8 100644 --- a/.azure/azure-pipelines-vcpkg.yml +++ b/.azure/azure-pipelines-vcpkg.yml @@ -34,7 +34,7 @@ variables: toolset: 'v142' generator: 'Visual Studio 16 2019' configuration: 'RelWithDebInfo' - VCPKG_REVISION: 'acc3bcf76b84ae5041c86ab55fe138ae7b8255c7' + VCPKG_REVISION: 'fc59c2a30a99536e8fb6e085c228e9f724dd87d0' jobs: - job: vcpkg diff --git a/.cirrus.yml b/.cirrus.yml index 183282b9e..ebdb49d0b 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -3,8 +3,8 @@ task: name: FreeBSD freebsd_instance: matrix: + image_family: freebsd-14-0 image_family: freebsd-13-2 - image_family: freebsd-13-1 install_script: pwd && ls -la && pkg update --force && pkg install -y cmake glib alsa-lib ladspa portaudio pulseaudio pkgconf sdl2 diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index 2b95d072d..b2ae8868d 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -17,6 +17,7 @@ env: # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) # Use Debug build for better code coverage results BUILD_TYPE: Debug + BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed name: SonarCloud Workflow jobs: @@ -60,20 +61,23 @@ jobs: shell: bash working-directory: ${{github.workspace}}/build run: cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -Werror=dev -Denable-portaudio=1 -Denable-ladspa=1 -Denable-coverage=1 -DNO_GUI=1 $GITHUB_WORKSPACE + + - name: Install sonar-scanner and build-wrapper + uses: SonarSource/sonarcloud-github-c-cpp@v2 - name: Build working-directory: ${{github.workspace}}/build shell: bash # Execute the build. You can specify a specific target with "--target " run: | - ./build-wrapper-linux-x86-64 --out-dir bw-output make + build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} make - name: Test working-directory: ${{github.workspace}}/build shell: bash # Execute tests defined by the CMake configuration. run: | - ./build-wrapper-linux-x86-64 --out-dir bw-output make coverage + build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} make coverage # sonar-scanner does not like utf8 filenames - name: Prepare for Sonar @@ -85,19 +89,11 @@ jobs: ls -la ${{ github.workspace }}/build ls -la ${{ github.workspace }}/build/coverage -# The official sonarsource/sonarcloud-github-action@v1.5 action does not work properly. -# It keeps complaining that the build-wrapper.json cannot be found. -# Hence, use a third party action to download and add sonar-scanner to PATH and then run it manually. - - name: Setup sonarqube - uses: warchant/setup-sonar-scanner@v3 - - - name: Run sonarqube + - name: Run sonar-scanner env: - # to get access to secrets.SONAR_TOKEN, provide GITHUB_TOKEN GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: sonar-scanner - -Dsonar.login=${{ secrets.SONAR_TOKEN }} - -Dsonar.cfamily.build-wrapper-output=${{ github.workspace }}/build/bw-output - -Dsonar.coverageReportPaths=build/coverage/sonarqube.report - -Dsonar.verbose=false - -Dsonar.host.url=https://sonarcloud.io/ + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + run: | + sonar-scanner \ + -Dsonar.cfamily.build-wrapper-output="${{github.workspace}}/build/${{ env.BUILD_WRAPPER_OUT_DIR }}" \ + -Dsonar.coverageReportPaths=${{github.workspace}}/build/coverage/sonarqube.report diff --git a/CMakeLists.txt b/CMakeLists.txt index d1e07e85f..7b002e47a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,7 +47,7 @@ set ( PACKAGE "fluidsynth" ) # FluidSynth package version set ( FLUIDSYNTH_VERSION_MAJOR 2 ) set ( FLUIDSYNTH_VERSION_MINOR 3 ) -set ( FLUIDSYNTH_VERSION_MICRO 3 ) +set ( FLUIDSYNTH_VERSION_MICRO 5 ) set ( VERSION "${FLUIDSYNTH_VERSION_MAJOR}.${FLUIDSYNTH_VERSION_MINOR}.${FLUIDSYNTH_VERSION_MICRO}" ) set ( FLUIDSYNTH_VERSION "\"${VERSION}\"" ) @@ -62,7 +62,7 @@ set ( FLUIDSYNTH_VERSION "\"${VERSION}\"" ) # This is not exactly the same algorithm as the libtool one, but the results are the same. set ( LIB_VERSION_CURRENT 3 ) set ( LIB_VERSION_AGE 2 ) -set ( LIB_VERSION_REVISION 1 ) +set ( LIB_VERSION_REVISION 3 ) set ( LIB_VERSION_INFO "${LIB_VERSION_CURRENT}.${LIB_VERSION_AGE}.${LIB_VERSION_REVISION}" ) @@ -399,8 +399,7 @@ unset ( DARWIN CACHE ) unset ( MACOSX_FRAMEWORK CACHE ) if ( CMAKE_SYSTEM MATCHES "Darwin" ) set ( DARWIN 1 ) - set ( CMAKE_INSTALL_NAME_DIR - ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR} ) + set ( CMAKE_INSTALL_NAME_DIR ${CMAKE_INSTALL_FULL_LIBDIR} ) if ( enable-coreaudio ) check_include_file ( CoreAudio/AudioHardware.h COREAUDIO_FOUND ) if ( COREAUDIO_FOUND ) @@ -547,7 +546,7 @@ endif ( enable-libsndfile ) unset ( PULSE_SUPPORT CACHE ) if ( enable-pulseaudio ) - find_package ( PulseAudio ${PULSEAUDIO_MINIMUM_VERSION} QUIET ) + find_package ( PulseAudio ${PULSEAUDIO_MINIMUM_VERSION} ) # Upstream config does not search for pulse-simple find_library ( PULSEAUDIO_SIMPLE_LIBRARY NAMES "pulse-simple" ) if ( PULSEAUDIO_FOUND AND PULSEAUDIO_SIMPLE_LIBRARY ) diff --git a/cmake_admin/FindInstPatch.cmake b/cmake_admin/FindInstPatch.cmake index e77504597..112892651 100644 --- a/cmake_admin/FindInstPatch.cmake +++ b/cmake_admin/FindInstPatch.cmake @@ -37,7 +37,7 @@ find_path( find_library( InstPatch_LIBRARY - NAMES "instpatch-1.0" + NAMES "instpatch-1.0" "instpatch-2" HINTS "${PC_INSTPATCH_LIBDIR}") # Get version from pkg-config or read the config header diff --git a/cmake_admin/FindJack.cmake b/cmake_admin/FindJack.cmake index cb0e06de3..0788014df 100644 --- a/cmake_admin/FindJack.cmake +++ b/cmake_admin/FindJack.cmake @@ -9,7 +9,7 @@ Imported Targets This module provides the following imported targets, if found: -``Jack::libJack`` +``Jack::Jack`` The Jack library Result Variables @@ -35,7 +35,7 @@ find_path( find_library( Jack_LIBRARY NAMES "jack" - HINTS "${PC_JACK_LIBDIR}") + HINTS "${PC_JACK_LIBDIR}" "${PC_JACK_LIBRARY_DIRS}") # Handle transitive dependencies if(PC_JACK_FOUND) diff --git a/cmake_admin/FindOpus.cmake b/cmake_admin/FindOpus.cmake index 0258d4561..bf77e293b 100644 --- a/cmake_admin/FindOpus.cmake +++ b/cmake_admin/FindOpus.cmake @@ -53,13 +53,13 @@ find_library( # Get the version from pkg-config if(PC_OPUS_VERSION) - set(Opus_VERSION "${PC_OPUS_VERSION}") + set(Opus_VERSION "${PC_OPUS_VERSION}.0") set(OPUS_VERSION "${Opus_VERSION}") set(OPUS_VERSION_STRING "${Opus_VERSION}") string(REPLACE "." ";" _opus_version_list "${Opus_VERSION}") list(GET _opus_version_list 0 OPUS_VERSION_MAJOR) list(GET _opus_version_list 1 OPUS_VERSION_MINOR) - list(GET _opus_version_list 2 OPUS_VERSION_PATCH) + list(GET _opus_version_list 2 OPUS_VERSION_PATCH) # might be missing if zero, hence adding the .0 above else() message(STATUS "Unable to get Opus version without pkg-config.") set(Opus_VERSION) diff --git a/cmake_admin/FindSndFile.cmake b/cmake_admin/FindSndFile.cmake index d77333ba0..271bb061f 100644 --- a/cmake_admin/FindSndFile.cmake +++ b/cmake_admin/FindSndFile.cmake @@ -50,7 +50,7 @@ find_path( find_library( _sndfile_library - NAMES "sndfile" + NAMES "sndfile" "sndfile-1" HINTS "${PC_SNDFILE_LIBDIR}") # Get version from pkg-config or read the config header @@ -69,7 +69,8 @@ elseif(SndFile_INCLUDE_DIR) endif() # Check the features SndFile was built with -if(PC_SNDFILE_FOUND) +# 2024-01-02: Recent versions of libsndfile don't seem to provide a pkgconfig file and older version who did are lacking private libraries like OGG. +if(FALSE) #PC_SNDFILE_FOUND if("vorbis" IN_LIST PC_SNDFILE_STATIC_LIBRARIES) set(SndFile_WITH_EXTERNAL_LIBS TRUE) endif() diff --git a/cmake_admin/Findmpg123.cmake b/cmake_admin/Findmpg123.cmake index 76e041275..3cb351679 100644 --- a/cmake_admin/Findmpg123.cmake +++ b/cmake_admin/Findmpg123.cmake @@ -92,7 +92,7 @@ find_package_handle_standard_args( # Create the targets foreach(_component libmpg123 libout123 libsyn123) if(mpg123_${_component}_FOUND AND NOT TARGET MPG123::${_component}) - add_library(MPG123::${_component}) + add_library(MPG123::${_component} UNKNOWN IMPORTED) set_target_properties( MPG123::${_component} PROPERTIES IMPORTED_LOCATION "${mpg123_${_component}_LIBRARY}" diff --git a/doc/fluidsynth-v20-devdoc.txt b/doc/fluidsynth-v20-devdoc.txt index 8feec2e2e..ed0a7d617 100644 --- a/doc/fluidsynth-v20-devdoc.txt +++ b/doc/fluidsynth-v20-devdoc.txt @@ -8,8 +8,8 @@ \author David Henningsson \author Tom Moebert \author Copyright © 2003-2023 Peter Hanappe, Conrad Berhörster, Antoine Schmitt, Pedro López-Cabanillas, Josh Green, David Henningsson, Tom Moebert -\version Revision 2.3.3 -\date 2023-06-14 +\version Revision 2.3.5 +\date 2024-01-11 All the source code examples in this document are in the public domain; you can use them as you please. This document is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License. To view a copy of this license, visit https://creativecommons.org/licenses/by-sa/3.0/ . The FluidSynth library is distributed under the GNU Lesser General Public License. A copy of the GNU Lesser General Public License is contained in the FluidSynth package; if not, visit https://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt or write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. diff --git a/doc/fluidsynth.1 b/doc/fluidsynth.1 index ad6695104..5140312d1 100644 --- a/doc/fluidsynth.1 +++ b/doc/fluidsynth.1 @@ -13,7 +13,7 @@ .\" along with this program; see the file LICENSE. If not, write to .\" the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. .\" -.TH FluidSynth 1 "Jan 1, 2022" +.TH FluidSynth 1 "Jan 1, 2024" .\" Please update the above date whenever this man page is modified. .\" .\" Some roff macros, for reference: diff --git a/sonar-project.properties b/sonar-project.properties index c1d7eb142..603bc9bad 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -1,8 +1,7 @@ sonar.projectKey=FluidSynth_fluidsynth sonar.organization=fluidsynth -sonar.cfamily.threads=4 -sonar.cfamily.cache.enabled=false +sonar.cfamily.threads=2 # This is the name and version displayed in the SonarCloud UI. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 693fbb58d..c8d5ab3c2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -207,7 +207,7 @@ set ( public_main_HEADER ${FluidSynth_BINARY_DIR}/include/fluidsynth.h ) -configure_file ( ${FluidSynth_SOURCE_DIR}/include/fluidsynth/version.h.in +configure_file ( ${FluidSynth_SOURCE_DIR}/include/fluidsynth/version.h.in ${FluidSynth_BINARY_DIR}/include/fluidsynth/version.h ) configure_file ( ${FluidSynth_SOURCE_DIR}/include/fluidsynth.cmake ${public_main_HEADER} ) @@ -277,6 +277,14 @@ if ( LIBFLUID_CPPFLAGS ) PROPERTIES COMPILE_FLAGS ${LIBFLUID_CPPFLAGS} ) endif ( LIBFLUID_CPPFLAGS ) +# The CMake Xcode generator fails to build the framework unless it references +# a source file. Create an empty one in the build directory to use for this +# purpose. +if ( MACOSX_FRAMEWORK ) + set ( MACOSX_FRAMEWORK_SOURCE_HACK ${CMAKE_BINARY_DIR}/empty_file_for_linking_issue.cpp ) + file ( TOUCH ${MACOSX_FRAMEWORK_SOURCE_HACK} ) +endif ( MACOSX_FRAMEWORK ) + # Note: by default this target creates a shared object (or dll). To build a # static library instead, set the option BUILD_SHARED_LIBS to FALSE. # Further note: The headers must be explicitly added here to have CMake install @@ -285,6 +293,7 @@ add_library ( libfluidsynth $ ${public_main_HEADER} ${public_HEADERS} + ${MACOSX_FRAMEWORK_SOURCE_HACK} ) if ( MACOSX_FRAMEWORK ) @@ -361,7 +370,8 @@ if ( TARGET SndFile::sndfile AND LIBSNDFILE_SUPPORT ) endif() if ( PULSE_SUPPORT ) - target_include_directories( libfluidsynth-OBJ PRIVATE ${PULSEAUDIO_INCLUDE_DIRS} ) + # need to include PULSEAUDIO_INCLUDE_DIR to make it compile with homebrew on Mac + target_include_directories( libfluidsynth-OBJ PRIVATE ${PULSEAUDIO_INCLUDE_DIRS} ${PULSEAUDIO_INCLUDE_DIR} ) target_link_libraries ( libfluidsynth-OBJ PUBLIC ${PULSEAUDIO_LIBRARIES} ) endif() @@ -485,10 +495,6 @@ if ( TARGET PipeWire::PipeWire AND PIPEWIRE_SUPPORT ) # because pw_init() etc. target_link_libraries ( fluidsynth PRIVATE PipeWire::PipeWire ) endif() -if ( TARGET InstPatch::libinstpatch AND LIBINSTPATCH_SUPPORT ) - target_link_libraries ( fluidsynth PRIVATE InstPatch::libinstpatch ) -endif() - if ( TARGET LASH::LASH AND LASH_SUPPORT ) target_link_libraries ( fluidsynth PRIVATE LASH::LASH ) endif() diff --git a/src/fluidsynth.c b/src/fluidsynth.c index 5a1dd6be2..f4fedb582 100644 --- a/src/fluidsynth.c +++ b/src/fluidsynth.c @@ -29,9 +29,6 @@ #define GETOPT_SUPPORT 1 #endif -#ifdef LIBINSTPATCH_SUPPORT -#include -#endif #include "fluid_lash.h" #ifdef SYSTEMD_SUPPORT @@ -1223,7 +1220,7 @@ void print_welcome() { printf("FluidSynth runtime version %s\n" - "Copyright (C) 2000-2023 Peter Hanappe and others.\n" + "Copyright (C) 2000-2024 Peter Hanappe and others.\n" "Distributed under the LGPL license.\n" "SoundFont(R) is a registered trademark of Creative Technology Ltd.\n\n", fluid_version_str()); diff --git a/src/midi/fluid_midi.c b/src/midi/fluid_midi.c index ecc7fe80d..a84e5ea39 100644 --- a/src/midi/fluid_midi.c +++ b/src/midi/fluid_midi.c @@ -1641,6 +1641,23 @@ fluid_player_handle_reset_synth(void *data, const char *name, int value) player->reset_synth_between_songs = value; } +static int check_for_on_notes(fluid_synth_t *synth) +{ + fluid_voice_t* v[1024]; + int i, res=FALSE; + fluid_synth_get_voicelist(synth, v, FLUID_N_ELEMENTS(v), -1); + for(i=0; iend_pedals_disabled) { + if(check_for_on_notes(synth)) + { + FLUID_LOG(FLUID_WARN, "End of the MIDI file reached, but not all notes have received a note off event! OFFing them now! Run with --verbose to spot pending voices."); + } + for(i = 0; i < synth->midi_channels; i++) { fluid_synth_cc(player->synth, i, SUSTAIN_SWITCH, 0); fluid_synth_cc(player->synth, i, SOSTENUTO_SWITCH, 0); + fluid_synth_cc(player->synth, i, ALL_NOTES_OFF, 0); } player->end_pedals_disabled = 1; @@ -2271,6 +2294,7 @@ fluid_player_play(fluid_player_t *player) if(!player->use_system_timer) { fluid_sample_timer_reset(player->synth, player->sample_timer); + player->cur_msec = 0; } /* If we're at the end of the playlist and there are no loops left, loop once */ diff --git a/src/synth/fluid_synth.c b/src/synth/fluid_synth.c index 096f23487..458dc39c2 100644 --- a/src/synth/fluid_synth.c +++ b/src/synth/fluid_synth.c @@ -202,16 +202,16 @@ void fluid_synth_settings(fluid_settings_t *settings) fluid_settings_register_int(settings, "synth.verbose", 0, 0, 1, FLUID_HINT_TOGGLED); fluid_settings_register_int(settings, "synth.reverb.active", 1, 0, 1, FLUID_HINT_TOGGLED); - fluid_settings_register_num(settings, "synth.reverb.room-size", FLUID_REVERB_DEFAULT_ROOMSIZE, 0.0f, 1.0f, 0); - fluid_settings_register_num(settings, "synth.reverb.damp", FLUID_REVERB_DEFAULT_DAMP, 0.0f, 1.0f, 0); - fluid_settings_register_num(settings, "synth.reverb.width", FLUID_REVERB_DEFAULT_WIDTH, 0.0f, 100.0f, 0); - fluid_settings_register_num(settings, "synth.reverb.level", FLUID_REVERB_DEFAULT_LEVEL, 0.0f, 1.0f, 0); + fluid_settings_register_num(settings, "synth.reverb.room-size", FLUID_REVERB_DEFAULT_ROOMSIZE, 0.0, 1.0, 0); + fluid_settings_register_num(settings, "synth.reverb.damp", FLUID_REVERB_DEFAULT_DAMP, 0.0, 1.0, 0); + fluid_settings_register_num(settings, "synth.reverb.width", FLUID_REVERB_DEFAULT_WIDTH, 0.0, 100.0, 0); + fluid_settings_register_num(settings, "synth.reverb.level", FLUID_REVERB_DEFAULT_LEVEL, 0.0, 1.0, 0); fluid_settings_register_int(settings, "synth.chorus.active", 1, 0, 1, FLUID_HINT_TOGGLED); fluid_settings_register_int(settings, "synth.chorus.nr", FLUID_CHORUS_DEFAULT_N, 0, 99, 0); - fluid_settings_register_num(settings, "synth.chorus.level", FLUID_CHORUS_DEFAULT_LEVEL, 0.0f, 10.0f, 0); - fluid_settings_register_num(settings, "synth.chorus.speed", FLUID_CHORUS_DEFAULT_SPEED, 0.1f, 5.0f, 0); - fluid_settings_register_num(settings, "synth.chorus.depth", FLUID_CHORUS_DEFAULT_DEPTH, 0.0f, 256.0f, 0); + fluid_settings_register_num(settings, "synth.chorus.level", FLUID_CHORUS_DEFAULT_LEVEL, 0.0, 10.0, 0); + fluid_settings_register_num(settings, "synth.chorus.speed", FLUID_CHORUS_DEFAULT_SPEED, 0.1, 5.0, 0); + fluid_settings_register_num(settings, "synth.chorus.depth", FLUID_CHORUS_DEFAULT_DEPTH, 0.0, 256.0, 0); fluid_settings_register_int(settings, "synth.ladspa.active", 0, 0, 1, FLUID_HINT_TOGGLED); fluid_settings_register_int(settings, "synth.lock-memory", 1, 0, 1, FLUID_HINT_TOGGLED); @@ -223,12 +223,12 @@ void fluid_synth_settings(fluid_settings_t *settings) fluid_settings_register_int(settings, "synth.polyphony", 256, 1, 65535, 0); fluid_settings_register_int(settings, "synth.midi-channels", 16, 16, 256, 0); - fluid_settings_register_num(settings, "synth.gain", 0.2f, 0.0f, 10.0f, 0); + fluid_settings_register_num(settings, "synth.gain", 0.2, 0.0, 10.0, 0); fluid_settings_register_int(settings, "synth.audio-channels", 1, 1, 128, 0); fluid_settings_register_int(settings, "synth.audio-groups", 1, 1, 128, 0); fluid_settings_register_int(settings, "synth.effects-channels", 2, 2, 2, 0); fluid_settings_register_int(settings, "synth.effects-groups", 1, 1, 128, 0); - fluid_settings_register_num(settings, "synth.sample-rate", 44100.0f, 8000.0f, 96000.0f, 0); + fluid_settings_register_num(settings, "synth.sample-rate", 44100.0, 8000.0, 96000.0, 0); fluid_settings_register_int(settings, "synth.device-id", 0, 0, 127, 0); #ifdef ENABLE_MIXER_THREADS fluid_settings_register_int(settings, "synth.cpu-cores", 1, 1, 256, 0); diff --git a/src/utils/fluid_sys.c b/src/utils/fluid_sys.c index c2594f22f..a09a370f4 100644 --- a/src/utils/fluid_sys.c +++ b/src/utils/fluid_sys.c @@ -1566,12 +1566,12 @@ fluid_server_socket_t * new_fluid_server_socket(int port, fluid_server_func_t func, void *data) { fluid_server_socket_t *server_socket; + struct sockaddr_in addr4; #ifdef IPV6_SUPPORT - struct sockaddr_in6 addr; -#else - struct sockaddr_in addr; + struct sockaddr_in6 addr6; #endif - + const struct sockaddr *addr; + size_t addr_size; fluid_socket_t sock; fluid_return_val_if_fail(func != NULL, NULL); @@ -1581,23 +1581,37 @@ new_fluid_server_socket(int port, fluid_server_func_t func, void *data) return NULL; } + FLUID_MEMSET(&addr4, 0, sizeof(addr4)); + addr4.sin_family = AF_INET; + addr4.sin_port = htons((uint16_t)port); + addr4.sin_addr.s_addr = htonl(INADDR_ANY); + +#ifdef IPV6_SUPPORT + FLUID_MEMSET(&addr6, 0, sizeof(addr6)); + addr6.sin6_family = AF_INET6; + addr6.sin6_port = htons((uint16_t)port); + addr6.sin6_addr = in6addr_any; +#endif + #ifdef IPV6_SUPPORT sock = socket(AF_INET6, SOCK_STREAM, 0); + addr = (const struct sockaddr *) &addr6; + addr_size = sizeof(addr6); if(sock == INVALID_SOCKET) { - FLUID_LOG(FLUID_ERR, "Failed to create server socket: %d", fluid_socket_get_error()); - fluid_socket_cleanup(); - return NULL; + FLUID_LOG(FLUID_WARN, "Failed to create IPv6 server socket: %d (will try with IPv4)", fluid_socket_get_error()); + + sock = socket(AF_INET, SOCK_STREAM, 0); + addr = (const struct sockaddr *) &addr4; + addr_size = sizeof(addr4); } - FLUID_MEMSET(&addr, 0, sizeof(addr)); - addr.sin6_family = AF_INET6; - addr.sin6_port = htons((uint16_t)port); - addr.sin6_addr = in6addr_any; #else - sock = socket(AF_INET, SOCK_STREAM, 0); + addr = (const struct sockaddr *) &addr4; + addr_size = sizeof(addr4); +#endif if(sock == INVALID_SOCKET) { @@ -1606,13 +1620,7 @@ new_fluid_server_socket(int port, fluid_server_func_t func, void *data) return NULL; } - FLUID_MEMSET(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons((uint16_t)port); - addr.sin_addr.s_addr = htonl(INADDR_ANY); -#endif - - if(bind(sock, (const struct sockaddr *) &addr, sizeof(addr)) == SOCKET_ERROR) + if(bind(sock, addr, addr_size) == SOCKET_ERROR) { FLUID_LOG(FLUID_ERR, "Failed to bind server socket: %d", fluid_socket_get_error()); fluid_socket_close(sock);