Created
August 13, 2010 01:48
-
-
Save piscisaureus/522105 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 33f60624e24d66d7bc601c0e51ae361beb88a4e6 Mon Sep 17 00:00:00 2001 | |
From: Bert Belder <bertbelder@gmail.com> | |
Date: Fri, 13 Aug 2010 03:45:51 +0200 | |
Subject: [PATCH] Implement process.title for cygwin | |
--- | |
src/platform_cygwin.cc | 136 ++++++++++++++++++++++++++++++++++++++++++++++- | |
1 files changed, 133 insertions(+), 3 deletions(-) | |
diff --git a/src/platform_cygwin.cc b/src/platform_cygwin.cc | |
index f2a1e84..2db0b87 100644 | |
--- a/src/platform_cygwin.cc | |
+++ b/src/platform_cygwin.cc | |
@@ -3,11 +3,31 @@ | |
#include <sys/param.h> // for MAXPATHLEN | |
#include <unistd.h> // getpagesize | |
+#include <windows.h> | |
namespace node { | |
static char buf[MAXPATHLEN + 1]; | |
+static char *process_title = NULL; | |
+ | |
+ | |
+// Does the about the same as perror(), but for windows api functions | |
+static void _winapi_perror(const char* prefix = NULL) { | |
+ DWORD errno = GetLastError(); | |
+ char *errmsg; | |
+ | |
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, | |
+ NULL, errno, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&errmsg, 0, NULL); | |
+ | |
+ // FormatMessage messages include a newline character | |
+ | |
+ if (prefix) { | |
+ fprintf(stderr, "%s: %s", prefix, errmsg); | |
+ } else { | |
+ fputs(errmsg, stderr); | |
+ } | |
+} | |
char** OS::SetupArgs(int argc, char *argv[]) { | |
@@ -16,13 +36,123 @@ char** OS::SetupArgs(int argc, char *argv[]) { | |
void OS::SetProcessTitle(char *title) { | |
- ; | |
+ // We need to convert _title_ to UTF-16 first, because that's what windows uses internally. | |
+ // It would be more efficient to use the UTF-16 value that we can obtain from v8, | |
+ // but it's not accessible from here. | |
+ | |
+ // Max title length; according to the specs it should be 64K but in practice it's a little over 30000, | |
+ // but who needs titles that long anyway? | |
+ const int MAX_TITLE_LENGTH = 30001; | |
+ | |
+ int length; | |
+ WCHAR *title_w; | |
+ | |
+ // Find out how big the buffer for the wide-char title must be | |
+ length = MultiByteToWideChar(CP_UTF8, 0, title, -1, NULL, 0); | |
+ if (!length) { | |
+ _winapi_perror("MultiByteToWideChar"); | |
+ return; | |
+ } | |
+ | |
+ // Convert to wide-char string | |
+ title_w = new WCHAR[length]; | |
+ length = MultiByteToWideChar(CP_UTF8, 0, title, -1, title_w, length); | |
+ if (!length) { | |
+ _winapi_perror("MultiByteToWideChar"); | |
+ delete title_w; | |
+ return; | |
+ }; | |
+ | |
+ // If the title must be truncated insert a \0 terminator there | |
+ if (length > MAX_TITLE_LENGTH) { | |
+ title_w[MAX_TITLE_LENGTH - 1] = *L"\0"; | |
+ } | |
+ | |
+ if (!SetConsoleTitleW(title_w)) { | |
+ _winapi_perror("SetConsoleTitleW"); | |
+ } | |
+ | |
+ free(process_title); | |
+ process_title = strdup(title); | |
+ | |
+ delete title_w; | |
+} | |
+ | |
+ | |
+static inline char* _getProcessTitle() { | |
+ WCHAR *title_w; | |
+ char *title; | |
+ int length, length_w; | |
+ | |
+ length_w = GetConsoleTitleW(L"\0", sizeof(WCHAR)); | |
+ | |
+ // If length is zero, there may be an error or the title may be empty | |
+ if (!length_w) { | |
+ if (GetLastError()) { | |
+ _winapi_perror("GetConsoleTitleW"); | |
+ return NULL; | |
+ } | |
+ else { | |
+ // The title is empty, so return empty string | |
+ process_title = strdup("\0"); | |
+ return process_title; | |
+ } | |
+ } | |
+ | |
+ // Room for \0 terminator | |
+ length_w++; | |
+ | |
+ title_w = new WCHAR[length_w]; | |
+ | |
+ if (!GetConsoleTitleW(title_w, length_w * sizeof(WCHAR))) { | |
+ _winapi_perror("GetConsoleTitleW"); | |
+ delete title_w; | |
+ return NULL; | |
+ } | |
+ | |
+ // Find out what the size of the buffer is that we need | |
+ length = WideCharToMultiByte(CP_UTF8, 0, title_w, length_w, NULL, 0, NULL, NULL); | |
+ if (!length) { | |
+ _winapi_perror("WideCharToMultiByte"); | |
+ delete title_w; | |
+ return NULL; | |
+ } | |
+ | |
+ title = (char *) malloc(length); | |
+ if (!title) { | |
+ perror("malloc"); | |
+ delete title_w; | |
+ return NULL; | |
+ } | |
+ | |
+ // Do utf16 -> utf8 conversion here | |
+ if (!WideCharToMultiByte(CP_UTF8, 0, title_w, -1, title, length, NULL, NULL)) { | |
+ _winapi_perror("WideCharToMultiByte"); | |
+ delete title_w; | |
+ free(title); | |
+ return NULL; | |
+ } | |
+ | |
+ delete title_w; | |
+ | |
+ return title; | |
} | |
const char* OS::GetProcessTitle(int *len) { | |
- *len = 0; | |
- return NULL; | |
+ // If the process_title was never read before nor explicitly set, | |
+ // we must query it with getConsoleTitleW | |
+ if (!process_title) { | |
+ process_title = _getProcessTitle(); | |
+ } | |
+ | |
+ if (process_title) { | |
+ *len = strlen(process_title); | |
+ return process_title; | |
+ } else { | |
+ *len = 0; | |
+ return NULL; | |
+ } | |
} | |
-- | |
1.7.0.2.msysgit.0 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment