* autoload.cc (LoadFuncEx): Define via new LoadFuncEx2 macro.
(LoadFuncEx2): Adapted from LoadFuncEx. Provides control of return value for nonexistent function. (NtQueryObject): Declare. (IsDebuggerPresent): Declare via LoadFuncEx2 and always return true if not available. * debug.h (being_debugged): Just rely on IsDebuggerPresent return value. * dtable.cc (handle_to_fn): New function. (dtable::init_std_file_from_handle): Attempt to derive std handle's name via handle_to_fn. (dtable::build_fhandler_from_name): Fill in what we can in path_conv structure when given a handle and path doesn't exist. * fhandler.cc (fhandler_base::open): Don't set the file pointer here. Use pc->exists () to determine if file exists rather than calling GetFileAttributes again. * fhandler.h (fhandler_base::exec_state_isknown): New method. (fhandler_base::fstat_helper): Add extra arguments to declaration. (fhandler_base::fstat_by_handle): Declare new method. (fhandler_base::fstat_by_name): Declare new method. * fhandler_disk_file (num_entries): Make __stdcall. (fhandler_base::fstat_by_handle): Define new method. (fhandler_base::fstat_by_name): Define new method. (fhandler_base:fstat): Call fstat_by_{handle,name} as appropriate. (fhandler_disk_file::fstat_helper): Accept extra arguments for filling out stat structure. Move handle or name specific stuff to new methods above. (fhandler_disk_file::open): Use real_path->exists rather than calling GetFileAttributes again. * ntdll.h (FILE_NAME_INFORMATION): Define new structure. (OBJECT_INFORMATION_CLASS): Partially define new enum. (OBJECT_NAME_INFORMATION): Define new structure. (NtQueryInformationFile): New declaration. (NtQueryObject): New declaration. * path.cc (path_conv::fillin): Define new method. * path.h (path_conv::fillin): Declare new method. (path_conv::drive_thpe): Rename from 'get_drive_type'. (path_conv::volser): Declare new method. (path_conv::volname): Declare new method. (path_conv::root_dir): Declare new method. * syscalls.cc (fstat64): Send real path_conv to fstat as second argument.
This commit is contained in:
parent
74b2f73ea4
commit
2402700d07
|
@ -1,15 +1,14 @@
|
|||
/* cygserver_shm.cc: Single unix specification IPC interface for Cygwin
|
||||
|
||||
Copyright 2001, 2002 Red Hat, Inc.
|
||||
Copyright 2001, 2002 Red Hat, Inc.
|
||||
|
||||
Originally written by Robert Collins <robert.collins@hotmail.com>
|
||||
Originally written by Robert Collins <robert.collins@hotmail.com>
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
This software is a copyrighted work licensed under the terms of the
|
||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||
details. */
|
||||
This file is part of Cygwin.
|
||||
|
||||
This software is a copyrighted work licensed under the terms of the
|
||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||
details. */
|
||||
|
||||
#ifdef __OUTSIDE_CYGWIN__
|
||||
#undef __INSIDE_CYGWIN__
|
||||
|
|
|
@ -1,3 +1,48 @@
|
|||
2002-05-27 Christopher Faylor <cgf@redhat.com>
|
||||
|
||||
* autoload.cc (LoadFuncEx): Define via new LoadFuncEx2 macro.
|
||||
(LoadFuncEx2): Adapted from LoadFuncEx. Provides control of return
|
||||
value for nonexistent function.
|
||||
(NtQueryObject): Declare.
|
||||
(IsDebuggerPresent): Declare via LoadFuncEx2 and always return true if
|
||||
not available.
|
||||
* debug.h (being_debugged): Just rely on IsDebuggerPresent return
|
||||
value.
|
||||
* dtable.cc (handle_to_fn): New function.
|
||||
(dtable::init_std_file_from_handle): Attempt to derive std handle's
|
||||
name via handle_to_fn.
|
||||
(dtable::build_fhandler_from_name): Fill in what we can in path_conv
|
||||
structure when given a handle and path doesn't exist.
|
||||
* fhandler.cc (fhandler_base::open): Don't set the file pointer here.
|
||||
Use pc->exists () to determine if file exists rather than calling
|
||||
GetFileAttributes again.
|
||||
* fhandler.h (fhandler_base::exec_state_isknown): New method.
|
||||
(fhandler_base::fstat_helper): Add extra arguments to declaration.
|
||||
(fhandler_base::fstat_by_handle): Declare new method.
|
||||
(fhandler_base::fstat_by_name): Declare new method.
|
||||
* fhandler_disk_file (num_entries): Make __stdcall.
|
||||
(fhandler_base::fstat_by_handle): Define new method.
|
||||
(fhandler_base::fstat_by_name): Define new method.
|
||||
(fhandler_base:fstat): Call fstat_by_{handle,name} as appropriate.
|
||||
(fhandler_disk_file::fstat_helper): Accept extra arguments for filling
|
||||
out stat structure. Move handle or name specific stuff to new methods
|
||||
above.
|
||||
(fhandler_disk_file::open): Use real_path->exists rather than calling
|
||||
GetFileAttributes again.
|
||||
* ntdll.h (FILE_NAME_INFORMATION): Define new structure.
|
||||
(OBJECT_INFORMATION_CLASS): Partially define new enum.
|
||||
(OBJECT_NAME_INFORMATION): Define new structure.
|
||||
(NtQueryInformationFile): New declaration.
|
||||
(NtQueryObject): New declaration.
|
||||
* path.cc (path_conv::fillin): Define new method.
|
||||
* path.h (path_conv::fillin): Declare new method.
|
||||
(path_conv::drive_thpe): Rename from 'get_drive_type'.
|
||||
(path_conv::volser): Declare new method.
|
||||
(path_conv::volname): Declare new method.
|
||||
(path_conv::root_dir): Declare new method.
|
||||
* syscalls.cc (fstat64): Send real path_conv to fstat as second
|
||||
argument.
|
||||
|
||||
2002-05-24 Pierre Humblet <pierre.humblet@ieee.org>
|
||||
|
||||
* security.cc (lsa2str): New function.
|
||||
|
|
|
@ -72,9 +72,10 @@ details. */
|
|||
/* Standard DLL load macro. Invokes a fatal warning if the function isn't
|
||||
found. */
|
||||
#define LoadDLLfunc(name, n, dllname) LoadDLLfuncEx (name, n, dllname, 0)
|
||||
#define LoadDLLfuncEx(name, n, dllname, notimp) LoadDLLfuncEx2(name, n, dllname, notimp, 0)
|
||||
|
||||
/* Main DLL setup stuff. */
|
||||
#define LoadDLLfuncEx(name, n, dllname, notimp) \
|
||||
#define LoadDLLfuncEx2(name, n, dllname, notimp, err) \
|
||||
LoadDLLprime (dllname, dll_func_load) \
|
||||
__asm__ (" \n\
|
||||
.section ." #dllname "_text,\"wx\" \n\
|
||||
|
@ -86,7 +87,7 @@ _win32_" mangle (name, n) ": \n\
|
|||
movl (1f),%eax \n\
|
||||
call *(%eax) \n\
|
||||
1:.long ." #dllname "_info \n\
|
||||
.long " #n "+" #notimp " \n\
|
||||
.long (" #n "+" #notimp ") | " #err "<<16 \n\
|
||||
.asciz \"" #name "\" \n\
|
||||
.text \n\
|
||||
");
|
||||
|
@ -121,11 +122,14 @@ noload: \n\
|
|||
jz 1f # Nope. \n\
|
||||
decl %eax # Yes. This is the # of bytes + 1 \n\
|
||||
popl %edx # Caller's caller \n\
|
||||
pushl %eax # Save for later \n\
|
||||
xorl $0xffff,%eax # Only want lower word \n\
|
||||
addl %eax,%esp # Pop off bytes \n\
|
||||
movl $127,%eax # ERROR_PROC_NOT_FOUND \n\
|
||||
pushl %eax # First argument \n\
|
||||
call _SetLastError@4 # Set it \n\
|
||||
xor %eax,%eax # Zero functional return \n\
|
||||
popl %eax # Get back argument \n\
|
||||
shrl $16,%eax # return value in high order word \n\
|
||||
jmp *%edx # Return \n\
|
||||
1: \n\
|
||||
movl (%edx),%eax # Handle value \n\
|
||||
|
@ -373,6 +377,8 @@ LoadDLLfunc (NetUserGetGroups, 28, netapi32)
|
|||
LoadDLLfunc (NetUserGetInfo, 16, netapi32)
|
||||
LoadDLLfunc (NetWkstaUserGetInfo, 12, netapi32)
|
||||
|
||||
LoadDLLfuncEx (NtQueryInformationFile, 20, ntdll, 1)
|
||||
LoadDLLfuncEx2 (NtQueryObject, 20, ntdll, 1, 1)
|
||||
LoadDLLfuncEx (NtCreateToken, 52, ntdll, 1)
|
||||
LoadDLLfuncEx (NtMapViewOfSection, 40, ntdll, 1)
|
||||
LoadDLLfuncEx (NtOpenFile, 24, ntdll, 1)
|
||||
|
@ -483,7 +489,7 @@ LoadDLLfunc (CoCreateInstance, 20, ole32)
|
|||
LoadDLLfuncEx (CancelIo, 4, kernel32, 1)
|
||||
LoadDLLfuncEx (CreateHardLinkA, 12, kernel32, 1)
|
||||
LoadDLLfuncEx (CreateToolhelp32Snapshot, 8, kernel32, 1)
|
||||
LoadDLLfuncEx (IsDebuggerPresent, 0, kernel32, 1)
|
||||
LoadDLLfuncEx2 (IsDebuggerPresent, 0, kernel32, 1, 1)
|
||||
LoadDLLfuncEx (Process32First, 8, kernel32, 1)
|
||||
LoadDLLfuncEx (Process32Next, 8, kernel32, 1)
|
||||
LoadDLLfuncEx (SignalObjectAndWait, 16, kernel32, 1)
|
||||
|
|
|
@ -469,7 +469,7 @@ cygheap_user::set_sid (PSID new_sid)
|
|||
if (psid)
|
||||
cfree (psid);
|
||||
if (orig_psid)
|
||||
cfree (orig_psid);
|
||||
cfree (orig_psid);
|
||||
psid = NULL;
|
||||
orig_psid = NULL;
|
||||
return TRUE;
|
||||
|
@ -477,7 +477,7 @@ cygheap_user::set_sid (PSID new_sid)
|
|||
else
|
||||
{
|
||||
if (!psid)
|
||||
{
|
||||
{
|
||||
if (!orig_psid)
|
||||
{
|
||||
orig_psid = cmalloc (HEAP_STR, MAX_SID_LEN);
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
/* cygserver_shm.cc: Single unix specification IPC interface for Cygwin
|
||||
|
||||
Copyright 2001, 2002 Red Hat, Inc.
|
||||
Copyright 2001, 2002 Red Hat, Inc.
|
||||
|
||||
Originally written by Robert Collins <robert.collins@hotmail.com>
|
||||
Originally written by Robert Collins <robert.collins@hotmail.com>
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
This software is a copyrighted work licensed under the terms of the
|
||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||
details. */
|
||||
This file is part of Cygwin.
|
||||
|
||||
This software is a copyrighted work licensed under the terms of the
|
||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||
details. */
|
||||
|
||||
#ifdef __OUTSIDE_CYGWIN__
|
||||
#undef __INSIDE_CYGWIN__
|
||||
|
|
|
@ -29,7 +29,7 @@ DWORD __stdcall WFMO (DWORD, CONST HANDLE *, BOOL, DWORD) __attribute__ ((regpar
|
|||
#define _DEBUG_H_
|
||||
|
||||
#define being_debugged() \
|
||||
(IsDebuggerPresent () || GetLastError () == ERROR_PROC_NOT_FOUND)
|
||||
(IsDebuggerPresent () /* || GetLastError () == ERROR_PROC_NOT_FOUND*/)
|
||||
|
||||
void threadname_init ();
|
||||
HANDLE __stdcall makethread (LPTHREAD_START_ROUTINE, LPVOID, DWORD, const char *) __attribute__ ((regparm(3)));
|
||||
|
|
|
@ -223,7 +223,7 @@ mkdir (const char *dir, mode_t mode)
|
|||
#ifdef HIDDEN_DOT_FILES
|
||||
char *c = strrchr (real_dir.get_win32 (), '\\');
|
||||
if ((c && c[1] == '.') || *real_dir.get_win32 () == '.')
|
||||
SetFileAttributes (real_dir.get_win32 (), FILE_ATTRIBUTE_HIDDEN);
|
||||
SetFileAttributes (real_dir.get_win32 (), FILE_ATTRIBUTE_HIDDEN);
|
||||
#endif
|
||||
res = 0;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@ details. */
|
|||
#include <fcntl.h>
|
||||
#include <sys/cygwin.h>
|
||||
#include <assert.h>
|
||||
#include <ntdef.h>
|
||||
#include <winnls.h>
|
||||
|
||||
#define USE_SYS_TYPES_FD_SET
|
||||
#include <winsock.h>
|
||||
|
@ -31,10 +33,13 @@ details. */
|
|||
#include "path.h"
|
||||
#include "dtable.h"
|
||||
#include "cygheap.h"
|
||||
#include "ntdll.h"
|
||||
|
||||
static const NO_COPY DWORD std_consts[] = {STD_INPUT_HANDLE, STD_OUTPUT_HANDLE,
|
||||
STD_ERROR_HANDLE};
|
||||
|
||||
static char *handle_to_fn (HANDLE, char *);
|
||||
|
||||
/* Set aside space for the table of fds */
|
||||
void
|
||||
dtable_init (void)
|
||||
|
@ -267,7 +272,7 @@ dtable::init_std_file_from_handle (int fd, HANDLE handle, DWORD myaccess)
|
|||
else if (GetCommState (handle, &dcb))
|
||||
name = "/dev/ttyS0"; // FIXME - determine correct device
|
||||
else
|
||||
name = "unknown disk file";
|
||||
name = handle_to_fn (handle, (char *) alloca (MAX_PATH + 100));
|
||||
|
||||
path_conv pc;
|
||||
build_fhandler_from_name (fd, name, handle, pc)->init (handle, myaccess, bin);
|
||||
|
@ -286,6 +291,9 @@ dtable::build_fhandler_from_name (int fd, const char *name, HANDLE handle,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (!pc.exists () && handle)
|
||||
pc.fillin (handle);
|
||||
|
||||
fhandler_base *fh = build_fhandler (fd, pc.get_devn (),
|
||||
pc.return_and_clear_normalized_path (),
|
||||
pc, pc.get_unitn ());
|
||||
|
@ -373,14 +381,14 @@ dtable::build_fhandler (int fd, DWORD dev, char *unix_name,
|
|||
fh = cnew (fhandler_dev_dsp) ();
|
||||
break;
|
||||
case FH_PROC:
|
||||
fh = cnew (fhandler_proc) ();
|
||||
break;
|
||||
fh = cnew (fhandler_proc) ();
|
||||
break;
|
||||
case FH_REGISTRY:
|
||||
fh = cnew (fhandler_registry) ();
|
||||
break;
|
||||
fh = cnew (fhandler_registry) ();
|
||||
break;
|
||||
case FH_PROCESS:
|
||||
fh = cnew (fhandler_process) ();
|
||||
break;
|
||||
fh = cnew (fhandler_process) ();
|
||||
break;
|
||||
default:
|
||||
system_printf ("internal error -- unknown device - %p", dev);
|
||||
fh = NULL;
|
||||
|
@ -688,3 +696,84 @@ dtable::vfork_child_fixup ()
|
|||
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static char *
|
||||
handle_to_fn (HANDLE h, char *posix_fn)
|
||||
{
|
||||
IO_STATUS_BLOCK io;
|
||||
FILE_NAME_INFORMATION ntfn;
|
||||
|
||||
io.Status = 0;
|
||||
io.Information = 0;
|
||||
|
||||
SetLastError (0);
|
||||
DWORD res = NtQueryInformationFile (h, &io, &ntfn, sizeof (ntfn), 9);
|
||||
if (res || GetLastError () == ERROR_PROC_NOT_FOUND)
|
||||
{
|
||||
strcpy (posix_fn, "some disk file");
|
||||
return posix_fn;
|
||||
}
|
||||
ntfn.FileName[ntfn.FileNameLength / sizeof (WCHAR)] = 0;
|
||||
|
||||
char win32_fn[MAX_PATH + 100];
|
||||
sys_wcstombs (win32_fn, ntfn.FileName, ntfn.FileNameLength);
|
||||
cygwin_conv_to_full_posix_path (win32_fn, posix_fn);
|
||||
return posix_fn;
|
||||
}
|
||||
#else
|
||||
#define DEVICE_PREFIX "\\device\\"
|
||||
#define DEVICE_PREFIX_LEN sizeof(DEVICE_PREFIX) - 1
|
||||
static char *
|
||||
handle_to_fn (HANDLE h, char *posix_fn)
|
||||
{
|
||||
OBJECT_NAME_INFORMATION *ntfn;
|
||||
char fnbuf[32768];
|
||||
|
||||
memset (fnbuf, 0, sizeof (fnbuf));
|
||||
ntfn = (OBJECT_NAME_INFORMATION *) fnbuf;
|
||||
ntfn->Name.MaximumLength = sizeof (fnbuf);
|
||||
ntfn->Name.Buffer = (WCHAR *) ntfn + 1;
|
||||
|
||||
DWORD res = NtQueryObject (h, ObjectNameInformation, ntfn, sizeof (fnbuf), NULL);
|
||||
if (res)
|
||||
{
|
||||
strcpy (posix_fn, "some disk file");
|
||||
return posix_fn;
|
||||
}
|
||||
ntfn->Name.Buffer[ntfn->Name.Length / sizeof (WCHAR)] = 0;
|
||||
|
||||
char win32_fn[MAX_PATH + 100];
|
||||
sys_wcstombs (win32_fn, ntfn->Name.Buffer, ntfn->Name.Length);
|
||||
if (!strncasematch (win32_fn, DEVICE_PREFIX, DEVICE_PREFIX_LEN)
|
||||
|| !QueryDosDevice (NULL, fnbuf, sizeof (fnbuf)))
|
||||
return strcpy (posix_fn, win32_fn);
|
||||
|
||||
char *p = strchr (win32_fn + DEVICE_PREFIX_LEN, '\\');
|
||||
if (!p)
|
||||
p = strchr (win32_fn + DEVICE_PREFIX_LEN, '\0');
|
||||
|
||||
int n = p - win32_fn;
|
||||
char *w32 = win32_fn;
|
||||
for (char *s = fnbuf; *s; s = strchr (s, '\0') + 1)
|
||||
{
|
||||
char device[MAX_PATH + 10];
|
||||
device[MAX_PATH + 9] = '\0';
|
||||
if (strchr (s, ':') == NULL)
|
||||
continue;
|
||||
if (!QueryDosDevice (s, device, sizeof (device) - 1))
|
||||
continue;
|
||||
if (!strncasematch (device, win32_fn, n) ||
|
||||
(device[n] != '\0' && (device[n] != '\\' || device[n + 1] != ';')))
|
||||
continue;
|
||||
n = strlen (s);
|
||||
w32 = p - (n + 1);
|
||||
memcpy (w32, s, n);
|
||||
p[-1] = '\\';
|
||||
break;
|
||||
}
|
||||
|
||||
cygwin_conv_to_full_posix_path (w32, posix_fn);
|
||||
return posix_fn;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1013,7 +1013,7 @@ sig_handle (int sig, bool thisproc)
|
|||
if (handler == (void *) SIG_DFL)
|
||||
{
|
||||
if (sig == SIGCHLD || sig == SIGIO || sig == SIGCONT || sig == SIGWINCH
|
||||
|| sig == SIGURG || (thisproc && hExeced && sig == SIGINT))
|
||||
|| sig == SIGURG || (thisproc && hExeced && sig == SIGINT))
|
||||
{
|
||||
sigproc_printf ("default signal %d ignored", sig);
|
||||
goto done;
|
||||
|
|
|
@ -309,7 +309,7 @@ fhandler_base::get_default_fmode (int flags)
|
|||
|
||||
/* Open system call handler function. */
|
||||
int
|
||||
fhandler_base::open (path_conv *, int flags, mode_t mode)
|
||||
fhandler_base::open (path_conv *pc, int flags, mode_t mode)
|
||||
{
|
||||
int res = 0;
|
||||
HANDLE x;
|
||||
|
@ -318,7 +318,7 @@ fhandler_base::open (path_conv *, int flags, mode_t mode)
|
|||
int creation_distribution;
|
||||
SECURITY_ATTRIBUTES sa = sec_none;
|
||||
|
||||
syscall_printf ("(%s, %p)", get_win32_name (), flags);
|
||||
syscall_printf ("(%s, %p) query_open %d", get_win32_name (), flags, get_query_open ());
|
||||
|
||||
if (get_win32_name () == NULL)
|
||||
{
|
||||
|
@ -375,7 +375,7 @@ fhandler_base::open (path_conv *, int flags, mode_t mode)
|
|||
{
|
||||
char *c = strrchr (get_win32_name (), '\\');
|
||||
if ((c && c[1] == '.') || *get_win32_name () == '.')
|
||||
file_attributes |= FILE_ATTRIBUTE_HIDDEN;
|
||||
file_attributes |= FILE_ATTRIBUTE_HIDDEN;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -385,7 +385,7 @@ fhandler_base::open (path_conv *, int flags, mode_t mode)
|
|||
if (get_query_open () &&
|
||||
isremote () &&
|
||||
creation_distribution == OPEN_EXISTING &&
|
||||
GetFileAttributes (get_win32_name ()) == INVALID_FILE_ATTRIBUTES)
|
||||
!pc->exists ())
|
||||
{
|
||||
set_errno (ENOENT);
|
||||
goto done;
|
||||
|
@ -447,16 +447,6 @@ fhandler_base::open (path_conv *, int flags, mode_t mode)
|
|||
set_w_binary (bin);
|
||||
syscall_printf ("filemode set to %s", bin ? "binary" : "text");
|
||||
|
||||
if (get_device () != FH_TAPE
|
||||
&& get_device () != FH_FLOPPY
|
||||
&& get_device () != FH_SERIAL)
|
||||
{
|
||||
if (flags & O_APPEND)
|
||||
SetFilePointer (get_handle(), 0, 0, FILE_END);
|
||||
else
|
||||
SetFilePointer (get_handle(), 0, 0, FILE_BEGIN);
|
||||
}
|
||||
|
||||
res = 1;
|
||||
set_open_status ();
|
||||
done:
|
||||
|
|
|
@ -246,13 +246,14 @@ class fhandler_base
|
|||
}
|
||||
void set_execable_p () { FHSETF (EXECABL); }
|
||||
bool dont_care_if_execable () { return FHISSETF (DCEXEC); }
|
||||
bool exec_state_isknown () { return FHISSETF (DCEXEC) || FHISSETF (EXECABL); }
|
||||
|
||||
bool get_append_p () { return FHISSETF (APPEND); }
|
||||
void set_append_p (int val) { FHCONDSETF (val, APPEND); }
|
||||
void set_append_p () { FHSETF (APPEND); }
|
||||
|
||||
bool get_query_open () { return FHISSETF (QUERYOPEN); }
|
||||
void set_query_open (int val) { FHCONDSETF (val, QUERYOPEN); }
|
||||
void set_query_open (bool val) { FHCONDSETF (val, QUERYOPEN); }
|
||||
|
||||
bool get_readahead_valid () { return raixget < ralen; }
|
||||
int puts_readahead (const char *s, size_t len = (size_t) -1);
|
||||
|
@ -552,7 +553,18 @@ class fhandler_disk_file: public fhandler_base
|
|||
int lock (int, struct flock *);
|
||||
BOOL is_device () { return FALSE; }
|
||||
int __stdcall fstat (struct __stat64 *buf, path_conv *pc) __attribute__ ((regparm (3)));
|
||||
int __stdcall fstat_helper (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
||||
int __stdcall fstat_helper (struct __stat64 *buf, path_conv *pc,
|
||||
FILETIME ftCreateionTime,
|
||||
FILETIME ftLastAccessTime,
|
||||
FILETIME ftLastWriteTime,
|
||||
DWORD nFileSizeHigh,
|
||||
DWORD nFileSizeLow,
|
||||
DWORD nFileIndexHigh = 0,
|
||||
DWORD nFileIndexLow = 0,
|
||||
DWORD nNumberOfLinks = 1)
|
||||
__attribute__ ((regparm (3)));
|
||||
int __stdcall fstat_by_handle (struct __stat64 *buf, path_conv *pc) __attribute__ ((regparm (3)));
|
||||
int __stdcall fstat_by_name (struct __stat64 *buf, path_conv *pc) __attribute__ ((regparm (3)));
|
||||
|
||||
HANDLE mmap (caddr_t *addr, size_t len, DWORD access, int flags, __off64_t off);
|
||||
int munmap (HANDLE h, caddr_t addr, size_t len);
|
||||
|
|
|
@ -1194,7 +1194,7 @@ fhandler_console::char_command (char c)
|
|||
ReadConsoleOutputA (get_output_handle (), savebuf,
|
||||
savebufsiz, cob, &now.srWindow);
|
||||
}
|
||||
else /* restore */
|
||||
else /* restore */
|
||||
{
|
||||
CONSOLE_SCREEN_BUFFER_INFO now;
|
||||
COORD cob = { 0, 0 };
|
||||
|
|
|
@ -31,7 +31,7 @@ details. */
|
|||
#define _COMPILING_NEWLIB
|
||||
#include <dirent.h>
|
||||
|
||||
static int
|
||||
static int __stdcall
|
||||
num_entries (const char *win32_name)
|
||||
{
|
||||
WIN32_FIND_DATA buf;
|
||||
|
@ -60,7 +60,68 @@ num_entries (const char *win32_name)
|
|||
return count;
|
||||
}
|
||||
|
||||
int
|
||||
int __stdcall
|
||||
fhandler_disk_file::fstat_by_handle (struct __stat64 *buf, path_conv *pc)
|
||||
{
|
||||
int res;
|
||||
BY_HANDLE_FILE_INFORMATION local;
|
||||
|
||||
/* NT 3.51 seems to have a bug when attempting to get vol serial
|
||||
numbers. This loop gets around this. */
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
if (!(res = GetFileInformationByHandle (get_handle (), &local)))
|
||||
break;
|
||||
if (local.dwVolumeSerialNumber && (long) local.dwVolumeSerialNumber != -1)
|
||||
break;
|
||||
}
|
||||
debug_printf ("%d = GetFileInformationByHandle (%s, %d)",
|
||||
res, get_win32_name (), get_handle ());
|
||||
if (res == 0)
|
||||
/* GetFileInformationByHandle will fail if it's given stdin/out/err
|
||||
or a pipe*/
|
||||
{
|
||||
memset (&local, 0, sizeof (local));
|
||||
local.nFileSizeLow = GetFileSize (get_handle (), &local.nFileSizeHigh);
|
||||
}
|
||||
|
||||
return fstat_helper (buf, pc,
|
||||
local.ftCreationTime,
|
||||
local.ftLastAccessTime,
|
||||
local.ftLastWriteTime,
|
||||
local.nFileSizeHigh,
|
||||
local.nFileSizeLow,
|
||||
local.nFileIndexHigh,
|
||||
local.nFileIndexLow,
|
||||
local.nNumberOfLinks);
|
||||
}
|
||||
|
||||
int __stdcall
|
||||
fhandler_disk_file::fstat_by_name (struct __stat64 *buf, path_conv *pc)
|
||||
{
|
||||
int res;
|
||||
HANDLE handle;
|
||||
WIN32_FIND_DATA local;
|
||||
|
||||
if ((handle = FindFirstFile (pc->get_win32 (), &local)) == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
__seterrno ();
|
||||
res = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
FindClose (handle);
|
||||
res = fstat_helper (buf, pc,
|
||||
local.ftCreationTime,
|
||||
local.ftLastAccessTime,
|
||||
local.ftLastWriteTime,
|
||||
local.nFileSizeHigh,
|
||||
local.nFileSizeLow);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int __stdcall
|
||||
fhandler_disk_file::fstat (struct __stat64 *buf, path_conv *pc)
|
||||
{
|
||||
int res = -1;
|
||||
|
@ -68,19 +129,29 @@ fhandler_disk_file::fstat (struct __stat64 *buf, path_conv *pc)
|
|||
__uid16_t uid;
|
||||
__gid16_t gid;
|
||||
int open_flags = O_RDONLY | O_BINARY | O_DIROPEN;
|
||||
bool query_open_already;
|
||||
|
||||
if (!pc)
|
||||
return fstat_helper (buf);
|
||||
if (get_io_handle ())
|
||||
return fstat_by_handle (buf, pc);
|
||||
|
||||
if ((oret = open (pc, open_flags, 0)))
|
||||
/* If we don't care if the file is executable or we already know if it is,
|
||||
then just do a "query open" as it is apparently much faster. */
|
||||
if (pc->exec_state () != dont_know_if_executable)
|
||||
set_query_open (query_open_already = true);
|
||||
else
|
||||
query_open_already = false;
|
||||
|
||||
if (query_open_already && strncasematch (pc->volname (), "FAT", 3))
|
||||
oret = 0;
|
||||
else if ((oret = open (pc, open_flags, 0)))
|
||||
/* ok */;
|
||||
else
|
||||
{
|
||||
int ntsec_atts = 0;
|
||||
/* If we couldn't open the file, try a "query open" with no permissions.
|
||||
This will allow us to determine *some* things about the file, at least. */
|
||||
set_query_open (TRUE);
|
||||
if ((oret = open (pc, open_flags, 0)))
|
||||
set_query_open (true);
|
||||
if (!query_open_already && (oret = open (pc, open_flags, 0)))
|
||||
/* ok */;
|
||||
else if (allow_ntsec && pc->has_acls () && get_errno () == EACCES
|
||||
&& !get_file_attribute (TRUE, get_win32_name (), &ntsec_atts, &uid, &gid)
|
||||
|
@ -96,150 +167,49 @@ fhandler_disk_file::fstat (struct __stat64 *buf, path_conv *pc)
|
|||
set_file_attribute (TRUE, get_win32_name (), ntsec_atts);
|
||||
}
|
||||
}
|
||||
|
||||
if (oret)
|
||||
{
|
||||
res = fstat_helper (buf);
|
||||
/* The number of links to a directory includes the
|
||||
number of subdirectories in the directory, since all
|
||||
those subdirectories point to it.
|
||||
This is too slow on remote drives, so we do without it and
|
||||
set the number of links to 2. */
|
||||
/* Unfortunately the count of 2 confuses `find (1)' command. So
|
||||
let's try it with `1' as link count. */
|
||||
if (pc->isdir ())
|
||||
buf->st_nlink = pc->isremote () ? 1 : num_entries (pc->get_win32 ());
|
||||
res = fstat_by_handle (buf, pc);
|
||||
close ();
|
||||
}
|
||||
else if (pc->exists ())
|
||||
{
|
||||
/* Unfortunately, the above open may fail if the file exists, though.
|
||||
So we have to care for this case here, too. */
|
||||
WIN32_FIND_DATA wfd;
|
||||
HANDLE handle;
|
||||
buf->st_nlink = 1;
|
||||
if (pc->isdir ())
|
||||
buf->st_nlink = pc->isremote () ? 1 : num_entries (pc->get_win32 ());
|
||||
buf->st_dev = FHDEVN (FH_DISK) << 8;
|
||||
buf->st_ino = hash_path_name (0, pc->get_win32 ());
|
||||
if (pc->isdir ())
|
||||
buf->st_mode = S_IFDIR;
|
||||
else if (pc->issymlink ())
|
||||
buf->st_mode = S_IFLNK;
|
||||
else if (pc->issocket ())
|
||||
buf->st_mode = S_IFSOCK;
|
||||
else
|
||||
buf->st_mode = S_IFREG;
|
||||
if (!pc->has_acls ()
|
||||
|| get_file_attribute (TRUE, pc->get_win32 (),
|
||||
&buf->st_mode, &uid, &gid))
|
||||
{
|
||||
buf->st_mode |= STD_RBITS | STD_XBITS;
|
||||
if (!(pc->has_attribute (FILE_ATTRIBUTE_READONLY)))
|
||||
buf->st_mode |= STD_WBITS;
|
||||
if (pc->issymlink ())
|
||||
buf->st_mode |= S_IRWXU | S_IRWXG | S_IRWXO;
|
||||
get_file_attribute (FALSE, pc->get_win32 (), NULL, &uid, &gid);
|
||||
}
|
||||
buf->st_uid = uid;
|
||||
buf->st_gid = gid;
|
||||
if ((handle = FindFirstFile (pc->get_win32 (), &wfd))
|
||||
!= INVALID_HANDLE_VALUE)
|
||||
{
|
||||
/* This is for FAT filesystems, which don't support atime/ctime */
|
||||
if (wfd.ftLastAccessTime.dwLowDateTime == 0
|
||||
&& wfd.ftLastAccessTime.dwHighDateTime == 0)
|
||||
wfd.ftLastAccessTime = wfd.ftLastWriteTime;
|
||||
if (wfd.ftCreationTime.dwLowDateTime == 0
|
||||
&& wfd.ftCreationTime.dwHighDateTime == 0)
|
||||
wfd.ftCreationTime = wfd.ftLastWriteTime;
|
||||
|
||||
buf->st_atime = to_time_t (&wfd.ftLastAccessTime);
|
||||
buf->st_mtime = to_time_t (&wfd.ftLastWriteTime);
|
||||
buf->st_ctime = to_time_t (&wfd.ftCreationTime);
|
||||
buf->st_size = wfd.nFileSizeLow;
|
||||
buf->st_size = ((__off64_t)wfd.nFileSizeHigh << 32)
|
||||
+ wfd.nFileSizeLow;
|
||||
buf->st_blksize = S_BLKSIZE;
|
||||
buf->st_blocks = (buf->st_size + S_BLKSIZE-1) / S_BLKSIZE;
|
||||
FindClose (handle);
|
||||
}
|
||||
res = 0;
|
||||
}
|
||||
res = fstat_by_name (buf, pc);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int
|
||||
fhandler_disk_file::fstat_helper (struct __stat64 *buf)
|
||||
int __stdcall
|
||||
fhandler_disk_file::fstat_helper (struct __stat64 *buf, path_conv *pc,
|
||||
FILETIME ftCreationTime,
|
||||
FILETIME ftLastAccessTime,
|
||||
FILETIME ftLastWriteTime,
|
||||
DWORD nFileSizeHigh,
|
||||
DWORD nFileSizeLow,
|
||||
DWORD nFileIndexHigh,
|
||||
DWORD nFileIndexLow,
|
||||
DWORD nNumberOfLinks)
|
||||
{
|
||||
int res = 0; // avoid a compiler warning
|
||||
BY_HANDLE_FILE_INFORMATION local;
|
||||
save_errno saved_errno;
|
||||
|
||||
/* NT 3.51 seems to have a bug when attempting to get vol serial
|
||||
numbers. This loop gets around this. */
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
if (!(res = GetFileInformationByHandle (get_handle (), &local)))
|
||||
break;
|
||||
if (local.dwVolumeSerialNumber && (long) local.dwVolumeSerialNumber != -1)
|
||||
break;
|
||||
}
|
||||
debug_printf ("%d = GetFileInformationByHandle (%s, %d)",
|
||||
res, get_win32_name (), get_handle ());
|
||||
if (res == 0)
|
||||
{
|
||||
/* GetFileInformationByHandle will fail if it's given stdin/out/err
|
||||
or a pipe*/
|
||||
DWORD lsize, hsize;
|
||||
|
||||
if (GetFileType (get_handle ()) != FILE_TYPE_DISK)
|
||||
buf->st_mode = S_IFCHR;
|
||||
|
||||
lsize = GetFileSize (get_handle (), &hsize);
|
||||
if (lsize == 0xffffffff && GetLastError () != NO_ERROR)
|
||||
buf->st_mode = S_IFCHR;
|
||||
else
|
||||
buf->st_size = ((__off64_t)hsize << 32) + lsize;
|
||||
/* We expect these to fail! */
|
||||
buf->st_mode |= STD_RBITS | STD_WBITS;
|
||||
buf->st_blksize = S_BLKSIZE;
|
||||
buf->st_ino = get_namehash ();
|
||||
syscall_printf ("0 = fstat (, %p)", buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!get_win32_name ())
|
||||
{
|
||||
saved_errno.set (ENOENT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* This is for FAT filesystems, which don't support atime/ctime */
|
||||
if (local.ftLastAccessTime.dwLowDateTime == 0
|
||||
&& local.ftLastAccessTime.dwHighDateTime == 0)
|
||||
local.ftLastAccessTime = local.ftLastWriteTime;
|
||||
if (local.ftCreationTime.dwLowDateTime == 0
|
||||
&& local.ftCreationTime.dwHighDateTime == 0)
|
||||
local.ftCreationTime = local.ftLastWriteTime;
|
||||
if (ftLastAccessTime.dwLowDateTime == 0
|
||||
&& ftLastAccessTime.dwHighDateTime == 0)
|
||||
ftLastAccessTime = ftLastWriteTime;
|
||||
if (ftCreationTime.dwLowDateTime == 0
|
||||
&& ftCreationTime.dwHighDateTime == 0)
|
||||
ftCreationTime = ftLastWriteTime;
|
||||
|
||||
buf->st_atime = to_time_t (&local.ftLastAccessTime);
|
||||
buf->st_mtime = to_time_t (&local.ftLastWriteTime);
|
||||
buf->st_ctime = to_time_t (&local.ftCreationTime);
|
||||
buf->st_nlink = local.nNumberOfLinks;
|
||||
buf->st_dev = local.dwVolumeSerialNumber;
|
||||
buf->st_size = ((__off64_t)local.nFileSizeHigh << 32)
|
||||
+ local.nFileSizeLow;
|
||||
|
||||
/* Allocate some place to determine the root directory. Need to allocate
|
||||
enough so that rootdir can add a trailing slash if path starts with \\. */
|
||||
char root[strlen (get_win32_name ()) + 3];
|
||||
strcpy (root, get_win32_name ());
|
||||
buf->st_atime = to_time_t (&ftLastAccessTime);
|
||||
buf->st_mtime = to_time_t (&ftLastWriteTime);
|
||||
buf->st_ctime = to_time_t (&ftCreationTime);
|
||||
buf->st_nlink = nNumberOfLinks;
|
||||
buf->st_dev = pc->volser ();
|
||||
buf->st_size = ((__off64_t)nFileSizeHigh << 32) + nFileSizeLow;
|
||||
|
||||
/* Assume that if a drive has ACL support it MAY have valid "inodes".
|
||||
It definitely does not have valid inodes if it does not have ACL
|
||||
support. */
|
||||
switch (has_acls () ? GetDriveType (rootdir (root)) : DRIVE_UNKNOWN)
|
||||
switch (pc->has_acls () && (nFileIndexHigh || nFileIndexLow)
|
||||
? pc->drive_type () : DRIVE_UNKNOWN)
|
||||
{
|
||||
case DRIVE_FIXED:
|
||||
case DRIVE_REMOVABLE:
|
||||
|
@ -247,7 +217,7 @@ fhandler_disk_file::fstat_helper (struct __stat64 *buf)
|
|||
case DRIVE_RAMDISK:
|
||||
/* Although the documentation indicates otherwise, it seems like
|
||||
"inodes" on these devices are persistent, at least across reboots. */
|
||||
buf->st_ino = local.nFileIndexHigh | local.nFileIndexLow;
|
||||
buf->st_ino = nFileIndexHigh | nFileIndexLow;
|
||||
break;
|
||||
default:
|
||||
/* Either the nFileIndex* fields are unreliable or unavailable. Use the
|
||||
|
@ -257,25 +227,25 @@ fhandler_disk_file::fstat_helper (struct __stat64 *buf)
|
|||
}
|
||||
|
||||
buf->st_blksize = S_BLKSIZE;
|
||||
buf->st_blocks = (buf->st_size + S_BLKSIZE-1) / S_BLKSIZE;
|
||||
buf->st_blocks = (buf->st_size + S_BLKSIZE - 1) / S_BLKSIZE;
|
||||
|
||||
buf->st_mode = 0;
|
||||
/* Using a side effect: get_file_attibutes checks for
|
||||
directory. This is used, to set S_ISVTX, if needed. */
|
||||
if (local.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
if (pc->fileattr & FILE_ATTRIBUTE_DIRECTORY)
|
||||
buf->st_mode = S_IFDIR;
|
||||
else if (get_symlink_p ())
|
||||
else if (pc->issymlink ())
|
||||
buf->st_mode = S_IFLNK;
|
||||
else if (get_socket_p ())
|
||||
else if (pc->issocket ())
|
||||
buf->st_mode = S_IFSOCK;
|
||||
|
||||
__uid16_t uid;
|
||||
__gid16_t gid;
|
||||
if (get_file_attribute (has_acls (), get_win32_name (), &buf->st_mode,
|
||||
if (get_file_attribute (pc->has_acls (), get_win32_name (), &buf->st_mode,
|
||||
&uid, &gid) == 0)
|
||||
{
|
||||
/* If read-only attribute is set, modify ntsec return value */
|
||||
if ((local.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
|
||||
&& !get_symlink_p ())
|
||||
if ((pc->fileattr & FILE_ATTRIBUTE_READONLY) && !get_symlink_p ())
|
||||
buf->st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
|
||||
|
||||
if (!(buf->st_mode & S_IFMT))
|
||||
|
@ -285,7 +255,7 @@ fhandler_disk_file::fstat_helper (struct __stat64 *buf)
|
|||
{
|
||||
buf->st_mode |= STD_RBITS;
|
||||
|
||||
if (!(local.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
|
||||
if (!(pc->fileattr & FILE_ATTRIBUTE_READONLY))
|
||||
buf->st_mode |= STD_WBITS;
|
||||
/* | S_IWGRP | S_IWOTH; we don't give write to group etc */
|
||||
|
||||
|
@ -293,54 +263,53 @@ fhandler_disk_file::fstat_helper (struct __stat64 *buf)
|
|||
buf->st_mode |= S_IFDIR | STD_XBITS;
|
||||
else if (buf->st_mode & S_IFMT)
|
||||
/* nothing */;
|
||||
else if (get_socket_p ())
|
||||
else if (pc->issocket ())
|
||||
buf->st_mode |= S_IFSOCK;
|
||||
else
|
||||
switch (GetFileType (get_handle ()))
|
||||
{
|
||||
case FILE_TYPE_CHAR:
|
||||
case FILE_TYPE_UNKNOWN:
|
||||
buf->st_mode |= S_IFCHR;
|
||||
break;
|
||||
case FILE_TYPE_DISK:
|
||||
buf->st_mode |= S_IFREG;
|
||||
if (!dont_care_if_execable () && !get_execable_p ())
|
||||
{
|
||||
DWORD cur, done;
|
||||
char magic[3];
|
||||
{
|
||||
buf->st_mode |= S_IFREG;
|
||||
if (!pc->exec_state () == dont_know_if_executable)
|
||||
{
|
||||
DWORD cur, done;
|
||||
char magic[3];
|
||||
|
||||
/* First retrieve current position, set to beginning
|
||||
of file if not already there. */
|
||||
cur = SetFilePointer (get_handle(), 0, NULL, FILE_CURRENT);
|
||||
if (cur != INVALID_SET_FILE_POINTER &&
|
||||
(!cur ||
|
||||
SetFilePointer (get_handle(), 0, NULL, FILE_BEGIN)
|
||||
!= INVALID_SET_FILE_POINTER))
|
||||
{
|
||||
/* FIXME should we use /etc/magic ? */
|
||||
magic[0] = magic[1] = magic[2] = '\0';
|
||||
if (ReadFile (get_handle (), magic, 3, &done, NULL) &&
|
||||
has_exec_chars (magic, done))
|
||||
set_execable_p ();
|
||||
SetFilePointer (get_handle(), cur, NULL, FILE_BEGIN);
|
||||
}
|
||||
}
|
||||
if (get_execable_p ())
|
||||
buf->st_mode |= STD_XBITS;
|
||||
break;
|
||||
case FILE_TYPE_PIPE:
|
||||
buf->st_mode |= S_IFSOCK;
|
||||
break;
|
||||
}
|
||||
/* First retrieve current position, set to beginning
|
||||
of file if not already there. */
|
||||
cur = SetFilePointer (get_handle(), 0, NULL, FILE_CURRENT);
|
||||
if (cur != INVALID_SET_FILE_POINTER &&
|
||||
(!cur ||
|
||||
SetFilePointer (get_handle(), 0, NULL, FILE_BEGIN)
|
||||
!= INVALID_SET_FILE_POINTER))
|
||||
{
|
||||
/* FIXME should we use /etc/magic ? */
|
||||
magic[0] = magic[1] = magic[2] = '\0';
|
||||
if (ReadFile (get_handle (), magic, 3, &done, NULL) &&
|
||||
has_exec_chars (magic, done))
|
||||
set_execable_p ();
|
||||
SetFilePointer (get_handle(), cur, NULL, FILE_BEGIN);
|
||||
}
|
||||
}
|
||||
if (pc->exec_state () == is_executable)
|
||||
buf->st_mode |= STD_XBITS;
|
||||
}
|
||||
}
|
||||
|
||||
buf->st_uid = uid;
|
||||
buf->st_gid = gid;
|
||||
|
||||
syscall_printf ("0 = fstat (, %p) st_atime=%x st_size=%D, st_mode=%p, st_ino=%d, sizeof=%d",
|
||||
buf, buf->st_atime, buf->st_size, buf->st_mode,
|
||||
(int) buf->st_ino, sizeof (*buf));
|
||||
/* The number of links to a directory includes the
|
||||
number of subdirectories in the directory, since all
|
||||
those subdirectories point to it.
|
||||
This is too slow on remote drives, so we do without it and
|
||||
set the number of links to 2. */
|
||||
/* Unfortunately the count of 2 confuses `find (1)' command. So
|
||||
let's try it with `1' as link count. */
|
||||
if (pc->isdir () && !buf->st_nlink)
|
||||
buf->st_nlink = pc->isremote () ? 1 : num_entries (pc->get_win32 ());
|
||||
|
||||
syscall_printf ("0 = fstat (, %p) st_atime=%x st_size=%D, st_mode=%p, st_ino=%d, sizeof=%d",
|
||||
buf, buf->st_atime, buf->st_size, buf->st_mode,
|
||||
(int) buf->st_ino, sizeof (*buf));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -391,8 +360,7 @@ fhandler_disk_file::open (path_conv *real_path, int flags, mode_t mode)
|
|||
The only known file system to date is the SUN NFS Solstice Client 3.1
|
||||
which returns a valid handle when trying to open a file in a nonexistent
|
||||
directory. */
|
||||
if (real_path->has_buggy_open ()
|
||||
&& GetFileAttributes (win32_path_name) == INVALID_FILE_ATTRIBUTES)
|
||||
if (real_path->has_buggy_open () && !real_path->exists ())
|
||||
{
|
||||
debug_printf ("Buggy open detected.");
|
||||
close ();
|
||||
|
|
|
@ -98,7 +98,7 @@ fhandler_proc::get_proc_fhandler (const char *path)
|
|||
for (int i = 0; proc_listing[i]; i++)
|
||||
{
|
||||
if (path_prefix_p (proc_listing[i], path, strlen (proc_listing[i])))
|
||||
return proc_fhandlers[i];
|
||||
return proc_fhandlers[i];
|
||||
}
|
||||
|
||||
int pid = atoi (path);
|
||||
|
@ -108,10 +108,10 @@ fhandler_proc::get_proc_fhandler (const char *path)
|
|||
_pinfo *p = pids[i];
|
||||
|
||||
if (!proc_exists (p))
|
||||
continue;
|
||||
continue;
|
||||
|
||||
if (p->pid == pid)
|
||||
return FH_PROCESS;
|
||||
return FH_PROCESS;
|
||||
}
|
||||
|
||||
bool has_subdir = false;
|
||||
|
@ -178,8 +178,8 @@ fhandler_proc::fstat (struct __stat64 *buf, path_conv *pc)
|
|||
{
|
||||
path++;
|
||||
for (int i = 0; proc_listing[i]; i++)
|
||||
if (pathmatch (path, proc_listing[i]))
|
||||
{
|
||||
if (pathmatch (path, proc_listing[i]))
|
||||
{
|
||||
if (proc_fhandlers[i] != FH_PROC)
|
||||
buf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
|
||||
else
|
||||
|
@ -187,8 +187,8 @@ fhandler_proc::fstat (struct __stat64 *buf, path_conv *pc)
|
|||
buf->st_mode &= NO_X;
|
||||
buf->st_mode |= S_IFREG;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
set_errno (ENOENT);
|
||||
return -1;
|
||||
|
@ -202,26 +202,26 @@ fhandler_proc::readdir (DIR * dir)
|
|||
winpids pids;
|
||||
int found = 0;
|
||||
for (unsigned i = 0; i < pids.npids; i++)
|
||||
{
|
||||
_pinfo *p = pids[i];
|
||||
{
|
||||
_pinfo *p = pids[i];
|
||||
|
||||
if (!proc_exists (p))
|
||||
continue;
|
||||
if (!proc_exists (p))
|
||||
continue;
|
||||
|
||||
if (found == dir->__d_position - PROC_LINK_COUNT)
|
||||
{
|
||||
__small_sprintf (dir->__d_dirent->d_name, "%d", p->pid);
|
||||
dir->__d_position++;
|
||||
return dir->__d_dirent;
|
||||
}
|
||||
found++;
|
||||
}
|
||||
if (found == dir->__d_position - PROC_LINK_COUNT)
|
||||
{
|
||||
__small_sprintf (dir->__d_dirent->d_name, "%d", p->pid);
|
||||
dir->__d_position++;
|
||||
return dir->__d_dirent;
|
||||
}
|
||||
found++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strcpy (dir->__d_dirent->d_name, proc_listing[dir->__d_position++]);
|
||||
syscall_printf ("%p = readdir (%p) (%s)", &dir->__d_dirent, dir,
|
||||
dir->__d_dirent->d_name);
|
||||
dir->__d_dirent->d_name);
|
||||
return dir->__d_dirent;
|
||||
}
|
||||
|
||||
|
@ -241,65 +241,65 @@ fhandler_proc::open (path_conv *pc, int flags, mode_t mode)
|
|||
if (!*path)
|
||||
{
|
||||
if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
|
||||
{
|
||||
set_errno (EEXIST);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
{
|
||||
set_errno (EEXIST);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
else if (flags & O_WRONLY)
|
||||
{
|
||||
set_errno (EISDIR);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
{
|
||||
set_errno (EISDIR);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
flags |= O_DIROPEN;
|
||||
goto success;
|
||||
}
|
||||
{
|
||||
flags |= O_DIROPEN;
|
||||
goto success;
|
||||
}
|
||||
}
|
||||
|
||||
proc_file_no = -1;
|
||||
for (int i = 0; proc_listing[i]; i++)
|
||||
if (path_prefix_p (proc_listing[i], path + 1, strlen (proc_listing[i])))
|
||||
{
|
||||
proc_file_no = i;
|
||||
if (proc_fhandlers[i] != FH_PROC)
|
||||
{
|
||||
if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
|
||||
{
|
||||
set_errno (EEXIST);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
else if (flags & O_WRONLY)
|
||||
{
|
||||
set_errno (EISDIR);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
flags |= O_DIROPEN;
|
||||
goto success;
|
||||
}
|
||||
}
|
||||
proc_file_no = i;
|
||||
if (proc_fhandlers[i] != FH_PROC)
|
||||
{
|
||||
if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
|
||||
{
|
||||
set_errno (EEXIST);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
else if (flags & O_WRONLY)
|
||||
{
|
||||
set_errno (EISDIR);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
flags |= O_DIROPEN;
|
||||
goto success;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (proc_file_no == -1)
|
||||
{
|
||||
if (flags & O_CREAT)
|
||||
{
|
||||
set_errno (EROFS);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
{
|
||||
set_errno (EROFS);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
set_errno (ENOENT);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
{
|
||||
set_errno (ENOENT);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (flags & O_WRONLY)
|
||||
{
|
||||
|
@ -332,51 +332,51 @@ fhandler_proc::fill_filebuf ()
|
|||
{
|
||||
case PROC_VERSION:
|
||||
{
|
||||
if (!filebuf)
|
||||
{
|
||||
struct utsname uts_name;
|
||||
uname (&uts_name);
|
||||
bufalloc = strlen (uts_name.sysname) + 1 + strlen (uts_name.release) +
|
||||
1 + strlen (uts_name.version) + 2;
|
||||
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc);
|
||||
filesize = __small_sprintf (filebuf, "%s %s %s\n", uts_name.sysname,
|
||||
uts_name.release, uts_name.version);
|
||||
}
|
||||
break;
|
||||
if (!filebuf)
|
||||
{
|
||||
struct utsname uts_name;
|
||||
uname (&uts_name);
|
||||
bufalloc = strlen (uts_name.sysname) + 1 + strlen (uts_name.release) +
|
||||
1 + strlen (uts_name.version) + 2;
|
||||
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc);
|
||||
filesize = __small_sprintf (filebuf, "%s %s %s\n", uts_name.sysname,
|
||||
uts_name.release, uts_name.version);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PROC_UPTIME:
|
||||
{
|
||||
if (!filebuf)
|
||||
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 80);
|
||||
filesize = format_proc_uptime (filebuf, bufalloc);
|
||||
break;
|
||||
if (!filebuf)
|
||||
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 80);
|
||||
filesize = format_proc_uptime (filebuf, bufalloc);
|
||||
break;
|
||||
}
|
||||
case PROC_STAT:
|
||||
{
|
||||
if (!filebuf)
|
||||
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 2048);
|
||||
filesize = format_proc_stat (filebuf, bufalloc);
|
||||
break;
|
||||
if (!filebuf)
|
||||
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 2048);
|
||||
filesize = format_proc_stat (filebuf, bufalloc);
|
||||
break;
|
||||
}
|
||||
case PROC_LOADAVG:
|
||||
{
|
||||
/*
|
||||
* not really supported - Windows doesn't keep track of these values
|
||||
* Windows 95/98/me does have the KERNEL/CPUUsage performance counter
|
||||
* which is similar.
|
||||
*/
|
||||
if (!filebuf)
|
||||
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 16);
|
||||
filesize = __small_sprintf (filebuf, "%u.%02u %u.%02u %u.%02u\n",
|
||||
0, 0, 0, 0, 0, 0);
|
||||
break;
|
||||
/*
|
||||
* not really supported - Windows doesn't keep track of these values
|
||||
* Windows 95/98/me does have the KERNEL/CPUUsage performance counter
|
||||
* which is similar.
|
||||
*/
|
||||
if (!filebuf)
|
||||
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 16);
|
||||
filesize = __small_sprintf (filebuf, "%u.%02u %u.%02u %u.%02u\n",
|
||||
0, 0, 0, 0, 0, 0);
|
||||
break;
|
||||
}
|
||||
case PROC_MEMINFO:
|
||||
{
|
||||
if (!filebuf)
|
||||
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 2048);
|
||||
filesize = format_proc_meminfo (filebuf, bufalloc);
|
||||
break;
|
||||
if (!filebuf)
|
||||
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 2048);
|
||||
filesize = format_proc_meminfo (filebuf, bufalloc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -386,7 +386,7 @@ off_t
|
|||
format_proc_meminfo (char *destbuf, size_t maxsize)
|
||||
{
|
||||
unsigned long mem_total = 0UL, mem_free = 0UL, swap_total = 0UL,
|
||||
swap_free = 0UL;
|
||||
swap_free = 0UL;
|
||||
MEMORYSTATUS memory_status;
|
||||
GlobalMemoryStatus (&memory_status);
|
||||
mem_total = memory_status.dwTotalPhys;
|
||||
|
@ -394,22 +394,22 @@ format_proc_meminfo (char *destbuf, size_t maxsize)
|
|||
swap_total = memory_status.dwTotalPageFile;
|
||||
swap_free = memory_status.dwAvailPageFile;
|
||||
return __small_sprintf (destbuf, " total: used: free:\n"
|
||||
"Mem: %10lu %10lu %10lu\n"
|
||||
"Swap: %10lu %10lu %10lu\n"
|
||||
"MemTotal: %10lu kB\n"
|
||||
"MemFree: %10lu kB\n"
|
||||
"MemShared: 0 kB\n"
|
||||
"HighTotal: 0 kB\n"
|
||||
"HighFree: 0 kB\n"
|
||||
"LowTotal: %10lu kB\n"
|
||||
"LowFree: %10lu kB\n"
|
||||
"SwapTotal: %10lu kB\n"
|
||||
"SwapFree: %10lu kB\n",
|
||||
mem_total, mem_total - mem_free, mem_free,
|
||||
swap_total, swap_total - swap_free, swap_free,
|
||||
mem_total >> 10, mem_free >> 10,
|
||||
mem_total >> 10, mem_free >> 10,
|
||||
swap_total >> 10, swap_free >> 10);
|
||||
"Mem: %10lu %10lu %10lu\n"
|
||||
"Swap: %10lu %10lu %10lu\n"
|
||||
"MemTotal: %10lu kB\n"
|
||||
"MemFree: %10lu kB\n"
|
||||
"MemShared: 0 kB\n"
|
||||
"HighTotal: 0 kB\n"
|
||||
"HighFree: 0 kB\n"
|
||||
"LowTotal: %10lu kB\n"
|
||||
"LowFree: %10lu kB\n"
|
||||
"SwapTotal: %10lu kB\n"
|
||||
"SwapFree: %10lu kB\n",
|
||||
mem_total, mem_total - mem_free, mem_free,
|
||||
swap_total, swap_total - swap_free, swap_free,
|
||||
mem_total >> 10, mem_free >> 10,
|
||||
mem_total >> 10, mem_free >> 10,
|
||||
swap_total >> 10, swap_free >> 10);
|
||||
}
|
||||
|
||||
static
|
||||
|
@ -435,13 +435,13 @@ format_proc_uptime (char *destbuf, size_t maxsize)
|
|||
{
|
||||
idle_time = spt.IdleTime.QuadPart / 100000ULL;
|
||||
uptime = (spt.InterruptTime.QuadPart + spt.KernelTime.QuadPart +
|
||||
spt.IdleTime.QuadPart + spt.UserTime.QuadPart +
|
||||
spt.DpcTime.QuadPart) / 100000ULL;
|
||||
spt.IdleTime.QuadPart + spt.UserTime.QuadPart +
|
||||
spt.DpcTime.QuadPart) / 100000ULL;
|
||||
}
|
||||
|
||||
return __small_sprintf (destbuf, "%U.%02u %U.%02u\n",
|
||||
uptime / 100, long (uptime % 100),
|
||||
idle_time / 100, long (idle_time % 100));
|
||||
uptime / 100, long (uptime % 100),
|
||||
idle_time / 100, long (idle_time % 100));
|
||||
}
|
||||
|
||||
static
|
||||
|
@ -450,7 +450,7 @@ format_proc_stat (char *destbuf, size_t maxsize)
|
|||
{
|
||||
unsigned long long user_time = 0ULL, kernel_time = 0ULL, idle_time = 0ULL;
|
||||
unsigned long pages_in = 0UL, pages_out = 0UL, interrupt_count = 0UL,
|
||||
context_switches = 0UL, swap_in = 0UL, swap_out = 0UL;
|
||||
context_switches = 0UL, swap_in = 0UL, swap_out = 0UL;
|
||||
time_t boot_time = 0;
|
||||
|
||||
if (wincap.is_winnt ())
|
||||
|
@ -460,24 +460,24 @@ format_proc_stat (char *destbuf, size_t maxsize)
|
|||
SYSTEM_PERFORMANCE_INFORMATION spi;
|
||||
SYSTEM_TIME_OF_DAY_INFORMATION stodi;
|
||||
ret = ZwQuerySystemInformation (SystemProcessorTimes,
|
||||
(PVOID) &spt,
|
||||
sizeof spt, NULL);
|
||||
(PVOID) &spt,
|
||||
sizeof spt, NULL);
|
||||
if (ret == STATUS_SUCCESS)
|
||||
ret = ZwQuerySystemInformation (SystemPerformanceInformation,
|
||||
(PVOID) &spi,
|
||||
sizeof spi, NULL);
|
||||
ret = ZwQuerySystemInformation (SystemPerformanceInformation,
|
||||
(PVOID) &spi,
|
||||
sizeof spi, NULL);
|
||||
if (ret == STATUS_SUCCESS)
|
||||
ret = ZwQuerySystemInformation (SystemTimeOfDayInformation,
|
||||
(PVOID) &stodi,
|
||||
sizeof stodi, NULL);
|
||||
ret = ZwQuerySystemInformation (SystemTimeOfDayInformation,
|
||||
(PVOID) &stodi,
|
||||
sizeof stodi, NULL);
|
||||
if (ret != STATUS_SUCCESS)
|
||||
{
|
||||
__seterrno_from_win_error (RtlNtStatusToDosError (ret));
|
||||
debug_printf("NtQuerySystemInformation: ret = %d, "
|
||||
"Dos(ret) = %d",
|
||||
ret, RtlNtStatusToDosError (ret));
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
__seterrno_from_win_error (RtlNtStatusToDosError (ret));
|
||||
debug_printf("NtQuerySystemInformation: ret = %d, "
|
||||
"Dos(ret) = %d",
|
||||
ret, RtlNtStatusToDosError (ret));
|
||||
return 0;
|
||||
}
|
||||
kernel_time = (spt.KernelTime.QuadPart + spt.InterruptTime.QuadPart + spt.DpcTime.QuadPart) / 100000ULL;
|
||||
user_time = spt.UserTime.QuadPart / 100000ULL;
|
||||
idle_time = spt.IdleTime.QuadPart / 100000ULL;
|
||||
|
@ -505,16 +505,16 @@ format_proc_stat (char *destbuf, size_t maxsize)
|
|||
* }
|
||||
*/
|
||||
return __small_sprintf (destbuf, "cpu %U %U %U %U\n"
|
||||
"page %u %u\n"
|
||||
"swap %u %u\n"
|
||||
"intr %u\n"
|
||||
"ctxt %u\n"
|
||||
"btime %u\n",
|
||||
user_time, 0ULL,
|
||||
kernel_time, idle_time,
|
||||
pages_in, pages_out,
|
||||
swap_in, swap_out,
|
||||
interrupt_count,
|
||||
context_switches,
|
||||
boot_time);
|
||||
"page %u %u\n"
|
||||
"swap %u %u\n"
|
||||
"intr %u\n"
|
||||
"ctxt %u\n"
|
||||
"btime %u\n",
|
||||
user_time, 0ULL,
|
||||
kernel_time, idle_time,
|
||||
pages_in, pages_out,
|
||||
swap_in, swap_out,
|
||||
interrupt_count,
|
||||
context_switches,
|
||||
boot_time);
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ static off_t format_process_status (_pinfo *p, char *destbuf, size_t maxsize);
|
|||
static off_t format_process_statm (_pinfo *p, char *destbuf, size_t maxsize);
|
||||
static int get_process_state (DWORD dwProcessId);
|
||||
static bool get_mem_values(DWORD dwProcessId, unsigned long *vmsize, unsigned long *vmrss, unsigned long *vmtext,
|
||||
unsigned long *vmdata, unsigned long *vmlib, unsigned long *vmshare);
|
||||
unsigned long *vmdata, unsigned long *vmlib, unsigned long *vmshare);
|
||||
|
||||
/* Returns 0 if path doesn't exist, >0 if path is a directory,
|
||||
* <0 if path is a file.
|
||||
|
@ -110,10 +110,10 @@ fhandler_process::fstat (struct __stat64 *buf, path_conv *pc)
|
|||
p = pids[i];
|
||||
|
||||
if (!proc_exists (p))
|
||||
continue;
|
||||
continue;
|
||||
|
||||
if (p->pid == pid)
|
||||
goto found;
|
||||
goto found;
|
||||
}
|
||||
set_errno(ENOENT);
|
||||
return -1;
|
||||
|
@ -152,7 +152,7 @@ fhandler_process::readdir (DIR * dir)
|
|||
return NULL;
|
||||
strcpy (dir->__d_dirent->d_name, process_listing[dir->__d_position++]);
|
||||
syscall_printf ("%p = readdir (%p) (%s)", &dir->__d_dirent, dir,
|
||||
dir->__d_dirent->d_name);
|
||||
dir->__d_dirent->d_name);
|
||||
return dir->__d_dirent;
|
||||
}
|
||||
|
||||
|
@ -176,45 +176,45 @@ fhandler_process::open (path_conv *pc, int flags, mode_t mode)
|
|||
if (*path == 0)
|
||||
{
|
||||
if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
|
||||
{
|
||||
set_errno (EEXIST);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
{
|
||||
set_errno (EEXIST);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
else if (flags & O_WRONLY)
|
||||
{
|
||||
set_errno (EISDIR);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
{
|
||||
set_errno (EISDIR);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
flags |= O_DIROPEN;
|
||||
goto success;
|
||||
}
|
||||
{
|
||||
flags |= O_DIROPEN;
|
||||
goto success;
|
||||
}
|
||||
}
|
||||
|
||||
process_file_no = -1;
|
||||
for (int i = 0; process_listing[i]; i++)
|
||||
{
|
||||
if (path_prefix_p
|
||||
(process_listing[i], path + 1, strlen (process_listing[i])))
|
||||
process_file_no = i;
|
||||
(process_listing[i], path + 1, strlen (process_listing[i])))
|
||||
process_file_no = i;
|
||||
}
|
||||
if (process_file_no == -1)
|
||||
{
|
||||
if (flags & O_CREAT)
|
||||
{
|
||||
set_errno (EROFS);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
{
|
||||
set_errno (EROFS);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
set_errno (ENOENT);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
{
|
||||
set_errno (ENOENT);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (flags & O_WRONLY)
|
||||
{
|
||||
|
@ -227,10 +227,10 @@ fhandler_process::open (path_conv *pc, int flags, mode_t mode)
|
|||
p = pids[i];
|
||||
|
||||
if (!proc_exists (p))
|
||||
continue;
|
||||
continue;
|
||||
|
||||
if (p->pid == pid)
|
||||
goto found;
|
||||
goto found;
|
||||
}
|
||||
set_errno (ENOENT);
|
||||
res = 0;
|
||||
|
@ -262,7 +262,7 @@ fhandler_process::fill_filebuf ()
|
|||
if (!proc_exists (saved_p) || saved_p->pid != saved_pid)
|
||||
{
|
||||
if (filebuf)
|
||||
cfree(filebuf);
|
||||
cfree(filebuf);
|
||||
filesize = 0; bufalloc = (size_t) -1;
|
||||
}
|
||||
switch (fileid)
|
||||
|
@ -274,95 +274,95 @@ fhandler_process::fill_filebuf ()
|
|||
case PROCESS_CTTY:
|
||||
case PROCESS_PPID:
|
||||
{
|
||||
if (!filebuf)
|
||||
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 40);
|
||||
int num;
|
||||
switch (fileid)
|
||||
{
|
||||
case PROCESS_PPID:
|
||||
num = saved_p->ppid;
|
||||
break;
|
||||
case PROCESS_UID:
|
||||
num = saved_p->uid;
|
||||
break;
|
||||
case PROCESS_PGID:
|
||||
num = saved_p->pgid;
|
||||
break;
|
||||
case PROCESS_SID:
|
||||
num = saved_p->sid;
|
||||
break;
|
||||
case PROCESS_GID:
|
||||
num = saved_p->gid;
|
||||
break;
|
||||
case PROCESS_CTTY:
|
||||
num = saved_p->ctty;
|
||||
break;
|
||||
default: // what's this here for?
|
||||
num = 0;
|
||||
break;
|
||||
}
|
||||
__small_sprintf (filebuf, "%d\n", num);
|
||||
filesize = strlen (filebuf);
|
||||
break;
|
||||
if (!filebuf)
|
||||
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 40);
|
||||
int num;
|
||||
switch (fileid)
|
||||
{
|
||||
case PROCESS_PPID:
|
||||
num = saved_p->ppid;
|
||||
break;
|
||||
case PROCESS_UID:
|
||||
num = saved_p->uid;
|
||||
break;
|
||||
case PROCESS_PGID:
|
||||
num = saved_p->pgid;
|
||||
break;
|
||||
case PROCESS_SID:
|
||||
num = saved_p->sid;
|
||||
break;
|
||||
case PROCESS_GID:
|
||||
num = saved_p->gid;
|
||||
break;
|
||||
case PROCESS_CTTY:
|
||||
num = saved_p->ctty;
|
||||
break;
|
||||
default: // what's this here for?
|
||||
num = 0;
|
||||
break;
|
||||
}
|
||||
__small_sprintf (filebuf, "%d\n", num);
|
||||
filesize = strlen (filebuf);
|
||||
break;
|
||||
}
|
||||
case PROCESS_EXENAME:
|
||||
{
|
||||
if (!filebuf)
|
||||
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = MAX_PATH);
|
||||
if (saved_p->process_state & (PID_ZOMBIE | PID_EXITED))
|
||||
strcpy (filebuf, "<defunct>");
|
||||
else
|
||||
{
|
||||
mount_table->conv_to_posix_path (saved_p->progname, filebuf, 1);
|
||||
int len = strlen (filebuf);
|
||||
if (len > 4)
|
||||
{
|
||||
char *s = filebuf + len - 4;
|
||||
if (strcasecmp (s, ".exe") == 0)
|
||||
*s = 0;
|
||||
}
|
||||
}
|
||||
filesize = strlen (filebuf);
|
||||
break;
|
||||
if (!filebuf)
|
||||
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = MAX_PATH);
|
||||
if (saved_p->process_state & (PID_ZOMBIE | PID_EXITED))
|
||||
strcpy (filebuf, "<defunct>");
|
||||
else
|
||||
{
|
||||
mount_table->conv_to_posix_path (saved_p->progname, filebuf, 1);
|
||||
int len = strlen (filebuf);
|
||||
if (len > 4)
|
||||
{
|
||||
char *s = filebuf + len - 4;
|
||||
if (strcasecmp (s, ".exe") == 0)
|
||||
*s = 0;
|
||||
}
|
||||
}
|
||||
filesize = strlen (filebuf);
|
||||
break;
|
||||
}
|
||||
case PROCESS_WINPID:
|
||||
{
|
||||
if (!filebuf)
|
||||
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 40);
|
||||
__small_sprintf (filebuf, "%d\n", saved_p->dwProcessId);
|
||||
filesize = strlen (filebuf);
|
||||
break;
|
||||
if (!filebuf)
|
||||
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 40);
|
||||
__small_sprintf (filebuf, "%d\n", saved_p->dwProcessId);
|
||||
filesize = strlen (filebuf);
|
||||
break;
|
||||
}
|
||||
case PROCESS_WINEXENAME:
|
||||
{
|
||||
int len = strlen (saved_p->progname);
|
||||
if (!filebuf)
|
||||
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = (len + 2));
|
||||
strcpy (filebuf, saved_p->progname);
|
||||
filebuf[len] = '\n';
|
||||
filesize = len + 1;
|
||||
break;
|
||||
int len = strlen (saved_p->progname);
|
||||
if (!filebuf)
|
||||
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = (len + 2));
|
||||
strcpy (filebuf, saved_p->progname);
|
||||
filebuf[len] = '\n';
|
||||
filesize = len + 1;
|
||||
break;
|
||||
}
|
||||
case PROCESS_STATUS:
|
||||
{
|
||||
if (!filebuf)
|
||||
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 2048);
|
||||
filesize = format_process_status (saved_p, filebuf, bufalloc);
|
||||
break;
|
||||
if (!filebuf)
|
||||
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 2048);
|
||||
filesize = format_process_status (saved_p, filebuf, bufalloc);
|
||||
break;
|
||||
}
|
||||
case PROCESS_STAT:
|
||||
{
|
||||
if (!filebuf)
|
||||
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 2048);
|
||||
filesize = format_process_stat (saved_p, filebuf, bufalloc);
|
||||
break;
|
||||
if (!filebuf)
|
||||
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 2048);
|
||||
filesize = format_process_stat (saved_p, filebuf, bufalloc);
|
||||
break;
|
||||
}
|
||||
case PROCESS_STATM:
|
||||
{
|
||||
if (!filebuf)
|
||||
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 2048);
|
||||
filesize = format_process_statm (saved_p, filebuf, bufalloc);
|
||||
break;
|
||||
if (!filebuf)
|
||||
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 2048);
|
||||
filesize = format_process_statm (saved_p, filebuf, bufalloc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -374,9 +374,9 @@ format_process_stat (_pinfo *p, char *destbuf, size_t maxsize)
|
|||
char cmd[MAX_PATH];
|
||||
int state = 'R';
|
||||
unsigned long fault_count = 0UL,
|
||||
utime = 0UL, stime = 0UL,
|
||||
start_time = 0UL,
|
||||
vmsize = 0UL, vmrss = 0UL, vmmaxrss = 0UL;
|
||||
utime = 0UL, stime = 0UL,
|
||||
start_time = 0UL,
|
||||
vmsize = 0UL, vmrss = 0UL, vmmaxrss = 0UL;
|
||||
int priority = 0;
|
||||
if (p->process_state & (PID_ZOMBIE | PID_EXITED))
|
||||
strcpy (cmd, "<defunct");
|
||||
|
@ -385,14 +385,14 @@ format_process_stat (_pinfo *p, char *destbuf, size_t maxsize)
|
|||
strcpy(cmd, p->progname);
|
||||
char *last_slash = strrchr (cmd, '\\');
|
||||
if (last_slash != NULL)
|
||||
strcpy (cmd, last_slash + 1);
|
||||
strcpy (cmd, last_slash + 1);
|
||||
int len = strlen (cmd);
|
||||
if (len > 4)
|
||||
{
|
||||
char *s = cmd + len - 4;
|
||||
if (strcasecmp (s, ".exe") == 0)
|
||||
*s = 0;
|
||||
}
|
||||
{
|
||||
char *s = cmd + len - 4;
|
||||
if (strcasecmp (s, ".exe") == 0)
|
||||
*s = 0;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Note: under Windows, a _process_ is always running - it's only _threads_
|
||||
|
@ -415,71 +415,71 @@ format_process_stat (_pinfo *p, char *destbuf, size_t maxsize)
|
|||
SYSTEM_TIME_OF_DAY_INFORMATION stodi;
|
||||
SYSTEM_PROCESSOR_TIMES spt;
|
||||
hProcess = OpenProcess (PROCESS_VM_READ | PROCESS_QUERY_INFORMATION,
|
||||
FALSE, p->dwProcessId);
|
||||
FALSE, p->dwProcessId);
|
||||
if (hProcess != NULL)
|
||||
{
|
||||
ret = ZwQueryInformationProcess (hProcess,
|
||||
ProcessVmCounters,
|
||||
(PVOID) &vmc,
|
||||
sizeof vmc, NULL);
|
||||
if (ret == STATUS_SUCCESS)
|
||||
ret = ZwQueryInformationProcess (hProcess,
|
||||
ProcessTimes,
|
||||
(PVOID) &put,
|
||||
sizeof put, NULL);
|
||||
if (ret == STATUS_SUCCESS)
|
||||
ret = ZwQueryInformationProcess (hProcess,
|
||||
ProcessBasicInformation,
|
||||
(PVOID) &pbi,
|
||||
sizeof pbi, NULL);
|
||||
if (ret == STATUS_SUCCESS)
|
||||
ret = ZwQueryInformationProcess (hProcess,
|
||||
ProcessQuotaLimits,
|
||||
(PVOID) &ql,
|
||||
sizeof ql, NULL);
|
||||
CloseHandle (hProcess);
|
||||
}
|
||||
{
|
||||
ret = ZwQueryInformationProcess (hProcess,
|
||||
ProcessVmCounters,
|
||||
(PVOID) &vmc,
|
||||
sizeof vmc, NULL);
|
||||
if (ret == STATUS_SUCCESS)
|
||||
ret = ZwQueryInformationProcess (hProcess,
|
||||
ProcessTimes,
|
||||
(PVOID) &put,
|
||||
sizeof put, NULL);
|
||||
if (ret == STATUS_SUCCESS)
|
||||
ret = ZwQueryInformationProcess (hProcess,
|
||||
ProcessBasicInformation,
|
||||
(PVOID) &pbi,
|
||||
sizeof pbi, NULL);
|
||||
if (ret == STATUS_SUCCESS)
|
||||
ret = ZwQueryInformationProcess (hProcess,
|
||||
ProcessQuotaLimits,
|
||||
(PVOID) &ql,
|
||||
sizeof ql, NULL);
|
||||
CloseHandle (hProcess);
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD error = GetLastError ();
|
||||
__seterrno_from_win_error (error);
|
||||
debug_printf("OpenProcess: ret = %d",
|
||||
error);
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
DWORD error = GetLastError ();
|
||||
__seterrno_from_win_error (error);
|
||||
debug_printf("OpenProcess: ret = %d",
|
||||
error);
|
||||
return 0;
|
||||
}
|
||||
if (ret == STATUS_SUCCESS)
|
||||
ret = ZwQuerySystemInformation (SystemTimeOfDayInformation,
|
||||
(PVOID) &stodi,
|
||||
sizeof stodi, NULL);
|
||||
ret = ZwQuerySystemInformation (SystemTimeOfDayInformation,
|
||||
(PVOID) &stodi,
|
||||
sizeof stodi, NULL);
|
||||
if (ret == STATUS_SUCCESS)
|
||||
ret = ZwQuerySystemInformation (SystemProcessorTimes,
|
||||
(PVOID) &spt,
|
||||
sizeof spt, NULL);
|
||||
ret = ZwQuerySystemInformation (SystemProcessorTimes,
|
||||
(PVOID) &spt,
|
||||
sizeof spt, NULL);
|
||||
if (ret != STATUS_SUCCESS)
|
||||
{
|
||||
__seterrno_from_win_error (RtlNtStatusToDosError (ret));
|
||||
debug_printf("NtQueryInformationProcess: ret = %d, "
|
||||
"Dos(ret) = %d",
|
||||
ret, RtlNtStatusToDosError (ret));
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
__seterrno_from_win_error (RtlNtStatusToDosError (ret));
|
||||
debug_printf("NtQueryInformationProcess: ret = %d, "
|
||||
"Dos(ret) = %d",
|
||||
ret, RtlNtStatusToDosError (ret));
|
||||
return 0;
|
||||
}
|
||||
fault_count = vmc.PageFaultCount;
|
||||
utime = put.UserTime.QuadPart / 100000ULL;
|
||||
stime = put.KernelTime.QuadPart / 100000ULL;
|
||||
if (stodi.CurrentTime.QuadPart > put.CreateTime.QuadPart)
|
||||
start_time = (spt.InterruptTime.QuadPart + spt.KernelTime.QuadPart +
|
||||
spt.IdleTime.QuadPart + spt.UserTime.QuadPart +
|
||||
spt.DpcTime.QuadPart - stodi.CurrentTime.QuadPart +
|
||||
put.CreateTime.QuadPart) / 100000ULL;
|
||||
start_time = (spt.InterruptTime.QuadPart + spt.KernelTime.QuadPart +
|
||||
spt.IdleTime.QuadPart + spt.UserTime.QuadPart +
|
||||
spt.DpcTime.QuadPart - stodi.CurrentTime.QuadPart +
|
||||
put.CreateTime.QuadPart) / 100000ULL;
|
||||
else
|
||||
/*
|
||||
* sometimes stodi.CurrentTime is a bit behind
|
||||
* Note: some older versions of procps are broken and can't cope
|
||||
* with process start times > time(NULL).
|
||||
*/
|
||||
start_time = (spt.InterruptTime.QuadPart + spt.KernelTime.QuadPart +
|
||||
spt.IdleTime.QuadPart + spt.UserTime.QuadPart +
|
||||
spt.DpcTime.QuadPart) / 100000ULL;
|
||||
/*
|
||||
* sometimes stodi.CurrentTime is a bit behind
|
||||
* Note: some older versions of procps are broken and can't cope
|
||||
* with process start times > time(NULL).
|
||||
*/
|
||||
start_time = (spt.InterruptTime.QuadPart + spt.KernelTime.QuadPart +
|
||||
spt.IdleTime.QuadPart + spt.UserTime.QuadPart +
|
||||
spt.DpcTime.QuadPart) / 100000ULL;
|
||||
priority = pbi.BasePriority;
|
||||
unsigned page_size = getpagesize();
|
||||
vmsize = vmc.VirtualSize;
|
||||
|
@ -491,20 +491,20 @@ format_process_stat (_pinfo *p, char *destbuf, size_t maxsize)
|
|||
start_time = (GetTickCount() / 1000 - time(NULL) + p->start_time) * 100;
|
||||
}
|
||||
return __small_sprintf (destbuf, "%d (%s) %c "
|
||||
"%d %d %d %d %d "
|
||||
"%lu %lu %lu %lu %lu %lu %lu "
|
||||
"%ld %ld %ld %ld %ld %ld "
|
||||
"%lu %lu "
|
||||
"%ld "
|
||||
"%lu",
|
||||
p->pid, cmd,
|
||||
state,
|
||||
p->ppid, p->pgid, p->sid, p->ctty, -1,
|
||||
0, fault_count, fault_count, 0, 0, utime, stime,
|
||||
utime, stime, priority, 0, 0, 0,
|
||||
start_time, vmsize,
|
||||
vmrss, vmmaxrss
|
||||
);
|
||||
"%d %d %d %d %d "
|
||||
"%lu %lu %lu %lu %lu %lu %lu "
|
||||
"%ld %ld %ld %ld %ld %ld "
|
||||
"%lu %lu "
|
||||
"%ld "
|
||||
"%lu",
|
||||
p->pid, cmd,
|
||||
state,
|
||||
p->ppid, p->pgid, p->sid, p->ctty, -1,
|
||||
0, fault_count, fault_count, 0, 0, utime, stime,
|
||||
utime, stime, priority, 0, 0, 0,
|
||||
start_time, vmsize,
|
||||
vmrss, vmmaxrss
|
||||
);
|
||||
}
|
||||
|
||||
static
|
||||
|
@ -515,7 +515,7 @@ format_process_status (_pinfo *p, char *destbuf, size_t maxsize)
|
|||
int state = 'R';
|
||||
const char *state_str = "unknown";
|
||||
unsigned long vmsize = 0UL, vmrss = 0UL, vmdata = 0UL, vmlib = 0UL, vmtext = 0UL,
|
||||
vmshare = 0UL;
|
||||
vmshare = 0UL;
|
||||
if (p->process_state & (PID_ZOMBIE | PID_EXITED))
|
||||
strcpy (cmd, "<defunct>");
|
||||
else
|
||||
|
@ -523,14 +523,14 @@ format_process_status (_pinfo *p, char *destbuf, size_t maxsize)
|
|||
strcpy(cmd, p->progname);
|
||||
char *last_slash = strrchr (cmd, '\\');
|
||||
if (last_slash != NULL)
|
||||
strcpy (cmd, last_slash + 1);
|
||||
strcpy (cmd, last_slash + 1);
|
||||
int len = strlen (cmd);
|
||||
if (len > 4)
|
||||
{
|
||||
char *s = cmd + len - 4;
|
||||
if (strcasecmp (s, ".exe") == 0)
|
||||
*s = 0;
|
||||
}
|
||||
{
|
||||
char *s = cmd + len - 4;
|
||||
if (strcasecmp (s, ".exe") == 0)
|
||||
*s = 0;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Note: under Windows, a _process_ is always running - it's only _threads_
|
||||
|
@ -564,38 +564,38 @@ format_process_status (_pinfo *p, char *destbuf, size_t maxsize)
|
|||
if (wincap.is_winnt ())
|
||||
{
|
||||
if (!get_mem_values (p->dwProcessId, &vmsize, &vmrss, &vmtext, &vmdata, &vmlib, &vmshare))
|
||||
return 0;
|
||||
return 0;
|
||||
unsigned page_size = getpagesize();
|
||||
vmsize *= page_size; vmrss *= page_size; vmdata *= page_size;
|
||||
vmtext *= page_size; vmlib *= page_size;
|
||||
}
|
||||
return __small_sprintf (destbuf, "Name: %s\n"
|
||||
"State: %c (%s)\n"
|
||||
"Tgid: %d\n"
|
||||
"Pid: %d\n"
|
||||
"PPid: %d\n"
|
||||
"Uid: %d %d %d %d\n"
|
||||
"Gid: %d %d %d %d\n"
|
||||
"VmSize: %8d kB\n"
|
||||
"VmLck: %8d kB\n"
|
||||
"VmRSS: %8d kB\n"
|
||||
"VmData: %8d kB\n"
|
||||
"VmStk: %8d kB\n"
|
||||
"VmExe: %8d kB\n"
|
||||
"VmLib: %8d kB\n"
|
||||
"SigPnd: %016x\n"
|
||||
"SigBlk: %016x\n"
|
||||
"SigIgn: %016x\n",
|
||||
cmd,
|
||||
state, state_str,
|
||||
p->pgid,
|
||||
p->pid,
|
||||
p->ppid,
|
||||
p->uid, cygheap->user.real_uid, cygheap->user.real_uid, p->uid,
|
||||
p->gid, cygheap->user.real_gid, cygheap->user.real_gid, p->gid,
|
||||
vmsize >> 10, 0, vmrss >> 10, vmdata >> 10, 0, vmtext >> 10, vmlib >> 10,
|
||||
0, 0, p->getsigmask ()
|
||||
);
|
||||
"State: %c (%s)\n"
|
||||
"Tgid: %d\n"
|
||||
"Pid: %d\n"
|
||||
"PPid: %d\n"
|
||||
"Uid: %d %d %d %d\n"
|
||||
"Gid: %d %d %d %d\n"
|
||||
"VmSize: %8d kB\n"
|
||||
"VmLck: %8d kB\n"
|
||||
"VmRSS: %8d kB\n"
|
||||
"VmData: %8d kB\n"
|
||||
"VmStk: %8d kB\n"
|
||||
"VmExe: %8d kB\n"
|
||||
"VmLib: %8d kB\n"
|
||||
"SigPnd: %016x\n"
|
||||
"SigBlk: %016x\n"
|
||||
"SigIgn: %016x\n",
|
||||
cmd,
|
||||
state, state_str,
|
||||
p->pgid,
|
||||
p->pid,
|
||||
p->ppid,
|
||||
p->uid, cygheap->user.real_uid, cygheap->user.real_uid, p->uid,
|
||||
p->gid, cygheap->user.real_gid, cygheap->user.real_gid, p->gid,
|
||||
vmsize >> 10, 0, vmrss >> 10, vmdata >> 10, 0, vmtext >> 10, vmlib >> 10,
|
||||
0, 0, p->getsigmask ()
|
||||
);
|
||||
}
|
||||
|
||||
static
|
||||
|
@ -603,15 +603,15 @@ off_t
|
|||
format_process_statm (_pinfo *p, char *destbuf, size_t maxsize)
|
||||
{
|
||||
unsigned long vmsize = 0UL, vmrss = 0UL, vmtext = 0UL, vmdata = 0UL, vmlib = 0UL,
|
||||
vmshare = 0UL;
|
||||
vmshare = 0UL;
|
||||
if (wincap.is_winnt ())
|
||||
{
|
||||
if (!get_mem_values (p->dwProcessId, &vmsize, &vmrss, &vmtext, &vmdata, &vmlib, &vmshare))
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
return __small_sprintf (destbuf, "%ld %ld %ld %ld %ld %ld %ld",
|
||||
vmsize, vmrss, vmshare, vmtext, vmlib, vmdata, 0
|
||||
);
|
||||
vmsize, vmrss, vmshare, vmtext, vmlib, vmdata, 0
|
||||
);
|
||||
}
|
||||
|
||||
static
|
||||
|
@ -629,15 +629,15 @@ get_process_state (DWORD dwProcessId)
|
|||
PULONG p = new ULONG[n];
|
||||
int state =' ';
|
||||
while (STATUS_INFO_LENGTH_MISMATCH ==
|
||||
(ret = ZwQuerySystemInformation (SystemProcessesAndThreadsInformation,
|
||||
(PVOID) p,
|
||||
n * sizeof *p, NULL)))
|
||||
(ret = ZwQuerySystemInformation (SystemProcessesAndThreadsInformation,
|
||||
(PVOID) p,
|
||||
n * sizeof *p, NULL)))
|
||||
delete [] p, p = new ULONG[n *= 2];
|
||||
if (ret != STATUS_SUCCESS)
|
||||
{
|
||||
debug_printf("NtQuerySystemInformation: ret = %d, "
|
||||
"Dos(ret) = %d",
|
||||
ret, RtlNtStatusToDosError (ret));
|
||||
"Dos(ret) = %d",
|
||||
ret, RtlNtStatusToDosError (ret));
|
||||
goto out;
|
||||
}
|
||||
state = 'Z';
|
||||
|
@ -645,36 +645,36 @@ get_process_state (DWORD dwProcessId)
|
|||
for (;;)
|
||||
{
|
||||
if (sp->ProcessId == dwProcessId)
|
||||
{
|
||||
SYSTEM_THREADS *st;
|
||||
if (wincap.has_process_io_counters ())
|
||||
/*
|
||||
* Windows 2000 and XP have an extra member in SYSTEM_PROCESSES
|
||||
* which means the offset of the first SYSTEM_THREADS entry is
|
||||
* different on these operating systems compared to NT 4.
|
||||
*/
|
||||
st = &sp->Threads[0];
|
||||
else
|
||||
/*
|
||||
* 136 is the offset of the first SYSTEM_THREADS entry on
|
||||
* Windows NT 4.
|
||||
*/
|
||||
st = (SYSTEM_THREADS *) ((char *) sp + 136);
|
||||
state = 'S';
|
||||
for (unsigned i = 0; i < sp->ThreadCount; i++)
|
||||
{
|
||||
if (st->State == StateRunning ||
|
||||
st->State == StateReady)
|
||||
{
|
||||
state = 'R';
|
||||
goto out;
|
||||
}
|
||||
st++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
{
|
||||
SYSTEM_THREADS *st;
|
||||
if (wincap.has_process_io_counters ())
|
||||
/*
|
||||
* Windows 2000 and XP have an extra member in SYSTEM_PROCESSES
|
||||
* which means the offset of the first SYSTEM_THREADS entry is
|
||||
* different on these operating systems compared to NT 4.
|
||||
*/
|
||||
st = &sp->Threads[0];
|
||||
else
|
||||
/*
|
||||
* 136 is the offset of the first SYSTEM_THREADS entry on
|
||||
* Windows NT 4.
|
||||
*/
|
||||
st = (SYSTEM_THREADS *) ((char *) sp + 136);
|
||||
state = 'S';
|
||||
for (unsigned i = 0; i < sp->ThreadCount; i++)
|
||||
{
|
||||
if (st->State == StateRunning ||
|
||||
st->State == StateReady)
|
||||
{
|
||||
state = 'R';
|
||||
goto out;
|
||||
}
|
||||
st++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!sp->NextEntryDelta)
|
||||
break;
|
||||
break;
|
||||
sp = (SYSTEM_PROCESSES *) ((char *) sp + sp->NextEntryDelta);
|
||||
}
|
||||
out:
|
||||
|
@ -685,7 +685,7 @@ out:
|
|||
static
|
||||
bool
|
||||
get_mem_values(DWORD dwProcessId, unsigned long *vmsize, unsigned long *vmrss, unsigned long *vmtext,
|
||||
unsigned long *vmdata, unsigned long *vmlib, unsigned long *vmshare)
|
||||
unsigned long *vmdata, unsigned long *vmlib, unsigned long *vmshare)
|
||||
{
|
||||
bool res = true;
|
||||
NTSTATUS ret;
|
||||
|
@ -696,27 +696,27 @@ get_mem_values(DWORD dwProcessId, unsigned long *vmsize, unsigned long *vmrss, u
|
|||
PULONG p = new ULONG[n];
|
||||
unsigned page_size = getpagesize();
|
||||
hProcess = OpenProcess (PROCESS_QUERY_INFORMATION,
|
||||
FALSE, dwProcessId);
|
||||
FALSE, dwProcessId);
|
||||
if (hProcess == NULL)
|
||||
{
|
||||
DWORD error = GetLastError();
|
||||
__seterrno_from_win_error (error);
|
||||
debug_printf("OpenProcess: ret = %d",
|
||||
error);
|
||||
error);
|
||||
return false;
|
||||
}
|
||||
while ((ret = ZwQueryVirtualMemory (hProcess, 0,
|
||||
MemoryWorkingSetList,
|
||||
(PVOID) p,
|
||||
n * sizeof *p, &length)),
|
||||
(ret == STATUS_SUCCESS || ret == STATUS_INFO_LENGTH_MISMATCH) &&
|
||||
length >= n * sizeof *p)
|
||||
MemoryWorkingSetList,
|
||||
(PVOID) p,
|
||||
n * sizeof *p, &length)),
|
||||
(ret == STATUS_SUCCESS || ret == STATUS_INFO_LENGTH_MISMATCH) &&
|
||||
length >= n * sizeof *p)
|
||||
delete [] p, p = new ULONG[n *= 2];
|
||||
if (ret != STATUS_SUCCESS)
|
||||
{
|
||||
debug_printf("NtQueryVirtualMemory: ret = %d, "
|
||||
"Dos(ret) = %d",
|
||||
ret, RtlNtStatusToDosError (ret));
|
||||
"Dos(ret) = %d",
|
||||
ret, RtlNtStatusToDosError (ret));
|
||||
res = false;
|
||||
goto out;
|
||||
}
|
||||
|
@ -726,23 +726,23 @@ get_mem_values(DWORD dwProcessId, unsigned long *vmsize, unsigned long *vmrss, u
|
|||
++*vmrss;
|
||||
unsigned flags = mwsl->WorkingSetList[i] & 0x0FFF;
|
||||
if (flags & (WSLE_PAGE_EXECUTE | WSLE_PAGE_SHAREABLE) == (WSLE_PAGE_EXECUTE | WSLE_PAGE_SHAREABLE))
|
||||
++*vmlib;
|
||||
++*vmlib;
|
||||
else if (flags & WSLE_PAGE_SHAREABLE)
|
||||
++*vmshare;
|
||||
++*vmshare;
|
||||
else if (flags & WSLE_PAGE_EXECUTE)
|
||||
++*vmtext;
|
||||
++*vmtext;
|
||||
else
|
||||
++*vmdata;
|
||||
++*vmdata;
|
||||
}
|
||||
ret = ZwQueryInformationProcess (hProcess,
|
||||
ProcessVmCounters,
|
||||
(PVOID) &vmc,
|
||||
sizeof vmc, NULL);
|
||||
ProcessVmCounters,
|
||||
(PVOID) &vmc,
|
||||
sizeof vmc, NULL);
|
||||
if (ret != STATUS_SUCCESS)
|
||||
{
|
||||
debug_printf("NtQueryInformationProcess: ret = %d, "
|
||||
"Dos(ret) = %d",
|
||||
ret, RtlNtStatusToDosError (ret));
|
||||
"Dos(ret) = %d",
|
||||
ret, RtlNtStatusToDosError (ret));
|
||||
res = false;
|
||||
goto out;
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ static const char *registry_listing[] =
|
|||
"HKEY_CURRENT_USER",
|
||||
"HKEY_LOCAL_MACHINE",
|
||||
"HKEY_USERS",
|
||||
"HKEY_DYN_DATA", // 95/98/Me
|
||||
"HKEY_DYN_DATA", // 95/98/Me
|
||||
"HKEY_PERFOMANCE_DATA", // NT/2000/XP
|
||||
NULL
|
||||
};
|
||||
|
@ -124,12 +124,12 @@ fhandler_registry::exists ()
|
|||
if (file == path)
|
||||
{
|
||||
for (int i = 0; registry_listing[i]; i++)
|
||||
if (path_prefix_p
|
||||
(registry_listing[i], path, strlen (registry_listing[i])))
|
||||
{
|
||||
file_type = 1;
|
||||
goto out;
|
||||
}
|
||||
if (path_prefix_p
|
||||
(registry_listing[i], path, strlen (registry_listing[i])))
|
||||
{
|
||||
file_type = 1;
|
||||
goto out;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -138,14 +138,14 @@ fhandler_registry::exists ()
|
|||
return 0;
|
||||
|
||||
while (ERROR_SUCCESS ==
|
||||
(error = RegEnumKeyEx (hKey, index++, buf, &buf_size, NULL, NULL,
|
||||
NULL, NULL)) || (error == ERROR_MORE_DATA))
|
||||
(error = RegEnumKeyEx (hKey, index++, buf, &buf_size, NULL, NULL,
|
||||
NULL, NULL)) || (error == ERROR_MORE_DATA))
|
||||
{
|
||||
if (pathmatch (buf, file))
|
||||
{
|
||||
file_type = 1;
|
||||
goto out;
|
||||
}
|
||||
{
|
||||
file_type = 1;
|
||||
goto out;
|
||||
}
|
||||
buf_size = MAX_PATH;
|
||||
}
|
||||
if (error != ERROR_NO_MORE_ITEMS)
|
||||
|
@ -156,15 +156,15 @@ fhandler_registry::exists ()
|
|||
index = 0;
|
||||
buf_size = MAX_PATH;
|
||||
while (ERROR_SUCCESS ==
|
||||
(error = RegEnumValue (hKey, index++, buf, &buf_size, NULL, NULL,
|
||||
NULL, NULL)) || (error == ERROR_MORE_DATA))
|
||||
(error = RegEnumValue (hKey, index++, buf, &buf_size, NULL, NULL,
|
||||
NULL, NULL)) || (error == ERROR_MORE_DATA))
|
||||
{
|
||||
if (pathmatch (buf, file) || (buf[0] == '\0' &&
|
||||
pathmatch (file, DEFAULT_VALUE_NAME)))
|
||||
{
|
||||
file_type = -1;
|
||||
goto out;
|
||||
}
|
||||
pathmatch (file, DEFAULT_VALUE_NAME)))
|
||||
{
|
||||
file_type = -1;
|
||||
goto out;
|
||||
}
|
||||
buf_size = MAX_PATH;
|
||||
}
|
||||
if (error != ERROR_NO_MORE_ITEMS)
|
||||
|
@ -223,7 +223,7 @@ fhandler_registry::readdir (DIR * dir)
|
|||
if (*path == 0)
|
||||
{
|
||||
if (dir->__d_position >= ROOT_KEY_COUNT)
|
||||
goto out;
|
||||
goto out;
|
||||
strcpy (dir->__d_dirent->d_name, registry_listing[dir->__d_position++]);
|
||||
res = dir->__d_dirent;
|
||||
goto out;
|
||||
|
@ -248,12 +248,12 @@ retry:
|
|||
* maybe add an extension for the type of each value?
|
||||
*/
|
||||
error = RegEnumValue ((HKEY) dir->__d_u.__d_data.__handle,
|
||||
(dir->__d_position & ~REG_ENUM_VALUES_MASK) >> 16,
|
||||
buf, &buf_size, NULL, NULL, NULL, NULL);
|
||||
(dir->__d_position & ~REG_ENUM_VALUES_MASK) >> 16,
|
||||
buf, &buf_size, NULL, NULL, NULL, NULL);
|
||||
else
|
||||
error =
|
||||
RegEnumKeyEx ((HKEY) dir->__d_u.__d_data.__handle, dir->__d_position -
|
||||
SPECIAL_DOT_FILE_COUNT, buf, &buf_size, NULL, NULL, NULL, NULL);
|
||||
SPECIAL_DOT_FILE_COUNT, buf, &buf_size, NULL, NULL, NULL, NULL);
|
||||
if (error == ERROR_NO_MORE_ITEMS
|
||||
&& (dir->__d_position & REG_ENUM_VALUES_MASK) == 0)
|
||||
{
|
||||
|
@ -267,7 +267,7 @@ retry:
|
|||
RegCloseKey ((HKEY) dir->__d_u.__d_data.__handle);
|
||||
dir->__d_u.__d_data.__handle = INVALID_HANDLE_VALUE;
|
||||
if (error != ERROR_NO_MORE_ITEMS)
|
||||
seterrno_from_win_error (__FILE__, __LINE__, error);
|
||||
seterrno_from_win_error (__FILE__, __LINE__, error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -348,22 +348,22 @@ fhandler_registry::open (path_conv *pc, int flags, mode_t mode)
|
|||
if (!*path)
|
||||
{
|
||||
if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
|
||||
{
|
||||
set_errno (EEXIST);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
{
|
||||
set_errno (EEXIST);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
else if (flags & O_WRONLY)
|
||||
{
|
||||
set_errno (EISDIR);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
{
|
||||
set_errno (EISDIR);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
flags |= O_DIROPEN;
|
||||
goto success;
|
||||
}
|
||||
{
|
||||
flags |= O_DIROPEN;
|
||||
goto success;
|
||||
}
|
||||
}
|
||||
path++;
|
||||
pathlen = strlen (path);
|
||||
|
@ -377,40 +377,40 @@ fhandler_registry::open (path_conv *pc, int flags, mode_t mode)
|
|||
if (file == path)
|
||||
{
|
||||
for (int i = 0; registry_listing[i]; i++)
|
||||
if (path_prefix_p
|
||||
(registry_listing[i], path, strlen (registry_listing[i])))
|
||||
{
|
||||
if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
|
||||
{
|
||||
set_errno (EEXIST);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
else if (flags & O_WRONLY)
|
||||
{
|
||||
set_errno (EISDIR);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
flags |= O_DIROPEN;
|
||||
goto success;
|
||||
}
|
||||
}
|
||||
if (path_prefix_p
|
||||
(registry_listing[i], path, strlen (registry_listing[i])))
|
||||
{
|
||||
if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
|
||||
{
|
||||
set_errno (EEXIST);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
else if (flags & O_WRONLY)
|
||||
{
|
||||
set_errno (EISDIR);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
flags |= O_DIROPEN;
|
||||
goto success;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & O_CREAT)
|
||||
{
|
||||
set_errno (EROFS);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
{
|
||||
set_errno (EROFS);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
set_errno (ENOENT);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
{
|
||||
set_errno (ENOENT);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & O_WRONLY)
|
||||
|
@ -433,44 +433,44 @@ fhandler_registry::open (path_conv *pc, int flags, mode_t mode)
|
|||
{
|
||||
error = RegQueryValueEx (hKey, file, NULL, &type, NULL, &size);
|
||||
if (error != ERROR_SUCCESS)
|
||||
{
|
||||
seterrno_from_win_error (__FILE__, __LINE__, error);
|
||||
res = -1;
|
||||
goto out;
|
||||
}
|
||||
{
|
||||
seterrno_from_win_error (__FILE__, __LINE__, error);
|
||||
res = -1;
|
||||
goto out;
|
||||
}
|
||||
bufalloc = size;
|
||||
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc);
|
||||
error =
|
||||
RegQueryValueEx (hKey, file, NULL, NULL, (BYTE *) filebuf, &size);
|
||||
RegQueryValueEx (hKey, file, NULL, NULL, (BYTE *) filebuf, &size);
|
||||
if (error != ERROR_SUCCESS)
|
||||
{
|
||||
seterrno_from_win_error (__FILE__, __LINE__, error);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
{
|
||||
seterrno_from_win_error (__FILE__, __LINE__, error);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
filesize = size;
|
||||
}
|
||||
else
|
||||
{
|
||||
bufalloc = 0;
|
||||
do
|
||||
{
|
||||
bufalloc += 1000;
|
||||
if (filebuf)
|
||||
{
|
||||
cfree (filebuf);
|
||||
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc);
|
||||
}
|
||||
error =
|
||||
RegQueryValueEx (hKey, file, NULL, &type, (BYTE *) filebuf,
|
||||
&size);
|
||||
if (error != ERROR_SUCCESS && res != ERROR_MORE_DATA)
|
||||
{
|
||||
seterrno_from_win_error (__FILE__, __LINE__, error);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
{
|
||||
bufalloc += 1000;
|
||||
if (filebuf)
|
||||
{
|
||||
cfree (filebuf);
|
||||
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc);
|
||||
}
|
||||
error =
|
||||
RegQueryValueEx (hKey, file, NULL, &type, (BYTE *) filebuf,
|
||||
&size);
|
||||
if (error != ERROR_SUCCESS && res != ERROR_MORE_DATA)
|
||||
{
|
||||
seterrno_from_win_error (__FILE__, __LINE__, error);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
while (error == ERROR_MORE_DATA);
|
||||
filesize = size;
|
||||
}
|
||||
|
@ -509,37 +509,37 @@ fhandler_registry::open_key (const char *name, REGSAM access, bool isValue)
|
|||
{
|
||||
const char *anchor = name;
|
||||
while (*name && !SLASH_P (*name))
|
||||
name++;
|
||||
name++;
|
||||
strncpy (component, anchor, name - anchor);
|
||||
component[name - anchor] = '\0';
|
||||
if (*name)
|
||||
name++;
|
||||
name++;
|
||||
if (*name == 0 && isValue == true)
|
||||
goto out;
|
||||
goto out;
|
||||
|
||||
if (hParentKey != (HKEY) INVALID_HANDLE_VALUE)
|
||||
{
|
||||
hKey = (HKEY) INVALID_HANDLE_VALUE;
|
||||
LONG error = RegOpenKeyEx (hParentKey, component, 0, access, &hKey);
|
||||
if (hKey == (HKEY) INVALID_HANDLE_VALUE)
|
||||
{
|
||||
seterrno_from_win_error (__FILE__, __LINE__, error);
|
||||
return hKey;
|
||||
}
|
||||
if (parentOpened)
|
||||
RegCloseKey (hParentKey);
|
||||
hParentKey = hKey;
|
||||
parentOpened = true;
|
||||
}
|
||||
{
|
||||
hKey = (HKEY) INVALID_HANDLE_VALUE;
|
||||
LONG error = RegOpenKeyEx (hParentKey, component, 0, access, &hKey);
|
||||
if (hKey == (HKEY) INVALID_HANDLE_VALUE)
|
||||
{
|
||||
seterrno_from_win_error (__FILE__, __LINE__, error);
|
||||
return hKey;
|
||||
}
|
||||
if (parentOpened)
|
||||
RegCloseKey (hParentKey);
|
||||
hParentKey = hKey;
|
||||
parentOpened = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; registry_listing[i]; i++)
|
||||
if (pathmatch (component, registry_listing[i]))
|
||||
hKey = registry_keys[i];
|
||||
if (hKey == (HKEY) INVALID_HANDLE_VALUE)
|
||||
return hKey;
|
||||
hParentKey = hKey;
|
||||
}
|
||||
{
|
||||
for (int i = 0; registry_listing[i]; i++)
|
||||
if (pathmatch (component, registry_listing[i]))
|
||||
hKey = registry_keys[i];
|
||||
if (hKey == (HKEY) INVALID_HANDLE_VALUE)
|
||||
return hKey;
|
||||
hParentKey = hKey;
|
||||
}
|
||||
}
|
||||
out:
|
||||
return hKey;
|
||||
|
|
|
@ -520,33 +520,33 @@ fhandler_tty_slave::open (path_conv *, int flags, mode_t)
|
|||
termios_printf ("cannot dup handles via server. using old method.");
|
||||
|
||||
HANDLE tty_owner = OpenProcess (PROCESS_DUP_HANDLE, FALSE,
|
||||
get_ttyp ()->master_pid);
|
||||
get_ttyp ()->master_pid);
|
||||
termios_printf ("tty own handle %p",tty_owner);
|
||||
if (tty_owner == NULL)
|
||||
{
|
||||
termios_printf ("can't open tty (%d) handle process %d",
|
||||
ttynum, get_ttyp ()->master_pid);
|
||||
__seterrno ();
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
termios_printf ("can't open tty (%d) handle process %d",
|
||||
ttynum, get_ttyp ()->master_pid);
|
||||
__seterrno ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!DuplicateHandle (tty_owner, get_ttyp ()->from_master,
|
||||
hMainProc, &from_master_local, 0, TRUE,
|
||||
hMainProc, &from_master_local, 0, TRUE,
|
||||
DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
termios_printf ("can't duplicate input, %E");
|
||||
__seterrno ();
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
termios_printf ("can't duplicate input, %E");
|
||||
__seterrno ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!DuplicateHandle (tty_owner, get_ttyp ()->to_master,
|
||||
hMainProc, &to_master_local, 0, TRUE,
|
||||
DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
termios_printf ("can't duplicate output, %E");
|
||||
__seterrno ();
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
termios_printf ("can't duplicate output, %E");
|
||||
__seterrno ();
|
||||
return 0;
|
||||
}
|
||||
CloseHandle (tty_owner);
|
||||
}
|
||||
|
||||
|
@ -568,7 +568,7 @@ fhandler_tty_slave::open (path_conv *, int flags, mode_t)
|
|||
|
||||
int
|
||||
fhandler_tty_slave::cygserver_attach_tty (LPHANDLE from_master_ptr,
|
||||
LPHANDLE to_master_ptr)
|
||||
LPHANDLE to_master_ptr)
|
||||
{
|
||||
if (!from_master_ptr || !to_master_ptr)
|
||||
return 0;
|
||||
|
|
|
@ -967,19 +967,19 @@ fixup_mmaps_after_fork (HANDLE parent)
|
|||
return -1;
|
||||
}
|
||||
if (rec->get_access () == FILE_MAP_COPY)
|
||||
{
|
||||
{
|
||||
for (char *address = rec->get_address ();
|
||||
address < rec->get_address () + rec->get_size ();
|
||||
address += getpagesize ())
|
||||
if (rec->access (address)
|
||||
&& !ReadProcessMemory (parent, address, address,
|
||||
&& !ReadProcessMemory (parent, address, address,
|
||||
getpagesize (), NULL))
|
||||
{
|
||||
system_printf ("ReadProcessMemory failed for MAP_PRIVATE address %p, %E",
|
||||
rec->get_address ());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
rec->fixup_map ();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -543,7 +543,7 @@ cygwin_socket (int af, int type, int protocol)
|
|||
if (fh)
|
||||
{
|
||||
fh->set_addr_family (af);
|
||||
fh->set_socket_type (type);
|
||||
fh->set_socket_type (type);
|
||||
}
|
||||
res = fd;
|
||||
}
|
||||
|
@ -1623,7 +1623,7 @@ get_2k_ifconf (struct ifconf *ifc, int what)
|
|||
switch (ift->table[if_cnt].dwType)
|
||||
{
|
||||
case MIB_IF_TYPE_TOKENRING:
|
||||
++*tok;
|
||||
++*tok;
|
||||
strcpy (ifr->ifr_name, "tok");
|
||||
strcat (ifr->ifr_name, tok);
|
||||
break;
|
||||
|
@ -2443,7 +2443,7 @@ socketpair (int family, int type, int protocol, int *sb)
|
|||
else
|
||||
{
|
||||
fh = fdsock (sb[0], type == SOCK_STREAM ? "/dev/tcp" : "/dev/udp",
|
||||
insock);
|
||||
insock);
|
||||
fh->set_addr_family (AF_INET);
|
||||
fh->set_socket_type (type);
|
||||
fh = fdsock (sb[1], type == SOCK_STREAM ? "/dev/tcp" : "/dev/udp",
|
||||
|
|
|
@ -336,11 +336,31 @@ typedef enum _MEMORY_INFORMATION_CLASS
|
|||
MemoryBaiscVlmInformation
|
||||
} MEMORY_INFORMATION_CLASS;
|
||||
|
||||
typedef struct _MEMORY_WORKING_SET_LIST {
|
||||
typedef struct _MEMORY_WORKING_SET_LIST
|
||||
{
|
||||
ULONG NumberOfPages;
|
||||
ULONG WorkingSetList[1];
|
||||
} MEMORY_WORKING_SET_LIST, *PMEMORY_WORKING_SET_LIST;
|
||||
|
||||
typedef struct _FILE_NAME_INFORMATION
|
||||
{
|
||||
DWORD FileNameLength;
|
||||
WCHAR FileName[MAX_PATH + 100];
|
||||
} FILE_NAME_INFORMATION;
|
||||
|
||||
typedef enum _OBJECT_INFORMATION_CLASS
|
||||
{
|
||||
ObjectBasicInformation = 0,
|
||||
ObjectNameInformation = 1,
|
||||
ObjectHandleInformation = 4
|
||||
// and many more
|
||||
} OBJECT_INFORMATION_CLASS;
|
||||
|
||||
typedef struct _OBJECT_NAME_INFORMATION
|
||||
{
|
||||
UNICODE_STRING Name;
|
||||
} OBJECT_NAME_INFORMATION;
|
||||
|
||||
/* Function declarations for ntdll.dll. These don't appear in any
|
||||
standard Win32 header. */
|
||||
extern "C"
|
||||
|
@ -368,4 +388,7 @@ extern "C"
|
|||
OUT PVOID, IN ULONG, OUT PULONG);
|
||||
NTSTATUS NTAPI ZwQueryVirtualMemory (IN HANDLE, IN PVOID, IN MEMORY_INFORMATION_CLASS,
|
||||
OUT PVOID, IN ULONG, OUT PULONG);
|
||||
NTSTATUS NTAPI NtQueryInformationFile (HANDLE, IO_STATUS_BLOCK *, VOID *,
|
||||
DWORD, DWORD);
|
||||
NTSTATUS NTAPI NtQueryObject (HANDLE, OBJECT_INFORMATION_CLASS, VOID *, ULONG, ULONG *);
|
||||
}
|
||||
|
|
|
@ -373,6 +373,23 @@ path_conv::return_and_clear_normalized_path ()
|
|||
return s;
|
||||
}
|
||||
|
||||
void
|
||||
path_conv::fillin (HANDLE h)
|
||||
{
|
||||
BY_HANDLE_FILE_INFORMATION local;
|
||||
if (!GetFileInformationByHandle (h, &local))
|
||||
{
|
||||
fileattr = INVALID_FILE_ATTRIBUTES;
|
||||
fs.serial = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
fileattr = local.dwFileAttributes;
|
||||
fs.serial = local.dwVolumeSerialNumber;
|
||||
}
|
||||
fs.drive_type = DRIVE_UNKNOWN;
|
||||
}
|
||||
|
||||
/* Convert an arbitrary path SRC to a pure Win32 path, suitable for
|
||||
passing to Win32 API routines.
|
||||
|
||||
|
@ -507,25 +524,25 @@ path_conv::check (const char *src, unsigned opt,
|
|||
}
|
||||
goto out;
|
||||
}
|
||||
else if (isvirtual_dev (devn))
|
||||
{
|
||||
else if (isvirtual_dev (devn))
|
||||
{
|
||||
/* FIXME: Calling build_fhandler here is not the right way to handle this. */
|
||||
fhandler_virtual *fh =
|
||||
(fhandler_virtual *) cygheap->fdtab.build_fhandler (-1, devn, (const char *) path_copy, NULL, unit);
|
||||
int file_type = fh->exists ();
|
||||
switch (file_type)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
fileattr = FILE_ATTRIBUTE_DIRECTORY;
|
||||
fhandler_virtual *fh =
|
||||
(fhandler_virtual *) cygheap->fdtab.build_fhandler (-1, devn, (const char *) path_copy, NULL, unit);
|
||||
int file_type = fh->exists ();
|
||||
switch (file_type)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
fileattr = FILE_ATTRIBUTE_DIRECTORY;
|
||||
break;
|
||||
default:
|
||||
case -1:
|
||||
fileattr = 0;
|
||||
}
|
||||
delete fh;
|
||||
default:
|
||||
case -1:
|
||||
fileattr = 0;
|
||||
}
|
||||
delete fh;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
/* devn should not be a device. If it is, then stop parsing now. */
|
||||
else if (devn != FH_BAD)
|
||||
{
|
||||
|
@ -1434,7 +1451,7 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst,
|
|||
{
|
||||
devn = fhandler_proc::get_proc_fhandler (pathbuf);
|
||||
if (devn == FH_BAD)
|
||||
return ENOENT;
|
||||
return ENOENT;
|
||||
}
|
||||
else if (iscygdrive (pathbuf))
|
||||
{
|
||||
|
@ -2679,7 +2696,7 @@ symlink (const char *topath, const char *frompath)
|
|||
&sa, alloca (4096), 4096);
|
||||
|
||||
h = CreateFileA(win32_path, GENERIC_WRITE, 0, &sa,
|
||||
CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
if (h == INVALID_HANDLE_VALUE)
|
||||
__seterrno ();
|
||||
else
|
||||
|
@ -2727,7 +2744,7 @@ symlink (const char *topath, const char *frompath)
|
|||
S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO);
|
||||
|
||||
DWORD attr = allow_winsymlinks ? FILE_ATTRIBUTE_READONLY
|
||||
: FILE_ATTRIBUTE_SYSTEM;
|
||||
: FILE_ATTRIBUTE_SYSTEM;
|
||||
#ifdef HIDDEN_DOT_FILES
|
||||
cp = strrchr (win32_path, '\\');
|
||||
if ((cp && cp[1] == '.') || *win32_path == '.')
|
||||
|
@ -3306,7 +3323,7 @@ chdir (const char *in_dir)
|
|||
if (res == -1)
|
||||
__seterrno ();
|
||||
else if ((!path.has_symlinks () && strpbrk (dir, ":\\") == NULL
|
||||
&& pcheck_case == PCHECK_RELAXED) || isvirtual_dev (devn))
|
||||
&& pcheck_case == PCHECK_RELAXED) || isvirtual_dev (devn))
|
||||
cygheap->cwd.set (native_dir, dir);
|
||||
else
|
||||
cygheap->cwd.set (native_dir, NULL);
|
||||
|
|
|
@ -143,10 +143,14 @@ class path_conv
|
|||
DWORD get_devn () {return devn == FH_BAD ? (DWORD) FH_DISK : devn;}
|
||||
short get_unitn () {return devn == FH_BAD ? 0 : unit;}
|
||||
DWORD file_attributes () {return fileattr;}
|
||||
DWORD get_drive_type () {return fs.drive_type;}
|
||||
DWORD drive_type () {return fs.drive_type;}
|
||||
BOOL fs_fast_ea () {return fs.sym_opt & PC_CHECK_EA;}
|
||||
void set_path (const char *p) {strcpy (path, p);}
|
||||
char *return_and_clear_normalized_path ();
|
||||
const char * root_dir () { return fs.root_dir; }
|
||||
DWORD volser () { return fs.serial; }
|
||||
const char *volname () {return fs.name; }
|
||||
void fillin (HANDLE h);
|
||||
};
|
||||
|
||||
/* Symlink marker */
|
||||
|
|
|
@ -55,19 +55,19 @@ poll (struct pollfd *fds, unsigned int nfds, int timeout)
|
|||
{
|
||||
fds[i].revents = 0;
|
||||
if (!cygheap->fdtab.not_open(fds[i].fd))
|
||||
{
|
||||
if (fds[i].events & POLLIN)
|
||||
FD_SET(fds[i].fd, read_fds);
|
||||
if (fds[i].events & POLLOUT)
|
||||
FD_SET(fds[i].fd, write_fds);
|
||||
if (fds[i].events & POLLPRI)
|
||||
FD_SET(fds[i].fd, except_fds);
|
||||
}
|
||||
{
|
||||
if (fds[i].events & POLLIN)
|
||||
FD_SET(fds[i].fd, read_fds);
|
||||
if (fds[i].events & POLLOUT)
|
||||
FD_SET(fds[i].fd, write_fds);
|
||||
if (fds[i].events & POLLPRI)
|
||||
FD_SET(fds[i].fd, except_fds);
|
||||
}
|
||||
else if (fds[i].fd >= 0)
|
||||
{
|
||||
++invalid_fds;
|
||||
fds[i].revents = POLLNVAL;
|
||||
}
|
||||
{
|
||||
++invalid_fds;
|
||||
fds[i].revents = POLLNVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (invalid_fds)
|
||||
|
@ -78,22 +78,22 @@ poll (struct pollfd *fds, unsigned int nfds, int timeout)
|
|||
if (ret > 0)
|
||||
for (unsigned int i = 0; i < nfds; ++i)
|
||||
{
|
||||
if (fds[i].fd >= 0)
|
||||
{
|
||||
if (cygheap->fdtab.not_open(fds[i].fd))
|
||||
fds[i].revents = POLLHUP;
|
||||
else
|
||||
{
|
||||
if (FD_ISSET(fds[i].fd, read_fds))
|
||||
fds[i].revents |= POLLIN;
|
||||
if (FD_ISSET(fds[i].fd, write_fds))
|
||||
fds[i].revents |= POLLOUT;
|
||||
if (FD_ISSET(fds[i].fd, read_fds) && FD_ISSET(fds[i].fd, write_fds))
|
||||
fds[i].revents |= POLLERR;
|
||||
if (FD_ISSET(fds[i].fd, except_fds))
|
||||
fds[i].revents |= POLLPRI;
|
||||
}
|
||||
}
|
||||
if (fds[i].fd >= 0)
|
||||
{
|
||||
if (cygheap->fdtab.not_open(fds[i].fd))
|
||||
fds[i].revents = POLLHUP;
|
||||
else
|
||||
{
|
||||
if (FD_ISSET(fds[i].fd, read_fds))
|
||||
fds[i].revents |= POLLIN;
|
||||
if (FD_ISSET(fds[i].fd, write_fds))
|
||||
fds[i].revents |= POLLOUT;
|
||||
if (FD_ISSET(fds[i].fd, read_fds) && FD_ISSET(fds[i].fd, write_fds))
|
||||
fds[i].revents |= POLLERR;
|
||||
if (FD_ISSET(fds[i].fd, except_fds))
|
||||
fds[i].revents |= POLLPRI;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -865,14 +865,14 @@ create_token (cygsid &usersid, cygsid &pgrpsid)
|
|||
!SetSecurityDescriptorGroup (
|
||||
(PSECURITY_DESCRIPTOR) psa->lpSecurityDescriptor,
|
||||
special_pgrp?pgrpsid:well_known_null_sid, FALSE))
|
||||
debug_printf ("SetSecurityDescriptorGroup %E");
|
||||
debug_printf ("SetSecurityDescriptorGroup %E");
|
||||
/* Convert to primary token. */
|
||||
if (!DuplicateTokenEx (token, MAXIMUM_ALLOWED, psa,
|
||||
SecurityImpersonation, TokenPrimary, &primary_token))
|
||||
{
|
||||
__seterrno ();
|
||||
debug_printf ("DuplicateTokenEx %E");
|
||||
}
|
||||
SecurityImpersonation, TokenPrimary, &primary_token))
|
||||
{
|
||||
__seterrno ();
|
||||
debug_printf ("DuplicateTokenEx %E");
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
/* shm.cc: Single unix specification IPC interface for Cygwin
|
||||
|
||||
Copyright 2001 Red Hat, Inc.
|
||||
Copyright 2001 Red Hat, Inc.
|
||||
|
||||
Originally written by Robert Collins <robert.collins@hotmail.com>
|
||||
Originally written by Robert Collins <robert.collins@hotmail.com>
|
||||
|
||||
This file is part of Cygwin.
|
||||
This file is part of Cygwin.
|
||||
|
||||
This software is a copyrighted work licensed under the terms of the
|
||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||
details. */
|
||||
This software is a copyrighted work licensed under the terms of the
|
||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||
details. */
|
||||
|
||||
#include "winsup.h"
|
||||
#include <sys/stat.h>
|
||||
|
@ -63,9 +63,9 @@ client_request (CYGSERVER_REQUEST_SHM_GET, sizeof (parameters))
|
|||
}
|
||||
|
||||
client_request_shm::client_request_shm (key_t nkey, size_t nsize,
|
||||
int nshmflg,
|
||||
char psdbuf[4096],
|
||||
pid_t npid):
|
||||
int nshmflg,
|
||||
char psdbuf[4096],
|
||||
pid_t npid):
|
||||
client_request (CYGSERVER_REQUEST_SHM_GET, sizeof (parameters))
|
||||
{
|
||||
buffer = (char *) ¶meters;
|
||||
|
@ -145,7 +145,7 @@ delete_inprocess_shmds (shmnode **nodeptr)
|
|||
{
|
||||
shmnode *tempnode = shm_head;
|
||||
while (tempnode && tempnode->next != node)
|
||||
tempnode = tempnode->next;
|
||||
tempnode = tempnode->next;
|
||||
if (tempnode)
|
||||
tempnode->next = node->next;
|
||||
// else log the unexpected !
|
||||
|
@ -460,7 +460,7 @@ shmget (key_t key, size_t size, int shmflg)
|
|||
PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR) sd_buf;
|
||||
/* create a sd for our open requests based on shmflag & 0x01ff */
|
||||
InitializeSecurityDescriptor (psd,
|
||||
SECURITY_DESCRIPTOR_REVISION);
|
||||
SECURITY_DESCRIPTOR_REVISION);
|
||||
psd = alloc_sd (getuid (), getgid (), cygheap->user.logsrv (),
|
||||
shmflg & 0x01ff, psd, &sd_size);
|
||||
|
||||
|
|
|
@ -195,7 +195,7 @@ _unlink (const char *ourname)
|
|||
/* Everything is fine if the file has disappeared or if we know that the
|
||||
FILE_FLAG_DELETE_ON_CLOSE will eventually work. */
|
||||
if (GetFileAttributes (win32_name) == INVALID_FILE_ATTRIBUTES
|
||||
|| delete_on_close_ok)
|
||||
|| delete_on_close_ok)
|
||||
goto ok; /* The file is either gone already or will eventually be
|
||||
deleted by the OS. */
|
||||
}
|
||||
|
@ -991,8 +991,9 @@ fstat64 (int fd, struct __stat64 *buf)
|
|||
res = -1;
|
||||
else
|
||||
{
|
||||
path_conv pc (cfd->get_win32_name ());
|
||||
memset (buf, 0, sizeof (struct __stat64));
|
||||
res = cfd->fstat (buf, NULL);
|
||||
res = cfd->fstat (buf, &pc);
|
||||
}
|
||||
|
||||
syscall_printf ("%d = fstat (%d, %p)", res, fd, buf);
|
||||
|
@ -1308,10 +1309,10 @@ done:
|
|||
#ifdef HIDDEN_DOT_FILES
|
||||
char *c = strrchr (real_old.get_win32 (), '\\');
|
||||
if ((c && c[1] == '.') || *real_old.get_win32 () == '.')
|
||||
attr &= ~FILE_ATTRIBUTE_HIDDEN;
|
||||
attr &= ~FILE_ATTRIBUTE_HIDDEN;
|
||||
c = strrchr (real_new.get_win32 (), '\\');
|
||||
if ((c && c[1] == '.') || *real_new.get_win32 () == '.')
|
||||
attr |= FILE_ATTRIBUTE_HIDDEN;
|
||||
attr |= FILE_ATTRIBUTE_HIDDEN;
|
||||
#endif
|
||||
SetFileAttributes (real_new, attr);
|
||||
|
||||
|
@ -1482,7 +1483,7 @@ pathconf (const char *file, int v)
|
|||
{
|
||||
case _PC_PATH_MAX:
|
||||
if (check_null_empty_str_errno (file))
|
||||
return -1;
|
||||
return -1;
|
||||
return PATH_MAX - strlen (file);
|
||||
case _PC_NAME_MAX:
|
||||
return PATH_MAX;
|
||||
|
@ -1996,7 +1997,7 @@ seteuid (__uid16_t uid)
|
|||
{
|
||||
if (cygheap->user.token == INVALID_HANDLE_VALUE ||
|
||||
! cygheap->user.impersonated )
|
||||
{
|
||||
{
|
||||
CloseHandle (ptok);
|
||||
return 0; /* No change */
|
||||
}
|
||||
|
@ -2011,7 +2012,7 @@ seteuid (__uid16_t uid)
|
|||
debug_printf("Thread token %d %sverified",
|
||||
cygheap->user.token, token_ok?"":"not ");
|
||||
if (token_ok)
|
||||
{
|
||||
{
|
||||
/* Return if current token is valid */
|
||||
if (cygheap->user.impersonated)
|
||||
{
|
||||
|
@ -2046,7 +2047,7 @@ seteuid (__uid16_t uid)
|
|||
if (cygheap->user.token != INVALID_HANDLE_VALUE)
|
||||
explicitly_created_token = TRUE;
|
||||
else
|
||||
{
|
||||
{
|
||||
/* create_token failed. Try subauthentication. */
|
||||
debug_printf ("create token failed, try subauthentication.");
|
||||
cygheap->user.token = subauth (pw_new);
|
||||
|
@ -2070,7 +2071,7 @@ seteuid (__uid16_t uid)
|
|||
/* If the token was explicitly created, all information has
|
||||
already been set correctly. */
|
||||
if (!explicitly_created_token)
|
||||
{
|
||||
{
|
||||
/* Try setting owner to same value as user. */
|
||||
if (!SetTokenInformation (cygheap->user.token, TokenOwner,
|
||||
&usersid, sizeof usersid))
|
||||
|
@ -2085,7 +2086,7 @@ seteuid (__uid16_t uid)
|
|||
}
|
||||
/* Now try to impersonate. */
|
||||
if (!ImpersonateLoggedOnUser (cygheap->user.token))
|
||||
{
|
||||
{
|
||||
debug_printf ("ImpersonateLoggedOnUser %E");
|
||||
__seterrno ();
|
||||
goto failed;
|
||||
|
@ -2097,7 +2098,7 @@ seteuid (__uid16_t uid)
|
|||
impersonation is active. If so, the token is used for
|
||||
retrieving user's SID. */
|
||||
user.token = cygheap->user.impersonated ? cygheap->user.token
|
||||
: INVALID_HANDLE_VALUE;
|
||||
: INVALID_HANDLE_VALUE;
|
||||
/* Unsetting these two env vars is necessary to get NetUserGetInfo()
|
||||
called in internal_getlogin (). Otherwise the wrong path is used
|
||||
after a user switch, probably. */
|
||||
|
|
|
@ -69,7 +69,7 @@ uname (struct utsname *name)
|
|||
else
|
||||
{
|
||||
if (sysinfo.dwProcessorType == PROCESSOR_INTEL_386 ||
|
||||
sysinfo.dwProcessorType == PROCESSOR_INTEL_486)
|
||||
sysinfo.dwProcessorType == PROCESSOR_INTEL_486)
|
||||
ptype = sysinfo.dwProcessorType / 100;
|
||||
else
|
||||
ptype = PROCESSOR_INTEL_PENTIUM / 100;
|
||||
|
|
|
@ -64,7 +64,7 @@ WndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|||
return 0;
|
||||
case WM_ASYNCIO:
|
||||
if (WSAGETSELECTEVENT(lParam) == FD_OOB)
|
||||
raise (SIGURG);
|
||||
raise (SIGURG);
|
||||
else
|
||||
raise (SIGIO);
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue