mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-27 21:33:09 +00:00
Enable mkostemp to be weak-linked
mkostemp is not available on some older versions of macOS. In order for our built binaries to run on them, mkostemp must be weak-linked. On other systems, we use the autoconf check. Introduce a function fish_mkstemp_cloexec which uses mkostemp if it was detected and is available at runtime, else falls back to mkstemp. This isolates some logic that is currently duplicated in two places. See #3138 for more on weak linking.
This commit is contained in:
parent
6eb88dc13f
commit
e5bfdb99b6
4 changed files with 23 additions and 20 deletions
|
@ -535,15 +535,7 @@ bool env_universal_t::open_temporary_file(const wcstring &directory, wcstring *o
|
||||||
|
|
||||||
for (size_t attempt = 0; attempt < 10 && !success; attempt++) {
|
for (size_t attempt = 0; attempt < 10 && !success; attempt++) {
|
||||||
char *narrow_str = wcs2str(tmp_name_template.c_str());
|
char *narrow_str = wcs2str(tmp_name_template.c_str());
|
||||||
#if HAVE_MKOSTEMP
|
int result_fd = fish_mkstemp_cloexec(narrow_str);
|
||||||
int result_fd = mkostemp(narrow_str, O_CLOEXEC);
|
|
||||||
#else
|
|
||||||
int result_fd = mkstemp(narrow_str);
|
|
||||||
if (result_fd != -1) {
|
|
||||||
fcntl(result_fd, F_SETFD, FD_CLOEXEC);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
saved_errno = errno;
|
saved_errno = errno;
|
||||||
success = result_fd != -1;
|
success = result_fd != -1;
|
||||||
*out_fd = result_fd;
|
*out_fd = result_fd;
|
||||||
|
|
|
@ -91,6 +91,20 @@ char *tparm_solaris_kludge(char *str, ...) {
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int fish_mkstemp_cloexec(char *name_template) {
|
||||||
|
#if HAVE_MKOSTEMP
|
||||||
|
// null check because mkostemp may be a weak symbol
|
||||||
|
if (&mkostemp != nullptr) {
|
||||||
|
return mkostemp(name_template, O_CLOEXEC);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
int result_fd = mkstemp(name_template);
|
||||||
|
if (result_fd != -1) {
|
||||||
|
fcntl(result_fd, F_SETFD, FD_CLOEXEC);
|
||||||
|
}
|
||||||
|
return result_fd;
|
||||||
|
}
|
||||||
|
|
||||||
/// Fallback implementations of wcsdup and wcscasecmp. On systems where these are not needed (e.g.
|
/// Fallback implementations of wcsdup and wcscasecmp. On systems where these are not needed (e.g.
|
||||||
/// building on Linux) these should end up just being stripped, as they are static functions that
|
/// building on Linux) these should end up just being stripped, as they are static functions that
|
||||||
/// are not referenced in this file.
|
/// are not referenced in this file.
|
||||||
|
|
|
@ -23,6 +23,11 @@
|
||||||
int fish_wcwidth(wchar_t wc);
|
int fish_wcwidth(wchar_t wc);
|
||||||
int fish_wcswidth(const wchar_t *str, size_t n);
|
int fish_wcswidth(const wchar_t *str, size_t n);
|
||||||
|
|
||||||
|
// Replacement for mkostemp(str, O_CLOEXEC)
|
||||||
|
// This uses mkostemp if available,
|
||||||
|
// otherwise it uses mkstemp followed by fcntl
|
||||||
|
int fish_mkstemp_cloexec(char *);
|
||||||
|
|
||||||
#ifndef WCHAR_MAX
|
#ifndef WCHAR_MAX
|
||||||
/// This _should_ be defined by wchar.h, but e.g. OpenBSD doesn't.
|
/// This _should_ be defined by wchar.h, but e.g. OpenBSD doesn't.
|
||||||
#define WCHAR_MAX INT_MAX
|
#define WCHAR_MAX INT_MAX
|
||||||
|
|
|
@ -1230,24 +1230,16 @@ bool history_t::save_internal_via_rewrite() {
|
||||||
|
|
||||||
signal_block();
|
signal_block();
|
||||||
|
|
||||||
// Try to create a temporary file, up to 10 times. We don't use mkstemps because we want to
|
// Try to create a CLO_EXEC temporary file, up to 10 times.
|
||||||
// open it CLO_EXEC. This should almost always succeed on the first try.
|
// This should almost always succeed on the first try.
|
||||||
int out_fd = -1;
|
int out_fd = -1;
|
||||||
wcstring tmp_name;
|
wcstring tmp_name;
|
||||||
for (size_t attempt = 0; attempt < 10 && out_fd == -1; attempt++) {
|
for (size_t attempt = 0; attempt < 10 && out_fd == -1; attempt++) {
|
||||||
char *narrow_str = wcs2str(tmp_name_template.c_str());
|
char *narrow_str = wcs2str(tmp_name_template.c_str());
|
||||||
#if HAVE_MKOSTEMP
|
out_fd = fish_mkstemp_cloexec(narrow_str);
|
||||||
out_fd = mkostemp(narrow_str, O_CLOEXEC);
|
|
||||||
if (out_fd >= 0) {
|
if (out_fd >= 0) {
|
||||||
tmp_name = str2wcstring(narrow_str);
|
tmp_name = str2wcstring(narrow_str);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
if (narrow_str && mktemp(narrow_str)) {
|
|
||||||
// It was successfully templated; try opening it atomically.
|
|
||||||
tmp_name = str2wcstring(narrow_str);
|
|
||||||
out_fd = wopen_cloexec(tmp_name, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, 0600);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
free(narrow_str);
|
free(narrow_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue