Skip to content

Commit

Permalink
First windows build (#305)
Browse files Browse the repository at this point in the history
  • Loading branch information
MisterTea authored May 19, 2020
1 parent b04d8a2 commit 3479419
Show file tree
Hide file tree
Showing 36 changed files with 1,373 additions and 969 deletions.
58 changes: 37 additions & 21 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ endif()
option(CODE_COVERAGE "Enable code coverage" OFF)
option(DISABLE_CRASH_LOG "Disable installing easylogging crash handler" OFF)

SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DET_VERSION='\"${PROJECT_VERSION}\"'")
add_definitions(-DET_VERSION="${PROJECT_VERSION}")
# For easylogging, disable default log file, enable crash log, ensure thread safe, and catch c++ exceptions
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DELPP_NO_DEFAULT_LOG_FILE -DELPP_FEATURE_CRASH_LOG -DELPP_THREAD_SAFE")
IF(CODE_COVERAGE)
Expand All @@ -27,13 +27,20 @@ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DELPP_DISABLE_DEFAULT_CRASH_HANDLING")
ENDIF(DISABLE_CRASH_LOG)

if(UNIX)
# Enable C++-11
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++11")

# Enable debug info
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")
endif()

# Enable C++-11
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

if(WIN32)
# Enable unicode
ADD_DEFINITIONS(-DUNICODE)
ADD_DEFINITIONS(-D_UNICODE)
endif()

#Using FreeBSD?
if (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
set(FREEBSD TRUE)
Expand Down Expand Up @@ -96,6 +103,8 @@ IF(FREEBSD)
set(CORE_LIBRARIES util execinfo)
ELSEIF(NETBSD)
set(CORE_LIBRARIES util resolv execinfo)
ELSEIF(WIN32)
set(CORE_LIBRARIES Ws2_32 Shlwapi dbghelp)
ELSE()
set(CORE_LIBRARIES util resolv)
ENDIF()
Expand Down Expand Up @@ -178,6 +187,11 @@ add_library(
src/base/RawSocketUtils.hpp
src/base/RawSocketUtils.cpp

src/base/WinsockContext.hpp

src/base/SubprocessToString.hpp
src/base/SubprocessToString.cpp

${ET_SRCS}
)
add_dependencies(
Expand Down Expand Up @@ -225,6 +239,24 @@ add_dependencies(
)
DECORATE_TARGET(TerminalCommon)

add_executable (
et
src/terminal/TerminalClientMain.cpp
)
target_link_libraries (
et
LINK_PUBLIC
TerminalCommon
et-lib
${CMAKE_THREAD_LIBS_INIT}
${PROTOBUF_LITE_LIBRARIES}
${sodium_LIBRARY_RELEASE}
${UTEMPTER_LIBRARIES}
${CORE_LIBRARIES}
)
DECORATE_TARGET(et)

IF(NOT WIN32)
add_executable (
etserver
src/terminal/TerminalServerMain.cpp
Expand Down Expand Up @@ -261,23 +293,6 @@ target_link_libraries (
)
DECORATE_TARGET(etterminal)

add_executable (
et
src/terminal/TerminalClientMain.cpp
)
target_link_libraries (
et
LINK_PUBLIC
TerminalCommon
et-lib
${CMAKE_THREAD_LIBS_INIT}
${PROTOBUF_LITE_LIBRARIES}
${sodium_LIBRARY_RELEASE}
${UTEMPTER_LIBRARIES}
${CORE_LIBRARIES}
)
DECORATE_TARGET(et)

add_library (
HtmCommon
STATIC
Expand Down Expand Up @@ -370,3 +385,4 @@ install(TARGETS etserver etterminal et htm htmd
PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ
DESTINATION "bin"
)
ENDIF()
2 changes: 1 addition & 1 deletion src/base/BackedWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ BackedWriterWriteState BackedWriter::write(Packet packet) {
if (bytesWritten == count) {
return BackedWriterWriteState::SUCCESS;
}
usleep(1000);
std::this_thread::sleep_for(std::chrono::microseconds(1000));
} else {
// Error, we don't know how many bytes were written but it
// doesn't matter because the reader is going to have to
Expand Down
2 changes: 1 addition & 1 deletion src/base/ClientConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ void ClientConnection::pollReconnect() {

if (socketFd == -1) {
VLOG_EVERY_N(10, 1) << "Waiting to retry...";
usleep(1000 * 1000);
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
LOG(INFO) << "Reconnect complete";
Expand Down
4 changes: 2 additions & 2 deletions src/base/Connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ void Connection::writePacket(const Packet& packet) {
// Yield the processor
if (hasConnection) {
// Have a connection, sleep for 1ms
usleep(1 * 1000);
std::this_thread::sleep_for(std::chrono::microseconds(1000));
} else {
// No connection, sleep for 100ms
usleep(100 * 1000);
std::this_thread::sleep_for(std::chrono::microseconds(100*1000));
}
LOG_EVERY_N(1000, INFO) << "Waiting to write...";
}
Expand Down
2 changes: 2 additions & 0 deletions src/base/DaemonCreator.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#ifndef WIN32
#include "DaemonCreator.hpp"

namespace et {
Expand Down Expand Up @@ -64,3 +65,4 @@ int DaemonCreator::create(bool parentExit, string childPidFile) {
return CHILD;
}
} // namespace et
#endif
107 changes: 85 additions & 22 deletions src/base/Headers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,41 +13,59 @@
#include <sys/socket.h>
#elif __NetBSD__ // do not need pty.h on NetBSD
#include <util.h>
#elif WIN32
#include <WinSock2.h>
#include <Ws2tcpip.h>
#include <afunix.h>
#include <signal.h>
inline int close(int fd) { return ::closesocket(fd); }
#else
#include <pty.h>
#include <signal.h>
#endif

#ifdef WIN32
#else
#include <arpa/inet.h>
#include <grp.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <paths.h>
#include <pthread.h>
#include <pwd.h>
#include <resolv.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <termios.h>
#include <unistd.h>
#endif

#include <errno.h>
#include <fcntl.h>
#include <google/protobuf/message_lite.h>
#include <pthread.h>
#include <pwd.h>
#include <sodium.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <termios.h>
#include <time.h>
#include <unistd.h>

#include <algorithm>
#include <array>
#include <atomic>
#include <codecvt>
#include <ctime>
#include <cxxopts.hpp>
#include <deque>
#include <exception>
#include <fstream>
#include <iostream>
#include <locale>
#include <memory>
#include <mutex>
#include <set>
Expand All @@ -68,6 +86,31 @@
#include "sole.hpp"
#include "ust.hpp"

#ifdef WITH_UTEMPTER
#include <utempter.h>
#endif

#if WIN32
#define popen _popen
#define pclose _pclose

/* ssize_t is not defined on Windows */
#ifndef ssize_t
#if defined(_WIN64)
typedef signed __int64 ssize_t;
#else
typedef signed long ssize_t;
#endif
#endif /* !ssize_t */

/* On MSVC, ssize_t is SSIZE_T */
#ifdef _MSC_VER
#include <BaseTsd.h>
#define ssize_t SSIZE_T
#endif

#endif

using namespace std;

using json = nlohmann::json;
Expand All @@ -93,15 +136,34 @@ const int SERVER_KEEP_ALIVE_DURATION = 11;

#define STERROR LOG(ERROR) << "Stack Trace: " << endl << ust::generate()

#ifdef WIN32
inline string WindowsErrnoToString() {
const int BUFSIZE = 4096;
char buf[BUFSIZE];
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, WSAGetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, BUFSIZE, NULL);
string s(buf, BUFSIZE);
return s;
}
#define FATAL_FAIL(X) \
if (((X) == -1)) \
LOG(FATAL) << "Error: (" << WSAGetLastError() \
<< "): " << WindowsErrnoToString();

#define FATAL_FAIL_UNLESS_EINVAL(X) FATAL_FAIL(X)

#else
#define FATAL_FAIL(X) \
if (((X) == -1)) \
STFATAL << "Error: (" << errno << "): " << strerror(errno);
if (((X) == -1)) STFATAL << "Error: (" << errno << "): " << strerror(errno);

// On BSD/OSX we can get EINVAL if the remote side has closed the connection
// before we have initialized it.
#define FATAL_FAIL_UNLESS_EINVAL(X) \
if (((X) == -1) && errno != EINVAL) \
STFATAL << "Error: (" << errno << "): " << strerror(errno);
#endif

#ifndef ET_VERSION
#define ET_VERSION "unknown"
Expand Down Expand Up @@ -135,18 +197,6 @@ inline std::vector<std::string> split(const std::string& s, char delim) {
return elems;
}

inline std::string SystemToStr(const char* cmd) {
std::array<char, 128> buffer;
std::string result;
std::shared_ptr<FILE> pipe(popen(cmd, "r"), pclose);
if (!pipe) throw std::runtime_error("popen() failed!");
while (!feof(pipe.get())) {
if (fgets(buffer.data(), 128, pipe.get()) != nullptr)
result += buffer.data();
}
return result;
}

inline bool replace(std::string& str, const std::string& from,
const std::string& to) {
size_t start_pos = str.find(from);
Expand Down Expand Up @@ -227,4 +277,17 @@ inline bool operator!=(const google::protobuf::MessageLite& msg_a,
(msg_a.SerializeAsString() != msg_b.SerializeAsString());
}

inline string GetTempDirectory() {
#ifdef WIN32
WCHAR buf[65536];
int retval = GetTempPath(65536, buf);
int a = 0;
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t> > converter;
std::string tmpDir = converter.to_bytes(wstring(buf, retval));
#else
string tmpDir = "/tmp";
#endif
return tmpDir;
}

#endif
3 changes: 3 additions & 0 deletions src/base/LogHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ string LogHandler::stderrToFile(const string &pathPrefix) {
string current_time(buffer);
string stderrFilename = pathPrefix + "_stderr_" + current_time;
FILE *stderr_stream = freopen(stderrFilename.c_str(), "w", stderr);
if (!stderr_stream) {
STFATAL << "Invalid filename " << stderrFilename;
}
setvbuf(stderr_stream, NULL, _IOLBF, BUFSIZ); // set to line buffering
return stderrFilename;
}
Expand Down
18 changes: 8 additions & 10 deletions src/base/PipeSocketHandler.cpp
Original file line number Diff line number Diff line change
@@ -1,18 +1,10 @@
#include "PipeSocketHandler.hpp"

#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <resolv.h>
#include <sys/socket.h>
#include <unistd.h>

namespace et {
PipeSocketHandler::PipeSocketHandler() {}

int PipeSocketHandler::connect(const SocketEndpoint& endpoint) {
lock_guard<std::recursive_mutex> guard(mutex);
lock_guard<std::recursive_mutex> mutexGuard(mutex);

string pipePath = endpoint.name();
sockaddr_un remote;
Expand All @@ -29,7 +21,11 @@ int PipeSocketHandler::connect(const SocketEndpoint& endpoint) {
if (result < 0 && errno != EINPROGRESS) {
VLOG(3) << "Connection result: " << result << " (" << strerror(errno)
<< ")";
#ifdef WIN32
::shutdown(sockFd, SD_BOTH);
#else
::shutdown(sockFd, SHUT_RDWR);
#endif
::close(sockFd);
sockFd = -1;
return sockFd;
Expand All @@ -49,7 +45,7 @@ int PipeSocketHandler::connect(const SocketEndpoint& endpoint) {
int so_error;
socklen_t len = sizeof so_error;

FATAL_FAIL(::getsockopt(sockFd, SOL_SOCKET, SO_ERROR, &so_error, &len));
FATAL_FAIL(::getsockopt(sockFd, SOL_SOCKET, SO_ERROR, (char*)&so_error, &len));

if (so_error == 0) {
LOG(INFO) << "Connected to endpoint " << endpoint;
Expand Down Expand Up @@ -97,7 +93,9 @@ set<int> PipeSocketHandler::listen(const SocketEndpoint& endpoint) {

FATAL_FAIL(::bind(fd, (struct sockaddr*)&local, sizeof(sockaddr_un)));
::listen(fd, 5);
#ifndef WIN32
FATAL_FAIL(::chmod(local.sun_path, S_IRUSR | S_IWUSR | S_IXUSR));
#endif

pipeServerSockets[pipePath] = set<int>({fd});
return pipeServerSockets[pipePath];
Expand Down
Loading

0 comments on commit 3479419

Please sign in to comment.