/* This file contains functions which implement those POSIX and Linux functions
 * that MinGW and Microsoft don't provide. The implementations contain just enough
 * functionality to support fio.
 */

#include <arpa/inet.h>
#include <netinet/in.h>
#include <windows.h>
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <pthread.h>
#include <time.h>
#include <semaphore.h>
#include <sys/shm.h>
#include <sys/mman.h>
#include <sys/uio.h>
#include <sys/resource.h>
#include <sys/poll.h>
#include <sys/wait.h>
#include <setjmp.h>

#include "../os-windows.h"
#include "../../lib/hweight.h"

extern unsigned long mtime_since_now(struct timeval *);
extern void fio_gettime(struct timeval *, void *);

/* These aren't defined in the MinGW headers */
HRESULT WINAPI StringCchCopyA(
  char *pszDest,
  size_t cchDest,
  const char *pszSrc);

HRESULT WINAPI StringCchPrintfA(
  char *pszDest,
  size_t cchDest,
  const char *pszFormat,
  ...);

int vsprintf_s(
  char *buffer,
  size_t numberOfElements,
  const char *format,
  va_list argptr);

int win_to_posix_error(DWORD winerr)
{
	switch (winerr)
	{
	case ERROR_FILE_NOT_FOUND:		return ENOENT;
	case ERROR_PATH_NOT_FOUND:		return ENOENT;
	case ERROR_ACCESS_DENIED:		return EACCES;
	case ERROR_INVALID_HANDLE:		return EBADF;
	case ERROR_NOT_ENOUGH_MEMORY:	return ENOMEM;
	case ERROR_INVALID_DATA:		return EINVAL;
	case ERROR_OUTOFMEMORY:			return ENOMEM;
	case ERROR_INVALID_DRIVE:		return ENODEV;
	case ERROR_NOT_SAME_DEVICE:		return EXDEV;
	case ERROR_WRITE_PROTECT:		return EROFS;
	case ERROR_BAD_UNIT:			return ENODEV;
	case ERROR_SHARING_VIOLATION:	return EACCES;
	case ERROR_LOCK_VIOLATION:		return EACCES;
	case ERROR_SHARING_BUFFER_EXCEEDED:	return ENOLCK;
	case ERROR_HANDLE_DISK_FULL:	return ENOSPC;
	case ERROR_NOT_SUPPORTED:		return ENOSYS;
	case ERROR_FILE_EXISTS:			return EEXIST;
	case ERROR_CANNOT_MAKE:			return EPERM;
	case ERROR_INVALID_PARAMETER:	return EINVAL;
	case ERROR_NO_PROC_SLOTS:		return EAGAIN;
	case ERROR_BROKEN_PIPE:			return EPIPE;
	case ERROR_OPEN_FAILED:			return EIO;
	case ERROR_NO_MORE_SEARCH_HANDLES:	return ENFILE;
	case ERROR_CALL_NOT_IMPLEMENTED:	return ENOSYS;
	case ERROR_INVALID_NAME:		return ENOENT;
	case ERROR_WAIT_NO_CHILDREN:	return ECHILD;
	case ERROR_CHILD_NOT_COMPLETE:	return EBUSY;
	case ERROR_DIR_NOT_EMPTY:		return ENOTEMPTY;
	case ERROR_SIGNAL_REFUSED:		return EIO;
	case ERROR_BAD_PATHNAME:		return ENOENT;
	case ERROR_SIGNAL_PENDING:		return EBUSY;
	case ERROR_MAX_THRDS_REACHED:	return EAGAIN;
	case ERROR_BUSY:				return EBUSY;
	case ERROR_ALREADY_EXISTS:		return EEXIST;
	case ERROR_NO_SIGNAL_SENT:		return EIO;
	case ERROR_FILENAME_EXCED_RANGE:	return EINVAL;
	case ERROR_META_EXPANSION_TOO_LONG:	return EINVAL;
	case ERROR_INVALID_SIGNAL_NUMBER:	return EINVAL;
	case ERROR_THREAD_1_INACTIVE:	return EINVAL;
	case ERROR_BAD_PIPE:			return EINVAL;
	case ERROR_PIPE_BUSY:			return EBUSY;
	case ERROR_NO_DATA:				return EPIPE;
	case ERROR_MORE_DATA:			return EAGAIN;
	case ERROR_DIRECTORY:			return ENOTDIR;
	case ERROR_PIPE_CONNECTED:		return EBUSY;
	case ERROR_NO_TOKEN:			return EINVAL;
	case ERROR_PROCESS_ABORTED:		return EFAULT;
	case ERROR_BAD_DEVICE:			return ENODEV;
	case ERROR_BAD_USERNAME:		return EINVAL;
	case ERROR_OPEN_FILES:			return EAGAIN;
	case ERROR_ACTIVE_CONNECTIONS:	return EAGAIN;
	case ERROR_DEVICE_IN_USE:		return EAGAIN;
	case ERROR_INVALID_AT_INTERRUPT_TIME:	return EINTR;
	case ERROR_IO_DEVICE:			return EIO;
	case ERROR_NOT_OWNER:			return EPERM;
	case ERROR_END_OF_MEDIA:		return ENOSPC;
	case ERROR_EOM_OVERFLOW:		return ENOSPC;
	case ERROR_BEGINNING_OF_MEDIA:	return ESPIPE;
	case ERROR_SETMARK_DETECTED:	return ESPIPE;
	case ERROR_NO_DATA_DETECTED:	return ENOSPC;
	case ERROR_POSSIBLE_DEADLOCK:	return EDEADLOCK;
	case ERROR_CRC:					return EIO;
	case ERROR_NEGATIVE_SEEK:		return EINVAL;
	case ERROR_DISK_FULL:			return ENOSPC;
	case ERROR_NOACCESS:			return EFAULT;
	case ERROR_FILE_INVALID:		return ENXIO;
	}

	return winerr;
}

