* Throughout, use __try/__except/__endtry blocks, rather than myfault
handler. * cygtls.cc (_cygtls::remove): Accommodate the fact that pathbufs has been moved from _local_storage to _cygtls. * cygtls.h (class tls_pathbuf): Add comment to hint to gendef usage of counters. Change type of counters to uint32_t for clarity. Remove _cygtls as friend class. (struct _local_storage): Move pathbufs from here... (struct _cygtls): ...to here, allowing to access it from _sigbe. (class san): Only define on 32 bit. Remove errno, _c_cnt and _w_cnt members. (san::setup): Drop parameter. Don't initialize removed members. (san::leave): Don't set removed members. (class myfault): Only define on 32 bit. (myfault::faulted): Only keep implementation not taking any parameter. Drop argument in call to sebastian.setup. (__try/__leave/__except/__endtry): Implement to support real SEH. For now stick to SJLJ on 32 bit. * dcrt0.cc (dll_crt0_0): Drop 64 bit call to exception::install_myfault_handler. * exception.h (exception_handler): Define with EXCEPTION_DISPOSITION as return type. (PDISPATCHER_CONTEXT): Define as void * on 32 bit. Define as pointer to _DISPATCHER_CONTEXT on 64 bit. (class exception): Define separately for 32 and 64 bit. (exception::myfault): Add handler for myfault SEH handling on 64 bit. (exception::exception): Fix mangled method name to account for change in type of last parameter. (exception::install_myfault_handler): Remove. * exceptions.cc (exception::myfault_handle): Remove. (exception::myfault): New SEH handler for 64 bit. * gendef (_sigbe): Set tls_pathbuf counters to 0 explicitely when returning to the caller. * ntdll.h: Move a comment to a better place. (struct _SCOPE_TABLE): Define on 64 bit. * thread.cc (verifyable_object_isvalid): Remove gcc 4.7 workaround. * tls_pbuf.cc (tls_pbuf): Fix to accommodate new place of pathbufs. (tls_pathbuf::destroy): Change type of loop variables to uint32_t. * tls_pbuf.h (class tmp_pathbuf): Change type of buffer counters to uint32_t. Accommodate new place of pathbufs. * tlsoffsets.h: Regenerate. * tlsoffsets64.h: Regenerate.
This commit is contained in:
parent
33ed7bb5bc
commit
3f3bd10104
|
@ -1,3 +1,48 @@
|
|||
2014-08-21 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* Throughout, use __try/__except/__endtry blocks, rather than myfault
|
||||
handler.
|
||||
* cygtls.cc (_cygtls::remove): Accommodate the fact that pathbufs
|
||||
has been moved from _local_storage to _cygtls.
|
||||
* cygtls.h (class tls_pathbuf): Add comment to hint to gendef usage
|
||||
of counters. Change type of counters to uint32_t for clarity.
|
||||
Remove _cygtls as friend class.
|
||||
(struct _local_storage): Move pathbufs from here...
|
||||
(struct _cygtls): ...to here, allowing to access it from _sigbe.
|
||||
(class san): Only define on 32 bit. Remove errno, _c_cnt and _w_cnt
|
||||
members.
|
||||
(san::setup): Drop parameter. Don't initialize removed members.
|
||||
(san::leave): Don't set removed members.
|
||||
(class myfault): Only define on 32 bit.
|
||||
(myfault::faulted): Only keep implementation not taking any parameter.
|
||||
Drop argument in call to sebastian.setup.
|
||||
(__try/__leave/__except/__endtry): Implement to support real SEH. For
|
||||
now stick to SJLJ on 32 bit.
|
||||
* dcrt0.cc (dll_crt0_0): Drop 64 bit call to
|
||||
exception::install_myfault_handler.
|
||||
* exception.h (exception_handler): Define with EXCEPTION_DISPOSITION
|
||||
as return type.
|
||||
(PDISPATCHER_CONTEXT): Define as void * on 32 bit. Define as pointer
|
||||
to _DISPATCHER_CONTEXT on 64 bit.
|
||||
(class exception): Define separately for 32 and 64 bit.
|
||||
(exception::myfault): Add handler for myfault SEH handling on 64 bit.
|
||||
(exception::exception): Fix mangled method name to account for change
|
||||
in type of last parameter.
|
||||
(exception::install_myfault_handler): Remove.
|
||||
* exceptions.cc (exception::myfault_handle): Remove.
|
||||
(exception::myfault): New SEH handler for 64 bit.
|
||||
* gendef (_sigbe): Set tls_pathbuf counters to 0 explicitely when
|
||||
returning to the caller.
|
||||
* ntdll.h: Move a comment to a better place.
|
||||
(struct _SCOPE_TABLE): Define on 64 bit.
|
||||
* thread.cc (verifyable_object_isvalid): Remove gcc 4.7 workaround.
|
||||
* tls_pbuf.cc (tls_pbuf): Fix to accommodate new place of pathbufs.
|
||||
(tls_pathbuf::destroy): Change type of loop variables to uint32_t.
|
||||
* tls_pbuf.h (class tmp_pathbuf): Change type of buffer counters to
|
||||
uint32_t. Accommodate new place of pathbufs.
|
||||
* tlsoffsets.h: Regenerate.
|
||||
* tlsoffsets64.h: Regenerate.
|
||||
|
||||
2014-08-21 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* miscfuncs.cc (__import_address): Cover the first dereference to imp
|
||||
|
|
|
@ -638,10 +638,7 @@ init_cygheap::find_tls (int sig, bool& issig_wait)
|
|||
_cygtls *t = NULL;
|
||||
issig_wait = false;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
threadlist[ix]->remove (INFINITE);
|
||||
else
|
||||
__try
|
||||
{
|
||||
ix = -1;
|
||||
/* Scan thread list looking for valid signal-delivery candidates */
|
||||
|
@ -652,11 +649,15 @@ init_cygheap::find_tls (int sig, bool& issig_wait)
|
|||
{
|
||||
t = cygheap->threadlist[ix];
|
||||
issig_wait = true;
|
||||
goto out;
|
||||
__leave;
|
||||
}
|
||||
else if (!t && !sigismember (&(threadlist[ix]->sigmask), sig))
|
||||
t = cygheap->threadlist[ix];
|
||||
}
|
||||
out:
|
||||
__except (NO_ERROR)
|
||||
{
|
||||
threadlist[ix]->remove (INFINITE);
|
||||
}
|
||||
__endtry
|
||||
return t;
|
||||
}
|
||||
|
|
|
@ -193,7 +193,7 @@ _cygtls::remove (DWORD wait)
|
|||
free_local (servent_buf);
|
||||
free_local (hostent_buf);
|
||||
/* Free temporary TLS path buffers. */
|
||||
locals.pathbufs.destroy ();
|
||||
pathbufs.destroy ();
|
||||
/* Close timer handle. */
|
||||
if (locals.cw_timer)
|
||||
NtClose (locals.cw_timer);
|
||||
|
|
|
@ -44,18 +44,21 @@ details. */
|
|||
#else
|
||||
#pragma pack(push,4)
|
||||
#endif
|
||||
|
||||
/* Defined here to support auto rebuild of tlsoffsets.h. */
|
||||
class tls_pathbuf
|
||||
{
|
||||
int c_cnt;
|
||||
int w_cnt;
|
||||
/* Make sure that c_cnt and w_cnt are always the first two members of this
|
||||
class, and never change the size (32 bit), unless you also change the
|
||||
mov statements in sigbe! */
|
||||
uint32_t c_cnt;
|
||||
uint32_t w_cnt;
|
||||
char *c_buf[TP_NUM_C_BUFS];
|
||||
WCHAR *w_buf[TP_NUM_W_BUFS];
|
||||
|
||||
public:
|
||||
void destroy ();
|
||||
friend class tmp_pathbuf;
|
||||
friend class _cygtls;
|
||||
friend class san;
|
||||
};
|
||||
|
||||
|
@ -129,8 +132,6 @@ struct _local_storage
|
|||
/* thread.cc */
|
||||
HANDLE cw_timer;
|
||||
|
||||
/* All functions requiring temporary path buffers. */
|
||||
tls_pathbuf pathbufs;
|
||||
char ttybuf[32];
|
||||
};
|
||||
|
||||
|
@ -188,6 +189,7 @@ public:
|
|||
struct pthread *tid;
|
||||
class cygthread *_ctinfo;
|
||||
class san *andreas;
|
||||
tls_pathbuf pathbufs;
|
||||
waitq wq;
|
||||
int sig;
|
||||
unsigned incyg;
|
||||
|
@ -281,34 +283,25 @@ const int CYGTLS_PADSIZE = 12700;
|
|||
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 *_sig_tls;
|
||||
|
||||
#ifndef __x86_64__
|
||||
class san
|
||||
{
|
||||
san *_clemente;
|
||||
jmp_buf _context;
|
||||
int _errno;
|
||||
unsigned _c_cnt;
|
||||
unsigned _w_cnt;
|
||||
public:
|
||||
int setup (int myerrno = 0) __attribute__ ((always_inline))
|
||||
int setup () __attribute__ ((always_inline))
|
||||
{
|
||||
_clemente = _my_tls.andreas;
|
||||
_my_tls.andreas = this;
|
||||
_errno = myerrno;
|
||||
_c_cnt = _my_tls.locals.pathbufs.c_cnt;
|
||||
_w_cnt = _my_tls.locals.pathbufs.w_cnt;
|
||||
return __sjfault (_context);
|
||||
}
|
||||
void leave () __attribute__ ((always_inline))
|
||||
{
|
||||
if (_errno)
|
||||
set_errno (_errno);
|
||||
/* Restore tls_pathbuf counters in case of error. */
|
||||
_my_tls.locals.pathbufs.c_cnt = _c_cnt;
|
||||
_my_tls.locals.pathbufs.w_cnt = _w_cnt;
|
||||
__ljfault (_context, 1);
|
||||
}
|
||||
void reset () __attribute__ ((always_inline))
|
||||
|
@ -324,17 +317,73 @@ public:
|
|||
~myfault () __attribute__ ((always_inline)) { sebastian.reset (); }
|
||||
inline int faulted () __attribute__ ((always_inline))
|
||||
{
|
||||
return sebastian.setup (0);
|
||||
}
|
||||
inline int faulted (void const *obj, int myerrno = 0) __attribute__ ((always_inline))
|
||||
{
|
||||
return !obj || !(*(const char **) obj) || sebastian.setup (myerrno);
|
||||
}
|
||||
inline int faulted (int myerrno) __attribute__ ((always_inline))
|
||||
{
|
||||
return sebastian.setup (myerrno);
|
||||
return sebastian.setup ();
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Exception handling macros. These are required because SEH differs a lot
|
||||
between 32 and 64 bit. Essentially, on 64 bit, we have to create compile
|
||||
time SEH tables which define the handler and try/except labels, while on
|
||||
32 bit we can simply set up an SJLJ handler within the myfault class. */
|
||||
#define __mem_barrier __asm__ __volatile__ ("" ::: "memory")
|
||||
#ifdef __x86_64__
|
||||
#define __try \
|
||||
{ \
|
||||
__label__ __l_try, __l_except, __l_endtry; \
|
||||
__mem_barrier; \
|
||||
__asm__ goto ("\n" \
|
||||
" .seh_handler _ZN9exception7myfaultEP17_EXCEPTION_RECORDPvP8_CONTEXTP19_DISPATCHER_CONTEXT, @except \n" \
|
||||
" .seh_handlerdata \n" \
|
||||
" .long 1 \n" \
|
||||
" .rva %l[__l_try],%l[__l_endtry],%l[__l_except],%l[__l_except] \n" \
|
||||
" .seh_code \n" \
|
||||
: : : : __l_try, __l_endtry, __l_except); \
|
||||
{ \
|
||||
__l_try: \
|
||||
__mem_barrier;
|
||||
|
||||
#define __leave \
|
||||
goto __l_endtry
|
||||
|
||||
#define __except(__errno) \
|
||||
goto __l_endtry; \
|
||||
} \
|
||||
{ \
|
||||
__l_except: \
|
||||
__mem_barrier; \
|
||||
if (__errno) \
|
||||
set_errno (__errno);
|
||||
|
||||
#define __endtry \
|
||||
} \
|
||||
__l_endtry: \
|
||||
__mem_barrier; \
|
||||
}
|
||||
|
||||
#else /* !__x86_64__ */
|
||||
#define __try \
|
||||
{ \
|
||||
myfault efault; \
|
||||
if (!efault.faulted ()) \
|
||||
{
|
||||
|
||||
#define __leave \
|
||||
goto __l_endtry
|
||||
|
||||
#define __except(__errno) \
|
||||
goto __l_endtry; \
|
||||
} \
|
||||
{ \
|
||||
if (__errno) \
|
||||
set_errno (__errno);
|
||||
|
||||
#define __endtry \
|
||||
} \
|
||||
__l_endtry: \
|
||||
__mem_barrier; \
|
||||
}
|
||||
#endif /* __x86_64__ */
|
||||
|
||||
class set_signal_arrived
|
||||
{
|
||||
|
|
|
@ -796,10 +796,6 @@ dll_crt0_0 ()
|
|||
|
||||
_main_tls = &_my_tls;
|
||||
|
||||
#ifdef __x86_64__
|
||||
exception::install_myfault_handler ();
|
||||
#endif
|
||||
|
||||
/* Initialize signal processing here, early, in the hopes that the creation
|
||||
of a thread early in the process will cause more predictability in memory
|
||||
layout for the main thread. */
|
||||
|
|
|
@ -28,16 +28,16 @@ details. */
|
|||
extern "C" int
|
||||
dirfd (DIR *dir)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
if (dir->__d_cookie != __DIRENT_COOKIE)
|
||||
__try
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
if (dir->__d_cookie == __DIRENT_COOKIE)
|
||||
return dir->__d_fd;
|
||||
syscall_printf ("-1 = dirfd (%p)", dir);
|
||||
return -1;
|
||||
set_errno (EINVAL);
|
||||
}
|
||||
return dir->__d_fd;
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Symbol kept for backward compatibility. Don't remove. Don't declare
|
||||
|
@ -93,79 +93,86 @@ fdopendir (int fd)
|
|||
static int
|
||||
readdir_worker (DIR *dir, dirent *de)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
return EFAULT;
|
||||
int res = 0;
|
||||
|
||||
if (dir->__d_cookie != __DIRENT_COOKIE)
|
||||
__try
|
||||
{
|
||||
syscall_printf ("%p = readdir (%p)", NULL, dir);
|
||||
return EBADF;
|
||||
}
|
||||
|
||||
de->d_ino = 0;
|
||||
de->d_type = DT_UNKNOWN;
|
||||
memset (&de->__d_unused1, 0, sizeof (de->__d_unused1));
|
||||
|
||||
int res = ((fhandler_base *) dir->__fh)->readdir (dir, de);
|
||||
|
||||
if (res == ENMFILE)
|
||||
{
|
||||
if (!(dir->__flags & dirent_saw_dot))
|
||||
if (dir->__d_cookie != __DIRENT_COOKIE)
|
||||
{
|
||||
strcpy (de->d_name, ".");
|
||||
dir->__flags |= dirent_saw_dot;
|
||||
dir->__d_position++;
|
||||
res = 0;
|
||||
}
|
||||
else if (!(dir->__flags & dirent_saw_dot_dot))
|
||||
{
|
||||
strcpy (de->d_name, "..");
|
||||
dir->__flags |= dirent_saw_dot_dot;
|
||||
dir->__d_position++;
|
||||
res = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!res && !de->d_ino)
|
||||
{
|
||||
bool is_dot = false;
|
||||
bool is_dot_dot = false;
|
||||
|
||||
if (de->d_name[0] == '.')
|
||||
{
|
||||
if (de->d_name[1] == '\0')
|
||||
is_dot = true;
|
||||
else if (de->d_name[1] == '.' && de->d_name[2] == '\0')
|
||||
is_dot_dot = true;
|
||||
syscall_printf ("%p = readdir (%p)", NULL, dir);
|
||||
res = EBADF;
|
||||
__leave;
|
||||
}
|
||||
|
||||
if (is_dot_dot && !(dir->__flags & dirent_isroot))
|
||||
de->d_ino = readdir_get_ino (((fhandler_base *) dir->__fh)->get_name (),
|
||||
true);
|
||||
else
|
||||
de->d_ino = 0;
|
||||
de->d_type = DT_UNKNOWN;
|
||||
memset (&de->__d_unused1, 0, sizeof (de->__d_unused1));
|
||||
|
||||
res = ((fhandler_base *) dir->__fh)->readdir (dir, de);
|
||||
|
||||
if (res == ENMFILE)
|
||||
{
|
||||
/* Compute d_ino by combining filename hash with directory hash. */
|
||||
de->d_ino = ((fhandler_base *) dir->__fh)->get_ino ();
|
||||
if (!is_dot && !is_dot_dot)
|
||||
if (!(dir->__flags & dirent_saw_dot))
|
||||
{
|
||||
PUNICODE_STRING w32name =
|
||||
((fhandler_base *) dir->__fh)->pc.get_nt_native_path ();
|
||||
DWORD devn = ((fhandler_base *) dir->__fh)->get_device ();
|
||||
/* Paths below /proc don't have a Win32 pendant. */
|
||||
if (isproc_dev (devn))
|
||||
de->d_ino = hash_path_name (de->d_ino, L"/");
|
||||
else if (w32name->Buffer[w32name->Length / sizeof (WCHAR) - 1]
|
||||
!= L'\\')
|
||||
de->d_ino = hash_path_name (de->d_ino, L"\\");
|
||||
de->d_ino = hash_path_name (de->d_ino, de->d_name);
|
||||
strcpy (de->d_name, ".");
|
||||
dir->__flags |= dirent_saw_dot;
|
||||
dir->__d_position++;
|
||||
res = 0;
|
||||
}
|
||||
else if (!(dir->__flags & dirent_saw_dot_dot))
|
||||
{
|
||||
strcpy (de->d_name, "..");
|
||||
dir->__flags |= dirent_saw_dot_dot;
|
||||
dir->__d_position++;
|
||||
res = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* This fills out the old 32 bit d_ino field for old applications,
|
||||
build under Cygwin before 1.5.x. */
|
||||
de->__d_internal1 = de->d_ino;
|
||||
|
||||
if (!res && !de->d_ino)
|
||||
{
|
||||
bool is_dot = false;
|
||||
bool is_dot_dot = false;
|
||||
|
||||
if (de->d_name[0] == '.')
|
||||
{
|
||||
if (de->d_name[1] == '\0')
|
||||
is_dot = true;
|
||||
else if (de->d_name[1] == '.' && de->d_name[2] == '\0')
|
||||
is_dot_dot = true;
|
||||
}
|
||||
|
||||
if (is_dot_dot && !(dir->__flags & dirent_isroot))
|
||||
de->d_ino = readdir_get_ino (((fhandler_base *)
|
||||
dir->__fh)->get_name (),
|
||||
true);
|
||||
else
|
||||
{
|
||||
/* Compute d_ino by combining filename hash with directory hash. */
|
||||
de->d_ino = ((fhandler_base *) dir->__fh)->get_ino ();
|
||||
if (!is_dot && !is_dot_dot)
|
||||
{
|
||||
PUNICODE_STRING w32name =
|
||||
((fhandler_base *) dir->__fh)->pc.get_nt_native_path ();
|
||||
DWORD devn = ((fhandler_base *) dir->__fh)->get_device ();
|
||||
/* Paths below /proc don't have a Win32 pendant. */
|
||||
if (isproc_dev (devn))
|
||||
de->d_ino = hash_path_name (de->d_ino, L"/");
|
||||
else if (w32name->Buffer[w32name->Length / sizeof (WCHAR) - 1]
|
||||
!= L'\\')
|
||||
de->d_ino = hash_path_name (de->d_ino, L"\\");
|
||||
de->d_ino = hash_path_name (de->d_ino, de->d_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* This fills out the old 32 bit d_ino field for old applications,
|
||||
build under Cygwin before 1.5.x. */
|
||||
de->__d_internal1 = de->d_ino;
|
||||
}
|
||||
__except (NO_ERROR)
|
||||
{
|
||||
res = EFAULT;
|
||||
}
|
||||
__endtry
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -200,16 +207,15 @@ readdir_r (DIR *__restrict dir, dirent *__restrict de, dirent **__restrict ode)
|
|||
extern "C" long
|
||||
telldir (DIR *dir)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
if (dir->__d_cookie != __DIRENT_COOKIE)
|
||||
__try
|
||||
{
|
||||
if (dir->__d_cookie == __DIRENT_COOKIE)
|
||||
return ((fhandler_base *) dir->__fh)->telldir (dir);
|
||||
set_errno (EBADF);
|
||||
return -1;
|
||||
}
|
||||
return ((fhandler_base *) dir->__fh)->telldir (dir);
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* telldir was never defined using off_t in POSIX, only in early versions
|
||||
|
@ -225,14 +231,17 @@ telldir64 (DIR *dir)
|
|||
extern "C" void
|
||||
seekdir (DIR *dir, long loc)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return;
|
||||
|
||||
if (dir->__d_cookie != __DIRENT_COOKIE)
|
||||
return;
|
||||
dir->__flags &= dirent_info_mask;
|
||||
return ((fhandler_base *) dir->__fh)->seekdir (dir, loc);
|
||||
__try
|
||||
{
|
||||
if (dir->__d_cookie == __DIRENT_COOKIE)
|
||||
{
|
||||
dir->__flags &= dirent_info_mask;
|
||||
((fhandler_base *) dir->__fh)->seekdir (dir, loc);
|
||||
}
|
||||
set_errno (EINVAL); /* Diagnosis */
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
}
|
||||
|
||||
/* seekdir was never defined using off_t in POSIX, only in early versions
|
||||
|
@ -248,42 +257,45 @@ seekdir64 (DIR *dir, off_t loc)
|
|||
extern "C" void
|
||||
rewinddir (DIR *dir)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return;
|
||||
|
||||
if (dir->__d_cookie != __DIRENT_COOKIE)
|
||||
return;
|
||||
dir->__flags &= dirent_info_mask;
|
||||
return ((fhandler_base *) dir->__fh)->rewinddir (dir);
|
||||
__try
|
||||
{
|
||||
if (dir->__d_cookie == __DIRENT_COOKIE)
|
||||
{
|
||||
dir->__flags &= dirent_info_mask;
|
||||
((fhandler_base *) dir->__fh)->rewinddir (dir);
|
||||
}
|
||||
set_errno (EINVAL); /* Diagnosis */
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
}
|
||||
|
||||
/* closedir: POSIX 5.1.2.1 */
|
||||
extern "C" int
|
||||
closedir (DIR *dir)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
if (dir->__d_cookie != __DIRENT_COOKIE)
|
||||
__try
|
||||
{
|
||||
if (dir->__d_cookie == __DIRENT_COOKIE)
|
||||
{
|
||||
/* Reset the marker in case the caller tries to use `dir' again. */
|
||||
dir->__d_cookie = 0;
|
||||
|
||||
int res = ((fhandler_base *) dir->__fh)->closedir (dir);
|
||||
|
||||
close (dir->__d_fd);
|
||||
free (dir->__d_dirname);
|
||||
free (dir->__d_dirent);
|
||||
free (dir);
|
||||
syscall_printf ("%R = closedir(%p)", res, dir);
|
||||
return res;
|
||||
}
|
||||
set_errno (EBADF);
|
||||
syscall_printf ("%R = closedir(%p)", -1, dir);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Reset the marker in case the caller tries to use `dir' again. */
|
||||
dir->__d_cookie = 0;
|
||||
|
||||
int res = ((fhandler_base *) dir->__fh)->closedir (dir);
|
||||
|
||||
close (dir->__d_fd);
|
||||
free (dir->__d_dirname);
|
||||
free (dir->__d_dirent);
|
||||
free (dir);
|
||||
syscall_printf ("%R = closedir(%p)", res, dir);
|
||||
return res;
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
syscall_printf ("%R = closedir(%p)", -1, dir);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* mkdir: POSIX 5.4.1.1 */
|
||||
|
@ -294,43 +306,42 @@ mkdir (const char *dir, mode_t mode)
|
|||
fhandler_base *fh = NULL;
|
||||
tmp_pathbuf tp;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
/* POSIX says mkdir("symlink-to-missing/") should create the
|
||||
directory "missing", but Linux rejects it with EEXIST. Copy
|
||||
Linux behavior for now. */
|
||||
|
||||
if (!*dir)
|
||||
__try
|
||||
{
|
||||
set_errno (ENOENT);
|
||||
goto done;
|
||||
}
|
||||
if (isdirsep (dir[strlen (dir) - 1]))
|
||||
{
|
||||
/* This converts // to /, but since both give EEXIST, we're okay. */
|
||||
char *buf;
|
||||
char *p = stpcpy (buf = tp.c_get (), dir) - 1;
|
||||
dir = buf;
|
||||
while (p > dir && isdirsep (*p))
|
||||
*p-- = '\0';
|
||||
}
|
||||
if (!(fh = build_fh_name (dir, PC_SYM_NOFOLLOW)))
|
||||
goto done; /* errno already set */;
|
||||
/* POSIX says mkdir("symlink-to-missing/") should create the
|
||||
directory "missing", but Linux rejects it with EEXIST. Copy
|
||||
Linux behavior for now. */
|
||||
|
||||
if (fh->error ())
|
||||
{
|
||||
debug_printf ("got %d error from build_fh_name", fh->error ());
|
||||
set_errno (fh->error ());
|
||||
}
|
||||
else if (has_dot_last_component (dir, true))
|
||||
set_errno (fh->exists () ? EEXIST : ENOENT);
|
||||
else if (!fh->mkdir (mode))
|
||||
res = 0;
|
||||
delete fh;
|
||||
if (!*dir)
|
||||
{
|
||||
set_errno (ENOENT);
|
||||
__leave;
|
||||
}
|
||||
if (isdirsep (dir[strlen (dir) - 1]))
|
||||
{
|
||||
/* This converts // to /, but since both give EEXIST, we're okay. */
|
||||
char *buf;
|
||||
char *p = stpcpy (buf = tp.c_get (), dir) - 1;
|
||||
dir = buf;
|
||||
while (p > dir && isdirsep (*p))
|
||||
*p-- = '\0';
|
||||
}
|
||||
if (!(fh = build_fh_name (dir, PC_SYM_NOFOLLOW)))
|
||||
__leave; /* errno already set */;
|
||||
|
||||
done:
|
||||
if (fh->error ())
|
||||
{
|
||||
debug_printf ("got %d error from build_fh_name", fh->error ());
|
||||
set_errno (fh->error ());
|
||||
}
|
||||
else if (has_dot_last_component (dir, true))
|
||||
set_errno (fh->exists () ? EEXIST : ENOENT);
|
||||
else if (!fh->mkdir (mode))
|
||||
res = 0;
|
||||
delete fh;
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
syscall_printf ("%R = mkdir(%s, %d)", res, dir, mode);
|
||||
return res;
|
||||
}
|
||||
|
@ -342,30 +353,28 @@ rmdir (const char *dir)
|
|||
int res = -1;
|
||||
fhandler_base *fh = NULL;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
if (!(fh = build_fh_name (dir, PC_SYM_NOFOLLOW)))
|
||||
goto done; /* errno already set */;
|
||||
|
||||
if (fh->error ())
|
||||
__try
|
||||
{
|
||||
debug_printf ("got %d error from build_fh_name", fh->error ());
|
||||
set_errno (fh->error ());
|
||||
if (!(fh = build_fh_name (dir, PC_SYM_NOFOLLOW)))
|
||||
__leave; /* errno already set */;
|
||||
|
||||
if (fh->error ())
|
||||
{
|
||||
debug_printf ("got %d error from build_fh_name", fh->error ());
|
||||
set_errno (fh->error ());
|
||||
}
|
||||
else if (!fh->exists ())
|
||||
set_errno (ENOENT);
|
||||
else if (has_dot_last_component (dir, false))
|
||||
set_errno (EINVAL);
|
||||
else if (isdev_dev (fh->dev ()))
|
||||
set_errno (ENOTEMPTY);
|
||||
else if (!fh->rmdir ())
|
||||
res = 0;
|
||||
delete fh;
|
||||
}
|
||||
else if (!fh->exists ())
|
||||
set_errno (ENOENT);
|
||||
else if (has_dot_last_component (dir, false))
|
||||
set_errno (EINVAL);
|
||||
else if (isdev_dev (fh->dev ()))
|
||||
set_errno (ENOTEMPTY);
|
||||
else if (!fh->rmdir ())
|
||||
res = 0;
|
||||
|
||||
delete fh;
|
||||
|
||||
done:
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
syscall_printf ("%R = rmdir(%s)", res, dir);
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
process's environment.
|
||||
|
||||
Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
|
||||
2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||
2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
This software is a copyrighted work licensed under the terms of the
|
||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||
|
@ -664,19 +664,22 @@ _addenv (const char *name, const char *value, int overwrite)
|
|||
extern "C" int
|
||||
putenv (char *str)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
if (*str)
|
||||
__try
|
||||
{
|
||||
char *eq = strchr (str, '=');
|
||||
if (eq)
|
||||
return _addenv (str, eq + 1, -1);
|
||||
if (*str)
|
||||
{
|
||||
char *eq = strchr (str, '=');
|
||||
if (eq)
|
||||
return _addenv (str, eq + 1, -1);
|
||||
|
||||
/* Remove str from the environment. */
|
||||
unsetenv (str);
|
||||
/* Remove str from the environment. */
|
||||
unsetenv (str);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set the value of the environment variable "name" to be
|
||||
|
@ -684,15 +687,18 @@ putenv (char *str)
|
|||
extern "C" int
|
||||
setenv (const char *name, const char *value, int overwrite)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
if (!name || !*name || strchr (name, '='))
|
||||
__try
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
if (!name || !*name || strchr (name, '='))
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
__leave;
|
||||
}
|
||||
return _addenv (name, value, !!overwrite);
|
||||
}
|
||||
return _addenv (name, value, !!overwrite);
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Delete environment variable "name". */
|
||||
|
@ -701,22 +707,26 @@ unsetenv (const char *name)
|
|||
{
|
||||
register char **e;
|
||||
int offset;
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
if (!name || *name == '\0' || strchr (name, '='))
|
||||
|
||||
__try
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
if (!name || *name == '\0' || strchr (name, '='))
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
__leave;
|
||||
}
|
||||
|
||||
while (my_findenv (name, &offset)) /* if set multiple times */
|
||||
/* Move up the rest of the array */
|
||||
for (e = cur_environ () + offset; ; e++)
|
||||
if (!(*e = *(e + 1)))
|
||||
break;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (my_findenv (name, &offset)) /* if set multiple times */
|
||||
/* Move up the rest of the array */
|
||||
for (e = cur_environ () + offset; ; e++)
|
||||
if (!(*e = *(e + 1)))
|
||||
break;
|
||||
|
||||
return 0;
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Minimal list of Windows vars which must be converted to uppercase.
|
||||
|
@ -822,96 +832,101 @@ environ_init (char **envp, int envc)
|
|||
bool envp_passed_in;
|
||||
bool got_something_from_registry;
|
||||
static char NO_COPY cygterm[] = "TERM=cygwin";
|
||||
myfault efault;
|
||||
tmp_pathbuf tp;
|
||||
|
||||
if (efault.faulted ())
|
||||
api_fatal ("internal error reading the windows environment - too many environment variables?");
|
||||
|
||||
char *tmpbuf = tp.t_get ();
|
||||
got_something_from_registry = regopt (L"default", tmpbuf);
|
||||
if (myself->progname[0])
|
||||
got_something_from_registry = regopt (myself->progname, tmpbuf)
|
||||
|| got_something_from_registry;
|
||||
|
||||
if (!envp)
|
||||
envp_passed_in = 0;
|
||||
else
|
||||
__try
|
||||
{
|
||||
envc++;
|
||||
envc *= sizeof (char *);
|
||||
char **newenv = (char **) malloc (envc);
|
||||
memcpy (newenv, envp, envc);
|
||||
cfree (envp);
|
||||
char *tmpbuf = tp.t_get ();
|
||||
got_something_from_registry = regopt (L"default", tmpbuf);
|
||||
if (myself->progname[0])
|
||||
got_something_from_registry = regopt (myself->progname, tmpbuf)
|
||||
|| got_something_from_registry;
|
||||
|
||||
/* Older applications relied on the fact that cygwin malloced elements of the
|
||||
environment list. */
|
||||
envp = newenv;
|
||||
if (ENVMALLOC)
|
||||
for (char **e = newenv; *e; e++)
|
||||
{
|
||||
char *p = *e;
|
||||
*e = strdup (p);
|
||||
cfree (p);
|
||||
}
|
||||
envp_passed_in = 1;
|
||||
goto out;
|
||||
if (!envp)
|
||||
envp_passed_in = 0;
|
||||
else
|
||||
{
|
||||
envc++;
|
||||
envc *= sizeof (char *);
|
||||
char **newenv = (char **) malloc (envc);
|
||||
memcpy (newenv, envp, envc);
|
||||
cfree (envp);
|
||||
|
||||
/* Older applications relied on the fact that cygwin malloced elements of the
|
||||
environment list. */
|
||||
envp = newenv;
|
||||
if (ENVMALLOC)
|
||||
for (char **e = newenv; *e; e++)
|
||||
{
|
||||
char *p = *e;
|
||||
*e = strdup (p);
|
||||
cfree (p);
|
||||
}
|
||||
envp_passed_in = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Allocate space for environment + trailing NULL + CYGWIN env. */
|
||||
lastenviron = envp = (char **) malloc ((4 + (envc = 100)) * sizeof (char *));
|
||||
|
||||
rawenv = GetEnvironmentStringsW ();
|
||||
if (!rawenv)
|
||||
{
|
||||
system_printf ("GetEnvironmentStrings returned NULL, %E");
|
||||
return;
|
||||
}
|
||||
debug_printf ("GetEnvironmentStrings returned %p", rawenv);
|
||||
|
||||
/* Current directory information is recorded as variables of the
|
||||
form "=X:=X:\foo\bar; these must be changed into something legal
|
||||
(we could just ignore them but maybe an application will
|
||||
eventually want to use them). */
|
||||
for (i = 0, w = rawenv; *w != L'\0'; w = wcschr (w, L'\0') + 1, i++)
|
||||
{
|
||||
sys_wcstombs_alloc (&newp, HEAP_NOTHEAP, w);
|
||||
if (i >= envc)
|
||||
envp = (char **) realloc (envp, (4 + (envc += 100)) * sizeof (char *));
|
||||
envp[i] = newp;
|
||||
if (*newp == '=')
|
||||
*newp = '!';
|
||||
char *eq = strchrnul (newp, '=');
|
||||
ucenv (newp, eq); /* uppercase env vars which need it */
|
||||
if (*newp == 'T' && strncmp (newp, "TERM=", 5) == 0)
|
||||
sawTERM = 1;
|
||||
else if (*newp == 'C' && strncmp (newp, "CYGWIN=", 7) == 0)
|
||||
parse_options (newp + 7);
|
||||
if (*eq)
|
||||
posify_maybe (envp + i, *++eq ? eq : --eq, tmpbuf);
|
||||
debug_printf ("%p: %s", envp[i], envp[i]);
|
||||
}
|
||||
|
||||
if (!sawTERM)
|
||||
envp[i++] = strdup (cygterm);
|
||||
envp[i] = NULL;
|
||||
FreeEnvironmentStringsW (rawenv);
|
||||
|
||||
out:
|
||||
findenv_func = (char * (*)(const char*, int*)) my_findenv;
|
||||
__cygwin_environ = envp;
|
||||
update_envptrs ();
|
||||
if (envp_passed_in)
|
||||
{
|
||||
p = getenv ("CYGWIN");
|
||||
if (p)
|
||||
parse_options (p);
|
||||
}
|
||||
|
||||
if (got_something_from_registry)
|
||||
parse_options (NULL); /* possibly export registry settings to
|
||||
environment */
|
||||
MALLOC_CHECK;
|
||||
}
|
||||
|
||||
/* Allocate space for environment + trailing NULL + CYGWIN env. */
|
||||
lastenviron = envp = (char **) malloc ((4 + (envc = 100)) * sizeof (char *));
|
||||
|
||||
rawenv = GetEnvironmentStringsW ();
|
||||
if (!rawenv)
|
||||
__except (NO_ERROR)
|
||||
{
|
||||
system_printf ("GetEnvironmentStrings returned NULL, %E");
|
||||
return;
|
||||
api_fatal ("internal error reading the windows environment "
|
||||
"- too many environment variables?");
|
||||
}
|
||||
debug_printf ("GetEnvironmentStrings returned %p", rawenv);
|
||||
|
||||
/* Current directory information is recorded as variables of the
|
||||
form "=X:=X:\foo\bar; these must be changed into something legal
|
||||
(we could just ignore them but maybe an application will
|
||||
eventually want to use them). */
|
||||
for (i = 0, w = rawenv; *w != L'\0'; w = wcschr (w, L'\0') + 1, i++)
|
||||
{
|
||||
sys_wcstombs_alloc (&newp, HEAP_NOTHEAP, w);
|
||||
if (i >= envc)
|
||||
envp = (char **) realloc (envp, (4 + (envc += 100)) * sizeof (char *));
|
||||
envp[i] = newp;
|
||||
if (*newp == '=')
|
||||
*newp = '!';
|
||||
char *eq = strchrnul (newp, '=');
|
||||
ucenv (newp, eq); /* uppercase env vars which need it */
|
||||
if (*newp == 'T' && strncmp (newp, "TERM=", 5) == 0)
|
||||
sawTERM = 1;
|
||||
else if (*newp == 'C' && strncmp (newp, "CYGWIN=", 7) == 0)
|
||||
parse_options (newp + 7);
|
||||
if (*eq)
|
||||
posify_maybe (envp + i, *++eq ? eq : --eq, tmpbuf);
|
||||
debug_printf ("%p: %s", envp[i], envp[i]);
|
||||
}
|
||||
|
||||
if (!sawTERM)
|
||||
envp[i++] = strdup (cygterm);
|
||||
envp[i] = NULL;
|
||||
FreeEnvironmentStringsW (rawenv);
|
||||
|
||||
out:
|
||||
findenv_func = (char * (*)(const char*, int*)) my_findenv;
|
||||
__cygwin_environ = envp;
|
||||
update_envptrs ();
|
||||
if (envp_passed_in)
|
||||
{
|
||||
p = getenv ("CYGWIN");
|
||||
if (p)
|
||||
parse_options (p);
|
||||
}
|
||||
|
||||
if (got_something_from_registry)
|
||||
parse_options (NULL); /* possibly export registry settings to
|
||||
environment */
|
||||
MALLOC_CHECK;
|
||||
__endtry
|
||||
}
|
||||
|
||||
/* Function called by qsort to sort environment strings. */
|
||||
|
|
|
@ -94,8 +94,10 @@ to install your own exception filter. This one is documented.
|
|||
a teensy bit of detail of the innards of exception handling (i.e. what we
|
||||
have to do). */
|
||||
|
||||
typedef int (exception_handler) (EXCEPTION_RECORD *, struct _exception_list *,
|
||||
CONTEXT *, void *);
|
||||
typedef EXCEPTION_DISPOSITION (exception_handler) (EXCEPTION_RECORD *,
|
||||
struct _exception_list *,
|
||||
CONTEXT *,
|
||||
void *);
|
||||
|
||||
typedef struct _exception_list
|
||||
{
|
||||
|
@ -104,70 +106,53 @@ typedef struct _exception_list
|
|||
} exception_list;
|
||||
|
||||
extern exception_list *_except_list asm ("%fs:0");
|
||||
#else
|
||||
typedef void exception_list;
|
||||
#endif /* !__x86_64 */
|
||||
typedef void *PDISPATCHER_CONTEXT;
|
||||
|
||||
class exception
|
||||
{
|
||||
#ifdef __x86_64__
|
||||
static LONG myfault_handle (LPEXCEPTION_POINTERS ep);
|
||||
#else
|
||||
exception_list el;
|
||||
exception_list *save;
|
||||
#endif /* __x86_64__ */
|
||||
static int handle (EXCEPTION_RECORD *, exception_list *, CONTEXT *, void *);
|
||||
static EXCEPTION_DISPOSITION handle (EXCEPTION_RECORD *, exception_list *,
|
||||
CONTEXT *, PDISPATCHER_CONTEXT);
|
||||
public:
|
||||
exception () __attribute__ ((always_inline))
|
||||
{
|
||||
/* Install SEH handler. */
|
||||
save = _except_list;
|
||||
el.handler = handle;
|
||||
el.prev = _except_list;
|
||||
_except_list = ⪙
|
||||
};
|
||||
~exception () __attribute__ ((always_inline)) { _except_list = save; }
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
#define exception_list void
|
||||
typedef struct _DISPATCHER_CONTEXT *PDISPATCHER_CONTEXT;
|
||||
|
||||
class exception
|
||||
{
|
||||
#ifdef __x86_64__
|
||||
static EXCEPTION_DISPOSITION myfault (EXCEPTION_RECORD *, exception_list *,
|
||||
CONTEXT *, PDISPATCHER_CONTEXT);
|
||||
#endif
|
||||
static EXCEPTION_DISPOSITION handle (EXCEPTION_RECORD *, exception_list *,
|
||||
CONTEXT *, PDISPATCHER_CONTEXT);
|
||||
public:
|
||||
exception () __attribute__ ((always_inline))
|
||||
{
|
||||
/* Install SEH handler. */
|
||||
asm volatile ("\n\
|
||||
1: \n\
|
||||
.seh_handler \
|
||||
_ZN9exception6handleEP17_EXCEPTION_RECORDPvP8_CONTEXTS2_, \
|
||||
_ZN9exception6handleEP17_EXCEPTION_RECORDPvP8_CONTEXTP19_DISPATCHER_CONTEXT, \
|
||||
@except \n\
|
||||
.seh_handlerdata \n\
|
||||
.long 1 \n\
|
||||
.rva 1b, 2f, 2f, 2f \n\
|
||||
.seh_code \n");
|
||||
#else
|
||||
save = _except_list;
|
||||
el.handler = handle;
|
||||
el.prev = _except_list;
|
||||
_except_list = ⪙
|
||||
#endif /* __x86_64__ */
|
||||
};
|
||||
#ifdef __x86_64__
|
||||
static void install_myfault_handler () __attribute__ ((always_inline))
|
||||
{
|
||||
/* Install myfault exception handler as VEH. Here's what happens:
|
||||
Some Windows DLLs (advapi32, for instance) are using SEH to catch
|
||||
exceptions inside its own functions. If we install a VEH handler
|
||||
to catch all exceptions, our Cygwin VEH handler would illegitimatly
|
||||
handle exceptions inside of Windows DLLs which are usually handled
|
||||
by its own SEH handler. So, for standard exceptions we use an SEH
|
||||
handler as installed in the constructor above so as not to override
|
||||
the SEH handlers in Windows DLLs.
|
||||
But we have a special case, myfault handling. The myfault handling
|
||||
catches exceptions inside of the Cygwin DLL, some of them entirely
|
||||
expected as in verifyable_object_isvalid. The ultimately right thing
|
||||
to do would be to install SEH handlers for each of these cases.
|
||||
But there are two problems with that:
|
||||
|
||||
1. It would be a massive and, partially unreliable change in the
|
||||
calling functions due to the incomplete SEH support in GCC.
|
||||
|
||||
2. It doesn't always work. Certain DLLs appear to call Cygwin
|
||||
functions during DLL initialization while the SEH handler is
|
||||
not installed in the active call frame. For these cases we
|
||||
need a more generic approach.
|
||||
|
||||
So, what we do here is to install a myfault VEH handler. This
|
||||
function is called from dll_crt0_0, so the myfault handler is
|
||||
available very early. */
|
||||
AddVectoredExceptionHandler (1, myfault_handle);
|
||||
}
|
||||
~exception () __attribute__ ((always_inline))
|
||||
{
|
||||
asm volatile ("\n\
|
||||
|
@ -175,11 +160,10 @@ public:
|
|||
2: \n\
|
||||
nop \n");
|
||||
}
|
||||
#else
|
||||
~exception () __attribute__ ((always_inline)) { _except_list = save; }
|
||||
#endif /* !__x86_64__ */
|
||||
};
|
||||
|
||||
#endif /* !__x86_64 */
|
||||
|
||||
class cygwin_exception
|
||||
{
|
||||
PUINT_PTR framep;
|
||||
|
|
|
@ -341,38 +341,41 @@ void
|
|||
cygwin_exception::dumpstack ()
|
||||
{
|
||||
static bool already_dumped;
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
return;
|
||||
|
||||
if (already_dumped || cygheap->rlim_core == 0Ul)
|
||||
return;
|
||||
already_dumped = true;
|
||||
open_stackdumpfile ();
|
||||
|
||||
if (e)
|
||||
dump_exception ();
|
||||
|
||||
int i;
|
||||
|
||||
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");
|
||||
#endif
|
||||
for (i = 0; i < 16 && thestack++; i++)
|
||||
__try
|
||||
{
|
||||
small_printf (_AFMT " " _AFMT, thestack.sf.AddrFrame.Offset,
|
||||
thestack.sf.AddrPC.Offset);
|
||||
for (unsigned j = 0; j < NPARAMS; j++)
|
||||
small_printf ("%s" _AFMT, j == 0 ? " (" : ", ", thestack.sf.Params[j]);
|
||||
small_printf (")\r\n");
|
||||
if (already_dumped || cygheap->rlim_core == 0Ul)
|
||||
return;
|
||||
already_dumped = true;
|
||||
open_stackdumpfile ();
|
||||
|
||||
if (e)
|
||||
dump_exception ();
|
||||
|
||||
int i;
|
||||
|
||||
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");
|
||||
#endif
|
||||
for (i = 0; i < 16 && thestack++; i++)
|
||||
{
|
||||
small_printf (_AFMT " " _AFMT, thestack.sf.AddrFrame.Offset,
|
||||
thestack.sf.AddrPC.Offset);
|
||||
for (unsigned j = 0; j < NPARAMS; j++)
|
||||
small_printf ("%s" _AFMT, j == 0 ? " (" : ", ",
|
||||
thestack.sf.Params[j]);
|
||||
small_printf (")\r\n");
|
||||
}
|
||||
small_printf ("End of stack trace%s\n",
|
||||
i == 16 ? " (more stack frames may be present)" : "");
|
||||
if (h)
|
||||
NtClose (h);
|
||||
}
|
||||
small_printf ("End of stack trace%s\n",
|
||||
i == 16 ? " (more stack frames may be present)" : "");
|
||||
if (h)
|
||||
NtClose (h);
|
||||
__except (NO_ERROR) {}
|
||||
__endtry
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -549,40 +552,24 @@ rtl_unwind (exception_list *frame, PEXCEPTION_RECORD e)
|
|||
#endif /* __x86_64 */
|
||||
|
||||
#ifdef __x86_64__
|
||||
/* myfault vectored exception handler */
|
||||
LONG
|
||||
exception::myfault_handle (LPEXCEPTION_POINTERS ep)
|
||||
/* myfault exception handler. */
|
||||
EXCEPTION_DISPOSITION
|
||||
exception::myfault (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in,
|
||||
PDISPATCHER_CONTEXT dispatch)
|
||||
{
|
||||
_cygtls& me = _my_tls;
|
||||
|
||||
if (me.andreas)
|
||||
{
|
||||
/* Only handle the minimum amount of exceptions the myfault handler
|
||||
was designed for. */
|
||||
switch (ep->ExceptionRecord->ExceptionCode)
|
||||
{
|
||||
case STATUS_ACCESS_VIOLATION:
|
||||
case STATUS_DATATYPE_MISALIGNMENT:
|
||||
#if 0
|
||||
/* PAGE_GUARD-based stack commits are based on structured exception
|
||||
handling. Short-circuiting STATUS_STACK_OVERFLOW in a vectored
|
||||
exception handler disables that, which can ultimately result in
|
||||
a spurious SEGV. */
|
||||
case STATUS_STACK_OVERFLOW:
|
||||
#endif
|
||||
case STATUS_ARRAY_BOUNDS_EXCEEDED:
|
||||
me.andreas->leave (); /* Return from a "san" caught fault */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
PSCOPE_TABLE table = (PSCOPE_TABLE) dispatch->HandlerData;
|
||||
RtlUnwindEx (frame,
|
||||
(char *) dispatch->ImageBase + table->ScopeRecord[0].JumpTarget,
|
||||
e, 0, in, dispatch->HistoryTable);
|
||||
/* NOTREACHED, make gcc happy. */
|
||||
return ExceptionContinueSearch;
|
||||
}
|
||||
#endif /* __x86_64 */
|
||||
#endif
|
||||
|
||||
/* Main exception handler. */
|
||||
int
|
||||
exception::handle (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in, void *)
|
||||
EXCEPTION_DISPOSITION
|
||||
exception::handle (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in,
|
||||
PDISPATCHER_CONTEXT dispatch)
|
||||
{
|
||||
static bool NO_COPY debugging;
|
||||
_cygtls& me = _my_tls;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* fcntl.cc: fcntl syscall
|
||||
|
||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2008, 2009,
|
||||
2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||
2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -28,53 +28,54 @@ fcntl64 (int fd, int cmd, ...)
|
|||
|
||||
pthread_testcancel ();
|
||||
|
||||
debug_printf ("fcntl(%d, %d, ...)", fd, cmd);
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
cygheap_fdget cfd (fd, true);
|
||||
if (cfd < 0)
|
||||
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);
|
||||
arg = va_arg (args, intptr_t);
|
||||
va_end (args);
|
||||
|
||||
switch (cmd)
|
||||
__try
|
||||
{
|
||||
case F_DUPFD:
|
||||
case F_DUPFD_CLOEXEC:
|
||||
if (arg >= 0 && arg < OPEN_MAX_MAX)
|
||||
|
||||
debug_printf ("fcntl(%d, %d, ...)", fd, cmd);
|
||||
cygheap_fdget cfd (fd, true);
|
||||
if (cfd < 0)
|
||||
__leave;
|
||||
|
||||
/* 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);
|
||||
arg = va_arg (args, intptr_t);
|
||||
va_end (args);
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
int flags = cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0;
|
||||
res = cygheap->fdtab.dup3 (fd, cygheap_fdnew ((arg) - 1), flags);
|
||||
case F_DUPFD:
|
||||
case F_DUPFD_CLOEXEC:
|
||||
if (arg >= 0 && arg < OPEN_MAX_MAX)
|
||||
{
|
||||
int flags = cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0;
|
||||
res = cygheap->fdtab.dup3 (fd, cygheap_fdnew ((arg) - 1), flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
res = -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
res = cfd->fcntl (cmd, arg);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
res = -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
res = cfd->fcntl (cmd, arg);
|
||||
break;
|
||||
}
|
||||
done:
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
syscall_printf ("%R = fcntl(%d, %d, %ly)", res, fd, cmd, arg);
|
||||
return res;
|
||||
}
|
||||
|
@ -91,32 +92,34 @@ _fcntl (int fd, int cmd, ...)
|
|||
struct __flock32 *src = NULL;
|
||||
struct flock dst;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
va_start (args, cmd);
|
||||
arg = va_arg (args, intptr_t);
|
||||
va_end (args);
|
||||
if (cmd == F_GETLK || cmd == F_SETLK || cmd == F_SETLKW)
|
||||
__try
|
||||
{
|
||||
src = (struct __flock32 *) arg;
|
||||
dst.l_type = src->l_type;
|
||||
dst.l_whence = src->l_whence;
|
||||
dst.l_start = src->l_start;
|
||||
dst.l_len = src->l_len;
|
||||
dst.l_pid = src->l_pid;
|
||||
arg = (intptr_t) &dst;
|
||||
va_start (args, cmd);
|
||||
arg = va_arg (args, intptr_t);
|
||||
va_end (args);
|
||||
if (cmd == F_GETLK || cmd == F_SETLK || cmd == F_SETLKW)
|
||||
{
|
||||
src = (struct __flock32 *) arg;
|
||||
dst.l_type = src->l_type;
|
||||
dst.l_whence = src->l_whence;
|
||||
dst.l_start = src->l_start;
|
||||
dst.l_len = src->l_len;
|
||||
dst.l_pid = src->l_pid;
|
||||
arg = (intptr_t) &dst;
|
||||
}
|
||||
int res = fcntl64 (fd, cmd, arg);
|
||||
if (cmd == F_GETLK)
|
||||
{
|
||||
src->l_type = dst.l_type;
|
||||
src->l_whence = dst.l_whence;
|
||||
src->l_start = dst.l_start;
|
||||
src->l_len = dst.l_len;
|
||||
src->l_pid = (short) dst.l_pid;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
int res = fcntl64 (fd, cmd, arg);
|
||||
if (cmd == F_GETLK)
|
||||
{
|
||||
src->l_type = dst.l_type;
|
||||
src->l_whence = dst.l_whence;
|
||||
src->l_start = dst.l_start;
|
||||
src->l_len = dst.l_len;
|
||||
src->l_pid = (short) dst.l_pid;
|
||||
}
|
||||
return res;
|
||||
__except (EFAULT)
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -2293,14 +2293,17 @@ fhandler_socket::getpeereid (pid_t *pid, uid_t *euid, gid_t *egid)
|
|||
return -1;
|
||||
}
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
if (pid)
|
||||
*pid = sec_peer_pid;
|
||||
if (euid)
|
||||
*euid = sec_peer_uid;
|
||||
if (egid)
|
||||
*egid = sec_peer_gid;
|
||||
return 0;
|
||||
__try
|
||||
{
|
||||
if (pid)
|
||||
*pid = sec_peer_pid;
|
||||
if (euid)
|
||||
*euid = sec_peer_uid;
|
||||
if (egid)
|
||||
*egid = sec_peer_gid;
|
||||
return 0;
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
classes.
|
||||
|
||||
Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
|
||||
2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||
2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -977,159 +977,163 @@ mtinfo_drive::set_options (HANDLE mt, int32_t options)
|
|||
int
|
||||
mtinfo_drive::ioctl (HANDLE mt, unsigned int cmd, void *buf)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
return ERROR_NOACCESS;
|
||||
if (cmd == MTIOCTOP)
|
||||
__try
|
||||
{
|
||||
struct mtop *op = (struct mtop *) buf;
|
||||
if (lasterr == ERROR_BUS_RESET)
|
||||
if (cmd == MTIOCTOP)
|
||||
{
|
||||
/* If a bus reset occurs, block further access to this device
|
||||
until the user rewinds, unloads or in any other way tries
|
||||
to maintain a well-known tape position. */
|
||||
if (op->mt_op != MTREW && op->mt_op != MTOFFL
|
||||
&& op->mt_op != MTRETEN && op->mt_op != MTERASE
|
||||
&& op->mt_op != MTSEEK && op->mt_op != MTEOM)
|
||||
return ERROR_BUS_RESET;
|
||||
/* Try to maintain last lock state after bus reset. */
|
||||
if (lock >= auto_locked && PrepareTape (mt, TAPE_LOCK, FALSE))
|
||||
struct mtop *op = (struct mtop *) buf;
|
||||
if (lasterr == ERROR_BUS_RESET)
|
||||
{
|
||||
debug_printf ("Couldn't relock drive after bus reset.");
|
||||
lock = unlocked;
|
||||
/* If a bus reset occurs, block further access to this device
|
||||
until the user rewinds, unloads or in any other way tries
|
||||
to maintain a well-known tape position. */
|
||||
if (op->mt_op != MTREW && op->mt_op != MTOFFL
|
||||
&& op->mt_op != MTRETEN && op->mt_op != MTERASE
|
||||
&& op->mt_op != MTSEEK && op->mt_op != MTEOM)
|
||||
return ERROR_BUS_RESET;
|
||||
/* Try to maintain last lock state after bus reset. */
|
||||
if (lock >= auto_locked && PrepareTape (mt, TAPE_LOCK, FALSE))
|
||||
{
|
||||
debug_printf ("Couldn't relock drive after bus reset.");
|
||||
lock = unlocked;
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (op->mt_op)
|
||||
{
|
||||
case MTRESET:
|
||||
break;
|
||||
case MTFSF:
|
||||
set_pos (mt, TAPE_SPACE_FILEMARKS, op->mt_count, false);
|
||||
break;
|
||||
case MTBSF:
|
||||
set_pos (mt, TAPE_SPACE_FILEMARKS, -op->mt_count, false);
|
||||
break;
|
||||
case MTFSR:
|
||||
set_pos (mt, TAPE_SPACE_RELATIVE_BLOCKS, op->mt_count, false);
|
||||
break;
|
||||
case MTBSR:
|
||||
set_pos (mt, TAPE_SPACE_RELATIVE_BLOCKS, -op->mt_count, false);
|
||||
break;
|
||||
case MTWEOF:
|
||||
write_marks (mt, TAPE_FILEMARKS, op->mt_count);
|
||||
break;
|
||||
case MTREW:
|
||||
set_pos (mt, TAPE_REWIND, 0, false);
|
||||
break;
|
||||
case MTOFFL:
|
||||
case MTUNLOAD:
|
||||
prepare (mt, TAPE_UNLOAD);
|
||||
break;
|
||||
case MTNOP:
|
||||
lasterr = 0;
|
||||
break;
|
||||
case MTRETEN:
|
||||
if (!get_feature (TAPE_DRIVE_TENSION))
|
||||
lasterr = ERROR_INVALID_PARAMETER;
|
||||
else if (!set_pos (mt, TAPE_REWIND, 0, false))
|
||||
prepare (mt, TAPE_TENSION);
|
||||
break;
|
||||
case MTBSFM:
|
||||
set_pos (mt, TAPE_SPACE_FILEMARKS, -op->mt_count, true);
|
||||
break;
|
||||
case MTFSFM:
|
||||
set_pos (mt, TAPE_SPACE_FILEMARKS, op->mt_count, true);
|
||||
break;
|
||||
case MTEOM:
|
||||
if (fast_eom () && get_feature (TAPE_DRIVE_END_OF_DATA))
|
||||
set_pos (mt, TAPE_SPACE_END_OF_DATA, 0, false);
|
||||
else
|
||||
set_pos (mt, TAPE_SPACE_FILEMARKS, 32767, false);
|
||||
break;
|
||||
case MTERASE:
|
||||
erase (mt, TAPE_ERASE_LONG);
|
||||
break;
|
||||
case MTRAS1:
|
||||
case MTRAS2:
|
||||
case MTRAS3:
|
||||
lasterr = ERROR_INVALID_PARAMETER;
|
||||
break;
|
||||
case MTSETBLK:
|
||||
if (!get_feature (TAPE_DRIVE_SET_BLOCK_SIZE))
|
||||
{
|
||||
lasterr = ERROR_INVALID_PARAMETER;
|
||||
switch (op->mt_op)
|
||||
{
|
||||
case MTRESET:
|
||||
break;
|
||||
}
|
||||
if ((DWORD) op->mt_count == mp ()->BlockSize)
|
||||
{
|
||||
/* Nothing has changed. */
|
||||
case MTFSF:
|
||||
set_pos (mt, TAPE_SPACE_FILEMARKS, op->mt_count, false);
|
||||
break;
|
||||
case MTBSF:
|
||||
set_pos (mt, TAPE_SPACE_FILEMARKS, -op->mt_count, false);
|
||||
break;
|
||||
case MTFSR:
|
||||
set_pos (mt, TAPE_SPACE_RELATIVE_BLOCKS, op->mt_count, false);
|
||||
break;
|
||||
case MTBSR:
|
||||
set_pos (mt, TAPE_SPACE_RELATIVE_BLOCKS, -op->mt_count, false);
|
||||
break;
|
||||
case MTWEOF:
|
||||
write_marks (mt, TAPE_FILEMARKS, op->mt_count);
|
||||
break;
|
||||
case MTREW:
|
||||
set_pos (mt, TAPE_REWIND, 0, false);
|
||||
break;
|
||||
case MTOFFL:
|
||||
case MTUNLOAD:
|
||||
prepare (mt, TAPE_UNLOAD);
|
||||
break;
|
||||
case MTNOP:
|
||||
lasterr = 0;
|
||||
break;
|
||||
}
|
||||
if ((op->mt_count == 0 && !get_feature (TAPE_DRIVE_VARIABLE_BLOCK))
|
||||
|| (op->mt_count > 0
|
||||
&& ((DWORD) op->mt_count < dp ()->MinimumBlockSize
|
||||
|| (DWORD) op->mt_count > dp ()->MaximumBlockSize)))
|
||||
{
|
||||
case MTRETEN:
|
||||
if (!get_feature (TAPE_DRIVE_TENSION))
|
||||
lasterr = ERROR_INVALID_PARAMETER;
|
||||
else if (!set_pos (mt, TAPE_REWIND, 0, false))
|
||||
prepare (mt, TAPE_TENSION);
|
||||
break;
|
||||
case MTBSFM:
|
||||
set_pos (mt, TAPE_SPACE_FILEMARKS, -op->mt_count, true);
|
||||
break;
|
||||
case MTFSFM:
|
||||
set_pos (mt, TAPE_SPACE_FILEMARKS, op->mt_count, true);
|
||||
break;
|
||||
case MTEOM:
|
||||
if (fast_eom () && get_feature (TAPE_DRIVE_END_OF_DATA))
|
||||
set_pos (mt, TAPE_SPACE_END_OF_DATA, 0, false);
|
||||
else
|
||||
set_pos (mt, TAPE_SPACE_FILEMARKS, 32767, false);
|
||||
break;
|
||||
case MTERASE:
|
||||
erase (mt, TAPE_ERASE_LONG);
|
||||
break;
|
||||
case MTRAS1:
|
||||
case MTRAS2:
|
||||
case MTRAS3:
|
||||
lasterr = ERROR_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
if (set_blocksize (mt, op->mt_count)
|
||||
&& lasterr == ERROR_INVALID_FUNCTION)
|
||||
lasterr = ERROR_INVALID_BLOCK_LENGTH;
|
||||
break;
|
||||
case MTSEEK:
|
||||
if (get_feature (TAPE_DRIVE_LOGICAL_BLK))
|
||||
set_pos (mt, TAPE_LOGICAL_BLOCK, op->mt_count, false);
|
||||
else if (!get_pos (mt))
|
||||
set_pos (mt, TAPE_SPACE_RELATIVE_BLOCKS,
|
||||
op->mt_count - block, false);
|
||||
break;
|
||||
case MTTELL:
|
||||
if (!get_pos (mt))
|
||||
op->mt_count = (int) block;
|
||||
break;
|
||||
case MTFSS:
|
||||
set_pos (mt, TAPE_SPACE_SETMARKS, op->mt_count, false);
|
||||
break;
|
||||
case MTBSS:
|
||||
set_pos (mt, TAPE_SPACE_SETMARKS, -op->mt_count, false);
|
||||
break;
|
||||
case MTWSM:
|
||||
write_marks (mt, TAPE_SETMARKS, op->mt_count);
|
||||
break;
|
||||
case MTLOCK:
|
||||
prepare (mt, TAPE_LOCK);
|
||||
break;
|
||||
case MTUNLOCK:
|
||||
prepare (mt, TAPE_UNLOCK);
|
||||
break;
|
||||
case MTLOAD:
|
||||
prepare (mt, TAPE_LOAD);
|
||||
break;
|
||||
case MTCOMPRESSION:
|
||||
set_compression (mt, op->mt_count);
|
||||
break;
|
||||
case MTSETPART:
|
||||
set_partition (mt, op->mt_count);
|
||||
break;
|
||||
case MTMKPART:
|
||||
create_partitions (mt, op->mt_count);
|
||||
break;
|
||||
case MTSETDRVBUFFER:
|
||||
set_options (mt, op->mt_count);
|
||||
break;
|
||||
case MTSETDENSITY:
|
||||
default:
|
||||
lasterr = ERROR_INVALID_PARAMETER;
|
||||
break;
|
||||
case MTSETBLK:
|
||||
if (!get_feature (TAPE_DRIVE_SET_BLOCK_SIZE))
|
||||
{
|
||||
lasterr = ERROR_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
if ((DWORD) op->mt_count == mp ()->BlockSize)
|
||||
{
|
||||
/* Nothing has changed. */
|
||||
lasterr = 0;
|
||||
break;
|
||||
}
|
||||
if ((op->mt_count == 0 && !get_feature (TAPE_DRIVE_VARIABLE_BLOCK))
|
||||
|| (op->mt_count > 0
|
||||
&& ((DWORD) op->mt_count < dp ()->MinimumBlockSize
|
||||
|| (DWORD) op->mt_count > dp ()->MaximumBlockSize)))
|
||||
{
|
||||
lasterr = ERROR_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
if (set_blocksize (mt, op->mt_count)
|
||||
&& lasterr == ERROR_INVALID_FUNCTION)
|
||||
lasterr = ERROR_INVALID_BLOCK_LENGTH;
|
||||
break;
|
||||
case MTSEEK:
|
||||
if (get_feature (TAPE_DRIVE_LOGICAL_BLK))
|
||||
set_pos (mt, TAPE_LOGICAL_BLOCK, op->mt_count, false);
|
||||
else if (!get_pos (mt))
|
||||
set_pos (mt, TAPE_SPACE_RELATIVE_BLOCKS,
|
||||
op->mt_count - block, false);
|
||||
break;
|
||||
case MTTELL:
|
||||
if (!get_pos (mt))
|
||||
op->mt_count = (int) block;
|
||||
break;
|
||||
case MTFSS:
|
||||
set_pos (mt, TAPE_SPACE_SETMARKS, op->mt_count, false);
|
||||
break;
|
||||
case MTBSS:
|
||||
set_pos (mt, TAPE_SPACE_SETMARKS, -op->mt_count, false);
|
||||
break;
|
||||
case MTWSM:
|
||||
write_marks (mt, TAPE_SETMARKS, op->mt_count);
|
||||
break;
|
||||
case MTLOCK:
|
||||
prepare (mt, TAPE_LOCK);
|
||||
break;
|
||||
case MTUNLOCK:
|
||||
prepare (mt, TAPE_UNLOCK);
|
||||
break;
|
||||
case MTLOAD:
|
||||
prepare (mt, TAPE_LOAD);
|
||||
break;
|
||||
case MTCOMPRESSION:
|
||||
set_compression (mt, op->mt_count);
|
||||
break;
|
||||
case MTSETPART:
|
||||
set_partition (mt, op->mt_count);
|
||||
break;
|
||||
case MTMKPART:
|
||||
create_partitions (mt, op->mt_count);
|
||||
break;
|
||||
case MTSETDRVBUFFER:
|
||||
set_options (mt, op->mt_count);
|
||||
break;
|
||||
case MTSETDENSITY:
|
||||
default:
|
||||
lasterr = ERROR_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (cmd == MTIOCGET)
|
||||
get_status (mt, (struct mtget *) buf);
|
||||
else if (cmd == MTIOCPOS && !get_pos (mt))
|
||||
((struct mtpos *) buf)->mt_blkno = (long) block;
|
||||
}
|
||||
else if (cmd == MTIOCGET)
|
||||
get_status (mt, (struct mtget *) buf);
|
||||
else if (cmd == MTIOCPOS && !get_pos (mt))
|
||||
((struct mtpos *) buf)->mt_blkno = (long) block;
|
||||
|
||||
__except (NO_ERROR)
|
||||
{
|
||||
lasterr = ERROR_NOACCESS;
|
||||
}
|
||||
__endtry
|
||||
return lasterr;
|
||||
}
|
||||
|
||||
|
|
|
@ -1761,37 +1761,37 @@ flock (int fd, int operation)
|
|||
int cmd;
|
||||
struct flock fl = { 0, SEEK_SET, 0, 0, 0 };
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
cygheap_fdget cfd (fd, true);
|
||||
if (cfd < 0)
|
||||
goto done;
|
||||
|
||||
cmd = (operation & LOCK_NB) ? F_SETLK : F_SETLKW;
|
||||
switch (operation & (~LOCK_NB))
|
||||
__try
|
||||
{
|
||||
case LOCK_EX:
|
||||
fl.l_type = F_WRLCK;
|
||||
break;
|
||||
case LOCK_SH:
|
||||
fl.l_type = F_RDLCK;
|
||||
break;
|
||||
case LOCK_UN:
|
||||
fl.l_type = F_UNLCK;
|
||||
break;
|
||||
default:
|
||||
set_errno (EINVAL);
|
||||
goto done;
|
||||
cygheap_fdget cfd (fd, true);
|
||||
if (cfd < 0)
|
||||
__leave;
|
||||
|
||||
cmd = (operation & LOCK_NB) ? F_SETLK : F_SETLKW;
|
||||
switch (operation & (~LOCK_NB))
|
||||
{
|
||||
case LOCK_EX:
|
||||
fl.l_type = F_WRLCK;
|
||||
break;
|
||||
case LOCK_SH:
|
||||
fl.l_type = F_RDLCK;
|
||||
break;
|
||||
case LOCK_UN:
|
||||
fl.l_type = F_UNLCK;
|
||||
break;
|
||||
default:
|
||||
set_errno (EINVAL);
|
||||
__leave;
|
||||
}
|
||||
if (!cfd->mandatory_locking ())
|
||||
fl.l_type |= F_FLOCK;
|
||||
res = cfd->mandatory_locking () ? cfd->mand_lock (cmd, &fl)
|
||||
: cfd->lock (cmd, &fl);
|
||||
if ((res == -1) && ((get_errno () == EAGAIN) || (get_errno () == EACCES)))
|
||||
set_errno (EWOULDBLOCK);
|
||||
}
|
||||
if (!cfd->mandatory_locking ())
|
||||
fl.l_type |= F_FLOCK;
|
||||
res = cfd->mandatory_locking () ? cfd->mand_lock (cmd, &fl)
|
||||
: cfd->lock (cmd, &fl);
|
||||
if ((res == -1) && ((get_errno () == EAGAIN) || (get_errno () == EACCES)))
|
||||
set_errno (EWOULDBLOCK);
|
||||
done:
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
syscall_printf ("%R = flock(%d, %d)", res, fd, operation);
|
||||
return res;
|
||||
}
|
||||
|
@ -1805,50 +1805,50 @@ lockf (int filedes, int function, off_t size)
|
|||
|
||||
pthread_testcancel ();
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
cygheap_fdget cfd (filedes, true);
|
||||
if (cfd < 0)
|
||||
goto done;
|
||||
|
||||
fl.l_start = 0;
|
||||
fl.l_len = size;
|
||||
fl.l_whence = SEEK_CUR;
|
||||
|
||||
switch (function)
|
||||
__try
|
||||
{
|
||||
case F_ULOCK:
|
||||
cmd = F_SETLK;
|
||||
fl.l_type = F_UNLCK;
|
||||
break;
|
||||
case F_LOCK:
|
||||
cmd = F_SETLKW;
|
||||
fl.l_type = F_WRLCK;
|
||||
break;
|
||||
case F_TLOCK:
|
||||
cmd = F_SETLK;
|
||||
fl.l_type = F_WRLCK;
|
||||
break;
|
||||
case F_TEST:
|
||||
fl.l_type = F_WRLCK;
|
||||
if (cfd->lock (F_GETLK, &fl) == -1)
|
||||
goto done;
|
||||
if (fl.l_type == F_UNLCK || fl.l_pid == getpid ())
|
||||
res = 0;
|
||||
else
|
||||
errno = EAGAIN;
|
||||
goto done;
|
||||
/* NOTREACHED */
|
||||
default:
|
||||
errno = EINVAL;
|
||||
goto done;
|
||||
/* NOTREACHED */
|
||||
cygheap_fdget cfd (filedes, true);
|
||||
if (cfd < 0)
|
||||
__leave;
|
||||
|
||||
fl.l_start = 0;
|
||||
fl.l_len = size;
|
||||
fl.l_whence = SEEK_CUR;
|
||||
|
||||
switch (function)
|
||||
{
|
||||
case F_ULOCK:
|
||||
cmd = F_SETLK;
|
||||
fl.l_type = F_UNLCK;
|
||||
break;
|
||||
case F_LOCK:
|
||||
cmd = F_SETLKW;
|
||||
fl.l_type = F_WRLCK;
|
||||
break;
|
||||
case F_TLOCK:
|
||||
cmd = F_SETLK;
|
||||
fl.l_type = F_WRLCK;
|
||||
break;
|
||||
case F_TEST:
|
||||
fl.l_type = F_WRLCK;
|
||||
if (cfd->lock (F_GETLK, &fl) == -1)
|
||||
__leave;
|
||||
if (fl.l_type == F_UNLCK || fl.l_pid == getpid ())
|
||||
res = 0;
|
||||
else
|
||||
errno = EAGAIN;
|
||||
__leave;
|
||||
/* NOTREACHED */
|
||||
default:
|
||||
errno = EINVAL;
|
||||
__leave;
|
||||
/* NOTREACHED */
|
||||
}
|
||||
res = cfd->mandatory_locking () ? cfd->mand_lock (cmd, &fl)
|
||||
: cfd->lock (cmd, &fl);
|
||||
}
|
||||
res = cfd->mandatory_locking () ? cfd->mand_lock (cmd, &fl)
|
||||
: cfd->lock (cmd, &fl);
|
||||
done:
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
syscall_printf ("%R = lockf(%d, %d, %D)", res, filedes, function, size);
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#!/usr/bin/perl
|
||||
# Copyright 2003, 2004, 2005, 2006, 2008, 2009, 2010, 2011, 2012, 2013
|
||||
# Copyright 2003, 2004, 2005, 2006, 2008, 2009, 2010, 2011, 2012, 2013, 2014
|
||||
# Red Hat, Inc.
|
||||
#
|
||||
# This file is part of Cygwin.
|
||||
|
@ -181,6 +181,8 @@ _sigbe: # return here after cygwin syscall
|
|||
movq -8(%r11),%r11 # get return address from signal stack
|
||||
decl $tls::incyg(%r10)
|
||||
decl $tls::stacklock(%r10) # release lock
|
||||
leaq $tls::pathbufs(%r10),%r10 # Address of tls_pathbufs
|
||||
movq \$0,(%r10) # Set c_cnt and w_cnt to 0
|
||||
jmp *%r11 # "return" to caller
|
||||
.seh_endproc
|
||||
|
||||
|
@ -366,7 +368,7 @@ stabilize_sig_stack:
|
|||
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
|
||||
movl %r10d,$tls::spinning(%r12) # flag if we are waiting for lock
|
||||
testl %r10d,%r10d
|
||||
jz 2f
|
||||
pause
|
||||
|
@ -374,14 +376,14 @@ stabilize_sig_stack:
|
|||
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
|
||||
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
|
||||
movq %r12,%r11 # return tls addr in r11
|
||||
popq %r12
|
||||
ret
|
||||
.seh_endproc
|
||||
|
@ -393,13 +395,13 @@ EOF
|
|||
__sigfe_maybe:
|
||||
pushl %ebx
|
||||
pushl %edx
|
||||
movl %fs:4,%ebx # location of bottom of stack
|
||||
addl \$$tls::initialized,%ebx # where we will be looking
|
||||
cmpl %ebx,%esp # stack loc > than tls
|
||||
jge 0f # yep. we don't have a tls.
|
||||
subl \$$tls::initialized,%ebx # where we will be looking
|
||||
movl %fs:4,%ebx # location of bottom of stack
|
||||
addl \$$tls::initialized,%ebx # where we will be looking
|
||||
cmpl %ebx,%esp # stack loc > than tls
|
||||
jge 0f # yep. we don't have a tls.
|
||||
subl \$$tls::initialized,%ebx # where we will be looking
|
||||
movl $tls::initialized(%ebx),%eax
|
||||
cmpl \$0xc763173f,%eax # initialized?
|
||||
cmpl \$0xc763173f,%eax # initialized?
|
||||
je 1f
|
||||
0: popl %edx
|
||||
popl %ebx
|
||||
|
@ -408,43 +410,46 @@ __sigfe_maybe:
|
|||
__sigfe:
|
||||
pushl %ebx
|
||||
pushl %edx
|
||||
movl %fs:4,%ebx # location of bottom of stack
|
||||
1: movl \$1,%eax # potential lock value
|
||||
xchgl %eax,$tls::stacklock(%ebx) # see if we can grab it
|
||||
movl %eax,$tls::spinning(%ebx) # flag if we are waiting for lock
|
||||
testl %eax,%eax # it will be zero
|
||||
jz 2f # if so
|
||||
call _yield # should be a short-time thing, so
|
||||
jmp 1b # sleep and loop
|
||||
2: movl \$4,%eax # have the lock, now increment the
|
||||
xadd %eax,$tls::stackptr(%ebx) # stack pointer and get pointer
|
||||
leal __sigbe,%edx # new place to return to
|
||||
xchgl %edx,12(%esp) # exchange with real return value
|
||||
movl %edx,(%eax) # store real return value on alt stack
|
||||
movl %fs:4,%ebx # location of bottom of stack
|
||||
1: movl \$1,%eax # potential lock value
|
||||
xchgl %eax,$tls::stacklock(%ebx) # see if we can grab it
|
||||
movl %eax,$tls::spinning(%ebx) # flag if we are waiting for lock
|
||||
testl %eax,%eax # it will be zero
|
||||
jz 2f # if so
|
||||
call _yield # should be a short-time thing, so
|
||||
jmp 1b # sleep and loop
|
||||
2: movl \$4,%eax # have the lock, now increment the
|
||||
xadd %eax,$tls::stackptr(%ebx) # stack pointer and get pointer
|
||||
leal __sigbe,%edx # new place to return to
|
||||
xchgl %edx,12(%esp) # exchange with real return value
|
||||
movl %edx,(%eax) # store real return value on alt stack
|
||||
incl $tls::incyg(%ebx)
|
||||
decl $tls::stacklock(%ebx) # remove lock
|
||||
popl %edx # restore saved value
|
||||
decl $tls::stacklock(%ebx) # remove lock
|
||||
popl %edx # restore saved value
|
||||
popl %ebx
|
||||
ret
|
||||
|
||||
.global __sigbe
|
||||
__sigbe: # return here after cygwin syscall
|
||||
pushl %eax # don't clobber
|
||||
pushl %ebx # tls pointer
|
||||
1: movl %fs:4,%ebx # address of bottom of tls
|
||||
movl \$1,%eax # potential lock value
|
||||
xchgl %eax,$tls::stacklock(%ebx) # see if we can grab it
|
||||
movl %eax,$tls::spinning(%ebx) # flag if we are waiting for lock
|
||||
testl %eax,%eax # it will be zero
|
||||
jz 2f # if so
|
||||
call _yield # sleep
|
||||
jmp 1b # and loop
|
||||
2: movl \$-4,%eax # now decrement aux stack
|
||||
xadd %eax,$tls::stackptr(%ebx) # and get pointer
|
||||
movl -4(%eax),%eax # get return address from signal stack
|
||||
xchgl %eax,4(%esp) # swap return address with saved eax
|
||||
__sigbe: # return here after cygwin syscall
|
||||
pushl %eax # don't clobber
|
||||
pushl %ebx # tls pointer
|
||||
1: movl %fs:4,%ebx # address of bottom of tls
|
||||
movl \$1,%eax # potential lock value
|
||||
xchgl %eax,$tls::stacklock(%ebx) # see if we can grab it
|
||||
movl %eax,$tls::spinning(%ebx) # flag if we are waiting for lock
|
||||
testl %eax,%eax # it will be zero
|
||||
jz 2f # if so
|
||||
call _yield # sleep
|
||||
jmp 1b # and loop
|
||||
2: movl \$-4,%eax # now decrement aux stack
|
||||
xadd %eax,$tls::stackptr(%ebx) # and get pointer
|
||||
movl -4(%eax),%eax # get return address from signal stack
|
||||
xchgl %eax,4(%esp) # swap return address with saved eax
|
||||
decl $tls::incyg(%ebx)
|
||||
decl $tls::stacklock(%ebx) # release lock
|
||||
decl $tls::stacklock(%ebx) # release lock
|
||||
leal $tls::pathbufs(%ebx),%ebx # Address of tls_pathbufs
|
||||
movl \$0,(%ebx) # Set c_cnt to 0
|
||||
movl \$0,4(%ebx) # Set w_cnt to 0
|
||||
popl %ebx
|
||||
ret
|
||||
|
||||
|
|
|
@ -249,8 +249,7 @@ getprogname (void)
|
|||
extern "C" void
|
||||
setprogname (const char *newprogname)
|
||||
{
|
||||
myfault efault;
|
||||
if (!efault.faulted (EFAULT))
|
||||
__try
|
||||
{
|
||||
/* Per BSD man page, setprogname keeps a pointer to the last
|
||||
path component of the argument. It does *not* copy the
|
||||
|
@ -261,6 +260,8 @@ setprogname (const char *newprogname)
|
|||
else
|
||||
__progname = (char *)newprogname;
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
|
|
|
@ -312,100 +312,101 @@ extern "C" int
|
|||
cygwin_rexec (char **ahost, unsigned short rport, char *name, char *pass,
|
||||
char *cmd, int *fd2p)
|
||||
{
|
||||
struct sockaddr_in sin, sin2, from;
|
||||
struct hostent *hp;
|
||||
u_short port = 0;
|
||||
int s, timo = 1, s3;
|
||||
char c;
|
||||
static char ahostbuf[INTERNET_MAX_HOST_NAME_LENGTH + 1];
|
||||
struct sockaddr_in sin, sin2, from;
|
||||
struct hostent *hp;
|
||||
u_short port = 0;
|
||||
int s, timo = 1, s3;
|
||||
char c;
|
||||
static char ahostbuf[INTERNET_MAX_HOST_NAME_LENGTH + 1];
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
hp = cygwin_gethostbyname(*ahost);
|
||||
if (hp == 0) {
|
||||
cygwin_herror(*ahost);
|
||||
return (-1);
|
||||
}
|
||||
*ahost = strcpy (ahostbuf, hp->h_name);
|
||||
ruserpass(hp->h_name, &name, &pass, NULL);
|
||||
if (!name)
|
||||
name = getlogin ();
|
||||
if (!pass)
|
||||
pass = almost_null;
|
||||
__try
|
||||
{
|
||||
hp = cygwin_gethostbyname(*ahost);
|
||||
if (hp == 0) {
|
||||
cygwin_herror(*ahost);
|
||||
return (-1);
|
||||
}
|
||||
*ahost = strcpy (ahostbuf, hp->h_name);
|
||||
ruserpass(hp->h_name, &name, &pass, NULL);
|
||||
if (!name)
|
||||
name = getlogin ();
|
||||
if (!pass)
|
||||
pass = almost_null;
|
||||
retry:
|
||||
s = cygwin_socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (s < 0) {
|
||||
perror("rexec: socket");
|
||||
return (-1);
|
||||
}
|
||||
sin.sin_family = hp->h_addrtype;
|
||||
sin.sin_port = rport;
|
||||
bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length);
|
||||
if (cygwin_connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
|
||||
if (errno == ECONNREFUSED && timo <= 16) {
|
||||
(void) close(s);
|
||||
sleep(timo);
|
||||
timo *= 2;
|
||||
goto retry;
|
||||
}
|
||||
perror(hp->h_name);
|
||||
return (-1);
|
||||
}
|
||||
if (fd2p == 0) {
|
||||
(void) write(s, "", 1);
|
||||
} else {
|
||||
char num[8];
|
||||
int s2, sin2len;
|
||||
s = cygwin_socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (s < 0) {
|
||||
perror("rexec: socket");
|
||||
return (-1);
|
||||
}
|
||||
sin.sin_family = hp->h_addrtype;
|
||||
sin.sin_port = rport;
|
||||
bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length);
|
||||
if (cygwin_connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
|
||||
if (errno == ECONNREFUSED && timo <= 16) {
|
||||
(void) close(s);
|
||||
sleep(timo);
|
||||
timo *= 2;
|
||||
goto retry;
|
||||
}
|
||||
perror(hp->h_name);
|
||||
return (-1);
|
||||
}
|
||||
if (fd2p == 0) {
|
||||
(void) write(s, "", 1);
|
||||
} else {
|
||||
char num[8];
|
||||
int s2, sin2len;
|
||||
|
||||
s2 = cygwin_socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (s2 < 0) {
|
||||
(void) close(s);
|
||||
return (-1);
|
||||
s2 = cygwin_socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (s2 < 0) {
|
||||
(void) close(s);
|
||||
return (-1);
|
||||
}
|
||||
cygwin_listen(s2, 1);
|
||||
sin2len = sizeof (sin2);
|
||||
if (cygwin_getsockname(s2, (struct sockaddr *)&sin2, &sin2len) < 0 ||
|
||||
sin2len != sizeof (sin2)) {
|
||||
perror("getsockname");
|
||||
(void) close(s2);
|
||||
goto bad;
|
||||
}
|
||||
port = ntohs((u_short)sin2.sin_port);
|
||||
(void) sprintf(num, "%u", port);
|
||||
(void) write(s, num, strlen(num)+1);
|
||||
{ int len = sizeof (from);
|
||||
s3 = cygwin_accept(s2, (struct sockaddr *)&from, &len);
|
||||
close(s2);
|
||||
if (s3 < 0) {
|
||||
perror("accept");
|
||||
port = 0;
|
||||
goto bad;
|
||||
}
|
||||
cygwin_listen(s2, 1);
|
||||
sin2len = sizeof (sin2);
|
||||
if (cygwin_getsockname(s2, (struct sockaddr *)&sin2, &sin2len) < 0 ||
|
||||
sin2len != sizeof (sin2)) {
|
||||
perror("getsockname");
|
||||
(void) close(s2);
|
||||
goto bad;
|
||||
}
|
||||
port = ntohs((u_short)sin2.sin_port);
|
||||
(void) sprintf(num, "%u", port);
|
||||
(void) write(s, num, strlen(num)+1);
|
||||
{ int len = sizeof (from);
|
||||
s3 = cygwin_accept(s2, (struct sockaddr *)&from, &len);
|
||||
close(s2);
|
||||
if (s3 < 0) {
|
||||
perror("accept");
|
||||
port = 0;
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
*fd2p = s3;
|
||||
}
|
||||
(void) write(s, name, strlen(name) + 1);
|
||||
/* should public key encypt the password here */
|
||||
(void) write(s, pass, strlen(pass) + 1);
|
||||
(void) write(s, cmd, strlen(cmd) + 1);
|
||||
if (read(s, &c, 1) != 1) {
|
||||
perror(*ahost);
|
||||
goto bad;
|
||||
}
|
||||
if (c != 0) {
|
||||
while (read(s, &c, 1) == 1) {
|
||||
(void) write(2, &c, 1);
|
||||
if (c == '\n')
|
||||
break;
|
||||
}
|
||||
goto bad;
|
||||
}
|
||||
return (s);
|
||||
}
|
||||
*fd2p = s3;
|
||||
}
|
||||
(void) write(s, name, strlen(name) + 1);
|
||||
/* should public key encypt the password here */
|
||||
(void) write(s, pass, strlen(pass) + 1);
|
||||
(void) write(s, cmd, strlen(cmd) + 1);
|
||||
if (read(s, &c, 1) != 1) {
|
||||
perror(*ahost);
|
||||
goto bad;
|
||||
}
|
||||
if (c != 0) {
|
||||
while (read(s, &c, 1) == 1) {
|
||||
(void) write(2, &c, 1);
|
||||
if (c == '\n')
|
||||
break;
|
||||
}
|
||||
goto bad;
|
||||
}
|
||||
return (s);
|
||||
bad:
|
||||
if (port)
|
||||
(void) close(*fd2p);
|
||||
(void) close(s);
|
||||
return (-1);
|
||||
if (port)
|
||||
(void) close(*fd2p);
|
||||
(void) close(s);
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return (-1);
|
||||
}
|
||||
|
|
|
@ -202,35 +202,38 @@ check_iovec (const struct iovec *iov, int iovcnt, bool forwrite)
|
|||
return -1;
|
||||
}
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
size_t tot = 0;
|
||||
|
||||
while (iovcnt != 0)
|
||||
__try
|
||||
{
|
||||
if (iov->iov_len > SSIZE_MAX || (tot += iov->iov_len) > SSIZE_MAX)
|
||||
|
||||
size_t tot = 0;
|
||||
|
||||
while (iovcnt != 0)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
if (iov->iov_len > SSIZE_MAX || (tot += iov->iov_len) > SSIZE_MAX)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
__leave;
|
||||
}
|
||||
|
||||
volatile char *p = ((char *) iov->iov_base) + iov->iov_len - 1;
|
||||
if (!iov->iov_len)
|
||||
/* nothing to do */;
|
||||
else if (!forwrite)
|
||||
*p = dummytest (p);
|
||||
else
|
||||
dummytest (p);
|
||||
|
||||
iov++;
|
||||
iovcnt--;
|
||||
}
|
||||
|
||||
volatile char *p = ((char *) iov->iov_base) + iov->iov_len - 1;
|
||||
if (!iov->iov_len)
|
||||
/* nothing to do */;
|
||||
else if (!forwrite)
|
||||
*p = dummytest (p);
|
||||
else
|
||||
dummytest (p);
|
||||
assert (tot <= SSIZE_MAX);
|
||||
|
||||
iov++;
|
||||
iovcnt--;
|
||||
return (ssize_t) tot;
|
||||
}
|
||||
|
||||
assert (tot <= SSIZE_MAX);
|
||||
|
||||
return (ssize_t) tot;
|
||||
__except (EFAULT)
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Try hard to schedule another thread.
|
||||
|
@ -512,18 +515,23 @@ slashify (const char *src, char *dst, bool trailing_slash_p)
|
|||
void * __reg1
|
||||
__import_address (void *imp)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
return NULL;
|
||||
if (*((uint16_t *) imp) != 0x25ff)
|
||||
return NULL;
|
||||
const char *ptr = (const char *) imp;
|
||||
__try
|
||||
{
|
||||
if (*((uint16_t *) imp) == 0x25ff)
|
||||
{
|
||||
const char *ptr = (const char *) imp;
|
||||
#ifdef __x86_64__
|
||||
const uintptr_t *jmpto = (uintptr_t *) (ptr + 6 + *(int32_t *)(ptr + 2));
|
||||
const uintptr_t *jmpto = (uintptr_t *)
|
||||
(ptr + 6 + *(int32_t *)(ptr + 2));
|
||||
#else
|
||||
const uintptr_t *jmpto = (uintptr_t *) *((uintptr_t *) (ptr + 2));
|
||||
const uintptr_t *jmpto = (uintptr_t *) *((uintptr_t *) (ptr + 2));
|
||||
#endif
|
||||
return (void *) *jmpto;
|
||||
return (void *) *jmpto;
|
||||
}
|
||||
}
|
||||
__except (NO_ERROR) {}
|
||||
__endtry
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* CygwinCreateThread.
|
||||
|
|
|
@ -1700,50 +1700,54 @@ mount (const char *win32_path, const char *posix_path, unsigned flags)
|
|||
isn't really supported except from fstab? */
|
||||
int res = -1;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
/* errno set */;
|
||||
else if (!*posix_path)
|
||||
set_errno (EINVAL);
|
||||
else if (strpbrk (posix_path, "\\:"))
|
||||
set_errno (EINVAL);
|
||||
else if (flags & MOUNT_CYGDRIVE) /* normal mount */
|
||||
__try
|
||||
{
|
||||
/* When flags include MOUNT_CYGDRIVE, take this to mean that
|
||||
we actually want to change the cygdrive prefix and flags
|
||||
without actually mounting anything. */
|
||||
res = mount_table->write_cygdrive_info (posix_path, flags);
|
||||
win32_path = NULL;
|
||||
}
|
||||
else if (!*win32_path)
|
||||
set_errno (EINVAL);
|
||||
else
|
||||
{
|
||||
char *w32_path = (char *) win32_path;
|
||||
if (flags & MOUNT_BIND)
|
||||
if (!*posix_path)
|
||||
set_errno (EINVAL);
|
||||
else if (strpbrk (posix_path, "\\:"))
|
||||
set_errno (EINVAL);
|
||||
else if (flags & MOUNT_CYGDRIVE) /* normal mount */
|
||||
{
|
||||
/* Prepend root path to bound path. */
|
||||
tmp_pathbuf tp;
|
||||
device dev;
|
||||
|
||||
unsigned conv_flags = 0;
|
||||
const char *bound_path = w32_path;
|
||||
|
||||
w32_path = tp.c_get ();
|
||||
int error = mount_table->conv_to_win32_path (bound_path, w32_path,
|
||||
dev, &conv_flags);
|
||||
if (error || strlen (w32_path) >= MAX_PATH)
|
||||
return true;
|
||||
if ((flags & ~MOUNT_SYSTEM) == (MOUNT_BIND | MOUNT_BINARY))
|
||||
flags = (MOUNT_BIND | conv_flags)
|
||||
& ~(MOUNT_IMMUTABLE | MOUNT_AUTOMATIC);
|
||||
/* When flags include MOUNT_CYGDRIVE, take this to mean that
|
||||
we actually want to change the cygdrive prefix and flags
|
||||
without actually mounting anything. */
|
||||
res = mount_table->write_cygdrive_info (posix_path, flags);
|
||||
win32_path = NULL;
|
||||
}
|
||||
/* Make sure all mounts are user mounts, even those added via mount -a. */
|
||||
flags &= ~MOUNT_SYSTEM;
|
||||
res = mount_table->add_item (w32_path, posix_path, flags);
|
||||
}
|
||||
else if (!*win32_path)
|
||||
set_errno (EINVAL);
|
||||
else
|
||||
{
|
||||
char *w32_path = (char *) win32_path;
|
||||
if (flags & MOUNT_BIND)
|
||||
{
|
||||
/* Prepend root path to bound path. */
|
||||
tmp_pathbuf tp;
|
||||
device dev;
|
||||
|
||||
syscall_printf ("%R = mount(%s, %s, %y)", res, win32_path, posix_path, flags);
|
||||
unsigned conv_flags = 0;
|
||||
const char *bound_path = w32_path;
|
||||
|
||||
w32_path = tp.c_get ();
|
||||
int error = mount_table->conv_to_win32_path (bound_path, w32_path,
|
||||
dev, &conv_flags);
|
||||
if (error || strlen (w32_path) >= MAX_PATH)
|
||||
return true;
|
||||
if ((flags & ~MOUNT_SYSTEM) == (MOUNT_BIND | MOUNT_BINARY))
|
||||
flags = (MOUNT_BIND | conv_flags)
|
||||
& ~(MOUNT_IMMUTABLE | MOUNT_AUTOMATIC);
|
||||
}
|
||||
/* Make sure all mounts are user mounts, even those added via
|
||||
mount -a. */
|
||||
flags &= ~MOUNT_SYSTEM;
|
||||
res = mount_table->add_item (w32_path, posix_path, flags);
|
||||
}
|
||||
|
||||
syscall_printf ("%R = mount(%s, %s, %y)",
|
||||
res, win32_path, posix_path, flags);
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -1755,15 +1759,18 @@ mount (const char *win32_path, const char *posix_path, unsigned flags)
|
|||
extern "C" int
|
||||
umount (const char *path)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
if (!*path)
|
||||
__try
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
if (!*path)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
__leave;
|
||||
}
|
||||
return cygwin_umount (path, 0);
|
||||
}
|
||||
return cygwin_umount (path, 0);
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* cygwin_umount: This is like umount but takes an additional flags
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* msg.cc: XSI IPC interface for Cygwin.
|
||||
|
||||
Copyright 2002, 2003, 2004, 2005, 2008, 2009 Red Hat, Inc.
|
||||
Copyright 2002, 2003, 2004, 2005, 2008, 2009, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -91,38 +91,40 @@ client_request_msg::client_request_msg (int msqid,
|
|||
extern "C" int
|
||||
msgctl (int msqid, int cmd, struct msqid_ds *buf)
|
||||
{
|
||||
syscall_printf ("msgctl (msqid = %d, cmd = %y, buf = %p)",
|
||||
msqid, cmd, buf);
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
switch (cmd)
|
||||
syscall_printf ("msgctl (msqid = %d, cmd = %y, buf = %p)", msqid, cmd, buf);
|
||||
__try
|
||||
{
|
||||
case IPC_STAT:
|
||||
break;
|
||||
case IPC_SET:
|
||||
break;
|
||||
case IPC_RMID:
|
||||
break;
|
||||
case IPC_INFO:
|
||||
break;
|
||||
case MSG_INFO:
|
||||
break;
|
||||
default:
|
||||
syscall_printf ("-1 [%d] = msgctl ()", EINVAL);
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
switch (cmd)
|
||||
{
|
||||
case IPC_STAT:
|
||||
break;
|
||||
case IPC_SET:
|
||||
break;
|
||||
case IPC_RMID:
|
||||
break;
|
||||
case IPC_INFO:
|
||||
break;
|
||||
case MSG_INFO:
|
||||
break;
|
||||
default:
|
||||
syscall_printf ("-1 [%d] = msgctl ()", EINVAL);
|
||||
set_errno (EINVAL);
|
||||
__leave;
|
||||
}
|
||||
client_request_msg request (msqid, cmd, buf);
|
||||
if (request.make_request () == -1 || request.retval () == -1)
|
||||
{
|
||||
syscall_printf ("-1 [%d] = msgctl ()", request.error_code ());
|
||||
set_errno (request.error_code ());
|
||||
if (request.error_code () == ENOSYS)
|
||||
raise (SIGSYS);
|
||||
__leave;
|
||||
}
|
||||
return request.retval ();
|
||||
}
|
||||
client_request_msg request (msqid, cmd, buf);
|
||||
if (request.make_request () == -1 || request.retval () == -1)
|
||||
{
|
||||
syscall_printf ("-1 [%d] = msgctl ()", request.error_code ());
|
||||
set_errno (request.error_code ());
|
||||
if (request.error_code () == ENOSYS)
|
||||
raise (SIGSYS);
|
||||
return -1;
|
||||
}
|
||||
return request.retval ();
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
|
@ -147,19 +149,22 @@ msgrcv (int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg)
|
|||
syscall_printf ("msgrcv (msqid = %d, msgp = %p, msgsz = %ld, "
|
||||
"msgtyp = %d, msgflg = %y)",
|
||||
msqid, msgp, msgsz, msgtyp, msgflg);
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
client_request_msg request (msqid, msgp, msgsz, msgtyp, msgflg);
|
||||
if (request.make_request () == -1 || request.rcvval () == -1)
|
||||
__try
|
||||
{
|
||||
syscall_printf ("-1 [%d] = msgrcv ()", request.error_code ());
|
||||
set_errno (request.error_code ());
|
||||
if (request.error_code () == ENOSYS)
|
||||
raise (SIGSYS);
|
||||
return -1;
|
||||
client_request_msg request (msqid, msgp, msgsz, msgtyp, msgflg);
|
||||
if (request.make_request () == -1 || request.rcvval () == -1)
|
||||
{
|
||||
syscall_printf ("-1 [%d] = msgrcv ()", request.error_code ());
|
||||
set_errno (request.error_code ());
|
||||
if (request.error_code () == ENOSYS)
|
||||
raise (SIGSYS);
|
||||
__leave;
|
||||
}
|
||||
return request.rcvval ();
|
||||
}
|
||||
return request.rcvval ();
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
|
@ -167,17 +172,20 @@ msgsnd (int msqid, const void *msgp, size_t msgsz, int msgflg)
|
|||
{
|
||||
syscall_printf ("msgsnd (msqid = %d, msgp = %p, msgsz = %ld, msgflg = %y)",
|
||||
msqid, msgp, msgsz, msgflg);
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
client_request_msg request (msqid, msgp, msgsz, msgflg);
|
||||
if (request.make_request () == -1 || request.retval () == -1)
|
||||
__try
|
||||
{
|
||||
syscall_printf ("-1 [%d] = msgsnd ()", request.error_code ());
|
||||
set_errno (request.error_code ());
|
||||
if (request.error_code () == ENOSYS)
|
||||
raise (SIGSYS);
|
||||
return -1;
|
||||
client_request_msg request (msqid, msgp, msgsz, msgflg);
|
||||
if (request.make_request () == -1 || request.retval () == -1)
|
||||
{
|
||||
syscall_printf ("-1 [%d] = msgsnd ()", request.error_code ());
|
||||
set_errno (request.error_code ());
|
||||
if (request.error_code () == ENOSYS)
|
||||
raise (SIGSYS);
|
||||
__leave;
|
||||
}
|
||||
return request.retval ();
|
||||
}
|
||||
return request.retval ();
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
|
1805
winsup/cygwin/net.cc
1805
winsup/cygwin/net.cc
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,7 @@
|
|||
/* ntdll.h. Contains ntdll specific stuff not defined elsewhere.
|
||||
|
||||
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||
2011, 2012, 2013 Red Hat, Inc.
|
||||
2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -1180,8 +1180,19 @@ typedef enum _SECTION_INHERIT
|
|||
|
||||
typedef VOID (APIENTRY *PTIMER_APC_ROUTINE)(PVOID, ULONG, ULONG);
|
||||
|
||||
/* Function declarations for ntdll.dll. These don't appear in any
|
||||
standard Win32 header. */
|
||||
#ifdef __x86_64__
|
||||
typedef struct _SCOPE_TABLE
|
||||
{
|
||||
ULONG Count;
|
||||
struct
|
||||
{
|
||||
ULONG BeginAddress;
|
||||
ULONG EndAddress;
|
||||
ULONG HandlerAddress;
|
||||
ULONG JumpTarget;
|
||||
} ScopeRecord[1];
|
||||
} SCOPE_TABLE, *PSCOPE_TABLE;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* This is the mapping of the KUSER_SHARED_DATA structure into the user
|
||||
|
@ -1190,6 +1201,9 @@ typedef VOID (APIENTRY *PTIMER_APC_ROUTINE)(PVOID, ULONG, ULONG);
|
|||
static volatile KUSER_SHARED_DATA &SharedUserData
|
||||
= *(volatile KUSER_SHARED_DATA *) 0x7ffe0000;
|
||||
|
||||
/* Function declarations for ntdll.dll. These don't appear in any
|
||||
standard Win32 header. */
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
|
|
@ -60,167 +60,171 @@ read_ea (HANDLE hdl, path_conv &pc, const char *name, char *value, size_t size)
|
|||
EA in the file is returned twice. */
|
||||
char lastname[MAX_EA_NAME_LEN];
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
goto out;
|
||||
|
||||
pc.get_object_attr (attr, sec_none_nih);
|
||||
|
||||
debug_printf ("read_ea (%S, %s, %p, %lu)",
|
||||
attr.ObjectName, name, value, size);
|
||||
|
||||
/* Early open if handle is NULL. This allows to return error codes like
|
||||
ENOENT before we actually check for the correctness of the EA name and
|
||||
stuff like that. */
|
||||
if (!hdl)
|
||||
__try
|
||||
{
|
||||
status = NtOpenFile (&h, READ_CONTROL | FILE_READ_EA, &attr, &io,
|
||||
FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT);
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
__seterrno_from_nt_status (status);
|
||||
goto out;
|
||||
}
|
||||
hdl = NULL;
|
||||
}
|
||||
pc.get_object_attr (attr, sec_none_nih);
|
||||
|
||||
fea = (PFILE_FULL_EA_INFORMATION) tp.w_get ();
|
||||
debug_printf ("read_ea (%S, %s, %p, %lu)",
|
||||
attr.ObjectName, name, value, size);
|
||||
|
||||
if (name)
|
||||
{
|
||||
size_t nlen;
|
||||
|
||||
/* For compatibility with Linux, we only allow user xattrs and
|
||||
return ENOTSUP otherwise. */
|
||||
if (ascii_strncasematch (name, "user.", 5))
|
||||
name += 5;
|
||||
else
|
||||
/* Early open if handle is NULL. This allows to return error codes like
|
||||
ENOENT before we actually check for the correctness of the EA name and
|
||||
stuff like that. */
|
||||
if (!hdl)
|
||||
{
|
||||
set_errno (ENOTSUP);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((nlen = strlen (name)) >= MAX_EA_NAME_LEN)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
glen = sizeof (FILE_GET_EA_INFORMATION) + nlen;
|
||||
gea = (PFILE_GET_EA_INFORMATION) alloca (glen);
|
||||
|
||||
gea->NextEntryOffset = 0;
|
||||
gea->EaNameLength = nlen;
|
||||
strcpy (gea->EaName, name);
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (h)
|
||||
{
|
||||
status = NtQueryEaFile (h, &io, fea, EA_BUFSIZ, TRUE, gea, glen,
|
||||
NULL, TRUE);
|
||||
if (status != STATUS_ACCESS_DENIED || !hdl)
|
||||
break;
|
||||
}
|
||||
status = NtOpenFile (&h, READ_CONTROL | FILE_READ_EA, &attr, &io,
|
||||
FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT);
|
||||
if (!NT_SUCCESS (status))
|
||||
break;
|
||||
hdl = NULL;
|
||||
}
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case STATUS_NO_EAS_ON_FILE:
|
||||
ret = 0;
|
||||
break;
|
||||
case STATUS_INVALID_DEVICE_REQUEST:
|
||||
set_errno (ENOTSUP);
|
||||
break;
|
||||
case STATUS_NOT_FOUND:
|
||||
/* STATUS_NOT_FOUND is returned when calling NtQueryEaFile on NFS.
|
||||
In theory this should mean that the file just has no EAs, but in
|
||||
fact NFS doesn't support EAs, other than the EAs which are used
|
||||
for NFS requests. We're playing safe and convert STATUS_NOT_FOUND
|
||||
to ENOATTR, unless we're on NFS, where we convert it to ENOTSUP. */
|
||||
set_errno (pc.fs_is_nfs () ? ENOTSUP : ENOATTR);
|
||||
break;
|
||||
case STATUS_NONEXISTENT_EA_ENTRY:
|
||||
/* Actually STATUS_NONEXISTENT_EA_ENTRY is either never generated, or
|
||||
it was only generated in some old and long forgotton NT version.
|
||||
See below. For safty reasons, we handle it here, nevertheless. */
|
||||
set_errno (ENOATTR);
|
||||
break;
|
||||
default:
|
||||
__seterrno_from_nt_status (status);
|
||||
break;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
if (name)
|
||||
{
|
||||
/* Another weird behaviour of NtQueryEaFile. If you ask for a
|
||||
specific EA which is not present in the file's EA list, you don't
|
||||
get a useful error code like STATUS_NONEXISTENT_EA_ENTRY. Rather
|
||||
NtQueryEaFile returns success with the entry's EaValueLength
|
||||
set to 0. */
|
||||
if (!fea->EaValueLength)
|
||||
{
|
||||
set_errno (ENOATTR);
|
||||
goto out;
|
||||
}
|
||||
if (size > 0)
|
||||
{
|
||||
if (size < fea->EaValueLength)
|
||||
status = NtOpenFile (&h, READ_CONTROL | FILE_READ_EA, &attr, &io,
|
||||
FILE_SHARE_VALID_FLAGS,
|
||||
FILE_OPEN_FOR_BACKUP_INTENT);
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
set_errno (ERANGE);
|
||||
goto out;
|
||||
__seterrno_from_nt_status (status);
|
||||
__leave;
|
||||
}
|
||||
memcpy (value, fea->EaName + fea->EaNameLength + 1,
|
||||
fea->EaValueLength);
|
||||
hdl = NULL;
|
||||
}
|
||||
ret = fea->EaValueLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = 0;
|
||||
do
|
||||
|
||||
fea = (PFILE_FULL_EA_INFORMATION) tp.w_get ();
|
||||
|
||||
if (name)
|
||||
{
|
||||
fea->EaNameLength += 5; /* "user." */
|
||||
size_t nlen;
|
||||
|
||||
/* For compatibility with Linux, we only allow user xattrs and
|
||||
return ENOTSUP otherwise. */
|
||||
if (ascii_strncasematch (name, "user.", 5))
|
||||
name += 5;
|
||||
else
|
||||
{
|
||||
set_errno (ENOTSUP);
|
||||
__leave;
|
||||
}
|
||||
|
||||
if ((nlen = strlen (name)) >= MAX_EA_NAME_LEN)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
glen = sizeof (FILE_GET_EA_INFORMATION) + nlen;
|
||||
gea = (PFILE_GET_EA_INFORMATION) alloca (glen);
|
||||
|
||||
gea->NextEntryOffset = 0;
|
||||
gea->EaNameLength = nlen;
|
||||
strcpy (gea->EaName, name);
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (h)
|
||||
{
|
||||
status = NtQueryEaFile (h, &io, fea, EA_BUFSIZ, TRUE, gea, glen,
|
||||
NULL, TRUE);
|
||||
if (status != STATUS_ACCESS_DENIED || !hdl)
|
||||
break;
|
||||
}
|
||||
status = NtOpenFile (&h, READ_CONTROL | FILE_READ_EA, &attr, &io,
|
||||
FILE_SHARE_VALID_FLAGS,
|
||||
FILE_OPEN_FOR_BACKUP_INTENT);
|
||||
if (!NT_SUCCESS (status))
|
||||
break;
|
||||
hdl = NULL;
|
||||
}
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case STATUS_NO_EAS_ON_FILE:
|
||||
ret = 0;
|
||||
break;
|
||||
case STATUS_INVALID_DEVICE_REQUEST:
|
||||
set_errno (ENOTSUP);
|
||||
break;
|
||||
case STATUS_NOT_FOUND:
|
||||
/* STATUS_NOT_FOUND is returned when calling NtQueryEaFile on NFS.
|
||||
In theory this should mean that the file just has no EAs, but
|
||||
in fact NFS doesn't support EAs, other than the EAs which are
|
||||
used for NFS requests. We're playing safe and convert
|
||||
STATUS_NOT_FOUND to ENOATTR, unless we're on NFS, where we
|
||||
convert it to ENOTSUP. */
|
||||
set_errno (pc.fs_is_nfs () ? ENOTSUP : ENOATTR);
|
||||
break;
|
||||
case STATUS_NONEXISTENT_EA_ENTRY:
|
||||
/* Actually STATUS_NONEXISTENT_EA_ENTRY is either never generated,
|
||||
or it was only generated in some old and long forgotton NT
|
||||
version. See below. For safty reasons, we handle it here,
|
||||
nevertheless. */
|
||||
set_errno (ENOATTR);
|
||||
break;
|
||||
default:
|
||||
__seterrno_from_nt_status (status);
|
||||
break;
|
||||
}
|
||||
__leave;
|
||||
}
|
||||
if (name)
|
||||
{
|
||||
/* Another weird behaviour of NtQueryEaFile. If you ask for a
|
||||
specific EA which is not present in the file's EA list, you don't
|
||||
get a useful error code like STATUS_NONEXISTENT_EA_ENTRY. Rather
|
||||
NtQueryEaFile returns success with the entry's EaValueLength
|
||||
set to 0. */
|
||||
if (!fea->EaValueLength)
|
||||
{
|
||||
set_errno (ENOATTR);
|
||||
__leave;
|
||||
}
|
||||
if (size > 0)
|
||||
{
|
||||
if ((size_t) ret + fea->EaNameLength + 1 > size)
|
||||
if (size < fea->EaValueLength)
|
||||
{
|
||||
set_errno (ERANGE);
|
||||
goto out;
|
||||
__leave;
|
||||
}
|
||||
/* For compatibility with Linux, we always prepend "user." to
|
||||
the attribute name, so effectively we only support user
|
||||
attributes from a application point of view. */
|
||||
char tmpbuf[MAX_EA_NAME_LEN * 2];
|
||||
char *tp = stpcpy (tmpbuf, "user.");
|
||||
stpcpy (tp, fea->EaName);
|
||||
/* NTFS stores all EA names in uppercase unfortunately. To keep
|
||||
compatibility with ext/xfs EA namespaces and accompanying
|
||||
tools, which expect the namespaces to be lower case, we return
|
||||
EA names in lowercase if the file is on a native NTFS. */
|
||||
if (pc.fs_is_ntfs ())
|
||||
strlwr (tp);
|
||||
tp = stpcpy (value, tmpbuf) + 1;
|
||||
ret += tp - value;
|
||||
value = tp;
|
||||
memcpy (value, fea->EaName + fea->EaNameLength + 1,
|
||||
fea->EaValueLength);
|
||||
}
|
||||
else
|
||||
ret += fea->EaNameLength + 1;
|
||||
strcpy (lastname, fea->EaName);
|
||||
status = NtQueryEaFile (h, &io, fea, EA_BUFSIZ, TRUE, NULL, 0,
|
||||
NULL, FALSE);
|
||||
ret = fea->EaValueLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = 0;
|
||||
do
|
||||
{
|
||||
fea->EaNameLength += 5; /* "user." */
|
||||
if (size > 0)
|
||||
{
|
||||
if ((size_t) ret + fea->EaNameLength + 1 > size)
|
||||
{
|
||||
set_errno (ERANGE);
|
||||
__leave;
|
||||
}
|
||||
/* For compatibility with Linux, we always prepend "user." to
|
||||
the attribute name, so effectively we only support user
|
||||
attributes from a application point of view. */
|
||||
char tmpbuf[MAX_EA_NAME_LEN * 2];
|
||||
char *tp = stpcpy (tmpbuf, "user.");
|
||||
stpcpy (tp, fea->EaName);
|
||||
/* NTFS stores all EA names in uppercase unfortunately. To
|
||||
keep compatibility with ext/xfs EA namespaces and
|
||||
accompanying tools, which expect the namespaces to be
|
||||
lower case, we return EA names in lowercase if the file
|
||||
is on a native NTFS. */
|
||||
if (pc.fs_is_ntfs ())
|
||||
strlwr (tp);
|
||||
tp = stpcpy (value, tmpbuf) + 1;
|
||||
ret += tp - value;
|
||||
value = tp;
|
||||
}
|
||||
else
|
||||
ret += fea->EaNameLength + 1;
|
||||
strcpy (lastname, fea->EaName);
|
||||
status = NtQueryEaFile (h, &io, fea, EA_BUFSIZ, TRUE, NULL, 0,
|
||||
NULL, FALSE);
|
||||
}
|
||||
while (NT_SUCCESS (status) && strcmp (lastname, fea->EaName) != 0);
|
||||
}
|
||||
while (NT_SUCCESS (status) && strcmp (lastname, fea->EaName) != 0);
|
||||
}
|
||||
|
||||
out:
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
if (!hdl)
|
||||
CloseHandle (h);
|
||||
debug_printf ("%d = read_ea(%S, %s, %p, %lu)",
|
||||
|
@ -241,120 +245,121 @@ write_ea (HANDLE hdl, path_conv &pc, const char *name, const char *value,
|
|||
ULONG flen;
|
||||
size_t nlen;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
goto out;
|
||||
|
||||
pc.get_object_attr (attr, sec_none_nih);
|
||||
|
||||
debug_printf ("write_ea (%S, %s, %p, %lu, %d)",
|
||||
attr.ObjectName, name, value, size, flags);
|
||||
|
||||
/* Early open if handle is NULL. This allows to return error codes like
|
||||
ENOENT before we actually check for the correctness of the EA name and
|
||||
stuff like that. */
|
||||
if (!hdl)
|
||||
__try
|
||||
{
|
||||
status = NtOpenFile (&h, READ_CONTROL | FILE_WRITE_EA, &attr, &io,
|
||||
FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT);
|
||||
if (!NT_SUCCESS (status))
|
||||
pc.get_object_attr (attr, sec_none_nih);
|
||||
|
||||
debug_printf ("write_ea (%S, %s, %p, %lu, %d)",
|
||||
attr.ObjectName, name, value, size, flags);
|
||||
|
||||
/* Early open if handle is NULL. This allows to return error codes like
|
||||
ENOENT before we actually check for the correctness of the EA name and
|
||||
stuff like that. */
|
||||
if (!hdl)
|
||||
{
|
||||
__seterrno_from_nt_status (status);
|
||||
goto out;
|
||||
status = NtOpenFile (&h, READ_CONTROL | FILE_WRITE_EA, &attr, &io,
|
||||
FILE_SHARE_VALID_FLAGS,
|
||||
FILE_OPEN_FOR_BACKUP_INTENT);
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
__seterrno_from_nt_status (status);
|
||||
__leave;
|
||||
}
|
||||
hdl = NULL;
|
||||
}
|
||||
hdl = NULL;
|
||||
}
|
||||
|
||||
/* For compatibility with Linux, we only allow user xattrs and
|
||||
return ENOTSUP otherwise. */
|
||||
if (!ascii_strncasematch (name, "user.", 5))
|
||||
{
|
||||
set_errno (ENOTSUP);
|
||||
goto out;
|
||||
}
|
||||
/* For compatibility with Linux, we only allow user xattrs and
|
||||
return ENOTSUP otherwise. */
|
||||
if (!ascii_strncasematch (name, "user.", 5))
|
||||
{
|
||||
set_errno (ENOTSUP);
|
||||
__leave;
|
||||
}
|
||||
|
||||
/* removexattr is supposed to fail with ENOATTR if the requested EA is not
|
||||
available. This is equivalent to the XATTR_REPLACE flag for setxattr. */
|
||||
if (!value)
|
||||
flags = XATTR_REPLACE;
|
||||
/* removexattr is supposed to fail with ENOATTR if the requested EA is
|
||||
not available. This is equivalent to XATTR_REPLACE for setxattr. */
|
||||
if (!value)
|
||||
flags = XATTR_REPLACE;
|
||||
|
||||
if (flags)
|
||||
{
|
||||
if (flags != XATTR_CREATE && flags != XATTR_REPLACE)
|
||||
if (flags)
|
||||
{
|
||||
if (flags != XATTR_CREATE && flags != XATTR_REPLACE)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
__leave;
|
||||
}
|
||||
ssize_t rret = read_ea (hdl, pc, name, NULL, 0);
|
||||
if (flags == XATTR_CREATE && rret > 0)
|
||||
{
|
||||
set_errno (EEXIST);
|
||||
__leave;
|
||||
}
|
||||
if (flags == XATTR_REPLACE && rret < 0)
|
||||
__leave;
|
||||
}
|
||||
|
||||
/* Skip "user." prefix. */
|
||||
name += 5;
|
||||
|
||||
if ((nlen = strlen (name)) >= MAX_EA_NAME_LEN)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
goto out;
|
||||
__leave;
|
||||
}
|
||||
ssize_t rret = read_ea (hdl, pc, name, NULL, 0);
|
||||
if (flags == XATTR_CREATE && rret > 0)
|
||||
flen = sizeof (FILE_FULL_EA_INFORMATION) + nlen + 1 + size;
|
||||
fea = (PFILE_FULL_EA_INFORMATION) alloca (flen);
|
||||
fea->NextEntryOffset = 0;
|
||||
fea->Flags = 0;
|
||||
fea->EaNameLength = nlen;
|
||||
fea->EaValueLength = size;
|
||||
strcpy (fea->EaName, name);
|
||||
if (value)
|
||||
memcpy (fea->EaName + fea->EaNameLength + 1, value, size);
|
||||
|
||||
while (true)
|
||||
{
|
||||
set_errno (EEXIST);
|
||||
goto out;
|
||||
}
|
||||
if (flags == XATTR_REPLACE && rret < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Skip "user." prefix. */
|
||||
name += 5;
|
||||
|
||||
if ((nlen = strlen (name)) >= MAX_EA_NAME_LEN)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
goto out;
|
||||
}
|
||||
flen = sizeof (FILE_FULL_EA_INFORMATION) + nlen + 1 + size;
|
||||
fea = (PFILE_FULL_EA_INFORMATION) alloca (flen);
|
||||
fea->NextEntryOffset = 0;
|
||||
fea->Flags = 0;
|
||||
fea->EaNameLength = nlen;
|
||||
fea->EaValueLength = size;
|
||||
strcpy (fea->EaName, name);
|
||||
if (value)
|
||||
memcpy (fea->EaName + fea->EaNameLength + 1, value, size);
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (h)
|
||||
{
|
||||
status = NtSetEaFile (h, &io, fea, flen);
|
||||
if (status != STATUS_ACCESS_DENIED || !hdl)
|
||||
if (h)
|
||||
{
|
||||
status = NtSetEaFile (h, &io, fea, flen);
|
||||
if (status != STATUS_ACCESS_DENIED || !hdl)
|
||||
break;
|
||||
}
|
||||
status = NtOpenFile (&h, READ_CONTROL | FILE_WRITE_EA, &attr, &io,
|
||||
FILE_SHARE_VALID_FLAGS,
|
||||
FILE_OPEN_FOR_BACKUP_INTENT);
|
||||
if (!NT_SUCCESS (status))
|
||||
break;
|
||||
hdl = NULL;
|
||||
}
|
||||
status = NtOpenFile (&h, READ_CONTROL | FILE_WRITE_EA, &attr, &io,
|
||||
FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT);
|
||||
if (!NT_SUCCESS (status))
|
||||
break;
|
||||
hdl = NULL;
|
||||
}
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case STATUS_EA_TOO_LARGE:
|
||||
/* STATUS_EA_TOO_LARGE has a matching Win32 error ERROR_EA_TABLE_FULL.
|
||||
For some unknown reason RtlNtStatusToDosError does not translate
|
||||
STATUS_EA_TOO_LARGE to ERROR_EA_TABLE_FULL, but instead to
|
||||
ERROR_EA_LIST_INCONSISTENT. This error code is also returned for
|
||||
STATUS_EA_LIST_INCONSISTENT, which means the incoming EA list is...
|
||||
inconsistent. For obvious reasons we translate
|
||||
ERROR_EA_LIST_INCONSISTENT to EINVAL, so we have to handle
|
||||
STATUS_EA_TOO_LARGE explicitely here, to get the correct mapping
|
||||
to ENOSPC. */
|
||||
set_errno (ENOSPC);
|
||||
break;
|
||||
case STATUS_INVALID_DEVICE_REQUEST:
|
||||
set_errno (ENOTSUP);
|
||||
break;
|
||||
default:
|
||||
__seterrno_from_nt_status (status);
|
||||
break;
|
||||
switch (status)
|
||||
{
|
||||
case STATUS_EA_TOO_LARGE:
|
||||
/* STATUS_EA_TOO_LARGE has a matching Win32 error code
|
||||
ERROR_EA_TABLE_FULL. For some reason RtlNtStatusToDosError
|
||||
does not translate STATUS_EA_TOO_LARGE to ERROR_EA_TABLE_FULL,
|
||||
but instead to ERROR_EA_LIST_INCONSISTENT. This error code is
|
||||
also returned for STATUS_EA_LIST_INCONSISTENT, which means the
|
||||
incoming EA list is... inconsistent. For obvious reasons we
|
||||
translate ERROR_EA_LIST_INCONSISTENT to EINVAL, so we have to
|
||||
handle STATUS_EA_TOO_LARGE explicitely here, to get the correct
|
||||
mapping to ENOSPC. */
|
||||
set_errno (ENOSPC);
|
||||
break;
|
||||
case STATUS_INVALID_DEVICE_REQUEST:
|
||||
set_errno (ENOTSUP);
|
||||
break;
|
||||
default:
|
||||
__seterrno_from_nt_status (status);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
if (!hdl)
|
||||
CloseHandle (h);
|
||||
debug_printf ("%d = write_ea(%S, %s, %p, %lu, %d)",
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,7 @@
|
|||
/* poll.cc. Implements poll(2) via usage of select(2) call.
|
||||
|
||||
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011,
|
||||
2012 Red Hat, Inc.
|
||||
2012, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -143,16 +143,19 @@ ppoll (struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts,
|
|||
int timeout;
|
||||
sigset_t oldset = _my_tls.sigmask;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
timeout = (timeout_ts == NULL)
|
||||
? -1
|
||||
: (timeout_ts->tv_sec * 1000 + timeout_ts->tv_nsec / 1000000);
|
||||
if (sigmask)
|
||||
set_signal_mask (_my_tls.sigmask, *sigmask);
|
||||
int ret = poll (fds, nfds, timeout);
|
||||
if (sigmask)
|
||||
set_signal_mask (_my_tls.sigmask, oldset);
|
||||
return ret;
|
||||
__try
|
||||
{
|
||||
timeout = (timeout_ts == NULL)
|
||||
? -1
|
||||
: (timeout_ts->tv_sec * 1000 + timeout_ts->tv_nsec / 1000000);
|
||||
if (sigmask)
|
||||
set_signal_mask (_my_tls.sigmask, *sigmask);
|
||||
int ret = poll (fds, nfds, timeout);
|
||||
if (sigmask)
|
||||
set_signal_mask (_my_tls.sigmask, oldset);
|
||||
return ret;
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,7 @@
|
|||
/* resource.cc: getrusage () and friends.
|
||||
|
||||
Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2005, 2008, 2009, 2010,
|
||||
2011, 2012, 2013 Red Hat, Inc.
|
||||
2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
Written by Steve Chamberlain (sac@cygnus.com), Doug Evans (dje@cygnus.com),
|
||||
Geoffrey Noer (noer@cygnus.com) of Cygnus Support.
|
||||
|
@ -116,53 +116,51 @@ getrlimit (int resource, struct rlimit *rlp)
|
|||
{
|
||||
MEMORY_BASIC_INFORMATION m;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
rlp->rlim_cur = RLIM_INFINITY;
|
||||
rlp->rlim_max = RLIM_INFINITY;
|
||||
|
||||
switch (resource)
|
||||
__try
|
||||
{
|
||||
case RLIMIT_CPU:
|
||||
case RLIMIT_FSIZE:
|
||||
case RLIMIT_DATA:
|
||||
case RLIMIT_AS:
|
||||
break;
|
||||
case RLIMIT_STACK:
|
||||
if (!VirtualQuery ((LPCVOID) &m, &m, sizeof m))
|
||||
debug_printf ("couldn't get stack info, returning def.values. %E");
|
||||
else
|
||||
rlp->rlim_cur = RLIM_INFINITY;
|
||||
rlp->rlim_max = RLIM_INFINITY;
|
||||
|
||||
switch (resource)
|
||||
{
|
||||
rlp->rlim_cur = (rlim_t) &m - (rlim_t) m.AllocationBase;
|
||||
rlp->rlim_max = (rlim_t) m.BaseAddress + m.RegionSize
|
||||
- (rlim_t) m.AllocationBase;
|
||||
case RLIMIT_CPU:
|
||||
case RLIMIT_FSIZE:
|
||||
case RLIMIT_DATA:
|
||||
case RLIMIT_AS:
|
||||
break;
|
||||
case RLIMIT_STACK:
|
||||
if (!VirtualQuery ((LPCVOID) &m, &m, sizeof m))
|
||||
debug_printf ("couldn't get stack info, returning def.values. %E");
|
||||
else
|
||||
{
|
||||
rlp->rlim_cur = (rlim_t) &m - (rlim_t) m.AllocationBase;
|
||||
rlp->rlim_max = (rlim_t) m.BaseAddress + m.RegionSize
|
||||
- (rlim_t) m.AllocationBase;
|
||||
}
|
||||
break;
|
||||
case RLIMIT_NOFILE:
|
||||
rlp->rlim_cur = getdtablesize ();
|
||||
if (rlp->rlim_cur < OPEN_MAX)
|
||||
rlp->rlim_cur = OPEN_MAX;
|
||||
rlp->rlim_max = OPEN_MAX_MAX;
|
||||
break;
|
||||
case RLIMIT_CORE:
|
||||
rlp->rlim_cur = cygheap->rlim_core;
|
||||
break;
|
||||
default:
|
||||
set_errno (EINVAL);
|
||||
__leave;
|
||||
}
|
||||
break;
|
||||
case RLIMIT_NOFILE:
|
||||
rlp->rlim_cur = getdtablesize ();
|
||||
if (rlp->rlim_cur < OPEN_MAX)
|
||||
rlp->rlim_cur = OPEN_MAX;
|
||||
rlp->rlim_max = OPEN_MAX_MAX;
|
||||
break;
|
||||
case RLIMIT_CORE:
|
||||
rlp->rlim_cur = cygheap->rlim_core;
|
||||
break;
|
||||
default:
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
setrlimit (int resource, const struct rlimit *rlp)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
struct rlimit oldlimits;
|
||||
|
||||
/* Check if the request is to actually change the resource settings.
|
||||
|
@ -170,29 +168,35 @@ setrlimit (int resource, const struct rlimit *rlp)
|
|||
if (getrlimit (resource, &oldlimits) < 0)
|
||||
return -1;
|
||||
|
||||
if (oldlimits.rlim_cur == rlp->rlim_cur &&
|
||||
oldlimits.rlim_max == rlp->rlim_max)
|
||||
/* No change in resource requirements, succeed immediately */
|
||||
return 0;
|
||||
|
||||
if (rlp->rlim_cur > rlp->rlim_max)
|
||||
__try
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
if (oldlimits.rlim_cur == rlp->rlim_cur &&
|
||||
oldlimits.rlim_max == rlp->rlim_max)
|
||||
/* No change in resource requirements, succeed immediately */
|
||||
return 0;
|
||||
|
||||
switch (resource)
|
||||
{
|
||||
case RLIMIT_CORE:
|
||||
cygheap->rlim_core = rlp->rlim_cur;
|
||||
break;
|
||||
case RLIMIT_NOFILE:
|
||||
if (rlp->rlim_cur != RLIM_INFINITY)
|
||||
return setdtablesize (rlp->rlim_cur);
|
||||
break;
|
||||
default:
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
if (rlp->rlim_cur > rlp->rlim_max)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
__leave;
|
||||
}
|
||||
|
||||
switch (resource)
|
||||
{
|
||||
case RLIMIT_CORE:
|
||||
cygheap->rlim_core = rlp->rlim_cur;
|
||||
break;
|
||||
case RLIMIT_NOFILE:
|
||||
if (rlp->rlim_cur != RLIM_INFINITY)
|
||||
return setdtablesize (rlp->rlim_cur);
|
||||
break;
|
||||
default:
|
||||
set_errno (EINVAL);
|
||||
__leave;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
__except (EFAULT)
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* select.cc
|
||||
|
||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
||||
2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||
2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -230,21 +230,24 @@ pselect(int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
|||
struct timeval tv;
|
||||
sigset_t oldset = _my_tls.sigmask;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
if (ts)
|
||||
__try
|
||||
{
|
||||
tv.tv_sec = ts->tv_sec;
|
||||
tv.tv_usec = ts->tv_nsec / 1000;
|
||||
if (ts)
|
||||
{
|
||||
tv.tv_sec = ts->tv_sec;
|
||||
tv.tv_usec = ts->tv_nsec / 1000;
|
||||
}
|
||||
if (set)
|
||||
set_signal_mask (_my_tls.sigmask, *set);
|
||||
int ret = cygwin_select (maxfds, readfds, writefds, exceptfds,
|
||||
ts ? &tv : NULL);
|
||||
if (set)
|
||||
set_signal_mask (_my_tls.sigmask, oldset);
|
||||
return ret;
|
||||
}
|
||||
if (set)
|
||||
set_signal_mask (_my_tls.sigmask, *set);
|
||||
int ret = cygwin_select (maxfds, readfds, writefds, exceptfds,
|
||||
ts ? &tv : NULL);
|
||||
if (set)
|
||||
set_signal_mask (_my_tls.sigmask, oldset);
|
||||
return ret;
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Call cleanup functions for all inspected fds. Gets rid of any
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* sem.cc: XSI IPC interface for Cygwin.
|
||||
|
||||
Copyright 2002, 2003, 2004, 2005, 2008, 2009, 2012 Red Hat, Inc.
|
||||
Copyright 2002, 2003, 2004, 2005, 2008, 2009, 2012, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -85,19 +85,22 @@ semctl (int semid, int semnum, int cmd, ...)
|
|||
}
|
||||
syscall_printf ("semctl (semid = %d, semnum = %d, cmd = %d, arg = %p)",
|
||||
semid, semnum, cmd, arg.buf);
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
client_request_sem request (semid, semnum, cmd, &arg);
|
||||
if (request.make_request () == -1 || request.retval () == -1)
|
||||
__try
|
||||
{
|
||||
syscall_printf ("-1 [%d] = semctl ()", request.error_code ());
|
||||
set_errno (request.error_code ());
|
||||
if (request.error_code () == ENOSYS)
|
||||
raise (SIGSYS);
|
||||
return -1;
|
||||
client_request_sem request (semid, semnum, cmd, &arg);
|
||||
if (request.make_request () == -1 || request.retval () == -1)
|
||||
{
|
||||
syscall_printf ("-1 [%d] = semctl ()", request.error_code ());
|
||||
set_errno (request.error_code ());
|
||||
if (request.error_code () == ENOSYS)
|
||||
raise (SIGSYS);
|
||||
__leave;
|
||||
}
|
||||
return request.retval ();
|
||||
}
|
||||
return request.retval ();
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
|
@ -122,17 +125,20 @@ semop (int semid, struct sembuf *sops, size_t nsops)
|
|||
{
|
||||
syscall_printf ("semop (semid = %d, sops = %p, nsops = %ld)",
|
||||
semid, sops, nsops);
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
client_request_sem request (semid, sops, nsops);
|
||||
if (request.make_request () == -1 || request.retval () == -1)
|
||||
__try
|
||||
{
|
||||
syscall_printf ("-1 [%d] = semop ()", request.error_code ());
|
||||
set_errno (request.error_code ());
|
||||
if (request.error_code () == ENOSYS)
|
||||
raise (SIGSYS);
|
||||
return -1;
|
||||
client_request_sem request (semid, sops, nsops);
|
||||
if (request.make_request () == -1 || request.retval () == -1)
|
||||
{
|
||||
syscall_printf ("-1 [%d] = semop ()", request.error_code ());
|
||||
set_errno (request.error_code ());
|
||||
if (request.error_code () == ENOSYS)
|
||||
raise (SIGSYS);
|
||||
__leave;
|
||||
}
|
||||
return request.retval ();
|
||||
}
|
||||
return request.retval ();
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -260,41 +260,45 @@ shmctl (int shmid, int cmd, struct shmid_ds *buf)
|
|||
{
|
||||
syscall_printf ("shmctl (shmid = %d, cmd = %d, buf = %p)",
|
||||
shmid, cmd, buf);
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
client_request_shm request (shmid, cmd, buf);
|
||||
if (request.make_request () == -1 || request.retval () == -1)
|
||||
__try
|
||||
{
|
||||
syscall_printf ("-1 [%d] = shmctl ()", request.error_code ());
|
||||
set_errno (request.error_code ());
|
||||
if (request.error_code () == ENOSYS)
|
||||
raise (SIGSYS);
|
||||
return -1;
|
||||
}
|
||||
if (cmd == IPC_RMID)
|
||||
{
|
||||
/* Cleanup */
|
||||
shm_shmid_list *ssh_entry, *ssh_next_entry;
|
||||
SLIST_LOCK ();
|
||||
SLIST_FOREACH_SAFE (ssh_entry, &ssh_list, ssh_next, ssh_next_entry)
|
||||
client_request_shm request (shmid, cmd, buf);
|
||||
if (request.make_request () == -1 || request.retval () == -1)
|
||||
{
|
||||
if (ssh_entry->shmid == shmid)
|
||||
{
|
||||
/* Remove this entry from the list and close the handle
|
||||
only if it's not in use anymore. */
|
||||
if (ssh_entry->ref_count <= 0)
|
||||
{
|
||||
SLIST_REMOVE (&ssh_list, ssh_entry, shm_shmid_list, ssh_next);
|
||||
CloseHandle (ssh_entry->hdl);
|
||||
delete ssh_entry;
|
||||
}
|
||||
break;
|
||||
}
|
||||
syscall_printf ("-1 [%d] = shmctl ()", request.error_code ());
|
||||
set_errno (request.error_code ());
|
||||
if (request.error_code () == ENOSYS)
|
||||
raise (SIGSYS);
|
||||
__leave;
|
||||
}
|
||||
SLIST_UNLOCK ();
|
||||
if (cmd == IPC_RMID)
|
||||
{
|
||||
/* Cleanup */
|
||||
shm_shmid_list *ssh_entry, *ssh_next_entry;
|
||||
SLIST_LOCK ();
|
||||
SLIST_FOREACH_SAFE (ssh_entry, &ssh_list, ssh_next, ssh_next_entry)
|
||||
{
|
||||
if (ssh_entry->shmid == shmid)
|
||||
{
|
||||
/* Remove this entry from the list and close the handle
|
||||
only if it's not in use anymore. */
|
||||
if (ssh_entry->ref_count <= 0)
|
||||
{
|
||||
SLIST_REMOVE (&ssh_list, ssh_entry, shm_shmid_list,
|
||||
ssh_next);
|
||||
CloseHandle (ssh_entry->hdl);
|
||||
delete ssh_entry;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
SLIST_UNLOCK ();
|
||||
}
|
||||
return request.retval ();
|
||||
}
|
||||
return request.retval ();
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* signal.cc
|
||||
|
||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
||||
2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||
2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
Written by Steve Chamberlain of Cygnus Support, sac@cygnus.com
|
||||
Significant changes by Sergey Okhapkin <sos@prospect.com.ru>
|
||||
|
@ -197,33 +197,37 @@ handle_sigprocmask (int how, const sigset_t *set, sigset_t *oldset, sigset_t& op
|
|||
return EINVAL;
|
||||
}
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return EFAULT;
|
||||
|
||||
if (oldset)
|
||||
*oldset = opmask;
|
||||
|
||||
if (set)
|
||||
{
|
||||
sigset_t newmask = opmask;
|
||||
switch (how)
|
||||
__try
|
||||
{
|
||||
case SIG_BLOCK:
|
||||
/* add set to current mask */
|
||||
newmask |= *set;
|
||||
break;
|
||||
case SIG_UNBLOCK:
|
||||
/* remove set from current mask */
|
||||
newmask &= ~*set;
|
||||
break;
|
||||
case SIG_SETMASK:
|
||||
/* just set it */
|
||||
newmask = *set;
|
||||
break;
|
||||
if (oldset)
|
||||
*oldset = opmask;
|
||||
|
||||
if (set)
|
||||
{
|
||||
sigset_t newmask = opmask;
|
||||
switch (how)
|
||||
{
|
||||
case SIG_BLOCK:
|
||||
/* add set to current mask */
|
||||
newmask |= *set;
|
||||
break;
|
||||
case SIG_UNBLOCK:
|
||||
/* remove set from current mask */
|
||||
newmask &= ~*set;
|
||||
break;
|
||||
case SIG_SETMASK:
|
||||
/* just set it */
|
||||
newmask = *set;
|
||||
break;
|
||||
}
|
||||
set_signal_mask (opmask, newmask);
|
||||
}
|
||||
set_signal_mask (opmask, newmask);
|
||||
}
|
||||
__except (EFAULT)
|
||||
{
|
||||
return EFAULT;
|
||||
}
|
||||
__endtry
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -382,8 +386,7 @@ sigaction_worker (int sig, const struct sigaction *newact,
|
|||
struct sigaction *oldact, bool isinternal)
|
||||
{
|
||||
int res = -1;
|
||||
myfault efault;
|
||||
if (!efault.faulted (EFAULT))
|
||||
__try
|
||||
{
|
||||
sig_dispatch_pending ();
|
||||
/* check that sig is in right range */
|
||||
|
@ -394,14 +397,17 @@ sigaction_worker (int sig, const struct sigaction *newact,
|
|||
struct sigaction oa = global_sigs[sig];
|
||||
|
||||
if (!newact)
|
||||
sigproc_printf ("signal %d, newact %p, oa %p", sig, newact, oa, oa.sa_handler);
|
||||
sigproc_printf ("signal %d, newact %p, oa %p",
|
||||
sig, newact, oa, oa.sa_handler);
|
||||
else
|
||||
{
|
||||
sigproc_printf ("signal %d, newact %p (handler %p), oa %p", sig, newact, newact->sa_handler, oa, oa.sa_handler);
|
||||
sigproc_printf ("signal %d, newact %p (handler %p), oa %p",
|
||||
sig, newact, newact->sa_handler, oa,
|
||||
oa.sa_handler);
|
||||
if (sig == SIGKILL || sig == SIGSTOP)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
goto out;
|
||||
__leave;
|
||||
}
|
||||
struct sigaction na = *newact;
|
||||
struct sigaction& gs = global_sigs[sig];
|
||||
|
@ -430,8 +436,8 @@ sigaction_worker (int sig, const struct sigaction *newact,
|
|||
res = 0;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -560,41 +566,41 @@ sigwait (const sigset_t *set, int *sig_ptr)
|
|||
extern "C" int
|
||||
sigwaitinfo (const sigset_t *set, siginfo_t *info)
|
||||
{
|
||||
int res = -1;
|
||||
|
||||
pthread_testcancel ();
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
set_signal_mask (_my_tls.sigwait_mask, *set);
|
||||
sig_dispatch_pending (true);
|
||||
|
||||
int res;
|
||||
switch (cygwait (NULL, cw_infinite, cw_sig_eintr | cw_cancel | cw_cancel_self))
|
||||
__try
|
||||
{
|
||||
case WAIT_SIGNALED:
|
||||
if (!sigismember (set, _my_tls.infodata.si_signo))
|
||||
{
|
||||
set_errno (EINTR);
|
||||
res = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
_my_tls.lock ();
|
||||
if (info)
|
||||
*info = _my_tls.infodata;
|
||||
res = _my_tls.infodata.si_signo;
|
||||
_my_tls.sig = 0;
|
||||
if (_my_tls.retaddr () == (__stack_t) sigdelayed)
|
||||
_my_tls.pop ();
|
||||
_my_tls.unlock ();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
__seterrno ();
|
||||
res = -1;
|
||||
}
|
||||
set_signal_mask (_my_tls.sigwait_mask, *set);
|
||||
sig_dispatch_pending (true);
|
||||
|
||||
switch (cygwait (NULL, cw_infinite, cw_sig_eintr | cw_cancel | cw_cancel_self))
|
||||
{
|
||||
case WAIT_SIGNALED:
|
||||
if (!sigismember (set, _my_tls.infodata.si_signo))
|
||||
set_errno (EINTR);
|
||||
else
|
||||
{
|
||||
_my_tls.lock ();
|
||||
if (info)
|
||||
*info = _my_tls.infodata;
|
||||
res = _my_tls.infodata.si_signo;
|
||||
_my_tls.sig = 0;
|
||||
if (_my_tls.retaddr () == (__stack_t) sigdelayed)
|
||||
_my_tls.pop ();
|
||||
_my_tls.unlock ();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
__seterrno ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
__except (EFAULT) {
|
||||
res = -1;
|
||||
}
|
||||
__endtry
|
||||
sigproc_printf ("returning signal %d", res);
|
||||
return res;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,7 @@
|
|||
/* thread.cc: Locking and threading module functions
|
||||
|
||||
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
|
||||
2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||
2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -122,28 +122,29 @@ __cygwin_lock_unlock (_LOCK_T *lock)
|
|||
paranoid_printf ("threadcount %d. unlocked", MT_INTERFACE->threadcount);
|
||||
}
|
||||
|
||||
#if __GNUC__ == 4 && __GNUC_MINOR__ >= 7
|
||||
/* FIXME: Temporarily workaround gcc 4.7+ bug. */
|
||||
static verifyable_object_state
|
||||
#else
|
||||
static inline verifyable_object_state
|
||||
#endif
|
||||
verifyable_object_isvalid (void const *objectptr, thread_magic_t magic, void *static_ptr1,
|
||||
void *static_ptr2, void *static_ptr3)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (objectptr))
|
||||
return INVALID_OBJECT;
|
||||
verifyable_object_state state = INVALID_OBJECT;
|
||||
|
||||
verifyable_object **object = (verifyable_object **) objectptr;
|
||||
__try
|
||||
{
|
||||
if (!objectptr || !(*(const char **) objectptr))
|
||||
__leave;
|
||||
|
||||
if ((static_ptr1 && *object == static_ptr1) ||
|
||||
(static_ptr2 && *object == static_ptr2) ||
|
||||
(static_ptr3 && *object == static_ptr3))
|
||||
return VALID_STATIC_OBJECT;
|
||||
if ((*object)->magic != magic)
|
||||
return INVALID_OBJECT;
|
||||
return VALID_OBJECT;
|
||||
verifyable_object **object = (verifyable_object **) objectptr;
|
||||
|
||||
if ((static_ptr1 && *object == static_ptr1) ||
|
||||
(static_ptr2 && *object == static_ptr2) ||
|
||||
(static_ptr3 && *object == static_ptr3))
|
||||
state = VALID_STATIC_OBJECT;
|
||||
else if ((*object)->magic == magic)
|
||||
state = VALID_OBJECT;
|
||||
}
|
||||
__except (NO_ERROR) {}
|
||||
__endtry
|
||||
return state;
|
||||
}
|
||||
|
||||
/* static members */
|
||||
|
@ -2684,18 +2685,20 @@ pthread_cond::init (pthread_cond_t *cond, const pthread_condattr_t *attr)
|
|||
return EAGAIN;
|
||||
}
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
int ret = 0;
|
||||
|
||||
__try
|
||||
{
|
||||
*cond = new_cond;
|
||||
}
|
||||
__except (NO_ERROR)
|
||||
{
|
||||
delete new_cond;
|
||||
cond_initialization_lock.unlock ();
|
||||
return EINVAL;
|
||||
ret = EINVAL;
|
||||
}
|
||||
|
||||
*cond = new_cond;
|
||||
__endtry
|
||||
cond_initialization_lock.unlock ();
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
|
@ -2747,45 +2750,47 @@ pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
|||
struct timespec tp;
|
||||
LARGE_INTEGER timeout;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
return EINVAL;
|
||||
|
||||
pthread_testcancel ();
|
||||
|
||||
int err = __pthread_cond_wait_init (cond, mutex);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* According to SUSv3, the abstime value must be checked for validity. */
|
||||
if (abstime->tv_sec < 0
|
||||
|| abstime->tv_nsec < 0
|
||||
|| abstime->tv_nsec > 999999999)
|
||||
return EINVAL;
|
||||
|
||||
clock_gettime ((*cond)->clock_id, &tp);
|
||||
|
||||
/* Check for immediate timeout before converting */
|
||||
if (tp.tv_sec > abstime->tv_sec
|
||||
|| (tp.tv_sec == abstime->tv_sec
|
||||
&& tp.tv_nsec > abstime->tv_nsec))
|
||||
return ETIMEDOUT;
|
||||
|
||||
timeout.QuadPart = abstime->tv_sec * NSPERSEC
|
||||
+ (abstime->tv_nsec + 99LL) / 100LL;
|
||||
|
||||
switch ((*cond)->clock_id)
|
||||
__try
|
||||
{
|
||||
case CLOCK_REALTIME:
|
||||
timeout.QuadPart += FACTOR;
|
||||
break;
|
||||
default:
|
||||
/* other clocks must be handled as relative timeout */
|
||||
timeout.QuadPart -= tp.tv_sec * NSPERSEC + tp.tv_nsec / 100LL;
|
||||
timeout.QuadPart *= -1LL;
|
||||
break;
|
||||
int err = __pthread_cond_wait_init (cond, mutex);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* According to SUSv3, the abstime value must be checked for validity. */
|
||||
if (abstime->tv_sec < 0
|
||||
|| abstime->tv_nsec < 0
|
||||
|| abstime->tv_nsec > 999999999)
|
||||
__leave;
|
||||
|
||||
clock_gettime ((*cond)->clock_id, &tp);
|
||||
|
||||
/* Check for immediate timeout before converting */
|
||||
if (tp.tv_sec > abstime->tv_sec
|
||||
|| (tp.tv_sec == abstime->tv_sec
|
||||
&& tp.tv_nsec > abstime->tv_nsec))
|
||||
return ETIMEDOUT;
|
||||
|
||||
timeout.QuadPart = abstime->tv_sec * NSPERSEC
|
||||
+ (abstime->tv_nsec + 99LL) / 100LL;
|
||||
|
||||
switch ((*cond)->clock_id)
|
||||
{
|
||||
case CLOCK_REALTIME:
|
||||
timeout.QuadPart += FACTOR;
|
||||
break;
|
||||
default:
|
||||
/* other clocks must be handled as relative timeout */
|
||||
timeout.QuadPart -= tp.tv_sec * NSPERSEC + tp.tv_nsec / 100LL;
|
||||
timeout.QuadPart *= -1LL;
|
||||
break;
|
||||
}
|
||||
return (*cond)->wait (*mutex, &timeout);
|
||||
}
|
||||
return (*cond)->wait (*mutex, &timeout);
|
||||
__except (NO_ERROR) {}
|
||||
__endtry
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
|
@ -2910,18 +2915,20 @@ pthread_rwlock::init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr
|
|||
return EAGAIN;
|
||||
}
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
int ret = 0;
|
||||
|
||||
__try
|
||||
{
|
||||
*rwlock = new_rwlock;
|
||||
}
|
||||
__except (NO_ERROR)
|
||||
{
|
||||
delete new_rwlock;
|
||||
rwlock_initialization_lock.unlock ();
|
||||
return EINVAL;
|
||||
ret = EINVAL;
|
||||
}
|
||||
|
||||
*rwlock = new_rwlock;
|
||||
__endtry
|
||||
rwlock_initialization_lock.unlock ();
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
|
@ -3133,15 +3140,17 @@ pthread_mutex::init (pthread_mutex_t *mutex,
|
|||
new_mutex->type = PTHREAD_MUTEX_ERRORCHECK;
|
||||
}
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
__try
|
||||
{
|
||||
*mutex = new_mutex;
|
||||
}
|
||||
__except (NO_ERROR)
|
||||
{
|
||||
delete new_mutex;
|
||||
mutex_initialization_lock.unlock ();
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
*mutex = new_mutex;
|
||||
__endtry
|
||||
}
|
||||
mutex_initialization_lock.unlock ();
|
||||
pthread_printf ("*mutex %p, attr %p, initializer %p", *mutex, attr, initializer);
|
||||
|
@ -3230,16 +3239,17 @@ pthread_spinlock::init (pthread_spinlock_t *spinlock, int pshared)
|
|||
return EAGAIN;
|
||||
}
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
__try
|
||||
{
|
||||
*spinlock = new_spinlock;
|
||||
}
|
||||
__except (NO_ERROR)
|
||||
{
|
||||
delete new_spinlock;
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
*spinlock = new_spinlock;
|
||||
__endtry
|
||||
pthread_printf ("*spinlock %p, pshared %d", *spinlock, pshared);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3502,35 +3512,38 @@ semaphore::_timedwait (const struct timespec *abstime)
|
|||
{
|
||||
LARGE_INTEGER timeout;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
__try
|
||||
{
|
||||
timeout.QuadPart = abstime->tv_sec * NSPERSEC
|
||||
+ (abstime->tv_nsec + 99) / 100 + FACTOR;
|
||||
|
||||
switch (cygwait (win32_obj_id, &timeout, cw_cancel | cw_cancel_self | cw_sig_eintr))
|
||||
{
|
||||
case WAIT_OBJECT_0:
|
||||
break;
|
||||
case WAIT_SIGNALED:
|
||||
set_errno (EINTR);
|
||||
return -1;
|
||||
case WAIT_TIMEOUT:
|
||||
set_errno (ETIMEDOUT);
|
||||
return -1;
|
||||
default:
|
||||
pthread_printf ("cygwait failed. %E");
|
||||
__seterrno ();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
__except (NO_ERROR)
|
||||
{
|
||||
/* According to SUSv3, abstime need not be checked for validity,
|
||||
if the semaphore can be locked immediately. */
|
||||
if (!_trywait ())
|
||||
return 0;
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
timeout.QuadPart = abstime->tv_sec * NSPERSEC
|
||||
+ (abstime->tv_nsec + 99) / 100 + FACTOR;
|
||||
|
||||
switch (cygwait (win32_obj_id, &timeout, cw_cancel | cw_cancel_self | cw_sig_eintr))
|
||||
{
|
||||
case WAIT_OBJECT_0:
|
||||
break;
|
||||
case WAIT_SIGNALED:
|
||||
set_errno (EINTR);
|
||||
return -1;
|
||||
case WAIT_TIMEOUT:
|
||||
set_errno (ETIMEDOUT);
|
||||
return -1;
|
||||
default:
|
||||
pthread_printf ("cygwait failed. %E");
|
||||
__seterrno ();
|
||||
return -1;
|
||||
if (_trywait ())
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
__endtry
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3761,36 +3774,38 @@ semaphore::post (sem_t *sem)
|
|||
int
|
||||
semaphore::getvalue (sem_t *sem, int *sval)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted () || !is_good_object (sem))
|
||||
__try
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
if (is_good_object (sem))
|
||||
return (*sem)->_getvalue (sval);
|
||||
}
|
||||
|
||||
return (*sem)->_getvalue (sval);
|
||||
__except (NO_ERROR) {}
|
||||
__endtry
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
semaphore::getinternal (sem_t *sem, int *sfd, unsigned long long *shash,
|
||||
LUID *sluid, unsigned int *sval)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted () || !is_good_object (sem))
|
||||
__try
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
if (!is_good_object (sem))
|
||||
__leave;
|
||||
if ((*sfd = (*sem)->fd) < 0)
|
||||
__leave;
|
||||
*shash = (*sem)->hash;
|
||||
*sluid = (*sem)->luid;
|
||||
/* POSIX defines the value in calls to sem_init/sem_open as unsigned,
|
||||
but the sem_getvalue gets a pointer to int to return the value.
|
||||
Go figure! */
|
||||
return (*sem)->_getvalue ((int *)sval);
|
||||
}
|
||||
if ((*sfd = (*sem)->fd) < 0)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
*shash = (*sem)->hash;
|
||||
*sluid = (*sem)->luid;
|
||||
/* POSIX defines the value in calls to sem_init/sem_open as unsigned, but
|
||||
the sem_getvalue gets a pointer to int to return the value. Go figure! */
|
||||
return (*sem)->_getvalue ((int *)sval);
|
||||
__except (NO_ERROR) {}
|
||||
__endtry
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* pthread_null */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* timer.cc
|
||||
|
||||
Copyright 2004, 2005, 2006, 2008, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||
Copyright 2004, 2005, 2006, 2008, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -219,45 +219,49 @@ it_bad (const timespec& t)
|
|||
int
|
||||
timer_tracker::settime (int in_flags, const itimerspec *value, itimerspec *ovalue)
|
||||
{
|
||||
if (!value)
|
||||
int ret = -1;
|
||||
|
||||
__try
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
if (!value)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
__leave;
|
||||
}
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT)
|
||||
|| it_bad (value->it_value)
|
||||
|| it_bad (value->it_interval))
|
||||
return -1;
|
||||
if (it_bad (value->it_value) || it_bad (value->it_interval))
|
||||
__leave;
|
||||
|
||||
long long now = in_flags & TIMER_ABSTIME ? 0 : gtod.usecs ();
|
||||
long long now = in_flags & TIMER_ABSTIME ? 0 : gtod.usecs ();
|
||||
|
||||
lock_timer_tracker here;
|
||||
cancel ();
|
||||
lock_timer_tracker here;
|
||||
cancel ();
|
||||
|
||||
if (ovalue)
|
||||
gettime (ovalue);
|
||||
if (ovalue)
|
||||
gettime (ovalue);
|
||||
|
||||
if (!value->it_value.tv_sec && !value->it_value.tv_nsec)
|
||||
interval_us = sleepto_us = 0;
|
||||
else
|
||||
{
|
||||
sleepto_us = now + to_us (value->it_value);
|
||||
interval_us = to_us (value->it_interval);
|
||||
it_interval = value->it_interval;
|
||||
if (!hcancel)
|
||||
hcancel = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
|
||||
if (!value->it_value.tv_sec && !value->it_value.tv_nsec)
|
||||
interval_us = sleepto_us = 0;
|
||||
else
|
||||
ResetEvent (hcancel);
|
||||
if (!syncthread)
|
||||
syncthread = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
|
||||
else
|
||||
ResetEvent (syncthread);
|
||||
new cygthread (timer_thread, this, "itimer", syncthread);
|
||||
{
|
||||
sleepto_us = now + to_us (value->it_value);
|
||||
interval_us = to_us (value->it_interval);
|
||||
it_interval = value->it_interval;
|
||||
if (!hcancel)
|
||||
hcancel = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
|
||||
else
|
||||
ResetEvent (hcancel);
|
||||
if (!syncthread)
|
||||
syncthread = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
|
||||
else
|
||||
ResetEvent (syncthread);
|
||||
new cygthread (timer_thread, this, "itimer", syncthread);
|
||||
}
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -280,43 +284,51 @@ timer_tracker::gettime (itimerspec *ovalue)
|
|||
extern "C" int
|
||||
timer_gettime (timer_t timerid, struct itimerspec *ovalue)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
int ret = -1;
|
||||
|
||||
timer_tracker *tt = (timer_tracker *) timerid;
|
||||
if (tt->magic != TT_MAGIC)
|
||||
__try
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
timer_tracker *tt = (timer_tracker *) timerid;
|
||||
if (tt->magic != TT_MAGIC)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
tt->gettime (ovalue);
|
||||
return 0;
|
||||
tt->gettime (ovalue);
|
||||
ret = 0;
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
timer_create (clockid_t clock_id, struct sigevent *__restrict evp,
|
||||
timer_t *__restrict timerid)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
int ret = -1;
|
||||
|
||||
if (CLOCKID_IS_PROCESS (clock_id) || CLOCKID_IS_THREAD (clock_id))
|
||||
__try
|
||||
{
|
||||
set_errno (ENOTSUP);
|
||||
return -1;
|
||||
}
|
||||
if (CLOCKID_IS_PROCESS (clock_id) || CLOCKID_IS_THREAD (clock_id))
|
||||
{
|
||||
set_errno (ENOTSUP);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (clock_id != CLOCK_REALTIME)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
if (clock_id != CLOCK_REALTIME)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*timerid = (timer_t) new timer_tracker (clock_id, evp);
|
||||
return 0;
|
||||
*timerid = (timer_t) new timer_tracker (clock_id, evp);
|
||||
ret = 0;
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
|
@ -324,42 +336,52 @@ timer_settime (timer_t timerid, int flags,
|
|||
const struct itimerspec *__restrict value,
|
||||
struct itimerspec *__restrict ovalue)
|
||||
{
|
||||
timer_tracker *tt = (timer_tracker *) timerid;
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
if (tt->magic != TT_MAGIC)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
int ret = -1;
|
||||
|
||||
return tt->settime (flags, value, ovalue);
|
||||
__try
|
||||
{
|
||||
timer_tracker *tt = (timer_tracker *) timerid;
|
||||
if (tt->magic != TT_MAGIC)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
__leave;
|
||||
}
|
||||
ret = tt->settime (flags, value, ovalue);
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
timer_delete (timer_t timerid)
|
||||
{
|
||||
timer_tracker *in_tt = (timer_tracker *) timerid;
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
if (in_tt->magic != TT_MAGIC)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
int ret = -1;
|
||||
|
||||
lock_timer_tracker here;
|
||||
for (timer_tracker *tt = &ttstart; tt->next != NULL; tt = tt->next)
|
||||
if (tt->next == in_tt)
|
||||
{
|
||||
tt->next = in_tt->next;
|
||||
delete in_tt;
|
||||
return 0;
|
||||
}
|
||||
set_errno (EINVAL);
|
||||
return 0;
|
||||
__try
|
||||
{
|
||||
timer_tracker *in_tt = (timer_tracker *) timerid;
|
||||
if (in_tt->magic != TT_MAGIC)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
__leave;
|
||||
}
|
||||
|
||||
lock_timer_tracker here;
|
||||
for (timer_tracker *tt = &ttstart; tt->next != NULL; tt = tt->next)
|
||||
if (tt->next == in_tt)
|
||||
{
|
||||
tt->next = in_tt->next;
|
||||
delete in_tt;
|
||||
ret = 0;
|
||||
__leave;
|
||||
}
|
||||
set_errno (EINVAL);
|
||||
ret = 0;
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -412,18 +434,13 @@ setitimer (int which, const struct itimerval *__restrict value,
|
|||
extern "C" int
|
||||
getitimer (int which, struct itimerval *ovalue)
|
||||
{
|
||||
int ret;
|
||||
int ret = -1;
|
||||
|
||||
if (which != ITIMER_REAL)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
ret = -1;
|
||||
}
|
||||
set_errno (EINVAL);
|
||||
else
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
ret = -1;
|
||||
else
|
||||
__try
|
||||
{
|
||||
struct itimerspec spec_ovalue;
|
||||
ret = timer_gettime ((timer_t) &ttstart, &spec_ovalue);
|
||||
|
@ -435,6 +452,8 @@ getitimer (int which, struct itimerval *ovalue)
|
|||
ovalue->it_value.tv_usec = spec_ovalue.it_value.tv_nsec / 1000;
|
||||
}
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
}
|
||||
syscall_printf ("%R = getitimer()", ret);
|
||||
return ret;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* times.cc
|
||||
|
||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
||||
2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||
2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -59,35 +59,39 @@ __to_clock_t (PLARGE_INTEGER src, int flag)
|
|||
extern "C" clock_t
|
||||
times (struct tms *buf)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return ((clock_t) -1);
|
||||
|
||||
static SYSTEM_TIMEOFDAY_INFORMATION stodi;
|
||||
KERNEL_USER_TIMES kut;
|
||||
LARGE_INTEGER ticks;
|
||||
clock_t tc = (clock_t) -1;
|
||||
|
||||
/* Fetch boot time if we haven't already. */
|
||||
if (!stodi.BootTime.QuadPart)
|
||||
NtQuerySystemInformation (SystemTimeOfDayInformation,
|
||||
&stodi, sizeof stodi, NULL);
|
||||
__try
|
||||
{
|
||||
/* Fetch boot time if we haven't already. */
|
||||
if (!stodi.BootTime.QuadPart)
|
||||
NtQuerySystemInformation (SystemTimeOfDayInformation,
|
||||
&stodi, sizeof stodi, NULL);
|
||||
|
||||
NtQueryInformationProcess (NtCurrentProcess (), ProcessTimes,
|
||||
&kut, sizeof kut, NULL);
|
||||
get_system_time (&ticks);
|
||||
NtQueryInformationProcess (NtCurrentProcess (), ProcessTimes,
|
||||
&kut, sizeof kut, NULL);
|
||||
get_system_time (&ticks);
|
||||
|
||||
/* uptime */
|
||||
ticks.QuadPart -= stodi.BootTime.QuadPart;
|
||||
/* ticks is in in 100ns, convert to clock ticks. */
|
||||
clock_t tc = (clock_t) (ticks.QuadPart * CLOCKS_PER_SEC / NSPERSEC);
|
||||
|
||||
buf->tms_stime = __to_clock_t (&kut.KernelTime, 0);
|
||||
buf->tms_utime = __to_clock_t (&kut.UserTime, 0);
|
||||
timeval_to_filetime (&myself->rusage_children.ru_stime, &kut.KernelTime);
|
||||
buf->tms_cstime = __to_clock_t (&kut.KernelTime, 1);
|
||||
timeval_to_filetime (&myself->rusage_children.ru_utime, &kut.UserTime);
|
||||
buf->tms_cutime = __to_clock_t (&kut.UserTime, 1);
|
||||
/* uptime */
|
||||
ticks.QuadPart -= stodi.BootTime.QuadPart;
|
||||
/* ticks is in in 100ns, convert to clock ticks. */
|
||||
tc = (clock_t) (ticks.QuadPart * CLOCKS_PER_SEC / NSPERSEC);
|
||||
|
||||
buf->tms_stime = __to_clock_t (&kut.KernelTime, 0);
|
||||
buf->tms_utime = __to_clock_t (&kut.UserTime, 0);
|
||||
timeval_to_filetime (&myself->rusage_children.ru_stime, &kut.KernelTime);
|
||||
buf->tms_cstime = __to_clock_t (&kut.KernelTime, 1);
|
||||
timeval_to_filetime (&myself->rusage_children.ru_utime, &kut.UserTime);
|
||||
buf->tms_cutime = __to_clock_t (&kut.UserTime, 1);
|
||||
}
|
||||
__except (EFAULT)
|
||||
{
|
||||
tc = (clock_t) -1;
|
||||
}
|
||||
__endtry
|
||||
syscall_printf ("%D = times(%p)", tc, buf);
|
||||
return tc;
|
||||
}
|
||||
|
@ -100,34 +104,37 @@ settimeofday (const struct timeval *tv, const struct timezone *tz)
|
|||
{
|
||||
SYSTEMTIME st;
|
||||
struct tm *ptm;
|
||||
int res;
|
||||
int res = -1;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
if (tv->tv_usec < 0 || tv->tv_usec >= 1000000)
|
||||
__try
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
if (tv->tv_usec < 0 || tv->tv_usec >= 1000000)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ptm = gmtime (&tv->tv_sec);
|
||||
st.wYear = ptm->tm_year + 1900;
|
||||
st.wMonth = ptm->tm_mon + 1;
|
||||
st.wDayOfWeek = ptm->tm_wday;
|
||||
st.wDay = ptm->tm_mday;
|
||||
st.wHour = ptm->tm_hour;
|
||||
st.wMinute = ptm->tm_min;
|
||||
st.wSecond = ptm->tm_sec;
|
||||
st.wMilliseconds = tv->tv_usec / 1000;
|
||||
|
||||
res = -!SetSystemTime (&st);
|
||||
gtod.reset ();
|
||||
|
||||
if (res)
|
||||
set_errno (EPERM);
|
||||
}
|
||||
|
||||
ptm = gmtime (&tv->tv_sec);
|
||||
st.wYear = ptm->tm_year + 1900;
|
||||
st.wMonth = ptm->tm_mon + 1;
|
||||
st.wDayOfWeek = ptm->tm_wday;
|
||||
st.wDay = ptm->tm_mday;
|
||||
st.wHour = ptm->tm_hour;
|
||||
st.wMinute = ptm->tm_min;
|
||||
st.wSecond = ptm->tm_sec;
|
||||
st.wMilliseconds = tv->tv_usec / 1000;
|
||||
|
||||
res = -!SetSystemTime (&st);
|
||||
gtod.reset ();
|
||||
|
||||
if (res)
|
||||
set_errno (EPERM);
|
||||
|
||||
__except (EFAULT)
|
||||
{
|
||||
res = -1;
|
||||
}
|
||||
__endtry
|
||||
syscall_printf ("%R = settimeofday(%p, %p)", res, tv, tz);
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -8,17 +8,16 @@ details. */
|
|||
|
||||
#include <winsup.h>
|
||||
#include <malloc.h>
|
||||
#include "cygtls.h"
|
||||
#include "tls_pbuf.h"
|
||||
|
||||
#define tls_pbuf _my_tls.locals.pathbufs
|
||||
#define tls_pbuf _my_tls.pathbufs
|
||||
|
||||
void
|
||||
tls_pathbuf::destroy ()
|
||||
{
|
||||
for (unsigned i = 0; i < TP_NUM_C_BUFS && c_buf[i]; ++i)
|
||||
for (uint32_t i = 0; i < TP_NUM_C_BUFS && c_buf[i]; ++i)
|
||||
free (c_buf[i]);
|
||||
for (unsigned i = 0; i < TP_NUM_W_BUFS && w_buf[i]; ++i)
|
||||
for (uint32_t i = 0; i < TP_NUM_W_BUFS && w_buf[i]; ++i)
|
||||
free (w_buf[i]);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,20 +10,20 @@ details. */
|
|||
|
||||
class tmp_pathbuf
|
||||
{
|
||||
unsigned c_buf_old;
|
||||
unsigned w_buf_old;
|
||||
uint32_t c_buf_old;
|
||||
uint32_t w_buf_old;
|
||||
public:
|
||||
tmp_pathbuf () __attribute__ ((always_inline))
|
||||
: c_buf_old (_my_tls.locals.pathbufs.c_cnt),
|
||||
w_buf_old (_my_tls.locals.pathbufs.w_cnt)
|
||||
: c_buf_old (_my_tls.pathbufs.c_cnt),
|
||||
w_buf_old (_my_tls.pathbufs.w_cnt)
|
||||
{}
|
||||
~tmp_pathbuf () __attribute__ ((always_inline))
|
||||
{
|
||||
_my_tls.locals.pathbufs.c_cnt = c_buf_old;
|
||||
_my_tls.locals.pathbufs.w_cnt = w_buf_old;
|
||||
_my_tls.pathbufs.c_cnt = c_buf_old;
|
||||
_my_tls.pathbufs.w_cnt = w_buf_old;
|
||||
}
|
||||
|
||||
inline bool check_usage (unsigned c_need, unsigned w_need)
|
||||
inline bool check_usage (uint32_t c_need, uint32_t w_need)
|
||||
{
|
||||
return c_need + c_buf_old < TP_NUM_C_BUFS
|
||||
&& w_need + w_buf_old < TP_NUM_W_BUFS;
|
||||
|
|
|
@ -3,44 +3,46 @@
|
|||
//; $tls::start_offset = -12700;
|
||||
//; $tls::locals = -12700;
|
||||
//; $tls::plocals = 0;
|
||||
//; $tls::local_clib = -10980;
|
||||
//; $tls::plocal_clib = 1720;
|
||||
//; $tls::__dontuse = -10980;
|
||||
//; $tls::p__dontuse = 1720;
|
||||
//; $tls::func = -9892;
|
||||
//; $tls::pfunc = 2808;
|
||||
//; $tls::saved_errno = -9888;
|
||||
//; $tls::psaved_errno = 2812;
|
||||
//; $tls::sa_flags = -9884;
|
||||
//; $tls::psa_flags = 2816;
|
||||
//; $tls::oldmask = -9880;
|
||||
//; $tls::poldmask = 2820;
|
||||
//; $tls::deltamask = -9876;
|
||||
//; $tls::pdeltamask = 2824;
|
||||
//; $tls::errno_addr = -9872;
|
||||
//; $tls::perrno_addr = 2828;
|
||||
//; $tls::sigmask = -9868;
|
||||
//; $tls::psigmask = 2832;
|
||||
//; $tls::sigwait_mask = -9864;
|
||||
//; $tls::psigwait_mask = 2836;
|
||||
//; $tls::sigwait_info = -9860;
|
||||
//; $tls::psigwait_info = 2840;
|
||||
//; $tls::signal_arrived = -9856;
|
||||
//; $tls::psignal_arrived = 2844;
|
||||
//; $tls::will_wait_for_signal = -9852;
|
||||
//; $tls::pwill_wait_for_signal = 2848;
|
||||
//; $tls::thread_context = -9848;
|
||||
//; $tls::pthread_context = 2852;
|
||||
//; $tls::thread_id = -9636;
|
||||
//; $tls::pthread_id = 3064;
|
||||
//; $tls::infodata = -9632;
|
||||
//; $tls::pinfodata = 3068;
|
||||
//; $tls::tid = -9484;
|
||||
//; $tls::ptid = 3216;
|
||||
//; $tls::_ctinfo = -9480;
|
||||
//; $tls::p_ctinfo = 3220;
|
||||
//; $tls::andreas = -9476;
|
||||
//; $tls::pandreas = 3224;
|
||||
//; $tls::local_clib = -11388;
|
||||
//; $tls::plocal_clib = 1312;
|
||||
//; $tls::__dontuse = -11388;
|
||||
//; $tls::p__dontuse = 1312;
|
||||
//; $tls::func = -10300;
|
||||
//; $tls::pfunc = 2400;
|
||||
//; $tls::saved_errno = -10296;
|
||||
//; $tls::psaved_errno = 2404;
|
||||
//; $tls::sa_flags = -10292;
|
||||
//; $tls::psa_flags = 2408;
|
||||
//; $tls::oldmask = -10288;
|
||||
//; $tls::poldmask = 2412;
|
||||
//; $tls::deltamask = -10284;
|
||||
//; $tls::pdeltamask = 2416;
|
||||
//; $tls::errno_addr = -10280;
|
||||
//; $tls::perrno_addr = 2420;
|
||||
//; $tls::sigmask = -10276;
|
||||
//; $tls::psigmask = 2424;
|
||||
//; $tls::sigwait_mask = -10272;
|
||||
//; $tls::psigwait_mask = 2428;
|
||||
//; $tls::sigwait_info = -10268;
|
||||
//; $tls::psigwait_info = 2432;
|
||||
//; $tls::signal_arrived = -10264;
|
||||
//; $tls::psignal_arrived = 2436;
|
||||
//; $tls::will_wait_for_signal = -10260;
|
||||
//; $tls::pwill_wait_for_signal = 2440;
|
||||
//; $tls::thread_context = -10256;
|
||||
//; $tls::pthread_context = 2444;
|
||||
//; $tls::thread_id = -10044;
|
||||
//; $tls::pthread_id = 2656;
|
||||
//; $tls::infodata = -10040;
|
||||
//; $tls::pinfodata = 2660;
|
||||
//; $tls::tid = -9892;
|
||||
//; $tls::ptid = 2808;
|
||||
//; $tls::_ctinfo = -9888;
|
||||
//; $tls::p_ctinfo = 2812;
|
||||
//; $tls::andreas = -9884;
|
||||
//; $tls::pandreas = 2816;
|
||||
//; $tls::pathbufs = -9880;
|
||||
//; $tls::ppathbufs = 2820;
|
||||
//; $tls::wq = -9472;
|
||||
//; $tls::pwq = 3228;
|
||||
//; $tls::sig = -9444;
|
||||
|
@ -61,44 +63,46 @@
|
|||
|
||||
#define tls_locals (-12700)
|
||||
#define tls_plocals (0)
|
||||
#define tls_local_clib (-10980)
|
||||
#define tls_plocal_clib (1720)
|
||||
#define tls___dontuse (-10980)
|
||||
#define tls_p__dontuse (1720)
|
||||
#define tls_func (-9892)
|
||||
#define tls_pfunc (2808)
|
||||
#define tls_saved_errno (-9888)
|
||||
#define tls_psaved_errno (2812)
|
||||
#define tls_sa_flags (-9884)
|
||||
#define tls_psa_flags (2816)
|
||||
#define tls_oldmask (-9880)
|
||||
#define tls_poldmask (2820)
|
||||
#define tls_deltamask (-9876)
|
||||
#define tls_pdeltamask (2824)
|
||||
#define tls_errno_addr (-9872)
|
||||
#define tls_perrno_addr (2828)
|
||||
#define tls_sigmask (-9868)
|
||||
#define tls_psigmask (2832)
|
||||
#define tls_sigwait_mask (-9864)
|
||||
#define tls_psigwait_mask (2836)
|
||||
#define tls_sigwait_info (-9860)
|
||||
#define tls_psigwait_info (2840)
|
||||
#define tls_signal_arrived (-9856)
|
||||
#define tls_psignal_arrived (2844)
|
||||
#define tls_will_wait_for_signal (-9852)
|
||||
#define tls_pwill_wait_for_signal (2848)
|
||||
#define tls_thread_context (-9848)
|
||||
#define tls_pthread_context (2852)
|
||||
#define tls_thread_id (-9636)
|
||||
#define tls_pthread_id (3064)
|
||||
#define tls_infodata (-9632)
|
||||
#define tls_pinfodata (3068)
|
||||
#define tls_tid (-9484)
|
||||
#define tls_ptid (3216)
|
||||
#define tls__ctinfo (-9480)
|
||||
#define tls_p_ctinfo (3220)
|
||||
#define tls_andreas (-9476)
|
||||
#define tls_pandreas (3224)
|
||||
#define tls_local_clib (-11388)
|
||||
#define tls_plocal_clib (1312)
|
||||
#define tls___dontuse (-11388)
|
||||
#define tls_p__dontuse (1312)
|
||||
#define tls_func (-10300)
|
||||
#define tls_pfunc (2400)
|
||||
#define tls_saved_errno (-10296)
|
||||
#define tls_psaved_errno (2404)
|
||||
#define tls_sa_flags (-10292)
|
||||
#define tls_psa_flags (2408)
|
||||
#define tls_oldmask (-10288)
|
||||
#define tls_poldmask (2412)
|
||||
#define tls_deltamask (-10284)
|
||||
#define tls_pdeltamask (2416)
|
||||
#define tls_errno_addr (-10280)
|
||||
#define tls_perrno_addr (2420)
|
||||
#define tls_sigmask (-10276)
|
||||
#define tls_psigmask (2424)
|
||||
#define tls_sigwait_mask (-10272)
|
||||
#define tls_psigwait_mask (2428)
|
||||
#define tls_sigwait_info (-10268)
|
||||
#define tls_psigwait_info (2432)
|
||||
#define tls_signal_arrived (-10264)
|
||||
#define tls_psignal_arrived (2436)
|
||||
#define tls_will_wait_for_signal (-10260)
|
||||
#define tls_pwill_wait_for_signal (2440)
|
||||
#define tls_thread_context (-10256)
|
||||
#define tls_pthread_context (2444)
|
||||
#define tls_thread_id (-10044)
|
||||
#define tls_pthread_id (2656)
|
||||
#define tls_infodata (-10040)
|
||||
#define tls_pinfodata (2660)
|
||||
#define tls_tid (-9892)
|
||||
#define tls_ptid (2808)
|
||||
#define tls__ctinfo (-9888)
|
||||
#define tls_p_ctinfo (2812)
|
||||
#define tls_andreas (-9884)
|
||||
#define tls_pandreas (2816)
|
||||
#define tls_pathbufs (-9880)
|
||||
#define tls_ppathbufs (2820)
|
||||
#define tls_wq (-9472)
|
||||
#define tls_pwq (3228)
|
||||
#define tls_sig (-9444)
|
||||
|
|
|
@ -3,44 +3,46 @@
|
|||
//; $tls::start_offset = -12800;
|
||||
//; $tls::locals = -12800;
|
||||
//; $tls::plocals = 0;
|
||||
//; $tls::local_clib = -10624;
|
||||
//; $tls::plocal_clib = 2176;
|
||||
//; $tls::__dontuse = -10624;
|
||||
//; $tls::p__dontuse = 2176;
|
||||
//; $tls::func = -8736;
|
||||
//; $tls::pfunc = 4064;
|
||||
//; $tls::saved_errno = -8728;
|
||||
//; $tls::psaved_errno = 4072;
|
||||
//; $tls::sa_flags = -8724;
|
||||
//; $tls::psa_flags = 4076;
|
||||
//; $tls::oldmask = -8720;
|
||||
//; $tls::poldmask = 4080;
|
||||
//; $tls::deltamask = -8712;
|
||||
//; $tls::pdeltamask = 4088;
|
||||
//; $tls::errno_addr = -8704;
|
||||
//; $tls::perrno_addr = 4096;
|
||||
//; $tls::sigmask = -8696;
|
||||
//; $tls::psigmask = 4104;
|
||||
//; $tls::sigwait_mask = -8688;
|
||||
//; $tls::psigwait_mask = 4112;
|
||||
//; $tls::sigwait_info = -8680;
|
||||
//; $tls::psigwait_info = 4120;
|
||||
//; $tls::signal_arrived = -8672;
|
||||
//; $tls::psignal_arrived = 4128;
|
||||
//; $tls::will_wait_for_signal = -8664;
|
||||
//; $tls::pwill_wait_for_signal = 4136;
|
||||
//; $tls::thread_context = -8656;
|
||||
//; $tls::pthread_context = 4144;
|
||||
//; $tls::thread_id = -7824;
|
||||
//; $tls::pthread_id = 4976;
|
||||
//; $tls::infodata = -7820;
|
||||
//; $tls::pinfodata = 4980;
|
||||
//; $tls::tid = -7672;
|
||||
//; $tls::ptid = 5128;
|
||||
//; $tls::_ctinfo = -7664;
|
||||
//; $tls::p_ctinfo = 5136;
|
||||
//; $tls::andreas = -7656;
|
||||
//; $tls::pandreas = 5144;
|
||||
//; $tls::local_clib = -11432;
|
||||
//; $tls::plocal_clib = 1368;
|
||||
//; $tls::__dontuse = -11432;
|
||||
//; $tls::p__dontuse = 1368;
|
||||
//; $tls::func = -9544;
|
||||
//; $tls::pfunc = 3256;
|
||||
//; $tls::saved_errno = -9536;
|
||||
//; $tls::psaved_errno = 3264;
|
||||
//; $tls::sa_flags = -9532;
|
||||
//; $tls::psa_flags = 3268;
|
||||
//; $tls::oldmask = -9528;
|
||||
//; $tls::poldmask = 3272;
|
||||
//; $tls::deltamask = -9520;
|
||||
//; $tls::pdeltamask = 3280;
|
||||
//; $tls::errno_addr = -9512;
|
||||
//; $tls::perrno_addr = 3288;
|
||||
//; $tls::sigmask = -9504;
|
||||
//; $tls::psigmask = 3296;
|
||||
//; $tls::sigwait_mask = -9496;
|
||||
//; $tls::psigwait_mask = 3304;
|
||||
//; $tls::sigwait_info = -9488;
|
||||
//; $tls::psigwait_info = 3312;
|
||||
//; $tls::signal_arrived = -9480;
|
||||
//; $tls::psignal_arrived = 3320;
|
||||
//; $tls::will_wait_for_signal = -9472;
|
||||
//; $tls::pwill_wait_for_signal = 3328;
|
||||
//; $tls::thread_context = -9464;
|
||||
//; $tls::pthread_context = 3336;
|
||||
//; $tls::thread_id = -8632;
|
||||
//; $tls::pthread_id = 4168;
|
||||
//; $tls::infodata = -8628;
|
||||
//; $tls::pinfodata = 4172;
|
||||
//; $tls::tid = -8480;
|
||||
//; $tls::ptid = 4320;
|
||||
//; $tls::_ctinfo = -8472;
|
||||
//; $tls::p_ctinfo = 4328;
|
||||
//; $tls::andreas = -8464;
|
||||
//; $tls::pandreas = 4336;
|
||||
//; $tls::pathbufs = -8456;
|
||||
//; $tls::ppathbufs = 4344;
|
||||
//; $tls::wq = -7648;
|
||||
//; $tls::pwq = 5152;
|
||||
//; $tls::sig = -7600;
|
||||
|
@ -61,44 +63,46 @@
|
|||
|
||||
#define tls_locals (-12800)
|
||||
#define tls_plocals (0)
|
||||
#define tls_local_clib (-10624)
|
||||
#define tls_plocal_clib (2176)
|
||||
#define tls___dontuse (-10624)
|
||||
#define tls_p__dontuse (2176)
|
||||
#define tls_func (-8736)
|
||||
#define tls_pfunc (4064)
|
||||
#define tls_saved_errno (-8728)
|
||||
#define tls_psaved_errno (4072)
|
||||
#define tls_sa_flags (-8724)
|
||||
#define tls_psa_flags (4076)
|
||||
#define tls_oldmask (-8720)
|
||||
#define tls_poldmask (4080)
|
||||
#define tls_deltamask (-8712)
|
||||
#define tls_pdeltamask (4088)
|
||||
#define tls_errno_addr (-8704)
|
||||
#define tls_perrno_addr (4096)
|
||||
#define tls_sigmask (-8696)
|
||||
#define tls_psigmask (4104)
|
||||
#define tls_sigwait_mask (-8688)
|
||||
#define tls_psigwait_mask (4112)
|
||||
#define tls_sigwait_info (-8680)
|
||||
#define tls_psigwait_info (4120)
|
||||
#define tls_signal_arrived (-8672)
|
||||
#define tls_psignal_arrived (4128)
|
||||
#define tls_will_wait_for_signal (-8664)
|
||||
#define tls_pwill_wait_for_signal (4136)
|
||||
#define tls_thread_context (-8656)
|
||||
#define tls_pthread_context (4144)
|
||||
#define tls_thread_id (-7824)
|
||||
#define tls_pthread_id (4976)
|
||||
#define tls_infodata (-7820)
|
||||
#define tls_pinfodata (4980)
|
||||
#define tls_tid (-7672)
|
||||
#define tls_ptid (5128)
|
||||
#define tls__ctinfo (-7664)
|
||||
#define tls_p_ctinfo (5136)
|
||||
#define tls_andreas (-7656)
|
||||
#define tls_pandreas (5144)
|
||||
#define tls_local_clib (-11432)
|
||||
#define tls_plocal_clib (1368)
|
||||
#define tls___dontuse (-11432)
|
||||
#define tls_p__dontuse (1368)
|
||||
#define tls_func (-9544)
|
||||
#define tls_pfunc (3256)
|
||||
#define tls_saved_errno (-9536)
|
||||
#define tls_psaved_errno (3264)
|
||||
#define tls_sa_flags (-9532)
|
||||
#define tls_psa_flags (3268)
|
||||
#define tls_oldmask (-9528)
|
||||
#define tls_poldmask (3272)
|
||||
#define tls_deltamask (-9520)
|
||||
#define tls_pdeltamask (3280)
|
||||
#define tls_errno_addr (-9512)
|
||||
#define tls_perrno_addr (3288)
|
||||
#define tls_sigmask (-9504)
|
||||
#define tls_psigmask (3296)
|
||||
#define tls_sigwait_mask (-9496)
|
||||
#define tls_psigwait_mask (3304)
|
||||
#define tls_sigwait_info (-9488)
|
||||
#define tls_psigwait_info (3312)
|
||||
#define tls_signal_arrived (-9480)
|
||||
#define tls_psignal_arrived (3320)
|
||||
#define tls_will_wait_for_signal (-9472)
|
||||
#define tls_pwill_wait_for_signal (3328)
|
||||
#define tls_thread_context (-9464)
|
||||
#define tls_pthread_context (3336)
|
||||
#define tls_thread_id (-8632)
|
||||
#define tls_pthread_id (4168)
|
||||
#define tls_infodata (-8628)
|
||||
#define tls_pinfodata (4172)
|
||||
#define tls_tid (-8480)
|
||||
#define tls_ptid (4320)
|
||||
#define tls__ctinfo (-8472)
|
||||
#define tls_p_ctinfo (4328)
|
||||
#define tls_andreas (-8464)
|
||||
#define tls_pandreas (4336)
|
||||
#define tls_pathbufs (-8456)
|
||||
#define tls_ppathbufs (4344)
|
||||
#define tls_wq (-7648)
|
||||
#define tls_pwq (5152)
|
||||
#define tls_sig (-7600)
|
||||
|
|
|
@ -217,10 +217,15 @@ getlogin_r (char *name, size_t namesize)
|
|||
size_t len = strlen (login) + 1;
|
||||
if (len > namesize)
|
||||
return ERANGE;
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
return EFAULT;
|
||||
strncpy (name, login, len);
|
||||
__try
|
||||
{
|
||||
strncpy (name, login, len);
|
||||
}
|
||||
__except (NO_ERROR)
|
||||
{
|
||||
return EFAULT;
|
||||
}
|
||||
__endtry
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* uname.cc
|
||||
|
||||
Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
||||
2006, 2007, 2008, 2013 Red Hat, Inc.
|
||||
2006, 2007, 2008, 2013, 2014 Red Hat, Inc.
|
||||
Written by Steve Chamberlain of Cygnus Support, sac@cygnus.com
|
||||
Rewritten by Geoffrey Noer of Cygnus Solutions, noer@cygnus.com
|
||||
|
||||
|
@ -22,74 +22,77 @@ uname (struct utsname *name)
|
|||
{
|
||||
SYSTEM_INFO sysinfo;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
char *snp = strstr (cygwin_version.dll_build_date, "SNP");
|
||||
|
||||
memset (name, 0, sizeof (*name));
|
||||
__small_sprintf (name->sysname, "CYGWIN_%s", wincap.osname ());
|
||||
|
||||
/* Add a hint to the sysname, that we're running under WOW64. This might
|
||||
give an early clue if somebody encounters problems. */
|
||||
if (wincap.is_wow64 ())
|
||||
strncat (name->sysname, "-WOW64",
|
||||
sizeof name->sysname - strlen (name->sysname) - 1);
|
||||
|
||||
GetSystemInfo (&sysinfo);
|
||||
|
||||
/* Computer name */
|
||||
cygwin_gethostname (name->nodename, sizeof (name->nodename) - 1);
|
||||
|
||||
/* Cygwin dll release */
|
||||
__small_sprintf (name->release, "%d.%d.%d%s(%d.%d/%d/%d)",
|
||||
cygwin_version.dll_major / 1000,
|
||||
cygwin_version.dll_major % 1000,
|
||||
cygwin_version.dll_minor,
|
||||
snp ? "s" : "",
|
||||
cygwin_version.api_major,
|
||||
cygwin_version.api_minor,
|
||||
cygwin_version.shared_data,
|
||||
cygwin_version.mount_registry);
|
||||
|
||||
/* Cygwin "version" aka build date */
|
||||
strcpy (name->version, cygwin_version.dll_build_date);
|
||||
if (snp)
|
||||
name->version[snp - cygwin_version.dll_build_date] = '\0';
|
||||
|
||||
/* CPU type */
|
||||
switch (sysinfo.wProcessorArchitecture)
|
||||
__try
|
||||
{
|
||||
case PROCESSOR_ARCHITECTURE_INTEL:
|
||||
unsigned int ptype;
|
||||
if (sysinfo.wProcessorLevel < 3) /* Shouldn't happen. */
|
||||
ptype = 3;
|
||||
else if (sysinfo.wProcessorLevel > 9) /* P4 */
|
||||
ptype = 6;
|
||||
else
|
||||
ptype = sysinfo.wProcessorLevel;
|
||||
__small_sprintf (name->machine, "i%d86", ptype);
|
||||
break;
|
||||
case PROCESSOR_ARCHITECTURE_IA64:
|
||||
strcpy (name->machine, "ia64");
|
||||
break;
|
||||
case PROCESSOR_ARCHITECTURE_AMD64:
|
||||
strcpy (name->machine, "x86_64");
|
||||
break;
|
||||
case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64:
|
||||
strcpy (name->machine, "ia32-win64");
|
||||
break;
|
||||
case PROCESSOR_ARCHITECTURE_ALPHA:
|
||||
strcpy (name->machine, "alpha");
|
||||
break;
|
||||
case PROCESSOR_ARCHITECTURE_MIPS:
|
||||
strcpy (name->machine, "mips");
|
||||
break;
|
||||
default:
|
||||
strcpy (name->machine, "unknown");
|
||||
break;
|
||||
}
|
||||
char *snp = strstr (cygwin_version.dll_build_date, "SNP");
|
||||
|
||||
memset (name, 0, sizeof (*name));
|
||||
__small_sprintf (name->sysname, "CYGWIN_%s", wincap.osname ());
|
||||
|
||||
/* Add a hint to the sysname, that we're running under WOW64. This might
|
||||
give an early clue if somebody encounters problems. */
|
||||
if (wincap.is_wow64 ())
|
||||
strncat (name->sysname, "-WOW64",
|
||||
sizeof name->sysname - strlen (name->sysname) - 1);
|
||||
|
||||
GetSystemInfo (&sysinfo);
|
||||
|
||||
/* Computer name */
|
||||
cygwin_gethostname (name->nodename, sizeof (name->nodename) - 1);
|
||||
|
||||
/* Cygwin dll release */
|
||||
__small_sprintf (name->release, "%d.%d.%d%s(%d.%d/%d/%d)",
|
||||
cygwin_version.dll_major / 1000,
|
||||
cygwin_version.dll_major % 1000,
|
||||
cygwin_version.dll_minor,
|
||||
snp ? "s" : "",
|
||||
cygwin_version.api_major,
|
||||
cygwin_version.api_minor,
|
||||
cygwin_version.shared_data,
|
||||
cygwin_version.mount_registry);
|
||||
|
||||
/* Cygwin "version" aka build date */
|
||||
strcpy (name->version, cygwin_version.dll_build_date);
|
||||
if (snp)
|
||||
name->version[snp - cygwin_version.dll_build_date] = '\0';
|
||||
|
||||
/* CPU type */
|
||||
switch (sysinfo.wProcessorArchitecture)
|
||||
{
|
||||
case PROCESSOR_ARCHITECTURE_INTEL:
|
||||
unsigned int ptype;
|
||||
if (sysinfo.wProcessorLevel < 3) /* Shouldn't happen. */
|
||||
ptype = 3;
|
||||
else if (sysinfo.wProcessorLevel > 9) /* P4 */
|
||||
ptype = 6;
|
||||
else
|
||||
ptype = sysinfo.wProcessorLevel;
|
||||
__small_sprintf (name->machine, "i%d86", ptype);
|
||||
break;
|
||||
case PROCESSOR_ARCHITECTURE_IA64:
|
||||
strcpy (name->machine, "ia64");
|
||||
break;
|
||||
case PROCESSOR_ARCHITECTURE_AMD64:
|
||||
strcpy (name->machine, "x86_64");
|
||||
break;
|
||||
case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64:
|
||||
strcpy (name->machine, "ia32-win64");
|
||||
break;
|
||||
case PROCESSOR_ARCHITECTURE_ALPHA:
|
||||
strcpy (name->machine, "alpha");
|
||||
break;
|
||||
case PROCESSOR_ARCHITECTURE_MIPS:
|
||||
strcpy (name->machine, "mips");
|
||||
break;
|
||||
default:
|
||||
strcpy (name->machine, "unknown");
|
||||
break;
|
||||
}
|
||||
}
|
||||
__except (EFAULT)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
__endtry
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue