<commit_before>/*
 * Copyright (c) 2008 Aconex.  All Rights Reserved.
 * 
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 * 
 * This library 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 Lesser General Public
 * License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA.
 */
#include "pmapi.h"
#include "impl.h"
#include <winbase.h>
#include <psapi.h>

#define MILLISEC_PER_SEC	1000
#define NANOSEC_PER_MILLISEC	1000000
#define NANOSEC_BOUND		(1000000000-1)

int
__pmProcessExists(pid_t pid)
{
    HANDLE ph = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
    if (ph == NULL)
	return 0;
    CloseHandle(ph);
    return 1;
}

int
__pmProcessTerminate(pid_t pid, int force)
{
    HANDLE ph = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
    if (ph != NULL) {
	TerminateProcess(ph, 0);
	CloseHandle(ph);
	return 0;
    }
    return -ESRCH;
}

int
__pmProcessCreate(char **argv, int *infd, int *outfd)
{
    HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr;
    PROCESS_INFORMATION piProcInfo; 
    SECURITY_ATTRIBUTES saAttr; 
    STARTUPINFO siStartInfo;
    LPTSTR cmdline = NULL;
    char *command;
    int sz = 0;
 
    ZeroMemory(&saAttr, sizeof(SECURITY_ATTRIBUTES));
    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 
    saAttr.bInheritHandle = TRUE;	/* pipe handles are inherited. */
    saAttr.lpSecurityDescriptor = NULL; 

    /*
     * Create a pipe for communication with the child process.
     * Ensure that the read handle to the child process's pipe for
     * STDOUT is not inherited.
     */
    if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
	return -1;
    SetHandleInformation(hChildStdoutRd, HANDLE_FLAG_INHERIT, 0);

    /*
     * Create a pipe for the child process's STDIN.
     * Ensure that the write handle to the child process's pipe for
     * STDIN is not inherited.
     */
    if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0)) {
	CloseHandle(hChildStdoutRd);
	CloseHandle(hChildStdoutWr);
	return -1;
    }
    SetHandleInformation(hChildStdinWr, HANDLE_FLAG_INHERIT, 0);

    ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION));
    ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
    siStartInfo.cb = sizeof(STARTUPINFO); 
    siStartInfo.hStdOutput = hChildStdoutWr;
    siStartInfo.hStdInput = hChildStdinRd;
    siStartInfo.dwFlags |= STARTF_USESTDHANDLES;

    /* Flatten the argv array for the Windows CreateProcess API */
    for (command = argv[0], sz = 0; *command; command++) {
	int length = strlen(command);
	cmdline = realloc(cmdline, sz + length + 1); /* 1space or 1null */
	strcpy(&cmdline[sz], command);
	cmdline[sz + length] = ' ';
	sz += length + 1;
    }
    cmdline[sz - 1] = '\0';

    if (0 == CreateProcess(NULL, 
	cmdline,       /* command line */
	NULL,          /* process security attributes */
	NULL,          /* primary thread security attributes */
	TRUE,          /* handles are inherited */
	0,             /* creation flags */
	NULL,          /* use parent's environment */
	NULL,          /* use parent's current directory */
	&siStartInfo,  /* STARTUPINFO pointer */
	&piProcInfo))  /* receives PROCESS_INFORMATION */
    {
	CloseHandle(hChildStdinRd);
	CloseHandle(hChildStdinWr);
	CloseHandle(hChildStdoutRd);
	CloseHandle(hChildStdoutWr);
	return -1;
    }
    else {
	CloseHandle(piProcInfo.hProcess);
	CloseHandle(piProcInfo.hThread);
    }

    *infd = _open_osfhandle((intptr_t)hChildStdoutRd, _O_RDONLY);
    *outfd = _open_osfhandle((intptr_t)hChildStdinWr, _O_WRONLY);
    return 0;
}

pid_t
__pmProcessWait(pid_t pid, int nowait, int *code, int *signal)
{
    HANDLE ph;
    DWORD status;

    if (pid == (pid_t)-1 || pid == (pid_t)-2)
	return -1;
    if ((ph = OpenProcess(SYNCHRONIZE, FALSE, pid)) == NULL)
	return -1;
    if (WaitForSingleObject(ph, (DWORD)(-1L)) == WAIT_FAILED) {
	CloseHandle(ph);
	return -1;
    }
    if (GetExitCodeProcess(ph, &status)) {
	CloseHandle(ph);
	return -1;
    }
    if (code)
	*code = status;
    CloseHandle(ph);
    *signal = -1;
    return pid;
}