int GetNumLogicalProcessors(void)
{
	SYSTEM_LOGICAL_PROCESSOR_INFORMATION *processor_info = NULL;
	DWORD len = 0;
	DWORD num_processors = 0;
	DWORD error = 0;
	DWORD i;

	while (!GetLogicalProcessorInformation(processor_info, &len)) {
		error = GetLastError();
		if (error == ERROR_INSUFFICIENT_BUFFER)
			processor_info = malloc(len);
		else {
			log_err("Error: GetLogicalProcessorInformation failed: %d\n", error);
			return -1;
		}

		if (processor_info == NULL) {
			log_err("Error: failed to allocate memory for GetLogicalProcessorInformation");
			return -1;
		}
	}

	for (i = 0; i < len / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); i++)
	{
		if (processor_info[i].Relationship == RelationProcessorCore)
			num_processors += hweight64(processor_info[i].ProcessorMask);
	}

	free(processor_info);
	return num_processors;
}

long sysconf(int name)
{
	long val = -1;
	long val2 = -1;
	SYSTEM_INFO sysInfo;
	MEMORYSTATUSEX status;

	switch (name)
	{
	case _SC_NPROCESSORS_ONLN:
		val = GetNumLogicalProcessors();
		if (val == -1)
			log_err("sysconf(_SC_NPROCESSORS_ONLN) failed\n");

		break;

	case _SC_PAGESIZE:
		GetSystemInfo(&sysInfo);
		val = sysInfo.dwPageSize;
		break;

	case _SC_PHYS_PAGES:
		status.dwLength = sizeof(status);
		val2 = sysconf(_SC_PAGESIZE);
		if (GlobalMemoryStatusEx(&status) && val2 != -1)
			val = status.ullTotalPhys / val2;
		else
			log_err("sysconf(_SC_PHYS_PAGES) failed\n");
		break;
	default:
		log_err("sysconf(%d) is not implemented\n", name);
		break;
	}

	return val;
}

char *dl_error = NULL;

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

void *dlopen(const char *file, int mode)
{
	HMODULE hMod;

	hMod = LoadLibrary(file);
	if (hMod == INVALID_HANDLE_VALUE)
		dl_error = (char*)"LoadLibrary failed";
	else
		dl_error = NULL;

	return hMod;
}

void *dlsym(void *handle, const char *name)
{
	FARPROC fnPtr;

	fnPtr = GetProcAddress((HMODULE)handle, name);
	if (fnPtr == NULL)
		dl_error = (char*)"GetProcAddress failed";
	else
		dl_error = NULL;

	return fnPtr;
}

char *dlerror(void)
{
	return dl_error;
}

int gettimeofday(struct timeval *restrict tp, void *restrict tzp)
{
	FILETIME fileTime;
	uint64_t unix_time, windows_time;
	const uint64_t MILLISECONDS_BETWEEN_1601_AND_1970 = 11644473600000;

	/* Ignore the timezone parameter */
	(void)tzp;

	/*
	 * Windows time is stored as the number 100 ns intervals since January 1 1601.
	 * Conversion details from http://www.informit.com/articles/article.aspx?p=102236&seqNum=3
	 * Its precision is 100 ns but accuracy is only one clock tick, or normally around 15 ms.
	 */
	GetSystemTimeAsFileTime(&fileTime);
	windows_time = ((uint64_t)fileTime.dwHighDateTime << 32) + fileTime.dwLowDateTime;
	/* Divide by 10,000 to convert to ms and subtract the time between 1601 and 1970 */
	unix_time = (((windows_time)/10000) - MILLISECONDS_BETWEEN_1601_AND_1970);
	/* unix_time is now the number of milliseconds since 1970 (the Unix epoch) */
	tp->tv_sec = unix_time / 1000;
	tp->tv_usec = (unix_time % 1000) * 1000;
	return 0;
}

int sigaction(int sig, const struct sigaction *act,
		struct sigaction *oact)
{
	int rc = 0;
	void (*prev_handler)(int);

	prev_handler = signal(sig, act->sa_handler);
	if (oact != NULL)
		oact->sa_handler = prev_handler;

	if (prev_handler == SIG_ERR)
		rc = -1;

	return rc;
}

int lstat(const char * path, struct stat * buf)
{
	return stat(path, buf);
}

void *mmap(void *addr, size_t len, int prot, int flags,
		int fildes, off_t off)
{
	DWORD vaProt = 0;
	void* allocAddr = NULL;

	if (prot & PROT_NONE)
		vaProt |= PAGE_NOACCESS;

	if ((prot & PROT_READ) && !(prot & PROT_WRITE))
		vaProt |= PAGE_READONLY;

	if (prot & PROT_WRITE)
		vaProt |= PAGE_READWRITE;

	if ((flags & MAP_ANON) | (flags & MAP_ANONYMOUS))
	{
		allocAddr = VirtualAlloc(addr, len, MEM_COMMIT, vaProt);
		if (allocAddr == NULL)
			errno = win_to_posix_error(GetLastError());
	}

	return allocAddr;
}

int munmap(void *addr, size_t len)
{
	if (!VirtualFree(addr, 0, MEM_RELEASE)) {
		errno = win_to_posix_error(GetLastError());
		return -1;
	}

	return 0;
}

int fork(void)
{
	log_err("%s is not implemented\n", __func__);
	errno = ENOSYS;
	return -1;
}

pid_t setsid(void)
{
	log_err("%s is not implemented\n", __func__);
	errno = ENOSYS;
	return -1;
}

static HANDLE log_file = INVALID_HANDLE_VALUE;

void openlog(const char *ident, int logopt, int facility)
{
	if (log_file == INVALID_HANDLE_VALUE)
		log_file = CreateFileA("syslog.txt", GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, 0, NULL);
}

void closelog(void)
{
	CloseHandle(log_file);
	log_file = INVALID_HANDLE_VALUE;
}

void syslog(int priority, const char *message, ... /* argument */)
{
	va_list v;
	int len;
	char *output;
	DWORD bytes_written;

	if (log_file == INVALID_HANDLE_VALUE) {
		log_file = CreateFileA("syslog.txt", GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, 0, NULL);
	}

	if (log_file == INVALID_HANDLE_VALUE) {
		log_err("syslog: failed to open log file\n");
		return;
	}

	va_start(v, message);
	len = _vscprintf(message, v);
	output = malloc(len + sizeof(char));
	vsprintf(output, message, v);
	WriteFile(log_file, output, len, &bytes_written, NULL);
	va_end(v);
	free(output);
}

int kill(pid_t pid, int sig)
{
	errno = ESRCH;
	return -1;
}

/*
 * This is assumed to be used only by the network code,
 * and so doesn't try and handle any of the other cases
 */
