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 <[EMAIL PROTECTED]> * 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 <[EMAIL PROTECTED]>, 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 <[EMAIL PROTECTED]>, 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,