summaryrefslogtreecommitdiff
path: root/misc/unix
diff options
context:
space:
mode:
authorbjh <bjh@13f79535-47bb-0310-9956-ffa450edef68>2004-03-14 03:01:08 +0000
committerbjh <bjh@13f79535-47bb-0310-9956-ffa450edef68>2004-03-14 03:01:08 +0000
commit5b507a910413e784e51222a5c37d8906e7ecf2a5 (patch)
treec030018f5f3908b50846efdc3ec45f311cd381b0 /misc/unix
parent44a69f2dcf6d14b35a1658605026b2d3b9c05d35 (diff)
downloadlibapr-5b507a910413e784e51222a5c37d8906e7ecf2a5.tar.gz
Reorganise the OS/2 random byte generation code to work with the new build scheme.
This is needed so buildconf uses misc/unix for OS/2. git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@64985 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'misc/unix')
-rw-r--r--misc/unix/rand.c2
-rw-r--r--misc/unix/randbyte_os2.inc122
2 files changed, 123 insertions, 1 deletions
diff --git a/misc/unix/rand.c b/misc/unix/rand.c
index d29c5581d..894022f6d 100644
--- a/misc/unix/rand.c
+++ b/misc/unix/rand.c
@@ -198,7 +198,7 @@ APR_DECLARE(apr_status_t) apr_generate_random_bytes(unsigned char *buf,
#undef XSTR
#ifdef OS2
-#include "../os2/randbyte.c"
+#include "randbyte_os2.inc"
#endif
#endif /* APR_HAS_RANDOM */
diff --git a/misc/unix/randbyte_os2.inc b/misc/unix/randbyte_os2.inc
new file mode 100644
index 000000000..e5c9bcb45
--- /dev/null
+++ b/misc/unix/randbyte_os2.inc
@@ -0,0 +1,122 @@
+/* Copyright 2000-2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* The high resolution timer API provides access to the hardware timer
+ * running at around 1.1MHz. The amount this changes in a time slice is
+ * varies randomly due to system events, hardware interrupts etc
+ */
+static UCHAR randbyte_hrtimer()
+{
+ QWORD t1, t2;
+ UCHAR byte;
+
+ DosTmrQueryTime(&t1);
+ DosSleep(5);
+ DosTmrQueryTime(&t2);
+
+ byte = (t2.ulLo - t1.ulLo) & 0xFF;
+ byte ^= (t2.ulLo - t1.ulLo) >> 8;
+ return byte;
+}
+
+
+
+/* A bunch of system information like memory & process stats.
+ * Not highly random but every bit helps....
+ */
+static UCHAR randbyte_sysinfo()
+{
+ UCHAR byte = 0;
+ UCHAR SysVars[100];
+ int b;
+
+ DosQuerySysInfo(1, QSV_FOREGROUND_PROCESS, SysVars, sizeof(SysVars));
+
+ for (b = 0; b < 100; b++) {
+ byte ^= SysVars[b];
+ }
+
+ return byte;
+}
+
+
+
+/* Similar in concept to randbyte_hrtimer() but accesses the CPU's internal
+ * counters which run at the CPU's MHz speed. We get separate
+ * idle / busy / interrupt cycle counts which should provide very good
+ * randomness due to interference of hardware events.
+ * This only works on newer CPUs (at least PPro or K6) and newer OS/2 versions
+ * which is why it's run-time linked.
+ */
+
+static APIRET APIENTRY(*DosPerfSysCall) (ULONG ulCommand, ULONG ulParm1,
+ ULONG ulParm2, ULONG ulParm3) = NULL;
+static HMODULE hDoscalls = 0;
+#define CMD_KI_RDCNT (0x63)
+
+typedef struct _CPUUTIL {
+ ULONG ulTimeLow; /* Low 32 bits of time stamp */
+ ULONG ulTimeHigh; /* High 32 bits of time stamp */
+ ULONG ulIdleLow; /* Low 32 bits of idle time */
+ ULONG ulIdleHigh; /* High 32 bits of idle time */
+ ULONG ulBusyLow; /* Low 32 bits of busy time */
+ ULONG ulBusyHigh; /* High 32 bits of busy time */
+ ULONG ulIntrLow; /* Low 32 bits of interrupt time */
+ ULONG ulIntrHigh; /* High 32 bits of interrupt time */
+} CPUUTIL;
+
+
+static UCHAR randbyte_perf()
+{
+ UCHAR byte = 0;
+ CPUUTIL util;
+ int c;
+
+ if (hDoscalls == 0) {
+ char failed_module[20];
+ ULONG rc;
+
+ rc = DosLoadModule(failed_module, sizeof(failed_module), "DOSCALLS",
+ &hDoscalls);
+
+ if (rc == 0) {
+ rc = DosQueryProcAddr(hDoscalls, 976, NULL, (PFN *)&DosPerfSysCall);
+
+ if (rc) {
+ DosPerfSysCall = NULL;
+ }
+ }
+ }
+
+ if (DosPerfSysCall) {
+ if (DosPerfSysCall(CMD_KI_RDCNT, (ULONG)&util, 0, 0) == 0) {
+ for (c = 0; c < sizeof(util); c++) {
+ byte ^= ((UCHAR *)&util)[c];
+ }
+ }
+ else {
+ DosPerfSysCall = NULL;
+ }
+ }
+
+ return byte;
+}
+
+
+
+static UCHAR randbyte()
+{
+ return randbyte_hrtimer() ^ randbyte_sysinfo() ^ randbyte_perf();
+}