int fcntl(int fildes, int cmd, ...)
{
	/*
	 * non-blocking mode doesn't work the same as in BSD sockets,
	 * so ignore it.
	 */
#if 0
	va_list ap;
	int val, opt, status;

	if (cmd == F_GETFL)
		return 0;
	else if (cmd != F_SETFL) {
		errno = EINVAL;
		return -1;
	}

	va_start(ap, 1);

	opt = va_arg(ap, int);
	if (opt & O_NONBLOCK)
		val = 1;
	else
		val = 0;

	status = ioctlsocket((SOCKET)fildes, opt, &val);

	if (status == SOCKET_ERROR) {
		errno = EINVAL;
		val = -1;
	}

	va_end(ap);

	return val;
#endif
return 0;
}

/*
 * Get the value of a local clock source.
 * This implementation supports 2 clocks: CLOCK_MONOTONIC provides high-accuracy
 * relative time, while CLOCK_REALTIME provides a low-accuracy wall time.
 */
int clock_gettime(clockid_t clock_id, struct timespec *tp)
{
	int rc = 0;

	if (clock_id == CLOCK_MONOTONIC)
	{
		static LARGE_INTEGER freq = {{0,0}};
		LARGE_INTEGER counts;
		uint64_t t;

		QueryPerformanceCounter(&counts);
		if (freq.QuadPart == 0)
			QueryPerformanceFrequency(&freq);

		tp->tv_sec = counts.QuadPart / freq.QuadPart;
		/* Get the difference between the number of ns stored
		 * in 'tv_sec' and that stored in 'counts' */
		t = tp->tv_sec * freq.QuadPart;
		t = counts.QuadPart - t;
		/* 't' now contains the number of cycles since the last second.
		 * We want the number of nanoseconds, so multiply out by 1,000,000,000
		 * and then divide by the frequency. */
		t *= 1000000000;
		tp->tv_nsec = t / freq.QuadPart;
	}
	else if (clock_id == CLOCK_REALTIME)
	{
		/* clock_gettime(CLOCK_REALTIME,...) is just an alias for gettimeofday with a
		 * higher-precision field. */
		struct timeval tv;
		gettimeofday(&tv, NULL);
		tp->tv_sec = tv.tv_sec;
		tp->tv_nsec = tv.tv_usec * 1000;
	} else {
		errno = EINVAL;
		rc = -1;
	}

	return rc;
}

int mlock(const void * addr, size_t len)
{
	SIZE_T min, max;
	BOOL success;
	HANDLE process = GetCurrentProcess();

	success = GetProcessWorkingSetSize(process, &min, &max);
	if (!success) {
		errno = win_to_posix_error(GetLastError());
		return -1;
	}

	min += len;
	max += len;
	success = SetProcessWorkingSetSize(process, min, max);
	if (!success) {
		errno = win_to_posix_error(GetLastError());
		return -1;
	}

	success = VirtualLock((LPVOID)addr, len);
	if (!success) {
		errno = win_to_posix_error(GetLastError());
		return -1;
	}

	return 0;
}

int munlock(const void * addr, size_t len)
{
	BOOL success = VirtualUnlock((LPVOID)addr, len);
	if (!success) {
		errno = win_to_posix_error(GetLastError());
		return -1;
	}

	return 0;
}

pid_t waitpid(pid_t pid, int *stat_loc, int options)
{
	log_err("%s is not implemented\n", __func__);
	errno = ENOSYS;
	return -1;
}

int usleep(useconds_t useconds)
{
	Sleep(useconds / 1000);
	return 0;
}

char *basename(char *path)
{
	static char name[MAX_PATH];
	int i;

	if (path == NULL || strlen(path) == 0)
		return (char*)".";

	i = strlen(path) - 1;

	while (path[i] != '\\' && path[i] != '/' && i >= 0)
		i--;

	strncpy(name, path + i + 1, MAX_PATH);

	return name;
}

int fsync(int fildes)
{
	HANDLE hFile = (HANDLE)_get_osfhandle(fildes);
	if (!FlushFileBuffers(hFile)) {
		errno = win_to_posix_error(GetLastError());
		return -1;
	}

	return 0;
}

int nFileMappings = 0;
HANDLE fileMappings[1024];

int shmget(key_t key, size_t size, int shmflg)
{
	int mapid = -1;
	uint32_t size_low = size & 0xFFFFFFFF;
	uint32_t size_high = ((uint64_t)size) >> 32;
	HANDLE hMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, (PAGE_EXECUTE_READWRITE | SEC_RESERVE), size_high, size_low, NULL);
	if (hMapping != NULL) {
		fileMappings[nFileMappings] = hMapping;
		mapid = nFileMappings;
		nFileMappings++;
	} else {
		errno = ENOSYS;
	}

	return mapid;
}

void *shmat(int shmid, const void *shmaddr, int shmflg)
{
	void* mapAddr;
	MEMORY_BASIC_INFORMATION memInfo;
	mapAddr = MapViewOfFile(fileMappings[shmid], FILE_MAP_ALL_ACCESS, 0, 0, 0);
	if (mapAddr == NULL) {
		errno = win_to_posix_error(GetLastError());
		return (void*)-1;
	}

	if (VirtualQuery(mapAddr, &memInfo, sizeof(memInfo)) == 0) {
		errno = win_to_posix_error(GetLastError());
		return (void*)-1;
	}

	mapAddr = VirtualAlloc(mapAddr, memInfo.RegionSize, MEM_COMMIT, PAGE_READWRITE);
	if (mapAddr == NULL) {
		errno = win_to_posix_error(GetLastError());
		return (void*)-1;
	}

	return mapAddr;
}

int shmdt(const void *shmaddr)
{
	if (!UnmapViewOfFile(shmaddr)) {
		errno = win_to_posix_error(GetLastError());
		return -1;
	}

	return 0;
}

int shmctl(int shmid, int cmd, struct shmid_ds *buf)
{
	if (cmd == IPC_RMID) {
		fileMappings[shmid] = INVALID_HANDLE_VALUE;
		return 0;
	} else {
		log_err("%s is not implemented\n", __func__);
	}
	errno = ENOSYS;
	return -1;
}

int setuid(uid_t uid)
{
	log_err("%s is not implemented\n", __func__);
	errno = ENOSYS;
	return -1;
}

int setgid(gid_t gid)
{
	log_err("%s is not implemented\n", __func__);
	errno = ENOSYS;
	return -1;
}

int nice(int incr)
{
	if (incr != 0) {
		errno = EINVAL;
		return -1;
	}

	return 0;
}

int getrusage(int who, struct rusage *r_usage)
{
	const uint64_t SECONDS_BETWEEN_1601_AND_1970 = 11644473600;
	FILETIME cTime, eTime, kTime, uTime;
	time_t time;
	HANDLE h;

	memset(r_usage, 0, sizeof(*r_usage));

	if (who == RUSAGE_SELF) {
		h = GetCurrentProcess();
		GetProcessTimes(h, &cTime, &eTime, &kTime, &uTime);
	} else if (who == RUSAGE_THREAD) {
		h = GetCurrentThread();
		GetThreadTimes(h, &cTime, &eTime, &kTime, &uTime);
	} else {
		log_err("fio: getrusage %d is not implemented\n", who);
		return -1;
	}

	time = ((uint64_t)uTime.dwHighDateTime << 32) + uTime.dwLowDateTime;
	/* Divide by 10,000,000 to get the number of seconds and move the epoch from
	 * 1601 to 1970 */
	time = (time_t)(((time)/10000000) - SECONDS_BETWEEN_1601_AND_1970);
	r_usage->ru_utime.tv_sec = time;
	/* getrusage() doesn't care about anything other than seconds, so set tv_usec to 0 */
	r_usage->ru_utime.tv_usec = 0;
	time = ((uint64_t)kTime.dwHighDateTime << 32) + kTime.dwLowDateTime;
	/* Divide by 10,000,000 to get the number of seconds and move the epoch from
	 * 1601 to 1970 */
	time = (time_t)(((time)/10000000) - SECONDS_BETWEEN_1601_AND_1970);
	r_usage->ru_stime.tv_sec = time;
	r_usage->ru_stime.tv_usec = 0;
	return 0;
}

int posix_madvise(void *addr, size_t len, int advice)
{
	log_err("%s is not implemented\n", __func__);
	return ENOSYS;
}

/* Windows doesn't support advice for memory pages. Just ignore it. */
int msync(void *addr, size_t len, int flags)
{
	errno = ENOSYS;
	return -1;
}

int fdatasync(int fildes)
{
	return fsync(fildes);
}

