summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
authorBernard Normier <bernard@zeroc.com>2003-04-12 15:42:19 +0000
committerBernard Normier <bernard@zeroc.com>2003-04-12 15:42:19 +0000
commit13eacdd52936ecd6800f959f84fff53e5339e969 (patch)
tree3063ca8d7bd6a25f1878af3d1801d1273a5b68d5 /cpp
parentAdded support for setting environment variables (diff)
downloadice-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/CHANGES3
-rw-r--r--cpp/INSTALL.LINUX12
-rw-r--r--cpp/INSTALL.SOLARIS13
-rw-r--r--cpp/config/Make.rules20
-rw-r--r--cpp/include/IceUtil/UUID.h11
-rw-r--r--cpp/src/IceUtil/Makefile4
-rw-r--r--cpp/src/IceUtil/UUID.cpp126
-rw-r--r--cpp/test/IceUtil/Makefile3
-rw-r--r--cpp/test/IceUtil/uuid/.depend1
-rw-r--r--cpp/test/IceUtil/uuid/Client.cpp47
-rw-r--r--cpp/test/IceUtil/uuid/Makefile34
-rwxr-xr-xcpp/test/IceUtil/uuid/run.py45
-rw-r--r--cpp/test/IceUtil/uuid/uuid.dsp106
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