Index | Thread | Search

From:
Chris Billington <cbillington@emulti.net>
Subject:
Re: Attempting new port: ctune Internet Radio player
To:
Stuart Henderson <stu@spacehopper.org>
Cc:
ports@openbsd.org, George Koehler <kernigh@gmail.com>
Date:
Tue, 10 Dec 2024 16:06:53 +0800

Download raw body.

Thread
On Mon, 9 Dec 2024 23:43:12 +0000
Stuart Henderson <stu@spacehopper.org> wrote:

> On 2024/12/08 13:36, Chris Billington wrote:
> > I am attempting to make a port of ctune [https://github.com/An7ar35/ctune], an nCurses Internet Radio player written in C.
> > 
> > This seems to be worthwhile, because audio/gradio and audio/curseradio are both currently nonfunctional due to API changes in underlying libraries, and are based on inactive projects.
> > 
> > I tested ctune on a Linux install and it seems to be both functional, low-resource and fast. It also includes support for sndio output.
> > 
> > First steps, getting the program to build, having solved a few type errors I have run into the following issue:
> > 
> > [ 23%] Building C object plugins/output/pulseaudio/CMakeFiles/ctune_plugin_pulseaudio.dir/__/__/__/src/datastructure/CircularBuffer.c.o
> > cd /home/chris/Downloads/build/ctune/plugins/output/pulseaudio && /usr/bin/cc -Dctune_plugin_pulseaudio_EXPORTS -I/home/chris/Downloads/build/ctune/libraries -I/usr/local/include -I/home/chris/Downloads/build/ctune/generated-src -Wextra -O2 -std=gnu99 -fPIC -MD -MT plugins/output/pulseaudio/CMakeFiles/ctune_plugin_pulseaudio.dir/__/__/__/src/datastructure/CircularBuffer.c.o -MF CMakeFiles/ctune_plugin_pulseaudio.dir/__/__/__/src/datastructure/CircularBuffer.c.o.d -o CMakeFiles/ctune_plugin_pulseaudio.dir/__/__/__/src/datastructure/CircularBuffer.c.o -c /home/chris/Downloads/build/ctune/src/datastructure/CircularBuffer.c
> > /home/chris/Downloads/build/ctune/src/datastructure/CircularBuffer.c:36:17: warning: call to undeclared function 'syscall'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
> >     long fd   = syscall( __NR_memfd_create, name, flags );
> >                 ^
> > /home/chris/Downloads/build/ctune/src/datastructure/CircularBuffer.c:36:26: error: use of undeclared identifier '__NR_memfd_create'
> >     long fd   = syscall( __NR_memfd_create, name, flags );
> >                          ^
> > 1 warning and 1 error generated.
> > *** Error 1 in . (plugins/output/pulseaudio/CMakeFiles/ctune_plugin_pulseaudio.dir/build.make:107 'plugins/output/pulseaudio/CMakeFiles/ctune_plugin_pulseaudio.dir/__/__/__/src/datastructure/CircularBuffer.c.o')
> > *** Error 2 in . (CMakeFiles/Makefile2:504 'plugins/output/pulseaudio/CMakeFiles/ctune_plugin_pulseaudio.dir/all')
> > *** Error 2 in /home/chris/Downloads/build/ctune (Makefile:139 'all')
> > 
> > Pulseaudio is installed on my machine because other progams I run require it .
> > 
> > The relevant lines of the file causing the above issue are:
> > 
> > (src/datastructure/CircularBuffer.c)
> > 
> > #include "CircularBuffer.h"
> > 
> > #include <errno.h>
> > #include <string.h>
> > #include <limits.h>
> > #include <sys/mman.h>
> > #include <sys/syscall.h>
> > #include <unistd.h>
> > 
> > #include "logger/src/Logger.h"
> > 
> > /**
> >  * [PRIVATE] Gets a string representation of the error enum val for pthread returns
> >  * @param i Error enum integer val
> >  * @return String
> >  */
> > static const char * CircularBuffer_getPThreadErrStr( int i ) {
> >     switch( i ) {
> >         case 0      : return "OK";
> >         case EINVAL : return "EINVAL";
> >         case EBUSY  : return "EBUSY";
> >         case EAGAIN : return "EAGAIN";
> >         case EDEADLK: return "EDEADLK";
> >         case EPERM  : return "EPERM";
> >         default     : return "UNKNOWN";
> >     }
> > }
> > 
> > /**
> >  * [PRIVATE] Gets a file descriptor for an anonymous file residing in memory (replica of https://man7.org/>
> >  * @param name  Name of file
> >  * @param flags Flags
> >  * @return File descriptor (-1 or error)
> >  */
> > static int CircularBuffer_memfd_create( const char * name, unsigned int flags ) {
> >     long fd   = syscall( __NR_memfd_create, name, flags );
> >     int  cast = 0;
> > 
> >     if( fd >= 0 ) {
> >         if( fd <= INT_MAX ) {
> >             cast = (int) fd;
> > 
> >         } else {
> >             CTUNE_LOG( CTUNE_LOG_ERROR,
> >                        "[CircularBuffer_memfd_create( \"%s\", %d )] Failed cast long->int (%ld)",
> >                        name, flags, fd
> >             );
> > 
> >             cast = -1;
> >         }
> >     }
> > 
> >     return cast;
> > }
> > 
> > 
> > Can anyone offer some assistance in resolving this 'undeclared function' issue please? 
> 
> As it has sndio support anyway, we don't want to build pulseaudio
> support anyway (nor the other plugins really). However this
> CircularBuffer data structure is also used in src/ui/EventQueue.c which
> looks more of a core thing so I think it will still need an alternative
> - try gkoehler's suggestion for that.
> 
> To disable - there doesn't seem to be a cmake flag you can use in
> CONFIGURE_ARGS to disable these but you can patch CMakeLists.txt - in
> the ports framework, extract the files (I usually type "make patch"
> for this, even if there aren't any yet), "cd `make show=WRKSRC`", "cp
> CMakeLists.txt CMakeLists.txt.orig.port", edit CMakeLists.txt, "cd -",
> "make update-patches"
> 
> Looking lower in cmakelists we have
> 
> target_link_libraries(ctune PRIVATE
>         ctune_logger            #CTUNE_LOG(..)
>         ${JSONC_LIBRARIES}      #(json-c/*.h) for `parse/JSON.c`
>         ${NCURSES_LIBRARIES}    #(ncurses.h) for `ui/*`
>         ${CURSES_LIBRARIES}     #(ncurses.h) for `ui/*`
>         panel                   #(panel.h) ncurses panel lib for `ui/*`
>         form                    #(form.h) ncurses form lib for `ui/*`
>         pthread                 #threading
>         OpenSSL::SSL            #(openssl/*.h) for `network/NetworkUtils.c`
>         OpenSSL::Crypto         #(openssl/*.h) for `network/NetworkUtils.c`
>         m                       #(math.h) for `utils/utilities.c`
>         uuid                    #(uuid/uuid.h) for `utils/utilities.c`
>         curl                    #(curl/curl.h) for `network/NetworkUtils.c`
>         dl                      #(dlfcn.h) for `fs/Plugin.c`
> )
> 
> giving some clues for other libraries you'll need installed - some
> are in base, from ports you'll want libjson-c (devel/json-c), libuuid
> (it probably wants the one in sysutils/e2fsprogs), curl (net/curl).
> OpenBSD doesn't use libdl and you probably need to delete that line
> in a patch (the relevant functions are just in libc on OpenBSD,
> there is no libdl, so trying to link with it will fail).
> 
> > How does one declare the 'syscall' function here, and why is it not needed on the Linux platform?
> > 
> > Do we have an equivalent for the Linux macro syscall __NR_memfd_create (which seems also to be aliased as SYS_memfd_create)?
> 
> IIUC: Linux has this history of adding things to the kernel that glibc
> doesn't want to add wrappers for, so in order to use them programs
> wanting to use it have to use the syscall directly.
> 
> OpenBSD (since recently) doesn't permit using syscall() at all any more
> - it's a potent vector for BROP attacks ("ret2syscall"). But because the
> kernel and libraries are developed alongside each other and we don't
> have a policy of maintaining ABI so that old binaries stay running, its
> not a problem to add wrappers for kernel calls to libc if we need them.
> 
> That said we don't have memfd support at all hence gkoehler's suggestion
> of a workaround.
> 

Thank you George and Stuart for the tips. 
Is it also possible to use shm_mkstemp(3) to put the buffer in Shared
Memory instead of a disk file? 
libjson-c is pulled from git at present as a cmake external, but I will
try and change it to use the port.
I will work on the port over the next couple of evenings and
hopefully will have something functional to test soon. 
-- 
Chris Billington