Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package fluidsynth for openSUSE:Factory 
checked in at 2026-04-21 12:41:55
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/fluidsynth (Old)
 and      /work/SRC/openSUSE:Factory/.fluidsynth.new.11940 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "fluidsynth"

Tue Apr 21 12:41:55 2026 rev:88 rq:1348263 version:2.5.4

Changes:
--------
--- /work/SRC/openSUSE:Factory/fluidsynth/fluidsynth.changes    2026-02-27 
17:04:40.687112132 +0100
+++ /work/SRC/openSUSE:Factory/.fluidsynth.new.11940/fluidsynth.changes 
2026-04-21 12:42:12.467913893 +0200
@@ -1,0 +2,8 @@
+Sun Apr 19 09:58:29 UTC 2026 - Martin Hauke <[email protected]>
+
+- Update to version 2.5.4
+  * The TCP port, fluidsynth's shell server may listen to, is now
+    auto-selected by default.
+  * The systemd lock-file /run/lock/fluidsynth has been removed.
+
+-------------------------------------------------------------------

Old:
----
  fluidsynth-2.5.3.tar.gz

New:
----
  fluidsynth-2.5.4.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ fluidsynth.spec ++++++
--- /var/tmp/diff_new_pack.dbTgSc/_old  2026-04-21 12:42:13.195944141 +0200
+++ /var/tmp/diff_new_pack.dbTgSc/_new  2026-04-21 12:42:13.195944141 +0200
@@ -20,7 +20,7 @@
 
 %define sover   3
 Name:           fluidsynth
-Version:        2.5.3
+Version:        2.5.4
 Release:        0
 Summary:        A Real-Time Software Synthesizer That Uses Soundfont(tm)
 License:        LGPL-2.1-or-later

++++++ fluidsynth-2.5.3.tar.gz -> fluidsynth-2.5.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fluidsynth-2.5.3/.github/workflows/ios.yml 
new/fluidsynth-2.5.4/.github/workflows/ios.yml
--- old/fluidsynth-2.5.3/.github/workflows/ios.yml      2026-02-21 
12:49:48.000000000 +0100
+++ new/fluidsynth-2.5.4/.github/workflows/ios.yml      2026-04-18 
16:43:33.000000000 +0200
@@ -12,8 +12,8 @@
       - '.github/workflows/sonarcloud.yml'
       - '.cirrus.yml'
       - 'README.md'
-  release:
-    types: [published]
+    tags:
+      - 'v*'
 
 env:
   # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
@@ -46,8 +46,8 @@
       shell: bash
       id: artifact_name
       run: |
-        if [[ "${{ github.event_name }}" == "release" ]]; then
-          echo "name=fluidsynth-${{ github.event.release.tag_name }}" >> 
$GITHUB_OUTPUT
+        if [[ "${{ github.ref_type }}" == "tag" ]]; then
+          echo "name=fluidsynth-${{ github.ref_name }}" >> $GITHUB_OUTPUT
         else
           echo "name=fluidsynth-${{ github.run_id }}" >> $GITHUB_OUTPUT
         fi
@@ -57,7 +57,7 @@
         ls -la publish
 
     - name: Upload Artifacts
-      uses: actions/upload-artifact@v6
+      uses: actions/upload-artifact@v7
       with:
         name: ${{ steps.artifact_name.outputs.name }}-iOS
         path: publish/
@@ -66,28 +66,32 @@
 
   # Publish artifacts to GitHub releases (only on release events)
   publish-release-ios:
-    if: github.event_name == 'release' && github.event.action == 'published'
+    if: github.ref_type == 'tag'
     needs:
       - ios-build
     runs-on: ubuntu-latest
     name: 🚀 Publish Release Artifacts
     steps:
+    - uses: actions/checkout@v6
+      with:
+        submodules: recursive
+
     - name: Download all artifacts
-      uses: actions/download-artifact@v7
+      uses: actions/download-artifact@v8
       with:
         path: ${{ needs.ios-build.outputs.artifact_name }}-iOS
         pattern: ${{ needs.ios-build.outputs.artifact_name }}-iOS
         merge-multiple: false
-        
+
     - name: Create release archives
       run: |
         ls -la
         zip -r "${{ needs.ios-build.outputs.artifact_name }}-iOS.zip" "${{ 
needs.ios-build.outputs.artifact_name }}-iOS"
 
-    - name: Upload release assets
-      uses: softprops/action-gh-release@v2
-      with:
-        files: |
-          *.zip
+    - name: Upload assets to matching Release (draft or published)
       env:
         GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+      run: |
+        set -euo pipefail
+        tag="${GITHUB_REF_NAME}"
+        gh release upload "$tag" *.zip --clobber
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fluidsynth-2.5.3/.github/workflows/solaris.yml 
new/fluidsynth-2.5.4/.github/workflows/solaris.yml
--- old/fluidsynth-2.5.3/.github/workflows/solaris.yml  2026-02-21 
12:49:48.000000000 +0100
+++ new/fluidsynth-2.5.4/.github/workflows/solaris.yml  2026-04-18 
16:43:33.000000000 +0200
@@ -34,7 +34,7 @@
             submodules: true
 
         - name: Build & test
-          uses: vmactions/[email protected]
+          uses: vmactions/[email protected]
           with:
             envs: 'CFLAGS_SOLARIS_CC'
             usesh: true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fluidsynth-2.5.3/.github/workflows/windows.yml 
new/fluidsynth-2.5.4/.github/workflows/windows.yml
--- old/fluidsynth-2.5.3/.github/workflows/windows.yml  2026-02-21 
12:49:48.000000000 +0100
+++ new/fluidsynth-2.5.4/.github/workflows/windows.yml  2026-04-18 
16:43:33.000000000 +0200
@@ -13,8 +13,8 @@
       - '.github/workflows/ios.yml'
       - '.cirrus.yml'
       - 'README.md'
-  release:
-    types: [published]
+    tags:
+      - 'v*'
 
 env:
   BUILD_TYPE: RelWithDebInfo
@@ -188,14 +188,14 @@
       shell: bash
       id: artifact_name
       run: |
-        if [[ "${{ github.event_name }}" == "release" ]]; then
-          echo "name=fluidsynth-${{ github.event.release.tag_name }}" >> 
$GITHUB_OUTPUT
+        if [[ "${{ github.ref_type }}" == "tag" ]]; then
+          echo "name=fluidsynth-${{ github.ref_name }}" >> $GITHUB_OUTPUT
         else
           echo "name=fluidsynth-${{ github.run_id }}" >> $GITHUB_OUTPUT
         fi
 
     - name: Upload Artifacts
-      uses: actions/upload-artifact@v6
+      uses: actions/upload-artifact@v7
       with:
         name: ${{ steps.artifact_name.outputs.name }}-win10-${{ 
matrix.platformAlt }}-${{ matrix.osal }}
         path: ${{ env.INSTALL_LOCATION }}
@@ -478,7 +478,7 @@
         fi
 
     - name: Upload Artifacts
-      uses: actions/upload-artifact@v6
+      uses: actions/upload-artifact@v7
       with:
         name: CI-${{ github.run_id }}-mingw-${{ matrix.artifactPrefix }}-${{ 
matrix.platform }}
         path: ${{ env.INSTALL_LOCATION }}
@@ -550,7 +550,7 @@
         fi
 
     - name: '${{ matrix.icon }} Upload Artifacts'
-      uses: actions/upload-artifact@v6
+      uses: actions/upload-artifact@v7
       with:
         name: CI-${{ github.run_id }}-msys2-${{matrix.sys}}-${{matrix.osal}}
         path: ${{env.INSTALL_LOCATION}}
@@ -566,7 +566,7 @@
     name: 🧪 Acceptance Test
     steps:
     - name: Download all artifacts
-      uses: actions/download-artifact@v7
+      uses: actions/download-artifact@v8
       with:
         path: artifacts
         pattern: fluidsynth-*
@@ -584,15 +584,19 @@
 
   # Publish artifacts to GitHub releases (only on release events)
   publish-release:
-    if: github.event_name == 'release' && github.event.action == 'published'
+    if: github.ref_type == 'tag'
     needs:
       - acceptance-test
       - msvc-build
     runs-on: ubuntu-latest
     name: 🚀 Publish Release Artifacts
     steps:
+    - uses: actions/checkout@v6
+      with:
+        submodules: recursive
+
     - name: Download all artifacts
-      uses: actions/download-artifact@v7
+      uses: actions/download-artifact@v8
       with:
         path: artifacts
         pattern: fluidsynth-*
@@ -608,17 +612,17 @@
         done
         ls -la *.zip
 
-    - name: Upload release assets
-      uses: softprops/action-gh-release@v2
-      with:
-        files: |
-          artifacts/*.zip
+    - name: Upload assets to matching Release (draft or published)
       env:
         GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+      run: |
+        set -euo pipefail
+        tag="${GITHUB_REF_NAME}"
+        gh release upload "$tag" artifacts/*.zip --clobber
 
   # Create announcement PR in website repository  
   announce-release:
-    if: github.event_name == 'release' && github.event.action == 'published'
+    if: github.ref_type == 'tag'
     needs: [publish-release]
     runs-on: ubuntu-22.04
     name: 📢 Announce Release
@@ -630,8 +634,7 @@
       - name: Generate HTML Release Announcement
         run: |
           set -e
-          TAG_NAME="${{ github.event.release.tag_name }}"
-          RELEASE_NAME="${{ github.event.release.name }}"
+          TAG_NAME="${{ github.ref_name }}"
           VERSION="${TAG_NAME#v}"
           DATE="$(date +%Y-%m-%d)"
           FILENAME="${DATE}-released-fluidsynth-${VERSION//./-}.md"
@@ -656,6 +659,6 @@
           target-folder: _posts/
           token: ${{ secrets.DEPLOY_API_TOKEN_NEW }}
           clean: false
-          commit-message: Announce FluidSynth ${{ 
github.event.release.tag_name }}
+          commit-message: Announce FluidSynth ${{ github.ref_name }}
           git-config-name: Fluid Release Announcer
           git-config-email: [email protected]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fluidsynth-2.5.3/.gitignore 
new/fluidsynth-2.5.4/.gitignore
--- old/fluidsynth-2.5.3/.gitignore     2026-02-21 12:49:48.000000000 +0100
+++ new/fluidsynth-2.5.4/.gitignore     2026-04-18 16:43:33.000000000 +0200
@@ -42,3 +42,5 @@
 *.pro.user*
 *.user
 *.vscode
+_codeql_build_dir/
+_codeql_detected_source_root
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fluidsynth-2.5.3/CMakeLists.txt 
new/fluidsynth-2.5.4/CMakeLists.txt
--- old/fluidsynth-2.5.3/CMakeLists.txt 2026-02-21 12:49:48.000000000 +0100
+++ new/fluidsynth-2.5.4/CMakeLists.txt 2026-04-18 16:43:33.000000000 +0200
@@ -47,7 +47,7 @@
 # FluidSynth package version
 set ( FLUIDSYNTH_VERSION_MAJOR 2 )
 set ( FLUIDSYNTH_VERSION_MINOR 5 )
-set ( FLUIDSYNTH_VERSION_MICRO 3 )
+set ( FLUIDSYNTH_VERSION_MICRO 4 )
 set ( VERSION 
"${FLUIDSYNTH_VERSION_MAJOR}.${FLUIDSYNTH_VERSION_MINOR}.${FLUIDSYNTH_VERSION_MICRO}"
 )
 set ( FLUIDSYNTH_VERSION ${VERSION} )
 
@@ -62,7 +62,7 @@
 # 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 5 )
-set ( LIB_VERSION_REVISION 2 )
+set ( LIB_VERSION_REVISION 3 )
 set ( LIB_VERSION_INFO
       "${LIB_VERSION_CURRENT}.${LIB_VERSION_AGE}.${LIB_VERSION_REVISION}" )
 
@@ -974,9 +974,6 @@
         configure_file ( fluidsynth.service.in
         ${FluidSynth_BINARY_DIR}/fluidsynth.service @ONLY )
 
-        configure_file ( fluidsynth.tmpfiles.in
-        ${FluidSynth_BINARY_DIR}/fluidsynth.tmpfiles @ONLY )
-
         configure_file ( fluidsynth.conf.in
         ${FluidSynth_BINARY_DIR}/fluidsynth.conf @ONLY )
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fluidsynth-2.5.3/contrib/fluidsynth.spec 
new/fluidsynth-2.5.4/contrib/fluidsynth.spec
--- old/fluidsynth-2.5.3/contrib/fluidsynth.spec        2026-02-21 
12:49:48.000000000 +0100
+++ new/fluidsynth-2.5.4/contrib/fluidsynth.spec        2026-04-18 
16:43:33.000000000 +0200
@@ -97,7 +97,6 @@
 # manually install systemd files
 install -Dm 644 build/fluidsynth.conf 
%{buildroot}%{_fillupdir}/sysconfig.%{name}
 install -Dm 644 build/fluidsynth.service 
%{buildroot}%{_unitdir}/%{name}.service
-install -Dm 644 build/fluidsynth.tmpfiles 
%{buildroot}%{_tmpfilesdir}/%{name}.conf
 install -d %{buildroot}%{_sbindir}
 ln -s %{_sbindir}/service %{buildroot}%{_sbindir}/rc%{name}
 
@@ -128,7 +127,6 @@
 %{_unitdir}/%{name}.service
 %{_sbindir}/rc%{name}
 %{_fillupdir}/sysconfig.%{name}
-%{_tmpfilesdir}/%{name}.conf
 %endif
 
 %files devel
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fluidsynth-2.5.3/doc/fluidsettings.xml 
new/fluidsynth-2.5.4/doc/fluidsettings.xml
--- old/fluidsynth-2.5.3/doc/fluidsettings.xml  2026-02-21 12:49:48.000000000 
+0100
+++ new/fluidsynth-2.5.4/doc/fluidsettings.xml  2026-04-18 16:43:33.000000000 
+0200
@@ -888,11 +888,10 @@
         <setting>
             <name>port</name>
             <type>int</type>
-            <def>9800</def>
-            <min>1</min>
+            <def>0</def>
+            <min>0</min>
             <max>65535</max>
-            <desc>The shell can be used in a client/server mode. This setting 
controls what TCP/IP port the server uses.</desc>
+            <desc>The shell can be used in a client/server mode. This setting 
controls what TCP/IP port the server uses. Since fluidsynth 2.5.4, a value of 0 
enables auto mode and selects the first free port, probing from 9800 upwards. 
Older versions used 9800 as default port. Note that when set to 0, fluidsynth 
will update the setting during server creation (new_fluid_server2()) with the 
actual port number used.</desc>
         </setting>
     </shell>
 </fluidsettings>
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fluidsynth-2.5.3/doc/fluidsynth-v20-devdoc.txt 
new/fluidsynth-2.5.4/doc/fluidsynth-v20-devdoc.txt
--- old/fluidsynth-2.5.3/doc/fluidsynth-v20-devdoc.txt  2026-02-21 
12:49:48.000000000 +0100
+++ new/fluidsynth-2.5.4/doc/fluidsynth-v20-devdoc.txt  2026-04-18 
16:43:33.000000000 +0200
@@ -8,8 +8,8 @@
 \author David Henningsson
 \author Tom Moebert
 \author Copyright &copy; 2003-2026 Peter Hanappe, Conrad Berhörster, Antoine 
Schmitt, Pedro López-Cabanillas, Josh Green, David Henningsson, Tom Moebert
-\version Revision 2.5.3
-\date 2026-02-21
+\version Revision 2.5.4
+\date 2026-04-18
 
 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.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fluidsynth-2.5.3/doc/recent_changes.txt 
new/fluidsynth-2.5.4/doc/recent_changes.txt
--- old/fluidsynth-2.5.3/doc/recent_changes.txt 2026-02-21 12:49:48.000000000 
+0100
+++ new/fluidsynth-2.5.4/doc/recent_changes.txt 2026-04-18 16:43:33.000000000 
+0200
@@ -1,6 +1,9 @@
 /*!
 
 \page RecentChanges Recent Changes
+\section NewIn2_5_4 What's new in 2.5.4?
+- By default, fluidsynth now auto selects the TCP port for the shell server, 
see \setting{shell_port}
+
 \section NewIn2_5_0 What's new in 2.5.0?
 - #FLUID_MOD_SIN is now deprecated, use the newly added 
fluid_mod_set_custom_mapping()
 - A new mode for the custom IIR filter has been added: #FLUID_IIR_BEANLAND
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fluidsynth-2.5.3/fluidsynth.service.in 
new/fluidsynth-2.5.4/fluidsynth.service.in
--- old/fluidsynth-2.5.3/fluidsynth.service.in  2026-02-21 12:49:48.000000000 
+0100
+++ new/fluidsynth-2.5.4/fluidsynth.service.in  2026-04-18 16:43:33.000000000 
+0200
@@ -4,8 +4,6 @@
 After=sound.target
 After=pipewire.service pulseaudio.service
 Wants=pipewire.service pulseaudio.service
-# If you need more than one instance, use `systemctl edit` to override this:
-ConditionPathExists=!/run/lock/fluidsynth/fluidsynth.lock
 ConditionUser=!@system
 
 [Service]
@@ -27,9 +25,6 @@
 EnvironmentFile=@FLUID_DAEMON_ENV_FILE@
 EnvironmentFile=-%h/.config/fluidsynth
 ExecStart=@CMAKE_INSTALL_FULL_BINDIR@/fluidsynth -is $OTHER_OPTS 
"${SOUND_FONT}"
-ExecStartPre=touch /run/lock/fluidsynth/fluidsynth.lock
-ExecStopPost=rm -f /run/lock/fluidsynth/fluidsynth.lock
 
 [Install]
 WantedBy=default.target
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fluidsynth-2.5.3/fluidsynth.tmpfiles.in 
new/fluidsynth-2.5.4/fluidsynth.tmpfiles.in
--- old/fluidsynth-2.5.3/fluidsynth.tmpfiles.in 2026-02-21 12:49:48.000000000 
+0100
+++ new/fluidsynth-2.5.4/fluidsynth.tmpfiles.in 1970-01-01 01:00:00.000000000 
+0100
@@ -1 +0,0 @@
-d /run/lock/fluidsynth 0777 root root
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fluidsynth-2.5.3/include/fluidsynth/shell.h 
new/fluidsynth-2.5.4/include/fluidsynth/shell.h
--- old/fluidsynth-2.5.3/include/fluidsynth/shell.h     2026-02-21 
12:49:48.000000000 +0100
+++ new/fluidsynth-2.5.4/include/fluidsynth/shell.h     2026-04-18 
16:43:33.000000000 +0200
@@ -114,9 +114,10 @@
  *
  * TCP socket server for a command handler.
  *
- * The socket server will open the TCP port set by \ref settings_shell_port 
- * (default 9800) and starts a new thread and \ref command_handler for each 
- * incoming connection.
+ * The socket server will open the TCP port set by \ref settings_shell_port
+ * (default 9800). If the setting is 0, the first free port is selected
+ * automatically, probing from 9800 upwards. The server starts a new thread and
+ * \ref command_handler for each incoming connection.
  *
  * @note The server is only available if libfluidsynth has been compiled
  * with network support (enable-network). Without network support, all related
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fluidsynth-2.5.3/src/bindings/fluid_cmd.c 
new/fluidsynth-2.5.4/src/bindings/fluid_cmd.c
--- old/fluidsynth-2.5.3/src/bindings/fluid_cmd.c       2026-02-21 
12:49:48.000000000 +0100
+++ new/fluidsynth-2.5.4/src/bindings/fluid_cmd.c       2026-04-18 
16:43:33.000000000 +0200
@@ -67,7 +67,7 @@
 void fluid_shell_settings(fluid_settings_t *settings)
 {
     fluid_settings_register_str(settings, "shell.prompt", "", 0);
-    fluid_settings_register_int(settings, "shell.port", 9800, 1, 65535, 0);
+    fluid_settings_register_int(settings, "shell.port", 0, 0, 65535, 0);
 }
 
 
@@ -4482,6 +4482,17 @@
         return NULL;
     }
 
+    if(port == 0)
+    {
+        int selected_port = fluid_server_socket_get_port(server->socket);
+
+        if(selected_port != FLUID_FAILED)
+        {
+            fluid_settings_setint(settings, "shell.port", selected_port);
+            FLUID_LOG(FLUID_INFO, "shell.port=0, using automatically selected 
port %d", selected_port);
+        }
+    }
+
     return server;
 #else
     FLUID_LOG(FLUID_WARN, "Network support disabled on this platform.");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fluidsynth-2.5.3/src/utils/fluid_sys.c 
new/fluidsynth-2.5.4/src/utils/fluid_sys.c
--- old/fluidsynth-2.5.3/src/utils/fluid_sys.c  2026-02-21 12:49:48.000000000 
+0100
+++ new/fluidsynth-2.5.4/src/utils/fluid_sys.c  2026-04-18 16:43:33.000000000 
+0200
@@ -70,6 +70,7 @@
 struct _fluid_server_socket_t
 {
     fluid_socket_t socket;
+    int port;
     fluid_thread_t *thread;
     int cont;
     fluid_server_func_t func;
@@ -1333,6 +1334,12 @@
     return fluid_thread_join(server_socket->thread);
 }
 
+int fluid_server_socket_get_port(fluid_server_socket_t *server_socket)
+{
+    fluid_return_val_if_fail(server_socket != NULL, FLUID_FAILED);
+    return server_socket->port;
+}
+
 static int fluid_socket_init(void)
 {
 #ifdef _WIN32
@@ -1380,10 +1387,13 @@
 {
     if(sock != INVALID_SOCKET)
     {
+        /* Trigger any pending blocking I/O (e.g. accept()) before closing. */
 #ifdef _WIN32
+        shutdown(sock, SD_BOTH);
         closesocket(sock);
 
 #else
+        shutdown(sock, SHUT_RDWR);
         close(sock);
 #endif
     }
@@ -1469,6 +1479,9 @@
     const struct sockaddr *addr;
     size_t addr_size;
     fluid_socket_t sock;
+    int current_port = port;
+    int auto_port = (port == 0);
+    int bind_error;
 
     fluid_return_val_if_fail(func != NULL, NULL);
 
@@ -1479,16 +1492,19 @@
 
     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
 
+    if(auto_port)
+    {
+        current_port = FLUID_SHELL_AUTO_PORT_START;
+    }
+
 #ifdef IPV6_SUPPORT
     sock = socket(AF_INET6, SOCK_STREAM, 0);
     addr = (const struct sockaddr *) &addr6;
@@ -1516,12 +1532,49 @@
         return NULL;
     }
     
-    if(bind(sock, addr, (int) addr_size) == SOCKET_ERROR)
+    while(1)
     {
-        FLUID_LOG(FLUID_ERR, "Got error %d while trying to bind server 
socket", fluid_socket_get_error());
-        fluid_socket_close(sock);
-        fluid_socket_cleanup();
-        return NULL;
+        addr4.sin_port = htons((uint16_t) current_port);
+#ifdef IPV6_SUPPORT
+        addr6.sin6_port = htons((uint16_t) current_port);
+#endif
+        if(bind(sock, addr, (int) addr_size) == 0)
+        {
+            break;
+        }
+
+        bind_error = fluid_socket_get_error();
+
+        if(!auto_port)
+        {
+            FLUID_LOG(FLUID_ERR, "Got error %d while trying to bind server 
socket", bind_error);
+            fluid_socket_close(sock);
+            fluid_socket_cleanup();
+            return NULL;
+        }
+
+#if defined(_WIN32)
+        if(bind_error != WSAEADDRINUSE)
+#else
+        if(bind_error != EADDRINUSE)
+#endif
+        {
+            FLUID_LOG(FLUID_ERR, "Got error %d while trying to bind server 
socket", bind_error);
+            fluid_socket_close(sock);
+            fluid_socket_cleanup();
+            return NULL;
+        }
+
+        if(current_port == FLUID_TCP_PORT_MAX)
+        {
+            FLUID_LOG(FLUID_ERR, "No free TCP port available for shell server 
auto mode (starting at %d)",
+                      FLUID_SHELL_AUTO_PORT_START);
+            fluid_socket_close(sock);
+            fluid_socket_cleanup();
+            return NULL;
+        }
+
+        current_port++;
     }
 
     if(listen(sock, SOMAXCONN) == SOCKET_ERROR)
@@ -1543,6 +1596,7 @@
     }
 
     server_socket->socket = sock;
+    server_socket->port = current_port;
     server_socket->func = func;
     server_socket->data = data;
     server_socket->cont = 1;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fluidsynth-2.5.3/src/utils/fluid_sys.h 
new/fluidsynth-2.5.4/src/utils/fluid_sys.h
--- old/fluidsynth-2.5.3/src/utils/fluid_sys.h  2026-02-21 12:49:48.000000000 
+0100
+++ new/fluidsynth-2.5.4/src/utils/fluid_sys.h  2026-04-18 16:43:33.000000000 
+0200
@@ -285,6 +285,9 @@
 
 /* Sockets and I/O */
 
+#define FLUID_SHELL_AUTO_PORT_START             9800
+#define FLUID_TCP_PORT_MAX                      65535
+
 int fluid_istream_readline(fluid_istream_t in, fluid_ostream_t out, char 
*prompt, char *buf, int len);
 int fluid_ostream_printf(fluid_ostream_t out, const char *format, ...);
 
@@ -302,6 +305,7 @@
 fluid_server_socket_t *new_fluid_server_socket(int port, fluid_server_func_t 
func, void *data);
 void delete_fluid_server_socket(fluid_server_socket_t *sock);
 int fluid_server_socket_join(fluid_server_socket_t *sock);
+int fluid_server_socket_get_port(fluid_server_socket_t *sock);
 void fluid_socket_close(fluid_socket_t sock);
 fluid_istream_t fluid_socket_get_istream(fluid_socket_t sock);
 fluid_ostream_t fluid_socket_get_ostream(fluid_socket_t sock);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fluidsynth-2.5.3/test/CMakeLists.txt 
new/fluidsynth-2.5.4/test/CMakeLists.txt
--- old/fluidsynth-2.5.3/test/CMakeLists.txt    2026-02-21 12:49:48.000000000 
+0100
+++ new/fluidsynth-2.5.4/test/CMakeLists.txt    2026-04-18 16:43:33.000000000 
+0200
@@ -35,6 +35,7 @@
 ADD_FLUID_TEST(test_default_mod)
 ADD_FLUID_TEST(test_ABI)
 ADD_FLUID_TEST(test_file_seek_tell)
+ADD_FLUID_TEST(test_shell_server_auto_port)
 
 if ( GLIB_SUPPORT AND GLib2_VERSION VERSION_GREATER_EQUAL 2.33.12 )
     # Earlier versions of GLib had broken comment handling and should not be 
compared to
@@ -390,4 +391,3 @@
 add_dependencies(check_manual renderBankSelect)
 add_dependencies(check_manual renderDMOD)
 add_dependencies(check_manual renderRPN)
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fluidsynth-2.5.3/test/test_shell_server_auto_port.c 
new/fluidsynth-2.5.4/test/test_shell_server_auto_port.c
--- old/fluidsynth-2.5.3/test/test_shell_server_auto_port.c     1970-01-01 
01:00:00.000000000 +0100
+++ new/fluidsynth-2.5.4/test/test_shell_server_auto_port.c     2026-04-18 
16:43:33.000000000 +0200
@@ -0,0 +1,60 @@
+#include "test.h"
+#include "fluidsynth.h"
+#include "fluid_sys.h"
+
+void test_server_creation(fluid_settings_t* settings1, fluid_settings_t* 
settings2)
+{
+    fluid_server_t *server1, *server2;
+    int port1, port2;
+
+    server1 = new_fluid_server2(settings1, NULL, NULL, NULL);
+    TEST_ASSERT(server1 != NULL);
+    TEST_SUCCESS(fluid_settings_getint(settings1, "shell.port", &port1));
+    TEST_ASSERT(port1 >= FLUID_SHELL_AUTO_PORT_START && port1 <= 
FLUID_TCP_PORT_MAX);
+
+    server2 = new_fluid_server2(settings2, NULL, NULL, NULL);
+    TEST_ASSERT(server2 != NULL);
+    TEST_SUCCESS(fluid_settings_getint(settings2, "shell.port", &port2));
+    TEST_ASSERT(port2 >= FLUID_SHELL_AUTO_PORT_START && port2 <= 
FLUID_TCP_PORT_MAX);
+    TEST_ASSERT(port1 != port2);
+
+    delete_fluid_server(server2);
+    delete_fluid_server(server1);
+}
+
+int main(void)
+{
+#ifdef NETWORK_SUPPORT
+    fluid_settings_t *settings1, *settings2;
+    fluid_server_t *server1, *server2;
+
+    settings1 = new_fluid_settings();
+    settings2 = new_fluid_settings();
+    TEST_ASSERT(settings1 != NULL);
+    TEST_ASSERT(settings2 != NULL);
+
+    // by default, auto-port probing should be enabled
+    test_server_creation(settings1, settings2);
+
+    TEST_SUCCESS(fluid_settings_setint(settings1, "shell.port", 0));
+    TEST_SUCCESS(fluid_settings_setint(settings2, "shell.port", 0));
+
+    // re-test by explicitly setting port to zero, should still work
+    test_server_creation(settings1, settings2);
+
+    TEST_SUCCESS(fluid_settings_setint(settings1, "shell.port", 12345));
+    TEST_SUCCESS(fluid_settings_setint(settings2, "shell.port", 12345));
+
+    server1 = new_fluid_server2(settings1, NULL, NULL, NULL);
+    TEST_ASSERT(server1 != NULL);
+    server2 = new_fluid_server2(settings2, NULL, NULL, NULL);
+    TEST_ASSERT(server2 == NULL); // should fail since port 12345 is already 
in use by server1
+
+    delete_fluid_server(server2);
+    delete_fluid_server(server1);
+    delete_fluid_settings(settings2);
+    delete_fluid_settings(settings1);
+#endif
+
+    return EXIT_SUCCESS;
+}

Reply via email to