* Merge in cygwin-64bit-branch.
This commit is contained in:
@ -1,3 +1,7 @@
|
|||||||
|
2013-04-23 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* Merge in cygwin-64bit-branch. See ChangeLog.64bit for details.
|
||||||
|
|
||||||
2012-11-27 Christopher Faylor <me.cygwin2012@cgf.cx>
|
2012-11-27 Christopher Faylor <me.cygwin2012@cgf.cx>
|
||||||
|
|
||||||
* Makefile.in: Remove old from CFLAGS and move C*FLAGS so that they can
|
* Makefile.in: Remove old from CFLAGS and move C*FLAGS so that they can
|
||||||
|
87
winsup/cygserver/ChangeLog.64bit
Normal file
87
winsup/cygserver/ChangeLog.64bit
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
2013-03-07 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* msg.cc (client_request_msg::serve): Revert change to refuse 64 bit
|
||||||
|
processes on 32 bit systems.
|
||||||
|
* sem.cc (client_request_sem::serve): Ditto.
|
||||||
|
* shm.cc (client_request_shm::serve): Ditto.
|
||||||
|
|
||||||
|
2013-03-01 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* client.cc: Revert changes to handle 32 bit processes on 64 bit
|
||||||
|
systems.
|
||||||
|
* sysv_msg.cc: Ditto.
|
||||||
|
* sysv_sem.cc: Ditto.
|
||||||
|
* sysv_shm.cc: Ditto.
|
||||||
|
|
||||||
|
2013-02-13 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* Makefile.in (cygserver.exe): Make cygwin_build a tooldir (-B instead
|
||||||
|
of -L) to support bootstrapping.
|
||||||
|
|
||||||
|
2013-02-09 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* configure: Regenerate to fix wrong ac_unique_file dependency.
|
||||||
|
|
||||||
|
2012-12-06 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* sysv_msg.cc (conv_timespec32_to_timespec): Move implementation to
|
||||||
|
cygserver_ipc.h.
|
||||||
|
(conv_timespec_to_timespec32): Ditto.
|
||||||
|
(conv_msqid_ds32_to_msqid_ds): Drop and move code into copyin_msqid_ds.
|
||||||
|
(conv_msqid_ds_to_msqid_ds32): Drop and move code into copyout_msqid_ds.
|
||||||
|
* sysv_sem.cc (copyin_semid_ds): New inline function on Cygwin.
|
||||||
|
(copyout_semid_ds): Ditto.
|
||||||
|
(__semctl): Use a conditional arg_size value rather than a fixed
|
||||||
|
sizeof(real_arg) throughout, to accommodate 64/32 bit conversion.
|
||||||
|
Use copyout_semid_ds and copyin_semid_ds to copy semid_ds
|
||||||
|
structures from cygserver to client and vice versa on Cygwin.
|
||||||
|
* sysv_shm.cc (copyin_shmid_ds): New inline function on Cygwin.
|
||||||
|
(copyout_shmid_ds): Ditto.
|
||||||
|
(shmctl): Use copyout_shmid_ds and copyin_shmid_ds to copy shmid_ds
|
||||||
|
structures from cygserver to client and vice versa on Cygwin.
|
||||||
|
|
||||||
|
2012-12-05 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* client.cc (client_request::header_t::header_t): Accommodate changes
|
||||||
|
to msglen member.
|
||||||
|
(client_request::handle_request): Ditto.
|
||||||
|
(client_request::client_request): Zero out entire parameter block.
|
||||||
|
Explain why.
|
||||||
|
* sysv_msg.cc (conv_timespec32_to_timespec): New inline function on
|
||||||
|
64 bit Cygwin.
|
||||||
|
(conv_timespec_to_timespec32): Ditto.
|
||||||
|
(conv_msqid_ds32_to_msqid_ds): Ditto.
|
||||||
|
(conv_msqid_ds_to_msqid_ds32): Ditto.
|
||||||
|
(copyin_msqid_ds): New inline function on Cygwin.
|
||||||
|
(copyout_msqid_ds): Ditto.
|
||||||
|
(msgctl): Use copyout_msqid_ds and copyin_msqid_ds to copy msqid_ds
|
||||||
|
structures from cygserver to client and vice versa on Cygwin.
|
||||||
|
(msgsnd): Special case copyin of msg_type on 64 bit Cygwin.
|
||||||
|
(msgrcv): Special case copyout of msg_type on 64 bit Cygwin.
|
||||||
|
|
||||||
|
2012-12-04 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* bsd_helper.cc (tunable_int_fetch): Convert 2nd parameter to
|
||||||
|
int32_t.
|
||||||
|
* bsd_helper.h (tunable_int_fetch): Fix declaration accordingly.
|
||||||
|
* bsd_log.cc (log_level): Change type to int32_t.
|
||||||
|
* bsd_log.h (log_level): Fix declaration accordingly.
|
||||||
|
* bsd_mutex.cc (msgmni): Change type to int32_t.
|
||||||
|
(semmni): Ditto.
|
||||||
|
* cygserver.cc: Fix debug output to be target agnostic. Use same
|
||||||
|
style throughout.
|
||||||
|
* msg.cc (client_request_msg::serve): Refuse to serve 64 bit processes
|
||||||
|
from 32 bit cygserver.
|
||||||
|
* sem.cc (client_request_sem::serve): Ditto.
|
||||||
|
* shm.cc (client_request_shm::serve): Ditto.
|
||||||
|
* sysv_shm.cc (shm_delete_mapping): Mark size as unused to make gcc
|
||||||
|
happy.
|
||||||
|
(kern_shmat): Ditto with flags.
|
||||||
|
* process.h (class process): Change type of _cleaning_up member to LONG.
|
||||||
|
* threaded_queue.h (class threaded_queue): Ditto for _workers_count.
|
||||||
|
|
||||||
|
2012-08-14 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* configure.in: Add AC_NO_EXECUTABLES to allow bootstrap.
|
||||||
|
* configure: Regenerate.
|
||||||
|
|
@ -71,7 +71,7 @@ libclean:
|
|||||||
fullclean: clean libclean
|
fullclean: clean libclean
|
||||||
|
|
||||||
cygserver.exe: $(CYGWIN_LIB) $(OBJS) $(CYGWIN_OBJS)
|
cygserver.exe: $(CYGWIN_LIB) $(OBJS) $(CYGWIN_OBJS)
|
||||||
$(CXX) -o $@ ${wordlist 2,999,$^} -static -static-libgcc -L$(cygwin_build) -lntdll
|
$(CXX) -o $@ ${wordlist 2,999,$^} -static -static-libgcc -B$(cygwin_build) -lntdll
|
||||||
|
|
||||||
$(cygwin_build)/%.o: $(cygwin_source)/%.cc
|
$(cygwin_build)/%.o: $(cygwin_source)/%.cc
|
||||||
@$(MAKE) -C $(@D) $(@F)
|
@$(MAKE) -C $(@D) $(@F)
|
||||||
|
@ -655,7 +655,7 @@ tunable_param_init (const char *config_file, bool force)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
tunable_int_fetch (const char *name, long *tunable_target)
|
tunable_int_fetch (const char *name, int32_t *tunable_target)
|
||||||
{
|
{
|
||||||
tun_struct *s;
|
tun_struct *s;
|
||||||
for (s = &tunable_params[0]; s->name; ++s)
|
for (s = &tunable_params[0]; s->name; ++s)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* bsd_helper.h: Helps integrating BSD kernel code
|
/* bsd_helper.h: Helps integrating BSD kernel code
|
||||||
|
|
||||||
Copyright 2003 Red Hat, Inc.
|
Copyright 2003, 2012 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ vm_object_t vm_object_duplicate (struct thread *td, vm_object_t object);
|
|||||||
void vm_object_deallocate (vm_object_t object);
|
void vm_object_deallocate (vm_object_t object);
|
||||||
|
|
||||||
void tunable_param_init (const char *, bool);
|
void tunable_param_init (const char *, bool);
|
||||||
void tunable_int_fetch (const char *, long *);
|
void tunable_int_fetch (const char *, int32_t *);
|
||||||
void tunable_bool_fetch (const char *, tun_bool_t *);
|
void tunable_bool_fetch (const char *, tun_bool_t *);
|
||||||
|
|
||||||
#endif /* _BSD_HELPER_H */
|
#endif /* _BSD_HELPER_H */
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* bsd_log.cc
|
/* bsd_log.cc
|
||||||
|
|
||||||
Copyright 2003, 2004 Red Hat Inc.
|
Copyright 2003, 2004, 2012 Red Hat Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -14,7 +14,7 @@ details. */
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
long log_level = 8; /* Illegal value. Don't change! */
|
int32_t log_level = 8; /* Illegal value. Don't change! */
|
||||||
tun_bool_t log_debug = TUN_UNDEF;
|
tun_bool_t log_debug = TUN_UNDEF;
|
||||||
tun_bool_t log_syslog = TUN_UNDEF;
|
tun_bool_t log_syslog = TUN_UNDEF;
|
||||||
tun_bool_t log_stderr = TUN_UNDEF;
|
tun_bool_t log_stderr = TUN_UNDEF;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* bsd_log.h: Helps integrating BSD kernel code
|
/* bsd_log.h: Helps integrating BSD kernel code
|
||||||
|
|
||||||
Copyright 2003 Red Hat, Inc.
|
Copyright 2003, 2012 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -13,7 +13,7 @@ details. */
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/syslog.h>
|
#include <sys/syslog.h>
|
||||||
|
|
||||||
extern long log_level;
|
extern int32_t log_level;
|
||||||
extern tun_bool_t log_debug;
|
extern tun_bool_t log_debug;
|
||||||
extern tun_bool_t log_syslog;
|
extern tun_bool_t log_syslog;
|
||||||
extern tun_bool_t log_stderr;
|
extern tun_bool_t log_stderr;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* bsd_mutex.cc
|
/* bsd_mutex.cc
|
||||||
|
|
||||||
Copyright 2003, 2004, 2005, 2007 Red Hat Inc.
|
Copyright 2003, 2004, 2005, 2007, 2012 Red Hat Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -285,8 +285,8 @@ msleep_init (void)
|
|||||||
msleep_glob_evt = CreateEvent (NULL, TRUE, FALSE, NULL);
|
msleep_glob_evt = CreateEvent (NULL, TRUE, FALSE, NULL);
|
||||||
if (!msleep_glob_evt)
|
if (!msleep_glob_evt)
|
||||||
panic ("CreateEvent in msleep_init failed: %lu", GetLastError ());
|
panic ("CreateEvent in msleep_init failed: %lu", GetLastError ());
|
||||||
long msgmni = support_msgqueues ? msginfo.msgmni : 0;
|
int32_t msgmni = support_msgqueues ? msginfo.msgmni : 0;
|
||||||
long semmni = support_semaphores ? seminfo.semmni : 0;
|
int32_t semmni = support_semaphores ? seminfo.semmni : 0;
|
||||||
TUNABLE_INT_FETCH ("kern.ipc.msgmni", &msgmni);
|
TUNABLE_INT_FETCH ("kern.ipc.msgmni", &msgmni);
|
||||||
TUNABLE_INT_FETCH ("kern.ipc.semmni", &semmni);
|
TUNABLE_INT_FETCH ("kern.ipc.semmni", &semmni);
|
||||||
debug ("Try allocating msgmni (%d) + semmni (%d) msleep records",
|
debug ("Try allocating msgmni (%d) + semmni (%d) msleep records",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* client.cc
|
/* client.cc
|
||||||
|
|
||||||
Copyright 2001, 2002, 2003, 2004, 2008, 2009 Red Hat Inc.
|
Copyright 2001, 2002, 2003, 2004, 2008, 2009, 2012, 2013 Red Hat Inc.
|
||||||
|
|
||||||
Written by Egor Duda <deo@logos-m.ru>
|
Written by Egor Duda <deo@logos-m.ru>
|
||||||
|
|
||||||
@ -115,11 +115,11 @@ client_request_attach_tty::send (transport_layer_base * const conn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
client_request::header_t::header_t (const request_code_t request_code,
|
client_request::header_t::header_t (const request_code_t request_code,
|
||||||
const size_t msglen)
|
const size_t len)
|
||||||
: msglen (msglen),
|
: request_code (request_code)
|
||||||
request_code (request_code)
|
|
||||||
{
|
{
|
||||||
assert (request_code >= 0 && request_code < CYGSERVER_REQUEST_LAST);
|
assert (request_code >= 0 && request_code < CYGSERVER_REQUEST_LAST);
|
||||||
|
msglen = len;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: also check write and read result for -1.
|
// FIXME: also check write and read result for -1.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* cygserver.cc
|
/* cygserver.cc
|
||||||
|
|
||||||
Copyright 2001, 2002, 2003, 2004, 2005, 2007, 2011 Red Hat Inc.
|
Copyright 2001, 2002, 2003, 2004, 2005, 2007, 2011, 2012 Red Hat Inc.
|
||||||
|
|
||||||
Written by Egor Duda <deo@logos-m.ru>
|
Written by Egor Duda <deo@logos-m.ru>
|
||||||
|
|
||||||
@ -51,13 +51,13 @@ setup_privileges ()
|
|||||||
rc = OpenProcessToken (GetCurrentProcess () , TOKEN_ALL_ACCESS , &hToken) ;
|
rc = OpenProcessToken (GetCurrentProcess () , TOKEN_ALL_ACCESS , &hToken) ;
|
||||||
if (!rc)
|
if (!rc)
|
||||||
{
|
{
|
||||||
debug ("error opening process token (%lu)", GetLastError ());
|
debug ("error opening process token (err %u)", GetLastError ());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
rc = LookupPrivilegeValue (NULL, SE_DEBUG_NAME, &sPrivileges.Privileges[0].Luid);
|
rc = LookupPrivilegeValue (NULL, SE_DEBUG_NAME, &sPrivileges.Privileges[0].Luid);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
{
|
{
|
||||||
debug ("error getting privilege luid (%lu)", GetLastError ());
|
debug ("error getting privilege luid (err %u)", GetLastError ());
|
||||||
ret_val = false;
|
ret_val = false;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -66,7 +66,7 @@ setup_privileges ()
|
|||||||
rc = AdjustTokenPrivileges (hToken, FALSE, &sPrivileges, 0, NULL, NULL) ;
|
rc = AdjustTokenPrivileges (hToken, FALSE, &sPrivileges, 0, NULL, NULL) ;
|
||||||
if (!rc)
|
if (!rc)
|
||||||
{
|
{
|
||||||
debug ("error adjusting privilege level. (%lu)", GetLastError ());
|
debug ("error adjusting privilege level. (err %u)", GetLastError ());
|
||||||
ret_val = false;
|
ret_val = false;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -106,8 +106,8 @@ check_and_dup_handle (HANDLE from_process, HANDLE to_process,
|
|||||||
0, bInheritHandle,
|
0, bInheritHandle,
|
||||||
DUPLICATE_SAME_ACCESS))
|
DUPLICATE_SAME_ACCESS))
|
||||||
{
|
{
|
||||||
log (LOG_ERR, "error getting handle(%u) to server (%lu)",
|
log (LOG_ERR, "error getting handle(%p) to server (err %u)",
|
||||||
(unsigned int)from_handle, GetLastError ());
|
from_handle, GetLastError ());
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
@ -119,7 +119,7 @@ check_and_dup_handle (HANDLE from_process, HANDLE to_process,
|
|||||||
| DACL_SECURITY_INFORMATION),
|
| DACL_SECURITY_INFORMATION),
|
||||||
sd, sizeof (sd_buf), &bytes_needed))
|
sd, sizeof (sd_buf), &bytes_needed))
|
||||||
{
|
{
|
||||||
log (LOG_ERR, "error getting handle SD (%lu)", GetLastError ());
|
log (LOG_ERR, "error getting handle SD (err %u)", GetLastError ());
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,8 +128,7 @@ check_and_dup_handle (HANDLE from_process, HANDLE to_process,
|
|||||||
if (!AccessCheck (sd, from_process_token, access, &access_mapping,
|
if (!AccessCheck (sd, from_process_token, access, &access_mapping,
|
||||||
&ps, &ps_len, &access, &status))
|
&ps, &ps_len, &access, &status))
|
||||||
{
|
{
|
||||||
log (LOG_ERR, "error checking access rights (%lu)",
|
log (LOG_ERR, "error checking access rights (err %u)", GetLastError ());
|
||||||
GetLastError ());
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,7 +142,7 @@ check_and_dup_handle (HANDLE from_process, HANDLE to_process,
|
|||||||
to_process, to_handle_ptr,
|
to_process, to_handle_ptr,
|
||||||
access, bInheritHandle, 0))
|
access, bInheritHandle, 0))
|
||||||
{
|
{
|
||||||
log (LOG_ERR, "error getting handle to client (%lu)", GetLastError ());
|
log (LOG_ERR, "error getting handle to client (err %u)", GetLastError ());
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,8 +190,7 @@ client_request_attach_tty::serve (transport_layer_base *const conn,
|
|||||||
|
|
||||||
if (!from_process_handle)
|
if (!from_process_handle)
|
||||||
{
|
{
|
||||||
log (LOG_ERR, "error opening `from' process, error = %lu",
|
log (LOG_ERR, "error opening `from' process (err %u)", GetLastError ());
|
||||||
GetLastError ());
|
|
||||||
error_code (EACCES);
|
error_code (EACCES);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -204,8 +202,7 @@ client_request_attach_tty::serve (transport_layer_base *const conn,
|
|||||||
|
|
||||||
if (!to_process_handle)
|
if (!to_process_handle)
|
||||||
{
|
{
|
||||||
log (LOG_ERR, "error opening `to' process, error = %lu",
|
log (LOG_ERR, "error opening `to' process (err %u)", GetLastError ());
|
||||||
GetLastError ());
|
|
||||||
CloseHandle (from_process_handle);
|
CloseHandle (from_process_handle);
|
||||||
error_code (EACCES);
|
error_code (EACCES);
|
||||||
return;
|
return;
|
||||||
@ -228,7 +225,7 @@ client_request_attach_tty::serve (transport_layer_base *const conn,
|
|||||||
TRUE,
|
TRUE,
|
||||||
&token_handle);
|
&token_handle);
|
||||||
|
|
||||||
debug ("opened thread token, rc=%lu", rc);
|
debug ("opened thread token, rc=%u", rc);
|
||||||
if (!conn->revert_to_self ())
|
if (!conn->revert_to_self ())
|
||||||
{
|
{
|
||||||
CloseHandle (from_process_handle);
|
CloseHandle (from_process_handle);
|
||||||
@ -239,8 +236,7 @@ client_request_attach_tty::serve (transport_layer_base *const conn,
|
|||||||
|
|
||||||
if (!rc)
|
if (!rc)
|
||||||
{
|
{
|
||||||
log (LOG_ERR, "error opening thread token, error = %lu",
|
log (LOG_ERR, "error opening thread token (err %u)", GetLastError ());
|
||||||
GetLastError ());
|
|
||||||
CloseHandle (from_process_handle);
|
CloseHandle (from_process_handle);
|
||||||
CloseHandle (to_process_handle);
|
CloseHandle (to_process_handle);
|
||||||
error_code (EACCES);
|
error_code (EACCES);
|
||||||
@ -264,7 +260,7 @@ client_request_attach_tty::serve (transport_layer_base *const conn,
|
|||||||
from_master,
|
from_master,
|
||||||
&req.from_master, TRUE) != 0)
|
&req.from_master, TRUE) != 0)
|
||||||
{
|
{
|
||||||
log (LOG_ERR, "error duplicating from_master handle, error = %lu",
|
log (LOG_ERR, "error duplicating from_master handle (err %u)",
|
||||||
GetLastError ());
|
GetLastError ());
|
||||||
error_code (EACCES);
|
error_code (EACCES);
|
||||||
}
|
}
|
||||||
@ -276,7 +272,7 @@ client_request_attach_tty::serve (transport_layer_base *const conn,
|
|||||||
to_master,
|
to_master,
|
||||||
&req.to_master, TRUE) != 0)
|
&req.to_master, TRUE) != 0)
|
||||||
{
|
{
|
||||||
log (LOG_ERR, "error duplicating to_master handle, error = %lu",
|
log (LOG_ERR, "error duplicating to_master handle (err %u)",
|
||||||
GetLastError ());
|
GetLastError ());
|
||||||
error_code (EACCES);
|
error_code (EACCES);
|
||||||
}
|
}
|
||||||
@ -285,9 +281,8 @@ client_request_attach_tty::serve (transport_layer_base *const conn,
|
|||||||
CloseHandle (to_process_handle);
|
CloseHandle (to_process_handle);
|
||||||
CloseHandle (token_handle);
|
CloseHandle (token_handle);
|
||||||
|
|
||||||
debug ("%lu(%lu, %lu) -> %lu(%lu,%lu)",
|
debug ("%u(%p, %p) -> %u(%p,%p)", req.master_pid, from_master, to_master,
|
||||||
req.master_pid, from_master, to_master,
|
req.pid, req.from_master, req.to_master);
|
||||||
req.pid, req.from_master, req.to_master);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -374,7 +369,7 @@ server_submission_loop::request_loop ()
|
|||||||
*/
|
*/
|
||||||
if (!SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST + 1))
|
if (!SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST + 1))
|
||||||
if (!SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST))
|
if (!SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST))
|
||||||
debug ("failed to raise accept thread priority, error = %lu",
|
debug ("failed to raise accept thread priority (err %u)",
|
||||||
GetLastError ());
|
GetLastError ());
|
||||||
|
|
||||||
while (_running)
|
while (_running)
|
||||||
@ -393,7 +388,7 @@ server_submission_loop::request_loop ()
|
|||||||
if (!conn && errno == EINTR)
|
if (!conn && errno == EINTR)
|
||||||
{
|
{
|
||||||
if (!SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_NORMAL))
|
if (!SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_NORMAL))
|
||||||
debug ("failed to reset thread priority, error = %lu",
|
debug ("failed to reset thread priority (err %u)",
|
||||||
GetLastError ());
|
GetLastError ());
|
||||||
|
|
||||||
Sleep (0);
|
Sleep (0);
|
||||||
@ -401,7 +396,7 @@ server_submission_loop::request_loop ()
|
|||||||
THREAD_PRIORITY_HIGHEST + 1))
|
THREAD_PRIORITY_HIGHEST + 1))
|
||||||
if (!SetThreadPriority (GetCurrentThread (),
|
if (!SetThreadPriority (GetCurrentThread (),
|
||||||
THREAD_PRIORITY_HIGHEST))
|
THREAD_PRIORITY_HIGHEST))
|
||||||
debug ("failed to raise thread priority, error = %lu",
|
debug ("failed to raise thread priority (err %u)",
|
||||||
GetLastError ());
|
GetLastError ());
|
||||||
}
|
}
|
||||||
if (conn)
|
if (conn)
|
||||||
@ -534,9 +529,9 @@ main (const int argc, char *argv[])
|
|||||||
|
|
||||||
const char opts[] = "c:deEf:hl:mp:qr:sSVyY";
|
const char opts[] = "c:deEf:hl:mp:qr:sSVyY";
|
||||||
|
|
||||||
long cleanup_threads = 0;
|
int32_t cleanup_threads = 0;
|
||||||
long request_threads = 0;
|
int32_t request_threads = 0;
|
||||||
long process_cache_size = 0;
|
int32_t process_cache_size = 0;
|
||||||
bool shutdown = false;
|
bool shutdown = false;
|
||||||
const char *config_file = DEF_CONFIG_FILE;
|
const char *config_file = DEF_CONFIG_FILE;
|
||||||
bool force_config_file = false;
|
bool force_config_file = false;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* msg.cc: Single unix specification IPC interface for Cygwin.
|
/* msg.cc: Single unix specification IPC interface for Cygwin.
|
||||||
|
|
||||||
Copyright 2003, 2004 Red Hat, Inc.
|
Copyright 2003, 2004, 2012 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* process.h
|
/* process.h
|
||||||
|
|
||||||
Copyright 2001, 2002, 2003, 2004, 2005 Red Hat Inc.
|
Copyright 2001, 2002, 2003, 2004, 2005, 2012 Red Hat Inc.
|
||||||
|
|
||||||
Written by Robert Collins <rbtcollins@hotmail.com>
|
Written by Robert Collins <rbtcollins@hotmail.com>
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ private:
|
|||||||
const DWORD _winpid;
|
const DWORD _winpid;
|
||||||
HANDLE _hProcess;
|
HANDLE _hProcess;
|
||||||
HANDLE _signal_arrived;
|
HANDLE _signal_arrived;
|
||||||
long _cleaning_up;
|
LONG _cleaning_up;
|
||||||
DWORD _exit_status; // Set in the constructor and in exit_code ().
|
DWORD _exit_status; // Set in the constructor and in exit_code ().
|
||||||
cleanup_routine *_routines_head;
|
cleanup_routine *_routines_head;
|
||||||
/* used to prevent races-on-delete */
|
/* used to prevent races-on-delete */
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* sem.cc: Single unix specification IPC interface for Cygwin.
|
/* sem.cc: Single unix specification IPC interface for Cygwin.
|
||||||
|
|
||||||
Copyright 2003, 2004 Red Hat, Inc.
|
Copyright 2003, 2004, 2012 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* shm.cc: Single unix specification IPC interface for Cygwin.
|
/* shm.cc: Single unix specification IPC interface for Cygwin.
|
||||||
|
|
||||||
Copyright 2003, 2004 Red Hat, Inc.
|
Copyright 2003, 2004, 2012 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
@ -258,7 +258,7 @@ shm_delete_mapping(struct vmspace *vm, struct shmmap_state *shmmap_s)
|
|||||||
{
|
{
|
||||||
struct shmid_ds *shmseg;
|
struct shmid_ds *shmseg;
|
||||||
int segnum, result;
|
int segnum, result;
|
||||||
size_t size;
|
size_t size __attribute__ ((unused));
|
||||||
|
|
||||||
GIANT_REQUIRED;
|
GIANT_REQUIRED;
|
||||||
|
|
||||||
@ -335,7 +335,7 @@ int
|
|||||||
kern_shmat(struct thread *td, int shmid, const void *shmaddr, int shmflg)
|
kern_shmat(struct thread *td, int shmid, const void *shmaddr, int shmflg)
|
||||||
{
|
{
|
||||||
struct proc *p = td->td_proc;
|
struct proc *p = td->td_proc;
|
||||||
int i, flags;
|
int i, flags __attribute__ ((unused));
|
||||||
struct shmid_ds *shmseg;
|
struct shmid_ds *shmseg;
|
||||||
struct shmmap_state *shmmap_s = NULL;
|
struct shmmap_state *shmmap_s = NULL;
|
||||||
#ifndef __CYGWIN__
|
#ifndef __CYGWIN__
|
||||||
@ -512,7 +512,7 @@ done2:
|
|||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif /* __CYGWIN__ */
|
#endif /* !__CYGWIN__ */
|
||||||
|
|
||||||
#ifndef _SYS_SYSPROTO_H_
|
#ifndef _SYS_SYSPROTO_H_
|
||||||
struct shmctl_args {
|
struct shmctl_args {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* threaded_queue.h
|
/* threaded_queue.h
|
||||||
|
|
||||||
Copyright 2001, 2002, 2003 Red Hat Inc.
|
Copyright 2001, 2002, 2003, 2012 Red Hat Inc.
|
||||||
|
|
||||||
Written by Robert Collins <rbtcollins@hotmail.com>
|
Written by Robert Collins <rbtcollins@hotmail.com>
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ public:
|
|||||||
void add (queue_request *);
|
void add (queue_request *);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
long _workers_count;
|
LONG _workers_count;
|
||||||
bool _running;
|
bool _running;
|
||||||
|
|
||||||
queue_submission_loop *_submitters_head;
|
queue_submission_loop *_submitters_head;
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
2013-04-23 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* Merge in cygwin-64bit-branch. See ChangeLog.64bit for details.
|
||||||
|
|
||||||
2013-04-22 Corinna Vinschen <corinna@vinschen.de>
|
2013-04-22 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* include/sys/queue.h: Delete in favor of more complete newlib file.
|
* include/sys/queue.h: Delete in favor of more complete newlib file.
|
||||||
|
1877
winsup/cygwin/ChangeLog.64bit
Normal file
1877
winsup/cygwin/ChangeLog.64bit
Normal file
File diff suppressed because it is too large
Load Diff
@ -31,6 +31,7 @@ export CCWRAP_DIRAFTER_HEADERS:=@windows_headers@
|
|||||||
|
|
||||||
VPATH+=$(CONFIG_DIR) $(srcdir)/regex $(srcdir)/lib $(srcdir)/libc
|
VPATH+=$(CONFIG_DIR) $(srcdir)/regex $(srcdir)/lib $(srcdir)/libc
|
||||||
|
|
||||||
|
target_cpu:=@target_cpu@
|
||||||
target_alias:=@target_alias@
|
target_alias:=@target_alias@
|
||||||
build_alias:=@build_alias@
|
build_alias:=@build_alias@
|
||||||
host_alias:=@host_alias@
|
host_alias:=@host_alias@
|
||||||
@ -76,6 +77,9 @@ MT_SAFE:=@MT_SAFE@
|
|||||||
DEFS:=@DEFS@
|
DEFS:=@DEFS@
|
||||||
CCEXTRA=
|
CCEXTRA=
|
||||||
COMMON_CFLAGS=-MMD ${$(*F)_CFLAGS} -Werror -fmerge-constants -ftracer $(CCEXTRA)
|
COMMON_CFLAGS=-MMD ${$(*F)_CFLAGS} -Werror -fmerge-constants -ftracer $(CCEXTRA)
|
||||||
|
ifeq ($(target_cpu),x86_64)
|
||||||
|
COMMON_CFLAGS+=-mcmodel=small
|
||||||
|
endif
|
||||||
COMPILE.cc+=${COMMON_CFLAGS} -mno-use-libstdc-wrappers
|
COMPILE.cc+=${COMMON_CFLAGS} -mno-use-libstdc-wrappers
|
||||||
COMPILE.c+=${COMMON_CFLAGS}
|
COMPILE.c+=${COMMON_CFLAGS}
|
||||||
|
|
||||||
@ -110,23 +114,26 @@ RUNTESTFLAGS =
|
|||||||
# native rebuilding issues (we don't want the build tools to see a partially
|
# native rebuilding issues (we don't want the build tools to see a partially
|
||||||
# built cygwin.dll and attempt to use it instead of the old one).
|
# built cygwin.dll and attempt to use it instead of the old one).
|
||||||
|
|
||||||
DLL_NAME:=cygwin1.dll
|
DLL_NAME:=@DLL_NAME@
|
||||||
TEST_DLL_NAME:=cygwin0.dll
|
TEST_DLL_NAME:=${patsubst %1.dll,%0.dll,@DLL_NAME@}
|
||||||
TEST_LIB_NAME:=libcygwin0.a
|
TEST_LIB_NAME:=libcygwin0.a
|
||||||
STATIC_LIB_NAME:=libcygwin_s.a
|
STATIC_LIB_NAME:=libcygwin_s.a
|
||||||
|
DIN_FILE=@DIN_FILE@
|
||||||
DEF_FILE:=cygwin.def
|
DEF_FILE:=cygwin.def
|
||||||
|
TLSOFFSETS_H:=@TLSOFFSETS_H@
|
||||||
DLL_ENTRY:=@DLL_ENTRY@
|
DLL_ENTRY:=@DLL_ENTRY@
|
||||||
|
|
||||||
LIBGMON_A:=libgmon.a
|
LIBGMON_A:=libgmon.a
|
||||||
CYGWIN_START:=crt0.o
|
CYGWIN_START:=crt0.o
|
||||||
GMON_START:=gcrt0.o
|
GMON_START:=gcrt0.o
|
||||||
|
|
||||||
toolopts:=--ar=${AR} --as=${AS} --nm=${NM} --objcopy=${OBJCOPY}
|
toolopts:=--cpu=${target_cpu} --ar=${AR} --as=${AS} --nm=${NM} --objcopy=${OBJCOPY}
|
||||||
speclib=\
|
speclib=\
|
||||||
${srcdir}/speclib ${toolopts} \
|
${srcdir}/speclib ${toolopts} \
|
||||||
--exclude='cygwin' \
|
--exclude='cygwin' \
|
||||||
--exclude='(?i:dll)' \
|
--exclude='(?i:dll)' \
|
||||||
--exclude='reloc' \
|
--exclude='reloc' \
|
||||||
|
--exclude='^main$$' \
|
||||||
--exclude='^_main$$' \
|
--exclude='^_main$$' \
|
||||||
$^
|
$^
|
||||||
|
|
||||||
@ -143,7 +150,7 @@ EXTRA_DLL_OFILES:=${addsuffix .o,${basename ${notdir ${wildcard $(CONFIG_DIR)/*.
|
|||||||
|
|
||||||
EXTRA_OFILES:=
|
EXTRA_OFILES:=
|
||||||
|
|
||||||
MALLOC_OFILES:=@MALLOC_OFILES@
|
MALLOC_OFILES:=malloc.o
|
||||||
|
|
||||||
DLL_IMPORTS:=${shell $(CC) -print-file-name=w32api/libkernel32.a} ${shell $(CC) -print-file-name=w32api/libntdll.a}
|
DLL_IMPORTS:=${shell $(CC) -print-file-name=w32api/libkernel32.a} ${shell $(CC) -print-file-name=w32api/libntdll.a}
|
||||||
|
|
||||||
@ -193,6 +200,9 @@ endif #PREPROCESS
|
|||||||
|
|
||||||
GMON_OFILES:=gmon.o mcount.o profil.o
|
GMON_OFILES:=gmon.o mcount.o profil.o
|
||||||
|
|
||||||
|
ifeq ($(target_cpu),x86_64)
|
||||||
|
NEW_FUNCTIONS:=
|
||||||
|
else
|
||||||
NEW_FUNCTIONS:=$(addprefix --replace=,\
|
NEW_FUNCTIONS:=$(addprefix --replace=,\
|
||||||
acl=_acl32 \
|
acl=_acl32 \
|
||||||
aclcheck=_aclcheck32 \
|
aclcheck=_aclcheck32 \
|
||||||
@ -245,6 +255,7 @@ NEW_FUNCTIONS:=$(addprefix --replace=,\
|
|||||||
tmpfile=_tmpfile64 \
|
tmpfile=_tmpfile64 \
|
||||||
truncate=_truncate64 \
|
truncate=_truncate64 \
|
||||||
)
|
)
|
||||||
|
endif
|
||||||
|
|
||||||
API_VER:=$(srcdir)/include/cygwin/version.h
|
API_VER:=$(srcdir)/include/cygwin/version.h
|
||||||
|
|
||||||
@ -390,20 +401,20 @@ uninstall-headers:
|
|||||||
uninstall-man:
|
uninstall-man:
|
||||||
cd $(srcdir); \
|
cd $(srcdir); \
|
||||||
for i in `find . -type f -name '*.2'`; do \
|
for i in `find . -type f -name '*.2'`; do \
|
||||||
rm -f $(tooldir)/man/man2/`basename $$i` ; \
|
rm -f $(DESTDIR)$(mandir)/man2/`basename $$i` ; \
|
||||||
done; \
|
done; \
|
||||||
for i in `find . -type f -name '*.3'`; do \
|
for i in `find . -type f -name '*.3'`; do \
|
||||||
rm -f $(tooldir)/man/man3/`basename $$i` ; \
|
rm -f $(DESTDIR)$(mandir)/man3/`basename $$i` ; \
|
||||||
done; \
|
done; \
|
||||||
for i in `find . -type f -name '*.5'`; do \
|
for i in `find . -type f -name '*.5'`; do \
|
||||||
rm -f $(tooldir)/man/man5/`basename $$i` ; \
|
rm -f $(DESTDIR)$(mandir)/man5/`basename $$i` ; \
|
||||||
done; \
|
done; \
|
||||||
for i in `find . -type f -name '*.7'`; do \
|
for i in `find . -type f -name '*.7'`; do \
|
||||||
rm -f $(tooldir)/man/man7/`basename $$i` ; \
|
rm -f $(DESTDIR)$(mandir)/man7/`basename $$i` ; \
|
||||||
done
|
done
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
-rm -f *.o *.dll *.dbg *.a *.exp junk *.base version.cc winver_stamp *.exe *.d *stamp* *_magic.h sigfe.s cygwin.def globals.h $(srcdir)/tlsoffsets.h $(srcdir)/devices.cc
|
-rm -f *.o *.dll *.dbg *.a *.exp junk *.base version.cc winver_stamp *.exe *.d *stamp* *_magic.h sigfe.s cygwin.def globals.h $(srcdir)/$(TLSOFFSETS_H) $(srcdir)/devices.cc
|
||||||
-@$(MAKE) -C ${cygserver_blddir} libclean
|
-@$(MAKE) -C ${cygserver_blddir} libclean
|
||||||
|
|
||||||
maintainer-clean realclean: clean
|
maintainer-clean realclean: clean
|
||||||
@ -411,6 +422,9 @@ maintainer-clean realclean: clean
|
|||||||
@echo "it deletes files that may require special tools to rebuild."
|
@echo "it deletes files that may require special tools to rebuild."
|
||||||
-rm -fr configure
|
-rm -fr configure
|
||||||
|
|
||||||
|
# Rule to build LDSCRIPT
|
||||||
|
$(LDSCRIPT): $(LDSCRIPT).in
|
||||||
|
$(CC) -E - -P < $^ -o $@
|
||||||
|
|
||||||
# Rule to build cygwin.dll
|
# Rule to build cygwin.dll
|
||||||
$(TEST_DLL_NAME): $(LDSCRIPT) dllfixdbg $(DLL_OFILES) $(LIBSERVER) $(LIBC) $(LIBM) $(API_VER) Makefile winver_stamp
|
$(TEST_DLL_NAME): $(LDSCRIPT) dllfixdbg $(DLL_OFILES) $(LIBSERVER) $(LIBC) $(LIBM) $(API_VER) Makefile winver_stamp
|
||||||
@ -423,8 +437,8 @@ $(TEST_DLL_NAME): $(LDSCRIPT) dllfixdbg $(DLL_OFILES) $(LIBSERVER) $(LIBC) $(LIB
|
|||||||
@ln -f $@ new-$(DLL_NAME)
|
@ln -f $@ new-$(DLL_NAME)
|
||||||
|
|
||||||
# Rule to build libcygwin.a
|
# Rule to build libcygwin.a
|
||||||
$(LIB_NAME): $(LIBCOS) | $(TEST_DLL_NAME)
|
$(LIB_NAME): $(DEF_FILE) $(LIBCOS) | $(TEST_DLL_NAME)
|
||||||
${srcdir}/mkimport ${toolopts} ${NEW_FUNCTIONS} $@ cygdll.a $^
|
${srcdir}/mkimport ${toolopts} ${NEW_FUNCTIONS} $@ cygdll.a $(wordlist 2,99,$^)
|
||||||
|
|
||||||
${STATIC_LIB_NAME}: mkstatic ${TEST_DLL_NAME}
|
${STATIC_LIB_NAME}: mkstatic ${TEST_DLL_NAME}
|
||||||
perl -d $< -x ${EXCLUDE_STATIC_OFILES} --library=${LIBC} --library=${LIBM} --ar=${AR} $@ cygwin.map
|
perl -d $< -x ${EXCLUDE_STATIC_OFILES} --library=${LIBC} --library=${LIBM} --ar=${AR} $@ cygwin.map
|
||||||
@ -446,7 +460,7 @@ dll_ofiles: $(DLL_OFILES)
|
|||||||
$(LIBGMON_A): $(GMON_OFILES) $(GMON_START)
|
$(LIBGMON_A): $(GMON_OFILES) $(GMON_START)
|
||||||
$(AR) rcv $(LIBGMON_A) $(GMON_OFILES)
|
$(AR) rcv $(LIBGMON_A) $(GMON_OFILES)
|
||||||
|
|
||||||
$(API_VER): $(srcdir)/cygwin.din
|
$(API_VER): $(srcdir)/$(DIN_FILE)
|
||||||
@echo Error: Version info is older than DLL API!
|
@echo Error: Version info is older than DLL API!
|
||||||
|
|
||||||
version.cc winver.o: winver_stamp
|
version.cc winver.o: winver_stamp
|
||||||
@ -500,14 +514,14 @@ winver_stamp: mkvers.sh include/cygwin/version.h winver.rc $(DLL_OFILES)
|
|||||||
$(COMPILE.cc) -c -o version.o version.cc && \
|
$(COMPILE.cc) -c -o version.o version.cc && \
|
||||||
touch $@
|
touch $@
|
||||||
|
|
||||||
Makefile: cygwin.din ${srcdir}/Makefile.in
|
Makefile: $(DIN_FILE) ${srcdir}/Makefile.in
|
||||||
/bin/sh ./config.status
|
/bin/sh ./config.status
|
||||||
|
|
||||||
$(DEF_FILE): gendef cygwin.din $(srcdir)/tlsoffsets.h
|
$(DEF_FILE): gendef $(DIN_FILE) $(srcdir)/$(TLSOFFSETS_H)
|
||||||
$^ $@ sigfe.s
|
$^ $(target_cpu) $@ sigfe.s
|
||||||
|
|
||||||
$(srcdir)/tlsoffsets.h: gentls_offsets cygtls.h
|
$(srcdir)/$(TLSOFFSETS_H): gentls_offsets cygtls.h
|
||||||
$^ $@ $(COMPILE.cc) -c
|
$^ $@ @CONFIG_DIR@ $(COMPILE.cc) -c
|
||||||
|
|
||||||
sigfe.s: $(DEF_FILE)
|
sigfe.s: $(DEF_FILE)
|
||||||
@[ -s $@ ] || \
|
@[ -s $@ ] || \
|
||||||
|
6
winsup/cygwin/aclocal.m4
vendored
6
winsup/cygwin/aclocal.m4
vendored
@ -1,7 +1,7 @@
|
|||||||
# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
|
# generated automatically by aclocal 1.12.1 -*- Autoconf -*-
|
||||||
|
|
||||||
|
# Copyright (C) 1996-2012 Free Software Foundation, Inc.
|
||||||
|
|
||||||
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
|
||||||
# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
|
|
||||||
# This file is free software; the Free Software Foundation
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
# with or without modifications, as long as this notice is preserved.
|
# with or without modifications, as long as this notice is preserved.
|
||||||
|
@ -43,7 +43,7 @@ DuplicateTokenEx (HANDLE tok, DWORD access, LPSECURITY_ATTRIBUTES sec_attr,
|
|||||||
OBJECT_ATTRIBUTES attr =
|
OBJECT_ATTRIBUTES attr =
|
||||||
{ sizeof attr, NULL, NULL,
|
{ sizeof attr, NULL, NULL,
|
||||||
(sec_attr && sec_attr->bInheritHandle) ? OBJ_INHERIT : 0U,
|
(sec_attr && sec_attr->bInheritHandle) ? OBJ_INHERIT : 0U,
|
||||||
(sec_attr ? sec_attr->lpSecurityDescriptor : NULL), &sqos };
|
sec_attr ? sec_attr->lpSecurityDescriptor : NULL, &sqos };
|
||||||
NTSTATUS status = NtDuplicateToken (tok, access, &attr, FALSE, type, new_tok);
|
NTSTATUS status = NtDuplicateToken (tok, access, &attr, FALSE, type, new_tok);
|
||||||
DEFAULT_NTSTATUS_TO_BOOL_RETURN
|
DEFAULT_NTSTATUS_TO_BOOL_RETURN
|
||||||
}
|
}
|
||||||
|
@ -32,34 +32,60 @@ bool NO_COPY wsock_started;
|
|||||||
*
|
*
|
||||||
* So, immediately following the the call to one of the above routines
|
* So, immediately following the the call to one of the above routines
|
||||||
* we have:
|
* we have:
|
||||||
* DLL info (4 bytes) Pointer to a block of information concerning
|
* DLL info (4/8 bytes) Pointer to a block of information concerning
|
||||||
* the DLL (see below).
|
* the DLL (see below).
|
||||||
* DLL args (4 bytes) The number of arguments pushed on the stack by
|
* DLL args (4 bytes) The number of arguments pushed on the stack by
|
||||||
* the call. If this is an odd value then this
|
* the call. If this is an odd value then this
|
||||||
* is a flag that non-existence of this function
|
* is a flag that non-existence of this function
|
||||||
* is not a fatal error
|
* is not a fatal error
|
||||||
|
* func addr (8 bytes) (64 bit ONLY!)
|
||||||
|
* Address of the actual Win32 function. For the
|
||||||
|
* reason why this is necessary, see the below
|
||||||
|
* description of the load_state.
|
||||||
* func name (n bytes) asciz string containing the name of the function
|
* func name (n bytes) asciz string containing the name of the function
|
||||||
* to be loaded.
|
* to be loaded.
|
||||||
*
|
*
|
||||||
* The DLL info block consists of the following
|
* The DLL info block consists of the following
|
||||||
* load_state (4 bytes) Pointer to a word containing the routine used
|
* load_state (4/8 bytes) Pointer to a word containing the routine used
|
||||||
* to eventually invoke the function. Initially
|
* to eventually invoke the function. Initially
|
||||||
* points to an init function which loads the
|
* points to an init function which loads the DLL,
|
||||||
* DLL, gets the process's load address,
|
* gets the process's load address, changes the contents
|
||||||
* changes the contents here to point to the
|
* here to point to the function address, and changes
|
||||||
* function address, and changes the call *(%eax)
|
* the address argument of the initial jmp call.
|
||||||
* to a jmp func. If the initialization has been
|
* On 64 bit, the jmp is not tweaked directly. Rather,
|
||||||
* done, only the load part is done.
|
* the address of the Win32 function is stored in the
|
||||||
* DLL handle (4 bytes) The handle to use when loading the DLL.
|
* aforementioned Win32 function address slot and fetched
|
||||||
|
* there for a jmp *%rax call. This indirection is
|
||||||
|
* necessary to workaround the lack of a jmp opcode with
|
||||||
|
* offset values > 32 bit. If the initialization has
|
||||||
|
* been done, only the load part is done.
|
||||||
|
* DLL handle (4/8 bytes) The handle to use when loading the DLL.
|
||||||
* DLL locker (4 bytes) Word to use to avoid multi-thread access during
|
* DLL locker (4 bytes) Word to use to avoid multi-thread access during
|
||||||
* initialization.
|
* initialization.
|
||||||
* extra init (4 bytes) Extra initialization function.
|
* extra init (4/8 bytes) Extra initialization function.
|
||||||
* DLL name (n bytes) asciz string containing the name of the DLL.
|
* DLL name (n bytes) asciz string containing the name of the DLL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* LoadDLLprime is used to prime the DLL info information, providing an
|
/* LoadDLLprime is used to prime the DLL info information, providing an
|
||||||
additional initialization routine to call prior to calling the first
|
additional initialization routine to call prior to calling the first
|
||||||
function. */
|
function. */
|
||||||
|
#ifdef __x86_64__
|
||||||
|
#define LoadDLLprime(dllname, init_also, no_resolve_on_fork) __asm__ (" \n\
|
||||||
|
.ifndef " #dllname "_primed \n\
|
||||||
|
.section .data_cygwin_nocopy,\"w\" \n\
|
||||||
|
.align 8 \n\
|
||||||
|
."#dllname "_info: \n\
|
||||||
|
.quad _std_dll_init \n\
|
||||||
|
.quad " #no_resolve_on_fork " \n\
|
||||||
|
.long -1 \n\
|
||||||
|
.align 8 \n\
|
||||||
|
.quad " #init_also " \n\
|
||||||
|
.string16 \"" #dllname ".dll\" \n\
|
||||||
|
.text \n\
|
||||||
|
.set " #dllname "_primed, 1 \n\
|
||||||
|
.endif \n\
|
||||||
|
");
|
||||||
|
#else
|
||||||
#define LoadDLLprime(dllname, init_also, no_resolve_on_fork) __asm__ (" \n\
|
#define LoadDLLprime(dllname, init_also, no_resolve_on_fork) __asm__ (" \n\
|
||||||
.ifndef " #dllname "_primed \n\
|
.ifndef " #dllname "_primed \n\
|
||||||
.section .data_cygwin_nocopy,\"w\" \n\
|
.section .data_cygwin_nocopy,\"w\" \n\
|
||||||
@ -74,6 +100,7 @@ bool NO_COPY wsock_started;
|
|||||||
.set " #dllname "_primed, 1 \n\
|
.set " #dllname "_primed, 1 \n\
|
||||||
.endif \n\
|
.endif \n\
|
||||||
");
|
");
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Create a "decorated" name */
|
/* Create a "decorated" name */
|
||||||
#define mangle(name, n) #name "@" #n
|
#define mangle(name, n) #name "@" #n
|
||||||
@ -88,6 +115,32 @@ bool NO_COPY wsock_started;
|
|||||||
LoadDLLfuncEx3(name, n, dllname, notimp, err, 0)
|
LoadDLLfuncEx3(name, n, dllname, notimp, err, 0)
|
||||||
|
|
||||||
/* Main DLL setup stuff. */
|
/* Main DLL setup stuff. */
|
||||||
|
#ifdef __x86_64__
|
||||||
|
#define LoadDLLfuncEx3(name, n, dllname, notimp, err, no_resolve_on_fork) \
|
||||||
|
LoadDLLprime (dllname, dll_func_load, no_resolve_on_fork) \
|
||||||
|
__asm__ (" \n\
|
||||||
|
.section ." #dllname "_autoload_text,\"wx\" \n\
|
||||||
|
.global " #name " \n\
|
||||||
|
.global _win32_" #name " \n\
|
||||||
|
.align 16 \n\
|
||||||
|
" #name ": \n\
|
||||||
|
_win32_" #name ": \n\
|
||||||
|
movq 3f(%rip),%rax \n\
|
||||||
|
jmp *%rax \n\
|
||||||
|
1:movq 2f(%rip),%rax \n\
|
||||||
|
push %rbp # Keep 16 byte aligned \n\
|
||||||
|
push %r9 \n\
|
||||||
|
push %r8 \n\
|
||||||
|
push %rdx \n\
|
||||||
|
push %rcx \n\
|
||||||
|
call *(%rax) \n\
|
||||||
|
2:.quad ." #dllname "_info \n\
|
||||||
|
.long (" #n "+" #notimp ") | (((" #err ") & 0xff) <<16) \n\
|
||||||
|
3:.quad 1b \n\
|
||||||
|
.asciz \"" #name "\" \n\
|
||||||
|
.text \n\
|
||||||
|
");
|
||||||
|
#else
|
||||||
#define LoadDLLfuncEx3(name, n, dllname, notimp, err, no_resolve_on_fork) \
|
#define LoadDLLfuncEx3(name, n, dllname, notimp, err, no_resolve_on_fork) \
|
||||||
LoadDLLprime (dllname, dll_func_load, no_resolve_on_fork) \
|
LoadDLLprime (dllname, dll_func_load, no_resolve_on_fork) \
|
||||||
__asm__ (" \n\
|
__asm__ (" \n\
|
||||||
@ -106,6 +159,7 @@ _win32_" mangle (name, n) ": \n\
|
|||||||
.asciz \"" #name "\" \n\
|
.asciz \"" #name "\" \n\
|
||||||
.text \n\
|
.text \n\
|
||||||
");
|
");
|
||||||
|
#endif
|
||||||
|
|
||||||
/* DLL loader helper functions used during initialization. */
|
/* DLL loader helper functions used during initialization. */
|
||||||
|
|
||||||
@ -121,6 +175,69 @@ extern "C" void dll_chain () __asm__ ("dll_chain");
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
|
#ifdef __x86_64__
|
||||||
|
__asm__ (" \n\
|
||||||
|
.section .rdata,\"r\" \n\
|
||||||
|
msg1: \n\
|
||||||
|
.ascii \"couldn't dynamically determine load address for '%s' (handle %p), %E\\0\"\n\
|
||||||
|
\n\
|
||||||
|
.text \n\
|
||||||
|
.p2align 4,,15 \n\
|
||||||
|
noload: \n\
|
||||||
|
movq 40(%rsp),%rdx # Get the address of the information block\n\
|
||||||
|
movl 8(%rdx),%eax # Should we 'ignore' the lack \n\
|
||||||
|
test $1,%eax # of this function? \n\
|
||||||
|
jz 1f # Nope. \n\
|
||||||
|
andl $0xffff0000,%eax# upper word (== desired return value) \n\
|
||||||
|
movl %eax,32(%rsp) # Save for later (in shadow space) \n\
|
||||||
|
movl $127,%ecx # ERROR_PROC_NOT_FOUND \n\
|
||||||
|
call SetLastError # Set it \n\
|
||||||
|
movl 32(%rsp),%eax # Get back return value \n\
|
||||||
|
sarl $16,%eax # swap to low order word \n\
|
||||||
|
addq $40,%rsp # Revert stack \n\
|
||||||
|
pop %r10 # Drop pointer to 'return address' \n\
|
||||||
|
pop %rcx # Restore arg registers \n\
|
||||||
|
pop %rdx \n\
|
||||||
|
pop %r8 \n\
|
||||||
|
pop %r9 \n\
|
||||||
|
pop %rbp # ...and restore frame pointer \n\
|
||||||
|
ret # Return \n\
|
||||||
|
1: \n\
|
||||||
|
movq (%rdx),%rax # Handle value \n\
|
||||||
|
movq 8(%rax),%r8 \n\
|
||||||
|
lea 20(%rdx),%rdx # Location of name of function \n\
|
||||||
|
lea msg1(%rip),%rcx # The message \n\
|
||||||
|
call api_fatal # Print message. Never returns \n\
|
||||||
|
\n\
|
||||||
|
.globl dll_func_load \n\
|
||||||
|
dll_func_load: \n\
|
||||||
|
movq (%rsp),%rdx # 'Return address' contains load info \n\
|
||||||
|
movq (%rdx),%rcx # Where handle lives \n\
|
||||||
|
movq 8(%rcx),%rcx # Address of Handle to DLL \n\
|
||||||
|
addq $20,%rdx # Address of name of function to load \n\
|
||||||
|
subq $40,%rsp # Shadow space + 8 byte for alignment \n\
|
||||||
|
call GetProcAddress # Load it \n\
|
||||||
|
test %rax,%rax # Success? \n\
|
||||||
|
jne gotit # Yes \n\
|
||||||
|
jmp noload # Issue an error or return \n\
|
||||||
|
gotit: \n\
|
||||||
|
addq $40,%rsp # Revert stack \n\
|
||||||
|
pop %r10 # Pointer to 'return address' \n\
|
||||||
|
movq %rax,12(%r10) # Move absolute address to address slot \n\
|
||||||
|
subq $25,%r10 # Point to jmp \n\
|
||||||
|
pop %rcx # Restore arg registers \n\
|
||||||
|
pop %rdx \n\
|
||||||
|
pop %r8 \n\
|
||||||
|
pop %r9 \n\
|
||||||
|
pop %rbp # ...and restore frame pointer \n\
|
||||||
|
jmp *%r10 # Jump to actual function \n\
|
||||||
|
\n\
|
||||||
|
.global dll_chain \n\
|
||||||
|
dll_chain: \n\
|
||||||
|
push %rax # Restore 'return address' \n\
|
||||||
|
jmp *%rdx # Jump to next init function \n\
|
||||||
|
");
|
||||||
|
#else
|
||||||
__asm__ (" \n\
|
__asm__ (" \n\
|
||||||
.text \n\
|
.text \n\
|
||||||
msg1: \n\
|
msg1: \n\
|
||||||
@ -177,13 +294,14 @@ dll_chain: \n\
|
|||||||
pushl %eax # Restore 'return address' \n\
|
pushl %eax # Restore 'return address' \n\
|
||||||
jmp *%edx # Jump to next init function \n\
|
jmp *%edx # Jump to next init function \n\
|
||||||
");
|
");
|
||||||
|
#endif
|
||||||
|
|
||||||
/* C representations of the two info blocks described above.
|
/* C representations of the two info blocks described above.
|
||||||
FIXME: These structures confuse gdb for some reason. GDB can print
|
FIXME: These structures confuse gdb for some reason. GDB can print
|
||||||
the whole structure but has problems with the name field? */
|
the whole structure but has problems with the name field? */
|
||||||
struct dll_info
|
struct dll_info
|
||||||
{
|
{
|
||||||
DWORD load_state;
|
UINT_PTR load_state;
|
||||||
HANDLE handle;
|
HANDLE handle;
|
||||||
LONG here;
|
LONG here;
|
||||||
void (*init) ();
|
void (*init) ();
|
||||||
@ -194,14 +312,22 @@ struct func_info
|
|||||||
{
|
{
|
||||||
struct dll_info *dll;
|
struct dll_info *dll;
|
||||||
LONG decoration;
|
LONG decoration;
|
||||||
|
#ifdef __x86_64__
|
||||||
|
UINT_PTR func_addr;
|
||||||
|
#endif
|
||||||
char name[];
|
char name[];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Mechanism for setting up info for passing to dll_chain routines. */
|
/* Mechanism for setting up info for passing to dll_chain routines. */
|
||||||
|
#ifdef __x86_64__
|
||||||
|
typedef __uint128_t two_addr_t;
|
||||||
|
#else
|
||||||
|
typedef __uint64_t two_addr_t;
|
||||||
|
#endif
|
||||||
union retchain
|
union retchain
|
||||||
{
|
{
|
||||||
struct {long high; long low;};
|
struct {uintptr_t high; uintptr_t low;};
|
||||||
long long ll;
|
two_addr_t ll;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -228,10 +354,56 @@ dll_load (HANDLE& handle, WCHAR *name)
|
|||||||
#define RETRY_COUNT 10
|
#define RETRY_COUNT 10
|
||||||
|
|
||||||
/* The standard DLL initialization routine. */
|
/* The standard DLL initialization routine. */
|
||||||
__attribute__ ((used, noinline)) static long long
|
#ifdef __x86_64__
|
||||||
|
|
||||||
|
/* On x86_64, we need assembler wrappers for std_dll_init and wsock_init.
|
||||||
|
In the x86_64 ABI it's no safe bet that frame[1] (aka 8(%rbp)) contains
|
||||||
|
the return address. Consequentially, if we try to overwrite frame[1]
|
||||||
|
with the address of dll_chain, we end up with a scrambled stack, the
|
||||||
|
result depending on the optimization settings and the current frame of
|
||||||
|
mind of the compiler. So for x86_64, we disable overwriting the return
|
||||||
|
address in the real std_dll_init/wsock_init function, but rather do this
|
||||||
|
in the wrapper, after return from the function, when we exactly know
|
||||||
|
where the original return address is stored on the stack. */
|
||||||
|
|
||||||
|
#define INIT_WRAPPER(func) \
|
||||||
|
__asm__ (" \n\
|
||||||
|
.text \n\
|
||||||
|
.p2align 4,,15 \n\
|
||||||
|
.seh_proc _" #func " \n\
|
||||||
|
_" #func ": \n\
|
||||||
|
pushq %rbp \n\
|
||||||
|
.seh_pushreg %rbp \n\
|
||||||
|
movq %rsp,%rbp \n\
|
||||||
|
.seh_setframe %rbp,0 \n\
|
||||||
|
subq $0x20,%rsp \n\
|
||||||
|
.seh_stackalloc 32 \n\
|
||||||
|
.seh_endprologue \n\
|
||||||
|
movq 0x28(%rsp),%rcx # return address as parameter \n\
|
||||||
|
call " #func " \n\
|
||||||
|
movdqa %xmm0,0x10(%rsp) # 128 bit return value in xmm0 \n\
|
||||||
|
movq 0x10(%rsp),%rax # copy over to %rax and %rdx \n\
|
||||||
|
movq 0x18(%rsp),%rdx \n\
|
||||||
|
leaq dll_chain(%rip),%rcx # load address of dll_chain \n\
|
||||||
|
movq %rcx,0x28(%rsp) # and overwrite return address \n\
|
||||||
|
addq $0x20,%rsp \n\
|
||||||
|
popq %rbp \n\
|
||||||
|
ret \n\
|
||||||
|
.seh_endproc \n\
|
||||||
|
");
|
||||||
|
|
||||||
|
INIT_WRAPPER (std_dll_init)
|
||||||
|
|
||||||
|
__attribute__ ((used, noinline)) static two_addr_t
|
||||||
|
std_dll_init (struct func_info *func)
|
||||||
|
#else
|
||||||
|
__attribute__ ((used, noinline)) static two_addr_t
|
||||||
std_dll_init ()
|
std_dll_init ()
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
|
#ifndef __x86_64__
|
||||||
struct func_info *func = (struct func_info *) __builtin_return_address (0);
|
struct func_info *func = (struct func_info *) __builtin_return_address (0);
|
||||||
|
#endif
|
||||||
struct dll_info *dll = func->dll;
|
struct dll_info *dll = func->dll;
|
||||||
retchain ret;
|
retchain ret;
|
||||||
|
|
||||||
@ -284,26 +456,38 @@ std_dll_init ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Set "arguments" for dll_chain. */
|
/* Set "arguments" for dll_chain. */
|
||||||
ret.low = (long) dll->init;
|
ret.low = (uintptr_t) dll->init;
|
||||||
ret.high = (long) func;
|
ret.high = (uintptr_t) func;
|
||||||
|
|
||||||
InterlockedDecrement (&dll->here);
|
InterlockedDecrement (&dll->here);
|
||||||
|
|
||||||
|
#ifndef __x86_64__
|
||||||
/* Kludge alert. Redirects the return address to dll_chain. */
|
/* Kludge alert. Redirects the return address to dll_chain. */
|
||||||
__asm__ __volatile__ (" \n\
|
uintptr_t *volatile frame = (uintptr_t *) __builtin_frame_address (0);
|
||||||
movl $dll_chain,4(%ebp) \n\
|
frame[1] = (uintptr_t) dll_chain;
|
||||||
");
|
#endif
|
||||||
|
|
||||||
return ret.ll;
|
return ret.ll;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialization function for winsock stuff. */
|
/* Initialization function for winsock stuff. */
|
||||||
WSADATA NO_COPY wsadata;
|
WSADATA NO_COPY wsadata;
|
||||||
static long long __attribute__ ((used, noinline))
|
|
||||||
|
#ifdef __x86_64__
|
||||||
|
/* See above comment preceeding std_dll_init. */
|
||||||
|
INIT_WRAPPER (wsock_init)
|
||||||
|
|
||||||
|
__attribute__ ((used, noinline)) static two_addr_t
|
||||||
|
wsock_init (struct func_info *func)
|
||||||
|
#else
|
||||||
|
__attribute__ ((used, noinline)) static two_addr_t
|
||||||
wsock_init ()
|
wsock_init ()
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
static LONG NO_COPY here = -1L;
|
static LONG NO_COPY here = -1L;
|
||||||
|
#ifndef __x86_64__
|
||||||
struct func_info *func = (struct func_info *) __builtin_return_address (0);
|
struct func_info *func = (struct func_info *) __builtin_return_address (0);
|
||||||
|
#endif
|
||||||
struct dll_info *dll = func->dll;
|
struct dll_info *dll = func->dll;
|
||||||
|
|
||||||
while (InterlockedIncrement (&here))
|
while (InterlockedIncrement (&here))
|
||||||
@ -330,23 +514,23 @@ wsock_init ()
|
|||||||
debug_printf ("szSystemStatus %s", wsadata.szSystemStatus);
|
debug_printf ("szSystemStatus %s", wsadata.szSystemStatus);
|
||||||
debug_printf ("iMaxSockets %d", wsadata.iMaxSockets);
|
debug_printf ("iMaxSockets %d", wsadata.iMaxSockets);
|
||||||
debug_printf ("iMaxUdpDg %d", wsadata.iMaxUdpDg);
|
debug_printf ("iMaxUdpDg %d", wsadata.iMaxUdpDg);
|
||||||
debug_printf ("lpVendorInfo %d", wsadata.lpVendorInfo);
|
|
||||||
|
|
||||||
wsock_started = 1;
|
wsock_started = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef __x86_64__
|
||||||
/* Kludge alert. Redirects the return address to dll_chain. */
|
/* Kludge alert. Redirects the return address to dll_chain. */
|
||||||
__asm__ __volatile__ (" \n\
|
uintptr_t *volatile frame = (uintptr_t *) __builtin_frame_address (0);
|
||||||
movl $dll_chain,4(%ebp) \n\
|
frame[1] = (uintptr_t) dll_chain;
|
||||||
");
|
#endif
|
||||||
|
|
||||||
InterlockedDecrement (&here);
|
InterlockedDecrement (&here);
|
||||||
|
|
||||||
volatile retchain ret;
|
volatile retchain ret;
|
||||||
/* Set "arguments for dll_chain. */
|
/* Set "arguments for dll_chain. */
|
||||||
ret.low = (long) dll_func_load;
|
ret.low = (uintptr_t) dll_func_load;
|
||||||
ret.high = (long) func;
|
ret.high = (uintptr_t) func;
|
||||||
return ret.ll;
|
return ret.ll;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,19 +567,14 @@ LoadDLLfunc (ReportEventW, 36, advapi32)
|
|||||||
LoadDLLfunc (DnsQuery_A, 24, dnsapi)
|
LoadDLLfunc (DnsQuery_A, 24, dnsapi)
|
||||||
LoadDLLfunc (DnsRecordListFree, 8, dnsapi)
|
LoadDLLfunc (DnsRecordListFree, 8, dnsapi)
|
||||||
|
|
||||||
// 50 = ERROR_NOT_SUPPORTED. Returned if OS doesn't support iphlpapi funcs
|
LoadDLLfunc (GetAdaptersAddresses, 20, iphlpapi)
|
||||||
LoadDLLfuncEx2 (GetAdaptersAddresses, 20, iphlpapi, 1, 50)
|
|
||||||
LoadDLLfunc (GetIfEntry, 4, iphlpapi)
|
LoadDLLfunc (GetIfEntry, 4, iphlpapi)
|
||||||
LoadDLLfunc (GetIpAddrTable, 12, iphlpapi)
|
LoadDLLfunc (GetIpAddrTable, 12, iphlpapi)
|
||||||
LoadDLLfunc (GetIpForwardTable, 12, iphlpapi)
|
LoadDLLfunc (GetIpForwardTable, 12, iphlpapi)
|
||||||
LoadDLLfunc (GetNetworkParams, 8, iphlpapi)
|
LoadDLLfunc (GetNetworkParams, 8, iphlpapi)
|
||||||
LoadDLLfunc (GetUdpTable, 12, iphlpapi)
|
LoadDLLfunc (GetUdpTable, 12, iphlpapi)
|
||||||
|
|
||||||
LoadDLLfuncEx (AttachConsole, 4, kernel32, 1)
|
|
||||||
LoadDLLfuncEx (GetModuleHandleExW, 12, kernel32, 1)
|
|
||||||
LoadDLLfuncEx (GetNamedPipeClientProcessId, 8, kernel32, 1)
|
LoadDLLfuncEx (GetNamedPipeClientProcessId, 8, kernel32, 1)
|
||||||
LoadDLLfuncEx (GetSystemWow64DirectoryW, 8, kernel32, 1)
|
|
||||||
LoadDLLfuncEx (GetVolumePathNamesForVolumeNameW, 16, kernel32, 1)
|
|
||||||
LoadDLLfunc (LocaleNameToLCID, 8, kernel32)
|
LoadDLLfunc (LocaleNameToLCID, 8, kernel32)
|
||||||
|
|
||||||
LoadDLLfunc (WNetCloseEnum, 4, mpr)
|
LoadDLLfunc (WNetCloseEnum, 4, mpr)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* automode.c
|
/* automode.c
|
||||||
|
|
||||||
Copyright 2000, 2001, 2010 Red Hat, Inc.
|
Copyright 2000, 2001, 2010, 2013 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -14,7 +14,9 @@ details. */
|
|||||||
|
|
||||||
extern int _fmode;
|
extern int _fmode;
|
||||||
void
|
void
|
||||||
cygwin_premain0 (int argc, char **argv, struct per_process *myself)
|
cygwin_premain0 (int argc __attribute__ ((unused)),
|
||||||
|
char **argv __attribute__ ((unused)),
|
||||||
|
struct per_process *myself __attribute__ ((unused)))
|
||||||
{
|
{
|
||||||
static struct __cygwin_perfile pf[] =
|
static struct __cygwin_perfile pf[] =
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* binmode.c
|
/* binmode.c
|
||||||
|
|
||||||
Copyright 2000, 2001, 2010 Red Hat, Inc.
|
Copyright 2000, 2001, 2010, 2013 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -14,7 +14,9 @@ details. */
|
|||||||
|
|
||||||
extern int _fmode;
|
extern int _fmode;
|
||||||
void
|
void
|
||||||
cygwin_premain0 (int argc, char **argv, struct per_process *myself)
|
cygwin_premain0 (int argc __attribute__ ((unused)),
|
||||||
|
char **argv __attribute__ ((unused)),
|
||||||
|
struct per_process *myself __attribute__ ((unused)))
|
||||||
{
|
{
|
||||||
_fmode &= ~_O_TEXT;
|
_fmode &= ~_O_TEXT;
|
||||||
_fmode |= _O_BINARY;
|
_fmode |= _O_BINARY;
|
||||||
|
@ -35,7 +35,7 @@ enum child_status
|
|||||||
#define EXEC_MAGIC_SIZE sizeof(child_info)
|
#define EXEC_MAGIC_SIZE sizeof(child_info)
|
||||||
|
|
||||||
/* Change this value if you get a message indicating that it is out-of-sync. */
|
/* Change this value if you get a message indicating that it is out-of-sync. */
|
||||||
#define CURR_CHILD_INFO_MAGIC 0xe399543U
|
#define CURR_CHILD_INFO_MAGIC 0x93737edaU
|
||||||
|
|
||||||
#define NPROCS 256
|
#define NPROCS 256
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ public:
|
|||||||
DWORD msv_count; // zeroed on < W2K3, set to pseudo-count on Vista
|
DWORD msv_count; // zeroed on < W2K3, set to pseudo-count on Vista
|
||||||
DWORD cb; // size of this record
|
DWORD cb; // size of this record
|
||||||
DWORD intro; // improbable string
|
DWORD intro; // improbable string
|
||||||
unsigned long magic; // magic number unique to child_info
|
DWORD magic; // magic number unique to child_info
|
||||||
unsigned short type; // type of record, exec, spawn, fork
|
unsigned short type; // type of record, exec, spawn, fork
|
||||||
init_cygheap *cygheap;
|
init_cygheap *cygheap;
|
||||||
void *cygheap_max;
|
void *cygheap_max;
|
||||||
@ -190,6 +190,6 @@ void __stdcall init_child_info (DWORD, child_info *, HANDLE);
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
extern child_info *child_proc_info;
|
extern child_info *child_proc_info;
|
||||||
extern child_info_spawn *spawn_info asm ("_child_proc_info");
|
extern child_info_spawn *spawn_info asm (_SYMSTR (child_proc_info));
|
||||||
extern child_info_fork *fork_info asm ("_child_proc_info");
|
extern child_info_fork *fork_info asm (_SYMSTR (child_proc_info));
|
||||||
}
|
}
|
||||||
|
21
winsup/cygwin/configure
vendored
21
winsup/cygwin/configure
vendored
@ -566,10 +566,12 @@ ac_no_link=no
|
|||||||
ac_subst_vars='LTLIBOBJS
|
ac_subst_vars='LTLIBOBJS
|
||||||
LIBOBJS
|
LIBOBJS
|
||||||
CONFIG_DIR
|
CONFIG_DIR
|
||||||
|
TLSOFFSETS_H
|
||||||
|
DIN_FILE
|
||||||
DEF_DLL_ENTRY
|
DEF_DLL_ENTRY
|
||||||
DLL_ENTRY
|
DLL_ENTRY
|
||||||
|
DLL_NAME
|
||||||
LIBSERVER
|
LIBSERVER
|
||||||
MALLOC_OFILES
|
|
||||||
configure_args
|
configure_args
|
||||||
SET_MAKE
|
SET_MAKE
|
||||||
WINDRES
|
WINDRES
|
||||||
@ -4410,14 +4412,23 @@ esac
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
MALLOC_OFILES=malloc.o
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
case "$target_cpu" in
|
case "$target_cpu" in
|
||||||
i?86) DLL_ENTRY="_dll_entry@12"
|
i?86)
|
||||||
|
DLL_NAME="cygwin1.dll"
|
||||||
|
DLL_ENTRY="_dll_entry@12"
|
||||||
DEF_DLL_ENTRY="dll_entry@12"
|
DEF_DLL_ENTRY="dll_entry@12"
|
||||||
|
DIN_FILE="cygwin.din"
|
||||||
|
TLSOFFSETS_H="tlsoffsets.h"
|
||||||
CONFIG_DIR="i386" ;;
|
CONFIG_DIR="i386" ;;
|
||||||
|
x86_64)
|
||||||
|
DLL_NAME="cygwin1.dll"
|
||||||
|
DLL_ENTRY="dll_entry"
|
||||||
|
DEF_DLL_ENTRY="dll_entry"
|
||||||
|
DIN_FILE="cygwin64.din"
|
||||||
|
TLSOFFSETS_H="tlsoffsets64.h"
|
||||||
|
CONFIG_DIR="x86_64" ;;
|
||||||
*) as_fn_error $? "Invalid target processor \"$target_cpu\"" "$LINENO" 5 ;;
|
*) as_fn_error $? "Invalid target processor \"$target_cpu\"" "$LINENO" 5 ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
@ -4437,6 +4448,8 @@ configure_args=$(/usr/bin/expr "$configure_args" : 'X \(.*\)')
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ac_config_files="$ac_config_files Makefile"
|
ac_config_files="$ac_config_files Makefile"
|
||||||
|
|
||||||
cat >confcache <<\_ACEOF
|
cat >confcache <<\_ACEOF
|
||||||
|
@ -55,8 +55,6 @@ no) ;;
|
|||||||
esac
|
esac
|
||||||
])
|
])
|
||||||
|
|
||||||
MALLOC_OFILES=malloc.o
|
|
||||||
|
|
||||||
dnl The only time we might want to transform the install names
|
dnl The only time we might want to transform the install names
|
||||||
dnl is for unix x cygwin. Otherwise we don't. For now we don't
|
dnl is for unix x cygwin. Otherwise we don't. For now we don't
|
||||||
dnl transform names.
|
dnl transform names.
|
||||||
@ -73,16 +71,29 @@ dnl fi
|
|||||||
dnl fi
|
dnl fi
|
||||||
|
|
||||||
case "$target_cpu" in
|
case "$target_cpu" in
|
||||||
i?86) DLL_ENTRY="_dll_entry@12"
|
i?86)
|
||||||
|
DLL_NAME="cygwin1.dll"
|
||||||
|
DLL_ENTRY="_dll_entry@12"
|
||||||
DEF_DLL_ENTRY="dll_entry@12"
|
DEF_DLL_ENTRY="dll_entry@12"
|
||||||
|
DIN_FILE="cygwin.din"
|
||||||
|
TLSOFFSETS_H="tlsoffsets.h"
|
||||||
CONFIG_DIR="i386" ;;
|
CONFIG_DIR="i386" ;;
|
||||||
|
x86_64)
|
||||||
|
DLL_NAME="cygwin1.dll"
|
||||||
|
DLL_ENTRY="dll_entry"
|
||||||
|
DEF_DLL_ENTRY="dll_entry"
|
||||||
|
DIN_FILE="cygwin64.din"
|
||||||
|
TLSOFFSETS_H="tlsoffsets64.h"
|
||||||
|
CONFIG_DIR="x86_64" ;;
|
||||||
*) AC_MSG_ERROR(Invalid target processor \"$target_cpu\") ;;
|
*) AC_MSG_ERROR(Invalid target processor \"$target_cpu\") ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
AC_CONFIGURE_ARGS
|
AC_CONFIGURE_ARGS
|
||||||
AC_SUBST(MALLOC_OFILES)
|
|
||||||
AC_SUBST(LIBSERVER)
|
AC_SUBST(LIBSERVER)
|
||||||
|
AC_SUBST(DLL_NAME)
|
||||||
AC_SUBST(DLL_ENTRY)
|
AC_SUBST(DLL_ENTRY)
|
||||||
AC_SUBST(DEF_DLL_ENTRY)
|
AC_SUBST(DEF_DLL_ENTRY)
|
||||||
|
AC_SUBST(DIN_FILE)
|
||||||
|
AC_SUBST(TLSOFFSETS_H)
|
||||||
AC_SUBST(CONFIG_DIR)
|
AC_SUBST(CONFIG_DIR)
|
||||||
AC_OUTPUT(Makefile)
|
AC_OUTPUT(Makefile)
|
||||||
|
@ -12,10 +12,31 @@ cpuid (unsigned *a, unsigned *b, unsigned *c, unsigned *d, unsigned in)
|
|||||||
: "a" (in));
|
: "a" (in));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __x86_64__
|
||||||
extern inline bool
|
extern inline bool
|
||||||
can_set_flag (unsigned flag)
|
can_set_flag (register unsigned long flag)
|
||||||
{
|
{
|
||||||
unsigned r1, r2;
|
register unsigned long r1, r2;
|
||||||
|
asm("pushfq\n"
|
||||||
|
"popq %0\n"
|
||||||
|
"movq %0, %1\n"
|
||||||
|
"xorq %2, %0\n"
|
||||||
|
"pushq %0\n"
|
||||||
|
"popfq\n"
|
||||||
|
"pushfq\n"
|
||||||
|
"popq %0\n"
|
||||||
|
"pushq %1\n"
|
||||||
|
"popfq\n"
|
||||||
|
: "=&r" (r1), "=&r" (r2)
|
||||||
|
: "ir" (flag)
|
||||||
|
);
|
||||||
|
return ((r1 ^ r2) & flag) != 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
extern inline bool
|
||||||
|
can_set_flag (register unsigned flag)
|
||||||
|
{
|
||||||
|
register unsigned r1, r2;
|
||||||
asm("pushfl\n"
|
asm("pushfl\n"
|
||||||
"popl %0\n"
|
"popl %0\n"
|
||||||
"movl %0, %1\n"
|
"movl %0, %1\n"
|
||||||
@ -31,5 +52,6 @@ can_set_flag (unsigned flag)
|
|||||||
);
|
);
|
||||||
return ((r1 ^ r2) & flag) != 0;
|
return ((r1 ^ r2) & flag) != 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // !CPUID_H
|
#endif // !CPUID_H
|
||||||
|
@ -12,16 +12,7 @@ details. */
|
|||||||
#ifndef _CYGERRNO_H
|
#ifndef _CYGERRNO_H
|
||||||
#define _CYGERRNO_H
|
#define _CYGERRNO_H
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include "regparm.h"
|
||||||
#ifndef __reg1
|
|
||||||
# define __reg1 __stdcall __attribute__ ((regparm (1)))
|
|
||||||
#endif
|
|
||||||
#ifndef __reg2
|
|
||||||
# define __reg2 __stdcall __attribute__ ((regparm (2)))
|
|
||||||
#endif
|
|
||||||
#ifndef __reg3
|
|
||||||
# define __reg3 __stdcall __attribute__ ((regparm (3)))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void __reg3 seterrno_from_win_error (const char *file, int line, DWORD code);
|
void __reg3 seterrno_from_win_error (const char *file, int line, DWORD code);
|
||||||
void __reg3 seterrno_from_nt_status (const char *file, int line, NTSTATUS status);
|
void __reg3 seterrno_from_nt_status (const char *file, int line, NTSTATUS status);
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "ntdll.h"
|
#include "ntdll.h"
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
|
||||||
static mini_cygheap NO_COPY cygheap_dummy =
|
static mini_cygheap NO_COPY cygheap_dummy =
|
||||||
{
|
{
|
||||||
@ -60,13 +61,11 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
muto NO_COPY tls_sentry::lock;
|
muto NO_COPY tls_sentry::lock;
|
||||||
static NO_COPY size_t nthreads;
|
static NO_COPY uint32_t nthreads;
|
||||||
|
|
||||||
#define THREADLIST_CHUNK 256
|
#define THREADLIST_CHUNK 256
|
||||||
|
|
||||||
#define NBUCKETS (sizeof (cygheap->buckets) / sizeof (cygheap->buckets[0]))
|
#define to_cmalloc(s) ((_cmalloc_entry *) (((char *) (s)) - offsetof (_cmalloc_entry, data)))
|
||||||
#define N0 ((_cmalloc_entry *) NULL)
|
|
||||||
#define to_cmalloc(s) ((_cmalloc_entry *) (((char *) (s)) - (unsigned) (N0->data)))
|
|
||||||
|
|
||||||
#define CFMAP_OPTIONS (SEC_RESERVE | PAGE_READWRITE)
|
#define CFMAP_OPTIONS (SEC_RESERVE | PAGE_READWRITE)
|
||||||
#define MVMAP_OPTIONS (FILE_MAP_WRITE)
|
#define MVMAP_OPTIONS (FILE_MAP_WRITE)
|
||||||
@ -116,47 +115,6 @@ init_cygheap::close_ctty ()
|
|||||||
cygheap->ctty = NULL;
|
cygheap->ctty = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define nextpage(x) ((char *) (((DWORD) ((char *) x + granmask)) & ~granmask))
|
|
||||||
#define allocsize(x) ((DWORD) nextpage (x))
|
|
||||||
#ifdef DEBUGGING
|
|
||||||
#define somekinda_printf debug_printf
|
|
||||||
#else
|
|
||||||
#define somekinda_printf malloc_printf
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void *__stdcall
|
|
||||||
_csbrk (int sbs)
|
|
||||||
{
|
|
||||||
void *prebrk = cygheap_max;
|
|
||||||
size_t granmask = wincap.allocation_granularity () - 1;
|
|
||||||
char *newbase = nextpage (prebrk);
|
|
||||||
cygheap_max = (char *) cygheap_max + sbs;
|
|
||||||
if (!sbs || (newbase >= cygheap_max) || (cygheap_max <= _cygheap_end))
|
|
||||||
/* nothing to do */;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (prebrk <= _cygheap_end)
|
|
||||||
newbase = _cygheap_end;
|
|
||||||
|
|
||||||
DWORD adjsbs = allocsize ((char *) cygheap_max - newbase);
|
|
||||||
if (adjsbs && !VirtualAlloc (newbase, adjsbs, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE))
|
|
||||||
{
|
|
||||||
MEMORY_BASIC_INFORMATION m;
|
|
||||||
if (!VirtualQuery (newbase, &m, sizeof m))
|
|
||||||
system_printf ("couldn't get memory info, %E");
|
|
||||||
somekinda_printf ("Couldn't reserve/commit %d bytes of space for cygwin's heap, %E",
|
|
||||||
adjsbs);
|
|
||||||
somekinda_printf ("AllocationBase %p, BaseAddress %p, RegionSize %p, State %p\n",
|
|
||||||
m.AllocationBase, m.BaseAddress, m.RegionSize, m.State);
|
|
||||||
__seterrno ();
|
|
||||||
cygheap_max = (char *) cygheap_max - sbs;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return prebrk;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Use absolute path of cygwin1.dll to derive the Win32 dir which
|
/* Use absolute path of cygwin1.dll to derive the Win32 dir which
|
||||||
is our installation_root. Note that we can't handle Cygwin installation
|
is our installation_root. Note that we can't handle Cygwin installation
|
||||||
root dirs of more than 4K path length. I assume that's ok...
|
root dirs of more than 4K path length. I assume that's ok...
|
||||||
@ -261,6 +219,21 @@ cygheap_init ()
|
|||||||
sizeof (*cygheap));
|
sizeof (*cygheap));
|
||||||
cygheap_max = cygheap;
|
cygheap_max = cygheap;
|
||||||
_csbrk (sizeof (*cygheap));
|
_csbrk (sizeof (*cygheap));
|
||||||
|
/* Initialize bucket_val. The value is the max size of a block
|
||||||
|
fitting into the bucket. The values are powers of two and their
|
||||||
|
medians: 12, 16, 24, 32, 48, 64, ... On 64 bit, start with 24 to
|
||||||
|
accommodate bigger size of struct cygheap_entry.
|
||||||
|
With NBUCKETS == 40, the maximum block size is 6291456/12582912.
|
||||||
|
The idea is to have better matching bucket sizes (not wasting
|
||||||
|
space) without trading in performance compared to the old powers
|
||||||
|
of 2 method. */
|
||||||
|
#ifdef __x86_64__
|
||||||
|
unsigned sz[2] = { 16, 24 }; /* sizeof cygheap_entry == 16 */
|
||||||
|
#else
|
||||||
|
unsigned sz[2] = { 8, 12 }; /* sizeof cygheap_entry == 8 */
|
||||||
|
#endif
|
||||||
|
for (unsigned b = 1; b < NBUCKETS; b++, sz[b & 1] <<= 1)
|
||||||
|
cygheap->bucket_val[b] = sz[b & 1];
|
||||||
/* Default locale settings. */
|
/* Default locale settings. */
|
||||||
cygheap->locale.mbtowc = __utf8_mbtowc;
|
cygheap->locale.mbtowc = __utf8_mbtowc;
|
||||||
cygheap->locale.wctomb = __utf8_wctomb;
|
cygheap->locale.wctomb = __utf8_wctomb;
|
||||||
@ -276,6 +249,47 @@ cygheap_init ()
|
|||||||
cygheap->init_tls_list ();
|
cygheap->init_tls_list ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define nextpage(x) ((char *) roundup2 ((uintptr_t) (x), \
|
||||||
|
wincap.allocation_granularity ()))
|
||||||
|
#define allocsize(x) ((SIZE_T) nextpage (x))
|
||||||
|
#ifdef DEBUGGING
|
||||||
|
#define somekinda_printf debug_printf
|
||||||
|
#else
|
||||||
|
#define somekinda_printf malloc_printf
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void *__stdcall
|
||||||
|
_csbrk (int sbs)
|
||||||
|
{
|
||||||
|
void *prebrk = cygheap_max;
|
||||||
|
char *newbase = nextpage (prebrk);
|
||||||
|
cygheap_max = (char *) cygheap_max + sbs;
|
||||||
|
if (!sbs || (newbase >= cygheap_max) || (cygheap_max <= _cygheap_end))
|
||||||
|
/* nothing to do */;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (prebrk <= _cygheap_end)
|
||||||
|
newbase = _cygheap_end;
|
||||||
|
|
||||||
|
SIZE_T adjsbs = allocsize ((char *) cygheap_max - newbase);
|
||||||
|
if (adjsbs && !VirtualAlloc (newbase, adjsbs, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE))
|
||||||
|
{
|
||||||
|
MEMORY_BASIC_INFORMATION m;
|
||||||
|
if (!VirtualQuery (newbase, &m, sizeof m))
|
||||||
|
system_printf ("couldn't get memory info, %E");
|
||||||
|
somekinda_printf ("Couldn't reserve/commit %ld bytes of space for cygwin's heap, %E",
|
||||||
|
adjsbs);
|
||||||
|
somekinda_printf ("AllocationBase %p, BaseAddress %p, RegionSize %lx, State %x\n",
|
||||||
|
m.AllocationBase, m.BaseAddress, m.RegionSize, m.State);
|
||||||
|
__seterrno ();
|
||||||
|
cygheap_max = (char *) cygheap_max - sbs;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return prebrk;
|
||||||
|
}
|
||||||
|
|
||||||
/* Copyright (C) 1997, 2000 DJ Delorie */
|
/* Copyright (C) 1997, 2000 DJ Delorie */
|
||||||
|
|
||||||
static void *__reg1 _cmalloc (unsigned size);
|
static void *__reg1 _cmalloc (unsigned size);
|
||||||
@ -285,11 +299,13 @@ static void *__reg1
|
|||||||
_cmalloc (unsigned size)
|
_cmalloc (unsigned size)
|
||||||
{
|
{
|
||||||
_cmalloc_entry *rvc;
|
_cmalloc_entry *rvc;
|
||||||
unsigned b, sz;
|
unsigned b;
|
||||||
|
|
||||||
/* Calculate "bit bucket" and size as a power of two. */
|
/* Calculate "bit bucket". */
|
||||||
for (b = 3, sz = 8; sz && sz < size; b++, sz <<= 1)
|
for (b = 1; b < NBUCKETS && cygheap->bucket_val[b] < size; b++)
|
||||||
continue;
|
continue;
|
||||||
|
if (b >= NBUCKETS)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
cygheap_protect.acquire ();
|
cygheap_protect.acquire ();
|
||||||
if (cygheap->buckets[b])
|
if (cygheap->buckets[b])
|
||||||
@ -300,7 +316,8 @@ _cmalloc (unsigned size)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rvc = (_cmalloc_entry *) _csbrk (sz + sizeof (_cmalloc_entry));
|
rvc = (_cmalloc_entry *) _csbrk (cygheap->bucket_val[b]
|
||||||
|
+ sizeof (_cmalloc_entry));
|
||||||
if (!rvc)
|
if (!rvc)
|
||||||
{
|
{
|
||||||
cygheap_protect.release ();
|
cygheap_protect.release ();
|
||||||
@ -320,7 +337,7 @@ _cfree (void *ptr)
|
|||||||
{
|
{
|
||||||
cygheap_protect.acquire ();
|
cygheap_protect.acquire ();
|
||||||
_cmalloc_entry *rvc = to_cmalloc (ptr);
|
_cmalloc_entry *rvc = to_cmalloc (ptr);
|
||||||
DWORD b = rvc->b;
|
unsigned b = rvc->b;
|
||||||
rvc->ptr = cygheap->buckets[b];
|
rvc->ptr = cygheap->buckets[b];
|
||||||
cygheap->buckets[b] = (char *) rvc;
|
cygheap->buckets[b] = (char *) rvc;
|
||||||
cygheap_protect.release ();
|
cygheap_protect.release ();
|
||||||
@ -334,7 +351,7 @@ _crealloc (void *ptr, unsigned size)
|
|||||||
newptr = _cmalloc (size);
|
newptr = _cmalloc (size);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned oldsize = 1 << to_cmalloc (ptr)->b;
|
unsigned oldsize = cygheap->bucket_val[to_cmalloc (ptr)->b];
|
||||||
if (size <= oldsize)
|
if (size <= oldsize)
|
||||||
return ptr;
|
return ptr;
|
||||||
newptr = _cmalloc (size);
|
newptr = _cmalloc (size);
|
||||||
@ -351,8 +368,7 @@ _crealloc (void *ptr, unsigned size)
|
|||||||
|
|
||||||
#define sizeof_cygheap(n) ((n) + sizeof (cygheap_entry))
|
#define sizeof_cygheap(n) ((n) + sizeof (cygheap_entry))
|
||||||
|
|
||||||
#define N ((cygheap_entry *) NULL)
|
#define tocygheap(s) ((cygheap_entry *) (((char *) (s)) - offsetof (cygheap_entry, data)))
|
||||||
#define tocygheap(s) ((cygheap_entry *) (((char *) (s)) - (int) (N->data)))
|
|
||||||
|
|
||||||
inline static void *
|
inline static void *
|
||||||
creturn (cygheap_types x, cygheap_entry * c, unsigned len, const char *fn = NULL)
|
creturn (cygheap_types x, cygheap_entry * c, unsigned len, const char *fn = NULL)
|
||||||
@ -600,12 +616,12 @@ init_cygheap::remove_tls (_cygtls *t, DWORD wait)
|
|||||||
tls_sentry here (wait);
|
tls_sentry here (wait);
|
||||||
if (here.acquired ())
|
if (here.acquired ())
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < nthreads; i++)
|
for (uint32_t i = 0; i < nthreads; i++)
|
||||||
if (t == threadlist[i])
|
if (t == threadlist[i])
|
||||||
{
|
{
|
||||||
if (i < --nthreads)
|
if (i < --nthreads)
|
||||||
threadlist[i] = threadlist[nthreads];
|
threadlist[i] = threadlist[nthreads];
|
||||||
debug_only_printf ("removed %p element %d", this, i);
|
debug_only_printf ("removed %p element %u", this, i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ struct _cmalloc_entry
|
|||||||
{
|
{
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
DWORD b;
|
unsigned b;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
};
|
};
|
||||||
struct _cmalloc_entry *prev;
|
struct _cmalloc_entry *prev;
|
||||||
@ -97,11 +97,11 @@ class cygheap_user
|
|||||||
cygsid effec_cygsid; /* buffer for user's SID */
|
cygsid effec_cygsid; /* buffer for user's SID */
|
||||||
cygsid saved_cygsid; /* Remains intact even after impersonation */
|
cygsid saved_cygsid; /* Remains intact even after impersonation */
|
||||||
public:
|
public:
|
||||||
__uid32_t saved_uid; /* Remains intact even after impersonation */
|
uid_t saved_uid; /* Remains intact even after impersonation */
|
||||||
__gid32_t saved_gid; /* Ditto */
|
gid_t saved_gid; /* Ditto */
|
||||||
__uid32_t real_uid; /* Remains intact on seteuid, replaced by setuid */
|
uid_t real_uid; /* Remains intact on seteuid, replaced by setuid */
|
||||||
__gid32_t real_gid; /* Ditto */
|
gid_t real_gid; /* Ditto */
|
||||||
user_groups groups; /* Primary and supp SIDs */
|
user_groups groups; /* Primary and supp SIDs */
|
||||||
|
|
||||||
/* token is needed if set(e)uid should be called. It can be set by a call
|
/* token is needed if set(e)uid should be called. It can be set by a call
|
||||||
to `set_impersonation_token()'. */
|
to `set_impersonation_token()'. */
|
||||||
@ -153,8 +153,8 @@ public:
|
|||||||
const char *p = env_domain ("USERDOMAIN=", sizeof ("USERDOMAIN=") - 1);
|
const char *p = env_domain ("USERDOMAIN=", sizeof ("USERDOMAIN=") - 1);
|
||||||
return (p == almost_null) ? NULL : p;
|
return (p == almost_null) ? NULL : p;
|
||||||
}
|
}
|
||||||
BOOL set_sid (PSID new_sid) {return (BOOL) (effec_cygsid = new_sid);}
|
void set_sid (PSID new_sid) { effec_cygsid = new_sid;}
|
||||||
BOOL set_saved_sid () { return (BOOL) (saved_cygsid = effec_cygsid); }
|
void set_saved_sid () { saved_cygsid = effec_cygsid; }
|
||||||
PSID sid () { return effec_cygsid; }
|
PSID sid () { return effec_cygsid; }
|
||||||
PSID saved_sid () { return saved_cygsid; }
|
PSID saved_sid () { return saved_cygsid; }
|
||||||
const char *ontherange (homebodies what, struct passwd * = NULL);
|
const char *ontherange (homebodies what, struct passwd * = NULL);
|
||||||
@ -216,9 +216,10 @@ enum fcwd_version_t {
|
|||||||
minimal locking and it's much more multi-thread friendly. Presumably
|
minimal locking and it's much more multi-thread friendly. Presumably
|
||||||
it minimizes contention when accessing the CWD.
|
it minimizes contention when accessing the CWD.
|
||||||
The class fcwd_access_t is supposed to encapsulate the gory implementation
|
The class fcwd_access_t is supposed to encapsulate the gory implementation
|
||||||
details depending on OS version from the calling functions. */
|
details depending on OS version from the calling functions.
|
||||||
|
The layout of all structures has been tested on 32 and 64 bit. */
|
||||||
class fcwd_access_t {
|
class fcwd_access_t {
|
||||||
/* This is the layout used in Windows 8 developer preview. */
|
/* This is the layout used in Windows 8. */
|
||||||
struct FAST_CWD_8 {
|
struct FAST_CWD_8 {
|
||||||
LONG ReferenceCount; /* Only release when this is 0. */
|
LONG ReferenceCount; /* Only release when this is 0. */
|
||||||
HANDLE DirectoryHandle;
|
HANDLE DirectoryHandle;
|
||||||
@ -227,7 +228,7 @@ class fcwd_access_t {
|
|||||||
UNICODE_STRING Path; /* Path's Buffer member always refers
|
UNICODE_STRING Path; /* Path's Buffer member always refers
|
||||||
to the following Buffer array. */
|
to the following Buffer array. */
|
||||||
LONG FSCharacteristics; /* Taken from FileFsDeviceInformation */
|
LONG FSCharacteristics; /* Taken from FileFsDeviceInformation */
|
||||||
WCHAR Buffer[MAX_PATH];
|
WCHAR Buffer[MAX_PATH] __attribute ((aligned (8)));
|
||||||
};
|
};
|
||||||
/* This is the layout used in Windows 7 and Vista. */
|
/* This is the layout used in Windows 7 and Vista. */
|
||||||
struct FAST_CWD_7 {
|
struct FAST_CWD_7 {
|
||||||
@ -238,7 +239,7 @@ class fcwd_access_t {
|
|||||||
LONG ReferenceCount; /* Only release when this is 0. */
|
LONG ReferenceCount; /* Only release when this is 0. */
|
||||||
ULONG OldDismountCount; /* Reflects the system DismountCount
|
ULONG OldDismountCount; /* Reflects the system DismountCount
|
||||||
at the time the CWD has been set. */
|
at the time the CWD has been set. */
|
||||||
WCHAR Buffer[MAX_PATH];
|
WCHAR Buffer[MAX_PATH] __attribute ((aligned (8)));
|
||||||
};
|
};
|
||||||
/* This is the old FAST_CWD structure up to the patch from KB 2393802,
|
/* This is the old FAST_CWD structure up to the patch from KB 2393802,
|
||||||
release in February 2011. */
|
release in February 2011. */
|
||||||
@ -349,8 +350,7 @@ struct user_heap_info
|
|||||||
void *ptr;
|
void *ptr;
|
||||||
void *top;
|
void *top;
|
||||||
void *max;
|
void *max;
|
||||||
unsigned chunk;
|
SIZE_T chunk;
|
||||||
unsigned slop;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hook_chain
|
struct hook_chain
|
||||||
@ -365,10 +365,13 @@ struct mini_cygheap
|
|||||||
cygheap_locale locale;
|
cygheap_locale locale;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define NBUCKETS 40
|
||||||
|
|
||||||
struct init_cygheap: public mini_cygheap
|
struct init_cygheap: public mini_cygheap
|
||||||
{
|
{
|
||||||
_cmalloc_entry *chain;
|
_cmalloc_entry *chain;
|
||||||
char *buckets[32];
|
unsigned bucket_val[NBUCKETS];
|
||||||
|
char *buckets[NBUCKETS];
|
||||||
WCHAR installation_root[PATH_MAX];
|
WCHAR installation_root[PATH_MAX];
|
||||||
UNICODE_STRING installation_key;
|
UNICODE_STRING installation_key;
|
||||||
WCHAR installation_key_buf[18];
|
WCHAR installation_key_buf[18];
|
||||||
@ -387,7 +390,7 @@ struct init_cygheap: public mini_cygheap
|
|||||||
|
|
||||||
fhandler_termios *ctty; /* Current tty */
|
fhandler_termios *ctty; /* Current tty */
|
||||||
struct _cygtls **threadlist;
|
struct _cygtls **threadlist;
|
||||||
size_t sthreads;
|
uint32_t sthreads;
|
||||||
pid_t pid; /* my pid */
|
pid_t pid; /* my pid */
|
||||||
struct { /* Equivalent to using LIST_HEAD. */
|
struct { /* Equivalent to using LIST_HEAD. */
|
||||||
struct inode_t *lh_first;
|
struct inode_t *lh_first;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# cygmagic - Generate "magic numbers" from a structure.
|
# cygmagic - Generate "magic numbers" from a structure.
|
||||||
#
|
#
|
||||||
# Copyright 2001, 2002, 2005 Red Hat, Inc.
|
# Copyright 2001, 2002, 2005, 2013 Red Hat, Inc.
|
||||||
#
|
#
|
||||||
# This file is part of Cygwin.
|
# This file is part of Cygwin.
|
||||||
#
|
#
|
||||||
@ -24,7 +24,7 @@ sumit() {
|
|||||||
while [ -n "$1" ]; do
|
while [ -n "$1" ]; do
|
||||||
define=$1; shift
|
define=$1; shift
|
||||||
struct=$1; shift
|
struct=$1; shift
|
||||||
sum=`$gcc -E $file | sed -n "/^$struct/,/^};/p" | sed -e 's/[ ]//g' -e '/^$/d' | sumit | awk '{printf "0x%xU", $1}'`
|
sum=`$gcc -D__CYGMAGIC__ -E $file | sed -n "/^$struct/,/^};/p" | sed -e 's/[ ]//g' -e '/^$/d' | sumit | awk '{printf "0x%xU", $1}'`
|
||||||
echo "#define $define $sum"
|
echo "#define $define $sum"
|
||||||
curr=`sed -n "s/^#[ ]*define CURR_$define[ ][ ]*\([^ ][^ ]*\)/\1/p" $file`
|
curr=`sed -n "s/^#[ ]*define CURR_$define[ ][ ]*\([^ ][^ ]*\)/\1/p" $file`
|
||||||
[ "$curr" != "$sum" ] && echo "*** WARNING WARNING WARNING WARNING WARNING ***
|
[ "$curr" != "$sum" ] && echo "*** WARNING WARNING WARNING WARNING WARNING ***
|
||||||
|
@ -11,18 +11,11 @@ details. */
|
|||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
#ifndef __reg1
|
#include "regparm.h"
|
||||||
# define __reg1 __stdcall __attribute__ ((regparm (1)))
|
|
||||||
#endif
|
|
||||||
#ifndef __reg2
|
|
||||||
# define __reg2 __stdcall __attribute__ ((regparm (2)))
|
|
||||||
#endif
|
|
||||||
#ifndef __reg3
|
|
||||||
# define __reg3 __stdcall __attribute__ ((regparm (3)))
|
|
||||||
#endif
|
|
||||||
void __reg1 dlfree (void *p);
|
void __reg1 dlfree (void *p);
|
||||||
void __reg1 *dlmalloc (unsigned size);
|
void __reg1 *dlmalloc (size_t size);
|
||||||
void __reg2 *dlrealloc (void *p, unsigned size);
|
void __reg2 *dlrealloc (void *p, size_t size);
|
||||||
void __reg2 *dlcalloc (size_t nmemb, size_t size);
|
void __reg2 *dlcalloc (size_t nmemb, size_t size);
|
||||||
void __reg2 *dlmemalign (size_t alignment, size_t bytes);
|
void __reg2 *dlmemalign (size_t alignment, size_t bytes);
|
||||||
void __reg1 *dlvalloc (size_t bytes);
|
void __reg1 *dlvalloc (size_t bytes);
|
||||||
@ -31,8 +24,14 @@ int __reg1 dlmalloc_trim (size_t);
|
|||||||
int __reg2 dlmallopt (int p, int v);
|
int __reg2 dlmallopt (int p, int v);
|
||||||
void dlmalloc_stats ();
|
void dlmalloc_stats ();
|
||||||
|
|
||||||
|
#ifdef __x86_64__
|
||||||
|
#define MALLOC_ALIGNMENT ((size_t)16U)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef __INSIDE_CYGWIN__
|
#ifndef __INSIDE_CYGWIN__
|
||||||
extern "C" void __set_ENOMEM ();
|
extern "C" void __set_ENOMEM ();
|
||||||
|
void *mmap64 (void *, size_t, int, int, int, off_t);
|
||||||
|
#define mmap mmap64
|
||||||
# define MALLOC_FAILURE_ACTION __set_ENOMEM ()
|
# define MALLOC_FAILURE_ACTION __set_ENOMEM ()
|
||||||
# define USE_DL_PREFIX 1
|
# define USE_DL_PREFIX 1
|
||||||
#else
|
#else
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* cygserver.h
|
/* cygserver.h
|
||||||
|
|
||||||
Copyright 2001, 2002, 2003, 2004, 2008 Red Hat Inc.
|
Copyright 2001, 2002, 2003, 2004, 2008, 2012, 2013 Red Hat Inc.
|
||||||
|
|
||||||
Written by Egor Duda <deo@logos-m.ru>
|
Written by Egor Duda <deo@logos-m.ru>
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ protected:
|
|||||||
union
|
union
|
||||||
{
|
{
|
||||||
request_code_t request_code;
|
request_code_t request_code;
|
||||||
ssize_t error_code;
|
int error_code;
|
||||||
};
|
};
|
||||||
|
|
||||||
header_t () {};
|
header_t () {};
|
||||||
@ -80,8 +80,8 @@ public:
|
|||||||
|
|
||||||
request_code_t request_code () const { return _header.request_code; }
|
request_code_t request_code () const { return _header.request_code; }
|
||||||
|
|
||||||
ssize_t error_code () const { return _header.error_code; };
|
int error_code () const { return _header.error_code; };
|
||||||
void error_code (ssize_t error_code) { _header.error_code = error_code; };
|
void error_code (int error_code) { _header.error_code = error_code; };
|
||||||
|
|
||||||
size_t msglen () const { return _header.msglen; };
|
size_t msglen () const { return _header.msglen; };
|
||||||
void msglen (size_t len) { _header.msglen = len; };
|
void msglen (size_t len) { _header.msglen = len; };
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* cygserver_ipc.h
|
/* cygserver_ipc.h
|
||||||
|
|
||||||
Copyright 2002, 2003, 2004, 2012 Red Hat, Inc.
|
Copyright 2002, 2003, 2004, 2012, 2013 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -22,10 +22,10 @@ struct vmspace {
|
|||||||
struct proc {
|
struct proc {
|
||||||
pid_t cygpid;
|
pid_t cygpid;
|
||||||
DWORD winpid;
|
DWORD winpid;
|
||||||
__uid32_t uid;
|
uid_t uid;
|
||||||
__gid32_t gid;
|
gid_t gid;
|
||||||
int gidcnt;
|
int gidcnt;
|
||||||
__gid32_t *gidlist;
|
gid_t *gidlist;
|
||||||
bool is_admin;
|
bool is_admin;
|
||||||
struct vmspace *p_vmspace;
|
struct vmspace *p_vmspace;
|
||||||
HANDLE signal_arrived;
|
HANDLE signal_arrived;
|
||||||
@ -52,7 +52,8 @@ class ipc_retval {
|
|||||||
private:
|
private:
|
||||||
union {
|
union {
|
||||||
int i;
|
int i;
|
||||||
unsigned int u;
|
ssize_t ssz;
|
||||||
|
size_t sz;
|
||||||
vm_offset_t off;
|
vm_offset_t off;
|
||||||
vm_object_t obj;
|
vm_object_t obj;
|
||||||
};
|
};
|
||||||
@ -63,8 +64,15 @@ public:
|
|||||||
operator int () const { return i; }
|
operator int () const { return i; }
|
||||||
int operator = (int ni) { return i = ni; }
|
int operator = (int ni) { return i = ni; }
|
||||||
|
|
||||||
operator unsigned int () const { return u; }
|
#ifndef __x86_64__
|
||||||
unsigned int operator = (unsigned int nu) { return u = nu; }
|
/* On x86_64: size_t == vm_offset_t == unsigned long */
|
||||||
|
operator size_t () const { return sz; }
|
||||||
|
size_t operator = (size_t nsz) { return sz = nsz; }
|
||||||
|
#else
|
||||||
|
/* On i686: ssize_t == long == int */
|
||||||
|
operator ssize_t () const { return ssz; }
|
||||||
|
ssize_t operator = (ssize_t nssz) { return ssz = nssz; }
|
||||||
|
#endif
|
||||||
|
|
||||||
operator vm_offset_t () const { return off; }
|
operator vm_offset_t () const { return off; }
|
||||||
vm_offset_t operator = (vm_offset_t noff) { return off = noff; }
|
vm_offset_t operator = (vm_offset_t noff) { return off = noff; }
|
||||||
|
@ -72,7 +72,7 @@ cygthread::stub (VOID *arg)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
info->stack_ptr = &arg;
|
info->stack_ptr = &arg;
|
||||||
debug_printf ("thread '%s', id %p, stack_ptr %p", info->name (), info->id, info->stack_ptr);
|
debug_printf ("thread '%s', id %y, stack_ptr %p", info->name (), info->id, info->stack_ptr);
|
||||||
if (!info->ev)
|
if (!info->ev)
|
||||||
{
|
{
|
||||||
info->ev = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
|
info->ev = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
|
||||||
@ -165,7 +165,7 @@ new (size_t)
|
|||||||
/* available */
|
/* available */
|
||||||
#ifdef DEBUGGING
|
#ifdef DEBUGGING
|
||||||
if (info->__name)
|
if (info->__name)
|
||||||
api_fatal ("name not NULL? %s, id %p, i %d", info->__name, info->id, info - threads);
|
api_fatal ("name not NULL? %s, id %y, i %ld", info->__name, info->id, info - threads);
|
||||||
#endif
|
#endif
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -197,7 +197,7 @@ cygthread::async_create (ULONG_PTR arg)
|
|||||||
void
|
void
|
||||||
cygthread::create ()
|
cygthread::create ()
|
||||||
{
|
{
|
||||||
thread_printf ("name %s, id %p, this %p", __name, id, this);
|
thread_printf ("name %s, id %y, this %p", __name, id, this);
|
||||||
HANDLE htobe;
|
HANDLE htobe;
|
||||||
if (h)
|
if (h)
|
||||||
{
|
{
|
||||||
@ -206,7 +206,7 @@ cygthread::create ()
|
|||||||
while (!thread_sync)
|
while (!thread_sync)
|
||||||
yield ();
|
yield ();
|
||||||
SetEvent (thread_sync);
|
SetEvent (thread_sync);
|
||||||
thread_printf ("activated name '%s', thread_sync %p for id %p", __name, thread_sync, id);
|
thread_printf ("activated name '%s', thread_sync %p for id %y", __name, thread_sync, id);
|
||||||
htobe = h;
|
htobe = h;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -215,8 +215,8 @@ cygthread::create ()
|
|||||||
htobe = CreateThread (&sec_none_nih, 0, is_freerange ? simplestub : stub,
|
htobe = CreateThread (&sec_none_nih, 0, is_freerange ? simplestub : stub,
|
||||||
this, 0, &id);
|
this, 0, &id);
|
||||||
if (!htobe)
|
if (!htobe)
|
||||||
api_fatal ("CreateThread failed for %s - %p<%p>, %E", __name, h, id);
|
api_fatal ("CreateThread failed for %s - %p<%y>, %E", __name, h, id);
|
||||||
thread_printf ("created name '%s', thread %p, id %p", __name, h, id);
|
thread_printf ("created name '%s', thread %p, id %y", __name, h, id);
|
||||||
#ifdef DEBUGGING
|
#ifdef DEBUGGING
|
||||||
terminated = false;
|
terminated = false;
|
||||||
#endif
|
#endif
|
||||||
@ -257,7 +257,7 @@ cygthread::name (DWORD tid)
|
|||||||
res = "main";
|
res = "main";
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
__small_sprintf (_my_tls.locals.unknown_thread_name, "unknown (%p)", tid);
|
__small_sprintf (_my_tls.locals.unknown_thread_name, "unknown (%y)", tid);
|
||||||
res = _my_tls.locals.unknown_thread_name;
|
res = _my_tls.locals.unknown_thread_name;
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
@ -296,7 +296,7 @@ bool
|
|||||||
cygthread::terminate_thread ()
|
cygthread::terminate_thread ()
|
||||||
{
|
{
|
||||||
bool terminated = true;
|
bool terminated = true;
|
||||||
debug_printf ("thread '%s', id %p, inuse %d, stack_ptr %p", __name, id, inuse, stack_ptr);
|
debug_printf ("thread '%s', id %y, inuse %d, stack_ptr %p", __name, id, inuse, stack_ptr);
|
||||||
while (inuse && !stack_ptr)
|
while (inuse && !stack_ptr)
|
||||||
yield ();
|
yield ();
|
||||||
|
|
||||||
@ -354,7 +354,7 @@ cygthread::detach (HANDLE sigwait)
|
|||||||
bool signalled = false;
|
bool signalled = false;
|
||||||
bool thread_was_reset = false;
|
bool thread_was_reset = false;
|
||||||
if (!inuse)
|
if (!inuse)
|
||||||
system_printf ("called detach but inuse %d, thread %p?", inuse, id);
|
system_printf ("called detach but inuse %d, thread %y?", inuse, id);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DWORD res;
|
DWORD res;
|
||||||
@ -429,7 +429,7 @@ cygthread::detach (HANDLE sigwait)
|
|||||||
::SetThreadPriority (hth, prio);
|
::SetThreadPriority (hth, prio);
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_printf ("%s returns %d, id %p", sigwait ? "WFMO" : "WFSO",
|
thread_printf ("%s returns %d, id %y", sigwait ? "WFMO" : "WFSO",
|
||||||
res, id);
|
res, id);
|
||||||
|
|
||||||
if (thread_was_reset)
|
if (thread_was_reset)
|
||||||
|
@ -166,7 +166,7 @@ _cygtls::remove (DWORD wait)
|
|||||||
if (exit_state >= ES_FINAL)
|
if (exit_state >= ES_FINAL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
debug_printf ("wait %p", wait);
|
debug_printf ("wait %u", wait);
|
||||||
|
|
||||||
/* FIXME: Need some sort of atthreadexit function to allow things like
|
/* FIXME: Need some sort of atthreadexit function to allow things like
|
||||||
select to control this themselves. */
|
select to control this themselves. */
|
||||||
|
@ -39,7 +39,11 @@ details. */
|
|||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __x86_64__
|
||||||
|
#pragma pack(push,8)
|
||||||
|
#else
|
||||||
#pragma pack(push,4)
|
#pragma pack(push,4)
|
||||||
|
#endif
|
||||||
/* Defined here to support auto rebuild of tlsoffsets.h. */
|
/* Defined here to support auto rebuild of tlsoffsets.h. */
|
||||||
class tls_pathbuf
|
class tls_pathbuf
|
||||||
{
|
{
|
||||||
@ -78,8 +82,6 @@ struct _local_storage
|
|||||||
/*
|
/*
|
||||||
Needed for the group functions
|
Needed for the group functions
|
||||||
*/
|
*/
|
||||||
struct __group16 grp;
|
|
||||||
char *namearray[2];
|
|
||||||
int grp_pos;
|
int grp_pos;
|
||||||
|
|
||||||
/* dlfcn.cc */
|
/* dlfcn.cc */
|
||||||
@ -157,15 +159,13 @@ typedef struct struct_waitq
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*gentls_offsets*/
|
/*gentls_offsets*/
|
||||||
#include "cygerrno.h"
|
|
||||||
#include "security.h"
|
|
||||||
|
|
||||||
extern "C" int __sjfault (jmp_buf);
|
extern "C" int __sjfault (jmp_buf);
|
||||||
extern "C" int __ljfault (jmp_buf, int);
|
extern "C" int __ljfault (jmp_buf, int);
|
||||||
|
|
||||||
/*gentls_offsets*/
|
/*gentls_offsets*/
|
||||||
|
|
||||||
typedef __uint32_t __stack_t;
|
typedef uintptr_t __stack_t;
|
||||||
|
|
||||||
class _cygtls
|
class _cygtls
|
||||||
{
|
{
|
||||||
@ -237,7 +237,7 @@ public:
|
|||||||
if (wait_for_lock)
|
if (wait_for_lock)
|
||||||
lock ();
|
lock ();
|
||||||
if (!signal_arrived)
|
if (!signal_arrived)
|
||||||
signal_arrived = CreateEvent (&sec_none_nih, false, false, NULL);
|
signal_arrived = CreateEvent (NULL, false, false, NULL);
|
||||||
if (wait_for_lock)
|
if (wait_for_lock)
|
||||||
unlock ();
|
unlock ();
|
||||||
}
|
}
|
||||||
@ -266,13 +266,29 @@ private:
|
|||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
const int CYGTLS_PADSIZE = 12700; /* FIXME: Find some way to autogenerate
|
/* FIXME: Find some way to autogenerate this value */
|
||||||
this value */
|
#ifdef __x86_64__
|
||||||
|
const int CYGTLS_PADSIZE = 12800; /* Must be 16-byte aligned */
|
||||||
|
#else
|
||||||
|
const int CYGTLS_PADSIZE = 12700;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*gentls_offsets*/
|
/*gentls_offsets*/
|
||||||
|
|
||||||
extern char *_tlsbase __asm__ ("%fs:4");
|
#include "cygerrno.h"
|
||||||
extern char *_tlstop __asm__ ("%fs:8");
|
#include "ntdll.h"
|
||||||
#define _my_tls (*((_cygtls *) (_tlsbase - CYGTLS_PADSIZE)))
|
|
||||||
|
#ifdef __x86_64__
|
||||||
|
/* When just using a "gs:X" asm for the x86_64 code, gcc wrongly creates
|
||||||
|
pc-relative instructions. However, NtCurrentTeb() is inline assembler
|
||||||
|
anyway, so using it here should be fast enough on x86_64. */
|
||||||
|
#define _tlsbase (NtCurrentTeb()->Tib.StackBase)
|
||||||
|
#define _tlstop (NtCurrentTeb()->Tib.StackLimit)
|
||||||
|
#else
|
||||||
|
extern PVOID _tlsbase __asm__ ("%fs:4");
|
||||||
|
extern PVOID _tlstop __asm__ ("%fs:8");
|
||||||
|
#endif
|
||||||
|
#define _my_tls (*((_cygtls *) ((char *)_tlsbase - CYGTLS_PADSIZE)))
|
||||||
extern _cygtls *_main_tls;
|
extern _cygtls *_main_tls;
|
||||||
extern _cygtls *_sig_tls;
|
extern _cygtls *_sig_tls;
|
||||||
|
|
||||||
|
@ -678,8 +678,8 @@ get_avphys_pages SIGFE
|
|||||||
get_current_dir_name SIGFE
|
get_current_dir_name SIGFE
|
||||||
get_nprocs SIGFE
|
get_nprocs SIGFE
|
||||||
get_nprocs_conf SIGFE
|
get_nprocs_conf SIGFE
|
||||||
get_osfhandle SIGFE
|
_get_osfhandle SIGFE
|
||||||
_get_osfhandle = get_osfhandle SIGFE
|
get_osfhandle = _get_osfhandle SIGFE
|
||||||
get_phys_pages SIGFE
|
get_phys_pages SIGFE
|
||||||
getaddrinfo = cygwin_getaddrinfo SIGFE
|
getaddrinfo = cygwin_getaddrinfo SIGFE
|
||||||
getc SIGFE
|
getc SIGFE
|
||||||
|
@ -1,17 +1,38 @@
|
|||||||
|
#ifdef __x86_64__
|
||||||
|
OUTPUT_FORMAT(pei-x86-64)
|
||||||
|
SEARCH_DIR("/usr/x86_64-pc-cygwin/lib/w32api"); SEARCH_DIR("=/usr/lib/w32api");
|
||||||
|
#else
|
||||||
|
#undef i386
|
||||||
OUTPUT_FORMAT(pei-i386)
|
OUTPUT_FORMAT(pei-i386)
|
||||||
|
SEARCH_DIR("/usr/i686-pc-cygwin/lib/w32api"); SEARCH_DIR("=/usr/lib/w32api");
|
||||||
|
#endif
|
||||||
|
#define __CONCAT1(a,b) a##b
|
||||||
|
#define __CONCAT(a,b) __CONCAT1(a,b)
|
||||||
|
#define _SYM(x) __CONCAT(__USER_LABEL_PREFIX__, x)
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
.text __image_base__ + __section_alignment__ :
|
.text __image_base__ + __section_alignment__ :
|
||||||
{
|
{
|
||||||
*(.init)
|
*(.init)
|
||||||
*(.text)
|
*(.text)
|
||||||
|
#ifdef __x86_64__
|
||||||
|
*(.text.*)
|
||||||
|
#endif
|
||||||
*(SORT(.text$*))
|
*(SORT(.text$*))
|
||||||
*(.glue_7t)
|
*(.glue_7t)
|
||||||
*(.glue_7)
|
*(.glue_7)
|
||||||
|
#ifdef __x86_64__
|
||||||
|
. = ALIGN(8);
|
||||||
|
___CTOR_LIST__ = .; __CTOR_LIST__ = .;
|
||||||
|
LONG (-1); LONG (-1); *(SORT(.ctors.*)); *(.ctors); *(.ctor); LONG (0); LONG (0);
|
||||||
|
___DTOR_LIST__ = .; __DTOR_LIST__ = .;
|
||||||
|
LONG (-1); LONG (-1); *(SORT(.dtors.*)); *(.dtors); *(.dtor); LONG (0); LONG (0);
|
||||||
|
#else
|
||||||
___CTOR_LIST__ = .; __CTOR_LIST__ = .;
|
___CTOR_LIST__ = .; __CTOR_LIST__ = .;
|
||||||
LONG (-1); *(SORT(.ctors.*)); *(.ctors); *(.ctor); LONG (0);
|
LONG (-1); *(SORT(.ctors.*)); *(.ctors); *(.ctor); LONG (0);
|
||||||
___DTOR_LIST__ = .; __DTOR_LIST__ = .;
|
___DTOR_LIST__ = .; __DTOR_LIST__ = .;
|
||||||
LONG (-1); *(SORT(.dtors.*)); *(.dtors); *(.dtor); LONG (0);
|
LONG (-1); *(SORT(.dtors.*)); *(.dtors); *(.dtor); LONG (0);
|
||||||
|
#endif
|
||||||
*(.fini)
|
*(.fini)
|
||||||
/* ??? Why is .gcc_exc here? */
|
/* ??? Why is .gcc_exc here? */
|
||||||
*(.gcc_exc)
|
*(.gcc_exc)
|
||||||
@ -23,10 +44,10 @@ SECTIONS
|
|||||||
*(.*_autoload_text);
|
*(.*_autoload_text);
|
||||||
}
|
}
|
||||||
/* The Cygwin DLL uses a section to avoid copying certain data
|
/* The Cygwin DLL uses a section to avoid copying certain data
|
||||||
on fork. This used to be named ".data". The linker used
|
on fork. This used to be named ".data$nocopy". The linker used
|
||||||
to include this between __data_start__ and __data_end__, but that
|
to include this between __data_start__ and __data_end__, but that
|
||||||
breaks building the cygwin32 dll. Instead, we name the section
|
breaks building the cygwin dll. Instead, we name the section
|
||||||
".data_cygwin_nocopy" and explictly include it after __data_end__. */
|
".data_cygwin_nocopy" and explicitly include it after __data_end__. */
|
||||||
.data ALIGN(__section_alignment__) :
|
.data ALIGN(__section_alignment__) :
|
||||||
{
|
{
|
||||||
__data_start__ = .;
|
__data_start__ = .;
|
||||||
@ -41,11 +62,18 @@ SECTIONS
|
|||||||
*(.rdata)
|
*(.rdata)
|
||||||
*(SORT(.rdata$*))
|
*(SORT(.rdata$*))
|
||||||
*(.eh_frame)
|
*(.eh_frame)
|
||||||
|
*(.rdata_cygwin_nocopy)
|
||||||
}
|
}
|
||||||
.pdata ALIGN(__section_alignment__) :
|
.pdata ALIGN(__section_alignment__) :
|
||||||
{
|
{
|
||||||
*(.pdata)
|
*(.pdata*)
|
||||||
}
|
}
|
||||||
|
#ifdef __x86_64__
|
||||||
|
.xdata ALIGN(__section_alignment__) :
|
||||||
|
{
|
||||||
|
*(.xdata*)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
.bss ALIGN(__section_alignment__) :
|
.bss ALIGN(__section_alignment__) :
|
||||||
{
|
{
|
||||||
__bss_start__ = .;
|
__bss_start__ = .;
|
||||||
@ -99,13 +127,17 @@ SECTIONS
|
|||||||
SORT(*)(.idata$6)
|
SORT(*)(.idata$6)
|
||||||
SORT(*)(.idata$7)
|
SORT(*)(.idata$7)
|
||||||
. = ALIGN(16);
|
. = ALIGN(16);
|
||||||
__cygheap_start = ABSOLUTE(.);
|
_SYM (_cygheap_start) = ABSOLUTE(.);
|
||||||
}
|
}
|
||||||
.cygheap ALIGN(__section_alignment__) :
|
.cygheap ALIGN(__section_alignment__) :
|
||||||
{
|
{
|
||||||
|
#ifdef __x86_64__
|
||||||
|
. = . + (3072 * 1024);
|
||||||
|
#else
|
||||||
. = . + (2048 * 1024);
|
. = . + (2048 * 1024);
|
||||||
|
#endif
|
||||||
. = ALIGN(0x10000);
|
. = ALIGN(0x10000);
|
||||||
__cygheap_end = ABSOLUTE(.);
|
_SYM (_cygheap_end) = ABSOLUTE(.);
|
||||||
}
|
}
|
||||||
/DISCARD/ :
|
/DISCARD/ :
|
||||||
{
|
{
|
||||||
@ -125,6 +157,7 @@ SECTIONS
|
|||||||
/* DWARF 1.1 and DWARF 2 */
|
/* DWARF 1.1 and DWARF 2 */
|
||||||
.debug_aranges ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_aranges) }
|
.debug_aranges ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_aranges) }
|
||||||
.debug_pubnames ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_pubnames) }
|
.debug_pubnames ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_pubnames) }
|
||||||
|
.debug_pubtypes ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_pubtypes) }
|
||||||
/* DWARF 2 */
|
/* DWARF 2 */
|
||||||
.debug_info ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_info) }
|
.debug_info ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_info) }
|
||||||
.debug_abbrev ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_abbrev) }
|
.debug_abbrev ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_abbrev) }
|
||||||
@ -133,6 +166,14 @@ SECTIONS
|
|||||||
.debug_str ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_str) }
|
.debug_str ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_str) }
|
||||||
.debug_loc ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_loc) }
|
.debug_loc ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_loc) }
|
||||||
.debug_macinfo ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_macinfo) }
|
.debug_macinfo ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_macinfo) }
|
||||||
|
/* SGI/MIPS DWARF 2 extensions. */
|
||||||
|
.debug_weaknames ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_weaknames) }
|
||||||
|
.debug_funcnames ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_funcnames) }
|
||||||
|
.debug_typenames ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_typenames) }
|
||||||
|
.debug_varnames ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_varnames) }
|
||||||
|
.debug_macro ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_macro) }
|
||||||
|
/* DWARF 3. */
|
||||||
.debug_ranges ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_ranges) }
|
.debug_ranges ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_ranges) }
|
||||||
.debug_pubtypes ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_pubtypes) }
|
/* DWARF 4. */
|
||||||
|
.debug_types ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_types .gnu.linkonce.wt.*) }
|
||||||
}
|
}
|
1346
winsup/cygwin/cygwin64.din
Normal file
1346
winsup/cygwin/cygwin64.din
Normal file
File diff suppressed because it is too large
Load Diff
@ -377,17 +377,17 @@ check_sanity_and_sync (per_process *p)
|
|||||||
|
|
||||||
/* Complain if older than last incompatible change */
|
/* Complain if older than last incompatible change */
|
||||||
if (p->dll_major < CYGWIN_VERSION_DLL_EPOCH)
|
if (p->dll_major < CYGWIN_VERSION_DLL_EPOCH)
|
||||||
api_fatal ("cygwin DLL and APP are out of sync -- DLL version mismatch %d < %d",
|
api_fatal ("cygwin DLL and APP are out of sync -- DLL version mismatch %u < %u",
|
||||||
p->dll_major, CYGWIN_VERSION_DLL_EPOCH);
|
p->dll_major, CYGWIN_VERSION_DLL_EPOCH);
|
||||||
|
|
||||||
/* magic_biscuit != 0 if using the old style version numbering scheme. */
|
/* magic_biscuit != 0 if using the old style version numbering scheme. */
|
||||||
if (p->magic_biscuit != SIZEOF_PER_PROCESS)
|
if (p->magic_biscuit != SIZEOF_PER_PROCESS)
|
||||||
api_fatal ("Incompatible cygwin .dll -- incompatible per_process info %d != %d",
|
api_fatal ("Incompatible cygwin .dll -- incompatible per_process info %u != %u",
|
||||||
p->magic_biscuit, SIZEOF_PER_PROCESS);
|
p->magic_biscuit, SIZEOF_PER_PROCESS);
|
||||||
|
|
||||||
/* Complain if incompatible API changes made */
|
/* Complain if incompatible API changes made */
|
||||||
if (p->api_major > cygwin_version.api_major)
|
if (p->api_major > cygwin_version.api_major)
|
||||||
api_fatal ("cygwin DLL and APP are out of sync -- API version mismatch %d > %d",
|
api_fatal ("cygwin DLL and APP are out of sync -- API version mismatch %u > %u",
|
||||||
p->api_major, cygwin_version.api_major);
|
p->api_major, cygwin_version.api_major);
|
||||||
|
|
||||||
/* This is a kludge to work around a version of _cygwin_common_crt0
|
/* This is a kludge to work around a version of _cygwin_common_crt0
|
||||||
@ -458,8 +458,12 @@ getstack (volatile char * volatile p)
|
|||||||
void
|
void
|
||||||
child_info_fork::alloc_stack ()
|
child_info_fork::alloc_stack ()
|
||||||
{
|
{
|
||||||
volatile char * volatile esp;
|
volatile char * volatile stackp;
|
||||||
__asm__ volatile ("movl %%esp,%0": "=r" (esp));
|
#ifdef __x86_64__
|
||||||
|
__asm__ volatile ("movq %%rsp,%0": "=r" (stackp));
|
||||||
|
#else
|
||||||
|
__asm__ volatile ("movl %%esp,%0": "=r" (stackp));
|
||||||
|
#endif
|
||||||
/* Make sure not to try a hard allocation if we have been forked off from
|
/* Make sure not to try a hard allocation if we have been forked off from
|
||||||
the main thread of a Cygwin process which has been started from a 64 bit
|
the main thread of a Cygwin process which has been started from a 64 bit
|
||||||
parent. In that case the _tlsbase of the forked child is not the same
|
parent. In that case the _tlsbase of the forked child is not the same
|
||||||
@ -471,18 +475,18 @@ child_info_fork::alloc_stack ()
|
|||||||
&& (!wincap.is_wow64 ()
|
&& (!wincap.is_wow64 ()
|
||||||
|| stacktop < (char *) NtCurrentTeb ()->DeallocationStack
|
|| stacktop < (char *) NtCurrentTeb ()->DeallocationStack
|
||||||
|| stackbottom > _tlsbase))
|
|| stackbottom > _tlsbase))
|
||||||
alloc_stack_hard_way (esp);
|
alloc_stack_hard_way (stackp);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char *st = (char *) stacktop - 4096;
|
char *st = (char *) stacktop - 4096;
|
||||||
while (_tlstop >= st)
|
while (_tlstop >= st)
|
||||||
esp = getstack (esp);
|
stackp = getstack (stackp);
|
||||||
stackaddr = 0;
|
stackaddr = 0;
|
||||||
/* This only affects forked children of a process started from a native
|
/* This only affects forked children of a process started from a native
|
||||||
64 bit process, but it doesn't hurt to do it unconditionally. Fix
|
64 bit process, but it doesn't hurt to do it unconditionally. Fix
|
||||||
StackBase in the child to be the same as in the parent, so that the
|
StackBase in the child to be the same as in the parent, so that the
|
||||||
computation of _my_tls is correct. */
|
computation of _my_tls is correct. */
|
||||||
_tlsbase = (char *) stackbottom;
|
_tlsbase = (PVOID) stackbottom;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -546,8 +550,8 @@ get_cygwin_startup_info ()
|
|||||||
if ((res->intro & OPROC_MAGIC_MASK) == OPROC_MAGIC_GENERIC)
|
if ((res->intro & OPROC_MAGIC_MASK) == OPROC_MAGIC_GENERIC)
|
||||||
multiple_cygwin_problem ("proc intro", res->intro, 0);
|
multiple_cygwin_problem ("proc intro", res->intro, 0);
|
||||||
else if (res->cygheap != (void *) &_cygheap_start)
|
else if (res->cygheap != (void *) &_cygheap_start)
|
||||||
multiple_cygwin_problem ("cygheap base", (DWORD) res->cygheap,
|
multiple_cygwin_problem ("cygheap base", (uintptr_t) res->cygheap,
|
||||||
(DWORD) &_cygheap_start);
|
(uintptr_t) &_cygheap_start);
|
||||||
|
|
||||||
unsigned should_be_cb = 0;
|
unsigned should_be_cb = 0;
|
||||||
switch (res->type)
|
switch (res->type)
|
||||||
@ -563,7 +567,8 @@ get_cygwin_startup_info ()
|
|||||||
if (should_be_cb != res->cb)
|
if (should_be_cb != res->cb)
|
||||||
multiple_cygwin_problem ("proc size", res->cb, should_be_cb);
|
multiple_cygwin_problem ("proc size", res->cb, should_be_cb);
|
||||||
else if (sizeof (fhandler_union) != res->fhandler_union_cb)
|
else if (sizeof (fhandler_union) != res->fhandler_union_cb)
|
||||||
multiple_cygwin_problem ("fhandler size", res->fhandler_union_cb, sizeof (fhandler_union));
|
multiple_cygwin_problem ("fhandler size", res->fhandler_union_cb,
|
||||||
|
sizeof (fhandler_union));
|
||||||
if (res->isstraced ())
|
if (res->isstraced ())
|
||||||
{
|
{
|
||||||
while (!being_debugged ())
|
while (!being_debugged ())
|
||||||
@ -572,7 +577,7 @@ get_cygwin_startup_info ()
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
system_printf ("unknown exec type %d", res->type);
|
system_printf ("unknown exec type %u", res->type);
|
||||||
/* intentionally fall through */
|
/* intentionally fall through */
|
||||||
case _CH_WHOOPS:
|
case _CH_WHOOPS:
|
||||||
res = NULL;
|
res = NULL;
|
||||||
@ -583,10 +588,17 @@ get_cygwin_startup_info ()
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __x86_64__
|
||||||
|
#define dll_data_start &__data_start__
|
||||||
|
#define dll_data_end &__data_end__
|
||||||
|
#define dll_bss_start &__bss_start__
|
||||||
|
#define dll_bss_end &__bss_end__
|
||||||
|
#else
|
||||||
#define dll_data_start &_data_start__
|
#define dll_data_start &_data_start__
|
||||||
#define dll_data_end &_data_end__
|
#define dll_data_end &_data_end__
|
||||||
#define dll_bss_start &_bss_start__
|
#define dll_bss_start &_bss_start__
|
||||||
#define dll_bss_end &_bss_end__
|
#define dll_bss_end &_bss_end__
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
child_info_fork::handle_fork ()
|
child_info_fork::handle_fork ()
|
||||||
@ -708,7 +720,7 @@ init_windows_system_directory ()
|
|||||||
api_fatal ("can't find windows system directory");
|
api_fatal ("can't find windows system directory");
|
||||||
windows_system_directory[windows_system_directory_length++] = L'\\';
|
windows_system_directory[windows_system_directory_length++] = L'\\';
|
||||||
windows_system_directory[windows_system_directory_length] = L'\0';
|
windows_system_directory[windows_system_directory_length] = L'\0';
|
||||||
|
#ifndef __x86_64__
|
||||||
system_wow64_directory_length =
|
system_wow64_directory_length =
|
||||||
GetSystemWow64DirectoryW (system_wow64_directory, MAX_PATH);
|
GetSystemWow64DirectoryW (system_wow64_directory, MAX_PATH);
|
||||||
if (system_wow64_directory_length)
|
if (system_wow64_directory_length)
|
||||||
@ -716,6 +728,7 @@ init_windows_system_directory ()
|
|||||||
system_wow64_directory[system_wow64_directory_length++] = L'\\';
|
system_wow64_directory[system_wow64_directory_length++] = L'\\';
|
||||||
system_wow64_directory[system_wow64_directory_length] = L'\0';
|
system_wow64_directory[system_wow64_directory_length] = L'\0';
|
||||||
}
|
}
|
||||||
|
#endif /* !__x86_64__ */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -725,7 +738,6 @@ dll_crt0_0 ()
|
|||||||
wincap.init ();
|
wincap.init ();
|
||||||
child_proc_info = get_cygwin_startup_info ();
|
child_proc_info = get_cygwin_startup_info ();
|
||||||
init_windows_system_directory ();
|
init_windows_system_directory ();
|
||||||
init_global_security ();
|
|
||||||
initial_env ();
|
initial_env ();
|
||||||
|
|
||||||
SetErrorMode (SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
|
SetErrorMode (SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
|
||||||
@ -753,12 +765,14 @@ dll_crt0_0 ()
|
|||||||
if (!child_proc_info)
|
if (!child_proc_info)
|
||||||
{
|
{
|
||||||
memory_init (true);
|
memory_init (true);
|
||||||
|
#ifndef __x86_64__
|
||||||
/* WOW64 process on XP/64 or Server 2003/64? Check if we have been
|
/* WOW64 process on XP/64 or Server 2003/64? Check if we have been
|
||||||
started from 64 bit process and if our stack is at an unusual
|
started from 64 bit process and if our stack is at an unusual
|
||||||
address. Set wow64_needs_stack_adjustment if so. Problem
|
address. Set wow64_needs_stack_adjustment if so. Problem
|
||||||
description in wow64_test_for_64bit_parent. */
|
description in wow64_test_for_64bit_parent. */
|
||||||
if (wincap.wow64_has_secondary_stack ())
|
if (wincap.wow64_has_secondary_stack ())
|
||||||
wow64_needs_stack_adjustment = wow64_test_for_64bit_parent ();
|
wow64_needs_stack_adjustment = wow64_test_for_64bit_parent ();
|
||||||
|
#endif /* !__x86_64__ */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -847,7 +861,7 @@ dll_crt0_1 (void *)
|
|||||||
small_printf ("cmalloc returns %p\n", cmalloc (HEAP_STR, n));
|
small_printf ("cmalloc returns %p\n", cmalloc (HEAP_STR, n));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
small_printf ("total allocated %p\n", (i - 1) * n);
|
small_printf ("total allocated %y\n", (i - 1) * n);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -890,8 +904,8 @@ dll_crt0_1 (void *)
|
|||||||
this step. */
|
this step. */
|
||||||
if (fork_info->stackaddr)
|
if (fork_info->stackaddr)
|
||||||
{
|
{
|
||||||
_tlsbase = (char *) fork_info->stackbottom;
|
_tlsbase = (PVOID) fork_info->stackbottom;
|
||||||
_tlstop = (char *) fork_info->stacktop;
|
_tlstop = (PVOID) fork_info->stacktop;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Not resetting _my_tls.incyg here because presumably fork will overwrite
|
/* Not resetting _my_tls.incyg here because presumably fork will overwrite
|
||||||
@ -1015,17 +1029,25 @@ dll_crt0_1 (void *)
|
|||||||
sig_dispatch_pending (false);
|
sig_dispatch_pending (false);
|
||||||
_my_tls.call_signal_handler ();
|
_my_tls.call_signal_handler ();
|
||||||
_my_tls.incyg--; /* Not in Cygwin anymore */
|
_my_tls.incyg--; /* Not in Cygwin anymore */
|
||||||
|
#ifdef __x86_64__
|
||||||
|
cygwin_exit (user_data->main (__argc, newargv, __cygwin_environ));
|
||||||
|
#else
|
||||||
cygwin_exit (user_data->main (__argc, newargv, *user_data->envptr));
|
cygwin_exit (user_data->main (__argc, newargv, *user_data->envptr));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
__asm__ (" \n\
|
__asm__ (" \n\
|
||||||
|
.global _cygwin_exit_return \n\
|
||||||
.global __cygwin_exit_return \n\
|
.global __cygwin_exit_return \n\
|
||||||
|
_cygwin_exit_return: \n\
|
||||||
__cygwin_exit_return: \n\
|
__cygwin_exit_return: \n\
|
||||||
|
nop \n\
|
||||||
");
|
");
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void __stdcall
|
extern "C" void __stdcall
|
||||||
_dll_crt0 ()
|
_dll_crt0 ()
|
||||||
{
|
{
|
||||||
|
#ifndef __x86_64__
|
||||||
/* Handle WOW64 process on XP/2K3 which has been started from native 64 bit
|
/* Handle WOW64 process on XP/2K3 which has been started from native 64 bit
|
||||||
process. See comment in wow64_test_for_64bit_parent for a full problem
|
process. See comment in wow64_test_for_64bit_parent for a full problem
|
||||||
description. */
|
description. */
|
||||||
@ -1056,10 +1078,11 @@ _dll_crt0 ()
|
|||||||
/* Fall back to respawn if wow64_revert_to_original_stack fails. */
|
/* Fall back to respawn if wow64_revert_to_original_stack fails. */
|
||||||
wow64_respawn_process ();
|
wow64_respawn_process ();
|
||||||
}
|
}
|
||||||
#ifdef __i386__
|
#endif /* !__x86_64__ */
|
||||||
_feinitialise ();
|
_feinitialise ();
|
||||||
#endif
|
#ifndef __x86_64__
|
||||||
main_environ = user_data->envptr;
|
main_environ = user_data->envptr;
|
||||||
|
#endif
|
||||||
if (in_forkee)
|
if (in_forkee)
|
||||||
{
|
{
|
||||||
fork_info->alloc_stack ();
|
fork_info->alloc_stack ();
|
||||||
@ -1092,12 +1115,16 @@ dll_crt0 (per_process *uptr)
|
|||||||
extern "C" void
|
extern "C" void
|
||||||
cygwin_dll_init ()
|
cygwin_dll_init ()
|
||||||
{
|
{
|
||||||
|
#ifndef __x86_64__
|
||||||
static char **envp;
|
static char **envp;
|
||||||
|
#endif
|
||||||
static int _fmode;
|
static int _fmode;
|
||||||
|
|
||||||
user_data->magic_biscuit = sizeof (per_process);
|
user_data->magic_biscuit = sizeof (per_process);
|
||||||
|
|
||||||
|
#ifndef __x86_64__
|
||||||
user_data->envptr = &envp;
|
user_data->envptr = &envp;
|
||||||
|
#endif
|
||||||
user_data->fmode_ptr = &_fmode;
|
user_data->fmode_ptr = &_fmode;
|
||||||
|
|
||||||
_dll_crt0 ();
|
_dll_crt0 ();
|
||||||
@ -1121,7 +1148,7 @@ __main (void)
|
|||||||
sig_dispatch_pending (true);
|
sig_dispatch_pending (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __stdcall
|
void __reg1
|
||||||
do_exit (int status)
|
do_exit (int status)
|
||||||
{
|
{
|
||||||
syscall_printf ("do_exit (%d), exit_state %d", status, exit_state);
|
syscall_printf ("do_exit (%d), exit_state %d", status, exit_state);
|
||||||
@ -1173,7 +1200,7 @@ do_exit (int status)
|
|||||||
siginfo_t si = {0};
|
siginfo_t si = {0};
|
||||||
si.si_signo = -SIGHUP;
|
si.si_signo = -SIGHUP;
|
||||||
si.si_code = SI_KERNEL;
|
si.si_code = SI_KERNEL;
|
||||||
sigproc_printf ("%d == pgrp %d, send SIG{HUP,CONT} to stopped children",
|
sigproc_printf ("%u == pgrp %u, send SIG{HUP,CONT} to stopped children",
|
||||||
myself->pid, myself->pgid);
|
myself->pid, myself->pgid);
|
||||||
kill_pgrp (myself->pgid, si);
|
kill_pgrp (myself->pgid, si);
|
||||||
}
|
}
|
||||||
@ -1186,7 +1213,7 @@ do_exit (int status)
|
|||||||
if (getpgrp () > 0 && myself->pid == myself->sid && real_tty_attached (myself))
|
if (getpgrp () > 0 && myself->pid == myself->sid && real_tty_attached (myself))
|
||||||
{
|
{
|
||||||
tty *tp = cygwin_shared->tty[myself->ctty];
|
tty *tp = cygwin_shared->tty[myself->ctty];
|
||||||
sigproc_printf ("%d == sid %d, send SIGHUP to children",
|
sigproc_printf ("%u == sid %u, send SIGHUP to children",
|
||||||
myself->pid, myself->sid);
|
myself->pid, myself->sid);
|
||||||
|
|
||||||
/* CGF FIXME: This can't be right. */
|
/* CGF FIXME: This can't be right. */
|
||||||
@ -1249,7 +1276,7 @@ api_fatal (const char *fmt, ...)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
multiple_cygwin_problem (const char *what, unsigned magic_version, unsigned version)
|
multiple_cygwin_problem (const char *what, uintptr_t magic_version, uintptr_t version)
|
||||||
{
|
{
|
||||||
if (_cygwin_testing && (strstr (what, "proc") || strstr (what, "cygheap")))
|
if (_cygwin_testing && (strstr (what, "proc") || strstr (what, "cygheap")))
|
||||||
{
|
{
|
||||||
@ -1261,9 +1288,9 @@ multiple_cygwin_problem (const char *what, unsigned magic_version, unsigned vers
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (CYGWIN_VERSION_MAGIC_VERSION (magic_version) == version)
|
if (CYGWIN_VERSION_MAGIC_VERSION (magic_version) == version)
|
||||||
system_printf ("%s magic number mismatch detected - %p/%p", what, magic_version, version);
|
system_printf ("%s magic number mismatch detected - %p/%ly", what, magic_version, version);
|
||||||
else
|
else
|
||||||
api_fatal ("%s mismatch detected - %p/%p.\n\
|
api_fatal ("%s mismatch detected - %ly/%ly.\n\
|
||||||
This problem is probably due to using incompatible versions of the cygwin DLL.\n\
|
This problem is probably due to using incompatible versions of the cygwin DLL.\n\
|
||||||
Search for cygwin1.dll using the Windows Start->Find/Search facility\n\
|
Search for cygwin1.dll using the Windows Start->Find/Search facility\n\
|
||||||
and delete all but the most recent version. The most recent version *should*\n\
|
and delete all but the most recent version. The most recent version *should*\n\
|
||||||
@ -1278,6 +1305,6 @@ void __stdcall
|
|||||||
cygbench (const char *s)
|
cygbench (const char *s)
|
||||||
{
|
{
|
||||||
if (GetEnvironmentVariableA ("CYGWIN_BENCH", NULL, 0))
|
if (GetEnvironmentVariableA ("CYGWIN_BENCH", NULL, 0))
|
||||||
small_printf ("%05d ***** %s : %10d\n", GetCurrentProcessId (), s, strace.microseconds ());
|
small_printf ("%05u ***** %s : %10d\n", GetCurrentProcessId (), s, strace.microseconds ());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* debug.h
|
/* debug.h
|
||||||
|
|
||||||
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2010
|
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2010,
|
||||||
Red Hat, Inc.
|
2013 Red Hat, Inc.
|
||||||
|
|
||||||
This software is a copyrighted work licensed under the terms of the
|
This software is a copyrighted work licensed under the terms of the
|
||||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
@ -11,7 +11,7 @@ details. */
|
|||||||
#define MALLOC_CHECK do {} while (0)
|
#define MALLOC_CHECK do {} while (0)
|
||||||
#else
|
#else
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "dlmalloc.h"
|
#include <malloc.h>
|
||||||
#define MALLOC_CHECK ({\
|
#define MALLOC_CHECK ({\
|
||||||
debug_printf ("checking malloc pool");\
|
debug_printf ("checking malloc pool");\
|
||||||
mallinfo ();\
|
mallinfo ();\
|
||||||
|
@ -70,7 +70,7 @@ exists_ntdev_silent (const device& dev)
|
|||||||
static int
|
static int
|
||||||
exists_console (const device& dev)
|
exists_console (const device& dev)
|
||||||
{
|
{
|
||||||
int devn = *const_cast<device *> (&dev);
|
fh_devices devn = *const_cast<device *> (&dev);
|
||||||
switch (devn)
|
switch (devn)
|
||||||
{
|
{
|
||||||
case FH_CONSOLE:
|
case FH_CONSOLE:
|
||||||
@ -45845,7 +45845,7 @@ device::init ()
|
|||||||
void
|
void
|
||||||
device::parse (_major_t major, _minor_t minor)
|
device::parse (_major_t major, _minor_t minor)
|
||||||
{
|
{
|
||||||
_dev_t devn = FHDEV (major, minor);
|
dev_t devn = FHDEV (major, minor);
|
||||||
|
|
||||||
d.devn = 0;
|
d.devn = 0;
|
||||||
|
|
||||||
@ -45861,7 +45861,7 @@ device::parse (_major_t major, _minor_t minor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
device::parse (_dev_t dev)
|
device::parse (dev_t dev)
|
||||||
{
|
{
|
||||||
parse (_major (dev), _minor (dev));
|
parse (_major (dev), _minor (dev));
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,6 @@ details. */
|
|||||||
typedef unsigned short _major_t;
|
typedef unsigned short _major_t;
|
||||||
typedef unsigned short _minor_t;
|
typedef unsigned short _minor_t;
|
||||||
typedef mode_t _mode_t;
|
typedef mode_t _mode_t;
|
||||||
typedef __dev32_t _dev_t;
|
|
||||||
|
|
||||||
#define FHDEV(maj, min) ((((unsigned) (maj)) << (sizeof (_major_t) * 8)) | (unsigned) (min))
|
#define FHDEV(maj, min) ((((unsigned) (maj)) << (sizeof (_major_t) * 8)) | (unsigned) (min))
|
||||||
#define _minor(dev) ((dev) & ((1 << (sizeof (_minor_t) * 8)) - 1))
|
#define _minor(dev) ((dev) & ((1 << (sizeof (_minor_t) * 8)) - 1))
|
||||||
@ -263,7 +262,7 @@ struct device
|
|||||||
const char *name;
|
const char *name;
|
||||||
union __cygwin_dev
|
union __cygwin_dev
|
||||||
{
|
{
|
||||||
_dev_t devn;
|
dev_t devn;
|
||||||
DWORD devn_dword;
|
DWORD devn_dword;
|
||||||
int devn_int;
|
int devn_int;
|
||||||
fh_devices devn_fh_devices;
|
fh_devices devn_fh_devices;
|
||||||
@ -281,7 +280,7 @@ struct device
|
|||||||
static const device *lookup (const char *, unsigned int = UINT32_MAX);
|
static const device *lookup (const char *, unsigned int = UINT32_MAX);
|
||||||
void parse (const char *);
|
void parse (const char *);
|
||||||
void parse (_major_t major, _minor_t minor);
|
void parse (_major_t major, _minor_t minor);
|
||||||
void parse (_dev_t dev);
|
void parse (dev_t dev);
|
||||||
void parsedisk (int, int);
|
void parsedisk (int, int);
|
||||||
inline bool setunit (unsigned n)
|
inline bool setunit (unsigned n)
|
||||||
{
|
{
|
||||||
@ -290,32 +289,31 @@ struct device
|
|||||||
}
|
}
|
||||||
static void init ();
|
static void init ();
|
||||||
|
|
||||||
static _major_t major (_dev_t n)
|
static _major_t major (dev_t n)
|
||||||
{
|
{
|
||||||
__cygwin_dev d;
|
__cygwin_dev d;
|
||||||
d.devn = n;
|
d.devn = n;
|
||||||
return d.major;
|
return d.major;
|
||||||
}
|
}
|
||||||
static _minor_t minor (_dev_t n)
|
static _minor_t minor (dev_t n)
|
||||||
{
|
{
|
||||||
__cygwin_dev d;
|
__cygwin_dev d;
|
||||||
d.devn = n;
|
d.devn = n;
|
||||||
return d.minor;
|
return d.minor;
|
||||||
}
|
}
|
||||||
static _major_t major (int n) {return major ((_dev_t) n);}
|
static _major_t major (int n) {return major ((dev_t) n);}
|
||||||
static _minor_t minor (int n) {return minor ((_dev_t) n);}
|
static _minor_t minor (int n) {return minor ((dev_t) n);}
|
||||||
|
|
||||||
bool is_device (_dev_t n) const {return n == d.devn; }
|
bool is_device (dev_t n) const {return n == d.devn; }
|
||||||
bool not_device (_dev_t n) const {return d.devn && n != d.devn; }
|
bool not_device (dev_t n) const {return d.devn && n != d.devn; }
|
||||||
|
|
||||||
_minor_t get_minor () const {return d.minor;}
|
_minor_t get_minor () const {return d.minor;}
|
||||||
_major_t get_major () const {return d.major;}
|
_major_t get_major () const {return d.major;}
|
||||||
_dev_t get_device () const {return d.devn;}
|
dev_t get_device () const {return d.devn;}
|
||||||
|
|
||||||
inline operator int& () {return d.devn_int;}
|
|
||||||
inline operator fh_devices () {return d.devn_fh_devices;}
|
inline operator fh_devices () {return d.devn_fh_devices;}
|
||||||
inline operator bool () {return !!d.devn_int;}
|
inline operator bool () {return !!d.devn_int;}
|
||||||
inline operator DWORD& () {return d.devn_dword;}
|
inline operator dev_t& () {return d.devn;}
|
||||||
fh_devices operator = (fh_devices n) {return d.devn_fh_devices = n;}
|
fh_devices operator = (fh_devices n) {return d.devn_fh_devices = n;}
|
||||||
inline void setfs (bool x) {dev_on_fs = x;}
|
inline void setfs (bool x) {dev_on_fs = x;}
|
||||||
inline bool isfs () const {return dev_on_fs || d.devn == FH_FS;}
|
inline bool isfs () const {return dev_on_fs || d.devn == FH_FS;}
|
||||||
@ -377,9 +375,9 @@ extern const device dev_fs_storage;
|
|||||||
(isproc_dev (devn) || devn == FH_CYGDRIVE || devn == FH_NETDRIVE)
|
(isproc_dev (devn) || devn == FH_CYGDRIVE || devn == FH_NETDRIVE)
|
||||||
|
|
||||||
#define iscons_dev(n) \
|
#define iscons_dev(n) \
|
||||||
((device::major ((int) (n)) == DEV_CONS_MAJOR) \
|
((device::major ((dev_t) (n)) == DEV_CONS_MAJOR) \
|
||||||
|| (((int) n) == FH_CONSOLE) \
|
|| (((dev_t) n) == FH_CONSOLE) \
|
||||||
|| (((int) n) == FH_CONIN) \
|
|| (((dev_t) n) == FH_CONIN) \
|
||||||
|| (((int) n) == FH_CONOUT))
|
|| (((dev_t) n) == FH_CONOUT))
|
||||||
|
|
||||||
#define istty_slave_dev(n) (device::major (n) == DEV_PTYS_MAJOR)
|
#define istty_slave_dev(n) (device::major (n) == DEV_PTYS_MAJOR)
|
||||||
|
@ -66,7 +66,7 @@ exists_ntdev_silent (const device& dev)
|
|||||||
static int
|
static int
|
||||||
exists_console (const device& dev)
|
exists_console (const device& dev)
|
||||||
{
|
{
|
||||||
int devn = *const_cast<device *> (&dev);
|
fh_devices devn = *const_cast<device *> (&dev);
|
||||||
switch (devn)
|
switch (devn)
|
||||||
{
|
{
|
||||||
case FH_CONSOLE:
|
case FH_CONSOLE:
|
||||||
@ -207,7 +207,7 @@ device::init ()
|
|||||||
void
|
void
|
||||||
device::parse (_major_t major, _minor_t minor)
|
device::parse (_major_t major, _minor_t minor)
|
||||||
{
|
{
|
||||||
_dev_t devn = FHDEV (major, minor);
|
dev_t devn = FHDEV (major, minor);
|
||||||
|
|
||||||
d.devn = 0;
|
d.devn = 0;
|
||||||
|
|
||||||
@ -223,7 +223,7 @@ device::parse (_major_t major, _minor_t minor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
device::parse (_dev_t dev)
|
device::parse (dev_t dev)
|
||||||
{
|
{
|
||||||
parse (_major (dev), _minor (dev));
|
parse (_major (dev), _minor (dev));
|
||||||
}
|
}
|
||||||
|
@ -204,10 +204,10 @@ telldir (DIR *dir)
|
|||||||
/* telldir was never defined using off_t in POSIX, only in early versions
|
/* telldir was never defined using off_t in POSIX, only in early versions
|
||||||
of glibc. We have to keep the function in as entry point for backward
|
of glibc. We have to keep the function in as entry point for backward
|
||||||
compatibility. */
|
compatibility. */
|
||||||
extern "C" _off64_t
|
extern "C" off_t
|
||||||
telldir64 (DIR *dir)
|
telldir64 (DIR *dir)
|
||||||
{
|
{
|
||||||
return (_off64_t) telldir (dir);
|
return (off_t) telldir (dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* seekdir */
|
/* seekdir */
|
||||||
@ -228,7 +228,7 @@ seekdir (DIR *dir, long loc)
|
|||||||
of glibc. We have to keep the function in as entry point for backward
|
of glibc. We have to keep the function in as entry point for backward
|
||||||
compatibility. */
|
compatibility. */
|
||||||
extern "C" void
|
extern "C" void
|
||||||
seekdir64 (DIR *dir, _off64_t loc)
|
seekdir64 (DIR *dir, off_t loc)
|
||||||
{
|
{
|
||||||
seekdir (dir, (long) loc);
|
seekdir (dir, (long) loc);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* dlfcn.cc
|
/* dlfcn.cc
|
||||||
|
|
||||||
Copyright 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
|
Copyright 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
|
||||||
2010, 2011 Red Hat, Inc.
|
2010, 2011, 2013 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -155,33 +155,9 @@ dlopen (const char *name, int flags)
|
|||||||
|| (ret = GetModuleHandleW (path)) != NULL)
|
|| (ret = GetModuleHandleW (path)) != NULL)
|
||||||
{
|
{
|
||||||
ret = (void *) LoadLibraryW (path);
|
ret = (void *) LoadLibraryW (path);
|
||||||
if (ret && (flags & RTLD_NODELETE)
|
if (ret && (flags & RTLD_NODELETE))
|
||||||
&& !GetModuleHandleExW (GET_MODULE_HANDLE_EX_FLAG_PIN, path,
|
GetModuleHandleExW (GET_MODULE_HANDLE_EX_FLAG_PIN, path,
|
||||||
(HMODULE *) &ret))
|
(HMODULE *) &ret);
|
||||||
{
|
|
||||||
/* Windows 2000 is missing the GetModuleHandleEx call, so we
|
|
||||||
use a non-documented way to set the DLL to "don't free".
|
|
||||||
This is how it works: Fetch the Windows Loader data from
|
|
||||||
the PEB. Iterate backwards through the list of loaded
|
|
||||||
DLLs and compare the DllBase address with the address
|
|
||||||
returned by LoadLibrary. If they are equal we found the
|
|
||||||
right entry. Now set the LoadCount to -1, which is the
|
|
||||||
marker for a DLL which should never be free'd. */
|
|
||||||
PPEB_LDR_DATA ldr = NtCurrentTeb ()->Peb->Ldr;
|
|
||||||
|
|
||||||
for (PLDR_DATA_TABLE_ENTRY entry = (PLDR_DATA_TABLE_ENTRY)
|
|
||||||
ldr->InLoadOrderModuleList.Blink;
|
|
||||||
entry && entry->DllBase;
|
|
||||||
entry = (PLDR_DATA_TABLE_ENTRY)
|
|
||||||
entry->InLoadOrderLinks.Blink)
|
|
||||||
{
|
|
||||||
if (entry->DllBase == ret)
|
|
||||||
{
|
|
||||||
entry->LoadCount = (WORD) -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Restore original cxx_malloc pointer. */
|
/* Restore original cxx_malloc pointer. */
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* dll_init.cc
|
/* dll_init.cc
|
||||||
|
|
||||||
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
|
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
|
||||||
2009, 2010, 2011, 2012 Red Hat, Inc.
|
2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||||
|
|
||||||
This software is a copyrighted work licensed under the terms of the
|
This software is a copyrighted work licensed under the terms of the
|
||||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
@ -86,11 +86,13 @@ dll::init ()
|
|||||||
{
|
{
|
||||||
int ret = 1;
|
int ret = 1;
|
||||||
|
|
||||||
|
#ifndef __x86_64__
|
||||||
/* This should be a no-op. Why didn't we just import this variable? */
|
/* This should be a no-op. Why didn't we just import this variable? */
|
||||||
if (!p.envptr)
|
if (!p.envptr)
|
||||||
p.envptr = &__cygwin_environ;
|
p.envptr = &__cygwin_environ;
|
||||||
else if (*(p.envptr) != __cygwin_environ)
|
else if (*(p.envptr) != __cygwin_environ)
|
||||||
*(p.envptr) = __cygwin_environ;
|
*(p.envptr) = __cygwin_environ;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Don't run constructors or the "main" if we've forked. */
|
/* Don't run constructors or the "main" if we've forked. */
|
||||||
if (!in_forkee)
|
if (!in_forkee)
|
||||||
@ -243,7 +245,9 @@ dll_list::alloc (HINSTANCE h, per_process *p, dll_type type)
|
|||||||
loaded_dlls++;
|
loaded_dlls++;
|
||||||
}
|
}
|
||||||
guard (false);
|
guard (false);
|
||||||
|
#ifndef __x86_64__
|
||||||
assert (p->envptr != NULL);
|
assert (p->envptr != NULL);
|
||||||
|
#endif
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -430,30 +434,29 @@ dll_list::init ()
|
|||||||
covering at least _dll_size_ bytes. However, we must take care not
|
covering at least _dll_size_ bytes. However, we must take care not
|
||||||
to clobber the dll's target address range because it often overlaps.
|
to clobber the dll's target address range because it often overlaps.
|
||||||
*/
|
*/
|
||||||
static DWORD
|
static PVOID
|
||||||
reserve_at (const PWCHAR name, DWORD here, DWORD dll_base, DWORD dll_size)
|
reserve_at (const PWCHAR name, PVOID here, PVOID dll_base, DWORD dll_size)
|
||||||
{
|
{
|
||||||
DWORD size;
|
DWORD size;
|
||||||
MEMORY_BASIC_INFORMATION mb;
|
MEMORY_BASIC_INFORMATION mb;
|
||||||
|
|
||||||
if (!VirtualQuery ((void *) here, &mb, sizeof (mb)))
|
if (!VirtualQuery (here, &mb, sizeof (mb)))
|
||||||
fabort ("couldn't examine memory at %08lx while mapping %W, %E",
|
fabort ("couldn't examine memory at %p while mapping %W, %E", here, name);
|
||||||
here, name);
|
|
||||||
if (mb.State != MEM_FREE)
|
if (mb.State != MEM_FREE)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
size = mb.RegionSize;
|
size = mb.RegionSize;
|
||||||
|
|
||||||
// don't clobber the space where we want the dll to land
|
// don't clobber the space where we want the dll to land
|
||||||
DWORD end = here + size;
|
caddr_t end = (caddr_t) here + size;
|
||||||
DWORD dll_end = dll_base + dll_size;
|
caddr_t dll_end = (caddr_t) dll_base + dll_size;
|
||||||
if (dll_base < here && dll_end > here)
|
if (dll_base < here && dll_end > (caddr_t) here)
|
||||||
here = dll_end; // the dll straddles our left edge
|
here = (PVOID) dll_end; // the dll straddles our left edge
|
||||||
else if (dll_base >= here && dll_base < end)
|
else if (dll_base >= here && (caddr_t) dll_base < end)
|
||||||
end = dll_base; // the dll overlaps partly or fully to our right
|
end = (caddr_t) dll_base; // the dll overlaps partly or fully to our right
|
||||||
|
|
||||||
size = end - here;
|
size = end - (caddr_t) here;
|
||||||
if (!VirtualAlloc ((void *) here, size, MEM_RESERVE, PAGE_NOACCESS))
|
if (!VirtualAlloc (here, size, MEM_RESERVE, PAGE_NOACCESS))
|
||||||
fabort ("couldn't allocate memory %p(%d) for '%W' alignment, %E\n",
|
fabort ("couldn't allocate memory %p(%d) for '%W' alignment, %E\n",
|
||||||
here, size, name);
|
here, size, name);
|
||||||
return here;
|
return here;
|
||||||
@ -461,9 +464,9 @@ reserve_at (const PWCHAR name, DWORD here, DWORD dll_base, DWORD dll_size)
|
|||||||
|
|
||||||
/* Release the memory previously allocated by "reserve_at" above. */
|
/* Release the memory previously allocated by "reserve_at" above. */
|
||||||
static void
|
static void
|
||||||
release_at (const PWCHAR name, DWORD here)
|
release_at (const PWCHAR name, PVOID here)
|
||||||
{
|
{
|
||||||
if (!VirtualFree ((void *) here, 0, MEM_RELEASE))
|
if (!VirtualFree (here, 0, MEM_RELEASE))
|
||||||
fabort ("couldn't release memory %p for '%W' alignment, %E\n",
|
fabort ("couldn't release memory %p for '%W' alignment, %E\n",
|
||||||
here, name);
|
here, name);
|
||||||
}
|
}
|
||||||
@ -536,7 +539,7 @@ void dll_list::load_after_fork_impl (HANDLE parent, dll* d, int retries)
|
|||||||
dll's protective reservation from step 1
|
dll's protective reservation from step 1
|
||||||
*/
|
*/
|
||||||
if (!retries && !VirtualFree (d->handle, 0, MEM_RELEASE))
|
if (!retries && !VirtualFree (d->handle, 0, MEM_RELEASE))
|
||||||
fabort ("unable to release protective reservation for %W (%08lx), %E",
|
fabort ("unable to release protective reservation for %W (%p), %E",
|
||||||
d->modname, d->handle);
|
d->modname, d->handle);
|
||||||
|
|
||||||
HMODULE h = LoadLibraryExW (d->name, NULL, DONT_RESOLVE_DLL_REFERENCES);
|
HMODULE h = LoadLibraryExW (d->name, NULL, DONT_RESOLVE_DLL_REFERENCES);
|
||||||
@ -544,11 +547,11 @@ void dll_list::load_after_fork_impl (HANDLE parent, dll* d, int retries)
|
|||||||
fabort ("unable to create interim mapping for %W, %E", d->name);
|
fabort ("unable to create interim mapping for %W, %E", d->name);
|
||||||
if (h != d->handle)
|
if (h != d->handle)
|
||||||
{
|
{
|
||||||
sigproc_printf ("%W loaded in wrong place: %08lx != %08lx",
|
sigproc_printf ("%W loaded in wrong place: %p != %p",
|
||||||
d->modname, h, d->handle);
|
d->modname, h, d->handle);
|
||||||
FreeLibrary (h);
|
FreeLibrary (h);
|
||||||
DWORD reservation = reserve_at (d->modname, (DWORD) h,
|
PVOID reservation = reserve_at (d->modname, h,
|
||||||
(DWORD) d->handle, d->image_size);
|
d->handle, d->image_size);
|
||||||
if (!reservation)
|
if (!reservation)
|
||||||
fabort ("unable to block off %p to prevent %W from loading there",
|
fabort ("unable to block off %p to prevent %W from loading there",
|
||||||
h, d->modname);
|
h, d->modname);
|
||||||
@ -556,12 +559,12 @@ void dll_list::load_after_fork_impl (HANDLE parent, dll* d, int retries)
|
|||||||
if (retries < DLL_RETRY_MAX)
|
if (retries < DLL_RETRY_MAX)
|
||||||
load_after_fork_impl (parent, d, retries+1);
|
load_after_fork_impl (parent, d, retries+1);
|
||||||
else
|
else
|
||||||
fabort ("unable to remap %W to same address as parent (%08lx) - try running rebaseall",
|
fabort ("unable to remap %W to same address as parent (%p) - try running rebaseall",
|
||||||
d->modname, d->handle);
|
d->modname, d->handle);
|
||||||
|
|
||||||
/* once the above returns all the dlls are mapped; release
|
/* once the above returns all the dlls are mapped; release
|
||||||
the reservation and continue unwinding */
|
the reservation and continue unwinding */
|
||||||
sigproc_printf ("releasing blocked space at %08lx", reservation);
|
sigproc_printf ("releasing blocked space at %p", reservation);
|
||||||
release_at (d->modname, reservation);
|
release_at (d->modname, reservation);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -577,7 +580,7 @@ void dll_list::load_after_fork_impl (HANDLE parent, dll* d, int retries)
|
|||||||
if (d->handle == d->preferred_base)
|
if (d->handle == d->preferred_base)
|
||||||
{
|
{
|
||||||
if (!VirtualFree (d->handle, 0, MEM_RELEASE))
|
if (!VirtualFree (d->handle, 0, MEM_RELEASE))
|
||||||
fabort ("unable to release protective reservation for %W (%08lx), %E",
|
fabort ("unable to release protective reservation for %W (%p), %E",
|
||||||
d->modname, d->handle);
|
d->modname, d->handle);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -601,15 +604,15 @@ struct dllcrt0_info
|
|||||||
{
|
{
|
||||||
HMODULE h;
|
HMODULE h;
|
||||||
per_process *p;
|
per_process *p;
|
||||||
int res;
|
PVOID res;
|
||||||
dllcrt0_info (HMODULE h0, per_process *p0): h (h0), p (p0) {}
|
dllcrt0_info (HMODULE h0, per_process *p0): h (h0), p (p0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
extern "C" int
|
extern "C" PVOID
|
||||||
dll_dllcrt0 (HMODULE h, per_process *p)
|
dll_dllcrt0 (HMODULE h, per_process *p)
|
||||||
{
|
{
|
||||||
if (dynamically_loaded)
|
if (dynamically_loaded)
|
||||||
return 1;
|
return (PVOID) 1;
|
||||||
dllcrt0_info x (h, p);
|
dllcrt0_info x (h, p);
|
||||||
dll_dllcrt0_1 (&x);
|
dll_dllcrt0_1 (&x);
|
||||||
return x.res;
|
return x.res;
|
||||||
@ -620,7 +623,7 @@ dll_dllcrt0_1 (VOID *x)
|
|||||||
{
|
{
|
||||||
HMODULE& h = ((dllcrt0_info *) x)->h;
|
HMODULE& h = ((dllcrt0_info *) x)->h;
|
||||||
per_process*& p = ((dllcrt0_info *) x)->p;
|
per_process*& p = ((dllcrt0_info *) x)->p;
|
||||||
int& res = ((dllcrt0_info *) x)->res;
|
PVOID& res = ((dllcrt0_info *) x)->res;
|
||||||
|
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
p = &__cygwin_user_data;
|
p = &__cygwin_user_data;
|
||||||
@ -677,20 +680,21 @@ dll_dllcrt0_1 (VOID *x)
|
|||||||
it may not be safe to call the dll's "main" since not
|
it may not be safe to call the dll's "main" since not
|
||||||
all of cygwin's internal structures may have been set up. */
|
all of cygwin's internal structures may have been set up. */
|
||||||
if (!d || (!linked && !d->init ()))
|
if (!d || (!linked && !d->init ()))
|
||||||
res = -1;
|
res = (PVOID) -1;
|
||||||
else
|
else
|
||||||
res = (DWORD) d;
|
res = (PVOID) d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef __x86_64__
|
||||||
/* OBSOLETE: This function is obsolete and will go away in the
|
/* OBSOLETE: This function is obsolete and will go away in the
|
||||||
future. Cygwin can now handle being loaded from a noncygwin app
|
future. Cygwin can now handle being loaded from a noncygwin app
|
||||||
using the same entry point. */
|
using the same entry point. */
|
||||||
|
|
||||||
extern "C" int
|
extern "C" int
|
||||||
dll_noncygwin_dllcrt0 (HMODULE h, per_process *p)
|
dll_noncygwin_dllcrt0 (HMODULE h, per_process *p)
|
||||||
{
|
{
|
||||||
return dll_dllcrt0 (h, p);
|
return (int) dll_dllcrt0 (h, p);
|
||||||
}
|
}
|
||||||
|
#endif /* !__x86_64__ */
|
||||||
|
|
||||||
extern "C" void
|
extern "C" void
|
||||||
cygwin_detach_dll (dll *)
|
cygwin_detach_dll (dll *)
|
||||||
@ -709,6 +713,7 @@ dlfork (int val)
|
|||||||
dlls.reload_on_fork = val;
|
dlls.reload_on_fork = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef __x86_64__
|
||||||
/* Called from various places to update all of the individual
|
/* Called from various places to update all of the individual
|
||||||
ideas of the environ block. Explain to me again why we didn't
|
ideas of the environ block. Explain to me again why we didn't
|
||||||
just import __cygwin_environ? */
|
just import __cygwin_environ? */
|
||||||
@ -720,3 +725,4 @@ update_envptrs ()
|
|||||||
*(d->p.envptr) = __cygwin_environ;
|
*(d->p.envptr) = __cygwin_environ;
|
||||||
*main_environ = __cygwin_environ;
|
*main_environ = __cygwin_environ;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* dll_init.h
|
/* dll_init.h
|
||||||
|
|
||||||
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007, 2008, 2009, 2010,
|
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007, 2008, 2009, 2010,
|
||||||
2011, 2012 Red Hat, Inc.
|
2011, 2012, 2013 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -11,7 +11,9 @@ details. */
|
|||||||
|
|
||||||
struct per_module
|
struct per_module
|
||||||
{
|
{
|
||||||
|
#ifndef __x86_64__
|
||||||
char ***envptr;
|
char ***envptr;
|
||||||
|
#endif
|
||||||
void (**ctors)(void);
|
void (**ctors)(void);
|
||||||
void (**dtors)(void);
|
void (**dtors)(void);
|
||||||
void *data_start;
|
void *data_start;
|
||||||
@ -21,7 +23,9 @@ struct per_module
|
|||||||
int (*main)(int, char **, char **);
|
int (*main)(int, char **, char **);
|
||||||
per_module &operator = (per_process *p)
|
per_module &operator = (per_process *p)
|
||||||
{
|
{
|
||||||
|
#ifndef __x86_64__
|
||||||
envptr = p->envptr;
|
envptr = p->envptr;
|
||||||
|
#endif
|
||||||
ctors = p->ctors;
|
ctors = p->ctors;
|
||||||
dtors = p->dtors;
|
dtors = p->dtors;
|
||||||
data_start = p->data_start;
|
data_start = p->data_start;
|
||||||
@ -129,12 +133,12 @@ struct pefile
|
|||||||
{
|
{
|
||||||
IMAGE_DOS_HEADER dos_hdr;
|
IMAGE_DOS_HEADER dos_hdr;
|
||||||
|
|
||||||
char* rva (long offset) { return (char*) this + offset; }
|
char* rva (ptrdiff_t offset) { return (char*) this + offset; }
|
||||||
PIMAGE_NT_HEADERS32 pe_hdr () { return (PIMAGE_NT_HEADERS32) rva (dos_hdr.e_lfanew); }
|
PIMAGE_NT_HEADERS pe_hdr () { return (PIMAGE_NT_HEADERS) rva (dos_hdr.e_lfanew); }
|
||||||
PIMAGE_OPTIONAL_HEADER32 optional_hdr () { return &pe_hdr ()->OptionalHeader; }
|
PIMAGE_OPTIONAL_HEADER optional_hdr () { return &pe_hdr ()->OptionalHeader; }
|
||||||
PIMAGE_DATA_DIRECTORY idata_dir (DWORD which)
|
PIMAGE_DATA_DIRECTORY idata_dir (DWORD which)
|
||||||
{
|
{
|
||||||
PIMAGE_OPTIONAL_HEADER32 oh = optional_hdr ();
|
PIMAGE_OPTIONAL_HEADER oh = optional_hdr ();
|
||||||
return (which < oh->NumberOfRvaAndSizes)? oh->DataDirectory + which : 0;
|
return (which < oh->NumberOfRvaAndSizes)? oh->DataDirectory + which : 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* dtable.cc: file descriptor support.
|
/* dtable.cc: file descriptor support.
|
||||||
|
|
||||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
||||||
2007, 2008, 2009, 2010, 2011, 2012 Red Hat, Inc.
|
2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -31,8 +31,8 @@ details. */
|
|||||||
#include "ntdll.h"
|
#include "ntdll.h"
|
||||||
#include "shared_info.h"
|
#include "shared_info.h"
|
||||||
|
|
||||||
static const NO_COPY DWORD std_consts[] = {STD_INPUT_HANDLE, STD_OUTPUT_HANDLE,
|
static const DWORD std_consts[] = {STD_INPUT_HANDLE, STD_OUTPUT_HANDLE,
|
||||||
STD_ERROR_HANDLE};
|
STD_ERROR_HANDLE};
|
||||||
|
|
||||||
static bool handle_to_fn (HANDLE, char *);
|
static bool handle_to_fn (HANDLE, char *);
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ dtable::extend (int howmuch)
|
|||||||
|
|
||||||
size = new_size;
|
size = new_size;
|
||||||
fds = newfds;
|
fds = newfds;
|
||||||
debug_printf ("size %d, fds %p", size, fds);
|
debug_printf ("size %ld, fds %p", size, fds);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,8 +115,8 @@ dtable::get_debugger_info ()
|
|||||||
{
|
{
|
||||||
char std[3][sizeof ("/dev/ptyNNNN")];
|
char std[3][sizeof ("/dev/ptyNNNN")];
|
||||||
std[0][0] = std[1][0] = std [2][0] = '\0';
|
std[0][0] = std[1][0] = std [2][0] = '\0';
|
||||||
char buf[sizeof ("cYgstd %x") + 32];
|
char buf[sizeof ("cYgstd %x") + 64];
|
||||||
sprintf (buf, "cYgstd %x %x %x", (unsigned) &std, sizeof (std[0]), 3);
|
sprintf (buf, "cYgstd %p %zx %x", &std, sizeof (std[0]), 3);
|
||||||
OutputDebugString (buf);
|
OutputDebugString (buf);
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
if (std[i][0])
|
if (std[i][0])
|
||||||
@ -194,7 +194,7 @@ fhandler_base *
|
|||||||
dtable::find_archetype (device& dev)
|
dtable::find_archetype (device& dev)
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < farchetype; i++)
|
for (unsigned i = 0; i < farchetype; i++)
|
||||||
if (archetypes[i]->get_device () == (DWORD) dev)
|
if (archetypes[i]->get_device () == (dev_t) dev)
|
||||||
return archetypes[i];
|
return archetypes[i];
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -482,7 +482,7 @@ fh_alloc (path_conv& pc)
|
|||||||
fh = cnew (fhandler_console, pc.dev);
|
fh = cnew (fhandler_console, pc.dev);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
switch ((DWORD) pc.dev)
|
switch ((dev_t) pc.dev)
|
||||||
{
|
{
|
||||||
case FH_CONSOLE:
|
case FH_CONSOLE:
|
||||||
case FH_CONIN:
|
case FH_CONIN:
|
||||||
@ -661,7 +661,7 @@ build_fh_pc (path_conv& pc)
|
|||||||
last_tty_dev = fh->dev ();
|
last_tty_dev = fh->dev ();
|
||||||
|
|
||||||
out:
|
out:
|
||||||
debug_printf ("fh %p, dev %p", fh, fh ? (DWORD) fh->dev () : 0);
|
debug_printf ("fh %p, dev %08x", fh, fh ? (dev_t) fh->dev () : 0);
|
||||||
return fh;
|
return fh;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -710,7 +710,7 @@ dtable::dup3 (int oldfd, int newfd, int flags)
|
|||||||
fhandler_base *newfh = NULL; // = NULL to avoid an incorrect warning
|
fhandler_base *newfh = NULL; // = NULL to avoid an incorrect warning
|
||||||
|
|
||||||
MALLOC_CHECK;
|
MALLOC_CHECK;
|
||||||
debug_printf ("dup3 (%d, %d, %p)", oldfd, newfd, flags);
|
debug_printf ("dup3 (%d, %d, %y)", oldfd, newfd, flags);
|
||||||
lock ();
|
lock ();
|
||||||
bool do_unlock = true;
|
bool do_unlock = true;
|
||||||
bool unlock_on_return;
|
bool unlock_on_return;
|
||||||
@ -736,7 +736,7 @@ dtable::dup3 (int oldfd, int newfd, int flags)
|
|||||||
}
|
}
|
||||||
if ((flags & ~O_CLOEXEC) != 0)
|
if ((flags & ~O_CLOEXEC) != 0)
|
||||||
{
|
{
|
||||||
syscall_printf ("invalid flags value %x", flags);
|
syscall_printf ("invalid flags value %y", flags);
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -778,7 +778,7 @@ done:
|
|||||||
MALLOC_CHECK;
|
MALLOC_CHECK;
|
||||||
if (do_unlock)
|
if (do_unlock)
|
||||||
unlock ();
|
unlock ();
|
||||||
syscall_printf ("%R = dup3(%d, %d, %p)", res, oldfd, newfd, flags);
|
syscall_printf ("%R = dup3(%d, %d, %y)", res, oldfd, newfd, flags);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -939,7 +939,7 @@ handle_to_fn (HANDLE h, char *posix_fn)
|
|||||||
|
|
||||||
NTSTATUS status = NtQueryObject (h, ObjectNameInformation, ntfn, 65536, &len);
|
NTSTATUS status = NtQueryObject (h, ObjectNameInformation, ntfn, 65536, &len);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
debug_printf ("NtQueryObject failed, %p", status);
|
debug_printf ("NtQueryObject failed, %y", status);
|
||||||
// NT seems to do this on an unopened file
|
// NT seems to do this on an unopened file
|
||||||
else if (!ntfn->Name.Buffer)
|
else if (!ntfn->Name.Buffer)
|
||||||
debug_printf ("nt->Name.Buffer == NULL");
|
debug_printf ("nt->Name.Buffer == NULL");
|
||||||
|
@ -187,7 +187,7 @@ parse_options (const char *inbuf)
|
|||||||
*k->setting.x = k->values[istrue].i;
|
*k->setting.x = k->values[istrue].i;
|
||||||
else
|
else
|
||||||
*k->setting.x = strtol (eq, NULL, 0);
|
*k->setting.x = strtol (eq, NULL, 0);
|
||||||
debug_printf ("%s %d", k->name, *k->setting.x);
|
debug_printf ("%s %u", k->name, *k->setting.x);
|
||||||
break;
|
break;
|
||||||
case setbool:
|
case setbool:
|
||||||
if (!istrue || !eq)
|
if (!istrue || !eq)
|
||||||
@ -1048,7 +1048,7 @@ build_env (const char * const *envp, PWCHAR &envblock, int &envc,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
*pass_dstp = NULL;
|
*pass_dstp = NULL;
|
||||||
debug_printf ("env count %d, bytes %d", pass_envc, tl);
|
debug_printf ("env count %ld, bytes %d", pass_envc, tl);
|
||||||
win_env temp;
|
win_env temp;
|
||||||
temp.reset ();
|
temp.reset ();
|
||||||
|
|
||||||
@ -1118,6 +1118,7 @@ build_env (const char * const *envp, PWCHAR &envblock, int &envc,
|
|||||||
return newenv;
|
return newenv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef __x86_64__
|
||||||
/* This idiocy is necessary because the early implementers of cygwin
|
/* This idiocy is necessary because the early implementers of cygwin
|
||||||
did not seem to know about importing data variables from the DLL.
|
did not seem to know about importing data variables from the DLL.
|
||||||
So, we have to synchronize cygwin's idea of the environment with the
|
So, we have to synchronize cygwin's idea of the environment with the
|
||||||
@ -1133,3 +1134,4 @@ cur_environ ()
|
|||||||
|
|
||||||
return __cygwin_environ;
|
return __cygwin_environ;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
@ -35,9 +35,15 @@ struct win_env
|
|||||||
win_env * __reg3 getwinenv (const char *name, const char *posix = NULL, win_env * = NULL);
|
win_env * __reg3 getwinenv (const char *name, const char *posix = NULL, win_env * = NULL);
|
||||||
char * __reg3 getwinenveq (const char *name, size_t len, int);
|
char * __reg3 getwinenveq (const char *name, size_t len, int);
|
||||||
|
|
||||||
|
#ifdef __x86_64__
|
||||||
|
#define update_envptrs()
|
||||||
|
extern "C" char **__cygwin_environ;
|
||||||
|
#define cur_environ() __cygwin_environ
|
||||||
|
#else
|
||||||
void __stdcall update_envptrs ();
|
void __stdcall update_envptrs ();
|
||||||
extern "C" char **__cygwin_environ, ***main_environ;
|
extern "C" char **__cygwin_environ, ***main_environ;
|
||||||
extern "C" char __stdcall **cur_environ ();
|
extern "C" char __stdcall **cur_environ ();
|
||||||
|
#endif
|
||||||
char ** __reg3 build_env (const char * const *envp, PWCHAR &envblock,
|
char ** __reg3 build_env (const char * const *envp, PWCHAR &envblock,
|
||||||
int &envc, bool need_envblock);
|
int &envc, bool need_envblock);
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ details. */
|
|||||||
|
|
||||||
#define X(w, e) {ERROR_##w, #w, e}
|
#define X(w, e) {ERROR_##w, #w, e}
|
||||||
|
|
||||||
static NO_COPY struct
|
static const struct
|
||||||
{
|
{
|
||||||
DWORD w; /* windows version of error */
|
DWORD w; /* windows version of error */
|
||||||
const char *s; /* text of windows version */
|
const char *s; /* text of windows version */
|
||||||
@ -162,7 +162,7 @@ static NO_COPY struct
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
const char *_sys_errlist[] NO_COPY_INIT =
|
const char *_sys_errlist[] =
|
||||||
{
|
{
|
||||||
/* NOERROR 0 */ "No error",
|
/* NOERROR 0 */ "No error",
|
||||||
/* EPERM 1 */ "Operation not permitted",
|
/* EPERM 1 */ "Operation not permitted",
|
||||||
@ -333,7 +333,7 @@ geterrno_from_win_error (DWORD code, int deferrno)
|
|||||||
void __reg3
|
void __reg3
|
||||||
seterrno_from_win_error (const char *file, int line, DWORD code)
|
seterrno_from_win_error (const char *file, int line, DWORD code)
|
||||||
{
|
{
|
||||||
syscall_printf ("%s:%d windows error %d", file, line, code);
|
syscall_printf ("%s:%d windows error %u", file, line, code);
|
||||||
errno = _impure_ptr->_errno = geterrno_from_win_error (code, EACCES);
|
errno = _impure_ptr->_errno = geterrno_from_win_error (code, EACCES);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,7 +350,7 @@ seterrno_from_nt_status (const char *file, int line, NTSTATUS status)
|
|||||||
{
|
{
|
||||||
DWORD code = RtlNtStatusToDosError (status);
|
DWORD code = RtlNtStatusToDosError (status);
|
||||||
SetLastError (code);
|
SetLastError (code);
|
||||||
syscall_printf ("%s:%d status %p -> windows error %d",
|
syscall_printf ("%s:%d status %y -> windows error %u",
|
||||||
file, line, status, code);
|
file, line, status, code);
|
||||||
errno = _impure_ptr->_errno = geterrno_from_win_error (code, EACCES);
|
errno = _impure_ptr->_errno = geterrno_from_win_error (code, EACCES);
|
||||||
}
|
}
|
||||||
|
@ -8,35 +8,61 @@ details. */
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __x86_64__
|
||||||
|
#define _exception_list _EXCEPTION_REGISTRATION_RECORD
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <exceptions.h>
|
#include <exceptions.h>
|
||||||
|
|
||||||
|
#ifndef __x86_64__
|
||||||
extern exception_list *_except_list asm ("%fs:0");
|
extern exception_list *_except_list asm ("%fs:0");
|
||||||
|
#endif
|
||||||
|
|
||||||
class exception
|
class exception
|
||||||
{
|
{
|
||||||
|
#ifdef __x86_64__
|
||||||
|
static bool handler_installed;
|
||||||
|
static int handle (LPEXCEPTION_POINTERS);
|
||||||
|
#else
|
||||||
exception_list el;
|
exception_list el;
|
||||||
exception_list *save;
|
exception_list *save;
|
||||||
static int handle (EXCEPTION_RECORD *, exception_list *, CONTEXT *, void *);
|
static int handle (EXCEPTION_RECORD *, exception_list *, CONTEXT *, void *);
|
||||||
|
#endif
|
||||||
public:
|
public:
|
||||||
exception () __attribute__ ((always_inline))
|
exception () __attribute__ ((always_inline))
|
||||||
{
|
{
|
||||||
|
#ifdef __x86_64__
|
||||||
|
if (!handler_installed)
|
||||||
|
{
|
||||||
|
handler_installed = true;
|
||||||
|
/* The unhandled exception filter goes first. It won't work if the
|
||||||
|
executable is debugged, but then the vectored continue handler
|
||||||
|
kicks in. For some reason the vectored continue handler doesn't
|
||||||
|
get called if no unhandled exception filter is installed. */
|
||||||
|
SetUnhandledExceptionFilter (handle);
|
||||||
|
AddVectoredContinueHandler (1, handle);
|
||||||
|
}
|
||||||
|
#else
|
||||||
save = _except_list;
|
save = _except_list;
|
||||||
el.handler = handle;
|
el.handler = handle;
|
||||||
el.prev = _except_list;
|
el.prev = _except_list;
|
||||||
_except_list = ⪙
|
_except_list = ⪙
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
#ifndef __x86_64__
|
||||||
~exception () __attribute__ ((always_inline)) { _except_list = save; }
|
~exception () __attribute__ ((always_inline)) { _except_list = save; }
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
class cygwin_exception
|
class cygwin_exception
|
||||||
{
|
{
|
||||||
DWORD ebp;
|
PUINT_PTR framep;
|
||||||
PCONTEXT ctx;
|
PCONTEXT ctx;
|
||||||
EXCEPTION_RECORD *e;
|
EXCEPTION_RECORD *e;
|
||||||
void dump_exception ();
|
void dump_exception ();
|
||||||
public:
|
public:
|
||||||
cygwin_exception (DWORD in_ebp, PCONTEXT in_ctx = NULL, EXCEPTION_RECORD *in_e = NULL):
|
cygwin_exception (PUINT_PTR in_framep, PCONTEXT in_ctx = NULL, EXCEPTION_RECORD *in_e = NULL):
|
||||||
ebp (in_ebp), ctx (in_ctx), e (in_e) {}
|
framep (in_framep), ctx (in_ctx), e (in_e) {}
|
||||||
void dumpstack ();
|
void dumpstack ();
|
||||||
PCONTEXT context () const {return ctx;}
|
PCONTEXT context () const {return ctx;}
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* exceptions.cc
|
/* exceptions.cc
|
||||||
|
|
||||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||||
2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -32,6 +32,17 @@ details. */
|
|||||||
#include "ntdll.h"
|
#include "ntdll.h"
|
||||||
#include "exception.h"
|
#include "exception.h"
|
||||||
|
|
||||||
|
/* Definitions for code simplification */
|
||||||
|
#ifdef __x86_64__
|
||||||
|
# define _GR(reg) R ## reg
|
||||||
|
# define _AFMT "%011X"
|
||||||
|
# define _ADDR DWORD64
|
||||||
|
#else
|
||||||
|
# define _GR(reg) E ## reg
|
||||||
|
# define _AFMT "%08x"
|
||||||
|
# define _ADDR DWORD
|
||||||
|
#endif
|
||||||
|
|
||||||
#define CALL_HANDLER_RETRY_OUTER 10
|
#define CALL_HANDLER_RETRY_OUTER 10
|
||||||
#define CALL_HANDLER_RETRY_INNER 10
|
#define CALL_HANDLER_RETRY_INNER 10
|
||||||
|
|
||||||
@ -39,7 +50,7 @@ char debugger_command[2 * NT_MAX_PATH + 20];
|
|||||||
|
|
||||||
static BOOL WINAPI ctrl_c_handler (DWORD);
|
static BOOL WINAPI ctrl_c_handler (DWORD);
|
||||||
|
|
||||||
NO_COPY static struct
|
static const struct
|
||||||
{
|
{
|
||||||
NTSTATUS code;
|
NTSTATUS code;
|
||||||
const char *name;
|
const char *name;
|
||||||
@ -178,6 +189,20 @@ cygwin_exception::dump_exception ()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __x86_64__
|
||||||
|
if (exception_name)
|
||||||
|
small_printf ("Exception: %s at rip=%011X\r\n", exception_name, ctx->Rip);
|
||||||
|
else
|
||||||
|
small_printf ("Signal %d at rip=%011X\r\n", e->ExceptionCode, ctx->Rip);
|
||||||
|
small_printf ("rax=%016X rbx=%016X rcx=%016X\r\n", ctx->Rax, ctx->Rbx, ctx->Rcx);
|
||||||
|
small_printf ("rdx=%016X rsi=%016X rdi=%016X\r\n", ctx->Rdx, ctx->Rsi, ctx->Rdi);
|
||||||
|
small_printf ("r8 =%016X r9 =%016X r10=%016X\r\n", ctx->R8, ctx->R9, ctx->R10);
|
||||||
|
small_printf ("r11=%016X r12=%016X r13=%016X\r\n", ctx->R11, ctx->R12, ctx->R13);
|
||||||
|
small_printf ("r14=%016X r15=%016X\r\n", ctx->R14, ctx->R15);
|
||||||
|
small_printf ("rbp=%016X rsp=%016X\r\n", ctx->Rbp, ctx->Rsp);
|
||||||
|
small_printf ("program=%W, pid %u, thread %s\r\n",
|
||||||
|
myself->progname, myself->pid, cygthread::name ());
|
||||||
|
#else
|
||||||
if (exception_name)
|
if (exception_name)
|
||||||
small_printf ("Exception: %s at eip=%08x\r\n", exception_name, ctx->Eip);
|
small_printf ("Exception: %s at eip=%08x\r\n", exception_name, ctx->Eip);
|
||||||
else
|
else
|
||||||
@ -185,7 +210,9 @@ cygwin_exception::dump_exception ()
|
|||||||
small_printf ("eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x\r\n",
|
small_printf ("eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x\r\n",
|
||||||
ctx->Eax, ctx->Ebx, ctx->Ecx, ctx->Edx, ctx->Esi, ctx->Edi);
|
ctx->Eax, ctx->Ebx, ctx->Ecx, ctx->Edx, ctx->Esi, ctx->Edi);
|
||||||
small_printf ("ebp=%08x esp=%08x program=%W, pid %u, thread %s\r\n",
|
small_printf ("ebp=%08x esp=%08x program=%W, pid %u, thread %s\r\n",
|
||||||
ctx->Ebp, ctx->Esp, myself->progname, myself->pid, cygthread::name ());
|
ctx->Ebp, ctx->Esp, myself->progname, myself->pid,
|
||||||
|
cygthread::name ());
|
||||||
|
#endif
|
||||||
small_printf ("cs=%04x ds=%04x es=%04x fs=%04x gs=%04x ss=%04x\r\n",
|
small_printf ("cs=%04x ds=%04x es=%04x fs=%04x gs=%04x ss=%04x\r\n",
|
||||||
ctx->SegCs, ctx->SegDs, ctx->SegEs, ctx->SegFs, ctx->SegGs, ctx->SegSs);
|
ctx->SegCs, ctx->SegDs, ctx->SegEs, ctx->SegFs, ctx->SegGs, ctx->SegSs);
|
||||||
}
|
}
|
||||||
@ -196,10 +223,14 @@ class stack_info
|
|||||||
int walk (); /* Uses the "old" method */
|
int walk (); /* Uses the "old" method */
|
||||||
char *next_offset () {return *((char **) sf.AddrFrame.Offset);}
|
char *next_offset () {return *((char **) sf.AddrFrame.Offset);}
|
||||||
bool needargs;
|
bool needargs;
|
||||||
DWORD dummy_frame;
|
PUINT_PTR dummy_frame;
|
||||||
|
#ifdef __x86_64__
|
||||||
|
CONTEXT c;
|
||||||
|
UNWIND_HISTORY_TABLE hist;
|
||||||
|
#endif
|
||||||
public:
|
public:
|
||||||
STACKFRAME sf; /* For storing the stack information */
|
STACKFRAME sf; /* For storing the stack information */
|
||||||
void init (DWORD, bool, bool); /* Called the first time that stack info is needed */
|
void init (PUINT_PTR, bool, PCONTEXT); /* Called the first time that stack info is needed */
|
||||||
|
|
||||||
/* Postfix ++ iterates over the stack, returning zero when nothing is left. */
|
/* Postfix ++ iterates over the stack, returning zero when nothing is left. */
|
||||||
int operator ++(int) { return walk (); }
|
int operator ++(int) { return walk (); }
|
||||||
@ -213,21 +244,30 @@ static NO_COPY stack_info thestack;
|
|||||||
|
|
||||||
/* Initialize everything needed to start iterating. */
|
/* Initialize everything needed to start iterating. */
|
||||||
void
|
void
|
||||||
stack_info::init (DWORD ebp, bool wantargs, bool goodframe)
|
stack_info::init (PUINT_PTR framep, bool wantargs, PCONTEXT ctx)
|
||||||
{
|
{
|
||||||
# define debp ((DWORD *) ebp)
|
#ifdef __x86_64__
|
||||||
memset (&sf, 0, sizeof (sf));
|
memset (&hist, 0, sizeof hist);
|
||||||
if (!goodframe)
|
if (ctx)
|
||||||
sf.AddrFrame.Offset = ebp;
|
memcpy (&c, ctx, sizeof c);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dummy_frame = ebp;
|
memset (&c, 0, sizeof c);
|
||||||
sf.AddrFrame.Offset = (DWORD) &dummy_frame;
|
c.ContextFlags = CONTEXT_ALL;
|
||||||
}
|
}
|
||||||
sf.AddrReturn.Offset = debp[1];
|
#endif
|
||||||
|
memset (&sf, 0, sizeof (sf));
|
||||||
|
if (ctx)
|
||||||
|
sf.AddrFrame.Offset = (UINT_PTR) framep;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dummy_frame = framep;
|
||||||
|
sf.AddrFrame.Offset = (UINT_PTR) &dummy_frame;
|
||||||
|
}
|
||||||
|
if (framep)
|
||||||
|
sf.AddrReturn.Offset = framep[1];
|
||||||
sf.AddrFrame.Mode = AddrModeFlat;
|
sf.AddrFrame.Mode = AddrModeFlat;
|
||||||
needargs = wantargs;
|
needargs = wantargs;
|
||||||
# undef debp
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void _cygwin_exit_return ();
|
extern "C" void _cygwin_exit_return ();
|
||||||
@ -237,26 +277,56 @@ extern "C" void _cygwin_exit_return ();
|
|||||||
int
|
int
|
||||||
stack_info::walk ()
|
stack_info::walk ()
|
||||||
{
|
{
|
||||||
char **ebp;
|
#ifdef __x86_64__
|
||||||
|
PRUNTIME_FUNCTION f;
|
||||||
|
ULONG64 imagebase;
|
||||||
|
DWORD64 establisher;
|
||||||
|
PVOID hdl;
|
||||||
|
|
||||||
|
if (!c.Rip)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
sf.AddrPC.Offset = c.Rip;
|
||||||
|
sf.AddrStack.Offset = c.Rsp;
|
||||||
|
sf.AddrFrame.Offset = c.Rbp;
|
||||||
|
|
||||||
|
f = RtlLookupFunctionEntry (c.Rip, &imagebase, &hist);
|
||||||
|
if (f)
|
||||||
|
RtlVirtualUnwind (0, imagebase, c.Rip, f, &c, &hdl, &establisher, NULL);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
c.Rip = *(ULONG_PTR *) c.Rsp;
|
||||||
|
c.Rsp += 8;
|
||||||
|
}
|
||||||
|
if (needargs && c.Rip)
|
||||||
|
{
|
||||||
|
PULONG_PTR p = (PULONG_PTR) c.Rsp;
|
||||||
|
for (unsigned i = 0; i < NPARAMS; ++i)
|
||||||
|
sf.Params[i] = p[i + 1];
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
#else
|
||||||
|
char **framep;
|
||||||
|
|
||||||
if ((void (*) ()) sf.AddrPC.Offset == _cygwin_exit_return)
|
if ((void (*) ()) sf.AddrPC.Offset == _cygwin_exit_return)
|
||||||
return 0; /* stack frames are exhausted */
|
return 0; /* stack frames are exhausted */
|
||||||
|
|
||||||
if (((ebp = (char **) next_offset ()) == NULL) || (ebp >= (char **) cygwin_hmodule))
|
if (((framep = (char **) next_offset ()) == NULL)
|
||||||
|
|| (framep >= (char **) cygwin_hmodule))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
sf.AddrFrame.Offset = (DWORD) ebp;
|
sf.AddrFrame.Offset = (_ADDR) framep;
|
||||||
sf.AddrPC.Offset = sf.AddrReturn.Offset;
|
sf.AddrPC.Offset = sf.AddrReturn.Offset;
|
||||||
|
|
||||||
/* The return address always follows the stack pointer */
|
/* The return address always follows the stack pointer */
|
||||||
sf.AddrReturn.Offset = (DWORD) *++ebp;
|
sf.AddrReturn.Offset = (_ADDR) *++framep;
|
||||||
|
|
||||||
if (needargs)
|
if (needargs)
|
||||||
{
|
{
|
||||||
unsigned nparams = NPARAMS;
|
unsigned nparams = NPARAMS;
|
||||||
|
|
||||||
/* The arguments follow the return address */
|
/* The arguments follow the return address */
|
||||||
sf.Params[0] = (DWORD) *++ebp;
|
sf.Params[0] = (_ADDR) *++framep;
|
||||||
/* Hack for XP/2K3 WOW64. If the first stack param points to the
|
/* Hack for XP/2K3 WOW64. If the first stack param points to the
|
||||||
application entry point, we can only fetch one additional
|
application entry point, we can only fetch one additional
|
||||||
parameter. Accessing anything beyond this address results in
|
parameter. Accessing anything beyond this address results in
|
||||||
@ -264,10 +334,10 @@ stack_info::walk ()
|
|||||||
if (wincap.has_restricted_stack_args () && sf.Params[0] == 0x401000)
|
if (wincap.has_restricted_stack_args () && sf.Params[0] == 0x401000)
|
||||||
nparams = 2;
|
nparams = 2;
|
||||||
for (unsigned i = 1; i < nparams; i++)
|
for (unsigned i = 1; i < nparams; i++)
|
||||||
sf.Params[i] = (DWORD) *++ebp;
|
sf.Params[i] = (_ADDR) *++framep;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -285,14 +355,18 @@ cygwin_exception::dumpstack ()
|
|||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
thestack.init (ebp, 1, !ctx); /* Initialize from the input CONTEXT */
|
thestack.init (framep, 1, ctx); /* Initialize from the input CONTEXT */
|
||||||
|
#ifdef __x86_64__
|
||||||
|
small_printf ("Stack trace:\r\nFrame Function Args\r\n");
|
||||||
|
#else
|
||||||
small_printf ("Stack trace:\r\nFrame Function Args\r\n");
|
small_printf ("Stack trace:\r\nFrame Function Args\r\n");
|
||||||
|
#endif
|
||||||
for (i = 0; i < 16 && thestack++; i++)
|
for (i = 0; i < 16 && thestack++; i++)
|
||||||
{
|
{
|
||||||
small_printf ("%08x %08x ", thestack.sf.AddrFrame.Offset,
|
small_printf (_AFMT " " _AFMT, thestack.sf.AddrFrame.Offset,
|
||||||
thestack.sf.AddrPC.Offset);
|
thestack.sf.AddrPC.Offset);
|
||||||
for (unsigned j = 0; j < NPARAMS; j++)
|
for (unsigned j = 0; j < NPARAMS; j++)
|
||||||
small_printf ("%s%08x", j == 0 ? " (" : ", ", thestack.sf.Params[j]);
|
small_printf ("%s" _AFMT, j == 0 ? " (" : ", ", thestack.sf.Params[j]);
|
||||||
small_printf (")\r\n");
|
small_printf (")\r\n");
|
||||||
}
|
}
|
||||||
small_printf ("End of stack trace%s\n",
|
small_printf ("End of stack trace%s\n",
|
||||||
@ -309,8 +383,8 @@ _cygtls::inside_kernel (CONTEXT *cx)
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
memset (&m, 0, sizeof m);
|
memset (&m, 0, sizeof m);
|
||||||
if (!VirtualQuery ((LPCVOID) cx->Eip, &m, sizeof m))
|
if (!VirtualQuery ((LPCVOID) cx->_GR(ip), &m, sizeof m))
|
||||||
sigproc_printf ("couldn't get memory info, pc %p, %E", cx->Eip);
|
sigproc_printf ("couldn't get memory info, pc %p, %E", cx->_GR(ip));
|
||||||
|
|
||||||
size_t size = (windows_system_directory_length + 6) * sizeof (WCHAR);
|
size_t size = (windows_system_directory_length + 6) * sizeof (WCHAR);
|
||||||
PWCHAR checkdir = (PWCHAR) alloca (size);
|
PWCHAR checkdir = (PWCHAR) alloca (size);
|
||||||
@ -330,12 +404,14 @@ _cygtls::inside_kernel (CONTEXT *cx)
|
|||||||
checkdir += 4;
|
checkdir += 4;
|
||||||
res = wcsncasecmp (windows_system_directory, checkdir,
|
res = wcsncasecmp (windows_system_directory, checkdir,
|
||||||
windows_system_directory_length) == 0;
|
windows_system_directory_length) == 0;
|
||||||
|
#ifndef __x86_64__
|
||||||
if (!res && system_wow64_directory_length)
|
if (!res && system_wow64_directory_length)
|
||||||
res = wcsncasecmp (system_wow64_directory, checkdir,
|
res = wcsncasecmp (system_wow64_directory, checkdir,
|
||||||
system_wow64_directory_length) == 0;
|
system_wow64_directory_length) == 0;
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
sigproc_printf ("pc %p, h %p, inside_kernel %d", cx->Eip, h, res);
|
sigproc_printf ("pc %p, h %p, inside_kernel %d", cx->_GR(ip), h, res);
|
||||||
# undef h
|
# undef h
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -346,8 +422,8 @@ cygwin_stackdump ()
|
|||||||
{
|
{
|
||||||
CONTEXT c;
|
CONTEXT c;
|
||||||
c.ContextFlags = CONTEXT_FULL;
|
c.ContextFlags = CONTEXT_FULL;
|
||||||
GetThreadContext (GetCurrentThread (), &c);
|
RtlCaptureContext (&c);
|
||||||
cygwin_exception exc (c.Ebp);
|
cygwin_exception exc ((PUINT_PTR) c._GR(bp), &c);
|
||||||
exc.dumpstack ();
|
exc.dumpstack ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -440,9 +516,13 @@ try_to_debug (bool waitloop)
|
|||||||
return dbg;
|
return dbg;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void WINAPI RtlUnwind (void *, void *, PEXCEPTION_RECORD, void *);
|
#ifdef __x86_64__
|
||||||
static void __reg3 rtl_unwind (exception_list *, PEXCEPTION_RECORD) __attribute__ ((noinline, ));
|
/* Don't unwind the stack on x86_64. It's not necessary to do that from the
|
||||||
void __stdcall
|
exception handler. */
|
||||||
|
#define rtl_unwind(el,er)
|
||||||
|
#else
|
||||||
|
static void __reg3 rtl_unwind (exception_list *, PEXCEPTION_RECORD) __attribute__ ((noinline, regparm (3)));
|
||||||
|
void __reg3
|
||||||
rtl_unwind (exception_list *frame, PEXCEPTION_RECORD e)
|
rtl_unwind (exception_list *frame, PEXCEPTION_RECORD e)
|
||||||
{
|
{
|
||||||
__asm__ ("\n\
|
__asm__ ("\n\
|
||||||
@ -460,27 +540,44 @@ rtl_unwind (exception_list *frame, PEXCEPTION_RECORD e)
|
|||||||
popl %%ebx \n\
|
popl %%ebx \n\
|
||||||
": : "r" (frame), "r" (e));
|
": : "r" (frame), "r" (e));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Main exception handler. */
|
/* Main exception handler. */
|
||||||
|
|
||||||
extern exception_list *_except_list asm ("%fs:0");
|
#ifdef __x86_64__
|
||||||
|
#define CYG_EXC_CONTINUE_EXECUTION EXCEPTION_CONTINUE_EXECUTION
|
||||||
|
#define CYG_EXC_CONTINUE_SEARCH EXCEPTION_CONTINUE_SEARCH
|
||||||
|
|
||||||
|
bool exception::handler_installed NO_COPY;
|
||||||
|
|
||||||
|
int
|
||||||
|
exception::handle (LPEXCEPTION_POINTERS ep)
|
||||||
|
#else
|
||||||
|
#define CYG_EXC_CONTINUE_EXECUTION 0
|
||||||
|
#define CYG_EXC_CONTINUE_SEARCH 1
|
||||||
|
|
||||||
int
|
int
|
||||||
exception::handle (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in, void *)
|
exception::handle (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in, void *)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
static bool NO_COPY debugging;
|
static bool NO_COPY debugging;
|
||||||
_cygtls& me = _my_tls;
|
_cygtls& me = _my_tls;
|
||||||
|
|
||||||
|
#ifdef __x86_64__
|
||||||
|
EXCEPTION_RECORD *e = ep->ExceptionRecord;
|
||||||
|
CONTEXT *in = ep->ContextRecord;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (debugging && ++debugging < 500000)
|
if (debugging && ++debugging < 500000)
|
||||||
{
|
{
|
||||||
SetThreadPriority (hMainThread, THREAD_PRIORITY_NORMAL);
|
SetThreadPriority (hMainThread, THREAD_PRIORITY_NORMAL);
|
||||||
return 0;
|
return CYG_EXC_CONTINUE_EXECUTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we're exiting, don't do anything here. Returning 1
|
/* If we're exiting, don't do anything here. Returning 1
|
||||||
tells Windows to keep looking for an exception handler. */
|
tells Windows to keep looking for an exception handler. */
|
||||||
if (exit_state || e->ExceptionFlags)
|
if (exit_state || e->ExceptionFlags)
|
||||||
return 1;
|
return CYG_EXC_CONTINUE_SEARCH;
|
||||||
|
|
||||||
siginfo_t si = {};
|
siginfo_t si = {};
|
||||||
si.si_code = SI_KERNEL;
|
si.si_code = SI_KERNEL;
|
||||||
@ -549,7 +646,7 @@ exception::handle (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in, void
|
|||||||
1))
|
1))
|
||||||
{
|
{
|
||||||
case MMAP_NORESERVE_COMMITED:
|
case MMAP_NORESERVE_COMMITED:
|
||||||
return 0;
|
return CYG_EXC_CONTINUE_EXECUTION;
|
||||||
case MMAP_RAISE_SIGBUS: /* MAP_NORESERVE page, commit failed, or
|
case MMAP_RAISE_SIGBUS: /* MAP_NORESERVE page, commit failed, or
|
||||||
access to mmap page beyond EOF. */
|
access to mmap page beyond EOF. */
|
||||||
si.si_signo = SIGBUS;
|
si.si_signo = SIGBUS;
|
||||||
@ -583,26 +680,34 @@ exception::handle (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in, void
|
|||||||
want CloseHandle to return an error. This can be revisited
|
want CloseHandle to return an error. This can be revisited
|
||||||
if gcc ever supports Windows style structured exception
|
if gcc ever supports Windows style structured exception
|
||||||
handling. */
|
handling. */
|
||||||
return 0;
|
return CYG_EXC_CONTINUE_EXECUTION;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* If we don't recognize the exception, we have to assume that
|
/* If we don't recognize the exception, we have to assume that
|
||||||
we are doing structured exception handling, and we let
|
we are doing structured exception handling, and we let
|
||||||
something else handle it. */
|
something else handle it. */
|
||||||
return 1;
|
return CYG_EXC_CONTINUE_SEARCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (me.andreas)
|
if (me.andreas)
|
||||||
me.andreas->leave (); /* Return from a "san" caught fault */
|
me.andreas->leave (); /* Return from a "san" caught fault */
|
||||||
|
|
||||||
debug_printf ("In cygwin_except_handler exception %p at %p sp %p", e->ExceptionCode, in->Eip, in->Esp);
|
debug_printf ("In cygwin_except_handler exception %y at %p sp %p", e->ExceptionCode, in->_GR(ip), in->_GR(sp));
|
||||||
debug_printf ("In cygwin_except_handler signal %d at %p", si.si_signo, in->Eip);
|
debug_printf ("In cygwin_except_handler signal %d at %p", si.si_signo, in->_GR(ip));
|
||||||
|
|
||||||
DWORD *ebp = (DWORD *) in->Esp;
|
#ifdef __x86_64__
|
||||||
for (DWORD *bpend = (DWORD *) __builtin_frame_address (0); ebp > bpend; ebp--)
|
PUINT_PTR framep = (PUINT_PTR) in->Rbp;
|
||||||
if (*ebp == in->SegCs && ebp[-1] == in->Eip)
|
/* Sometimes, when a stack is screwed up, Rbp tends to be NULL. In that
|
||||||
|
case, base the stacktrace on Rsp. In most cases, it allows to generate
|
||||||
|
useful stack trace. */
|
||||||
|
if (!framep)
|
||||||
|
framep = (PUINT_PTR) in->Rsp;
|
||||||
|
#else
|
||||||
|
PUINT_PTR framep = (PUINT_PTR) in->_GR(sp);
|
||||||
|
for (PUINT_PTR bpend = (PUINT_PTR) __builtin_frame_address (0); framep > bpend; framep--)
|
||||||
|
if (*framep == in->SegCs && framep[-1] == in->_GR(ip))
|
||||||
{
|
{
|
||||||
ebp -= 2;
|
framep -= 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -610,6 +715,7 @@ exception::handle (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in, void
|
|||||||
We don't want any Windows magic kicking in. This top level frame
|
We don't want any Windows magic kicking in. This top level frame
|
||||||
will be removed automatically after our exception handler returns. */
|
will be removed automatically after our exception handler returns. */
|
||||||
_except_list->handler = handle;
|
_except_list->handler = handle;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (exit_state >= ES_SIGNAL_EXIT
|
if (exit_state >= ES_SIGNAL_EXIT
|
||||||
&& (NTSTATUS) e->ExceptionCode != STATUS_CONTROL_C_EXIT)
|
&& (NTSTATUS) e->ExceptionCode != STATUS_CONTROL_C_EXIT)
|
||||||
@ -619,7 +725,7 @@ exception::handle (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in, void
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
debugging = true;
|
debugging = true;
|
||||||
return 0;
|
return CYG_EXC_CONTINUE_EXECUTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: Probably should be handled in signal processing code */
|
/* FIXME: Probably should be handled in signal processing code */
|
||||||
@ -632,19 +738,24 @@ exception::handle (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in, void
|
|||||||
error_code |= 2;
|
error_code |= 2;
|
||||||
if (!me.inside_kernel (in)) /* User space */
|
if (!me.inside_kernel (in)) /* User space */
|
||||||
error_code |= 4;
|
error_code |= 4;
|
||||||
klog (LOG_INFO, "%s[%d]: segfault at %08x rip %08x rsp %08x error %d",
|
klog (LOG_INFO,
|
||||||
__progname, myself->pid, e->ExceptionInformation[1],
|
#ifdef __x86_64__
|
||||||
in->Eip, in->Esp, error_code);
|
"%s[%d]: segfault at %011X rip %011X rsp %011X error %d",
|
||||||
|
#else
|
||||||
|
"%s[%d]: segfault at %08x rip %08x rsp %08x error %d",
|
||||||
|
#endif
|
||||||
|
__progname, myself->pid,
|
||||||
|
e->ExceptionInformation[1], in->_GR(ip), in->_GR(sp),
|
||||||
|
error_code);
|
||||||
}
|
}
|
||||||
|
cygwin_exception exc (framep, in, e);
|
||||||
cygwin_exception exc ((DWORD) ebp, in, e);
|
|
||||||
si.si_cyg = (void *) &exc;
|
si.si_cyg = (void *) &exc;
|
||||||
si.si_addr = (void *) in->Eip;
|
si.si_addr = (void *) in->_GR(ip);
|
||||||
me.incyg++;
|
me.incyg++;
|
||||||
sig_send (NULL, si, &me); /* Signal myself */
|
sig_send (NULL, si, &me); /* Signal myself */
|
||||||
me.incyg--;
|
me.incyg--;
|
||||||
e->ExceptionFlags = 0;
|
e->ExceptionFlags = 0;
|
||||||
return 0;
|
return CYG_EXC_CONTINUE_EXECUTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Utilities to call a user supplied exception handler. */
|
/* Utilities to call a user supplied exception handler. */
|
||||||
@ -664,7 +775,7 @@ handle_sigsuspend (sigset_t tempmask)
|
|||||||
sigset_t oldmask = _my_tls.sigmask; // Remember for restoration
|
sigset_t oldmask = _my_tls.sigmask; // Remember for restoration
|
||||||
|
|
||||||
set_signal_mask (_my_tls.sigmask, tempmask);
|
set_signal_mask (_my_tls.sigmask, tempmask);
|
||||||
sigproc_printf ("oldmask %p, newmask %p", oldmask, tempmask);
|
sigproc_printf ("oldmask %ly, newmask %ly", oldmask, tempmask);
|
||||||
|
|
||||||
pthread_testcancel ();
|
pthread_testcancel ();
|
||||||
cygwait (NULL, cw_infinite, cw_cancel | cw_cancel_self | cw_sig_eintr);
|
cygwait (NULL, cw_infinite, cw_cancel | cw_cancel_self | cw_sig_eintr);
|
||||||
@ -730,16 +841,17 @@ _cygtls::interrupt_now (CONTEXT *cx, siginfo_t& si, void *handler,
|
|||||||
interrupted = false;
|
interrupted = false;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
push ((__stack_t) cx->Eip);
|
_ADDR &ip = cx->_GR(ip);
|
||||||
|
push (ip);
|
||||||
interrupt_setup (si, handler, siga);
|
interrupt_setup (si, handler, siga);
|
||||||
cx->Eip = pop ();
|
ip = pop ();
|
||||||
SetThreadContext (*this, cx); /* Restart the thread in a new location */
|
SetThreadContext (*this, cx); /* Restart the thread in a new location */
|
||||||
interrupted = true;
|
interrupted = true;
|
||||||
}
|
}
|
||||||
return interrupted;
|
return interrupted;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __stdcall
|
void __reg3
|
||||||
_cygtls::interrupt_setup (siginfo_t& si, void *handler, struct sigaction& siga)
|
_cygtls::interrupt_setup (siginfo_t& si, void *handler, struct sigaction& siga)
|
||||||
{
|
{
|
||||||
push ((__stack_t) sigdelayed);
|
push ((__stack_t) sigdelayed);
|
||||||
@ -1050,7 +1162,7 @@ set_process_mask_delta ()
|
|||||||
else
|
else
|
||||||
oldmask = _my_tls.sigmask;
|
oldmask = _my_tls.sigmask;
|
||||||
newmask = (oldmask | _my_tls.deltamask) & ~SIG_NONMASKABLE;
|
newmask = (oldmask | _my_tls.deltamask) & ~SIG_NONMASKABLE;
|
||||||
sigproc_printf ("oldmask %p, newmask %p, deltamask %p", oldmask, newmask,
|
sigproc_printf ("oldmask %lx, newmask %lx, deltamask %lx", oldmask, newmask,
|
||||||
_my_tls.deltamask);
|
_my_tls.deltamask);
|
||||||
_my_tls.sigmask = newmask;
|
_my_tls.sigmask = newmask;
|
||||||
return oldmask;
|
return oldmask;
|
||||||
@ -1064,7 +1176,7 @@ set_signal_mask (sigset_t& setmask, sigset_t newmask)
|
|||||||
{
|
{
|
||||||
newmask &= ~SIG_NONMASKABLE;
|
newmask &= ~SIG_NONMASKABLE;
|
||||||
sigset_t mask_bits = setmask & ~newmask;
|
sigset_t mask_bits = setmask & ~newmask;
|
||||||
sigproc_printf ("setmask %p, newmask %p, mask_bits %p", setmask, newmask,
|
sigproc_printf ("setmask %lx, newmask %lx, mask_bits %lx", setmask, newmask,
|
||||||
mask_bits);
|
mask_bits);
|
||||||
setmask = newmask;
|
setmask = newmask;
|
||||||
if (mask_bits)
|
if (mask_bits)
|
||||||
@ -1092,16 +1204,23 @@ signal_exit (int sig, siginfo_t *si)
|
|||||||
case SIGTRAP:
|
case SIGTRAP:
|
||||||
case SIGXCPU:
|
case SIGXCPU:
|
||||||
case SIGXFSZ:
|
case SIGXFSZ:
|
||||||
if (try_to_debug ())
|
if (try_to_debug ())
|
||||||
break;
|
break;
|
||||||
if (si->si_code != SI_USER && si->si_cyg)
|
if (si->si_code != SI_USER && si->si_cyg)
|
||||||
((cygwin_exception *) si->si_cyg)->dumpstack ();
|
((cygwin_exception *) si->si_cyg)->dumpstack ();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cygwin_exception exc (_my_tls.thread_context.ebp);
|
CONTEXT c;
|
||||||
exc.dumpstack ();
|
c.ContextFlags = CONTEXT_FULL;
|
||||||
}
|
RtlCaptureContext (&c);
|
||||||
break;
|
#ifdef __x86_64__
|
||||||
|
cygwin_exception exc ((PUINT_PTR) _my_tls.thread_context.rbp, &c);
|
||||||
|
#else
|
||||||
|
cygwin_exception exc ((PUINT_PTR) _my_tls.thread_context.ebp, &c);
|
||||||
|
#endif
|
||||||
|
exc.dumpstack ();
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
lock_process until_exit (true);
|
lock_process until_exit (true);
|
||||||
@ -1129,22 +1248,22 @@ _cygtls::handle_SIGCONT ()
|
|||||||
int state = 0;
|
int state = 0;
|
||||||
/* Carefully tell sig_handle_tty_stop to wake up. */
|
/* Carefully tell sig_handle_tty_stop to wake up. */
|
||||||
while (state < 2)
|
while (state < 2)
|
||||||
{
|
{
|
||||||
lock ();
|
lock ();
|
||||||
if (sig)
|
if (sig)
|
||||||
yield (); /* state <= 1 */
|
yield (); /* state <= 1 */
|
||||||
else if (state)
|
else if (state)
|
||||||
state++; /* state == 2 */
|
state++; /* state == 2 */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sig = SIGCONT;
|
sig = SIGCONT;
|
||||||
SetEvent (signal_arrived);
|
SetEvent (signal_arrived);
|
||||||
state++; /* state == 1 */
|
state++; /* state == 1 */
|
||||||
}
|
}
|
||||||
unlock ();
|
unlock ();
|
||||||
}
|
}
|
||||||
/* Tell wait_sig to handle any queued signals now that we're alive
|
/* Tell wait_sig to handle any queued signals now that we're alive
|
||||||
again. */
|
again. */
|
||||||
sig_dispatch_pending (false);
|
sig_dispatch_pending (false);
|
||||||
}
|
}
|
||||||
/* Clear pending stop signals */
|
/* Clear pending stop signals */
|
||||||
@ -1154,7 +1273,7 @@ _cygtls::handle_SIGCONT ()
|
|||||||
sig_clear (SIGTTOU);
|
sig_clear (SIGTTOU);
|
||||||
}
|
}
|
||||||
|
|
||||||
int __stdcall
|
int __reg1
|
||||||
sigpacket::process ()
|
sigpacket::process ()
|
||||||
{
|
{
|
||||||
int rc = 1;
|
int rc = 1;
|
||||||
@ -1200,7 +1319,7 @@ sigpacket::process ()
|
|||||||
else
|
else
|
||||||
tls = NULL;
|
tls = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* !tls means no threads available to catch a signal. */
|
/* !tls means no threads available to catch a signal. */
|
||||||
if (!tls)
|
if (!tls)
|
||||||
{
|
{
|
||||||
@ -1350,16 +1469,24 @@ _cygtls::signal_debugger (siginfo_t& si)
|
|||||||
else
|
else
|
||||||
goto out;
|
goto out;
|
||||||
if (incyg)
|
if (incyg)
|
||||||
|
#ifdef __x86_64__
|
||||||
|
c.Rip = retaddr ();
|
||||||
|
#else
|
||||||
c.Eip = retaddr ();
|
c.Eip = retaddr ();
|
||||||
|
#endif
|
||||||
|
memcpy (&thread_context, pc, (&thread_context._internal -
|
||||||
|
(unsigned char *) &thread_context));
|
||||||
}
|
}
|
||||||
memcpy (&thread_context, pc, (&thread_context._internal -
|
#ifdef __x86_64__
|
||||||
(unsigned char *) &thread_context));
|
char sigmsg[2 * sizeof (_CYGWIN_SIGNAL_STRING " ffffffff ffffffffffffffff")];
|
||||||
|
#else
|
||||||
char sigmsg[2 * sizeof (_CYGWIN_SIGNAL_STRING " ffffffff ffffffff")];
|
char sigmsg[2 * sizeof (_CYGWIN_SIGNAL_STRING " ffffffff ffffffff")];
|
||||||
__small_sprintf (sigmsg, _CYGWIN_SIGNAL_STRING " %d %p %p", si.si_signo,
|
#endif
|
||||||
|
__small_sprintf (sigmsg, _CYGWIN_SIGNAL_STRING " %d %y %p", si.si_signo,
|
||||||
thread_id, &thread_context);
|
thread_id, &thread_context);
|
||||||
OutputDebugString (sigmsg);
|
OutputDebugString (sigmsg);
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
if (th)
|
if (th)
|
||||||
ResumeThread (th);
|
ResumeThread (th);
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,7 @@ fillout_pinfo (pid_t pid, int winpid)
|
|||||||
return &ep;
|
return &ep;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline DWORD
|
static inline uintptr_t
|
||||||
get_cygdrive_info (char *user, char *system, char *user_flags,
|
get_cygdrive_info (char *user, char *system, char *user_flags,
|
||||||
char *system_flags)
|
char *system_flags)
|
||||||
{
|
{
|
||||||
@ -122,7 +122,7 @@ get_cygdrive_info (char *user, char *system, char *user_flags,
|
|||||||
return (res == ERROR_SUCCESS) ? 1 : 0;
|
return (res == ERROR_SUCCESS) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DWORD
|
static bool
|
||||||
check_ntsec (const char *filename)
|
check_ntsec (const char *filename)
|
||||||
{
|
{
|
||||||
if (!filename)
|
if (!filename)
|
||||||
@ -200,7 +200,7 @@ exit_process (UINT status, bool useTerminateProcess)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extern "C" unsigned long
|
extern "C" uintptr_t
|
||||||
cygwin_internal (cygwin_getinfo_types t, ...)
|
cygwin_internal (cygwin_getinfo_types t, ...)
|
||||||
{
|
{
|
||||||
va_list arg;
|
va_list arg;
|
||||||
@ -218,7 +218,7 @@ cygwin_internal (cygwin_getinfo_types t, ...)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CW_GETTHREADNAME:
|
case CW_GETTHREADNAME:
|
||||||
res = (DWORD) cygthread::name (va_arg (arg, DWORD));
|
res = (uintptr_t) cygthread::name (va_arg (arg, DWORD));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CW_SETTHREADNAME:
|
case CW_SETTHREADNAME:
|
||||||
@ -229,11 +229,11 @@ cygwin_internal (cygwin_getinfo_types t, ...)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CW_GETPINFO:
|
case CW_GETPINFO:
|
||||||
res = (DWORD) fillout_pinfo (va_arg (arg, DWORD), 0);
|
res = (uintptr_t) fillout_pinfo (va_arg (arg, DWORD), 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CW_GETVERSIONINFO:
|
case CW_GETVERSIONINFO:
|
||||||
res = (DWORD) cygwin_version_strings;
|
res = (uintptr_t) cygwin_version_strings;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CW_READ_V1_MOUNT_TABLES:
|
case CW_READ_V1_MOUNT_TABLES:
|
||||||
@ -247,7 +247,7 @@ cygwin_internal (cygwin_getinfo_types t, ...)
|
|||||||
Hilarity ensues if the DLL is not loaded like while the process
|
Hilarity ensues if the DLL is not loaded like while the process
|
||||||
is forking. */
|
is forking. */
|
||||||
__cygwin_user_data.cxx_malloc = &default_cygwin_cxx_malloc;
|
__cygwin_user_data.cxx_malloc = &default_cygwin_cxx_malloc;
|
||||||
res = (DWORD) &__cygwin_user_data;
|
res = (uintptr_t) &__cygwin_user_data;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CW_PERFILE:
|
case CW_PERFILE:
|
||||||
@ -264,7 +264,7 @@ cygwin_internal (cygwin_getinfo_types t, ...)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CW_GETPINFO_FULL:
|
case CW_GETPINFO_FULL:
|
||||||
res = (DWORD) fillout_pinfo (va_arg (arg, pid_t), 1);
|
res = (uintptr_t) fillout_pinfo (va_arg (arg, pid_t), 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CW_INIT_EXCEPTIONS:
|
case CW_INIT_EXCEPTIONS:
|
||||||
@ -299,7 +299,7 @@ cygwin_internal (cygwin_getinfo_types t, ...)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
set_errno (ESRCH);
|
set_errno (ESRCH);
|
||||||
res = (DWORD) -1;
|
res = (uintptr_t) -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -337,7 +337,7 @@ cygwin_internal (cygwin_getinfo_types t, ...)
|
|||||||
size_t n;
|
size_t n;
|
||||||
pid_t pid = va_arg (arg, pid_t);
|
pid_t pid = va_arg (arg, pid_t);
|
||||||
pinfo p (pid);
|
pinfo p (pid);
|
||||||
res = (DWORD) p->cmdline (n);
|
res = (uintptr_t) p->cmdline (n);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CW_CHECK_NTSEC:
|
case CW_CHECK_NTSEC:
|
||||||
@ -406,24 +406,24 @@ cygwin_internal (cygwin_getinfo_types t, ...)
|
|||||||
const char *name = va_arg (arg, const char *);
|
const char *name = va_arg (arg, const char *);
|
||||||
const void *hookfn = va_arg (arg, const void *);
|
const void *hookfn = va_arg (arg, const void *);
|
||||||
WORD subsys;
|
WORD subsys;
|
||||||
res = (unsigned long) hook_or_detect_cygwin (name, hookfn, subsys);
|
res = (uintptr_t) hook_or_detect_cygwin (name, hookfn, subsys);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CW_ARGV:
|
case CW_ARGV:
|
||||||
{
|
{
|
||||||
child_info_spawn *ci = (child_info_spawn *) get_cygwin_startup_info ();
|
child_info_spawn *ci = (child_info_spawn *) get_cygwin_startup_info ();
|
||||||
res = (unsigned long) (ci ? ci->moreinfo->argv : NULL);
|
res = (uintptr_t) (ci ? ci->moreinfo->argv : NULL);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CW_ENVP:
|
case CW_ENVP:
|
||||||
{
|
{
|
||||||
child_info_spawn *ci = (child_info_spawn *) get_cygwin_startup_info ();
|
child_info_spawn *ci = (child_info_spawn *) get_cygwin_startup_info ();
|
||||||
res = (unsigned long) (ci ? ci->moreinfo->envp : NULL);
|
res = (uintptr_t) (ci ? ci->moreinfo->envp : NULL);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CW_DEBUG_SELF:
|
case CW_DEBUG_SELF:
|
||||||
error_start_init (va_arg (arg, const char *));
|
error_start_init (va_arg (arg, const char *));
|
||||||
try_to_debug ();
|
res = try_to_debug ();
|
||||||
break;
|
break;
|
||||||
case CW_SYNC_WINENV:
|
case CW_SYNC_WINENV:
|
||||||
create_winenv (NULL);
|
create_winenv (NULL);
|
||||||
|
@ -23,7 +23,7 @@ extern "C" int
|
|||||||
fcntl64 (int fd, int cmd, ...)
|
fcntl64 (int fd, int cmd, ...)
|
||||||
{
|
{
|
||||||
int res = -1;
|
int res = -1;
|
||||||
void *arg = NULL;
|
intptr_t arg = 0;
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
||||||
pthread_testcancel ();
|
pthread_testcancel ();
|
||||||
@ -37,18 +37,32 @@ fcntl64 (int fd, int cmd, ...)
|
|||||||
if (cfd < 0)
|
if (cfd < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
/* FIXME? All numerical args to fcntl are defined as long on Linux.
|
||||||
|
This relies on a really dirty trick on x86_64: A 32 bit mov to
|
||||||
|
a register (e.g. mov $1, %edx) always sets the high 32 bit to 0.
|
||||||
|
We're following the Linux lead here since the third arg to any
|
||||||
|
function is in a register anyway (%r8 in MS ABI). That's the easy
|
||||||
|
case which is covered here by always reading the arg with
|
||||||
|
sizeof (intptr_t) == sizeof (long) == sizeof (void*) which matches
|
||||||
|
all targets.
|
||||||
|
|
||||||
|
However, the POSIX standard defines all numerical args as type int.
|
||||||
|
If we take that literally, we had a (small) problem on 64 bit, since
|
||||||
|
sizeof (void*) != sizeof (int). If we would like to follow POSIX
|
||||||
|
more closely than Linux, we'd have to call va_arg on a per cmd basis. */
|
||||||
|
|
||||||
va_start (args, cmd);
|
va_start (args, cmd);
|
||||||
arg = va_arg (args, void *);
|
arg = va_arg (args, intptr_t);
|
||||||
va_end (args);
|
va_end (args);
|
||||||
|
|
||||||
switch (cmd)
|
switch (cmd)
|
||||||
{
|
{
|
||||||
case F_DUPFD:
|
case F_DUPFD:
|
||||||
case F_DUPFD_CLOEXEC:
|
case F_DUPFD_CLOEXEC:
|
||||||
if ((int) arg >= 0 && (int) arg < OPEN_MAX_MAX)
|
if (arg >= 0 && arg < OPEN_MAX_MAX)
|
||||||
{
|
{
|
||||||
int flags = cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0;
|
int flags = cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0;
|
||||||
res = cygheap->fdtab.dup3 (fd, cygheap_fdnew (((int) arg) - 1), flags);
|
res = cygheap->fdtab.dup3 (fd, cygheap_fdnew ((arg) - 1), flags);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -60,7 +74,7 @@ fcntl64 (int fd, int cmd, ...)
|
|||||||
case F_SETLK:
|
case F_SETLK:
|
||||||
case F_SETLKW:
|
case F_SETLKW:
|
||||||
{
|
{
|
||||||
struct __flock64 *fl = (struct __flock64 *) arg;
|
struct flock *fl = (struct flock *) arg;
|
||||||
fl->l_type &= F_RDLCK | F_WRLCK | F_UNLCK;
|
fl->l_type &= F_RDLCK | F_WRLCK | F_UNLCK;
|
||||||
res = cfd->lock (cmd, fl);
|
res = cfd->lock (cmd, fl);
|
||||||
}
|
}
|
||||||
@ -70,24 +84,27 @@ fcntl64 (int fd, int cmd, ...)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
syscall_printf ("%R = fcntl(%d, %d, %p)", res, fd, cmd, arg);
|
syscall_printf ("%R = fcntl(%d, %d, %ly)", res, fd, cmd, arg);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __x86_64__
|
||||||
|
EXPORT_ALIAS (fcntl64, _fcntl)
|
||||||
|
#else
|
||||||
extern "C" int
|
extern "C" int
|
||||||
_fcntl (int fd, int cmd, ...)
|
_fcntl (int fd, int cmd, ...)
|
||||||
{
|
{
|
||||||
void *arg = NULL;
|
intptr_t arg = 0;
|
||||||
va_list args;
|
va_list args;
|
||||||
struct __flock32 *src = NULL;
|
struct __flock32 *src = NULL;
|
||||||
struct __flock64 dst;
|
struct flock dst;
|
||||||
|
|
||||||
myfault efault;
|
myfault efault;
|
||||||
if (efault.faulted (EFAULT))
|
if (efault.faulted (EFAULT))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
va_start (args, cmd);
|
va_start (args, cmd);
|
||||||
arg = va_arg (args, void *);
|
arg = va_arg (args, intptr_t);
|
||||||
va_end (args);
|
va_end (args);
|
||||||
if (cmd == F_GETLK || cmd == F_SETLK || cmd == F_SETLKW)
|
if (cmd == F_GETLK || cmd == F_SETLK || cmd == F_SETLKW)
|
||||||
{
|
{
|
||||||
@ -97,7 +114,7 @@ _fcntl (int fd, int cmd, ...)
|
|||||||
dst.l_start = src->l_start;
|
dst.l_start = src->l_start;
|
||||||
dst.l_len = src->l_len;
|
dst.l_len = src->l_len;
|
||||||
dst.l_pid = src->l_pid;
|
dst.l_pid = src->l_pid;
|
||||||
arg = &dst;
|
arg = (intptr_t) &dst;
|
||||||
}
|
}
|
||||||
int res = fcntl64 (fd, cmd, arg);
|
int res = fcntl64 (fd, cmd, arg);
|
||||||
if (cmd == F_GETLK)
|
if (cmd == F_GETLK)
|
||||||
@ -110,4 +127,4 @@ _fcntl (int fd, int cmd, ...)
|
|||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
@ -421,8 +421,7 @@ _feinitialise (void)
|
|||||||
/* Check for presence of SSE: invoke CPUID #1, check EDX bit 25. */
|
/* Check for presence of SSE: invoke CPUID #1, check EDX bit 25. */
|
||||||
eax = 1;
|
eax = 1;
|
||||||
__asm__ volatile ("cpuid" : "=d" (edx), "+a" (eax) :: "%ecx", "%ebx");
|
__asm__ volatile ("cpuid" : "=d" (edx), "+a" (eax) :: "%ecx", "%ebx");
|
||||||
/* If this flag isn't set, or if the OS doesn't support SSE (NT4, at least
|
/* If this flag isn't set we'll avoid trying to execute any SSE. */
|
||||||
up to SP4) we'll avoid trying to execute any SSE. */
|
|
||||||
if ((edx & (1 << 25)) != 0)
|
if ((edx & (1 << 25)) != 0)
|
||||||
use_sse = true;
|
use_sse = true;
|
||||||
|
|
||||||
|
@ -190,9 +190,9 @@ fhandler_base::set_flags (int flags, int supplied_bin)
|
|||||||
{
|
{
|
||||||
int bin;
|
int bin;
|
||||||
int fmode;
|
int fmode;
|
||||||
debug_printf ("flags %p, supplied_bin %p", flags, supplied_bin);
|
debug_printf ("flags %y, supplied_bin %y", flags, supplied_bin);
|
||||||
if ((bin = flags & (O_BINARY | O_TEXT)))
|
if ((bin = flags & (O_BINARY | O_TEXT)))
|
||||||
debug_printf ("O_TEXT/O_BINARY set in flags %p", bin);
|
debug_printf ("O_TEXT/O_BINARY set in flags %y", bin);
|
||||||
else if (rbinset () && wbinset ())
|
else if (rbinset () && wbinset ())
|
||||||
bin = rbinary () ? O_BINARY : O_TEXT; // FIXME: Not quite right
|
bin = rbinary () ? O_BINARY : O_TEXT; // FIXME: Not quite right
|
||||||
else if ((fmode = get_default_fmode (flags)) & O_BINARY)
|
else if ((fmode = get_default_fmode (flags)) & O_BINARY)
|
||||||
@ -217,34 +217,36 @@ fhandler_base::set_flags (int flags, int supplied_bin)
|
|||||||
/* Cover function to ReadFile to achieve (as much as possible) Posix style
|
/* Cover function to ReadFile to achieve (as much as possible) Posix style
|
||||||
semantics and use of errno. */
|
semantics and use of errno. */
|
||||||
void __stdcall
|
void __stdcall
|
||||||
fhandler_base::raw_read (void *ptr, size_t& ulen)
|
fhandler_base::raw_read (void *ptr, size_t& len)
|
||||||
{
|
{
|
||||||
#define bytes_read ulen
|
NTSTATUS status;
|
||||||
|
IO_STATUS_BLOCK io;
|
||||||
int try_noreserve = 1;
|
int try_noreserve = 1;
|
||||||
DWORD len = ulen;
|
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
ulen = (size_t) -1;
|
status = NtReadFile (get_handle (), NULL, NULL, NULL, &io, ptr, len,
|
||||||
BOOL res = ReadFile (get_handle (), ptr, len, (DWORD *) &ulen, NULL);
|
NULL, NULL);
|
||||||
if (!res)
|
if (NT_SUCCESS (status))
|
||||||
|
len = io.Information;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
/* Some errors are not really errors. Detect such cases here. */
|
/* Some errors are not really errors. Detect such cases here. */
|
||||||
|
switch (status)
|
||||||
DWORD errcode = GetLastError ();
|
|
||||||
switch (errcode)
|
|
||||||
{
|
{
|
||||||
case ERROR_BROKEN_PIPE:
|
case STATUS_END_OF_FILE:
|
||||||
|
case STATUS_PIPE_BROKEN:
|
||||||
/* This is really EOF. */
|
/* This is really EOF. */
|
||||||
bytes_read = 0;
|
len = 0;
|
||||||
break;
|
break;
|
||||||
case ERROR_MORE_DATA:
|
case STATUS_MORE_ENTRIES:
|
||||||
/* `bytes_read' is supposedly valid. */
|
case STATUS_BUFFER_OVERFLOW:
|
||||||
|
/* `io.Information' is supposedly valid. */
|
||||||
|
len = io.Information;
|
||||||
break;
|
break;
|
||||||
case ERROR_NOACCESS:
|
case STATUS_ACCESS_VIOLATION:
|
||||||
if (is_at_eof (get_handle ()))
|
if (is_at_eof (get_handle ()))
|
||||||
{
|
{
|
||||||
bytes_read = 0;
|
len = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (try_noreserve)
|
if (try_noreserve)
|
||||||
@ -261,23 +263,21 @@ retry:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*FALLTHRU*/
|
/*FALLTHRU*/
|
||||||
case ERROR_INVALID_FUNCTION:
|
case STATUS_INVALID_DEVICE_REQUEST:
|
||||||
case ERROR_INVALID_PARAMETER:
|
case STATUS_INVALID_PARAMETER:
|
||||||
case ERROR_INVALID_HANDLE:
|
case STATUS_INVALID_HANDLE:
|
||||||
if (pc.isdir ())
|
if (pc.isdir ())
|
||||||
{
|
{
|
||||||
set_errno (EISDIR);
|
set_errno (EISDIR);
|
||||||
bytes_read = (size_t) -1;
|
len = (size_t) -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
syscall_printf ("ReadFile %s(%p) failed, %E", get_name (), get_handle ());
|
__seterrno_from_nt_status (status);
|
||||||
__seterrno_from_win_error (errcode);
|
len = (size_t) -1;
|
||||||
bytes_read = (size_t) -1;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#undef bytes_read
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cover function to WriteFile to provide Posix interface and semantics
|
/* Cover function to WriteFile to provide Posix interface and semantics
|
||||||
@ -388,7 +388,7 @@ fhandler_base::fhaccess (int flags, bool effective)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct __stat64 st;
|
struct stat st;
|
||||||
if (fstat (&st))
|
if (fstat (&st))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
@ -516,7 +516,7 @@ fhandler_base::open (int flags, mode_t mode)
|
|||||||
PFILE_FULL_EA_INFORMATION p = NULL;
|
PFILE_FULL_EA_INFORMATION p = NULL;
|
||||||
ULONG plen = 0;
|
ULONG plen = 0;
|
||||||
|
|
||||||
syscall_printf ("(%S, %p)", pc.get_nt_native_path (), flags);
|
syscall_printf ("(%S, %y)", pc.get_nt_native_path (), flags);
|
||||||
|
|
||||||
pc.get_object_attr (attr, *sec_none_cloexec (flags));
|
pc.get_object_attr (attr, *sec_none_cloexec (flags));
|
||||||
|
|
||||||
@ -586,11 +586,10 @@ fhandler_base::open (int flags, mode_t mode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Starting with Windows 2000, when trying to overwrite an already
|
/* Trying to overwrite an already existing file with FILE_ATTRIBUTE_HIDDEN
|
||||||
existing file with FILE_ATTRIBUTE_HIDDEN and/or FILE_ATTRIBUTE_SYSTEM
|
and/or FILE_ATTRIBUTE_SYSTEM attribute set, NtCreateFile fails with
|
||||||
attribute set, CreateFile fails with ERROR_ACCESS_DENIED.
|
STATUS_ACCESS_DENIED. Per MSDN you have to create the file with the
|
||||||
Per MSDN you have to create the file with the same attributes as
|
same attributes as already specified for the file. */
|
||||||
already specified for the file. */
|
|
||||||
if (((flags & O_CREAT) || create_disposition == FILE_OVERWRITE)
|
if (((flags & O_CREAT) || create_disposition == FILE_OVERWRITE)
|
||||||
&& has_attribute (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM))
|
&& has_attribute (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM))
|
||||||
file_attributes |= pc.file_attributes ();
|
file_attributes |= pc.file_attributes ();
|
||||||
@ -705,12 +704,12 @@ fhandler_base::open (int flags, mode_t mode)
|
|||||||
res = 1;
|
res = 1;
|
||||||
set_open_status ();
|
set_open_status ();
|
||||||
done:
|
done:
|
||||||
debug_printf ("%x = NtCreateFile "
|
debug_printf ("%y = NtCreateFile "
|
||||||
"(%p, %x, %S, io, NULL, %x, %x, %x, %x, NULL, 0)",
|
"(%p, %y, %S, io, NULL, %y, %y, %y, %y, NULL, 0)",
|
||||||
status, fh, access, pc.get_nt_native_path (), file_attributes,
|
status, fh, access, pc.get_nt_native_path (), file_attributes,
|
||||||
shared, create_disposition, options);
|
shared, create_disposition, options);
|
||||||
|
|
||||||
syscall_printf ("%d = fhandler_base::open(%S, %p)",
|
syscall_printf ("%d = fhandler_base::open(%S, %y)",
|
||||||
res, pc.get_nt_native_path (), flags);
|
res, pc.get_nt_native_path (), flags);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -729,26 +728,13 @@ fhandler_base::read (void *in_ptr, size_t& len)
|
|||||||
char *ptr = (char *) in_ptr;
|
char *ptr = (char *) in_ptr;
|
||||||
ssize_t copied_chars = get_readahead_into_buffer (ptr, len);
|
ssize_t copied_chars = get_readahead_into_buffer (ptr, len);
|
||||||
|
|
||||||
if (copied_chars)
|
if (copied_chars || !len)
|
||||||
{
|
{
|
||||||
len = (size_t) copied_chars;
|
len = (size_t) copied_chars;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
len -= copied_chars;
|
raw_read (ptr, len);
|
||||||
if (!len)
|
|
||||||
{
|
|
||||||
len = (size_t) copied_chars;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
raw_read (ptr + copied_chars, len);
|
|
||||||
if (!copied_chars)
|
|
||||||
/* nothing */;
|
|
||||||
else if ((ssize_t) len > 0)
|
|
||||||
len += copied_chars;
|
|
||||||
else
|
|
||||||
len = copied_chars;
|
|
||||||
|
|
||||||
if (rbinary () || (ssize_t) len <= 0)
|
if (rbinary () || (ssize_t) len <= 0)
|
||||||
goto out;
|
goto out;
|
||||||
@ -791,24 +777,6 @@ fhandler_base::read (void *in_ptr, size_t& len)
|
|||||||
|
|
||||||
len = dst - (char *) ptr;
|
len = dst - (char *) ptr;
|
||||||
|
|
||||||
#ifndef NOSTRACE
|
|
||||||
if (strace.active ())
|
|
||||||
{
|
|
||||||
char buf[16 * 6 + 1];
|
|
||||||
char *p = buf;
|
|
||||||
|
|
||||||
for (int i = 0; i < copied_chars && i < 16; ++i)
|
|
||||||
{
|
|
||||||
unsigned char c = ((unsigned char *) ptr)[i];
|
|
||||||
__small_sprintf (p, " %c", c);
|
|
||||||
p += strlen (p);
|
|
||||||
}
|
|
||||||
*p = '\0';
|
|
||||||
debug_printf ("read %d bytes (%s%s)", copied_chars, buf,
|
|
||||||
copied_chars > 16 ? " ..." : "");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
debug_printf ("returning %d, %s mode", len, rbinary () ? "binary" : "text");
|
debug_printf ("returning %d, %s mode", len, rbinary () ? "binary" : "text");
|
||||||
}
|
}
|
||||||
@ -846,7 +814,7 @@ fhandler_base::write (const void *ptr, size_t len)
|
|||||||
if (NT_SUCCESS (status))
|
if (NT_SUCCESS (status))
|
||||||
pc.file_attributes (pc.file_attributes ()
|
pc.file_attributes (pc.file_attributes ()
|
||||||
| FILE_ATTRIBUTE_SPARSE_FILE);
|
| FILE_ATTRIBUTE_SPARSE_FILE);
|
||||||
debug_printf ("%p = NtFsControlFile(%S, FSCTL_SET_SPARSE)",
|
debug_printf ("%y = NtFsControlFile(%S, FSCTL_SET_SPARSE)",
|
||||||
status, pc.get_nt_native_path ());
|
status, pc.get_nt_native_path ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1018,8 +986,8 @@ fhandler_base::writev (const struct iovec *const iov, const int iovcnt,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
_off64_t
|
off_t
|
||||||
fhandler_base::lseek (_off64_t offset, int whence)
|
fhandler_base::lseek (off_t offset, int whence)
|
||||||
{
|
{
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
IO_STATUS_BLOCK io;
|
IO_STATUS_BLOCK io;
|
||||||
@ -1071,7 +1039,7 @@ fhandler_base::lseek (_off64_t offset, int whence)
|
|||||||
__seterrno_from_nt_status (status);
|
__seterrno_from_nt_status (status);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
_off64_t res = fpi.CurrentByteOffset.QuadPart;
|
off_t res = fpi.CurrentByteOffset.QuadPart;
|
||||||
|
|
||||||
/* When next we write(), we will check to see if *this* seek went beyond
|
/* When next we write(), we will check to see if *this* seek went beyond
|
||||||
the end of the file and if so, potentially sparsify the file. */
|
the end of the file and if so, potentially sparsify the file. */
|
||||||
@ -1088,14 +1056,14 @@ fhandler_base::lseek (_off64_t offset, int whence)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ssize_t __stdcall
|
ssize_t __stdcall
|
||||||
fhandler_base::pread (void *, size_t, _off64_t)
|
fhandler_base::pread (void *, size_t, off_t)
|
||||||
{
|
{
|
||||||
set_errno (ESPIPE);
|
set_errno (ESPIPE);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t __stdcall
|
ssize_t __stdcall
|
||||||
fhandler_base::pwrite (void *, size_t, _off64_t)
|
fhandler_base::pwrite (void *, size_t, off_t)
|
||||||
{
|
{
|
||||||
set_errno (ESPIPE);
|
set_errno (ESPIPE);
|
||||||
return -1;
|
return -1;
|
||||||
@ -1263,14 +1231,14 @@ fhandler_base::ioctl (unsigned int cmd, void *buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_base::lock (int, struct __flock64 *)
|
fhandler_base::lock (int, struct flock *)
|
||||||
{
|
{
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int __reg2
|
int __reg2
|
||||||
fhandler_base::fstat (struct __stat64 *buf)
|
fhandler_base::fstat (struct stat *buf)
|
||||||
{
|
{
|
||||||
if (is_fs_special ())
|
if (is_fs_special ())
|
||||||
return fstat_fs (buf);
|
return fstat_fs (buf);
|
||||||
@ -1351,7 +1319,7 @@ fhandler_base::dup (fhandler_base *child, int)
|
|||||||
GetCurrentProcess (), &nh,
|
GetCurrentProcess (), &nh,
|
||||||
0, TRUE, DUPLICATE_SAME_ACCESS))
|
0, TRUE, DUPLICATE_SAME_ACCESS))
|
||||||
{
|
{
|
||||||
debug_printf ("dup(%s) failed, handle %x, %E",
|
debug_printf ("dup(%s) failed, handle %p, %E",
|
||||||
get_name (), get_handle ());
|
get_name (), get_handle ());
|
||||||
__seterrno ();
|
__seterrno ();
|
||||||
return -1;
|
return -1;
|
||||||
@ -1371,7 +1339,7 @@ fhandler_base_overlapped::dup (fhandler_base *child, int flags)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fhandler_base::fcntl (int cmd, void *arg)
|
int fhandler_base::fcntl (int cmd, intptr_t arg)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
@ -1381,12 +1349,12 @@ int fhandler_base::fcntl (int cmd, void *arg)
|
|||||||
res = close_on_exec () ? FD_CLOEXEC : 0;
|
res = close_on_exec () ? FD_CLOEXEC : 0;
|
||||||
break;
|
break;
|
||||||
case F_SETFD:
|
case F_SETFD:
|
||||||
set_close_on_exec (((int) arg & FD_CLOEXEC) ? 1 : 0);
|
set_close_on_exec ((arg & FD_CLOEXEC) ? 1 : 0);
|
||||||
res = 0;
|
res = 0;
|
||||||
break;
|
break;
|
||||||
case F_GETFL:
|
case F_GETFL:
|
||||||
res = get_flags ();
|
res = get_flags ();
|
||||||
debug_printf ("GETFL: %p", res);
|
debug_printf ("GETFL: %y", res);
|
||||||
break;
|
break;
|
||||||
case F_SETFL:
|
case F_SETFL:
|
||||||
{
|
{
|
||||||
@ -1395,7 +1363,7 @@ int fhandler_base::fcntl (int cmd, void *arg)
|
|||||||
Since O_ASYNC isn't defined in fcntl.h it's currently
|
Since O_ASYNC isn't defined in fcntl.h it's currently
|
||||||
ignored as well. */
|
ignored as well. */
|
||||||
const int allowed_flags = O_APPEND | O_NONBLOCK_MASK;
|
const int allowed_flags = O_APPEND | O_NONBLOCK_MASK;
|
||||||
int new_flags = (int) arg & allowed_flags;
|
int new_flags = arg & allowed_flags;
|
||||||
/* Carefully test for the O_NONBLOCK or deprecated OLD_O_NDELAY flag.
|
/* Carefully test for the O_NONBLOCK or deprecated OLD_O_NDELAY flag.
|
||||||
Set only the flag that has been passed in. If both are set, just
|
Set only the flag that has been passed in. If both are set, just
|
||||||
record O_NONBLOCK. */
|
record O_NONBLOCK. */
|
||||||
@ -1679,7 +1647,7 @@ fhandler_base::fchmod (mode_t mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_base::fchown (__uid32_t uid, __gid32_t gid)
|
fhandler_base::fchown (uid_t uid, gid_t gid)
|
||||||
{
|
{
|
||||||
if (pc.is_fs_special ())
|
if (pc.is_fs_special ())
|
||||||
return ((fhandler_disk_file *) this)->fhandler_disk_file::fchown (uid, gid);
|
return ((fhandler_disk_file *) this)->fhandler_disk_file::fchown (uid, gid);
|
||||||
@ -1688,7 +1656,7 @@ fhandler_base::fchown (__uid32_t uid, __gid32_t gid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_base::facl (int cmd, int nentries, __aclent32_t *aclbufp)
|
fhandler_base::facl (int cmd, int nentries, aclent_t *aclbufp)
|
||||||
{
|
{
|
||||||
int res = -1;
|
int res = -1;
|
||||||
switch (cmd)
|
switch (cmd)
|
||||||
@ -1745,14 +1713,14 @@ fhandler_base::fsetxattr (const char *name, const void *value, size_t size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_base::fadvise (_off64_t offset, _off64_t length, int advice)
|
fhandler_base::fadvise (off_t offset, off_t length, int advice)
|
||||||
{
|
{
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_base::ftruncate (_off64_t length, bool allow_truncate)
|
fhandler_base::ftruncate (off_t length, bool allow_truncate)
|
||||||
{
|
{
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return -1;
|
return -1;
|
||||||
@ -1966,7 +1934,7 @@ fhandler_base_overlapped::wait_overlapped (bool inres, bool writing, DWORD *byte
|
|||||||
wores = GetOverlappedResult (h, get_overlapped (), bytes, false);
|
wores = GetOverlappedResult (h, get_overlapped (), bytes, false);
|
||||||
err = GetLastError ();
|
err = GetLastError ();
|
||||||
ResetEvent (get_overlapped ()->hEvent); /* Probably not needed but CYA */
|
ResetEvent (get_overlapped ()->hEvent); /* Probably not needed but CYA */
|
||||||
debug_printf ("wfres %d, wores %d, bytes %u", wfres, wores, *bytes);
|
debug_printf ("wfres %u, wores %d, bytes %u", wfres, wores, *bytes);
|
||||||
if (wores)
|
if (wores)
|
||||||
res = overlapped_success; /* operation succeeded */
|
res = overlapped_success; /* operation succeeded */
|
||||||
else if (wfres == WAIT_OBJECT_0 + 1)
|
else if (wfres == WAIT_OBJECT_0 + 1)
|
||||||
@ -1981,7 +1949,7 @@ fhandler_base_overlapped::wait_overlapped (bool inres, bool writing, DWORD *byte
|
|||||||
res = overlapped_nonblocking_no_data; /* more handling below */
|
res = overlapped_nonblocking_no_data; /* more handling below */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
debug_printf ("GetOverLappedResult failed, h %p, bytes %u, %E", h, *bytes);
|
debug_printf ("GetOverlappedResult failed, h %p, bytes %u, %E", h, *bytes);
|
||||||
res = overlapped_error;
|
res = overlapped_error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2041,7 +2009,7 @@ fhandler_base_overlapped::raw_read (void *ptr, size_t& len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (keep_looping);
|
while (keep_looping);
|
||||||
len = (size_t) nbytes;
|
len = (nbytes == (DWORD) -1) ? (size_t) -1 : (size_t) nbytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t __reg3
|
ssize_t __reg3
|
||||||
@ -2051,13 +2019,13 @@ fhandler_base_overlapped::raw_write (const void *ptr, size_t len)
|
|||||||
if (has_ongoing_io ())
|
if (has_ongoing_io ())
|
||||||
{
|
{
|
||||||
set_errno (EAGAIN);
|
set_errno (EAGAIN);
|
||||||
nbytes = (DWORD) -1;
|
nbytes = (size_t) -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
size_t chunk;
|
size_t chunk;
|
||||||
if (!max_atomic_write || len < max_atomic_write)
|
if (!max_atomic_write || len < max_atomic_write)
|
||||||
chunk = len;
|
chunk = MIN (len, INT_MAX);
|
||||||
else if (is_nonblocking ())
|
else if (is_nonblocking ())
|
||||||
chunk = len = max_atomic_write;
|
chunk = len = max_atomic_write;
|
||||||
else
|
else
|
||||||
@ -2065,7 +2033,7 @@ fhandler_base_overlapped::raw_write (const void *ptr, size_t len)
|
|||||||
|
|
||||||
nbytes = 0;
|
nbytes = 0;
|
||||||
DWORD nbytes_now = 0;
|
DWORD nbytes_now = 0;
|
||||||
/* Write to fd in smaller chunks, accumlating a total.
|
/* Write to fd in smaller chunks, accumulating a total.
|
||||||
If there's an error, just return the accumulated total
|
If there's an error, just return the accumulated total
|
||||||
unless the first write fails, in which case return value
|
unless the first write fails, in which case return value
|
||||||
from wait_overlapped(). */
|
from wait_overlapped(). */
|
||||||
@ -2095,7 +2063,7 @@ fhandler_base_overlapped::raw_write (const void *ptr, size_t len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!nbytes)
|
if (!nbytes)
|
||||||
nbytes = nbytes_now;
|
nbytes = (nbytes_now == (DWORD) -1) ? (size_t) -1 : nbytes_now;
|
||||||
}
|
}
|
||||||
return nbytes;
|
return nbytes;
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ class inode_t;
|
|||||||
typedef struct __DIR DIR;
|
typedef struct __DIR DIR;
|
||||||
struct dirent;
|
struct dirent;
|
||||||
struct iovec;
|
struct iovec;
|
||||||
struct __acl32;
|
struct acl;
|
||||||
|
|
||||||
enum dirent_states
|
enum dirent_states
|
||||||
{
|
{
|
||||||
@ -162,8 +162,8 @@ class fhandler_base
|
|||||||
|
|
||||||
HANDLE io_handle;
|
HANDLE io_handle;
|
||||||
|
|
||||||
__ino64_t ino; /* file ID or hashed filename, depends on FS. */
|
ino_t ino; /* file ID or hashed filename, depends on FS. */
|
||||||
long _refcnt;
|
LONG _refcnt;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/* File open flags from open () and fcntl () calls */
|
/* File open flags from open () and fcntl () calls */
|
||||||
@ -182,8 +182,8 @@ class fhandler_base
|
|||||||
HANDLE read_state;
|
HANDLE read_state;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
long inc_refcnt () {return InterlockedIncrement (&_refcnt);}
|
LONG inc_refcnt () {return InterlockedIncrement (&_refcnt);}
|
||||||
long dec_refcnt () {return InterlockedDecrement (&_refcnt);}
|
LONG dec_refcnt () {return InterlockedDecrement (&_refcnt);}
|
||||||
class fhandler_base *archetype;
|
class fhandler_base *archetype;
|
||||||
int usecount;
|
int usecount;
|
||||||
|
|
||||||
@ -209,10 +209,9 @@ class fhandler_base
|
|||||||
/* Non-virtual simple accessor functions. */
|
/* Non-virtual simple accessor functions. */
|
||||||
void set_io_handle (HANDLE x) { io_handle = x; }
|
void set_io_handle (HANDLE x) { io_handle = x; }
|
||||||
|
|
||||||
DWORD& get_device () { return dev (); }
|
dev_t& get_device () { return dev (); }
|
||||||
DWORD get_major () { return dev ().get_major (); }
|
_major_t get_major () { return dev ().get_major (); }
|
||||||
DWORD get_minor () { return dev ().get_minor (); }
|
_minor_t get_minor () { return dev ().get_minor (); }
|
||||||
virtual int get_unit () { return dev ().get_minor (); }
|
|
||||||
|
|
||||||
ACCESS_MASK get_access () const { return access; }
|
ACCESS_MASK get_access () const { return access; }
|
||||||
void set_access (ACCESS_MASK x) { access = x; }
|
void set_access (ACCESS_MASK x) { access = x; }
|
||||||
@ -295,8 +294,8 @@ class fhandler_base
|
|||||||
bool has_attribute (DWORD x) const {return pc.has_attribute (x);}
|
bool has_attribute (DWORD x) const {return pc.has_attribute (x);}
|
||||||
const char *get_name () const { return pc.normalized_path; }
|
const char *get_name () const { return pc.normalized_path; }
|
||||||
const char *get_win32_name () { return pc.get_win32 (); }
|
const char *get_win32_name () { return pc.get_win32 (); }
|
||||||
__dev32_t get_dev () { return pc.fs_serial_number (); }
|
dev_t get_dev () { return pc.fs_serial_number (); }
|
||||||
__ino64_t get_ino () { return ino ?: ino = hash_path_name (0, pc.get_nt_native_path ()); }
|
ino_t get_ino () { return ino ?: ino = hash_path_name (0, pc.get_nt_native_path ()); }
|
||||||
long long get_unique_id () const { return unique_id; }
|
long long get_unique_id () const { return unique_id; }
|
||||||
/* Returns name used for /proc/<pid>/fd in buf. */
|
/* Returns name used for /proc/<pid>/fd in buf. */
|
||||||
virtual char *get_proc_fd_name (char *buf);
|
virtual char *get_proc_fd_name (char *buf);
|
||||||
@ -328,48 +327,48 @@ class fhandler_base
|
|||||||
int open_fs (int, mode_t = 0);
|
int open_fs (int, mode_t = 0);
|
||||||
# define archetype_usecount(n) _archetype_usecount (__PRETTY_FUNCTION__, __LINE__, (n))
|
# define archetype_usecount(n) _archetype_usecount (__PRETTY_FUNCTION__, __LINE__, (n))
|
||||||
int close_fs () { return fhandler_base::close (); }
|
int close_fs () { return fhandler_base::close (); }
|
||||||
virtual int __reg2 fstat (struct __stat64 *buf);
|
virtual int __reg2 fstat (struct stat *buf);
|
||||||
void __reg2 stat_fixup (struct __stat64 *buf);
|
void __reg2 stat_fixup (struct stat *buf);
|
||||||
int __reg2 fstat_fs (struct __stat64 *buf);
|
int __reg2 fstat_fs (struct stat *buf);
|
||||||
private:
|
private:
|
||||||
int __reg3 fstat_helper (struct __stat64 *buf,
|
int __reg3 fstat_helper (struct stat *buf,
|
||||||
DWORD nNumberOfLinks);
|
DWORD nNumberOfLinks);
|
||||||
int __reg2 fstat_by_nfs_ea (struct __stat64 *buf);
|
int __reg2 fstat_by_nfs_ea (struct stat *buf);
|
||||||
int __reg2 fstat_by_handle (struct __stat64 *buf);
|
int __reg2 fstat_by_handle (struct stat *buf);
|
||||||
int __reg2 fstat_by_name (struct __stat64 *buf);
|
int __reg2 fstat_by_name (struct stat *buf);
|
||||||
public:
|
public:
|
||||||
virtual int __reg2 fstatvfs (struct statvfs *buf);
|
virtual int __reg2 fstatvfs (struct statvfs *buf);
|
||||||
int __reg2 utimens_fs (const struct timespec *);
|
int __reg2 utimens_fs (const struct timespec *);
|
||||||
virtual int __reg1 fchmod (mode_t mode);
|
virtual int __reg1 fchmod (mode_t mode);
|
||||||
virtual int __reg2 fchown (__uid32_t uid, __gid32_t gid);
|
virtual int __reg2 fchown (uid_t uid, gid_t gid);
|
||||||
virtual int __reg3 facl (int, int, __acl32 *);
|
virtual int __reg3 facl (int, int, struct acl *);
|
||||||
virtual ssize_t __reg3 fgetxattr (const char *, void *, size_t);
|
virtual ssize_t __reg3 fgetxattr (const char *, void *, size_t);
|
||||||
virtual int __reg3 fsetxattr (const char *, const void *, size_t, int);
|
virtual int __reg3 fsetxattr (const char *, const void *, size_t, int);
|
||||||
virtual int __reg3 fadvise (_off64_t, _off64_t, int);
|
virtual int __reg3 fadvise (off_t, off_t, int);
|
||||||
virtual int __reg3 ftruncate (_off64_t, bool);
|
virtual int __reg3 ftruncate (off_t, bool);
|
||||||
virtual int __reg2 link (const char *);
|
virtual int __reg2 link (const char *);
|
||||||
virtual int __reg2 utimens (const struct timespec *);
|
virtual int __reg2 utimens (const struct timespec *);
|
||||||
virtual int __reg1 fsync ();
|
virtual int __reg1 fsync ();
|
||||||
virtual int ioctl (unsigned int cmd, void *);
|
virtual int ioctl (unsigned int cmd, void *);
|
||||||
virtual int fcntl (int cmd, void *);
|
virtual int fcntl (int cmd, intptr_t);
|
||||||
virtual char const *ttyname () { return get_name (); }
|
virtual char const *ttyname () { return get_name (); }
|
||||||
virtual void __reg3 read (void *ptr, size_t& len);
|
virtual void __reg3 read (void *ptr, size_t& len);
|
||||||
virtual ssize_t __stdcall write (const void *ptr, size_t len);
|
virtual ssize_t __stdcall write (const void *ptr, size_t len);
|
||||||
virtual ssize_t __stdcall readv (const struct iovec *, int iovcnt, ssize_t tot = -1);
|
virtual ssize_t __stdcall readv (const struct iovec *, int iovcnt, ssize_t tot = -1);
|
||||||
virtual ssize_t __stdcall writev (const struct iovec *, int iovcnt, ssize_t tot = -1);
|
virtual ssize_t __stdcall writev (const struct iovec *, int iovcnt, ssize_t tot = -1);
|
||||||
virtual ssize_t __reg3 pread (void *, size_t, _off64_t);
|
virtual ssize_t __reg3 pread (void *, size_t, off_t);
|
||||||
virtual ssize_t __reg3 pwrite (void *, size_t, _off64_t);
|
virtual ssize_t __reg3 pwrite (void *, size_t, off_t);
|
||||||
virtual _off64_t lseek (_off64_t offset, int whence);
|
virtual off_t lseek (off_t offset, int whence);
|
||||||
virtual int lock (int, struct __flock64 *);
|
virtual int lock (int, struct flock *);
|
||||||
virtual int dup (fhandler_base *child, int flags);
|
virtual int dup (fhandler_base *child, int flags);
|
||||||
virtual int fpathconf (int);
|
virtual int fpathconf (int);
|
||||||
|
|
||||||
virtual HANDLE mmap (caddr_t *addr, size_t len, int prot,
|
virtual HANDLE mmap (caddr_t *addr, size_t len, int prot,
|
||||||
int flags, _off64_t off);
|
int flags, off_t off);
|
||||||
virtual int munmap (HANDLE h, caddr_t addr, size_t len);
|
virtual int munmap (HANDLE h, caddr_t addr, size_t len);
|
||||||
virtual int msync (HANDLE h, caddr_t addr, size_t len, int flags);
|
virtual int msync (HANDLE h, caddr_t addr, size_t len, int flags);
|
||||||
virtual bool fixup_mmap_after_fork (HANDLE h, int prot, int flags,
|
virtual bool fixup_mmap_after_fork (HANDLE h, int prot, int flags,
|
||||||
_off64_t offset, DWORD size,
|
off_t offset, DWORD size,
|
||||||
void *address);
|
void *address);
|
||||||
|
|
||||||
void *operator new (size_t, void *p) __attribute__ ((nothrow)) {return p;}
|
void *operator new (size_t, void *p) __attribute__ ((nothrow)) {return p;}
|
||||||
@ -480,12 +479,12 @@ class fhandler_socket: public fhandler_base
|
|||||||
int wait_for_events (const long event_mask, const DWORD flags);
|
int wait_for_events (const long event_mask, const DWORD flags);
|
||||||
void release_events ();
|
void release_events ();
|
||||||
|
|
||||||
pid_t sec_pid;
|
pid_t sec_pid;
|
||||||
__uid32_t sec_uid;
|
uid_t sec_uid;
|
||||||
__gid32_t sec_gid;
|
gid_t sec_gid;
|
||||||
pid_t sec_peer_pid;
|
pid_t sec_peer_pid;
|
||||||
__uid32_t sec_peer_uid;
|
uid_t sec_peer_uid;
|
||||||
__gid32_t sec_peer_gid;
|
gid_t sec_peer_gid;
|
||||||
void af_local_set_secret (char *);
|
void af_local_set_secret (char *);
|
||||||
void af_local_setblocking (bool &, bool &);
|
void af_local_setblocking (bool &, bool &);
|
||||||
void af_local_unsetblocking (bool, bool);
|
void af_local_unsetblocking (bool, bool);
|
||||||
@ -536,7 +535,14 @@ class fhandler_socket: public fhandler_base
|
|||||||
public:
|
public:
|
||||||
fhandler_socket ();
|
fhandler_socket ();
|
||||||
~fhandler_socket ();
|
~fhandler_socket ();
|
||||||
int get_socket () { return (int) get_handle(); }
|
/* Originally get_socket returned an int, which is not a good idea
|
||||||
|
to cast a handle to on 64 bit. The right type here is very certainly
|
||||||
|
SOCKET instead. On the other hand, we don't want to have to include
|
||||||
|
winsock.h just to build fhandler.h. Therefore we define get_socket
|
||||||
|
now only when building network related code. */
|
||||||
|
#ifdef __INSIDE_CYGWIN_NET__
|
||||||
|
SOCKET get_socket () { return (SOCKET) get_handle(); }
|
||||||
|
#endif
|
||||||
fhandler_socket *is_socket () { return this; }
|
fhandler_socket *is_socket () { return this; }
|
||||||
|
|
||||||
IMPLEMENT_STATUS_FLAG (bool, async_io)
|
IMPLEMENT_STATUS_FLAG (bool, async_io)
|
||||||
@ -552,7 +558,7 @@ class fhandler_socket: public fhandler_base
|
|||||||
int accept4 (struct sockaddr *peer, int *len, int flags);
|
int accept4 (struct sockaddr *peer, int *len, int flags);
|
||||||
int getsockname (struct sockaddr *name, int *namelen);
|
int getsockname (struct sockaddr *name, int *namelen);
|
||||||
int getpeername (struct sockaddr *name, int *namelen);
|
int getpeername (struct sockaddr *name, int *namelen);
|
||||||
int getpeereid (pid_t *pid, __uid32_t *euid, __gid32_t *egid);
|
int getpeereid (pid_t *pid, uid_t *euid, gid_t *egid);
|
||||||
|
|
||||||
int open (int flags, mode_t mode = 0);
|
int open (int flags, mode_t mode = 0);
|
||||||
void __reg3 read (void *ptr, size_t& len);
|
void __reg3 read (void *ptr, size_t& len);
|
||||||
@ -570,8 +576,8 @@ class fhandler_socket: public fhandler_base
|
|||||||
ssize_t sendmsg (const struct msghdr *msg, int flags);
|
ssize_t sendmsg (const struct msghdr *msg, int flags);
|
||||||
|
|
||||||
int ioctl (unsigned int cmd, void *);
|
int ioctl (unsigned int cmd, void *);
|
||||||
int fcntl (int cmd, void *);
|
int fcntl (int cmd, intptr_t);
|
||||||
_off64_t lseek (_off64_t, int) { return 0; }
|
off_t lseek (off_t, int) { return 0; }
|
||||||
int shutdown (int how);
|
int shutdown (int how);
|
||||||
int close ();
|
int close ();
|
||||||
void hclose (HANDLE) {close ();}
|
void hclose (HANDLE) {close ();}
|
||||||
@ -595,11 +601,11 @@ class fhandler_socket: public fhandler_base
|
|||||||
void set_peer_sun_path (const char *path);
|
void set_peer_sun_path (const char *path);
|
||||||
char *get_peer_sun_path () {return peer_sun_path;}
|
char *get_peer_sun_path () {return peer_sun_path;}
|
||||||
|
|
||||||
int __reg2 fstat (struct __stat64 *buf);
|
int __reg2 fstat (struct stat *buf);
|
||||||
int __reg2 fstatvfs (struct statvfs *buf);
|
int __reg2 fstatvfs (struct statvfs *buf);
|
||||||
int __reg1 fchmod (mode_t mode);
|
int __reg1 fchmod (mode_t mode);
|
||||||
int __reg2 fchown (__uid32_t uid, __gid32_t gid);
|
int __reg2 fchown (uid_t uid, gid_t gid);
|
||||||
int __reg3 facl (int, int, __acl32 *);
|
int __reg3 facl (int, int, struct acl *);
|
||||||
int __reg2 link (const char *);
|
int __reg2 link (const char *);
|
||||||
|
|
||||||
fhandler_socket (void *) {}
|
fhandler_socket (void *) {}
|
||||||
@ -693,7 +699,7 @@ public:
|
|||||||
|
|
||||||
void set_popen_pid (pid_t pid) {popen_pid = pid;}
|
void set_popen_pid (pid_t pid) {popen_pid = pid;}
|
||||||
pid_t get_popen_pid () const {return popen_pid;}
|
pid_t get_popen_pid () const {return popen_pid;}
|
||||||
_off64_t lseek (_off64_t offset, int whence);
|
off_t lseek (off_t offset, int whence);
|
||||||
select_record *select_read (select_stuff *);
|
select_record *select_read (select_stuff *);
|
||||||
select_record *select_write (select_stuff *);
|
select_record *select_write (select_stuff *);
|
||||||
select_record *select_except (select_stuff *);
|
select_record *select_except (select_stuff *);
|
||||||
@ -702,8 +708,8 @@ public:
|
|||||||
int dup (fhandler_base *child, int);
|
int dup (fhandler_base *child, int);
|
||||||
int ioctl (unsigned int cmd, void *);
|
int ioctl (unsigned int cmd, void *);
|
||||||
int __reg2 fstatvfs (struct statvfs *buf);
|
int __reg2 fstatvfs (struct statvfs *buf);
|
||||||
int __reg3 fadvise (_off64_t, _off64_t, int);
|
int __reg3 fadvise (off_t, off_t, int);
|
||||||
int __reg3 ftruncate (_off64_t, bool);
|
int __reg3 ftruncate (off_t, bool);
|
||||||
int init (HANDLE, DWORD, mode_t);
|
int init (HANDLE, DWORD, mode_t);
|
||||||
static int create (fhandler_pipe *[2], unsigned, int);
|
static int create (fhandler_pipe *[2], unsigned, int);
|
||||||
static DWORD create (LPSECURITY_ATTRIBUTES, HANDLE *, HANDLE *, DWORD,
|
static DWORD create (LPSECURITY_ATTRIBUTES, HANDLE *, HANDLE *, DWORD,
|
||||||
@ -770,7 +776,7 @@ class fhandler_mailslot : public fhandler_base_overlapped
|
|||||||
POBJECT_ATTRIBUTES get_object_attr (OBJECT_ATTRIBUTES &, PUNICODE_STRING, int);
|
POBJECT_ATTRIBUTES get_object_attr (OBJECT_ATTRIBUTES &, PUNICODE_STRING, int);
|
||||||
public:
|
public:
|
||||||
fhandler_mailslot ();
|
fhandler_mailslot ();
|
||||||
int __reg2 fstat (struct __stat64 *buf);
|
int __reg2 fstat (struct stat *buf);
|
||||||
int open (int flags, mode_t mode = 0);
|
int open (int flags, mode_t mode = 0);
|
||||||
ssize_t __reg3 raw_write (const void *, size_t);
|
ssize_t __reg3 raw_write (const void *, size_t);
|
||||||
int ioctl (unsigned int cmd, void *);
|
int ioctl (unsigned int cmd, void *);
|
||||||
@ -799,10 +805,10 @@ class fhandler_dev_raw: public fhandler_base
|
|||||||
protected:
|
protected:
|
||||||
char *devbufalloc;
|
char *devbufalloc;
|
||||||
char *devbuf;
|
char *devbuf;
|
||||||
size_t devbufalign;
|
DWORD devbufalign;
|
||||||
size_t devbufsiz;
|
DWORD devbufsiz;
|
||||||
size_t devbufstart;
|
DWORD devbufstart;
|
||||||
size_t devbufend;
|
DWORD devbufend;
|
||||||
struct status_flags
|
struct status_flags
|
||||||
{
|
{
|
||||||
unsigned lastblk_to_read : 1;
|
unsigned lastblk_to_read : 1;
|
||||||
@ -819,7 +825,7 @@ class fhandler_dev_raw: public fhandler_base
|
|||||||
|
|
||||||
int open (int flags, mode_t mode = 0);
|
int open (int flags, mode_t mode = 0);
|
||||||
|
|
||||||
int __reg2 fstat (struct __stat64 *buf);
|
int __reg2 fstat (struct stat *buf);
|
||||||
|
|
||||||
int dup (fhandler_base *child, int);
|
int dup (fhandler_base *child, int);
|
||||||
int ioctl (unsigned int cmd, void *buf);
|
int ioctl (unsigned int cmd, void *buf);
|
||||||
@ -856,7 +862,7 @@ struct part_t
|
|||||||
class fhandler_dev_floppy: public fhandler_dev_raw
|
class fhandler_dev_floppy: public fhandler_dev_raw
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
_off64_t drive_size;
|
off_t drive_size;
|
||||||
part_t *partitions;
|
part_t *partitions;
|
||||||
struct status_flags
|
struct status_flags
|
||||||
{
|
{
|
||||||
@ -867,7 +873,7 @@ class fhandler_dev_floppy: public fhandler_dev_raw
|
|||||||
|
|
||||||
IMPLEMENT_STATUS_FLAG (bool, eom_detected)
|
IMPLEMENT_STATUS_FLAG (bool, eom_detected)
|
||||||
|
|
||||||
inline _off64_t get_current_position ();
|
inline off_t get_current_position ();
|
||||||
int get_drive_info (struct hd_geometry *geo);
|
int get_drive_info (struct hd_geometry *geo);
|
||||||
|
|
||||||
int lock_partition (DWORD to_write);
|
int lock_partition (DWORD to_write);
|
||||||
@ -883,7 +889,7 @@ class fhandler_dev_floppy: public fhandler_dev_raw
|
|||||||
int dup (fhandler_base *child, int);
|
int dup (fhandler_base *child, int);
|
||||||
void __reg3 raw_read (void *ptr, size_t& ulen);
|
void __reg3 raw_read (void *ptr, size_t& ulen);
|
||||||
ssize_t __reg3 raw_write (const void *ptr, size_t ulen);
|
ssize_t __reg3 raw_write (const void *ptr, size_t ulen);
|
||||||
_off64_t lseek (_off64_t offset, int whence);
|
off_t lseek (off_t offset, int whence);
|
||||||
int ioctl (unsigned int cmd, void *buf);
|
int ioctl (unsigned int cmd, void *buf);
|
||||||
|
|
||||||
fhandler_dev_floppy (void *) {}
|
fhandler_dev_floppy (void *) {}
|
||||||
@ -907,7 +913,7 @@ class fhandler_dev_floppy: public fhandler_dev_raw
|
|||||||
class fhandler_dev_tape: public fhandler_dev_raw
|
class fhandler_dev_tape: public fhandler_dev_raw
|
||||||
{
|
{
|
||||||
HANDLE mt_mtx;
|
HANDLE mt_mtx;
|
||||||
HANDLE mt_evt;
|
OVERLAPPED ov;
|
||||||
|
|
||||||
bool is_rewind_device () { return get_minor () < 128; }
|
bool is_rewind_device () { return get_minor () < 128; }
|
||||||
unsigned int driveno () { return (unsigned int) get_minor () & 0x7f; }
|
unsigned int driveno () { return (unsigned int) get_minor () & 0x7f; }
|
||||||
@ -925,9 +931,9 @@ class fhandler_dev_tape: public fhandler_dev_raw
|
|||||||
void __reg3 raw_read (void *ptr, size_t& ulen);
|
void __reg3 raw_read (void *ptr, size_t& ulen);
|
||||||
ssize_t __reg3 raw_write (const void *ptr, size_t ulen);
|
ssize_t __reg3 raw_write (const void *ptr, size_t ulen);
|
||||||
|
|
||||||
virtual _off64_t lseek (_off64_t offset, int whence);
|
virtual off_t lseek (off_t offset, int whence);
|
||||||
|
|
||||||
virtual int __reg2 fstat (struct __stat64 *buf);
|
virtual int __reg2 fstat (struct stat *buf);
|
||||||
|
|
||||||
virtual int dup (fhandler_base *child, int);
|
virtual int dup (fhandler_base *child, int);
|
||||||
virtual void fixup_after_fork (HANDLE parent);
|
virtual void fixup_after_fork (HANDLE parent);
|
||||||
@ -969,25 +975,25 @@ class fhandler_disk_file: public fhandler_base
|
|||||||
int close ();
|
int close ();
|
||||||
int dup (fhandler_base *child, int);
|
int dup (fhandler_base *child, int);
|
||||||
void fixup_after_fork (HANDLE parent);
|
void fixup_after_fork (HANDLE parent);
|
||||||
int lock (int, struct __flock64 *);
|
int lock (int, struct flock *);
|
||||||
bool isdevice () const { return false; }
|
bool isdevice () const { return false; }
|
||||||
int __reg2 fstat (struct __stat64 *buf);
|
int __reg2 fstat (struct stat *buf);
|
||||||
int __reg1 fchmod (mode_t mode);
|
int __reg1 fchmod (mode_t mode);
|
||||||
int __reg2 fchown (__uid32_t uid, __gid32_t gid);
|
int __reg2 fchown (uid_t uid, gid_t gid);
|
||||||
int __reg3 facl (int, int, __acl32 *);
|
int __reg3 facl (int, int, struct acl *);
|
||||||
ssize_t __reg3 fgetxattr (const char *, void *, size_t);
|
ssize_t __reg3 fgetxattr (const char *, void *, size_t);
|
||||||
int __reg3 fsetxattr (const char *, const void *, size_t, int);
|
int __reg3 fsetxattr (const char *, const void *, size_t, int);
|
||||||
int __reg3 fadvise (_off64_t, _off64_t, int);
|
int __reg3 fadvise (off_t, off_t, int);
|
||||||
int __reg3 ftruncate (_off64_t, bool);
|
int __reg3 ftruncate (off_t, bool);
|
||||||
int __reg2 link (const char *);
|
int __reg2 link (const char *);
|
||||||
int __reg2 utimens (const struct timespec *);
|
int __reg2 utimens (const struct timespec *);
|
||||||
int __reg2 fstatvfs (struct statvfs *buf);
|
int __reg2 fstatvfs (struct statvfs *buf);
|
||||||
|
|
||||||
HANDLE mmap (caddr_t *addr, size_t len, int prot, int flags, _off64_t off);
|
HANDLE mmap (caddr_t *addr, size_t len, int prot, int flags, off_t off);
|
||||||
int munmap (HANDLE h, caddr_t addr, size_t len);
|
int munmap (HANDLE h, caddr_t addr, size_t len);
|
||||||
int msync (HANDLE h, caddr_t addr, size_t len, int flags);
|
int msync (HANDLE h, caddr_t addr, size_t len, int flags);
|
||||||
bool fixup_mmap_after_fork (HANDLE h, int prot, int flags,
|
bool fixup_mmap_after_fork (HANDLE h, int prot, int flags,
|
||||||
_off64_t offset, DWORD size, void *address);
|
off_t offset, DWORD size, void *address);
|
||||||
int mkdir (mode_t mode);
|
int mkdir (mode_t mode);
|
||||||
int rmdir ();
|
int rmdir ();
|
||||||
DIR __reg2 *opendir (int fd);
|
DIR __reg2 *opendir (int fd);
|
||||||
@ -997,8 +1003,8 @@ class fhandler_disk_file: public fhandler_base
|
|||||||
void rewinddir (DIR *);
|
void rewinddir (DIR *);
|
||||||
int closedir (DIR *);
|
int closedir (DIR *);
|
||||||
|
|
||||||
ssize_t __reg3 pread (void *, size_t, _off64_t);
|
ssize_t __reg3 pread (void *, size_t, off_t);
|
||||||
ssize_t __reg3 pwrite (void *, size_t, _off64_t);
|
ssize_t __reg3 pwrite (void *, size_t, off_t);
|
||||||
|
|
||||||
fhandler_disk_file (void *) {}
|
fhandler_disk_file (void *) {}
|
||||||
|
|
||||||
@ -1026,7 +1032,7 @@ public:
|
|||||||
fhandler_dev ();
|
fhandler_dev ();
|
||||||
int open (int flags, mode_t mode);
|
int open (int flags, mode_t mode);
|
||||||
int close ();
|
int close ();
|
||||||
int __reg2 fstat (struct __stat64 *buf);
|
int __reg2 fstat (struct stat *buf);
|
||||||
int __reg2 fstatvfs (struct statvfs *buf);
|
int __reg2 fstatvfs (struct statvfs *buf);
|
||||||
DIR __reg2 *opendir (int fd);
|
DIR __reg2 *opendir (int fd);
|
||||||
int __reg3 readdir (DIR *, dirent *);
|
int __reg3 readdir (DIR *, dirent *);
|
||||||
@ -1068,7 +1074,7 @@ class fhandler_cygdrive: public fhandler_disk_file
|
|||||||
int __reg3 readdir (DIR *, dirent *);
|
int __reg3 readdir (DIR *, dirent *);
|
||||||
void rewinddir (DIR *);
|
void rewinddir (DIR *);
|
||||||
int closedir (DIR *);
|
int closedir (DIR *);
|
||||||
int __reg2 fstat (struct __stat64 *buf);
|
int __reg2 fstat (struct stat *buf);
|
||||||
int __reg2 fstatvfs (struct statvfs *buf);
|
int __reg2 fstatvfs (struct statvfs *buf);
|
||||||
|
|
||||||
fhandler_cygdrive (void *) {}
|
fhandler_cygdrive (void *) {}
|
||||||
@ -1120,7 +1126,7 @@ class fhandler_serial: public fhandler_base
|
|||||||
int switch_modem_lines (int set, int clr);
|
int switch_modem_lines (int set, int clr);
|
||||||
int tcsetattr (int a, const struct termios *t);
|
int tcsetattr (int a, const struct termios *t);
|
||||||
int tcgetattr (struct termios *t);
|
int tcgetattr (struct termios *t);
|
||||||
_off64_t lseek (_off64_t, int) { return 0; }
|
off_t lseek (off_t, int) { return 0; }
|
||||||
int tcflush (int);
|
int tcflush (int);
|
||||||
bool is_tty () const { return true; }
|
bool is_tty () const { return true; }
|
||||||
void fixup_after_fork (HANDLE parent);
|
void fixup_after_fork (HANDLE parent);
|
||||||
@ -1190,7 +1196,7 @@ class fhandler_termios: public fhandler_base
|
|||||||
virtual DWORD __acquire_output_mutex (const char *fn, int ln, DWORD ms) {return 1;}
|
virtual DWORD __acquire_output_mutex (const char *fn, int ln, DWORD ms) {return 1;}
|
||||||
virtual void __release_output_mutex (const char *fn, int ln) {}
|
virtual void __release_output_mutex (const char *fn, int ln) {}
|
||||||
void echo_erase (int force = 0);
|
void echo_erase (int force = 0);
|
||||||
virtual _off64_t lseek (_off64_t, int);
|
virtual off_t lseek (off_t, int);
|
||||||
pid_t tcgetsid ();
|
pid_t tcgetsid ();
|
||||||
|
|
||||||
fhandler_termios (void *) {}
|
fhandler_termios (void *) {}
|
||||||
@ -1438,7 +1444,7 @@ class fhandler_pty_common: public fhandler_termios
|
|||||||
void __release_output_mutex (const char *fn, int ln);
|
void __release_output_mutex (const char *fn, int ln);
|
||||||
|
|
||||||
int close ();
|
int close ();
|
||||||
_off64_t lseek (_off64_t, int);
|
off_t lseek (off_t, int);
|
||||||
bool bytes_available (DWORD& n);
|
bool bytes_available (DWORD& n);
|
||||||
void set_close_on_exec (bool val);
|
void set_close_on_exec (bool val);
|
||||||
select_record *select_read (select_stuff *);
|
select_record *select_read (select_stuff *);
|
||||||
@ -1493,11 +1499,10 @@ class fhandler_pty_slave: public fhandler_pty_common
|
|||||||
void fixup_after_exec ();
|
void fixup_after_exec ();
|
||||||
|
|
||||||
select_record *select_read (select_stuff *);
|
select_record *select_read (select_stuff *);
|
||||||
int get_unit ();
|
|
||||||
virtual char const *ttyname () { return pc.dev.name; }
|
virtual char const *ttyname () { return pc.dev.name; }
|
||||||
int __reg2 fstat (struct __stat64 *buf);
|
int __reg2 fstat (struct stat *buf);
|
||||||
int __reg1 fchmod (mode_t mode);
|
int __reg1 fchmod (mode_t mode);
|
||||||
int __reg2 fchown (__uid32_t uid, __gid32_t gid);
|
int __reg2 fchown (uid_t uid, gid_t gid);
|
||||||
|
|
||||||
fhandler_pty_slave (void *) {}
|
fhandler_pty_slave (void *) {}
|
||||||
|
|
||||||
@ -1611,14 +1616,14 @@ class fhandler_dev_zero: public fhandler_base
|
|||||||
int open (int flags, mode_t mode = 0);
|
int open (int flags, mode_t mode = 0);
|
||||||
ssize_t __stdcall write (const void *ptr, size_t len);
|
ssize_t __stdcall write (const void *ptr, size_t len);
|
||||||
void __reg3 read (void *ptr, size_t& len);
|
void __reg3 read (void *ptr, size_t& len);
|
||||||
_off64_t lseek (_off64_t offset, int whence);
|
off_t lseek (off_t offset, int whence);
|
||||||
|
|
||||||
virtual HANDLE mmap (caddr_t *addr, size_t len, int prot,
|
virtual HANDLE mmap (caddr_t *addr, size_t len, int prot,
|
||||||
int flags, _off64_t off);
|
int flags, off_t off);
|
||||||
virtual int munmap (HANDLE h, caddr_t addr, size_t len);
|
virtual int munmap (HANDLE h, caddr_t addr, size_t len);
|
||||||
virtual int msync (HANDLE h, caddr_t addr, size_t len, int flags);
|
virtual int msync (HANDLE h, caddr_t addr, size_t len, int flags);
|
||||||
virtual bool fixup_mmap_after_fork (HANDLE h, int prot, int flags,
|
virtual bool fixup_mmap_after_fork (HANDLE h, int prot, int flags,
|
||||||
_off64_t offset, DWORD size,
|
off_t offset, DWORD size,
|
||||||
void *address);
|
void *address);
|
||||||
|
|
||||||
fhandler_dev_zero (void *) {}
|
fhandler_dev_zero (void *) {}
|
||||||
@ -1644,7 +1649,7 @@ class fhandler_dev_random: public fhandler_base
|
|||||||
protected:
|
protected:
|
||||||
HCRYPTPROV crypt_prov;
|
HCRYPTPROV crypt_prov;
|
||||||
long pseudo;
|
long pseudo;
|
||||||
_off64_t dummy_offset;
|
off_t dummy_offset;
|
||||||
|
|
||||||
bool crypt_gen_random (void *ptr, size_t len);
|
bool crypt_gen_random (void *ptr, size_t len);
|
||||||
int pseudo_write (const void *ptr, size_t len);
|
int pseudo_write (const void *ptr, size_t len);
|
||||||
@ -1655,7 +1660,7 @@ class fhandler_dev_random: public fhandler_base
|
|||||||
int open (int flags, mode_t mode = 0);
|
int open (int flags, mode_t mode = 0);
|
||||||
ssize_t __stdcall write (const void *ptr, size_t len);
|
ssize_t __stdcall write (const void *ptr, size_t len);
|
||||||
void __reg3 read (void *ptr, size_t& len);
|
void __reg3 read (void *ptr, size_t& len);
|
||||||
_off64_t lseek (_off64_t offset, int whence);
|
off_t lseek (off_t offset, int whence);
|
||||||
int close ();
|
int close ();
|
||||||
int dup (fhandler_base *child, int);
|
int dup (fhandler_base *child, int);
|
||||||
|
|
||||||
@ -1680,8 +1685,8 @@ class fhandler_dev_random: public fhandler_base
|
|||||||
class fhandler_dev_mem: public fhandler_base
|
class fhandler_dev_mem: public fhandler_base
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
DWORD mem_size;
|
SIZE_T mem_size;
|
||||||
_off64_t pos;
|
off_t pos;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
fhandler_dev_mem ();
|
fhandler_dev_mem ();
|
||||||
@ -1690,14 +1695,14 @@ class fhandler_dev_mem: public fhandler_base
|
|||||||
int open (int flags, mode_t mode = 0);
|
int open (int flags, mode_t mode = 0);
|
||||||
ssize_t __stdcall write (const void *ptr, size_t ulen);
|
ssize_t __stdcall write (const void *ptr, size_t ulen);
|
||||||
void __reg3 read (void *ptr, size_t& len);
|
void __reg3 read (void *ptr, size_t& len);
|
||||||
_off64_t lseek (_off64_t offset, int whence);
|
off_t lseek (off_t offset, int whence);
|
||||||
int __reg2 fstat (struct __stat64 *buf);
|
int __reg2 fstat (struct stat *buf);
|
||||||
|
|
||||||
HANDLE mmap (caddr_t *addr, size_t len, int prot, int flags, _off64_t off);
|
HANDLE mmap (caddr_t *addr, size_t len, int prot, int flags, off_t off);
|
||||||
int munmap (HANDLE h, caddr_t addr, size_t len);
|
int munmap (HANDLE h, caddr_t addr, size_t len);
|
||||||
int msync (HANDLE h, caddr_t addr, size_t len, int flags);
|
int msync (HANDLE h, caddr_t addr, size_t len, int flags);
|
||||||
bool fixup_mmap_after_fork (HANDLE h, int prot, int flags,
|
bool fixup_mmap_after_fork (HANDLE h, int prot, int flags,
|
||||||
_off64_t offset, DWORD size, void *address);
|
off_t offset, DWORD size, void *address);
|
||||||
|
|
||||||
fhandler_dev_mem (void *) {}
|
fhandler_dev_mem (void *) {}
|
||||||
|
|
||||||
@ -1719,17 +1724,17 @@ class fhandler_dev_mem: public fhandler_base
|
|||||||
|
|
||||||
class fhandler_dev_clipboard: public fhandler_base
|
class fhandler_dev_clipboard: public fhandler_base
|
||||||
{
|
{
|
||||||
_off64_t pos;
|
off_t pos;
|
||||||
void *membuffer;
|
void *membuffer;
|
||||||
size_t msize;
|
size_t msize;
|
||||||
public:
|
public:
|
||||||
fhandler_dev_clipboard ();
|
fhandler_dev_clipboard ();
|
||||||
int is_windows () { return 1; }
|
int is_windows () { return 1; }
|
||||||
int open (int flags, mode_t mode = 0);
|
int open (int flags, mode_t mode = 0);
|
||||||
int __reg2 fstat (struct __stat64 *buf);
|
int __reg2 fstat (struct stat *buf);
|
||||||
ssize_t __stdcall write (const void *ptr, size_t len);
|
ssize_t __stdcall write (const void *ptr, size_t len);
|
||||||
void __reg3 read (void *ptr, size_t& len);
|
void __reg3 read (void *ptr, size_t& len);
|
||||||
_off64_t lseek (_off64_t offset, int whence);
|
off_t lseek (off_t offset, int whence);
|
||||||
int close ();
|
int close ();
|
||||||
|
|
||||||
int dup (fhandler_base *child, int);
|
int dup (fhandler_base *child, int);
|
||||||
@ -1765,7 +1770,7 @@ class fhandler_windows: public fhandler_base
|
|||||||
ssize_t __stdcall write (const void *ptr, size_t len);
|
ssize_t __stdcall write (const void *ptr, size_t len);
|
||||||
void __reg3 read (void *ptr, size_t& len);
|
void __reg3 read (void *ptr, size_t& len);
|
||||||
int ioctl (unsigned int cmd, void *);
|
int ioctl (unsigned int cmd, void *);
|
||||||
_off64_t lseek (_off64_t, int) { return 0; }
|
off_t lseek (off_t, int) { return 0; }
|
||||||
int close () { return 0; }
|
int close () { return 0; }
|
||||||
|
|
||||||
void set_close_on_exec (bool val);
|
void set_close_on_exec (bool val);
|
||||||
@ -1812,7 +1817,7 @@ class fhandler_dev_dsp: public fhandler_base
|
|||||||
ssize_t __stdcall write (const void *ptr, size_t len);
|
ssize_t __stdcall write (const void *ptr, size_t len);
|
||||||
void __reg3 read (void *ptr, size_t& len);
|
void __reg3 read (void *ptr, size_t& len);
|
||||||
int ioctl (unsigned int cmd, void *);
|
int ioctl (unsigned int cmd, void *);
|
||||||
_off64_t lseek (_off64_t, int);
|
off_t lseek (off_t, int);
|
||||||
int close ();
|
int close ();
|
||||||
void fixup_after_fork (HANDLE parent);
|
void fixup_after_fork (HANDLE parent);
|
||||||
void fixup_after_exec ();
|
void fixup_after_exec ();
|
||||||
@ -1843,8 +1848,8 @@ class fhandler_virtual : public fhandler_base
|
|||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
char *filebuf;
|
char *filebuf;
|
||||||
_off64_t filesize;
|
off_t filesize;
|
||||||
_off64_t position;
|
off_t position;
|
||||||
int fileid; // unique within each class
|
int fileid; // unique within each class
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -1859,15 +1864,14 @@ class fhandler_virtual : public fhandler_base
|
|||||||
int closedir (DIR *);
|
int closedir (DIR *);
|
||||||
ssize_t __stdcall write (const void *ptr, size_t len);
|
ssize_t __stdcall write (const void *ptr, size_t len);
|
||||||
void __reg3 read (void *ptr, size_t& len);
|
void __reg3 read (void *ptr, size_t& len);
|
||||||
_off64_t lseek (_off64_t, int);
|
off_t lseek (off_t, int);
|
||||||
int dup (fhandler_base *child, int);
|
int dup (fhandler_base *child, int);
|
||||||
int open (int flags, mode_t mode = 0);
|
int open (int flags, mode_t mode = 0);
|
||||||
int close ();
|
int close ();
|
||||||
int __reg2 fstat (struct stat *buf);
|
|
||||||
int __reg2 fstatvfs (struct statvfs *buf);
|
int __reg2 fstatvfs (struct statvfs *buf);
|
||||||
int __reg1 fchmod (mode_t mode);
|
int __reg1 fchmod (mode_t mode);
|
||||||
int __reg2 fchown (__uid32_t uid, __gid32_t gid);
|
int __reg2 fchown (uid_t uid, gid_t gid);
|
||||||
int __reg3 facl (int, int, __acl32 *);
|
int __reg3 facl (int, int, struct acl *);
|
||||||
virtual bool fill_filebuf ();
|
virtual bool fill_filebuf ();
|
||||||
char *get_filebuf () { return filebuf; }
|
char *get_filebuf () { return filebuf; }
|
||||||
void fixup_after_exec ();
|
void fixup_after_exec ();
|
||||||
@ -1901,7 +1905,7 @@ class fhandler_proc: public fhandler_virtual
|
|||||||
static fh_devices get_proc_fhandler (const char *path);
|
static fh_devices get_proc_fhandler (const char *path);
|
||||||
|
|
||||||
int open (int flags, mode_t mode = 0);
|
int open (int flags, mode_t mode = 0);
|
||||||
int __reg2 fstat (struct __stat64 *buf);
|
int __reg2 fstat (struct stat *buf);
|
||||||
bool fill_filebuf ();
|
bool fill_filebuf ();
|
||||||
|
|
||||||
fhandler_proc (void *) {}
|
fhandler_proc (void *) {}
|
||||||
@ -1926,7 +1930,7 @@ class fhandler_procsys: public fhandler_virtual
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
fhandler_procsys ();
|
fhandler_procsys ();
|
||||||
virtual_ftype_t __reg2 exists(struct __stat64 *buf);
|
virtual_ftype_t __reg2 exists(struct stat *buf);
|
||||||
virtual_ftype_t exists();
|
virtual_ftype_t exists();
|
||||||
DIR __reg2 *opendir (int fd);
|
DIR __reg2 *opendir (int fd);
|
||||||
int __reg3 readdir (DIR *, dirent *);
|
int __reg3 readdir (DIR *, dirent *);
|
||||||
@ -1937,7 +1941,7 @@ class fhandler_procsys: public fhandler_virtual
|
|||||||
int close ();
|
int close ();
|
||||||
void __reg3 read (void *ptr, size_t& len);
|
void __reg3 read (void *ptr, size_t& len);
|
||||||
ssize_t __stdcall write (const void *ptr, size_t len);
|
ssize_t __stdcall write (const void *ptr, size_t len);
|
||||||
int __reg2 fstat (struct __stat64 *buf);
|
int __reg2 fstat (struct stat *buf);
|
||||||
bool fill_filebuf ();
|
bool fill_filebuf ();
|
||||||
|
|
||||||
fhandler_procsys (void *) {}
|
fhandler_procsys (void *) {}
|
||||||
@ -1966,7 +1970,7 @@ class fhandler_procsysvipc: public fhandler_proc
|
|||||||
virtual_ftype_t exists();
|
virtual_ftype_t exists();
|
||||||
int __reg3 readdir (DIR *, dirent *);
|
int __reg3 readdir (DIR *, dirent *);
|
||||||
int open (int flags, mode_t mode = 0);
|
int open (int flags, mode_t mode = 0);
|
||||||
int __reg2 fstat (struct __stat64 *buf);
|
int __reg2 fstat (struct stat *buf);
|
||||||
bool fill_filebuf ();
|
bool fill_filebuf ();
|
||||||
|
|
||||||
fhandler_procsysvipc (void *) {}
|
fhandler_procsysvipc (void *) {}
|
||||||
@ -1997,7 +2001,7 @@ class fhandler_netdrive: public fhandler_virtual
|
|||||||
void rewinddir (DIR *);
|
void rewinddir (DIR *);
|
||||||
int closedir (DIR *);
|
int closedir (DIR *);
|
||||||
int open (int flags, mode_t mode = 0);
|
int open (int flags, mode_t mode = 0);
|
||||||
int __reg2 fstat (struct __stat64 *buf);
|
int __reg2 fstat (struct stat *buf);
|
||||||
|
|
||||||
fhandler_netdrive (void *) {}
|
fhandler_netdrive (void *) {}
|
||||||
|
|
||||||
@ -2035,7 +2039,7 @@ class fhandler_registry: public fhandler_proc
|
|||||||
int closedir (DIR *);
|
int closedir (DIR *);
|
||||||
|
|
||||||
int open (int flags, mode_t mode = 0);
|
int open (int flags, mode_t mode = 0);
|
||||||
int __reg2 fstat (struct __stat64 *buf);
|
int __reg2 fstat (struct stat *buf);
|
||||||
bool fill_filebuf ();
|
bool fill_filebuf ();
|
||||||
int close ();
|
int close ();
|
||||||
int dup (fhandler_base *child, int);
|
int dup (fhandler_base *child, int);
|
||||||
@ -2069,7 +2073,7 @@ class fhandler_process: public fhandler_proc
|
|||||||
int closedir (DIR *);
|
int closedir (DIR *);
|
||||||
int __reg3 readdir (DIR *, dirent *);
|
int __reg3 readdir (DIR *, dirent *);
|
||||||
int open (int flags, mode_t mode = 0);
|
int open (int flags, mode_t mode = 0);
|
||||||
int __reg2 fstat (struct __stat64 *buf);
|
int __reg2 fstat (struct stat *buf);
|
||||||
bool fill_filebuf ();
|
bool fill_filebuf ();
|
||||||
|
|
||||||
fhandler_process (void *) {}
|
fhandler_process (void *) {}
|
||||||
@ -2098,7 +2102,7 @@ class fhandler_procnet: public fhandler_proc
|
|||||||
virtual_ftype_t exists();
|
virtual_ftype_t exists();
|
||||||
int __reg3 readdir (DIR *, dirent *);
|
int __reg3 readdir (DIR *, dirent *);
|
||||||
int open (int flags, mode_t mode = 0);
|
int open (int flags, mode_t mode = 0);
|
||||||
int __reg2 fstat (struct __stat64 *buf);
|
int __reg2 fstat (struct stat *buf);
|
||||||
bool fill_filebuf ();
|
bool fill_filebuf ();
|
||||||
|
|
||||||
fhandler_procnet (void *) {}
|
fhandler_procnet (void *) {}
|
||||||
|
@ -29,7 +29,7 @@ details. */
|
|||||||
* changed? How does /dev/clipboard operate under (say) linux?
|
* changed? How does /dev/clipboard operate under (say) linux?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const NO_COPY WCHAR *CYGWIN_NATIVE = L"CYGWIN_NATIVE_CLIPBOARD";
|
static const WCHAR *CYGWIN_NATIVE = L"CYGWIN_NATIVE_CLIPBOARD";
|
||||||
/* this is MT safe because windows format id's are atomic */
|
/* this is MT safe because windows format id's are atomic */
|
||||||
static UINT cygnativeformat;
|
static UINT cygnativeformat;
|
||||||
|
|
||||||
@ -181,7 +181,7 @@ fhandler_dev_clipboard::write (const void *buf, size_t len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int __reg2
|
int __reg2
|
||||||
fhandler_dev_clipboard::fstat (struct __stat64 *buf)
|
fhandler_dev_clipboard::fstat (struct stat *buf)
|
||||||
{
|
{
|
||||||
buf->st_mode = S_IFCHR | STD_RBITS | STD_WBITS | S_IWGRP | S_IWOTH;
|
buf->st_mode = S_IFCHR | STD_RBITS | STD_WBITS | S_IWGRP | S_IWOTH;
|
||||||
buf->st_uid = geteuid32 ();
|
buf->st_uid = geteuid32 ();
|
||||||
@ -243,7 +243,7 @@ fhandler_dev_clipboard::read (void *ptr, size_t& len)
|
|||||||
{
|
{
|
||||||
cygcb_t *clipbuf = (cygcb_t *) cb_data;
|
cygcb_t *clipbuf = (cygcb_t *) cb_data;
|
||||||
|
|
||||||
if (pos < clipbuf->len)
|
if (pos < (off_t) clipbuf->len)
|
||||||
{
|
{
|
||||||
ret = ((len > (clipbuf->len - pos)) ? (clipbuf->len - pos) : len);
|
ret = ((len > (clipbuf->len - pos)) ? (clipbuf->len - pos) : len);
|
||||||
memcpy (ptr, clipbuf->data + pos , ret);
|
memcpy (ptr, clipbuf->data + pos , ret);
|
||||||
@ -267,7 +267,7 @@ fhandler_dev_clipboard::read (void *ptr, size_t& len)
|
|||||||
wchar_t *buf = (wchar_t *) cb_data;
|
wchar_t *buf = (wchar_t *) cb_data;
|
||||||
|
|
||||||
size_t glen = GlobalSize (hglb) / sizeof (WCHAR) - 1;
|
size_t glen = GlobalSize (hglb) / sizeof (WCHAR) - 1;
|
||||||
if (pos < glen)
|
if (pos < (off_t) glen)
|
||||||
{
|
{
|
||||||
/* If caller's buffer is too small to hold at least one
|
/* If caller's buffer is too small to hold at least one
|
||||||
max-size character, redirect algorithm to local
|
max-size character, redirect algorithm to local
|
||||||
@ -325,8 +325,8 @@ fhandler_dev_clipboard::read (void *ptr, size_t& len)
|
|||||||
len = ret;
|
len = ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
_off64_t
|
off_t
|
||||||
fhandler_dev_clipboard::lseek (_off64_t offset, int whence)
|
fhandler_dev_clipboard::lseek (off_t offset, int whence)
|
||||||
{
|
{
|
||||||
/* On reads we check this at read time, not seek time.
|
/* On reads we check this at read time, not seek time.
|
||||||
* On writes we use this to decide how to write - empty and write, or open, copy, empty
|
* On writes we use this to decide how to write - empty and write, or open, copy, empty
|
||||||
|
@ -216,7 +216,7 @@ fhandler_console::setup ()
|
|||||||
tty_min *
|
tty_min *
|
||||||
tty_list::get_cttyp ()
|
tty_list::get_cttyp ()
|
||||||
{
|
{
|
||||||
_dev_t n = myself->ctty;
|
dev_t n = myself->ctty;
|
||||||
if (iscons_dev (n))
|
if (iscons_dev (n))
|
||||||
return fhandler_console::shared_console_info ?
|
return fhandler_console::shared_console_info ?
|
||||||
&fhandler_console::shared_console_info->tty_min_state : NULL;
|
&fhandler_console::shared_console_info->tty_min_state : NULL;
|
||||||
@ -944,9 +944,9 @@ fhandler_console::ioctl (unsigned int cmd, void *arg)
|
|||||||
*(int *) arg = (dev_state.metabit) ? K_METABIT : K_ESCPREFIX;
|
*(int *) arg = (dev_state.metabit) ? K_METABIT : K_ESCPREFIX;
|
||||||
return 0;
|
return 0;
|
||||||
case KDSKBMETA:
|
case KDSKBMETA:
|
||||||
if ((int) arg == K_METABIT)
|
if ((intptr_t) arg == K_METABIT)
|
||||||
dev_state.metabit = TRUE;
|
dev_state.metabit = TRUE;
|
||||||
else if ((int) arg == K_ESCPREFIX)
|
else if ((intptr_t) arg == K_ESCPREFIX)
|
||||||
dev_state.metabit = FALSE;
|
dev_state.metabit = FALSE;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1013,7 +1013,7 @@ fhandler_console::output_tcsetattr (int, struct termios const *t)
|
|||||||
int res = SetConsoleMode (get_output_handle (), flags) ? 0 : -1;
|
int res = SetConsoleMode (get_output_handle (), flags) ? 0 : -1;
|
||||||
if (res)
|
if (res)
|
||||||
__seterrno_from_win_error (GetLastError ());
|
__seterrno_from_win_error (GetLastError ());
|
||||||
syscall_printf ("%d = tcsetattr(,%x) (ENABLE FLAGS %x) (lflag %x oflag %x)",
|
syscall_printf ("%d = tcsetattr(,%p) (ENABLE FLAGS %y) (lflag %y oflag %y)",
|
||||||
res, t, flags, t->c_lflag, t->c_oflag);
|
res, t, flags, t->c_lflag, t->c_oflag);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -1075,7 +1075,7 @@ fhandler_console::input_tcsetattr (int, struct termios const *t)
|
|||||||
res = SetConsoleMode (get_io_handle (), flags) ? 0 : -1;
|
res = SetConsoleMode (get_io_handle (), flags) ? 0 : -1;
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
__seterrno ();
|
__seterrno ();
|
||||||
syscall_printf ("%d = tcsetattr(,%x) enable flags %p, c_lflag %p iflag %p",
|
syscall_printf ("%d = tcsetattr(,%p) enable flags %y, c_lflag %y iflag %y",
|
||||||
res, t, flags, t->c_lflag, t->c_iflag);
|
res, t, flags, t->c_lflag, t->c_iflag);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1126,7 +1126,7 @@ fhandler_console::tcgetattr (struct termios *t)
|
|||||||
/* All the output bits we can ignore */
|
/* All the output bits we can ignore */
|
||||||
res = 0;
|
res = 0;
|
||||||
}
|
}
|
||||||
syscall_printf ("%d = tcgetattr(%p) enable flags %p, t->lflag %p, t->iflag %p",
|
syscall_printf ("%d = tcgetattr(%p) enable flags %y, t->lflag %y, t->iflag %y",
|
||||||
res, t, flags, t->c_lflag, t->c_iflag);
|
res, t, flags, t->c_lflag, t->c_iflag);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -2044,7 +2044,7 @@ fhandler_console::write (const void *vsrc, size_t len)
|
|||||||
tmp_pathbuf tp;
|
tmp_pathbuf tp;
|
||||||
write_buf = tp.w_get ();
|
write_buf = tp.w_get ();
|
||||||
|
|
||||||
debug_printf ("%x, %d", vsrc, len);
|
debug_printf ("%p, %ld", vsrc, len);
|
||||||
|
|
||||||
while (src < end)
|
while (src < end)
|
||||||
{
|
{
|
||||||
@ -2211,15 +2211,15 @@ fhandler_console::write (const void *vsrc, size_t len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
syscall_printf ("%d = fhandler_console::write(...)", len);
|
syscall_printf ("%ld = fhandler_console::write(...)", len);
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct {
|
static const struct {
|
||||||
int vk;
|
int vk;
|
||||||
const char *val[4];
|
const char *val[4];
|
||||||
} keytable[] NO_COPY = {
|
} keytable[] = {
|
||||||
/* NORMAL */ /* SHIFT */ /* CTRL */ /* CTRL-SHIFT */
|
/* NORMAL */ /* SHIFT */ /* CTRL */ /* CTRL-SHIFT */
|
||||||
/* Unmodified and Alt-modified keypad keys comply with linux console
|
/* Unmodified and Alt-modified keypad keys comply with linux console
|
||||||
SHIFT, CTRL, CTRL-SHIFT modifiers comply with xterm modifier usage */
|
SHIFT, CTRL, CTRL-SHIFT modifiers comply with xterm modifier usage */
|
||||||
@ -2366,7 +2366,7 @@ fhandler_console::create_invisible_console (HWINSTA horig)
|
|||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ugly workaround for Windows 7.
|
/* Ugly workaround for Windows 7 and later.
|
||||||
|
|
||||||
First try to just attach to any console which may have started this
|
First try to just attach to any console which may have started this
|
||||||
app. If that works use this as our "invisible console".
|
app. If that works use this as our "invisible console".
|
||||||
|
@ -68,7 +68,7 @@ fhandler_dev::close ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
int __reg2
|
int __reg2
|
||||||
fhandler_dev::fstat (struct __stat64 *st)
|
fhandler_dev::fstat (struct stat *st)
|
||||||
{
|
{
|
||||||
/* If /dev really exists on disk, return correct disk information. */
|
/* If /dev really exists on disk, return correct disk information. */
|
||||||
if (pc.fs_got_fs ())
|
if (pc.fs_got_fs ())
|
||||||
|
@ -44,11 +44,11 @@ class __DIR_mounts
|
|||||||
#define __DIR_CYGDRIVE (MAX_MOUNTS+1)
|
#define __DIR_CYGDRIVE (MAX_MOUNTS+1)
|
||||||
#define __DIR_DEV (MAX_MOUNTS+2)
|
#define __DIR_DEV (MAX_MOUNTS+2)
|
||||||
|
|
||||||
__ino64_t eval_ino (int idx)
|
ino_t eval_ino (int idx)
|
||||||
{
|
{
|
||||||
__ino64_t ino = 0;
|
ino_t ino = 0;
|
||||||
char fname[parent_dir_len + mounts[idx].Length + 2];
|
char fname[parent_dir_len + mounts[idx].Length + 2];
|
||||||
struct __stat64 st;
|
struct stat st;
|
||||||
|
|
||||||
char *c = stpcpy (fname, parent_dir);
|
char *c = stpcpy (fname, parent_dir);
|
||||||
if (c[- 1] != '/')
|
if (c[- 1] != '/')
|
||||||
@ -76,7 +76,7 @@ public:
|
|||||||
RtlFreeUnicodeString (&mounts[i]);
|
RtlFreeUnicodeString (&mounts[i]);
|
||||||
RtlFreeUnicodeString (&cygdrive);
|
RtlFreeUnicodeString (&cygdrive);
|
||||||
}
|
}
|
||||||
__ino64_t check_mount (PUNICODE_STRING fname, __ino64_t ino,
|
ino_t check_mount (PUNICODE_STRING fname, ino_t ino,
|
||||||
bool eval = true)
|
bool eval = true)
|
||||||
{
|
{
|
||||||
if (parent_dir_len == 1) /* root dir */
|
if (parent_dir_len == 1) /* root dir */
|
||||||
@ -106,7 +106,7 @@ public:
|
|||||||
}
|
}
|
||||||
return ino;
|
return ino;
|
||||||
}
|
}
|
||||||
__ino64_t check_missing_mount (PUNICODE_STRING retname = NULL)
|
ino_t check_missing_mount (PUNICODE_STRING retname = NULL)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < count; ++i)
|
for (int i = 0; i < count; ++i)
|
||||||
if (!found[i])
|
if (!found[i])
|
||||||
@ -152,7 +152,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
path_conv::isgood_inode (__ino64_t ino) const
|
path_conv::isgood_inode (ino_t ino) const
|
||||||
{
|
{
|
||||||
/* If the FS doesn't support nonambiguous inode numbers anyway, bail out
|
/* If the FS doesn't support nonambiguous inode numbers anyway, bail out
|
||||||
immediately. */
|
immediately. */
|
||||||
@ -220,7 +220,7 @@ readdir_check_reparse_point (POBJECT_ATTRIBUTES attr)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline __ino64_t
|
inline ino_t
|
||||||
path_conv::get_ino_by_handle (HANDLE hdl)
|
path_conv::get_ino_by_handle (HANDLE hdl)
|
||||||
{
|
{
|
||||||
IO_STATUS_BLOCK io;
|
IO_STATUS_BLOCK io;
|
||||||
@ -256,7 +256,7 @@ path_conv::ndisk_links (DWORD nNumberOfLinks)
|
|||||||
|
|
||||||
unsigned count = 0;
|
unsigned count = 0;
|
||||||
bool first = true;
|
bool first = true;
|
||||||
PFILE_BOTH_DIRECTORY_INFORMATION fdibuf = (PFILE_BOTH_DIRECTORY_INFORMATION)
|
PFILE_BOTH_DIR_INFORMATION fdibuf = (PFILE_BOTH_DIR_INFORMATION)
|
||||||
alloca (65536);
|
alloca (65536);
|
||||||
__DIR_mounts *dir = new __DIR_mounts (normalized_path);
|
__DIR_mounts *dir = new __DIR_mounts (normalized_path);
|
||||||
while (NT_SUCCESS (NtQueryDirectoryFile (fh, NULL, NULL, NULL, &io, fdibuf,
|
while (NT_SUCCESS (NtQueryDirectoryFile (fh, NULL, NULL, NULL, &io, fdibuf,
|
||||||
@ -272,9 +272,9 @@ path_conv::ndisk_links (DWORD nNumberOfLinks)
|
|||||||
if (fdibuf->FileNameLength != 2 || fdibuf->FileName[0] != L'.')
|
if (fdibuf->FileNameLength != 2 || fdibuf->FileName[0] != L'.')
|
||||||
count = 2;
|
count = 2;
|
||||||
}
|
}
|
||||||
for (PFILE_BOTH_DIRECTORY_INFORMATION pfdi = fdibuf;
|
for (PFILE_BOTH_DIR_INFORMATION pfdi = fdibuf;
|
||||||
pfdi;
|
pfdi;
|
||||||
pfdi = (PFILE_BOTH_DIRECTORY_INFORMATION)
|
pfdi = (PFILE_BOTH_DIR_INFORMATION)
|
||||||
(pfdi->NextEntryOffset ? (PBYTE) pfdi + pfdi->NextEntryOffset
|
(pfdi->NextEntryOffset ? (PBYTE) pfdi + pfdi->NextEntryOffset
|
||||||
: NULL))
|
: NULL))
|
||||||
{
|
{
|
||||||
@ -320,7 +320,7 @@ path_conv::ndisk_links (DWORD nNumberOfLinks)
|
|||||||
The content is the NFS equivalent of struct stat. so there's not much
|
The content is the NFS equivalent of struct stat. so there's not much
|
||||||
to do here except for copying. */
|
to do here except for copying. */
|
||||||
int __stdcall
|
int __stdcall
|
||||||
fhandler_base::fstat_by_nfs_ea (struct __stat64 *buf)
|
fhandler_base::fstat_by_nfs_ea (struct stat *buf)
|
||||||
{
|
{
|
||||||
fattr3 *nfs_attr = pc.nfsattr ();
|
fattr3 *nfs_attr = pc.nfsattr ();
|
||||||
|
|
||||||
@ -353,14 +353,17 @@ fhandler_base::fstat_by_nfs_ea (struct __stat64 *buf)
|
|||||||
buf->st_size = nfs_attr->size;
|
buf->st_size = nfs_attr->size;
|
||||||
buf->st_blksize = PREFERRED_IO_BLKSIZE;
|
buf->st_blksize = PREFERRED_IO_BLKSIZE;
|
||||||
buf->st_blocks = (nfs_attr->used + S_BLKSIZE - 1) / S_BLKSIZE;
|
buf->st_blocks = (nfs_attr->used + S_BLKSIZE - 1) / S_BLKSIZE;
|
||||||
buf->st_atim = nfs_attr->atime;
|
buf->st_atim.tv_sec = nfs_attr->atime.tv_sec;
|
||||||
buf->st_mtim = nfs_attr->mtime;
|
buf->st_atim.tv_nsec = nfs_attr->atime.tv_nsec;
|
||||||
buf->st_ctim = nfs_attr->ctime;
|
buf->st_mtim.tv_sec = nfs_attr->mtime.tv_sec;
|
||||||
|
buf->st_mtim.tv_nsec = nfs_attr->mtime.tv_nsec;
|
||||||
|
buf->st_ctim.tv_sec = nfs_attr->ctime.tv_sec;
|
||||||
|
buf->st_ctim.tv_nsec = nfs_attr->ctime.tv_nsec;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int __stdcall
|
int __stdcall
|
||||||
fhandler_base::fstat_by_handle (struct __stat64 *buf)
|
fhandler_base::fstat_by_handle (struct stat *buf)
|
||||||
{
|
{
|
||||||
/* Don't use FileAllInformation info class. It returns a pathname rather
|
/* Don't use FileAllInformation info class. It returns a pathname rather
|
||||||
than a filename, so it needs a really big buffer for no good reason
|
than a filename, so it needs a really big buffer for no good reason
|
||||||
@ -380,7 +383,7 @@ fhandler_base::fstat_by_handle (struct __stat64 *buf)
|
|||||||
status = file_get_fnoi (h, pc.fs_is_netapp (), pc.fnoi ());
|
status = file_get_fnoi (h, pc.fs_is_netapp (), pc.fnoi ());
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
debug_printf ("%p = NtQueryInformationFile(%S, "
|
debug_printf ("%y = NtQueryInformationFile(%S, "
|
||||||
"FileNetworkOpenInformation)",
|
"FileNetworkOpenInformation)",
|
||||||
status, pc.get_nt_native_path ());
|
status, pc.get_nt_native_path ());
|
||||||
return -1;
|
return -1;
|
||||||
@ -394,7 +397,7 @@ fhandler_base::fstat_by_handle (struct __stat64 *buf)
|
|||||||
FileStandardInformation);
|
FileStandardInformation);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
debug_printf ("%p = NtQueryInformationFile(%S, "
|
debug_printf ("%y = NtQueryInformationFile(%S, "
|
||||||
"FileStandardInformation)",
|
"FileStandardInformation)",
|
||||||
status, pc.get_nt_native_path ());
|
status, pc.get_nt_native_path ());
|
||||||
return -1;
|
return -1;
|
||||||
@ -405,7 +408,7 @@ fhandler_base::fstat_by_handle (struct __stat64 *buf)
|
|||||||
FileInternalInformation);
|
FileInternalInformation);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
debug_printf ("%p = NtQueryInformationFile(%S, "
|
debug_printf ("%y = NtQueryInformationFile(%S, "
|
||||||
"FileInternalInformation)",
|
"FileInternalInformation)",
|
||||||
status, pc.get_nt_native_path ());
|
status, pc.get_nt_native_path ());
|
||||||
return -1;
|
return -1;
|
||||||
@ -418,7 +421,7 @@ fhandler_base::fstat_by_handle (struct __stat64 *buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int __stdcall
|
int __stdcall
|
||||||
fhandler_base::fstat_by_name (struct __stat64 *buf)
|
fhandler_base::fstat_by_name (struct stat *buf)
|
||||||
{
|
{
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
OBJECT_ATTRIBUTES attr;
|
OBJECT_ATTRIBUTES attr;
|
||||||
@ -442,7 +445,7 @@ fhandler_base::fstat_by_name (struct __stat64 *buf)
|
|||||||
| FILE_OPEN_FOR_BACKUP_INTENT
|
| FILE_OPEN_FOR_BACKUP_INTENT
|
||||||
| FILE_DIRECTORY_FILE);
|
| FILE_DIRECTORY_FILE);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
debug_printf ("%p = NtOpenFile(%S)", status,
|
debug_printf ("%y = NtOpenFile(%S)", status,
|
||||||
pc.get_nt_native_path ());
|
pc.get_nt_native_path ());
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -452,7 +455,7 @@ fhandler_base::fstat_by_name (struct __stat64 *buf)
|
|||||||
TRUE, &basename, TRUE);
|
TRUE, &basename, TRUE);
|
||||||
NtClose (dir);
|
NtClose (dir);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
debug_printf ("%p = NtQueryDirectoryFile(%S)", status,
|
debug_printf ("%y = NtQueryDirectoryFile(%S)", status,
|
||||||
pc.get_nt_native_path ());
|
pc.get_nt_native_path ());
|
||||||
else
|
else
|
||||||
ino = fdi_buf.fdi.FileId.QuadPart;
|
ino = fdi_buf.fdi.FileId.QuadPart;
|
||||||
@ -462,7 +465,7 @@ fhandler_base::fstat_by_name (struct __stat64 *buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int __stdcall
|
int __stdcall
|
||||||
fhandler_base::fstat_fs (struct __stat64 *buf)
|
fhandler_base::fstat_fs (struct stat *buf)
|
||||||
{
|
{
|
||||||
int res = -1;
|
int res = -1;
|
||||||
int oret;
|
int oret;
|
||||||
@ -506,7 +509,7 @@ fhandler_base::fstat_fs (struct __stat64 *buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int __stdcall
|
int __stdcall
|
||||||
fhandler_base::fstat_helper (struct __stat64 *buf,
|
fhandler_base::fstat_helper (struct stat *buf,
|
||||||
DWORD nNumberOfLinks)
|
DWORD nNumberOfLinks)
|
||||||
{
|
{
|
||||||
IO_STATUS_BLOCK st;
|
IO_STATUS_BLOCK st;
|
||||||
@ -531,7 +534,7 @@ fhandler_base::fstat_helper (struct __stat64 *buf,
|
|||||||
0 in the first call and size > 0 in the second call. This in turn can
|
0 in the first call and size > 0 in the second call. This in turn can
|
||||||
affect applications like newer tar.
|
affect applications like newer tar.
|
||||||
FIXME: Is the allocation size affected as well? */
|
FIXME: Is the allocation size affected as well? */
|
||||||
buf->st_size = pc.isdir () ? 0 : (_off64_t) pfnoi->EndOfFile.QuadPart;
|
buf->st_size = pc.isdir () ? 0 : (off_t) pfnoi->EndOfFile.QuadPart;
|
||||||
/* The number of links to a directory includes the number of subdirectories
|
/* The number of links to a directory includes the number of subdirectories
|
||||||
in the directory, since all those subdirectories point to it. However,
|
in the directory, since all those subdirectories point to it. However,
|
||||||
this is painfully slow, so we do without it. */
|
this is painfully slow, so we do without it. */
|
||||||
@ -543,7 +546,7 @@ fhandler_base::fstat_helper (struct __stat64 *buf,
|
|||||||
|
|
||||||
/* Enforce namehash as inode number on untrusted file systems. */
|
/* Enforce namehash as inode number on untrusted file systems. */
|
||||||
if (ino && pc.isgood_inode (ino))
|
if (ino && pc.isgood_inode (ino))
|
||||||
buf->st_ino = (__ino64_t) ino;
|
buf->st_ino = (ino_t) ino;
|
||||||
else
|
else
|
||||||
buf->st_ino = get_ino ();
|
buf->st_ino = get_ino ();
|
||||||
|
|
||||||
@ -651,7 +654,7 @@ fhandler_base::fstat_helper (struct __stat64 *buf,
|
|||||||
FILE_OPEN_FOR_BACKUP_INTENT
|
FILE_OPEN_FOR_BACKUP_INTENT
|
||||||
| FILE_SYNCHRONOUS_IO_NONALERT);
|
| FILE_SYNCHRONOUS_IO_NONALERT);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
debug_printf ("%p = NtOpenFile(%S)", status,
|
debug_printf ("%y = NtOpenFile(%S)", status,
|
||||||
pc.get_nt_native_path ());
|
pc.get_nt_native_path ());
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -661,7 +664,7 @@ fhandler_base::fstat_helper (struct __stat64 *buf,
|
|||||||
status = NtReadFile (h, NULL, NULL, NULL,
|
status = NtReadFile (h, NULL, NULL, NULL,
|
||||||
&io, magic, 3, &off, NULL);
|
&io, magic, 3, &off, NULL);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
debug_printf ("%p = NtReadFile(%S)", status,
|
debug_printf ("%y = NtReadFile(%S)", status,
|
||||||
pc.get_nt_native_path ());
|
pc.get_nt_native_path ());
|
||||||
else if (has_exec_chars (magic, io.Information))
|
else if (has_exec_chars (magic, io.Information))
|
||||||
{
|
{
|
||||||
@ -687,9 +690,9 @@ fhandler_base::fstat_helper (struct __stat64 *buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
syscall_printf ("0 = fstat (%S, %p) st_size=%D, st_mode=%p, st_ino=%D"
|
syscall_printf ("0 = fstat (%S, %p) st_size=%D, st_mode=%y, st_ino=%D"
|
||||||
"st_atim=%x.%x st_ctim=%x.%x "
|
"st_atim=%lx.%lx st_ctim=%lx.%lx "
|
||||||
"st_mtim=%x.%x st_birthtim=%x.%x",
|
"st_mtim=%lx.%lx st_birthtim=%lx.%lx",
|
||||||
pc.get_nt_native_path (), buf,
|
pc.get_nt_native_path (), buf,
|
||||||
buf->st_size, buf->st_mode, buf->st_ino,
|
buf->st_size, buf->st_mode, buf->st_ino,
|
||||||
buf->st_atim.tv_sec, buf->st_atim.tv_nsec,
|
buf->st_atim.tv_sec, buf->st_atim.tv_nsec,
|
||||||
@ -700,7 +703,7 @@ fhandler_base::fstat_helper (struct __stat64 *buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int __reg2
|
int __reg2
|
||||||
fhandler_disk_file::fstat (struct __stat64 *buf)
|
fhandler_disk_file::fstat (struct stat *buf)
|
||||||
{
|
{
|
||||||
return fstat_fs (buf);
|
return fstat_fs (buf);
|
||||||
}
|
}
|
||||||
@ -712,7 +715,6 @@ fhandler_disk_file::fstatvfs (struct statvfs *sfs)
|
|||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
IO_STATUS_BLOCK io;
|
IO_STATUS_BLOCK io;
|
||||||
FILE_FS_FULL_SIZE_INFORMATION full_fsi;
|
FILE_FS_FULL_SIZE_INFORMATION full_fsi;
|
||||||
FILE_FS_SIZE_INFORMATION fsi;
|
|
||||||
/* We must not use the stat handle here, even if it exists. The handle
|
/* We must not use the stat handle here, even if it exists. The handle
|
||||||
has been opened with FILE_OPEN_REPARSE_POINT, thus, in case of a volume
|
has been opened with FILE_OPEN_REPARSE_POINT, thus, in case of a volume
|
||||||
mount point, it points to the FS of the mount point, rather than to the
|
mount point, it points to the FS of the mount point, rather than to the
|
||||||
@ -746,18 +748,18 @@ fhandler_disk_file::fstatvfs (struct statvfs *sfs)
|
|||||||
sfs->f_fsid = pc.fs_serial_number ();
|
sfs->f_fsid = pc.fs_serial_number ();
|
||||||
sfs->f_flag = pc.fs_flags ();
|
sfs->f_flag = pc.fs_flags ();
|
||||||
sfs->f_namemax = pc.fs_name_len ();
|
sfs->f_namemax = pc.fs_name_len ();
|
||||||
/* Get allocation related information. Try to get "full" information
|
/* Get allocation related information. */
|
||||||
first, which is only available since W2K. If that fails, try to
|
|
||||||
retrieve normal allocation information. */
|
|
||||||
status = NtQueryVolumeInformationFile (fh, &io, &full_fsi, sizeof full_fsi,
|
status = NtQueryVolumeInformationFile (fh, &io, &full_fsi, sizeof full_fsi,
|
||||||
FileFsFullSizeInformation);
|
FileFsFullSizeInformation);
|
||||||
if (NT_SUCCESS (status))
|
if (NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
sfs->f_bsize = full_fsi.BytesPerSector * full_fsi.SectorsPerAllocationUnit;
|
sfs->f_bsize = full_fsi.BytesPerSector * full_fsi.SectorsPerAllocationUnit;
|
||||||
sfs->f_frsize = sfs->f_bsize;
|
sfs->f_frsize = sfs->f_bsize;
|
||||||
sfs->f_blocks = full_fsi.TotalAllocationUnits.LowPart;
|
sfs->f_blocks = (fsblkcnt_t) full_fsi.TotalAllocationUnits.QuadPart;
|
||||||
sfs->f_bfree = full_fsi.ActualAvailableAllocationUnits.LowPart;
|
sfs->f_bfree = (fsblkcnt_t)
|
||||||
sfs->f_bavail = full_fsi.CallerAvailableAllocationUnits.LowPart;
|
full_fsi.ActualAvailableAllocationUnits.QuadPart;
|
||||||
|
sfs->f_bavail = (fsblkcnt_t)
|
||||||
|
full_fsi.CallerAvailableAllocationUnits.QuadPart;
|
||||||
if (sfs->f_bfree > sfs->f_bavail)
|
if (sfs->f_bfree > sfs->f_bavail)
|
||||||
{
|
{
|
||||||
/* Quotas active. We can't trust TotalAllocationUnits. */
|
/* Quotas active. We can't trust TotalAllocationUnits. */
|
||||||
@ -767,29 +769,13 @@ fhandler_disk_file::fstatvfs (struct statvfs *sfs)
|
|||||||
FSCTL_GET_NTFS_VOLUME_DATA,
|
FSCTL_GET_NTFS_VOLUME_DATA,
|
||||||
NULL, 0, &nvdb, sizeof nvdb);
|
NULL, 0, &nvdb, sizeof nvdb);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
debug_printf ("%p = NtFsControlFile(%S, FSCTL_GET_NTFS_VOLUME_DATA)",
|
debug_printf ("%y = NtFsControlFile(%S, FSCTL_GET_NTFS_VOLUME_DATA)",
|
||||||
status, pc.get_nt_native_path ());
|
status, pc.get_nt_native_path ());
|
||||||
else
|
else
|
||||||
sfs->f_blocks = nvdb.TotalClusters.QuadPart;
|
sfs->f_blocks = (fsblkcnt_t) nvdb.TotalClusters.QuadPart;
|
||||||
}
|
}
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
status = NtQueryVolumeInformationFile (fh, &io, &fsi, sizeof fsi,
|
|
||||||
FileFsSizeInformation);
|
|
||||||
if (!NT_SUCCESS (status))
|
|
||||||
{
|
|
||||||
__seterrno_from_nt_status (status);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
sfs->f_bsize = fsi.BytesPerSector * fsi.SectorsPerAllocationUnit;
|
|
||||||
sfs->f_frsize = sfs->f_bsize;
|
|
||||||
sfs->f_blocks = fsi.TotalAllocationUnits.LowPart;
|
|
||||||
sfs->f_bfree = fsi.AvailableAllocationUnits.LowPart;
|
|
||||||
sfs->f_bavail = sfs->f_bfree;
|
|
||||||
ret = 0;
|
|
||||||
}
|
|
||||||
out:
|
out:
|
||||||
if (opened)
|
if (opened)
|
||||||
NtClose (fh);
|
NtClose (fh);
|
||||||
@ -906,7 +892,7 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int __stdcall
|
int __stdcall
|
||||||
fhandler_disk_file::fchown (__uid32_t uid, __gid32_t gid)
|
fhandler_disk_file::fchown (uid_t uid, gid_t gid)
|
||||||
{
|
{
|
||||||
int oret = 0;
|
int oret = 0;
|
||||||
|
|
||||||
@ -928,7 +914,7 @@ fhandler_disk_file::fchown (__uid32_t uid, __gid32_t gid)
|
|||||||
mode_t attrib = 0;
|
mode_t attrib = 0;
|
||||||
if (pc.isdir ())
|
if (pc.isdir ())
|
||||||
attrib |= S_IFDIR;
|
attrib |= S_IFDIR;
|
||||||
__uid32_t old_uid;
|
uid_t old_uid;
|
||||||
int res = get_file_attribute (get_handle (), pc, &attrib, &old_uid, NULL);
|
int res = get_file_attribute (get_handle (), pc, &attrib, &old_uid, NULL);
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
@ -974,7 +960,7 @@ fhandler_disk_file::fchown (__uid32_t uid, __gid32_t gid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall
|
int _stdcall
|
||||||
fhandler_disk_file::facl (int cmd, int nentries, __aclent32_t *aclbufp)
|
fhandler_disk_file::facl (int cmd, int nentries, aclent_t *aclbufp)
|
||||||
{
|
{
|
||||||
int res = -1;
|
int res = -1;
|
||||||
int oret = 0;
|
int oret = 0;
|
||||||
@ -999,7 +985,7 @@ cant_access_acl:
|
|||||||
set_errno (ENOSPC);
|
set_errno (ENOSPC);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
struct __stat64 st;
|
struct stat st;
|
||||||
if (!fstat (&st))
|
if (!fstat (&st))
|
||||||
{
|
{
|
||||||
aclbufp[0].a_type = USER_OBJ;
|
aclbufp[0].a_type = USER_OBJ;
|
||||||
@ -1113,7 +1099,7 @@ fhandler_disk_file::fsetxattr (const char *name, const void *value, size_t size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_disk_file::fadvise (_off64_t offset, _off64_t length, int advice)
|
fhandler_disk_file::fadvise (off_t offset, off_t length, int advice)
|
||||||
{
|
{
|
||||||
if (advice < POSIX_FADV_NORMAL || advice > POSIX_FADV_NOREUSE)
|
if (advice < POSIX_FADV_NORMAL || advice > POSIX_FADV_NOREUSE)
|
||||||
{
|
{
|
||||||
@ -1156,7 +1142,7 @@ fhandler_disk_file::fadvise (_off64_t offset, _off64_t length, int advice)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_disk_file::ftruncate (_off64_t length, bool allow_truncate)
|
fhandler_disk_file::ftruncate (off_t length, bool allow_truncate)
|
||||||
{
|
{
|
||||||
int res = -1;
|
int res = -1;
|
||||||
|
|
||||||
@ -1197,8 +1183,8 @@ fhandler_disk_file::ftruncate (_off64_t length, bool allow_truncate)
|
|||||||
FSCTL_SET_SPARSE, NULL, 0, NULL, 0);
|
FSCTL_SET_SPARSE, NULL, 0, NULL, 0);
|
||||||
if (NT_SUCCESS (status))
|
if (NT_SUCCESS (status))
|
||||||
pc.file_attributes (pc.file_attributes ()
|
pc.file_attributes (pc.file_attributes ()
|
||||||
| FILE_ATTRIBUTE_SPARSE_FILE);
|
| FILE_ATTRIBUTE_SPARSE_FILE);
|
||||||
syscall_printf ("%p = NtFsControlFile(%S, FSCTL_SET_SPARSE)",
|
syscall_printf ("%y = NtFsControlFile(%S, FSCTL_SET_SPARSE)",
|
||||||
status, pc.get_nt_native_path ());
|
status, pc.get_nt_native_path ());
|
||||||
}
|
}
|
||||||
status = NtSetInformationFile (get_handle (), &io,
|
status = NtSetInformationFile (get_handle (), &io,
|
||||||
@ -1350,7 +1336,7 @@ fhandler_base::utimens_fs (const struct timespec *tvp)
|
|||||||
tmp[0] = (tvp[0].tv_nsec == UTIME_NOW) ? timeofday : tvp[0];
|
tmp[0] = (tvp[0].tv_nsec == UTIME_NOW) ? timeofday : tvp[0];
|
||||||
tmp[1] = (tvp[1].tv_nsec == UTIME_NOW) ? timeofday : tvp[1];
|
tmp[1] = (tvp[1].tv_nsec == UTIME_NOW) ? timeofday : tvp[1];
|
||||||
}
|
}
|
||||||
debug_printf ("incoming lastaccess %08x %08x", tmp[0].tv_sec, tmp[0].tv_nsec);
|
debug_printf ("incoming lastaccess %ly %ly", tmp[0].tv_sec, tmp[0].tv_nsec);
|
||||||
|
|
||||||
IO_STATUS_BLOCK io;
|
IO_STATUS_BLOCK io;
|
||||||
FILE_BASIC_INFORMATION fbi;
|
FILE_BASIC_INFORMATION fbi;
|
||||||
@ -1477,7 +1463,7 @@ fhandler_base::open_fs (int flags, mode_t mode)
|
|||||||
NtAllocateLocallyUniqueId ((PLUID) &unique_id);
|
NtAllocateLocallyUniqueId ((PLUID) &unique_id);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
syscall_printf ("%d = fhandler_disk_file::open(%S, %p)", res,
|
syscall_printf ("%d = fhandler_disk_file::open(%S, %y)", res,
|
||||||
pc.get_nt_native_path (), flags);
|
pc.get_nt_native_path (), flags);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -1538,7 +1524,7 @@ fhandler_disk_file::prw_open (bool write)
|
|||||||
status = NtOpenFile (&prw_handle, access, &attr, &io,
|
status = NtOpenFile (&prw_handle, access, &attr, &io,
|
||||||
FILE_SHARE_VALID_FLAGS, get_options ());
|
FILE_SHARE_VALID_FLAGS, get_options ());
|
||||||
}
|
}
|
||||||
debug_printf ("%x = NtOpenFile (%p, %x, %S, io, %x, %x)",
|
debug_printf ("%y = NtOpenFile (%p, %y, %S, io, %y, %y)",
|
||||||
status, prw_handle, access, pc.get_nt_native_path (),
|
status, prw_handle, access, pc.get_nt_native_path (),
|
||||||
FILE_SHARE_VALID_FLAGS, get_options ());
|
FILE_SHARE_VALID_FLAGS, get_options ());
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
@ -1550,8 +1536,10 @@ fhandler_disk_file::prw_open (bool write)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ssize_t __stdcall
|
ssize_t __stdcall
|
||||||
fhandler_disk_file::pread (void *buf, size_t count, _off64_t offset)
|
fhandler_disk_file::pread (void *buf, size_t count, off_t offset)
|
||||||
{
|
{
|
||||||
|
ssize_t res;
|
||||||
|
|
||||||
if ((get_flags () & O_ACCMODE) == O_WRONLY)
|
if ((get_flags () & O_ACCMODE) == O_WRONLY)
|
||||||
{
|
{
|
||||||
set_errno (EBADF);
|
set_errno (EBADF);
|
||||||
@ -1570,7 +1558,7 @@ fhandler_disk_file::pread (void *buf, size_t count, _off64_t offset)
|
|||||||
goto non_atomic;
|
goto non_atomic;
|
||||||
status = NtReadFile (prw_handle, NULL, NULL, NULL, &io, buf, count,
|
status = NtReadFile (prw_handle, NULL, NULL, NULL, &io, buf, count,
|
||||||
&off, NULL);
|
&off, NULL);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status) && status != STATUS_END_OF_FILE)
|
||||||
{
|
{
|
||||||
if (pc.isdir ())
|
if (pc.isdir ())
|
||||||
{
|
{
|
||||||
@ -1598,29 +1586,31 @@ fhandler_disk_file::pread (void *buf, size_t count, _off64_t offset)
|
|||||||
__seterrno_from_nt_status (status);
|
__seterrno_from_nt_status (status);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
res = io.Information; /* Valid on EOF. */
|
||||||
}
|
}
|
||||||
|
|
||||||
non_atomic:
|
|
||||||
/* Text mode stays slow and non-atomic. */
|
|
||||||
ssize_t res;
|
|
||||||
_off64_t curpos = lseek (0, SEEK_CUR);
|
|
||||||
if (curpos < 0 || lseek (offset, SEEK_SET) < 0)
|
|
||||||
res = -1;
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
size_t tmp_count = count;
|
non_atomic:
|
||||||
read (buf, tmp_count);
|
/* Text mode stays slow and non-atomic. */
|
||||||
if (lseek (curpos, SEEK_SET) >= 0)
|
off_t curpos = lseek (0, SEEK_CUR);
|
||||||
res = (ssize_t) tmp_count;
|
if (curpos < 0 || lseek (offset, SEEK_SET) < 0)
|
||||||
else
|
|
||||||
res = -1;
|
res = -1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size_t tmp_count = count;
|
||||||
|
read (buf, tmp_count);
|
||||||
|
if (lseek (curpos, SEEK_SET) >= 0)
|
||||||
|
res = (ssize_t) tmp_count;
|
||||||
|
else
|
||||||
|
res = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
debug_printf ("%d = pread(%p, %d, %d)\n", res, buf, count, offset);
|
debug_printf ("%d = pread(%p, %ld, %D)\n", res, buf, count, offset);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t __stdcall
|
ssize_t __stdcall
|
||||||
fhandler_disk_file::pwrite (void *buf, size_t count, _off64_t offset)
|
fhandler_disk_file::pwrite (void *buf, size_t count, off_t offset)
|
||||||
{
|
{
|
||||||
if ((get_flags () & O_ACCMODE) == O_RDONLY)
|
if ((get_flags () & O_ACCMODE) == O_RDONLY)
|
||||||
{
|
{
|
||||||
@ -1650,7 +1640,7 @@ fhandler_disk_file::pwrite (void *buf, size_t count, _off64_t offset)
|
|||||||
non_atomic:
|
non_atomic:
|
||||||
/* Text mode stays slow and non-atomic. */
|
/* Text mode stays slow and non-atomic. */
|
||||||
int res;
|
int res;
|
||||||
_off64_t curpos = lseek (0, SEEK_CUR);
|
off_t curpos = lseek (0, SEEK_CUR);
|
||||||
if (curpos < 0 || lseek (offset, SEEK_SET) < 0)
|
if (curpos < 0 || lseek (offset, SEEK_SET) < 0)
|
||||||
res = curpos;
|
res = curpos;
|
||||||
else
|
else
|
||||||
@ -1659,7 +1649,7 @@ non_atomic:
|
|||||||
if (lseek (curpos, SEEK_SET) < 0)
|
if (lseek (curpos, SEEK_SET) < 0)
|
||||||
res = -1;
|
res = -1;
|
||||||
}
|
}
|
||||||
debug_printf ("%d = pwrite(%p, %d, %d)\n", res, buf, count, offset);
|
debug_printf ("%d = pwrite(%p, %ld, %D)\n", res, buf, count, offset);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1784,7 +1774,7 @@ fhandler_disk_file::rmdir ()
|
|||||||
|
|
||||||
struct __DIR_cache
|
struct __DIR_cache
|
||||||
{
|
{
|
||||||
char __cache[DIR_BUF_SIZE]; /* W2K needs this buffer 8 byte aligned. */
|
char __cache[DIR_BUF_SIZE];
|
||||||
ULONG __pos;
|
ULONG __pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1827,7 +1817,7 @@ fhandler_disk_file::opendir (int fd)
|
|||||||
dir->__d_position = 0;
|
dir->__d_position = 0;
|
||||||
dir->__flags = (get_name ()[0] == '/' && get_name ()[1] == '\0')
|
dir->__flags = (get_name ()[0] == '/' && get_name ()[1] == '\0')
|
||||||
? dirent_isroot : 0;
|
? dirent_isroot : 0;
|
||||||
dir->__d_internal = (unsigned) new __DIR_mounts (get_name ());
|
dir->__d_internal = (uintptr_t) new __DIR_mounts (get_name ());
|
||||||
d_cachepos (dir) = 0;
|
d_cachepos (dir) = 0;
|
||||||
|
|
||||||
if (!pc.iscygdrive ())
|
if (!pc.iscygdrive ())
|
||||||
@ -1880,10 +1870,9 @@ fhandler_disk_file::opendir (int fd)
|
|||||||
XP when accessing directories on UDF. When trying to use it
|
XP when accessing directories on UDF. When trying to use it
|
||||||
so, NtQueryDirectoryFile returns with STATUS_ACCESS_VIOLATION.
|
so, NtQueryDirectoryFile returns with STATUS_ACCESS_VIOLATION.
|
||||||
It's not clear if the call isn't also unsupported on other
|
It's not clear if the call isn't also unsupported on other
|
||||||
OS/FS combinations (say, Win2K/CDFS or so). Instead of
|
OS/FS combinations. Instead of testing for yet another error
|
||||||
testing in readdir for yet another error code, let's use
|
code, let's use FileIdBothDirectoryInformation only on FSes
|
||||||
FileIdBothDirectoryInformation only on filesystems supporting
|
supporting persistent ACLs, FileBothDirectoryInformation otherwise.
|
||||||
persistent ACLs, FileBothDirectoryInformation otherwise.
|
|
||||||
|
|
||||||
NFS clients hide dangling symlinks from directory queries,
|
NFS clients hide dangling symlinks from directory queries,
|
||||||
unless you use the FileNamesInformation info class.
|
unless you use the FileNamesInformation info class.
|
||||||
@ -1935,15 +1924,15 @@ free_dir:
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
__ino64_t __stdcall
|
ino_t __stdcall
|
||||||
readdir_get_ino (const char *path, bool dot_dot)
|
readdir_get_ino (const char *path, bool dot_dot)
|
||||||
{
|
{
|
||||||
char *fname;
|
char *fname;
|
||||||
struct __stat64 st;
|
struct stat st;
|
||||||
HANDLE hdl;
|
HANDLE hdl;
|
||||||
OBJECT_ATTRIBUTES attr;
|
OBJECT_ATTRIBUTES attr;
|
||||||
IO_STATUS_BLOCK io;
|
IO_STATUS_BLOCK io;
|
||||||
__ino64_t ino = 0;
|
ino_t ino = 0;
|
||||||
|
|
||||||
if (dot_dot)
|
if (dot_dot)
|
||||||
{
|
{
|
||||||
@ -2118,11 +2107,10 @@ fhandler_disk_file::readdir (DIR *dir, dirent *de)
|
|||||||
FileIdBothDirectoryInformation,
|
FileIdBothDirectoryInformation,
|
||||||
FALSE, NULL, dir->__d_position == 0);
|
FALSE, NULL, dir->__d_position == 0);
|
||||||
/* FileIdBothDirectoryInformation isn't supported for remote drives
|
/* FileIdBothDirectoryInformation isn't supported for remote drives
|
||||||
on NT4 and 2K systems, and it's also not supported on 2K at all,
|
on NT4 and 2K systems. There are also hacked versions of
|
||||||
when accessing network drives on any remote OS. There are also
|
Samba 3.0.x out there (Debian-based it seems), which return
|
||||||
hacked versions of Samba 3.0.x out there (Debian-based it seems),
|
STATUS_NOT_SUPPORTED rather than handling this info class.
|
||||||
which return STATUS_NOT_SUPPORTED rather than handling this info
|
We just fall back to using a standard directory query in
|
||||||
class. We just fall back to using a standard directory query in
|
|
||||||
this case and note this case using the dirent_get_d_ino flag. */
|
this case and note this case using the dirent_get_d_ino flag. */
|
||||||
if (!NT_SUCCESS (status) && status != STATUS_NO_MORE_FILES
|
if (!NT_SUCCESS (status) && status != STATUS_NO_MORE_FILES
|
||||||
&& (status == STATUS_INVALID_LEVEL
|
&& (status == STATUS_INVALID_LEVEL
|
||||||
@ -2193,7 +2181,7 @@ go_ahead:
|
|||||||
if (status == STATUS_NO_MORE_FILES)
|
if (status == STATUS_NO_MORE_FILES)
|
||||||
/*nothing*/;
|
/*nothing*/;
|
||||||
else if (!NT_SUCCESS (status))
|
else if (!NT_SUCCESS (status))
|
||||||
debug_printf ("NtQueryDirectoryFile failed, status %p, win32 error %lu",
|
debug_printf ("NtQueryDirectoryFile failed, status %y, win32 error %u",
|
||||||
status, RtlNtStatusToDosError (status));
|
status, RtlNtStatusToDosError (status));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2217,11 +2205,11 @@ go_ahead:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FileName = ((PFILE_BOTH_DIRECTORY_INFORMATION) buf)->FileName;
|
FileName = ((PFILE_BOTH_DIR_INFORMATION) buf)->FileName;
|
||||||
FileNameLength =
|
FileNameLength =
|
||||||
((PFILE_BOTH_DIRECTORY_INFORMATION) buf)->FileNameLength;
|
((PFILE_BOTH_DIR_INFORMATION) buf)->FileNameLength;
|
||||||
FileAttributes =
|
FileAttributes =
|
||||||
((PFILE_BOTH_DIRECTORY_INFORMATION) buf)->FileAttributes;
|
((PFILE_BOTH_DIR_INFORMATION) buf)->FileAttributes;
|
||||||
}
|
}
|
||||||
RtlInitCountedUnicodeString (&fname, FileName, FileNameLength);
|
RtlInitCountedUnicodeString (&fname, FileName, FileNameLength);
|
||||||
de->d_ino = d_mounts (dir)->check_mount (&fname, de->d_ino);
|
de->d_ino = d_mounts (dir)->check_mount (&fname, de->d_ino);
|
||||||
@ -2319,7 +2307,7 @@ go_ahead:
|
|||||||
res = 0;
|
res = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
syscall_printf ("%d = readdir(%p, %p) (L\"%lS\" > \"%ls\") (attr %p > type %d)",
|
syscall_printf ("%d = readdir(%p, %p) (L\"%lS\" > \"%ls\") (attr %y > type %d)",
|
||||||
res, dir, &de, res ? NULL : &fname, res ? "***" : de->d_name,
|
res, dir, &de, res ? NULL : &fname, res ? "***" : de->d_name,
|
||||||
FileAttributes, de->d_type);
|
FileAttributes, de->d_type);
|
||||||
return res;
|
return res;
|
||||||
@ -2344,32 +2332,6 @@ void
|
|||||||
fhandler_disk_file::rewinddir (DIR *dir)
|
fhandler_disk_file::rewinddir (DIR *dir)
|
||||||
{
|
{
|
||||||
d_cachepos (dir) = 0;
|
d_cachepos (dir) = 0;
|
||||||
if (wincap.has_buggy_restart_scan () && isremote ())
|
|
||||||
{
|
|
||||||
/* This works around a W2K bug. The RestartScan parameter in calls
|
|
||||||
to NtQueryDirectoryFile on remote shares is ignored, thus
|
|
||||||
resulting in not being able to rewind on remote shares. By
|
|
||||||
reopening the directory, we get a fresh new directory pointer. */
|
|
||||||
OBJECT_ATTRIBUTES attr;
|
|
||||||
NTSTATUS status;
|
|
||||||
IO_STATUS_BLOCK io;
|
|
||||||
HANDLE new_dir;
|
|
||||||
|
|
||||||
pc.init_reopen_attr (&attr, get_handle ());
|
|
||||||
status = NtOpenFile (&new_dir, SYNCHRONIZE | FILE_LIST_DIRECTORY,
|
|
||||||
&attr, &io, FILE_SHARE_VALID_FLAGS,
|
|
||||||
FILE_SYNCHRONOUS_IO_NONALERT
|
|
||||||
| FILE_OPEN_FOR_BACKUP_INTENT
|
|
||||||
| FILE_DIRECTORY_FILE);
|
|
||||||
if (!NT_SUCCESS (status))
|
|
||||||
debug_printf ("Unable to reopen dir %s, NT error: %p",
|
|
||||||
get_name (), status);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
NtClose (get_handle ());
|
|
||||||
set_io_handle (new_dir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dir->__d_position = 0;
|
dir->__d_position = 0;
|
||||||
d_mounts (dir)->rewind ();
|
d_mounts (dir)->rewind ();
|
||||||
}
|
}
|
||||||
@ -2422,7 +2384,7 @@ fhandler_cygdrive::set_drives ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_cygdrive::fstat (struct __stat64 *buf)
|
fhandler_cygdrive::fstat (struct stat *buf)
|
||||||
{
|
{
|
||||||
fhandler_base::fstat (buf);
|
fhandler_base::fstat (buf);
|
||||||
buf->st_ino = 2;
|
buf->st_ino = 2;
|
||||||
|
@ -102,8 +102,9 @@ class fhandler_dev_dsp::Audio::queue
|
|||||||
WAVEHDR **storage_;
|
WAVEHDR **storage_;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void CALLBACK waveOut_callback (HWAVEOUT hWave, UINT msg, DWORD instance,
|
static void CALLBACK waveOut_callback (HWAVEOUT hWave, UINT msg,
|
||||||
DWORD param1, DWORD param2);
|
DWORD_PTR instance, DWORD_PTR param1,
|
||||||
|
DWORD_PTR param2);
|
||||||
|
|
||||||
class fhandler_dev_dsp::Audio_out: public Audio
|
class fhandler_dev_dsp::Audio_out: public Audio
|
||||||
{
|
{
|
||||||
@ -135,8 +136,9 @@ class fhandler_dev_dsp::Audio_out: public Audio
|
|||||||
int channels_;
|
int channels_;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void CALLBACK waveIn_callback (HWAVEIN hWave, UINT msg, DWORD instance,
|
static void CALLBACK waveIn_callback (HWAVEIN hWave, UINT msg,
|
||||||
DWORD param1, DWORD param2);
|
DWORD_PTR instance, DWORD_PTR param1,
|
||||||
|
DWORD_PTR param2);
|
||||||
|
|
||||||
class fhandler_dev_dsp::Audio_in: public Audio
|
class fhandler_dev_dsp::Audio_in: public Audio
|
||||||
{
|
{
|
||||||
@ -365,7 +367,7 @@ fhandler_dev_dsp::Audio_out::fork_fixup (HANDLE parent)
|
|||||||
/* Null dev_.
|
/* Null dev_.
|
||||||
It will be necessary to reset the queue, open the device
|
It will be necessary to reset the queue, open the device
|
||||||
and create a lock when writing */
|
and create a lock when writing */
|
||||||
debug_printf ("parent=0x%08x", parent);
|
debug_printf ("parent=%p", parent);
|
||||||
dev_ = NULL;
|
dev_ = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -378,7 +380,7 @@ fhandler_dev_dsp::Audio_out::query (int rate, int bits, int channels)
|
|||||||
|
|
||||||
fillFormat (&format, rate, bits, channels);
|
fillFormat (&format, rate, bits, channels);
|
||||||
rc = waveOutOpen (NULL, WAVE_MAPPER, &format, 0L, 0L, WAVE_FORMAT_QUERY);
|
rc = waveOutOpen (NULL, WAVE_MAPPER, &format, 0L, 0L, WAVE_FORMAT_QUERY);
|
||||||
debug_printf ("%d = waveOutOpen(freq=%d bits=%d channels=%d)", rc, rate, bits, channels);
|
debug_printf ("%u = waveOutOpen(freq=%d bits=%d channels=%d)", rc, rate, bits, channels);
|
||||||
return (rc == MMSYSERR_NOERROR);
|
return (rc == MMSYSERR_NOERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -400,12 +402,12 @@ fhandler_dev_dsp::Audio_out::start ()
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
fillFormat (&format, freq_, bits_, channels_);
|
fillFormat (&format, freq_, bits_, channels_);
|
||||||
rc = waveOutOpen (&dev_, WAVE_MAPPER, &format, (DWORD) waveOut_callback,
|
rc = waveOutOpen (&dev_, WAVE_MAPPER, &format, (DWORD_PTR) waveOut_callback,
|
||||||
(DWORD) this, CALLBACK_FUNCTION);
|
(DWORD_PTR) this, CALLBACK_FUNCTION);
|
||||||
if (rc == MMSYSERR_NOERROR)
|
if (rc == MMSYSERR_NOERROR)
|
||||||
init (bSize);
|
init (bSize);
|
||||||
|
|
||||||
debug_printf ("%d = waveOutOpen(freq=%d bits=%d channels=%d)", rc, freq_, bits_, channels_);
|
debug_printf ("%u = waveOutOpen(freq=%d bits=%d channels=%d)", rc, freq_, bits_, channels_);
|
||||||
|
|
||||||
return (rc == MMSYSERR_NOERROR);
|
return (rc == MMSYSERR_NOERROR);
|
||||||
}
|
}
|
||||||
@ -416,7 +418,7 @@ fhandler_dev_dsp::Audio_out::stop (bool immediately)
|
|||||||
MMRESULT rc;
|
MMRESULT rc;
|
||||||
WAVEHDR *pHdr;
|
WAVEHDR *pHdr;
|
||||||
|
|
||||||
debug_printf ("dev_=%08x", (int)dev_);
|
debug_printf ("dev_=%p", dev_);
|
||||||
if (dev_)
|
if (dev_)
|
||||||
{
|
{
|
||||||
if (!immediately)
|
if (!immediately)
|
||||||
@ -426,15 +428,15 @@ fhandler_dev_dsp::Audio_out::stop (bool immediately)
|
|||||||
}
|
}
|
||||||
|
|
||||||
rc = waveOutReset (dev_);
|
rc = waveOutReset (dev_);
|
||||||
debug_printf ("%d = waveOutReset()", rc);
|
debug_printf ("%u = waveOutReset()", rc);
|
||||||
while (Qisr2app_->recv (&pHdr))
|
while (Qisr2app_->recv (&pHdr))
|
||||||
{
|
{
|
||||||
rc = waveOutUnprepareHeader (dev_, pHdr, sizeof (WAVEHDR));
|
rc = waveOutUnprepareHeader (dev_, pHdr, sizeof (WAVEHDR));
|
||||||
debug_printf ("%d = waveOutUnprepareHeader(0x%08x)", rc, pHdr);
|
debug_printf ("%u = waveOutUnprepareHeader(%p)", rc, pHdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = waveOutClose (dev_);
|
rc = waveOutClose (dev_);
|
||||||
debug_printf ("%d = waveOutClose()", rc);
|
debug_printf ("%u = waveOutClose()", rc);
|
||||||
|
|
||||||
Qisr2app_->dellock ();
|
Qisr2app_->dellock ();
|
||||||
}
|
}
|
||||||
@ -564,7 +566,7 @@ fhandler_dev_dsp::Audio_out::waitforspace ()
|
|||||||
/* Errors are ignored here. They will probbaly cause a failure
|
/* Errors are ignored here. They will probbaly cause a failure
|
||||||
in the subsequent PrepareHeader */
|
in the subsequent PrepareHeader */
|
||||||
rc = waveOutUnprepareHeader (dev_, pHdr, sizeof (WAVEHDR));
|
rc = waveOutUnprepareHeader (dev_, pHdr, sizeof (WAVEHDR));
|
||||||
debug_printf ("%d = waveOutUnprepareHeader(0x%08x)", rc, pHdr);
|
debug_printf ("%u = waveOutUnprepareHeader(%p)", rc, pHdr);
|
||||||
}
|
}
|
||||||
pHdr_ = pHdr;
|
pHdr_ = pHdr;
|
||||||
bufferIndex_ = 0;
|
bufferIndex_ = 0;
|
||||||
@ -587,7 +589,7 @@ fhandler_dev_dsp::Audio_out::sendcurrent ()
|
|||||||
{
|
{
|
||||||
WAVEHDR *pHdr = pHdr_;
|
WAVEHDR *pHdr = pHdr_;
|
||||||
MMRESULT rc;
|
MMRESULT rc;
|
||||||
debug_printf ("pHdr=0x%08x bytes=%d", pHdr, bufferIndex_);
|
debug_printf ("pHdr=%p bytes=%d", pHdr, bufferIndex_);
|
||||||
|
|
||||||
if (pHdr_ == NULL)
|
if (pHdr_ == NULL)
|
||||||
return false;
|
return false;
|
||||||
@ -599,11 +601,11 @@ fhandler_dev_dsp::Audio_out::sendcurrent ()
|
|||||||
// Send internal buffer out to the soundcard
|
// Send internal buffer out to the soundcard
|
||||||
pHdr->dwBufferLength = bufferIndex_;
|
pHdr->dwBufferLength = bufferIndex_;
|
||||||
rc = waveOutPrepareHeader (dev_, pHdr, sizeof (WAVEHDR));
|
rc = waveOutPrepareHeader (dev_, pHdr, sizeof (WAVEHDR));
|
||||||
debug_printf ("%d = waveOutPrepareHeader(0x%08x)", rc, pHdr);
|
debug_printf ("%u = waveOutPrepareHeader(%p)", rc, pHdr);
|
||||||
if (rc == MMSYSERR_NOERROR)
|
if (rc == MMSYSERR_NOERROR)
|
||||||
{
|
{
|
||||||
rc = waveOutWrite (dev_, pHdr, sizeof (WAVEHDR));
|
rc = waveOutWrite (dev_, pHdr, sizeof (WAVEHDR));
|
||||||
debug_printf ("%d = waveOutWrite(0x%08x)", rc, pHdr);
|
debug_printf ("%u = waveOutWrite(%p)", rc, pHdr);
|
||||||
}
|
}
|
||||||
if (rc == MMSYSERR_NOERROR)
|
if (rc == MMSYSERR_NOERROR)
|
||||||
return true;
|
return true;
|
||||||
@ -617,8 +619,8 @@ fhandler_dev_dsp::Audio_out::sendcurrent ()
|
|||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
// Call back routine
|
// Call back routine
|
||||||
static void CALLBACK
|
static void CALLBACK
|
||||||
waveOut_callback (HWAVEOUT hWave, UINT msg, DWORD instance, DWORD param1,
|
waveOut_callback (HWAVEOUT hWave, UINT msg, DWORD_PTR instance,
|
||||||
DWORD param2)
|
DWORD_PTR param1, DWORD_PTR param2)
|
||||||
{
|
{
|
||||||
if (msg == WOM_DONE)
|
if (msg == WOM_DONE)
|
||||||
{
|
{
|
||||||
@ -663,7 +665,7 @@ fhandler_dev_dsp::Audio_out::parsewav (const char * &pData, int &nBytes,
|
|||||||
setconvert (bits_ == 8 ? AFMT_U8 : AFMT_S16_LE);
|
setconvert (bits_ == 8 ? AFMT_U8 : AFMT_S16_LE);
|
||||||
|
|
||||||
// Check alignment first: A lot of the code below depends on it
|
// Check alignment first: A lot of the code below depends on it
|
||||||
if (((int)pData & 0x3) != 0)
|
if (((uintptr_t)pData & 0x3) != 0)
|
||||||
return false;
|
return false;
|
||||||
if (!(pData[0] == 'R' && pData[1] == 'I'
|
if (!(pData[0] == 'R' && pData[1] == 'I'
|
||||||
&& pData[2] == 'F' && pData[3] == 'F'))
|
&& pData[2] == 'F' && pData[3] == 'F'))
|
||||||
@ -740,7 +742,7 @@ fhandler_dev_dsp::Audio_in::fork_fixup (HANDLE parent)
|
|||||||
/* Null dev_.
|
/* Null dev_.
|
||||||
It will be necessary to reset the queue, open the device
|
It will be necessary to reset the queue, open the device
|
||||||
and create a lock when reading */
|
and create a lock when reading */
|
||||||
debug_printf ("parent=0x%08x", parent);
|
debug_printf ("parent=%p", parent);
|
||||||
dev_ = NULL;
|
dev_ = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -752,7 +754,7 @@ fhandler_dev_dsp::Audio_in::query (int rate, int bits, int channels)
|
|||||||
|
|
||||||
fillFormat (&format, rate, bits, channels);
|
fillFormat (&format, rate, bits, channels);
|
||||||
rc = waveInOpen (NULL, WAVE_MAPPER, &format, 0L, 0L, WAVE_FORMAT_QUERY);
|
rc = waveInOpen (NULL, WAVE_MAPPER, &format, 0L, 0L, WAVE_FORMAT_QUERY);
|
||||||
debug_printf ("%d = waveInOpen(freq=%d bits=%d channels=%d)", rc, rate, bits, channels);
|
debug_printf ("%u = waveInOpen(freq=%d bits=%d channels=%d)", rc, rate, bits, channels);
|
||||||
return (rc == MMSYSERR_NOERROR);
|
return (rc == MMSYSERR_NOERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -774,9 +776,9 @@ fhandler_dev_dsp::Audio_in::start (int rate, int bits, int channels)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
fillFormat (&format, rate, bits, channels);
|
fillFormat (&format, rate, bits, channels);
|
||||||
rc = waveInOpen (&dev_, WAVE_MAPPER, &format, (DWORD) waveIn_callback,
|
rc = waveInOpen (&dev_, WAVE_MAPPER, &format, (DWORD_PTR) waveIn_callback,
|
||||||
(DWORD) this, CALLBACK_FUNCTION);
|
(DWORD_PTR) this, CALLBACK_FUNCTION);
|
||||||
debug_printf ("%d = waveInOpen(rate=%d bits=%d channels=%d)", rc, rate, bits, channels);
|
debug_printf ("%u = waveInOpen(rate=%d bits=%d channels=%d)", rc, rate, bits, channels);
|
||||||
|
|
||||||
if (rc == MMSYSERR_NOERROR)
|
if (rc == MMSYSERR_NOERROR)
|
||||||
{
|
{
|
||||||
@ -792,7 +794,7 @@ fhandler_dev_dsp::Audio_in::stop ()
|
|||||||
MMRESULT rc;
|
MMRESULT rc;
|
||||||
WAVEHDR *pHdr;
|
WAVEHDR *pHdr;
|
||||||
|
|
||||||
debug_printf ("dev_=%08x", (int)dev_);
|
debug_printf ("dev_=%p", dev_);
|
||||||
if (dev_)
|
if (dev_)
|
||||||
{
|
{
|
||||||
/* Note that waveInReset calls our callback for all incomplete buffers.
|
/* Note that waveInReset calls our callback for all incomplete buffers.
|
||||||
@ -800,16 +802,16 @@ fhandler_dev_dsp::Audio_in::stop ()
|
|||||||
we must not call into the wave API from the callback.
|
we must not call into the wave API from the callback.
|
||||||
Otherwise we end up in a deadlock. */
|
Otherwise we end up in a deadlock. */
|
||||||
rc = waveInReset (dev_);
|
rc = waveInReset (dev_);
|
||||||
debug_printf ("%d = waveInReset()", rc);
|
debug_printf ("%u = waveInReset()", rc);
|
||||||
|
|
||||||
while (Qisr2app_->recv (&pHdr))
|
while (Qisr2app_->recv (&pHdr))
|
||||||
{
|
{
|
||||||
rc = waveInUnprepareHeader (dev_, pHdr, sizeof (WAVEHDR));
|
rc = waveInUnprepareHeader (dev_, pHdr, sizeof (WAVEHDR));
|
||||||
debug_printf ("%d = waveInUnprepareHeader(0x%08x)", rc, pHdr);
|
debug_printf ("%u = waveInUnprepareHeader(%p)", rc, pHdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = waveInClose (dev_);
|
rc = waveInClose (dev_);
|
||||||
debug_printf ("%d = waveInClose()", rc);
|
debug_printf ("%u = waveInClose()", rc);
|
||||||
|
|
||||||
Qisr2app_->dellock ();
|
Qisr2app_->dellock ();
|
||||||
}
|
}
|
||||||
@ -820,11 +822,11 @@ fhandler_dev_dsp::Audio_in::queueblock (WAVEHDR *pHdr)
|
|||||||
{
|
{
|
||||||
MMRESULT rc;
|
MMRESULT rc;
|
||||||
rc = waveInPrepareHeader (dev_, pHdr, sizeof (WAVEHDR));
|
rc = waveInPrepareHeader (dev_, pHdr, sizeof (WAVEHDR));
|
||||||
debug_printf ("%d = waveInPrepareHeader(0x%08x)", rc, pHdr);
|
debug_printf ("%u = waveInPrepareHeader(%p)", rc, pHdr);
|
||||||
if (rc == MMSYSERR_NOERROR)
|
if (rc == MMSYSERR_NOERROR)
|
||||||
{
|
{
|
||||||
rc = waveInAddBuffer (dev_, pHdr, sizeof (WAVEHDR));
|
rc = waveInAddBuffer (dev_, pHdr, sizeof (WAVEHDR));
|
||||||
debug_printf ("%d = waveInAddBuffer(0x%08x)", rc, pHdr);
|
debug_printf ("%u = waveInAddBuffer(%p)", rc, pHdr);
|
||||||
}
|
}
|
||||||
if (rc == MMSYSERR_NOERROR)
|
if (rc == MMSYSERR_NOERROR)
|
||||||
return true;
|
return true;
|
||||||
@ -854,7 +856,7 @@ fhandler_dev_dsp::Audio_in::init (unsigned blockSize)
|
|||||||
}
|
}
|
||||||
pHdr_ = NULL;
|
pHdr_ = NULL;
|
||||||
rc = waveInStart (dev_);
|
rc = waveInStart (dev_);
|
||||||
debug_printf ("%d = waveInStart(), queued=%d", rc, i);
|
debug_printf ("%u = waveInStart(), queued=%d", rc, i);
|
||||||
return (rc == MMSYSERR_NOERROR);
|
return (rc == MMSYSERR_NOERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -863,7 +865,7 @@ fhandler_dev_dsp::Audio_in::read (char *pSampleData, int &nBytes)
|
|||||||
{
|
{
|
||||||
int bytes_to_read = nBytes;
|
int bytes_to_read = nBytes;
|
||||||
nBytes = 0;
|
nBytes = 0;
|
||||||
debug_printf ("pSampleData=%08x nBytes=%d", pSampleData, bytes_to_read);
|
debug_printf ("pSampleData=%p nBytes=%d", pSampleData, bytes_to_read);
|
||||||
while (bytes_to_read != 0)
|
while (bytes_to_read != 0)
|
||||||
{ // Block till next sound has been read
|
{ // Block till next sound has been read
|
||||||
if (!waitfordata ())
|
if (!waitfordata ())
|
||||||
@ -942,7 +944,7 @@ fhandler_dev_dsp::Audio_in::waitfordata ()
|
|||||||
/* Errors are ignored here. They will probbaly cause a failure
|
/* Errors are ignored here. They will probbaly cause a failure
|
||||||
in the subsequent PrepareHeader */
|
in the subsequent PrepareHeader */
|
||||||
rc = waveInUnprepareHeader (dev_, pHdr, sizeof (WAVEHDR));
|
rc = waveInUnprepareHeader (dev_, pHdr, sizeof (WAVEHDR));
|
||||||
debug_printf ("%d = waveInUnprepareHeader(0x%08x)", rc, pHdr);
|
debug_printf ("%u = waveInUnprepareHeader(%p)", rc, pHdr);
|
||||||
}
|
}
|
||||||
pHdr_ = pHdr;
|
pHdr_ = pHdr;
|
||||||
bufferIndex_ = 0;
|
bufferIndex_ = 0;
|
||||||
@ -978,8 +980,8 @@ fhandler_dev_dsp::Audio_in::callback_blockfull (WAVEHDR *pHdr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void CALLBACK
|
static void CALLBACK
|
||||||
waveIn_callback (HWAVEIN hWave, UINT msg, DWORD instance, DWORD param1,
|
waveIn_callback (HWAVEIN hWave, UINT msg, DWORD_PTR instance, DWORD_PTR param1,
|
||||||
DWORD param2)
|
DWORD_PTR param2)
|
||||||
{
|
{
|
||||||
if (msg == WIM_DATA)
|
if (msg == WIM_DATA)
|
||||||
{
|
{
|
||||||
@ -1039,7 +1041,7 @@ fhandler_dev_dsp::open (int flags, mode_t mode)
|
|||||||
else
|
else
|
||||||
set_errno (err);
|
set_errno (err);
|
||||||
|
|
||||||
debug_printf ("ACCMODE=0x%08x audio_in=%d audio_out=%d, err=%d",
|
debug_printf ("ACCMODE=%y audio_in=%d audio_out=%d, err=%d",
|
||||||
flags & O_ACCMODE, num_in, num_out, err);
|
flags & O_ACCMODE, num_in, num_out, err);
|
||||||
return !err;
|
return !err;
|
||||||
}
|
}
|
||||||
@ -1050,7 +1052,7 @@ fhandler_dev_dsp::open (int flags, mode_t mode)
|
|||||||
ssize_t __stdcall
|
ssize_t __stdcall
|
||||||
fhandler_dev_dsp::write (const void *ptr, size_t len)
|
fhandler_dev_dsp::write (const void *ptr, size_t len)
|
||||||
{
|
{
|
||||||
debug_printf ("ptr=%08x len=%d", ptr, len);
|
debug_printf ("ptr=%p len=%ld", ptr, len);
|
||||||
int len_s = len;
|
int len_s = len;
|
||||||
const char *ptr_s = static_cast <const char *> (ptr);
|
const char *ptr_s = static_cast <const char *> (ptr);
|
||||||
|
|
||||||
@ -1066,7 +1068,7 @@ fhandler_dev_dsp::write (const void *ptr, size_t len)
|
|||||||
|
|
||||||
if (audio_out_->parsewav (ptr_s, len_s,
|
if (audio_out_->parsewav (ptr_s, len_s,
|
||||||
audiofreq_, audiobits_, audiochannels_))
|
audiofreq_, audiobits_, audiochannels_))
|
||||||
debug_printf ("=> ptr_s=%08x len_s=%d", ptr_s, len_s);
|
debug_printf ("=> ptr_s=%p len_s=%d", ptr_s, len_s);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1096,7 +1098,7 @@ fhandler_dev_dsp::write (const void *ptr, size_t len)
|
|||||||
void __stdcall
|
void __stdcall
|
||||||
fhandler_dev_dsp::read (void *ptr, size_t& len)
|
fhandler_dev_dsp::read (void *ptr, size_t& len)
|
||||||
{
|
{
|
||||||
debug_printf ("ptr=%08x len=%d", ptr, len);
|
debug_printf ("ptr=%p len=%ld", ptr, len);
|
||||||
|
|
||||||
if (audio_in_)
|
if (audio_in_)
|
||||||
/* nothing to do */;
|
/* nothing to do */;
|
||||||
@ -1129,8 +1131,8 @@ fhandler_dev_dsp::read (void *ptr, size_t& len)
|
|||||||
audio_in_->read ((char *)ptr, (int&)len);
|
audio_in_->read ((char *)ptr, (int&)len);
|
||||||
}
|
}
|
||||||
|
|
||||||
_off64_t
|
off_t
|
||||||
fhandler_dev_dsp::lseek (_off64_t offset, int whence)
|
fhandler_dev_dsp::lseek (off_t offset, int whence)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1160,8 +1162,7 @@ fhandler_dev_dsp::close_audio_out (bool immediately)
|
|||||||
int
|
int
|
||||||
fhandler_dev_dsp::close ()
|
fhandler_dev_dsp::close ()
|
||||||
{
|
{
|
||||||
debug_printf ("audio_in=%08x audio_out=%08x",
|
debug_printf ("audio_in=%p audio_out=%p", audio_in_, audio_out_);
|
||||||
(int)audio_in_, (int)audio_out_);
|
|
||||||
close_audio_in ();
|
close_audio_in ();
|
||||||
close_audio_out (exit_state != ES_NOT_EXITING);
|
close_audio_out (exit_state != ES_NOT_EXITING);
|
||||||
return 0;
|
return 0;
|
||||||
@ -1170,8 +1171,7 @@ fhandler_dev_dsp::close ()
|
|||||||
int
|
int
|
||||||
fhandler_dev_dsp::ioctl (unsigned int cmd, void *buf)
|
fhandler_dev_dsp::ioctl (unsigned int cmd, void *buf)
|
||||||
{
|
{
|
||||||
debug_printf ("audio_in=%08x audio_out=%08x",
|
debug_printf ("audio_in=%p audio_out=%p", audio_in_, audio_out_);
|
||||||
(int)audio_in_, (int)audio_out_);
|
|
||||||
int *intbuf = (int *) buf;
|
int *intbuf = (int *) buf;
|
||||||
switch (cmd)
|
switch (cmd)
|
||||||
{
|
{
|
||||||
@ -1374,8 +1374,8 @@ fhandler_dev_dsp::ioctl (unsigned int cmd, void *buf)
|
|||||||
void
|
void
|
||||||
fhandler_dev_dsp::fixup_after_fork (HANDLE parent)
|
fhandler_dev_dsp::fixup_after_fork (HANDLE parent)
|
||||||
{ // called from new child process
|
{ // called from new child process
|
||||||
debug_printf ("audio_in=%08x audio_out=%08x",
|
debug_printf ("audio_in=%p audio_out=%p",
|
||||||
(int)audio_in_, (int)audio_out_);
|
audio_in_, audio_out_);
|
||||||
|
|
||||||
if (audio_in_)
|
if (audio_in_)
|
||||||
audio_in_->fork_fixup (parent);
|
audio_in_->fork_fixup (parent);
|
||||||
@ -1386,8 +1386,8 @@ fhandler_dev_dsp::fixup_after_fork (HANDLE parent)
|
|||||||
void
|
void
|
||||||
fhandler_dev_dsp::fixup_after_exec ()
|
fhandler_dev_dsp::fixup_after_exec ()
|
||||||
{
|
{
|
||||||
debug_printf ("audio_in=%08x audio_out=%08x, close_on_exec %d",
|
debug_printf ("audio_in=%p audio_out=%p, close_on_exec %d",
|
||||||
(int) audio_in_, (int) audio_out_, close_on_exec ());
|
audio_in_, audio_out_, close_on_exec ());
|
||||||
if (!close_on_exec ())
|
if (!close_on_exec ())
|
||||||
{
|
{
|
||||||
audio_in_ = NULL;
|
audio_in_ = NULL;
|
||||||
|
@ -290,7 +290,7 @@ fhandler_fifo::raw_read (void *in_ptr, size_t& len)
|
|||||||
could hang indefinitely. Maybe implement a timeout? */
|
could hang indefinitely. Maybe implement a timeout? */
|
||||||
if (!DisconnectNamedPipe (get_io_handle ()))
|
if (!DisconnectNamedPipe (get_io_handle ()))
|
||||||
{
|
{
|
||||||
debug_printf ("DisconnecttNamedPipe failed, %E");
|
debug_printf ("DisconnectNamedPipe failed, %E");
|
||||||
goto errno_out;
|
goto errno_out;
|
||||||
}
|
}
|
||||||
else if (!ConnectNamedPipe (get_io_handle (), get_overlapped ())
|
else if (!ConnectNamedPipe (get_io_handle (), get_overlapped ())
|
||||||
|
@ -53,7 +53,7 @@ fhandler_dev_floppy::get_drive_info (struct hd_geometry *geo)
|
|||||||
/* Always try using the new EX ioctls first (>= XP). If not available,
|
/* Always try using the new EX ioctls first (>= XP). If not available,
|
||||||
fall back to trying the old non-EX ioctls.
|
fall back to trying the old non-EX ioctls.
|
||||||
Unfortunately the EX ioctls are not implemented in the floppy driver. */
|
Unfortunately the EX ioctls are not implemented in the floppy driver. */
|
||||||
if (wincap.has_disk_ex_ioctls () && get_major () != DEV_FLOPPY_MAJOR)
|
if (get_major () != DEV_FLOPPY_MAJOR)
|
||||||
{
|
{
|
||||||
if (!DeviceIoControl (get_handle (),
|
if (!DeviceIoControl (get_handle (),
|
||||||
IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0,
|
IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0,
|
||||||
@ -76,95 +76,49 @@ fhandler_dev_floppy::get_drive_info (struct hd_geometry *geo)
|
|||||||
if (!DeviceIoControl (get_handle (),
|
if (!DeviceIoControl (get_handle (),
|
||||||
IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0,
|
IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0,
|
||||||
dbuf, 256, &bytes_read, NULL))
|
dbuf, 256, &bytes_read, NULL))
|
||||||
__seterrno ();
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
di = (DISK_GEOMETRY *) dbuf;
|
__seterrno ();
|
||||||
if (!DeviceIoControl (get_handle (),
|
|
||||||
IOCTL_DISK_GET_PARTITION_INFO, NULL, 0,
|
|
||||||
pbuf, 256, &bytes_read, NULL))
|
|
||||||
__seterrno ();
|
|
||||||
else
|
|
||||||
pi = (PARTITION_INFORMATION *) pbuf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!di)
|
|
||||||
{
|
|
||||||
/* Up to Win2K, even IOCTL_DISK_GET_DRIVE_GEOMETRY fails when trying
|
|
||||||
it on CD or DVD drives. In that case fall back to requesting
|
|
||||||
simple file system information. */
|
|
||||||
NTSTATUS status;
|
|
||||||
IO_STATUS_BLOCK io;
|
|
||||||
FILE_FS_SIZE_INFORMATION ffsi;
|
|
||||||
|
|
||||||
status = NtQueryVolumeInformationFile (get_handle (), &io, &ffsi,
|
|
||||||
sizeof ffsi,
|
|
||||||
FileFsSizeInformation);
|
|
||||||
if (!NT_SUCCESS (status))
|
|
||||||
{
|
|
||||||
__seterrno_from_nt_status (status);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
debug_printf ("fsys geometry: (%D units)*(%u sec)*(%u bps)",
|
di = (DISK_GEOMETRY *) dbuf;
|
||||||
ffsi.TotalAllocationUnits.QuadPart,
|
if (!DeviceIoControl (get_handle (),
|
||||||
ffsi.SectorsPerAllocationUnit,
|
IOCTL_DISK_GET_PARTITION_INFO, NULL, 0,
|
||||||
ffsi.BytesPerSector);
|
pbuf, 256, &bytes_read, NULL))
|
||||||
bytes_per_sector = ffsi.BytesPerSector;
|
__seterrno ();
|
||||||
drive_size = ffsi.TotalAllocationUnits.QuadPart
|
else
|
||||||
* ffsi.SectorsPerAllocationUnit
|
pi = (PARTITION_INFORMATION *) pbuf;
|
||||||
* ffsi.BytesPerSector;
|
}
|
||||||
if (geo)
|
debug_printf ("disk geometry: (%D cyl)*(%u trk)*(%u sec)*(%u bps)",
|
||||||
{
|
di->Cylinders.QuadPart,
|
||||||
geo->heads = 1;
|
di->TracksPerCylinder,
|
||||||
geo->sectors = ffsi.SectorsPerAllocationUnit;
|
di->SectorsPerTrack,
|
||||||
geo->cylinders = ffsi.TotalAllocationUnits.LowPart;
|
di->BytesPerSector);
|
||||||
geo->start = 0;
|
bytes_per_sector = di->BytesPerSector;
|
||||||
}
|
if (pix)
|
||||||
|
{
|
||||||
|
debug_printf ("partition info: offset %D length %D",
|
||||||
|
pix->StartingOffset.QuadPart,
|
||||||
|
pix->PartitionLength.QuadPart);
|
||||||
|
drive_size = pix->PartitionLength.QuadPart;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
debug_printf ("disk geometry: (%D cyl)*(%u trk)*(%u sec)*(%u bps)",
|
debug_printf ("partition info: offset %D length %D",
|
||||||
di->Cylinders.QuadPart,
|
pi->StartingOffset.QuadPart,
|
||||||
di->TracksPerCylinder,
|
pi->PartitionLength.QuadPart);
|
||||||
di->SectorsPerTrack,
|
drive_size = pi->PartitionLength.QuadPart;
|
||||||
di->BytesPerSector);
|
}
|
||||||
bytes_per_sector = di->BytesPerSector;
|
if (geo)
|
||||||
|
{
|
||||||
|
geo->heads = di->TracksPerCylinder;
|
||||||
|
geo->sectors = di->SectorsPerTrack;
|
||||||
|
geo->cylinders = di->Cylinders.LowPart;
|
||||||
if (pix)
|
if (pix)
|
||||||
{
|
geo->start = pix->StartingOffset.QuadPart >> 9ULL;
|
||||||
debug_printf ("partition info: offset %D length %D",
|
|
||||||
pix->StartingOffset.QuadPart,
|
|
||||||
pix->PartitionLength.QuadPart);
|
|
||||||
drive_size = pix->PartitionLength.QuadPart;
|
|
||||||
}
|
|
||||||
else if (pi)
|
else if (pi)
|
||||||
{
|
geo->start = pi->StartingOffset.QuadPart >> 9ULL;
|
||||||
debug_printf ("partition info: offset %D length %D",
|
|
||||||
pi->StartingOffset.QuadPart,
|
|
||||||
pi->PartitionLength.QuadPart);
|
|
||||||
drive_size = pi->PartitionLength.QuadPart;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
geo->start = 0;
|
||||||
/* Getting the partition size by using the drive geometry information
|
|
||||||
looks wrong, but this is a historical necessity. NT4 didn't
|
|
||||||
maintain partition information for the whole drive (aka
|
|
||||||
"partition 0"), but returned ERROR_INVALID_HANDLE instead. That
|
|
||||||
got fixed in W2K. */
|
|
||||||
drive_size = di->Cylinders.QuadPart * di->TracksPerCylinder
|
|
||||||
* di->SectorsPerTrack * di->BytesPerSector;
|
|
||||||
}
|
|
||||||
if (geo)
|
|
||||||
{
|
|
||||||
geo->heads = di->TracksPerCylinder;
|
|
||||||
geo->sectors = di->SectorsPerTrack;
|
|
||||||
geo->cylinders = di->Cylinders.LowPart;
|
|
||||||
if (pix)
|
|
||||||
geo->start = pix->StartingOffset.QuadPart >> 9ULL;
|
|
||||||
else if (pi)
|
|
||||||
geo->start = pi->StartingOffset.QuadPart >> 9ULL;
|
|
||||||
else
|
|
||||||
geo->start = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
debug_printf ("drive size: %D", drive_size);
|
debug_printf ("drive size: %D", drive_size);
|
||||||
|
|
||||||
@ -180,7 +134,7 @@ fhandler_dev_floppy::read_file (void *buf, DWORD to_read, DWORD *read, int *err)
|
|||||||
*err = 0;
|
*err = 0;
|
||||||
if (!(ret = ReadFile (get_handle (), buf, to_read, read, 0)))
|
if (!(ret = ReadFile (get_handle (), buf, to_read, read, 0)))
|
||||||
*err = GetLastError ();
|
*err = GetLastError ();
|
||||||
syscall_printf ("%d (err %d) = ReadFile (%d, %d, to_read %d, read %d, 0)",
|
syscall_printf ("%d (err %d) = ReadFile (%p, %p, to_read %u, read %u, 0)",
|
||||||
ret, *err, get_handle (), buf, to_read, *read);
|
ret, *err, get_handle (), buf, to_read, *read);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -234,7 +188,7 @@ fhandler_dev_floppy::lock_partition (DWORD to_write)
|
|||||||
FilePositionInformation);
|
FilePositionInformation);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
debug_printf ("NtQueryInformationFile(FilePositionInformation): %p",
|
debug_printf ("NtQueryInformationFile(FilePositionInformation): %y",
|
||||||
status);
|
status);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -268,7 +222,7 @@ fhandler_dev_floppy::lock_partition (DWORD to_write)
|
|||||||
if (part_no >= MAX_PARTITIONS)
|
if (part_no >= MAX_PARTITIONS)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
found = TRUE;
|
found = TRUE;
|
||||||
debug_printf ("%d %D->%D : %D->%D", part_no,
|
debug_printf ("%u %D->%D : %D->%D", part_no,
|
||||||
ppie->StartingOffset.QuadPart,
|
ppie->StartingOffset.QuadPart,
|
||||||
ppie->StartingOffset.QuadPart
|
ppie->StartingOffset.QuadPart
|
||||||
+ ppie->PartitionLength.QuadPart,
|
+ ppie->PartitionLength.QuadPart,
|
||||||
@ -305,7 +259,7 @@ fhandler_dev_floppy::lock_partition (DWORD to_write)
|
|||||||
&io, FILE_SHARE_READ | FILE_SHARE_WRITE, 0);
|
&io, FILE_SHARE_READ | FILE_SHARE_WRITE, 0);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
debug_printf ("NtCreateFile(%W): %p", part, status);
|
debug_printf ("NtCreateFile(%W): %y", part, status);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (!DeviceIoControl (partitions->hdl[part_no - 1], FSCTL_LOCK_VOLUME,
|
if (!DeviceIoControl (partitions->hdl[part_no - 1], FSCTL_LOCK_VOLUME,
|
||||||
@ -349,7 +303,7 @@ fhandler_dev_floppy::write_file (const void *buf, DWORD to_write,
|
|||||||
if (!(ret = WriteFile (get_handle (), buf, to_write, written, 0)))
|
if (!(ret = WriteFile (get_handle (), buf, to_write, written, 0)))
|
||||||
*err = GetLastError ();
|
*err = GetLastError ();
|
||||||
}
|
}
|
||||||
syscall_printf ("%d (err %d) = WriteFile (%d, %d, write %d, written %d, 0)",
|
syscall_printf ("%d (err %d) = WriteFile (%p, %p, write %u, written %u, 0)",
|
||||||
ret, *err, get_handle (), buf, to_write, *written);
|
ret, *err, get_handle (), buf, to_write, *written);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -377,7 +331,8 @@ fhandler_dev_floppy::open (int flags, mode_t)
|
|||||||
Whoever uses O_DIRECT has my condolences. */
|
Whoever uses O_DIRECT has my condolences. */
|
||||||
devbufsiz = MAX (16 * bytes_per_sector, 65536);
|
devbufsiz = MAX (16 * bytes_per_sector, 65536);
|
||||||
devbufalloc = new char [devbufsiz + devbufalign];
|
devbufalloc = new char [devbufsiz + devbufalign];
|
||||||
devbuf = (char *) roundup2 ((uintptr_t) devbufalloc, devbufalign);
|
devbuf = (char *) roundup2 ((uintptr_t) devbufalloc,
|
||||||
|
(uintptr_t) devbufalign);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we're not trying to access a floppy disk, make sure we're actually
|
/* If we're not trying to access a floppy disk, make sure we're actually
|
||||||
@ -418,7 +373,7 @@ fhandler_dev_floppy::dup (fhandler_base *child, int flags)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline _off64_t
|
inline off_t
|
||||||
fhandler_dev_floppy::get_current_position ()
|
fhandler_dev_floppy::get_current_position ()
|
||||||
{
|
{
|
||||||
LARGE_INTEGER off = { QuadPart: 0LL };
|
LARGE_INTEGER off = { QuadPart: 0LL };
|
||||||
@ -451,7 +406,7 @@ fhandler_dev_floppy::raw_read (void *ptr, size_t& ulen)
|
|||||||
if (devbufstart < devbufend)
|
if (devbufstart < devbufend)
|
||||||
{
|
{
|
||||||
bytes_to_read = MIN (len, devbufend - devbufstart);
|
bytes_to_read = MIN (len, devbufend - devbufstart);
|
||||||
debug_printf ("read %d bytes from buffer (rest %d)",
|
debug_printf ("read %u bytes from buffer (rest %u)",
|
||||||
bytes_to_read,
|
bytes_to_read,
|
||||||
devbufend - devbufstart - bytes_to_read);
|
devbufend - devbufstart - bytes_to_read);
|
||||||
memcpy (p, devbuf + devbufstart, bytes_to_read);
|
memcpy (p, devbuf + devbufstart, bytes_to_read);
|
||||||
@ -478,13 +433,13 @@ fhandler_dev_floppy::raw_read (void *ptr, size_t& ulen)
|
|||||||
tgt = devbuf;
|
tgt = devbuf;
|
||||||
bytes_to_read = devbufsiz;
|
bytes_to_read = devbufsiz;
|
||||||
}
|
}
|
||||||
_off64_t current_position = get_current_position ();
|
off_t current_position = get_current_position ();
|
||||||
if (current_position + bytes_to_read >= drive_size)
|
if (current_position + bytes_to_read >= drive_size)
|
||||||
bytes_to_read = drive_size - current_position;
|
bytes_to_read = drive_size - current_position;
|
||||||
if (!bytes_to_read)
|
if (!bytes_to_read)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
debug_printf ("read %d bytes from pos %U %s", bytes_to_read,
|
debug_printf ("read %u bytes from pos %U %s", bytes_to_read,
|
||||||
current_position,
|
current_position,
|
||||||
len < devbufsiz ? "into buffer" : "directly");
|
len < devbufsiz ? "into buffer" : "directly");
|
||||||
if (!read_file (tgt, bytes_to_read, &read2, &ret))
|
if (!read_file (tgt, bytes_to_read, &read2, &ret))
|
||||||
@ -527,11 +482,11 @@ fhandler_dev_floppy::raw_read (void *ptr, size_t& ulen)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_off64_t current_position = get_current_position ();
|
off_t current_position = get_current_position ();
|
||||||
bytes_to_read = len;
|
bytes_to_read = len;
|
||||||
if (current_position + bytes_to_read >= drive_size)
|
if (current_position + bytes_to_read >= drive_size)
|
||||||
bytes_to_read = drive_size - current_position;
|
bytes_to_read = drive_size - current_position;
|
||||||
debug_printf ("read %d bytes from pos %U directly", bytes_to_read,
|
debug_printf ("read %u bytes from pos %U directly", bytes_to_read,
|
||||||
current_position);
|
current_position);
|
||||||
if (bytes_to_read && !read_file (p, bytes_to_read, &bytes_read, &ret))
|
if (bytes_to_read && !read_file (p, bytes_to_read, &bytes_read, &ret))
|
||||||
{
|
{
|
||||||
@ -558,7 +513,7 @@ err:
|
|||||||
ulen = (size_t) -1;
|
ulen = (size_t) -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int __stdcall
|
ssize_t __stdcall
|
||||||
fhandler_dev_floppy::raw_write (const void *ptr, size_t len)
|
fhandler_dev_floppy::raw_write (const void *ptr, size_t len)
|
||||||
{
|
{
|
||||||
DWORD bytes_written = 0;
|
DWORD bytes_written = 0;
|
||||||
@ -585,7 +540,7 @@ fhandler_dev_floppy::raw_write (const void *ptr, size_t len)
|
|||||||
buffer in case we seek to an address which is not sector aligned. */
|
buffer in case we seek to an address which is not sector aligned. */
|
||||||
if (devbufend && devbufstart < devbufend)
|
if (devbufend && devbufstart < devbufend)
|
||||||
{
|
{
|
||||||
_off64_t current_pos = get_current_position ();
|
off_t current_pos = get_current_position ();
|
||||||
cplen = MIN (len, devbufend - devbufstart);
|
cplen = MIN (len, devbufend - devbufstart);
|
||||||
memcpy (devbuf + devbufstart, p, cplen);
|
memcpy (devbuf + devbufstart, p, cplen);
|
||||||
LARGE_INTEGER off = { QuadPart:current_pos - devbufend };
|
LARGE_INTEGER off = { QuadPart:current_pos - devbufend };
|
||||||
@ -647,7 +602,7 @@ fhandler_dev_floppy::raw_write (const void *ptr, size_t len)
|
|||||||
}
|
}
|
||||||
return bytes_written;
|
return bytes_written;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* In O_DIRECT case, just write. */
|
/* In O_DIRECT case, just write. */
|
||||||
if (write_file (p, len, &bytes_written, &ret))
|
if (write_file (p, len, &bytes_written, &ret))
|
||||||
return bytes_written;
|
return bytes_written;
|
||||||
@ -664,11 +619,11 @@ err:
|
|||||||
return bytes_written ?: -1;
|
return bytes_written ?: -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
_off64_t
|
off_t
|
||||||
fhandler_dev_floppy::lseek (_off64_t offset, int whence)
|
fhandler_dev_floppy::lseek (off_t offset, int whence)
|
||||||
{
|
{
|
||||||
char buf[bytes_per_sector];
|
char buf[bytes_per_sector];
|
||||||
_off64_t current_pos = (_off64_t) -1;
|
off_t current_pos = (off_t) -1;
|
||||||
LARGE_INTEGER sector_aligned_offset;
|
LARGE_INTEGER sector_aligned_offset;
|
||||||
size_t bytes_left;
|
size_t bytes_left;
|
||||||
|
|
||||||
@ -680,7 +635,7 @@ fhandler_dev_floppy::lseek (_off64_t offset, int whence)
|
|||||||
else if (whence == SEEK_CUR)
|
else if (whence == SEEK_CUR)
|
||||||
{
|
{
|
||||||
current_pos = get_current_position ();
|
current_pos = get_current_position ();
|
||||||
_off64_t exact_pos = current_pos - (devbufend - devbufstart);
|
off_t exact_pos = current_pos - (devbufend - devbufstart);
|
||||||
/* Shortcut when used to get current position. */
|
/* Shortcut when used to get current position. */
|
||||||
if (offset == 0)
|
if (offset == 0)
|
||||||
return exact_pos;
|
return exact_pos;
|
||||||
@ -697,7 +652,7 @@ fhandler_dev_floppy::lseek (_off64_t offset, int whence)
|
|||||||
/* If new position is in buffered range, adjust buffer and return */
|
/* If new position is in buffered range, adjust buffer and return */
|
||||||
if (devbufstart < devbufend)
|
if (devbufstart < devbufend)
|
||||||
{
|
{
|
||||||
if (current_pos == (_off64_t) -1)
|
if (current_pos == (off_t) -1)
|
||||||
current_pos = get_current_position ();
|
current_pos = get_current_position ();
|
||||||
if (current_pos - devbufend <= offset && offset <= current_pos)
|
if (current_pos - devbufend <= offset && offset <= current_pos)
|
||||||
{
|
{
|
||||||
@ -749,7 +704,7 @@ fhandler_dev_floppy::ioctl (unsigned int cmd, void *buf)
|
|||||||
if (cmd == BLKGETSIZE)
|
if (cmd == BLKGETSIZE)
|
||||||
*(long *)buf = drive_size >> 9UL;
|
*(long *)buf = drive_size >> 9UL;
|
||||||
else
|
else
|
||||||
*(_off64_t *)buf = drive_size;
|
*(off_t *)buf = drive_size;
|
||||||
break;
|
break;
|
||||||
case BLKRRPART:
|
case BLKRRPART:
|
||||||
debug_printf ("BLKRRPART");
|
debug_printf ("BLKRRPART");
|
||||||
@ -764,19 +719,19 @@ fhandler_dev_floppy::ioctl (unsigned int cmd, void *buf)
|
|||||||
break;
|
break;
|
||||||
case BLKSSZGET:
|
case BLKSSZGET:
|
||||||
debug_printf ("BLKSSZGET");
|
debug_printf ("BLKSSZGET");
|
||||||
*(int *)buf = bytes_per_sector;
|
*(int *)buf = (int) bytes_per_sector;
|
||||||
break;
|
break;
|
||||||
case BLKIOMIN:
|
case BLKIOMIN:
|
||||||
debug_printf ("BLKIOMIN");
|
debug_printf ("BLKIOMIN");
|
||||||
*(int *)buf = bytes_per_sector;
|
*(int *)buf = (int) bytes_per_sector;
|
||||||
break;
|
break;
|
||||||
case BLKIOOPT:
|
case BLKIOOPT:
|
||||||
debug_printf ("BLKIOOPT");
|
debug_printf ("BLKIOOPT");
|
||||||
*(int *)buf = bytes_per_sector;
|
*(int *)buf = (int) bytes_per_sector;
|
||||||
break;
|
break;
|
||||||
case BLKPBSZGET:
|
case BLKPBSZGET:
|
||||||
debug_printf ("BLKPBSZGET");
|
debug_printf ("BLKPBSZGET");
|
||||||
*(int *)buf = bytes_per_sector;
|
*(int *)buf = (int) bytes_per_sector;
|
||||||
break;
|
break;
|
||||||
case BLKALIGNOFF:
|
case BLKALIGNOFF:
|
||||||
debug_printf ("BLKALIGNOFF");
|
debug_printf ("BLKALIGNOFF");
|
||||||
|
@ -29,7 +29,7 @@ fhandler_mailslot::fhandler_mailslot ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
int __reg2
|
int __reg2
|
||||||
fhandler_mailslot::fstat (struct __stat64 *buf)
|
fhandler_mailslot::fstat (struct stat *buf)
|
||||||
{
|
{
|
||||||
debug_printf ("here");
|
debug_printf ("here");
|
||||||
|
|
||||||
@ -177,7 +177,7 @@ fhandler_mailslot::ioctl (unsigned int cmd, void *buf)
|
|||||||
FileMailslotSetInformation);
|
FileMailslotSetInformation);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
debug_printf ("NtSetInformationFile (%X): %08x",
|
debug_printf ("NtSetInformationFile (%X): %p",
|
||||||
fmsi.ReadTimeout.QuadPart, status);
|
fmsi.ReadTimeout.QuadPart, status);
|
||||||
__seterrno_from_nt_status (status);
|
__seterrno_from_nt_status (status);
|
||||||
break;
|
break;
|
||||||
|
@ -37,7 +37,7 @@ fhandler_dev_mem::open (int flags, mode_t)
|
|||||||
if (!wincap.has_physical_mem_access ())
|
if (!wincap.has_physical_mem_access ())
|
||||||
{
|
{
|
||||||
set_errno (EACCES);
|
set_errno (EACCES);
|
||||||
debug_printf ("%s is accessible under NT4/W2K/XP only", dev ().name);
|
debug_printf ("%s is accessible under XP only", dev ().name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,17 +49,18 @@ fhandler_dev_mem::open (int flags, mode_t)
|
|||||||
if (NT_SUCCESS (status))
|
if (NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
__seterrno_from_nt_status (status);
|
__seterrno_from_nt_status (status);
|
||||||
debug_printf("NtQuerySystemInformation: status %p, %E", status);
|
debug_printf("NtQuerySystemInformation: status %p", status);
|
||||||
mem_size = 0;
|
mem_size = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
mem_size = sbi.PhysicalPageSize * sbi.NumberOfPhysicalPages;
|
mem_size = (SIZE_T) sbi.PhysicalPageSize
|
||||||
debug_printf ("MemSize: %d MB", mem_size >> 20);
|
* (SIZE_T) sbi.NumberOfPhysicalPages;
|
||||||
|
debug_printf ("MemSize: %ld MB", mem_size >> 20);
|
||||||
}
|
}
|
||||||
else if (dev () == FH_KMEM) /* /dev/kmem - Not yet supported */
|
else if (dev () == FH_KMEM) /* /dev/kmem - Not yet supported */
|
||||||
{
|
{
|
||||||
mem_size = 0;
|
mem_size = 0;
|
||||||
debug_printf ("KMemSize: %d MB", mem_size >> 20);
|
debug_printf ("KMemSize: %ld MB", mem_size >> 20);
|
||||||
}
|
}
|
||||||
else if (dev () == FH_PORT) /* /dev/port == First 64K of /dev/mem */
|
else if (dev () == FH_PORT) /* /dev/port == First 64K of /dev/mem */
|
||||||
{
|
{
|
||||||
@ -119,7 +120,7 @@ fhandler_dev_mem::open (int flags, mode_t)
|
|||||||
ssize_t __stdcall
|
ssize_t __stdcall
|
||||||
fhandler_dev_mem::write (const void *ptr, size_t ulen)
|
fhandler_dev_mem::write (const void *ptr, size_t ulen)
|
||||||
{
|
{
|
||||||
if (!ulen || pos >= mem_size)
|
if (!ulen || pos >= (off_t) mem_size)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!(get_access () & GENERIC_WRITE))
|
if (!(get_access () & GENERIC_WRITE))
|
||||||
@ -129,12 +130,12 @@ fhandler_dev_mem::write (const void *ptr, size_t ulen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (pos + ulen > mem_size)
|
if (pos + ulen > mem_size)
|
||||||
ulen = mem_size - pos;
|
ulen = (off_t) mem_size - pos;
|
||||||
|
|
||||||
PHYSICAL_ADDRESS phys;
|
PHYSICAL_ADDRESS phys;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
void *viewmem = NULL;
|
void *viewmem = NULL;
|
||||||
DWORD len = ulen + wincap.page_size () - 1;
|
SIZE_T len = ulen + wincap.page_size () - 1;
|
||||||
|
|
||||||
phys.QuadPart = (ULONGLONG) pos;
|
phys.QuadPart = (ULONGLONG) pos;
|
||||||
status = NtMapViewOfSection (get_handle (), INVALID_HANDLE_VALUE, &viewmem,
|
status = NtMapViewOfSection (get_handle (), INVALID_HANDLE_VALUE, &viewmem,
|
||||||
@ -162,7 +163,7 @@ fhandler_dev_mem::write (const void *ptr, size_t ulen)
|
|||||||
void __stdcall
|
void __stdcall
|
||||||
fhandler_dev_mem::read (void *ptr, size_t& ulen)
|
fhandler_dev_mem::read (void *ptr, size_t& ulen)
|
||||||
{
|
{
|
||||||
if (!ulen || pos >= mem_size)
|
if (!ulen || pos >= (off_t) mem_size)
|
||||||
{
|
{
|
||||||
ulen = 0;
|
ulen = 0;
|
||||||
return;
|
return;
|
||||||
@ -176,12 +177,12 @@ fhandler_dev_mem::read (void *ptr, size_t& ulen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (pos + ulen > mem_size)
|
if (pos + ulen > mem_size)
|
||||||
ulen = mem_size - pos;
|
ulen = (off_t) mem_size - pos;
|
||||||
|
|
||||||
PHYSICAL_ADDRESS phys;
|
PHYSICAL_ADDRESS phys;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
void *viewmem = NULL;
|
void *viewmem = NULL;
|
||||||
DWORD len = ulen + wincap.page_size () - 1;
|
SIZE_T len = ulen + wincap.page_size () - 1;
|
||||||
|
|
||||||
phys.QuadPart = (ULONGLONG) pos;
|
phys.QuadPart = (ULONGLONG) pos;
|
||||||
status = NtMapViewOfSection (get_handle (), INVALID_HANDLE_VALUE, &viewmem,
|
status = NtMapViewOfSection (get_handle (), INVALID_HANDLE_VALUE, &viewmem,
|
||||||
@ -207,8 +208,8 @@ fhandler_dev_mem::read (void *ptr, size_t& ulen)
|
|||||||
pos += ulen;
|
pos += ulen;
|
||||||
}
|
}
|
||||||
|
|
||||||
_off64_t
|
off_t
|
||||||
fhandler_dev_mem::lseek (_off64_t offset, int whence)
|
fhandler_dev_mem::lseek (off_t offset, int whence)
|
||||||
{
|
{
|
||||||
switch (whence)
|
switch (whence)
|
||||||
{
|
{
|
||||||
@ -221,7 +222,7 @@ fhandler_dev_mem::lseek (_off64_t offset, int whence)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SEEK_END:
|
case SEEK_END:
|
||||||
pos = mem_size;
|
pos = (off_t) mem_size;
|
||||||
pos += offset;
|
pos += offset;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -230,7 +231,7 @@ fhandler_dev_mem::lseek (_off64_t offset, int whence)
|
|||||||
return ILLEGAL_SEEK;
|
return ILLEGAL_SEEK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pos > mem_size)
|
if (pos > (off_t) mem_size)
|
||||||
{
|
{
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return ILLEGAL_SEEK;
|
return ILLEGAL_SEEK;
|
||||||
@ -240,7 +241,7 @@ fhandler_dev_mem::lseek (_off64_t offset, int whence)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int __reg2
|
int __reg2
|
||||||
fhandler_dev_mem::fstat (struct __stat64 *buf)
|
fhandler_dev_mem::fstat (struct stat *buf)
|
||||||
{
|
{
|
||||||
fhandler_base::fstat (buf);
|
fhandler_base::fstat (buf);
|
||||||
buf->st_blksize = wincap.page_size ();
|
buf->st_blksize = wincap.page_size ();
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* fhandler_netdrive.cc: fhandler for // and //MACHINE handling
|
/* fhandler_netdrive.cc: fhandler for // and //MACHINE handling
|
||||||
|
|
||||||
Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013 Red Hat, Inc.
|
Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -175,7 +175,7 @@ fhandler_netdrive::fhandler_netdrive ():
|
|||||||
}
|
}
|
||||||
|
|
||||||
int __reg2
|
int __reg2
|
||||||
fhandler_netdrive::fstat (struct __stat64 *buf)
|
fhandler_netdrive::fstat (struct stat *buf)
|
||||||
{
|
{
|
||||||
const char *path = get_name ();
|
const char *path = get_name ();
|
||||||
debug_printf ("fstat (%s)", path);
|
debug_printf ("fstat (%s)", path);
|
||||||
@ -246,7 +246,7 @@ fhandler_netdrive::readdir (DIR *dir, dirent *de)
|
|||||||
de->d_ino = readdir_get_ino (nro->lpRemoteName, false);
|
de->d_ino = readdir_get_ino (nro->lpRemoteName, false);
|
||||||
/* We can't trust remote inode numbers of only 32 bit. That means,
|
/* We can't trust remote inode numbers of only 32 bit. That means,
|
||||||
remote NT4 NTFS, as well as shares of Samba version < 3.0. */
|
remote NT4 NTFS, as well as shares of Samba version < 3.0. */
|
||||||
if (de->d_ino <= UINT_MAX)
|
if (de->d_ino <= UINT32_MAX)
|
||||||
de->d_ino = hash_path_name (0, nro->lpRemoteName);
|
de->d_ino = hash_path_name (0, nro->lpRemoteName);
|
||||||
}
|
}
|
||||||
de->d_type = DT_DIR;
|
de->d_type = DT_DIR;
|
||||||
@ -318,7 +318,7 @@ fhandler_netdrive::open (int flags, mode_t mode)
|
|||||||
set_flags ((flags & ~O_TEXT) | O_BINARY | O_DIROPEN);
|
set_flags ((flags & ~O_TEXT) | O_BINARY | O_DIROPEN);
|
||||||
set_open_status ();
|
set_open_status ();
|
||||||
out:
|
out:
|
||||||
syscall_printf ("%d = fhandler_netdrive::open(%p, %d)", res, flags, mode);
|
syscall_printf ("%d = fhandler_netdrive::open(%y, 0%o)", res, flags, mode);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* fhandler_proc.cc: fhandler for /proc virtual filesystem
|
/* fhandler_proc.cc: fhandler for /proc virtual filesystem
|
||||||
|
|
||||||
Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013
|
Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012,
|
||||||
Red Hat, Inc.
|
2013 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -36,19 +36,19 @@ details. */
|
|||||||
#define _COMPILING_NEWLIB
|
#define _COMPILING_NEWLIB
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
|
||||||
static _off64_t format_proc_loadavg (void *, char *&);
|
static off_t format_proc_loadavg (void *, char *&);
|
||||||
static _off64_t format_proc_meminfo (void *, char *&);
|
static off_t format_proc_meminfo (void *, char *&);
|
||||||
static _off64_t format_proc_stat (void *, char *&);
|
static off_t format_proc_stat (void *, char *&);
|
||||||
static _off64_t format_proc_version (void *, char *&);
|
static off_t format_proc_version (void *, char *&);
|
||||||
static _off64_t format_proc_uptime (void *, char *&);
|
static off_t format_proc_uptime (void *, char *&);
|
||||||
static _off64_t format_proc_cpuinfo (void *, char *&);
|
static off_t format_proc_cpuinfo (void *, char *&);
|
||||||
static _off64_t format_proc_partitions (void *, char *&);
|
static off_t format_proc_partitions (void *, char *&);
|
||||||
static _off64_t format_proc_self (void *, char *&);
|
static off_t format_proc_self (void *, char *&);
|
||||||
static _off64_t format_proc_mounts (void *, char *&);
|
static off_t format_proc_mounts (void *, char *&);
|
||||||
static _off64_t format_proc_filesystems (void *, char *&);
|
static off_t format_proc_filesystems (void *, char *&);
|
||||||
static _off64_t format_proc_swaps (void *, char *&);
|
static off_t format_proc_swaps (void *, char *&);
|
||||||
static _off64_t format_proc_devices (void *, char *&);
|
static off_t format_proc_devices (void *, char *&);
|
||||||
static _off64_t format_proc_misc (void *, char *&);
|
static off_t format_proc_misc (void *, char *&);
|
||||||
|
|
||||||
/* names of objects in /proc */
|
/* names of objects in /proc */
|
||||||
static const virt_tab_t proc_tab[] = {
|
static const virt_tab_t proc_tab[] = {
|
||||||
@ -185,7 +185,7 @@ fhandler_proc::fhandler_proc ():
|
|||||||
}
|
}
|
||||||
|
|
||||||
int __reg2
|
int __reg2
|
||||||
fhandler_proc::fstat (struct __stat64 *buf)
|
fhandler_proc::fstat (struct stat *buf)
|
||||||
{
|
{
|
||||||
const char *path = get_name ();
|
const char *path = get_name ();
|
||||||
debug_printf ("fstat (%s)", path);
|
debug_printf ("fstat (%s)", path);
|
||||||
@ -377,7 +377,7 @@ success:
|
|||||||
set_flags ((flags & ~O_TEXT) | O_BINARY);
|
set_flags ((flags & ~O_TEXT) | O_BINARY);
|
||||||
set_open_status ();
|
set_open_status ();
|
||||||
out:
|
out:
|
||||||
syscall_printf ("%d = fhandler_proc::open(%p, %d)", res, flags, mode);
|
syscall_printf ("%d = fhandler_proc::open(%y, 0%o)", res, flags, mode);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -393,7 +393,7 @@ fhandler_proc::fill_filebuf ()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_proc_version (void *, char *&destbuf)
|
format_proc_version (void *, char *&destbuf)
|
||||||
{
|
{
|
||||||
tmp_pathbuf tp;
|
tmp_pathbuf tp;
|
||||||
@ -411,7 +411,7 @@ format_proc_version (void *, char *&destbuf)
|
|||||||
return bufptr - buf;
|
return bufptr - buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_proc_loadavg (void *, char *&destbuf)
|
format_proc_loadavg (void *, char *&destbuf)
|
||||||
{
|
{
|
||||||
extern int get_process_state (DWORD dwProcessId);
|
extern int get_process_state (DWORD dwProcessId);
|
||||||
@ -431,7 +431,7 @@ format_proc_loadavg (void *, char *&destbuf)
|
|||||||
0, 0, 0, 0, 0, 0, running, pids.npids);
|
0, 0, 0, 0, 0, 0, running, pids.npids);
|
||||||
}
|
}
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_proc_meminfo (void *, char *&destbuf)
|
format_proc_meminfo (void *, char *&destbuf)
|
||||||
{
|
{
|
||||||
unsigned long long mem_total, mem_free, swap_total, swap_free;
|
unsigned long long mem_total, mem_free, swap_total, swap_free;
|
||||||
@ -457,12 +457,12 @@ format_proc_meminfo (void *, char *&destbuf)
|
|||||||
swap_total >> 10, swap_free >> 10);
|
swap_total >> 10, swap_free >> 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_proc_uptime (void *, char *&destbuf)
|
format_proc_uptime (void *, char *&destbuf)
|
||||||
{
|
{
|
||||||
unsigned long long uptime = 0ULL, idle_time = 0ULL;
|
unsigned long long uptime = 0ULL, idle_time = 0ULL;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
SYSTEM_TIME_OF_DAY_INFORMATION stodi;
|
SYSTEM_TIMEOFDAY_INFORMATION stodi;
|
||||||
/* Sizeof SYSTEM_PERFORMANCE_INFORMATION on 64 bit systems. It
|
/* Sizeof SYSTEM_PERFORMANCE_INFORMATION on 64 bit systems. It
|
||||||
appears to contain some trailing additional information from
|
appears to contain some trailing additional information from
|
||||||
what I can tell after examining the content.
|
what I can tell after examining the content.
|
||||||
@ -477,7 +477,7 @@ format_proc_uptime (void *, char *&destbuf)
|
|||||||
uptime = (stodi.CurrentTime.QuadPart - stodi.BootTime.QuadPart) / 100000ULL;
|
uptime = (stodi.CurrentTime.QuadPart - stodi.BootTime.QuadPart) / 100000ULL;
|
||||||
else
|
else
|
||||||
debug_printf ("NtQuerySystemInformation(SystemTimeOfDayInformation), "
|
debug_printf ("NtQuerySystemInformation(SystemTimeOfDayInformation), "
|
||||||
"status %p", status);
|
"status %y", status);
|
||||||
|
|
||||||
if (NT_SUCCESS (NtQuerySystemInformation (SystemPerformanceInformation,
|
if (NT_SUCCESS (NtQuerySystemInformation (SystemPerformanceInformation,
|
||||||
spi, sizeof_spi, NULL)))
|
spi, sizeof_spi, NULL)))
|
||||||
@ -490,7 +490,7 @@ format_proc_uptime (void *, char *&destbuf)
|
|||||||
idle_time / 100, long (idle_time % 100));
|
idle_time / 100, long (idle_time % 100));
|
||||||
}
|
}
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_proc_stat (void *, char *&destbuf)
|
format_proc_stat (void *, char *&destbuf)
|
||||||
{
|
{
|
||||||
unsigned long pages_in = 0UL, pages_out = 0UL, interrupt_count = 0UL,
|
unsigned long pages_in = 0UL, pages_out = 0UL, interrupt_count = 0UL,
|
||||||
@ -504,18 +504,19 @@ format_proc_stat (void *, char *&destbuf)
|
|||||||
const size_t sizeof_spi = sizeof (SYSTEM_PERFORMANCE_INFORMATION) + 16;
|
const size_t sizeof_spi = sizeof (SYSTEM_PERFORMANCE_INFORMATION) + 16;
|
||||||
PSYSTEM_PERFORMANCE_INFORMATION spi = (PSYSTEM_PERFORMANCE_INFORMATION)
|
PSYSTEM_PERFORMANCE_INFORMATION spi = (PSYSTEM_PERFORMANCE_INFORMATION)
|
||||||
alloca (sizeof_spi);
|
alloca (sizeof_spi);
|
||||||
SYSTEM_TIME_OF_DAY_INFORMATION stodi;
|
SYSTEM_TIMEOFDAY_INFORMATION stodi;
|
||||||
tmp_pathbuf tp;
|
tmp_pathbuf tp;
|
||||||
|
|
||||||
char *buf = tp.c_get ();
|
char *buf = tp.c_get ();
|
||||||
char *eobuf = buf;
|
char *eobuf = buf;
|
||||||
|
|
||||||
SYSTEM_PROCESSOR_TIMES spt[wincap.cpu_count ()];
|
SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION spt[wincap.cpu_count ()];
|
||||||
status = NtQuerySystemInformation (SystemProcessorTimes, (PVOID) spt,
|
status = NtQuerySystemInformation (SystemProcessorPerformanceInformation,
|
||||||
|
(PVOID) spt,
|
||||||
sizeof spt[0] * wincap.cpu_count (), NULL);
|
sizeof spt[0] * wincap.cpu_count (), NULL);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
debug_printf ("NtQuerySystemInformation(SystemProcessorTimes), "
|
debug_printf ("NtQuerySystemInformation(SystemProcessorPerformanceInformation), "
|
||||||
"status %p", status);
|
"status %y", status);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned long long user_time = 0ULL, kernel_time = 0ULL, idle_time = 0ULL;
|
unsigned long long user_time = 0ULL, kernel_time = 0ULL, idle_time = 0ULL;
|
||||||
@ -545,14 +546,14 @@ format_proc_stat (void *, char *&destbuf)
|
|||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
debug_printf ("NtQuerySystemInformation(SystemPerformanceInformation)"
|
debug_printf ("NtQuerySystemInformation(SystemPerformanceInformation)"
|
||||||
", status %p", status);
|
", status %y", status);
|
||||||
memset (spi, 0, sizeof_spi);
|
memset (spi, 0, sizeof_spi);
|
||||||
}
|
}
|
||||||
status = NtQuerySystemInformation (SystemTimeOfDayInformation,
|
status = NtQuerySystemInformation (SystemTimeOfDayInformation,
|
||||||
(PVOID) &stodi, sizeof stodi, NULL);
|
(PVOID) &stodi, sizeof stodi, NULL);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
debug_printf ("NtQuerySystemInformation(SystemTimeOfDayInformation), "
|
debug_printf ("NtQuerySystemInformation(SystemTimeOfDayInformation), "
|
||||||
"status %p", status);
|
"status %y", status);
|
||||||
}
|
}
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
@ -588,7 +589,7 @@ format_proc_stat (void *, char *&destbuf)
|
|||||||
|
|
||||||
#define print(x) { bufptr = stpcpy (bufptr, (x)); }
|
#define print(x) { bufptr = stpcpy (bufptr, (x)); }
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_proc_cpuinfo (void *, char *&destbuf)
|
format_proc_cpuinfo (void *, char *&destbuf)
|
||||||
{
|
{
|
||||||
DWORD orig_affinity_mask;
|
DWORD orig_affinity_mask;
|
||||||
@ -1078,7 +1079,7 @@ format_proc_cpuinfo (void *, char *&destbuf)
|
|||||||
return bufptr - buf;
|
return bufptr - buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_proc_partitions (void *, char *&destbuf)
|
format_proc_partitions (void *, char *&destbuf)
|
||||||
{
|
{
|
||||||
OBJECT_ATTRIBUTES attr;
|
OBJECT_ATTRIBUTES attr;
|
||||||
@ -1098,7 +1099,7 @@ format_proc_partitions (void *, char *&destbuf)
|
|||||||
status = NtOpenDirectoryObject (&dirhdl, DIRECTORY_QUERY, &attr);
|
status = NtOpenDirectoryObject (&dirhdl, DIRECTORY_QUERY, &attr);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
debug_printf ("NtOpenDirectoryObject, status %p", status);
|
debug_printf ("NtOpenDirectoryObject, status %y", status);
|
||||||
__seterrno_from_nt_status (status);
|
__seterrno_from_nt_status (status);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1138,14 +1139,11 @@ format_proc_partitions (void *, char *&destbuf)
|
|||||||
upath.MaximumLength = upath.Length + sizeof (WCHAR);
|
upath.MaximumLength = upath.Length + sizeof (WCHAR);
|
||||||
InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE,
|
InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE,
|
||||||
dirhdl, NULL);
|
dirhdl, NULL);
|
||||||
/* Up to W2K the handle needs read access to fetch the partition info. */
|
status = NtOpenFile (&devhdl, READ_CONTROL, &attr, &io,
|
||||||
status = NtOpenFile (&devhdl, wincap.has_disk_ex_ioctls ()
|
FILE_SHARE_VALID_FLAGS, 0);
|
||||||
? READ_CONTROL
|
|
||||||
: READ_CONTROL | FILE_READ_DATA,
|
|
||||||
&attr, &io, FILE_SHARE_VALID_FLAGS, 0);
|
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
debug_printf ("NtOpenFile(%S), status %p", &upath, status);
|
debug_printf ("NtOpenFile(%S), status %y", &upath, status);
|
||||||
__seterrno_from_nt_status (status);
|
__seterrno_from_nt_status (status);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1155,9 +1153,8 @@ format_proc_partitions (void *, char *&destbuf)
|
|||||||
got_one = true;
|
got_one = true;
|
||||||
}
|
}
|
||||||
/* Fetch partition info for the entire disk to get its size. */
|
/* Fetch partition info for the entire disk to get its size. */
|
||||||
if (wincap.has_disk_ex_ioctls ()
|
if (DeviceIoControl (devhdl, IOCTL_DISK_GET_PARTITION_INFO_EX, NULL, 0,
|
||||||
&& DeviceIoControl (devhdl, IOCTL_DISK_GET_PARTITION_INFO_EX, NULL, 0,
|
ioctl_buf, NT_MAX_PATH, &bytes_read, NULL))
|
||||||
ioctl_buf, NT_MAX_PATH, &bytes_read, NULL))
|
|
||||||
{
|
{
|
||||||
pix = (PARTITION_INFORMATION_EX *) ioctl_buf;
|
pix = (PARTITION_INFORMATION_EX *) ioctl_buf;
|
||||||
size = pix->PartitionLength.QuadPart;
|
size = pix->PartitionLength.QuadPart;
|
||||||
@ -1179,9 +1176,8 @@ format_proc_partitions (void *, char *&destbuf)
|
|||||||
dev.get_major (), dev.get_minor (),
|
dev.get_major (), dev.get_minor (),
|
||||||
size >> 10, dev.name + 5);
|
size >> 10, dev.name + 5);
|
||||||
/* Fetch drive layout info to get size of all partitions on the disk. */
|
/* Fetch drive layout info to get size of all partitions on the disk. */
|
||||||
if (wincap.has_disk_ex_ioctls ()
|
if (DeviceIoControl (devhdl, IOCTL_DISK_GET_DRIVE_LAYOUT_EX,
|
||||||
&& DeviceIoControl (devhdl, IOCTL_DISK_GET_DRIVE_LAYOUT_EX,
|
NULL, 0, ioctl_buf, NT_MAX_PATH, &bytes_read, NULL))
|
||||||
NULL, 0, ioctl_buf, NT_MAX_PATH, &bytes_read, NULL))
|
|
||||||
{
|
{
|
||||||
PDRIVE_LAYOUT_INFORMATION_EX pdlix = (PDRIVE_LAYOUT_INFORMATION_EX)
|
PDRIVE_LAYOUT_INFORMATION_EX pdlix = (PDRIVE_LAYOUT_INFORMATION_EX)
|
||||||
ioctl_buf;
|
ioctl_buf;
|
||||||
@ -1213,13 +1209,7 @@ format_proc_partitions (void *, char *&destbuf)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
size = pi->PartitionLength.QuadPart;
|
size = pi->PartitionLength.QuadPart;
|
||||||
/* Pre-W2K you can't rely on the partition number info for
|
part_num = pi->PartitionNumber;
|
||||||
unused partitions. */
|
|
||||||
if (pi->PartitionType == PARTITION_ENTRY_UNUSED
|
|
||||||
|| pi->PartitionType == PARTITION_EXTENDED)
|
|
||||||
part_num = 0;
|
|
||||||
else
|
|
||||||
part_num = pi->PartitionNumber;
|
|
||||||
++pi;
|
++pi;
|
||||||
}
|
}
|
||||||
/* A partition number of 0 denotes an extended partition or a
|
/* A partition number of 0 denotes an extended partition or a
|
||||||
@ -1244,21 +1234,21 @@ format_proc_partitions (void *, char *&destbuf)
|
|||||||
return bufptr - buf;
|
return bufptr - buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_proc_self (void *, char *&destbuf)
|
format_proc_self (void *, char *&destbuf)
|
||||||
{
|
{
|
||||||
destbuf = (char *) crealloc_abort (destbuf, 16);
|
destbuf = (char *) crealloc_abort (destbuf, 16);
|
||||||
return __small_sprintf (destbuf, "%d", getpid ());
|
return __small_sprintf (destbuf, "%d", getpid ());
|
||||||
}
|
}
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_proc_mounts (void *, char *&destbuf)
|
format_proc_mounts (void *, char *&destbuf)
|
||||||
{
|
{
|
||||||
destbuf = (char *) crealloc_abort (destbuf, sizeof ("self/mounts"));
|
destbuf = (char *) crealloc_abort (destbuf, sizeof ("self/mounts"));
|
||||||
return __small_sprintf (destbuf, "self/mounts");
|
return __small_sprintf (destbuf, "self/mounts");
|
||||||
}
|
}
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_proc_filesystems (void *, char *&destbuf)
|
format_proc_filesystems (void *, char *&destbuf)
|
||||||
{
|
{
|
||||||
tmp_pathbuf tp;
|
tmp_pathbuf tp;
|
||||||
@ -1276,7 +1266,7 @@ format_proc_filesystems (void *, char *&destbuf)
|
|||||||
return bufptr - buf;
|
return bufptr - buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_proc_swaps (void *, char *&destbuf)
|
format_proc_swaps (void *, char *&destbuf)
|
||||||
{
|
{
|
||||||
unsigned long long total = 0ULL, used = 0ULL;
|
unsigned long long total = 0ULL, used = 0ULL;
|
||||||
@ -1338,7 +1328,7 @@ format_proc_swaps (void *, char *&destbuf)
|
|||||||
return bufptr - buf;
|
return bufptr - buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_proc_devices (void *, char *&destbuf)
|
format_proc_devices (void *, char *&destbuf)
|
||||||
{
|
{
|
||||||
tmp_pathbuf tp;
|
tmp_pathbuf tp;
|
||||||
@ -1382,7 +1372,7 @@ format_proc_devices (void *, char *&destbuf)
|
|||||||
return bufptr - buf;
|
return bufptr - buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_proc_misc (void *, char *&destbuf)
|
format_proc_misc (void *, char *&destbuf)
|
||||||
{
|
{
|
||||||
tmp_pathbuf tp;
|
tmp_pathbuf tp;
|
||||||
|
@ -34,25 +34,25 @@ details. */
|
|||||||
#define _COMPILING_NEWLIB
|
#define _COMPILING_NEWLIB
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
|
||||||
static _off64_t format_process_maps (void *, char *&);
|
static off_t format_process_maps (void *, char *&);
|
||||||
static _off64_t format_process_stat (void *, char *&);
|
static off_t format_process_stat (void *, char *&);
|
||||||
static _off64_t format_process_status (void *, char *&);
|
static off_t format_process_status (void *, char *&);
|
||||||
static _off64_t format_process_statm (void *, char *&);
|
static off_t format_process_statm (void *, char *&);
|
||||||
static _off64_t format_process_winexename (void *, char *&);
|
static off_t format_process_winexename (void *, char *&);
|
||||||
static _off64_t format_process_winpid (void *, char *&);
|
static off_t format_process_winpid (void *, char *&);
|
||||||
static _off64_t format_process_exename (void *, char *&);
|
static off_t format_process_exename (void *, char *&);
|
||||||
static _off64_t format_process_root (void *, char *&);
|
static off_t format_process_root (void *, char *&);
|
||||||
static _off64_t format_process_cwd (void *, char *&);
|
static off_t format_process_cwd (void *, char *&);
|
||||||
static _off64_t format_process_cmdline (void *, char *&);
|
static off_t format_process_cmdline (void *, char *&);
|
||||||
static _off64_t format_process_ppid (void *, char *&);
|
static off_t format_process_ppid (void *, char *&);
|
||||||
static _off64_t format_process_uid (void *, char *&);
|
static off_t format_process_uid (void *, char *&);
|
||||||
static _off64_t format_process_pgid (void *, char *&);
|
static off_t format_process_pgid (void *, char *&);
|
||||||
static _off64_t format_process_sid (void *, char *&);
|
static off_t format_process_sid (void *, char *&);
|
||||||
static _off64_t format_process_gid (void *, char *&);
|
static off_t format_process_gid (void *, char *&);
|
||||||
static _off64_t format_process_ctty (void *, char *&);
|
static off_t format_process_ctty (void *, char *&);
|
||||||
static _off64_t format_process_fd (void *, char *&);
|
static off_t format_process_fd (void *, char *&);
|
||||||
static _off64_t format_process_mounts (void *, char *&);
|
static off_t format_process_mounts (void *, char *&);
|
||||||
static _off64_t format_process_mountinfo (void *, char *&);
|
static off_t format_process_mountinfo (void *, char *&);
|
||||||
|
|
||||||
static const virt_tab_t process_tab[] =
|
static const virt_tab_t process_tab[] =
|
||||||
{
|
{
|
||||||
@ -137,7 +137,7 @@ fhandler_process::fhandler_process ():
|
|||||||
}
|
}
|
||||||
|
|
||||||
int __reg2
|
int __reg2
|
||||||
fhandler_process::fstat (struct __stat64 *buf)
|
fhandler_process::fstat (struct stat *buf)
|
||||||
{
|
{
|
||||||
const char *path = get_name ();
|
const char *path = get_name ();
|
||||||
int file_type = exists ();
|
int file_type = exists ();
|
||||||
@ -222,7 +222,7 @@ fhandler_process::readdir (DIR *dir, dirent *de)
|
|||||||
int res = ENMFILE;
|
int res = ENMFILE;
|
||||||
if (process_tab[fileid].fhandler == FH_PROCESSFD)
|
if (process_tab[fileid].fhandler == FH_PROCESSFD)
|
||||||
{
|
{
|
||||||
if (dir->__d_position >= 2 + filesize / sizeof (int))
|
if ((size_t) dir->__d_position >= 2 + filesize / sizeof (int))
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
else if (dir->__d_position >= PROCESS_LINK_COUNT)
|
else if (dir->__d_position >= PROCESS_LINK_COUNT)
|
||||||
@ -314,7 +314,7 @@ success:
|
|||||||
set_flags ((flags & ~O_TEXT) | O_BINARY);
|
set_flags ((flags & ~O_TEXT) | O_BINARY);
|
||||||
set_open_status ();
|
set_open_status ();
|
||||||
out:
|
out:
|
||||||
syscall_printf ("%d = fhandler_proc::open(%p, %d)", res, flags, mode);
|
syscall_printf ("%d = fhandler_proc::open(%y, 0%o)", res, flags, mode);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -356,7 +356,7 @@ fhandler_process::fill_filebuf ()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_process_fd (void *data, char *&destbuf)
|
format_process_fd (void *data, char *&destbuf)
|
||||||
{
|
{
|
||||||
_pinfo *p = ((process_fd_t *) data)->p;
|
_pinfo *p = ((process_fd_t *) data)->p;
|
||||||
@ -390,7 +390,7 @@ format_process_fd (void *data, char *&destbuf)
|
|||||||
return fs;
|
return fs;
|
||||||
}
|
}
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_process_ppid (void *data, char *&destbuf)
|
format_process_ppid (void *data, char *&destbuf)
|
||||||
{
|
{
|
||||||
_pinfo *p = (_pinfo *) data;
|
_pinfo *p = (_pinfo *) data;
|
||||||
@ -398,7 +398,7 @@ format_process_ppid (void *data, char *&destbuf)
|
|||||||
return __small_sprintf (destbuf, "%d\n", p->ppid);
|
return __small_sprintf (destbuf, "%d\n", p->ppid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_process_uid (void *data, char *&destbuf)
|
format_process_uid (void *data, char *&destbuf)
|
||||||
{
|
{
|
||||||
_pinfo *p = (_pinfo *) data;
|
_pinfo *p = (_pinfo *) data;
|
||||||
@ -406,7 +406,7 @@ format_process_uid (void *data, char *&destbuf)
|
|||||||
return __small_sprintf (destbuf, "%d\n", p->uid);
|
return __small_sprintf (destbuf, "%d\n", p->uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_process_pgid (void *data, char *&destbuf)
|
format_process_pgid (void *data, char *&destbuf)
|
||||||
{
|
{
|
||||||
_pinfo *p = (_pinfo *) data;
|
_pinfo *p = (_pinfo *) data;
|
||||||
@ -414,7 +414,7 @@ format_process_pgid (void *data, char *&destbuf)
|
|||||||
return __small_sprintf (destbuf, "%d\n", p->pgid);
|
return __small_sprintf (destbuf, "%d\n", p->pgid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_process_sid (void *data, char *&destbuf)
|
format_process_sid (void *data, char *&destbuf)
|
||||||
{
|
{
|
||||||
_pinfo *p = (_pinfo *) data;
|
_pinfo *p = (_pinfo *) data;
|
||||||
@ -422,7 +422,7 @@ format_process_sid (void *data, char *&destbuf)
|
|||||||
return __small_sprintf (destbuf, "%d\n", p->sid);
|
return __small_sprintf (destbuf, "%d\n", p->sid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_process_gid (void *data, char *&destbuf)
|
format_process_gid (void *data, char *&destbuf)
|
||||||
{
|
{
|
||||||
_pinfo *p = (_pinfo *) data;
|
_pinfo *p = (_pinfo *) data;
|
||||||
@ -430,7 +430,7 @@ format_process_gid (void *data, char *&destbuf)
|
|||||||
return __small_sprintf (destbuf, "%d\n", p->gid);
|
return __small_sprintf (destbuf, "%d\n", p->gid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_process_ctty (void *data, char *&destbuf)
|
format_process_ctty (void *data, char *&destbuf)
|
||||||
{
|
{
|
||||||
device d;
|
device d;
|
||||||
@ -440,7 +440,7 @@ format_process_ctty (void *data, char *&destbuf)
|
|||||||
return __small_sprintf (destbuf, "%s\n", d.name);
|
return __small_sprintf (destbuf, "%s\n", d.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_process_root (void *data, char *&destbuf)
|
format_process_root (void *data, char *&destbuf)
|
||||||
{
|
{
|
||||||
_pinfo *p = (_pinfo *) data;
|
_pinfo *p = (_pinfo *) data;
|
||||||
@ -460,7 +460,7 @@ format_process_root (void *data, char *&destbuf)
|
|||||||
return fs;
|
return fs;
|
||||||
}
|
}
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_process_cwd (void *data, char *&destbuf)
|
format_process_cwd (void *data, char *&destbuf)
|
||||||
{
|
{
|
||||||
_pinfo *p = (_pinfo *) data;
|
_pinfo *p = (_pinfo *) data;
|
||||||
@ -480,7 +480,7 @@ format_process_cwd (void *data, char *&destbuf)
|
|||||||
return fs;
|
return fs;
|
||||||
}
|
}
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_process_cmdline (void *data, char *&destbuf)
|
format_process_cmdline (void *data, char *&destbuf)
|
||||||
{
|
{
|
||||||
_pinfo *p = (_pinfo *) data;
|
_pinfo *p = (_pinfo *) data;
|
||||||
@ -500,7 +500,7 @@ format_process_cmdline (void *data, char *&destbuf)
|
|||||||
return fs;
|
return fs;
|
||||||
}
|
}
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_process_exename (void *data, char *&destbuf)
|
format_process_exename (void *data, char *&destbuf)
|
||||||
{
|
{
|
||||||
_pinfo *p = (_pinfo *) data;
|
_pinfo *p = (_pinfo *) data;
|
||||||
@ -526,7 +526,7 @@ format_process_exename (void *data, char *&destbuf)
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_process_winpid (void *data, char *&destbuf)
|
format_process_winpid (void *data, char *&destbuf)
|
||||||
{
|
{
|
||||||
_pinfo *p = (_pinfo *) data;
|
_pinfo *p = (_pinfo *) data;
|
||||||
@ -534,7 +534,7 @@ format_process_winpid (void *data, char *&destbuf)
|
|||||||
return __small_sprintf (destbuf, "%d\n", p->dwProcessId);
|
return __small_sprintf (destbuf, "%d\n", p->dwProcessId);
|
||||||
}
|
}
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_process_winexename (void *data, char *&destbuf)
|
format_process_winexename (void *data, char *&destbuf)
|
||||||
{
|
{
|
||||||
_pinfo *p = (_pinfo *) data;
|
_pinfo *p = (_pinfo *) data;
|
||||||
@ -647,15 +647,15 @@ struct thread_info
|
|||||||
{
|
{
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
PVOID buf = NULL;
|
PVOID buf = NULL;
|
||||||
size_t size = 50 * (sizeof (SYSTEM_PROCESSES)
|
ULONG size = 50 * (sizeof (SYSTEM_PROCESS_INFORMATION)
|
||||||
+ 16 * sizeof (SYSTEM_THREADS));
|
+ 16 * sizeof (SYSTEM_THREADS));
|
||||||
PSYSTEM_PROCESSES proc;
|
PSYSTEM_PROCESS_INFORMATION proc;
|
||||||
PSYSTEM_THREADS thread;
|
PSYSTEM_THREADS thread;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
buf = realloc (buf, size);
|
buf = realloc (buf, size);
|
||||||
status = NtQuerySystemInformation (SystemProcessesAndThreadsInformation,
|
status = NtQuerySystemInformation (SystemProcessInformation,
|
||||||
buf, size, NULL);
|
buf, size, NULL);
|
||||||
size <<= 1;
|
size <<= 1;
|
||||||
}
|
}
|
||||||
@ -664,30 +664,30 @@ struct thread_info
|
|||||||
{
|
{
|
||||||
if (buf)
|
if (buf)
|
||||||
free (buf);
|
free (buf);
|
||||||
debug_printf ("NtQuerySystemInformation, %p", status);
|
debug_printf ("NtQuerySystemInformation, %y", status);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
proc = (PSYSTEM_PROCESSES) buf;
|
proc = (PSYSTEM_PROCESS_INFORMATION) buf;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (proc->ProcessId == pid)
|
if ((DWORD) (uintptr_t) proc->UniqueProcessId == pid)
|
||||||
break;
|
break;
|
||||||
if (!proc->NextEntryDelta)
|
if (!proc->NextEntryOffset)
|
||||||
{
|
{
|
||||||
free (buf);
|
free (buf);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
proc = (PSYSTEM_PROCESSES) ((PBYTE) proc + proc->NextEntryDelta);
|
proc = (PSYSTEM_PROCESS_INFORMATION) ((PBYTE) proc + proc->NextEntryOffset);
|
||||||
}
|
}
|
||||||
thread = proc->Threads;
|
thread = proc->Threads;
|
||||||
for (ULONG i = 0; i < proc->ThreadCount; ++i)
|
for (ULONG i = 0; i < proc->NumberOfThreads; ++i)
|
||||||
{
|
{
|
||||||
THREAD_BASIC_INFORMATION tbi;
|
THREAD_BASIC_INFORMATION tbi;
|
||||||
TEB teb;
|
TEB teb;
|
||||||
HANDLE thread_h;
|
HANDLE thread_h;
|
||||||
|
|
||||||
if (!(thread_h = OpenThread (THREAD_QUERY_INFORMATION, FALSE,
|
if (!(thread_h = OpenThread (THREAD_QUERY_INFORMATION, FALSE,
|
||||||
(ULONG) thread[i].ClientId.UniqueThread)))
|
(ULONG) (ULONG_PTR) thread[i].ClientId.UniqueThread)))
|
||||||
continue;
|
continue;
|
||||||
status = NtQueryInformationThread (thread_h, ThreadBasicInformation,
|
status = NtQueryInformationThread (thread_h, ThreadBasicInformation,
|
||||||
&tbi, sizeof tbi, NULL);
|
&tbi, sizeof tbi, NULL);
|
||||||
@ -697,7 +697,7 @@ struct thread_info
|
|||||||
region *r = (region *) malloc (sizeof (region));
|
region *r = (region *) malloc (sizeof (region));
|
||||||
if (r)
|
if (r)
|
||||||
{
|
{
|
||||||
*r = (region) { regions, (ULONG) thread[i].ClientId.UniqueThread,
|
*r = (region) { regions, (ULONG) (ULONG_PTR) thread[i].ClientId.UniqueThread,
|
||||||
(char *) tbi.TebBaseAddress,
|
(char *) tbi.TebBaseAddress,
|
||||||
(char *) tbi.TebBaseAddress + wincap.page_size (),
|
(char *) tbi.TebBaseAddress + wincap.page_size (),
|
||||||
true };
|
true };
|
||||||
@ -709,7 +709,7 @@ struct thread_info
|
|||||||
r = (region *) malloc (sizeof (region));
|
r = (region *) malloc (sizeof (region));
|
||||||
if (r)
|
if (r)
|
||||||
{
|
{
|
||||||
*r = (region) { regions, (ULONG) thread[i].ClientId.UniqueThread,
|
*r = (region) { regions, (ULONG) (ULONG_PTR) thread[i].ClientId.UniqueThread,
|
||||||
(char *) (teb.DeallocationStack
|
(char *) (teb.DeallocationStack
|
||||||
?: teb.Tib.StackLimit),
|
?: teb.Tib.StackLimit),
|
||||||
(char *) teb.Tib.StackBase,
|
(char *) teb.Tib.StackBase,
|
||||||
@ -751,7 +751,7 @@ struct thread_info
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_process_maps (void *data, char *&destbuf)
|
format_process_maps (void *data, char *&destbuf)
|
||||||
{
|
{
|
||||||
_pinfo *p = (_pinfo *) data;
|
_pinfo *p = (_pinfo *) data;
|
||||||
@ -780,12 +780,12 @@ format_process_maps (void *data, char *&destbuf)
|
|||||||
ReadProcessMemory (proc, &cygheap->user_heap, &user_heap,
|
ReadProcessMemory (proc, &cygheap->user_heap, &user_heap,
|
||||||
sizeof user_heap, NULL);
|
sizeof user_heap, NULL);
|
||||||
|
|
||||||
_off64_t len = 0;
|
off_t len = 0;
|
||||||
|
|
||||||
union access
|
union access
|
||||||
{
|
{
|
||||||
char flags[8];
|
char flags[8];
|
||||||
_off64_t word;
|
off_t word;
|
||||||
} a;
|
} a;
|
||||||
|
|
||||||
struct region {
|
struct region {
|
||||||
@ -799,7 +799,7 @@ format_process_maps (void *data, char *&destbuf)
|
|||||||
dos_drive_mappings drive_maps;
|
dos_drive_mappings drive_maps;
|
||||||
heap_info heaps (p->dwProcessId);
|
heap_info heaps (p->dwProcessId);
|
||||||
thread_info threads (p->dwProcessId, proc);
|
thread_info threads (p->dwProcessId, proc);
|
||||||
struct __stat64 st;
|
struct stat st;
|
||||||
long last_pass = 0;
|
long last_pass = 0;
|
||||||
|
|
||||||
tmp_pathbuf tp;
|
tmp_pathbuf tp;
|
||||||
@ -815,7 +815,12 @@ format_process_maps (void *data, char *&destbuf)
|
|||||||
|
|
||||||
/* Iterate over each VM region in the address space, coalescing
|
/* Iterate over each VM region in the address space, coalescing
|
||||||
memory regions with the same permissions. Once we run out, do one
|
memory regions with the same permissions. Once we run out, do one
|
||||||
last_pass to trigger output of the last accumulated region. */
|
last_pass to trigger output of the last accumulated region.
|
||||||
|
|
||||||
|
FIXME: 32 bit processes can't get address information beyond the
|
||||||
|
32 bit address space from 64 bit processes. We have to run
|
||||||
|
this functionality in the target process, if the target
|
||||||
|
process is 64 bit and our own process is 32 bit. */
|
||||||
for (char *i = 0;
|
for (char *i = 0;
|
||||||
VirtualQueryEx (proc, i, &mb, sizeof(mb)) || (1 == ++last_pass);
|
VirtualQueryEx (proc, i, &mb, sizeof(mb)) || (1 == ++last_pass);
|
||||||
i = cur.rend)
|
i = cur.rend)
|
||||||
@ -867,9 +872,9 @@ format_process_maps (void *data, char *&destbuf)
|
|||||||
{
|
{
|
||||||
size_t newlen = strlen (posix_modname) + 62;
|
size_t newlen = strlen (posix_modname) + 62;
|
||||||
if (len + newlen >= maxsize)
|
if (len + newlen >= maxsize)
|
||||||
destbuf = (char *) crealloc_abort (destbuf,
|
destbuf = (char *)
|
||||||
maxsize += roundup2 (newlen,
|
crealloc_abort (destbuf,
|
||||||
2048));
|
maxsize += roundup2 (newlen, 2048UL));
|
||||||
int written = __small_sprintf (destbuf + len,
|
int written = __small_sprintf (destbuf + len,
|
||||||
"%08lx-%08lx %s %08lx %04x:%04x %U ",
|
"%08lx-%08lx %s %08lx %04x:%04x %U ",
|
||||||
cur.rbase, cur.rend, cur.a.flags,
|
cur.rbase, cur.rend, cur.a.flags,
|
||||||
@ -889,7 +894,7 @@ format_process_maps (void *data, char *&destbuf)
|
|||||||
{
|
{
|
||||||
/* If the return length pointer is missing, NtQueryVirtualMemory
|
/* If the return length pointer is missing, NtQueryVirtualMemory
|
||||||
returns with STATUS_ACCESS_VIOLATION on Windows 2000. */
|
returns with STATUS_ACCESS_VIOLATION on Windows 2000. */
|
||||||
ULONG ret_len = 0;
|
SIZE_T ret_len = 0;
|
||||||
|
|
||||||
st.st_dev = 0;
|
st.st_dev = 0;
|
||||||
st.st_ino = 0;
|
st.st_ino = 0;
|
||||||
@ -932,7 +937,7 @@ format_process_maps (void *data, char *&destbuf)
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_process_stat (void *data, char *&destbuf)
|
format_process_stat (void *data, char *&destbuf)
|
||||||
{
|
{
|
||||||
_pinfo *p = (_pinfo *) data;
|
_pinfo *p = (_pinfo *) data;
|
||||||
@ -975,8 +980,8 @@ format_process_stat (void *data, char *&destbuf)
|
|||||||
KERNEL_USER_TIMES put;
|
KERNEL_USER_TIMES put;
|
||||||
PROCESS_BASIC_INFORMATION pbi;
|
PROCESS_BASIC_INFORMATION pbi;
|
||||||
QUOTA_LIMITS ql;
|
QUOTA_LIMITS ql;
|
||||||
SYSTEM_TIME_OF_DAY_INFORMATION stodi;
|
SYSTEM_TIMEOFDAY_INFORMATION stodi;
|
||||||
SYSTEM_PROCESSOR_TIMES spt;
|
SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION spt;
|
||||||
hProcess = OpenProcess (PROCESS_VM_READ | PROCESS_QUERY_INFORMATION,
|
hProcess = OpenProcess (PROCESS_VM_READ | PROCESS_QUERY_INFORMATION,
|
||||||
FALSE, p->dwProcessId);
|
FALSE, p->dwProcessId);
|
||||||
if (hProcess != NULL)
|
if (hProcess != NULL)
|
||||||
@ -998,19 +1003,19 @@ format_process_stat (void *data, char *&destbuf)
|
|||||||
{
|
{
|
||||||
DWORD error = GetLastError ();
|
DWORD error = GetLastError ();
|
||||||
__seterrno_from_win_error (error);
|
__seterrno_from_win_error (error);
|
||||||
debug_printf ("OpenProcess: ret %d", error);
|
debug_printf ("OpenProcess: ret %u", error);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (NT_SUCCESS (status))
|
if (NT_SUCCESS (status))
|
||||||
status = NtQuerySystemInformation (SystemTimeOfDayInformation,
|
status = NtQuerySystemInformation (SystemTimeOfDayInformation,
|
||||||
(PVOID) &stodi, sizeof stodi, NULL);
|
(PVOID) &stodi, sizeof stodi, NULL);
|
||||||
if (NT_SUCCESS (status))
|
if (NT_SUCCESS (status))
|
||||||
status = NtQuerySystemInformation (SystemProcessorTimes, (PVOID) &spt,
|
status = NtQuerySystemInformation (SystemProcessorPerformanceInformation,
|
||||||
sizeof spt, NULL);
|
(PVOID) &spt, sizeof spt, NULL);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
__seterrno_from_nt_status (status);
|
__seterrno_from_nt_status (status);
|
||||||
debug_printf ("NtQueryInformationProcess: status %p, %E", status);
|
debug_printf ("NtQueryInformationProcess: status %y, %E", status);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
fault_count = vmc.PageFaultCount;
|
fault_count = vmc.PageFaultCount;
|
||||||
@ -1028,7 +1033,13 @@ format_process_stat (void *data, char *&destbuf)
|
|||||||
*/
|
*/
|
||||||
start_time = (spt.KernelTme.QuadPart + spt.UserTime.QuadPart) * HZ / 10000000ULL;
|
start_time = (spt.KernelTme.QuadPart + spt.UserTime.QuadPart) * HZ / 10000000ULL;
|
||||||
#endif
|
#endif
|
||||||
priority = pbi.BasePriority;
|
/* The BasePriority returned to a 32 bit process under WOW64 is
|
||||||
|
apparently broken, for 32 and 64 bit target processes. 64 bit
|
||||||
|
processes get the correct base priority, even for 32 bit processes. */
|
||||||
|
if (wincap.is_wow64 ())
|
||||||
|
priority = 8; /* Default value. */
|
||||||
|
else
|
||||||
|
priority = pbi.BasePriority;
|
||||||
unsigned page_size = wincap.page_size ();
|
unsigned page_size = wincap.page_size ();
|
||||||
vmsize = vmc.PagefileUsage;
|
vmsize = vmc.PagefileUsage;
|
||||||
vmrss = vmc.WorkingSetSize / page_size;
|
vmrss = vmc.WorkingSetSize / page_size;
|
||||||
@ -1037,22 +1048,20 @@ format_process_stat (void *data, char *&destbuf)
|
|||||||
destbuf = (char *) crealloc_abort (destbuf, strlen (cmd) + 320);
|
destbuf = (char *) crealloc_abort (destbuf, strlen (cmd) + 320);
|
||||||
return __small_sprintf (destbuf, "%d (%s) %c "
|
return __small_sprintf (destbuf, "%d (%s) %c "
|
||||||
"%d %d %d %d %d "
|
"%d %d %d %d %d "
|
||||||
"%lu %lu %lu %lu %lu %lu %lu "
|
"%u %lu %lu %u %u %lu %lu "
|
||||||
"%ld %ld %ld %ld %ld %ld "
|
"%ld %ld %d %d %d %d "
|
||||||
"%lu %lu "
|
"%lu %lu "
|
||||||
"%ld "
|
"%ld %lu",
|
||||||
"%lu",
|
p->pid, cmd, state,
|
||||||
p->pid, cmd,
|
p->ppid, p->pgid, p->sid, p->ctty, -1,
|
||||||
state,
|
0, fault_count, fault_count, 0, 0, utime, stime,
|
||||||
p->ppid, p->pgid, p->sid, p->ctty,
|
|
||||||
-1, 0, fault_count, fault_count, 0, 0, utime, stime,
|
|
||||||
utime, stime, priority, 0, 0, 0,
|
utime, stime, priority, 0, 0, 0,
|
||||||
start_time, vmsize,
|
start_time, vmsize,
|
||||||
vmrss, vmmaxrss
|
vmrss, vmmaxrss
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_process_status (void *data, char *&destbuf)
|
format_process_status (void *data, char *&destbuf)
|
||||||
{
|
{
|
||||||
_pinfo *p = (_pinfo *) data;
|
_pinfo *p = (_pinfo *) data;
|
||||||
@ -1139,7 +1148,7 @@ format_process_status (void *data, char *&destbuf)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_process_statm (void *data, char *&destbuf)
|
format_process_statm (void *data, char *&destbuf)
|
||||||
{
|
{
|
||||||
_pinfo *p = (_pinfo *) data;
|
_pinfo *p = (_pinfo *) data;
|
||||||
@ -1158,13 +1167,13 @@ extern "C" {
|
|||||||
struct mntent *getmntent (FILE *);
|
struct mntent *getmntent (FILE *);
|
||||||
};
|
};
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_process_mountstuff (void *data, char *&destbuf, bool mountinfo)
|
format_process_mountstuff (void *data, char *&destbuf, bool mountinfo)
|
||||||
{
|
{
|
||||||
_pinfo *p = (_pinfo *) data;
|
_pinfo *p = (_pinfo *) data;
|
||||||
user_info *u_shared = NULL;
|
user_info *u_shared = NULL;
|
||||||
HANDLE u_hdl = NULL;
|
HANDLE u_hdl = NULL;
|
||||||
_off64_t len = 0;
|
off_t len = 0;
|
||||||
struct mntent *mnt;
|
struct mntent *mnt;
|
||||||
|
|
||||||
if (p->uid != myself->uid)
|
if (p->uid != myself->uid)
|
||||||
@ -1203,7 +1212,7 @@ format_process_mountstuff (void *data, char *&destbuf, bool mountinfo)
|
|||||||
each cygdrive entry if it's a remote drive. If so, ignore it. */
|
each cygdrive entry if it's a remote drive. If so, ignore it. */
|
||||||
if (iteration >= mtab->nmounts && u_hdl)
|
if (iteration >= mtab->nmounts && u_hdl)
|
||||||
{
|
{
|
||||||
WCHAR drive[3] = { mnt->mnt_fsname[0], L':', L'\0' };
|
WCHAR drive[3] = { (WCHAR) mnt->mnt_fsname[0], L':', L'\0' };
|
||||||
disk_type dt = get_disk_type (drive);
|
disk_type dt = get_disk_type (drive);
|
||||||
|
|
||||||
if (dt == DT_SHARE_SMB || dt == DT_SHARE_NFS)
|
if (dt == DT_SHARE_SMB || dt == DT_SHARE_NFS)
|
||||||
@ -1246,13 +1255,13 @@ format_process_mountstuff (void *data, char *&destbuf, bool mountinfo)
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_process_mounts (void *data, char *&destbuf)
|
format_process_mounts (void *data, char *&destbuf)
|
||||||
{
|
{
|
||||||
return format_process_mountstuff (data, destbuf, false);
|
return format_process_mountstuff (data, destbuf, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_process_mountinfo (void *data, char *&destbuf)
|
format_process_mountinfo (void *data, char *&destbuf)
|
||||||
{
|
{
|
||||||
return format_process_mountstuff (data, destbuf, true);
|
return format_process_mountstuff (data, destbuf, true);
|
||||||
@ -1264,28 +1273,28 @@ get_process_state (DWORD dwProcessId)
|
|||||||
/* This isn't really heavy magic - just go through the processes' threads
|
/* This isn't really heavy magic - just go through the processes' threads
|
||||||
one by one and return a value accordingly. Errors are silently ignored. */
|
one by one and return a value accordingly. Errors are silently ignored. */
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
PSYSTEM_PROCESSES p, sp;
|
PSYSTEM_PROCESS_INFORMATION p, sp;
|
||||||
ULONG n = 0x4000;
|
ULONG n = 0x4000;
|
||||||
int state =' ';
|
int state =' ';
|
||||||
|
|
||||||
p = (PSYSTEM_PROCESSES) malloc (n);
|
p = (PSYSTEM_PROCESS_INFORMATION) malloc (n);
|
||||||
if (!p)
|
if (!p)
|
||||||
return state;
|
return state;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
status = NtQuerySystemInformation (SystemProcessesAndThreadsInformation,
|
status = NtQuerySystemInformation (SystemProcessInformation,
|
||||||
(PVOID) p, n, NULL);
|
(PVOID) p, n, NULL);
|
||||||
if (status != STATUS_INFO_LENGTH_MISMATCH)
|
if (status != STATUS_INFO_LENGTH_MISMATCH)
|
||||||
break;
|
break;
|
||||||
n <<= 1;
|
n <<= 1;
|
||||||
PSYSTEM_PROCESSES new_p = (PSYSTEM_PROCESSES) realloc (p, n);
|
PSYSTEM_PROCESS_INFORMATION new_p = (PSYSTEM_PROCESS_INFORMATION) realloc (p, n);
|
||||||
if (!new_p)
|
if (!new_p)
|
||||||
goto out;
|
goto out;
|
||||||
p = new_p;
|
p = new_p;
|
||||||
}
|
}
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
debug_printf ("NtQuerySystemInformation: status %p, %lu",
|
debug_printf ("NtQuerySystemInformation: status %y, %u",
|
||||||
status, RtlNtStatusToDosError (status));
|
status, RtlNtStatusToDosError (status));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -1293,12 +1302,12 @@ get_process_state (DWORD dwProcessId)
|
|||||||
sp = p;
|
sp = p;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if (sp->ProcessId == dwProcessId)
|
if ((DWORD) (uintptr_t) sp->UniqueProcessId == dwProcessId)
|
||||||
{
|
{
|
||||||
SYSTEM_THREADS *st;
|
SYSTEM_THREADS *st;
|
||||||
st = &sp->Threads[0];
|
st = &sp->Threads[0];
|
||||||
state = 'S';
|
state = 'S';
|
||||||
for (unsigned i = 0; i < sp->ThreadCount; i++)
|
for (unsigned i = 0; i < sp->NumberOfThreads; i++)
|
||||||
{
|
{
|
||||||
/* FIXME: at some point we should consider generating 'O' */
|
/* FIXME: at some point we should consider generating 'O' */
|
||||||
if (st->State == StateRunning ||
|
if (st->State == StateRunning ||
|
||||||
@ -1311,9 +1320,9 @@ get_process_state (DWORD dwProcessId)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!sp->NextEntryDelta)
|
if (!sp->NextEntryOffset)
|
||||||
break;
|
break;
|
||||||
sp = (PSYSTEM_PROCESSES) ((char *) sp + sp->NextEntryDelta);
|
sp = (PSYSTEM_PROCESS_INFORMATION) ((char *) sp + sp->NextEntryOffset);
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
free (p);
|
free (p);
|
||||||
@ -1330,7 +1339,7 @@ get_mem_values (DWORD dwProcessId, unsigned long *vmsize, unsigned long *vmrss,
|
|||||||
HANDLE hProcess;
|
HANDLE hProcess;
|
||||||
VM_COUNTERS vmc;
|
VM_COUNTERS vmc;
|
||||||
PMEMORY_WORKING_SET_LIST p;
|
PMEMORY_WORKING_SET_LIST p;
|
||||||
ULONG n = 0x4000, length;
|
SIZE_T n = 0x4000, length;
|
||||||
|
|
||||||
p = (PMEMORY_WORKING_SET_LIST) malloc (n);
|
p = (PMEMORY_WORKING_SET_LIST) malloc (n);
|
||||||
if (!p)
|
if (!p)
|
||||||
@ -1346,7 +1355,7 @@ get_mem_values (DWORD dwProcessId, unsigned long *vmsize, unsigned long *vmrss,
|
|||||||
{
|
{
|
||||||
status = NtQueryVirtualMemory (hProcess, 0, MemoryWorkingSetList,
|
status = NtQueryVirtualMemory (hProcess, 0, MemoryWorkingSetList,
|
||||||
(PVOID) p, n,
|
(PVOID) p, n,
|
||||||
(length = ULONG_MAX, &length));
|
(length = (SIZE_T) -1, &length));
|
||||||
if (status != STATUS_INFO_LENGTH_MISMATCH)
|
if (status != STATUS_INFO_LENGTH_MISMATCH)
|
||||||
break;
|
break;
|
||||||
n <<= 1;
|
n <<= 1;
|
||||||
@ -1358,7 +1367,7 @@ get_mem_values (DWORD dwProcessId, unsigned long *vmsize, unsigned long *vmrss,
|
|||||||
}
|
}
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
debug_printf ("NtQueryVirtualMemory: status %p", status);
|
debug_printf ("NtQueryVirtualMemory: status %y", status);
|
||||||
if (status == STATUS_PROCESS_IS_TERMINATING)
|
if (status == STATUS_PROCESS_IS_TERMINATING)
|
||||||
{
|
{
|
||||||
*vmsize = *vmrss = *vmtext = *vmdata = *vmlib = *vmshare = 0;
|
*vmsize = *vmrss = *vmtext = *vmdata = *vmlib = *vmshare = 0;
|
||||||
@ -1386,7 +1395,7 @@ get_mem_values (DWORD dwProcessId, unsigned long *vmsize, unsigned long *vmrss,
|
|||||||
sizeof vmc, NULL);
|
sizeof vmc, NULL);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
debug_printf ("NtQueryInformationProcess: status %p", status);
|
debug_printf ("NtQueryInformationProcess: status %y", status);
|
||||||
__seterrno_from_nt_status (status);
|
__seterrno_from_nt_status (status);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,8 @@ details. */
|
|||||||
#define __INSIDE_CYGWIN_NET__
|
#define __INSIDE_CYGWIN_NET__
|
||||||
#define USE_SYS_TYPES_FD_SET
|
#define USE_SYS_TYPES_FD_SET
|
||||||
#include "winsup.h"
|
#include "winsup.h"
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#include <iphlpapi.h>
|
||||||
#include "cygerrno.h"
|
#include "cygerrno.h"
|
||||||
#include "security.h"
|
#include "security.h"
|
||||||
#include "path.h"
|
#include "path.h"
|
||||||
@ -18,8 +20,6 @@ details. */
|
|||||||
#include "fhandler_virtual.h"
|
#include "fhandler_virtual.h"
|
||||||
#include "dtable.h"
|
#include "dtable.h"
|
||||||
#include "cygheap.h"
|
#include "cygheap.h"
|
||||||
#include <ws2tcpip.h>
|
|
||||||
#include <iphlpapi.h>
|
|
||||||
#include <asm/byteorder.h>
|
#include <asm/byteorder.h>
|
||||||
|
|
||||||
#define _COMPILING_NEWLIB
|
#define _COMPILING_NEWLIB
|
||||||
@ -31,7 +31,7 @@ extern "C" int ip_addr_prefix (PIP_ADAPTER_UNICAST_ADDRESS pua,
|
|||||||
PIP_ADAPTER_PREFIX pap);
|
PIP_ADAPTER_PREFIX pap);
|
||||||
bool get_adapters_addresses (PIP_ADAPTER_ADDRESSES *pa0, ULONG family);
|
bool get_adapters_addresses (PIP_ADAPTER_ADDRESSES *pa0, ULONG family);
|
||||||
|
|
||||||
static _off64_t format_procnet_ifinet6 (void *, char *&);
|
static off_t format_procnet_ifinet6 (void *, char *&);
|
||||||
|
|
||||||
static const virt_tab_t procnet_tab[] =
|
static const virt_tab_t procnet_tab[] =
|
||||||
{
|
{
|
||||||
@ -63,12 +63,8 @@ fhandler_procnet::exists ()
|
|||||||
PROCNET_LINK_COUNT);
|
PROCNET_LINK_COUNT);
|
||||||
if (entry)
|
if (entry)
|
||||||
{
|
{
|
||||||
if (entry->type == virt_file)
|
if (entry->type == virt_file && !get_adapters_addresses (NULL, AF_INET6))
|
||||||
{
|
return virt_none;
|
||||||
if (!wincap.has_gaa_prefixes ()
|
|
||||||
|| !get_adapters_addresses (NULL, AF_INET6))
|
|
||||||
return virt_none;
|
|
||||||
}
|
|
||||||
fileid = entry - procnet_tab;
|
fileid = entry - procnet_tab;
|
||||||
return entry->type;
|
return entry->type;
|
||||||
}
|
}
|
||||||
@ -81,7 +77,7 @@ fhandler_procnet::fhandler_procnet ():
|
|||||||
}
|
}
|
||||||
|
|
||||||
int __reg2
|
int __reg2
|
||||||
fhandler_procnet::fstat (struct __stat64 *buf)
|
fhandler_procnet::fstat (struct stat *buf)
|
||||||
{
|
{
|
||||||
fhandler_base::fstat (buf);
|
fhandler_base::fstat (buf);
|
||||||
buf->st_mode &= ~_IFMT & NO_W;
|
buf->st_mode &= ~_IFMT & NO_W;
|
||||||
@ -109,12 +105,9 @@ fhandler_procnet::readdir (DIR *dir, dirent *de)
|
|||||||
int res = ENMFILE;
|
int res = ENMFILE;
|
||||||
if (dir->__d_position >= PROCNET_LINK_COUNT)
|
if (dir->__d_position >= PROCNET_LINK_COUNT)
|
||||||
goto out;
|
goto out;
|
||||||
if (procnet_tab[dir->__d_position].type == virt_file)
|
if (procnet_tab[dir->__d_position].type == virt_file
|
||||||
{
|
&& !get_adapters_addresses (NULL, AF_INET6))
|
||||||
if (!wincap.has_gaa_prefixes ()
|
goto out;
|
||||||
|| !get_adapters_addresses (NULL, AF_INET6))
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
strcpy (de->d_name, procnet_tab[dir->__d_position++].name);
|
strcpy (de->d_name, procnet_tab[dir->__d_position++].name);
|
||||||
dir->__flags |= dirent_saw_dot | dirent_saw_dot_dot;
|
dir->__flags |= dirent_saw_dot | dirent_saw_dot_dot;
|
||||||
res = 0;
|
res = 0;
|
||||||
@ -190,7 +183,7 @@ success:
|
|||||||
set_flags ((flags & ~O_TEXT) | O_BINARY);
|
set_flags ((flags & ~O_TEXT) | O_BINARY);
|
||||||
set_open_status ();
|
set_open_status ();
|
||||||
out:
|
out:
|
||||||
syscall_printf ("%d = fhandler_proc::open(%p, %d)", res, flags, mode);
|
syscall_printf ("%d = fhandler_proc::open(%y, 0%o)", res, flags, mode);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,16 +223,14 @@ static unsigned int dad_to_flags[] =
|
|||||||
0x80 /* Preferred -> PERMANENT */
|
0x80 /* Preferred -> PERMANENT */
|
||||||
};
|
};
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_procnet_ifinet6 (void *, char *&filebuf)
|
format_procnet_ifinet6 (void *, char *&filebuf)
|
||||||
{
|
{
|
||||||
PIP_ADAPTER_ADDRESSES pa0 = NULL, pap;
|
PIP_ADAPTER_ADDRESSES pa0 = NULL, pap;
|
||||||
PIP_ADAPTER_UNICAST_ADDRESS pua;
|
PIP_ADAPTER_UNICAST_ADDRESS pua;
|
||||||
ULONG alloclen;
|
ULONG alloclen;
|
||||||
|
off_t filesize = 0;
|
||||||
|
|
||||||
if (!wincap.has_gaa_prefixes ())
|
|
||||||
return 0;
|
|
||||||
_off64_t filesize = 0;
|
|
||||||
if (!get_adapters_addresses (&pa0, AF_INET6))
|
if (!get_adapters_addresses (&pa0, AF_INET6))
|
||||||
goto out;
|
goto out;
|
||||||
alloclen = 0;
|
alloclen = 0;
|
||||||
@ -263,7 +254,7 @@ format_procnet_ifinet6 (void *, char *&filebuf)
|
|||||||
filebuf[filesize++] = ' ';
|
filebuf[filesize++] = ' ';
|
||||||
filesize += sprintf (filebuf + filesize,
|
filesize += sprintf (filebuf + filesize,
|
||||||
"%02lx %02x %02x %02x %s\n",
|
"%02lx %02x %02x %02x %s\n",
|
||||||
pap->Ipv6IfIndex,
|
(long) pap->Ipv6IfIndex,
|
||||||
ip_addr_prefix (pua, pap->FirstPrefix),
|
ip_addr_prefix (pua, pap->FirstPrefix),
|
||||||
get_scope (&((struct sockaddr_in6 *)
|
get_scope (&((struct sockaddr_in6 *)
|
||||||
pua->Address.lpSockaddr)->sin6_addr),
|
pua->Address.lpSockaddr)->sin6_addr),
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* fhandler_procsys.cc: fhandler for native NT namespace.
|
/* fhandler_procsys.cc: fhandler for native NT namespace.
|
||||||
|
|
||||||
Copyright 2010, 2011, 2013 Red Hat, Inc.
|
Copyright 2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ const size_t procsys_len = sizeof (procsys) - 1;
|
|||||||
/* Returns 0 if path doesn't exist, >0 if path is a directory,
|
/* Returns 0 if path doesn't exist, >0 if path is a directory,
|
||||||
-1 if path is a file, -2 if it's a symlink. */
|
-1 if path is a file, -2 if it's a symlink. */
|
||||||
virtual_ftype_t
|
virtual_ftype_t
|
||||||
fhandler_procsys::exists (struct __stat64 *buf)
|
fhandler_procsys::exists (struct stat *buf)
|
||||||
{
|
{
|
||||||
UNICODE_STRING path;
|
UNICODE_STRING path;
|
||||||
UNICODE_STRING dir;
|
UNICODE_STRING dir;
|
||||||
@ -74,7 +74,7 @@ fhandler_procsys::exists (struct __stat64 *buf)
|
|||||||
dir.Length -= sizeof (WCHAR);
|
dir.Length -= sizeof (WCHAR);
|
||||||
InitializeObjectAttributes (&attr, &dir, OBJ_CASE_INSENSITIVE, NULL, NULL);
|
InitializeObjectAttributes (&attr, &dir, OBJ_CASE_INSENSITIVE, NULL, NULL);
|
||||||
status = NtOpenDirectoryObject (&h, DIRECTORY_QUERY, &attr);
|
status = NtOpenDirectoryObject (&h, DIRECTORY_QUERY, &attr);
|
||||||
debug_printf ("NtOpenDirectoryObject: %p", status);
|
debug_printf ("NtOpenDirectoryObject: %y", status);
|
||||||
if (NT_SUCCESS (status))
|
if (NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
internal = true;
|
internal = true;
|
||||||
@ -85,7 +85,7 @@ fhandler_procsys::exists (struct __stat64 *buf)
|
|||||||
InitializeObjectAttributes (&attr, &path, OBJ_CASE_INSENSITIVE, NULL, NULL);
|
InitializeObjectAttributes (&attr, &path, OBJ_CASE_INSENSITIVE, NULL, NULL);
|
||||||
status = NtOpenSymbolicLinkObject (&h, READ_CONTROL | SYMBOLIC_LINK_QUERY,
|
status = NtOpenSymbolicLinkObject (&h, READ_CONTROL | SYMBOLIC_LINK_QUERY,
|
||||||
&attr);
|
&attr);
|
||||||
debug_printf ("NtOpenSymbolicLinkObject: %p", status);
|
debug_printf ("NtOpenSymbolicLinkObject: %y", status);
|
||||||
if (NT_SUCCESS (status))
|
if (NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
/* If requested, check permissions. */
|
/* If requested, check permissions. */
|
||||||
@ -98,7 +98,7 @@ fhandler_procsys::exists (struct __stat64 *buf)
|
|||||||
return virt_symlink;
|
return virt_symlink;
|
||||||
/* Then check if it's an object directory. */
|
/* Then check if it's an object directory. */
|
||||||
status = NtOpenDirectoryObject (&h, READ_CONTROL | DIRECTORY_QUERY, &attr);
|
status = NtOpenDirectoryObject (&h, READ_CONTROL | DIRECTORY_QUERY, &attr);
|
||||||
debug_printf ("NtOpenDirectoryObject: %p", status);
|
debug_printf ("NtOpenDirectoryObject: %y", status);
|
||||||
if (NT_SUCCESS (status))
|
if (NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
/* If requested, check permissions. */
|
/* If requested, check permissions. */
|
||||||
@ -112,7 +112,7 @@ fhandler_procsys::exists (struct __stat64 *buf)
|
|||||||
/* Next try to open as file/device. */
|
/* Next try to open as file/device. */
|
||||||
status = NtOpenFile (&h, READ_CONTROL | FILE_READ_ATTRIBUTES, &attr, &io,
|
status = NtOpenFile (&h, READ_CONTROL | FILE_READ_ATTRIBUTES, &attr, &io,
|
||||||
FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT);
|
FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT);
|
||||||
debug_printf ("NtOpenFile: %p", status);
|
debug_printf ("NtOpenFile: %y", status);
|
||||||
/* Name is invalid, that's nothing. */
|
/* Name is invalid, that's nothing. */
|
||||||
if (status == STATUS_OBJECT_NAME_INVALID)
|
if (status == STATUS_OBJECT_NAME_INVALID)
|
||||||
return virt_none;
|
return virt_none;
|
||||||
@ -135,7 +135,7 @@ fhandler_procsys::exists (struct __stat64 *buf)
|
|||||||
since NtQueryAttributesFile might crash the machine if the underlying
|
since NtQueryAttributesFile might crash the machine if the underlying
|
||||||
driver is badly written. */
|
driver is badly written. */
|
||||||
status = NtQueryAttributesFile (&attr, &fbi);
|
status = NtQueryAttributesFile (&attr, &fbi);
|
||||||
debug_printf ("NtQueryAttributesFile: %p", status);
|
debug_printf ("NtQueryAttributesFile: %y", status);
|
||||||
if (NT_SUCCESS (status))
|
if (NT_SUCCESS (status))
|
||||||
return (fbi.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
return (fbi.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||||
? virt_fsdir : virt_fsfile;
|
? virt_fsdir : virt_fsfile;
|
||||||
@ -154,7 +154,7 @@ fhandler_procsys::exists (struct __stat64 *buf)
|
|||||||
status = NtOpenFile (&h, READ_CONTROL | FILE_READ_ATTRIBUTES,
|
status = NtOpenFile (&h, READ_CONTROL | FILE_READ_ATTRIBUTES,
|
||||||
&attr, &io, FILE_SHARE_VALID_FLAGS,
|
&attr, &io, FILE_SHARE_VALID_FLAGS,
|
||||||
FILE_OPEN_FOR_BACKUP_INTENT);
|
FILE_OPEN_FOR_BACKUP_INTENT);
|
||||||
debug_printf ("NtOpenDirectoryObject: %p", status);
|
debug_printf ("NtOpenDirectoryObject: %y", status);
|
||||||
if (dir.Length > sizeof (WCHAR))
|
if (dir.Length > sizeof (WCHAR))
|
||||||
dir.Length -= sizeof (WCHAR);
|
dir.Length -= sizeof (WCHAR);
|
||||||
}
|
}
|
||||||
@ -173,7 +173,7 @@ fhandler_procsys::exists (struct __stat64 *buf)
|
|||||||
/* Check for the device type. */
|
/* Check for the device type. */
|
||||||
status = NtQueryVolumeInformationFile (h, &io, &ffdi, sizeof ffdi,
|
status = NtQueryVolumeInformationFile (h, &io, &ffdi, sizeof ffdi,
|
||||||
FileFsDeviceInformation);
|
FileFsDeviceInformation);
|
||||||
debug_printf ("NtQueryVolumeInformationFile: %p", status);
|
debug_printf ("NtQueryVolumeInformationFile: %y", status);
|
||||||
/* Don't call NtQueryInformationFile unless we know it's a safe type.
|
/* Don't call NtQueryInformationFile unless we know it's a safe type.
|
||||||
The call is known to crash machines, if the underlying driver is
|
The call is known to crash machines, if the underlying driver is
|
||||||
badly written. */
|
badly written. */
|
||||||
@ -195,7 +195,7 @@ fhandler_procsys::exists (struct __stat64 *buf)
|
|||||||
into a real FS through /proc/sys. */
|
into a real FS through /proc/sys. */
|
||||||
status = NtQueryInformationFile (h, &io, &fbi, sizeof fbi,
|
status = NtQueryInformationFile (h, &io, &fbi, sizeof fbi,
|
||||||
FileBasicInformation);
|
FileBasicInformation);
|
||||||
debug_printf ("NtQueryInformationFile: %p", status);
|
debug_printf ("NtQueryInformationFile: %y", status);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
file_type = virt_blk;
|
file_type = virt_blk;
|
||||||
else
|
else
|
||||||
@ -261,7 +261,7 @@ unreadable:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int __reg2
|
int __reg2
|
||||||
fhandler_procsys::fstat (struct __stat64 *buf)
|
fhandler_procsys::fstat (struct stat *buf)
|
||||||
{
|
{
|
||||||
const char *path = get_name ();
|
const char *path = get_name ();
|
||||||
debug_printf ("fstat (%s)", path);
|
debug_printf ("fstat (%s)", path);
|
||||||
@ -271,7 +271,7 @@ fhandler_procsys::fstat (struct __stat64 *buf)
|
|||||||
buf->st_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
|
buf->st_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
|
||||||
buf->st_uid = 544;
|
buf->st_uid = 544;
|
||||||
buf->st_gid = 18;
|
buf->st_gid = 18;
|
||||||
buf->st_dev = buf->st_rdev = (int) dev ();
|
buf->st_dev = buf->st_rdev = dev ();
|
||||||
buf->st_ino = get_ino ();
|
buf->st_ino = get_ino ();
|
||||||
switch (exists (buf))
|
switch (exists (buf))
|
||||||
{
|
{
|
||||||
@ -446,7 +446,7 @@ fhandler_procsys::open (int flags, mode_t mode)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
syscall_printf ("%d = fhandler_procsys::open(%p, %d)", res, flags, mode);
|
syscall_printf ("%d = fhandler_procsys::open(%p, 0%o)", res, flags, mode);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* fhandler_procsysvipc.cc: fhandler for /proc/sysvipc virtual filesystem
|
/* fhandler_procsysvipc.cc: fhandler for /proc/sysvipc virtual filesystem
|
||||||
|
|
||||||
Copyright 2011, 2013 Red Hat, Inc.
|
Copyright 2011, 2012, 2013 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -38,9 +38,9 @@ details. */
|
|||||||
#include <sys/sem.h>
|
#include <sys/sem.h>
|
||||||
#include <sys/shm.h>
|
#include <sys/shm.h>
|
||||||
|
|
||||||
static _off64_t format_procsysvipc_msg (void *, char *&);
|
static off_t format_procsysvipc_msg (void *, char *&);
|
||||||
static _off64_t format_procsysvipc_sem (void *, char *&);
|
static off_t format_procsysvipc_sem (void *, char *&);
|
||||||
static _off64_t format_procsysvipc_shm (void *, char *&);
|
static off_t format_procsysvipc_shm (void *, char *&);
|
||||||
|
|
||||||
static const virt_tab_t procsysvipc_tab[] =
|
static const virt_tab_t procsysvipc_tab[] =
|
||||||
{
|
{
|
||||||
@ -93,7 +93,7 @@ fhandler_procsysvipc::fhandler_procsysvipc ():
|
|||||||
}
|
}
|
||||||
|
|
||||||
int __reg2
|
int __reg2
|
||||||
fhandler_procsysvipc::fstat (struct __stat64 *buf)
|
fhandler_procsysvipc::fstat (struct stat *buf)
|
||||||
{
|
{
|
||||||
fhandler_base::fstat (buf);
|
fhandler_base::fstat (buf);
|
||||||
buf->st_mode &= ~_IFMT & NO_W;
|
buf->st_mode &= ~_IFMT & NO_W;
|
||||||
@ -202,7 +202,7 @@ success:
|
|||||||
set_flags ((flags & ~O_TEXT) | O_BINARY);
|
set_flags ((flags & ~O_TEXT) | O_BINARY);
|
||||||
set_open_status ();
|
set_open_status ();
|
||||||
out:
|
out:
|
||||||
syscall_printf ("%d = fhandler_proc::open(%p, %d)", res, flags, mode);
|
syscall_printf ("%d = fhandler_proc::open(%p, 0%o)", res, flags, mode);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,7 +217,7 @@ fhandler_procsysvipc::fill_filebuf ()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_procsysvipc_msg (void *, char *&destbuf)
|
format_procsysvipc_msg (void *, char *&destbuf)
|
||||||
{
|
{
|
||||||
tmp_pathbuf tp;
|
tmp_pathbuf tp;
|
||||||
@ -238,7 +238,7 @@ format_procsysvipc_msg (void *, char *&destbuf)
|
|||||||
for (int i = 0; i < msginfo.msgmni; i++) {
|
for (int i = 0; i < msginfo.msgmni; i++) {
|
||||||
if (xmsqids[i].msg_qbytes != 0) {
|
if (xmsqids[i].msg_qbytes != 0) {
|
||||||
bufptr += sprintf (bufptr,
|
bufptr += sprintf (bufptr,
|
||||||
"%10llu %10u %5o %11lu %10lu %5d %5d %5lu %5lu %5lu %5lu %10ld %10ld %10ld\n",
|
"%10llu %10u %5o %11u %10u %5d %5d %5u %5u %5u %5u %10ld %10ld %10ld\n",
|
||||||
xmsqids[i].msg_perm.key,
|
xmsqids[i].msg_perm.key,
|
||||||
IXSEQ_TO_IPCID(i, xmsqids[i].msg_perm),
|
IXSEQ_TO_IPCID(i, xmsqids[i].msg_perm),
|
||||||
xmsqids[i].msg_perm.mode,
|
xmsqids[i].msg_perm.mode,
|
||||||
@ -246,10 +246,10 @@ format_procsysvipc_msg (void *, char *&destbuf)
|
|||||||
xmsqids[i].msg_qnum,
|
xmsqids[i].msg_qnum,
|
||||||
xmsqids[i].msg_lspid,
|
xmsqids[i].msg_lspid,
|
||||||
xmsqids[i].msg_lrpid,
|
xmsqids[i].msg_lrpid,
|
||||||
xmsqids[i].msg_perm.uid,
|
(unsigned) xmsqids[i].msg_perm.uid,
|
||||||
xmsqids[i].msg_perm.gid,
|
(unsigned) xmsqids[i].msg_perm.gid,
|
||||||
xmsqids[i].msg_perm.cuid,
|
(unsigned) xmsqids[i].msg_perm.cuid,
|
||||||
xmsqids[i].msg_perm.cgid,
|
(unsigned) xmsqids[i].msg_perm.cgid,
|
||||||
xmsqids[i].msg_stime,
|
xmsqids[i].msg_stime,
|
||||||
xmsqids[i].msg_rtime,
|
xmsqids[i].msg_rtime,
|
||||||
xmsqids[i].msg_ctime);
|
xmsqids[i].msg_ctime);
|
||||||
@ -261,7 +261,7 @@ format_procsysvipc_msg (void *, char *&destbuf)
|
|||||||
return bufptr - buf;
|
return bufptr - buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_procsysvipc_sem (void *, char *&destbuf)
|
format_procsysvipc_sem (void *, char *&destbuf)
|
||||||
{
|
{
|
||||||
tmp_pathbuf tp;
|
tmp_pathbuf tp;
|
||||||
@ -284,15 +284,15 @@ format_procsysvipc_sem (void *, char *&destbuf)
|
|||||||
for (int i = 0; i < seminfo.semmni; i++) {
|
for (int i = 0; i < seminfo.semmni; i++) {
|
||||||
if ((xsemids[i].sem_perm.mode & SEM_ALLOC) != 0) {
|
if ((xsemids[i].sem_perm.mode & SEM_ALLOC) != 0) {
|
||||||
bufptr += sprintf (bufptr,
|
bufptr += sprintf (bufptr,
|
||||||
"%10llu %10u %5o %10d %5lu %5lu %5lu %5lu %10ld %10ld\n",
|
"%10llu %10u %5o %10d %5u %5u %5u %5u %10ld %10ld\n",
|
||||||
xsemids[i].sem_perm.key,
|
xsemids[i].sem_perm.key,
|
||||||
IXSEQ_TO_IPCID(i, xsemids[i].sem_perm),
|
IXSEQ_TO_IPCID(i, xsemids[i].sem_perm),
|
||||||
xsemids[i].sem_perm.mode,
|
xsemids[i].sem_perm.mode,
|
||||||
xsemids[i].sem_nsems,
|
xsemids[i].sem_nsems,
|
||||||
xsemids[i].sem_perm.uid,
|
(unsigned) xsemids[i].sem_perm.uid,
|
||||||
xsemids[i].sem_perm.gid,
|
(unsigned) xsemids[i].sem_perm.gid,
|
||||||
xsemids[i].sem_perm.cuid,
|
(unsigned) xsemids[i].sem_perm.cuid,
|
||||||
xsemids[i].sem_perm.cgid,
|
(unsigned) xsemids[i].sem_perm.cgid,
|
||||||
xsemids[i].sem_otime,
|
xsemids[i].sem_otime,
|
||||||
xsemids[i].sem_ctime);
|
xsemids[i].sem_ctime);
|
||||||
}
|
}
|
||||||
@ -303,7 +303,7 @@ format_procsysvipc_sem (void *, char *&destbuf)
|
|||||||
return bufptr - buf;
|
return bufptr - buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static _off64_t
|
static off_t
|
||||||
format_procsysvipc_shm (void *, char *&destbuf)
|
format_procsysvipc_shm (void *, char *&destbuf)
|
||||||
{
|
{
|
||||||
tmp_pathbuf tp;
|
tmp_pathbuf tp;
|
||||||
@ -323,7 +323,7 @@ format_procsysvipc_shm (void *, char *&destbuf)
|
|||||||
for (int i = 0; i < shminfo.shmmni; i++) {
|
for (int i = 0; i < shminfo.shmmni; i++) {
|
||||||
if (xshmids[i].shm_perm.mode & 0x0800) {
|
if (xshmids[i].shm_perm.mode & 0x0800) {
|
||||||
bufptr += sprintf (bufptr,
|
bufptr += sprintf (bufptr,
|
||||||
"%10llu %10u %5o %10u %5d %5d %6u %5lu %5lu %5lu %5lu %10ld %10ld %10ld\n",
|
"%10llu %10u %5o %10u %5d %5d %6u %5u %5u %5u %5u %10ld %10ld %10ld\n",
|
||||||
xshmids[i].shm_perm.key,
|
xshmids[i].shm_perm.key,
|
||||||
IXSEQ_TO_IPCID(i, xshmids[i].shm_perm),
|
IXSEQ_TO_IPCID(i, xshmids[i].shm_perm),
|
||||||
xshmids[i].shm_perm.mode,
|
xshmids[i].shm_perm.mode,
|
||||||
@ -331,10 +331,10 @@ format_procsysvipc_shm (void *, char *&destbuf)
|
|||||||
xshmids[i].shm_cpid,
|
xshmids[i].shm_cpid,
|
||||||
xshmids[i].shm_lpid,
|
xshmids[i].shm_lpid,
|
||||||
xshmids[i].shm_nattch,
|
xshmids[i].shm_nattch,
|
||||||
xshmids[i].shm_perm.uid,
|
(unsigned) xshmids[i].shm_perm.uid,
|
||||||
xshmids[i].shm_perm.gid,
|
(unsigned) xshmids[i].shm_perm.gid,
|
||||||
xshmids[i].shm_perm.cuid,
|
(unsigned) xshmids[i].shm_perm.cuid,
|
||||||
xshmids[i].shm_perm.cgid,
|
(unsigned) xshmids[i].shm_perm.cgid,
|
||||||
xshmids[i].shm_atime,
|
xshmids[i].shm_atime,
|
||||||
xshmids[i].shm_dtime,
|
xshmids[i].shm_dtime,
|
||||||
xshmids[i].shm_ctime);
|
xshmids[i].shm_ctime);
|
||||||
|
@ -143,13 +143,13 @@ fhandler_dev_random::read (void *ptr, size_t& len)
|
|||||||
len = (size_t) -1;
|
len = (size_t) -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
_off64_t
|
off_t
|
||||||
fhandler_dev_random::lseek (_off64_t off, int whence)
|
fhandler_dev_random::lseek (off_t off, int whence)
|
||||||
{
|
{
|
||||||
/* As on Linux, fake being able to set an offset. The fact that neither
|
/* As on Linux, fake being able to set an offset. The fact that neither
|
||||||
reading nor writing changes the dummy offset is also the same as on
|
reading nor writing changes the dummy offset is also the same as on
|
||||||
Linux (tested with kernel 2.6.23). */
|
Linux (tested with kernel 2.6.23). */
|
||||||
_off64_t new_off;
|
off_t new_off;
|
||||||
|
|
||||||
switch (whence)
|
switch (whence)
|
||||||
{
|
{
|
||||||
@ -161,12 +161,12 @@ fhandler_dev_random::lseek (_off64_t off, int whence)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return (_off64_t) -1;
|
return (off_t) -1;
|
||||||
}
|
}
|
||||||
if (new_off < 0)
|
if (new_off < 0)
|
||||||
{
|
{
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return (_off64_t) -1;
|
return (off_t) -1;
|
||||||
}
|
}
|
||||||
return dummy_offset = new_off;
|
return dummy_offset = new_off;
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ fhandler_dev_raw::~fhandler_dev_raw ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
int __reg2
|
int __reg2
|
||||||
fhandler_dev_raw::fstat (struct __stat64 *buf)
|
fhandler_dev_raw::fstat (struct stat *buf)
|
||||||
{
|
{
|
||||||
debug_printf ("here");
|
debug_printf ("here");
|
||||||
|
|
||||||
@ -95,7 +95,7 @@ fhandler_dev_raw::dup (fhandler_base *child, int flags)
|
|||||||
/* Create sector-aligned buffer */
|
/* Create sector-aligned buffer */
|
||||||
fhc->devbufalloc = new char [devbufsiz + devbufalign];
|
fhc->devbufalloc = new char [devbufsiz + devbufalign];
|
||||||
fhc->devbuf = (char *) roundup2 ((uintptr_t) fhc->devbufalloc,
|
fhc->devbuf = (char *) roundup2 ((uintptr_t) fhc->devbufalloc,
|
||||||
devbufalign);
|
(uintptr_t) devbufalign);
|
||||||
}
|
}
|
||||||
fhc->devbufstart = 0;
|
fhc->devbufstart = 0;
|
||||||
fhc->devbufend = 0;
|
fhc->devbufend = 0;
|
||||||
@ -121,7 +121,8 @@ fhandler_dev_raw::fixup_after_exec ()
|
|||||||
{
|
{
|
||||||
/* Create sector-aligned buffer */
|
/* Create sector-aligned buffer */
|
||||||
devbufalloc = new char [devbufsiz + devbufalign];
|
devbufalloc = new char [devbufsiz + devbufalign];
|
||||||
devbuf = (char *) roundup2 ((uintptr_t) devbufalloc, devbufalign);
|
devbuf = (char *) roundup2 ((uintptr_t) devbufalloc,
|
||||||
|
(uintptr_t) devbufalign);
|
||||||
}
|
}
|
||||||
devbufstart = 0;
|
devbufstart = 0;
|
||||||
devbufend = 0;
|
devbufend = 0;
|
||||||
@ -165,7 +166,7 @@ fhandler_dev_raw::ioctl (unsigned int cmd, void *buf)
|
|||||||
else if (!devbuf || op->rd_parm != devbufsiz)
|
else if (!devbuf || op->rd_parm != devbufsiz)
|
||||||
{
|
{
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
_off64_t curpos = lseek (0, SEEK_CUR);
|
off_t curpos = lseek (0, SEEK_CUR);
|
||||||
|
|
||||||
if (op->rd_parm > 1L)
|
if (op->rd_parm > 1L)
|
||||||
buf = new char [op->rd_parm + devbufalign];
|
buf = new char [op->rd_parm + devbufalign];
|
||||||
@ -174,7 +175,8 @@ fhandler_dev_raw::ioctl (unsigned int cmd, void *buf)
|
|||||||
delete [] devbufalloc;
|
delete [] devbufalloc;
|
||||||
|
|
||||||
devbufalloc = buf;
|
devbufalloc = buf;
|
||||||
devbuf = (char *) roundup2 ((uintptr_t) buf, devbufalign);
|
devbuf = (char *) roundup2 ((uintptr_t) buf,
|
||||||
|
(uintptr_t) devbufalign);
|
||||||
devbufsiz = op->rd_parm ?: 1L;
|
devbufsiz = op->rd_parm ?: 1L;
|
||||||
devbufstart = devbufend = 0;
|
devbufstart = devbufend = 0;
|
||||||
lseek (curpos, SEEK_SET);
|
lseek (curpos, SEEK_SET);
|
||||||
|
@ -29,8 +29,8 @@ details. */
|
|||||||
* the bottom 16 bits are the absolute position and the top 15 bits
|
* the bottom 16 bits are the absolute position and the top 15 bits
|
||||||
* make up the value index if we are enuerating values.
|
* make up the value index if we are enuerating values.
|
||||||
*/
|
*/
|
||||||
static const _off_t REG_ENUM_VALUES_MASK = 0x8000000;
|
static const __int32_t REG_ENUM_VALUES_MASK = 0x8000000;
|
||||||
static const _off_t REG_POSITION_MASK = 0xffff;
|
static const __int32_t REG_POSITION_MASK = 0xffff;
|
||||||
|
|
||||||
/* These key paths are used below whenever we return key information.
|
/* These key paths are used below whenever we return key information.
|
||||||
The problem is UAC virtualization when running an admin account with
|
The problem is UAC virtualization when running an admin account with
|
||||||
@ -59,7 +59,7 @@ static const char *registry_listing[] =
|
|||||||
"HKEY_CURRENT_USER",
|
"HKEY_CURRENT_USER",
|
||||||
"HKEY_LOCAL_MACHINE",
|
"HKEY_LOCAL_MACHINE",
|
||||||
"HKEY_USERS",
|
"HKEY_USERS",
|
||||||
"HKEY_PERFORMANCE_DATA", // NT/2000/XP
|
"HKEY_PERFORMANCE_DATA",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -462,7 +462,7 @@ fhandler_proc ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
int __reg2
|
int __reg2
|
||||||
fhandler_registry::fstat (struct __stat64 *buf)
|
fhandler_registry::fstat (struct stat *buf)
|
||||||
{
|
{
|
||||||
fhandler_base::fstat (buf);
|
fhandler_base::fstat (buf);
|
||||||
buf->st_mode &= ~_IFMT & NO_W;
|
buf->st_mode &= ~_IFMT & NO_W;
|
||||||
@ -551,8 +551,8 @@ fhandler_registry::fstat (struct __stat64 *buf)
|
|||||||
else
|
else
|
||||||
buf->st_size = dwSize;
|
buf->st_size = dwSize;
|
||||||
}
|
}
|
||||||
__uid32_t uid;
|
uid_t uid;
|
||||||
__gid32_t gid;
|
gid_t gid;
|
||||||
if (get_reg_attribute (hKey, &buf->st_mode, &uid, &gid) == 0)
|
if (get_reg_attribute (hKey, &buf->st_mode, &uid, &gid) == 0)
|
||||||
{
|
{
|
||||||
buf->st_uid = uid;
|
buf->st_uid = uid;
|
||||||
@ -616,7 +616,7 @@ fhandler_registry::readdir (DIR *dir, dirent *de)
|
|||||||
dir->__handle = open_key (path + 1, KEY_READ, wow64, false);
|
dir->__handle = open_key (path + 1, KEY_READ, wow64, false);
|
||||||
if (dir->__handle == INVALID_HANDLE_VALUE)
|
if (dir->__handle == INVALID_HANDLE_VALUE)
|
||||||
goto out;
|
goto out;
|
||||||
dir->__d_internal = (unsigned) new __DIR_hash ();
|
dir->__d_internal = (uintptr_t) new __DIR_hash ();
|
||||||
}
|
}
|
||||||
if (dir->__d_position < SPECIAL_DOT_FILE_COUNT)
|
if (dir->__d_position < SPECIAL_DOT_FILE_COUNT)
|
||||||
{
|
{
|
||||||
@ -893,7 +893,7 @@ success:
|
|||||||
set_flags ((flags & ~O_TEXT) | O_BINARY);
|
set_flags ((flags & ~O_TEXT) | O_BINARY);
|
||||||
set_open_status ();
|
set_open_status ();
|
||||||
out:
|
out:
|
||||||
syscall_printf ("%d = fhandler_registry::open(%p, %d)", res, flags, mode);
|
syscall_printf ("%d = fhandler_registry::open(%p, 0%o)", res, flags, mode);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,8 +49,8 @@ fhandler_serial::raw_read (void *ptr, size_t& ulen)
|
|||||||
|
|
||||||
size_t minchars = vmin_ ? MIN (vmin_, ulen) : ulen;
|
size_t minchars = vmin_ ? MIN (vmin_, ulen) : ulen;
|
||||||
|
|
||||||
debug_printf ("ulen %d, vmin_ %d, vtime_ %d, hEvent %p", ulen, vmin_, vtime_,
|
debug_printf ("ulen %ld, vmin_ %ld, vtime_ %u, hEvent %p",
|
||||||
io_status.hEvent);
|
ulen, vmin_, vtime_, io_status.hEvent);
|
||||||
if (!overlapped_armed)
|
if (!overlapped_armed)
|
||||||
{
|
{
|
||||||
SetCommMask (get_handle (), EV_RXCHAR);
|
SetCommMask (get_handle (), EV_RXCHAR);
|
||||||
@ -94,7 +94,7 @@ fhandler_serial::raw_read (void *ptr, size_t& ulen)
|
|||||||
if (!GetOverlappedResult (get_handle (), &io_status, &n,
|
if (!GetOverlappedResult (get_handle (), &io_status, &n,
|
||||||
FALSE))
|
FALSE))
|
||||||
goto err;
|
goto err;
|
||||||
debug_printf ("n %d, ev %x", n, ev);
|
debug_printf ("n %u, ev %x", n, ev);
|
||||||
break;
|
break;
|
||||||
case WAIT_SIGNALED:
|
case WAIT_SIGNALED:
|
||||||
tot = -1;
|
tot = -1;
|
||||||
@ -117,7 +117,7 @@ fhandler_serial::raw_read (void *ptr, size_t& ulen)
|
|||||||
ResetEvent (io_status.hEvent);
|
ResetEvent (io_status.hEvent);
|
||||||
if (inq > ulen)
|
if (inq > ulen)
|
||||||
inq = ulen;
|
inq = ulen;
|
||||||
debug_printf ("inq %d", inq);
|
debug_printf ("inq %u", inq);
|
||||||
if (ReadFile (get_handle (), ptr, inq, &n, &io_status))
|
if (ReadFile (get_handle (), ptr, inq, &n, &io_status))
|
||||||
/* Got something */;
|
/* Got something */;
|
||||||
else if (GetLastError () != ERROR_IO_PENDING)
|
else if (GetLastError () != ERROR_IO_PENDING)
|
||||||
@ -143,7 +143,7 @@ fhandler_serial::raw_read (void *ptr, size_t& ulen)
|
|||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
tot += n;
|
tot += n;
|
||||||
debug_printf ("vtime_ %d, vmin_ %d, n %d, tot %d", vtime_, vmin_, n, tot);
|
debug_printf ("vtime_ %u, vmin_ %lu, n %u, tot %d", vtime_, vmin_, n, tot);
|
||||||
if (vtime_ || !vmin_ || !n)
|
if (vtime_ || !vmin_ || !n)
|
||||||
break;
|
break;
|
||||||
continue;
|
continue;
|
||||||
@ -244,8 +244,8 @@ fhandler_serial::open (int flags, mode_t mode)
|
|||||||
int res;
|
int res;
|
||||||
COMMTIMEOUTS to;
|
COMMTIMEOUTS to;
|
||||||
|
|
||||||
syscall_printf ("fhandler_serial::open (%s, %p, %p)",
|
syscall_printf ("fhandler_serial::open (%s, %y, 0%o)",
|
||||||
get_name (), flags, mode);
|
get_name (), flags, mode);
|
||||||
|
|
||||||
if (!fhandler_base::open (flags, mode))
|
if (!fhandler_base::open (flags, mode))
|
||||||
return 0;
|
return 0;
|
||||||
@ -301,8 +301,8 @@ fhandler_serial::open (int flags, mode_t mode)
|
|||||||
|
|
||||||
SetCommMask (get_handle (), EV_RXCHAR);
|
SetCommMask (get_handle (), EV_RXCHAR);
|
||||||
set_open_status ();
|
set_open_status ();
|
||||||
syscall_printf ("%p = fhandler_serial::open (%s, %p, %p)",
|
syscall_printf ("%p = fhandler_serial::open (%s, %y, 0%o)",
|
||||||
res, get_name (), flags, mode);
|
res, get_name (), flags, mode);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -446,7 +446,7 @@ fhandler_serial::ioctl (unsigned int cmd, void *buf)
|
|||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
# define ibuf ((int) buf)
|
# define ibuf ((int) (intptr_t) buf)
|
||||||
# define ipbuf (*(int *) buf)
|
# define ipbuf (*(int *) buf)
|
||||||
|
|
||||||
DWORD ev;
|
DWORD ev;
|
||||||
@ -544,7 +544,7 @@ fhandler_serial::ioctl (unsigned int cmd, void *buf)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
termios_printf ("%d = ioctl(%p, %p)", res, cmd, buf);
|
termios_printf ("%d = ioctl(%x, %p)", res, cmd, buf);
|
||||||
# undef ibuf
|
# undef ibuf
|
||||||
# undef ipbuf
|
# undef ipbuf
|
||||||
return res;
|
return res;
|
||||||
@ -699,7 +699,7 @@ fhandler_serial::tcsetattr (int action, const struct termios *t)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Unsupported baud rate! */
|
/* Unsupported baud rate! */
|
||||||
termios_printf ("Invalid t->c_ospeed %d", t->c_ospeed);
|
termios_printf ("Invalid t->c_ospeed %u", t->c_ospeed);
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -722,7 +722,7 @@ fhandler_serial::tcsetattr (int action, const struct termios *t)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Unsupported byte size! */
|
/* Unsupported byte size! */
|
||||||
termios_printf ("Invalid t->c_cflag byte size %d",
|
termios_printf ("Invalid t->c_cflag byte size %u",
|
||||||
t->c_cflag & CSIZE);
|
t->c_cflag & CSIZE);
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return -1;
|
return -1;
|
||||||
@ -902,7 +902,7 @@ fhandler_serial::tcsetattr (int action, const struct termios *t)
|
|||||||
vmin_ = t->c_cc[VMIN];
|
vmin_ = t->c_cc[VMIN];
|
||||||
}
|
}
|
||||||
|
|
||||||
debug_printf ("vtime %d, vmin %d", vtime_, vmin_);
|
debug_printf ("vtime %d, vmin %ld", vtime_, vmin_);
|
||||||
|
|
||||||
if (ovmin != vmin_ || ovtime != vtime_)
|
if (ovmin != vmin_ || ovtime != vtime_)
|
||||||
{
|
{
|
||||||
@ -935,7 +935,7 @@ fhandler_serial::tcsetattr (int action, const struct termios *t)
|
|||||||
to.ReadIntervalTimeout = MAXDWORD;
|
to.ReadIntervalTimeout = MAXDWORD;
|
||||||
}
|
}
|
||||||
|
|
||||||
debug_printf ("ReadTotalTimeoutConstant %d, ReadIntervalTimeout %d, ReadTotalTimeoutMultiplier %d",
|
debug_printf ("ReadTotalTimeoutConstant %u, ReadIntervalTimeout %u, ReadTotalTimeoutMultiplier %u",
|
||||||
to.ReadTotalTimeoutConstant, to.ReadIntervalTimeout, to.ReadTotalTimeoutMultiplier);
|
to.ReadTotalTimeoutConstant, to.ReadIntervalTimeout, to.ReadTotalTimeoutMultiplier);
|
||||||
|
|
||||||
if (!SetCommTimeouts(get_handle (), &to))
|
if (!SetCommTimeouts(get_handle (), &to))
|
||||||
@ -1042,7 +1042,7 @@ fhandler_serial::tcgetattr (struct termios *t)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Unsupported baud rate! */
|
/* Unsupported baud rate! */
|
||||||
termios_printf ("Invalid baud rate %d", state.BaudRate);
|
termios_printf ("Invalid baud rate %u", state.BaudRate);
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1065,7 +1065,7 @@ fhandler_serial::tcgetattr (struct termios *t)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Unsupported byte size! */
|
/* Unsupported byte size! */
|
||||||
termios_printf ("Invalid byte size %d", state.ByteSize);
|
termios_printf ("Invalid byte size %u", state.ByteSize);
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1136,7 +1136,7 @@ fhandler_serial::tcgetattr (struct termios *t)
|
|||||||
t->c_cc[VTIME] = vtime_ / 100;
|
t->c_cc[VTIME] = vtime_ / 100;
|
||||||
t->c_cc[VMIN] = vmin_;
|
t->c_cc[VMIN] = vmin_;
|
||||||
|
|
||||||
debug_printf ("vmin_ %d, vtime_ %d", vmin_, vtime_);
|
debug_printf ("vmin_ %lu, vtime_ %u", vmin_, vtime_);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -14,16 +14,18 @@
|
|||||||
#define __INSIDE_CYGWIN_NET__
|
#define __INSIDE_CYGWIN_NET__
|
||||||
#define USE_SYS_TYPES_FD_SET
|
#define USE_SYS_TYPES_FD_SET
|
||||||
|
|
||||||
|
#define _BSDTYPES_DEFINED
|
||||||
#include "winsup.h"
|
#include "winsup.h"
|
||||||
|
#undef _BSDTYPES_DEFINED
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#include <mswsock.h>
|
||||||
|
#include <iphlpapi.h>
|
||||||
#include "cygerrno.h"
|
#include "cygerrno.h"
|
||||||
#include "security.h"
|
#include "security.h"
|
||||||
#include "path.h"
|
#include "path.h"
|
||||||
#include "fhandler.h"
|
#include "fhandler.h"
|
||||||
#include "dtable.h"
|
#include "dtable.h"
|
||||||
#include "cygheap.h"
|
#include "cygheap.h"
|
||||||
#include <ws2tcpip.h>
|
|
||||||
#include <mswsock.h>
|
|
||||||
#include <iphlpapi.h>
|
|
||||||
#include <asm/byteorder.h>
|
#include <asm/byteorder.h>
|
||||||
#include "cygwin/version.h"
|
#include "cygwin/version.h"
|
||||||
#include "perprocess.h"
|
#include "perprocess.h"
|
||||||
@ -232,7 +234,7 @@ fhandler_socket::~fhandler_socket ()
|
|||||||
char *
|
char *
|
||||||
fhandler_socket::get_proc_fd_name (char *buf)
|
fhandler_socket::get_proc_fd_name (char *buf)
|
||||||
{
|
{
|
||||||
__small_sprintf (buf, "socket:[%d]", get_socket ());
|
__small_sprintf (buf, "socket:[%lu]", get_socket ());
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -328,7 +330,7 @@ fhandler_socket::af_local_send_secret ()
|
|||||||
bool
|
bool
|
||||||
fhandler_socket::af_local_recv_cred ()
|
fhandler_socket::af_local_recv_cred ()
|
||||||
{
|
{
|
||||||
struct ucred out = { (pid_t) 0, (__uid32_t) -1, (__gid32_t) -1 };
|
struct ucred out = { (pid_t) 0, (uid_t) -1, (gid_t) -1 };
|
||||||
int rest = sizeof out;
|
int rest = sizeof out;
|
||||||
char *ptr = (char *) &out;
|
char *ptr = (char *) &out;
|
||||||
while (rest > 0)
|
while (rest > 0)
|
||||||
@ -421,8 +423,8 @@ fhandler_socket::af_local_set_cred ()
|
|||||||
sec_uid = geteuid32 ();
|
sec_uid = geteuid32 ();
|
||||||
sec_gid = getegid32 ();
|
sec_gid = getegid32 ();
|
||||||
sec_peer_pid = (pid_t) 0;
|
sec_peer_pid = (pid_t) 0;
|
||||||
sec_peer_uid = (__uid32_t) -1;
|
sec_peer_uid = (uid_t) -1;
|
||||||
sec_peer_gid = (__gid32_t) -1;
|
sec_peer_gid = (gid_t) -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -504,7 +506,7 @@ search_wsa_event_slot (LONG new_serial_number)
|
|||||||
everyone_sd (CYG_MUTANT_ACCESS));
|
everyone_sd (CYG_MUTANT_ACCESS));
|
||||||
status = NtCreateMutant (&wsa_slot_mtx, CYG_MUTANT_ACCESS, &attr, FALSE);
|
status = NtCreateMutant (&wsa_slot_mtx, CYG_MUTANT_ACCESS, &attr, FALSE);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
api_fatal ("Couldn't create/open shared socket mutex %S, %p",
|
api_fatal ("Couldn't create/open shared socket mutex %S, %y",
|
||||||
&uname, status);
|
&uname, status);
|
||||||
}
|
}
|
||||||
switch (WaitForSingleObject (wsa_slot_mtx, INFINITE))
|
switch (WaitForSingleObject (wsa_slot_mtx, INFINITE))
|
||||||
@ -566,7 +568,7 @@ fhandler_socket::init_events ()
|
|||||||
status = NtCreateMutant (&wsock_mtx, CYG_MUTANT_ACCESS, &attr, FALSE);
|
status = NtCreateMutant (&wsock_mtx, CYG_MUTANT_ACCESS, &attr, FALSE);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
debug_printf ("NtCreateMutant(%S), %p", &uname, status);
|
debug_printf ("NtCreateMutant(%S), %y", &uname, status);
|
||||||
set_errno (ENOBUFS);
|
set_errno (ENOBUFS);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -722,7 +724,7 @@ fhandler_socket::fixup_before_fork_exec (DWORD win_pid)
|
|||||||
if (ret)
|
if (ret)
|
||||||
set_winsock_errno ();
|
set_winsock_errno ();
|
||||||
else
|
else
|
||||||
debug_printf ("WSADuplicateSocket succeeded (%lx)", prot_info_ptr->dwProviderReserved);
|
debug_printf ("WSADuplicateSocket succeeded (%x)", prot_info_ptr->dwProviderReserved);
|
||||||
return (int) ret;
|
return (int) ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -752,7 +754,7 @@ fhandler_socket::fixup_after_fork (HANDLE parent)
|
|||||||
socket is potentially inheritable again. */
|
socket is potentially inheritable again. */
|
||||||
SetHandleInformation ((HANDLE) new_sock, HANDLE_FLAG_INHERIT, 0);
|
SetHandleInformation ((HANDLE) new_sock, HANDLE_FLAG_INHERIT, 0);
|
||||||
set_io_handle ((HANDLE) new_sock);
|
set_io_handle ((HANDLE) new_sock);
|
||||||
debug_printf ("WSASocket succeeded (%lx)", new_sock);
|
debug_printf ("WSASocket succeeded (%p)", new_sock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -818,7 +820,7 @@ fhandler_socket::dup (fhandler_base *child, int flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int __reg2
|
int __reg2
|
||||||
fhandler_socket::fstat (struct __stat64 *buf)
|
fhandler_socket::fstat (struct stat *buf)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
if (get_device () == FH_UNIX)
|
if (get_device () == FH_UNIX)
|
||||||
@ -836,7 +838,7 @@ fhandler_socket::fstat (struct __stat64 *buf)
|
|||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
buf->st_dev = 0;
|
buf->st_dev = 0;
|
||||||
buf->st_ino = (__ino64_t) ((DWORD) get_handle ());
|
buf->st_ino = (ino_t) ((uintptr_t) get_handle ());
|
||||||
buf->st_mode = S_IFSOCK | S_IRWXU | S_IRWXG | S_IRWXO;
|
buf->st_mode = S_IFSOCK | S_IRWXU | S_IRWXG | S_IRWXO;
|
||||||
buf->st_size = 0;
|
buf->st_size = 0;
|
||||||
}
|
}
|
||||||
@ -872,7 +874,7 @@ fhandler_socket::fchmod (mode_t mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_socket::fchown (__uid32_t uid, __gid32_t gid)
|
fhandler_socket::fchown (uid_t uid, gid_t gid)
|
||||||
{
|
{
|
||||||
if (get_device () == FH_UNIX)
|
if (get_device () == FH_UNIX)
|
||||||
{
|
{
|
||||||
@ -884,7 +886,7 @@ fhandler_socket::fchown (__uid32_t uid, __gid32_t gid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_socket::facl (int cmd, int nentries, __aclent32_t *aclbufp)
|
fhandler_socket::facl (int cmd, int nentries, aclent_t *aclbufp)
|
||||||
{
|
{
|
||||||
if (get_device () == FH_UNIX)
|
if (get_device () == FH_UNIX)
|
||||||
{
|
{
|
||||||
@ -1022,7 +1024,7 @@ fhandler_socket::bind (const struct sockaddr *name, int namelen)
|
|||||||
status = NtSetInformationFile (fh, &io, &fdi, sizeof fdi,
|
status = NtSetInformationFile (fh, &io, &fdi, sizeof fdi,
|
||||||
FileDispositionInformation);
|
FileDispositionInformation);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
debug_printf ("Setting delete dispostion failed, status = %p",
|
debug_printf ("Setting delete dispostion failed, status = %y",
|
||||||
status);
|
status);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1041,10 +1043,7 @@ fhandler_socket::bind (const struct sockaddr *name, int namelen)
|
|||||||
/* If the application didn't explicitely request SO_REUSEADDR,
|
/* If the application didn't explicitely request SO_REUSEADDR,
|
||||||
enforce POSIX standard socket binding behaviour by setting the
|
enforce POSIX standard socket binding behaviour by setting the
|
||||||
SO_EXCLUSIVEADDRUSE socket option. See cygwin_setsockopt()
|
SO_EXCLUSIVEADDRUSE socket option. See cygwin_setsockopt()
|
||||||
for a more detailed description.
|
for a more detailed description. */
|
||||||
|
|
||||||
KB 870562: Note that a bug in Win2K SP1-3 and XP up to SP1 only
|
|
||||||
enables this option for users in the local administrators group. */
|
|
||||||
int on = 1;
|
int on = 1;
|
||||||
int ret = ::setsockopt (get_socket (), SOL_SOCKET,
|
int ret = ::setsockopt (get_socket (), SOL_SOCKET,
|
||||||
~(SO_REUSEADDR),
|
~(SO_REUSEADDR),
|
||||||
@ -1069,8 +1068,6 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen)
|
|||||||
DWORD err;
|
DWORD err;
|
||||||
int type;
|
int type;
|
||||||
|
|
||||||
pthread_testcancel ();
|
|
||||||
|
|
||||||
if (get_inet_addr (name, namelen, &sst, &namelen, &type, connect_secret)
|
if (get_inet_addr (name, namelen, &sst, &namelen, &type, connect_secret)
|
||||||
== SOCKET_ERROR)
|
== SOCKET_ERROR)
|
||||||
return SOCKET_ERROR;
|
return SOCKET_ERROR;
|
||||||
@ -1181,8 +1178,6 @@ fhandler_socket::accept4 (struct sockaddr *peer, int *len, int flags)
|
|||||||
struct sockaddr_storage lpeer;
|
struct sockaddr_storage lpeer;
|
||||||
int llen = sizeof (struct sockaddr_storage);
|
int llen = sizeof (struct sockaddr_storage);
|
||||||
|
|
||||||
pthread_testcancel ();
|
|
||||||
|
|
||||||
int res = 0;
|
int res = 0;
|
||||||
while (!(res = wait_for_events (FD_ACCEPT | FD_CLOSE, 0))
|
while (!(res = wait_for_events (FD_ACCEPT | FD_CLOSE, 0))
|
||||||
&& (res = ::accept (get_socket (), (struct sockaddr *) &lpeer, &llen))
|
&& (res = ::accept (get_socket (), (struct sockaddr *) &lpeer, &llen))
|
||||||
@ -1355,30 +1350,6 @@ fhandler_socket::getpeername (struct sockaddr *name, int *namelen)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __stdcall
|
|
||||||
fhandler_socket::read (void *in_ptr, size_t& len)
|
|
||||||
{
|
|
||||||
WSABUF wsabuf = { len, (char *) in_ptr };
|
|
||||||
WSAMSG wsamsg = { NULL, 0, &wsabuf, 1, { 0, NULL }, 0 };
|
|
||||||
len = recv_internal (&wsamsg, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
fhandler_socket::readv (const struct iovec *const iov, const int iovcnt,
|
|
||||||
ssize_t tot)
|
|
||||||
{
|
|
||||||
WSABUF wsabuf[iovcnt];
|
|
||||||
WSABUF *wsaptr = wsabuf + iovcnt;
|
|
||||||
const struct iovec *iovptr = iov + iovcnt;
|
|
||||||
while (--wsaptr >= wsabuf)
|
|
||||||
{
|
|
||||||
wsaptr->len = (--iovptr)->iov_len;
|
|
||||||
wsaptr->buf = (char *) iovptr->iov_base;
|
|
||||||
}
|
|
||||||
WSAMSG wsamsg = { NULL, 0, wsabuf, iovcnt, { 0, NULL}, 0 };
|
|
||||||
return recv_internal (&wsamsg, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* There's no DLL which exports the symbol WSARecvMsg. One has to call
|
/* There's no DLL which exports the symbol WSARecvMsg. One has to call
|
||||||
WSAIoctl as below to fetch the function pointer. Why on earth did the
|
WSAIoctl as below to fetch the function pointer. Why on earth did the
|
||||||
MS developers decide not to export a normal symbol for these extension
|
MS developers decide not to export a normal symbol for these extension
|
||||||
@ -1556,17 +1527,79 @@ fhandler_socket::recv_internal (LPWSAMSG wsamsg, bool use_recvmsg)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void __stdcall
|
||||||
|
fhandler_socket::read (void *in_ptr, size_t& len)
|
||||||
|
{
|
||||||
|
char *ptr = (char *) in_ptr;
|
||||||
|
|
||||||
|
#ifdef __x86_64__
|
||||||
|
/* size_t is 64 bit, but the len member in WSABUF is 32 bit.
|
||||||
|
Split buffer if necessary. */
|
||||||
|
DWORD bufcnt = len / UINT32_MAX + ((!len || (len % UINT32_MAX)) ? 1 : 0);
|
||||||
|
WSABUF wsabuf[bufcnt];
|
||||||
|
WSAMSG wsamsg = { NULL, 0, wsabuf, bufcnt, { 0, NULL }, 0 };
|
||||||
|
/* Don't use len as loop condition, it could be 0. */
|
||||||
|
for (WSABUF *wsaptr = wsabuf; bufcnt--; ++wsaptr)
|
||||||
|
{
|
||||||
|
wsaptr->len = MIN (len, UINT32_MAX);
|
||||||
|
wsaptr->buf = ptr;
|
||||||
|
len -= wsaptr->len;
|
||||||
|
ptr += wsaptr->len;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
WSABUF wsabuf = { len, ptr };
|
||||||
|
WSAMSG wsamsg = { NULL, 0, &wsabuf, 1, { 0, NULL }, 0 };
|
||||||
|
#endif
|
||||||
|
|
||||||
|
len = recv_internal (&wsamsg, false);
|
||||||
|
}
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
fhandler_socket::recvfrom (void *ptr, size_t len, int flags,
|
fhandler_socket::readv (const struct iovec *const iov, const int iovcnt,
|
||||||
|
ssize_t tot)
|
||||||
|
{
|
||||||
|
WSABUF wsabuf[iovcnt];
|
||||||
|
WSABUF *wsaptr = wsabuf + iovcnt;
|
||||||
|
const struct iovec *iovptr = iov + iovcnt;
|
||||||
|
while (--wsaptr >= wsabuf)
|
||||||
|
{
|
||||||
|
wsaptr->len = (--iovptr)->iov_len;
|
||||||
|
wsaptr->buf = (char *) iovptr->iov_base;
|
||||||
|
}
|
||||||
|
WSAMSG wsamsg = { NULL, 0, wsabuf, (DWORD) iovcnt, { 0, NULL}, 0 };
|
||||||
|
return recv_internal (&wsamsg, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
fhandler_socket::recvfrom (void *in_ptr, size_t len, int flags,
|
||||||
struct sockaddr *from, int *fromlen)
|
struct sockaddr *from, int *fromlen)
|
||||||
{
|
{
|
||||||
pthread_testcancel ();
|
char *ptr = (char *) in_ptr;
|
||||||
|
|
||||||
WSABUF wsabuf = { len, (char *) ptr };
|
#ifdef __x86_64__
|
||||||
|
/* size_t is 64 bit, but the len member in WSABUF is 32 bit.
|
||||||
|
Split buffer if necessary. */
|
||||||
|
DWORD bufcnt = len / UINT32_MAX + ((!len || (len % UINT32_MAX)) ? 1 : 0);
|
||||||
|
WSABUF wsabuf[bufcnt];
|
||||||
|
WSAMSG wsamsg = { from, from && fromlen ? *fromlen : 0,
|
||||||
|
wsabuf, bufcnt,
|
||||||
|
{ 0, NULL },
|
||||||
|
(DWORD) flags };
|
||||||
|
/* Don't use len as loop condition, it could be 0. */
|
||||||
|
for (WSABUF *wsaptr = wsabuf; bufcnt--; ++wsaptr)
|
||||||
|
{
|
||||||
|
wsaptr->len = MIN (len, UINT32_MAX);
|
||||||
|
wsaptr->buf = ptr;
|
||||||
|
len -= wsaptr->len;
|
||||||
|
ptr += wsaptr->len;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
WSABUF wsabuf = { len, ptr };
|
||||||
WSAMSG wsamsg = { from, from && fromlen ? *fromlen : 0,
|
WSAMSG wsamsg = { from, from && fromlen ? *fromlen : 0,
|
||||||
&wsabuf, 1,
|
&wsabuf, 1,
|
||||||
{ 0, NULL},
|
{ 0, NULL},
|
||||||
flags };
|
(DWORD) flags };
|
||||||
|
#endif
|
||||||
ssize_t ret = recv_internal (&wsamsg, false);
|
ssize_t ret = recv_internal (&wsamsg, false);
|
||||||
if (fromlen)
|
if (fromlen)
|
||||||
*fromlen = wsamsg.namelen;
|
*fromlen = wsamsg.namelen;
|
||||||
@ -1576,15 +1609,12 @@ fhandler_socket::recvfrom (void *ptr, size_t len, int flags,
|
|||||||
ssize_t
|
ssize_t
|
||||||
fhandler_socket::recvmsg (struct msghdr *msg, int flags)
|
fhandler_socket::recvmsg (struct msghdr *msg, int flags)
|
||||||
{
|
{
|
||||||
pthread_testcancel ();
|
|
||||||
|
|
||||||
/* TODO: Descriptor passing on AF_LOCAL sockets. */
|
/* TODO: Descriptor passing on AF_LOCAL sockets. */
|
||||||
|
|
||||||
/* Disappointing but true: Even if WSARecvMsg is supported, it's only
|
/* Disappointing but true: Even if WSARecvMsg is supported, it's only
|
||||||
supported for datagram and raw sockets. */
|
supported for datagram and raw sockets. */
|
||||||
bool use_recvmsg = true;
|
bool use_recvmsg = true;
|
||||||
if (get_socket_type () == SOCK_STREAM || get_addr_family () == AF_LOCAL
|
if (get_socket_type () == SOCK_STREAM || get_addr_family () == AF_LOCAL)
|
||||||
|| !wincap.has_recvmsg ())
|
|
||||||
{
|
{
|
||||||
use_recvmsg = false;
|
use_recvmsg = false;
|
||||||
msg->msg_controllen = 0;
|
msg->msg_controllen = 0;
|
||||||
@ -1599,9 +1629,9 @@ fhandler_socket::recvmsg (struct msghdr *msg, int flags)
|
|||||||
wsaptr->buf = (char *) iovptr->iov_base;
|
wsaptr->buf = (char *) iovptr->iov_base;
|
||||||
}
|
}
|
||||||
WSAMSG wsamsg = { (struct sockaddr *) msg->msg_name, msg->msg_namelen,
|
WSAMSG wsamsg = { (struct sockaddr *) msg->msg_name, msg->msg_namelen,
|
||||||
wsabuf, msg->msg_iovlen,
|
wsabuf, (DWORD) msg->msg_iovlen,
|
||||||
{ msg->msg_controllen, (char *) msg->msg_control },
|
{ (DWORD) msg->msg_controllen, (char *) msg->msg_control },
|
||||||
flags };
|
(DWORD) flags };
|
||||||
ssize_t ret = recv_internal (&wsamsg, use_recvmsg);
|
ssize_t ret = recv_internal (&wsamsg, use_recvmsg);
|
||||||
if (ret >= 0)
|
if (ret >= 0)
|
||||||
{
|
{
|
||||||
@ -1613,34 +1643,10 @@ fhandler_socket::recvmsg (struct msghdr *msg, int flags)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
fhandler_socket::write (const void *ptr, size_t len)
|
|
||||||
{
|
|
||||||
WSABUF wsabuf = { len, (char *) ptr };
|
|
||||||
WSAMSG wsamsg = { NULL, 0, &wsabuf, 1, { 0, NULL }, 0 };
|
|
||||||
return send_internal (&wsamsg, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
fhandler_socket::writev (const struct iovec *const iov, const int iovcnt,
|
|
||||||
ssize_t tot)
|
|
||||||
{
|
|
||||||
WSABUF wsabuf[iovcnt];
|
|
||||||
WSABUF *wsaptr = wsabuf;
|
|
||||||
const struct iovec *iovptr = iov;
|
|
||||||
for (int i = 0; i < iovcnt; ++i)
|
|
||||||
{
|
|
||||||
wsaptr->len = iovptr->iov_len;
|
|
||||||
(wsaptr++)->buf = (char *) (iovptr++)->iov_base;
|
|
||||||
}
|
|
||||||
WSAMSG wsamsg = { NULL, 0, wsabuf, iovcnt, { 0, NULL}, 0 };
|
|
||||||
return send_internal (&wsamsg, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline ssize_t
|
inline ssize_t
|
||||||
fhandler_socket::send_internal (struct _WSAMSG *wsamsg, int flags)
|
fhandler_socket::send_internal (struct _WSAMSG *wsamsg, int flags)
|
||||||
{
|
{
|
||||||
int res = 0;
|
ssize_t res = 0;
|
||||||
DWORD ret = 0, err = 0, sum = 0, off = 0;
|
DWORD ret = 0, err = 0, sum = 0, off = 0;
|
||||||
WSABUF buf;
|
WSABUF buf;
|
||||||
bool use_sendmsg = false;
|
bool use_sendmsg = false;
|
||||||
@ -1721,25 +1727,85 @@ fhandler_socket::send_internal (struct _WSAMSG *wsamsg, int flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
fhandler_socket::sendto (const void *ptr, size_t len, int flags,
|
fhandler_socket::write (const void *in_ptr, size_t len)
|
||||||
|
{
|
||||||
|
char *ptr = (char *) in_ptr;
|
||||||
|
|
||||||
|
#ifdef __x86_64__
|
||||||
|
/* size_t is 64 bit, but the len member in WSABUF is 32 bit.
|
||||||
|
Split buffer if necessary. */
|
||||||
|
DWORD bufcnt = len / UINT32_MAX + ((!len || (len % UINT32_MAX)) ? 1 : 0);
|
||||||
|
WSABUF wsabuf[bufcnt];
|
||||||
|
WSAMSG wsamsg = { NULL, 0, wsabuf, bufcnt, { 0, NULL }, 0 };
|
||||||
|
/* Don't use len as loop condition, it could be 0. */
|
||||||
|
for (WSABUF *wsaptr = wsabuf; bufcnt--; ++wsaptr)
|
||||||
|
{
|
||||||
|
wsaptr->len = MIN (len, UINT32_MAX);
|
||||||
|
wsaptr->buf = ptr;
|
||||||
|
len -= wsaptr->len;
|
||||||
|
ptr += wsaptr->len;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
WSABUF wsabuf = { len, ptr };
|
||||||
|
WSAMSG wsamsg = { NULL, 0, &wsabuf, 1, { 0, NULL }, 0 };
|
||||||
|
#endif
|
||||||
|
return send_internal (&wsamsg, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
fhandler_socket::writev (const struct iovec *const iov, const int iovcnt,
|
||||||
|
ssize_t tot)
|
||||||
|
{
|
||||||
|
WSABUF wsabuf[iovcnt];
|
||||||
|
WSABUF *wsaptr = wsabuf;
|
||||||
|
const struct iovec *iovptr = iov;
|
||||||
|
for (int i = 0; i < iovcnt; ++i)
|
||||||
|
{
|
||||||
|
wsaptr->len = iovptr->iov_len;
|
||||||
|
(wsaptr++)->buf = (char *) (iovptr++)->iov_base;
|
||||||
|
}
|
||||||
|
WSAMSG wsamsg = { NULL, 0, wsabuf, (DWORD) iovcnt, { 0, NULL}, 0 };
|
||||||
|
return send_internal (&wsamsg, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
fhandler_socket::sendto (const void *in_ptr, size_t len, int flags,
|
||||||
const struct sockaddr *to, int tolen)
|
const struct sockaddr *to, int tolen)
|
||||||
{
|
{
|
||||||
|
char *ptr = (char *) in_ptr;
|
||||||
struct sockaddr_storage sst;
|
struct sockaddr_storage sst;
|
||||||
|
|
||||||
pthread_testcancel ();
|
|
||||||
|
|
||||||
if (to && get_inet_addr (to, tolen, &sst, &tolen) == SOCKET_ERROR)
|
if (to && get_inet_addr (to, tolen, &sst, &tolen) == SOCKET_ERROR)
|
||||||
return SOCKET_ERROR;
|
return SOCKET_ERROR;
|
||||||
|
|
||||||
WSABUF wsabuf = { len, (char *) ptr };
|
#ifdef __x86_64__
|
||||||
|
/* size_t is 64 bit, but the len member in WSABUF is 32 bit.
|
||||||
|
Split buffer if necessary. */
|
||||||
|
DWORD bufcnt = len / UINT32_MAX + ((!len || (len % UINT32_MAX)) ? 1 : 0);
|
||||||
|
WSABUF wsabuf[bufcnt];
|
||||||
|
WSAMSG wsamsg = { to ? (struct sockaddr *) &sst : NULL, tolen,
|
||||||
|
wsabuf, bufcnt,
|
||||||
|
{ 0, NULL },
|
||||||
|
0 };
|
||||||
|
/* Don't use len as loop condition, it could be 0. */
|
||||||
|
for (WSABUF *wsaptr = wsabuf; bufcnt--; ++wsaptr)
|
||||||
|
{
|
||||||
|
wsaptr->len = MIN (len, UINT32_MAX);
|
||||||
|
wsaptr->buf = ptr;
|
||||||
|
len -= wsaptr->len;
|
||||||
|
ptr += wsaptr->len;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
WSABUF wsabuf = { len, ptr };
|
||||||
WSAMSG wsamsg = { to ? (struct sockaddr *) &sst : NULL, tolen,
|
WSAMSG wsamsg = { to ? (struct sockaddr *) &sst : NULL, tolen,
|
||||||
&wsabuf, 1,
|
&wsabuf, 1,
|
||||||
{ 0, NULL},
|
{ 0, NULL},
|
||||||
0 };
|
0 };
|
||||||
|
#endif
|
||||||
return send_internal (&wsamsg, flags);
|
return send_internal (&wsamsg, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
ssize_t
|
||||||
fhandler_socket::sendmsg (const struct msghdr *msg, int flags)
|
fhandler_socket::sendmsg (const struct msghdr *msg, int flags)
|
||||||
{
|
{
|
||||||
/* TODO: Descriptor passing on AF_LOCAL sockets. */
|
/* TODO: Descriptor passing on AF_LOCAL sockets. */
|
||||||
@ -1747,8 +1813,6 @@ fhandler_socket::sendmsg (const struct msghdr *msg, int flags)
|
|||||||
struct sockaddr_storage sst;
|
struct sockaddr_storage sst;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
pthread_testcancel ();
|
|
||||||
|
|
||||||
if (msg->msg_name
|
if (msg->msg_name
|
||||||
&& get_inet_addr ((struct sockaddr *) msg->msg_name, msg->msg_namelen,
|
&& get_inet_addr ((struct sockaddr *) msg->msg_name, msg->msg_namelen,
|
||||||
&sst, &len) == SOCKET_ERROR)
|
&sst, &len) == SOCKET_ERROR)
|
||||||
@ -1762,15 +1826,15 @@ fhandler_socket::sendmsg (const struct msghdr *msg, int flags)
|
|||||||
wsaptr->len = iovptr->iov_len;
|
wsaptr->len = iovptr->iov_len;
|
||||||
(wsaptr++)->buf = (char *) (iovptr++)->iov_base;
|
(wsaptr++)->buf = (char *) (iovptr++)->iov_base;
|
||||||
}
|
}
|
||||||
|
/* Disappointing but true: Even if WSASendMsg is supported, it's only
|
||||||
|
supported for datagram and raw sockets. */
|
||||||
|
DWORD controllen = (DWORD) (!wincap.has_sendmsg ()
|
||||||
|
|| get_socket_type () == SOCK_STREAM
|
||||||
|
|| get_addr_family () == AF_LOCAL
|
||||||
|
? 0 : msg->msg_controllen);
|
||||||
WSAMSG wsamsg = { msg->msg_name ? (struct sockaddr *) &sst : NULL, len,
|
WSAMSG wsamsg = { msg->msg_name ? (struct sockaddr *) &sst : NULL, len,
|
||||||
wsabuf, msg->msg_iovlen,
|
wsabuf, (DWORD) msg->msg_iovlen,
|
||||||
/* Disappointing but true: Even if WSASendMsg is
|
{ controllen, (char *) msg->msg_control },
|
||||||
supported, it's only supported for datagram and
|
|
||||||
raw sockets. */
|
|
||||||
{ !wincap.has_sendmsg ()
|
|
||||||
|| get_socket_type () == SOCK_STREAM
|
|
||||||
|| get_addr_family () == AF_LOCAL
|
|
||||||
? 0 : msg->msg_controllen, (char *) msg->msg_control },
|
|
||||||
0 };
|
0 };
|
||||||
return send_internal (&wsamsg, flags);
|
return send_internal (&wsamsg, flags);
|
||||||
}
|
}
|
||||||
@ -1818,20 +1882,7 @@ int
|
|||||||
fhandler_socket::close ()
|
fhandler_socket::close ()
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
/* TODO: CV - 2008-04-16. Lingering disabled. The original problem
|
|
||||||
could be no longer reproduced on NT4, XP, 2K8. Any return of a
|
|
||||||
spurious "Connection reset by peer" *could* be caused by disabling
|
|
||||||
the linger code here... */
|
|
||||||
#if 0
|
|
||||||
/* HACK to allow a graceful shutdown even if shutdown() hasn't been
|
|
||||||
called by the application. Note that this isn't the ultimate
|
|
||||||
solution but it helps in many cases. */
|
|
||||||
struct linger linger;
|
|
||||||
linger.l_onoff = 1;
|
|
||||||
linger.l_linger = 240; /* secs. default 2MSL value according to MSDN. */
|
|
||||||
setsockopt (get_socket (), SOL_SOCKET, SO_LINGER,
|
|
||||||
(const char *)&linger, sizeof linger);
|
|
||||||
#endif
|
|
||||||
release_events ();
|
release_events ();
|
||||||
while ((res = closesocket (get_socket ())) != 0)
|
while ((res = closesocket (get_socket ())) != 0)
|
||||||
{
|
{
|
||||||
@ -2040,7 +2091,17 @@ fhandler_socket::ioctl (unsigned int cmd, void *p)
|
|||||||
WSAEventSelect (get_socket (), wsock_evt, EVENT_MASK);
|
WSAEventSelect (get_socket (), wsock_evt, EVENT_MASK);
|
||||||
break;
|
break;
|
||||||
case FIONREAD:
|
case FIONREAD:
|
||||||
res = ioctlsocket (get_socket (), FIONREAD, (unsigned long *) p);
|
#ifdef __x86_64__
|
||||||
|
/* FIXME: This looks broken in the Mingw64 headers. If I make sure
|
||||||
|
to use the Windows u_long definition, I'd expect that it's defined
|
||||||
|
as a 4 byte type on LP64 as well. But that's not the case right now.
|
||||||
|
The *additional* type __ms_u_long is available on LP64, and that's
|
||||||
|
used in subsequent function declarations, but that's not available
|
||||||
|
on 32 bit or LLP64. The LP64-ness shouldn't require to use another
|
||||||
|
type name in the application code. */
|
||||||
|
#define u_long __ms_u_long
|
||||||
|
#endif
|
||||||
|
res = ioctlsocket (get_socket (), FIONREAD, (u_long *) p);
|
||||||
if (res == SOCKET_ERROR)
|
if (res == SOCKET_ERROR)
|
||||||
set_winsock_errno ();
|
set_winsock_errno ();
|
||||||
break;
|
break;
|
||||||
@ -2055,15 +2116,15 @@ fhandler_socket::ioctl (unsigned int cmd, void *p)
|
|||||||
res = 0;
|
res = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
res = ioctlsocket (get_socket (), cmd, (unsigned long *) p);
|
res = ioctlsocket (get_socket (), cmd, (u_long *) p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
syscall_printf ("%d = ioctl_socket(%x, %x)", res, cmd, p);
|
syscall_printf ("%d = ioctl_socket(%x, %p)", res, cmd, p);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_socket::fcntl (int cmd, void *arg)
|
fhandler_socket::fcntl (int cmd, intptr_t arg)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
int request, current;
|
int request, current;
|
||||||
@ -2087,7 +2148,7 @@ fhandler_socket::fcntl (int cmd, void *arg)
|
|||||||
/* Carefully test for the O_NONBLOCK or deprecated OLD_O_NDELAY flag.
|
/* Carefully test for the O_NONBLOCK or deprecated OLD_O_NDELAY flag.
|
||||||
Set only the flag that has been passed in. If both are set, just
|
Set only the flag that has been passed in. If both are set, just
|
||||||
record O_NONBLOCK. */
|
record O_NONBLOCK. */
|
||||||
int new_flags = (int) arg & O_NONBLOCK_MASK;
|
int new_flags = arg & O_NONBLOCK_MASK;
|
||||||
if ((new_flags & OLD_O_NDELAY) && (new_flags & O_NONBLOCK))
|
if ((new_flags & OLD_O_NDELAY) && (new_flags & O_NONBLOCK))
|
||||||
new_flags = O_NONBLOCK;
|
new_flags = O_NONBLOCK;
|
||||||
current = get_flags () & O_NONBLOCK_MASK;
|
current = get_flags () & O_NONBLOCK_MASK;
|
||||||
@ -2131,7 +2192,7 @@ fhandler_socket::set_peer_sun_path (const char *path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_socket::getpeereid (pid_t *pid, __uid32_t *euid, __gid32_t *egid)
|
fhandler_socket::getpeereid (pid_t *pid, uid_t *euid, gid_t *egid)
|
||||||
{
|
{
|
||||||
if (get_addr_family () != AF_LOCAL || get_socket_type () != SOCK_STREAM)
|
if (get_addr_family () != AF_LOCAL || get_socket_type () != SOCK_STREAM)
|
||||||
{
|
{
|
||||||
|
@ -53,7 +53,7 @@ details. */
|
|||||||
/* mtinfo_part */
|
/* mtinfo_part */
|
||||||
|
|
||||||
void
|
void
|
||||||
mtinfo_part::initialize (long nblock)
|
mtinfo_part::initialize (int32_t nblock)
|
||||||
{
|
{
|
||||||
block = nblock;
|
block = nblock;
|
||||||
if (block == 0)
|
if (block == 0)
|
||||||
@ -182,7 +182,7 @@ mtinfo_drive::close (HANDLE mt, bool rewind)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
mtinfo_drive::read (HANDLE mt, HANDLE mt_evt, void *ptr, size_t &ulen)
|
mtinfo_drive::read (HANDLE mt, LPOVERLAPPED pov, void *ptr, size_t &ulen)
|
||||||
{
|
{
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
DWORD bytes_read = 0;
|
DWORD bytes_read = 0;
|
||||||
@ -231,17 +231,17 @@ mtinfo_drive::read (HANDLE mt, HANDLE mt_evt, void *ptr, size_t &ulen)
|
|||||||
part (partition)->smark = false;
|
part (partition)->smark = false;
|
||||||
if (auto_lock () && lock < auto_locked)
|
if (auto_lock () && lock < auto_locked)
|
||||||
prepare (mt, TAPE_LOCK, true);
|
prepare (mt, TAPE_LOCK, true);
|
||||||
ov.Offset = ov.OffsetHigh = 0;
|
ov = pov;
|
||||||
ov.hEvent = mt_evt;
|
ov->Offset = ov->OffsetHigh = 0;
|
||||||
ret = ReadFile (mt, ptr, ulen, &bytes_read, &ov);
|
ret = ReadFile (mt, ptr, ulen, &bytes_read, ov);
|
||||||
lasterr = ret ? 0 : GetLastError ();
|
lasterr = ret ? 0 : GetLastError ();
|
||||||
if (lasterr == ERROR_IO_PENDING)
|
if (lasterr == ERROR_IO_PENDING)
|
||||||
lasterr = async_wait (mt, &bytes_read);
|
lasterr = async_wait (mt, &bytes_read);
|
||||||
ulen = (size_t) bytes_read;
|
ulen = (size_t) bytes_read;
|
||||||
if (bytes_read > 0)
|
if (bytes_read > 0)
|
||||||
{
|
{
|
||||||
long blocks_read = mp ()->BlockSize == 0
|
int32_t blocks_read = mp ()->BlockSize == 0
|
||||||
? 1 : howmany (bytes_read, mp ()->BlockSize);
|
? 1 : howmany (bytes_read, mp ()->BlockSize);
|
||||||
block += blocks_read;
|
block += blocks_read;
|
||||||
part (partition)->block += blocks_read;
|
part (partition)->block += blocks_read;
|
||||||
if (part (partition)->fblock >= 0)
|
if (part (partition)->fblock >= 0)
|
||||||
@ -287,14 +287,14 @@ mtinfo_drive::async_wait (HANDLE mt, DWORD *bytes_written)
|
|||||||
{
|
{
|
||||||
DWORD written;
|
DWORD written;
|
||||||
|
|
||||||
bool ret = GetOverlappedResult (mt, &ov, &written, TRUE);
|
bool ret = GetOverlappedResult (mt, ov, &written, TRUE);
|
||||||
if (bytes_written)
|
if (bytes_written)
|
||||||
*bytes_written = written;
|
*bytes_written = written;
|
||||||
return ret ? 0 : GetLastError ();
|
return ret ? 0 : GetLastError ();
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
mtinfo_drive::write (HANDLE mt, HANDLE mt_evt, const void *ptr, size_t &len)
|
mtinfo_drive::write (HANDLE mt, LPOVERLAPPED pov, const void *ptr, size_t &len)
|
||||||
{
|
{
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
DWORD bytes_written = 0;
|
DWORD bytes_written = 0;
|
||||||
@ -313,9 +313,9 @@ mtinfo_drive::write (HANDLE mt, HANDLE mt_evt, const void *ptr, size_t &len)
|
|||||||
part (partition)->smark = false;
|
part (partition)->smark = false;
|
||||||
if (auto_lock () && lock < auto_locked)
|
if (auto_lock () && lock < auto_locked)
|
||||||
prepare (mt, TAPE_LOCK, true);
|
prepare (mt, TAPE_LOCK, true);
|
||||||
ov.Offset = ov.OffsetHigh = 0;
|
ov = pov;
|
||||||
ov.hEvent = mt_evt;
|
ov->Offset = ov->OffsetHigh = 0;
|
||||||
ret = WriteFile (mt, ptr, len, &bytes_written, &ov);
|
ret = WriteFile (mt, ptr, len, &bytes_written, ov);
|
||||||
lasterr = ret ? 0: GetLastError ();
|
lasterr = ret ? 0: GetLastError ();
|
||||||
if (lasterr == ERROR_IO_PENDING)
|
if (lasterr == ERROR_IO_PENDING)
|
||||||
{
|
{
|
||||||
@ -328,8 +328,8 @@ mtinfo_drive::write (HANDLE mt, HANDLE mt_evt, const void *ptr, size_t &len)
|
|||||||
len = (size_t) bytes_written;
|
len = (size_t) bytes_written;
|
||||||
if (bytes_written > 0)
|
if (bytes_written > 0)
|
||||||
{
|
{
|
||||||
long blocks_written = mp ()->BlockSize == 0
|
int32_t blocks_written = mp ()->BlockSize == 0
|
||||||
? 1 : howmany (bytes_written, mp ()->BlockSize);
|
? 1 : howmany (bytes_written, mp ()->BlockSize);
|
||||||
block += blocks_written;
|
block += blocks_written;
|
||||||
part (partition)->block += blocks_written;
|
part (partition)->block += blocks_written;
|
||||||
if (part (partition)->fblock >= 0)
|
if (part (partition)->fblock >= 0)
|
||||||
@ -353,7 +353,7 @@ mtinfo_drive::write (HANDLE mt, HANDLE mt_evt, const void *ptr, size_t &len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
mtinfo_drive::get_pos (HANDLE mt, long *ppartition, long *pblock)
|
mtinfo_drive::get_pos (HANDLE mt, int32_t *ppartition, int32_t *pblock)
|
||||||
{
|
{
|
||||||
DWORD p, low, high;
|
DWORD p, low, high;
|
||||||
|
|
||||||
@ -363,8 +363,8 @@ mtinfo_drive::get_pos (HANDLE mt, long *ppartition, long *pblock)
|
|||||||
if (!lasterr)
|
if (!lasterr)
|
||||||
{
|
{
|
||||||
if (p > 0)
|
if (p > 0)
|
||||||
partition = (long) p - 1;
|
partition = (int32_t) p - 1;
|
||||||
block = (long) low;
|
block = (int32_t) low;
|
||||||
if (ppartition)
|
if (ppartition)
|
||||||
*ppartition= partition;
|
*ppartition= partition;
|
||||||
if (pblock)
|
if (pblock)
|
||||||
@ -379,7 +379,7 @@ mtinfo_drive::get_pos (HANDLE mt, long *ppartition, long *pblock)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
mtinfo_drive::_set_pos (HANDLE mt, int mode, long count, int partition,
|
mtinfo_drive::_set_pos (HANDLE mt, int mode, int32_t count, int partition,
|
||||||
BOOL dont_wait)
|
BOOL dont_wait)
|
||||||
{
|
{
|
||||||
/* If an async write is still pending, wait for completion. */
|
/* If an async write is still pending, wait for completion. */
|
||||||
@ -392,11 +392,11 @@ mtinfo_drive::_set_pos (HANDLE mt, int mode, long count, int partition,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
mtinfo_drive::set_pos (HANDLE mt, int mode, long count,
|
mtinfo_drive::set_pos (HANDLE mt, int mode, int32_t count,
|
||||||
bool sfm_func)
|
bool sfm_func)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
long undone = count;
|
int32_t undone = count;
|
||||||
BOOL dont_wait = FALSE;
|
BOOL dont_wait = FALSE;
|
||||||
|
|
||||||
switch (mode)
|
switch (mode)
|
||||||
@ -547,7 +547,7 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
mtinfo_drive::create_partitions (HANDLE mt, long count)
|
mtinfo_drive::create_partitions (HANDLE mt, int32_t count)
|
||||||
{
|
{
|
||||||
if (dp ()->MaximumPartitionCount <= 1)
|
if (dp ()->MaximumPartitionCount <= 1)
|
||||||
return ERROR_INVALID_PARAMETER;
|
return ERROR_INVALID_PARAMETER;
|
||||||
@ -578,9 +578,9 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
mtinfo_drive::set_partition (HANDLE mt, long count)
|
mtinfo_drive::set_partition (HANDLE mt, int32_t count)
|
||||||
{
|
{
|
||||||
if (count < 0 || (unsigned long) count >= MAX_PARTITION_NUM)
|
if (count < 0 || (uint32_t) count >= MAX_PARTITION_NUM)
|
||||||
lasterr = ERROR_INVALID_PARAMETER;
|
lasterr = ERROR_INVALID_PARAMETER;
|
||||||
else if ((DWORD) count >= dp ()->MaximumPartitionCount)
|
else if ((DWORD) count >= dp ()->MaximumPartitionCount)
|
||||||
lasterr = ERROR_IO_DEVICE;
|
lasterr = ERROR_IO_DEVICE;
|
||||||
@ -715,14 +715,14 @@ mtinfo_drive::prepare (HANDLE mt, int action, bool is_auto)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
mtinfo_drive::set_compression (HANDLE mt, long count)
|
mtinfo_drive::set_compression (HANDLE mt, int32_t count)
|
||||||
{
|
{
|
||||||
if (!get_feature (TAPE_DRIVE_SET_COMPRESSION))
|
if (!get_feature (TAPE_DRIVE_SET_COMPRESSION))
|
||||||
return ERROR_INVALID_PARAMETER;
|
return ERROR_INVALID_PARAMETER;
|
||||||
TAPE_SET_DRIVE_PARAMETERS sdp =
|
TAPE_SET_DRIVE_PARAMETERS sdp =
|
||||||
{
|
{
|
||||||
dp ()->ECC,
|
dp ()->ECC,
|
||||||
count ? TRUE : FALSE,
|
(BOOLEAN) (count ? TRUE : FALSE),
|
||||||
dp ()->DataPadding,
|
dp ()->DataPadding,
|
||||||
dp ()->ReportSetmarks,
|
dp ()->ReportSetmarks,
|
||||||
dp ()->EOTWarningZoneSize
|
dp ()->EOTWarningZoneSize
|
||||||
@ -738,7 +738,7 @@ mtinfo_drive::set_compression (HANDLE mt, long count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
mtinfo_drive::set_blocksize (HANDLE mt, long count)
|
mtinfo_drive::set_blocksize (HANDLE mt, DWORD count)
|
||||||
{
|
{
|
||||||
TAPE_SET_MEDIA_PARAMETERS smp = {count};
|
TAPE_SET_MEDIA_PARAMETERS smp = {count};
|
||||||
TAPE_FUNC (SetTapeParameters (mt, SET_TAPE_MEDIA_INFORMATION, &smp));
|
TAPE_FUNC (SetTapeParameters (mt, SET_TAPE_MEDIA_INFORMATION, &smp));
|
||||||
@ -768,32 +768,29 @@ mtinfo_drive::get_status (HANDLE mt, struct mtget *get)
|
|||||||
get->mt_dsreg = (dp ()->DefaultBlockSize << MT_ST_BLKSIZE_SHIFT)
|
get->mt_dsreg = (dp ()->DefaultBlockSize << MT_ST_BLKSIZE_SHIFT)
|
||||||
& MT_ST_BLKSIZE_MASK;
|
& MT_ST_BLKSIZE_MASK;
|
||||||
|
|
||||||
if (wincap.has_ioctl_storage_get_media_types_ex ())
|
DWORD size = sizeof (GET_MEDIA_TYPES) + 10 * sizeof (DEVICE_MEDIA_INFO);
|
||||||
|
void *buf = alloca (size);
|
||||||
|
if (DeviceIoControl (mt, IOCTL_STORAGE_GET_MEDIA_TYPES_EX,
|
||||||
|
NULL, 0, buf, size, &size, NULL)
|
||||||
|
|| GetLastError () == ERROR_MORE_DATA)
|
||||||
{
|
{
|
||||||
DWORD size = sizeof (GET_MEDIA_TYPES) + 10 * sizeof (DEVICE_MEDIA_INFO);
|
PGET_MEDIA_TYPES gmt = (PGET_MEDIA_TYPES) buf;
|
||||||
void *buf = alloca (size);
|
for (DWORD i = 0; i < gmt->MediaInfoCount; ++i)
|
||||||
if (DeviceIoControl (mt, IOCTL_STORAGE_GET_MEDIA_TYPES_EX,
|
|
||||||
NULL, 0, buf, size, &size, NULL)
|
|
||||||
|| GetLastError () == ERROR_MORE_DATA)
|
|
||||||
{
|
{
|
||||||
PGET_MEDIA_TYPES gmt = (PGET_MEDIA_TYPES) buf;
|
PDEVICE_MEDIA_INFO dmi = &gmt->MediaInfo[i];
|
||||||
for (DWORD i = 0; i < gmt->MediaInfoCount; ++i)
|
get->mt_type = dmi->DeviceSpecific.TapeInfo.MediaType;
|
||||||
{
|
|
||||||
PDEVICE_MEDIA_INFO dmi = &gmt->MediaInfo[i];
|
|
||||||
get->mt_type = dmi->DeviceSpecific.TapeInfo.MediaType;
|
|
||||||
#define TINFO DeviceSpecific.TapeInfo
|
#define TINFO DeviceSpecific.TapeInfo
|
||||||
if (dmi->TINFO.MediaCharacteristics & MEDIA_CURRENTLY_MOUNTED)
|
if (dmi->TINFO.MediaCharacteristics & MEDIA_CURRENTLY_MOUNTED)
|
||||||
{
|
{
|
||||||
get->mt_type = dmi->DeviceSpecific.TapeInfo.MediaType;
|
get->mt_type = dmi->DeviceSpecific.TapeInfo.MediaType;
|
||||||
if (dmi->TINFO.BusType == BusTypeScsi)
|
if (dmi->TINFO.BusType == BusTypeScsi)
|
||||||
get->mt_dsreg |=
|
get->mt_dsreg |=
|
||||||
(dmi->TINFO.BusSpecificData.ScsiInformation.DensityCode
|
(dmi->TINFO.BusSpecificData.ScsiInformation.DensityCode
|
||||||
<< MT_ST_DENSITY_SHIFT)
|
<< MT_ST_DENSITY_SHIFT)
|
||||||
& MT_ST_DENSITY_MASK;
|
& MT_ST_DENSITY_MASK;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
#undef TINFO
|
|
||||||
}
|
}
|
||||||
|
#undef TINFO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -870,9 +867,9 @@ mtinfo_drive::get_status (HANDLE mt, struct mtget *get)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
mtinfo_drive::set_options (HANDLE mt, long options)
|
mtinfo_drive::set_options (HANDLE mt, int32_t options)
|
||||||
{
|
{
|
||||||
long what = (options & MT_ST_OPTIONS);
|
int32_t what = (options & MT_ST_OPTIONS);
|
||||||
bool call_setparams = false;
|
bool call_setparams = false;
|
||||||
bool set;
|
bool set;
|
||||||
TAPE_SET_DRIVE_PARAMETERS sdp =
|
TAPE_SET_DRIVE_PARAMETERS sdp =
|
||||||
@ -1234,8 +1231,8 @@ fhandler_dev_tape::close ()
|
|||||||
cret = fhandler_dev_raw::close ();
|
cret = fhandler_dev_raw::close ();
|
||||||
unlock (0);
|
unlock (0);
|
||||||
}
|
}
|
||||||
if (mt_evt)
|
if (ov.hEvent)
|
||||||
CloseHandle (mt_evt);
|
CloseHandle (ov.hEvent);
|
||||||
CloseHandle (mt_mtx);
|
CloseHandle (mt_mtx);
|
||||||
return ret ? -1 : cret;
|
return ret ? -1 : cret;
|
||||||
}
|
}
|
||||||
@ -1267,7 +1264,7 @@ fhandler_dev_tape::raw_read (void *ptr, size_t &ulen)
|
|||||||
if (devbufend > devbufstart)
|
if (devbufend > devbufstart)
|
||||||
{
|
{
|
||||||
bytes_to_read = MIN (len, devbufend - devbufstart);
|
bytes_to_read = MIN (len, devbufend - devbufstart);
|
||||||
debug_printf ("read %d bytes from buffer (rest %d)",
|
debug_printf ("read %lu bytes from buffer (rest %lu)",
|
||||||
bytes_to_read, devbufend - devbufstart - bytes_to_read);
|
bytes_to_read, devbufend - devbufstart - bytes_to_read);
|
||||||
memcpy (buf, devbuf + devbufstart, bytes_to_read);
|
memcpy (buf, devbuf + devbufstart, bytes_to_read);
|
||||||
len -= bytes_to_read;
|
len -= bytes_to_read;
|
||||||
@ -1284,15 +1281,16 @@ fhandler_dev_tape::raw_read (void *ptr, size_t &ulen)
|
|||||||
}
|
}
|
||||||
if (len > 0)
|
if (len > 0)
|
||||||
{
|
{
|
||||||
if (!mt_evt && !(mt_evt = CreateEvent (&sec_none, TRUE, FALSE, NULL)))
|
if (!ov.hEvent
|
||||||
|
&& !(ov.hEvent = CreateEvent (&sec_none, TRUE, FALSE, NULL)))
|
||||||
debug_printf ("Creating event failed, %E");
|
debug_printf ("Creating event failed, %E");
|
||||||
size_t block_fit = !block_size ? len : rounddown(len, block_size);
|
size_t block_fit = !block_size ? len : rounddown(len, block_size);
|
||||||
if (block_fit)
|
if (block_fit)
|
||||||
{
|
{
|
||||||
debug_printf ("read %d bytes from tape (rest %d)",
|
debug_printf ("read %lu bytes from tape (rest %lu)",
|
||||||
block_fit, len - block_fit);
|
block_fit, len - block_fit);
|
||||||
ret = mt.drive (driveno ())->read (get_handle (), mt_evt, buf,
|
ret = mt.drive (driveno ())->read (get_handle (), &ov, buf,
|
||||||
block_fit);
|
block_fit);
|
||||||
if (ret)
|
if (ret)
|
||||||
__seterrno_from_win_error (ret);
|
__seterrno_from_win_error (ret);
|
||||||
else if (block_fit)
|
else if (block_fit)
|
||||||
@ -1312,9 +1310,9 @@ fhandler_dev_tape::raw_read (void *ptr, size_t &ulen)
|
|||||||
}
|
}
|
||||||
if (!ret && len > 0)
|
if (!ret && len > 0)
|
||||||
{
|
{
|
||||||
debug_printf ("read %d bytes from tape (one block)", block_size);
|
debug_printf ("read %lu bytes from tape (one block)", block_size);
|
||||||
ret = mt.drive (driveno ())->read (get_handle (), mt_evt, devbuf,
|
ret = mt.drive (driveno ())->read (get_handle (), &ov, devbuf,
|
||||||
block_size);
|
block_size);
|
||||||
if (ret)
|
if (ret)
|
||||||
__seterrno_from_win_error (ret);
|
__seterrno_from_win_error (ret);
|
||||||
else if (block_size)
|
else if (block_size)
|
||||||
@ -1331,11 +1329,11 @@ fhandler_dev_tape::raw_read (void *ptr, size_t &ulen)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!mt_evt && !(mt_evt = CreateEvent (&sec_none, TRUE, FALSE, NULL)))
|
if (!ov.hEvent
|
||||||
|
&& !(ov.hEvent = CreateEvent (&sec_none, TRUE, FALSE, NULL)))
|
||||||
debug_printf ("Creating event failed, %E");
|
debug_printf ("Creating event failed, %E");
|
||||||
bytes_read = ulen;
|
bytes_read = ulen;
|
||||||
ret = mt.drive (driveno ())->read (get_handle (), mt_evt, ptr,
|
ret = mt.drive (driveno ())->read (get_handle (), &ov, ptr, bytes_read);
|
||||||
bytes_read);
|
|
||||||
}
|
}
|
||||||
ulen = (ret ? (size_t) -1 : bytes_read);
|
ulen = (ret ? (size_t) -1 : bytes_read);
|
||||||
unlock ();
|
unlock ();
|
||||||
@ -1346,25 +1344,25 @@ fhandler_dev_tape::raw_write (const void *ptr, size_t len)
|
|||||||
{
|
{
|
||||||
if (!_lock (true))
|
if (!_lock (true))
|
||||||
return -1;
|
return -1;
|
||||||
if (!mt_evt && !(mt_evt = CreateEvent (&sec_none, TRUE, FALSE, NULL)))
|
if (!ov.hEvent && !(ov.hEvent = CreateEvent (&sec_none, TRUE, FALSE, NULL)))
|
||||||
debug_printf ("Creating event failed, %E");
|
debug_printf ("Creating event failed, %E");
|
||||||
int ret = mt.drive (driveno ())->write (get_handle (), mt_evt, ptr, len);
|
int ret = mt.drive (driveno ())->write (get_handle (), &ov, ptr, len);
|
||||||
if (ret)
|
if (ret)
|
||||||
__seterrno_from_win_error (ret);
|
__seterrno_from_win_error (ret);
|
||||||
return unlock (ret ? -1 : (int) len);
|
return unlock (ret ? -1 : (int) len);
|
||||||
}
|
}
|
||||||
|
|
||||||
_off64_t
|
off_t
|
||||||
fhandler_dev_tape::lseek (_off64_t offset, int whence)
|
fhandler_dev_tape::lseek (off_t offset, int whence)
|
||||||
{
|
{
|
||||||
struct mtop op;
|
struct mtop op;
|
||||||
struct mtpos pos;
|
struct mtpos pos;
|
||||||
DWORD block_size;
|
DWORD block_size;
|
||||||
_off64_t ret = ILLEGAL_SEEK;
|
off_t ret = ILLEGAL_SEEK;
|
||||||
|
|
||||||
lock (ILLEGAL_SEEK);
|
lock (ILLEGAL_SEEK);
|
||||||
|
|
||||||
debug_printf ("lseek (%s, %d, %d)", get_name (), offset, whence);
|
debug_printf ("lseek (%s, %D, %d)", get_name (), offset, whence);
|
||||||
|
|
||||||
block_size = mt.drive (driveno ())->mp ()->BlockSize;
|
block_size = mt.drive (driveno ())->mp ()->BlockSize;
|
||||||
if (block_size == 0)
|
if (block_size == 0)
|
||||||
@ -1418,7 +1416,7 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int __reg2
|
int __reg2
|
||||||
fhandler_dev_tape::fstat (struct __stat64 *buf)
|
fhandler_dev_tape::fstat (struct stat *buf)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -1441,19 +1439,19 @@ fhandler_dev_tape::dup (fhandler_base *child, int flags)
|
|||||||
GetCurrentProcess (), &fh->mt_mtx,
|
GetCurrentProcess (), &fh->mt_mtx,
|
||||||
0, TRUE, DUPLICATE_SAME_ACCESS))
|
0, TRUE, DUPLICATE_SAME_ACCESS))
|
||||||
{
|
{
|
||||||
debug_printf ("dup(%s) failed, mutex handle %x, %E",
|
debug_printf ("dup(%s) failed, mutex handle %p, %E",
|
||||||
get_name (), mt_mtx);
|
get_name (), mt_mtx);
|
||||||
__seterrno ();
|
__seterrno ();
|
||||||
return unlock (-1);
|
return unlock (-1);
|
||||||
}
|
}
|
||||||
fh->mt_evt = NULL;
|
fh->ov.hEvent = NULL;
|
||||||
if (mt_evt &&
|
if (ov.hEvent &&
|
||||||
!DuplicateHandle (GetCurrentProcess (), mt_evt,
|
!DuplicateHandle (GetCurrentProcess (), ov.hEvent,
|
||||||
GetCurrentProcess (), &fh->mt_evt,
|
GetCurrentProcess (), &fh->ov.hEvent,
|
||||||
0, TRUE, DUPLICATE_SAME_ACCESS))
|
0, TRUE, DUPLICATE_SAME_ACCESS))
|
||||||
{
|
{
|
||||||
debug_printf ("dup(%s) failed, event handle %x, %E",
|
debug_printf ("dup(%s) failed, event handle %p, %E",
|
||||||
get_name (), mt_evt);
|
get_name (), ov.hEvent);
|
||||||
__seterrno ();
|
__seterrno ();
|
||||||
return unlock (-1);
|
return unlock (-1);
|
||||||
}
|
}
|
||||||
@ -1465,8 +1463,8 @@ fhandler_dev_tape::fixup_after_fork (HANDLE parent)
|
|||||||
{
|
{
|
||||||
fhandler_dev_raw::fixup_after_fork (parent);
|
fhandler_dev_raw::fixup_after_fork (parent);
|
||||||
fork_fixup (parent, mt_mtx, "mt_mtx");
|
fork_fixup (parent, mt_mtx, "mt_mtx");
|
||||||
if (mt_evt)
|
if (ov.hEvent)
|
||||||
fork_fixup (parent, mt_evt, "mt_evt");
|
fork_fixup (parent, ov.hEvent, "ov.hEvent");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1474,8 +1472,8 @@ fhandler_dev_tape::set_close_on_exec (bool val)
|
|||||||
{
|
{
|
||||||
fhandler_dev_raw::set_close_on_exec (val);
|
fhandler_dev_raw::set_close_on_exec (val);
|
||||||
set_no_inheritance (mt_mtx, val);
|
set_no_inheritance (mt_mtx, val);
|
||||||
if (mt_evt)
|
if (ov.hEvent)
|
||||||
set_no_inheritance (mt_evt, val);
|
set_no_inheritance (ov.hEvent, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -306,6 +306,7 @@ fhandler_termios::line_edit (const char *rptr, int nread, termios& ti)
|
|||||||
else
|
else
|
||||||
set_input_done (iscanon);
|
set_input_done (iscanon);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iscanon && ti.c_lflag & IEXTEN && CCEQ (ti.c_cc[VDISCARD], c))
|
if (iscanon && ti.c_lflag & IEXTEN && CCEQ (ti.c_cc[VDISCARD], c))
|
||||||
{
|
{
|
||||||
ti.c_lflag ^= FLUSHO;
|
ti.c_lflag ^= FLUSHO;
|
||||||
@ -392,8 +393,8 @@ fhandler_termios::line_edit (const char *rptr, int nread, termios& ti)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
_off64_t
|
off_t
|
||||||
fhandler_termios::lseek (_off64_t, int)
|
fhandler_termios::lseek (off_t, int)
|
||||||
{
|
{
|
||||||
set_errno (ESPIPE);
|
set_errno (ESPIPE);
|
||||||
return -1;
|
return -1;
|
||||||
@ -426,7 +427,7 @@ fhandler_termios::ioctl (int cmd, void *varg)
|
|||||||
if (cmd != TIOCSCTTY)
|
if (cmd != TIOCSCTTY)
|
||||||
return 1; /* Not handled by this function */
|
return 1; /* Not handled by this function */
|
||||||
|
|
||||||
int arg = (int) varg;
|
int arg = (int) (intptr_t) varg;
|
||||||
|
|
||||||
if (arg != 0 && arg != 1)
|
if (arg != 0 && arg != 1)
|
||||||
{
|
{
|
||||||
|
@ -45,12 +45,6 @@ struct pipe_reply {
|
|||||||
DWORD error;
|
DWORD error;
|
||||||
};
|
};
|
||||||
|
|
||||||
int
|
|
||||||
fhandler_pty_slave::get_unit ()
|
|
||||||
{
|
|
||||||
return dev ().get_minor ();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
bytes_available (DWORD& n, HANDLE h)
|
bytes_available (DWORD& n, HANDLE h)
|
||||||
{
|
{
|
||||||
@ -176,7 +170,7 @@ fhandler_pty_master::accept_input ()
|
|||||||
DWORD rc;
|
DWORD rc;
|
||||||
DWORD written = 0;
|
DWORD written = 0;
|
||||||
|
|
||||||
paranoid_printf ("about to write %d chars to slave", bytes_left);
|
paranoid_printf ("about to write %u chars to slave", bytes_left);
|
||||||
rc = WriteFile (get_output_handle (), p, bytes_left, &written, NULL);
|
rc = WriteFile (get_output_handle (), p, bytes_left, &written, NULL);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
{
|
{
|
||||||
@ -352,7 +346,7 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on
|
|||||||
if (optr - buf >= (int) len)
|
if (optr - buf >= (int) len)
|
||||||
{
|
{
|
||||||
if (*iptr != '\n' || n != 0)
|
if (*iptr != '\n' || n != 0)
|
||||||
system_printf ("internal error: %d unexpected characters", n);
|
system_printf ("internal error: %u unexpected characters", n);
|
||||||
need_nl = 1;
|
need_nl = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -402,11 +396,11 @@ fhandler_pty_slave::open (int flags, mode_t)
|
|||||||
for (HANDLE **h = handles; *h; h++)
|
for (HANDLE **h = handles; *h; h++)
|
||||||
**h = NULL;
|
**h = NULL;
|
||||||
|
|
||||||
_tc = cygwin_shared->tty[get_unit ()];
|
_tc = cygwin_shared->tty[get_minor ()];
|
||||||
|
|
||||||
tcinit (false);
|
tcinit (false);
|
||||||
|
|
||||||
cygwin_shared->tty.attach (get_unit ());
|
cygwin_shared->tty.attach (get_minor ());
|
||||||
|
|
||||||
/* Create synchronisation events */
|
/* Create synchronisation events */
|
||||||
char buf[MAX_PATH];
|
char buf[MAX_PATH];
|
||||||
@ -423,7 +417,7 @@ fhandler_pty_slave::open (int flags, mode_t)
|
|||||||
errmsg = "open input mutex failed, %E";
|
errmsg = "open input mutex failed, %E";
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
shared_name (buf, INPUT_AVAILABLE_EVENT, get_unit ());
|
shared_name (buf, INPUT_AVAILABLE_EVENT, get_minor ());
|
||||||
if (!(input_available_event = OpenEvent (MAXIMUM_ALLOWED, TRUE, buf)))
|
if (!(input_available_event = OpenEvent (MAXIMUM_ALLOWED, TRUE, buf)))
|
||||||
{
|
{
|
||||||
errmsg = "open input event failed, %E";
|
errmsg = "open input event failed, %E";
|
||||||
@ -447,7 +441,7 @@ fhandler_pty_slave::open (int flags, mode_t)
|
|||||||
release_output_mutex ();
|
release_output_mutex ();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!get_ttyp ()->from_master || !get_ttyp ()->to_master)
|
if (!get_ttyp ()->from_master () || !get_ttyp ()->to_master ())
|
||||||
{
|
{
|
||||||
errmsg = "pty handles have been closed";
|
errmsg = "pty handles have been closed";
|
||||||
set_errno (EACCES);
|
set_errno (EACCES);
|
||||||
@ -488,16 +482,16 @@ fhandler_pty_slave::open (int flags, mode_t)
|
|||||||
}
|
}
|
||||||
if (pty_owner)
|
if (pty_owner)
|
||||||
{
|
{
|
||||||
if (!DuplicateHandle (pty_owner, get_ttyp ()->from_master,
|
if (!DuplicateHandle (pty_owner, get_ttyp ()->from_master (),
|
||||||
GetCurrentProcess (), &from_master_local, 0, TRUE,
|
GetCurrentProcess (), &from_master_local, 0, TRUE,
|
||||||
DUPLICATE_SAME_ACCESS))
|
DUPLICATE_SAME_ACCESS))
|
||||||
{
|
{
|
||||||
termios_printf ("can't duplicate input from %u/%p, %E",
|
termios_printf ("can't duplicate input from %u/%p, %E",
|
||||||
get_ttyp ()->master_pid, get_ttyp ()->from_master);
|
get_ttyp ()->master_pid, get_ttyp ()->from_master ());
|
||||||
__seterrno ();
|
__seterrno ();
|
||||||
goto err_no_msg;
|
goto err_no_msg;
|
||||||
}
|
}
|
||||||
if (!DuplicateHandle (pty_owner, get_ttyp ()->to_master,
|
if (!DuplicateHandle (pty_owner, get_ttyp ()->to_master (),
|
||||||
GetCurrentProcess (), &to_master_local, 0, TRUE,
|
GetCurrentProcess (), &to_master_local, 0, TRUE,
|
||||||
DUPLICATE_SAME_ACCESS))
|
DUPLICATE_SAME_ACCESS))
|
||||||
{
|
{
|
||||||
@ -514,7 +508,7 @@ fhandler_pty_slave::open (int flags, mode_t)
|
|||||||
DWORD len;
|
DWORD len;
|
||||||
|
|
||||||
__small_sprintf (buf, "\\\\.\\pipe\\cygwin-%S-pty%d-master-ctl",
|
__small_sprintf (buf, "\\\\.\\pipe\\cygwin-%S-pty%d-master-ctl",
|
||||||
&cygheap->installation_key, get_unit ());
|
&cygheap->installation_key, get_minor ());
|
||||||
termios_printf ("dup handles via master control pipe %s", buf);
|
termios_printf ("dup handles via master control pipe %s", buf);
|
||||||
if (!CallNamedPipe (buf, &req, sizeof req, &repl, sizeof repl,
|
if (!CallNamedPipe (buf, &req, sizeof req, &repl, sizeof repl,
|
||||||
&len, 500))
|
&len, 500))
|
||||||
@ -535,9 +529,9 @@ fhandler_pty_slave::open (int flags, mode_t)
|
|||||||
VerifyHandle (to_master_local);
|
VerifyHandle (to_master_local);
|
||||||
|
|
||||||
termios_printf ("duplicated from_master %p->%p from pty_owner",
|
termios_printf ("duplicated from_master %p->%p from pty_owner",
|
||||||
get_ttyp ()->from_master, from_master_local);
|
get_ttyp ()->from_master (), from_master_local);
|
||||||
termios_printf ("duplicated to_master %p->%p from pty_owner",
|
termios_printf ("duplicated to_master %p->%p from pty_owner",
|
||||||
get_ttyp ()->to_master, to_master_local);
|
get_ttyp ()->to_master (), to_master_local);
|
||||||
|
|
||||||
set_io_handle (from_master_local);
|
set_io_handle (from_master_local);
|
||||||
set_output_handle (to_master_local);
|
set_output_handle (to_master_local);
|
||||||
@ -587,7 +581,7 @@ fhandler_pty_slave::close ()
|
|||||||
termios_printf ("CloseHandle (inuse), %E");
|
termios_printf ("CloseHandle (inuse), %E");
|
||||||
if (!ForceCloseHandle (input_available_event))
|
if (!ForceCloseHandle (input_available_event))
|
||||||
termios_printf ("CloseHandle (input_available_event<%p>), %E", input_available_event);
|
termios_printf ("CloseHandle (input_available_event<%p>), %E", input_available_event);
|
||||||
if ((unsigned) myself->ctty == FHDEV (DEV_PTYS_MAJOR, get_unit ()))
|
if ((unsigned) myself->ctty == FHDEV (DEV_PTYS_MAJOR, get_minor ()))
|
||||||
fhandler_console::free_console (); /* assumes that we are the last pty closer */
|
fhandler_console::free_console (); /* assumes that we are the last pty closer */
|
||||||
return fhandler_pty_common::close ();
|
return fhandler_pty_common::close ();
|
||||||
}
|
}
|
||||||
@ -635,13 +629,14 @@ fhandler_pty_slave::init (HANDLE h, DWORD a, mode_t)
|
|||||||
ssize_t __stdcall
|
ssize_t __stdcall
|
||||||
fhandler_pty_slave::write (const void *ptr, size_t len)
|
fhandler_pty_slave::write (const void *ptr, size_t len)
|
||||||
{
|
{
|
||||||
DWORD n, towrite = len;
|
DWORD n;
|
||||||
|
ssize_t towrite = len;
|
||||||
|
|
||||||
bg_check_types bg = bg_check (SIGTTOU);
|
bg_check_types bg = bg_check (SIGTTOU);
|
||||||
if (bg <= bg_eof)
|
if (bg <= bg_eof)
|
||||||
return (ssize_t) bg;
|
return (ssize_t) bg;
|
||||||
|
|
||||||
termios_printf ("pty%d, write(%x, %d)", get_unit (), ptr, len);
|
termios_printf ("pty%d, write(%p, %lu)", get_minor (), ptr, len);
|
||||||
|
|
||||||
push_process_state process_state (PID_TTYOU);
|
push_process_state process_state (PID_TTYOU);
|
||||||
|
|
||||||
@ -662,7 +657,7 @@ fhandler_pty_slave::write (const void *ptr, size_t len)
|
|||||||
if (get_ttyp ()->write_error)
|
if (get_ttyp ()->write_error)
|
||||||
{
|
{
|
||||||
set_errno (get_ttyp ()->write_error);
|
set_errno (get_ttyp ()->write_error);
|
||||||
towrite = (DWORD) -1;
|
towrite = -1;
|
||||||
get_ttyp ()->write_error = 0;
|
get_ttyp ()->write_error = 0;
|
||||||
release_output_mutex ();
|
release_output_mutex ();
|
||||||
break;
|
break;
|
||||||
@ -682,7 +677,7 @@ fhandler_pty_slave::write (const void *ptr, size_t len)
|
|||||||
__seterrno_from_win_error (err);
|
__seterrno_from_win_error (err);
|
||||||
}
|
}
|
||||||
raise (SIGHUP); /* FIXME: Should this be SIGTTOU? */
|
raise (SIGHUP); /* FIXME: Should this be SIGTTOU? */
|
||||||
towrite = (DWORD) -1;
|
towrite = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -692,7 +687,7 @@ fhandler_pty_slave::write (const void *ptr, size_t len)
|
|||||||
void __stdcall
|
void __stdcall
|
||||||
fhandler_pty_slave::read (void *ptr, size_t& len)
|
fhandler_pty_slave::read (void *ptr, size_t& len)
|
||||||
{
|
{
|
||||||
int totalread = 0;
|
ssize_t totalread = 0;
|
||||||
int vmin = 0;
|
int vmin = 0;
|
||||||
int vtime = 0; /* Initialized to prevent -Wuninitialized warning */
|
int vtime = 0; /* Initialized to prevent -Wuninitialized warning */
|
||||||
size_t readlen;
|
size_t readlen;
|
||||||
@ -707,7 +702,7 @@ fhandler_pty_slave::read (void *ptr, size_t& len)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
termios_printf ("read(%x, %d) handle %p", ptr, len, get_handle ());
|
termios_printf ("read(%p, %lu) handle %p", ptr, len, get_handle ());
|
||||||
|
|
||||||
push_process_state process_state (PID_TTYIN);
|
push_process_state process_state (PID_TTYIN);
|
||||||
|
|
||||||
@ -836,7 +831,7 @@ fhandler_pty_slave::read (void *ptr, size_t& len)
|
|||||||
DWORD n = 0;
|
DWORD n = 0;
|
||||||
if (readlen)
|
if (readlen)
|
||||||
{
|
{
|
||||||
termios_printf ("reading %d bytes (vtime %d)", readlen, vtime);
|
termios_printf ("reading %lu bytes (vtime %d)", readlen, vtime);
|
||||||
if (!ReadFile (get_handle (), buf, readlen, &n, NULL))
|
if (!ReadFile (get_handle (), buf, readlen, &n, NULL))
|
||||||
{
|
{
|
||||||
termios_printf ("read failed, %E");
|
termios_printf ("read failed, %E");
|
||||||
@ -912,7 +907,7 @@ fhandler_pty_slave::read (void *ptr, size_t& len)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
termios_printf ("%d=read(%x, %d)", totalread, ptr, len);
|
termios_printf ("%d=read(%p, %lu)", totalread, ptr, len);
|
||||||
len = (size_t) totalread;
|
len = (size_t) totalread;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -987,7 +982,7 @@ fhandler_pty_slave::ioctl (unsigned int cmd, void *arg)
|
|||||||
return res;
|
return res;
|
||||||
|
|
||||||
if (myself->pgid && get_ttyp ()->getpgid () != myself->pgid
|
if (myself->pgid && get_ttyp ()->getpgid () != myself->pgid
|
||||||
&& (unsigned) myself->ctty == FHDEV (DEV_PTYS_MAJOR, get_unit ())
|
&& (unsigned) myself->ctty == FHDEV (DEV_PTYS_MAJOR, get_minor ())
|
||||||
&& (get_ttyp ()->ti.c_lflag & TOSTOP))
|
&& (get_ttyp ()->ti.c_lflag & TOSTOP))
|
||||||
{
|
{
|
||||||
/* background process */
|
/* background process */
|
||||||
@ -1015,7 +1010,7 @@ fhandler_pty_slave::ioctl (unsigned int cmd, void *arg)
|
|||||||
}
|
}
|
||||||
goto out;
|
goto out;
|
||||||
case TIOCSPGRP:
|
case TIOCSPGRP:
|
||||||
retval = this->tcsetpgrp ((pid_t) arg);
|
retval = this->tcsetpgrp ((pid_t) (intptr_t) arg);
|
||||||
goto out;
|
goto out;
|
||||||
case FIONREAD:
|
case FIONREAD:
|
||||||
{
|
{
|
||||||
@ -1072,7 +1067,7 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int __reg2
|
int __reg2
|
||||||
fhandler_pty_slave::fstat (struct __stat64 *st)
|
fhandler_pty_slave::fstat (struct stat *st)
|
||||||
{
|
{
|
||||||
fhandler_base::fstat (st);
|
fhandler_base::fstat (st);
|
||||||
|
|
||||||
@ -1080,7 +1075,7 @@ fhandler_pty_slave::fstat (struct __stat64 *st)
|
|||||||
if (!input_available_event)
|
if (!input_available_event)
|
||||||
{
|
{
|
||||||
char buf[MAX_PATH];
|
char buf[MAX_PATH];
|
||||||
shared_name (buf, INPUT_AVAILABLE_EVENT, get_unit ());
|
shared_name (buf, INPUT_AVAILABLE_EVENT, get_minor ());
|
||||||
input_available_event = OpenEvent (READ_CONTROL, TRUE, buf);
|
input_available_event = OpenEvent (READ_CONTROL, TRUE, buf);
|
||||||
if (input_available_event)
|
if (input_available_event)
|
||||||
to_close = true;
|
to_close = true;
|
||||||
@ -1107,8 +1102,8 @@ fhandler_pty_slave::fch_open_handles ()
|
|||||||
{
|
{
|
||||||
char buf[MAX_PATH];
|
char buf[MAX_PATH];
|
||||||
|
|
||||||
_tc = cygwin_shared->tty[get_unit ()];
|
_tc = cygwin_shared->tty[get_minor ()];
|
||||||
shared_name (buf, INPUT_AVAILABLE_EVENT, get_unit ());
|
shared_name (buf, INPUT_AVAILABLE_EVENT, get_minor ());
|
||||||
input_available_event = OpenEvent (READ_CONTROL | WRITE_DAC | WRITE_OWNER,
|
input_available_event = OpenEvent (READ_CONTROL | WRITE_DAC | WRITE_OWNER,
|
||||||
TRUE, buf);
|
TRUE, buf);
|
||||||
output_mutex = get_ttyp ()->open_output_mutex (WRITE_DAC | WRITE_OWNER);
|
output_mutex = get_ttyp ()->open_output_mutex (WRITE_DAC | WRITE_OWNER);
|
||||||
@ -1161,8 +1156,8 @@ fhandler_pty_slave::fchmod (mode_t mode)
|
|||||||
int ret = -1;
|
int ret = -1;
|
||||||
bool to_close = false;
|
bool to_close = false;
|
||||||
security_descriptor sd;
|
security_descriptor sd;
|
||||||
__uid32_t uid;
|
uid_t uid;
|
||||||
__gid32_t gid;
|
gid_t gid;
|
||||||
|
|
||||||
if (!input_available_event)
|
if (!input_available_event)
|
||||||
{
|
{
|
||||||
@ -1182,13 +1177,13 @@ errout:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int __stdcall
|
int __stdcall
|
||||||
fhandler_pty_slave::fchown (__uid32_t uid, __gid32_t gid)
|
fhandler_pty_slave::fchown (uid_t uid, gid_t gid)
|
||||||
{
|
{
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
bool to_close = false;
|
bool to_close = false;
|
||||||
mode_t mode = 0;
|
mode_t mode = 0;
|
||||||
__uid32_t o_uid;
|
uid_t o_uid;
|
||||||
__gid32_t o_gid;
|
gid_t o_gid;
|
||||||
security_descriptor sd;
|
security_descriptor sd;
|
||||||
|
|
||||||
if (uid == ILLEGAL_UID && gid == ILLEGAL_GID)
|
if (uid == ILLEGAL_UID && gid == ILLEGAL_GID)
|
||||||
@ -1247,12 +1242,12 @@ fhandler_pty_master::open_setup (int flags)
|
|||||||
{
|
{
|
||||||
set_flags ((flags & ~O_TEXT) | O_BINARY);
|
set_flags ((flags & ~O_TEXT) | O_BINARY);
|
||||||
char buf[sizeof ("opened pty master for ptyNNNNNNNNNNN")];
|
char buf[sizeof ("opened pty master for ptyNNNNNNNNNNN")];
|
||||||
__small_sprintf (buf, "opened pty master for pty%d", get_unit ());
|
__small_sprintf (buf, "opened pty master for pty%d", get_minor ());
|
||||||
report_tty_counts (this, buf, "");
|
report_tty_counts (this, buf, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
_off64_t
|
off_t
|
||||||
fhandler_pty_common::lseek (_off64_t, int)
|
fhandler_pty_common::lseek (off_t, int)
|
||||||
{
|
{
|
||||||
set_errno (ESPIPE);
|
set_errno (ESPIPE);
|
||||||
return -1;
|
return -1;
|
||||||
@ -1261,7 +1256,7 @@ fhandler_pty_common::lseek (_off64_t, int)
|
|||||||
int
|
int
|
||||||
fhandler_pty_common::close ()
|
fhandler_pty_common::close ()
|
||||||
{
|
{
|
||||||
termios_printf ("pty%d <%p,%p> closing", get_unit (), get_handle (), get_output_handle ());
|
termios_printf ("pty%d <%p,%p> closing", get_minor (), get_handle (), get_output_handle ());
|
||||||
if (!ForceCloseHandle (input_mutex))
|
if (!ForceCloseHandle (input_mutex))
|
||||||
termios_printf ("CloseHandle (input_mutex<%p>), %E", input_mutex);
|
termios_printf ("CloseHandle (input_mutex<%p>), %E", input_mutex);
|
||||||
if (!ForceCloseHandle (output_mutex))
|
if (!ForceCloseHandle (output_mutex))
|
||||||
@ -1285,7 +1280,7 @@ fhandler_pty_master::cleanup ()
|
|||||||
int
|
int
|
||||||
fhandler_pty_master::close ()
|
fhandler_pty_master::close ()
|
||||||
{
|
{
|
||||||
termios_printf ("closing from_master(%p)/to_master(%p) since we own them(%d)",
|
termios_printf ("closing from_master(%p)/to_master(%p) since we own them(%u)",
|
||||||
from_master, to_master, dwProcessId);
|
from_master, to_master, dwProcessId);
|
||||||
if (cygwin_finished_initializing)
|
if (cygwin_finished_initializing)
|
||||||
{
|
{
|
||||||
@ -1297,7 +1292,7 @@ fhandler_pty_master::close ()
|
|||||||
DWORD len;
|
DWORD len;
|
||||||
|
|
||||||
__small_sprintf (buf, "\\\\.\\pipe\\cygwin-%S-pty%d-master-ctl",
|
__small_sprintf (buf, "\\\\.\\pipe\\cygwin-%S-pty%d-master-ctl",
|
||||||
&cygheap->installation_key, get_unit ());
|
&cygheap->installation_key, get_minor ());
|
||||||
CallNamedPipe (buf, &req, sizeof req, &repl, sizeof repl, &len, 500);
|
CallNamedPipe (buf, &req, sizeof req, &repl, sizeof repl, &len, 500);
|
||||||
CloseHandle (master_ctl);
|
CloseHandle (master_ctl);
|
||||||
master_thread->detach ();
|
master_thread->detach ();
|
||||||
@ -1376,14 +1371,14 @@ fhandler_pty_master::read (void *ptr, size_t& len)
|
|||||||
int
|
int
|
||||||
fhandler_pty_master::tcgetattr (struct termios *t)
|
fhandler_pty_master::tcgetattr (struct termios *t)
|
||||||
{
|
{
|
||||||
*t = cygwin_shared->tty[get_unit ()]->ti;
|
*t = cygwin_shared->tty[get_minor ()]->ti;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_pty_master::tcsetattr (int, const struct termios *t)
|
fhandler_pty_master::tcsetattr (int, const struct termios *t)
|
||||||
{
|
{
|
||||||
cygwin_shared->tty[get_unit ()]->ti = *t;
|
cygwin_shared->tty[get_minor ()]->ti = *t;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1432,7 +1427,7 @@ fhandler_pty_master::ioctl (unsigned int cmd, void *arg)
|
|||||||
*((pid_t *) arg) = this->tcgetpgrp ();
|
*((pid_t *) arg) = this->tcgetpgrp ();
|
||||||
break;
|
break;
|
||||||
case TIOCSPGRP:
|
case TIOCSPGRP:
|
||||||
return this->tcsetpgrp ((pid_t) arg);
|
return this->tcsetpgrp ((pid_t) (intptr_t) arg);
|
||||||
case FIONREAD:
|
case FIONREAD:
|
||||||
{
|
{
|
||||||
DWORD n;
|
DWORD n;
|
||||||
@ -1455,7 +1450,7 @@ fhandler_pty_master::ptsname_r (char *buf, size_t buflen)
|
|||||||
{
|
{
|
||||||
char tmpbuf[TTY_NAME_MAX];
|
char tmpbuf[TTY_NAME_MAX];
|
||||||
|
|
||||||
__ptsname (tmpbuf, get_unit ());
|
__ptsname (tmpbuf, get_minor ());
|
||||||
if (buflen <= strlen (tmpbuf))
|
if (buflen <= strlen (tmpbuf))
|
||||||
{
|
{
|
||||||
set_errno (ERANGE);
|
set_errno (ERANGE);
|
||||||
@ -1556,7 +1551,7 @@ fhandler_pty_master::pty_master_thread ()
|
|||||||
&token);
|
&token);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
termios_printf ("NtOpenThreadToken, %p", status);
|
termios_printf ("NtOpenThreadToken, %y", status);
|
||||||
SetLastError (RtlNtStatusToDosError (status));
|
SetLastError (RtlNtStatusToDosError (status));
|
||||||
goto reply;
|
goto reply;
|
||||||
}
|
}
|
||||||
@ -1566,7 +1561,7 @@ fhandler_pty_master::pty_master_thread ()
|
|||||||
NtClose (token);
|
NtClose (token);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
termios_printf ("NtAccessCheck, %p", status);
|
termios_printf ("NtAccessCheck, %y", status);
|
||||||
SetLastError (RtlNtStatusToDosError (status));
|
SetLastError (RtlNtStatusToDosError (status));
|
||||||
goto reply;
|
goto reply;
|
||||||
}
|
}
|
||||||
@ -1614,7 +1609,7 @@ reply:
|
|||||||
if (deimp)
|
if (deimp)
|
||||||
cygheap->user.reimpersonate ();
|
cygheap->user.reimpersonate ();
|
||||||
sd.free ();
|
sd.free ();
|
||||||
termios_printf ("Reply: from %p, to %p, error %lu",
|
termios_printf ("Reply: from %p, to %p, error %u",
|
||||||
repl.from_master, repl.to_master, repl.error );
|
repl.from_master, repl.to_master, repl.error );
|
||||||
if (!WriteFile (master_ctl, &repl, sizeof repl, &len, NULL))
|
if (!WriteFile (master_ctl, &repl, sizeof repl, &len, NULL))
|
||||||
termios_printf ("WriteFile, %E");
|
termios_printf ("WriteFile, %E");
|
||||||
@ -1699,10 +1694,13 @@ fhandler_pty_master::setup ()
|
|||||||
the pty pipe handles to processes which deserve it. */
|
the pty pipe handles to processes which deserve it. */
|
||||||
__small_sprintf (buf, "\\\\.\\pipe\\cygwin-%S-pty%d-master-ctl",
|
__small_sprintf (buf, "\\\\.\\pipe\\cygwin-%S-pty%d-master-ctl",
|
||||||
&cygheap->installation_key, unit);
|
&cygheap->installation_key, unit);
|
||||||
master_ctl = CreateNamedPipe (buf, PIPE_ACCESS_DUPLEX,
|
master_ctl = CreateNamedPipe (buf, PIPE_ACCESS_DUPLEX
|
||||||
|
| FILE_FLAG_FIRST_PIPE_INSTANCE,
|
||||||
PIPE_WAIT | PIPE_TYPE_MESSAGE
|
PIPE_WAIT | PIPE_TYPE_MESSAGE
|
||||||
| PIPE_READMODE_MESSAGE, 1, 4096, 4096,
|
| PIPE_READMODE_MESSAGE
|
||||||
0, &sec_all_nih);
|
| (wincap.has_pipe_reject_remote_clients ()
|
||||||
|
? PIPE_REJECT_REMOTE_CLIENTS : 0),
|
||||||
|
1, 4096, 4096, 0, &sec_all_nih);
|
||||||
if (master_ctl == INVALID_HANDLE_VALUE)
|
if (master_ctl == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
errstr = "pty master control pipe";
|
errstr = "pty master control pipe";
|
||||||
@ -1715,8 +1713,8 @@ fhandler_pty_master::setup ()
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
t.from_master = from_master;
|
t.set_from_master (from_master);
|
||||||
t.to_master = to_master;
|
t.set_to_master (to_master);
|
||||||
t.winsize.ws_col = 80;
|
t.winsize.ws_col = 80;
|
||||||
t.winsize.ws_row = 25;
|
t.winsize.ws_row = 25;
|
||||||
t.master_pid = myself->pid;
|
t.master_pid = myself->pid;
|
||||||
@ -1751,8 +1749,8 @@ fhandler_pty_master::fixup_after_fork (HANDLE parent)
|
|||||||
tty& t = *get_ttyp ();
|
tty& t = *get_ttyp ();
|
||||||
if (myself->pid == t.master_pid)
|
if (myself->pid == t.master_pid)
|
||||||
{
|
{
|
||||||
t.from_master = arch->from_master;
|
t.set_from_master (arch->from_master);
|
||||||
t.to_master = arch->to_master;
|
t.set_to_master (arch->to_master);
|
||||||
}
|
}
|
||||||
arch->dwProcessId = wpid;
|
arch->dwProcessId = wpid;
|
||||||
}
|
}
|
||||||
|
@ -126,15 +126,15 @@ fhandler_virtual::closedir (DIR * dir)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
_off64_t
|
off_t
|
||||||
fhandler_virtual::lseek (_off64_t offset, int whence)
|
fhandler_virtual::lseek (off_t offset, int whence)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* On Linux, when you lseek within a /proc file,
|
* On Linux, when you lseek within a /proc file,
|
||||||
* the contents of the file are updated.
|
* the contents of the file are updated.
|
||||||
*/
|
*/
|
||||||
if (!fill_filebuf ())
|
if (!fill_filebuf ())
|
||||||
return (_off64_t) -1;
|
return (off_t) -1;
|
||||||
switch (whence)
|
switch (whence)
|
||||||
{
|
{
|
||||||
case SEEK_SET:
|
case SEEK_SET:
|
||||||
@ -148,7 +148,7 @@ fhandler_virtual::lseek (_off64_t offset, int whence)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return (_off64_t) -1;
|
return (off_t) -1;
|
||||||
}
|
}
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
@ -246,7 +246,7 @@ fhandler_virtual::fchmod (mode_t mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_virtual::fchown (__uid32_t uid, __gid32_t gid)
|
fhandler_virtual::fchown (uid_t uid, gid_t gid)
|
||||||
{
|
{
|
||||||
/* Same as on Linux. */
|
/* Same as on Linux. */
|
||||||
set_errno (EPERM);
|
set_errno (EPERM);
|
||||||
@ -254,7 +254,7 @@ fhandler_virtual::fchown (__uid32_t uid, __gid32_t gid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_virtual::facl (int cmd, int nentries, __aclent32_t *aclbufp)
|
fhandler_virtual::facl (int cmd, int nentries, aclent_t *aclbufp)
|
||||||
{
|
{
|
||||||
int res = fhandler_base::facl (cmd, nentries, aclbufp);
|
int res = fhandler_base::facl (cmd, nentries, aclbufp);
|
||||||
if (res >= 0 && cmd == GETACL)
|
if (res >= 0 && cmd == GETACL)
|
||||||
|
@ -13,7 +13,7 @@ struct virt_tab_t {
|
|||||||
size_t name_len;
|
size_t name_len;
|
||||||
fh_devices fhandler;
|
fh_devices fhandler;
|
||||||
virtual_ftype_t type;
|
virtual_ftype_t type;
|
||||||
_off64_t (*format_func)(void *data, char *&);
|
off_t (*format_func)(void *data, char *&);
|
||||||
};
|
};
|
||||||
|
|
||||||
#define _VN(s) s, sizeof (s) - 1
|
#define _VN(s) s, sizeof (s) - 1
|
||||||
|
@ -47,8 +47,8 @@ fhandler_dev_zero::read (void *ptr, size_t& len)
|
|||||||
memset (ptr, 0, len);
|
memset (ptr, 0, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
_off64_t
|
off_t
|
||||||
fhandler_dev_zero::lseek (_off64_t, int)
|
fhandler_dev_zero::lseek (off_t, int)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -170,7 +170,7 @@ allow_others_to_sync ()
|
|||||||
MAX_PROCESS_SD_SIZE, &len);
|
MAX_PROCESS_SD_SIZE, &len);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
debug_printf ("NtQuerySecurityObject: %p", status);
|
debug_printf ("NtQuerySecurityObject: %y", status);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* Create a valid dacl pointer and set its size to be as big as
|
/* Create a valid dacl pointer and set its size to be as big as
|
||||||
@ -197,14 +197,14 @@ allow_others_to_sync ()
|
|||||||
well_known_world_sid);
|
well_known_world_sid);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
debug_printf ("RtlAddAccessAllowedAce: %p", status);
|
debug_printf ("RtlAddAccessAllowedAce: %y", status);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* Set the size of the DACL correctly. */
|
/* Set the size of the DACL correctly. */
|
||||||
status = RtlFirstFreeAce (dacl, &ace);
|
status = RtlFirstFreeAce (dacl, &ace);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
debug_printf ("RtlFirstFreeAce: %p", status);
|
debug_printf ("RtlFirstFreeAce: %y", status);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dacl->AclSize = (char *) ace - (char *) dacl;
|
dacl->AclSize = (char *) ace - (char *) dacl;
|
||||||
@ -212,7 +212,7 @@ allow_others_to_sync ()
|
|||||||
status = NtSetSecurityObject (NtCurrentProcess (), DACL_SECURITY_INFORMATION, sd);
|
status = NtSetSecurityObject (NtCurrentProcess (), DACL_SECURITY_INFORMATION, sd);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
debug_printf ("NtSetSecurityObject: %p", status);
|
debug_printf ("NtSetSecurityObject: %y", status);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
done = true;
|
done = true;
|
||||||
@ -228,7 +228,7 @@ get_obj_handle_count (HANDLE h)
|
|||||||
|
|
||||||
status = NtQueryObject (h, ObjectBasicInformation, &obi, sizeof obi, NULL);
|
status = NtQueryObject (h, ObjectBasicInformation, &obi, sizeof obi, NULL);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
debug_printf ("NtQueryObject: %p\n", status);
|
debug_printf ("NtQueryObject: %y", status);
|
||||||
else
|
else
|
||||||
hdl_cnt = obi.HandleCount;
|
hdl_cnt = obi.HandleCount;
|
||||||
return hdl_cnt;
|
return hdl_cnt;
|
||||||
@ -248,9 +248,9 @@ class lockf_t
|
|||||||
public:
|
public:
|
||||||
uint16_t lf_flags; /* Semantics: F_POSIX, F_FLOCK, F_WAIT */
|
uint16_t lf_flags; /* Semantics: F_POSIX, F_FLOCK, F_WAIT */
|
||||||
uint16_t lf_type; /* Lock type: F_RDLCK, F_WRLCK */
|
uint16_t lf_type; /* Lock type: F_RDLCK, F_WRLCK */
|
||||||
_off64_t lf_start; /* Byte # of the start of the lock */
|
off_t lf_start; /* Byte # of the start of the lock */
|
||||||
_off64_t lf_end; /* Byte # of the end of the lock (-1=EOF) */
|
off_t lf_end; /* Byte # of the end of the lock (-1=EOF) */
|
||||||
int64_t lf_id; /* Cygwin PID for POSIX locks, a unique id per
|
int64_t lf_id; /* Cygwin PID for POSIX locks, a unique id per
|
||||||
file table entry for BSD flock locks. */
|
file table entry for BSD flock locks. */
|
||||||
DWORD lf_wid; /* Win PID of the resource holding the lock */
|
DWORD lf_wid; /* Win PID of the resource holding the lock */
|
||||||
uint16_t lf_ver; /* Version number of the lock. If a released
|
uint16_t lf_ver; /* Version number of the lock. If a released
|
||||||
@ -268,7 +268,7 @@ class lockf_t
|
|||||||
lf_next (NULL), lf_obj (NULL)
|
lf_next (NULL), lf_obj (NULL)
|
||||||
{}
|
{}
|
||||||
lockf_t (class inode_t *node, class lockf_t **head,
|
lockf_t (class inode_t *node, class lockf_t **head,
|
||||||
short flags, short type, _off64_t start, _off64_t end,
|
short flags, short type, off_t start, off_t end,
|
||||||
long long id, DWORD wid, uint16_t ver)
|
long long id, DWORD wid, uint16_t ver)
|
||||||
: lf_flags (flags), lf_type (type), lf_start (start), lf_end (end),
|
: lf_flags (flags), lf_type (type), lf_start (start), lf_end (end),
|
||||||
lf_id (id), lf_wid (wid), lf_ver (ver), lf_head (head), lf_inode (node),
|
lf_id (id), lf_wid (wid), lf_ver (ver), lf_head (head), lf_inode (node),
|
||||||
@ -308,8 +308,8 @@ class inode_t
|
|||||||
lockf_t *i_lockf; /* List of locks of this process. */
|
lockf_t *i_lockf; /* List of locks of this process. */
|
||||||
lockf_t *i_all_lf; /* Temp list of all locks for this file. */
|
lockf_t *i_all_lf; /* Temp list of all locks for this file. */
|
||||||
|
|
||||||
__dev32_t i_dev; /* Device ID */
|
dev_t i_dev; /* Device ID */
|
||||||
__ino64_t i_ino; /* inode number */
|
ino_t i_ino; /* inode number */
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HANDLE i_dir;
|
HANDLE i_dir;
|
||||||
@ -317,7 +317,7 @@ class inode_t
|
|||||||
uint32_t i_cnt; /* # of threads referencing this instance. */
|
uint32_t i_cnt; /* # of threads referencing this instance. */
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inode_t (__dev32_t dev, __ino64_t ino);
|
inode_t (dev_t dev, ino_t ino);
|
||||||
~inode_t ();
|
~inode_t ();
|
||||||
|
|
||||||
void *operator new (size_t size)
|
void *operator new (size_t size)
|
||||||
@ -325,7 +325,7 @@ class inode_t
|
|||||||
void operator delete (void *p)
|
void operator delete (void *p)
|
||||||
{ cfree (p); }
|
{ cfree (p); }
|
||||||
|
|
||||||
static inode_t *get (__dev32_t dev, __ino64_t ino,
|
static inode_t *get (dev_t dev, ino_t ino,
|
||||||
bool create_if_missing, bool lock);
|
bool create_if_missing, bool lock);
|
||||||
|
|
||||||
void LOCK () { WaitForSingleObject (i_mtx, INFINITE); }
|
void LOCK () { WaitForSingleObject (i_mtx, INFINITE); }
|
||||||
@ -482,7 +482,7 @@ fixup_lockf_after_exec ()
|
|||||||
file. The file is specified by the device and inode_t number. If inode_t
|
file. The file is specified by the device and inode_t number. If inode_t
|
||||||
doesn't exist, create it. */
|
doesn't exist, create it. */
|
||||||
inode_t *
|
inode_t *
|
||||||
inode_t::get (__dev32_t dev, __ino64_t ino, bool create_if_missing, bool lock)
|
inode_t::get (dev_t dev, ino_t ino, bool create_if_missing, bool lock)
|
||||||
{
|
{
|
||||||
inode_t *node;
|
inode_t *node;
|
||||||
|
|
||||||
@ -504,7 +504,7 @@ inode_t::get (__dev32_t dev, __ino64_t ino, bool create_if_missing, bool lock)
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
inode_t::inode_t (__dev32_t dev, __ino64_t ino)
|
inode_t::inode_t (dev_t dev, ino_t ino)
|
||||||
: i_lockf (NULL), i_all_lf (NULL), i_dev (dev), i_ino (ino), i_cnt (0L)
|
: i_lockf (NULL), i_all_lf (NULL), i_dev (dev), i_ino (ino), i_cnt (0L)
|
||||||
{
|
{
|
||||||
HANDLE parent_dir;
|
HANDLE parent_dir;
|
||||||
@ -522,14 +522,14 @@ inode_t::inode_t (__dev32_t dev, __ino64_t ino)
|
|||||||
parent_dir, everyone_sd (FLOCK_INODE_DIR_ACCESS));
|
parent_dir, everyone_sd (FLOCK_INODE_DIR_ACCESS));
|
||||||
status = NtCreateDirectoryObject (&i_dir, FLOCK_INODE_DIR_ACCESS, &attr);
|
status = NtCreateDirectoryObject (&i_dir, FLOCK_INODE_DIR_ACCESS, &attr);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
api_fatal ("NtCreateDirectoryObject(inode): %p", status);
|
api_fatal ("NtCreateDirectoryObject(inode): %y", status);
|
||||||
/* Create a mutex object in the file specific dir, which is used for
|
/* Create a mutex object in the file specific dir, which is used for
|
||||||
access synchronization on the dir and its objects. */
|
access synchronization on the dir and its objects. */
|
||||||
InitializeObjectAttributes (&attr, &ro_u_mtx, OBJ_INHERIT | OBJ_OPENIF, i_dir,
|
InitializeObjectAttributes (&attr, &ro_u_mtx, OBJ_INHERIT | OBJ_OPENIF, i_dir,
|
||||||
everyone_sd (CYG_MUTANT_ACCESS));
|
everyone_sd (CYG_MUTANT_ACCESS));
|
||||||
status = NtCreateMutant (&i_mtx, CYG_MUTANT_ACCESS, &attr, FALSE);
|
status = NtCreateMutant (&i_mtx, CYG_MUTANT_ACCESS, &attr, FALSE);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
api_fatal ("NtCreateMutant(inode): %p", status);
|
api_fatal ("NtCreateMutant(inode): %y", status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enumerate all lock event objects for this file and create a lockf_t
|
/* Enumerate all lock event objects for this file and create a lockf_t
|
||||||
@ -554,10 +554,10 @@ lockf_t::from_obj_name (inode_t *node, lockf_t **head, const wchar_t *name)
|
|||||||
lf_type = wcstol (endptr + 1, &endptr, 16);
|
lf_type = wcstol (endptr + 1, &endptr, 16);
|
||||||
if ((lf_type != F_RDLCK && lf_type != F_WRLCK) || !endptr || *endptr != L'-')
|
if ((lf_type != F_RDLCK && lf_type != F_WRLCK) || !endptr || *endptr != L'-')
|
||||||
return false;
|
return false;
|
||||||
lf_start = (_off64_t) wcstoull (endptr + 1, &endptr, 16);
|
lf_start = (off_t) wcstoull (endptr + 1, &endptr, 16);
|
||||||
if (lf_start < 0 || !endptr || *endptr != L'-')
|
if (lf_start < 0 || !endptr || *endptr != L'-')
|
||||||
return false;
|
return false;
|
||||||
lf_end = (_off64_t) wcstoull (endptr + 1, &endptr, 16);
|
lf_end = (off_t) wcstoull (endptr + 1, &endptr, 16);
|
||||||
if (lf_end < -1LL
|
if (lf_end < -1LL
|
||||||
|| (lf_end > 0 && lf_end < lf_start)
|
|| (lf_end > 0 && lf_end < lf_start)
|
||||||
|| !endptr || *endptr != L'-')
|
|| !endptr || *endptr != L'-')
|
||||||
@ -640,8 +640,8 @@ create_lock_in_parent (PVOID param)
|
|||||||
OBJECT_NAME_INFORMATION *ntfn;
|
OBJECT_NAME_INFORMATION *ntfn;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
wchar_t *lockname, *inodename, *endptr;
|
wchar_t *lockname, *inodename, *endptr;
|
||||||
__dev32_t dev;
|
dev_t dev;
|
||||||
__ino64_t ino;
|
ino_t ino;
|
||||||
inode_t *node;
|
inode_t *node;
|
||||||
lockf_t newlock, *lock;
|
lockf_t newlock, *lock;
|
||||||
int cnt;
|
int cnt;
|
||||||
@ -753,7 +753,7 @@ lockf_t::create_lock_obj ()
|
|||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
if (status != STATUS_OBJECT_NAME_COLLISION)
|
if (status != STATUS_OBJECT_NAME_COLLISION)
|
||||||
api_fatal ("NtCreateEvent(lock): %p", status);
|
api_fatal ("NtCreateEvent(lock): %y", status);
|
||||||
/* If we get a STATUS_OBJECT_NAME_COLLISION, the event still exists
|
/* If we get a STATUS_OBJECT_NAME_COLLISION, the event still exists
|
||||||
because some other process is waiting for it in lf_setlock.
|
because some other process is waiting for it in lf_setlock.
|
||||||
If so, check the event's signal state. If we can't open it, it
|
If so, check the event's signal state. If we can't open it, it
|
||||||
@ -764,7 +764,7 @@ lockf_t::create_lock_obj ()
|
|||||||
if (open_lock_obj ())
|
if (open_lock_obj ())
|
||||||
{
|
{
|
||||||
if (!IsEventSignalled (lf_obj))
|
if (!IsEventSignalled (lf_obj))
|
||||||
api_fatal ("NtCreateEvent(lock): %p", status);
|
api_fatal ("NtCreateEvent(lock): %y", status);
|
||||||
close_lock_obj ();
|
close_lock_obj ();
|
||||||
/* Increment the lf_ver field until we have no collision. */
|
/* Increment the lf_ver field until we have no collision. */
|
||||||
++lf_ver;
|
++lf_ver;
|
||||||
@ -910,15 +910,15 @@ static int maxlockdepth = MAXDEPTH;
|
|||||||
static int lf_clearlock (lockf_t *, lockf_t **, HANDLE);
|
static int lf_clearlock (lockf_t *, lockf_t **, HANDLE);
|
||||||
static int lf_findoverlap (lockf_t *, lockf_t *, int, lockf_t ***, lockf_t **);
|
static int lf_findoverlap (lockf_t *, lockf_t *, int, lockf_t ***, lockf_t **);
|
||||||
static lockf_t *lf_getblock (lockf_t *, inode_t *node);
|
static lockf_t *lf_getblock (lockf_t *, inode_t *node);
|
||||||
static int lf_getlock (lockf_t *, inode_t *, struct __flock64 *);
|
static int lf_getlock (lockf_t *, inode_t *, struct flock *);
|
||||||
static int lf_setlock (lockf_t *, inode_t *, lockf_t **, HANDLE);
|
static int lf_setlock (lockf_t *, inode_t *, lockf_t **, HANDLE);
|
||||||
static void lf_split (lockf_t *, lockf_t *, lockf_t **);
|
static void lf_split (lockf_t *, lockf_t *, lockf_t **);
|
||||||
static void lf_wakelock (lockf_t *, HANDLE);
|
static void lf_wakelock (lockf_t *, HANDLE);
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_disk_file::lock (int a_op, struct __flock64 *fl)
|
fhandler_disk_file::lock (int a_op, struct flock *fl)
|
||||||
{
|
{
|
||||||
_off64_t start, end, oadd;
|
off_t start, end, oadd;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
short a_flags = fl->l_type & (F_POSIX | F_FLOCK);
|
short a_flags = fl->l_type & (F_POSIX | F_FLOCK);
|
||||||
@ -1499,7 +1499,7 @@ lf_clearlock (lockf_t *unlock, lockf_t **clean, HANDLE fhdl)
|
|||||||
* and if so return its process identifier.
|
* and if so return its process identifier.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
lf_getlock (lockf_t *lock, inode_t *node, struct __flock64 *fl)
|
lf_getlock (lockf_t *lock, inode_t *node, struct flock *fl)
|
||||||
{
|
{
|
||||||
lockf_t *block;
|
lockf_t *block;
|
||||||
tmp_pathbuf tp;
|
tmp_pathbuf tp;
|
||||||
@ -1577,7 +1577,7 @@ static int
|
|||||||
lf_findoverlap (lockf_t *lf, lockf_t *lock, int type, lockf_t ***prev,
|
lf_findoverlap (lockf_t *lf, lockf_t *lock, int type, lockf_t ***prev,
|
||||||
lockf_t **overlap)
|
lockf_t **overlap)
|
||||||
{
|
{
|
||||||
_off64_t start, end;
|
off_t start, end;
|
||||||
|
|
||||||
*overlap = lf;
|
*overlap = lf;
|
||||||
if (lf == NOLOCKF)
|
if (lf == NOLOCKF)
|
||||||
@ -1716,7 +1716,7 @@ flock (int fd, int operation)
|
|||||||
{
|
{
|
||||||
int res = -1;
|
int res = -1;
|
||||||
int cmd;
|
int cmd;
|
||||||
struct __flock64 fl = { 0, SEEK_SET, 0, 0, 0 };
|
struct flock fl = { 0, SEEK_SET, 0, 0, 0 };
|
||||||
|
|
||||||
myfault efault;
|
myfault efault;
|
||||||
if (efault.faulted (EFAULT))
|
if (efault.faulted (EFAULT))
|
||||||
@ -1751,11 +1751,11 @@ done:
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int
|
extern "C" int
|
||||||
lockf (int filedes, int function, _off64_t size)
|
lockf (int filedes, int function, off_t size)
|
||||||
{
|
{
|
||||||
int res = -1;
|
int res = -1;
|
||||||
int cmd;
|
int cmd;
|
||||||
struct __flock64 fl;
|
struct flock fl;
|
||||||
|
|
||||||
pthread_testcancel ();
|
pthread_testcancel ();
|
||||||
|
|
||||||
|
@ -328,7 +328,7 @@ frok::parent (volatile char * volatile stack_here)
|
|||||||
ch.guardsize = _my_tls.tid->attr.guardsize;
|
ch.guardsize = _my_tls.tid->attr.guardsize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
debug_printf ("stack - bottom %p, top %p, addr %p, guardsize %p",
|
debug_printf ("stack - bottom %p, top %p, addr %p, guardsize %lu",
|
||||||
ch.stackbottom, ch.stacktop, ch.stackaddr, ch.guardsize);
|
ch.stackbottom, ch.stacktop, ch.stackaddr, ch.guardsize);
|
||||||
|
|
||||||
PROCESS_INFORMATION pi;
|
PROCESS_INFORMATION pi;
|
||||||
@ -340,7 +340,7 @@ frok::parent (volatile char * volatile stack_here)
|
|||||||
si.lpReserved2 = (LPBYTE) &ch;
|
si.lpReserved2 = (LPBYTE) &ch;
|
||||||
si.cbReserved2 = sizeof (ch);
|
si.cbReserved2 = sizeof (ch);
|
||||||
|
|
||||||
syscall_printf ("CreateProcessW (%W, %W, 0, 0, 1, %p, 0, 0, %p, %p)",
|
syscall_printf ("CreateProcessW (%W, %W, 0, 0, 1, %y, 0, 0, %p, %p)",
|
||||||
myself->progname, myself->progname, c_flags, &si, &pi);
|
myself->progname, myself->progname, c_flags, &si, &pi);
|
||||||
bool locked = __malloc_lock ();
|
bool locked = __malloc_lock ();
|
||||||
time_t start_time = time (NULL);
|
time_t start_time = time (NULL);
|
||||||
@ -598,14 +598,18 @@ fork ()
|
|||||||
|
|
||||||
ischild = !!setjmp (grouped.ch.jmp);
|
ischild = !!setjmp (grouped.ch.jmp);
|
||||||
|
|
||||||
volatile char * volatile esp;
|
volatile char * volatile stackp;
|
||||||
__asm__ volatile ("movl %%esp,%0": "=r" (esp));
|
#ifdef __x86_64__
|
||||||
|
__asm__ volatile ("movq %%rsp,%0": "=r" (stackp));
|
||||||
|
#else
|
||||||
|
__asm__ volatile ("movl %%esp,%0": "=r" (stackp));
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!ischild)
|
if (!ischild)
|
||||||
res = grouped.parent (esp);
|
res = grouped.parent (stackp);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
res = grouped.child (esp);
|
res = grouped.child (stackp);
|
||||||
in_forkee = false;
|
in_forkee = false;
|
||||||
ischild = true; /* might have been reset by fork mem copy */
|
ischild = true; /* might have been reset by fork mem copy */
|
||||||
}
|
}
|
||||||
@ -664,12 +668,12 @@ child_copy (HANDLE hp, bool write, ...)
|
|||||||
{
|
{
|
||||||
char *low = va_arg (args, char *);
|
char *low = va_arg (args, char *);
|
||||||
char *high = va_arg (args, char *);
|
char *high = va_arg (args, char *);
|
||||||
DWORD todo = high - low;
|
SIZE_T todo = high - low;
|
||||||
char *here;
|
char *here;
|
||||||
|
|
||||||
for (here = low; here < high; here += todo)
|
for (here = low; here < high; here += todo)
|
||||||
{
|
{
|
||||||
DWORD done = 0;
|
SIZE_T done = 0;
|
||||||
if (here + todo > high)
|
if (here + todo > high)
|
||||||
todo = high - here;
|
todo = high - here;
|
||||||
int res;
|
int res;
|
||||||
@ -684,7 +688,7 @@ child_copy (HANDLE hp, bool write, ...)
|
|||||||
__seterrno ();
|
__seterrno ();
|
||||||
/* If this happens then there is a bug in our fork
|
/* If this happens then there is a bug in our fork
|
||||||
implementation somewhere. */
|
implementation somewhere. */
|
||||||
system_printf ("%s %s copy failed, %p..%p, done %d, windows pid %u, %E",
|
system_printf ("%s %s copy failed, %p..%p, done %lu, windows pid %u, %E",
|
||||||
what, huh[write], low, high, done, myself->dwProcessId);
|
what, huh[write], low, high, done, myself->dwProcessId);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
@ -13,16 +13,20 @@ sub cleanup(@);
|
|||||||
|
|
||||||
my $in = shift;
|
my $in = shift;
|
||||||
my $tls_offsets = shift;
|
my $tls_offsets = shift;
|
||||||
|
my $cpu = shift;
|
||||||
my $out = shift;
|
my $out = shift;
|
||||||
my $sigfe = shift;
|
my $sigfe = shift;
|
||||||
|
|
||||||
$main::first = 0;
|
$main::first = 0;
|
||||||
if (!defined($in) || !defined($out) || !defined($sigfe)) {
|
if (!defined($in) || !defined($cpu) || !defined($out) || !defined($sigfe)) {
|
||||||
die "usage: $0 deffile.in cygtls.h deffile.def sigfe.s\n";
|
die "usage: $0 deffile.in cygtls.h target-cpu deffile.def sigfe.s\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
require $tls_offsets;
|
require $tls_offsets;
|
||||||
|
|
||||||
|
my $is64bit = ($cpu eq 'x86_64' ? 1 : 0);
|
||||||
|
my $sym_prefix = ($is64bit ? '' : '_');
|
||||||
|
|
||||||
open(IN, $in) or die "$0: couldn't open \"$in\" - $!\n";
|
open(IN, $in) or die "$0: couldn't open \"$in\" - $!\n";
|
||||||
my @top = ();
|
my @top = ();
|
||||||
while (<IN>) {
|
while (<IN>) {
|
||||||
@ -47,7 +51,7 @@ for (@in) {
|
|||||||
# nothing
|
# nothing
|
||||||
} elsif (s/\s+SIGFE(_MAYBE)?$//) {
|
} elsif (s/\s+SIGFE(_MAYBE)?$//) {
|
||||||
my $func = (split(' '))[2];
|
my $func = (split(' '))[2];
|
||||||
my $maybe = lc $1 . '_';
|
my $maybe = (defined($1) ? lc $1 : '') . '_';
|
||||||
$sigfe{$func} = '_sigfe' . $maybe . $func;
|
$sigfe{$func} = '_sigfe' . $maybe . $func;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -86,20 +90,312 @@ for my $k (sort keys %sigfe) {
|
|||||||
close SIGFE;
|
close SIGFE;
|
||||||
|
|
||||||
sub fefunc {
|
sub fefunc {
|
||||||
my $func = '_' . shift;
|
my $func = $sym_prefix . shift;
|
||||||
my $fe = '_' . shift;
|
my $fe = $sym_prefix . shift;
|
||||||
my $sigfe_func = ($fe =~ /^(.*)$func/)[0];
|
my $sigfe_func;
|
||||||
|
if ($is64bit) {
|
||||||
|
$sigfe_func = ($fe =~ /^(.*)_${func}$/)[0];
|
||||||
|
} else {
|
||||||
|
$sigfe_func = ($fe =~ /^(.*)${func}$/)[0];
|
||||||
|
}
|
||||||
my $extra;
|
my $extra;
|
||||||
my $res = <<EOF;
|
my $res;
|
||||||
|
if ($is64bit) {
|
||||||
|
$res = <<EOF;
|
||||||
.extern $func
|
.extern $func
|
||||||
.global $fe
|
.global $fe
|
||||||
|
.seh_proc $fe
|
||||||
$fe:
|
$fe:
|
||||||
pushl \$$func
|
leaq $func(%rip),%r10
|
||||||
|
pushq %r10
|
||||||
|
.seh_pushreg %r10
|
||||||
|
.seh_endprologue
|
||||||
jmp $sigfe_func
|
jmp $sigfe_func
|
||||||
|
.seh_endproc
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
|
} else {
|
||||||
|
$res = <<EOF;
|
||||||
|
.extern $func
|
||||||
|
.global $fe
|
||||||
|
$fe:
|
||||||
|
pushl \$$func
|
||||||
|
jmp $sigfe_func
|
||||||
|
|
||||||
|
EOF
|
||||||
|
}
|
||||||
if (!$main::first++) {
|
if (!$main::first++) {
|
||||||
$res = <<EOF . longjmp () . $res;
|
if ($is64bit) {
|
||||||
|
$res = <<EOF . longjmp () . $res;
|
||||||
|
.text
|
||||||
|
|
||||||
|
.seh_proc _sigfe_maybe
|
||||||
|
_sigfe_maybe:
|
||||||
|
pushq %r12
|
||||||
|
.seh_pushreg %r12
|
||||||
|
.seh_endprologue
|
||||||
|
movq %gs:8,%r12 # location of bottom of stack
|
||||||
|
addq \$$tls::initialized,%r12 # where we will be looking
|
||||||
|
cmpq %r12,%rsp # stack loc > than tls
|
||||||
|
jge 0f # yep. we don't have a tls.
|
||||||
|
subq \$$tls::initialized,%r12 # where we will be looking
|
||||||
|
movl $tls::initialized(%r12),%r11d
|
||||||
|
cmpl \$0xc763173f,%r11d # initialized?
|
||||||
|
je 1f
|
||||||
|
0:
|
||||||
|
popq %r12
|
||||||
|
ret
|
||||||
|
.seh_endproc
|
||||||
|
|
||||||
|
.seh_proc _sigfe
|
||||||
|
_sigfe: # stack is aligned on entry!
|
||||||
|
pushq %r12
|
||||||
|
.seh_pushreg %r12
|
||||||
|
.seh_endprologue
|
||||||
|
movq %gs:8,%r12 # location of bottom of stack
|
||||||
|
1: movl \$1,%r11d # potential lock value
|
||||||
|
xchgl %r11d,$tls::stacklock(%r12) # see if we can grab it
|
||||||
|
movl %r11d,$tls::spinning(%r12) # flag if we are waiting for lock
|
||||||
|
testl %r11d,%r11d # it will be zero
|
||||||
|
jz 2f # if so
|
||||||
|
pause
|
||||||
|
jmp 1b # loop
|
||||||
|
2: movq \$8,%rax # have the lock, now increment the
|
||||||
|
xaddq %rax,$tls::stackptr(%r12) # stack pointer and get pointer
|
||||||
|
leaq _sigbe(%rip),%r11 # new place to return to
|
||||||
|
xchgq %r11,16(%rsp) # exchange with real return value
|
||||||
|
movq %r11,(%rax) # store real return value on alt stack
|
||||||
|
incl $tls::incyg(%r12)
|
||||||
|
decl $tls::stacklock(%r12) # remove lock
|
||||||
|
popq %r12 # restore saved value
|
||||||
|
popq %rax # pop real function address from stack
|
||||||
|
jmp *%rax # and jmp to it
|
||||||
|
.seh_endproc
|
||||||
|
|
||||||
|
.seh_proc _sigfe
|
||||||
|
_sigbe: # return here after cygwin syscall
|
||||||
|
# stack is aligned on entry!
|
||||||
|
pushq %r12
|
||||||
|
.seh_pushreg %r12
|
||||||
|
.seh_endprologue
|
||||||
|
movq %gs:8,%r12 # address of bottom of tls
|
||||||
|
1: movl \$1,%r11d # potential lock value
|
||||||
|
xchgl %r11d,$tls::stacklock(%r12) # see if we can grab it
|
||||||
|
movl %r11d,$tls::spinning(%r12) # flag if we are waiting for lock
|
||||||
|
testl %r11d,%r11d # it will be zero
|
||||||
|
jz 2f # if so
|
||||||
|
pause
|
||||||
|
jmp 1b # and loop
|
||||||
|
2: movq \$-8,%r11 # now decrement aux stack
|
||||||
|
xaddq %r11,$tls::stackptr(%r12) # and get pointer
|
||||||
|
movq -8(%r11),%r11 # get return address from signal stack
|
||||||
|
decl $tls::incyg(%r12)
|
||||||
|
decl $tls::stacklock(%r12) # release lock
|
||||||
|
popq %r12
|
||||||
|
jmp *%r11 # "return" to caller
|
||||||
|
.seh_endproc
|
||||||
|
|
||||||
|
.global sigdelayed
|
||||||
|
.seh_proc sigdelayed
|
||||||
|
sigdelayed:
|
||||||
|
pushq %r10 # used for return address injection
|
||||||
|
.seh_pushreg %rbp
|
||||||
|
pushq %rbp
|
||||||
|
.seh_pushreg %rbp
|
||||||
|
movq %rsp,%rbp
|
||||||
|
# stack is aligned or unaligned on entry!
|
||||||
|
# make sure it is aligned from here on
|
||||||
|
# We could be called from an interrupted thread which doesn't know
|
||||||
|
# about his fate, so save and restore everything and the kitchen sink.
|
||||||
|
andq \$0xfffffffffffffff0,%rsp
|
||||||
|
.seh_setframe %rbp,0
|
||||||
|
pushq %r15
|
||||||
|
.seh_pushreg %r15
|
||||||
|
pushq %r14
|
||||||
|
.seh_pushreg %r14
|
||||||
|
pushq %r13
|
||||||
|
.seh_pushreg %r13
|
||||||
|
pushq %r12
|
||||||
|
.seh_pushreg %r12
|
||||||
|
pushq %r11
|
||||||
|
.seh_pushreg %r11
|
||||||
|
pushq %r9
|
||||||
|
.seh_pushreg %r9
|
||||||
|
pushq %r8
|
||||||
|
.seh_pushreg %r8
|
||||||
|
pushq %rsi
|
||||||
|
.seh_pushreg %rsi
|
||||||
|
pushq %rdi
|
||||||
|
.seh_pushreg %rdi
|
||||||
|
pushq %rdx
|
||||||
|
.seh_pushreg %rdx
|
||||||
|
pushq %rcx
|
||||||
|
.seh_pushreg %rcx
|
||||||
|
pushq %rbx
|
||||||
|
.seh_pushreg %rbx
|
||||||
|
pushq %rax
|
||||||
|
.seh_pushreg %rax
|
||||||
|
pushf
|
||||||
|
subq \$0x120,%rsp
|
||||||
|
.seh_stackalloc 0x120
|
||||||
|
movdqa %xmm15,0x110(%rsp)
|
||||||
|
movdqa %xmm14,0x100(%rsp)
|
||||||
|
movdqa %xmm13,0xf0(%rsp)
|
||||||
|
movdqa %xmm12,0xe0(%rsp)
|
||||||
|
movdqa %xmm11,0xd0(%rsp)
|
||||||
|
movdqa %xmm10,0xc0(%rsp)
|
||||||
|
movdqa %xmm9,0xb0(%rsp)
|
||||||
|
movdqa %xmm8,0xa0(%rsp)
|
||||||
|
movdqa %xmm7,0x90(%rsp)
|
||||||
|
movdqa %xmm6,0x80(%rsp)
|
||||||
|
movdqa %xmm5,0x70(%rsp)
|
||||||
|
movdqa %xmm4,0x60(%rsp)
|
||||||
|
movdqa %xmm3,0x50(%rsp)
|
||||||
|
movdqa %xmm2,0x40(%rsp)
|
||||||
|
movdqa %xmm1,0x30(%rsp)
|
||||||
|
movdqa %xmm0,0x20(%rsp)
|
||||||
|
.seh_endprologue
|
||||||
|
|
||||||
|
movq %gs:8,%r12 # get tls
|
||||||
|
movl $tls::saved_errno(%r12),%r15d # temporarily save saved_errno
|
||||||
|
movq \$$tls::start_offset,%rcx # point to beginning of tls block
|
||||||
|
addq %r12,%rcx # and store as first arg to method
|
||||||
|
call _ZN7_cygtls19call_signal_handlerEv # call handler
|
||||||
|
|
||||||
|
1: movl \$1,%r11d # potential lock value
|
||||||
|
xchgl %r11d,$tls::stacklock(%r12) # see if we can grab it
|
||||||
|
movl %r11d,$tls::spinning(%r12) # flag if we are waiting for lock
|
||||||
|
testl %r11d,%r11d # it will be zero
|
||||||
|
jz 2f # if so
|
||||||
|
pause
|
||||||
|
jmp 1b # and loop
|
||||||
|
2: testl %r15d,%r15d # was saved_errno < 0
|
||||||
|
jl 3f # yup. ignore it
|
||||||
|
movq $tls::errno_addr(%r12),%r11
|
||||||
|
movl %r15d,(%r11)
|
||||||
|
3: movq \$-8,%r11 # now decrement aux stack
|
||||||
|
xaddq %r11,$tls::stackptr(%r12) # and get pointer
|
||||||
|
xorq %r10,%r10
|
||||||
|
xchgq %r10,-8(%r11) # get return address from signal stack
|
||||||
|
xorl %r11d,%r11d
|
||||||
|
movl %r11d,$tls::incyg(%r12)
|
||||||
|
movl %r11d,$tls::stacklock(%r12) # unlock
|
||||||
|
movdqa 0x20(%rsp),%xmm0
|
||||||
|
movdqa 0x30(%rsp),%xmm1
|
||||||
|
movdqa 0x40(%rsp),%xmm2
|
||||||
|
movdqa 0x50(%rsp),%xmm3
|
||||||
|
movdqa 0x60(%rsp),%xmm4
|
||||||
|
movdqa 0x70(%rsp),%xmm5
|
||||||
|
movdqa 0x80(%rsp),%xmm6
|
||||||
|
movdqa 0x90(%rsp),%xmm7
|
||||||
|
movdqa 0xa0(%rsp),%xmm8
|
||||||
|
movdqa 0xb0(%rsp),%xmm9
|
||||||
|
movdqa 0xc0(%rsp),%xmm10
|
||||||
|
movdqa 0xd0(%rsp),%xmm11
|
||||||
|
movdqa 0xe0(%rsp),%xmm12
|
||||||
|
movdqa 0xf0(%rsp),%xmm13
|
||||||
|
movdqa 0x100(%rsp),%xmm14
|
||||||
|
movdqa 0x110(%rsp),%xmm15
|
||||||
|
addq \$0x120,%rsp
|
||||||
|
popf
|
||||||
|
popq %rax
|
||||||
|
popq %rbx
|
||||||
|
popq %rcx
|
||||||
|
popq %rdx
|
||||||
|
popq %rdi
|
||||||
|
popq %rsi
|
||||||
|
popq %r8
|
||||||
|
popq %r9
|
||||||
|
popq %r11
|
||||||
|
popq %r12
|
||||||
|
popq %r13
|
||||||
|
popq %r14
|
||||||
|
popq %r15
|
||||||
|
movq %rbp,%rsp
|
||||||
|
popq %rbp
|
||||||
|
xchgq %r10,(%rsp)
|
||||||
|
ret
|
||||||
|
.seh_endproc
|
||||||
|
|
||||||
|
# _cygtls::pop
|
||||||
|
.global _ZN7_cygtls3popEv
|
||||||
|
.seh_proc _ZN7_cygtls3popEv
|
||||||
|
_ZN7_cygtls3popEv:
|
||||||
|
.seh_endprologue
|
||||||
|
movq \$-8,%r11
|
||||||
|
xaddq %r11,$tls::pstackptr(%rcx)
|
||||||
|
movq -8(%r11),%rax
|
||||||
|
ret
|
||||||
|
.seh_endproc
|
||||||
|
|
||||||
|
# _cygtls::lock
|
||||||
|
.global _ZN7_cygtls4lockEv
|
||||||
|
.seh_proc _ZN7_cygtls4lockEv
|
||||||
|
_ZN7_cygtls4lockEv:
|
||||||
|
pushq %r12
|
||||||
|
.seh_pushreg %r12
|
||||||
|
.seh_endprologue
|
||||||
|
movq %rcx,%r12
|
||||||
|
1: movl \$1,%r11d
|
||||||
|
xchgl %r11d,$tls::pstacklock(%r12)
|
||||||
|
testl %r11d,%r11d
|
||||||
|
jz 2f
|
||||||
|
pause
|
||||||
|
jmp 1b
|
||||||
|
2: popq %r12
|
||||||
|
ret
|
||||||
|
.seh_endproc
|
||||||
|
|
||||||
|
# _cygtls::unlock
|
||||||
|
.global _ZN7_cygtls6unlockEv
|
||||||
|
.seh_proc _ZN7_cygtls6unlockEv
|
||||||
|
_ZN7_cygtls6unlockEv:
|
||||||
|
.seh_endprologue
|
||||||
|
decl $tls::pstacklock(%rcx)
|
||||||
|
ret
|
||||||
|
.seh_endproc
|
||||||
|
|
||||||
|
# _cygtls::locked
|
||||||
|
.global _ZN7_cygtls6lockedEv
|
||||||
|
.seh_proc _ZN7_cygtls6lockedEv
|
||||||
|
_ZN7_cygtls6lockedEv:
|
||||||
|
.seh_endprologue
|
||||||
|
movl $tls::pstacklock(%rcx),%eax
|
||||||
|
ret
|
||||||
|
.seh_endproc
|
||||||
|
|
||||||
|
.seh_proc stabilize_sig_stack
|
||||||
|
stabilize_sig_stack:
|
||||||
|
pushq %r12
|
||||||
|
.seh_pushreg %r12
|
||||||
|
subq \$0x20,%rsp
|
||||||
|
.seh_stackalloc 32
|
||||||
|
.seh_endprologue
|
||||||
|
movq %gs:8,%r12
|
||||||
|
1: movl \$1,%r10d
|
||||||
|
xchgl %r10d,$tls::stacklock(%r12)
|
||||||
|
movl %r10d,$tls::spinning(%r12) # flag if we are waiting for lock
|
||||||
|
testl %r10d,%r10d
|
||||||
|
jz 2f
|
||||||
|
pause
|
||||||
|
jmp 1b
|
||||||
|
2: incl $tls::incyg(%r12)
|
||||||
|
cmpl \$0,$tls::sig(%r12)
|
||||||
|
jz 3f
|
||||||
|
decl $tls::stacklock(%r12) # unlock
|
||||||
|
movq \$$tls::start_offset,%rcx # point to beginning
|
||||||
|
addq %r12,%rcx # of tls block
|
||||||
|
call _ZN7_cygtls19call_signal_handlerEv
|
||||||
|
jmp 1b
|
||||||
|
3: decl $tls::incyg(%r12)
|
||||||
|
addq \$0x20,%rsp
|
||||||
|
movq %r12,%r11 # return tls addr in r11
|
||||||
|
popq %r12
|
||||||
|
ret
|
||||||
|
.seh_endproc
|
||||||
|
EOF
|
||||||
|
} else {
|
||||||
|
$res = <<EOF . longjmp () . $res;
|
||||||
.text
|
.text
|
||||||
|
|
||||||
__sigfe_maybe:
|
__sigfe_maybe:
|
||||||
@ -265,12 +561,170 @@ stabilize_sig_stack:
|
|||||||
3: decl $tls::incyg(%ebx)
|
3: decl $tls::incyg(%ebx)
|
||||||
ret
|
ret
|
||||||
EOF
|
EOF
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub longjmp {
|
sub longjmp {
|
||||||
return <<EOF;
|
if ($is64bit) {
|
||||||
|
return <<EOF;
|
||||||
|
|
||||||
|
.globl setjmp
|
||||||
|
.seh_proc setjmp
|
||||||
|
setjmp:
|
||||||
|
.seh_endprologue
|
||||||
|
# We use the Windows jmp_buf layout. Store ExceptionList in Frame.
|
||||||
|
# Store alternative stackptr in Spare.
|
||||||
|
movq %gs:0,%r10
|
||||||
|
movq %r10,(%rcx)
|
||||||
|
movq %rbx,0x8(%rcx)
|
||||||
|
movq %rsp,0x10(%rcx)
|
||||||
|
movq %rbp,0x18(%rcx)
|
||||||
|
movq %rsi,0x20(%rcx)
|
||||||
|
movq %rdi,0x28(%rcx)
|
||||||
|
movq %r12,0x30(%rcx)
|
||||||
|
movq %r13,0x38(%rcx)
|
||||||
|
movq %r14,0x40(%rcx)
|
||||||
|
movq %r15,0x48(%rcx)
|
||||||
|
movq (%rsp),%r10
|
||||||
|
movq %r10,0x50(%rcx)
|
||||||
|
# jmp_buf is potentially unaligned!
|
||||||
|
movdqu %xmm6,0x60(%rcx)
|
||||||
|
movdqu %xmm7,0x70(%rcx)
|
||||||
|
movdqu %xmm8,0x80(%rcx)
|
||||||
|
movdqu %xmm9,0x90(%rcx)
|
||||||
|
movdqu %xmm10,0xa0(%rcx)
|
||||||
|
movdqu %xmm11,0xb0(%rcx)
|
||||||
|
movdqu %xmm12,0xc0(%rcx)
|
||||||
|
movdqu %xmm13,0xd0(%rcx)
|
||||||
|
movdqu %xmm14,0xe0(%rcx)
|
||||||
|
movdqu %xmm15,0xf0(%rcx)
|
||||||
|
pushq %rcx
|
||||||
|
.seh_pushreg %rcx
|
||||||
|
call stabilize_sig_stack # returns tls in r11
|
||||||
|
popq %rcx
|
||||||
|
movq $tls::stackptr(%r11),%r10
|
||||||
|
movq %r10,0x58(%rcx)
|
||||||
|
decl $tls::stacklock(%r11)
|
||||||
|
movl \$0,%eax
|
||||||
|
ret
|
||||||
|
.seh_endproc
|
||||||
|
|
||||||
|
.globl __sjfault
|
||||||
|
.seh_proc __sjfault
|
||||||
|
__sjfault:
|
||||||
|
.seh_endprologue
|
||||||
|
# Like setjmp, just w/o storing the alternate stackptr.
|
||||||
|
movq %gs:0,%r10
|
||||||
|
movq %r10,(%rcx)
|
||||||
|
movq %rbx,0x8(%rcx)
|
||||||
|
movq %rsp,0x10(%rcx)
|
||||||
|
movq %rbp,0x18(%rcx)
|
||||||
|
movq %rsi,0x20(%rcx)
|
||||||
|
movq %rdi,0x28(%rcx)
|
||||||
|
movq %r12,0x30(%rcx)
|
||||||
|
movq %r13,0x38(%rcx)
|
||||||
|
movq %r14,0x40(%rcx)
|
||||||
|
movq %r15,0x48(%rcx)
|
||||||
|
movq (%rsp),%r10
|
||||||
|
movq %r10,0x50(%rcx)
|
||||||
|
# jmp_buf is potentially unaligned!
|
||||||
|
movdqu %xmm6,0x60(%rcx)
|
||||||
|
movdqu %xmm7,0x70(%rcx)
|
||||||
|
movdqu %xmm8,0x80(%rcx)
|
||||||
|
movdqu %xmm9,0x90(%rcx)
|
||||||
|
movdqu %xmm10,0xa0(%rcx)
|
||||||
|
movdqu %xmm11,0xb0(%rcx)
|
||||||
|
movdqu %xmm12,0xc0(%rcx)
|
||||||
|
movdqu %xmm13,0xd0(%rcx)
|
||||||
|
movdqu %xmm14,0xe0(%rcx)
|
||||||
|
movdqu %xmm15,0xf0(%rcx)
|
||||||
|
movl \$0,%eax
|
||||||
|
ret
|
||||||
|
.seh_endproc
|
||||||
|
|
||||||
|
.globl __ljfault
|
||||||
|
.seh_proc __ljfault
|
||||||
|
__ljfault:
|
||||||
|
movq (%rcx),%r10
|
||||||
|
movq %r10,%gs:0
|
||||||
|
movq 0x8(%rcx),%rbx
|
||||||
|
movq 0x10(%rcx),%rsp
|
||||||
|
movq 0x18(%rcx),%rbp
|
||||||
|
movq 0x20(%rcx),%rsi
|
||||||
|
movq 0x28(%rcx),%rdi
|
||||||
|
movq 0x30(%rcx),%r12
|
||||||
|
movq 0x38(%rcx),%r13
|
||||||
|
movq 0x40(%rcx),%r14
|
||||||
|
movq 0x48(%rcx),%r15
|
||||||
|
movq 0x50(%rcx),%r10
|
||||||
|
movq %r10,(%rsp)
|
||||||
|
# jmp_buf is potentially unaligned!
|
||||||
|
movdqu 0x60(%rcx),%xmm6
|
||||||
|
movdqu 0x70(%rcx),%xmm7
|
||||||
|
movdqu 0x80(%rcx),%xmm8
|
||||||
|
movdqu 0x90(%rcx),%xmm9
|
||||||
|
movdqu 0xa0(%rcx),%xmm10
|
||||||
|
movdqu 0xb0(%rcx),%xmm11
|
||||||
|
movdqu 0xc0(%rcx),%xmm12
|
||||||
|
movdqu 0xd0(%rcx),%xmm13
|
||||||
|
movdqu 0xe0(%rcx),%xmm14
|
||||||
|
movdqu 0xf0(%rcx),%xmm15
|
||||||
|
movl %edx,%eax
|
||||||
|
testl %eax,%eax
|
||||||
|
jne 0f
|
||||||
|
incl %eax
|
||||||
|
0: ret
|
||||||
|
.seh_endproc
|
||||||
|
|
||||||
|
.globl longjmp
|
||||||
|
.seh_proc longjmp
|
||||||
|
longjmp:
|
||||||
|
pushq %rcx
|
||||||
|
.seh_pushreg %rcx
|
||||||
|
.seh_endprologue
|
||||||
|
movl %edx,%r12d # save return value (r12 is overwritten anyway)
|
||||||
|
call stabilize_sig_stack # returns tls in r11
|
||||||
|
popq %rcx
|
||||||
|
movl %r12d,%eax # restore return value
|
||||||
|
movq 0x58(%rcx),%r10 # get old signal stack
|
||||||
|
movq %r10,$tls::stackptr(%r11) # restore
|
||||||
|
decl $tls::stacklock(%r11) # relinquish lock
|
||||||
|
xorl %r10d,%r10d
|
||||||
|
movl %r10d,$tls::incyg(%r11) # we're definitely not in cygwin anymore
|
||||||
|
movq (%rcx),%r10
|
||||||
|
movq %r10,%gs:0
|
||||||
|
movq 0x8(%rcx),%rbx
|
||||||
|
movq 0x10(%rcx),%rsp
|
||||||
|
movq 0x18(%rcx),%rbp
|
||||||
|
movq 0x20(%rcx),%rsi
|
||||||
|
movq 0x28(%rcx),%rdi
|
||||||
|
movq 0x30(%rcx),%r12
|
||||||
|
movq 0x38(%rcx),%r13
|
||||||
|
movq 0x40(%rcx),%r14
|
||||||
|
movq 0x48(%rcx),%r15
|
||||||
|
movq 0x50(%rcx),%r10
|
||||||
|
movq %r10,(%rsp)
|
||||||
|
# jmp_buf is potentially unaligned!
|
||||||
|
movdqu 0x60(%rcx),%xmm6
|
||||||
|
movdqu 0x70(%rcx),%xmm7
|
||||||
|
movdqu 0x80(%rcx),%xmm8
|
||||||
|
movdqu 0x90(%rcx),%xmm9
|
||||||
|
movdqu 0xa0(%rcx),%xmm10
|
||||||
|
movdqu 0xb0(%rcx),%xmm11
|
||||||
|
movdqu 0xc0(%rcx),%xmm12
|
||||||
|
movdqu 0xd0(%rcx),%xmm13
|
||||||
|
movdqu 0xe0(%rcx),%xmm14
|
||||||
|
movdqu 0xf0(%rcx),%xmm15
|
||||||
|
testl %eax,%eax
|
||||||
|
jne 0f
|
||||||
|
incl %eax
|
||||||
|
0: ret
|
||||||
|
.seh_endproc
|
||||||
|
EOF
|
||||||
|
} else {
|
||||||
|
return <<EOF;
|
||||||
|
|
||||||
.globl _setjmp
|
.globl _setjmp
|
||||||
_setjmp:
|
_setjmp:
|
||||||
@ -424,6 +878,7 @@ _longjmp:
|
|||||||
popfl
|
popfl
|
||||||
ret
|
ret
|
||||||
EOF
|
EOF
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub cleanup(@) {
|
sub cleanup(@) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/perl -s
|
#!/usr/bin/perl -s
|
||||||
# Copyright 2003, 2004, 2005, 2006, 2008, 2012, 2013 Red Hat, Inc.
|
# Copyright 2003, 2004, 2005, 2012, 2013 Red Hat, Inc.
|
||||||
#
|
#
|
||||||
# This file is part of Cygwin.
|
# This file is part of Cygwin.
|
||||||
#
|
#
|
||||||
@ -9,6 +9,13 @@
|
|||||||
#
|
#
|
||||||
my $tls = shift;
|
my $tls = shift;
|
||||||
my $tls_out = shift;
|
my $tls_out = shift;
|
||||||
|
my $tgt = shift;
|
||||||
|
# FIXME? This method obviously requires a 64 bit OS to build tlsoffsets64.h
|
||||||
|
# Another method which doesn't requires to run an executable would be to
|
||||||
|
# generate assembler code accessing the various struct members and analyzing
|
||||||
|
# it, but that's arguably a lot more effort.
|
||||||
|
my $tgt_opt='-m64';
|
||||||
|
$tgt_opt='-m32' unless ($tgt eq 'x86_64');
|
||||||
open(TLS, $tls) or die "$0: couldn't open tls file \"$tls\" - $!\n";
|
open(TLS, $tls) or die "$0: couldn't open tls file \"$tls\" - $!\n";
|
||||||
my $struct = '';
|
my $struct = '';
|
||||||
my @fields = ();
|
my @fields = ();
|
||||||
@ -44,7 +51,9 @@ close TLS;
|
|||||||
open(TMP, '>', "/tmp/$$.cc") or die "$0: couldn't open temporary index file \"/tmp/$$.c\" - $!\n";
|
open(TMP, '>', "/tmp/$$.cc") or die "$0: couldn't open temporary index file \"/tmp/$$.c\" - $!\n";
|
||||||
print TMP <<EOF;
|
print TMP <<EOF;
|
||||||
#define __INSIDE_CYGWIN__
|
#define __INSIDE_CYGWIN__
|
||||||
|
#ifndef __x86_64__
|
||||||
#define __attribute__(X)
|
#define __attribute__(X)
|
||||||
|
#endif
|
||||||
#define __reg1
|
#define __reg1
|
||||||
#define __reg2
|
#define __reg2
|
||||||
#define __reg3
|
#define __reg3
|
||||||
@ -81,13 +90,13 @@ EOF
|
|||||||
EOF
|
EOF
|
||||||
close TMP;
|
close TMP;
|
||||||
system @ARGV, '-o', "/tmp/$$-1.cc", '-E', "/tmp/$$.cc";
|
system @ARGV, '-o', "/tmp/$$-1.cc", '-E', "/tmp/$$.cc";
|
||||||
system 'g++', '-m32', '-o', "/tmp/$$.a.out", "/tmp/$$-1.cc" and
|
system 'g++', "$tgt_opt", '-o', "/tmp/$$.a.out", "/tmp/$$-1.cc" and
|
||||||
($? == 127 && system 'c++', '-m32', '-o', "/tmp/$$.a.out", "/tmp/$$-1.cc") and
|
($? == 127 && system 'c++', "$tgt_opt", '-o', "/tmp/$$.a.out", "/tmp/$$-1.cc") and
|
||||||
die "$0: couldn't generate executable for offset calculation \"/tmp/$$.a.out\" - $!\n";
|
die "$0: couldn't generate executable for offset calculation \"/tmp/$$.a.out\" - $!\n";
|
||||||
open(TLS_OUT, '>', $tls_out) or die "$0: couldn't open tls index file \"$tls_out\" - $!\n";
|
open(TLS_OUT, '>', $tls_out) or die "$0: couldn't open tls index file \"$tls_out\" - $!\n";
|
||||||
open(OFFS, "/tmp/$$.a.out|") or die "$0: couldn't run \"/tmp/$$.a.out\" - $!\n";
|
open(OFFS, "/tmp/$$.a.out|") or die "$0: couldn't run \"/tmp/$$.a.out\" - $!\n";
|
||||||
print TLS_OUT <OFFS>;
|
print TLS_OUT <OFFS>;
|
||||||
close OFFS;
|
close OFFS;
|
||||||
close TLS_OUT;
|
close TLS_OUT;
|
||||||
unlink "/tmp/$$.cc", "/tmp/$$.a.out";
|
unlink "/tmp/$$.cc", "/tmp/$$-1.cc", "/tmp/$$-1.d", "/tmp/$$.a.out";
|
||||||
exit(0);
|
exit(0);
|
||||||
|
@ -105,8 +105,6 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/glob.c,v 1.28 2010/05/12 17:44:00 gordon Ex
|
|||||||
#define getuid() getuid32 ()
|
#define getuid() getuid32 ()
|
||||||
#define issetugid() (cygheap->user.issetuid ())
|
#define issetugid() (cygheap->user.issetuid ())
|
||||||
|
|
||||||
#define stat __stat64
|
|
||||||
|
|
||||||
#define CCHAR(c) (ignore_case_with_glob ? towlower (CHAR (c)) : CHAR (c))
|
#define CCHAR(c) (ignore_case_with_glob ? towlower (CHAR (c)) : CHAR (c))
|
||||||
#define Cchar(c) (ignore_case_with_glob ? towlower (c) : (c))
|
#define Cchar(c) (ignore_case_with_glob ? towlower (c) : (c))
|
||||||
#endif
|
#endif
|
||||||
@ -858,8 +856,11 @@ g_opendir(Char *str, glob_t *pglob)
|
|||||||
return(opendir(buf));
|
return(opendir(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __x86_64__
|
||||||
|
#define CYGWIN_gl_stat(sfptr) ((*pglob->sfptr) (buf, sb))
|
||||||
|
#else
|
||||||
static void
|
static void
|
||||||
stat32_to_stat64 (struct __stat32 *src, struct __stat64 *dst)
|
stat32_to_stat64 (struct __stat32 *src, struct stat *dst)
|
||||||
{
|
{
|
||||||
dst->st_dev = src->st_dev;
|
dst->st_dev = src->st_dev;
|
||||||
dst->st_ino = src->st_ino;
|
dst->st_ino = src->st_ino;
|
||||||
@ -882,10 +883,11 @@ stat32_to_stat64 (struct __stat32 *src, struct __stat64 *dst)
|
|||||||
struct __stat32 lsb; \
|
struct __stat32 lsb; \
|
||||||
if (CYGWIN_VERSION_CHECK_FOR_USING_BIG_TYPES) \
|
if (CYGWIN_VERSION_CHECK_FOR_USING_BIG_TYPES) \
|
||||||
ret = (*pglob->sfptr) (buf, sb); \
|
ret = (*pglob->sfptr) (buf, sb); \
|
||||||
else if (!(ret = (*pglob->sfptr) (buf, (struct __stat64 *) &lsb))) \
|
else if (!(ret = (*pglob->sfptr) (buf, (struct stat *) &lsb))) \
|
||||||
stat32_to_stat64 (&lsb, sb); \
|
stat32_to_stat64 (&lsb, sb); \
|
||||||
ret; \
|
ret; \
|
||||||
})
|
})
|
||||||
|
#endif
|
||||||
|
|
||||||
static int
|
static int
|
||||||
g_lstat(Char *fn, struct stat *sb, glob_t *pglob)
|
g_lstat(Char *fn, struct stat *sb, glob_t *pglob)
|
||||||
|
@ -26,8 +26,10 @@ HMODULE NO_COPY cygwin_hmodule;
|
|||||||
int NO_COPY sigExeced;
|
int NO_COPY sigExeced;
|
||||||
WCHAR windows_system_directory[MAX_PATH];
|
WCHAR windows_system_directory[MAX_PATH];
|
||||||
UINT windows_system_directory_length;
|
UINT windows_system_directory_length;
|
||||||
|
#ifndef __x86_64__
|
||||||
WCHAR system_wow64_directory[MAX_PATH];
|
WCHAR system_wow64_directory[MAX_PATH];
|
||||||
UINT system_wow64_directory_length;
|
UINT system_wow64_directory_length;
|
||||||
|
#endif /* !__x86_64__ */
|
||||||
|
|
||||||
/* program exit the program */
|
/* program exit the program */
|
||||||
|
|
||||||
@ -78,64 +80,74 @@ bool NO_COPY _cygwin_testing;
|
|||||||
|
|
||||||
char NO_COPY almost_null[1];
|
char NO_COPY almost_null[1];
|
||||||
|
|
||||||
/* Heavily-used const UNICODE_STRINGs are defined here once. The idea is a
|
extern "C" {
|
||||||
speed improvement by not having to initialize a UNICODE_STRING every time
|
|
||||||
we make a string comparison. The strings are not defined as const,
|
/* Heavily-used const UNICODE_STRINGs are defined here once. The idea is a
|
||||||
because the respective NT functions are not taking const arguments
|
speed improvement by not having to initialize a UNICODE_STRING every time
|
||||||
and doing so here results in lots of extra casts for no good reason.
|
we make a string comparison. The _RDATA trick allows defining the strings
|
||||||
Rather, the strings are placed in the R/O section .rdata, so we get
|
as const (so we get a SEGV if some code erroneously tries to overwrite
|
||||||
a SEGV if some code erroneously tries to overwrite these strings. */
|
them), while declaring them as non-const in the auto-generated globals.h.
|
||||||
|
The strings are usually used in NT functions which don't take const
|
||||||
|
arguments. We avoid a lot of extra casts here...
|
||||||
|
Note: The "extern" is required, otherwise either the variables are dropped
|
||||||
|
entirely, or C++ name mangling is applied despite the extern "C"
|
||||||
|
bracket, depending on the compiler version */
|
||||||
|
#ifndef _RDATA
|
||||||
|
# define _RDATA const
|
||||||
|
#endif
|
||||||
|
|
||||||
#define _ROU(_s) \
|
#define _ROU(_s) \
|
||||||
{ Length: sizeof (_s) - sizeof (WCHAR), \
|
{ Length: sizeof (_s) - sizeof (WCHAR), \
|
||||||
MaximumLength: sizeof (_s), \
|
MaximumLength: sizeof (_s), \
|
||||||
Buffer: (PWSTR) (_s) }
|
Buffer: (PWSTR) (_s) }
|
||||||
UNICODE_STRING _RDATA ro_u_empty = _ROU (L"");
|
extern UNICODE_STRING _RDATA ro_u_empty = _ROU (L"");
|
||||||
UNICODE_STRING _RDATA ro_u_lnk = _ROU (L".lnk");
|
extern UNICODE_STRING _RDATA ro_u_lnk = _ROU (L".lnk");
|
||||||
UNICODE_STRING _RDATA ro_u_exe = _ROU (L".exe");
|
extern UNICODE_STRING _RDATA ro_u_exe = _ROU (L".exe");
|
||||||
UNICODE_STRING _RDATA ro_u_dll = _ROU (L".dll");
|
extern UNICODE_STRING _RDATA ro_u_dll = _ROU (L".dll");
|
||||||
UNICODE_STRING _RDATA ro_u_com = _ROU (L".com");
|
extern UNICODE_STRING _RDATA ro_u_com = _ROU (L".com");
|
||||||
UNICODE_STRING _RDATA ro_u_scr = _ROU (L".scr");
|
extern UNICODE_STRING _RDATA ro_u_scr = _ROU (L".scr");
|
||||||
UNICODE_STRING _RDATA ro_u_sys = _ROU (L".sys");
|
extern UNICODE_STRING _RDATA ro_u_sys = _ROU (L".sys");
|
||||||
UNICODE_STRING _RDATA ro_u_proc = _ROU (L"proc");
|
extern UNICODE_STRING _RDATA ro_u_proc = _ROU (L"proc");
|
||||||
UNICODE_STRING _RDATA ro_u_dev = _ROU (L"dev");
|
extern UNICODE_STRING _RDATA ro_u_dev = _ROU (L"dev");
|
||||||
UNICODE_STRING _RDATA ro_u_pmem = _ROU (L"\\Device\\PhysicalMemory");
|
extern UNICODE_STRING _RDATA ro_u_pmem = _ROU (L"\\Device\\PhysicalMemory");
|
||||||
UNICODE_STRING _RDATA ro_u_natp = _ROU (L"\\??\\");
|
extern UNICODE_STRING _RDATA ro_u_natp = _ROU (L"\\??\\");
|
||||||
UNICODE_STRING _RDATA ro_u_uncp = _ROU (L"\\??\\UNC\\");
|
extern UNICODE_STRING _RDATA ro_u_uncp = _ROU (L"\\??\\UNC\\");
|
||||||
UNICODE_STRING _RDATA ro_u_mtx = _ROU (L"mtx");
|
extern UNICODE_STRING _RDATA ro_u_mtx = _ROU (L"mtx");
|
||||||
UNICODE_STRING _RDATA ro_u_csc = _ROU (L"CSC-CACHE");
|
extern UNICODE_STRING _RDATA ro_u_csc = _ROU (L"CSC-CACHE");
|
||||||
UNICODE_STRING _RDATA ro_u_fat = _ROU (L"FAT");
|
extern UNICODE_STRING _RDATA ro_u_fat = _ROU (L"FAT");
|
||||||
UNICODE_STRING _RDATA ro_u_mvfs = _ROU (L"MVFS");
|
extern UNICODE_STRING _RDATA ro_u_mvfs = _ROU (L"MVFS");
|
||||||
UNICODE_STRING _RDATA ro_u_nfs = _ROU (L"NFS");
|
extern UNICODE_STRING _RDATA ro_u_nfs = _ROU (L"NFS");
|
||||||
UNICODE_STRING _RDATA ro_u_ntfs = _ROU (L"NTFS");
|
extern UNICODE_STRING _RDATA ro_u_ntfs = _ROU (L"NTFS");
|
||||||
UNICODE_STRING _RDATA ro_u_refs = _ROU (L"ReFS");
|
extern UNICODE_STRING _RDATA ro_u_refs = _ROU (L"ReFS");
|
||||||
UNICODE_STRING _RDATA ro_u_sunwnfs = _ROU (L"SUNWNFS");
|
extern UNICODE_STRING _RDATA ro_u_sunwnfs = _ROU (L"SUNWNFS");
|
||||||
UNICODE_STRING _RDATA ro_u_udf = _ROU (L"UDF");
|
extern UNICODE_STRING _RDATA ro_u_udf = _ROU (L"UDF");
|
||||||
UNICODE_STRING _RDATA ro_u_unixfs = _ROU (L"UNIXFS");
|
extern UNICODE_STRING _RDATA ro_u_unixfs = _ROU (L"UNIXFS");
|
||||||
UNICODE_STRING _RDATA ro_u_nwfs = _ROU (L"NWFS");
|
extern UNICODE_STRING _RDATA ro_u_nwfs = _ROU (L"NWFS");
|
||||||
UNICODE_STRING _RDATA ro_u_ncfsd = _ROU (L"NcFsd");
|
extern UNICODE_STRING _RDATA ro_u_ncfsd = _ROU (L"NcFsd");
|
||||||
UNICODE_STRING _RDATA ro_u_volume = _ROU (L"\\??\\Volume{");
|
extern UNICODE_STRING _RDATA ro_u_volume = _ROU (L"\\??\\Volume{");
|
||||||
UNICODE_STRING _RDATA ro_u_pipedir = _ROU (L"\\\\?\\PIPE\\");
|
extern UNICODE_STRING _RDATA ro_u_pipedir = _ROU (L"\\\\?\\PIPE\\");
|
||||||
UNICODE_STRING _RDATA ro_u_globalroot = _ROU (L"\\\\.\\GLOBALROOT");
|
extern UNICODE_STRING _RDATA ro_u_globalroot = _ROU (L"\\\\.\\GLOBALROOT");
|
||||||
#undef _ROU
|
#undef _ROU
|
||||||
|
|
||||||
/* Cygwin properties are meant to be readonly data placed in the DLL, but
|
/* Cygwin properties are meant to be readonly data placed in the DLL, but
|
||||||
which can be changed by external tools to make adjustments to the
|
which can be changed by external tools to make adjustments to the
|
||||||
behaviour of a DLL based on the binary of the DLL itself. This is
|
behaviour of a DLL based on the binary of the DLL itself. This is
|
||||||
different from $CYGWIN since it only affects that very DLL, not all
|
different from $CYGWIN since it only affects that very DLL, not all
|
||||||
DLLs which have access to the $CYGWIN environment variable. */
|
DLLs which have access to the $CYGWIN environment variable. We use the
|
||||||
cygwin_props_t _RDATA cygwin_props =
|
same _RDATA trick as for the above UNICODE_STRINGs. */
|
||||||
{
|
extern cygwin_props_t _RDATA cygwin_props =
|
||||||
CYGWIN_PROPS_MAGIC,
|
{
|
||||||
sizeof (cygwin_props_t),
|
CYGWIN_PROPS_MAGIC,
|
||||||
0
|
sizeof (cygwin_props_t),
|
||||||
};
|
0
|
||||||
|
};
|
||||||
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
/* This is an exported copy of environ which can be used by DLLs
|
/* This is an exported copy of environ which can be used by DLLs
|
||||||
which use cygwin.dll. */
|
which use cygwin.dll. */
|
||||||
char **__cygwin_environ;
|
char **__cygwin_environ;
|
||||||
|
#ifndef __x86_64__
|
||||||
char ***main_environ = &__cygwin_environ;
|
char ***main_environ = &__cygwin_environ;
|
||||||
|
#endif
|
||||||
/* __progname used in getopt error message */
|
/* __progname used in getopt error message */
|
||||||
char *__progname;
|
char *__progname;
|
||||||
char *program_invocation_name;
|
char *program_invocation_name;
|
||||||
@ -145,7 +157,10 @@ extern "C"
|
|||||||
{/* initial_sp */ 0, /* magic_biscuit */ 0,
|
{/* initial_sp */ 0, /* magic_biscuit */ 0,
|
||||||
/* dll_major */ CYGWIN_VERSION_DLL_MAJOR,
|
/* dll_major */ CYGWIN_VERSION_DLL_MAJOR,
|
||||||
/* dll_major */ CYGWIN_VERSION_DLL_MINOR,
|
/* dll_major */ CYGWIN_VERSION_DLL_MINOR,
|
||||||
/* impure_ptr_ptr */ NULL, /* envptr */ NULL,
|
/* impure_ptr_ptr */ NULL,
|
||||||
|
#ifndef __x86_64__
|
||||||
|
/* envptr */ NULL,
|
||||||
|
#endif
|
||||||
/* malloc */ malloc, /* free */ free,
|
/* malloc */ malloc, /* free */ free,
|
||||||
/* realloc */ realloc,
|
/* realloc */ realloc,
|
||||||
/* fmode_ptr */ NULL, /* main */ NULL, /* ctors */ NULL,
|
/* fmode_ptr */ NULL, /* main */ NULL, /* ctors */ NULL,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* grp.cc
|
/* grp.cc
|
||||||
|
|
||||||
Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
|
Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
|
||||||
2008, 2009, 2011, 2012 Red Hat, Inc.
|
2008, 2009, 2011, 2012, 2013 Red Hat, Inc.
|
||||||
|
|
||||||
Original stubs by Jason Molenda of Cygnus Support, crash@cygnus.com
|
Original stubs by Jason Molenda of Cygnus Support, crash@cygnus.com
|
||||||
First implementation by Gunther Ebert, gunther.ebert@ixos-leipzig.de
|
First implementation by Gunther Ebert, gunther.ebert@ixos-leipzig.de
|
||||||
@ -25,14 +25,14 @@ details. */
|
|||||||
#include "ntdll.h"
|
#include "ntdll.h"
|
||||||
#include "pwdgrp.h"
|
#include "pwdgrp.h"
|
||||||
|
|
||||||
static __group32 *group_buf;
|
static group *group_buf;
|
||||||
static pwdgrp gr (group_buf);
|
static pwdgrp gr (group_buf);
|
||||||
static char * NO_COPY null_ptr;
|
static char * NO_COPY_RO null_ptr;
|
||||||
|
|
||||||
bool
|
bool
|
||||||
pwdgrp::parse_group ()
|
pwdgrp::parse_group ()
|
||||||
{
|
{
|
||||||
__group32 &grp = (*group_buf)[curr_lines];
|
group &grp = (*group_buf)[curr_lines];
|
||||||
grp.gr_name = next_str (':');
|
grp.gr_name = next_str (':');
|
||||||
if (!*grp.gr_name)
|
if (!*grp.gr_name)
|
||||||
return false;
|
return false;
|
||||||
@ -81,15 +81,15 @@ pwdgrp::read_group ()
|
|||||||
static char linebuf [200];
|
static char linebuf [200];
|
||||||
char group_name [UNLEN + 1] = "mkgroup";
|
char group_name [UNLEN + 1] = "mkgroup";
|
||||||
char strbuf[128] = "";
|
char strbuf[128] = "";
|
||||||
struct __group32 *gr;
|
struct group *gr;
|
||||||
|
|
||||||
cygheap->user.groups.pgsid.string (strbuf);
|
cygheap->user.groups.pgsid.string (strbuf);
|
||||||
if ((gr = internal_getgrsid (cygheap->user.groups.pgsid)))
|
if ((gr = internal_getgrsid (cygheap->user.groups.pgsid)))
|
||||||
snprintf (group_name, sizeof (group_name),
|
snprintf (group_name, sizeof (group_name),
|
||||||
"passwd/group_GID_clash(%lu/%lu)", myself->gid, gr->gr_gid);
|
"passwd/group_GID_clash(%u/%u)", myself->gid, gr->gr_gid);
|
||||||
if (myself->uid == UNKNOWN_UID)
|
if (myself->uid == UNKNOWN_UID)
|
||||||
strcpy (group_name, "mkpasswd"); /* Feedback... */
|
strcpy (group_name, "mkpasswd"); /* Feedback... */
|
||||||
snprintf (linebuf, sizeof (linebuf), "%s:%s:%lu:%s",
|
snprintf (linebuf, sizeof (linebuf), "%s:%s:%u:%s",
|
||||||
group_name, strbuf, myself->gid, cygheap->user.name ());
|
group_name, strbuf, myself->gid, cygheap->user.name ());
|
||||||
debug_printf ("Completing /etc/group: %s", linebuf);
|
debug_printf ("Completing /etc/group: %s", linebuf);
|
||||||
add_line (linebuf);
|
add_line (linebuf);
|
||||||
@ -108,7 +108,7 @@ pwdgrp::pwdgrp (passwd *&pbuf) :
|
|||||||
pglock.init ("pglock");
|
pglock.init ("pglock");
|
||||||
}
|
}
|
||||||
|
|
||||||
pwdgrp::pwdgrp (__group32 *&gbuf) :
|
pwdgrp::pwdgrp (group *&gbuf) :
|
||||||
pwdgrp_buf_elem_size (sizeof (*gbuf)), group_buf (&gbuf)
|
pwdgrp_buf_elem_size (sizeof (*gbuf)), group_buf (&gbuf)
|
||||||
{
|
{
|
||||||
read = &pwdgrp::read_group;
|
read = &pwdgrp::read_group;
|
||||||
@ -116,7 +116,7 @@ pwdgrp::pwdgrp (__group32 *&gbuf) :
|
|||||||
pglock.init ("pglock");
|
pglock.init ("pglock");
|
||||||
}
|
}
|
||||||
|
|
||||||
struct __group32 *
|
struct group *
|
||||||
internal_getgrsid (cygpsid &sid)
|
internal_getgrsid (cygpsid &sid)
|
||||||
{
|
{
|
||||||
char sid_string[128];
|
char sid_string[128];
|
||||||
@ -130,8 +130,8 @@ internal_getgrsid (cygpsid &sid)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct __group32 *
|
struct group *
|
||||||
internal_getgrgid (__gid32_t gid, bool check)
|
internal_getgrgid (gid_t gid, bool check)
|
||||||
{
|
{
|
||||||
gr.refresh (check);
|
gr.refresh (check);
|
||||||
|
|
||||||
@ -141,7 +141,7 @@ internal_getgrgid (__gid32_t gid, bool check)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct __group32 *
|
struct group *
|
||||||
internal_getgrnam (const char *name, bool check)
|
internal_getgrnam (const char *name, bool check)
|
||||||
{
|
{
|
||||||
gr.refresh (check);
|
gr.refresh (check);
|
||||||
@ -154,8 +154,9 @@ internal_getgrnam (const char *name, bool check)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef __x86_64__
|
||||||
static struct __group16 *
|
static struct __group16 *
|
||||||
grp32togrp16 (struct __group16 *gp16, struct __group32 *gp32)
|
grp32togrp16 (struct __group16 *gp16, struct group *gp32)
|
||||||
{
|
{
|
||||||
if (!gp16 || !gp32)
|
if (!gp16 || !gp32)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -169,17 +170,18 @@ grp32togrp16 (struct __group16 *gp16, struct __group32 *gp32)
|
|||||||
|
|
||||||
return gp16;
|
return gp16;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
extern "C" int
|
extern "C" int
|
||||||
getgrgid_r (__gid32_t gid, struct __group32 *grp, char *buffer, size_t bufsize,
|
getgrgid_r (gid_t gid, struct group *grp, char *buffer, size_t bufsize,
|
||||||
struct __group32 **result)
|
struct group **result)
|
||||||
{
|
{
|
||||||
*result = NULL;
|
*result = NULL;
|
||||||
|
|
||||||
if (!grp || !buffer)
|
if (!grp || !buffer)
|
||||||
return ERANGE;
|
return ERANGE;
|
||||||
|
|
||||||
struct __group32 *tempgr = internal_getgrgid (gid, true);
|
struct group *tempgr = internal_getgrgid (gid, true);
|
||||||
pthread_testcancel ();
|
pthread_testcancel ();
|
||||||
if (!tempgr)
|
if (!tempgr)
|
||||||
return 0;
|
return 0;
|
||||||
@ -206,12 +208,15 @@ getgrgid_r (__gid32_t gid, struct __group32 *grp, char *buffer, size_t bufsize,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" struct __group32 *
|
extern "C" struct group *
|
||||||
getgrgid32 (__gid32_t gid)
|
getgrgid32 (gid_t gid)
|
||||||
{
|
{
|
||||||
return internal_getgrgid (gid, true);
|
return internal_getgrgid (gid, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __x86_64__
|
||||||
|
EXPORT_ALIAS (getgrgid32, getgrgid)
|
||||||
|
#else
|
||||||
extern "C" struct __group16 *
|
extern "C" struct __group16 *
|
||||||
getgrgid (__gid16_t gid)
|
getgrgid (__gid16_t gid)
|
||||||
{
|
{
|
||||||
@ -219,17 +224,18 @@ getgrgid (__gid16_t gid)
|
|||||||
|
|
||||||
return grp32togrp16 (&g16, getgrgid32 (gid16togid32 (gid)));
|
return grp32togrp16 (&g16, getgrgid32 (gid16togid32 (gid)));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
extern "C" int
|
extern "C" int
|
||||||
getgrnam_r (const char *nam, struct __group32 *grp, char *buffer,
|
getgrnam_r (const char *nam, struct group *grp, char *buffer,
|
||||||
size_t bufsize, struct __group32 **result)
|
size_t bufsize, struct group **result)
|
||||||
{
|
{
|
||||||
*result = NULL;
|
*result = NULL;
|
||||||
|
|
||||||
if (!grp || !buffer)
|
if (!grp || !buffer)
|
||||||
return ERANGE;
|
return ERANGE;
|
||||||
|
|
||||||
struct __group32 *tempgr = internal_getgrnam (nam, true);
|
struct group *tempgr = internal_getgrnam (nam, true);
|
||||||
pthread_testcancel ();
|
pthread_testcancel ();
|
||||||
if (!tempgr)
|
if (!tempgr)
|
||||||
return 0;
|
return 0;
|
||||||
@ -256,12 +262,15 @@ getgrnam_r (const char *nam, struct __group32 *grp, char *buffer,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" struct __group32 *
|
extern "C" struct group *
|
||||||
getgrnam32 (const char *name)
|
getgrnam32 (const char *name)
|
||||||
{
|
{
|
||||||
return internal_getgrnam (name, true);
|
return internal_getgrnam (name, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __x86_64__
|
||||||
|
EXPORT_ALIAS (getgrnam32, getgrnam)
|
||||||
|
#else
|
||||||
extern "C" struct __group16 *
|
extern "C" struct __group16 *
|
||||||
getgrnam (const char *name)
|
getgrnam (const char *name)
|
||||||
{
|
{
|
||||||
@ -269,6 +278,7 @@ getgrnam (const char *name)
|
|||||||
|
|
||||||
return grp32togrp16 (&g16, getgrnam32 (name));
|
return grp32togrp16 (&g16, getgrnam32 (name));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
extern "C" void
|
extern "C" void
|
||||||
endgrent ()
|
endgrent ()
|
||||||
@ -276,7 +286,7 @@ endgrent ()
|
|||||||
_my_tls.locals.grp_pos = 0;
|
_my_tls.locals.grp_pos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" struct __group32 *
|
extern "C" struct group *
|
||||||
getgrent32 ()
|
getgrent32 ()
|
||||||
{
|
{
|
||||||
if (_my_tls.locals.grp_pos == 0)
|
if (_my_tls.locals.grp_pos == 0)
|
||||||
@ -287,6 +297,9 @@ getgrent32 ()
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __x86_64__
|
||||||
|
EXPORT_ALIAS (getgrent32, getgrent)
|
||||||
|
#else
|
||||||
extern "C" struct __group16 *
|
extern "C" struct __group16 *
|
||||||
getgrent ()
|
getgrent ()
|
||||||
{
|
{
|
||||||
@ -294,6 +307,7 @@ getgrent ()
|
|||||||
|
|
||||||
return grp32togrp16 (&g16, getgrent32 ());
|
return grp32togrp16 (&g16, getgrent32 ());
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
extern "C" void
|
extern "C" void
|
||||||
setgrent ()
|
setgrent ()
|
||||||
@ -302,7 +316,7 @@ setgrent ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Internal function. ONLY USE THIS INTERNALLY, NEVER `getgrent'!!! */
|
/* Internal function. ONLY USE THIS INTERNALLY, NEVER `getgrent'!!! */
|
||||||
struct __group32 *
|
struct group *
|
||||||
internal_getgrent (int pos)
|
internal_getgrent (int pos)
|
||||||
{
|
{
|
||||||
gr.refresh (false);
|
gr.refresh (false);
|
||||||
@ -313,13 +327,13 @@ internal_getgrent (int pos)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
internal_getgroups (int gidsetsize, __gid32_t *grouplist, cygpsid * srchsid)
|
internal_getgroups (int gidsetsize, gid_t *grouplist, cygpsid * srchsid)
|
||||||
{
|
{
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
HANDLE hToken = NULL;
|
HANDLE hToken = NULL;
|
||||||
ULONG size;
|
ULONG size;
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
struct __group32 *gr;
|
struct group *gr;
|
||||||
|
|
||||||
if (!srchsid && cygheap->user.groups.issetgroups ())
|
if (!srchsid && cygheap->user.groups.issetgroups ())
|
||||||
{
|
{
|
||||||
@ -383,7 +397,7 @@ internal_getgroups (int gidsetsize, __gid32_t *grouplist, cygpsid * srchsid)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
debug_printf ("%lu = NtQueryInformationToken(NULL) %p", size, status);
|
debug_printf ("%u = NtQueryInformationToken(NULL) %y", size, status);
|
||||||
return cnt;
|
return cnt;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
@ -392,15 +406,18 @@ error:
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int
|
extern "C" int
|
||||||
getgroups32 (int gidsetsize, __gid32_t *grouplist)
|
getgroups32 (int gidsetsize, gid_t *grouplist)
|
||||||
{
|
{
|
||||||
return internal_getgroups (gidsetsize, grouplist);
|
return internal_getgroups (gidsetsize, grouplist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __x86_64__
|
||||||
|
EXPORT_ALIAS (getgroups32, getgroups)
|
||||||
|
#else
|
||||||
extern "C" int
|
extern "C" int
|
||||||
getgroups (int gidsetsize, __gid16_t *grouplist)
|
getgroups (int gidsetsize, __gid16_t *grouplist)
|
||||||
{
|
{
|
||||||
__gid32_t *grouplist32 = NULL;
|
gid_t *grouplist32 = NULL;
|
||||||
|
|
||||||
if (gidsetsize < 0)
|
if (gidsetsize < 0)
|
||||||
{
|
{
|
||||||
@ -408,7 +425,7 @@ getgroups (int gidsetsize, __gid16_t *grouplist)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (gidsetsize > 0 && grouplist)
|
if (gidsetsize > 0 && grouplist)
|
||||||
grouplist32 = (__gid32_t *) alloca (gidsetsize * sizeof (__gid32_t));
|
grouplist32 = (gid_t *) alloca (gidsetsize * sizeof (gid_t));
|
||||||
|
|
||||||
int ret = internal_getgroups (gidsetsize, grouplist32);
|
int ret = internal_getgroups (gidsetsize, grouplist32);
|
||||||
|
|
||||||
@ -418,6 +435,7 @@ getgroups (int gidsetsize, __gid16_t *grouplist)
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Core functionality of initgroups and getgrouplist. */
|
/* Core functionality of initgroups and getgrouplist. */
|
||||||
static int
|
static int
|
||||||
@ -427,7 +445,7 @@ get_groups (const char *user, gid_t gid, cygsidlist &gsids)
|
|||||||
|
|
||||||
cygheap->user.deimpersonate ();
|
cygheap->user.deimpersonate ();
|
||||||
struct passwd *pw = internal_getpwnam (user);
|
struct passwd *pw = internal_getpwnam (user);
|
||||||
struct __group32 *gr = internal_getgrgid (gid);
|
struct group *gr = internal_getgrgid (gid);
|
||||||
cygsid usersid, grpsid;
|
cygsid usersid, grpsid;
|
||||||
if (!usersid.getfrompw (pw) || !grpsid.getfromgr (gr))
|
if (!usersid.getfrompw (pw) || !grpsid.getfromgr (gr))
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
@ -441,7 +459,7 @@ get_groups (const char *user, gid_t gid, cygsidlist &gsids)
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int
|
extern "C" int
|
||||||
initgroups32 (const char *user, __gid32_t gid)
|
initgroups32 (const char *user, gid_t gid)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -459,11 +477,15 @@ initgroups32 (const char *user, __gid32_t gid)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __x86_64__
|
||||||
|
EXPORT_ALIAS (initgroups32, initgroups)
|
||||||
|
#else
|
||||||
extern "C" int
|
extern "C" int
|
||||||
initgroups (const char *user, __gid16_t gid)
|
initgroups (const char *user, __gid16_t gid)
|
||||||
{
|
{
|
||||||
return initgroups32 (user, gid16togid32(gid));
|
return initgroups32 (user, gid16togid32(gid));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
extern "C" int
|
extern "C" int
|
||||||
getgrouplist (const char *user, gid_t gid, gid_t *groups, int *ngroups)
|
getgrouplist (const char *user, gid_t gid, gid_t *groups, int *ngroups)
|
||||||
@ -484,7 +506,7 @@ getgrouplist (const char *user, gid_t gid, gid_t *groups, int *ngroups)
|
|||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
for (int i = 0; i < tmp_gsids.count (); i++)
|
for (int i = 0; i < tmp_gsids.count (); i++)
|
||||||
{
|
{
|
||||||
struct __group32 *gr = internal_getgrsid (tmp_gsids.sids[i]);
|
struct group *gr = internal_getgrsid (tmp_gsids.sids[i]);
|
||||||
if (gr)
|
if (gr)
|
||||||
{
|
{
|
||||||
if (groups && cnt < *ngroups)
|
if (groups && cnt < *ngroups)
|
||||||
@ -503,7 +525,7 @@ getgrouplist (const char *user, gid_t gid, gid_t *groups, int *ngroups)
|
|||||||
|
|
||||||
/* setgroups32: standards? */
|
/* setgroups32: standards? */
|
||||||
extern "C" int
|
extern "C" int
|
||||||
setgroups32 (int ngroups, const __gid32_t *grouplist)
|
setgroups32 (int ngroups, const gid_t *grouplist)
|
||||||
{
|
{
|
||||||
syscall_printf ("setgroups32 (%d)", ngroups);
|
syscall_printf ("setgroups32 (%d)", ngroups);
|
||||||
if (ngroups < 0 || (ngroups > 0 && !grouplist))
|
if (ngroups < 0 || (ngroups > 0 && !grouplist))
|
||||||
@ -513,7 +535,7 @@ setgroups32 (int ngroups, const __gid32_t *grouplist)
|
|||||||
}
|
}
|
||||||
|
|
||||||
cygsidlist gsids (cygsidlist_alloc, ngroups);
|
cygsidlist gsids (cygsidlist_alloc, ngroups);
|
||||||
struct __group32 *gr;
|
struct group *gr;
|
||||||
|
|
||||||
if (ngroups && !gsids.sids)
|
if (ngroups && !gsids.sids)
|
||||||
return -1;
|
return -1;
|
||||||
@ -523,7 +545,7 @@ setgroups32 (int ngroups, const __gid32_t *grouplist)
|
|||||||
if ((gr = internal_getgrgid (grouplist[gidx]))
|
if ((gr = internal_getgrgid (grouplist[gidx]))
|
||||||
&& gsids.addfromgr (gr))
|
&& gsids.addfromgr (gr))
|
||||||
continue;
|
continue;
|
||||||
debug_printf ("No sid found for gid %d", grouplist[gidx]);
|
debug_printf ("No sid found for gid %u", grouplist[gidx]);
|
||||||
gsids.free_sids ();
|
gsids.free_sids ();
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return -1;
|
return -1;
|
||||||
@ -532,14 +554,17 @@ setgroups32 (int ngroups, const __gid32_t *grouplist)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __x86_64__
|
||||||
|
EXPORT_ALIAS (setgroups32, setgroups)
|
||||||
|
#else
|
||||||
extern "C" int
|
extern "C" int
|
||||||
setgroups (int ngroups, const __gid16_t *grouplist)
|
setgroups (int ngroups, const __gid16_t *grouplist)
|
||||||
{
|
{
|
||||||
__gid32_t *grouplist32 = NULL;
|
gid_t *grouplist32 = NULL;
|
||||||
|
|
||||||
if (ngroups > 0 && grouplist)
|
if (ngroups > 0 && grouplist)
|
||||||
{
|
{
|
||||||
grouplist32 = (__gid32_t *) alloca (ngroups * sizeof (__gid32_t));
|
grouplist32 = (gid_t *) alloca (ngroups * sizeof (gid_t));
|
||||||
if (grouplist32 == NULL)
|
if (grouplist32 == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
for (int i = 0; i < ngroups; i++)
|
for (int i = 0; i < ngroups; i++)
|
||||||
@ -547,3 +572,4 @@ setgroups (int ngroups, const __gid16_t *grouplist)
|
|||||||
}
|
}
|
||||||
return setgroups32 (ngroups, grouplist32);
|
return setgroups32 (ngroups, grouplist32);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* heap.cc: Cygwin heap manager.
|
/* heap.cc: Cygwin heap manager.
|
||||||
|
|
||||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
||||||
2007, 2008, 2009, 2010, 2011, 2012 Red Hat, Inc.
|
2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -22,13 +22,22 @@ details. */
|
|||||||
|
|
||||||
#define assert(x)
|
#define assert(x)
|
||||||
|
|
||||||
static unsigned page_const;
|
static ptrdiff_t page_const;
|
||||||
|
|
||||||
#define MINHEAP_SIZE (4 * 1024 * 1024)
|
#define MINHEAP_SIZE (4 * 1024 * 1024)
|
||||||
|
|
||||||
static uintptr_t
|
static uintptr_t
|
||||||
eval_start_address ()
|
eval_start_address ()
|
||||||
{
|
{
|
||||||
|
#ifdef __x86_64__
|
||||||
|
/* On 64 bit, we choose a fixed address outside the 32 bit area. The
|
||||||
|
executable starts at 0x1:00400000L, the Cygwin DLL starts at
|
||||||
|
0x1:80040000L, other rebased DLLs are located in the region from
|
||||||
|
0x2:00000000L up to 0x4:00000000L, -auto-image-based DLLs are located
|
||||||
|
in the region from 0x4:00000000L up to 0x6:00000000L.
|
||||||
|
So we let the heap start at 0x6:00000000L. */
|
||||||
|
uintptr_t start_address = 0x600000000L;
|
||||||
|
#else
|
||||||
/* Starting with Vista, Windows performs heap ASLR. This spoils the entire
|
/* Starting with Vista, Windows performs heap ASLR. This spoils the entire
|
||||||
region below 0x20000000 for us, because that region is used by Windows
|
region below 0x20000000 for us, because that region is used by Windows
|
||||||
to randomize heap and stack addresses. Therefore we put our heap into a
|
to randomize heap and stack addresses. Therefore we put our heap into a
|
||||||
@ -53,30 +62,41 @@ eval_start_address ()
|
|||||||
memory for heap, thread stacks, and shared memory regions. */
|
memory for heap, thread stacks, and shared memory regions. */
|
||||||
start_address = 0x80000000L;
|
start_address = 0x80000000L;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return start_address;
|
return start_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned
|
static SIZE_T
|
||||||
eval_initial_heap_size ()
|
eval_initial_heap_size ()
|
||||||
{
|
{
|
||||||
PIMAGE_DOS_HEADER dosheader;
|
PIMAGE_DOS_HEADER dosheader;
|
||||||
PIMAGE_NT_HEADERS32 ntheader;
|
PIMAGE_NT_HEADERS ntheader;
|
||||||
unsigned size;
|
SIZE_T size;
|
||||||
|
|
||||||
dosheader = (PIMAGE_DOS_HEADER) GetModuleHandle (NULL);
|
dosheader = (PIMAGE_DOS_HEADER) GetModuleHandle (NULL);
|
||||||
ntheader = (PIMAGE_NT_HEADERS32) ((PBYTE) dosheader + dosheader->e_lfanew);
|
ntheader = (PIMAGE_NT_HEADERS) ((PBYTE) dosheader + dosheader->e_lfanew);
|
||||||
/* LoaderFlags is an obsolete DWORD member of the PE/COFF file header.
|
/* LoaderFlags is an obsolete DWORD member of the PE/COFF file header.
|
||||||
It's value is ignored by the loader, so we're free to use it for
|
It's value is ignored by the loader, so we're free to use it for
|
||||||
Cygwin. If it's 0, we default to the usual 384 Megs. Otherwise,
|
Cygwin. If it's 0, we default to the usual 384 Megs on 32 bit and
|
||||||
we use it as the default initial heap size in megabyte. Valid values
|
512 on 64 bit. Otherwise, we use it as the default initial heap size
|
||||||
are between 4 and 2048 Megs. */
|
in megabyte. Valid values are between 4 and 2048/8388608 Megs. */
|
||||||
|
|
||||||
size = ntheader->OptionalHeader.LoaderFlags;
|
size = ntheader->OptionalHeader.LoaderFlags;
|
||||||
|
#ifdef __x86_64__
|
||||||
|
if (size == 0)
|
||||||
|
size = 512;
|
||||||
|
else if (size < 4)
|
||||||
|
size = 4;
|
||||||
|
else if (size > 8388608)
|
||||||
|
size = 8388608;
|
||||||
|
#else
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
size = 384;
|
size = 384;
|
||||||
else if (size < 4)
|
else if (size < 4)
|
||||||
size = 4;
|
size = 4;
|
||||||
else if (size > 2048)
|
else if (size > 2048)
|
||||||
size = 2048;
|
size = 2048;
|
||||||
|
#endif
|
||||||
return size << 20;
|
return size << 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,7 +113,7 @@ heap_init ()
|
|||||||
{
|
{
|
||||||
uintptr_t start_address = eval_start_address ();
|
uintptr_t start_address = eval_start_address ();
|
||||||
PVOID largest_found = NULL;
|
PVOID largest_found = NULL;
|
||||||
size_t largest_found_size = 0;
|
SIZE_T largest_found_size = 0;
|
||||||
SIZE_T ret;
|
SIZE_T ret;
|
||||||
MEMORY_BASIC_INFORMATION mbi;
|
MEMORY_BASIC_INFORMATION mbi;
|
||||||
|
|
||||||
@ -156,7 +176,7 @@ heap_init ()
|
|||||||
}
|
}
|
||||||
while (!cygheap->user_heap.base && ret);
|
while (!cygheap->user_heap.base && ret);
|
||||||
if (cygheap->user_heap.base == NULL)
|
if (cygheap->user_heap.base == NULL)
|
||||||
api_fatal ("unable to allocate heap, heap_chunk_size %p, %E",
|
api_fatal ("unable to allocate heap, heap_chunk_size %ly, %E",
|
||||||
cygheap->user_heap.chunk);
|
cygheap->user_heap.chunk);
|
||||||
cygheap->user_heap.ptr = cygheap->user_heap.top = cygheap->user_heap.base;
|
cygheap->user_heap.ptr = cygheap->user_heap.top = cygheap->user_heap.base;
|
||||||
cygheap->user_heap.max = (char *) cygheap->user_heap.base
|
cygheap->user_heap.max = (char *) cygheap->user_heap.base
|
||||||
@ -164,14 +184,21 @@ heap_init ()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DWORD chunk = cygheap->user_heap.chunk; /* allocation chunk */
|
SIZE_T chunk = cygheap->user_heap.chunk; /* allocation chunk */
|
||||||
/* total size commited in parent */
|
/* total size commited in parent */
|
||||||
DWORD allocsize = (char *) cygheap->user_heap.top -
|
SIZE_T allocsize = (char *) cygheap->user_heap.top -
|
||||||
(char *) cygheap->user_heap.base;
|
(char *) cygheap->user_heap.base;
|
||||||
|
|
||||||
/* Loop until we've managed to reserve an adequate amount of memory. */
|
/* Loop until we've managed to reserve an adequate amount of memory. */
|
||||||
char *p;
|
char *p;
|
||||||
DWORD reserve_size = chunk * ((allocsize + (chunk - 1)) / chunk);
|
SIZE_T reserve_size = chunk * ((allocsize + (chunk - 1)) / chunk);
|
||||||
|
/* With ptmalloc3 there's a good chance that there has been no memory
|
||||||
|
allocated on the heap. If we don't check that, reserve_size will
|
||||||
|
be 0 and from there, the below loop will end up overallocating due
|
||||||
|
to integer overflow. */
|
||||||
|
if (!reserve_size)
|
||||||
|
reserve_size = chunk;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
p = (char *) VirtualAlloc (cygheap->user_heap.base, reserve_size,
|
p = (char *) VirtualAlloc (cygheap->user_heap.base, reserve_size,
|
||||||
@ -183,12 +210,14 @@ heap_init ()
|
|||||||
}
|
}
|
||||||
if (!p && in_forkee && !fork_info->abort (NULL))
|
if (!p && in_forkee && !fork_info->abort (NULL))
|
||||||
api_fatal ("couldn't allocate heap, %E, base %p, top %p, "
|
api_fatal ("couldn't allocate heap, %E, base %p, top %p, "
|
||||||
"reserve_size %d, allocsize %d, page_const %d",
|
"reserve_size %ld, allocsize %ld, page_const %d",
|
||||||
cygheap->user_heap.base, cygheap->user_heap.top,
|
cygheap->user_heap.base, cygheap->user_heap.top,
|
||||||
reserve_size, allocsize, page_const);
|
reserve_size, allocsize, page_const);
|
||||||
if (p != cygheap->user_heap.base)
|
if (p != cygheap->user_heap.base)
|
||||||
api_fatal ("heap allocated at wrong address %p (mapped) != %p (expected)", p, cygheap->user_heap.base);
|
api_fatal ("heap allocated at wrong address %p (mapped) "
|
||||||
if (allocsize && !VirtualAlloc (cygheap->user_heap.base, allocsize, MEM_COMMIT, PAGE_READWRITE))
|
"!= %p (expected)", p, cygheap->user_heap.base);
|
||||||
|
if (allocsize && !VirtualAlloc (cygheap->user_heap.base, allocsize,
|
||||||
|
MEM_COMMIT, PAGE_READWRITE))
|
||||||
api_fatal ("MEM_COMMIT failed, %E");
|
api_fatal ("MEM_COMMIT failed, %E");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,7 +227,7 @@ heap_init ()
|
|||||||
size has not been evaluated yet, except in a forked child. Since
|
size has not been evaluated yet, except in a forked child. Since
|
||||||
heap_init is called early, the heap size is printed pretty much at the
|
heap_init is called early, the heap size is printed pretty much at the
|
||||||
start of the strace output, so there isn't anything lost. */
|
start of the strace output, so there isn't anything lost. */
|
||||||
debug_printf ("heap base %p, heap top %p, heap size %p (%u)",
|
debug_printf ("heap base %p, heap top %p, heap size %ly (%lu)",
|
||||||
cygheap->user_heap.base, cygheap->user_heap.top,
|
cygheap->user_heap.base, cygheap->user_heap.top,
|
||||||
cygheap->user_heap.chunk, cygheap->user_heap.chunk);
|
cygheap->user_heap.chunk, cygheap->user_heap.chunk);
|
||||||
page_const--;
|
page_const--;
|
||||||
@ -209,11 +238,14 @@ heap_init ()
|
|||||||
|
|
||||||
/* FIXME: This function no longer handles "split heaps". */
|
/* FIXME: This function no longer handles "split heaps". */
|
||||||
|
|
||||||
|
/* Linux defines n to be intptr_t, newlib defines it to be ptrdiff_t.
|
||||||
|
It shouldn't matter much, though, since the function is not standarized
|
||||||
|
and sizeof(ptrdiff_t) == sizeof(intptr_t) anyway. */
|
||||||
extern "C" void *
|
extern "C" void *
|
||||||
sbrk (int n)
|
sbrk (ptrdiff_t n)
|
||||||
{
|
{
|
||||||
char *newtop, *newbrk;
|
char *newtop, *newbrk;
|
||||||
unsigned commitbytes, newbrksize;
|
SIZE_T commitbytes, newbrksize;
|
||||||
|
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
return cygheap->user_heap.ptr; /* Just wanted to find current cygheap->user_heap.ptr address */
|
return cygheap->user_heap.ptr; /* Just wanted to find current cygheap->user_heap.ptr address */
|
||||||
@ -230,9 +262,8 @@ sbrk (int n)
|
|||||||
assert (newtop < cygheap->user_heap.top);
|
assert (newtop < cygheap->user_heap.top);
|
||||||
n = (char *) cygheap->user_heap.top - newtop;
|
n = (char *) cygheap->user_heap.top - newtop;
|
||||||
if (VirtualFree (newtop, n, MEM_DECOMMIT)) /* Give it back to OS */
|
if (VirtualFree (newtop, n, MEM_DECOMMIT)) /* Give it back to OS */
|
||||||
goto good; /* Didn't take */
|
goto good;
|
||||||
else
|
goto err; /* Didn't take */
|
||||||
goto err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assert (newtop > cygheap->user_heap.top);
|
assert (newtop > cygheap->user_heap.top);
|
||||||
@ -256,11 +287,15 @@ sbrk (int n)
|
|||||||
if ((newbrksize = cygheap->user_heap.chunk) < commitbytes)
|
if ((newbrksize = cygheap->user_heap.chunk) < commitbytes)
|
||||||
newbrksize = commitbytes;
|
newbrksize = commitbytes;
|
||||||
|
|
||||||
if ((VirtualAlloc (cygheap->user_heap.top, newbrksize, MEM_RESERVE, PAGE_NOACCESS)
|
if ((VirtualAlloc (cygheap->user_heap.top, newbrksize,
|
||||||
|| VirtualAlloc (cygheap->user_heap.top, newbrksize = commitbytes, MEM_RESERVE, PAGE_NOACCESS))
|
MEM_RESERVE, PAGE_NOACCESS)
|
||||||
&& VirtualAlloc (cygheap->user_heap.top, commitbytes, MEM_COMMIT, PAGE_READWRITE) != NULL)
|
|| VirtualAlloc (cygheap->user_heap.top, newbrksize = commitbytes,
|
||||||
|
MEM_RESERVE, PAGE_NOACCESS))
|
||||||
|
&& VirtualAlloc (cygheap->user_heap.top, commitbytes,
|
||||||
|
MEM_COMMIT, PAGE_READWRITE) != NULL)
|
||||||
{
|
{
|
||||||
cygheap->user_heap.max = (char *) cygheap->user_heap.max + pround (newbrksize);
|
cygheap->user_heap.max = (char *) cygheap->user_heap.max
|
||||||
|
+ pround (newbrksize);
|
||||||
goto good;
|
goto good;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* hookapi.cc
|
/* hookapi.cc
|
||||||
|
|
||||||
Copyright 2005, 2006, 2007, 2008, 2011, 2012 Red Hat, Inc.
|
Copyright 2005, 2006, 2007, 2008, 2011, 2012, 2013 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -29,13 +29,13 @@ struct function_hook
|
|||||||
void *origfn; // Stored by HookAPICalls, the address of the original function.
|
void *origfn; // Stored by HookAPICalls, the address of the original function.
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Given an HMODULE, returns a pointer to the PE header */
|
/* Given an HMODULE, returns a pointer to the PE header. */
|
||||||
static PIMAGE_NT_HEADERS
|
static PIMAGE_NT_HEADERS
|
||||||
PEHeaderFromHModule (HMODULE hModule)
|
PEHeaderFromHModule (HMODULE hModule, bool &is_64bit)
|
||||||
{
|
{
|
||||||
PIMAGE_NT_HEADERS pNTHeader;
|
PIMAGE_NT_HEADERS pNTHeader;
|
||||||
|
|
||||||
if (PIMAGE_DOS_HEADER(hModule) ->e_magic != IMAGE_DOS_SIGNATURE)
|
if (PIMAGE_DOS_HEADER (hModule) ->e_magic != IMAGE_DOS_SIGNATURE)
|
||||||
pNTHeader = NULL;
|
pNTHeader = NULL;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -43,6 +43,12 @@ PEHeaderFromHModule (HMODULE hModule)
|
|||||||
+ PIMAGE_DOS_HEADER (hModule) ->e_lfanew);
|
+ PIMAGE_DOS_HEADER (hModule) ->e_lfanew);
|
||||||
if (pNTHeader->Signature != IMAGE_NT_SIGNATURE)
|
if (pNTHeader->Signature != IMAGE_NT_SIGNATURE)
|
||||||
pNTHeader = NULL;
|
pNTHeader = NULL;
|
||||||
|
else if (pNTHeader->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64)
|
||||||
|
is_64bit = true;
|
||||||
|
else if (pNTHeader->FileHeader.Machine == IMAGE_FILE_MACHINE_I386)
|
||||||
|
is_64bit = false;
|
||||||
|
else
|
||||||
|
pNTHeader = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pNTHeader;
|
return pNTHeader;
|
||||||
@ -55,7 +61,6 @@ rvadelta (PIMAGE_NT_HEADERS pnt, DWORD import_rva, DWORD &max_size)
|
|||||||
for (int i = 0; i < pnt->FileHeader.NumberOfSections; i++)
|
for (int i = 0; i < pnt->FileHeader.NumberOfSections; i++)
|
||||||
if (section[i].VirtualAddress <= import_rva
|
if (section[i].VirtualAddress <= import_rva
|
||||||
&& (section[i].VirtualAddress + section[i].Misc.VirtualSize) > import_rva)
|
&& (section[i].VirtualAddress + section[i].Misc.VirtualSize) > import_rva)
|
||||||
// if (ascii_strncasematch ((char *) section[i].Name, ".idata", IMAGE_SIZEOF_SHORT_NAME))
|
|
||||||
{
|
{
|
||||||
max_size = section[i].SizeOfRawData
|
max_size = section[i].SizeOfRawData
|
||||||
- (import_rva - section[i].VirtualAddress);
|
- (import_rva - section[i].VirtualAddress);
|
||||||
@ -64,21 +69,30 @@ rvadelta (PIMAGE_NT_HEADERS pnt, DWORD import_rva, DWORD &max_size)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This function is only used for the current architecture.
|
||||||
|
Just the size of the IMAGE_THUNK_DATA Function member differs. */
|
||||||
static void *
|
static void *
|
||||||
putmem (PIMAGE_THUNK_DATA pi, const void *hookfn)
|
putmem (PIMAGE_THUNK_DATA pi, const void *hookfn)
|
||||||
{
|
{
|
||||||
|
#ifdef __x86_64__
|
||||||
|
#define THUNK_FUNC_TYPE ULONGLONG
|
||||||
|
#else
|
||||||
|
#define THUNK_FUNC_TYPE DWORD
|
||||||
|
#endif
|
||||||
|
|
||||||
DWORD ofl;
|
DWORD ofl;
|
||||||
if (!VirtualProtect (pi, sizeof (PVOID), PAGE_READWRITE, &ofl) )
|
if (!VirtualProtect (pi, sizeof (THUNK_FUNC_TYPE), PAGE_READWRITE, &ofl) )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
void *origfn = (void *) pi->u1.Function;
|
void *origfn = (void *) pi->u1.Function;
|
||||||
pi->u1.Function = (DWORD) hookfn;
|
pi->u1.Function = (THUNK_FUNC_TYPE) hookfn;
|
||||||
|
|
||||||
VirtualProtect (pi, sizeof (PVOID), ofl, &ofl);
|
VirtualProtect (pi, sizeof (THUNK_FUNC_TYPE), ofl, &ofl);
|
||||||
return origfn;
|
return origfn;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Builds stubs for and redirects the IAT for one DLL (pImportDesc) */
|
/* Builds stubs for and redirects the IAT for one DLL (pImportDesc)
|
||||||
|
This function is only used for the current architecture. */
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
RedirectIAT (function_hook& fh, PIMAGE_IMPORT_DESCRIPTOR pImportDesc,
|
RedirectIAT (function_hook& fh, PIMAGE_IMPORT_DESCRIPTOR pImportDesc,
|
||||||
@ -122,6 +136,7 @@ RedirectIAT (function_hook& fh, PIMAGE_IMPORT_DESCRIPTOR pImportDesc,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This function is only used for the current architecture. */
|
||||||
static void
|
static void
|
||||||
get_export (function_hook& fh)
|
get_export (function_hook& fh)
|
||||||
{
|
{
|
||||||
@ -162,6 +177,59 @@ makename (const char *name, char *&buf, int& i, int inc)
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HMODULE
|
||||||
|
remap (PIMAGE_IMPORT_DESCRIPTOR &pdfirst, long &delta, HANDLE hc,
|
||||||
|
DWORD importRVA, DWORD importRVASize, DWORD importRVAMaxSize)
|
||||||
|
{
|
||||||
|
/* If h is not NULL, the calling function only mapped at most the first
|
||||||
|
64K of the image. The IAT is usually at the end of the image, so
|
||||||
|
what we do here is to map the IAT into our address space if it doesn't
|
||||||
|
reside in the first 64K anyway. The offset must be a multiple of the
|
||||||
|
allocation granularity, though, so we have to map a bit more. */
|
||||||
|
HMODULE map;
|
||||||
|
DWORD offset = rounddown (importRVA, wincap.allocation_granularity ());
|
||||||
|
/* But that's not all, unfortunately. Apparently there's a difference
|
||||||
|
between the importRVASize of applications built with gcc and those
|
||||||
|
built with Visual Studio. When built with gcc, importRVASize contains
|
||||||
|
the size of the import RVA table plus the size of the referenced
|
||||||
|
string table with the DLL names. When built with VS, it only contains
|
||||||
|
the size of the naked import RVA table. The following code handles
|
||||||
|
the situation. importRVAMaxSize contains the size of the remainder
|
||||||
|
of the section. If the difference between importRVAMaxSize and
|
||||||
|
importRVASize is less than 64K, we just use importRVAMaxSize to
|
||||||
|
compute the size of the memory map. Otherwise the executable may be
|
||||||
|
very big. In that case we only map the import RVA table and ... */
|
||||||
|
DWORD size = importRVA - offset + ((importRVAMaxSize - importRVASize
|
||||||
|
<= wincap.allocation_granularity ())
|
||||||
|
? importRVAMaxSize : importRVASize);
|
||||||
|
map = (HMODULE) MapViewOfFile (hc, FILE_MAP_READ, 0, offset, size);
|
||||||
|
if (!map)
|
||||||
|
return NULL;
|
||||||
|
pdfirst = rva (PIMAGE_IMPORT_DESCRIPTOR, map, importRVA - offset);
|
||||||
|
/* ... carefully check the required size to fit the string table into
|
||||||
|
the map as well. Allow NAME_MAX bytes for the DLL name, but don't
|
||||||
|
go beyond the remainder of the section. */
|
||||||
|
if (importRVAMaxSize - importRVASize > wincap.allocation_granularity ())
|
||||||
|
{
|
||||||
|
DWORD newsize = size;
|
||||||
|
for (PIMAGE_IMPORT_DESCRIPTOR pd = pdfirst; pd->FirstThunk; pd++)
|
||||||
|
if (pd->Name - delta - offset + (NAME_MAX + 1) > newsize)
|
||||||
|
newsize = pd->Name - delta - offset + (NAME_MAX + 1);
|
||||||
|
if (newsize > size)
|
||||||
|
{
|
||||||
|
if (newsize > importRVA - offset + importRVAMaxSize)
|
||||||
|
newsize = importRVA - offset + importRVAMaxSize;
|
||||||
|
UnmapViewOfFile (map);
|
||||||
|
map = (HMODULE) MapViewOfFile (hc, FILE_MAP_READ, 0, offset, newsize);
|
||||||
|
if (!map)
|
||||||
|
return NULL;
|
||||||
|
pdfirst = rva (PIMAGE_IMPORT_DESCRIPTOR, map, importRVA - offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delta += offset;
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
/* Find first missing dll in a given executable.
|
/* Find first missing dll in a given executable.
|
||||||
FIXME: This is not foolproof since it doesn't look for dlls in the
|
FIXME: This is not foolproof since it doesn't look for dlls in the
|
||||||
same directory as the given executable, like Windows. Instead it
|
same directory as the given executable, like Windows. Instead it
|
||||||
@ -178,6 +246,10 @@ find_first_notloaded_dll (path_conv& pc)
|
|||||||
HANDLE h;
|
HANDLE h;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
LARGE_INTEGER size;
|
LARGE_INTEGER size;
|
||||||
|
PIMAGE_NT_HEADERS pExeNTHdr;
|
||||||
|
DWORD importRVA, importRVASize, importRVAMaxSize;
|
||||||
|
HMODULE map;
|
||||||
|
long delta;
|
||||||
|
|
||||||
status = NtOpenFile (&h, SYNCHRONIZE | GENERIC_READ,
|
status = NtOpenFile (&h, SYNCHRONIZE | GENERIC_READ,
|
||||||
pc.get_object_attr (attr, sec_none_nih),
|
pc.get_object_attr (attr, sec_none_nih),
|
||||||
@ -199,7 +271,7 @@ find_first_notloaded_dll (path_conv& pc)
|
|||||||
NtClose (h);
|
NtClose (h);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (size.QuadPart > wincap.allocation_granularity ())
|
if (size.QuadPart > (LONGLONG) wincap.allocation_granularity ())
|
||||||
size.LowPart = wincap.allocation_granularity ();
|
size.LowPart = wincap.allocation_granularity ();
|
||||||
hc = CreateFileMapping (h, &sec_none_nih, PAGE_READONLY, 0, 0, NULL);
|
hc = CreateFileMapping (h, &sec_none_nih, PAGE_READONLY, 0, 0, NULL);
|
||||||
NtClose (h);
|
NtClose (h);
|
||||||
@ -209,55 +281,58 @@ find_first_notloaded_dll (path_conv& pc)
|
|||||||
if (!hm)
|
if (!hm)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
PIMAGE_NT_HEADERS pExeNTHdr;
|
bool is_64bit;
|
||||||
pExeNTHdr = PEHeaderFromHModule (hm);
|
pExeNTHdr = PEHeaderFromHModule (hm, is_64bit);
|
||||||
|
|
||||||
if (pExeNTHdr)
|
if (!pExeNTHdr)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
#ifdef __x86_64__
|
||||||
|
if (!is_64bit)
|
||||||
|
#else
|
||||||
|
if (is_64bit)
|
||||||
|
#endif
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
importRVA = pExeNTHdr->OptionalHeader.DataDirectory
|
||||||
|
[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
|
||||||
|
importRVASize = pExeNTHdr->OptionalHeader.DataDirectory
|
||||||
|
[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;
|
||||||
|
if (!importRVA)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
delta = rvadelta (pExeNTHdr, importRVA, importRVAMaxSize);
|
||||||
|
if (delta < 0)
|
||||||
|
goto out;
|
||||||
|
importRVA -= delta;
|
||||||
|
map = NULL;
|
||||||
|
|
||||||
|
PIMAGE_IMPORT_DESCRIPTOR pdfirst;
|
||||||
|
|
||||||
|
if (importRVA + importRVAMaxSize > wincap.allocation_granularity ())
|
||||||
{
|
{
|
||||||
DWORD importRVA;
|
map = remap (pdfirst, delta, hc, importRVA, importRVASize,
|
||||||
DWORD importRVAMaxSize;
|
importRVAMaxSize);
|
||||||
importRVA = pExeNTHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
|
if (!map)
|
||||||
if (importRVA)
|
goto out;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pdfirst = rva (PIMAGE_IMPORT_DESCRIPTOR, hm, importRVA);
|
||||||
|
|
||||||
|
/* Iterate through each import descriptor, and check if DLL can be loaded. */
|
||||||
|
for (PIMAGE_IMPORT_DESCRIPTOR pd = pdfirst; pd->FirstThunk; pd++)
|
||||||
|
{
|
||||||
|
const char *lib = rva (PSTR, map ?: hm, pd->Name - delta);
|
||||||
|
if (!LoadLibraryEx (lib, NULL, DONT_RESOLVE_DLL_REFERENCES
|
||||||
|
| LOAD_LIBRARY_AS_DATAFILE))
|
||||||
{
|
{
|
||||||
long delta = rvadelta (pExeNTHdr, importRVA, importRVAMaxSize);
|
static char buf[MAX_PATH];
|
||||||
if (delta < 0)
|
strlcpy (buf, lib, MAX_PATH);
|
||||||
goto out;
|
res = buf;
|
||||||
importRVA -= delta;
|
|
||||||
|
|
||||||
DWORD offset = 0;
|
|
||||||
HMODULE map = NULL;
|
|
||||||
if (importRVA + importRVAMaxSize > wincap.allocation_granularity ())
|
|
||||||
{
|
|
||||||
offset = rounddown (importRVA, wincap.allocation_granularity ());
|
|
||||||
DWORD size = importRVA - offset + importRVAMaxSize;
|
|
||||||
map = (HMODULE) MapViewOfFile (hc, FILE_MAP_READ, 0,
|
|
||||||
offset, size);
|
|
||||||
if (!map)
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert imports RVA to a usable pointer
|
|
||||||
PIMAGE_IMPORT_DESCRIPTOR pdfirst;
|
|
||||||
pdfirst = rva (PIMAGE_IMPORT_DESCRIPTOR, map ?: hm,
|
|
||||||
importRVA - offset);
|
|
||||||
|
|
||||||
// Iterate through each import descriptor, and redirect if appropriate
|
|
||||||
for (PIMAGE_IMPORT_DESCRIPTOR pd = pdfirst; pd->FirstThunk; pd++)
|
|
||||||
{
|
|
||||||
const char *lib = rva (PSTR, map ?: hm,
|
|
||||||
pd->Name - delta - offset);
|
|
||||||
if (!LoadLibraryEx (lib, NULL, DONT_RESOLVE_DLL_REFERENCES
|
|
||||||
| LOAD_LIBRARY_AS_DATAFILE))
|
|
||||||
{
|
|
||||||
static char buf[MAX_PATH];
|
|
||||||
strlcpy (buf, lib, MAX_PATH);
|
|
||||||
res = buf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (map)
|
|
||||||
UnmapViewOfFile (map);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (map)
|
||||||
|
UnmapViewOfFile (map);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (hm)
|
if (hm)
|
||||||
@ -273,25 +348,32 @@ void *
|
|||||||
hook_or_detect_cygwin (const char *name, const void *fn, WORD& subsys, HANDLE h)
|
hook_or_detect_cygwin (const char *name, const void *fn, WORD& subsys, HANDLE h)
|
||||||
{
|
{
|
||||||
HMODULE hm = fn ? GetModuleHandle (NULL) : (HMODULE) name;
|
HMODULE hm = fn ? GetModuleHandle (NULL) : (HMODULE) name;
|
||||||
PIMAGE_NT_HEADERS pExeNTHdr = PEHeaderFromHModule (hm);
|
bool is_64bit;
|
||||||
|
PIMAGE_NT_HEADERS pExeNTHdr = PEHeaderFromHModule (hm, is_64bit);
|
||||||
|
|
||||||
if (!pExeNTHdr)
|
if (!pExeNTHdr)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* FIXME: This code has to be made 64 bit capable. */
|
/* Shortcut. We don't have to do anything further from here, if the
|
||||||
if (pExeNTHdr->FileHeader.Machine != IMAGE_FILE_MACHINE_I386)
|
executable's architecture doesn't match, unless we want to support
|
||||||
|
a mix of 32 and 64 bit Cygwin at one point. */
|
||||||
|
#ifdef __x86_64__
|
||||||
|
if (!is_64bit)
|
||||||
|
#else
|
||||||
|
if (is_64bit)
|
||||||
|
#endif
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
subsys = pExeNTHdr->OptionalHeader.Subsystem;
|
DWORD importRVA, importRVASize;
|
||||||
|
subsys = pExeNTHdr->OptionalHeader.Subsystem;
|
||||||
DWORD importRVA = pExeNTHdr->OptionalHeader.DataDirectory
|
importRVA = pExeNTHdr->OptionalHeader.DataDirectory
|
||||||
[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
|
[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
|
||||||
DWORD importRVASize = pExeNTHdr->OptionalHeader.DataDirectory
|
importRVASize = pExeNTHdr->OptionalHeader.DataDirectory
|
||||||
[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;
|
[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;
|
||||||
if (!importRVA)
|
if (!importRVA)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
DWORD importRVAMaxSize;
|
DWORD importRVAMaxSize = 0;
|
||||||
long delta = fn ? 0 : rvadelta (pExeNTHdr, importRVA, importRVAMaxSize);
|
long delta = fn ? 0 : rvadelta (pExeNTHdr, importRVA, importRVAMaxSize);
|
||||||
if (delta < 0)
|
if (delta < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -300,55 +382,12 @@ hook_or_detect_cygwin (const char *name, const void *fn, WORD& subsys, HANDLE h)
|
|||||||
// Convert imports RVA to a usable pointer
|
// Convert imports RVA to a usable pointer
|
||||||
PIMAGE_IMPORT_DESCRIPTOR pdfirst;
|
PIMAGE_IMPORT_DESCRIPTOR pdfirst;
|
||||||
char *map = NULL;
|
char *map = NULL;
|
||||||
DWORD offset = 0;
|
|
||||||
if (h && importRVA + importRVAMaxSize > wincap.allocation_granularity ())
|
if (h && importRVA + importRVAMaxSize > wincap.allocation_granularity ())
|
||||||
{
|
{
|
||||||
/* If h is not NULL, the calling function only mapped at most the first
|
map = (char *) remap (pdfirst, delta, h, importRVA, importRVASize,
|
||||||
64K of the image. The IAT is usually at the end of the image, so
|
importRVAMaxSize);
|
||||||
what we do here is to map the IAT into our address space if it doesn't
|
|
||||||
reside in the first 64K anyway. The offset must be a multiple of the
|
|
||||||
allocation granularity, though, so we have to map a bit more. */
|
|
||||||
offset = rounddown (importRVA, wincap.allocation_granularity ());
|
|
||||||
/* But that's not all, unfortunately. Apparently there's a difference
|
|
||||||
between the importRVASize of applications built with gcc and those
|
|
||||||
built with Visual Studio. When built with gcc, importRVASize contains
|
|
||||||
the size of the import RVA table plus the size of the referenced
|
|
||||||
string table with the DLL names. When built with VS, it only contains
|
|
||||||
the size of the naked import RVA table. The following code handles
|
|
||||||
the situation. importRVAMaxSize contains the size of the remainder
|
|
||||||
of the section. If the difference between importRVAMaxSize and
|
|
||||||
importRVASize is less than 64K, we just use importRVAMaxSize to
|
|
||||||
compute the size of the memory map. Otherwise the executable may be
|
|
||||||
very big. In that case we only map the import RVA table and ... */
|
|
||||||
DWORD size = importRVA - offset
|
|
||||||
+ ((importRVAMaxSize - importRVASize
|
|
||||||
<= wincap.allocation_granularity ())
|
|
||||||
? importRVAMaxSize : importRVASize);
|
|
||||||
map = (char *) MapViewOfFile (h, FILE_MAP_READ, 0, offset, size);
|
|
||||||
if (!map)
|
if (!map)
|
||||||
return NULL;
|
return NULL;
|
||||||
pdfirst = rva (PIMAGE_IMPORT_DESCRIPTOR, map, importRVA - offset);
|
|
||||||
/* ... carefully check the required size to fit the string table into
|
|
||||||
the map as well. Allow NAME_MAX bytes for the DLL name, but don't
|
|
||||||
go beyond the remainder of the section. */
|
|
||||||
if (importRVAMaxSize - importRVASize > wincap.allocation_granularity ())
|
|
||||||
{
|
|
||||||
DWORD newsize = size;
|
|
||||||
for (PIMAGE_IMPORT_DESCRIPTOR pd = pdfirst; pd->FirstThunk; pd++)
|
|
||||||
if (pd->Name - delta - offset + (NAME_MAX + 1) > newsize)
|
|
||||||
newsize = pd->Name - delta - offset + (NAME_MAX + 1);
|
|
||||||
if (newsize > size)
|
|
||||||
{
|
|
||||||
if (newsize > importRVA - offset + importRVAMaxSize)
|
|
||||||
newsize = importRVA - offset + importRVAMaxSize;
|
|
||||||
UnmapViewOfFile (map);
|
|
||||||
map = (char *) MapViewOfFile (h, FILE_MAP_READ, 0, offset,
|
|
||||||
newsize);
|
|
||||||
if (!map)
|
|
||||||
return NULL;
|
|
||||||
pdfirst = rva (PIMAGE_IMPORT_DESCRIPTOR, map, importRVA - offset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
pdfirst = rva (PIMAGE_IMPORT_DESCRIPTOR, hm, importRVA);
|
pdfirst = rva (PIMAGE_IMPORT_DESCRIPTOR, hm, importRVA);
|
||||||
@ -363,14 +402,15 @@ hook_or_detect_cygwin (const char *name, const void *fn, WORD& subsys, HANDLE h)
|
|||||||
// Iterate through each import descriptor, and redirect if appropriate
|
// Iterate through each import descriptor, and redirect if appropriate
|
||||||
for (PIMAGE_IMPORT_DESCRIPTOR pd = pdfirst; pd->FirstThunk; pd++)
|
for (PIMAGE_IMPORT_DESCRIPTOR pd = pdfirst; pd->FirstThunk; pd++)
|
||||||
{
|
{
|
||||||
if (!ascii_strcasematch (rva (PSTR, map ?: (char *) hm,
|
if (!ascii_strcasematch (rva (PSTR, map ?: (char *) hm, pd->Name - delta),
|
||||||
pd->Name - delta - offset), "cygwin1.dll"))
|
"cygwin1.dll"))
|
||||||
continue;
|
continue;
|
||||||
if (!fn)
|
if (!fn)
|
||||||
{
|
{
|
||||||
|
/* Just checking if executable used cygwin1.dll. */
|
||||||
if (map)
|
if (map)
|
||||||
UnmapViewOfFile (map);
|
UnmapViewOfFile (map);
|
||||||
return (void *) "found it"; // just checking if executable used cygwin1.dll
|
return (void *) "found it";
|
||||||
}
|
}
|
||||||
i = -1;
|
i = -1;
|
||||||
while (!fh.origfn && (fh.name = makename (name, buf, i, 1)))
|
while (!fh.origfn && (fh.name = makename (name, buf, i, 1)))
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* a.out.h
|
/* a.out.h
|
||||||
|
|
||||||
Copyright 1997, 1998, 1999, 2000, 2001 Red Hat, Inc.
|
Copyright 1997, 1998, 1999, 2000, 2001, 2013 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -14,22 +14,25 @@ details. */
|
|||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#define COFF_IMAGE_WITH_PE
|
#define COFF_IMAGE_WITH_PE
|
||||||
#define COFF_LONG_SECTION_NAMES
|
#define COFF_LONG_SECTION_NAMES
|
||||||
|
|
||||||
/*** coff information for Intel 386/486. */
|
/*** coff information for Intel 386/486 and AMD64. */
|
||||||
|
|
||||||
|
|
||||||
/********************** FILE HEADER **********************/
|
/********************** FILE HEADER **********************/
|
||||||
|
|
||||||
struct external_filehdr {
|
struct external_filehdr {
|
||||||
short f_magic; /* magic number */
|
uint16_t f_magic; /* magic number */
|
||||||
short f_nscns; /* number of sections */
|
uint16_t f_nscns; /* number of sections */
|
||||||
unsigned long f_timdat; /* time & date stamp */
|
uint32_t f_timdat; /* time & date stamp */
|
||||||
unsigned long f_symptr; /* file pointer to symtab */
|
uint32_t f_symptr; /* file pointer to symtab */
|
||||||
unsigned long f_nsyms; /* number of symtab entries */
|
uint32_t f_nsyms; /* number of symtab entries */
|
||||||
short f_opthdr; /* sizeof(optional hdr) */
|
uint16_t f_opthdr; /* sizeof(optional hdr) */
|
||||||
short f_flags; /* flags */
|
uint16_t f_flags; /* flags */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Bits for f_flags:
|
/* Bits for f_flags:
|
||||||
@ -50,6 +53,7 @@ struct external_filehdr {
|
|||||||
#define I386MAGIC 0x14c
|
#define I386MAGIC 0x14c
|
||||||
#define I386PTXMAGIC 0x154
|
#define I386PTXMAGIC 0x154
|
||||||
#define I386AIXMAGIC 0x175
|
#define I386AIXMAGIC 0x175
|
||||||
|
#define AMD64MAGIC 0x8664
|
||||||
|
|
||||||
/* This is Lynx's all-platform magic number for executables. */
|
/* This is Lynx's all-platform magic number for executables. */
|
||||||
|
|
||||||
@ -70,14 +74,14 @@ struct external_filehdr {
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
unsigned short magic; /* type of file */
|
uint16_t magic; /* type of file */
|
||||||
unsigned short vstamp; /* version stamp */
|
uint16_t vstamp; /* version stamp */
|
||||||
unsigned long tsize; /* text size in bytes, padded to FW bdry*/
|
uint32_t tsize; /* text size in bytes, padded to FW bdry*/
|
||||||
unsigned long dsize; /* initialized data " " */
|
uint32_t dsize; /* initialized data " " */
|
||||||
unsigned long bsize; /* uninitialized data " " */
|
uint32_t bsize; /* uninitialized data " " */
|
||||||
unsigned long entry; /* entry pt. */
|
uint32_t entry; /* entry pt. */
|
||||||
unsigned long text_start; /* base of text used for this file */
|
uint32_t text_start; /* base of text used for this file */
|
||||||
unsigned long data_start; /* base of data used for this file=
|
uint32_t data_start; /* base of data used for this file=
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
AOUTHDR;
|
AOUTHDR;
|
||||||
@ -103,16 +107,16 @@ AOUTHDR;
|
|||||||
|
|
||||||
struct external_scnhdr {
|
struct external_scnhdr {
|
||||||
char s_name[8]; /* section name */
|
char s_name[8]; /* section name */
|
||||||
unsigned long s_paddr; /* physical address, offset
|
uint32_t s_paddr; /* physical address, offset
|
||||||
of last addr in scn */
|
of last addr in scn */
|
||||||
unsigned long s_vaddr; /* virtual address */
|
uint32_t s_vaddr; /* virtual address */
|
||||||
unsigned long s_size; /* section size */
|
uint32_t s_size; /* section size */
|
||||||
unsigned long s_scnptr; /* file ptr to raw data for section */
|
uint32_t s_scnptr; /* file ptr to raw data for section */
|
||||||
unsigned long s_relptr; /* file ptr to relocation */
|
uint32_t s_relptr; /* file ptr to relocation */
|
||||||
unsigned long s_lnnoptr; /* file ptr to line numbers */
|
uint32_t s_lnnoptr; /* file ptr to line numbers */
|
||||||
unsigned short s_nreloc; /* number of relocation entries */
|
uint16_t s_nreloc; /* number of relocation entries */
|
||||||
unsigned short s_nlnno; /* number of line number entries*/
|
uint16_t s_nlnno; /* number of line number entries*/
|
||||||
unsigned long s_flags; /* flags */
|
uint32_t s_flags; /* flags */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SCNHDR struct external_scnhdr
|
#define SCNHDR struct external_scnhdr
|
||||||
@ -136,10 +140,10 @@ struct external_scnhdr {
|
|||||||
*/
|
*/
|
||||||
struct external_lineno {
|
struct external_lineno {
|
||||||
union {
|
union {
|
||||||
unsigned long l_symndx; /* function name symbol index, iff l_lnno 0 */
|
uint32_t l_symndx; /* function name symbol index, iff l_lnno 0 */
|
||||||
unsigned long l_paddr; /* (physical) address of line number */
|
uint32_t l_paddr; /* (physical) address of line number */
|
||||||
} l_addr;
|
} l_addr;
|
||||||
unsigned short l_lnno; /* line number */
|
uint16_t l_lnno; /* line number */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define LINENO struct external_lineno
|
#define LINENO struct external_lineno
|
||||||
@ -156,13 +160,13 @@ struct external_syment
|
|||||||
union {
|
union {
|
||||||
char e_name[E_SYMNMLEN];
|
char e_name[E_SYMNMLEN];
|
||||||
struct {
|
struct {
|
||||||
unsigned long e_zeroes;
|
uint32_t e_zeroes;
|
||||||
unsigned long e_offset;
|
uint32_t e_offset;
|
||||||
} e;
|
} e;
|
||||||
} e;
|
} e;
|
||||||
unsigned long e_value;
|
uint32_t e_value;
|
||||||
unsigned short e_scnum;
|
uint16_t e_scnum;
|
||||||
unsigned short e_type;
|
uint16_t e_type;
|
||||||
char e_sclass[1];
|
char e_sclass[1];
|
||||||
char e_numaux[1];
|
char e_numaux[1];
|
||||||
};
|
};
|
||||||
@ -174,46 +178,46 @@ struct external_syment
|
|||||||
|
|
||||||
union external_auxent {
|
union external_auxent {
|
||||||
struct {
|
struct {
|
||||||
unsigned long x_tagndx; /* str, un, or enum tag indx */
|
uint32_t x_tagndx; /* str, un, or enum tag indx */
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
unsigned short x_lnno; /* declaration line number */
|
uint16_t x_lnno; /* declaration line number */
|
||||||
unsigned short x_size; /* str/union/array size */
|
uint16_t x_size; /* str/union/array size */
|
||||||
} x_lnsz;
|
} x_lnsz;
|
||||||
unsigned long x_fsize; /* size of function */
|
uint32_t x_fsize; /* size of function */
|
||||||
} x_misc;
|
} x_misc;
|
||||||
union {
|
union {
|
||||||
struct { /* if ISFCN, tag, or .bb */
|
struct { /* if ISFCN, tag, or .bb */
|
||||||
unsigned long x_lnnoptr;/* ptr to fcn line # */
|
uint32_t x_lnnoptr; /* ptr to fcn line # */
|
||||||
unsigned long x_endndx; /* entry ndx past block end */
|
uint32_t x_endndx; /* entry ndx past block end */
|
||||||
} x_fcn;
|
} x_fcn;
|
||||||
struct { /* if ISARY, up to 4 dimen. */
|
struct { /* if ISARY, up to 4 dimen. */
|
||||||
char x_dimen[E_DIMNUM][2];
|
char x_dimen[E_DIMNUM][2];
|
||||||
} x_ary;
|
} x_ary;
|
||||||
} x_fcnary;
|
} x_fcnary;
|
||||||
unsigned short x_tvndx; /* tv index */
|
uint16_t x_tvndx; /* tv index */
|
||||||
} x_sym;
|
} x_sym;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
char x_fname[E_FILNMLEN];
|
char x_fname[E_FILNMLEN];
|
||||||
struct {
|
struct {
|
||||||
unsigned long x_zeroes;
|
uint32_t x_zeroes;
|
||||||
unsigned long x_offset;
|
uint32_t x_offset;
|
||||||
} x_n;
|
} x_n;
|
||||||
} x_file;
|
} x_file;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
unsigned long x_scnlen; /* section length */
|
uint32_t x_scnlen; /* section length */
|
||||||
unsigned short x_nreloc; /* # relocation entries */
|
uint16_t x_nreloc; /* # relocation entries */
|
||||||
unsigned short x_nlinno; /* # line numbers */
|
uint16_t x_nlinno; /* # line numbers */
|
||||||
unsigned long x_checksum; /* section COMDAT checksum */
|
uint32_t x_checksum; /* section COMDAT checksum */
|
||||||
unsigned short x_associated;/* COMDAT associated section index */
|
uint16_t x_associated; /* COMDAT associated section index */
|
||||||
char x_comdat[1]; /* COMDAT selection number */
|
char x_comdat[1]; /* COMDAT selection number */
|
||||||
} x_scn;
|
} x_scn;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
unsigned long x_tvfill; /* tv fill value */
|
uint32_t x_tvfill; /* tv fill value */
|
||||||
unsigned short x_tvlen; /* length of .tv */
|
uint16_t x_tvlen; /* length of .tv */
|
||||||
char x_tvran[2][2]; /* tv range */
|
char x_tvran[2][2]; /* tv range */
|
||||||
} x_tv; /* info about .tv section (in auxent of symbol .tv)) */
|
} x_tv; /* info about .tv section (in auxent of symbol .tv)) */
|
||||||
|
|
||||||
@ -244,6 +248,20 @@ struct external_reloc {
|
|||||||
#ifndef _PE_H
|
#ifndef _PE_H
|
||||||
#define _PE_H
|
#define _PE_H
|
||||||
|
|
||||||
|
#define IMAGE_FILE_MACHINE_I386 0x014c
|
||||||
|
#define IMAGE_FILE_MACHINE_AMD64 0x8664
|
||||||
|
|
||||||
|
#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b
|
||||||
|
#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b
|
||||||
|
|
||||||
|
#define IMAGE_SIZEOF_STD_OPTIONAL_HEADER 28
|
||||||
|
#define IMAGE_SIZEOF_NT_OPTIONAL32_HEADER 224
|
||||||
|
#define IMAGE_SIZEOF_NT_OPTIONAL64_HEADER 240
|
||||||
|
|
||||||
|
#define IMAGE_SUBSYSTEM_NATIVE 1
|
||||||
|
#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2
|
||||||
|
#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3
|
||||||
|
|
||||||
/* NT specific file attributes */
|
/* NT specific file attributes */
|
||||||
#define IMAGE_FILE_RELOCS_STRIPPED 0x0001
|
#define IMAGE_FILE_RELOCS_STRIPPED 0x0001
|
||||||
#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002
|
#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002
|
||||||
@ -320,43 +338,43 @@ struct external_reloc {
|
|||||||
|
|
||||||
|
|
||||||
#ifdef COFF_IMAGE_WITH_PE
|
#ifdef COFF_IMAGE_WITH_PE
|
||||||
/* The filehdr is only weired in images */
|
/* The filehdr is only weird in images */
|
||||||
|
|
||||||
#undef FILHDR
|
#undef FILHDR
|
||||||
struct external_PE_filehdr
|
struct external_PE_filehdr
|
||||||
{
|
{
|
||||||
/* DOS header fields */
|
/* DOS header fields */
|
||||||
unsigned short e_magic; /* Magic number, 0x5a4d */
|
uint16_t e_magic; /* Magic number, 0x5a4d */
|
||||||
unsigned short e_cblp; /* Bytes on last page of file, 0x90 */
|
uint16_t e_cblp; /* Bytes on last page of file, 0x90 */
|
||||||
unsigned short e_cp; /* Pages in file, 0x3 */
|
uint16_t e_cp; /* Pages in file, 0x3 */
|
||||||
unsigned short e_crlc; /* Relocations, 0x0 */
|
uint16_t e_crlc; /* Relocations, 0x0 */
|
||||||
unsigned short e_cparhdr; /* Size of header in paragraphs, 0x4 */
|
uint16_t e_cparhdr; /* Size of header in paragraphs, 0x4 */
|
||||||
unsigned short e_minalloc; /* Minimum extra paragraphs needed, 0x0 */
|
uint16_t e_minalloc; /* Minimum extra paragraphs needed, 0x0 */
|
||||||
unsigned short e_maxalloc; /* Maximum extra paragraphs needed, 0xFFFF */
|
uint16_t e_maxalloc; /* Maximum extra paragraphs needed, 0xFFFF */
|
||||||
unsigned short e_ss; /* Initial (relative) SS value, 0x0 */
|
uint16_t e_ss; /* Initial (relative) SS value, 0x0 */
|
||||||
unsigned short e_sp; /* Initial SP value, 0xb8 */
|
uint16_t e_sp; /* Initial SP value, 0xb8 */
|
||||||
unsigned short e_csum; /* Checksum, 0x0 */
|
uint16_t e_csum; /* Checksum, 0x0 */
|
||||||
unsigned short e_ip; /* Initial IP value, 0x0 */
|
uint16_t e_ip; /* Initial IP value, 0x0 */
|
||||||
unsigned short e_cs; /* Initial (relative) CS value, 0x0 */
|
uint16_t e_cs; /* Initial (relative) CS value, 0x0 */
|
||||||
unsigned short e_lfarlc; /* File address of relocation table, 0x40 */
|
uint16_t e_lfarlc; /* File address of relocation table, 0x40 */
|
||||||
unsigned short e_ovno; /* Overlay number, 0x0 */
|
uint16_t e_ovno; /* Overlay number, 0x0 */
|
||||||
char e_res[4][2]; /* Reserved words, all 0x0 */
|
char e_res[4][2]; /* Reserved words, all 0x0 */
|
||||||
unsigned short e_oemid; /* OEM identifier (for e_oeminfo), 0x0 */
|
uint16_t e_oemid; /* OEM identifier (for e_oeminfo), 0x0 */
|
||||||
unsigned short e_oeminfo; /* OEM information; e_oemid specific, 0x0 */
|
uint16_t e_oeminfo; /* OEM information; e_oemid specific, 0x0 */
|
||||||
char e_res2[10][2]; /* Reserved words, all 0x0 */
|
char e_res2[10][2]; /* Reserved words, all 0x0 */
|
||||||
unsigned long e_lfanew; /* File address of new exe header, 0x80 */
|
uint32_t e_lfanew; /* File address of new exe header, 0x80 */
|
||||||
char dos_message[16][4]; /* other stuff, always follow DOS header */
|
char dos_message[16][4]; /* other stuff, always follow DOS header */
|
||||||
unsigned int nt_signature; /* required NT signature, 0x4550 */
|
uint32_t nt_signature; /* required NT signature, 0x4550 */
|
||||||
|
|
||||||
/* From standard header */
|
/* From standard header */
|
||||||
|
|
||||||
unsigned short f_magic; /* magic number */
|
uint16_t f_magic; /* magic number */
|
||||||
unsigned short f_nscns; /* number of sections */
|
uint16_t f_nscns; /* number of sections */
|
||||||
unsigned long f_timdat; /* time & date stamp */
|
uint32_t f_timdat; /* time & date stamp */
|
||||||
unsigned long f_symptr; /* file pointer to symtab */
|
uint32_t f_symptr; /* file pointer to symtab */
|
||||||
unsigned long f_nsyms; /* number of symtab entries */
|
uint32_t f_nsyms; /* number of symtab entries */
|
||||||
unsigned short f_opthdr; /* sizeof(optional hdr) */
|
uint16_t f_opthdr; /* sizeof(optional hdr) */
|
||||||
unsigned short f_flags; /* flags */
|
uint16_t f_flags; /* flags */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -368,37 +386,39 @@ struct external_PE_filehdr
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
unsigned short magic; /* type of file */
|
uint16_t magic; /* type of file */
|
||||||
unsigned short vstamp; /* version stamp */
|
uint16_t vstamp; /* version stamp */
|
||||||
unsigned long tsize; /* text size in bytes, padded to FW bdry*/
|
uint32_t tsize; /* text size in bytes, padded to FW bdry*/
|
||||||
unsigned long dsize; /* initialized data " " */
|
uint32_t dsize; /* initialized data " " */
|
||||||
unsigned long bsize; /* uninitialized data " " */
|
uint32_t bsize; /* uninitialized data " " */
|
||||||
unsigned long entry; /* entry pt. */
|
uint32_t entry; /* entry pt. */
|
||||||
unsigned long text_start; /* base of text used for this file */
|
uint32_t text_start; /* base of text used for this file */
|
||||||
unsigned long data_start; /* base of all data used for this file */
|
#ifndef __x86_64__
|
||||||
|
uint32_t data_start; /* base of all data used for this file */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* NT extra fields; see internal.h for descriptions */
|
/* NT extra fields; see internal.h for descriptions */
|
||||||
unsigned long ImageBase;
|
uintptr_t ImageBase;
|
||||||
unsigned long SectionAlignment;
|
uint32_t SectionAlignment;
|
||||||
unsigned long FileAlignment;
|
uint32_t FileAlignment;
|
||||||
unsigned short MajorOperatingSystemVersion;
|
uint16_t MajorOperatingSystemVersion;
|
||||||
unsigned short MinorOperatingSystemVersion;
|
uint16_t MinorOperatingSystemVersion;
|
||||||
unsigned short MajorImageVersion;
|
uint16_t MajorImageVersion;
|
||||||
unsigned short MinorImageVersion;
|
uint16_t MinorImageVersion;
|
||||||
unsigned short MajorSubsystemVersion;
|
uint16_t MajorSubsystemVersion;
|
||||||
unsigned short MinorSubsystemVersion;
|
uint16_t MinorSubsystemVersion;
|
||||||
char Reserved1[4];
|
char Reserved1[4];
|
||||||
unsigned long SizeOfImage;
|
uint32_t SizeOfImage;
|
||||||
unsigned long SizeOfHeaders;
|
uint32_t SizeOfHeaders;
|
||||||
unsigned long CheckSum;
|
uint32_t CheckSum;
|
||||||
unsigned short Subsystem;
|
uint16_t Subsystem;
|
||||||
unsigned short DllCharacteristics;
|
uint16_t DllCharacteristics;
|
||||||
unsigned long SizeOfStackReserve;
|
uintptr_t SizeOfStackReserve;
|
||||||
unsigned long SizeOfStackCommit;
|
uintptr_t SizeOfStackCommit;
|
||||||
unsigned long SizeOfHeapReserve;
|
uintptr_t SizeOfHeapReserve;
|
||||||
unsigned long SizeOfHeapCommit;
|
uintptr_t SizeOfHeapCommit;
|
||||||
unsigned long LoaderFlags;
|
uint32_t LoaderFlags;
|
||||||
unsigned long NumberOfRvaAndSizes;
|
uint32_t NumberOfRvaAndSizes;
|
||||||
/* IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; */
|
/* IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; */
|
||||||
char DataDirectory[16][2][4]; /* 16 entries, 2 elements/entry, 4 chars */
|
char DataDirectory[16][2][4]; /* 16 entries, 2 elements/entry, 4 chars */
|
||||||
|
|
||||||
@ -406,7 +426,11 @@ typedef struct
|
|||||||
|
|
||||||
|
|
||||||
#undef AOUTSZ
|
#undef AOUTSZ
|
||||||
|
#ifdef __x86_64__
|
||||||
|
#define AOUTSZ (AOUTHDRSZ + 212)
|
||||||
|
#else
|
||||||
#define AOUTSZ (AOUTHDRSZ + 196)
|
#define AOUTSZ (AOUTHDRSZ + 196)
|
||||||
|
#endif
|
||||||
|
|
||||||
#undef E_FILNMLEN
|
#undef E_FILNMLEN
|
||||||
#define E_FILNMLEN 18 /* # characters in a file name */
|
#define E_FILNMLEN 18 /* # characters in a file name */
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* asm/byteorder.h
|
/* asm/byteorder.h
|
||||||
|
|
||||||
Copyright 1996, 1998, 2000, 2001, 2006, 2009, 2011 Red Hat, Inc.
|
Copyright 1996, 1998, 2001, 2006, 2009, 2011, 2012 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -34,11 +34,7 @@ _ELIDABLE_INLINE uint16_t __ntohs(uint16_t);
|
|||||||
_ELIDABLE_INLINE uint32_t
|
_ELIDABLE_INLINE uint32_t
|
||||||
__ntohl(uint32_t x)
|
__ntohl(uint32_t x)
|
||||||
{
|
{
|
||||||
__asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */
|
__asm__("bswap %0" : "=r" (x) : "0" (x));
|
||||||
"rorl $16,%0\n\t" /* swap words */
|
|
||||||
"xchgb %b0,%h0" /* swap higher bytes */
|
|
||||||
:"=q" (x)
|
|
||||||
: "0" (x));
|
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,7 +48,7 @@ _ELIDABLE_INLINE uint16_t
|
|||||||
__ntohs(uint16_t x)
|
__ntohs(uint16_t x)
|
||||||
{
|
{
|
||||||
__asm__("xchgb %b0,%h0" /* swap bytes */
|
__asm__("xchgb %b0,%h0" /* swap bytes */
|
||||||
: "=q" (x)
|
: "=Q" (x)
|
||||||
: "0" (x));
|
: "0" (x));
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
@ -2,5 +2,10 @@
|
|||||||
|
|
||||||
#ifndef _WORDSIZE_H
|
#ifndef _WORDSIZE_H
|
||||||
#define _WORDSIZE_H 1
|
#define _WORDSIZE_H 1
|
||||||
#define __WORDSIZE 32
|
#ifdef __x86_64__
|
||||||
|
# define __WORDSIZE 64
|
||||||
|
# define __WORDSIZE_COMPAT32 1
|
||||||
|
#else
|
||||||
|
# define __WORDSIZE 32
|
||||||
|
#endif
|
||||||
#endif /*_WORDSIZE_H*/
|
#endif /*_WORDSIZE_H*/
|
||||||
|
@ -59,24 +59,20 @@ extern "C" {
|
|||||||
#define OTHER OTHER_OBJ
|
#define OTHER OTHER_OBJ
|
||||||
|
|
||||||
#ifdef __INSIDE_CYGWIN__
|
#ifdef __INSIDE_CYGWIN__
|
||||||
|
#ifndef __x86_64__
|
||||||
typedef struct __acl16 {
|
typedef struct __acl16 {
|
||||||
int a_type;
|
int a_type;
|
||||||
__uid16_t a_id;
|
__uid16_t a_id;
|
||||||
mode_t a_perm;
|
mode_t a_perm;
|
||||||
} __aclent16_t;
|
} __aclent16_t;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct __acl32 {
|
|
||||||
int a_type;
|
|
||||||
__uid32_t a_id;
|
|
||||||
mode_t a_perm;
|
|
||||||
} __aclent32_t;
|
|
||||||
#else
|
|
||||||
typedef struct acl {
|
typedef struct acl {
|
||||||
int a_type; /* entry type */
|
int a_type; /* entry type */
|
||||||
uid_t a_id; /* UID | GID */
|
uid_t a_id; /* UID | GID */
|
||||||
mode_t a_perm; /* permissions */
|
mode_t a_perm; /* permissions */
|
||||||
} aclent_t;
|
} aclent_t;
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __INSIDE_CYGWIN__
|
#ifndef __INSIDE_CYGWIN__
|
||||||
int _EXFUN(acl,(const char *path, int cmd, int nentries, aclent_t *aclbufp));
|
int _EXFUN(acl,(const char *path, int cmd, int nentries, aclent_t *aclbufp));
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user