int
__pmProcessDataSize(unsigned long *datasize)
{
    PROCESS_MEMORY_COUNTERS pmc;
    HANDLE ph;
    int sts = -1;

    if (!datasize)
	return 0;
    *datasize = 0UL;
    ph = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId());
    if (ph == NULL)
	return sts;
    else if (GetProcessMemoryInfo(ph, &pmc, sizeof(pmc))) {
	*datasize = pmc.WorkingSetSize / 1024;
	sts = 0;
    }
    CloseHandle(ph);
    return sts;
}

int
__pmProcessRunTimes(double *usr, double *sys)
{
    ULARGE_INTEGER ul;
    FILETIME times[4];
    HANDLE ph;
    int sts = -1;

    *usr = *sys = 0.0;
    ph = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId());
    if (ph == NULL)
	return sts;
    else if (GetProcessTimes(ph, &times[0], &times[1], &times[2], &times[3])) {
	ul.LowPart = times[2].dwLowDateTime;
	ul.HighPart = times[2].dwHighDateTime;
	*sys = ul.QuadPart / 10000000.0;
	ul.LowPart = times[3].dwLowDateTime;
	ul.HighPart = times[3].dwHighDateTime;
	*usr = ul.QuadPart / 10000000.0;
	sts = 0;
    }
    CloseHandle(ph);
    return sts;
}

int
nanosleep(const struct timespec *req, struct timespec *rem)
{
    DWORD milliseconds;

    if (req->tv_sec < 0 || req->tv_nsec < 0 || req->tv_nsec > NANOSEC_BOUND) {
	errno = EINVAL;
	return -1;
    }
    milliseconds = req->tv_sec * MILLISEC_PER_SEC
			+ req->tv_nsec / NANOSEC_PER_MILLISEC;
    Sleep(milliseconds);
    if (rem)
	memset(rem, 0, sizeof(*rem));
    return 0;
}

unsigned int
sleep(unsigned int seconds)
{
    Sleep(seconds * 1000);
    return 0;
}

void setlinebuf(FILE *stream)
{
    setvbuf(stream, NULL, _IONBF, 0);	/* no line buffering in Win32 */
}

const char *
hstrerror(int error)
{
    return strerror(error);
}

long int
lrand48(void)
{
    return rand();
}

void
srand48(long int seed)
{
    srand(seed);
}

const char *
index(const char *string, int marker)
{
    const char *p;
    for (p = string; *p != '\0'; p++)
	if (*p == marker)
	    return p;
    return NULL;
}

const char *
rindex(const char *string, int marker)
{
    const char *p;
    for (p = string; *p != '\0'; p++)
	;
    for (--p; p != string; p--)
	if (*p == marker)
	    return p;
    return NULL;
}

void *
dlopen(const char *filename, int flag)
{
    return LoadLibrary(filename);
}

void *
dlsym(void *handle, const char *symbol)
{
    return GetProcAddress(handle, symbol);
}

int
dlclose(void *handle)
{
    return FreeLibrary(handle);
}

char *
dlerror(void)
{
    return strerror(GetLastError());
}

void
openlog(const char *ident, int option, int facility)
{
    /* TODO */
}

void
syslog(int priority, const char *format, ...)
{
    /* TODO */
}

void
closelog(void)
{
    /* TODO */<commit_msg>Complete the implementation of the Win32 wrapper for the syslog API routines, mapping the PCP use of those APIs to the Windows eventlog services.<commit_after>/*
 * Copyright (c) 2008 Aconex.  All Rights Reserved.
 * 
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 * 
 * This library 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 Lesser General Public
 * License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA.
 */
#include "pmapi.h"
#include "impl.h"
#include <winbase.h>
#include <psapi.h>

#define MILLISEC_PER_SEC	1000
#define NANOSEC_PER_MILLISEC	1000000
#define NANOSEC_BOUND		(1000000000-1)

int
__pmProcessExists(pid_t pid)
{
    HANDLE ph = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
    if (ph == NULL)
	return 0;
    CloseHandle(ph);
    return 1;
}

int
__pmProcessTerminate(pid_t pid, int force)
{
    HANDLE ph = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
    if (ph != NULL) {
	TerminateProcess(ph, 0);
	CloseHandle(ph);
	return 0;
    }
    return -ESRCH;
}

int
__pmProcessCreate(char **argv, int *infd, int *outfd)
{
    HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr;
    PROCESS_INFORMATION piProcInfo; 
    SECURITY_ATTRIBUTES saAttr; 
    STARTUPINFO siStartInfo;
    LPTSTR cmdline = NULL;
    char *command;
    int sz = 0;
 
    ZeroMemory(&saAttr, sizeof(SECURITY_ATTRIBUTES));
    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 
    saAttr.bInheritHandle = TRUE;	/* pipe handles are inherited. */
    saAttr.lpSecurityDescriptor = NULL; 

    /*
     * Create a pipe for communication with the child process.
     * Ensure that the read handle to the child process's pipe for
     * STDOUT is not inherited.
     */
    if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
	return -1;
    SetHandleInformation(hChildStdoutRd, HANDLE_FLAG_INHERIT, 0);

    /*
     * Create a pipe for the child process's STDIN.
     * Ensure that the write handle to the child process's pipe for
     * STDIN is not inherited.
     */
    if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0)) {
	CloseHandle(hChildStdoutRd);
	CloseHandle(hChildStdoutWr);
	return -1;
    }
    SetHandleInformation(hChildStdinWr, HANDLE_FLAG_INHERIT, 0);

    ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION));
    ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
    siStartInfo.cb = sizeof(STARTUPINFO); 
    siStartInfo.hStdOutput = hChildStdoutWr;
    siStartInfo.hStdInput = hChildStdinRd;
    siStartInfo.dwFlags |= STARTF_USESTDHANDLES;

    /* Flatten the argv array for the Windows CreateProcess API */
    for (command = argv[0], sz = 0; *command; command++) {
	int length = strlen(command);
	cmdline = realloc(cmdline, sz + length + 1); /* 1space or 1null */
	strcpy(&cmdline[sz], command);
	cmdline[sz + length] = ' ';
	sz += length + 1;
    }
    cmdline[sz - 1] = '\0';

    if (0 == CreateProcess(NULL, 
	cmdline,       /* command line */
	NULL,          /* process security attributes */
	NULL,          /* primary thread security attributes */
	TRUE,          /* handles are inherited */
	0,             /* creation flags */
	NULL,          /* use parent's environment */
	NULL,          /* use parent's current directory */
	&siStartInfo,  /* STARTUPINFO pointer */
	&piProcInfo))  /* receives PROCESS_INFORMATION */
    {
	CloseHandle(hChildStdinRd);
	CloseHandle(hChildStdinWr);
	CloseHandle(hChildStdoutRd);
	CloseHandle(hChildStdoutWr);
	return -1;
    }
    else {
	CloseHandle(piProcInfo.hProcess);
	CloseHandle(piProcInfo.hThread);
    }

    *infd = _open_osfhandle((intptr_t)hChildStdoutRd, _O_RDONLY);
    *outfd = _open_osfhandle((intptr_t)hChildStdinWr, _O_WRONLY);
    return 0;
}

pid_t
__pmProcessWait(pid_t pid, int nowait, int *code, int *signal)
{
    HANDLE ph;
    DWORD status;

    if (pid == (pid_t)-1 || pid == (pid_t)-2)
	return -1;
    if ((ph = OpenProcess(SYNCHRONIZE, FALSE, pid)) == NULL)
	return -1;
    if (WaitForSingleObject(ph, (DWORD)(-1L)) == WAIT_FAILED) {
	CloseHandle(ph);
	return -1;
    }
    if (GetExitCodeProcess(ph, &status)) {
	CloseHandle(ph);
	return -1;
    }
    if (code)
	*code = status;
    CloseHandle(ph);
    *signal = -1;
    return pid;
}

int
__pmProcessDataSize(unsigned long *datasize)
{
    PROCESS_MEMORY_COUNTERS pmc;
    HANDLE ph;
    int sts = -1;

    if (!datasize)
	return 0;
    *datasize = 0UL;
    ph = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId());
    if (ph == NULL)
	return sts;
    else if (GetProcessMemoryInfo(ph, &pmc, sizeof(pmc))) {
	*datasize = pmc.WorkingSetSize / 1024;
	sts = 0;
    }
    CloseHandle(ph);
    return sts;
}