ssize_t pwrite(int fildes, const void *buf, size_t nbyte,
		off_t offset)
{
	int64_t pos = _telli64(fildes);
	ssize_t len = _write(fildes, buf, nbyte);
	_lseeki64(fildes, pos, SEEK_SET);
	return len;
}

ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset)
{
	int64_t pos = _telli64(fildes);
	ssize_t len = read(fildes, buf, nbyte);
	_lseeki64(fildes, pos, SEEK_SET);
	return len;
}

ssize_t readv(int fildes, const struct iovec *iov, int iovcnt)
{
	log_err("%s is not implemented\n", __func__);
	errno = ENOSYS;
	return -1;
}

ssize_t writev(int fildes, const struct iovec *iov, int iovcnt)
{
	int i;
	DWORD bytes_written = 0;
	for (i = 0; i < iovcnt; i++)
	{
		int len = send((SOCKET)fildes, iov[i].iov_base, iov[i].iov_len, 0);
		if (len == SOCKET_ERROR)
		{
			DWORD err = GetLastError();
			errno = win_to_posix_error(err);
			bytes_written = -1;
			break;
		}
		bytes_written += len;
	}

	return bytes_written;
}

long long strtoll(const char *restrict str, char **restrict endptr,
		int base)
{
	return _strtoi64(str, endptr, base);
}

int poll(struct pollfd fds[], nfds_t nfds, int timeout)
{
	struct timeval tv;
	struct timeval *to = NULL;
	fd_set readfds, writefds, exceptfds;
	int i;
	int rc;

	if (timeout != -1) {
		to = &tv;
		to->tv_sec = timeout / 1000;
		to->tv_usec = (timeout % 1000) * 1000;
	}

	FD_ZERO(&readfds);
	FD_ZERO(&writefds);
	FD_ZERO(&exceptfds);

	for (i = 0; i < nfds; i++)
	{
		if (fds[i].fd < 0) {
			fds[i].revents = 0;
			continue;
		}

		if (fds[i].events & POLLIN)
			FD_SET(fds[i].fd, &readfds);

		if (fds[i].events & POLLOUT)
			FD_SET(fds[i].fd, &writefds);

		FD_SET(fds[i].fd, &exceptfds);
	}
	rc = select(nfds, &readfds, &writefds, &exceptfds, to);

	if (rc != SOCKET_ERROR) {
		for (i = 0; i < nfds; i++)
		{
			if (fds[i].fd < 0) {
				continue;
			}

			if ((fds[i].events & POLLIN) && FD_ISSET(fds[i].fd, &readfds))
				fds[i].revents |= POLLIN;

			if ((fds[i].events & POLLOUT) && FD_ISSET(fds[i].fd, &writefds))
				fds[i].revents |= POLLOUT;

			if (FD_ISSET(fds[i].fd, &exceptfds))
				fds[i].revents |= POLLHUP;
		}
	}
	return rc;
}

int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
{
	struct timeval tv;
	DWORD ms_remaining;
	DWORD ms_total = (rqtp->tv_sec * 1000) + (rqtp->tv_nsec / 1000000.0);

	if (ms_total == 0)
		ms_total = 1;

	ms_remaining = ms_total;

	/* Since Sleep() can sleep for less than the requested time, add a loop to
	   ensure we only return after the requested length of time has elapsed */
	do {
		fio_gettime(&tv, NULL);
		Sleep(ms_remaining);
		ms_remaining = ms_total - mtime_since_now(&tv);
	} while (ms_remaining > 0 && ms_remaining < ms_total);

	/* this implementation will never sleep for less than the requested time */
	if (rmtp != NULL) {
		rmtp->tv_sec = 0;
		rmtp->tv_nsec = 0;
	}

	return 0;
}

DIR *opendir(const char *dirname)
{
	struct dirent_ctx *dc = NULL;

	/* See if we can open it. If not, we'll return an error here */
	HANDLE file = CreateFileA(dirname, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
	if (file != INVALID_HANDLE_VALUE) {
		CloseHandle(file);
		dc = (struct dirent_ctx*)malloc(sizeof(struct dirent_ctx));
		StringCchCopyA(dc->dirname, MAX_PATH, dirname);
		dc->find_handle = INVALID_HANDLE_VALUE;
	} else {
		DWORD error = GetLastError();
		if (error == ERROR_FILE_NOT_FOUND)
			errno = ENOENT;

		else if (error == ERROR_PATH_NOT_FOUND)
			errno = ENOTDIR;
		else if (error == ERROR_TOO_MANY_OPEN_FILES)
			errno = ENFILE;
		else if (error == ERROR_ACCESS_DENIED)
			errno = EACCES;
		else
			errno = error;
	}

	return dc;
}

int closedir(DIR *dirp)
{
	if (dirp != NULL && dirp->find_handle != INVALID_HANDLE_VALUE)
		FindClose(dirp->find_handle);

	free(dirp);
	return 0;
}

struct dirent *readdir(DIR *dirp)
{
	static struct dirent de;
	WIN32_FIND_DATA find_data;

	if (dirp == NULL)
		return NULL;

	if (dirp->find_handle == INVALID_HANDLE_VALUE) {
		char search_pattern[MAX_PATH];
		StringCchPrintfA(search_pattern, MAX_PATH, "%s\\*", dirp->dirname);
		dirp->find_handle = FindFirstFileA(search_pattern, &find_data);
		if (dirp->find_handle == INVALID_HANDLE_VALUE)
			return NULL;
	} else {
		if (!FindNextFile(dirp->find_handle, &find_data))
			return NULL;
	}

	StringCchCopyA(de.d_name, MAX_PATH, find_data.cFileName);
	de.d_ino = 0;

	return &de;
}

uid_t geteuid(void)
{
	log_err("%s is not implemented\n", __func__);
	errno = ENOSYS;
	return -1;
}

in_addr_t inet_network(const char *cp)
{
	in_addr_t hbo;
	in_addr_t nbo = inet_addr(cp);
	hbo = ((nbo & 0xFF) << 24) + ((nbo & 0xFF00) << 8) + ((nbo & 0xFF0000) >> 8) + ((nbo & 0xFF000000) >> 24);
	return hbo;
}

const char* inet_ntop(int af, const void *restrict src,
		char *restrict dst, socklen_t size)
{
	INT status = SOCKET_ERROR;
	WSADATA wsd;
	char *ret = NULL;

	if (af != AF_INET && af != AF_INET6) {
		errno = EAFNOSUPPORT;
		return NULL;
	}

	WSAStartup(MAKEWORD(2,2), &wsd);

	if (af == AF_INET) {
		struct sockaddr_in si;
		DWORD len = size;
		memset(&si, 0, sizeof(si));
		si.sin_family = af;
		memcpy(&si.sin_addr, src, sizeof(si.sin_addr));
		status = WSAAddressToString((struct sockaddr*)&si, sizeof(si), NULL, dst, &len);
	} else if (af == AF_INET6) {
		struct sockaddr_in6 si6;
		DWORD len = size;
		memset(&si6, 0, sizeof(si6));
		si6.sin6_family = af;
		memcpy(&si6.sin6_addr, src, sizeof(si6.sin6_addr));
		status = WSAAddressToString((struct sockaddr*)&si6, sizeof(si6), NULL, dst, &len);
	}

	if (status != SOCKET_ERROR)
		ret = dst;
	else
		errno = ENOSPC;

	WSACleanup();

	return ret;
}

int inet_pton(int af, const char *restrict src, void *restrict dst)
{
	INT status = SOCKET_ERROR;
	WSADATA wsd;
	int ret = 1;

	if (af != AF_INET && af != AF_INET6) {
		errno = EAFNOSUPPORT;
		return -1;
	}

	WSAStartup(MAKEWORD(2,2), &wsd);

	if (af == AF_INET) {
		struct sockaddr_in si;
		INT len = sizeof(si);
		memset(&si, 0, sizeof(si));
		si.sin_family = af;
		status = WSAStringToAddressA((char*)src, af, NULL, (struct sockaddr*)&si, &len);
		if (status != SOCKET_ERROR)
			memcpy(dst, &si.sin_addr, sizeof(si.sin_addr));
	} else if (af == AF_INET6) {
		struct sockaddr_in6 si6;
		INT len = sizeof(si6);
		memset(&si6, 0, sizeof(si6));
		si6.sin6_family = af;
		status = WSAStringToAddressA((char*)src, af, NULL, (struct sockaddr*)&si6, &len);
		if (status != SOCKET_ERROR)
			memcpy(dst, &si6.sin6_addr, sizeof(si6.sin6_addr));
	}

	if (status == SOCKET_ERROR) {
		errno = ENOSPC;
		ret = 0;
	}

	WSACleanup();

	return ret;
}
