* 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>
|
2014-02-06 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* fhandler_disk_file.cc (fhandler_disk_file::fchown): Fix typo in
|
* 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
|
/* miscfuncs.cc: misc funcs that don't belong anywhere else
|
||||||
|
|
||||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
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.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
@ -384,6 +384,82 @@ WritePipeOverlapped (HANDLE h, LPCVOID buf, DWORD len, LPDWORD ret_len,
|
||||||
return ret;
|
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
|
/* 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
|
in dst path. Add a trailing slash to dst when trailing_slash_p arg
|
||||||
is set to 1. */
|
is set to 1. */
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* miscfuncs.h: main Cygwin header file.
|
/* miscfuncs.h: main Cygwin header file.
|
||||||
|
|
||||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
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.
|
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,
|
BOOL WINAPI WritePipeOverlapped (HANDLE h, LPCVOID buf, DWORD len,
|
||||||
LPDWORD ret_len, DWORD timeout);
|
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 ();
|
extern "C" void yield ();
|
||||||
|
|
||||||
#define import_address(x) __import_address ((void *)(x))
|
#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;
|
UNICODE_STRING upath;
|
||||||
OBJECT_ATTRIBUTES attr;
|
OBJECT_ATTRIBUTES attr;
|
||||||
IO_STATUS_BLOCK io;
|
NT_readline rl;
|
||||||
NTSTATUS status;
|
|
||||||
HANDLE fh;
|
|
||||||
tmp_pathbuf tp;
|
tmp_pathbuf tp;
|
||||||
|
char *buf = tp.c_get ();
|
||||||
|
|
||||||
if (user)
|
if (user)
|
||||||
{
|
{
|
||||||
|
@ -1195,81 +1194,10 @@ mount_info::from_fstab (bool user, WCHAR fstab[], PWCHAR fstab_end)
|
||||||
RtlInitUnicodeString (&upath, fstab);
|
RtlInitUnicodeString (&upath, fstab);
|
||||||
InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE, NULL, NULL);
|
InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE, NULL, NULL);
|
||||||
debug_printf ("Try to read mounts from %W", fstab);
|
debug_printf ("Try to read mounts from %W", fstab);
|
||||||
status = NtOpenFile (&fh, SYNCHRONIZE | FILE_READ_DATA, &attr, &io,
|
if (rl.init (&attr, buf, NT_MAX_PATH))
|
||||||
FILE_SHARE_VALID_FLAGS,
|
while ((buf = rl.gets ()))
|
||||||
FILE_SYNCHRONOUS_IO_NONALERT
|
if (!from_fstab_line (buf, user))
|
||||||
| 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))
|
|
||||||
break;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue