📄 uxrng.c
字号:
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- *//* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (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.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Netscape Portable Runtime (NSPR). * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1999-2000 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */#include "primpl.h"#include <string.h>#include <unistd.h>#include <errno.h>#include <sys/time.h>#if defined(SOLARIS)static size_tGetHighResClock(void *buf, size_t maxbytes){ hrtime_t t; t = gethrtime(); if (t) { return _pr_CopyLowBits(buf, maxbytes, &t, sizeof(t)); } return 0;}#elif defined(SUNOS4)static size_tGetHighResClock(void *buf, size_t maxbytes){ return 0;}#elif defined(HPUX)#ifdef __ia64#include <ia64/sys/inline.h>static size_tGetHighResClock(void *buf, size_t maxbytes){ PRUint64 t; t = _Asm_mov_from_ar(_AREG44); return _pr_CopyLowBits(buf, maxbytes, &t, sizeof(t));}#elsestatic size_tGetHighResClock(void *buf, size_t maxbytes){ extern int ret_cr16(); int cr16val; cr16val = ret_cr16(); return(_pr_CopyLowBits(buf, maxbytes, &cr16val, sizeof(cr16val)));}#endif#elif defined(OSF1)#include <c_asm.h>/* * Use the "get the cycle counter" instruction on the alpha. * The low 32 bits completely turn over in less than a minute. * The high 32 bits are some non-counter gunk that changes sometimes. */static size_tGetHighResClock(void *buf, size_t maxbytes){ unsigned long t;#ifdef __GNUC__ __asm__("rpcc %0" : "=r" (t));#else t = asm("rpcc %v0");#endif return _pr_CopyLowBits(buf, maxbytes, &t, sizeof(t));}#elif defined(VMS)#include <ints.h>/* * Use the "get the cycle counter" instruction on the alpha. * The low 32 bits completely turn over in less than a minute. * The high 32 bits are some non-counter gunk that changes sometimes. */static size_tGetHighResClock(void *buf, size_t maxbytes){ uint64 t; t = __RPCC(); return _pr_CopyLowBits(buf, maxbytes, &t, sizeof(t));}#elif defined(AIX)static size_tGetHighResClock(void *buf, size_t maxbytes){ return 0;}#elif (defined(LINUX) || defined(FREEBSD) || defined(NETBSD) || defined(OPENBSD))#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>static int fdDevRandom;static PRCallOnceType coOpenDevRandom;static PRStatus OpenDevRandom( void ){ fdDevRandom = open( "/dev/random", O_RDONLY ); return((-1 == fdDevRandom)? PR_FAILURE : PR_SUCCESS );} /* end OpenDevRandom() */static size_t GetDevRandom( void *buf, size_t size ){ int bytesIn; int rc; rc = PR_CallOnce( &coOpenDevRandom, OpenDevRandom ); if ( PR_FAILURE == rc ) { _PR_MD_MAP_OPEN_ERROR( errno ); return(0); } bytesIn = read( fdDevRandom, buf, size ); if ( -1 == bytesIn ) { _PR_MD_MAP_READ_ERROR( errno ); return(0); } return( bytesIn );} /* end GetDevRandom() */static size_tGetHighResClock(void *buf, size_t maxbytes){ return(GetDevRandom( buf, maxbytes ));}#elif defined(NCR)static size_tGetHighResClock(void *buf, size_t maxbytes){ return 0;}#elif defined(IRIX)#include <fcntl.h>#undef PRIVATE#include <sys/mman.h>#include <sys/syssgi.h>#include <sys/immu.h>#include <sys/systeminfo.h>#include <sys/utsname.h>static size_t GetHighResClock(void *buf, size_t maxbuf){ unsigned phys_addr, raddr, cycleval; static volatile unsigned *iotimer_addr = NULL; static int tries = 0; static int cntr_size; int mfd; unsigned s0[2];#ifndef SGI_CYCLECNTR_SIZE#define SGI_CYCLECNTR_SIZE 165 /* Size user needs to use to read CC */#endif if (iotimer_addr == NULL) { if (tries++ > 1) { /* Don't keep trying if it didn't work */ return 0; } /* ** For SGI machines we can use the cycle counter, if it has one, ** to generate some truly random numbers */ phys_addr = syssgi(SGI_QUERY_CYCLECNTR, &cycleval); if (phys_addr) { int pgsz = getpagesize(); int pgoffmask = pgsz - 1; raddr = phys_addr & ~pgoffmask; mfd = open("/dev/mmem", O_RDONLY); if (mfd < 0) { return 0; } iotimer_addr = (unsigned *) mmap(0, pgoffmask, PROT_READ, MAP_PRIVATE, mfd, (int)raddr); if (iotimer_addr == (unsigned*)-1) { close(mfd); iotimer_addr = NULL; return 0; } iotimer_addr = (unsigned*) ((__psint_t)iotimer_addr | (phys_addr & pgoffmask)); /* * The file 'mfd' is purposefully not closed. */ cntr_size = syssgi(SGI_CYCLECNTR_SIZE); if (cntr_size < 0) { struct utsname utsinfo; /* * We must be executing on a 6.0 or earlier system, since the * SGI_CYCLECNTR_SIZE call is not supported. * * The only pre-6.1 platforms with 64-bit counters are * IP19 and IP21 (Challenge, PowerChallenge, Onyx). */ uname(&utsinfo); if (!strncmp(utsinfo.machine, "IP19", 4) || !strncmp(utsinfo.machine, "IP21", 4)) cntr_size = 64; else cntr_size = 32; } cntr_size /= 8; /* Convert from bits to bytes */ } } s0[0] = *iotimer_addr; if (cntr_size > 4) s0[1] = *(iotimer_addr + 1); memcpy(buf, (char *)&s0[0], cntr_size); return _pr_CopyLowBits(buf, maxbuf, &s0, cntr_size);}#elif defined(SONY)static size_tGetHighResClock(void *buf, size_t maxbytes){ return 0;}#elif defined(SNI)#include <sys/times.h>static size_tGetHighResClock(void *buf, size_t maxbytes){ int ticks; struct tms buffer; ticks=times(&buffer); return _pr_CopyLowBits(buf, maxbytes, &ticks, sizeof(ticks));}#elif defined(NEC)static size_tGetHighResClock(void *buf, size_t maxbytes){ return 0;}#elif defined(SCO) || defined(UNIXWARE) || defined(BSDI) || defined(NTO) \ || defined(QNX) || defined(DARWIN)#include <sys/times.h>static size_tGetHighResClock(void *buf, size_t maxbytes){ int ticks; struct tms buffer; ticks=times(&buffer); return _pr_CopyLowBits(buf, maxbytes, &ticks, sizeof(ticks));}#else#error! Platform undefined#endif /* defined(SOLARIS) */extern PRSize _PR_MD_GetRandomNoise( void *buf, PRSize size ){ struct timeval tv; int n = 0; int s; n += GetHighResClock(buf, size); size -= n; GETTIMEOFDAY(&tv); if ( size > 0 ) { s = _pr_CopyLowBits((char*)buf+n, size, &tv.tv_usec, sizeof(tv.tv_usec)); size -= s; n += s; } if ( size > 0 ) { s = _pr_CopyLowBits((char*)buf+n, size, &tv.tv_sec, sizeof(tv.tv_usec)); size -= s; n += s; } return n;} /* end _PR_MD_GetRandomNoise() */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -