mirror of https://github.com/nodejs/node.git
win: Duplicate platform_cygwin.cc into platform_win32.cc
parent
fa94d55f87
commit
5ea2a61596
|
@ -0,0 +1,246 @@
|
|||
#include "node.h"
|
||||
#include "platform.h"
|
||||
|
||||
#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[]) {
|
||||
return 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) {
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int OS::GetMemory(size_t *rss, size_t *vsize) {
|
||||
FILE *f = fopen("/proc/self/stat", "r");
|
||||
if (!f) return -1;
|
||||
|
||||
int itmp;
|
||||
char ctmp;
|
||||
size_t page_size = getpagesize();
|
||||
|
||||
/* PID */
|
||||
if (fscanf(f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* Exec file */
|
||||
if (fscanf (f, "%s ", buf) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* State */
|
||||
if (fscanf (f, "%c ", &ctmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* Parent process */
|
||||
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* Process group */
|
||||
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* Session id */
|
||||
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* TTY */
|
||||
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* TTY owner process group */
|
||||
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* Flags */
|
||||
if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* Minor faults (no memory page) */
|
||||
if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* Minor faults, children */
|
||||
if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* Major faults (memory page faults) */
|
||||
if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* Major faults, children */
|
||||
if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* utime */
|
||||
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* stime */
|
||||
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* utime, children */
|
||||
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* stime, children */
|
||||
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* jiffies remaining in current time slice */
|
||||
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* 'nice' value */
|
||||
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* jiffies until next timeout */
|
||||
if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* jiffies until next SIGALRM */
|
||||
if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* start time (jiffies since system boot) */
|
||||
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
|
||||
/* Virtual memory size */
|
||||
if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
*vsize = (size_t) itmp;
|
||||
|
||||
/* Resident set size */
|
||||
if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
*rss = (size_t) itmp * page_size;
|
||||
|
||||
/* rlim */
|
||||
if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* Start of text */
|
||||
if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* End of text */
|
||||
if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* Start of stack */
|
||||
if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
|
||||
fclose (f);
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
fclose (f);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int OS::GetExecutablePath(char* buffer, size_t* size) {
|
||||
*size = readlink("/proc/self/exe", buffer, *size - 1);
|
||||
if (*size <= 0) return -1;
|
||||
buffer[*size] = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace node
|
Loading…
Reference in New Issue