[PATCH] Set FILE_ATTRIBUTE_TEMPORARY on files opened by mkstemp() on WinNT

Vaclav Haisman V.Haisman@sh.cvut.cz
Fri Jul 22 01:18:00 GMT 2005


On Thu, 21 Jul 2005, Christopher Faylor wrote:

> On Fri, Jul 22, 2005 at 01:32:50AM +0200, Vaclav Haisman wrote:
> >the attached patch sets FILE_ATTRIBUTE_TEMPORARY on files opened by
> >mkstemp() on WinNT class systems.  Theoretically the OS should then be
> >less eager to write such files onto the physical storage and use cache
> >instead.
>
> Thank you for the patch but unless you can demonstrate some obvious
> performance improvements I don't think we'll be applying it.  You've
> slowed down (slightly) the common case of calling open for the uncommon
> case of calling mk?temp.

I am not sure what kind of slow down do you mean. Is it the one extra call? In
that case the attached modified patch should fix it. The call to
open_with_attributes() in open() gets inlined, I have checked the resulting .s
file.

>
> Also, if this was to be accepted, the preference for this type of thing
> is to add a capability like wincap.has_file_attribute_temporary () rather
> than just relying on is_winnt ().

Done.

>
> cgf
>


VH


2005-07-22  Vaclav Haisman  <v.haisman@sh.cvut.cz>

	* wincap.h (wincap::has_file_attribute_temporary): New field.
	(wincapc::has_file_attribute_temporary): New accessor.
	* wincap.cc (wincap_unknown): Initialize
	has_file_attribute_temporary field.
	(wincap_95): Ditto.
	(wincap_95osr2): Ditto.
	(wincap_98): Ditto.
	(wincap_98se): Ditto.
	(wincap_me): Ditto.
	(wincap_nt3): Ditto.
	(wincap_nt4): Ditto.
	(wincap_nt4sp4): Ditto.
	(wincap_2000): Ditto.
	(wincap_xp): Ditto.
	(wincap_2003): Ditto.
	* syscalls.cc (open_with_attributes): Rename open() to
	open_with_attributes(). Add fileattr parameter and use it. Add
	explicit mode_t parameter for mode. Tweak debugging
	syscall_printf() calls to reflect the new parameter.
	(open): Reimplement using open_with_attributes().
	* fhandler.cc (fhandler_base::open): Use pc.file_attributes() when
	opening disk file.
	* mktemp.cc (_gettemp): Set FILE_ATTRIBUTE_TEMPORARY on WinNT
	using open_with_attributes().
