The ultimate socket library for C and C++, supporting TCP, UDP and Unix sockets (DGRAM and STREAM) on Linux, FreeBSD, Solaris. See also my uvco library for a refreshed version!
Hello, I was trying to build libsocket in an Alpine Linux based Docker container and came across two errors. The errors occur at the same time and in the same file, but I've separated them for clarity.
Error 1:
In file included from /workspace/libsocket/headers/streamclient.hpp:5,
from /workspace/libsocket/C++/streamclient.cpp:48:
/workspace/libsocket/headers/socket.hpp:92:22: error: 'socklen_t' has not been declared
92 | socklen_t optlen) const;
| ^~~~~~~~~
make[2]: *** [C++/CMakeFiles/socket++_o.dir/build.make:154: C++/CMakeFiles/socket++_o.dir/streamclient.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:268: C++/CMakeFiles/socket++_o.dir/all] Error 2
make: *** [Makefile:152: all] Error 2
I think the reason for this error is because of where and how the definition for
socklen_t can be acquired on Alpine versus, for example, Ubuntu 18.04.
On Ubuntu 18.04 when compiling streamclient.cpp, the definition for
socklen_t is acquired by including <unistd.h> on line 37. This puts the
definition into the global scope, granting visibility of socklen_t to the
contents of the "socket.hpp" include, and therefore resulting in a successful compliation.
On Alpine, it seems like the primary way to get socklen_t is by including <sys/socket.h>,
which includes <bits/alltypes.h> in the following manner:
The header <unistd.h> also includes <bits/alltypes.h>, but the explicit
requirement of the __NEED_socklen_t definition on Alpine breaks
the manner in which the streamclient.cpp file acquires the globally scoped
definition of socklen_t.
Error 2:
In file included from /usr/include/fortify/sys/socket.h:22,
from /workspace/libsocket/C++/streamclient.cpp:42:
/workspace/libsocket/C++/streamclient.cpp: In member function 'void libsocket::stream_client_socket::shutdown(int)':
/workspace/libsocket/C++/streamclient.cpp:290:21: error: expected unqualified-id before numeric constant
290 | using BERKELEY::SHUT_RD;
| ^~~~~~~
/workspace/libsocket/C++/streamclient.cpp:290:21: error: expected ';' before numeric constant
290 | using BERKELEY::SHUT_RD;
| ^
| ;
In file included from /usr/include/fortify/sys/socket.h:22,
from /workspace/libsocket/C++/streamclient.cpp:42:
/workspace/libsocket/C++/streamclient.cpp:291:21: error: expected unqualified-id before numeric constant
291 | using BERKELEY::SHUT_RDWR;
| ^~~~~~~~~
/workspace/libsocket/C++/streamclient.cpp:291:21: error: expected ';' before numeric constant
291 | using BERKELEY::SHUT_RDWR;
| ^
| ;
In file included from /usr/include/fortify/sys/socket.h:22,
from /workspace/libsocket/C++/streamclient.cpp:42:
/workspace/libsocket/C++/streamclient.cpp:292:21: error: expected unqualified-id before numeric constant
292 | using BERKELEY::SHUT_WR;
| ^~~~~~~
/workspace/libsocket/C++/streamclient.cpp:292:21: error: expected ';' before numeric constant
292 | using BERKELEY::SHUT_WR;
| ^
| ;
make[2]: *** [C++/CMakeFiles/socket++_o.dir/build.make:154: C++/CMakeFiles/socket++_o.dir/streamclient
.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:268: C++/CMakeFiles/socket++_o.dir/all] Error 2
make: *** [Makefile:152: all] Error 2
I think the reason for these errors is because SHUT_RD, SHUT_WR, and
SHUT_RDWR are only #defined in the header <sys/socket.h> on Alpine:
While on Ubuntu 18.04, for example, the header <sys/socket.h> is as follows:
// Ubuntu 18.04 <sys/sock.h>:
// ...
enum
{
SHUT_RD = 0, /* No more receptions. */
#define SHUT_RD SHUT_RD
SHUT_WR, /* No more transmissions. */
#define SHUT_WR SHUT_WR
SHUT_RDWR /* No more receptions or transmissions. */
#define SHUT_RDWR SHUT_RDWR
};
// ...
Thus, wrapping the #include <sys/socket.h> in the BERKELEY namespace in
streamclient.cpp on line 42-44 and the subsequent using directives at the
lines seen in the error message will break on Alpine Linux due to
the nonexistance of the enum.
Reproduction steps:
Build the following Docker image:
FROM alpine:3.11
RUN apk update && \
apk upgrade && \
apk add git bash wget curl cmake make && \
apk add build-base
WORKDIR /workspace
RUN git clone https://github.com/dermesser/libsocket.git && \
cd libsocket && \
mkdir build && \
cd build && \
cmake .. -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ && \
make
Thank you for reporting this! Please check if this works for you as well; I built it in an Alpine image myself and the change seems to have fixed the error.
Hello, I was trying to build libsocket in an Alpine Linux based Docker container and came across two errors. The errors occur at the same time and in the same file, but I've separated them for clarity.
Error 1:
I think the reason for this error is because of where and how the definition for
socklen_t
can be acquired on Alpine versus, for example, Ubuntu 18.04.On Ubuntu 18.04 when compiling
streamclient.cpp
, the definition forsocklen_t
is acquired by including<unistd.h>
on line 37. This puts the definition into the global scope, granting visibility ofsocklen_t
to the contents of the"socket.hpp"
include, and therefore resulting in a successful compliation.On Alpine, it seems like the primary way to get
socklen_t
is by including<sys/socket.h>
, which includes<bits/alltypes.h>
in the following manner:Satisfying the following definition in
<bits/alltypes.h>
:The header
<unistd.h>
also includes<bits/alltypes.h>
, but the explicit requirement of the__NEED_socklen_t
definition on Alpine breaks the manner in which thestreamclient.cpp
file acquires the globally scoped definition ofsocklen_t
.Error 2:
I think the reason for these errors is because
SHUT_RD
,SHUT_WR
, andSHUT_RDWR
are only #defined in the header<sys/socket.h>
on Alpine:While on Ubuntu 18.04, for example, the header
<sys/socket.h>
is as follows:Thus, wrapping the
#include <sys/socket.h>
in theBERKELEY
namespace instreamclient.cpp
on line 42-44 and the subsequentusing
directives at the lines seen in the error message will break on Alpine Linux due to the nonexistance of theenum
.Reproduction steps: Build the following Docker image: