#include "systime.h"
#ifdef WINDOWSNT
#include <share.h>
+#include <sys/socket.h> /* for fcntl */
#include "w32.h" /* for dostounix_filename */
#endif
since utmp is typically much smaller than wtmp.
Passing a null pointer causes get_boot_time_1
to inspect the default file, namely utmp. */
- get_boot_time_1 ((char *) 0, 0);
+ get_boot_time_1 (0, 0);
if (boot_time)
return boot_time;
get_boot_time_1 (const char *filename, bool newest)
{
struct utmp ut, *utp;
- int desc;
if (filename)
{
/* On some versions of IRIX, opening a nonexistent file name
is likely to crash in the utmp routines. */
- desc = emacs_open (filename, O_RDONLY, 0);
- if (desc < 0)
+ if (faccessat (AT_FDCWD, filename, R_OK, AT_EACCESS) != 0)
return;
- emacs_close (desc);
-
utmpname (filename);
}
#endif
}
-/* Create the lock file FILE with contents CONTENTS. Return 0 if
+/* Create the lock file LFNAME with contents LOCK_INFO_STR. Return 0 if
successful, an errno value on failure. If FORCE, remove any
- existing FILE if necessary. */
+ existing LFNAME if necessary. */
static int
create_lock_file (char *lfname, char *lock_info_str, bool force)
USE_SAFE_ALLOCA;
char *nonce = SAFE_ALLOCA (lfdirlen + sizeof nonce_base);
int fd;
- bool need_fchmod;
- mode_t world_readable = S_IRUSR | S_IRGRP | S_IROTH;
memcpy (nonce, lfname, lfdirlen);
strcpy (nonce + lfdirlen, nonce_base);
-#if HAVE_MKSTEMP
- /* Prefer mkstemp if available, as it avoids a race between
- mktemp and emacs_open. */
- fd = mkstemp (nonce);
- need_fchmod = 1;
-#else
- mktemp (nonce);
- fd = emacs_open (nonce, O_WRONLY | O_CREAT | O_EXCL | O_BINARY,
- world_readable);
- need_fchmod = 0;
-#endif
-
+ fd = mkostemp (nonce, O_BINARY | O_CLOEXEC);
if (fd < 0)
err = errno;
else
{
- ptrdiff_t lock_info_len = strlen (lock_info_str);
+ ptrdiff_t lock_info_len;
+ if (! O_CLOEXEC)
+ fcntl (fd, F_SETFD, FD_CLOEXEC);
+ lock_info_len = strlen (lock_info_str);
err = 0;
- if (emacs_write (fd, lock_info_str, lock_info_len) != lock_info_len
- || (need_fchmod && fchmod (fd, world_readable) != 0))
+ /* Use 'write', not 'emacs_write', as garbage collection
+ might signal an error, which would leak FD. */
+ if (write (fd, lock_info_str, lock_info_len) != lock_info_len
+ || fchmod (fd, S_IRUSR | S_IRGRP | S_IROTH) != 0)
err = errno;
+ /* There is no need to call fsync here, as the contents of
+ the lock file need not survive system crashes. */
if (emacs_close (fd) != 0)
err = errno;
if (!err && rename_lock_file (nonce, lfname, force) != 0)
int fd = emacs_open (lfname, O_RDONLY | O_BINARY | O_NOFOLLOW, 0);
if (0 <= fd)
{
- ptrdiff_t read_bytes = emacs_read (fd, lfinfo, MAX_LFINFO + 1);
+ /* Use read, not emacs_read, since FD isn't unwind-protected. */
+ ptrdiff_t read_bytes = read (fd, lfinfo, MAX_LFINFO + 1);
int read_errno = errno;
if (emacs_close (fd) != 0)
return -1;
void
unlock_all_files (void)
{
- register Lisp_Object tail;
+ register Lisp_Object tail, buf;
register struct buffer *b;
- for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
+ FOR_EACH_LIVE_BUFFER (tail, buf)
{
- b = XBUFFER (XCDR (XCAR (tail)));
- if (STRINGP (BVAR (b, file_truename)) && BUF_SAVE_MODIFF (b) < BUF_MODIFF (b))
- {
- unlock_file (BVAR (b, file_truename));
- }
+ b = XBUFFER (buf);
+ if (STRINGP (BVAR (b, file_truename))
+ && BUF_SAVE_MODIFF (b) < BUF_MODIFF (b))
+ unlock_file (BVAR (b, file_truename));
}
}
\f