Initial win32 Release

This commit is contained in:
Danny Mayer
2001-07-06 05:08:39 +00:00
parent 2773eae702
commit e35c1bb3ec
8 changed files with 697 additions and 209 deletions

View File

@@ -15,15 +15,17 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: condition.c,v 1.15 2001/01/09 21:58:48 bwelling Exp $ */
/* $Id: condition.c,v 1.16 2001/07/06 05:05:51 mayer Exp $ */
#include <config.h>
#include <isc/condition.h>
#include <isc/assertions.h>
#include <isc/util.h>
#include <isc/time.h>
#define SIGNAL 0
#define BROADCAST 1
#define LSIGNAL 0
#define LBROADCAST 1
isc_result_t
isc_condition_init(isc_condition_t *cond) {
@@ -37,14 +39,14 @@ isc_condition_init(isc_condition_t *cond) {
/* XXX */
return (ISC_R_UNEXPECTED);
}
cond->events[SIGNAL] = h;
cond->events[LSIGNAL] = h;
h = CreateEvent(NULL, TRUE, FALSE, NULL);
if (h == NULL) {
(void)CloseHandle(cond->events[SIGNAL]);
(void)CloseHandle(cond->events[LSIGNAL]);
/* XXX */
return (ISC_R_UNEXPECTED);
}
cond->events[BROADCAST] = h;
cond->events[LBROADCAST] = h;
return (ISC_R_SUCCESS);
}
@@ -59,7 +61,7 @@ isc_condition_signal(isc_condition_t *cond) {
REQUIRE(cond != NULL);
if (cond->waiters > 0 &&
!SetEvent(cond->events[SIGNAL])) {
!SetEvent(cond->events[LSIGNAL])) {
/* XXX */
return (ISC_R_UNEXPECTED);
}
@@ -77,7 +79,7 @@ isc_condition_broadcast(isc_condition_t *cond) {
REQUIRE(cond != NULL);
if (cond->waiters > 0 &&
!SetEvent(cond->events[BROADCAST])) {
!SetEvent(cond->events[LBROADCAST])) {
/* XXX */
return (ISC_R_UNEXPECTED);
}
@@ -90,8 +92,8 @@ isc_condition_destroy(isc_condition_t *cond) {
REQUIRE(cond != NULL);
(void)CloseHandle(cond->events[SIGNAL]);
(void)CloseHandle(cond->events[BROADCAST]);
(void)CloseHandle(cond->events[LSIGNAL]);
(void)CloseHandle(cond->events[LBROADCAST]);
return (ISC_R_SUCCESS);
}
@@ -110,7 +112,7 @@ wait(isc_condition_t *cond, isc_mutex_t *mutex, DWORD milliseconds) {
EnterCriticalSection(mutex);
cond->waiters--;
if (cond->waiters == 0 &&
!ResetEvent(cond->events[BROADCAST])) {
!ResetEvent(cond->events[LBROADCAST])) {
/* XXX */
LeaveCriticalSection(mutex);
return (ISC_R_UNEXPECTED);

View File

@@ -15,14 +15,30 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: dir.c,v 1.8 2001/06/04 19:33:37 tale Exp $ */
/* $Id: dir.c,v 1.9 2001/07/06 05:06:11 mayer Exp $ */
/* Principal Authors: DCL */
/*
* isc_dir_chroot is currently stubbed out for Win32
* This will need to be revisited
*/
#include <config.h>
#include <string.h>
#include <direct.h>
#include <process.h>
#include <io.h>
#include <sys/stat.h>
#include <isc/dir.h>
#include <isc/magic.h>
#include <isc/assertions.h>
#include <isc/util.h>
#include "errno2result.h"
#define ISC_DIR_MAGIC ISC_MAGIC('D', 'I', 'R', '*')
#define VALID_DIR(dir) ISC_MAGIC_VALID(dir, ISC_DIR_MAGIC)
@@ -218,5 +234,112 @@ isc_dir_chdir(const char *dirname) {
REQUIRE(dirname != NULL);
return (ISC_R_NOTIMPLEMENTED);
if (chdir(dirname) < 0)
return (isc__errno2result(errno));
return (ISC_R_SUCCESS);
}
isc_result_t
isc_dir_chroot(const char *dirname) {
return (ISC_R_SUCCESS);
}
isc_result_t
isc_dir_current(char *dirname, size_t length, isc_boolean_t end_sep) {
char *cwd;
isc_result_t result = ISC_R_SUCCESS;
/*
* XXXDCL Could automatically allocate memory if dirname == NULL.
*/
REQUIRE(dirname != NULL);
REQUIRE(length > 0);
cwd = getcwd(dirname, length);
if (cwd == NULL) {
if (errno == ERANGE)
result = ISC_R_NOSPACE;
else
result = isc__errno2result(errno);
} else if (end_sep) {
if (strlen(dirname) + 1 == length)
result = ISC_R_NOSPACE;
else if (dirname[1] != '\0')
strcat(dirname, "/");
}
return (result);
}
isc_result_t
isc_dir_createunique(char *templet) {
isc_result_t result;
char *x;
char *p;
int i;
int pid;
REQUIRE(templet != NULL);
/*
* mkdtemp is not portable, so this emulates it.
*/
pid = getpid();
/*
* Replace trailing Xs with the process-id, zero-filled.
*/
for (x = templet + strlen(templet) - 1; *x == 'X' && x >= templet;
x--, pid /= 10)
*x = pid % 10 + '0';
x++; /* Set x to start of ex-Xs. */
do {
i = mkdir(templet);
i = chmod(templet, 0700);
if (i == 0 || errno != EEXIST)
break;
/*
* The BSD algorithm.
*/
p = x;
while (*p != '\0') {
if (isdigit(*p & 0xff))
*p = 'a';
else if (*p != 'z')
++*p;
else {
/*
* Reset character and move to next.
*/
*p++ = 'a';
continue;
}
break;
}
if (*p == '\0') {
/*
* Tried all combinations. errno should already
* be EEXIST, but ensure it is anyway for
* isc__errno2result().
*/
errno = EEXIST;
break;
}
} while (1);
if (i == -1)
result = isc__errno2result(errno);
else
result = ISC_R_SUCCESS;
return (result);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2000, 2001 Internet Software Consortium.
* Copyright (C) 2000 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -15,41 +15,419 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: file.c,v 1.6 2001/01/09 21:58:50 bwelling Exp $ */
/* $Id: file.c,v 1.7 2001/07/06 05:06:25 mayer Exp $ */
#include <string.h>
#include <config.h>
#undef TEMPLATE
#define TEMPLATE "tXXXXXXX.tmp"
#undef rename
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#include <io.h>
#include <process.h>
isc_result_t
isc_file_mktemplate(const char *file, char *buf, size_t buflen) {
char *s;
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/utime.h>
s = ;
if ((s = strrchr(file, '\\')) != NULL) {
if ((s - file + 1 + sizeof(TEMPLATE)) > buflen)
return (ISC_R_NOSPACE);
#include <isc/file.h>
#include <isc/result.h>
#include <isc/time.h>
#include <isc/util.h>
#include <isc/stat.h>
strncpy(buf, file, s - file + 1);
buf[s - file + 1] = '\0';
strcat(buf, TEMPLATE);
#include "errno2result.h"
} else if ((s = strrchr(file, ':')) != NULL) {
if ((s - file + 2 + sizeof(TEMPLATE)) > buflen)
return (ISC_R_NOSPACE);
/*
* Emulate UNIX mkstemp, which returns an open FD to the new file
*
*/
static int
gettemp(char *path, int *doopen) {
char *start, *trv;
struct stat sbuf;
int pid;
strncpy(buf, file, s - file + 1);
buf[s - file + 1] = '\\';
buf[s - file + 2] = '\0';
strcat(buf, TEMPLATE);
} else {
if (sizeof(TEMPLATE) > buflen)
return (ISC_R_NOSPACE);
strcpy(buf, TEMPLATE);
trv = strrchr(path, 'X');
trv++;
pid = getpid();
/* extra X's get set to 0's */
while (*--trv == 'X') {
*trv = (pid % 10) + '0';
pid /= 10;
}
/*
* check the target directory; if you have six X's and it
* doesn't exist this runs for a *very* long time.
*/
for (start = trv + 1;; --trv) {
if (trv <= path)
break;
if (*trv == '\\') {
*trv = '\0';
if (stat(path, &sbuf))
return(0);
if (!S_ISDIR(sbuf.st_mode)) {
errno = ENOTDIR;
return(0);
}
*trv = '\\';
break;
}
}
for (;;) {
if (doopen) {
if ((*doopen =
open(path, O_CREAT|O_EXCL|O_RDWR, _S_IREAD | _S_IWRITE)) >= 0)
return(1);
if (errno != EEXIST)
return(0);
}
else if (stat(path, &sbuf))
return(errno == ENOENT ? 1 : 0);
/* tricky little algorithm for backward compatibility */
for (trv = start;;) {
if (!*trv)
return(0);
if (*trv == 'z')
*trv++ = 'a';
else {
if (isdigit(*trv))
*trv = 'a';
else
++*trv;
break;
}
}
}
/*NOTREACHED*/
}
int
mkstemp(char *path) {
int fd;
return (gettemp(path, &fd) ? fd : -1);
}
/*
* XXXDCL As the API for accessing file statistics undoubtedly gets expanded,
* it might be good to provide a mechanism that allows for the results
* of a previous stat() to be used again without having to do another stat,
* such as perl's mechanism of using "_" in place of a file name to indicate
* that the results of the last stat should be used. But then you get into
* annoying MP issues. BTW, Win32 has stat().
*/
static isc_result_t
file_stats(const char *file, struct stat *stats) {
isc_result_t result = ISC_R_SUCCESS;
if (stat(file, stats) != 0)
result = isc__errno2result(errno);
return (result);
}
/* isc_file_safemovefile is needed to be defined here to ensure that any file with
* the new name is renamed to a backup name and then the rename is done. If all goes
* well then the backup can be deleted, otherwise it gets renamed back.
*/
int
isc_file_safemovefile(const char *oldname, const char *newname) {
BOOL filestatus;
char buf[512];
struct stat sbuf;
BOOL exists = FALSE;
int tmpfd;
/*
* Make sure we have something to do
*/
if(stat(oldname, &sbuf) != 0) {
errno = ENOENT;
return(-1);
}
/*
* Rename to a backup the new file if it still exists
*/
if(stat(newname, &sbuf) == 0)
exists = TRUE;
strcpy(buf, newname);
strcat(buf, ".XXXXX");
tmpfd = mkstemp(buf);
if(tmpfd > 0)
_close(tmpfd);
DeleteFile(buf);
if(exists == TRUE) {
_chmod(newname, _S_IREAD | _S_IWRITE);
}
filestatus = MoveFile(newname, buf);
if(filestatus == 0) {
}
/* Now rename the file to the new name
*/
_chmod(oldname, _S_IREAD | _S_IWRITE);
filestatus = MoveFile(oldname, newname);
if(filestatus == 0) {
/* Try and rename the backup back to the original name if the backup got created
*/
if(exists == TRUE) {
filestatus = MoveFile(buf, newname);
if(filestatus == 0) {
errno = EACCES;
}
}
return(-1);
}
/* Delete the backup file if it got created
*/
if(exists == TRUE) {
filestatus = DeleteFile(buf);
}
return(0);
}
isc_result_t
isc_file_getmodtime(const char *file, isc_time_t *time) {
isc_result_t result;
struct stat stats;
REQUIRE(file != NULL && time != NULL);
result = file_stats(file, &stats);
if (result == ISC_R_SUCCESS)
/*
* XXXDCL some operating systems provide nanoseconds, too,
* such as BSD/OS via st_mtimespec.
*/
isc_time_set(time, stats.st_mtime, 0);
return (result);
}
isc_result_t
isc_file_settime(const char *file, isc_time_t *time) {
struct utimbuf timem;
REQUIRE(file != NULL && time != NULL);
/*
* tv_sec is at least a 32 bit quantity on all platforms we're
* dealing with, but it is signed on most (all?) of them,
* so we need to make sure the high bit isn't set. This unfortunately
* loses when either:
* * tv_sec becomes a signed 64 bit integer but long is 32 bits
* and isc_time_seconds > LONG_MAX, or
* * isc_time_seconds is changed to be > 32 bits but long is 32 bits
* and isc_time_seconds has at least 33 significant bits.
*/
timem.actime = timem.modtime = (long)isc_time_seconds(time);
/*
* Here is the real check for the high bit being set.
*/
if ((timem.actime &
(1UL << (sizeof(timem.actime) * CHAR_BIT - 1))) != 0)
return (ISC_R_RANGE);
if (utime(file, &timem) < 0)
return (isc__errno2result(errno));
return (ISC_R_SUCCESS);
}
#undef TEMPLATE
#define TEMPLATE "XXXXXXXXXX.tmp" /* 14 characters. */
isc_result_t
isc_file_mktemplate(const char *path, char *buf, size_t buflen) {
return (isc_file_template(path, TEMPLATE, buf, buflen));
}
isc_result_t
isc_file_template(const char *path, const char *templet, char *buf,
size_t buflen) {
char *s;
REQUIRE(buf != NULL);
s = strrchr(templet, '\\');
if (s != NULL)
templet = s + 1;
s = strrchr(path, '\\');
if (s != NULL) {
if ((s - path + 1 + strlen(templet) + 1) > buflen)
return (ISC_R_NOSPACE);
strncpy(buf, path, s - path + 1);
buf[s - path + 1] = '\0';
strcat(buf, templet);
} else {
if ((strlen(templet) + 1) > buflen)
return (ISC_R_NOSPACE);
strcpy(buf, templet);
}
return (ISC_R_SUCCESS);
}
isc_result_t
isc_file_renameunique(const char *file, char *templet) {
int fd = -1;
int res = 0;
isc_result_t result = ISC_R_SUCCESS;
fd = mkstemp(templet);
if (fd == -1) {
result = isc__errno2result(errno);
}
if (result == ISC_R_SUCCESS) {
res = isc_file_safemovefile(file, templet);
if (res != 0) {
result = isc__errno2result(errno);
(void)unlink(templet);
}
}
if (fd != -1)
close(fd);
return (result);
}
isc_result_t
isc_file_openunique(char *templet, FILE **fp) {
int fd;
FILE *f;
isc_result_t result = ISC_R_SUCCESS;
REQUIRE(templet != NULL);
REQUIRE(fp != NULL && *fp == NULL);
/*
* Win32 does not have mkstemp.
*/
fd = mkstemp(templet);
if (fd == -1)
result = isc__errno2result(errno);
if (result == ISC_R_SUCCESS) {
f = fdopen(fd, "w+");
if (f == NULL) {
result = isc__errno2result(errno);
(void)remove(templet);
(void)close(fd);
} else
*fp = f;
}
return (result);
}
isc_result_t
isc_file_remove(const char *filename) {
int r;
r = unlink(filename);
if (r == 0)
return (ISC_R_SUCCESS);
else
return (isc__errno2result(errno));
}
isc_result_t
isc_file_rename(const char *oldname, const char *newname) {
int r;
r = isc_file_safemovefile(oldname, newname);
if (r == 0)
return (ISC_R_SUCCESS);
else
return (isc__errno2result(errno));
}
isc_boolean_t
isc_file_exists(const char *pathname) {
struct stat stats;
return (ISC_TF(file_stats(pathname, &stats) == ISC_R_SUCCESS));
}
isc_boolean_t
isc_file_isabsolute(const char *filename) {
/*
* Look for c:\path\... style or \\computer\shar\path... UNC style file specs
*/
return ((ISC_TF(filename[1] == ':') && ISC_TF(filename[2] == '\\')) ||
(ISC_TF(filename[0] == '\\') && ISC_TF(filename[1] == '\\')));
}
isc_boolean_t
isc_file_iscurrentdir(const char *filename) {
return (ISC_TF(filename[0] == '.' && filename[1] == '\0'));
}
const char *
isc_file_basename(const char *filename) {
char *s;
s = strrchr(filename, '\\');
if(s == NULL)
return(filename);
return(s + 1);
}
isc_result_t
isc_file_progname(const char *filename, char *progname, size_t namelen) {
const char *s;
char *p;
size_t len;
REQUIRE(filename != NULL);
/*
* Strip the path from the name
*/
s = isc_file_basename(filename);
if(s == NULL) {
return(ISC_R_NOSPACE);
}
/*
* Strip any and all suffixes
*/
p = strchr(s, '.');
if(p == NULL) {
if(namelen <= strlen(s))
return(ISC_R_NOSPACE);
strcpy(progname, s);
return(ISC_R_SUCCESS);
}
/*
* Copy the result to the buffer
*/
len = p - s;
if(len >= namelen)
return(ISC_R_NOSPACE);
strncpy(progname, s, len);
progname[len] = '\0';
return(ISC_R_SUCCESS);
}

View File

@@ -15,18 +15,29 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: fsaccess.c,v 1.6 2001/01/09 21:58:51 bwelling Exp $ */
#include <windows.h>
#include <winerror.h>
#include <aclapi.h>
/* $Id: fsaccess.c,v 1.8 2001/07/08 05:09:01 mayer Exp $ */
/*
* This file is entirely theoretical. It has never been compiled or tested.
* At the very least, even if this is all perfect (HAH!), isc__winerror2result
* needs to be written.
* Note that Win32 does not have the concept of files having access and ownership
* bits. The FAT File system only has a readonly flag for everyone and that's
* all. NTFS uses ACL's which is a totally different concept of controlling
* access.
*
* This code needs to be revisited to set up proper access control for NTFS file systems.
* Nothing can be done for FAT file systems.
*/
#include <config.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <io.h>
#include <errno.h>
#include <isc/stat.h>
#include "errno2result.h"
/*
* The OS-independent part of the API is in lib/isc.
*/
@@ -34,145 +45,64 @@
isc_result_t
isc_fsaccess_set(const char *path, isc_fsaccess_t access) {
isc_result_t result;
isc_fsaccess_t bits, mask;
struct stat statb;
int mode;
isc_boolean_t is_dir = ISC_FALSE;
int i;
DWORD winerror;
PACL dacl;
PSID psid[3];
#define owner psid[0]
#define group psid[1]
#define world psid[2]
PSECURITY_DESCRIPTOR sd;
EXPLICIT_ACCESS ea[3], *pea;
TRUSTEETYPE trustee_type[3] = {
TRUSTEE_IS_USER, TRUSTEE_IS_GROUP, TRUSTEE_IS_WELL_KNOWN_GROUP
};
isc_fsaccess_t bits;
isc_result_t result;
owner = group = world = dacl = sd = NULL;
if (stat(path, &statb) != 0)
return (isc__errno2result(errno));
if ((statb.st_mode & S_IFDIR) != 0)
is_dir = ISC_TRUE;
else if ((statb.st_mode & S_IFREG) == 0)
return (ISC_R_INVALIDFILE);
/* XXXDCL -- NEED TO SET is_dir! Maybe use stat; what is native way? */
result = check_bad_bits(access, is_dir);
if (result != ISC_R_SUCCESS)
return (result);
winerror = GetNamedSecurityInfo(path, SE_FILE_OBJECT,
OWNER_SECURITY_INFORMATION |
GROUP_SECURITY_INFORMATION,
&owner, &group, NULL, NULL, &sd);
/*
* "ERROR_SUCCESS". Heh heh heh.
* Done with checking bad bits. Set mode_t.
*/
if (winerror != ERROR_SUCCESS)
return (isc__winerror2result(winerror));
mode = 0;
ZeroMemory(&ea, sizeof(ea));
ea.grfAccessMode = SET_ACCESS;
ea.grfInheritance = NO_INHERITANCE;
#define SET_AND_CLEAR1(modebit) \
if ((access & bits) != 0) { \
mode |= modebit; \
access &= ~bits; \
}
#define SET_AND_CLEAR(user, group, other) \
SET_AND_CLEAR1(user); \
bits <<= STEP; \
SET_AND_CLEAR1(group); \
bits <<= STEP; \
SET_AND_CLEAR1(other);
bits = ISC_FSACCESS_READ | ISC_FSACCESS_LISTDIRECTORY;
SET_AND_CLEAR(S_IRUSR, S_IRGRP, S_IROTH);
bits = ISC_FSACCESS_WRITE |
ISC_FSACCESS_CREATECHILD |
ISC_FSACCESS_DELETECHILD;
SET_AND_CLEAR(S_IWUSR, S_IWGRP, S_IWOTH);
/*
* Make a mask for the number of bits per owner/group/other.
*/
for (i = mask = 0; i < ISC__FSACCESS_PERMISSIONBITS; i++) {
mask <<= 1;
mask |= 1;
}
* WIN32 doesn't have the concept of execute bits. We leave this here
* for when we review this module.
*
bits = ISC_FSACCESS_EXECUTE |
ISC_FSACCESS_ACCESSCHILD;
#define MAP(isc, win32) \
if ((bits & (isc)) != 0) { \
ea.grfAccessPermissions |= (win32); \
bits &= ~(isc); \
}
SET_AND_CLEAR(S_IXUSR, S_IXGRP, S_IXOTH);
*/
INSIST(access == 0);
for (i = 0; i < 2; i++) {
bits = access & mask;
if (_chmod(path, mode) < 0)
return (isc__errno2result(errno));
pea = &ea[i];
pea->grfAccessPermissions =
SYNCHRONIZE | READ_CONTROL | FILE_READ_ATTRIBUTES;
if (i == 0)
/*
* Owner-only permissions.
*/
pea->grfAccessPermissions |= WRITE_DAC | DELETE;
/*
* File access rights.
*/
MAP(ISC_FSACCESS_READ, FILE_READ_DATA | FILE_READ_EA);
MAP(ISC_FSACCESS_WRITE,
FILE_WRITE_DATA | FILE_WRITE_EA | FILE_APPEND_DATA);
MAP(ISC_FSACCESS_EXECUTE, FILE_EXECUTE);
/*
* Directory access rights.
*/
MAP(ISC_FSACCESS_LISTDIRECTORY, FILE_LIST_DIRECTORY);
MAP(ISC_FSACCESS_CREATECHILD, FILE_CREATE_CHILD);
MAP(ISC_FSACCESS_DELETECHILD, FILE_DELETE_CHILD);
MAP(ISC_FSACCESS_ACCESSCHILD, FILE_TRAVERSE);
/*
* Ensure no other bits were set.
*/
INSIST(bits == 0);
if (i == 2) {
/*
* Setting world.
*/
SID_IDENTIFIER_AUTHORITY authworld =
SECURITY_WORLD_SID_AUTHORITY;
if (AllocateAndInitializeSid(&authworld, 1,
SECURITY_WORLD_RID,
0, 0, 0, 0, 0, 0, 0,
&world)
== 0)
winerror = GetLastError();
else
/*
* This should already be ERROR_SUCCESS.
*/
ENSURE(winerror == ERROR_SUCCESS);
}
if (winerror == ERROR_SUCCESS) {
BuildTrusteeWithSid(&pea->Trustee, psid[i]);
pea->Trustee.Trusteetype = trustee_type[i];
winerror = SetEntriesInAcl(3, ea, NULL, &dacl);
}
if (winerror == ERROR_SUCCESS)
winerror =
SetNamedSecurityInfo(path, SE_FILE_OBJECT,
DACL_SECURITY_INFORMATION,
NULL, NULL, dacl, NULL);
if (winerror == ERROR_SUCCESS)
access >> shift;
else
break;
}
if (sd != NULL)
LocalFree(sd);
if (dacl != NULL)
LocalFree(dacl);
if (world != NULL)
FreeSid(world);
if (winerror == ERROR_SUCCESS) {
/*
* Ensure no other bits were set.
*/
INSIST(access == 0);
return (ISC_R_SUCCESS);
} else
return (isc__winerror2result(winerror));
return (ISC_R_SUCCESS);
}

View File

@@ -15,14 +15,17 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: once.c,v 1.6 2001/01/09 21:58:52 bwelling Exp $ */
/* $Id: once.c,v 1.8 2001/07/08 05:09:10 mayer Exp $ */
/* Principal Authors: DCL */
#include <config.h>
#include <windows.h>
#include <isc/once.h>
#include <isc/assertions.h>
#include <isc/util.h>
isc_result_t
isc_once_do(isc_once_t *controller, void(*function)(void))

View File

@@ -15,12 +15,15 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: stdtime.c,v 1.7 2001/01/09 21:58:53 bwelling Exp $ */
/* $Id: stdtime.c,v 1.9 2001/07/08 05:09:14 mayer Exp $ */
#include <config.h>
#include <time.h>
#include <isc/assertions.h>
#include <isc/stdtime.h>
#include <isc/util.h>
void
isc_stdtime_get(isc_stdtime_t *t) {

View File

@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: thread.c,v 1.14 2001/01/09 21:58:55 bwelling Exp $ */
/* $Id: thread.c,v 1.15 2001/07/06 05:07:54 mayer Exp $ */
#include <config.h>
@@ -58,3 +58,11 @@ isc_thread_join(isc_thread_t thread, isc_threadresult_t *rp) {
return (ISC_R_SUCCESS);
}
void
isc_thread_setconcurrency(unsigned int level) {
/*
* This is unnecessary on Win32 systems
*/
}

View File

@@ -15,7 +15,18 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: time.c,v 1.20 2001/01/09 21:58:56 bwelling Exp $ */
/* $Id: time.c,v 1.21 2001/07/06 05:07:44 mayer Exp $ */
/*
* Windows has a different epoch than Unix. Therefore this code sets the epoch
* value to the Unix epoch. Care should be used when using these routines to
* ensure that this difference is taken into account. System and File times
* may require adjusting for this when modifying any time value that needs
* to be an absolute Windows time.
*
* Currently only epoch-specific code and the isc_time_seconds
* and isc_time_secondsastimet use the epoch-adjusted code.
*/
#include <config.h>
@@ -30,6 +41,7 @@
#include <isc/assertions.h>
#include <isc/time.h>
#include <isc/util.h>
/*
* struct FILETIME uses "100-nanoseconds intervals".
@@ -40,8 +52,23 @@
#define NS_PER_S 1000000000
#define NS_INTERVAL 100
#define INTERVALS_PER_S (NS_PER_S / NS_INTERVAL)
#define UINT64_MAX 0xffffffffffffffffui64
#define UINT64_MAX _UI64_MAX
/***
*** Absolute Times
***/
static isc_time_t epoch = { 0, 0 };
isc_time_t *isc_time_epoch = &epoch;
void
TimetToFileTime(time_t t, LPFILETIME pft) {
LONGLONG i;
i = Int32x32To64(t, 10000000) + 116444736000000000;
pft->dwLowDateTime = (DWORD) i;
pft->dwHighDateTime = (DWORD) (i >>32);
}
/***
*** Intervals
***/
@@ -60,7 +87,7 @@ isc_interval_set(isc_interval_t *i,
*/
REQUIRE(i != NULL);
REQUIRE(nanoseconds < 1000000000);
REQUIRE(nanoseconds < NS_PER_S);
i->interval = (LONGLONG)seconds * INTERVALS_PER_S
+ nanoseconds / NS_INTERVAL;
@@ -81,13 +108,6 @@ isc_interval_iszero(isc_interval_t *i) {
}
/***
*** Absolute Times
***/
static isc_time_t epoch = { 0, 0 };
isc_time_t *isc_time_epoch = &epoch;
void
isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds) {
ULARGE_INTEGER i;
@@ -97,7 +117,7 @@ isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds) {
* epoch.
*/
REQUIRE(t != NULL);
REQUIRE(nanoseconds < 1000000000);
REQUIRE(nanoseconds < NS_PER_S);
i.QuadPart = (LONGLONG)seconds * INTERVALS_PER_S
+ nanoseconds / NS_INTERVAL;
@@ -107,6 +127,11 @@ isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds) {
}
void
isc_time_initepoch() {
TimetToFileTime(0, &epoch.absolute);
}
void
isc_time_settoepoch(isc_time_t *t) {
/*
@@ -115,20 +140,21 @@ isc_time_settoepoch(isc_time_t *t) {
REQUIRE(t != NULL);
t->absolute.dwLowDateTime = 0;
t->absolute.dwHighDateTime = 0;
t->absolute.dwLowDateTime = epoch.absolute.dwLowDateTime;
t->absolute.dwHighDateTime = epoch.absolute.dwHighDateTime;
}
isc_boolean_t
isc_time_isepoch(isc_time_t *t) {
/*
* Returns ISC_TRUE iff. 't' is the epoch ("time zero").
*/
REQUIRE(t != NULL);
if (t->absolute.dwLowDateTime == 0 &&
t->absolute.dwHighDateTime == 0)
if (t->absolute.dwLowDateTime == epoch.absolute.dwLowDateTime &&
t->absolute.dwHighDateTime == epoch.absolute.dwHighDateTime)
return (ISC_TRUE);
return (ISC_FALSE);
@@ -136,6 +162,8 @@ isc_time_isepoch(isc_time_t *t) {
isc_result_t
isc_time_now(isc_time_t *t) {
char dtime[10];
/*
* Set *t to the current absolute time.
*/
@@ -144,6 +172,7 @@ isc_time_now(isc_time_t *t) {
GetSystemTimeAsFileTime(&t->absolute);
_strtime(dtime);
return (ISC_R_SUCCESS);
}
@@ -163,7 +192,7 @@ isc_time_nowplusinterval(isc_time_t *t, isc_interval_t *i) {
i1.LowPart = t->absolute.dwLowDateTime;
i1.HighPart = t->absolute.dwHighDateTime;
if (UINT64_MAX - i1.QuadPart < i->interval)
if (UINT64_MAX - i1.QuadPart < (unsigned __int64)i->interval)
return (ISC_R_RANGE);
i1.QuadPart += i->interval;
@@ -198,7 +227,7 @@ isc_time_add(isc_time_t *t, isc_interval_t *i, isc_time_t *result) {
i1.LowPart = t->absolute.dwLowDateTime;
i1.HighPart = t->absolute.dwHighDateTime;
if (UINT64_MAX - i1.QuadPart < i->interval)
if (UINT64_MAX - i1.QuadPart < (unsigned __int64)i->interval)
return (ISC_R_RANGE);
i1.QuadPart += i->interval;
@@ -222,13 +251,15 @@ isc_time_subtract(isc_time_t *t, isc_interval_t *i, isc_time_t *result) {
i1.LowPart = t->absolute.dwLowDateTime;
i1.HighPart = t->absolute.dwHighDateTime;
if (i.QuadPart < i->interval)
if (i1.QuadPart < (unsigned __int64) i->interval)
return (ISC_R_RANGE);
i1.QuadPart -= i->interval;
result->absolute.dwLowDateTime = i1.LowPart;
result->absolute.dwHighDateTime = i1.HighPart;
return (ISC_R_SUCCESS);
}
isc_uint64_t
@@ -254,16 +285,21 @@ isc_time_microdiff(isc_time_t *t1, isc_time_t *t2) {
return (i3);
}
/*
* Note that the value returned is the seconds relative to the Unix epoch rather than
* the seconds since Windows epoch.
* This is for compatibility with the Unix side.
*/
isc_uint32_t
isc_time_seconds(isc_time_t *t) {
ULARGE_INTEGER i;
REQUIRE(t != NULL);
i.LowPart = t->absolute.dwLowDateTime;
i.HighPart = t->absolute.dwHighDateTime;
i.LowPart = t->absolute.dwLowDateTime - epoch.absolute.dwLowDateTime;
i.HighPart = t->absolute.dwHighDateTime - epoch.absolute.dwHighDateTime;
INSIST(i.QuadPart / INTERVALS_PER_S <= (isc_uint32_t)-1);
// INSIST(i.QuadPart / INTERVALS_PER_S <= (isc_uint32_t)-1);
return ((isc_uint32_t)(i.QuadPart / INTERVALS_PER_S));
}
@@ -278,6 +314,14 @@ isc_time_secondsastimet(isc_time_t *t, time_t *secondsp) {
i1.LowPart = t->absolute.dwLowDateTime;
i1.HighPart = t->absolute.dwHighDateTime;
/*
* Get the time_t zero equivalent in FILETIME
* The zero point for FILETIME is 1 January, 1601
* while for timet it is 1 January, 1970
*/
i1.LowPart -= epoch.absolute.dwLowDateTime;
i1.HighPart -= epoch.absolute.dwHighDateTime;
i1.QuadPart /= INTERVALS_PER_S;
/*
@@ -363,16 +407,13 @@ isc_time_secondsastimet(isc_time_t *t, time_t *secondsp) {
isc_uint32_t
isc_time_nanoseconds(isc_time_t *t) {
ULARGE_INTEGER i;
SYSTEMTIME st;
REQUIRE(t != NULL);
/*
* Convert the time to a SYSTEMTIME structure and the grab the
* milliseconds
*/
FileTimeToSystemTime(&t->absolute, &st);
i.LowPart = t->absolute.dwLowDateTime;
i.HighPart = t->absolute.dwHighDateTime;
i.QuadPart -= isc_time_seconds(t);
ENSURE(i.QuadPart * NS_INTERVAL < NS);
return ((isc_uint32_t)(i.QuadPart * NS_INTERVAL));
return ((isc_uint32_t)(st.wMilliseconds * 1000000));
}