make android compile again

pull/45/head
Jeff Becker 6 years ago
parent 962303fb03
commit f1cca956f9
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

@ -95,6 +95,7 @@ if(CMAKE_BUILD_TYPE MATCHES "[Dd][Ee][Bb][Uu][Gg]")
add_compile_options( ${DEBUG_FLAGS} )
endif()
if(NOT ANDROID)
if (NOT USE_AVX2)
set(CRYPTO_FLAGS -march=native)
set(CMAKE_ASM_FLAGS "-march=native ${CMAKE_ASM_FLAGS} $ENV{ASFLAGS}")
@ -102,6 +103,7 @@ else()
set(CRYPTO_FLAGS -march=haswell -mtune=native)
set(CMAKE_ASM_FLAGS "-march=haswell -mtune=native ${CMAKE_ASM_FLAGS} $ENV{ASFLAGS}")
endif(NOT USE_AVX2)
endif()
add_compile_options(${OPTIMIZE_FLAGS} ${CRYPTO_FLAGS})
@ -138,6 +140,10 @@ endif(WIN32)
# it is only required on win32 -rick
set(LIBS Threads::Threads ${MALLOC_LIB} ${FS_LIB})
if(ANDROID)
set(LIBS ${LIBS} log)
endif()
set(LIB lokinet)
set(SHARED_LIB ${LIB})
set(STATIC_LIB ${LIB}-static)
@ -574,7 +580,7 @@ if(WITH_STATIC)
endif(WITH_STATIC)
if(ANDROID)
add_library(${ANDROID_LIB} SHARED jni/lokinet_android.cpp)
target_link_libraries(${ANDROID_LIB} ${STATIC_LIB} ${LIBS} log)
target_link_libraries(${ANDROID_LIB} ${STATIC_LIB} ${LIBS})
endif()
if(WITH_SHARED)

@ -34,7 +34,7 @@ TESTNET_DEBUG ?= 0
ANDROID_NDK ?= $(HOME)/Android/Ndk
ANDROID_SDK ?= $(HOME)/Android/Sdk
ANDROID_ABI ?= armeabi-v7a
ANDROID_API_LEVEL ?= android-18
ANDROID_API_LEVEL ?= 18
JSONRPC = OFF
CXX17 = ON
@ -134,11 +134,13 @@ test: debug
android-configure: clean
mkdir -p '$(BUILD_ROOT)'
cd '$(BUILD_ROOT)' && cmake -DANDROID_NATIVE_API_LEVEL='$(ANDROID_API_LEVEL)' -DANDROID_NDK='$(ANDROID_NDK)' -DANDROID_ABI='$(ANDROID_ABI)' -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE='$(REPO)/contrib/cross/android.toolchain.cmake' '$(REPO)'
cd '$(BUILD_ROOT)' && cmake -DANDROID_API='$(ANDROID_API_LEVEL)' -DANDROID_NDK='$(ANDROID_NDK)' -DANDROID_ARCH_ABI='$(ANDROID_ABI)' -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE='$(REPO)/contrib/cross/android.toolchain.cmake' '$(REPO)'
android: android-configure
android-build: android-configure
$(MAKE) -C '$(BUILD_ROOT)'
android: andorid-build
abyss: debug
$(ABYSS_EXE)

File diff suppressed because it is too large Load Diff

