On 28/09/16 03:25 PM, Thorsten Glaser wrote:
Jack Bates dixit:
A) Call dlsym() early, before anything calls open(). Not possible
because even if you managed to call dlsym() before anything else,
dlsym() itself might call open() before it was done initializing :-(
B) Avoid dlsym() altogether. What are the options in this case?
1) Use sys_open() instead of dlsym(RTLD_NEXT, "open)
How about a combination of both?
Something like this (pseudo code, mostly):
static void initialise_open(void) __attribute__((__constructor__));
static uint8_t open_initialised = 0;
int
open(const char *path, int flags, mode_t mode)
{
if (!open_initialised)
return (sys_open(path, flags, mode));
/* current code with dlsym’s result */
}
static void
initialise_open(void)
{
/* call dlsym, which is now allowed to call open() */
/* store its result */
open_initialised = 1;
}
Of course, I probably ought to better go to bed, but someone
might make something off this. Also, completely untested, modulo
that I have an application in which these constructors work, in
plain GCC (no C++).
My intuition is that not having one consistent implementation might be
surprising to callers of open(), however your solution is AS-safe and
minimizes the change from the current behavior.
Do you know of or anticipate any cases where implementing open() with
sys_open() instead of dlsym(RTLD_NEXT, "open") would cause a problem?