From 599b966b41aff639fedf4753a3fd41caa223ce8a Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Thu, 31 Jan 2008 21:47:39 +0000 Subject: [PATCH] Compile time and runtime checks for library compatibility --- libisoburn/trunk/libisoburn/burn_wrap.c | 127 ++++++++++++++++-- libisoburn/trunk/libisoburn/libisoburn.h | 86 +++++++++--- .../trunk/xorriso/make_xorriso_standalone.sh | 8 +- libisoburn/trunk/xorriso/xorriso_timestamp.h | 2 +- libisoburn/trunk/xorriso/xorrisoburn.h | 6 + 5 files changed, 199 insertions(+), 30 deletions(-) diff --git a/libisoburn/trunk/libisoburn/burn_wrap.c b/libisoburn/trunk/libisoburn/burn_wrap.c index cd7f0337..01e1ce7b 100644 --- a/libisoburn/trunk/libisoburn/burn_wrap.c +++ b/libisoburn/trunk/libisoburn/burn_wrap.c @@ -49,7 +49,89 @@ extern struct isoburn *isoburn_list_start; /* in isoburn.c */ int isoburn_initialize(char msg[1024], int flag) { - int major, minor, micro; + int major, minor, micro, bad_match= 0; + + +/* First two ugly compile time checks for header version compatibility. + If everthing matches, then they produce no C code. In case of mismatch, + intentionally faulty C code will be inserted. +*/ + +#ifdef iso_lib_header_version_major +/* The minimum requirement of libisoburn towards the libisofs header + at compile time is defined in libisoburn/libisoburn.h : + isoburn_libisofs_req_major + isoburn_libisofs_req_minor + isoburn_libisofs_req_micro + It gets compared against the version macros in libisofs/libisofs.h : + iso_lib_header_version_major + iso_lib_header_version_minor + iso_lib_header_version_micro + If the header is too old then the following code shall cause failure of + cdrskin compilation rather than to allow production of a program with + unpredictable bugs or memory corruption. + The compiler messages supposed to appear in this case are: + error: 'LIBISOFS_MISCONFIGURATION' undeclared (first use in this function) + error: 'INTENTIONAL_ABORT_OF_COMPILATION__HEADERFILE_libisofs_dot_h_TOO_OLD__SEE_libisoburn_dot_h_and_burn_wrap_dot_h' undeclared (first use in this function) + error: 'LIBISOFS_MISCONFIGURATION_' undeclared (first use in this function) +*/ +/* The indendation is an advise of man gcc to help old compilers ignoring */ + #if isoburn_libisofs_req_major > iso_lib_header_version_major + #define Isoburn_libisofs_dot_h_too_olD 1 + #endif + #if isoburn_libisofs_req_major == iso_lib_header_version_major && isoburn_libisofs_req_minor > iso_lib_header_version_minor + #define Isoburn_libisofs_dot_h_too_olD 1 + #endif + #if isoburn_libisofs_req_minor == iso_lib_header_version_minor && isoburn_libisofs_req_micro > iso_lib_header_version_micro + #define Isoburn_libisofs_dot_h_too_olD 1 + #endif + +#ifdef Isoburn_libisofs_dot_h_too_olD +LIBISOFS_MISCONFIGURATION = 0; +INTENTIONAL_ABORT_OF_COMPILATION__HEADERFILE_libisofs_dot_h_TOO_OLD__SEE_libisoburn_dot_h_and_burn_wrap_dot_h = 0; +LIBISOFS_MISCONFIGURATION_ = 0; +#endif + +#endif /* iso_lib_header_version_major */ + +/* The minimum requirement of libisoburn towards the libburn header + at compile time is defined in libisoburn/libisoburn.h : + isoburn_libburn_req_major + isoburn_libburn_req_minor + isoburn_libburn_req_micro + It gets compared against the version macros in libburn/libburn.h : + burn_header_version_major + burn_header_version_minor + burn_header_version_micro + If the header is too old then the following code shall cause failure of + cdrskin compilation rather than to allow production of a program with + unpredictable bugs or memory corruption. + The compiler messages supposed to appear in this case are: + error: 'LIBBURN_MISCONFIGURATION' undeclared (first use in this function) + error: 'INTENTIONAL_ABORT_OF_COMPILATION__HEADERFILE_libburn_dot_h_TOO_OLD__SEE_libisoburn_dot_h_and_burn_wrap_dot_h' undeclared (first use in this function) + error: 'LIBBURN_MISCONFIGURATION_' undeclared (first use in this function) +*/ + +/* The indendation is an advise of man gcc to help old compilers ignoring */ + #if isoburn_libburn_req_major > burn_header_version_major + #define Isoburn_libburn_dot_h_too_olD 1 + #endif + #if isoburn_libburn_req_major == burn_header_version_major && isoburn_libburn_req_minor > burn_header_version_minor + #define Isoburn_libburn_dot_h_too_olD 1 + #endif + #if isoburn_libburn_req_minor == burn_header_version_minor && isoburn_libburn_req_micro > burn_header_version_micro + #define Isoburn_libburn_dot_h_too_olD 1 + #endif + +#ifdef Isoburn_libburn_dot_h_too_olD +LIBBURN_MISCONFIGURATION = 0; +INTENTIONAL_ABORT_OF_COMPILATION__HEADERFILE_libburn_dot_h_TOO_OLD__SEE_libisoburn_dot_h_and_burn_wrap_dot_h = 0; +LIBBURN_MISCONFIGURATION_ = 0; +#endif + +/* End of ugly compile time tests (scroll up for explanation) */ + + msg[0]= 0; if(iso_init()<0) { @@ -57,33 +139,56 @@ int isoburn_initialize(char msg[1024], int flag) return(0); } iso_lib_version(&major, &minor, µ); - sprintf(msg+strlen(msg), "libisofs-%d.%d.%d , ", major, minor, micro); - - /* >>> check for suitability of library */ + sprintf(msg+strlen(msg), "libisofs-%d.%d.%d ", major, minor, micro); +#ifdef iso_lib_header_version_major + if(iso_lib_is_compatible(iso_lib_header_version_major, + iso_lib_header_version_minor, + iso_lib_header_version_micro)) { + sprintf(msg+strlen(msg), "ok, "); + } else { + sprintf(msg+strlen(msg),"- TOO OLD -, need at least libisofs-%d.%d.%d ,\n", + iso_lib_header_version_major, iso_lib_header_version_minor, + iso_lib_header_version_micro); + bad_match= 1; + } +#else + if(iso_lib_is_compatible(isoburn_libisofs_req_major, + isoburn_libisofs_req_minor, + isoburn_libisofs_req_micro)) { + sprintf(msg+strlen(msg), "suspicious, "); + } else { + sprintf(msg+strlen(msg),"- TOO OLD -, need at least libisofs-%d.%d.%d ,\n", + isoburn_libisofs_req_major, isoburn_libisofs_req_minor, + isoburn_libisofs_req_micro); + bad_match= 1; + } +#endif /* ! iso_lib_header_version_major */ if(!burn_initialize()) { sprintf(msg+strlen(msg), "Cannot initialize libburn\n"); return(0); } burn_version(&major, &minor, µ); - sprintf(msg+strlen(msg), "libburn-%d.%d.%d , ", major, minor, micro); + sprintf(msg+strlen(msg), "libburn-%d.%d.%d ", major, minor, micro); if(major > burn_header_version_major || (major == burn_header_version_major && (minor > burn_header_version_minor || (minor == burn_header_version_minor && micro >= burn_header_version_micro)))) { - ; /* ok */ + sprintf(msg+strlen(msg), "ok, "); } else { - sprintf(msg+strlen(msg), "- TOO OLD -, need at least libburn-%d.%d.%d , \n", + sprintf(msg+strlen(msg), "- TOO OLD -, need at least libburn-%d.%d.%d ,\n", burn_header_version_major, burn_header_version_minor, burn_header_version_micro); - return(0); + bad_match= 1; } - isoburn_destroy_all(&isoburn_list_start, 0); /* isoburn_list_start= NULL */ - isoburn_version(&major, &minor, µ); - sprintf(msg+strlen(msg), "libisoburn-%d.%d.%d", major, minor, micro); + sprintf(msg+strlen(msg), "for libisoburn-%d.%d.%d", major, minor, micro); + if(bad_match) + return(0); + + isoburn_destroy_all(&isoburn_list_start, 0); /* isoburn_list_start= NULL */ return(1); } diff --git a/libisoburn/trunk/libisoburn/libisoburn.h b/libisoburn/trunk/libisoburn/libisoburn.h index e359927f..0e51f48a 100644 --- a/libisoburn/trunk/libisoburn/libisoburn.h +++ b/libisoburn/trunk/libisoburn/libisoburn.h @@ -138,21 +138,6 @@ int isoburn_initialize(char msg[1024], int flag); int isoburn_is_compatible(int major, int minor, int micro, int flag); -/** These three release version numbers tell the revision of this header file - and of the API it describes. They are memorized by applications at build - time. -*/ -#define isoburn_header_version_major 0 -#define isoburn_header_version_minor 0 -#define isoburn_header_version_micro 1 -/** Note: - Above version numbers are also recorded in configure.ac because libtool - wants them as parameters at build time. - For the library compatibility check ISOBURN_*_VERSION in configure.ac - are not decisive. Only the three numbers above do matter. -*/ - - /** Obtain the three release version numbers of the library. These are the numbers encountered by the application when linking with libisoburn, i.e. possibly not before run time. @@ -174,6 +159,77 @@ int isoburn_is_compatible(int major, int minor, int micro, int flag); */ void isoburn_version(int *major, int *minor, int *micro); +/** The minimum version of libisofs to be used with this version of libisoburn +*/ +#define isoburn_libisofs_req_major 0 +#define isoburn_libisofs_req_minor 6 +#define isoburn_libisofs_req_micro 1 + +/** The minimum version of libburn to be used with this version of libisoburn +*/ +#define isoburn_libburn_req_major 0 +#define isoburn_libburn_req_minor 4 +#define isoburn_libburn_req_micro 2 + +/** These three release version numbers tell the revision of this header file + and of the API it describes. They are memorized by applications at build + time. +*/ +#define isoburn_header_version_major 0 +#define isoburn_header_version_minor 0 +#define isoburn_header_version_micro 1 +/** Note: + Above version numbers are also recorded in configure.ac because libtool + wants them as parameters at build time. + For the library compatibility check ISOBURN_*_VERSION in configure.ac + are not decisive. Only the three numbers above do matter. +*/ +/** Usage discussion: + +Some developers of the libburnia project have differing +opinions how to ensure the compatibility of libaries +and applications. + +It is about whether to use at compile time and at runtime +the version numbers isoburn_header_version_* provided here. +Thomas Schmitt advises to use them. +Vreixo Formoso advises to use other means. + +At compile time: + +Vreixo Formoso advises to leave proper version matching +to properly programmed checks in the the application's +build system, which will eventually refuse compilation. + +Thomas Schmitt advises to use the macros defined here +for comparison with the application's requirements of +library revisions and to eventually break compilation. + +Both advises are combinable. I.e. be master of your +build system and have #if checks in the source code +of your application, nevertheless. + +At runtime (via *_is_compatible()): + +Vreixo Formoso advises to compare the application's +requirements of library revisions with the runtime +library. This is to allow runtime libraries which are +young enough for the application but too old for +the lib*.h files seen at compile time. + +Thomas Schmitt advises to compare the header +revisions defined here with the runtime library. +This is to enforce a strictly monotonous chain +of revisions from app to header to library, +at the cost of excluding some older libraries. + +These two advises are mutually exclusive. + +For an implementation of the Thomas Schmitt approach, +see libisoburn/burn_wrap.c : isoburn_initialize() + +*/ + /** Aquire a target drive by its filesystem path resp. libburn persistent address. diff --git a/libisoburn/trunk/xorriso/make_xorriso_standalone.sh b/libisoburn/trunk/xorriso/make_xorriso_standalone.sh index 91474bc6..b845f9d6 100755 --- a/libisoburn/trunk/xorriso/make_xorriso_standalone.sh +++ b/libisoburn/trunk/xorriso/make_xorriso_standalone.sh @@ -134,14 +134,16 @@ copy_files libisofs/*.[ch] "$lone_dir"/libisofs # To get a common version.h cat version.h.in >> "$lone_dir"/version.h.in -sed -e 's/FNM_FILE_NAME/FNM_PATHNAME/g' \ -"$lone_dir"/libisofs/tree.c +# <<< obsoleted patchings -# <<< obsoleted if test 1 = 0 then +# Change GNU macro name to POSIX name +sed -e 's/FNM_FILE_NAME/FNM_PATHNAME/g' \ + "$lone_dir"/libisofs/tree.c + # Filter out the semi-illegal TODO comments ( cd "$lone_dir"/libisofs && grep '^[[:space:]]*//' *.[ch] | less ) echo "Is it ok delete all shown //-lines ?" diff --git a/libisoburn/trunk/xorriso/xorriso_timestamp.h b/libisoburn/trunk/xorriso/xorriso_timestamp.h index e7ea7b70..2fbc2c7a 100644 --- a/libisoburn/trunk/xorriso/xorriso_timestamp.h +++ b/libisoburn/trunk/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2008.01.31.152131" +#define Xorriso_timestamP "2008.01.31.214647" diff --git a/libisoburn/trunk/xorriso/xorrisoburn.h b/libisoburn/trunk/xorriso/xorrisoburn.h index ffe2ec05..fe32cb98 100644 --- a/libisoburn/trunk/xorriso/xorrisoburn.h +++ b/libisoburn/trunk/xorriso/xorrisoburn.h @@ -17,6 +17,12 @@ struct XorrisO; struct FindjoB; +/* The minimum version of libisoburn to be used with this version of xorriso +*/ +#define xorriso_libisoburn_req_major 0 +#define xorriso_libisoburn_req_minor 0 +#define xorriso_libisoburn_req_micro 1 + int Xorriso_startup_libraries(struct XorrisO *xorriso, int flag); /* @param flag bit0= global shutdown of libraries */