-------------- next part --------------
Index: fhandler.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/fhandler.cc,v
retrieving revision 1.239
diff -u -p -d -r1.239 fhandler.cc
--- fhandler.cc	6 Jul 2005 20:05:00 -0000	1.239
+++ fhandler.cc	22 Jul 2005 01:07:45 -0000
@@ -639,7 +639,10 @@ fhandler_base::open (int flags, mode_t m
 
   if (flags & O_CREAT && get_device () == FH_FS)
     {
-      file_attributes = FILE_ATTRIBUTE_NORMAL;
+      if (pc.file_attributes () == INVALID_FILE_ATTRIBUTES)
+        file_attributes = FILE_ATTRIBUTE_NORMAL;
+      else
+        file_attributes = pc.file_attributes ();
       /* If mode has no write bits set, we set the R/O attribute. */
       if (!(mode & (S_IWUSR | S_IWGRP | S_IWOTH)))
 	file_attributes |= FILE_ATTRIBUTE_READONLY;
Index: mktemp.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/mktemp.cc,v
retrieving revision 1.2
diff -u -p -d -r1.2 mktemp.cc
--- mktemp.cc	25 May 2005 03:43:58 -0000	1.2
+++ mktemp.cc	22 Jul 2005 01:07:46 -0000
@@ -101,11 +101,15 @@ _gettemp(char *path, int *doopen, int do
 	}
     }
 
+  DWORD const fileattr = wincap.has_file_attribute_temporary () ? 
+    FILE_ATTRIBUTE_TEMPORARY : FILE_ATTRIBUTE_NORMAL;
   for (;;)
     {
       if (doopen)
 	{
-	  if ((*doopen = open (path, O_CREAT | O_EXCL | O_RDWR, 0600)) >= 0)
+          extern int open_with_attributes (const char *, int, mode_t, DWORD);
+	  if ((*doopen = open_with_attributes (path, O_CREAT | O_EXCL | O_RDWR,
+                                               0600, fileattr)) >= 0)
 	    return 1;
 	  if (errno != EEXIST)
 	    return 0;
Index: syscalls.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/syscalls.cc,v
retrieving revision 1.386
diff -u -p -d -r1.386 syscalls.cc
--- syscalls.cc	6 Jul 2005 20:05:03 -0000	1.386
+++ syscalls.cc	22 Jul 2005 01:07:47 -0000
@@ -539,18 +539,17 @@ done:
   return res;
 }
 
-/* _open */
-/* newlib's fcntl.h defines _open as taking variable args so we must
-   correspond.  The third arg if it exists is: mode_t mode. */
-extern "C" int
-open (const char *unix_path, int flags, ...)
+
+int open_with_attributes (const char *unix_path, int flags, mode_t mode, 
+                          DWORD fileattr) __attribute__ ((used));
+extern inline int
+open_with_attributes (const char *unix_path, int flags, mode_t mode, 
+                      DWORD fileattr)
 {
   int res = -1;
-  va_list ap;
-  mode_t mode = 0;
   sig_dispatch_pending ();
 
-  syscall_printf ("open (%s, %p)", unix_path, flags);
+  syscall_printf ("open (%s, %p, %p, %p)", unix_path, flags, mode, fileattr);
   myfault efault;
   if (efault.faulted (EFAULT))
     /* errno already set */;
@@ -558,30 +557,36 @@ open (const char *unix_path, int flags, 
     set_errno (ENOENT);
   else
     {
-      /* check for optional mode argument */
-      va_start (ap, flags);
-      mode = va_arg (ap, mode_t);
-      va_end (ap);
-
       fhandler_base *fh;
       cygheap_fdnew fd;
 
       if (fd >= 0)
 	{
 	  if (!(fh = build_fh_name (unix_path, NULL, PC_SYM_FOLLOW)))
-	    res = -1;		// errno already set
-	  else if (((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) && fh->exists ())
+            {
+              res = -1;		// errno already set
+              goto out;
+            }
+	  else if (((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) 
+              && fh->exists ())
 	    {
 	      delete fh;
 	      res = -1;
 	      set_errno (EEXIST);
+              goto out;
 	    }
 	  else if (fh->is_fs_special () && fh->device_access_denied (flags))
 	    {
 	      delete fh;
 	      res = -1;
+              goto out;
 	    }
-	  else if (!fh->open (flags, (mode & 07777) & ~cygheap->umask))
+          
+          if (static_cast<DWORD &>(*fh) == INVALID_FILE_ATTRIBUTES)
+            static_cast<DWORD &>(*fh) = fileattr;
+          else
+            static_cast<DWORD &>(*fh) = static_cast<DWORD &>(*fh) | fileattr;
+	  if (!fh->open (flags, (mode & 07777) & ~cygheap->umask))
 	    {
 	      delete fh;
 	      res = -1;
@@ -595,10 +600,31 @@ open (const char *unix_path, int flags, 
 	}
     }
 
-  syscall_printf ("%d = open (%s, %p)", res, unix_path, flags);
+ out:
+  syscall_printf ("%d = open (%s, %p, %p, %p)", res, unix_path, flags, mode,
+                  fileattr);
   return res;
 }
 
+
+/* _open */
+/* newlib's fcntl.h defines _open as taking variable args so we must
+   correspond.  The third arg if it exists is: mode_t mode. */
+extern "C" int
+open (const char *unix_path, int flags, ...)
+{
+  va_list ap;
+  int ret;
+  mode_t mode;
+
+  va_start (ap, flags);
+  mode = flags & O_CREAT ? va_arg (ap, mode_t) : 0;
+  ret = open_with_attributes (unix_path, flags, mode, FILE_ATTRIBUTE_NORMAL);
+  va_end (ap);
+
+  return ret;
+}
+
 EXPORT_ALIAS (open, _open )
 EXPORT_ALIAS (open, _open64 )
 
Index: wincap.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/wincap.cc,v
retrieving revision 1.40
diff -u -p -d -r1.40 wincap.cc
--- wincap.cc	30 Jun 2005 02:52:14 -0000	1.40
+++ wincap.cc	22 Jul 2005 01:07:48 -0000
@@ -59,7 +59,8 @@ static NO_COPY wincaps wincap_unknown = 
   has_extended_priority_class:false,
   has_guid_volumes:false,
   detect_win16_exe:true,
-  has_null_console_handler_routine:false
+  has_null_console_handler_routine:false,
+  has_file_attribute_temporary:false
 };
 
 static NO_COPY wincaps wincap_95 = {
@@ -110,7 +111,8 @@ static NO_COPY wincaps wincap_95 = {
   has_extended_priority_class:false,
   has_guid_volumes:false,
   detect_win16_exe:true,
-  has_null_console_handler_routine:false
+  has_null_console_handler_routine:false,
+  has_file_attribute_temporary:false
 };
 
 static NO_COPY wincaps wincap_95osr2 = {
@@ -161,7 +163,8 @@ static NO_COPY wincaps wincap_95osr2 = {
   has_extended_priority_class:false,
   has_guid_volumes:false,
   detect_win16_exe:true,
-  has_null_console_handler_routine:false
+  has_null_console_handler_routine:false,
+  has_file_attribute_temporary:false
 };
 
 static NO_COPY wincaps wincap_98 = {
@@ -212,7 +215,8 @@ static NO_COPY wincaps wincap_98 = {
   has_extended_priority_class:false,
   has_guid_volumes:false,
   detect_win16_exe:true,
-  has_null_console_handler_routine:false
+  has_null_console_handler_routine:false,
+  has_file_attribute_temporary:false
 };
 
 static NO_COPY wincaps wincap_98se = {
@@ -263,7 +267,8 @@ static NO_COPY wincaps wincap_98se = {
   has_extended_priority_class:false,
   has_guid_volumes:false,
   detect_win16_exe:true,
-  has_null_console_handler_routine:false
+  has_null_console_handler_routine:false,
+  has_file_attribute_temporary:false
 };
 
 static NO_COPY wincaps wincap_me = {
@@ -314,7 +319,8 @@ static NO_COPY wincaps wincap_me = {
   has_extended_priority_class:false,
   has_guid_volumes:false,
   detect_win16_exe:true,
-  has_null_console_handler_routine:false
+  has_null_console_handler_routine:false,
+  has_file_attribute_temporary:false
 };
 
 static NO_COPY wincaps wincap_nt3 = {
@@ -365,7 +371,8 @@ static NO_COPY wincaps wincap_nt3 = {
   has_extended_priority_class:false,
   has_guid_volumes:false,
   detect_win16_exe:false,
-  has_null_console_handler_routine:true
+  has_null_console_handler_routine:true,
+  has_file_attribute_temporary:true
 };
 
 static NO_COPY wincaps wincap_nt4 = {
@@ -416,7 +423,8 @@ static NO_COPY wincaps wincap_nt4 = {
   has_extended_priority_class:false,
   has_guid_volumes:false,
   detect_win16_exe:false,
-  has_null_console_handler_routine:true
+  has_null_console_handler_routine:true,
+  has_file_attribute_temporary:true
 };
 
 static NO_COPY wincaps wincap_nt4sp4 = {
@@ -467,7 +475,8 @@ static NO_COPY wincaps wincap_nt4sp4 = {
   has_extended_priority_class:false,
   has_guid_volumes:false,
   detect_win16_exe:false,
-  has_null_console_handler_routine:true
+  has_null_console_handler_routine:true,
+  has_file_attribute_temporary:true
 };
 
 static NO_COPY wincaps wincap_2000 = {
@@ -518,7 +527,8 @@ static NO_COPY wincaps wincap_2000 = {
   has_extended_priority_class:true,
   has_guid_volumes:true,
   detect_win16_exe:false,
-  has_null_console_handler_routine:true
+  has_null_console_handler_routine:true,
+  has_file_attribute_temporary:true
 };
 
 static NO_COPY wincaps wincap_xp = {
@@ -569,7 +579,8 @@ static NO_COPY wincaps wincap_xp = {
   has_extended_priority_class:true,
   has_guid_volumes:true,
   detect_win16_exe:false,
-  has_null_console_handler_routine:true
+  has_null_console_handler_routine:true,
+  has_file_attribute_temporary:true
 };
 
 static NO_COPY wincaps wincap_2003 = {
@@ -620,7 +631,8 @@ static NO_COPY wincaps wincap_2003 = {
   has_extended_priority_class:true,
   has_guid_volumes:true,
   detect_win16_exe:false,
-  has_null_console_handler_routine:true
+  has_null_console_handler_routine:true,
+  has_file_attribute_temporary:true
 };
 
 wincapc wincap;
Index: wincap.h
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/wincap.h,v
retrieving revision 1.32
diff -u -p -d -r1.32 wincap.h
--- wincap.h	30 Jun 2005 02:52:14 -0000	1.32
+++ wincap.h	22 Jul 2005 01:07:48 -0000
@@ -61,6 +61,7 @@ struct wincaps
   unsigned has_guid_volumes				: 1;
   unsigned detect_win16_exe				: 1;
   unsigned has_null_console_handler_routine		: 1;
+  unsigned has_file_attribute_temporary			: 1;
 };
 
 class wincapc
@@ -126,6 +127,7 @@ public:
   bool	IMPLEMENT (has_guid_volumes)
   bool	IMPLEMENT (detect_win16_exe)
   bool	IMPLEMENT (has_null_console_handler_routine)
+  bool	IMPLEMENT (has_file_attribute_temporary)
 
 #undef IMPLEMENT
 };
-------------- next part --------------
2005-07-22  Vaclav Haisman  <v.haisman@sh.cvut.cz>



	* wincap.h (wincap::has_file_attribute_temporary): New field.

	(wincapc::has_file_attribute_temporary): New accessor.

	* wincap.cc (wincap_unknown): Initialize

	has_file_attribute_temporary field.

	(wincap_95): Ditto.

	(wincap_95osr2): Ditto.

	(wincap_98): Ditto.

	(wincap_98se): Ditto.

	(wincap_me): Ditto.

	(wincap_nt3): Ditto.

	(wincap_nt4): Ditto.

	(wincap_nt4sp4): Ditto.

	(wincap_2000): Ditto.

	(wincap_xp): Ditto.

	(wincap_2003): Ditto.

	* syscalls.cc (open_with_attributes): Rename open() to

	open_with_attributes(). Add fileattr parameter and use it. Add

	explicit mode_t parameter for mode. Tweak debugging

	syscall_printf() calls to reflect the new parameter.

	(open): Reimplement using open_with_attributes().

	* fhandler.cc (fhandler_base::open): Use pc.file_attributes() when

	opening disk file.

	* mktemp.cc (_gettemp): Set FILE_ATTRIBUTE_TEMPORARY on WinNT

	using open_with_attributes().



More information about the Cygwin-patches mailing list