From 166db74597e2bb9dc1396ed90852a06df8697fed Mon Sep 17 00:00:00 2001 From: Hackerpilot Date: Fri, 15 Jan 2016 00:49:08 -0800 Subject: [PATCH 1/7] Implement #217 --- src/client/client.d | 72 +++++++++++++++++++++------ src/common/socket.d | 45 +++++++++++++++++ src/server/server.d | 118 ++++++++++++++++++++++++++++++++------------ 3 files changed, 188 insertions(+), 47 deletions(-) create mode 100644 src/common/socket.d diff --git a/src/client/client.d b/src/client/client.d index b3d47be..515baae 100644 --- a/src/client/client.d +++ b/src/client/client.d @@ -33,6 +33,7 @@ import std.experimental.logger; import msgpack; import common.messages; import common.dcd_version; +import common.socket; int main(string[] args) { @@ -48,6 +49,16 @@ int main(string[] args) bool printVersion; bool listImports; string search; + version(Windows) + { + bool useTCP = true; + string socketFile; + } + else + { + bool useTCP = false; + string socketFile = generateSocketName(); + } try { @@ -55,7 +66,8 @@ int main(string[] args) "port|p", &port, "help|h", &help, "shutdown", &shutdown, "clearCache", &clearCache, "symbolLocation|l", &symbolLocation, "doc|d", &doc, "query|status|q", &query, "search|s", &search, - "version", &printVersion, "listImports", &listImports); + "version", &printVersion, "listImports", &listImports, + "tcp", &useTCP, "socketFile", &socketFile); } catch (ConvException e) { @@ -66,6 +78,12 @@ int main(string[] args) AutocompleteRequest request; + if (help) + { + printHelp(args[0]); + return 0; + } + if (printVersion) { version (Windows) @@ -76,16 +94,21 @@ int main(string[] args) write(DCD_VERSION, " ", GIT_HASH); return 0; } - else if (help) + + version (Windows) if (socketFile !is null) { - printHelp(args[0]); - return 0; + fatal("UNIX domain sockets not supported on Windows"); + return 1; } - else if (query) + + if (useTCP) + socketFile = null; + + if (query) { try { - TcpSocket socket = createSocket(port); + Socket socket = createSocket(socketFile, port); scope (exit) { socket.shutdown(SocketShutdown.BOTH); socket.close(); } request.kind = RequestKind.query; if (sendRequest(socket, request)) @@ -112,7 +135,7 @@ int main(string[] args) request.kind = RequestKind.shutdown; else if (clearCache) request.kind = RequestKind.clearCache; - TcpSocket socket = createSocket(port); + Socket socket = createSocket(socketFile, port); scope (exit) { socket.shutdown(SocketShutdown.BOTH); socket.close(); } return sendRequest(socket, request) ? 0 : 1; } @@ -122,7 +145,7 @@ int main(string[] args) request.importPaths = importPaths.map!(a => absolutePath(a)).array; if (cursorPos == size_t.max) { - TcpSocket socket = createSocket(port); + Socket socket = createSocket(socketFile, port); scope (exit) { socket.shutdown(SocketShutdown.BOTH); socket.close(); } if (!sendRequest(socket, request)) return 1; @@ -132,7 +155,7 @@ int main(string[] args) else if (listImports) { request.kind |= RequestKind.listImports; - TcpSocket socket = createSocket(port); + Socket socket = createSocket(socketFile, port); scope (exit) { socket.shutdown(SocketShutdown.BOTH); socket.close(); } sendRequest(socket, request); AutocompleteResponse response = getResponse(socket); @@ -194,7 +217,7 @@ int main(string[] args) request.kind |= RequestKind.autocomplete; // Send message to server - TcpSocket socket = createSocket(port); + Socket socket = createSocket(socketFile, port); scope (exit) { socket.shutdown(SocketShutdown.BOTH); socket.close(); } if (!sendRequest(socket, request)) return 1; @@ -266,16 +289,33 @@ Options: --port PORTNUMBER | -p PORTNUMBER Uses PORTNUMBER to communicate with the server instead of the default - port 9166.`, programName); + port 9166. Only used on Windows or when the --tcp option is set. + + --tcp + Send requests on a TCP socket instead of a UNIX domain socket. This + switch has no effect on Windows. + + --socketFile FILENAME + Use the given FILENAME as the path to the UNIX domain socket. Using + this switch is an error on Windows.`, programName); } -TcpSocket createSocket(ushort port) +Socket createSocket(string socketFile, ushort port) { import core.time : dur; - TcpSocket socket = new TcpSocket(AddressFamily.INET); + Socket socket; + if (socketFile is null) + { + socket = new TcpSocket(AddressFamily.INET); + socket.connect(new InternetAddress("localhost", port)); + } + else + { + socket = new Socket(AddressFamily.UNIX, SocketType.STREAM); + socket.connect(new UnixAddress(socketFile)); + } socket.setOption(SocketOptionLevel.SOCKET, SocketOption.RCVTIMEO, dur!"seconds"(5)); - socket.connect(new InternetAddress("localhost", port)); socket.blocking = true; return socket; } @@ -283,7 +323,7 @@ TcpSocket createSocket(ushort port) /** * Returns: true on success */ -bool sendRequest(TcpSocket socket, AutocompleteRequest request) +bool sendRequest(Socket socket, AutocompleteRequest request) { ubyte[] message = msgpack.pack(request); ubyte[] messageBuffer = new ubyte[message.length + message.length.sizeof]; @@ -296,7 +336,7 @@ bool sendRequest(TcpSocket socket, AutocompleteRequest request) /** * Gets the response from the server */ -AutocompleteResponse getResponse(TcpSocket socket) +AutocompleteResponse getResponse(Socket socket) { ubyte[1024 * 16] buffer; auto bytesReceived = socket.receive(buffer); diff --git a/src/common/socket.d b/src/common/socket.d new file mode 100644 index 0000000..05623f6 --- /dev/null +++ b/src/common/socket.d @@ -0,0 +1,45 @@ +/** + * This file is part of DCD, a development tool for the D programming language. + * Copyright (C) 2015 Brian Schott + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +module common.socket; + +import core.sys.posix.unistd; // getuid +import std.format; +import std.process; +import std.path; + +version (OSX) version = haveUnixSockets; +version (linux) version = haveUnixSockets; +version (BSD) version = haveUnixSockets; +version (FreeBSD) version = haveUnixSockets; + +string generateSocketName() +{ + version (haveUnixSockets) + { + immutable string socketFileName = "dcd-%d.socket".format(getuid()); + version (OSX) + return buildPath("/", "var", "tmp", socketFileName); + else + { + immutable string xdg = environment.get("XDG_RUNTIME_DIR"); + return xdg is null ? buildPath("/", "tmp", socketFileName) : buildPath(xdg, + "dcd.socket"); + } + } +} diff --git a/src/server/server.d b/src/server/server.d index 62e89be..406dc32 100644 --- a/src/server/server.d +++ b/src/server/server.d @@ -18,30 +18,33 @@ module server.server; -import std.socket; -import std.stdio; -import std.getopt; +import core.sys.posix.sys.stat; import std.algorithm; -import std.path; -import std.file; import std.array; -import std.process; -import std.datetime; import std.conv; +import std.datetime; +import std.exception : enforce; import std.experimental.allocator; import std.experimental.allocator.mallocator; -import std.exception : enforce; import std.experimental.logger; +import std.file; +import std.file; +import std.getopt; +import std.path; +import std.process; +import std.socket; +import std.stdio; import msgpack; import dsymbol.string_interning; +import common.dcd_version; import common.messages; -import server.autocomplete; +import common.socket; import dsymbol.modulecache; import dsymbol.symbol; -import common.dcd_version; +import server.autocomplete; /// Name of the server configuration file enum CONFIG_FILE_NAME = "dcd.conf"; @@ -59,12 +62,22 @@ int main(string[] args) bool ignoreConfig; string[] importPaths; LogLevel level = globalLogLevel; + version(Windows) + { + bool useTCP = true; + string socketFile; + } + else + { + bool useTCP = false; + string socketFile = generateSocketName(); + } try { getopt(args, "port|p", &port, "I", &importPaths, "help|h", &help, "version", &printVersion, "ignoreConfig", &ignoreConfig, - "logLevel", &level); + "logLevel", &level, "tcp", &useTCP, "socketFile", &socketFile); } catch (ConvException e) { @@ -73,11 +86,6 @@ int main(string[] args) return 1; } - globalLogLevel = level; - - info("Starting up..."); - StopWatch sw = StopWatch(AutoStart.yes); - if (printVersion) { version (Windows) @@ -95,19 +103,52 @@ int main(string[] args) return 0; } + version (Windows) if (socketFile !is null) + { + fatal("UNIX domain sockets not supported on Windows"); + return 1; + } + + globalLogLevel = level; + + info("Starting up..."); + StopWatch sw = StopWatch(AutoStart.yes); + if (!ignoreConfig) importPaths ~= loadConfiguredImportDirs(); - auto socket = new TcpSocket(AddressFamily.INET); - socket.blocking = true; - socket.setOption(SocketOptionLevel.SOCKET, SocketOption.REUSEADDR, true); - socket.bind(new InternetAddress("localhost", port)); + Socket socket; + if (useTCP) + { + socket = new TcpSocket(AddressFamily.INET); + socket.blocking = true; + socket.setOption(SocketOptionLevel.SOCKET, SocketOption.REUSEADDR, true); + socket.bind(new InternetAddress("localhost", port)); + info("Listening on port ", port); + } + else + { + socket = new Socket(AddressFamily.UNIX, SocketType.STREAM); + if (exists(socketFile)) + { + info("Cleaning up old socket file at ", socketFile); + remove(socketFile); + } + socket.blocking = true; + socket.setOption(SocketOptionLevel.SOCKET, SocketOption.REUSEADDR, true); + socket.bind(new UnixAddress(socketFile)); + setAttributes(socketFile, S_IRUSR | S_IWUSR); + info("Listening at ", socketFile); + } socket.listen(0); + scope (exit) { info("Shutting down sockets..."); socket.shutdown(SocketShutdown.BOTH); socket.close(); + if (!useTCP) + remove(socketFile); info("Sockets shut down."); } @@ -126,22 +167,28 @@ int main(string[] args) version (Posix) chdir("/"); version (LittleEndian) - immutable expectedClient = IPv4Union([127, 0, 0, 1]); - else immutable expectedClient = IPv4Union([1, 0, 0, 127]); + else + immutable expectedClient = IPv4Union([127, 0, 0, 1]); serverLoop: while (true) { auto s = socket.accept(); s.blocking = true; - // Only accept connections from localhost - IPv4Union actual; - InternetAddress clientAddr = cast(InternetAddress) s.remoteAddress(); - actual.i = clientAddr.addr; - // Shut down if somebody tries connecting from outside - enforce(actual.i = expectedClient.i, "Connection attempted from " - ~ clientAddr.toAddrString()); + if (useTCP) + { + // Only accept connections from localhost + IPv4Union actual; + InternetAddress clientAddr = cast(InternetAddress) s.remoteAddress(); + actual.i = clientAddr.addr; + // Shut down if somebody tries connecting from outside + if (actual.i != expectedClient.i) + { + fatal("Connection attempted from ", clientAddr.toAddrString()); + return 1; + } + } scope (exit) { @@ -340,9 +387,18 @@ options: Prints the version number and then exits. --port PORTNUMBER | -pPORTNUMBER - Listens on PORTNUMBER instead of the default port 9166. + Listens on PORTNUMBER instead of the default port 9166 when TCP sockets + are used. --logLevel LEVEL The logging level. Valid values are 'all', 'trace', 'info', 'warning', - 'error', 'critical', 'fatal', and 'off'`, programName); + 'error', 'critical', 'fatal', and 'off'. + + --tcp + Listen on a TCP socket instead of a UNIX domain socket. This switch + has no effect on Windows. + + --socketFile FILENAME + Use the given FILENAME as the path to the UNIX domain socket. Using + this switch is an error on Windows.`, programName); } From 83ab71cc26b45ce1954137076252808d112a532b Mon Sep 17 00:00:00 2001 From: Hackerpilot Date: Fri, 15 Jan 2016 00:49:24 -0800 Subject: [PATCH 2/7] Tests for #217 --- tests/actual.txt | 0 tests/run_tests.sh | 57 ++++++++++++++++++++++++++++++---------------- tests/tc001/run.sh | 2 +- tests/tc002/run.sh | 2 +- tests/tc003/run.sh | 4 ++-- tests/tc004/run.sh | 2 +- tests/tc005/run.sh | 2 +- tests/tc006/run.sh | 8 +++---- tests/tc007/run.sh | 4 ++-- tests/tc008/run.sh | 2 +- tests/tc009/run.sh | 6 ++--- tests/tc010/run.sh | 4 ++-- tests/tc011/run.sh | 2 +- tests/tc012/run.sh | 4 ++-- tests/tc013/run.sh | 4 ++-- tests/tc014/run.sh | 4 ++-- tests/tc015/run.sh | 4 ++-- tests/tc016/run.sh | 4 ++-- tests/tc017/run.sh | 2 +- tests/tc018/run.sh | 4 ++-- tests/tc019/run.sh | 4 ++-- tests/tc020/run.sh | 4 ++-- tests/tc021/run.sh | 2 +- tests/tc022/run.sh | 2 +- tests/tc023/run.sh | 4 ++-- tests/tc024/run.sh | 14 ++++++------ tests/tc025/run.sh | 2 +- 27 files changed, 85 insertions(+), 68 deletions(-) create mode 100644 tests/actual.txt diff --git a/tests/actual.txt b/tests/actual.txt new file mode 100644 index 0000000..e69de29 diff --git a/tests/run_tests.sh b/tests/run_tests.sh index 29a7975..cf1da05 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -11,35 +11,52 @@ pass_count=0 # Make sure that the server is shut down echo "Shutting down currently-running server..." ../bin/dcd-client --shutdown 2>/dev/null > /dev/null +../bin/dcd-client --shutdown --tcp 2>/dev/null > /dev/null sleep 1s; -# Start up the server -echo "Starting server..." -../bin/dcd-server --ignoreConfig -I $IMPORTS 2>stderr.txt > stdout.txt & -sleep 1s; +for socket in unix tcp; do + echo "Running tests for $socket sockets" -# Run tests -for testCase in tc*; do - cd $testCase; - - ./run.sh; - if [ $? -eq 0 ]; then - echo -e "${YELLOW}$testCase:${NORMAL} ... ${GREEN}Pass${NORMAL}"; - let pass_count=pass_count+1 + # Start up the server + echo "Starting server..." + if [[ $socket == "unix" ]]; then + ../bin/dcd-server --ignoreConfig -I $IMPORTS 2>stderr.txt > stdout.txt & else - echo -e "${YELLOW}$testCase:${NORMAL} ... ${RED}Fail${NORMAL}"; - let fail_count=fail_count+1 + ../bin/dcd-server --tcp --ignoreConfig -I $IMPORTS 2>stderr.txt > stdout.txt & fi + sleep 1s; - cd - > /dev/null; + # Run tests + for testCase in tc*; do + cd $testCase + + if [[ $socket == "unix" ]]; then + ./run.sh "" + else + ./run.sh "--tcp" + fi + if [[ $? -eq 0 ]]; then + echo -e "${YELLOW}$socket:$testCase:${NORMAL} ... ${GREEN}Pass${NORMAL}"; + let pass_count=pass_count+1 + else + echo -e "${YELLOW}$socket:$testCase:${NORMAL} ... ${RED}Fail${NORMAL}"; + let fail_count=fail_count+1 + fi + + cd - > /dev/null; + done + + # Shut down + echo "Shutting down server..." + if [[ $socket == "unix" ]]; then + ../bin/dcd-client --shutdown 2>/dev/null > /dev/null + else + ../bin/dcd-client --shutdown --tcp 2>/dev/null > /dev/null + fi done -# Shut down -echo "Shutting down server..." -../bin/dcd-client --shutdown 2>/dev/null > /dev/null - # Report -if [ $fail_count -eq 0 ]; then +if [[ $fail_count -eq 0 ]]; then echo -e "${GREEN}${pass_count} tests passed and ${fail_count} failed.${NORMAL}" else echo -e "${RED}${pass_count} tests passed and ${fail_count} failed.${NORMAL}" diff --git a/tests/tc001/run.sh b/tests/tc001/run.sh index 4afc788..9c7daf9 100755 --- a/tests/tc001/run.sh +++ b/tests/tc001/run.sh @@ -1,5 +1,5 @@ set -e set -u -../../bin/dcd-client file.d -c12 > actual.txt +../../bin/dcd-client $1 file.d -c12 > actual.txt diff actual.txt expected.txt diff --git a/tests/tc002/run.sh b/tests/tc002/run.sh index 5653647..0bcbfde 100755 --- a/tests/tc002/run.sh +++ b/tests/tc002/run.sh @@ -1,5 +1,5 @@ set -e set -u -../../bin/dcd-client file.d -c52 > actual.txt +../../bin/dcd-client $1 file.d -c52 > actual.txt diff actual.txt expected.txt diff --git a/tests/tc003/run.sh b/tests/tc003/run.sh index f26e2bf..24f3602 100755 --- a/tests/tc003/run.sh +++ b/tests/tc003/run.sh @@ -1,8 +1,8 @@ set -e set -u -../../bin/dcd-client file.d -c839 > actual1.txt +../../bin/dcd-client $1 file.d -c839 > actual1.txt diff actual1.txt expected1.txt -../../bin/dcd-client file.d -c862 > actual2.txt +../../bin/dcd-client $1 file.d -c862 > actual2.txt diff actual2.txt expected2.txt diff --git a/tests/tc004/run.sh b/tests/tc004/run.sh index 0fe8f48..4c55c94 100755 --- a/tests/tc004/run.sh +++ b/tests/tc004/run.sh @@ -1,5 +1,5 @@ set -e set -u -../../bin/dcd-client file.d -c13 > actual.txt +../../bin/dcd-client $1 file.d -c13 > actual.txt diff actual.txt expected.txt diff --git a/tests/tc005/run.sh b/tests/tc005/run.sh index e78def1..c3b3062 100755 --- a/tests/tc005/run.sh +++ b/tests/tc005/run.sh @@ -1,5 +1,5 @@ set -e set -u -../../bin/dcd-client file.d -c154 > actual.txt +../../bin/dcd-client $1 file.d -c154 > actual.txt diff actual.txt expected.txt diff --git a/tests/tc006/run.sh b/tests/tc006/run.sh index 78a2a09..7b80b64 100755 --- a/tests/tc006/run.sh +++ b/tests/tc006/run.sh @@ -1,14 +1,14 @@ set -e set -u -../../bin/dcd-client file.d -c184 > actual1.txt +../../bin/dcd-client $1 file.d -c184 > actual1.txt diff actual1.txt expected1.txt -../../bin/dcd-client file.d -c199 > actual2.txt +../../bin/dcd-client $1 file.d -c199 > actual2.txt diff actual2.txt expected2.txt -../../bin/dcd-client file.d -c216 > actual3.txt +../../bin/dcd-client $1 file.d -c216 > actual3.txt diff actual3.txt expected3.txt -../../bin/dcd-client file.d -c231 > actual4.txt +../../bin/dcd-client $1 file.d -c231 > actual4.txt diff actual4.txt expected4.txt diff --git a/tests/tc007/run.sh b/tests/tc007/run.sh index 0bc1745..e6c624c 100755 --- a/tests/tc007/run.sh +++ b/tests/tc007/run.sh @@ -1,8 +1,8 @@ set -e set -u -../../bin/dcd-client file.d -c97 > actual1.txt +../../bin/dcd-client $1 file.d -c97 > actual1.txt diff actual1.txt expected1.txt -../../bin/dcd-client file.d -c130 > actual2.txt +../../bin/dcd-client $1 file.d -c130 > actual2.txt diff actual2.txt expected2.txt diff --git a/tests/tc008/run.sh b/tests/tc008/run.sh index fc40d3c..224788d 100755 --- a/tests/tc008/run.sh +++ b/tests/tc008/run.sh @@ -1,5 +1,5 @@ set -e set -u -../../bin/dcd-client file.d -c113 > actual1.txt +../../bin/dcd-client $1 file.d -c113 > actual1.txt diff actual1.txt expected1.txt diff --git a/tests/tc009/run.sh b/tests/tc009/run.sh index d7e9ea1..4c52ea7 100755 --- a/tests/tc009/run.sh +++ b/tests/tc009/run.sh @@ -1,11 +1,11 @@ set -e set -u -../../bin/dcd-client file.d -c83 > actual1.txt +../../bin/dcd-client $1 file.d -c83 > actual1.txt diff actual1.txt expected1.txt -../../bin/dcd-client file.d -c93 > actual2.txt +../../bin/dcd-client $1 file.d -c93 > actual2.txt diff actual2.txt expected2.txt -../../bin/dcd-client file.d -c148 > actual3.txt +../../bin/dcd-client $1 file.d -c148 > actual3.txt diff actual3.txt expected3.txt diff --git a/tests/tc010/run.sh b/tests/tc010/run.sh index 70cb4bf..a9cfee0 100755 --- a/tests/tc010/run.sh +++ b/tests/tc010/run.sh @@ -6,12 +6,12 @@ cp testfile1_old.d ../imports/testfile1.d # than one second sleep 1s; -../../bin/dcd-client file.d -c84 > actual1.txt +../../bin/dcd-client $1 file.d -c84 > actual1.txt diff actual1.txt expected1.txt cp testfile1_new.d ../imports/testfile1.d # Same here sleep 1s; -../../bin/dcd-client file.d -c84 > actual2.txt +../../bin/dcd-client $1 file.d -c84 > actual2.txt diff actual2.txt expected2.txt diff --git a/tests/tc011/run.sh b/tests/tc011/run.sh index 8fae6ed..d4f6489 100755 --- a/tests/tc011/run.sh +++ b/tests/tc011/run.sh @@ -1,5 +1,5 @@ set -e set -u -../../bin/dcd-client file.d -c48 > actual1.txt +../../bin/dcd-client $1 file.d -c48 > actual1.txt diff actual1.txt expected1.txt diff --git a/tests/tc012/run.sh b/tests/tc012/run.sh index a82297c..a79e8a3 100755 --- a/tests/tc012/run.sh +++ b/tests/tc012/run.sh @@ -1,8 +1,8 @@ set -e set -u -../../bin/dcd-client file.d -c35 > actual1.txt +../../bin/dcd-client $1 file.d -c35 > actual1.txt diff actual1.txt expected1.txt -../../bin/dcd-client file.d -c61 > actual2.txt +../../bin/dcd-client $1 file.d -c61 > actual2.txt diff actual2.txt expected2.txt diff --git a/tests/tc013/run.sh b/tests/tc013/run.sh index 7324a02..64c65a7 100755 --- a/tests/tc013/run.sh +++ b/tests/tc013/run.sh @@ -1,8 +1,8 @@ set -e set -u -../../bin/dcd-client file.d -c187 > actual1.txt +../../bin/dcd-client $1 file.d -c187 > actual1.txt diff actual1.txt expected1.txt -../../bin/dcd-client file.d -c211 > actual2.txt +../../bin/dcd-client $1 file.d -c211 > actual2.txt diff actual2.txt expected2.txt diff --git a/tests/tc014/run.sh b/tests/tc014/run.sh index 032b74c..7883039 100755 --- a/tests/tc014/run.sh +++ b/tests/tc014/run.sh @@ -6,12 +6,12 @@ cp testfile2_old.d ../imports/testfile2.d # than one second sleep 1s; -../../bin/dcd-client file.d -c39 > actual1.txt +../../bin/dcd-client $1 file.d -c39 > actual1.txt diff actual1.txt expected1.txt cp testfile2_new.d ../imports/testfile2.d # Same here sleep 1s; -../../bin/dcd-client file.d -c39 > actual2.txt +../../bin/dcd-client $1 file.d -c39 > actual2.txt diff actual2.txt expected2.txt diff --git a/tests/tc015/run.sh b/tests/tc015/run.sh index 6ab4dc2..16cb5b7 100755 --- a/tests/tc015/run.sh +++ b/tests/tc015/run.sh @@ -1,8 +1,8 @@ set -e set -u -../../bin/dcd-client file1.d -c84 > actual1.txt +../../bin/dcd-client $1 file1.d -c84 > actual1.txt diff actual1.txt expected1.txt -../../bin/dcd-client file2.d -c73 > actual2.txt +../../bin/dcd-client $1 file2.d -c73 > actual2.txt diff actual2.txt expected2.txt diff --git a/tests/tc016/run.sh b/tests/tc016/run.sh index a3311a4..446f354 100755 --- a/tests/tc016/run.sh +++ b/tests/tc016/run.sh @@ -1,8 +1,8 @@ set -e set -u -../../bin/dcd-client file.d -c24 > actual1.txt +../../bin/dcd-client $1 file.d -c24 > actual1.txt diff actual1.txt expected1.txt -../../bin/dcd-client file.d -c57 > actual2.txt +../../bin/dcd-client $1 file.d -c57 > actual2.txt diff actual2.txt expected2.txt diff --git a/tests/tc017/run.sh b/tests/tc017/run.sh index 5ffe242..e55e675 100755 --- a/tests/tc017/run.sh +++ b/tests/tc017/run.sh @@ -1,5 +1,5 @@ set -e set -u -../../bin/dcd-client file.d -c33 > actual.txt +../../bin/dcd-client $1 file.d -c33 > actual.txt diff actual.txt expected.txt diff --git a/tests/tc018/run.sh b/tests/tc018/run.sh index 545cb43..3a59839 100755 --- a/tests/tc018/run.sh +++ b/tests/tc018/run.sh @@ -1,8 +1,8 @@ set -e set -u -../../bin/dcd-client file.d -c61 > actual1.txt +../../bin/dcd-client $1 file.d -c61 > actual1.txt diff actual1.txt expected1.txt -../../bin/dcd-client file.d -c88 > actual2.txt +../../bin/dcd-client $1 file.d -c88 > actual2.txt diff actual2.txt expected2.txt diff --git a/tests/tc019/run.sh b/tests/tc019/run.sh index 83f690b..7247b9c 100755 --- a/tests/tc019/run.sh +++ b/tests/tc019/run.sh @@ -1,8 +1,8 @@ set -e set -u -../../bin/dcd-client file.d -c84 > actual1.txt +../../bin/dcd-client $1 file.d -c84 > actual1.txt diff actual1.txt expected1.txt -../../bin/dcd-client file.d -c111 > actual2.txt +../../bin/dcd-client $1 file.d -c111 > actual2.txt diff actual2.txt expected2.txt diff --git a/tests/tc020/run.sh b/tests/tc020/run.sh index 8751e55..49dbb3d 100755 --- a/tests/tc020/run.sh +++ b/tests/tc020/run.sh @@ -1,8 +1,8 @@ set -e set -u -../../bin/dcd-client file.d -c159 > actual1.txt +../../bin/dcd-client $1 file.d -c159 > actual1.txt diff actual1.txt expected1.txt -../../bin/dcd-client file.d -c199 > actual2.txt +../../bin/dcd-client $1 file.d -c199 > actual2.txt diff actual2.txt expected2.txt diff --git a/tests/tc021/run.sh b/tests/tc021/run.sh index 03fe27b..f64af43 100755 --- a/tests/tc021/run.sh +++ b/tests/tc021/run.sh @@ -1,5 +1,5 @@ set -e set -u -../../bin/dcd-client file.d -c1 > actual.txt +../../bin/dcd-client $1 file.d -c1 > actual.txt diff actual.txt expected.txt diff --git a/tests/tc022/run.sh b/tests/tc022/run.sh index 7964eb9..6e2b067 100755 --- a/tests/tc022/run.sh +++ b/tests/tc022/run.sh @@ -1,5 +1,5 @@ set -e set -u -../../bin/dcd-client file.d -c16 > actual.txt +../../bin/dcd-client $1 file.d -c16 > actual.txt diff actual.txt expected.txt diff --git a/tests/tc023/run.sh b/tests/tc023/run.sh index 86ea69f..ef46816 100755 --- a/tests/tc023/run.sh +++ b/tests/tc023/run.sh @@ -1,8 +1,8 @@ set -e set -u -../../bin/dcd-client file.d -c117 > actual1.txt +../../bin/dcd-client $1 file.d -c117 > actual1.txt diff actual1.txt expected1.txt -../../bin/dcd-client file.d -c89 > actual2.txt +../../bin/dcd-client $1 file.d -c89 > actual2.txt diff actual2.txt expected2.txt diff --git a/tests/tc024/run.sh b/tests/tc024/run.sh index e480213..71eeeb2 100755 --- a/tests/tc024/run.sh +++ b/tests/tc024/run.sh @@ -1,23 +1,23 @@ set -e set -u -../../bin/dcd-client file.d -c286 -d > actual1.txt +../../bin/dcd-client $1 file.d -c286 -d > actual1.txt diff actual1.txt expected1.txt -../../bin/dcd-client file.d -c290 -d > actual2.txt +../../bin/dcd-client $1 file.d -c290 -d > actual2.txt diff actual2.txt expected2.txt -../../bin/dcd-client file.d -c294 -d > actual3.txt +../../bin/dcd-client $1 file.d -c294 -d > actual3.txt diff actual3.txt expected3.txt -../../bin/dcd-client file.d -c298 -d> actual4.txt +../../bin/dcd-client $1 file.d -c298 -d> actual4.txt diff actual4.txt expected4.txt -../../bin/dcd-client file.d -c302 -d> actual5.txt +../../bin/dcd-client $1 file.d -c302 -d> actual5.txt diff actual5.txt expected5.txt -../../bin/dcd-client file.d -c306 -d> actual6.txt +../../bin/dcd-client $1 file.d -c306 -d> actual6.txt diff actual6.txt expected6.txt -../../bin/dcd-client file.d -c313 -d> actual7.txt +../../bin/dcd-client $1 file.d -c313 -d> actual7.txt diff actual7.txt expected7.txt diff --git a/tests/tc025/run.sh b/tests/tc025/run.sh index 02e6232..65ff518 100755 --- a/tests/tc025/run.sh +++ b/tests/tc025/run.sh @@ -1,5 +1,5 @@ set -e set -u -../../bin/dcd-client file.d -c94 > actual1.txt +../../bin/dcd-client $1 file.d -c94 > actual1.txt diff actual1.txt expected1.txt From 12e5b25e621cc77da2027b9c6f3d3cfb32695c34 Mon Sep 17 00:00:00 2001 From: Hackerpilot Date: Fri, 15 Jan 2016 00:49:39 -0800 Subject: [PATCH 3/7] Documentation for #217 --- README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/README.md b/README.md index 32af8ac..8eb59aa 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,23 @@ the issue.) 1. ```dub build --build=release --config=server``` +# Sockets +## TCP +On Windows DCD will use TCP sockets to communicate between the client and server. +Other operating systems can use TCP sockets if the client and server use the `--tcp` +command-line switch. + +## UNIX domain sockets +Operating systems that support UNIX domain sockets will use them by default. + +#### OSX +The socket will be created at `/var/tmp/dcd-${UID}.socket` + +#### Linux/BSD +The client and server will attempt to create the socket in the following locations: +* `${XDG_RUNTIME_DIR}/dcd.socket` +* `/tmp/dcd-${UID}.socket` + # Client Because DCD is designed to be used from a text editor, this section is written primarily for plugin authors. From 7186c70bdc996ae0c64d14eb815702a0d81b62f4 Mon Sep 17 00:00:00 2001 From: Hackerpilot Date: Fri, 15 Jan 2016 00:54:15 -0800 Subject: [PATCH 4/7] Update man pages for #217 --- man1/dcd-client.1 | 19 +++++++++++++++++-- man1/dcd-server.1 | 35 +++++++++++++++++++++++++++++++---- 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/man1/dcd-client.1 b/man1/dcd-client.1 index 9b2bb9c..e37e131 100644 --- a/man1/dcd-client.1 +++ b/man1/dcd-client.1 @@ -1,4 +1,4 @@ -.TH dcd-client 1 "Oct 30 2015" "" https://github.com/Hackerpilot/DCD +.TH dcd-client 1 "Jan 15 2016" "" https://github.com/Hackerpilot/DCD .SH NAME dcd-client \- autocompletion client for the D programming language .PD @@ -6,6 +6,8 @@ dcd-client \- autocompletion client for the D programming language .SY dcd-client .OP "\-c, \-\-cursorPos" cursorPosition .OP "\-p, \-\-port" portNumber +.OP \-\-tcp +.OP \-\-socketFile filePath .OP "\-I" directory .OP "\-h, \-\-help" .OP "\-l, \-\-symbolLocation" @@ -34,7 +36,20 @@ position is measured in bytes from the beginning of the source code. .RS Choose the port number on which .B dcd-client -listens. +listens. This has no effect unless +.B dcd-client +is being run on Windows or the \-\-tcp switch is used. +.RE +.B \-\-tcp +.RS +Listen on a TCP socket instead of a UNIX domain socket. This is the default on +Windows. +.RE +.B \-\-socketFile +.I filePath +.RS +Set the path to use for the UNIX domain socket. Has no effect if the \-\-tcp +switch is used. .RE .B \-I .I directory diff --git a/man1/dcd-server.1 b/man1/dcd-server.1 index ed46e35..3976d6c 100644 --- a/man1/dcd-server.1 +++ b/man1/dcd-server.1 @@ -1,4 +1,4 @@ -.TH dcd-server 1 "Oct 30 2015" "" https://github.com/Hackerpilot/DCD +.TH dcd-server 1 "Jan 15 2016" "" https://github.com/Hackerpilot/DCD .SH NAME dcd-server \- autocompletion server for the D programming language .PD @@ -6,6 +6,8 @@ dcd-server \- autocompletion server for the D programming language .SY dcd-server .OP \-I directory .OP \-p|\-\-port portNumber +.OP \-\-tcp +.OP \-\-socketFile filePath .OP \-\-logLevel level .OP \-h|\-\-help .OP \-\-version @@ -20,7 +22,20 @@ dcd-server \- autocompletion server for the D programming language .RS Choose the port number on which .B dcd-server -listens. +listens. This has no effect unless +.B dcd-server +is being run on Windows or the \-\-tcp switch is used. +.RE +.B \-\-tcp +.RS +Listen on a TCP socket instead of a UNIX domain socket. This is the default on +Windows. +.RE +.B \-\-socketFile +.I filePath +.RS +Set the path to use for the UNIX domain socket. Has no effect if the \-\-tcp +switch is used. .RE .B \-\-logLevel .I level @@ -60,10 +75,10 @@ This file should be placed in one of the following locations: .I /etc/dcd.conf .RE .IP \(bu -.I $XDG_CONFIG_HOME/dcd/dcd.conf +.I ${XDG_CONFIG_HOME}/dcd/dcd.conf .RE .IP \(bu -.I $HOME/.config/dcd/dcd.conf +.I ${HOME}/.config/dcd/dcd.conf .RE Each line in the file should be a path to search for D source files. A line in @@ -73,6 +88,18 @@ is equivalent to passing that same line to with the .I -I option. Lines that start with the '#' character are ignored. + +Unless the \-\-tcp switch is used, +.B dcd-server +will default to communicating with the client over a UNIX domain socket. +.B dcd-server +will attempt to create the socket in the following locations: +.IP \(bu +.I ${XDG_RUNTIME_DIR}/dcd.socket +.RE +.IP \(bu +.I /tmp/dcd-${UID}.socket +.RE .SH AUTHOR Written by Brian Schott (@Hackerpilot on Github) .PD From 3f5a1eaebffb180ab9e8a29c6a4013c53f711b94 Mon Sep 17 00:00:00 2001 From: Hackerpilot Date: Fri, 15 Jan 2016 01:13:29 -0800 Subject: [PATCH 5/7] Fix #218 and update version to 0.7.5 --- src/common/dcd_version.d | 2 +- src/server/autocomplete.d | 2 ++ tests/tc026/expected1.txt | 0 tests/tc026/file.d | 7 +++++++ tests/tc026/run.sh | 5 +++++ 5 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 tests/tc026/expected1.txt create mode 100644 tests/tc026/file.d create mode 100755 tests/tc026/run.sh diff --git a/src/common/dcd_version.d b/src/common/dcd_version.d index 16e051c..50963a8 100644 --- a/src/common/dcd_version.d +++ b/src/common/dcd_version.d @@ -21,7 +21,7 @@ module common.dcd_version; /** * Human-readable version number */ -enum DCD_VERSION = "v0.7.4"; +enum DCD_VERSION = "v0.7.5"; version (Windows) {} else version (built_with_dub) {} diff --git a/src/server/autocomplete.d b/src/server/autocomplete.d index 095d160..09ff5d9 100644 --- a/src/server/autocomplete.d +++ b/src/server/autocomplete.d @@ -751,6 +751,8 @@ DSymbol*[] getSymbolsByTokenChain(T)(Scope* completionScope, // returns void. void filterProperties() @nogc @safe { + if (symbols.length == 0) + return; if (symbols[0].kind == CompletionKind.functionName || symbols[0].qualifier == SymbolQualifier.func) { diff --git a/tests/tc026/expected1.txt b/tests/tc026/expected1.txt new file mode 100644 index 0000000..e69de29 diff --git a/tests/tc026/file.d b/tests/tc026/file.d new file mode 100644 index 0000000..5fdfbcb --- /dev/null +++ b/tests/tc026/file.d @@ -0,0 +1,7 @@ +struct Issue281 {} + +unittest +{ + Issue281 i; + i.abcde( +} \ No newline at end of file diff --git a/tests/tc026/run.sh b/tests/tc026/run.sh new file mode 100755 index 0000000..c9bc7d0 --- /dev/null +++ b/tests/tc026/run.sh @@ -0,0 +1,5 @@ +set -e +set -u + +../../bin/dcd-client file.d -c53 > actual1.txt +diff actual1.txt expected1.txt From d88ed636ba16b3a116e368dc6f10dc6b08ca1166 Mon Sep 17 00:00:00 2001 From: Hackerpilot Date: Fri, 15 Jan 2016 01:48:53 -0800 Subject: [PATCH 6/7] Update test case for new CLI options --- tests/tc026/run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tc026/run.sh b/tests/tc026/run.sh index c9bc7d0..36de925 100755 --- a/tests/tc026/run.sh +++ b/tests/tc026/run.sh @@ -1,5 +1,5 @@ set -e set -u -../../bin/dcd-client file.d -c53 > actual1.txt +../../bin/dcd-client $1 file.d -c53 > actual1.txt diff actual1.txt expected1.txt From b3dc41f2f8ff1a56e6d8c16c62d9325e7e101e9b Mon Sep 17 00:00:00 2001 From: Hackerpilot Date: Tue, 19 Jan 2016 09:20:11 -0800 Subject: [PATCH 7/7] Increase version number --- src/common/dcd_version.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/dcd_version.d b/src/common/dcd_version.d index 50963a8..01ca019 100644 --- a/src/common/dcd_version.d +++ b/src/common/dcd_version.d @@ -21,7 +21,7 @@ module common.dcd_version; /** * Human-readable version number */ -enum DCD_VERSION = "v0.7.5"; +enum DCD_VERSION = "v0.8.0-alpha1"; version (Windows) {} else version (built_with_dub) {}