@ -1,3 +1,4 @@
#if __AVX2__
#include <immintrin.h>
#include "params.h"
#include "small.h"
@ -5,36 +6,43 @@
/* XXX: these functions rely on p mod 4 = 1 */
/* all coefficients in -1, 0, 1 */
void small_encode(unsigned char *c,const small *f)
void
small_encode(unsigned char *c, const small *f)
{
small c0;
int i;
for (i = 0;i < p/4;++i) {
for(i = 0; i < p / 4; ++i)
{
c0 = *f++ + 1;
c0 += (*f++ + 1) << 2;
c0 += (*f++ + 1) << 4;
c0 += (*f++ + 1) << 6;
*c++ = c0;
}
c0 = *f++ + 1;
c0 = *f++ + 1;
*c++ = c0;
}
void small_decode(small *f,const unsigned char *c)
void
small_decode(small *f, const unsigned char *c)
{
unsigned char c0;
int i;
for (i = 0;i < p/4;++i) {
c0 = *c++;
*f++ = ((small) (c0 & 3)) - 1; c0 >>= 2;
*f++ = ((small) (c0 & 3)) - 1; c0 >>= 2;
*f++ = ((small) (c0 & 3)) - 1; c0 >>= 2;
*f++ = ((small) (c0 & 3)) - 1;
for(i = 0; i < p / 4; ++i)
{
c0 = *c++;
*f++ = ((small)(c0 & 3)) - 1;
c0 >>= 2;
*f++ = ((small)(c0 & 3)) - 1;
c0 >>= 2;
*f++ = ((small)(c0 & 3)) - 1;
c0 >>= 2;
*f++ = ((small)(c0 & 3)) - 1;
}
c0 = *c++;
*f++ = ((small) (c0 & 3)) - 1;
c0 = *c++;
*f++ = ((small)(c0 & 3)) - 1;
*f++ = 0;
*f++ = 0;
*f++ = 0;
@ -43,3 +51,4 @@ void small_decode(small *f,const unsigned char *c)
*f++ = 0;
*f++ = 0;
}
#endif

@ -1,4 +1,4 @@
#ifndef ANDROID
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
@ -118,3 +118,4 @@ struct crypto_stream_salsa20_implementation
crypto_stream_salsa20_xmm6int_sse2_implementation = {
SODIUM_C99(.stream =) stream_sse2,
SODIUM_C99(.stream_xor_ic =) stream_sse2_xor_ic};
#endif

@ -3,6 +3,7 @@
#include "../stream_salsa20.h"
#include <sodium/crypto_stream_salsa20.h>
#ifndef ANDROID
extern struct crypto_stream_salsa20_implementation
crypto_stream_salsa20_xmm6int_sse2_implementation;
#endif

@ -15,6 +15,15 @@ extern "C"
{
#endif
/// ensure configuration exists
/// populate with defaults
/// return if this succeeded
/// if overwrite is true then overwrite old config file
/// if basedir is not nullptr then use basedir as an absolute
/// base path for all files in config
bool
llarp_ensure_config(const char *, const char *, bool, bool);
/// llarp application context for C api
struct llarp_main;

@ -62,7 +62,13 @@ namespace llarp
{
char tmp[128] = {0};
inet_ntop(AF_INET6, &a.ip, tmp, sizeof(tmp));
return out << tmp << "." << std::to_string(a.port);
out << tmp << ".";
#ifdef ANDROID
snprintf(tmp, sizeof(tmp), "%u", a.port);
return out << tmp;
#else
return out << std::to_string(a.port);
#endif
}
struct Hash

@ -53,8 +53,14 @@ namespace llarp
else
return out;
out << std::string("/");
#ifdef ANDROID
snprintf(tmp, sizeof(tmp), "%u",
llarp::bits::count_array_bits(xi.netmask.s6_addr));
return out << tmp;
#else
return out << std::to_string(
llarp::bits::count_array_bits(xi.netmask.s6_addr));
#endif
}
};
} // namespace llarp

@ -77,7 +77,13 @@ namespace llarp
auto tid = std::this_thread::get_id();
std::hash< std::thread::id > h;
uint16_t id = h(tid) % 1000;
#ifdef ANDROID
char buff[8] = {0};
snprintf(buff, sizeof(buff), "%u", id);
return buff;
#else
return std::to_string(id);
#endif
}
struct log_timestamp
@ -91,8 +97,12 @@ namespace llarp
friend std::ostream&
operator<<(std::ostream& out, const log_timestamp& ts)
{
#ifdef ANDROID
return out;
#else
auto now = llarp::Clock_t::to_time_t(llarp::Clock_t::now());
return out << std::put_time(std::localtime(&now), ts.format);
#endif
}
};
@ -161,12 +171,8 @@ namespace llarp
_glog.out << ss.str() << std::endl;
#else
{
std::unique_lock< std::mutex > lock(_glog.access);
tag = "LOKINET|" + tag;
__android_log_write(ANDROID_LOG_INFO, tag.c_str(), ss.str().c_str());
//__android_log_write(ANDROID_LOG_INFO, "LOKINET", ss.str().c_str());
llarp::util::Lock lock(_glog.access);
_glog.out << ss.str() << std::endl;
__android_log_write(loglev, tag.c_str(), ss.str().c_str());
}
#endif
#ifdef SHADOW_TESTNET

@ -2,9 +2,11 @@
//#include <string.h>
#include <jni.h>
#include <llarp.h>
#include <llarp/config.h>
#include <signal.h>
#include <memory>
#include <thread>
#include "fs.hpp"
struct AndroidMain
{
@ -12,11 +14,11 @@ struct AndroidMain
std::thread* m_thread = nullptr;
bool
Start(const char* conf)
Start(const char* conf, const char* basedir)
{
if(m_impl || m_thread)
return true;
if(!llarp_ensure_config(conf))
if(!llarp_ensure_config(conf, basedir, false, false))
return false;
m_impl = llarp_main_init(conf, true);
if(m_impl == nullptr)
@ -70,15 +72,16 @@ extern "C"
if(daemon->Running())
return env->NewStringUTF("already running");
std::string conf;
fs::path basepath;
{
const char* nativeString = env->GetStringUTFChars(configfile, JNI_FALSE);
conf += std::string(nativeString);
env->ReleaseStringUTFChars(configfile, nativeString);
basepath = fs::path(conf).parent_path();
}
if(daemon->Start(conf.c_str()))
if(daemon->Start(conf.c_str(), basepath.string().c_str()))
return env->NewStringUTF("ok");
else
return env->NewStringUTF("failed to start");
return env->NewStringUTF("failed to start");
}
JNIEXPORT void JNICALL

@ -43,7 +43,7 @@ namespace llarp
} // namespace llarp
bool
extern "C" bool
llarp_ensure_config(const char *fname, const char *basedir, bool overwrite,
bool asRouter)
{

@ -32,16 +32,6 @@ struct llarp_config
llarp::Config impl;
};
/// ensure configuration exists
/// populate with defaults
/// return if this succeeded
/// if overwrite is true then overwrite old config file
/// if basedir is not nullptr then use basedir as an absolute
/// base path for all files in config
bool
llarp_ensure_config(const char *fname, const char *basedir = nullptr,
bool overwrite = false, bool asRouter = true);
void
llarp_generic_ensure_config(std::ofstream &f, std::string basepath);

@ -13,11 +13,6 @@
#include <pthread_np.h>
#endif
#if _WIN32 || __sun
#define wmin(x, y) (((x) < (y)) ? (x) : (y))
#define MIN wmin
#endif
namespace llarp
{
Context::~Context()
@ -510,23 +505,21 @@ extern "C"
conffname = optarg;
break;
case 'o':
if(strncmp(optarg, "debug", MIN(strlen(optarg), (unsigned long)5))
== 0)
if(strncmp(optarg, "debug", std::min(strlen(optarg), size_t(5))) == 0)
{
cSetLogLevel(eLogDebug);
}
else if(strncmp(optarg, "info", MIN(strlen(optarg), (unsigned long)4))
else if(strncmp(optarg, "info", std::min(strlen(optarg), size_t(4)))
== 0)
{
cSetLogLevel(eLogInfo);
}
else if(strncmp(optarg, "warn", MIN(strlen(optarg), (unsigned long)4))
else if(strncmp(optarg, "warn", std::min(strlen(optarg), size_t(4)))
== 0)
{
cSetLogLevel(eLogWarn);
}
else if(strncmp(optarg, "error",
MIN(strlen(optarg), (unsigned long)5))
else if(strncmp(optarg, "error", std::min(strlen(optarg), size_t(5)))
== 0)
{
cSetLogLevel(eLogError);

@ -214,8 +214,10 @@ extern "C"
question->qClass = get16bits(moveable);
(*pos) += 2;
// printf("Now2 at [%d]\n", buffer - start);
/*
llarp::LogDebug("Type ", std::to_string(question->type), " Class ",
std::to_string(question->qClass));
*/
// hexDump(moveable, 4);
return question;
}
@ -298,8 +300,10 @@ extern "C"
llarp::LogDebug("Answer TTL: ", answer->ttl);
answer->rdLen = get16bits(moveable);
(*pos) += 2;
/*
llarp::LogDebug("Answer rdL: ", answer->rdLen, " at ",
std::to_string(*pos));
*/
// uint32_t cPos = moveable - buffer;
// llarp::LogInfo("pos at ", std::to_string(*pos), " calculated: ",
// std::to_string(cPos));
@ -310,10 +314,12 @@ extern "C"
{
answer->rData = new uint8_t[answer->rdLen];
memcpy(answer->rData, moveable, answer->rdLen);
/*
llarp::LogDebug("Read ", std::to_string(answer->rData[0]), ".",
std::to_string(answer->rData[1]), ".",
std::to_string(answer->rData[2]), ".",
std::to_string(answer->rData[3]));
*/
moveable += answer->rdLen;
(*pos) += answer->rdLen; // advance the length
}

@ -191,6 +191,14 @@ struct reverse_handler_iter_context
const struct dnsd_question_request *request;
};
#ifdef ANDROID
static int
stoi(const std::string &s)
{
return atoi(s.c_str());
}
#endif
bool
ReverseHandlerIter(struct llarp::service::Context::endpoint_iter *endpointCfg)
{

@ -39,11 +39,11 @@ dns_iptracker_setup(dns_iptracker *iptracker, llarp::huint32_t tunGatewayIp)
// struct in_addr *addr = tunGatewayIp.addr4();
// unsigned char *ip = (unsigned char *)&(addr->s_addr);
unsigned char *ip = (unsigned char *)&(tunGatewayIp.h);
llarp::LogInfo("iptracker setup: (", std::to_string(ip[0]), ").[",
std::to_string(ip[1]), '.', std::to_string(ip[2]), "].",
std::to_string(ip[3]));
/*
llarp::LogInfo("iptracker setup: (", std::to_string(ip[0]), ").[",
std::to_string(ip[1]), '.', std::to_string(ip[2]), "].",
std::to_string(ip[3]));
*/
std::unique_ptr< ip_range > range(new ip_range);
range->octet2 = ip[1]; // 2nd octet
range->octet3 = ip[2]; // 3rd octet

@ -234,7 +234,7 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
for(uint32_t i = 0; i < hdr->qdCount; i++)
{
question = decode_question(castBufc, &pos);
llarp::LogDebug("Read a question, now at ", std::to_string(pos));
// llarp::LogDebug("Read a question, now at ", std::to_string(pos));
// 1 dot: 1 byte for length + length
// 4 bytes for class/type
// castBuf += question->name.length() + 1 + 4;
@ -249,8 +249,10 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
// pos = 0; // reset pos
answer = decode_answer(castBufc, &pos);
answers.push_back(answer);
/*
llarp::LogDebug("Read an answer ", answer->type, " for ",
request->question.name, ", now at ", std::to_string(pos));
*/
// llarp::LogInfo("Read an answer. Label Len: ", answer->name.length(), "
// rdLen: ", answer->rdLen);
// name + Type (2) + Class (2) + TTL (4) + rdLen (2) + rdData + skip next
@ -372,7 +374,7 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
llarp::LogInfo("ans2 rdlen ", answer2->rdLen);
*/
llarp::LogDebug("rcode ", std::to_string(rcode));
// llarp::LogDebug("rcode ", std::to_string(rcode));
if(rcode == 2)
{
llarp::LogWarn("nameserver ", upstreamAddr, " returned SERVFAIL:");
@ -395,8 +397,10 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
/* search for and print IPv4 addresses */
// if(dnsQuery->reqType == 0x01)
/*
llarp::LogDebug("request question type: ",
std::to_string(request->question.type));
*/
if(request->question.type == 1)
{
// llarp::LogInfo("DNS server's answer is: (type#=", ATYPE, "):");

@ -16,6 +16,11 @@
#include "mem.hpp"
#include <cassert>
#ifdef ANDROID
/** TODO: correct this value */
#define SOCK_NONBLOCK (0)
#endif
namespace llarp
{
int

@ -83,7 +83,13 @@ namespace llarp
auto pos = v.find("/");
if(pos != std::string::npos)
{
auto num = std::stoi(v.substr(pos + 1));
int num;
std::string part = v.substr(pos + 1);
#ifdef ANDROID
num = atoi(part.c_str());
#else
num = std::stoi(part);
#endif
if(num > 0)
{
tunif.netmask = num;

@ -5,7 +5,9 @@
#endif
#ifndef _WIN32
#include <arpa/inet.h>
#ifndef ANDROID
#include <ifaddrs.h>
#endif
#include <net/if.h>
#endif
#include <cstdio>
@ -904,7 +906,9 @@ namespace llarp
uint8_t num = 0;
while(num < 255)
{
std::string iftestname = "lokitun" + std::to_string(num);
std::stringstream ifname_ss;
ifname_ss << "lokitun" << num;
std::string iftestname = ifname_ss.str();
struct sockaddr addr;
bool found = llarp_getifaddr(iftestname.c_str(), AF_INET, &addr);
if(!found)
@ -920,8 +924,14 @@ namespace llarp
// llarp::LogError("Could not find any free lokitun interface names");
return "";
}
// include lokitun prefix to communicate result is valid
// include lokitun prefix to communicate result is valid
#ifdef ANDROID
char buff[IFNAMSIZ + 1] = {0};
snprintf(buff, sizeof(buff), "lokitun%u", num);
return buff;
#else
return "lokitun" + std::to_string(num);
#endif
}
bool

@ -110,7 +110,8 @@ namespace llarp
Addr::Addr(string_view addr_str, string_view port_str)
{
this->from_char_array(llarp::string_view_string(addr_str).c_str());
this->port(std::stoi(llarp::string_view_string(port_str)));
this->port(
std::strtoul(llarp::string_view_string(port_str).c_str(), nullptr, 10));
}
bool
@ -331,7 +332,7 @@ namespace llarp
Addr::CopyInto(sockaddr* other) const
{
void *dst, *src;
in_port_t* ptr;
uint16_t* ptr;
size_t slen;
switch(af())
{

@ -827,10 +827,11 @@ llarp_router::ShouldCreateDefaultHiddenService()
{
// auto detect if we have any pre-defined endpoints
// no if we have a endpoints
llarp::LogInfo("Auto mode detected, hasEndpoints: ",
std::to_string(this->hiddenServiceContext.hasEndpoints()));
if(this->hiddenServiceContext.hasEndpoints())
if(hiddenServiceContext.hasEndpoints())
{
llarp::LogInfo("Auto mode detected and we have endpoints");
return false;
}
// we don't have any endpoints, auto configure settings
// set a default IP range

@ -13,8 +13,10 @@
#endif
#ifdef __linux__
#ifndef ANDROID
#include <llarp/linux/netns.hpp>
#endif
#endif
namespace llarp
{
@ -142,6 +144,7 @@ namespace llarp
}
#ifdef __linux__
#ifndef ANDROID
struct LinuxNetNSIsolatedPool : public _NetIsolatedPool
{
LinuxNetNSIsolatedPool(std::function< bool(void *, bool) > setup,
@ -160,6 +163,7 @@ namespace llarp
typedef LinuxNetNSIsolatedPool NetIsolatedPool;
#define NET_ISOLATION_SUPPORTED
#endif
#endif
#if defined(__FreeBSD__)
struct FreeBSDJailedThreadPool : public _NetIsolatedPool

@ -1,30 +1,31 @@
/* Copyright (c) 2014, Pollard Banknote Limited
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#include "absolute.h"
@ -35,56 +36,61 @@
namespace cpp17
{
namespace filesystem
{
path absolute(const path& filename)
{
if ( !filename.empty() )
{
#if (( defined( _POSIX_VERSION ) && _POSIX_VERSION >= 200809l ) || defined( __GLIBC__ ))
// Preferred - POSIX-2008 and glibc will allocate the path buffer
char* res = ::realpath(filename.c_str(), NULL);
if ( res )
{
path s = res;
::free(res);
return s;
}
#else
#ifdef _GNU_SOURCE
// Maybe we can rely on the GNU extension
char* res = ::canonicalize_file_name( filename.c_str() );
if ( res )
{
std::string s = res;
::free(res);
return s;
}
#elif ((( defined( _POSIX_VERSION ) && _POSIX_VERSION >= 200112L ) || ( defined( _XOPEN_VERSION ) && _XOPEN_VERSION >= 500 )) && defined( PATH_MAX ))
/// @todo PATH_MAX may be huge or -1, according to man pages for realpath
char resolved[PATH_MAX + 1];
char* res = ::realpath(filename.c_str(), resolved);
if ( res )
{
return resolved;
}
#else
#error "No way to get absolute file path!"
#endif // if 1
#endif // if ( defined( _POSIX_VERSION ) && _POSIX_VERSION >= 200809l )
}
return path();
}
}
}
namespace filesystem
{
path
absolute(const path& filename)
{
if(!filename.empty())
{
#if((defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809l) \
|| defined(__GLIBC__)) \
|| defined(ANDROID)
// Preferred - POSIX-2008 and glibc will allocate the path buffer
char* res = ::realpath(filename.c_str(), NULL);
if(res)
{
path s = res;
::free(res);
return s;
}
#else
#ifdef _GNU_SOURCE
// Maybe we can rely on the GNU extension
char* res = ::canonicalize_file_name(filename.c_str());
if(res)
{
std::string s = res;
::free(res);
return s;
}
#elif(((defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L) \
|| (defined(_XOPEN_VERSION) && _XOPEN_VERSION >= 500)) \
&& defined(PATH_MAX))
/// @todo PATH_MAX may be huge or -1, according to man pages for
/// realpath
char resolved[PATH_MAX + 1];
char* res = ::realpath(filename.c_str(), resolved);
if(res)
{
return resolved;
}
#else
#error "No way to get absolute file path!"
#endif // if 1
#endif // if ( defined( _POSIX_VERSION ) && _POSIX_VERSION >= 200809l )
}
return path();
}
} // namespace filesystem
} // namespace cpp17

@ -43,6 +43,8 @@
#include <net/if.h>
#if defined DragonFly
#include <net/tun/if_tun.h>
#elif defined ANDROID
#include <linux/if_tun.h>
#elif !defined Darwin
#include <net/if_tun.h>
#endif

Loading…
Cancel
Save