int
__pmProcessRunTimes(double *usr, double *sys)
{
    ULARGE_INTEGER ul;
    FILETIME times[4];
    HANDLE ph;
    int sts = -1;

    *usr = *sys = 0.0;
    ph = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId());
    if (ph == NULL)
	return sts;
    else if (GetProcessTimes(ph, &times[0], &times[1], &times[2], &times[3])) {
	ul.LowPart = times[2].dwLowDateTime;
	ul.HighPart = times[2].dwHighDateTime;
	*sys = ul.QuadPart / 10000000.0;
	ul.LowPart = times[3].dwLowDateTime;
	ul.HighPart = times[3].dwHighDateTime;
	*usr = ul.QuadPart / 10000000.0;
	sts = 0;
    }
    CloseHandle(ph);
    return sts;
}

int
nanosleep(const struct timespec *req, struct timespec *rem)
{
    DWORD milliseconds;

    if (req->tv_sec < 0 || req->tv_nsec < 0 || req->tv_nsec > NANOSEC_BOUND) {
	errno = EINVAL;
	return -1;
    }
    milliseconds = req->tv_sec * MILLISEC_PER_SEC
			+ req->tv_nsec / NANOSEC_PER_MILLISEC;
    Sleep(milliseconds);
    if (rem)
	memset(rem, 0, sizeof(*rem));
    return 0;
}

unsigned int
sleep(unsigned int seconds)
{
    Sleep(seconds * 1000);
    return 0;
}

void setlinebuf(FILE *stream)
{
    setvbuf(stream, NULL, _IONBF, 0);	/* no line buffering in Win32 */
}

const char *
hstrerror(int error)
{
    return strerror(error);
}

long int
lrand48(void)
{
    return rand();
}

void
srand48(long int seed)
{
    srand(seed);
}

const char *
index(const char *string, int marker)
{
    const char *p;
    for (p = string; *p != '\0'; p++)
	if (*p == marker)
	    return p;
    return NULL;
}

const char *
rindex(const char *string, int marker)
{
    const char *p;
    for (p = string; *p != '\0'; p++)
	;
    for (--p; p != string; p--)
	if (*p == marker)
	    return p;
    return NULL;
}

void *
dlopen(const char *filename, int flag)
{
    return LoadLibrary(filename);
}

void *
dlsym(void *handle, const char *symbol)
{
    return GetProcAddress(handle, symbol);
}

int
dlclose(void *handle)
{
    return FreeLibrary(handle);
}

char *
dlerror(void)
{
    return strerror(GetLastError());
}

static HANDLE eventlog;
static char *eventlogPrefix;

void
openlog(const char *ident, int option, int facility)
{
    if (eventlog)
	closelog();
    eventlog = RegisterEventSource(NULL, "Application");
    if (ident)
	eventlogPrefix = strdup(ident);
}

void
syslog(int priority, const char *format, ...)
{
    va_list	arg;
    LPCSTR	msgptr;
    char	logmsg[2048];
    char	*p = logmsg;
    int		offset = 0;
    DWORD	eventlogPriority;

    va_start(arg, format);

    if (!eventlog)
	openlog(NULL, 0, 0);

    if (eventlogPrefix)
	offset = snprintf(p, sizeof(logmsg), "%s: ", eventlogPrefix);

    switch (priority) {
    case LOG_EMERG:
    case LOG_CRIT:
    case LOG_ERR:
	eventlogPriority = EVENTLOG_ERROR_TYPE;
	break;
    case LOG_WARNING:
    case LOG_ALERT:
	eventlogPriority = EVENTLOG_WARNING_TYPE;
	break;
    case LOG_NOTICE:
    case LOG_DEBUG:
    case LOG_INFO:
    default:
	eventlogPriority = EVENTLOG_INFORMATION_TYPE;
	break;
    }
    msgptr = logmsg;
    snprintf(p + offset, sizeof(logmsg) - offset, format, arg);
    ReportEvent(eventlog, eventlogPriority, 0, 0, NULL, 1, 0, &msgptr, NULL);
    va_end(arg);
}

void
closelog(void)
{
    if (eventlog) {
	DeregisterEventSource(eventlog);
	if (eventlogPrefix)
	    free(eventlogPrefix);
	eventlogPrefix = NULL;
    }
    eventlog = NULL;
{'fraction_non_alphanumeric': 0.12013234919826928, 'fraction_numerical': 0.017498091117332654, 'mean_word_length': 3.3670464017782717, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 6, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3706072', 'n_tokens_mistral': 5849, 'n_tokens_neox': 5564, 'n_words': 1510}