diff options
author | Bernard Normier <bernard@zeroc.com> | 2003-04-12 15:42:19 +0000 |
---|---|---|
committer | Bernard Normier <bernard@zeroc.com> | 2003-04-12 15:42:19 +0000 |
commit | 13eacdd52936ecd6800f959f84fff53e5339e969 (patch) | |
tree | 3063ca8d7bd6a25f1878af3d1801d1273a5b68d5 /cpp | |
parent | Added support for setting environment variables (diff) | |
download | ice-13eacdd52936ecd6800f959f84fff53e5339e969.tar.bz2 ice-13eacdd52936ecd6800f959f84fff53e5339e969.tar.xz ice-13eacdd52936ecd6800f959f84fff53e5339e969.zip |
Updated UUID Unix implementation to use /dev/urandom directly instead of
through E2FSPROGS libuuid.
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/CHANGES | 3 | ||||
-rw-r--r-- | cpp/INSTALL.LINUX | 12 | ||||
-rw-r--r-- | cpp/INSTALL.SOLARIS | 13 | ||||
-rw-r--r-- | cpp/config/Make.rules | 20 | ||||
-rw-r--r-- | cpp/include/IceUtil/UUID.h | 11 | ||||
-rw-r--r-- | cpp/src/IceUtil/Makefile | 4 | ||||
-rw-r--r-- | cpp/src/IceUtil/UUID.cpp | 126 | ||||
-rw-r--r-- | cpp/test/IceUtil/Makefile | 3 | ||||
-rw-r--r-- | cpp/test/IceUtil/uuid/.depend | 1 | ||||
-rw-r--r-- | cpp/test/IceUtil/uuid/Client.cpp | 47 | ||||
-rw-r--r-- | cpp/test/IceUtil/uuid/Makefile | 34 | ||||
-rwxr-xr-x | cpp/test/IceUtil/uuid/run.py | 45 | ||||
-rw-r--r-- | cpp/test/IceUtil/uuid/uuid.dsp | 106 |
13 files changed, 376 insertions, 49 deletions
diff --git a/cpp/CHANGES b/cpp/CHANGES index 40cca5a0c97..d13f5e2e033 100644 --- a/cpp/CHANGES +++ b/cpp/CHANGES @@ -1,6 +1,9 @@ Changes since version 1.0.1 --------------------------- +- Removed dependency on E2FSPROGS for UUID generation. On Unix, + UUIDs are now generated directly with /dev/urandom. + - Added support for `env' XML element in IcePack descriptors to allow setting environment variables. diff --git a/cpp/INSTALL.LINUX b/cpp/INSTALL.LINUX index 354494e7966..8f8017ade5d 100644 --- a/cpp/INSTALL.LINUX +++ b/cpp/INSTALL.LINUX @@ -33,21 +33,17 @@ Third-party libraries - OpenSSL 0.96 or 0.97 -- e2fsprogs 1.27 (only for the UUID library, which is part of this - package) - - bzip2 1.0 Xerces-C++ can be download from: http://xml.apache.org/xerces-c -Berkeley DB, OpenSSL, e2fsprogs, and bzip2 are usually available with -your Linux distribution. The RPMs for Redhat 8.0 are: +Berkeley DB, OpenSSL, and bzip2 are usually available with your Linux +distribution. The RPMs for Redhat 8.0 are: db4-devel-4.0.14-14 openssl-devel-0.9.6b-29 -e2fsprogs-devel-1.27-9 bzip2-devel-1.0.2-5 If you don't have them, you can download Berkeley DB from: @@ -62,10 +58,6 @@ And bzip2 from: http://sources.redhat.com/bzip2 -We are not aware of any download possibilities for e2fsprogs-devel (or -the UUID routines included in this RPM). But to our knowledge, every -Linux distribution includes this, so there should be no problem. - Python 2.2 ---------- diff --git a/cpp/INSTALL.SOLARIS b/cpp/INSTALL.SOLARIS index 3e39028670c..26ef616fb4c 100644 --- a/cpp/INSTALL.SOLARIS +++ b/cpp/INSTALL.SOLARIS @@ -2,6 +2,12 @@ Requirements ====================================================================== +OS +-- +Solaris 8 or Solaris 9 on SPARC. + +You also need to have /dev/urandom installed. This is the default with +Solaris 9; on Solaris 8, you need to install patch 112438-01. C++ compiler ------------ @@ -18,9 +24,6 @@ Third-party libraries - OpenSSL 0.97 -- e2fsprogs 1.32 (only for the UUID library, which is part of this - package) - - bzip2 1.0 Xerces-C++ can be download from: @@ -39,10 +42,6 @@ And bzip2 from: http://sources.redhat.com/bzip2 -And E2fsprogs from: - -http://sourceforge.net/projects/e2fsprogs - Python 2.2 ---------- diff --git a/cpp/config/Make.rules b/cpp/config/Make.rules index 4a00a0e44c6..22fd709eb2a 100644 --- a/cpp/config/Make.rules +++ b/cpp/config/Make.rules @@ -75,18 +75,6 @@ KERBEROS_HOME ?= /usr/kerberos # -# If E2fsprogs is not installed in a standard location where the -# compiler can find it, set E2FSPROGS_HOME to the E2fsprogs -# installation directory. -# E2fsprogs is used only for its UUID library. -# -# - -#E2FSPROGS_HOME ?= /opt/e2fsprogs - - - -# # If readline is not installed in a standard location where the # compiler can find it, AND you want to use readline, # set READLINE_HOME to the readline installation directory. @@ -171,14 +159,6 @@ else XERCESC_LIBS = -lxerces-c endif -ifneq ($(E2FSPROGS_HOME),) - E2FSPROGS_FLAGS = -I$(E2FSPROGS_HOME)/include - E2FSPROGS_LIBS = -L$(E2FSPROGS_HOME)/lib -luuid -else - E2FSPROGS_FLAGS = - E2FSPROGS_LIBS = -luuid -endif - ifneq ($(USE_READLINE),) ifneq ($(READLINE_HOME),) diff --git a/cpp/include/IceUtil/UUID.h b/cpp/include/IceUtil/UUID.h index a49207e6c12..a1902d120f5 100644 --- a/cpp/include/IceUtil/UUID.h +++ b/cpp/include/IceUtil/UUID.h @@ -16,10 +16,21 @@ #define ICE_UTIL_UUID_H #include <IceUtil/Config.h> +#include <IceUtil/Exception.h> namespace IceUtil { +class ICE_UTIL_API UUIDGenerationException : public Exception +{ +public: + + UUIDGenerationException(const char*, int); + virtual std::string ice_name() const; + virtual Exception* ice_clone() const; + virtual void ice_throw() const; +}; + ICE_UTIL_API std::string generateUUID(); } diff --git a/cpp/src/IceUtil/Makefile b/cpp/src/IceUtil/Makefile index a6d950fc77a..6c01957d272 100644 --- a/cpp/src/IceUtil/Makefile +++ b/cpp/src/IceUtil/Makefile @@ -35,8 +35,8 @@ SRCS = $(OBJS:.o=.cpp) include $(top_srcdir)/config/Make.rules -CPPFLAGS := $(CPPFLAGS) $(E2FSPROGS_FLAGS) -LINKWITH := $(STLPORT_LIBS) $(E2FSPROGS_LIBS) +CPPFLAGS := $(CPPFLAGS) +LINKWITH := $(STLPORT_LIBS) $(VERSIONED_NAME): $(OBJS) rm -f $@ diff --git a/cpp/src/IceUtil/UUID.cpp b/cpp/src/IceUtil/UUID.cpp index 70932f32eb6..db3070a8e9e 100644 --- a/cpp/src/IceUtil/UUID.cpp +++ b/cpp/src/IceUtil/UUID.cpp @@ -15,17 +15,71 @@ #include <IceUtil/UUID.h> #include <IceUtil/Unicode.h> +// On Windows, we use Windows's RPC UUID generator. +// On other platforms, we use a high quality random number generator +// (/dev/random) to generate "version 4" UUIDs, as described in +// http://www.ietf.org/internet-drafts/draft-mealling-uuid-urn-00.txt + +#include <assert.h> + #ifdef _WIN32 # include <rpc.h> #else -extern "C" // uuid/uuid.h seems to miss extern "C" declarations. -{ -# include <uuid/uuid.h> -} +#include <sys/types.h> +# include <sys/stat.h> +# include <fcntl.h> +# include <unistd.h> #endif using namespace std; +// Helper char to hex functions +// +inline void halfByteToHex(unsigned char hb, char*& hexBuffer) +{ + if(hb < 10) + { + *hexBuffer++ = '0' + hb; + } + else + { + *hexBuffer++ = 'A' + (hb - 10); + } +} + +inline void bytesToHex(unsigned char* bytes, int len, char*& hexBuffer) +{ + for(int i = 0; i < len; i++) + { + halfByteToHex((bytes[i] & 0xF0) >> 4, hexBuffer); + halfByteToHex((bytes[i] & 0x0F), hexBuffer); + } +} + + +IceUtil::UUIDGenerationException::UUIDGenerationException(const char* file, int line) : + Exception(file, line) +{} + +string +IceUtil::UUIDGenerationException::ice_name() const +{ + return "IceUtil::UUIDGenerationException"; +} + +IceUtil::Exception* +IceUtil::UUIDGenerationException::ice_clone() const +{ + return new UUIDGenerationException(*this); +} + +void +IceUtil::UUIDGenerationException::ice_throw() const +{ + throw *this; +} + + string IceUtil::generateUUID() { @@ -55,13 +109,67 @@ IceUtil::generateUUID() #else - uuid_t uuid; - uuid_generate(uuid); + // On Linux, /dev/random, even when used in blocking mode, sometimes + // fails or returns fewer bytes. + // Maybe we should use a combination of version 4 UUIDs (with /dev/random), + // and version 1 UUIDs (MAC address + time), when /dev/random is exhausted? + + int fd = open("/dev/urandom", O_RDONLY); + + if (fd == -1) + { + assert(0); + throw UUIDGenerationException(__FILE__, __LINE__); + } + + struct UUID + { + unsigned char timeLow[4]; + unsigned char timeMid[2]; + unsigned char timeHighAndVersion[2]; + unsigned char clockSeqHiAndReserved; + unsigned char clockSeqLow; + unsigned char node[6]; + }; + UUID uuid; + + assert(sizeof(UUID) == 16); + + ssize_t bytesRead = read(fd, &uuid, sizeof(UUID)); + + if (bytesRead != sizeof(UUID)) + { + assert(0); + close(fd); + throw UUIDGenerationException(__FILE__, __LINE__); + } + + close(fd); + + // Adjust the bits that say "version 4" UUID + // + uuid.timeHighAndVersion[0] &= 0x0F; + uuid.timeHighAndVersion[0] |= (3 << 4); + uuid.clockSeqHiAndReserved &= 0x3F; + uuid.clockSeqHiAndReserved |= 0x80; - char str[37]; - uuid_unparse(uuid, str); + // Convert to a UUID string + // + char uuidString[16 * 2 + 4 + 1]; // 16 bytes, 4 '-' and a final '\0' + char* uuidIndex = uuidString; + bytesToHex(uuid.timeLow, sizeof(uuid.timeLow), uuidIndex); + *uuidIndex++ = '-'; + bytesToHex(uuid.timeMid, sizeof(uuid.timeMid), uuidIndex); + *uuidIndex++ = '-'; + bytesToHex(uuid.timeHighAndVersion, sizeof(uuid.timeHighAndVersion), uuidIndex); + *uuidIndex++ = '-'; + bytesToHex(&uuid.clockSeqHiAndReserved, sizeof(uuid.clockSeqHiAndReserved), uuidIndex); + bytesToHex(&uuid.clockSeqLow, sizeof(uuid.clockSeqLow), uuidIndex); + *uuidIndex++ = '-'; + bytesToHex(uuid.node, sizeof(uuid.node), uuidIndex); + *uuidIndex = '\0'; - return str; + return uuidString; #endif } diff --git a/cpp/test/IceUtil/Makefile b/cpp/test/IceUtil/Makefile index 1a636b8e4ae..f364f682ec3 100644 --- a/cpp/test/IceUtil/Makefile +++ b/cpp/test/IceUtil/Makefile @@ -18,7 +18,8 @@ include $(top_srcdir)/config/Make.rules SUBDIRS = thread \ unicode \ - inputUtil + inputUtil \ + uuid $(EVERYTHING):: @for subdir in $(SUBDIRS); \ diff --git a/cpp/test/IceUtil/uuid/.depend b/cpp/test/IceUtil/uuid/.depend new file mode 100644 index 00000000000..5b9c0c4fba7 --- /dev/null +++ b/cpp/test/IceUtil/uuid/.depend @@ -0,0 +1 @@ +Client.o: Client.cpp ../../../include/IceUtil/Unicode.h ../../../include/IceUtil/Config.h ../../include/TestCommon.h diff --git a/cpp/test/IceUtil/uuid/Client.cpp b/cpp/test/IceUtil/uuid/Client.cpp new file mode 100644 index 00000000000..7a66f5de927 --- /dev/null +++ b/cpp/test/IceUtil/uuid/Client.cpp @@ -0,0 +1,47 @@ +// ********************************************************************** +// +// Copyright (c) 2003 +// ZeroC, Inc. +// Billerica, MA, USA +// +// All Rights Reserved. +// +// Ice is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License version 2 as published by +// the Free Software Foundation. +// +// ********************************************************************** + +#include <IceUtil/UUID.h> +#include <IceUtil/Time.h> +#include <TestCommon.h> +#include <set> + +using namespace IceUtil; +using namespace std; + +int +main() +{ + const int howMany = 100000; + + cout << "Generating " << howMany << " UUIds ... " << endl; + + set<string> uuidSet; + + Time start = Time::now(); + for (int i = 0; i < howMany; i++) + { + pair<set<string>::iterator, bool> ok + = uuidSet.insert(generateUUID()); + test(ok.second); + } + Time finish = Time::now(); + + cout << "UUIDs generated every 100 ns: " + << (double) howMany / ((finish - start).toMicroSeconds() * 10) + << endl; + cout << "ok" << endl; + + return EXIT_SUCCESS; +} diff --git a/cpp/test/IceUtil/uuid/Makefile b/cpp/test/IceUtil/uuid/Makefile new file mode 100644 index 00000000000..93c28e32751 --- /dev/null +++ b/cpp/test/IceUtil/uuid/Makefile @@ -0,0 +1,34 @@ +# ********************************************************************** +# +# Copyright (c) 2003 +# ZeroC, Inc. +# Billerica, MA, USA +# +# All Rights Reserved. +# +# Ice is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License version 2 as published by +# the Free Software Foundation. +# +# ********************************************************************** + +top_srcdir = ../../.. + +CLIENT = client + +TARGETS = $(CLIENT) + +OBJS = Client.o + + +SRCS = $(OBJS:.o=.cpp) + +include $(top_srcdir)/config/Make.rules + +CPPFLAGS := -I. -I../../include $(CPPFLAGS) + +$(CLIENT): $(OBJS) + rm -f $@ + $(CXX) $(LDFLAGS) -o $@ $(OBJS) $(BASELIBS) + +include .depend diff --git a/cpp/test/IceUtil/uuid/run.py b/cpp/test/IceUtil/uuid/run.py new file mode 100755 index 00000000000..35af18aaf04 --- /dev/null +++ b/cpp/test/IceUtil/uuid/run.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003 +# ZeroC, Inc. +# Billerica, MA, USA +# +# All Rights Reserved. +# +# Ice is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License version 2 as published by +# the Free Software Foundation. +# +# ********************************************************************** + +import os, sys + +for toplevel in [".", "..", "../..", "../../..", "../../../.."]: + toplevel = os.path.normpath(toplevel) + if os.path.exists(os.path.join(toplevel, "config", "TestUtil.py")): + break +else: + raise "can't find toplevel directory!" + +sys.path.append(os.path.join(toplevel, "config")) +import TestUtil + +name = os.path.join("IceUtil", "uuid") +testdir = os.path.join(toplevel, "test", name) + +client = os.path.join(testdir, "client") + +print "starting client...", +clientPipe = os.popen(client) +print "ok" + +for output in clientPipe.xreadlines(): + print output, + +clientStatus = clientPipe.close() + +if clientStatus: + sys.exit(1) + +sys.exit(0) diff --git a/cpp/test/IceUtil/uuid/uuid.dsp b/cpp/test/IceUtil/uuid/uuid.dsp new file mode 100644 index 00000000000..70b26ea0778 --- /dev/null +++ b/cpp/test/IceUtil/uuid/uuid.dsp @@ -0,0 +1,106 @@ +# Microsoft Developer Studio Project File - Name="uuid" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=uuid - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "uuid.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "uuid.mak" CFG="uuid - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "uuid - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "uuid - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "uuid - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /WX /GR /GX /O2 /I "." /I "../../../include" /I "../../include" /D "NDEBUG" /D "_CONSOLE" /D "_UNICODE" /YX /FD /c
+# SUBTRACT CPP /Fr
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 /nologo /subsystem:console /machine:I386 /out:"client.exe" /libpath:"../../../lib"
+# SUBTRACT LINK32 /nodefaultlib
+
+!ELSEIF "$(CFG)" == "uuid - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /WX /Gm /GR /GX /Zi /Od /I "." /I "../../../include" /I "../../include" /D "_DEBUG" /D "_CONSOLE" /D "_UNICODE" /YX /FD /GZ /c
+# SUBTRACT CPP /Fr
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /out:"client.exe" /pdbtype:sept /libpath:"../../../lib"
+# SUBTRACT LINK32 /nodefaultlib
+
+!ENDIF
+
+# Begin Target
+
+# Name "uuid - Win32 Release"
+# Name "uuid - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\Client.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
|