* miscfuncs.h (class NT_readline): New class to implement line-wise
reading from file using native NT functions. * miscfuncs.cc (NT_readline::init): New method. * mount.cc (mount_info::from_fstab): Utilize NT_readline to read fstab files.
This commit is contained in:
		
							parent
							
								
									abbe1f5320
								
							
						
					
					
						commit
						234074f683
					
				|  | @ -1,3 +1,11 @@ | |||
| 2014-02-08  Corinna Vinschen  <corinna@vinschen.de> | ||||
| 
 | ||||
| 	* miscfuncs.h (class NT_readline): New class to implement line-wise | ||||
| 	reading from file using native NT functions. | ||||
| 	* miscfuncs.cc (NT_readline::init): New method. | ||||
| 	* mount.cc (mount_info::from_fstab): Utilize NT_readline to read | ||||
| 	fstab files. | ||||
| 
 | ||||
| 2014-02-06  Corinna Vinschen  <corinna@vinschen.de> | ||||
| 
 | ||||
| 	* fhandler_disk_file.cc (fhandler_disk_file::fchown): Fix typo in | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| /* miscfuncs.cc: misc funcs that don't belong anywhere else
 | ||||
| 
 | ||||
|    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, | ||||
|    2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc. | ||||
|    2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc. | ||||
| 
 | ||||
| This file is part of Cygwin. | ||||
| 
 | ||||
|  | @ -384,6 +384,82 @@ WritePipeOverlapped (HANDLE h, LPCVOID buf, DWORD len, LPDWORD ret_len, | |||
|   return ret; | ||||
| } | ||||
| 
 | ||||
| bool | ||||
| NT_readline::init (POBJECT_ATTRIBUTES attr, PCHAR in_buf, ULONG in_buflen) | ||||
| { | ||||
|   NTSTATUS status; | ||||
|   IO_STATUS_BLOCK io; | ||||
| 
 | ||||
|   status = NtOpenFile (&fh, SYNCHRONIZE | FILE_READ_DATA, attr, &io, | ||||
|                        FILE_SHARE_VALID_FLAGS, | ||||
|                        FILE_SYNCHRONOUS_IO_NONALERT | ||||
|                        | FILE_OPEN_FOR_BACKUP_INTENT); | ||||
|   if (!NT_SUCCESS (status)) | ||||
|     { | ||||
|       paranoid_printf ("NtOpenFile(%S) failed, status %y", | ||||
| 		       &attr->ObjectName, status); | ||||
|       return false; | ||||
|     } | ||||
|   buf = in_buf; | ||||
|   buflen = in_buflen; | ||||
|   got = end = buf; | ||||
|   len = 0; | ||||
|   line = 1; | ||||
|   return true; | ||||
| } | ||||
| 
 | ||||
| PCHAR  | ||||
| NT_readline::gets () | ||||
| { | ||||
|   IO_STATUS_BLOCK io; | ||||
| 
 | ||||
|   while (true) | ||||
|     { | ||||
|       /* len == 0 indicates we have to read from the file. */ | ||||
|       if (!len) | ||||
| 	{ | ||||
| 	  if (!NT_SUCCESS (NtReadFile (fh, NULL, NULL, NULL, &io, got, | ||||
| 				       (buflen - 2) - (got - buf), NULL, NULL))) | ||||
| 	    return NULL; | ||||
| 	  len = io.Information; | ||||
| 	  /* Set end marker. */ | ||||
| 	  got[len] = got[len + 1] = '\0'; | ||||
| 	  /* Set len to the absolute len of bytes in buf. */ | ||||
| 	  len += got - buf; | ||||
| 	  /* Reset got to start reading at the start of the buffer again. */ | ||||
| 	  got = end = buf; | ||||
| 	} | ||||
|       else | ||||
| 	{ | ||||
| 	  got = end + 1; | ||||
| 	  ++line; | ||||
| 	} | ||||
|       /* Still some valid full line? */ | ||||
|       if (got < buf + len) | ||||
| 	{ | ||||
| 	  if ((end = strchr (got, '\n'))) | ||||
| 	    { | ||||
| 	      end[end[-1] == '\r' ? -1 : 0] = '\0'; | ||||
| 	      return got; | ||||
| 	    } | ||||
| 	  /* Last line missing a \n at EOF? */ | ||||
| 	  if (len < buflen - 2) | ||||
| 	    { | ||||
| 	      len = 0; | ||||
| 	      return got; | ||||
| 	    } | ||||
| 	} | ||||
|       /* We have to read once more.  Move remaining bytes to the start of
 | ||||
|          the buffer and reposition got so that it points to the end of | ||||
|          the remaining bytes. */ | ||||
|       len = buf + len - got; | ||||
|       memmove (buf, got, len); | ||||
|       got = buf + len; | ||||
|       buf[len] = buf[len + 1] = '\0'; | ||||
|       len = 0; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /* backslashify: Convert all forward slashes in src path to back slashes
 | ||||
|    in dst path.  Add a trailing slash to dst when trailing_slash_p arg | ||||
|    is set to 1. */ | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| /* miscfuncs.h: main Cygwin header file.
 | ||||
| 
 | ||||
|    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, | ||||
|    2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc. | ||||
|    2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc. | ||||
| 
 | ||||
| This file is part of Cygwin. | ||||
| 
 | ||||
|  | @ -23,6 +23,24 @@ BOOL WINAPI ReadPipeOverlapped (HANDLE h, PVOID buf, DWORD len, | |||
| BOOL WINAPI WritePipeOverlapped (HANDLE h, LPCVOID buf, DWORD len, | ||||
| 				 LPDWORD ret_len, DWORD timeout); | ||||
| 
 | ||||
| /* class for per-line reading using native functions.  The caller provides
 | ||||
|    the file as an POBJECT_ATTRIBUTES, and the buffer space. */ | ||||
| class NT_readline | ||||
| { | ||||
|   HANDLE fh; | ||||
|   PCHAR buf; | ||||
|   PCHAR got; | ||||
|   PCHAR end; | ||||
|   ULONG buflen; | ||||
|   ULONG len; | ||||
|   ULONG line; | ||||
| public: | ||||
|   NT_readline () : fh (NULL) {} | ||||
|   bool init (POBJECT_ATTRIBUTES attr, char *buf, ULONG buflen); | ||||
|   PCHAR gets (); | ||||
|   ~NT_readline () { if (fh) NtClose (fh); } | ||||
| }; | ||||
| 
 | ||||
| extern "C" void yield (); | ||||
| 
 | ||||
| #define import_address(x) __import_address ((void *)(x)) | ||||
|  |  | |||
|  | @ -1177,10 +1177,9 @@ mount_info::from_fstab (bool user, WCHAR fstab[], PWCHAR fstab_end) | |||
| { | ||||
|   UNICODE_STRING upath; | ||||
|   OBJECT_ATTRIBUTES attr; | ||||
|   IO_STATUS_BLOCK io; | ||||
|   NTSTATUS status; | ||||
|   HANDLE fh; | ||||
|   NT_readline rl; | ||||
|   tmp_pathbuf tp; | ||||
|   char *buf = tp.c_get (); | ||||
| 
 | ||||
|   if (user) | ||||
|     { | ||||
|  | @ -1195,81 +1194,10 @@ mount_info::from_fstab (bool user, WCHAR fstab[], PWCHAR fstab_end) | |||
|   RtlInitUnicodeString (&upath, fstab); | ||||
|   InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE, NULL, NULL); | ||||
|   debug_printf ("Try to read mounts from %W", fstab); | ||||
|   status = NtOpenFile (&fh, SYNCHRONIZE | FILE_READ_DATA, &attr, &io, | ||||
| 		       FILE_SHARE_VALID_FLAGS, | ||||
| 		       FILE_SYNCHRONOUS_IO_NONALERT | ||||
| 		       | FILE_OPEN_FOR_BACKUP_INTENT); | ||||
|   if (!NT_SUCCESS (status)) | ||||
|     { | ||||
|       debug_printf ("NtOpenFile(%S) failed, %y", &upath, status); | ||||
|       return false; | ||||
|     } | ||||
| 
 | ||||
|   char *buf = tp.c_get (); | ||||
|   char *got = buf; | ||||
|   DWORD len = 0; | ||||
|   unsigned line = 1; | ||||
|   /* Using buffer size - 2 leaves space to append two \0. */ | ||||
|   while (NT_SUCCESS (NtReadFile (fh, NULL, NULL, NULL, &io, got, | ||||
| 				 (NT_MAX_PATH - 2) - (got - buf), NULL, NULL))) | ||||
|     { | ||||
|       char *end; | ||||
| 
 | ||||
|       len = io.Information; | ||||
|       /* Set end marker. */ | ||||
|       got[len] = got[len + 1] = '\0'; | ||||
|       /* Set len to the absolute len of bytes in buf. */ | ||||
|       len += got - buf; | ||||
|       /* Reset got to start reading at the start of the buffer again. */ | ||||
|       got = buf; | ||||
| retry: | ||||
|       bool got_nl = false; | ||||
|       while (got < buf + len && (end = strchr (got, '\n'))) | ||||
| 	{ | ||||
| 	  got_nl = true; | ||||
| 	  end[end[-1] == '\r' ? -1 : 0] = '\0'; | ||||
| 	  if (!from_fstab_line (got, user)) | ||||
| 	    goto done; | ||||
| 	  got = end + 1; | ||||
| 	  ++line; | ||||
| 	} | ||||
|       if (len < (NT_MAX_PATH - 2)) | ||||
|   if (rl.init (&attr, buf, NT_MAX_PATH)) | ||||
|     while ((buf = rl.gets ())) | ||||
|       if (!from_fstab_line (buf, user)) | ||||
| 	break; | ||||
|       /* Check if the buffer contained at least one \n.  If not, the
 | ||||
| 	 line length is > 32K.  We don't take such long lines.  Print | ||||
| 	 a debug message and skip this line entirely. */ | ||||
|       if (!got_nl) | ||||
| 	{ | ||||
| 	  system_printf ("%W: Line %d too long, skipping...", fstab, line); | ||||
| 	  while (NT_SUCCESS (NtReadFile (fh, NULL, NULL, NULL, &io, buf, | ||||
| 					 (NT_MAX_PATH - 2), NULL, NULL))) | ||||
| 	    { | ||||
| 	      len = io.Information; | ||||
| 	      buf[len] = buf[len + 1] = '\0'; | ||||
| 	      got = strchr (buf, '\n'); | ||||
| 	      if (got) | ||||
| 		{ | ||||
| 		  ++got; | ||||
| 		  ++line; | ||||
| 		  goto retry; | ||||
| 		} | ||||
| 	    } | ||||
| 	  got = buf; | ||||
| 	  break; | ||||
| 	} | ||||
|       /* We have to read once more.  Move remaining bytes to the start of
 | ||||
| 	 the buffer and reposition got so that it points to the end of | ||||
| 	 the remaining bytes. */ | ||||
|       len = buf + len - got; | ||||
|       memmove (buf, got, len); | ||||
|       got = buf + len; | ||||
|       buf[len] = buf[len + 1] = '\0'; | ||||
|     } | ||||
|   /* Catch a last line without trailing \n. */ | ||||
|   if (got > buf) | ||||
|     from_fstab_line (got, user); | ||||
| done: | ||||
|   NtClose (fh); | ||||
|   return true; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue