mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-08 03:18:05 +02:00
Merge branch 'cloexec' into 'master'
Set CLOEXEC when opening files Closes #213 See merge request cairo/cairo!563
This commit is contained in:
commit
a308881018
3 changed files with 90 additions and 17 deletions
|
|
@ -48,6 +48,9 @@
|
|||
#ifdef HAVE_XLOCALE_H
|
||||
#include <xlocale.h>
|
||||
#endif
|
||||
#if HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
COMPILE_TIME_ASSERT ((int)CAIRO_STATUS_LAST_STATUS < (int)CAIRO_INT_STATUS_UNSUPPORTED);
|
||||
COMPILE_TIME_ASSERT (CAIRO_INT_STATUS_LAST_STATUS <= 127);
|
||||
|
|
@ -956,14 +959,40 @@ _cairo_fopen (const char *filename, const char *mode, FILE **file_out)
|
|||
return status;
|
||||
}
|
||||
|
||||
result = _wfopen(filename_w, mode_w);
|
||||
result = _wfopen (filename_w, mode_w);
|
||||
|
||||
free (filename_w);
|
||||
free (mode_w);
|
||||
|
||||
#else /* Use fopen directly */
|
||||
|
||||
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 7)
|
||||
/* Glibc 2.7 supports the "e" mode flag that opens the file with O_CLOEXEC.
|
||||
* this avoid the race condition in the fcntl fallback below. */
|
||||
|
||||
char new_mode[20];
|
||||
snprintf (new_mode, sizeof (new_mode), "%s%s", mode, "e");
|
||||
result = fopen (filename, new_mode);
|
||||
|
||||
#else /* fopen "e" not available */
|
||||
|
||||
result = fopen (filename, mode);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_FCNTL_H) && defined(FD_CLOEXEC)
|
||||
/* Manually set CLOEXEC */
|
||||
if (result != NULL) {
|
||||
int fd = fileno (result);
|
||||
if (fd != -1) {
|
||||
int flags = fcntl (fd, F_GETFD);
|
||||
if (flags >= 0)
|
||||
flags = fcntl (fd, F_SETFD, flags | FD_CLOEXEC);
|
||||
}
|
||||
}
|
||||
#endif /* defined(HAVE_FCNTL_H) && defined(FD_CLOEXEC) */
|
||||
|
||||
#endif /* fopen "e" not available */
|
||||
|
||||
#endif /* !_WIN32 */
|
||||
|
||||
*file_out = result;
|
||||
|
||||
|
|
@ -971,18 +1000,15 @@ _cairo_fopen (const char *filename, const char *mode, FILE **file_out)
|
|||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <windows.h>
|
||||
#include <io.h>
|
||||
|
||||
#if !_WIN32_WCE
|
||||
/* tmpfile() replacement for Windows.
|
||||
*
|
||||
* On Windows tmpfile() creates the file in the root directory. This
|
||||
* may fail due to insufficient privileges. However, this isn't a
|
||||
* problem on Windows CE so we don't use it there.
|
||||
* may fail due to insufficient privileges.
|
||||
*/
|
||||
FILE *
|
||||
static FILE *
|
||||
_cairo_win32_tmpfile (void)
|
||||
{
|
||||
DWORD path_len;
|
||||
|
|
@ -996,7 +1022,7 @@ _cairo_win32_tmpfile (void)
|
|||
if (path_len <= 0 || path_len >= MAX_PATH)
|
||||
return NULL;
|
||||
|
||||
if (GetTempFileNameW (path_name, L"ps_", 0, file_name) == 0)
|
||||
if (GetTempFileNameW (path_name, L"cairo_", 0, file_name) == 0)
|
||||
return NULL;
|
||||
|
||||
handle = CreateFileW (file_name,
|
||||
|
|
@ -1025,10 +1051,60 @@ _cairo_win32_tmpfile (void)
|
|||
|
||||
return fp;
|
||||
}
|
||||
#endif /* !_WIN32_WCE */
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
/**
|
||||
* _cairo_tmpfile:
|
||||
*
|
||||
* Exactly like the C library function. On platforms that support
|
||||
* O_CLOEXEC, the file will be opened with this flag. On Windows, the
|
||||
* file is opened in the temp directory instead of the root directory.
|
||||
*
|
||||
* Return value: a file handle or NULL on error.
|
||||
**/
|
||||
FILE *
|
||||
_cairo_tmpfile (void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return _cairo_win32_tmpfile ();
|
||||
#else /* !_WIN32 */
|
||||
int fd;
|
||||
FILE *file;
|
||||
int flags;
|
||||
|
||||
#ifdef O_TMPFILE
|
||||
fd = open(P_tmpdir,
|
||||
O_TMPFILE | O_EXCL | O_RDWR | O_NOATIME | O_CLOEXEC,
|
||||
0600);
|
||||
if (fd == -1 && errno == ENOENT) {
|
||||
fd = open("/tmp",
|
||||
O_TMPFILE | O_EXCL | O_RDWR | O_NOATIME | O_CLOEXEC,
|
||||
0600);
|
||||
}
|
||||
if (fd != -1)
|
||||
return fdopen (fd, "wb+");
|
||||
|
||||
/* Fallback */
|
||||
#endif /* O_TMPFILE */
|
||||
|
||||
file = tmpfile();
|
||||
|
||||
#if defined(HAVE_FCNTL_H) && defined(FD_CLOEXEC)
|
||||
/* Manually set CLOEXEC */
|
||||
if (file != NULL) {
|
||||
fd = fileno(file);
|
||||
if (fd != -1) {
|
||||
flags = fcntl(fd, F_GETFD);
|
||||
if (flags >= 0 && !(flags & FD_CLOEXEC))
|
||||
fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
|
||||
}
|
||||
}
|
||||
#endif /* defined(HAVE_FCNTL_H) && defined(FD_CLOEXEC) */
|
||||
|
||||
return file;
|
||||
#endif /* !_WIN32 */
|
||||
}
|
||||
|
||||
typedef struct _cairo_intern_string {
|
||||
cairo_hash_entry_t hash_entry;
|
||||
int len;
|
||||
|
|
|
|||
|
|
@ -1115,7 +1115,7 @@ _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,
|
|||
|
||||
surface->final_stream = stream;
|
||||
|
||||
surface->tmpfile = tmpfile ();
|
||||
surface->tmpfile = _cairo_tmpfile ();
|
||||
if (surface->tmpfile == NULL) {
|
||||
switch (errno) {
|
||||
case ENOMEM:
|
||||
|
|
|
|||
|
|
@ -89,12 +89,6 @@
|
|||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
#if _WIN32 && !_WIN32_WCE /* Permissions on WinCE? No worries! */
|
||||
cairo_private FILE *
|
||||
_cairo_win32_tmpfile (void);
|
||||
#define tmpfile() _cairo_win32_tmpfile()
|
||||
#endif
|
||||
|
||||
#undef MIN
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
|
|
@ -1962,6 +1956,9 @@ _cairo_observers_notify (cairo_list_t *observers, void *arg);
|
|||
cairo_private cairo_status_t
|
||||
_cairo_fopen (const char *filename, const char *mode, FILE **file_out);
|
||||
|
||||
cairo_private FILE *
|
||||
_cairo_tmpfile (void);
|
||||
|
||||
#include "cairo-mutex-private.h"
|
||||
#include "cairo-fixed-private.h"
|
||||
#include "cairo-wideint-private.h"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue