/* * Copyright © 2013 Christian Persch * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #ifndef _GNU_SOURCE #define _GNU_SOURCE /* for O_TMPFILE */ #endif #include "vteutils.h" #include #include #include #include /* Temporary define until glibc release catches up */ #ifdef __linux__ #include #include #ifndef O_TMPFILE #ifndef __O_TMPFILE #define __O_TMPFILE 020000000 #endif #define O_TMPFILE (__O_TMPFILE | O_DIRECTORY) #endif #endif /* __linux__ */ int _vte_mkstemp (void) { int fd; gchar *file_name; #ifdef O_TMPFILE fd = open (g_get_tmp_dir (), O_TMPFILE | O_EXCL | O_RDWR | O_NOATIME | O_CLOEXEC, 0600); if (fd != -1) goto done; /* Try again with g_file_open_tmp */ #endif fd = g_file_open_tmp ("vteXXXXXX", &file_name, NULL); if (fd == -1) return -1; unlink (file_name); g_free (file_name); #ifdef O_NOATIME do { } while (fcntl (fd, F_SETFL, O_NOATIME) == -1 && errno == EINTR); #endif #ifdef O_TMPFILE done: #endif #ifdef __linux__ { /* Mark the tmpfile as no-cow on file systems that support it. * * (Note that the definition of the ioctls make you think @flags would * be long instead of int, but it turns out that this is not the case; * see http://lwn.net/Articles/575846/ ). */ int flags; if (ioctl (fd, FS_IOC_GETFLAGS, &flags) == 0) { flags |= FS_SECRM_FL | FS_NOATIME_FL | FS_NOCOMP_FL | FS_NOCOW_FL | FS_NODUMP_FL; ioctl (fd, FS_IOC_SETFLAGS, &flags); } } #endif /* __linux__ */ return fd; }