[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: fix inadequate Windows implementation of tmpfile
From: |
Bruno Haible |
Subject: |
Re: fix inadequate Windows implementation of tmpfile |
Date: |
Fri, 16 Feb 2007 04:03:34 +0100 |
User-agent: |
KMail/1.5.4 |
Ben Pfaff wrote:
> There seems to be some kind of problem with
> FILE_FLAG_DELETE_ON_CLOSE, with which _O_TEMPORARY is presumably
> implemented, under Windows 95:
> http://cygwin.com/ml/cygwin-cvs/2003-q4/msg00025.html
>
> In fact, it appears that FILE_FLAG_DELETE_ON_CLOSE works on NT
> derivatives, not on the older Windows systems, based on the
> has_delete_on_close definitions here (sorry about citing a patch
> when a source file would probably be better, this is based on a
> very quick search):
> http://www.cygwin.com/ml/cygwin-patches/2003-q1/msg00170.html
>
> Where it works, it appears to be implemented such that it always
> works, even if a program is terminated abruptly, based on what
> I've read on the web.
Thanks for these explanations. It appears worth to use this in the
clean-temp module.
2007-02-15 Bruno Haible <address@hidden>
* lib/clean-temp.c [WIN32 && !CYGWIN]: Include <windows.h>.
(supports_delete_on_close): New function.
(open_temp, fopen_temp): Use _O_TEMPORARY when supported.
*** lib/clean-temp.c 14 Jan 2007 11:32:10 -0000 1.11
--- lib/clean-temp.c 16 Feb 2007 02:38:34 -0000
***************
*** 1,5 ****
/* Temporary directories and temporary files with automatic cleanup.
! Copyright (C) 2001, 2003, 2006 Free Software Foundation, Inc.
Written by Bruno Haible <address@hidden>, 2006.
This program is free software; you can redistribute it and/or modify
--- 1,5 ----
/* Temporary directories and temporary files with automatic cleanup.
! Copyright (C) 2001, 2003, 2006-2007 Free Software Foundation, Inc.
Written by Bruno Haible <address@hidden>, 2006.
This program is free software; you can redistribute it and/or modify
***************
*** 30,35 ****
--- 30,40 ----
#include <string.h>
#include <unistd.h>
+ #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+ # define WIN32_LEAN_AND_MEAN /* avoid including junk */
+ # include <windows.h>
+ #endif
+
#include "error.h"
#include "fatal-signal.h"
#include "pathmax.h"
***************
*** 563,568 ****
--- 568,600 ----
}
+ #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+
+ /* On Windows, opening a file with _O_TEMPORARY has the effect of passing
+ the FILE_FLAG_DELETE_ON_CLOSE flag to CreateFile(), which has the effect
+ of deleting the file when it is closed - even when the program crashes.
+ But (according to the Cygwin sources) it works only on Windows NT or newer.
+ So we cache the info whether we are running on Windows NT or newer. */
+
+ static bool
+ supports_delete_on_close ()
+ {
+ static int known; /* 1 = yes, -1 = no, 0 = unknown */
+ if (!known)
+ {
+ OSVERSIONINFO v;
+
+ if (GetVersionEx (&v))
+ known = (v.dwPlatformId == VER_PLATFORM_WIN32_NT ? 1 : -1);
+ else
+ known = -1;
+ }
+ return (known > 0);
+ }
+
+ #endif
+
+
/* Register a file descriptor to be closed. */
static void
register_fd (int fd)
***************
*** 598,604 ****
int saved_errno;
block_fatal_signals ();
! fd = open (file_name, flags, mode); /* actually open or open_safer */
saved_errno = errno;
if (fd >= 0)
register_fd (fd);
--- 630,644 ----
int saved_errno;
block_fatal_signals ();
! /* Note: 'open' here is actually open() or open_safer(). */
! #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
! /* Use _O_TEMPORARY when possible, to increase the chances that the
! temporary file is removed when the process crashes. */
! if (supports_delete_on_close ())
! fd = open (file_name, flags | _O_TEMPORARY, mode);
! else
! #endif
! fd = open (file_name, flags, mode);
saved_errno = errno;
if (fd >= 0)
register_fd (fd);
***************
*** 616,623 ****
int saved_errno;
block_fatal_signals ();
! fp = fopen (file_name, mode); /* actually fopen or fopen_safer */
! saved_errno = errno;
if (fp != NULL)
{
/* It is sufficient to register fileno (fp) instead of the entire fp,
--- 656,683 ----
int saved_errno;
block_fatal_signals ();
! /* Note: 'fopen' here is actually fopen() or fopen_safer(). */
! #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
! /* Use _O_TEMPORARY when possible, to increase the chances that the
! temporary file is removed when the process crashes. */
! if (supports_delete_on_close ())
! {
! size_t mode_len = strlen (mode);
! char *augmented_mode = (char *) xallocsa (mode_len + 2);
! memcpy (augmented_mode, mode, mode_len);
! memcpy (augmented_mode + mode_len, "D", 2);
!
! fp = fopen (file_name, augmented_mode);
! saved_errno = errno;
!
! freesa (augmented_mode);
! }
! else
! #endif
! {
! fp = fopen (file_name, mode);
! saved_errno = errno;
! }
if (fp != NULL)
{
/* It is sufficient to register fileno (fp) instead of the entire fp,
- fix inadequate Windows implementation of tmpfile, Ben Pfaff, 2007/02/15
- Re: fix inadequate Windows implementation of tmpfile, Ben Pfaff, 2007/02/15
- Re: fix inadequate Windows implementation of tmpfile, Bruno Haible, 2007/02/15
- Re: fix inadequate Windows implementation of tmpfile, Ben Pfaff, 2007/02/15
- Re: fix inadequate Windows implementation of tmpfile,
Bruno Haible <=
- Re: fix inadequate Windows implementation of tmpfile, Bruno Haible, 2007/02/15
- Re: fix inadequate Windows implementation of tmpfile, Paul Eggert, 2007/02/16
- Re: fix inadequate Windows implementation of tmpfile, Bruno Haible, 2007/02/17
- Re: fix inadequate Windows implementation of tmpfile, Ben Pfaff, 2007/02/17
- Re: fix inadequate Windows implementation of tmpfile, Bruno Haible, 2007/02/20
- Re: fix inadequate Windows implementation of tmpfile, Ben Pfaff, 2007/02/20