unix: cache address of dlsym("mkostemp")
Look up the "mkostemp" symbol once instead of on every call to uv_fs_mkstemp(). PR-URL: https://github.com/libuv/libuv/pull/2564 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com> Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
This commit is contained in:
parent
0d3b487f5d
commit
a0530ce77e
@ -259,10 +259,29 @@ static ssize_t uv__fs_mkdtemp(uv_fs_t* req) {
|
||||
}
|
||||
|
||||
|
||||
static int (*uv__mkostemp)(char*, int);
|
||||
|
||||
|
||||
static void uv__mkostemp_initonce(void) {
|
||||
/* z/os doesn't have RTLD_DEFAULT but that's okay
|
||||
* because it doesn't have mkostemp(O_CLOEXEC) either.
|
||||
*/
|
||||
#ifdef RTLD_DEFAULT
|
||||
uv__mkostemp = (int (*)(char*, int)) dlsym(RTLD_DEFAULT, "mkostemp");
|
||||
|
||||
/* We don't care about errors, but we do want to clean them up.
|
||||
* If there has been no error, then dlerror() will just return
|
||||
* NULL.
|
||||
*/
|
||||
dlerror();
|
||||
#endif /* RTLD_DEFAULT */
|
||||
}
|
||||
|
||||
|
||||
static int uv__fs_mkstemp(uv_fs_t* req) {
|
||||
static uv_once_t once = UV_ONCE_INIT;
|
||||
int r;
|
||||
#ifdef O_CLOEXEC
|
||||
int (*mkostemp_function)(char*, int);
|
||||
static int no_cloexec_support;
|
||||
#endif
|
||||
static const char pattern[] = "XXXXXX";
|
||||
@ -284,30 +303,23 @@ static int uv__fs_mkstemp(uv_fs_t* req) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uv_once(&once, uv__mkostemp_initonce);
|
||||
|
||||
#ifdef O_CLOEXEC
|
||||
if (no_cloexec_support == 0) {
|
||||
mkostemp_function = (int (*)(char*, int)) dlsym(RTLD_DEFAULT, "mkostemp");
|
||||
if (no_cloexec_support == 0 && uv__mkostemp != NULL) {
|
||||
r = uv__mkostemp(path, O_CLOEXEC);
|
||||
|
||||
/* We don't care about errors, but we do want to clean them up.
|
||||
If there has been no error, then dlerror() will just return
|
||||
NULL. */
|
||||
dlerror();
|
||||
if (r >= 0)
|
||||
return r;
|
||||
|
||||
if (mkostemp_function != NULL) {
|
||||
r = mkostemp_function(path, O_CLOEXEC);
|
||||
/* If mkostemp() returns EINVAL, it means the kernel doesn't
|
||||
support O_CLOEXEC, so we just fallback to mkstemp() below. */
|
||||
if (errno != EINVAL)
|
||||
return r;
|
||||
|
||||
if (r >= 0)
|
||||
return r;
|
||||
|
||||
/* If mkostemp() returns EINVAL, it means the kernel doesn't
|
||||
support O_CLOEXEC, so we just fallback to mkstemp() below. */
|
||||
if (errno != EINVAL)
|
||||
return r;
|
||||
|
||||
/* We set the static variable so that next calls don't even
|
||||
try to use mkostemp. */
|
||||
no_cloexec_support = 1;
|
||||
}
|
||||
/* We set the static variable so that next calls don't even
|
||||
try to use mkostemp. */
|
||||
no_cloexec_support = 1;
|
||||
}
|
||||
#endif /* O_CLOEXEC */
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user