summaryrefslogtreecommitdiff
path: root/system.h
diff options
context:
space:
mode:
authorKamil Rytarowski <n54@gmx.com>2013-08-17 21:50:41 +0200
committerFlorian Festi <ffesti@redhat.com>2016-02-11 14:05:25 +0100
commit61109446ac67ca8f3d96a5592814561db908d83c (patch)
treeacd6cd2f684c97f854cb71716d4b04aac49cf982 /system.h
parent159351d7f30909a12bddb4f7c55c22ee087169e1 (diff)
downloadrpm-61109446ac67ca8f3d96a5592814561db908d83c.tar.gz
Reimplement setprogname() and getprogname() to be generic and portable
The RPM code contains setprogname()/getprogname() support implemented through compatiblity layer with very old GLIBC (internals supported back to '95 and earlier), before stabilization of the GNU C library. This compatiblity layer (__progname, __assert_progname, setprogname()) is supposed to support well archaic GLIBC, but on the other hand it pollutes the library namespace and introduces unpredicable compillation errors on BSD systems. The functions setprogname() and getprogname() are natively supported in NetBSD and work the same way as __progname from the GNU C library (they are even implemented in the same way - but with a slightly changed logic). The support for very old (20 years and older) GNU C Library is obfuscating the code, because it uses defines over defines without a word of explaination why to do so. It's important to note that the setprogname()/getprogname() was inconstiently implemented in the codebase, duplicating the code and/or functionality. Add new generic functions getprogname() and setprogname() and bind it to: - the current and for two decades stable GNU LIB C implementation, - the current NetBSD implementation (introduces to NetBSD in 2002), - fallback reimplementation functions of the setprogname() and getprogname() functionality for other systems. Don't support anymore old GNU Lib C internals and don't support older NetBSD systems, as they aren't supported for many years. Add to the codebase comments explaining the relevant codeparts.
Diffstat (limited to 'system.h')
-rw-r--r--system.h39
1 files changed, 26 insertions, 13 deletions
diff --git a/system.h b/system.h
index 2d25b9274..ed34688e9 100644
--- a/system.h
+++ b/system.h
@@ -92,20 +92,33 @@ extern int fdatasync(int fildes);
#define xstrdup(_str) rstrdup((_str))
#define _free(_ptr) rfree((_ptr))
-/* Retrofit glibc __progname */
-#if defined __GLIBC__ && __GLIBC__ >= 2
-#if __GLIBC_MINOR__ >= 1
-#define __progname __assert_program_name
+/* To extract program's name: use calls (reimplemented or shipped with system):
+ - void setprogname(const char *pn)
+ - const char *getprogname(void)
+
+ setprogname(*pn) must be the first call in main() in order to set the name
+ as soon as possible. */
+#if defined(__NetBSD__)
+/* `man setprogname' v. May 21, 2011 (NetBSD 6.1) says:
+ Portable programs that wish to use getprogname() should call setprogname()
+ in main(). In some systems (like NetBSD) it can be set only once and it is
+ done before an execution of main() -- therefore calling it again has no
+ effect.
+
+ Getprogname and setprogname function calls appeared in NetBSD 1.6
+ (released in 2002). So nothing to (re)implement for this platform. */
+# include <stdlib.h> /* Make sure this header is included */
+# define xsetprogname(pn) setprogname(pn)
+# define xgetprogname(pn) getprogname(pn)
+#elif defined(__GLIBC__) /* GNU LIBC ships with (const *char *) __progname */
+# define xsetprogname(pn) /* No need to implement it in GNU LIBC. */
+ extern const char *__progname;
+# define xgetprogname(pn) __progname
+#else /* Reimplement setprogname and getprogname */
+# include "misc/rpmxprogname.h"
+# define xsetprogname(pn) _rpmxsetprogname(pn)
+# define xgetprogname() _rpmxgetprogname()
#endif
-#define setprogname(pn)
-#else
-#define __progname program_name
-#define setprogname(pn) \
- { if ((__progname = strrchr(pn, '/')) != NULL) __progname++; \
- else __progname = pn; \
- }
-#endif
-extern const char *__progname;
/* Take care of NLS matters. */
#if ENABLE_NLS