* 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>
|
2014-08-21 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* miscfuncs.cc (__import_address): Cover the first dereference to imp
|
* 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;
|
_cygtls *t = NULL;
|
||||||
issig_wait = false;
|
issig_wait = false;
|
||||||
|
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted ())
|
|
||||||
threadlist[ix]->remove (INFINITE);
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
ix = -1;
|
ix = -1;
|
||||||
/* Scan thread list looking for valid signal-delivery candidates */
|
/* 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];
|
t = cygheap->threadlist[ix];
|
||||||
issig_wait = true;
|
issig_wait = true;
|
||||||
goto out;
|
__leave;
|
||||||
}
|
}
|
||||||
else if (!t && !sigismember (&(threadlist[ix]->sigmask), sig))
|
else if (!t && !sigismember (&(threadlist[ix]->sigmask), sig))
|
||||||
t = cygheap->threadlist[ix];
|
t = cygheap->threadlist[ix];
|
||||||
}
|
}
|
||||||
out:
|
__except (NO_ERROR)
|
||||||
|
{
|
||||||
|
threadlist[ix]->remove (INFINITE);
|
||||||
|
}
|
||||||
|
__endtry
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
@ -193,7 +193,7 @@ _cygtls::remove (DWORD wait)
|
|||||||
free_local (servent_buf);
|
free_local (servent_buf);
|
||||||
free_local (hostent_buf);
|
free_local (hostent_buf);
|
||||||
/* Free temporary TLS path buffers. */
|
/* Free temporary TLS path buffers. */
|
||||||
locals.pathbufs.destroy ();
|
pathbufs.destroy ();
|
||||||
/* Close timer handle. */
|
/* Close timer handle. */
|
||||||
if (locals.cw_timer)
|
if (locals.cw_timer)
|
||||||
NtClose (locals.cw_timer);
|
NtClose (locals.cw_timer);
|
||||||
|
@ -44,18 +44,21 @@ details. */
|
|||||||
#else
|
#else
|
||||||
#pragma pack(push,4)
|
#pragma pack(push,4)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Defined here to support auto rebuild of tlsoffsets.h. */
|
/* Defined here to support auto rebuild of tlsoffsets.h. */
|
||||||
class tls_pathbuf
|
class tls_pathbuf
|
||||||
{
|
{
|
||||||
int c_cnt;
|
/* Make sure that c_cnt and w_cnt are always the first two members of this
|
||||||
int w_cnt;
|
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];
|
char *c_buf[TP_NUM_C_BUFS];
|
||||||
WCHAR *w_buf[TP_NUM_W_BUFS];
|
WCHAR *w_buf[TP_NUM_W_BUFS];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void destroy ();
|
void destroy ();
|
||||||
friend class tmp_pathbuf;
|
friend class tmp_pathbuf;
|
||||||
friend class _cygtls;
|
|
||||||
friend class san;
|
friend class san;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -129,8 +132,6 @@ struct _local_storage
|
|||||||
/* thread.cc */
|
/* thread.cc */
|
||||||
HANDLE cw_timer;
|
HANDLE cw_timer;
|
||||||
|
|
||||||
/* All functions requiring temporary path buffers. */
|
|
||||||
tls_pathbuf pathbufs;
|
|
||||||
char ttybuf[32];
|
char ttybuf[32];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -188,6 +189,7 @@ public:
|
|||||||
struct pthread *tid;
|
struct pthread *tid;
|
||||||
class cygthread *_ctinfo;
|
class cygthread *_ctinfo;
|
||||||
class san *andreas;
|
class san *andreas;
|
||||||
|
tls_pathbuf pathbufs;
|
||||||
waitq wq;
|
waitq wq;
|
||||||
int sig;
|
int sig;
|
||||||
unsigned incyg;
|
unsigned incyg;
|
||||||
@ -281,34 +283,25 @@ const int CYGTLS_PADSIZE = 12700;
|
|||||||
extern PVOID _tlsbase __asm__ ("%fs:4");
|
extern PVOID _tlsbase __asm__ ("%fs:4");
|
||||||
extern PVOID _tlstop __asm__ ("%fs:8");
|
extern PVOID _tlstop __asm__ ("%fs:8");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define _my_tls (*((_cygtls *) ((char *)_tlsbase - CYGTLS_PADSIZE)))
|
#define _my_tls (*((_cygtls *) ((char *)_tlsbase - CYGTLS_PADSIZE)))
|
||||||
extern _cygtls *_main_tls;
|
extern _cygtls *_main_tls;
|
||||||
extern _cygtls *_sig_tls;
|
extern _cygtls *_sig_tls;
|
||||||
|
|
||||||
|
#ifndef __x86_64__
|
||||||
class san
|
class san
|
||||||
{
|
{
|
||||||
san *_clemente;
|
san *_clemente;
|
||||||
jmp_buf _context;
|
jmp_buf _context;
|
||||||
int _errno;
|
|
||||||
unsigned _c_cnt;
|
|
||||||
unsigned _w_cnt;
|
|
||||||
public:
|
public:
|
||||||
int setup (int myerrno = 0) __attribute__ ((always_inline))
|
int setup () __attribute__ ((always_inline))
|
||||||
{
|
{
|
||||||
_clemente = _my_tls.andreas;
|
_clemente = _my_tls.andreas;
|
||||||
_my_tls.andreas = this;
|
_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);
|
return __sjfault (_context);
|
||||||
}
|
}
|
||||||
void leave () __attribute__ ((always_inline))
|
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);
|
__ljfault (_context, 1);
|
||||||
}
|
}
|
||||||
void reset () __attribute__ ((always_inline))
|
void reset () __attribute__ ((always_inline))
|
||||||
@ -324,17 +317,73 @@ public:
|
|||||||
~myfault () __attribute__ ((always_inline)) { sebastian.reset (); }
|
~myfault () __attribute__ ((always_inline)) { sebastian.reset (); }
|
||||||
inline int faulted () __attribute__ ((always_inline))
|
inline int faulted () __attribute__ ((always_inline))
|
||||||
{
|
{
|
||||||
return sebastian.setup (0);
|
return sebastian.setup ();
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
#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
|
class set_signal_arrived
|
||||||
{
|
{
|
||||||
|
@ -796,10 +796,6 @@ dll_crt0_0 ()
|
|||||||
|
|
||||||
_main_tls = &_my_tls;
|
_main_tls = &_my_tls;
|
||||||
|
|
||||||
#ifdef __x86_64__
|
|
||||||
exception::install_myfault_handler ();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Initialize signal processing here, early, in the hopes that the creation
|
/* Initialize signal processing here, early, in the hopes that the creation
|
||||||
of a thread early in the process will cause more predictability in memory
|
of a thread early in the process will cause more predictability in memory
|
||||||
layout for the main thread. */
|
layout for the main thread. */
|
||||||
|
@ -28,16 +28,16 @@ details. */
|
|||||||
extern "C" int
|
extern "C" int
|
||||||
dirfd (DIR *dir)
|
dirfd (DIR *dir)
|
||||||
{
|
{
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EFAULT))
|
|
||||||
return -1;
|
|
||||||
if (dir->__d_cookie != __DIRENT_COOKIE)
|
|
||||||
{
|
{
|
||||||
set_errno (EINVAL);
|
if (dir->__d_cookie == __DIRENT_COOKIE)
|
||||||
syscall_printf ("-1 = dirfd (%p)", dir);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return dir->__d_fd;
|
return dir->__d_fd;
|
||||||
|
syscall_printf ("-1 = dirfd (%p)", dir);
|
||||||
|
set_errno (EINVAL);
|
||||||
|
}
|
||||||
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Symbol kept for backward compatibility. Don't remove. Don't declare
|
/* Symbol kept for backward compatibility. Don't remove. Don't declare
|
||||||
@ -93,21 +93,22 @@ fdopendir (int fd)
|
|||||||
static int
|
static int
|
||||||
readdir_worker (DIR *dir, dirent *de)
|
readdir_worker (DIR *dir, dirent *de)
|
||||||
{
|
{
|
||||||
myfault efault;
|
int res = 0;
|
||||||
if (efault.faulted ())
|
|
||||||
return EFAULT;
|
|
||||||
|
|
||||||
|
__try
|
||||||
|
{
|
||||||
if (dir->__d_cookie != __DIRENT_COOKIE)
|
if (dir->__d_cookie != __DIRENT_COOKIE)
|
||||||
{
|
{
|
||||||
syscall_printf ("%p = readdir (%p)", NULL, dir);
|
syscall_printf ("%p = readdir (%p)", NULL, dir);
|
||||||
return EBADF;
|
res = EBADF;
|
||||||
|
__leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
de->d_ino = 0;
|
de->d_ino = 0;
|
||||||
de->d_type = DT_UNKNOWN;
|
de->d_type = DT_UNKNOWN;
|
||||||
memset (&de->__d_unused1, 0, sizeof (de->__d_unused1));
|
memset (&de->__d_unused1, 0, sizeof (de->__d_unused1));
|
||||||
|
|
||||||
int res = ((fhandler_base *) dir->__fh)->readdir (dir, de);
|
res = ((fhandler_base *) dir->__fh)->readdir (dir, de);
|
||||||
|
|
||||||
if (res == ENMFILE)
|
if (res == ENMFILE)
|
||||||
{
|
{
|
||||||
@ -141,7 +142,8 @@ readdir_worker (DIR *dir, dirent *de)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (is_dot_dot && !(dir->__flags & dirent_isroot))
|
if (is_dot_dot && !(dir->__flags & dirent_isroot))
|
||||||
de->d_ino = readdir_get_ino (((fhandler_base *) dir->__fh)->get_name (),
|
de->d_ino = readdir_get_ino (((fhandler_base *)
|
||||||
|
dir->__fh)->get_name (),
|
||||||
true);
|
true);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -165,7 +167,12 @@ readdir_worker (DIR *dir, dirent *de)
|
|||||||
/* This fills out the old 32 bit d_ino field for old applications,
|
/* This fills out the old 32 bit d_ino field for old applications,
|
||||||
build under Cygwin before 1.5.x. */
|
build under Cygwin before 1.5.x. */
|
||||||
de->__d_internal1 = de->d_ino;
|
de->__d_internal1 = de->d_ino;
|
||||||
|
}
|
||||||
|
__except (NO_ERROR)
|
||||||
|
{
|
||||||
|
res = EFAULT;
|
||||||
|
}
|
||||||
|
__endtry
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,16 +207,15 @@ readdir_r (DIR *__restrict dir, dirent *__restrict de, dirent **__restrict ode)
|
|||||||
extern "C" long
|
extern "C" long
|
||||||
telldir (DIR *dir)
|
telldir (DIR *dir)
|
||||||
{
|
{
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EFAULT))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (dir->__d_cookie != __DIRENT_COOKIE)
|
|
||||||
{
|
{
|
||||||
set_errno (EBADF);
|
if (dir->__d_cookie == __DIRENT_COOKIE)
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return ((fhandler_base *) dir->__fh)->telldir (dir);
|
return ((fhandler_base *) dir->__fh)->telldir (dir);
|
||||||
|
set_errno (EBADF);
|
||||||
|
}
|
||||||
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* telldir was never defined using off_t in POSIX, only in early versions
|
/* telldir was never defined using off_t in POSIX, only in early versions
|
||||||
@ -225,14 +231,17 @@ telldir64 (DIR *dir)
|
|||||||
extern "C" void
|
extern "C" void
|
||||||
seekdir (DIR *dir, long loc)
|
seekdir (DIR *dir, long loc)
|
||||||
{
|
{
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EFAULT))
|
{
|
||||||
return;
|
if (dir->__d_cookie == __DIRENT_COOKIE)
|
||||||
|
{
|
||||||
if (dir->__d_cookie != __DIRENT_COOKIE)
|
|
||||||
return;
|
|
||||||
dir->__flags &= dirent_info_mask;
|
dir->__flags &= dirent_info_mask;
|
||||||
return ((fhandler_base *) dir->__fh)->seekdir (dir, loc);
|
((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
|
/* seekdir was never defined using off_t in POSIX, only in early versions
|
||||||
@ -248,31 +257,27 @@ seekdir64 (DIR *dir, off_t loc)
|
|||||||
extern "C" void
|
extern "C" void
|
||||||
rewinddir (DIR *dir)
|
rewinddir (DIR *dir)
|
||||||
{
|
{
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EFAULT))
|
{
|
||||||
return;
|
if (dir->__d_cookie == __DIRENT_COOKIE)
|
||||||
|
{
|
||||||
if (dir->__d_cookie != __DIRENT_COOKIE)
|
|
||||||
return;
|
|
||||||
dir->__flags &= dirent_info_mask;
|
dir->__flags &= dirent_info_mask;
|
||||||
return ((fhandler_base *) dir->__fh)->rewinddir (dir);
|
((fhandler_base *) dir->__fh)->rewinddir (dir);
|
||||||
|
}
|
||||||
|
set_errno (EINVAL); /* Diagnosis */
|
||||||
|
}
|
||||||
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
}
|
}
|
||||||
|
|
||||||
/* closedir: POSIX 5.1.2.1 */
|
/* closedir: POSIX 5.1.2.1 */
|
||||||
extern "C" int
|
extern "C" int
|
||||||
closedir (DIR *dir)
|
closedir (DIR *dir)
|
||||||
{
|
{
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EFAULT))
|
{
|
||||||
return -1;
|
if (dir->__d_cookie == __DIRENT_COOKIE)
|
||||||
|
|
||||||
if (dir->__d_cookie != __DIRENT_COOKIE)
|
|
||||||
{
|
{
|
||||||
set_errno (EBADF);
|
|
||||||
syscall_printf ("%R = closedir(%p)", -1, dir);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reset the marker in case the caller tries to use `dir' again. */
|
/* Reset the marker in case the caller tries to use `dir' again. */
|
||||||
dir->__d_cookie = 0;
|
dir->__d_cookie = 0;
|
||||||
|
|
||||||
@ -284,6 +289,13 @@ closedir (DIR *dir)
|
|||||||
free (dir);
|
free (dir);
|
||||||
syscall_printf ("%R = closedir(%p)", res, dir);
|
syscall_printf ("%R = closedir(%p)", res, dir);
|
||||||
return res;
|
return res;
|
||||||
|
}
|
||||||
|
set_errno (EBADF);
|
||||||
|
}
|
||||||
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
|
syscall_printf ("%R = closedir(%p)", -1, dir);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* mkdir: POSIX 5.4.1.1 */
|
/* mkdir: POSIX 5.4.1.1 */
|
||||||
@ -294,10 +306,8 @@ mkdir (const char *dir, mode_t mode)
|
|||||||
fhandler_base *fh = NULL;
|
fhandler_base *fh = NULL;
|
||||||
tmp_pathbuf tp;
|
tmp_pathbuf tp;
|
||||||
|
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EFAULT))
|
{
|
||||||
return -1;
|
|
||||||
|
|
||||||
/* POSIX says mkdir("symlink-to-missing/") should create the
|
/* POSIX says mkdir("symlink-to-missing/") should create the
|
||||||
directory "missing", but Linux rejects it with EEXIST. Copy
|
directory "missing", but Linux rejects it with EEXIST. Copy
|
||||||
Linux behavior for now. */
|
Linux behavior for now. */
|
||||||
@ -305,7 +315,7 @@ mkdir (const char *dir, mode_t mode)
|
|||||||
if (!*dir)
|
if (!*dir)
|
||||||
{
|
{
|
||||||
set_errno (ENOENT);
|
set_errno (ENOENT);
|
||||||
goto done;
|
__leave;
|
||||||
}
|
}
|
||||||
if (isdirsep (dir[strlen (dir) - 1]))
|
if (isdirsep (dir[strlen (dir) - 1]))
|
||||||
{
|
{
|
||||||
@ -317,7 +327,7 @@ mkdir (const char *dir, mode_t mode)
|
|||||||
*p-- = '\0';
|
*p-- = '\0';
|
||||||
}
|
}
|
||||||
if (!(fh = build_fh_name (dir, PC_SYM_NOFOLLOW)))
|
if (!(fh = build_fh_name (dir, PC_SYM_NOFOLLOW)))
|
||||||
goto done; /* errno already set */;
|
__leave; /* errno already set */;
|
||||||
|
|
||||||
if (fh->error ())
|
if (fh->error ())
|
||||||
{
|
{
|
||||||
@ -329,8 +339,9 @@ mkdir (const char *dir, mode_t mode)
|
|||||||
else if (!fh->mkdir (mode))
|
else if (!fh->mkdir (mode))
|
||||||
res = 0;
|
res = 0;
|
||||||
delete fh;
|
delete fh;
|
||||||
|
}
|
||||||
done:
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
syscall_printf ("%R = mkdir(%s, %d)", res, dir, mode);
|
syscall_printf ("%R = mkdir(%s, %d)", res, dir, mode);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -342,12 +353,10 @@ rmdir (const char *dir)
|
|||||||
int res = -1;
|
int res = -1;
|
||||||
fhandler_base *fh = NULL;
|
fhandler_base *fh = NULL;
|
||||||
|
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EFAULT))
|
{
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (!(fh = build_fh_name (dir, PC_SYM_NOFOLLOW)))
|
if (!(fh = build_fh_name (dir, PC_SYM_NOFOLLOW)))
|
||||||
goto done; /* errno already set */;
|
__leave; /* errno already set */;
|
||||||
|
|
||||||
if (fh->error ())
|
if (fh->error ())
|
||||||
{
|
{
|
||||||
@ -362,10 +371,10 @@ rmdir (const char *dir)
|
|||||||
set_errno (ENOTEMPTY);
|
set_errno (ENOTEMPTY);
|
||||||
else if (!fh->rmdir ())
|
else if (!fh->rmdir ())
|
||||||
res = 0;
|
res = 0;
|
||||||
|
|
||||||
delete fh;
|
delete fh;
|
||||||
|
}
|
||||||
done:
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
syscall_printf ("%R = rmdir(%s)", res, dir);
|
syscall_printf ("%R = rmdir(%s)", res, dir);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
process's environment.
|
process's environment.
|
||||||
|
|
||||||
Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
|
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
|
This software is a copyrighted work licensed under the terms of the
|
||||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
@ -664,9 +664,8 @@ _addenv (const char *name, const char *value, int overwrite)
|
|||||||
extern "C" int
|
extern "C" int
|
||||||
putenv (char *str)
|
putenv (char *str)
|
||||||
{
|
{
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EFAULT))
|
{
|
||||||
return -1;
|
|
||||||
if (*str)
|
if (*str)
|
||||||
{
|
{
|
||||||
char *eq = strchr (str, '=');
|
char *eq = strchr (str, '=');
|
||||||
@ -677,6 +676,10 @@ putenv (char *str)
|
|||||||
unsetenv (str);
|
unsetenv (str);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the value of the environment variable "name" to be
|
/* Set the value of the environment variable "name" to be
|
||||||
@ -684,15 +687,18 @@ putenv (char *str)
|
|||||||
extern "C" int
|
extern "C" int
|
||||||
setenv (const char *name, const char *value, int overwrite)
|
setenv (const char *name, const char *value, int overwrite)
|
||||||
{
|
{
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EFAULT))
|
{
|
||||||
return -1;
|
|
||||||
if (!name || !*name || strchr (name, '='))
|
if (!name || !*name || strchr (name, '='))
|
||||||
{
|
{
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return -1;
|
__leave;
|
||||||
}
|
}
|
||||||
return _addenv (name, value, !!overwrite);
|
return _addenv (name, value, !!overwrite);
|
||||||
|
}
|
||||||
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delete environment variable "name". */
|
/* Delete environment variable "name". */
|
||||||
@ -701,13 +707,13 @@ unsetenv (const char *name)
|
|||||||
{
|
{
|
||||||
register char **e;
|
register char **e;
|
||||||
int offset;
|
int offset;
|
||||||
myfault efault;
|
|
||||||
if (efault.faulted (EFAULT))
|
__try
|
||||||
return -1;
|
{
|
||||||
if (!name || *name == '\0' || strchr (name, '='))
|
if (!name || *name == '\0' || strchr (name, '='))
|
||||||
{
|
{
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return -1;
|
__leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (my_findenv (name, &offset)) /* if set multiple times */
|
while (my_findenv (name, &offset)) /* if set multiple times */
|
||||||
@ -717,6 +723,10 @@ unsetenv (const char *name)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Minimal list of Windows vars which must be converted to uppercase.
|
/* Minimal list of Windows vars which must be converted to uppercase.
|
||||||
@ -822,12 +832,10 @@ environ_init (char **envp, int envc)
|
|||||||
bool envp_passed_in;
|
bool envp_passed_in;
|
||||||
bool got_something_from_registry;
|
bool got_something_from_registry;
|
||||||
static char NO_COPY cygterm[] = "TERM=cygwin";
|
static char NO_COPY cygterm[] = "TERM=cygwin";
|
||||||
myfault efault;
|
|
||||||
tmp_pathbuf tp;
|
tmp_pathbuf tp;
|
||||||
|
|
||||||
if (efault.faulted ())
|
__try
|
||||||
api_fatal ("internal error reading the windows environment - too many environment variables?");
|
{
|
||||||
|
|
||||||
char *tmpbuf = tp.t_get ();
|
char *tmpbuf = tp.t_get ();
|
||||||
got_something_from_registry = regopt (L"default", tmpbuf);
|
got_something_from_registry = regopt (L"default", tmpbuf);
|
||||||
if (myself->progname[0])
|
if (myself->progname[0])
|
||||||
@ -897,7 +905,7 @@ environ_init (char **envp, int envc)
|
|||||||
envp[i] = NULL;
|
envp[i] = NULL;
|
||||||
FreeEnvironmentStringsW (rawenv);
|
FreeEnvironmentStringsW (rawenv);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
findenv_func = (char * (*)(const char*, int*)) my_findenv;
|
findenv_func = (char * (*)(const char*, int*)) my_findenv;
|
||||||
__cygwin_environ = envp;
|
__cygwin_environ = envp;
|
||||||
update_envptrs ();
|
update_envptrs ();
|
||||||
@ -912,6 +920,13 @@ out:
|
|||||||
parse_options (NULL); /* possibly export registry settings to
|
parse_options (NULL); /* possibly export registry settings to
|
||||||
environment */
|
environment */
|
||||||
MALLOC_CHECK;
|
MALLOC_CHECK;
|
||||||
|
}
|
||||||
|
__except (NO_ERROR)
|
||||||
|
{
|
||||||
|
api_fatal ("internal error reading the windows environment "
|
||||||
|
"- too many environment variables?");
|
||||||
|
}
|
||||||
|
__endtry
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function called by qsort to sort environment strings. */
|
/* 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
|
a teensy bit of detail of the innards of exception handling (i.e. what we
|
||||||
have to do). */
|
have to do). */
|
||||||
|
|
||||||
typedef int (exception_handler) (EXCEPTION_RECORD *, struct _exception_list *,
|
typedef EXCEPTION_DISPOSITION (exception_handler) (EXCEPTION_RECORD *,
|
||||||
CONTEXT *, void *);
|
struct _exception_list *,
|
||||||
|
CONTEXT *,
|
||||||
|
void *);
|
||||||
|
|
||||||
typedef struct _exception_list
|
typedef struct _exception_list
|
||||||
{
|
{
|
||||||
@ -104,70 +106,53 @@ typedef struct _exception_list
|
|||||||
} exception_list;
|
} exception_list;
|
||||||
|
|
||||||
extern exception_list *_except_list asm ("%fs:0");
|
extern exception_list *_except_list asm ("%fs:0");
|
||||||
#else
|
typedef void *PDISPATCHER_CONTEXT;
|
||||||
typedef void exception_list;
|
|
||||||
#endif /* !__x86_64 */
|
|
||||||
|
|
||||||
class exception
|
class exception
|
||||||
{
|
{
|
||||||
#ifdef __x86_64__
|
|
||||||
static LONG myfault_handle (LPEXCEPTION_POINTERS ep);
|
|
||||||
#else
|
|
||||||
exception_list el;
|
exception_list el;
|
||||||
exception_list *save;
|
exception_list *save;
|
||||||
#endif /* __x86_64__ */
|
static EXCEPTION_DISPOSITION handle (EXCEPTION_RECORD *, exception_list *,
|
||||||
static int handle (EXCEPTION_RECORD *, exception_list *, CONTEXT *, void *);
|
CONTEXT *, PDISPATCHER_CONTEXT);
|
||||||
public:
|
public:
|
||||||
exception () __attribute__ ((always_inline))
|
exception () __attribute__ ((always_inline))
|
||||||
{
|
{
|
||||||
/* Install SEH handler. */
|
/* 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__
|
#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\
|
asm volatile ("\n\
|
||||||
1: \n\
|
1: \n\
|
||||||
.seh_handler \
|
.seh_handler \
|
||||||
_ZN9exception6handleEP17_EXCEPTION_RECORDPvP8_CONTEXTS2_, \
|
_ZN9exception6handleEP17_EXCEPTION_RECORDPvP8_CONTEXTP19_DISPATCHER_CONTEXT, \
|
||||||
@except \n\
|
@except \n\
|
||||||
.seh_handlerdata \n\
|
.seh_handlerdata \n\
|
||||||
.long 1 \n\
|
.long 1 \n\
|
||||||
.rva 1b, 2f, 2f, 2f \n\
|
.rva 1b, 2f, 2f, 2f \n\
|
||||||
.seh_code \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))
|
~exception () __attribute__ ((always_inline))
|
||||||
{
|
{
|
||||||
asm volatile ("\n\
|
asm volatile ("\n\
|
||||||
@ -175,11 +160,10 @@ public:
|
|||||||
2: \n\
|
2: \n\
|
||||||
nop \n");
|
nop \n");
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
~exception () __attribute__ ((always_inline)) { _except_list = save; }
|
|
||||||
#endif /* !__x86_64__ */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif /* !__x86_64 */
|
||||||
|
|
||||||
class cygwin_exception
|
class cygwin_exception
|
||||||
{
|
{
|
||||||
PUINT_PTR framep;
|
PUINT_PTR framep;
|
||||||
|
@ -341,10 +341,9 @@ void
|
|||||||
cygwin_exception::dumpstack ()
|
cygwin_exception::dumpstack ()
|
||||||
{
|
{
|
||||||
static bool already_dumped;
|
static bool already_dumped;
|
||||||
myfault efault;
|
|
||||||
if (efault.faulted ())
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
__try
|
||||||
|
{
|
||||||
if (already_dumped || cygheap->rlim_core == 0Ul)
|
if (already_dumped || cygheap->rlim_core == 0Ul)
|
||||||
return;
|
return;
|
||||||
already_dumped = true;
|
already_dumped = true;
|
||||||
@ -366,13 +365,17 @@ cygwin_exception::dumpstack ()
|
|||||||
small_printf (_AFMT " " _AFMT, thestack.sf.AddrFrame.Offset,
|
small_printf (_AFMT " " _AFMT, thestack.sf.AddrFrame.Offset,
|
||||||
thestack.sf.AddrPC.Offset);
|
thestack.sf.AddrPC.Offset);
|
||||||
for (unsigned j = 0; j < NPARAMS; j++)
|
for (unsigned j = 0; j < NPARAMS; j++)
|
||||||
small_printf ("%s" _AFMT, j == 0 ? " (" : ", ", thestack.sf.Params[j]);
|
small_printf ("%s" _AFMT, j == 0 ? " (" : ", ",
|
||||||
|
thestack.sf.Params[j]);
|
||||||
small_printf (")\r\n");
|
small_printf (")\r\n");
|
||||||
}
|
}
|
||||||
small_printf ("End of stack trace%s\n",
|
small_printf ("End of stack trace%s\n",
|
||||||
i == 16 ? " (more stack frames may be present)" : "");
|
i == 16 ? " (more stack frames may be present)" : "");
|
||||||
if (h)
|
if (h)
|
||||||
NtClose (h);
|
NtClose (h);
|
||||||
|
}
|
||||||
|
__except (NO_ERROR) {}
|
||||||
|
__endtry
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -549,40 +552,24 @@ rtl_unwind (exception_list *frame, PEXCEPTION_RECORD e)
|
|||||||
#endif /* __x86_64 */
|
#endif /* __x86_64 */
|
||||||
|
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
/* myfault vectored exception handler */
|
/* myfault exception handler. */
|
||||||
LONG
|
EXCEPTION_DISPOSITION
|
||||||
exception::myfault_handle (LPEXCEPTION_POINTERS ep)
|
exception::myfault (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in,
|
||||||
|
PDISPATCHER_CONTEXT dispatch)
|
||||||
{
|
{
|
||||||
_cygtls& me = _my_tls;
|
PSCOPE_TABLE table = (PSCOPE_TABLE) dispatch->HandlerData;
|
||||||
|
RtlUnwindEx (frame,
|
||||||
if (me.andreas)
|
(char *) dispatch->ImageBase + table->ScopeRecord[0].JumpTarget,
|
||||||
{
|
e, 0, in, dispatch->HistoryTable);
|
||||||
/* Only handle the minimum amount of exceptions the myfault handler
|
/* NOTREACHED, make gcc happy. */
|
||||||
was designed for. */
|
return ExceptionContinueSearch;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
#endif /* __x86_64 */
|
#endif
|
||||||
|
|
||||||
/* Main exception handler. */
|
/* Main exception handler. */
|
||||||
int
|
EXCEPTION_DISPOSITION
|
||||||
exception::handle (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in, void *)
|
exception::handle (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in,
|
||||||
|
PDISPATCHER_CONTEXT dispatch)
|
||||||
{
|
{
|
||||||
static bool NO_COPY debugging;
|
static bool NO_COPY debugging;
|
||||||
_cygtls& me = _my_tls;
|
_cygtls& me = _my_tls;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* fcntl.cc: fcntl syscall
|
/* fcntl.cc: fcntl syscall
|
||||||
|
|
||||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2008, 2009,
|
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.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -28,14 +28,13 @@ fcntl64 (int fd, int cmd, ...)
|
|||||||
|
|
||||||
pthread_testcancel ();
|
pthread_testcancel ();
|
||||||
|
|
||||||
debug_printf ("fcntl(%d, %d, ...)", fd, cmd);
|
__try
|
||||||
myfault efault;
|
{
|
||||||
if (efault.faulted (EFAULT))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
|
debug_printf ("fcntl(%d, %d, ...)", fd, cmd);
|
||||||
cygheap_fdget cfd (fd, true);
|
cygheap_fdget cfd (fd, true);
|
||||||
if (cfd < 0)
|
if (cfd < 0)
|
||||||
goto done;
|
__leave;
|
||||||
|
|
||||||
/* FIXME? All numerical args to fcntl are defined as long on Linux.
|
/* 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
|
This relies on a really dirty trick on x86_64: A 32 bit mov to
|
||||||
@ -48,8 +47,8 @@ fcntl64 (int fd, int cmd, ...)
|
|||||||
|
|
||||||
However, the POSIX standard defines all numerical args as type int.
|
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
|
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
|
sizeof (void*) != sizeof (int). If we would like to follow POSIX more
|
||||||
more closely than Linux, we'd have to call va_arg on a per cmd basis. */
|
closely than Linux, we'd have to call va_arg on a per cmd basis. */
|
||||||
|
|
||||||
va_start (args, cmd);
|
va_start (args, cmd);
|
||||||
arg = va_arg (args, intptr_t);
|
arg = va_arg (args, intptr_t);
|
||||||
@ -74,7 +73,9 @@ fcntl64 (int fd, int cmd, ...)
|
|||||||
res = cfd->fcntl (cmd, arg);
|
res = cfd->fcntl (cmd, arg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
done:
|
}
|
||||||
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
syscall_printf ("%R = fcntl(%d, %d, %ly)", res, fd, cmd, arg);
|
syscall_printf ("%R = fcntl(%d, %d, %ly)", res, fd, cmd, arg);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -91,10 +92,8 @@ _fcntl (int fd, int cmd, ...)
|
|||||||
struct __flock32 *src = NULL;
|
struct __flock32 *src = NULL;
|
||||||
struct flock dst;
|
struct flock dst;
|
||||||
|
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EFAULT))
|
{
|
||||||
return -1;
|
|
||||||
|
|
||||||
va_start (args, cmd);
|
va_start (args, cmd);
|
||||||
arg = va_arg (args, intptr_t);
|
arg = va_arg (args, intptr_t);
|
||||||
va_end (args);
|
va_end (args);
|
||||||
@ -118,5 +117,9 @@ _fcntl (int fd, int cmd, ...)
|
|||||||
src->l_pid = (short) dst.l_pid;
|
src->l_pid = (short) dst.l_pid;
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
|
}
|
||||||
|
__except (EFAULT)
|
||||||
|
__endtry
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -2293,9 +2293,8 @@ fhandler_socket::getpeereid (pid_t *pid, uid_t *euid, gid_t *egid)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EFAULT))
|
{
|
||||||
return -1;
|
|
||||||
if (pid)
|
if (pid)
|
||||||
*pid = sec_peer_pid;
|
*pid = sec_peer_pid;
|
||||||
if (euid)
|
if (euid)
|
||||||
@ -2303,4 +2302,8 @@ fhandler_socket::getpeereid (pid_t *pid, uid_t *euid, gid_t *egid)
|
|||||||
if (egid)
|
if (egid)
|
||||||
*egid = sec_peer_gid;
|
*egid = sec_peer_gid;
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
classes.
|
classes.
|
||||||
|
|
||||||
Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
|
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.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -977,9 +977,8 @@ mtinfo_drive::set_options (HANDLE mt, int32_t options)
|
|||||||
int
|
int
|
||||||
mtinfo_drive::ioctl (HANDLE mt, unsigned int cmd, void *buf)
|
mtinfo_drive::ioctl (HANDLE mt, unsigned int cmd, void *buf)
|
||||||
{
|
{
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted ())
|
{
|
||||||
return ERROR_NOACCESS;
|
|
||||||
if (cmd == MTIOCTOP)
|
if (cmd == MTIOCTOP)
|
||||||
{
|
{
|
||||||
struct mtop *op = (struct mtop *) buf;
|
struct mtop *op = (struct mtop *) buf;
|
||||||
@ -1129,7 +1128,12 @@ mtinfo_drive::ioctl (HANDLE mt, unsigned int cmd, void *buf)
|
|||||||
get_status (mt, (struct mtget *) buf);
|
get_status (mt, (struct mtget *) buf);
|
||||||
else if (cmd == MTIOCPOS && !get_pos (mt))
|
else if (cmd == MTIOCPOS && !get_pos (mt))
|
||||||
((struct mtpos *) buf)->mt_blkno = (long) block;
|
((struct mtpos *) buf)->mt_blkno = (long) block;
|
||||||
|
}
|
||||||
|
__except (NO_ERROR)
|
||||||
|
{
|
||||||
|
lasterr = ERROR_NOACCESS;
|
||||||
|
}
|
||||||
|
__endtry
|
||||||
return lasterr;
|
return lasterr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1761,13 +1761,11 @@ flock (int fd, int operation)
|
|||||||
int cmd;
|
int cmd;
|
||||||
struct flock fl = { 0, SEEK_SET, 0, 0, 0 };
|
struct flock fl = { 0, SEEK_SET, 0, 0, 0 };
|
||||||
|
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EFAULT))
|
{
|
||||||
return -1;
|
|
||||||
|
|
||||||
cygheap_fdget cfd (fd, true);
|
cygheap_fdget cfd (fd, true);
|
||||||
if (cfd < 0)
|
if (cfd < 0)
|
||||||
goto done;
|
__leave;
|
||||||
|
|
||||||
cmd = (operation & LOCK_NB) ? F_SETLK : F_SETLKW;
|
cmd = (operation & LOCK_NB) ? F_SETLK : F_SETLKW;
|
||||||
switch (operation & (~LOCK_NB))
|
switch (operation & (~LOCK_NB))
|
||||||
@ -1783,7 +1781,7 @@ flock (int fd, int operation)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
goto done;
|
__leave;
|
||||||
}
|
}
|
||||||
if (!cfd->mandatory_locking ())
|
if (!cfd->mandatory_locking ())
|
||||||
fl.l_type |= F_FLOCK;
|
fl.l_type |= F_FLOCK;
|
||||||
@ -1791,7 +1789,9 @@ flock (int fd, int operation)
|
|||||||
: cfd->lock (cmd, &fl);
|
: cfd->lock (cmd, &fl);
|
||||||
if ((res == -1) && ((get_errno () == EAGAIN) || (get_errno () == EACCES)))
|
if ((res == -1) && ((get_errno () == EAGAIN) || (get_errno () == EACCES)))
|
||||||
set_errno (EWOULDBLOCK);
|
set_errno (EWOULDBLOCK);
|
||||||
done:
|
}
|
||||||
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
syscall_printf ("%R = flock(%d, %d)", res, fd, operation);
|
syscall_printf ("%R = flock(%d, %d)", res, fd, operation);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -1805,13 +1805,11 @@ lockf (int filedes, int function, off_t size)
|
|||||||
|
|
||||||
pthread_testcancel ();
|
pthread_testcancel ();
|
||||||
|
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EFAULT))
|
{
|
||||||
return -1;
|
|
||||||
|
|
||||||
cygheap_fdget cfd (filedes, true);
|
cygheap_fdget cfd (filedes, true);
|
||||||
if (cfd < 0)
|
if (cfd < 0)
|
||||||
goto done;
|
__leave;
|
||||||
|
|
||||||
fl.l_start = 0;
|
fl.l_start = 0;
|
||||||
fl.l_len = size;
|
fl.l_len = size;
|
||||||
@ -1834,21 +1832,23 @@ lockf (int filedes, int function, off_t size)
|
|||||||
case F_TEST:
|
case F_TEST:
|
||||||
fl.l_type = F_WRLCK;
|
fl.l_type = F_WRLCK;
|
||||||
if (cfd->lock (F_GETLK, &fl) == -1)
|
if (cfd->lock (F_GETLK, &fl) == -1)
|
||||||
goto done;
|
__leave;
|
||||||
if (fl.l_type == F_UNLCK || fl.l_pid == getpid ())
|
if (fl.l_type == F_UNLCK || fl.l_pid == getpid ())
|
||||||
res = 0;
|
res = 0;
|
||||||
else
|
else
|
||||||
errno = EAGAIN;
|
errno = EAGAIN;
|
||||||
goto done;
|
__leave;
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
default:
|
default:
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
goto done;
|
__leave;
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
res = cfd->mandatory_locking () ? cfd->mand_lock (cmd, &fl)
|
res = cfd->mandatory_locking () ? cfd->mand_lock (cmd, &fl)
|
||||||
: cfd->lock (cmd, &fl);
|
: cfd->lock (cmd, &fl);
|
||||||
done:
|
}
|
||||||
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
syscall_printf ("%R = lockf(%d, %d, %D)", res, filedes, function, size);
|
syscall_printf ("%R = lockf(%d, %d, %D)", res, filedes, function, size);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/perl
|
#!/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.
|
# Red Hat, Inc.
|
||||||
#
|
#
|
||||||
# This file is part of Cygwin.
|
# 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
|
movq -8(%r11),%r11 # get return address from signal stack
|
||||||
decl $tls::incyg(%r10)
|
decl $tls::incyg(%r10)
|
||||||
decl $tls::stacklock(%r10) # release lock
|
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
|
jmp *%r11 # "return" to caller
|
||||||
.seh_endproc
|
.seh_endproc
|
||||||
|
|
||||||
@ -445,6 +447,9 @@ __sigbe: # return here after cygwin syscall
|
|||||||
xchgl %eax,4(%esp) # swap return address with saved eax
|
xchgl %eax,4(%esp) # swap return address with saved eax
|
||||||
decl $tls::incyg(%ebx)
|
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
|
popl %ebx
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
@ -249,8 +249,7 @@ getprogname (void)
|
|||||||
extern "C" void
|
extern "C" void
|
||||||
setprogname (const char *newprogname)
|
setprogname (const char *newprogname)
|
||||||
{
|
{
|
||||||
myfault efault;
|
__try
|
||||||
if (!efault.faulted (EFAULT))
|
|
||||||
{
|
{
|
||||||
/* Per BSD man page, setprogname keeps a pointer to the last
|
/* Per BSD man page, setprogname keeps a pointer to the last
|
||||||
path component of the argument. It does *not* copy the
|
path component of the argument. It does *not* copy the
|
||||||
@ -261,6 +260,8 @@ setprogname (const char *newprogname)
|
|||||||
else
|
else
|
||||||
__progname = (char *)newprogname;
|
__progname = (char *)newprogname;
|
||||||
}
|
}
|
||||||
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void
|
extern "C" void
|
||||||
|
@ -319,10 +319,8 @@ cygwin_rexec (char **ahost, unsigned short rport, char *name, char *pass,
|
|||||||
char c;
|
char c;
|
||||||
static char ahostbuf[INTERNET_MAX_HOST_NAME_LENGTH + 1];
|
static char ahostbuf[INTERNET_MAX_HOST_NAME_LENGTH + 1];
|
||||||
|
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EFAULT))
|
{
|
||||||
return -1;
|
|
||||||
|
|
||||||
hp = cygwin_gethostbyname(*ahost);
|
hp = cygwin_gethostbyname(*ahost);
|
||||||
if (hp == 0) {
|
if (hp == 0) {
|
||||||
cygwin_herror(*ahost);
|
cygwin_herror(*ahost);
|
||||||
@ -407,5 +405,8 @@ bad:
|
|||||||
if (port)
|
if (port)
|
||||||
(void) close(*fd2p);
|
(void) close(*fd2p);
|
||||||
(void) close(s);
|
(void) close(s);
|
||||||
|
}
|
||||||
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
@ -202,9 +202,8 @@ check_iovec (const struct iovec *iov, int iovcnt, bool forwrite)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EFAULT))
|
{
|
||||||
return -1;
|
|
||||||
|
|
||||||
size_t tot = 0;
|
size_t tot = 0;
|
||||||
|
|
||||||
@ -213,7 +212,7 @@ check_iovec (const struct iovec *iov, int iovcnt, bool forwrite)
|
|||||||
if (iov->iov_len > SSIZE_MAX || (tot += iov->iov_len) > SSIZE_MAX)
|
if (iov->iov_len > SSIZE_MAX || (tot += iov->iov_len) > SSIZE_MAX)
|
||||||
{
|
{
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return -1;
|
__leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
volatile char *p = ((char *) iov->iov_base) + iov->iov_len - 1;
|
volatile char *p = ((char *) iov->iov_base) + iov->iov_len - 1;
|
||||||
@ -231,6 +230,10 @@ check_iovec (const struct iovec *iov, int iovcnt, bool forwrite)
|
|||||||
assert (tot <= SSIZE_MAX);
|
assert (tot <= SSIZE_MAX);
|
||||||
|
|
||||||
return (ssize_t) tot;
|
return (ssize_t) tot;
|
||||||
|
}
|
||||||
|
__except (EFAULT)
|
||||||
|
__endtry
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try hard to schedule another thread.
|
/* Try hard to schedule another thread.
|
||||||
@ -512,18 +515,23 @@ slashify (const char *src, char *dst, bool trailing_slash_p)
|
|||||||
void * __reg1
|
void * __reg1
|
||||||
__import_address (void *imp)
|
__import_address (void *imp)
|
||||||
{
|
{
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted ())
|
{
|
||||||
return NULL;
|
if (*((uint16_t *) imp) == 0x25ff)
|
||||||
if (*((uint16_t *) imp) != 0x25ff)
|
{
|
||||||
return NULL;
|
|
||||||
const char *ptr = (const char *) imp;
|
const char *ptr = (const char *) imp;
|
||||||
#ifdef __x86_64__
|
#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
|
#else
|
||||||
const uintptr_t *jmpto = (uintptr_t *) *((uintptr_t *) (ptr + 2));
|
const uintptr_t *jmpto = (uintptr_t *) *((uintptr_t *) (ptr + 2));
|
||||||
#endif
|
#endif
|
||||||
return (void *) *jmpto;
|
return (void *) *jmpto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
__except (NO_ERROR) {}
|
||||||
|
__endtry
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* CygwinCreateThread.
|
/* CygwinCreateThread.
|
||||||
|
@ -1700,10 +1700,9 @@ mount (const char *win32_path, const char *posix_path, unsigned flags)
|
|||||||
isn't really supported except from fstab? */
|
isn't really supported except from fstab? */
|
||||||
int res = -1;
|
int res = -1;
|
||||||
|
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EFAULT))
|
{
|
||||||
/* errno set */;
|
if (!*posix_path)
|
||||||
else if (!*posix_path)
|
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
else if (strpbrk (posix_path, "\\:"))
|
else if (strpbrk (posix_path, "\\:"))
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
@ -1738,12 +1737,17 @@ mount (const char *win32_path, const char *posix_path, unsigned flags)
|
|||||||
flags = (MOUNT_BIND | conv_flags)
|
flags = (MOUNT_BIND | conv_flags)
|
||||||
& ~(MOUNT_IMMUTABLE | MOUNT_AUTOMATIC);
|
& ~(MOUNT_IMMUTABLE | MOUNT_AUTOMATIC);
|
||||||
}
|
}
|
||||||
/* Make sure all mounts are user mounts, even those added via mount -a. */
|
/* Make sure all mounts are user mounts, even those added via
|
||||||
|
mount -a. */
|
||||||
flags &= ~MOUNT_SYSTEM;
|
flags &= ~MOUNT_SYSTEM;
|
||||||
res = mount_table->add_item (w32_path, posix_path, flags);
|
res = mount_table->add_item (w32_path, posix_path, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
syscall_printf ("%R = mount(%s, %s, %y)", res, win32_path, posix_path, flags);
|
syscall_printf ("%R = mount(%s, %s, %y)",
|
||||||
|
res, win32_path, posix_path, flags);
|
||||||
|
}
|
||||||
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1755,15 +1759,18 @@ mount (const char *win32_path, const char *posix_path, unsigned flags)
|
|||||||
extern "C" int
|
extern "C" int
|
||||||
umount (const char *path)
|
umount (const char *path)
|
||||||
{
|
{
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EFAULT))
|
{
|
||||||
return -1;
|
|
||||||
if (!*path)
|
if (!*path)
|
||||||
{
|
{
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return -1;
|
__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
|
/* cygwin_umount: This is like umount but takes an additional flags
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* msg.cc: XSI IPC interface for Cygwin.
|
/* 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.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -91,11 +91,9 @@ client_request_msg::client_request_msg (int msqid,
|
|||||||
extern "C" int
|
extern "C" int
|
||||||
msgctl (int msqid, int cmd, struct msqid_ds *buf)
|
msgctl (int msqid, int cmd, struct msqid_ds *buf)
|
||||||
{
|
{
|
||||||
syscall_printf ("msgctl (msqid = %d, cmd = %y, buf = %p)",
|
syscall_printf ("msgctl (msqid = %d, cmd = %y, buf = %p)", msqid, cmd, buf);
|
||||||
msqid, cmd, buf);
|
__try
|
||||||
myfault efault;
|
{
|
||||||
if (efault.faulted (EFAULT))
|
|
||||||
return -1;
|
|
||||||
switch (cmd)
|
switch (cmd)
|
||||||
{
|
{
|
||||||
case IPC_STAT:
|
case IPC_STAT:
|
||||||
@ -111,7 +109,7 @@ msgctl (int msqid, int cmd, struct msqid_ds *buf)
|
|||||||
default:
|
default:
|
||||||
syscall_printf ("-1 [%d] = msgctl ()", EINVAL);
|
syscall_printf ("-1 [%d] = msgctl ()", EINVAL);
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return -1;
|
__leave;
|
||||||
}
|
}
|
||||||
client_request_msg request (msqid, cmd, buf);
|
client_request_msg request (msqid, cmd, buf);
|
||||||
if (request.make_request () == -1 || request.retval () == -1)
|
if (request.make_request () == -1 || request.retval () == -1)
|
||||||
@ -120,9 +118,13 @@ msgctl (int msqid, int cmd, struct msqid_ds *buf)
|
|||||||
set_errno (request.error_code ());
|
set_errno (request.error_code ());
|
||||||
if (request.error_code () == ENOSYS)
|
if (request.error_code () == ENOSYS)
|
||||||
raise (SIGSYS);
|
raise (SIGSYS);
|
||||||
return -1;
|
__leave;
|
||||||
}
|
}
|
||||||
return request.retval ();
|
return request.retval ();
|
||||||
|
}
|
||||||
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int
|
extern "C" int
|
||||||
@ -147,9 +149,8 @@ msgrcv (int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg)
|
|||||||
syscall_printf ("msgrcv (msqid = %d, msgp = %p, msgsz = %ld, "
|
syscall_printf ("msgrcv (msqid = %d, msgp = %p, msgsz = %ld, "
|
||||||
"msgtyp = %d, msgflg = %y)",
|
"msgtyp = %d, msgflg = %y)",
|
||||||
msqid, msgp, msgsz, msgtyp, msgflg);
|
msqid, msgp, msgsz, msgtyp, msgflg);
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EFAULT))
|
{
|
||||||
return -1;
|
|
||||||
client_request_msg request (msqid, msgp, msgsz, msgtyp, msgflg);
|
client_request_msg request (msqid, msgp, msgsz, msgtyp, msgflg);
|
||||||
if (request.make_request () == -1 || request.rcvval () == -1)
|
if (request.make_request () == -1 || request.rcvval () == -1)
|
||||||
{
|
{
|
||||||
@ -157,9 +158,13 @@ msgrcv (int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg)
|
|||||||
set_errno (request.error_code ());
|
set_errno (request.error_code ());
|
||||||
if (request.error_code () == ENOSYS)
|
if (request.error_code () == ENOSYS)
|
||||||
raise (SIGSYS);
|
raise (SIGSYS);
|
||||||
return -1;
|
__leave;
|
||||||
}
|
}
|
||||||
return request.rcvval ();
|
return request.rcvval ();
|
||||||
|
}
|
||||||
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int
|
extern "C" int
|
||||||
@ -167,9 +172,8 @@ msgsnd (int msqid, const void *msgp, size_t msgsz, int msgflg)
|
|||||||
{
|
{
|
||||||
syscall_printf ("msgsnd (msqid = %d, msgp = %p, msgsz = %ld, msgflg = %y)",
|
syscall_printf ("msgsnd (msqid = %d, msgp = %p, msgsz = %ld, msgflg = %y)",
|
||||||
msqid, msgp, msgsz, msgflg);
|
msqid, msgp, msgsz, msgflg);
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EFAULT))
|
{
|
||||||
return -1;
|
|
||||||
client_request_msg request (msqid, msgp, msgsz, msgflg);
|
client_request_msg request (msqid, msgp, msgsz, msgflg);
|
||||||
if (request.make_request () == -1 || request.retval () == -1)
|
if (request.make_request () == -1 || request.retval () == -1)
|
||||||
{
|
{
|
||||||
@ -177,7 +181,11 @@ msgsnd (int msqid, const void *msgp, size_t msgsz, int msgflg)
|
|||||||
set_errno (request.error_code ());
|
set_errno (request.error_code ());
|
||||||
if (request.error_code () == ENOSYS)
|
if (request.error_code () == ENOSYS)
|
||||||
raise (SIGSYS);
|
raise (SIGSYS);
|
||||||
return -1;
|
__leave;
|
||||||
}
|
}
|
||||||
return request.retval ();
|
return request.retval ();
|
||||||
|
}
|
||||||
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
|||||||
/* ntdll.h. Contains ntdll specific stuff not defined elsewhere.
|
/* ntdll.h. Contains ntdll specific stuff not defined elsewhere.
|
||||||
|
|
||||||
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
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.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -1180,8 +1180,19 @@ typedef enum _SECTION_INHERIT
|
|||||||
|
|
||||||
typedef VOID (APIENTRY *PTIMER_APC_ROUTINE)(PVOID, ULONG, ULONG);
|
typedef VOID (APIENTRY *PTIMER_APC_ROUTINE)(PVOID, ULONG, ULONG);
|
||||||
|
|
||||||
/* Function declarations for ntdll.dll. These don't appear in any
|
#ifdef __x86_64__
|
||||||
standard Win32 header. */
|
typedef struct _SCOPE_TABLE
|
||||||
|
{
|
||||||
|
ULONG Count;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
ULONG BeginAddress;
|
||||||
|
ULONG EndAddress;
|
||||||
|
ULONG HandlerAddress;
|
||||||
|
ULONG JumpTarget;
|
||||||
|
} ScopeRecord[1];
|
||||||
|
} SCOPE_TABLE, *PSCOPE_TABLE;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
/* This is the mapping of the KUSER_SHARED_DATA structure into the user
|
/* 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
|
static volatile KUSER_SHARED_DATA &SharedUserData
|
||||||
= *(volatile KUSER_SHARED_DATA *) 0x7ffe0000;
|
= *(volatile KUSER_SHARED_DATA *) 0x7ffe0000;
|
||||||
|
|
||||||
|
/* Function declarations for ntdll.dll. These don't appear in any
|
||||||
|
standard Win32 header. */
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
@ -60,10 +60,8 @@ read_ea (HANDLE hdl, path_conv &pc, const char *name, char *value, size_t size)
|
|||||||
EA in the file is returned twice. */
|
EA in the file is returned twice. */
|
||||||
char lastname[MAX_EA_NAME_LEN];
|
char lastname[MAX_EA_NAME_LEN];
|
||||||
|
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EFAULT))
|
{
|
||||||
goto out;
|
|
||||||
|
|
||||||
pc.get_object_attr (attr, sec_none_nih);
|
pc.get_object_attr (attr, sec_none_nih);
|
||||||
|
|
||||||
debug_printf ("read_ea (%S, %s, %p, %lu)",
|
debug_printf ("read_ea (%S, %s, %p, %lu)",
|
||||||
@ -75,11 +73,12 @@ read_ea (HANDLE hdl, path_conv &pc, const char *name, char *value, size_t size)
|
|||||||
if (!hdl)
|
if (!hdl)
|
||||||
{
|
{
|
||||||
status = NtOpenFile (&h, READ_CONTROL | FILE_READ_EA, &attr, &io,
|
status = NtOpenFile (&h, READ_CONTROL | FILE_READ_EA, &attr, &io,
|
||||||
FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT);
|
FILE_SHARE_VALID_FLAGS,
|
||||||
|
FILE_OPEN_FOR_BACKUP_INTENT);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
__seterrno_from_nt_status (status);
|
__seterrno_from_nt_status (status);
|
||||||
goto out;
|
__leave;
|
||||||
}
|
}
|
||||||
hdl = NULL;
|
hdl = NULL;
|
||||||
}
|
}
|
||||||
@ -97,7 +96,7 @@ read_ea (HANDLE hdl, path_conv &pc, const char *name, char *value, size_t size)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
set_errno (ENOTSUP);
|
set_errno (ENOTSUP);
|
||||||
goto out;
|
__leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((nlen = strlen (name)) >= MAX_EA_NAME_LEN)
|
if ((nlen = strlen (name)) >= MAX_EA_NAME_LEN)
|
||||||
@ -123,7 +122,8 @@ read_ea (HANDLE hdl, path_conv &pc, const char *name, char *value, size_t size)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
status = NtOpenFile (&h, READ_CONTROL | FILE_READ_EA, &attr, &io,
|
status = NtOpenFile (&h, READ_CONTROL | FILE_READ_EA, &attr, &io,
|
||||||
FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT);
|
FILE_SHARE_VALID_FLAGS,
|
||||||
|
FILE_OPEN_FOR_BACKUP_INTENT);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
break;
|
break;
|
||||||
hdl = NULL;
|
hdl = NULL;
|
||||||
@ -140,23 +140,25 @@ read_ea (HANDLE hdl, path_conv &pc, const char *name, char *value, size_t size)
|
|||||||
break;
|
break;
|
||||||
case STATUS_NOT_FOUND:
|
case STATUS_NOT_FOUND:
|
||||||
/* STATUS_NOT_FOUND is returned when calling NtQueryEaFile on NFS.
|
/* STATUS_NOT_FOUND is returned when calling NtQueryEaFile on NFS.
|
||||||
In theory this should mean that the file just has no EAs, but in
|
In theory this should mean that the file just has no EAs, but
|
||||||
fact NFS doesn't support EAs, other than the EAs which are used
|
in fact NFS doesn't support EAs, other than the EAs which are
|
||||||
for NFS requests. We're playing safe and convert STATUS_NOT_FOUND
|
used for NFS requests. We're playing safe and convert
|
||||||
to ENOATTR, unless we're on NFS, where we convert it to ENOTSUP. */
|
STATUS_NOT_FOUND to ENOATTR, unless we're on NFS, where we
|
||||||
|
convert it to ENOTSUP. */
|
||||||
set_errno (pc.fs_is_nfs () ? ENOTSUP : ENOATTR);
|
set_errno (pc.fs_is_nfs () ? ENOTSUP : ENOATTR);
|
||||||
break;
|
break;
|
||||||
case STATUS_NONEXISTENT_EA_ENTRY:
|
case STATUS_NONEXISTENT_EA_ENTRY:
|
||||||
/* Actually STATUS_NONEXISTENT_EA_ENTRY is either never generated, or
|
/* Actually STATUS_NONEXISTENT_EA_ENTRY is either never generated,
|
||||||
it was only generated in some old and long forgotton NT version.
|
or it was only generated in some old and long forgotton NT
|
||||||
See below. For safty reasons, we handle it here, nevertheless. */
|
version. See below. For safty reasons, we handle it here,
|
||||||
|
nevertheless. */
|
||||||
set_errno (ENOATTR);
|
set_errno (ENOATTR);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
__seterrno_from_nt_status (status);
|
__seterrno_from_nt_status (status);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
goto out;
|
__leave;
|
||||||
}
|
}
|
||||||
if (name)
|
if (name)
|
||||||
{
|
{
|
||||||
@ -168,14 +170,14 @@ read_ea (HANDLE hdl, path_conv &pc, const char *name, char *value, size_t size)
|
|||||||
if (!fea->EaValueLength)
|
if (!fea->EaValueLength)
|
||||||
{
|
{
|
||||||
set_errno (ENOATTR);
|
set_errno (ENOATTR);
|
||||||
goto out;
|
__leave;
|
||||||
}
|
}
|
||||||
if (size > 0)
|
if (size > 0)
|
||||||
{
|
{
|
||||||
if (size < fea->EaValueLength)
|
if (size < fea->EaValueLength)
|
||||||
{
|
{
|
||||||
set_errno (ERANGE);
|
set_errno (ERANGE);
|
||||||
goto out;
|
__leave;
|
||||||
}
|
}
|
||||||
memcpy (value, fea->EaName + fea->EaNameLength + 1,
|
memcpy (value, fea->EaName + fea->EaNameLength + 1,
|
||||||
fea->EaValueLength);
|
fea->EaValueLength);
|
||||||
@ -193,7 +195,7 @@ read_ea (HANDLE hdl, path_conv &pc, const char *name, char *value, size_t size)
|
|||||||
if ((size_t) ret + fea->EaNameLength + 1 > size)
|
if ((size_t) ret + fea->EaNameLength + 1 > size)
|
||||||
{
|
{
|
||||||
set_errno (ERANGE);
|
set_errno (ERANGE);
|
||||||
goto out;
|
__leave;
|
||||||
}
|
}
|
||||||
/* For compatibility with Linux, we always prepend "user." to
|
/* For compatibility with Linux, we always prepend "user." to
|
||||||
the attribute name, so effectively we only support user
|
the attribute name, so effectively we only support user
|
||||||
@ -201,10 +203,11 @@ read_ea (HANDLE hdl, path_conv &pc, const char *name, char *value, size_t size)
|
|||||||
char tmpbuf[MAX_EA_NAME_LEN * 2];
|
char tmpbuf[MAX_EA_NAME_LEN * 2];
|
||||||
char *tp = stpcpy (tmpbuf, "user.");
|
char *tp = stpcpy (tmpbuf, "user.");
|
||||||
stpcpy (tp, fea->EaName);
|
stpcpy (tp, fea->EaName);
|
||||||
/* NTFS stores all EA names in uppercase unfortunately. To keep
|
/* NTFS stores all EA names in uppercase unfortunately. To
|
||||||
compatibility with ext/xfs EA namespaces and accompanying
|
keep compatibility with ext/xfs EA namespaces and
|
||||||
tools, which expect the namespaces to be lower case, we return
|
accompanying tools, which expect the namespaces to be
|
||||||
EA names in lowercase if the file is on a native NTFS. */
|
lower case, we return EA names in lowercase if the file
|
||||||
|
is on a native NTFS. */
|
||||||
if (pc.fs_is_ntfs ())
|
if (pc.fs_is_ntfs ())
|
||||||
strlwr (tp);
|
strlwr (tp);
|
||||||
tp = stpcpy (value, tmpbuf) + 1;
|
tp = stpcpy (value, tmpbuf) + 1;
|
||||||
@ -219,8 +222,9 @@ read_ea (HANDLE hdl, path_conv &pc, const char *name, char *value, size_t size)
|
|||||||
}
|
}
|
||||||
while (NT_SUCCESS (status) && strcmp (lastname, fea->EaName) != 0);
|
while (NT_SUCCESS (status) && strcmp (lastname, fea->EaName) != 0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
out:
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
if (!hdl)
|
if (!hdl)
|
||||||
CloseHandle (h);
|
CloseHandle (h);
|
||||||
debug_printf ("%d = read_ea(%S, %s, %p, %lu)",
|
debug_printf ("%d = read_ea(%S, %s, %p, %lu)",
|
||||||
@ -241,10 +245,8 @@ write_ea (HANDLE hdl, path_conv &pc, const char *name, const char *value,
|
|||||||
ULONG flen;
|
ULONG flen;
|
||||||
size_t nlen;
|
size_t nlen;
|
||||||
|
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EFAULT))
|
{
|
||||||
goto out;
|
|
||||||
|
|
||||||
pc.get_object_attr (attr, sec_none_nih);
|
pc.get_object_attr (attr, sec_none_nih);
|
||||||
|
|
||||||
debug_printf ("write_ea (%S, %s, %p, %lu, %d)",
|
debug_printf ("write_ea (%S, %s, %p, %lu, %d)",
|
||||||
@ -256,11 +258,12 @@ write_ea (HANDLE hdl, path_conv &pc, const char *name, const char *value,
|
|||||||
if (!hdl)
|
if (!hdl)
|
||||||
{
|
{
|
||||||
status = NtOpenFile (&h, READ_CONTROL | FILE_WRITE_EA, &attr, &io,
|
status = NtOpenFile (&h, READ_CONTROL | FILE_WRITE_EA, &attr, &io,
|
||||||
FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT);
|
FILE_SHARE_VALID_FLAGS,
|
||||||
|
FILE_OPEN_FOR_BACKUP_INTENT);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
__seterrno_from_nt_status (status);
|
__seterrno_from_nt_status (status);
|
||||||
goto out;
|
__leave;
|
||||||
}
|
}
|
||||||
hdl = NULL;
|
hdl = NULL;
|
||||||
}
|
}
|
||||||
@ -270,11 +273,11 @@ write_ea (HANDLE hdl, path_conv &pc, const char *name, const char *value,
|
|||||||
if (!ascii_strncasematch (name, "user.", 5))
|
if (!ascii_strncasematch (name, "user.", 5))
|
||||||
{
|
{
|
||||||
set_errno (ENOTSUP);
|
set_errno (ENOTSUP);
|
||||||
goto out;
|
__leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* removexattr is supposed to fail with ENOATTR if the requested EA is not
|
/* removexattr is supposed to fail with ENOATTR if the requested EA is
|
||||||
available. This is equivalent to the XATTR_REPLACE flag for setxattr. */
|
not available. This is equivalent to XATTR_REPLACE for setxattr. */
|
||||||
if (!value)
|
if (!value)
|
||||||
flags = XATTR_REPLACE;
|
flags = XATTR_REPLACE;
|
||||||
|
|
||||||
@ -283,16 +286,16 @@ write_ea (HANDLE hdl, path_conv &pc, const char *name, const char *value,
|
|||||||
if (flags != XATTR_CREATE && flags != XATTR_REPLACE)
|
if (flags != XATTR_CREATE && flags != XATTR_REPLACE)
|
||||||
{
|
{
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
goto out;
|
__leave;
|
||||||
}
|
}
|
||||||
ssize_t rret = read_ea (hdl, pc, name, NULL, 0);
|
ssize_t rret = read_ea (hdl, pc, name, NULL, 0);
|
||||||
if (flags == XATTR_CREATE && rret > 0)
|
if (flags == XATTR_CREATE && rret > 0)
|
||||||
{
|
{
|
||||||
set_errno (EEXIST);
|
set_errno (EEXIST);
|
||||||
goto out;
|
__leave;
|
||||||
}
|
}
|
||||||
if (flags == XATTR_REPLACE && rret < 0)
|
if (flags == XATTR_REPLACE && rret < 0)
|
||||||
goto out;
|
__leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Skip "user." prefix. */
|
/* Skip "user." prefix. */
|
||||||
@ -301,7 +304,7 @@ write_ea (HANDLE hdl, path_conv &pc, const char *name, const char *value,
|
|||||||
if ((nlen = strlen (name)) >= MAX_EA_NAME_LEN)
|
if ((nlen = strlen (name)) >= MAX_EA_NAME_LEN)
|
||||||
{
|
{
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
goto out;
|
__leave;
|
||||||
}
|
}
|
||||||
flen = sizeof (FILE_FULL_EA_INFORMATION) + nlen + 1 + size;
|
flen = sizeof (FILE_FULL_EA_INFORMATION) + nlen + 1 + size;
|
||||||
fea = (PFILE_FULL_EA_INFORMATION) alloca (flen);
|
fea = (PFILE_FULL_EA_INFORMATION) alloca (flen);
|
||||||
@ -322,7 +325,8 @@ write_ea (HANDLE hdl, path_conv &pc, const char *name, const char *value,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
status = NtOpenFile (&h, READ_CONTROL | FILE_WRITE_EA, &attr, &io,
|
status = NtOpenFile (&h, READ_CONTROL | FILE_WRITE_EA, &attr, &io,
|
||||||
FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT);
|
FILE_SHARE_VALID_FLAGS,
|
||||||
|
FILE_OPEN_FOR_BACKUP_INTENT);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
break;
|
break;
|
||||||
hdl = NULL;
|
hdl = NULL;
|
||||||
@ -332,15 +336,15 @@ write_ea (HANDLE hdl, path_conv &pc, const char *name, const char *value,
|
|||||||
switch (status)
|
switch (status)
|
||||||
{
|
{
|
||||||
case STATUS_EA_TOO_LARGE:
|
case STATUS_EA_TOO_LARGE:
|
||||||
/* STATUS_EA_TOO_LARGE has a matching Win32 error ERROR_EA_TABLE_FULL.
|
/* STATUS_EA_TOO_LARGE has a matching Win32 error code
|
||||||
For some unknown reason RtlNtStatusToDosError does not translate
|
ERROR_EA_TABLE_FULL. For some reason RtlNtStatusToDosError
|
||||||
STATUS_EA_TOO_LARGE to ERROR_EA_TABLE_FULL, but instead to
|
does not translate STATUS_EA_TOO_LARGE to ERROR_EA_TABLE_FULL,
|
||||||
ERROR_EA_LIST_INCONSISTENT. This error code is also returned for
|
but instead to ERROR_EA_LIST_INCONSISTENT. This error code is
|
||||||
STATUS_EA_LIST_INCONSISTENT, which means the incoming EA list is...
|
also returned for STATUS_EA_LIST_INCONSISTENT, which means the
|
||||||
inconsistent. For obvious reasons we translate
|
incoming EA list is... inconsistent. For obvious reasons we
|
||||||
ERROR_EA_LIST_INCONSISTENT to EINVAL, so we have to handle
|
translate ERROR_EA_LIST_INCONSISTENT to EINVAL, so we have to
|
||||||
STATUS_EA_TOO_LARGE explicitely here, to get the correct mapping
|
handle STATUS_EA_TOO_LARGE explicitely here, to get the correct
|
||||||
to ENOSPC. */
|
mapping to ENOSPC. */
|
||||||
set_errno (ENOSPC);
|
set_errno (ENOSPC);
|
||||||
break;
|
break;
|
||||||
case STATUS_INVALID_DEVICE_REQUEST:
|
case STATUS_INVALID_DEVICE_REQUEST:
|
||||||
@ -353,8 +357,9 @@ write_ea (HANDLE hdl, path_conv &pc, const char *name, const char *value,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
}
|
||||||
out:
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
if (!hdl)
|
if (!hdl)
|
||||||
CloseHandle (h);
|
CloseHandle (h);
|
||||||
debug_printf ("%d = write_ea(%S, %s, %p, %lu, %d)",
|
debug_printf ("%d = write_ea(%S, %s, %p, %lu, %d)",
|
||||||
|
@ -651,12 +651,8 @@ path_conv::check (const char *src, unsigned opt,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted ())
|
|
||||||
{
|
{
|
||||||
error = EFAULT;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int loop = 0;
|
int loop = 0;
|
||||||
path_flags = 0;
|
path_flags = 0;
|
||||||
known_suffix = NULL;
|
known_suffix = NULL;
|
||||||
@ -706,9 +702,9 @@ path_conv::check (const char *src, unsigned opt,
|
|||||||
error = 0;
|
error = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Detect if the user was looking for a directory. We have to strip the
|
/* Detect if the user was looking for a directory. We have to strip
|
||||||
trailing slash initially while trying to add extensions but take it
|
the trailing slash initially while trying to add extensions but
|
||||||
into account during processing */
|
take it into account during processing */
|
||||||
if (tail > path_copy + 2 && isslash (tail[-1]))
|
if (tail > path_copy + 2 && isslash (tail[-1]))
|
||||||
{
|
{
|
||||||
need_directory = 1;
|
need_directory = 1;
|
||||||
@ -748,8 +744,8 @@ path_conv::check (const char *src, unsigned opt,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Convert to native path spec sans symbolic link info. */
|
/* Convert to native path spec sans symbolic link info. */
|
||||||
error = mount_table->conv_to_win32_path (path_copy, full_path, dev,
|
error = mount_table->conv_to_win32_path (path_copy, full_path,
|
||||||
&sym.pflags);
|
dev, &sym.pflags);
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
return;
|
return;
|
||||||
@ -765,7 +761,8 @@ path_conv::check (const char *src, unsigned opt,
|
|||||||
if (iscygdrive_dev (dev))
|
if (iscygdrive_dev (dev))
|
||||||
{
|
{
|
||||||
if (!component)
|
if (!component)
|
||||||
fileattr = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_READONLY;
|
fileattr = FILE_ATTRIBUTE_DIRECTORY
|
||||||
|
| FILE_ATTRIBUTE_READONLY;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fileattr = getfileattr (THIS_path,
|
fileattr = getfileattr (THIS_path,
|
||||||
@ -776,12 +773,14 @@ path_conv::check (const char *src, unsigned opt,
|
|||||||
}
|
}
|
||||||
else if (isdev_dev (dev))
|
else if (isdev_dev (dev))
|
||||||
{
|
{
|
||||||
/* Just make sure that the path handling goes on as with FH_FS. */
|
/* Make sure that the path handling goes on as with FH_FS. */
|
||||||
}
|
}
|
||||||
else if (isvirtual_dev (dev))
|
else if (isvirtual_dev (dev))
|
||||||
{
|
{
|
||||||
/* FIXME: Calling build_fhandler here is not the right way to handle this. */
|
/* FIXME: Calling build_fhandler here is not the right way to
|
||||||
fhandler_virtual *fh = (fhandler_virtual *) build_fh_dev (dev, path_copy);
|
handle this. */
|
||||||
|
fhandler_virtual *fh = (fhandler_virtual *)
|
||||||
|
build_fh_dev (dev, path_copy);
|
||||||
virtual_ftype_t file_type;
|
virtual_ftype_t file_type;
|
||||||
if (!fh)
|
if (!fh)
|
||||||
file_type = virt_none;
|
file_type = virt_none;
|
||||||
@ -832,8 +831,8 @@ path_conv::check (const char *src, unsigned opt,
|
|||||||
case virt_blk:
|
case virt_blk:
|
||||||
/* Block special device. If the trailing slash has been
|
/* Block special device. If the trailing slash has been
|
||||||
requested, the target is the root directory of the
|
requested, the target is the root directory of the
|
||||||
filesystem on this block device. So we convert this to
|
filesystem on this block device. So we convert this
|
||||||
a real file and attach the backslash. */
|
to a real file and attach the backslash. */
|
||||||
if (component == 0 && need_directory)
|
if (component == 0 && need_directory)
|
||||||
{
|
{
|
||||||
dev.parse (FH_FS);
|
dev.parse (FH_FS);
|
||||||
@ -856,7 +855,7 @@ path_conv::check (const char *src, unsigned opt,
|
|||||||
path_flags |= PATH_RO;
|
path_flags |= PATH_RO;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
/* devn should not be a device. If it is, then stop parsing now. */
|
/* devn should not be a device. If it is, then stop parsing. */
|
||||||
else if (dev != FH_FS)
|
else if (dev != FH_FS)
|
||||||
{
|
{
|
||||||
fileattr = 0;
|
fileattr = 0;
|
||||||
@ -886,11 +885,11 @@ path_conv::check (const char *src, unsigned opt,
|
|||||||
if (is_msdos)
|
if (is_msdos)
|
||||||
sym.pflags |= PATH_NOPOSIX | PATH_NOACL;
|
sym.pflags |= PATH_NOPOSIX | PATH_NOACL;
|
||||||
|
|
||||||
is_fs_via_procsys:
|
is_fs_via_procsys:
|
||||||
|
|
||||||
symlen = sym.check (full_path, suff, fs, conv_handle);
|
symlen = sym.check (full_path, suff, fs, conv_handle);
|
||||||
|
|
||||||
is_virtual_symlink:
|
is_virtual_symlink:
|
||||||
|
|
||||||
if (sym.isdevice)
|
if (sym.isdevice)
|
||||||
{
|
{
|
||||||
@ -928,15 +927,15 @@ is_virtual_symlink:
|
|||||||
}
|
}
|
||||||
else if (isdev_dev (dev))
|
else if (isdev_dev (dev))
|
||||||
{
|
{
|
||||||
/* If we're looking for a file below /dev, which doesn't exist,
|
/* If we're looking for a non-existing file below /dev,
|
||||||
make sure that the device type is converted to FH_FS, so that
|
make sure that the device type is converted to FH_FS, so
|
||||||
subsequent code handles the file correctly.
|
that subsequent code handles the file correctly. Unless
|
||||||
Unless /dev itself doesn't exist on disk. In that case /dev
|
/dev itself doesn't exist on disk. In that case /dev
|
||||||
is handled as virtual filesystem, and virtual filesystems are
|
is handled as virtual filesystem, and virtual filesystems
|
||||||
read-only. The PC_KEEP_HANDLE check allows to check for
|
are read-only. The PC_KEEP_HANDLE check allows to check
|
||||||
a call from an informational system call. In that case we
|
for a call from an informational system call. In that
|
||||||
just stick to ENOENT, and the device type doesn't matter
|
case we just stick to ENOENT, and the device type doesn't
|
||||||
anyway. */
|
matter anyway. */
|
||||||
if (sym.error == ENOENT && !(opt & PC_KEEP_HANDLE))
|
if (sym.error == ENOENT && !(opt & PC_KEEP_HANDLE))
|
||||||
sym.error = EROFS;
|
sym.error = EROFS;
|
||||||
else
|
else
|
||||||
@ -968,9 +967,11 @@ is_virtual_symlink:
|
|||||||
saw_symlinks = 1;
|
saw_symlinks = 1;
|
||||||
if (component == 0 && !need_directory
|
if (component == 0 && !need_directory
|
||||||
&& (!(opt & PC_SYM_FOLLOW)
|
&& (!(opt & PC_SYM_FOLLOW)
|
||||||
|| (is_rep_symlink () && (opt & PC_SYM_NOFOLLOW_REP))))
|
|| (is_rep_symlink ()
|
||||||
|
&& (opt & PC_SYM_NOFOLLOW_REP))))
|
||||||
{
|
{
|
||||||
set_symlink (symlen); // last component of path is a symlink.
|
/* last component of path is a symlink. */
|
||||||
|
set_symlink (symlen);
|
||||||
if (opt & PC_SYM_CONTENTS)
|
if (opt & PC_SYM_CONTENTS)
|
||||||
{
|
{
|
||||||
strcpy (THIS_path, sym.contents);
|
strcpy (THIS_path, sym.contents);
|
||||||
@ -979,8 +980,8 @@ is_virtual_symlink:
|
|||||||
add_ext = true;
|
add_ext = true;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
/* Following a symlink we can't trust the collected filesystem
|
/* Following a symlink we can't trust the collected
|
||||||
information any longer. */
|
filesystem information any longer. */
|
||||||
fs.clear ();
|
fs.clear ();
|
||||||
/* Close handle, if we have any. Otherwise we're collecting
|
/* Close handle, if we have any. Otherwise we're collecting
|
||||||
handles while following symlinks. */
|
handles while following symlinks. */
|
||||||
@ -994,7 +995,7 @@ is_virtual_symlink:
|
|||||||
}
|
}
|
||||||
/* No existing file found. */
|
/* No existing file found. */
|
||||||
|
|
||||||
virtual_component_retry:
|
virtual_component_retry:
|
||||||
/* Find the new "tail" of the path, e.g. in '/for/bar/baz',
|
/* Find the new "tail" of the path, e.g. in '/for/bar/baz',
|
||||||
/baz is the tail. */
|
/baz is the tail. */
|
||||||
if (tail != path_end)
|
if (tail != path_end)
|
||||||
@ -1021,14 +1022,16 @@ virtual_component_retry:
|
|||||||
MALLOC_CHECK;
|
MALLOC_CHECK;
|
||||||
|
|
||||||
|
|
||||||
/* Place the link content, possibly with head and/or tail, in tmp_buf */
|
/* Place the link content, possibly with head and/or tail,
|
||||||
|
in tmp_buf */
|
||||||
|
|
||||||
char *headptr;
|
char *headptr;
|
||||||
if (isabspath (sym.contents))
|
if (isabspath (sym.contents))
|
||||||
headptr = tmp_buf; /* absolute path */
|
headptr = tmp_buf; /* absolute path */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Copy the first part of the path (with ending /) and point to the end. */
|
/* Copy the first part of the path (with ending /) and point to
|
||||||
|
the end. */
|
||||||
char *prevtail = tail;
|
char *prevtail = tail;
|
||||||
while (--prevtail > path_copy && *prevtail != '/') {}
|
while (--prevtail > path_copy && *prevtail != '/') {}
|
||||||
int headlen = prevtail - path_copy + 1;;
|
int headlen = prevtail - path_copy + 1;;
|
||||||
@ -1070,7 +1073,7 @@ virtual_component_retry:
|
|||||||
if (!(opt & PC_SYM_CONTENTS))
|
if (!(opt & PC_SYM_CONTENTS))
|
||||||
add_ext = true;
|
add_ext = true;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
set_path (THIS_path);
|
set_path (THIS_path);
|
||||||
if (add_ext)
|
if (add_ext)
|
||||||
add_ext_from_sym (sym);
|
add_ext_from_sym (sym);
|
||||||
@ -1098,7 +1101,8 @@ out:
|
|||||||
else if (!need_directory || error)
|
else if (!need_directory || error)
|
||||||
/* nothing to do */;
|
/* nothing to do */;
|
||||||
else if (fileattr == INVALID_FILE_ATTRIBUTES)
|
else if (fileattr == INVALID_FILE_ATTRIBUTES)
|
||||||
strcat (modifiable_path (), "\\"); /* Reattach trailing dirsep in native path. */
|
/* Reattach trailing dirsep in native path. */
|
||||||
|
strcat (modifiable_path (), "\\");
|
||||||
else if (fileattr & FILE_ATTRIBUTE_DIRECTORY)
|
else if (fileattr & FILE_ATTRIBUTE_DIRECTORY)
|
||||||
path_flags &= ~PATH_SYMLINK;
|
path_flags &= ~PATH_SYMLINK;
|
||||||
else
|
else
|
||||||
@ -1123,21 +1127,24 @@ out:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If FS hasn't been checked already in symlink_info::check, do so now. */
|
/* If FS hasn't been checked already in symlink_info::check,
|
||||||
|
do so now. */
|
||||||
if (fs.inited ()|| fs.update (get_nt_native_path (), NULL))
|
if (fs.inited ()|| fs.update (get_nt_native_path (), NULL))
|
||||||
{
|
{
|
||||||
/* Incoming DOS paths are treated like DOS paths in native
|
/* Incoming DOS paths are treated like DOS paths in native
|
||||||
Windows applications. No ACLs, just default settings. */
|
Windows applications. No ACLs, just default settings. */
|
||||||
if (is_msdos)
|
if (is_msdos)
|
||||||
fs.has_acls (false);
|
fs.has_acls (false);
|
||||||
debug_printf ("this->path(%s), has_acls(%d)", path, fs.has_acls ());
|
debug_printf ("this->path(%s), has_acls(%d)",
|
||||||
|
path, fs.has_acls ());
|
||||||
/* CV: We could use this->has_acls() but I want to make sure that
|
/* CV: We could use this->has_acls() but I want to make sure that
|
||||||
we don't forget that the PATH_NOACL flag must be taken into
|
we don't forget that the PATH_NOACL flag must be taken into
|
||||||
account here. */
|
account here. */
|
||||||
if (!(path_flags & PATH_NOACL) && fs.has_acls ())
|
if (!(path_flags & PATH_NOACL) && fs.has_acls ())
|
||||||
set_exec (0); /* We really don't know if this is executable or not here
|
set_exec (0); /* We really don't know if this is executable or
|
||||||
but set it to not executable since it will be figured out
|
not here but set it to not executable since
|
||||||
later by anything which cares about this. */
|
it will be figured out later by anything
|
||||||
|
which cares about this. */
|
||||||
}
|
}
|
||||||
/* If the FS has been found to have unrelibale inodes, note
|
/* If the FS has been found to have unrelibale inodes, note
|
||||||
that in path_flags. */
|
that in path_flags. */
|
||||||
@ -1206,6 +1213,12 @@ out:
|
|||||||
strcpy (last_src, src);
|
strcpy (last_src, src);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
__except (NO_ERROR)
|
||||||
|
{
|
||||||
|
error = EFAULT;
|
||||||
|
}
|
||||||
|
__endtry
|
||||||
}
|
}
|
||||||
|
|
||||||
path_conv::~path_conv ()
|
path_conv::~path_conv ()
|
||||||
@ -1688,19 +1701,18 @@ symlink_worker (const char *oldpath, const char *newpath, bool isdevice)
|
|||||||
/* POSIX says that empty 'newpath' is invalid input while empty
|
/* POSIX says that empty 'newpath' is invalid input while empty
|
||||||
'oldpath' is valid -- it's symlink resolver job to verify if
|
'oldpath' is valid -- it's symlink resolver job to verify if
|
||||||
symlink contents point to existing filesystem object */
|
symlink contents point to existing filesystem object */
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EFAULT))
|
{
|
||||||
goto done;
|
|
||||||
if (!*oldpath || !*newpath)
|
if (!*oldpath || !*newpath)
|
||||||
{
|
{
|
||||||
set_errno (ENOENT);
|
set_errno (ENOENT);
|
||||||
goto done;
|
__leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strlen (oldpath) > SYMLINK_MAX)
|
if (strlen (oldpath) > SYMLINK_MAX)
|
||||||
{
|
{
|
||||||
set_errno (ENAMETOOLONG);
|
set_errno (ENAMETOOLONG);
|
||||||
goto done;
|
__leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Trailing dirsep is a no-no. */
|
/* Trailing dirsep is a no-no. */
|
||||||
@ -1716,8 +1728,8 @@ symlink_worker (const char *oldpath, const char *newpath, bool isdevice)
|
|||||||
/* We need the normalized full path below. */
|
/* We need the normalized full path below. */
|
||||||
win32_newpath.check (newpath, check_opt, stat_suffixes);
|
win32_newpath.check (newpath, check_opt, stat_suffixes);
|
||||||
|
|
||||||
/* Default symlink type is determined by global allow_winsymlinks variable.
|
/* Default symlink type is determined by global allow_winsymlinks
|
||||||
Device files are always shortcuts. */
|
variable. Device files are always shortcuts. */
|
||||||
wsym_type = isdevice ? WSYM_lnk : allow_winsymlinks;
|
wsym_type = isdevice ? WSYM_lnk : allow_winsymlinks;
|
||||||
/* NFS has its own, dedicated way to create symlinks. */
|
/* NFS has its own, dedicated way to create symlinks. */
|
||||||
if (win32_newpath.fs_is_nfs ())
|
if (win32_newpath.fs_is_nfs ())
|
||||||
@ -1733,11 +1745,11 @@ symlink_worker (const char *oldpath, const char *newpath, bool isdevice)
|
|||||||
if (wincap.max_sys_priv () < SE_CREATE_SYMBOLIC_LINK_PRIVILEGE)
|
if (wincap.max_sys_priv () < SE_CREATE_SYMBOLIC_LINK_PRIVILEGE)
|
||||||
{
|
{
|
||||||
set_errno (EPERM);
|
set_errno (EPERM);
|
||||||
goto done;
|
__leave;
|
||||||
}
|
}
|
||||||
wsym_type = WSYM_nativestrict;
|
wsym_type = WSYM_nativestrict;
|
||||||
}
|
}
|
||||||
/* Don't try native symlinks on filesystems not supporting reparse points. */
|
/* Don't try native symlinks on FSes not supporting reparse points. */
|
||||||
else if ((wsym_type == WSYM_native || wsym_type == WSYM_nativestrict)
|
else if ((wsym_type == WSYM_native || wsym_type == WSYM_nativestrict)
|
||||||
&& !(win32_newpath.fs_flags () & FILE_SUPPORTS_REPARSE_POINTS))
|
&& !(win32_newpath.fs_flags () & FILE_SUPPORTS_REPARSE_POINTS))
|
||||||
wsym_type = WSYM_sysfile;
|
wsym_type = WSYM_sysfile;
|
||||||
@ -1754,7 +1766,7 @@ symlink_worker (const char *oldpath, const char *newpath, bool isdevice)
|
|||||||
if (win32_newpath.error)
|
if (win32_newpath.error)
|
||||||
{
|
{
|
||||||
set_errno (win32_newpath.error);
|
set_errno (win32_newpath.error);
|
||||||
goto done;
|
__leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
syscall_printf ("symlink (%s, %S) wsym_type %d", oldpath,
|
syscall_printf ("symlink (%s, %S) wsym_type %d", oldpath,
|
||||||
@ -1764,12 +1776,12 @@ symlink_worker (const char *oldpath, const char *newpath, bool isdevice)
|
|||||||
|| win32_newpath.is_auto_device ())
|
|| win32_newpath.is_auto_device ())
|
||||||
{
|
{
|
||||||
set_errno (EEXIST);
|
set_errno (EEXIST);
|
||||||
goto done;
|
__leave;
|
||||||
}
|
}
|
||||||
if (has_trailing_dirsep && !win32_newpath.exists ())
|
if (has_trailing_dirsep && !win32_newpath.exists ())
|
||||||
{
|
{
|
||||||
set_errno (ENOENT);
|
set_errno (ENOENT);
|
||||||
goto done;
|
__leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle NFS and native symlinks in their own functions. */
|
/* Handle NFS and native symlinks in their own functions. */
|
||||||
@ -1777,17 +1789,17 @@ symlink_worker (const char *oldpath, const char *newpath, bool isdevice)
|
|||||||
{
|
{
|
||||||
case WSYM_nfs:
|
case WSYM_nfs:
|
||||||
res = symlink_nfs (oldpath, win32_newpath);
|
res = symlink_nfs (oldpath, win32_newpath);
|
||||||
goto done;
|
__leave;
|
||||||
case WSYM_native:
|
case WSYM_native:
|
||||||
case WSYM_nativestrict:
|
case WSYM_nativestrict:
|
||||||
res = symlink_native (oldpath, win32_newpath);
|
res = symlink_native (oldpath, win32_newpath);
|
||||||
if (!res)
|
if (!res)
|
||||||
goto done;
|
__leave;
|
||||||
/* Strictly native? Too bad. */
|
/* Strictly native? Too bad. */
|
||||||
if (wsym_type == WSYM_nativestrict)
|
if (wsym_type == WSYM_nativestrict)
|
||||||
{
|
{
|
||||||
__seterrno ();
|
__seterrno ();
|
||||||
goto done;
|
__leave;
|
||||||
}
|
}
|
||||||
/* Otherwise, fall back to default symlink type. */
|
/* Otherwise, fall back to default symlink type. */
|
||||||
wsym_type = WSYM_sysfile;
|
wsym_type = WSYM_sysfile;
|
||||||
@ -1810,9 +1822,9 @@ symlink_worker (const char *oldpath, const char *newpath, bool isdevice)
|
|||||||
going to be. */
|
going to be. */
|
||||||
IShellFolder *psl;
|
IShellFolder *psl;
|
||||||
|
|
||||||
/* The symlink target is relative to the directory in which
|
/* The symlink target is relative to the directory in which the
|
||||||
the symlink gets created, not relative to the cwd. Therefore
|
symlink gets created, not relative to the cwd. Therefore we
|
||||||
we have to mangle the path quite a bit before calling path_conv. */
|
have to mangle the path quite a bit before calling path_conv.*/
|
||||||
if (isabspath (oldpath))
|
if (isabspath (oldpath))
|
||||||
win32_oldpath.check (oldpath,
|
win32_oldpath.check (oldpath,
|
||||||
PC_SYM_NOFOLLOW,
|
PC_SYM_NOFOLLOW,
|
||||||
@ -1822,9 +1834,11 @@ symlink_worker (const char *oldpath, const char *newpath, bool isdevice)
|
|||||||
len = strrchr (win32_newpath.normalized_path, '/')
|
len = strrchr (win32_newpath.normalized_path, '/')
|
||||||
- win32_newpath.normalized_path + 1;
|
- win32_newpath.normalized_path + 1;
|
||||||
char *absoldpath = tp.t_get ();
|
char *absoldpath = tp.t_get ();
|
||||||
stpcpy (stpncpy (absoldpath, win32_newpath.normalized_path, len),
|
stpcpy (stpncpy (absoldpath, win32_newpath.normalized_path,
|
||||||
|
len),
|
||||||
oldpath);
|
oldpath);
|
||||||
win32_oldpath.check (absoldpath, PC_SYM_NOFOLLOW, stat_suffixes);
|
win32_oldpath.check (absoldpath, PC_SYM_NOFOLLOW,
|
||||||
|
stat_suffixes);
|
||||||
}
|
}
|
||||||
if (SUCCEEDED (SHGetDesktopFolder (&psl)))
|
if (SUCCEEDED (SHGetDesktopFolder (&psl)))
|
||||||
{
|
{
|
||||||
@ -1839,8 +1853,9 @@ symlink_worker (const char *oldpath, const char *newpath, bool isdevice)
|
|||||||
if (wc[1] != L':') /* native UNC path */
|
if (wc[1] != L':') /* native UNC path */
|
||||||
*(wc += 2) = L'\\';
|
*(wc += 2) = L'\\';
|
||||||
HRESULT res;
|
HRESULT res;
|
||||||
if (SUCCEEDED (res = psl->ParseDisplayName (NULL, NULL, wc, NULL,
|
if (SUCCEEDED (res = psl->ParseDisplayName (NULL, NULL, wc,
|
||||||
&pidl, NULL)))
|
NULL, &pidl,
|
||||||
|
NULL)))
|
||||||
{
|
{
|
||||||
ITEMIDLIST *p;
|
ITEMIDLIST *p;
|
||||||
|
|
||||||
@ -1924,7 +1939,8 @@ symlink_worker (const char *oldpath, const char *newpath, bool isdevice)
|
|||||||
cp += 2;
|
cp += 2;
|
||||||
*(PWCHAR) cp = 0xfeff; /* BOM */
|
*(PWCHAR) cp = 0xfeff; /* BOM */
|
||||||
cp += 2;
|
cp += 2;
|
||||||
*plen = sys_mbstowcs ((PWCHAR) cp, NT_MAX_PATH, oldpath) * sizeof (WCHAR);
|
*plen = sys_mbstowcs ((PWCHAR) cp, NT_MAX_PATH, oldpath)
|
||||||
|
* sizeof (WCHAR);
|
||||||
cp += *plen;
|
cp += *plen;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1935,7 +1951,8 @@ symlink_worker (const char *oldpath, const char *newpath, bool isdevice)
|
|||||||
*(PWCHAR) cp = 0xfeff; /* BOM */
|
*(PWCHAR) cp = 0xfeff; /* BOM */
|
||||||
cp += 2;
|
cp += 2;
|
||||||
/* Note that the terminating nul is written. */
|
/* Note that the terminating nul is written. */
|
||||||
cp += sys_mbstowcs ((PWCHAR) cp, NT_MAX_PATH, oldpath) * sizeof (WCHAR);
|
cp += sys_mbstowcs ((PWCHAR) cp, NT_MAX_PATH, oldpath)
|
||||||
|
* sizeof (WCHAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
OBJECT_ATTRIBUTES attr;
|
OBJECT_ATTRIBUTES attr;
|
||||||
@ -1948,22 +1965,24 @@ symlink_worker (const char *oldpath, const char *newpath, bool isdevice)
|
|||||||
if (isdevice && win32_newpath.exists ())
|
if (isdevice && win32_newpath.exists ())
|
||||||
{
|
{
|
||||||
status = NtOpenFile (&fh, FILE_WRITE_ATTRIBUTES,
|
status = NtOpenFile (&fh, FILE_WRITE_ATTRIBUTES,
|
||||||
win32_newpath.get_object_attr (attr, sec_none_nih),
|
win32_newpath.get_object_attr (attr,
|
||||||
|
sec_none_nih),
|
||||||
&io, 0, FILE_OPEN_FOR_BACKUP_INTENT);
|
&io, 0, FILE_OPEN_FOR_BACKUP_INTENT);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
__seterrno_from_nt_status (status);
|
__seterrno_from_nt_status (status);
|
||||||
goto done;
|
__leave;
|
||||||
}
|
}
|
||||||
status = NtSetAttributesFile (fh, FILE_ATTRIBUTE_NORMAL);
|
status = NtSetAttributesFile (fh, FILE_ATTRIBUTE_NORMAL);
|
||||||
NtClose (fh);
|
NtClose (fh);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
__seterrno_from_nt_status (status);
|
__seterrno_from_nt_status (status);
|
||||||
goto done;
|
__leave;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!isdevice && win32_newpath.has_acls () && !win32_newpath.isremote ())
|
else if (!isdevice && win32_newpath.has_acls ()
|
||||||
|
&& !win32_newpath.isremote ())
|
||||||
/* If the filesystem supports ACLs, we will overwrite the DACL after the
|
/* If the filesystem supports ACLs, we will overwrite the DACL after the
|
||||||
call to NtCreateFile. This requires a handle with READ_CONTROL and
|
call to NtCreateFile. This requires a handle with READ_CONTROL and
|
||||||
WRITE_DAC access, otherwise get_file_sd and set_file_sd both have to
|
WRITE_DAC access, otherwise get_file_sd and set_file_sd both have to
|
||||||
@ -1986,13 +2005,14 @@ symlink_worker (const char *oldpath, const char *newpath, bool isdevice)
|
|||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
__seterrno_from_nt_status (status);
|
__seterrno_from_nt_status (status);
|
||||||
goto done;
|
__leave;
|
||||||
}
|
}
|
||||||
if (win32_newpath.has_acls ())
|
if (win32_newpath.has_acls ())
|
||||||
set_file_attribute (fh, win32_newpath, ILLEGAL_UID, ILLEGAL_GID,
|
set_file_attribute (fh, win32_newpath, ILLEGAL_UID, ILLEGAL_GID,
|
||||||
(io.Information == FILE_CREATED ? S_JUSTCREATED : 0)
|
(io.Information == FILE_CREATED ? S_JUSTCREATED : 0)
|
||||||
| S_IFLNK | STD_RBITS | STD_WBITS);
|
| S_IFLNK | STD_RBITS | STD_WBITS);
|
||||||
status = NtWriteFile (fh, NULL, NULL, NULL, &io, buf, cp - buf, NULL, NULL);
|
status = NtWriteFile (fh, NULL, NULL, NULL, &io, buf, cp - buf,
|
||||||
|
NULL, NULL);
|
||||||
if (NT_SUCCESS (status) && io.Information == (ULONG) (cp - buf))
|
if (NT_SUCCESS (status) && io.Information == (ULONG) (cp - buf))
|
||||||
{
|
{
|
||||||
status = NtSetAttributesFile (fh, wsym_type == WSYM_lnk
|
status = NtSetAttributesFile (fh, wsym_type == WSYM_lnk
|
||||||
@ -2009,11 +2029,14 @@ symlink_worker (const char *oldpath, const char *newpath, bool isdevice)
|
|||||||
status = NtSetInformationFile (fh, &io, &fdi, sizeof fdi,
|
status = NtSetInformationFile (fh, &io, &fdi, sizeof fdi,
|
||||||
FileDispositionInformation);
|
FileDispositionInformation);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
debug_printf ("Setting delete dispostion failed, status = %y", status);
|
debug_printf ("Setting delete dispostion failed, status = %y",
|
||||||
|
status);
|
||||||
}
|
}
|
||||||
NtClose (fh);
|
NtClose (fh);
|
||||||
|
|
||||||
done:
|
}
|
||||||
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
syscall_printf ("%d = symlink_worker(%s, %s, %d)",
|
syscall_printf ("%d = symlink_worker(%s, %s, %d)",
|
||||||
res, oldpath, newpath, isdevice);
|
res, oldpath, newpath, isdevice);
|
||||||
if (has_trailing_dirsep)
|
if (has_trailing_dirsep)
|
||||||
@ -3109,13 +3132,16 @@ extern "C" char *
|
|||||||
getcwd (char *buf, size_t ulen)
|
getcwd (char *buf, size_t ulen)
|
||||||
{
|
{
|
||||||
char* res = NULL;
|
char* res = NULL;
|
||||||
myfault efault;
|
|
||||||
if (efault.faulted (EFAULT))
|
__try
|
||||||
/* errno set */;
|
{
|
||||||
else if (ulen == 0 && buf)
|
if (ulen == 0 && buf)
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
else
|
else
|
||||||
res = cygheap->cwd.get (buf, 1, 1, ulen);
|
res = cygheap->cwd.get (buf, 1, 1, ulen);
|
||||||
|
}
|
||||||
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3150,28 +3176,28 @@ get_current_dir_name (void)
|
|||||||
extern "C" int
|
extern "C" int
|
||||||
chdir (const char *in_dir)
|
chdir (const char *in_dir)
|
||||||
{
|
{
|
||||||
myfault efault;
|
int res = -1;
|
||||||
if (efault.faulted (EFAULT))
|
|
||||||
return -1;
|
__try
|
||||||
|
{
|
||||||
if (!*in_dir)
|
if (!*in_dir)
|
||||||
{
|
{
|
||||||
set_errno (ENOENT);
|
set_errno (ENOENT);
|
||||||
return -1;
|
__leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
syscall_printf ("dir '%s'", in_dir);
|
syscall_printf ("dir '%s'", in_dir);
|
||||||
|
|
||||||
/* Convert path. First argument ensures that we don't check for NULL/empty/invalid
|
/* Convert path. First argument ensures that we don't check for
|
||||||
again. */
|
NULL/empty/invalid again. */
|
||||||
path_conv path (PC_NONULLEMPTY, in_dir, PC_SYM_FOLLOW | PC_POSIX);
|
path_conv path (PC_NONULLEMPTY, in_dir, PC_SYM_FOLLOW | PC_POSIX);
|
||||||
if (path.error)
|
if (path.error)
|
||||||
{
|
{
|
||||||
set_errno (path.error);
|
set_errno (path.error);
|
||||||
syscall_printf ("-1 = chdir (%s)", in_dir);
|
syscall_printf ("-1 = chdir (%s)", in_dir);
|
||||||
return -1;
|
__leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
int res = -1;
|
|
||||||
const char *posix_cwd = NULL;
|
const char *posix_cwd = NULL;
|
||||||
dev_t devn = path.get_device ();
|
dev_t devn = path.get_device ();
|
||||||
if (!path.exists ())
|
if (!path.exists ())
|
||||||
@ -3198,10 +3224,16 @@ chdir (const char *in_dir)
|
|||||||
if (!res)
|
if (!res)
|
||||||
res = cygheap->cwd.set (&path, posix_cwd);
|
res = cygheap->cwd.set (&path, posix_cwd);
|
||||||
|
|
||||||
/* Note that we're accessing cwd.posix without a lock here. I didn't think
|
/* Note that we're accessing cwd.posix without a lock here.
|
||||||
it was worth locking just for strace. */
|
I didn't think it was worth locking just for strace. */
|
||||||
syscall_printf ("%R = chdir() cygheap->cwd.posix '%s' native '%S'", res,
|
syscall_printf ("%R = chdir() cygheap->cwd.posix '%s' native '%S'", res,
|
||||||
cygheap->cwd.get_posix (), path.get_nt_native_path ());
|
cygheap->cwd.get_posix (), path.get_nt_native_path ());
|
||||||
|
}
|
||||||
|
__except (EFAULT)
|
||||||
|
{
|
||||||
|
res = -1;
|
||||||
|
}
|
||||||
|
__endtry
|
||||||
MALLOC_CHECK;
|
MALLOC_CHECK;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -3239,10 +3271,6 @@ cygwin_conv_path (cygwin_conv_path_t what, const void *from, void *to,
|
|||||||
size_t size)
|
size_t size)
|
||||||
{
|
{
|
||||||
tmp_pathbuf tp;
|
tmp_pathbuf tp;
|
||||||
myfault efault;
|
|
||||||
if (efault.faulted (EFAULT))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
path_conv p;
|
path_conv p;
|
||||||
size_t lsiz = 0;
|
size_t lsiz = 0;
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
@ -3250,11 +3278,14 @@ cygwin_conv_path (cygwin_conv_path_t what, const void *from, void *to,
|
|||||||
int error = 0;
|
int error = 0;
|
||||||
bool relative = !!(what & CCP_RELATIVE);
|
bool relative = !!(what & CCP_RELATIVE);
|
||||||
what &= CCP_CONVTYPE_MASK;
|
what &= CCP_CONVTYPE_MASK;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
__try
|
||||||
|
{
|
||||||
if (!from)
|
if (!from)
|
||||||
{
|
{
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return -1;
|
__leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (what)
|
switch (what)
|
||||||
@ -3265,7 +3296,10 @@ cygwin_conv_path (cygwin_conv_path_t what, const void *from, void *to,
|
|||||||
PC_POSIX | PC_SYM_FOLLOW | PC_SYM_NOFOLLOW_REP
|
PC_POSIX | PC_SYM_FOLLOW | PC_SYM_NOFOLLOW_REP
|
||||||
| PC_NO_ACCESS_CHECK | PC_NOWARN | (relative ? PC_NOFULL : 0));
|
| PC_NO_ACCESS_CHECK | PC_NOWARN | (relative ? PC_NOFULL : 0));
|
||||||
if (p.error)
|
if (p.error)
|
||||||
return_with_errno (p.error);
|
{
|
||||||
|
set_errno (p.error);
|
||||||
|
__leave;
|
||||||
|
}
|
||||||
PUNICODE_STRING up = p.get_nt_native_path ();
|
PUNICODE_STRING up = p.get_nt_native_path ();
|
||||||
buf = tp.c_get ();
|
buf = tp.c_get ();
|
||||||
sys_wcstombs (buf, NT_MAX_PATH,
|
sys_wcstombs (buf, NT_MAX_PATH,
|
||||||
@ -3306,7 +3340,10 @@ cygwin_conv_path (cygwin_conv_path_t what, const void *from, void *to,
|
|||||||
PC_POSIX | PC_SYM_FOLLOW | PC_SYM_NOFOLLOW_REP
|
PC_POSIX | PC_SYM_FOLLOW | PC_SYM_NOFOLLOW_REP
|
||||||
| PC_NO_ACCESS_CHECK | PC_NOWARN | (relative ? PC_NOFULL : 0));
|
| PC_NO_ACCESS_CHECK | PC_NOWARN | (relative ? PC_NOFULL : 0));
|
||||||
if (p.error)
|
if (p.error)
|
||||||
return_with_errno (p.error);
|
{
|
||||||
|
set_errno (p.error);
|
||||||
|
__leave;
|
||||||
|
}
|
||||||
/* Relative Windows paths are always restricted to MAX_PATH chars. */
|
/* Relative Windows paths are always restricted to MAX_PATH chars. */
|
||||||
if (relative && !isabspath (p.get_win32 ())
|
if (relative && !isabspath (p.get_win32 ())
|
||||||
&& sys_mbstowcs (NULL, 0, p.get_win32 ()) > MAX_PATH)
|
&& sys_mbstowcs (NULL, 0, p.get_win32 ()) > MAX_PATH)
|
||||||
@ -3315,7 +3352,10 @@ cygwin_conv_path (cygwin_conv_path_t what, const void *from, void *to,
|
|||||||
p.check ((const char *) from, PC_POSIX | PC_SYM_FOLLOW
|
p.check ((const char *) from, PC_POSIX | PC_SYM_FOLLOW
|
||||||
| PC_NO_ACCESS_CHECK | PC_NOWARN);
|
| PC_NO_ACCESS_CHECK | PC_NOWARN);
|
||||||
if (p.error)
|
if (p.error)
|
||||||
return_with_errno (p.error);
|
{
|
||||||
|
set_errno (p.error);
|
||||||
|
__leave;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
lsiz = p.get_wide_win32_path_len () + 1;
|
lsiz = p.get_wide_win32_path_len () + 1;
|
||||||
path = p.get_nt_native_path ()->Buffer;
|
path = p.get_nt_native_path ()->Buffer;
|
||||||
@ -3362,7 +3402,10 @@ cygwin_conv_path (cygwin_conv_path_t what, const void *from, void *to,
|
|||||||
error = mount_table->conv_to_posix_path ((const char *) from, buf,
|
error = mount_table->conv_to_posix_path ((const char *) from, buf,
|
||||||
relative);
|
relative);
|
||||||
if (error)
|
if (error)
|
||||||
return_with_errno (error);
|
{
|
||||||
|
set_errno (p.error);
|
||||||
|
__leave;
|
||||||
|
}
|
||||||
lsiz = strlen (buf) + 1;
|
lsiz = strlen (buf) + 1;
|
||||||
break;
|
break;
|
||||||
case CCP_WIN_W_TO_POSIX:
|
case CCP_WIN_W_TO_POSIX:
|
||||||
@ -3370,19 +3413,25 @@ cygwin_conv_path (cygwin_conv_path_t what, const void *from, void *to,
|
|||||||
error = mount_table->conv_to_posix_path ((const PWCHAR) from, buf,
|
error = mount_table->conv_to_posix_path ((const PWCHAR) from, buf,
|
||||||
relative);
|
relative);
|
||||||
if (error)
|
if (error)
|
||||||
return_with_errno (error);
|
{
|
||||||
|
set_errno (error);
|
||||||
|
__leave;
|
||||||
|
}
|
||||||
lsiz = strlen (buf) + 1;
|
lsiz = strlen (buf) + 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return -1;
|
__leave;
|
||||||
}
|
}
|
||||||
if (!size)
|
if (!size)
|
||||||
return lsiz;
|
{
|
||||||
|
ret = lsiz;
|
||||||
|
__leave;
|
||||||
|
}
|
||||||
if (size < lsiz)
|
if (size < lsiz)
|
||||||
{
|
{
|
||||||
set_errno (ENOSPC);
|
set_errno (ENOSPC);
|
||||||
return -1;
|
__leave;
|
||||||
}
|
}
|
||||||
switch (what)
|
switch (what)
|
||||||
{
|
{
|
||||||
@ -3395,7 +3444,11 @@ cygwin_conv_path (cygwin_conv_path_t what, const void *from, void *to,
|
|||||||
wcpcpy ((PWCHAR) to, path);
|
wcpcpy ((PWCHAR) to, path);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
ret = 0;
|
||||||
|
}
|
||||||
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void *
|
extern "C" void *
|
||||||
@ -3454,6 +3507,9 @@ cygwin_conv_to_full_posix_path (const char *path, char *posix_path)
|
|||||||
extern "C" char *
|
extern "C" char *
|
||||||
realpath (const char *__restrict path, char *__restrict resolved)
|
realpath (const char *__restrict path, char *__restrict resolved)
|
||||||
{
|
{
|
||||||
|
tmp_pathbuf tp;
|
||||||
|
char *tpath;
|
||||||
|
|
||||||
/* Make sure the right errno is returned if path is NULL. */
|
/* Make sure the right errno is returned if path is NULL. */
|
||||||
if (!path)
|
if (!path)
|
||||||
{
|
{
|
||||||
@ -3463,15 +3519,11 @@ realpath (const char *__restrict path, char *__restrict resolved)
|
|||||||
|
|
||||||
/* Guard reading from a potentially invalid path and writing to a
|
/* Guard reading from a potentially invalid path and writing to a
|
||||||
potentially invalid resolved. */
|
potentially invalid resolved. */
|
||||||
tmp_pathbuf tp;
|
__try
|
||||||
myfault efault;
|
{
|
||||||
if (efault.faulted (EFAULT))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* Win32 drive letter paths have to be converted to a POSIX path first,
|
/* Win32 drive letter paths have to be converted to a POSIX path first,
|
||||||
because path_conv leaves the incoming path untouched except for
|
because path_conv leaves the incoming path untouched except for
|
||||||
converting backslashes to forward slashes. */
|
converting backslashes to forward slashes. */
|
||||||
char *tpath;
|
|
||||||
if (isdrive (path))
|
if (isdrive (path))
|
||||||
{
|
{
|
||||||
tpath = tp.c_get ();
|
tpath = tp.c_get ();
|
||||||
@ -3491,7 +3543,8 @@ realpath (const char *__restrict path, char *__restrict resolved)
|
|||||||
{
|
{
|
||||||
if (!resolved)
|
if (!resolved)
|
||||||
{
|
{
|
||||||
resolved = (char *) malloc (strlen (real_path.normalized_path) + 1);
|
resolved = (char *)
|
||||||
|
malloc (strlen (real_path.normalized_path) + 1);
|
||||||
if (!resolved)
|
if (!resolved)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -3505,6 +3558,9 @@ realpath (const char *__restrict path, char *__restrict resolved)
|
|||||||
if (resolved)
|
if (resolved)
|
||||||
resolved[0] = '\0';
|
resolved[0] = '\0';
|
||||||
set_errno (real_path.error ?: ENOENT);
|
set_errno (real_path.error ?: ENOENT);
|
||||||
|
}
|
||||||
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* poll.cc. Implements poll(2) via usage of select(2) call.
|
/* poll.cc. Implements poll(2) via usage of select(2) call.
|
||||||
|
|
||||||
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011,
|
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.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -143,9 +143,8 @@ ppoll (struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts,
|
|||||||
int timeout;
|
int timeout;
|
||||||
sigset_t oldset = _my_tls.sigmask;
|
sigset_t oldset = _my_tls.sigmask;
|
||||||
|
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EFAULT))
|
{
|
||||||
return -1;
|
|
||||||
timeout = (timeout_ts == NULL)
|
timeout = (timeout_ts == NULL)
|
||||||
? -1
|
? -1
|
||||||
: (timeout_ts->tv_sec * 1000 + timeout_ts->tv_nsec / 1000000);
|
: (timeout_ts->tv_sec * 1000 + timeout_ts->tv_nsec / 1000000);
|
||||||
@ -155,4 +154,8 @@ ppoll (struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts,
|
|||||||
if (sigmask)
|
if (sigmask)
|
||||||
set_signal_mask (_my_tls.sigmask, oldset);
|
set_signal_mask (_my_tls.sigmask, oldset);
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* posix_ipc.cc: POSIX IPC API for Cygwin.
|
/* posix_ipc.cc: POSIX IPC API for Cygwin.
|
||||||
|
|
||||||
Copyright 2007, 2008, 2009, 2010, 2011, 2012 Red Hat, Inc.
|
Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2014 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -414,17 +414,17 @@ extern "C" void *mmap64 (void *, size_t, int, int, int, off_t);
|
|||||||
extern "C" mqd_t
|
extern "C" mqd_t
|
||||||
mq_open (const char *name, int oflag, ...)
|
mq_open (const char *name, int oflag, ...)
|
||||||
{
|
{
|
||||||
int i, fd = -1, nonblock, created;
|
int i, fd = -1, nonblock, created = 0;
|
||||||
long msgsize, index;
|
long msgsize, index;
|
||||||
off_t filesize = 0;
|
off_t filesize = 0;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
mode_t mode;
|
mode_t mode;
|
||||||
int8_t *mptr;
|
int8_t *mptr = (int8_t *) MAP_FAILED;
|
||||||
struct stat statbuff;
|
struct stat statbuff;
|
||||||
struct mq_hdr *mqhdr;
|
struct mq_hdr *mqhdr;
|
||||||
struct msg_hdr *msghdr;
|
struct msg_hdr *msghdr;
|
||||||
struct mq_attr *attr;
|
struct mq_attr *attr;
|
||||||
struct mq_info *mqinfo;
|
struct mq_info *mqinfo = NULL;
|
||||||
LUID luid;
|
LUID luid;
|
||||||
|
|
||||||
size_t len = strlen (name);
|
size_t len = strlen (name);
|
||||||
@ -433,18 +433,13 @@ mq_open (const char *name, int oflag, ...)
|
|||||||
if (!check_path (mqname, mqueue, name, len))
|
if (!check_path (mqname, mqueue, name, len))
|
||||||
return (mqd_t) -1;
|
return (mqd_t) -1;
|
||||||
|
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EFAULT))
|
{
|
||||||
return (mqd_t) -1;
|
|
||||||
|
|
||||||
oflag &= (O_CREAT | O_EXCL | O_NONBLOCK);
|
oflag &= (O_CREAT | O_EXCL | O_NONBLOCK);
|
||||||
created = 0;
|
|
||||||
nonblock = oflag & O_NONBLOCK;
|
nonblock = oflag & O_NONBLOCK;
|
||||||
oflag &= ~O_NONBLOCK;
|
oflag &= ~O_NONBLOCK;
|
||||||
mptr = (int8_t *) MAP_FAILED;
|
|
||||||
mqinfo = NULL;
|
|
||||||
|
|
||||||
again:
|
again:
|
||||||
if (oflag & O_CREAT)
|
if (oflag & O_CREAT)
|
||||||
{
|
{
|
||||||
va_start (ap, oflag); /* init ap to final named argument */
|
va_start (ap, oflag); /* init ap to final named argument */
|
||||||
@ -453,7 +448,8 @@ again:
|
|||||||
va_end (ap);
|
va_end (ap);
|
||||||
|
|
||||||
/* Open and specify O_EXCL and user-execute */
|
/* Open and specify O_EXCL and user-execute */
|
||||||
fd = open (mqname, oflag | O_EXCL | O_RDWR | O_CLOEXEC, mode | S_IXUSR);
|
fd = open (mqname, oflag | O_EXCL | O_RDWR | O_CLOEXEC,
|
||||||
|
mode | S_IXUSR);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
if (errno == EEXIST && (oflag & O_EXCL) == 0)
|
if (errno == EEXIST && (oflag & O_EXCL) == 0)
|
||||||
@ -472,26 +468,28 @@ again:
|
|||||||
|| attr->mq_msgsize <= 0 || attr->mq_msgsize > 1048576)
|
|| attr->mq_msgsize <= 0 || attr->mq_msgsize > 1048576)
|
||||||
{
|
{
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
goto err;
|
__leave;
|
||||||
}
|
}
|
||||||
/* Calculate and set the file size */
|
/* Calculate and set the file size */
|
||||||
msgsize = MSGSIZE (attr->mq_msgsize);
|
msgsize = MSGSIZE (attr->mq_msgsize);
|
||||||
filesize = sizeof (struct mq_hdr)
|
filesize = sizeof (struct mq_hdr)
|
||||||
+ (attr->mq_maxmsg * (sizeof (struct msg_hdr) + msgsize));
|
+ (attr->mq_maxmsg * (sizeof (struct msg_hdr) + msgsize));
|
||||||
if (lseek64 (fd, filesize - 1, SEEK_SET) == -1)
|
if (lseek64 (fd, filesize - 1, SEEK_SET) == -1)
|
||||||
goto err;
|
__leave;
|
||||||
if (write (fd, "", 1) == -1)
|
if (write (fd, "", 1) == -1)
|
||||||
goto err;
|
__leave;
|
||||||
|
|
||||||
/* Memory map the file */
|
/* Memory map the file */
|
||||||
mptr = (int8_t *) mmap64 (NULL, (size_t) filesize, PROT_READ | PROT_WRITE,
|
mptr = (int8_t *) mmap64 (NULL, (size_t) filesize,
|
||||||
|
PROT_READ | PROT_WRITE,
|
||||||
MAP_SHARED, fd, 0);
|
MAP_SHARED, fd, 0);
|
||||||
if (mptr == (int8_t *) MAP_FAILED)
|
if (mptr == (int8_t *) MAP_FAILED)
|
||||||
goto err;
|
__leave;
|
||||||
|
|
||||||
/* Allocate one mq_info{} for the queue */
|
/* Allocate one mq_info{} for the queue */
|
||||||
if (!(mqinfo = (struct mq_info *) calloc (1, sizeof (struct mq_info))))
|
if (!(mqinfo = (struct mq_info *)
|
||||||
goto err;
|
calloc (1, sizeof (struct mq_info))))
|
||||||
|
__leave;
|
||||||
mqinfo->mqi_hdr = mqhdr = (struct mq_hdr *) mptr;
|
mqinfo->mqi_hdr = mqhdr = (struct mq_hdr *) mptr;
|
||||||
mqinfo->mqi_magic = MQI_MAGIC;
|
mqinfo->mqi_magic = MQI_MAGIC;
|
||||||
mqinfo->mqi_flags = nonblock;
|
mqinfo->mqi_flags = nonblock;
|
||||||
@ -524,30 +522,36 @@ again:
|
|||||||
/* Initialize mutex & condition variables */
|
/* Initialize mutex & condition variables */
|
||||||
i = ipc_mutex_init (&mqinfo->mqi_lock, mqhdr->mqh_uname);
|
i = ipc_mutex_init (&mqinfo->mqi_lock, mqhdr->mqh_uname);
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
goto pthreaderr;
|
{
|
||||||
|
set_errno (i);
|
||||||
|
__leave;
|
||||||
|
}
|
||||||
i = ipc_cond_init (&mqinfo->mqi_waitsend, mqhdr->mqh_uname, 'S');
|
i = ipc_cond_init (&mqinfo->mqi_waitsend, mqhdr->mqh_uname, 'S');
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
goto pthreaderr;
|
{
|
||||||
|
set_errno (i);
|
||||||
|
__leave;
|
||||||
|
}
|
||||||
i = ipc_cond_init (&mqinfo->mqi_waitrecv, mqhdr->mqh_uname, 'R');
|
i = ipc_cond_init (&mqinfo->mqi_waitrecv, mqhdr->mqh_uname, 'R');
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
goto pthreaderr;
|
{
|
||||||
|
set_errno (i);
|
||||||
|
__leave;
|
||||||
|
}
|
||||||
/* Initialization complete, turn off user-execute bit */
|
/* Initialization complete, turn off user-execute bit */
|
||||||
if (fchmod (fd, mode) == -1)
|
if (fchmod (fd, mode) == -1)
|
||||||
goto err;
|
__leave;
|
||||||
close (fd);
|
close (fd);
|
||||||
return ((mqd_t) mqinfo);
|
return ((mqd_t) mqinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
exists:
|
exists:
|
||||||
/* Open the file then memory map */
|
/* Open the file then memory map */
|
||||||
if ((fd = open (mqname, O_RDWR | O_CLOEXEC)) < 0)
|
if ((fd = open (mqname, O_RDWR | O_CLOEXEC)) < 0)
|
||||||
{
|
{
|
||||||
if (errno == ENOENT && (oflag & O_CREAT))
|
if (errno == ENOENT && (oflag & O_CREAT))
|
||||||
goto again;
|
goto again;
|
||||||
goto err;
|
__leave;
|
||||||
}
|
}
|
||||||
/* Make certain initialization is complete */
|
/* Make certain initialization is complete */
|
||||||
for (i = 0; i < MAX_TRIES; i++)
|
for (i = 0; i < MAX_TRIES; i++)
|
||||||
@ -560,7 +564,7 @@ exists:
|
|||||||
fd = -1;
|
fd = -1;
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
goto err;
|
__leave;
|
||||||
}
|
}
|
||||||
if ((statbuff.st_mode & S_IXUSR) == 0)
|
if ((statbuff.st_mode & S_IXUSR) == 0)
|
||||||
break;
|
break;
|
||||||
@ -569,29 +573,29 @@ exists:
|
|||||||
if (i == MAX_TRIES)
|
if (i == MAX_TRIES)
|
||||||
{
|
{
|
||||||
set_errno (ETIMEDOUT);
|
set_errno (ETIMEDOUT);
|
||||||
goto err;
|
__leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
filesize = statbuff.st_size;
|
filesize = statbuff.st_size;
|
||||||
mptr = (int8_t *) mmap64 (NULL, (size_t) filesize, PROT_READ | PROT_WRITE,
|
mptr = (int8_t *) mmap64 (NULL, (size_t) filesize, PROT_READ | PROT_WRITE,
|
||||||
MAP_SHARED, fd, 0);
|
MAP_SHARED, fd, 0);
|
||||||
if (mptr == (int8_t *) MAP_FAILED)
|
if (mptr == (int8_t *) MAP_FAILED)
|
||||||
goto err;
|
__leave;
|
||||||
close (fd);
|
close (fd);
|
||||||
fd = -1;
|
fd = -1;
|
||||||
|
|
||||||
/* Allocate one mq_info{} for each open */
|
/* Allocate one mq_info{} for each open */
|
||||||
if (!(mqinfo = (struct mq_info *) calloc (1, sizeof (struct mq_info))))
|
if (!(mqinfo = (struct mq_info *) calloc (1, sizeof (struct mq_info))))
|
||||||
goto err;
|
__leave;
|
||||||
mqinfo->mqi_hdr = mqhdr = (struct mq_hdr *) mptr;
|
mqinfo->mqi_hdr = mqhdr = (struct mq_hdr *) mptr;
|
||||||
if (mqhdr->mqh_magic != MQI_MAGIC)
|
if (mqhdr->mqh_magic != MQI_MAGIC)
|
||||||
{
|
{
|
||||||
system_printf (
|
system_printf (
|
||||||
"Old message queue \"%s\" detected!\n"
|
"Old message queue \"%s\" detected!\n"
|
||||||
"This file is not usable as message queue anymore due to changes in the "
|
"This file is not usable as message queue anymore due to changes in the "
|
||||||
"internal file layout. Please remove the file and try again.", mqname);
|
"internal file layout. Please remove the file and try again.", mqname);
|
||||||
set_errno (EACCES);
|
set_errno (EACCES);
|
||||||
goto err;
|
__leave;
|
||||||
}
|
}
|
||||||
mqinfo->mqi_magic = MQI_MAGIC;
|
mqinfo->mqi_magic = MQI_MAGIC;
|
||||||
mqinfo->mqi_flags = nonblock;
|
mqinfo->mqi_flags = nonblock;
|
||||||
@ -599,24 +603,28 @@ exists:
|
|||||||
/* Initialize mutex & condition variable */
|
/* Initialize mutex & condition variable */
|
||||||
i = ipc_mutex_init (&mqinfo->mqi_lock, mqhdr->mqh_uname);
|
i = ipc_mutex_init (&mqinfo->mqi_lock, mqhdr->mqh_uname);
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
goto pthreaderr;
|
{
|
||||||
|
set_errno (i);
|
||||||
|
__leave;
|
||||||
|
}
|
||||||
i = ipc_cond_init (&mqinfo->mqi_waitsend, mqhdr->mqh_uname, 'S');
|
i = ipc_cond_init (&mqinfo->mqi_waitsend, mqhdr->mqh_uname, 'S');
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
goto pthreaderr;
|
{
|
||||||
|
set_errno (i);
|
||||||
|
__leave;
|
||||||
|
}
|
||||||
i = ipc_cond_init (&mqinfo->mqi_waitrecv, mqhdr->mqh_uname, 'R');
|
i = ipc_cond_init (&mqinfo->mqi_waitrecv, mqhdr->mqh_uname, 'R');
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
goto pthreaderr;
|
{
|
||||||
|
set_errno (i);
|
||||||
|
__leave;
|
||||||
|
}
|
||||||
return (mqd_t) mqinfo;
|
return (mqd_t) mqinfo;
|
||||||
|
}
|
||||||
pthreaderr:
|
__except (EFAULT) {}
|
||||||
errno = i;
|
__endtry
|
||||||
err:
|
|
||||||
/* Don't let following function calls change errno */
|
/* Don't let following function calls change errno */
|
||||||
save_errno save;
|
save_errno save;
|
||||||
|
|
||||||
if (created)
|
if (created)
|
||||||
unlink (mqname);
|
unlink (mqname);
|
||||||
if (mptr != (int8_t *) MAP_FAILED)
|
if (mptr != (int8_t *) MAP_FAILED)
|
||||||
@ -644,22 +652,20 @@ mq_getattr (mqd_t mqd, struct mq_attr *mqstat)
|
|||||||
struct mq_fattr *attr;
|
struct mq_fattr *attr;
|
||||||
struct mq_info *mqinfo;
|
struct mq_info *mqinfo;
|
||||||
|
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EBADF))
|
{
|
||||||
return -1;
|
|
||||||
|
|
||||||
mqinfo = (struct mq_info *) mqd;
|
mqinfo = (struct mq_info *) mqd;
|
||||||
if (mqinfo->mqi_magic != MQI_MAGIC)
|
if (mqinfo->mqi_magic != MQI_MAGIC)
|
||||||
{
|
{
|
||||||
set_errno (EBADF);
|
set_errno (EBADF);
|
||||||
return -1;
|
__leave;
|
||||||
}
|
}
|
||||||
mqhdr = mqinfo->mqi_hdr;
|
mqhdr = mqinfo->mqi_hdr;
|
||||||
attr = &mqhdr->mqh_attr;
|
attr = &mqhdr->mqh_attr;
|
||||||
if ((n = ipc_mutex_lock (mqinfo->mqi_lock)) != 0)
|
if ((n = ipc_mutex_lock (mqinfo->mqi_lock)) != 0)
|
||||||
{
|
{
|
||||||
errno = n;
|
errno = n;
|
||||||
return -1;
|
__leave;
|
||||||
}
|
}
|
||||||
mqstat->mq_flags = mqinfo->mqi_flags; /* per-open */
|
mqstat->mq_flags = mqinfo->mqi_flags; /* per-open */
|
||||||
mqstat->mq_maxmsg = attr->mq_maxmsg; /* remaining three per-queue */
|
mqstat->mq_maxmsg = attr->mq_maxmsg; /* remaining three per-queue */
|
||||||
@ -668,6 +674,10 @@ mq_getattr (mqd_t mqd, struct mq_attr *mqstat)
|
|||||||
|
|
||||||
ipc_mutex_unlock (mqinfo->mqi_lock);
|
ipc_mutex_unlock (mqinfo->mqi_lock);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
__except (EBADF) {}
|
||||||
|
__endtry
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int
|
extern "C" int
|
||||||
@ -678,22 +688,20 @@ mq_setattr (mqd_t mqd, const struct mq_attr *mqstat, struct mq_attr *omqstat)
|
|||||||
struct mq_fattr *attr;
|
struct mq_fattr *attr;
|
||||||
struct mq_info *mqinfo;
|
struct mq_info *mqinfo;
|
||||||
|
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EBADF))
|
{
|
||||||
return -1;
|
|
||||||
|
|
||||||
mqinfo = (struct mq_info *) mqd;
|
mqinfo = (struct mq_info *) mqd;
|
||||||
if (mqinfo->mqi_magic != MQI_MAGIC)
|
if (mqinfo->mqi_magic != MQI_MAGIC)
|
||||||
{
|
{
|
||||||
set_errno (EBADF);
|
set_errno (EBADF);
|
||||||
return -1;
|
__leave;
|
||||||
}
|
}
|
||||||
mqhdr = mqinfo->mqi_hdr;
|
mqhdr = mqinfo->mqi_hdr;
|
||||||
attr = &mqhdr->mqh_attr;
|
attr = &mqhdr->mqh_attr;
|
||||||
if ((n = ipc_mutex_lock (mqinfo->mqi_lock)) != 0)
|
if ((n = ipc_mutex_lock (mqinfo->mqi_lock)) != 0)
|
||||||
{
|
{
|
||||||
errno = n;
|
errno = n;
|
||||||
return -1;
|
__leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (omqstat != NULL)
|
if (omqstat != NULL)
|
||||||
@ -711,6 +719,10 @@ mq_setattr (mqd_t mqd, const struct mq_attr *mqstat, struct mq_attr *omqstat)
|
|||||||
|
|
||||||
ipc_mutex_unlock (mqinfo->mqi_lock);
|
ipc_mutex_unlock (mqinfo->mqi_lock);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
__except (EBADF) {}
|
||||||
|
__endtry
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int
|
extern "C" int
|
||||||
@ -721,21 +733,19 @@ mq_notify (mqd_t mqd, const struct sigevent *notification)
|
|||||||
struct mq_hdr *mqhdr;
|
struct mq_hdr *mqhdr;
|
||||||
struct mq_info *mqinfo;
|
struct mq_info *mqinfo;
|
||||||
|
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EBADF))
|
{
|
||||||
return -1;
|
|
||||||
|
|
||||||
mqinfo = (struct mq_info *) mqd;
|
mqinfo = (struct mq_info *) mqd;
|
||||||
if (mqinfo->mqi_magic != MQI_MAGIC)
|
if (mqinfo->mqi_magic != MQI_MAGIC)
|
||||||
{
|
{
|
||||||
set_errno (EBADF);
|
set_errno (EBADF);
|
||||||
return -1;
|
__leave;
|
||||||
}
|
}
|
||||||
mqhdr = mqinfo->mqi_hdr;
|
mqhdr = mqinfo->mqi_hdr;
|
||||||
if ((n = ipc_mutex_lock (mqinfo->mqi_lock)) != 0)
|
if ((n = ipc_mutex_lock (mqinfo->mqi_lock)) != 0)
|
||||||
{
|
{
|
||||||
errno = n;
|
errno = n;
|
||||||
return -1;
|
__leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
pid = getpid ();
|
pid = getpid ();
|
||||||
@ -752,7 +762,7 @@ mq_notify (mqd_t mqd, const struct sigevent *notification)
|
|||||||
{
|
{
|
||||||
set_errno (EBUSY);
|
set_errno (EBUSY);
|
||||||
ipc_mutex_unlock (mqinfo->mqi_lock);
|
ipc_mutex_unlock (mqinfo->mqi_lock);
|
||||||
return -1;
|
__leave;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mqhdr->mqh_pid = pid;
|
mqhdr->mqh_pid = pid;
|
||||||
@ -760,6 +770,10 @@ mq_notify (mqd_t mqd, const struct sigevent *notification)
|
|||||||
}
|
}
|
||||||
ipc_mutex_unlock (mqinfo->mqi_lock);
|
ipc_mutex_unlock (mqinfo->mqi_lock);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
__except (EBADF) {}
|
||||||
|
__endtry
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -773,24 +787,24 @@ _mq_send (mqd_t mqd, const char *ptr, size_t len, unsigned int prio,
|
|||||||
struct mq_hdr *mqhdr;
|
struct mq_hdr *mqhdr;
|
||||||
struct mq_fattr *attr;
|
struct mq_fattr *attr;
|
||||||
struct msg_hdr *msghdr, *nmsghdr, *pmsghdr;
|
struct msg_hdr *msghdr, *nmsghdr, *pmsghdr;
|
||||||
struct mq_info *mqinfo;
|
struct mq_info *mqinfo = NULL;
|
||||||
|
bool ipc_mutex_locked = false;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
pthread_testcancel ();
|
pthread_testcancel ();
|
||||||
|
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EBADF))
|
{
|
||||||
return -1;
|
|
||||||
|
|
||||||
mqinfo = (struct mq_info *) mqd;
|
mqinfo = (struct mq_info *) mqd;
|
||||||
if (mqinfo->mqi_magic != MQI_MAGIC)
|
if (mqinfo->mqi_magic != MQI_MAGIC)
|
||||||
{
|
{
|
||||||
set_errno (EBADF);
|
set_errno (EBADF);
|
||||||
return -1;
|
__leave;
|
||||||
}
|
}
|
||||||
if (prio > MQ_PRIO_MAX)
|
if (prio > MQ_PRIO_MAX)
|
||||||
{
|
{
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return -1;
|
__leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
mqhdr = mqinfo->mqi_hdr; /* struct pointer */
|
mqhdr = mqinfo->mqi_hdr; /* struct pointer */
|
||||||
@ -799,13 +813,13 @@ _mq_send (mqd_t mqd, const char *ptr, size_t len, unsigned int prio,
|
|||||||
if ((n = ipc_mutex_lock (mqinfo->mqi_lock)) != 0)
|
if ((n = ipc_mutex_lock (mqinfo->mqi_lock)) != 0)
|
||||||
{
|
{
|
||||||
errno = n;
|
errno = n;
|
||||||
return -1;
|
__leave;
|
||||||
}
|
}
|
||||||
|
ipc_mutex_locked = true;
|
||||||
if (len > (size_t) attr->mq_msgsize)
|
if (len > (size_t) attr->mq_msgsize)
|
||||||
{
|
{
|
||||||
set_errno (EMSGSIZE);
|
set_errno (EMSGSIZE);
|
||||||
goto err;
|
__leave;
|
||||||
}
|
}
|
||||||
if (attr->mq_curmsgs == 0)
|
if (attr->mq_curmsgs == 0)
|
||||||
{
|
{
|
||||||
@ -813,7 +827,8 @@ _mq_send (mqd_t mqd, const char *ptr, size_t len, unsigned int prio,
|
|||||||
{
|
{
|
||||||
sigev = &mqhdr->mqh_event;
|
sigev = &mqhdr->mqh_event;
|
||||||
if (sigev->sigev_notify == SIGEV_SIGNAL)
|
if (sigev->sigev_notify == SIGEV_SIGNAL)
|
||||||
sigqueue (mqhdr->mqh_pid, sigev->sigev_signo, sigev->sigev_value);
|
sigqueue (mqhdr->mqh_pid, sigev->sigev_signo,
|
||||||
|
sigev->sigev_value);
|
||||||
mqhdr->mqh_pid = 0; /* unregister */
|
mqhdr->mqh_pid = 0; /* unregister */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -823,17 +838,17 @@ _mq_send (mqd_t mqd, const char *ptr, size_t len, unsigned int prio,
|
|||||||
if (mqinfo->mqi_flags & O_NONBLOCK)
|
if (mqinfo->mqi_flags & O_NONBLOCK)
|
||||||
{
|
{
|
||||||
set_errno (EAGAIN);
|
set_errno (EAGAIN);
|
||||||
goto err;
|
__leave;
|
||||||
}
|
}
|
||||||
/* Wait for room for one message on the queue */
|
/* Wait for room for one message on the queue */
|
||||||
while (attr->mq_curmsgs >= attr->mq_maxmsg)
|
while (attr->mq_curmsgs >= attr->mq_maxmsg)
|
||||||
{
|
{
|
||||||
int ret = ipc_cond_timedwait (mqinfo->mqi_waitsend, mqinfo->mqi_lock,
|
int ret = ipc_cond_timedwait (mqinfo->mqi_waitsend,
|
||||||
abstime);
|
mqinfo->mqi_lock, abstime);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
{
|
{
|
||||||
set_errno (ret);
|
set_errno (ret);
|
||||||
return -1;
|
__leave;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -875,11 +890,13 @@ _mq_send (mqd_t mqd, const char *ptr, size_t len, unsigned int prio,
|
|||||||
attr->mq_curmsgs++;
|
attr->mq_curmsgs++;
|
||||||
|
|
||||||
ipc_mutex_unlock (mqinfo->mqi_lock);
|
ipc_mutex_unlock (mqinfo->mqi_lock);
|
||||||
return 0;
|
ret = 0;
|
||||||
|
}
|
||||||
err:
|
__except (EBADF) {}
|
||||||
|
__endtry
|
||||||
|
if (ipc_mutex_locked)
|
||||||
ipc_mutex_unlock (mqinfo->mqi_lock);
|
ipc_mutex_unlock (mqinfo->mqi_lock);
|
||||||
return -1;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int
|
extern "C" int
|
||||||
@ -902,23 +919,21 @@ _mq_receive (mqd_t mqd, char *ptr, size_t maxlen, unsigned int *priop,
|
|||||||
int n;
|
int n;
|
||||||
long index;
|
long index;
|
||||||
int8_t *mptr;
|
int8_t *mptr;
|
||||||
ssize_t len;
|
ssize_t len = -1;
|
||||||
struct mq_hdr *mqhdr;
|
struct mq_hdr *mqhdr;
|
||||||
struct mq_fattr *attr;
|
struct mq_fattr *attr;
|
||||||
struct msg_hdr *msghdr;
|
struct msg_hdr *msghdr;
|
||||||
struct mq_info *mqinfo;
|
struct mq_info *mqinfo = (struct mq_info *) mqd;
|
||||||
|
bool ipc_mutex_locked = false;
|
||||||
|
|
||||||
pthread_testcancel ();
|
pthread_testcancel ();
|
||||||
|
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EBADF))
|
{
|
||||||
return -1;
|
|
||||||
|
|
||||||
mqinfo = (struct mq_info *) mqd;
|
|
||||||
if (mqinfo->mqi_magic != MQI_MAGIC)
|
if (mqinfo->mqi_magic != MQI_MAGIC)
|
||||||
{
|
{
|
||||||
set_errno (EBADF);
|
set_errno (EBADF);
|
||||||
return -1;
|
__leave;
|
||||||
}
|
}
|
||||||
mqhdr = mqinfo->mqi_hdr; /* struct pointer */
|
mqhdr = mqinfo->mqi_hdr; /* struct pointer */
|
||||||
mptr = (int8_t *) mqhdr; /* byte pointer */
|
mptr = (int8_t *) mqhdr; /* byte pointer */
|
||||||
@ -926,31 +941,31 @@ _mq_receive (mqd_t mqd, char *ptr, size_t maxlen, unsigned int *priop,
|
|||||||
if ((n = ipc_mutex_lock (mqinfo->mqi_lock)) != 0)
|
if ((n = ipc_mutex_lock (mqinfo->mqi_lock)) != 0)
|
||||||
{
|
{
|
||||||
errno = n;
|
errno = n;
|
||||||
return -1;
|
__leave;
|
||||||
}
|
}
|
||||||
|
ipc_mutex_locked = true;
|
||||||
if (maxlen < (size_t) attr->mq_msgsize)
|
if (maxlen < (size_t) attr->mq_msgsize)
|
||||||
{
|
{
|
||||||
set_errno (EMSGSIZE);
|
set_errno (EMSGSIZE);
|
||||||
goto err;
|
__leave;
|
||||||
}
|
}
|
||||||
if (attr->mq_curmsgs == 0) /* queue is empty */
|
if (attr->mq_curmsgs == 0) /* queue is empty */
|
||||||
{
|
{
|
||||||
if (mqinfo->mqi_flags & O_NONBLOCK)
|
if (mqinfo->mqi_flags & O_NONBLOCK)
|
||||||
{
|
{
|
||||||
set_errno (EAGAIN);
|
set_errno (EAGAIN);
|
||||||
goto err;
|
__leave;
|
||||||
}
|
}
|
||||||
/* Wait for a message to be placed onto queue */
|
/* Wait for a message to be placed onto queue */
|
||||||
mqhdr->mqh_nwait++;
|
mqhdr->mqh_nwait++;
|
||||||
while (attr->mq_curmsgs == 0)
|
while (attr->mq_curmsgs == 0)
|
||||||
{
|
{
|
||||||
int ret = ipc_cond_timedwait (mqinfo->mqi_waitrecv, mqinfo->mqi_lock,
|
int ret = ipc_cond_timedwait (mqinfo->mqi_waitrecv,
|
||||||
abstime);
|
mqinfo->mqi_lock, abstime);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
{
|
{
|
||||||
set_errno (ret);
|
set_errno (ret);
|
||||||
return -1;
|
__leave;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mqhdr->mqh_nwait--;
|
mqhdr->mqh_nwait--;
|
||||||
@ -976,11 +991,12 @@ _mq_receive (mqd_t mqd, char *ptr, size_t maxlen, unsigned int *priop,
|
|||||||
attr->mq_curmsgs--;
|
attr->mq_curmsgs--;
|
||||||
|
|
||||||
ipc_mutex_unlock (mqinfo->mqi_lock);
|
ipc_mutex_unlock (mqinfo->mqi_lock);
|
||||||
return len;
|
}
|
||||||
|
__except (EBADF) {}
|
||||||
err:
|
__endtry
|
||||||
|
if (ipc_mutex_locked)
|
||||||
ipc_mutex_unlock (mqinfo->mqi_lock);
|
ipc_mutex_unlock (mqinfo->mqi_lock);
|
||||||
return -1;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" ssize_t
|
extern "C" ssize_t
|
||||||
@ -1004,27 +1020,25 @@ mq_close (mqd_t mqd)
|
|||||||
struct mq_fattr *attr;
|
struct mq_fattr *attr;
|
||||||
struct mq_info *mqinfo;
|
struct mq_info *mqinfo;
|
||||||
|
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EBADF))
|
{
|
||||||
return -1;
|
|
||||||
|
|
||||||
mqinfo = (struct mq_info *) mqd;
|
mqinfo = (struct mq_info *) mqd;
|
||||||
if (mqinfo->mqi_magic != MQI_MAGIC)
|
if (mqinfo->mqi_magic != MQI_MAGIC)
|
||||||
{
|
{
|
||||||
set_errno (EBADF);
|
set_errno (EBADF);
|
||||||
return -1;
|
__leave;
|
||||||
}
|
}
|
||||||
mqhdr = mqinfo->mqi_hdr;
|
mqhdr = mqinfo->mqi_hdr;
|
||||||
attr = &mqhdr->mqh_attr;
|
attr = &mqhdr->mqh_attr;
|
||||||
|
|
||||||
if (mq_notify (mqd, NULL)) /* unregister calling process */
|
if (mq_notify (mqd, NULL)) /* unregister calling process */
|
||||||
return -1;
|
__leave;
|
||||||
|
|
||||||
msgsize = MSGSIZE (attr->mq_msgsize);
|
msgsize = MSGSIZE (attr->mq_msgsize);
|
||||||
filesize = sizeof (struct mq_hdr)
|
filesize = sizeof (struct mq_hdr)
|
||||||
+ (attr->mq_maxmsg * (sizeof (struct msg_hdr) + msgsize));
|
+ (attr->mq_maxmsg * (sizeof (struct msg_hdr) + msgsize));
|
||||||
if (munmap (mqinfo->mqi_hdr, filesize) == -1)
|
if (munmap (mqinfo->mqi_hdr, filesize) == -1)
|
||||||
return -1;
|
__leave;
|
||||||
|
|
||||||
mqinfo->mqi_magic = 0; /* just in case */
|
mqinfo->mqi_magic = 0; /* just in case */
|
||||||
ipc_cond_close (mqinfo->mqi_waitsend);
|
ipc_cond_close (mqinfo->mqi_waitsend);
|
||||||
@ -1032,6 +1046,10 @@ mq_close (mqd_t mqd)
|
|||||||
ipc_mutex_close (mqinfo->mqi_lock);
|
ipc_mutex_close (mqinfo->mqi_lock);
|
||||||
free (mqinfo);
|
free (mqinfo);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
__except (EBADF) {}
|
||||||
|
__endtry
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int
|
extern "C" int
|
||||||
@ -1062,7 +1080,7 @@ struct sem_finfo
|
|||||||
extern "C" sem_t *
|
extern "C" sem_t *
|
||||||
sem_open (const char *name, int oflag, ...)
|
sem_open (const char *name, int oflag, ...)
|
||||||
{
|
{
|
||||||
int i, fd = -1, created;
|
int i, fd = -1, created = 0;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
mode_t mode = 0;
|
mode_t mode = 0;
|
||||||
unsigned int value = 0;
|
unsigned int value = 0;
|
||||||
@ -1078,14 +1096,11 @@ sem_open (const char *name, int oflag, ...)
|
|||||||
if (!check_path (semname, semaphore, name, len))
|
if (!check_path (semname, semaphore, name, len))
|
||||||
return SEM_FAILED;
|
return SEM_FAILED;
|
||||||
|
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EFAULT))
|
{
|
||||||
return SEM_FAILED;
|
|
||||||
|
|
||||||
created = 0;
|
|
||||||
oflag &= (O_CREAT | O_EXCL);
|
oflag &= (O_CREAT | O_EXCL);
|
||||||
|
|
||||||
again:
|
again:
|
||||||
if (oflag & O_CREAT)
|
if (oflag & O_CREAT)
|
||||||
{
|
{
|
||||||
va_start (ap, oflag); /* init ap to final named argument */
|
va_start (ap, oflag); /* init ap to final named argument */
|
||||||
@ -1094,7 +1109,8 @@ again:
|
|||||||
va_end (ap);
|
va_end (ap);
|
||||||
|
|
||||||
/* Open and specify O_EXCL and user-execute */
|
/* Open and specify O_EXCL and user-execute */
|
||||||
fd = open (semname, oflag | O_EXCL | O_RDWR | O_CLOEXEC, mode | S_IXUSR);
|
fd = open (semname, oflag | O_EXCL | O_RDWR | O_CLOEXEC,
|
||||||
|
mode | S_IXUSR);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
if (errno == EEXIST && (oflag & O_EXCL) == 0)
|
if (errno == EEXIST && (oflag & O_EXCL) == 0)
|
||||||
@ -1107,24 +1123,25 @@ again:
|
|||||||
sf.value = value;
|
sf.value = value;
|
||||||
sf.hash = hash_path_name (0, semname);
|
sf.hash = hash_path_name (0, semname);
|
||||||
if (write (fd, &sf, sizeof sf) != sizeof sf)
|
if (write (fd, &sf, sizeof sf) != sizeof sf)
|
||||||
goto err;
|
__leave;
|
||||||
sem = semaphore::open (sf.hash, sf.luid, fd, oflag, mode, value, wasopen);
|
sem = semaphore::open (sf.hash, sf.luid, fd, oflag, mode, value,
|
||||||
|
wasopen);
|
||||||
if (sem == SEM_FAILED)
|
if (sem == SEM_FAILED)
|
||||||
goto err;
|
__leave;
|
||||||
/* Initialization complete, turn off user-execute bit */
|
/* Initialization complete, turn off user-execute bit */
|
||||||
if (fchmod (fd, mode) == -1)
|
if (fchmod (fd, mode) == -1)
|
||||||
goto err;
|
__leave;
|
||||||
/* Don't close (fd); */
|
/* Don't close (fd); */
|
||||||
return sem;
|
return sem;
|
||||||
}
|
}
|
||||||
|
|
||||||
exists:
|
exists:
|
||||||
/* Open the file and fetch the semaphore name. */
|
/* Open the file and fetch the semaphore name. */
|
||||||
if ((fd = open (semname, O_RDWR | O_CLOEXEC)) < 0)
|
if ((fd = open (semname, O_RDWR | O_CLOEXEC)) < 0)
|
||||||
{
|
{
|
||||||
if (errno == ENOENT && (oflag & O_CREAT))
|
if (errno == ENOENT && (oflag & O_CREAT))
|
||||||
goto again;
|
goto again;
|
||||||
goto err;
|
__leave;
|
||||||
}
|
}
|
||||||
/* Make certain initialization is complete */
|
/* Make certain initialization is complete */
|
||||||
for (i = 0; i < MAX_TRIES; i++)
|
for (i = 0; i < MAX_TRIES; i++)
|
||||||
@ -1137,7 +1154,7 @@ exists:
|
|||||||
fd = -1;
|
fd = -1;
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
goto err;
|
__leave;
|
||||||
}
|
}
|
||||||
if ((statbuff.st_mode & S_IXUSR) == 0)
|
if ((statbuff.st_mode & S_IXUSR) == 0)
|
||||||
break;
|
break;
|
||||||
@ -1146,16 +1163,17 @@ exists:
|
|||||||
if (i == MAX_TRIES)
|
if (i == MAX_TRIES)
|
||||||
{
|
{
|
||||||
set_errno (ETIMEDOUT);
|
set_errno (ETIMEDOUT);
|
||||||
goto err;
|
__leave;
|
||||||
}
|
}
|
||||||
if (file.lock (fd, sizeof sf))
|
if (file.lock (fd, sizeof sf))
|
||||||
goto err;
|
__leave;
|
||||||
if (read (fd, &sf, sizeof sf) != sizeof sf)
|
if (read (fd, &sf, sizeof sf) != sizeof sf)
|
||||||
goto err;
|
__leave;
|
||||||
sem = semaphore::open (sf.hash, sf.luid, fd, oflag, mode, sf.value, wasopen);
|
sem = semaphore::open (sf.hash, sf.luid, fd, oflag, mode, sf.value,
|
||||||
|
wasopen);
|
||||||
file.unlock (fd);
|
file.unlock (fd);
|
||||||
if (sem == SEM_FAILED)
|
if (sem == SEM_FAILED)
|
||||||
goto err;
|
__leave;
|
||||||
/* If wasopen is set, the semaphore was already opened and we already have
|
/* If wasopen is set, the semaphore was already opened and we already have
|
||||||
an open file descriptor pointing to the file. This means, we have to
|
an open file descriptor pointing to the file. This means, we have to
|
||||||
close the file descriptor created in this call. It won't be stored
|
close the file descriptor created in this call. It won't be stored
|
||||||
@ -1163,11 +1181,13 @@ exists:
|
|||||||
if (wasopen)
|
if (wasopen)
|
||||||
close (fd);
|
close (fd);
|
||||||
return sem;
|
return sem;
|
||||||
|
}
|
||||||
err:
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
/* Don't let following function calls change errno */
|
/* Don't let following function calls change errno */
|
||||||
save_errno save;
|
save_errno save;
|
||||||
|
|
||||||
|
if (fd >= 0)
|
||||||
file.unlock (fd);
|
file.unlock (fd);
|
||||||
if (created)
|
if (created)
|
||||||
unlink (semname);
|
unlink (semname);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* resource.cc: getrusage () and friends.
|
/* resource.cc: getrusage () and friends.
|
||||||
|
|
||||||
Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2005, 2008, 2009, 2010,
|
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),
|
Written by Steve Chamberlain (sac@cygnus.com), Doug Evans (dje@cygnus.com),
|
||||||
Geoffrey Noer (noer@cygnus.com) of Cygnus Support.
|
Geoffrey Noer (noer@cygnus.com) of Cygnus Support.
|
||||||
@ -116,10 +116,8 @@ getrlimit (int resource, struct rlimit *rlp)
|
|||||||
{
|
{
|
||||||
MEMORY_BASIC_INFORMATION m;
|
MEMORY_BASIC_INFORMATION m;
|
||||||
|
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EFAULT))
|
{
|
||||||
return -1;
|
|
||||||
|
|
||||||
rlp->rlim_cur = RLIM_INFINITY;
|
rlp->rlim_cur = RLIM_INFINITY;
|
||||||
rlp->rlim_max = RLIM_INFINITY;
|
rlp->rlim_max = RLIM_INFINITY;
|
||||||
|
|
||||||
@ -151,18 +149,18 @@ getrlimit (int resource, struct rlimit *rlp)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return -1;
|
__leave;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int
|
extern "C" int
|
||||||
setrlimit (int resource, const struct rlimit *rlp)
|
setrlimit (int resource, const struct rlimit *rlp)
|
||||||
{
|
{
|
||||||
myfault efault;
|
|
||||||
if (efault.faulted (EFAULT))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
struct rlimit oldlimits;
|
struct rlimit oldlimits;
|
||||||
|
|
||||||
/* Check if the request is to actually change the resource settings.
|
/* Check if the request is to actually change the resource settings.
|
||||||
@ -170,6 +168,8 @@ setrlimit (int resource, const struct rlimit *rlp)
|
|||||||
if (getrlimit (resource, &oldlimits) < 0)
|
if (getrlimit (resource, &oldlimits) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
__try
|
||||||
|
{
|
||||||
if (oldlimits.rlim_cur == rlp->rlim_cur &&
|
if (oldlimits.rlim_cur == rlp->rlim_cur &&
|
||||||
oldlimits.rlim_max == rlp->rlim_max)
|
oldlimits.rlim_max == rlp->rlim_max)
|
||||||
/* No change in resource requirements, succeed immediately */
|
/* No change in resource requirements, succeed immediately */
|
||||||
@ -178,7 +178,7 @@ setrlimit (int resource, const struct rlimit *rlp)
|
|||||||
if (rlp->rlim_cur > rlp->rlim_max)
|
if (rlp->rlim_cur > rlp->rlim_max)
|
||||||
{
|
{
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return -1;
|
__leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (resource)
|
switch (resource)
|
||||||
@ -192,7 +192,11 @@ setrlimit (int resource, const struct rlimit *rlp)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return -1;
|
__leave;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
__except (EFAULT)
|
||||||
|
__endtry
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* select.cc
|
/* select.cc
|
||||||
|
|
||||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
||||||
2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -230,9 +230,8 @@ pselect(int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
|||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
sigset_t oldset = _my_tls.sigmask;
|
sigset_t oldset = _my_tls.sigmask;
|
||||||
|
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EFAULT))
|
{
|
||||||
return -1;
|
|
||||||
if (ts)
|
if (ts)
|
||||||
{
|
{
|
||||||
tv.tv_sec = ts->tv_sec;
|
tv.tv_sec = ts->tv_sec;
|
||||||
@ -245,6 +244,10 @@ pselect(int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
|||||||
if (set)
|
if (set)
|
||||||
set_signal_mask (_my_tls.sigmask, oldset);
|
set_signal_mask (_my_tls.sigmask, oldset);
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Call cleanup functions for all inspected fds. Gets rid of any
|
/* Call cleanup functions for all inspected fds. Gets rid of any
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* sem.cc: XSI IPC interface for Cygwin.
|
/* 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.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -85,9 +85,8 @@ semctl (int semid, int semnum, int cmd, ...)
|
|||||||
}
|
}
|
||||||
syscall_printf ("semctl (semid = %d, semnum = %d, cmd = %d, arg = %p)",
|
syscall_printf ("semctl (semid = %d, semnum = %d, cmd = %d, arg = %p)",
|
||||||
semid, semnum, cmd, arg.buf);
|
semid, semnum, cmd, arg.buf);
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EFAULT))
|
{
|
||||||
return -1;
|
|
||||||
client_request_sem request (semid, semnum, cmd, &arg);
|
client_request_sem request (semid, semnum, cmd, &arg);
|
||||||
if (request.make_request () == -1 || request.retval () == -1)
|
if (request.make_request () == -1 || request.retval () == -1)
|
||||||
{
|
{
|
||||||
@ -95,9 +94,13 @@ semctl (int semid, int semnum, int cmd, ...)
|
|||||||
set_errno (request.error_code ());
|
set_errno (request.error_code ());
|
||||||
if (request.error_code () == ENOSYS)
|
if (request.error_code () == ENOSYS)
|
||||||
raise (SIGSYS);
|
raise (SIGSYS);
|
||||||
return -1;
|
__leave;
|
||||||
}
|
}
|
||||||
return request.retval ();
|
return request.retval ();
|
||||||
|
}
|
||||||
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int
|
extern "C" int
|
||||||
@ -122,9 +125,8 @@ semop (int semid, struct sembuf *sops, size_t nsops)
|
|||||||
{
|
{
|
||||||
syscall_printf ("semop (semid = %d, sops = %p, nsops = %ld)",
|
syscall_printf ("semop (semid = %d, sops = %p, nsops = %ld)",
|
||||||
semid, sops, nsops);
|
semid, sops, nsops);
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EFAULT))
|
{
|
||||||
return -1;
|
|
||||||
client_request_sem request (semid, sops, nsops);
|
client_request_sem request (semid, sops, nsops);
|
||||||
if (request.make_request () == -1 || request.retval () == -1)
|
if (request.make_request () == -1 || request.retval () == -1)
|
||||||
{
|
{
|
||||||
@ -132,7 +134,11 @@ semop (int semid, struct sembuf *sops, size_t nsops)
|
|||||||
set_errno (request.error_code ());
|
set_errno (request.error_code ());
|
||||||
if (request.error_code () == ENOSYS)
|
if (request.error_code () == ENOSYS)
|
||||||
raise (SIGSYS);
|
raise (SIGSYS);
|
||||||
return -1;
|
__leave;
|
||||||
}
|
}
|
||||||
return request.retval ();
|
return request.retval ();
|
||||||
|
}
|
||||||
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -260,9 +260,8 @@ shmctl (int shmid, int cmd, struct shmid_ds *buf)
|
|||||||
{
|
{
|
||||||
syscall_printf ("shmctl (shmid = %d, cmd = %d, buf = %p)",
|
syscall_printf ("shmctl (shmid = %d, cmd = %d, buf = %p)",
|
||||||
shmid, cmd, buf);
|
shmid, cmd, buf);
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EFAULT))
|
{
|
||||||
return -1;
|
|
||||||
client_request_shm request (shmid, cmd, buf);
|
client_request_shm request (shmid, cmd, buf);
|
||||||
if (request.make_request () == -1 || request.retval () == -1)
|
if (request.make_request () == -1 || request.retval () == -1)
|
||||||
{
|
{
|
||||||
@ -270,7 +269,7 @@ shmctl (int shmid, int cmd, struct shmid_ds *buf)
|
|||||||
set_errno (request.error_code ());
|
set_errno (request.error_code ());
|
||||||
if (request.error_code () == ENOSYS)
|
if (request.error_code () == ENOSYS)
|
||||||
raise (SIGSYS);
|
raise (SIGSYS);
|
||||||
return -1;
|
__leave;
|
||||||
}
|
}
|
||||||
if (cmd == IPC_RMID)
|
if (cmd == IPC_RMID)
|
||||||
{
|
{
|
||||||
@ -285,7 +284,8 @@ shmctl (int shmid, int cmd, struct shmid_ds *buf)
|
|||||||
only if it's not in use anymore. */
|
only if it's not in use anymore. */
|
||||||
if (ssh_entry->ref_count <= 0)
|
if (ssh_entry->ref_count <= 0)
|
||||||
{
|
{
|
||||||
SLIST_REMOVE (&ssh_list, ssh_entry, shm_shmid_list, ssh_next);
|
SLIST_REMOVE (&ssh_list, ssh_entry, shm_shmid_list,
|
||||||
|
ssh_next);
|
||||||
CloseHandle (ssh_entry->hdl);
|
CloseHandle (ssh_entry->hdl);
|
||||||
delete ssh_entry;
|
delete ssh_entry;
|
||||||
}
|
}
|
||||||
@ -295,6 +295,10 @@ shmctl (int shmid, int cmd, struct shmid_ds *buf)
|
|||||||
SLIST_UNLOCK ();
|
SLIST_UNLOCK ();
|
||||||
}
|
}
|
||||||
return request.retval ();
|
return request.retval ();
|
||||||
|
}
|
||||||
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int
|
extern "C" int
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* signal.cc
|
/* signal.cc
|
||||||
|
|
||||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
||||||
2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||||
|
|
||||||
Written by Steve Chamberlain of Cygnus Support, sac@cygnus.com
|
Written by Steve Chamberlain of Cygnus Support, sac@cygnus.com
|
||||||
Significant changes by Sergey Okhapkin <sos@prospect.com.ru>
|
Significant changes by Sergey Okhapkin <sos@prospect.com.ru>
|
||||||
@ -197,10 +197,8 @@ handle_sigprocmask (int how, const sigset_t *set, sigset_t *oldset, sigset_t& op
|
|||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EFAULT))
|
{
|
||||||
return EFAULT;
|
|
||||||
|
|
||||||
if (oldset)
|
if (oldset)
|
||||||
*oldset = opmask;
|
*oldset = opmask;
|
||||||
|
|
||||||
@ -224,6 +222,12 @@ handle_sigprocmask (int how, const sigset_t *set, sigset_t *oldset, sigset_t& op
|
|||||||
}
|
}
|
||||||
set_signal_mask (opmask, newmask);
|
set_signal_mask (opmask, newmask);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
__except (EFAULT)
|
||||||
|
{
|
||||||
|
return EFAULT;
|
||||||
|
}
|
||||||
|
__endtry
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,8 +386,7 @@ sigaction_worker (int sig, const struct sigaction *newact,
|
|||||||
struct sigaction *oldact, bool isinternal)
|
struct sigaction *oldact, bool isinternal)
|
||||||
{
|
{
|
||||||
int res = -1;
|
int res = -1;
|
||||||
myfault efault;
|
__try
|
||||||
if (!efault.faulted (EFAULT))
|
|
||||||
{
|
{
|
||||||
sig_dispatch_pending ();
|
sig_dispatch_pending ();
|
||||||
/* check that sig is in right range */
|
/* 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];
|
struct sigaction oa = global_sigs[sig];
|
||||||
|
|
||||||
if (!newact)
|
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
|
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)
|
if (sig == SIGKILL || sig == SIGSTOP)
|
||||||
{
|
{
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
goto out;
|
__leave;
|
||||||
}
|
}
|
||||||
struct sigaction na = *newact;
|
struct sigaction na = *newact;
|
||||||
struct sigaction& gs = global_sigs[sig];
|
struct sigaction& gs = global_sigs[sig];
|
||||||
@ -430,8 +436,8 @@ sigaction_worker (int sig, const struct sigaction *newact,
|
|||||||
res = 0;
|
res = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
__except (EFAULT) {}
|
||||||
out:
|
__endtry
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -560,24 +566,20 @@ sigwait (const sigset_t *set, int *sig_ptr)
|
|||||||
extern "C" int
|
extern "C" int
|
||||||
sigwaitinfo (const sigset_t *set, siginfo_t *info)
|
sigwaitinfo (const sigset_t *set, siginfo_t *info)
|
||||||
{
|
{
|
||||||
|
int res = -1;
|
||||||
|
|
||||||
pthread_testcancel ();
|
pthread_testcancel ();
|
||||||
|
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EFAULT))
|
{
|
||||||
return -1;
|
|
||||||
|
|
||||||
set_signal_mask (_my_tls.sigwait_mask, *set);
|
set_signal_mask (_my_tls.sigwait_mask, *set);
|
||||||
sig_dispatch_pending (true);
|
sig_dispatch_pending (true);
|
||||||
|
|
||||||
int res;
|
|
||||||
switch (cygwait (NULL, cw_infinite, cw_sig_eintr | cw_cancel | cw_cancel_self))
|
switch (cygwait (NULL, cw_infinite, cw_sig_eintr | cw_cancel | cw_cancel_self))
|
||||||
{
|
{
|
||||||
case WAIT_SIGNALED:
|
case WAIT_SIGNALED:
|
||||||
if (!sigismember (set, _my_tls.infodata.si_signo))
|
if (!sigismember (set, _my_tls.infodata.si_signo))
|
||||||
{
|
|
||||||
set_errno (EINTR);
|
set_errno (EINTR);
|
||||||
res = -1;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_my_tls.lock ();
|
_my_tls.lock ();
|
||||||
@ -592,9 +594,13 @@ sigwaitinfo (const sigset_t *set, siginfo_t *info)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
__seterrno ();
|
__seterrno ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
__except (EFAULT) {
|
||||||
res = -1;
|
res = -1;
|
||||||
}
|
}
|
||||||
|
__endtry
|
||||||
sigproc_printf ("returning signal %d", res);
|
sigproc_printf ("returning signal %d", res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* spawn.cc
|
/* spawn.cc
|
||||||
|
|
||||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
||||||
2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -330,18 +330,10 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
|
|||||||
STARTUPINFOW si = {};
|
STARTUPINFOW si = {};
|
||||||
int looped = 0;
|
int looped = 0;
|
||||||
|
|
||||||
myfault efault;
|
|
||||||
system_call_handle system_call (mode == _P_SYSTEM);
|
system_call_handle system_call (mode == _P_SYSTEM);
|
||||||
if (efault.faulted ())
|
|
||||||
{
|
|
||||||
if (get_errno () == ENOMEM)
|
|
||||||
set_errno (E2BIG);
|
|
||||||
else
|
|
||||||
set_errno (EFAULT);
|
|
||||||
res = -1;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
__try
|
||||||
|
{
|
||||||
child_info_types chtype;
|
child_info_types chtype;
|
||||||
if (mode == _P_OVERLAY)
|
if (mode == _P_OVERLAY)
|
||||||
chtype = _CH_EXEC;
|
chtype = _CH_EXEC;
|
||||||
@ -363,13 +355,13 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
|
|||||||
{
|
{
|
||||||
set_errno (err);
|
set_errno (err);
|
||||||
res = -1;
|
res = -1;
|
||||||
goto out;
|
__leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = newargv.setup (prog_arg, real_path, ext, ac, argv, p_type_exec);
|
res = newargv.setup (prog_arg, real_path, ext, ac, argv, p_type_exec);
|
||||||
|
|
||||||
if (res)
|
if (res)
|
||||||
goto out;
|
__leave;
|
||||||
|
|
||||||
if (!real_path.iscygexec () && ::cygheap->cwd.get_error ())
|
if (!real_path.iscygexec () && ::cygheap->cwd.get_error ())
|
||||||
{
|
{
|
||||||
@ -378,7 +370,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
|
|||||||
::cygheap->cwd.get_error_desc ());
|
::cygheap->cwd.get_error_desc ());
|
||||||
set_errno (::cygheap->cwd.get_error ());
|
set_errno (::cygheap->cwd.get_error ());
|
||||||
res = -1;
|
res = -1;
|
||||||
goto out;
|
__leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ac == 3 && argv[1][0] == '/' && tolower (argv[1][1]) == 'c' &&
|
if (ac == 3 && argv[1][0] == '/' && tolower (argv[1][1]) == 'c' &&
|
||||||
@ -410,7 +402,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
|
|||||||
real_path.iscygexec ()))
|
real_path.iscygexec ()))
|
||||||
{
|
{
|
||||||
res = -1;
|
res = -1;
|
||||||
goto out;
|
__leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -530,7 +522,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
|
|||||||
{
|
{
|
||||||
set_errno (ENAMETOOLONG);
|
set_errno (ENAMETOOLONG);
|
||||||
res = -1;
|
res = -1;
|
||||||
goto out;
|
__leave;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -545,7 +537,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
|
|||||||
{
|
{
|
||||||
set_errno (E2BIG);
|
set_errno (E2BIG);
|
||||||
res = -1;
|
res = -1;
|
||||||
goto out;
|
__leave;
|
||||||
}
|
}
|
||||||
set (chtype, real_path.iscygexec ());
|
set (chtype, real_path.iscygexec ());
|
||||||
__stdin = in__stdin;
|
__stdin = in__stdin;
|
||||||
@ -600,7 +592,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
|
|||||||
SetHandleInformation (my_wr_proc_pipe, HANDLE_FLAG_INHERIT, 0);
|
SetHandleInformation (my_wr_proc_pipe, HANDLE_FLAG_INHERIT, 0);
|
||||||
parent_winpid = GetCurrentProcessId ();
|
parent_winpid = GetCurrentProcessId ();
|
||||||
|
|
||||||
loop:
|
loop:
|
||||||
/* When ruid != euid we create the new process under the current original
|
/* When ruid != euid we create the new process under the current original
|
||||||
account and impersonate in child, this way maintaining the different
|
account and impersonate in child, this way maintaining the different
|
||||||
effective vs. real ids.
|
effective vs. real ids.
|
||||||
@ -737,7 +729,7 @@ loop:
|
|||||||
::cygheap->user.reimpersonate ();
|
::cygheap->user.reimpersonate ();
|
||||||
|
|
||||||
res = -1;
|
res = -1;
|
||||||
goto out;
|
__leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The CREATE_SUSPENDED case is handled below */
|
/* The CREATE_SUSPENDED case is handled below */
|
||||||
@ -783,7 +775,7 @@ loop:
|
|||||||
if (get_errno () != ENOMEM)
|
if (get_errno () != ENOMEM)
|
||||||
set_errno (EAGAIN);
|
set_errno (EAGAIN);
|
||||||
res = -1;
|
res = -1;
|
||||||
goto out;
|
__leave;
|
||||||
}
|
}
|
||||||
child->dwProcessId = pi.dwProcessId;
|
child->dwProcessId = pi.dwProcessId;
|
||||||
child.hProcess = pi.hProcess;
|
child.hProcess = pi.hProcess;
|
||||||
@ -805,7 +797,7 @@ loop:
|
|||||||
CloseHandle (pi.hProcess);
|
CloseHandle (pi.hProcess);
|
||||||
ForceCloseHandle (pi.hThread);
|
ForceCloseHandle (pi.hThread);
|
||||||
res = -1;
|
res = -1;
|
||||||
goto out;
|
__leave;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -874,8 +866,16 @@ loop:
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
out:
|
__except (NO_ERROR)
|
||||||
|
{
|
||||||
|
if (get_errno () == ENOMEM)
|
||||||
|
set_errno (E2BIG);
|
||||||
|
else
|
||||||
|
set_errno (EFAULT);
|
||||||
|
res = -1;
|
||||||
|
}
|
||||||
|
__endtry
|
||||||
this->cleanup ();
|
this->cleanup ();
|
||||||
if (envblock)
|
if (envblock)
|
||||||
free (envblock);
|
free (envblock);
|
||||||
@ -1137,14 +1137,8 @@ av::setup (const char *prog_arg, path_conv& real_path, const char *ext,
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted ())
|
|
||||||
{
|
{
|
||||||
UnmapViewOfFile (buf);
|
|
||||||
CloseHandle (hm);
|
|
||||||
real_path.set_cygexec (false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (buf[0] == 'M' && buf[1] == 'Z')
|
if (buf[0] == 'M' && buf[1] == 'Z')
|
||||||
{
|
{
|
||||||
WORD subsys;
|
WORD subsys;
|
||||||
@ -1160,6 +1154,15 @@ av::setup (const char *prog_arg, path_conv& real_path, const char *ext,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
__except (NO_ERROR)
|
||||||
|
{
|
||||||
|
UnmapViewOfFile (buf);
|
||||||
|
CloseHandle (hm);
|
||||||
|
real_path.set_cygexec (false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
__endtry
|
||||||
|
}
|
||||||
CloseHandle (hm);
|
CloseHandle (hm);
|
||||||
|
|
||||||
debug_printf ("%s is possibly a script", real_path.get_win32 ());
|
debug_printf ("%s is possibly a script", real_path.get_win32 ());
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
|||||||
/* thread.cc: Locking and threading module functions
|
/* thread.cc: Locking and threading module functions
|
||||||
|
|
||||||
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
|
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
|
||||||
2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -122,28 +122,29 @@ __cygwin_lock_unlock (_LOCK_T *lock)
|
|||||||
paranoid_printf ("threadcount %d. unlocked", MT_INTERFACE->threadcount);
|
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
|
static inline verifyable_object_state
|
||||||
#endif
|
|
||||||
verifyable_object_isvalid (void const *objectptr, thread_magic_t magic, void *static_ptr1,
|
verifyable_object_isvalid (void const *objectptr, thread_magic_t magic, void *static_ptr1,
|
||||||
void *static_ptr2, void *static_ptr3)
|
void *static_ptr2, void *static_ptr3)
|
||||||
{
|
{
|
||||||
myfault efault;
|
verifyable_object_state state = INVALID_OBJECT;
|
||||||
if (efault.faulted (objectptr))
|
|
||||||
return INVALID_OBJECT;
|
__try
|
||||||
|
{
|
||||||
|
if (!objectptr || !(*(const char **) objectptr))
|
||||||
|
__leave;
|
||||||
|
|
||||||
verifyable_object **object = (verifyable_object **) objectptr;
|
verifyable_object **object = (verifyable_object **) objectptr;
|
||||||
|
|
||||||
if ((static_ptr1 && *object == static_ptr1) ||
|
if ((static_ptr1 && *object == static_ptr1) ||
|
||||||
(static_ptr2 && *object == static_ptr2) ||
|
(static_ptr2 && *object == static_ptr2) ||
|
||||||
(static_ptr3 && *object == static_ptr3))
|
(static_ptr3 && *object == static_ptr3))
|
||||||
return VALID_STATIC_OBJECT;
|
state = VALID_STATIC_OBJECT;
|
||||||
if ((*object)->magic != magic)
|
else if ((*object)->magic == magic)
|
||||||
return INVALID_OBJECT;
|
state = VALID_OBJECT;
|
||||||
return VALID_OBJECT;
|
}
|
||||||
|
__except (NO_ERROR) {}
|
||||||
|
__endtry
|
||||||
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static members */
|
/* static members */
|
||||||
@ -2684,18 +2685,20 @@ pthread_cond::init (pthread_cond_t *cond, const pthread_condattr_t *attr)
|
|||||||
return EAGAIN;
|
return EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
myfault efault;
|
int ret = 0;
|
||||||
if (efault.faulted ())
|
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
*cond = new_cond;
|
||||||
|
}
|
||||||
|
__except (NO_ERROR)
|
||||||
{
|
{
|
||||||
delete new_cond;
|
delete new_cond;
|
||||||
cond_initialization_lock.unlock ();
|
ret = EINVAL;
|
||||||
return EINVAL;
|
|
||||||
}
|
}
|
||||||
|
__endtry
|
||||||
*cond = new_cond;
|
|
||||||
cond_initialization_lock.unlock ();
|
cond_initialization_lock.unlock ();
|
||||||
|
return ret;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int
|
extern "C" int
|
||||||
@ -2747,12 +2750,10 @@ pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
|||||||
struct timespec tp;
|
struct timespec tp;
|
||||||
LARGE_INTEGER timeout;
|
LARGE_INTEGER timeout;
|
||||||
|
|
||||||
myfault efault;
|
|
||||||
if (efault.faulted ())
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
pthread_testcancel ();
|
pthread_testcancel ();
|
||||||
|
|
||||||
|
__try
|
||||||
|
{
|
||||||
int err = __pthread_cond_wait_init (cond, mutex);
|
int err = __pthread_cond_wait_init (cond, mutex);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
@ -2761,7 +2762,7 @@ pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
|||||||
if (abstime->tv_sec < 0
|
if (abstime->tv_sec < 0
|
||||||
|| abstime->tv_nsec < 0
|
|| abstime->tv_nsec < 0
|
||||||
|| abstime->tv_nsec > 999999999)
|
|| abstime->tv_nsec > 999999999)
|
||||||
return EINVAL;
|
__leave;
|
||||||
|
|
||||||
clock_gettime ((*cond)->clock_id, &tp);
|
clock_gettime ((*cond)->clock_id, &tp);
|
||||||
|
|
||||||
@ -2786,6 +2787,10 @@ pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return (*cond)->wait (*mutex, &timeout);
|
return (*cond)->wait (*mutex, &timeout);
|
||||||
|
}
|
||||||
|
__except (NO_ERROR) {}
|
||||||
|
__endtry
|
||||||
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int
|
extern "C" int
|
||||||
@ -2910,18 +2915,20 @@ pthread_rwlock::init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr
|
|||||||
return EAGAIN;
|
return EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
myfault efault;
|
int ret = 0;
|
||||||
if (efault.faulted ())
|
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
*rwlock = new_rwlock;
|
||||||
|
}
|
||||||
|
__except (NO_ERROR)
|
||||||
{
|
{
|
||||||
delete new_rwlock;
|
delete new_rwlock;
|
||||||
rwlock_initialization_lock.unlock ();
|
ret = EINVAL;
|
||||||
return EINVAL;
|
|
||||||
}
|
}
|
||||||
|
__endtry
|
||||||
*rwlock = new_rwlock;
|
|
||||||
rwlock_initialization_lock.unlock ();
|
rwlock_initialization_lock.unlock ();
|
||||||
|
return ret;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int
|
extern "C" int
|
||||||
@ -3133,15 +3140,17 @@ pthread_mutex::init (pthread_mutex_t *mutex,
|
|||||||
new_mutex->type = PTHREAD_MUTEX_ERRORCHECK;
|
new_mutex->type = PTHREAD_MUTEX_ERRORCHECK;
|
||||||
}
|
}
|
||||||
|
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted ())
|
{
|
||||||
|
*mutex = new_mutex;
|
||||||
|
}
|
||||||
|
__except (NO_ERROR)
|
||||||
{
|
{
|
||||||
delete new_mutex;
|
delete new_mutex;
|
||||||
mutex_initialization_lock.unlock ();
|
mutex_initialization_lock.unlock ();
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
__endtry
|
||||||
*mutex = new_mutex;
|
|
||||||
}
|
}
|
||||||
mutex_initialization_lock.unlock ();
|
mutex_initialization_lock.unlock ();
|
||||||
pthread_printf ("*mutex %p, attr %p, initializer %p", *mutex, attr, initializer);
|
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;
|
return EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted ())
|
{
|
||||||
|
*spinlock = new_spinlock;
|
||||||
|
}
|
||||||
|
__except (NO_ERROR)
|
||||||
{
|
{
|
||||||
delete new_spinlock;
|
delete new_spinlock;
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
__endtry
|
||||||
*spinlock = new_spinlock;
|
|
||||||
pthread_printf ("*spinlock %p, pshared %d", *spinlock, pshared);
|
pthread_printf ("*spinlock %p, pshared %d", *spinlock, pshared);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3502,17 +3512,8 @@ semaphore::_timedwait (const struct timespec *abstime)
|
|||||||
{
|
{
|
||||||
LARGE_INTEGER timeout;
|
LARGE_INTEGER timeout;
|
||||||
|
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted ())
|
|
||||||
{
|
{
|
||||||
/* 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
|
timeout.QuadPart = abstime->tv_sec * NSPERSEC
|
||||||
+ (abstime->tv_nsec + 99) / 100 + FACTOR;
|
+ (abstime->tv_nsec + 99) / 100 + FACTOR;
|
||||||
|
|
||||||
@ -3531,6 +3532,18 @@ semaphore::_timedwait (const struct timespec *abstime)
|
|||||||
__seterrno ();
|
__seterrno ();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
__except (NO_ERROR)
|
||||||
|
{
|
||||||
|
/* According to SUSv3, abstime need not be checked for validity,
|
||||||
|
if the semaphore can be locked immediately. */
|
||||||
|
if (_trywait ())
|
||||||
|
{
|
||||||
|
set_errno (EINVAL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
__endtry
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3761,36 +3774,38 @@ semaphore::post (sem_t *sem)
|
|||||||
int
|
int
|
||||||
semaphore::getvalue (sem_t *sem, int *sval)
|
semaphore::getvalue (sem_t *sem, int *sval)
|
||||||
{
|
{
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted () || !is_good_object (sem))
|
|
||||||
{
|
{
|
||||||
|
if (is_good_object (sem))
|
||||||
|
return (*sem)->_getvalue (sval);
|
||||||
|
}
|
||||||
|
__except (NO_ERROR) {}
|
||||||
|
__endtry
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
return (*sem)->_getvalue (sval);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
semaphore::getinternal (sem_t *sem, int *sfd, unsigned long long *shash,
|
semaphore::getinternal (sem_t *sem, int *sfd, unsigned long long *shash,
|
||||||
LUID *sluid, unsigned int *sval)
|
LUID *sluid, unsigned int *sval)
|
||||||
{
|
{
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted () || !is_good_object (sem))
|
|
||||||
{
|
{
|
||||||
set_errno (EINVAL);
|
if (!is_good_object (sem))
|
||||||
return -1;
|
__leave;
|
||||||
}
|
|
||||||
if ((*sfd = (*sem)->fd) < 0)
|
if ((*sfd = (*sem)->fd) < 0)
|
||||||
{
|
__leave;
|
||||||
set_errno (EINVAL);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
*shash = (*sem)->hash;
|
*shash = (*sem)->hash;
|
||||||
*sluid = (*sem)->luid;
|
*sluid = (*sem)->luid;
|
||||||
/* POSIX defines the value in calls to sem_init/sem_open as unsigned, but
|
/* POSIX defines the value in calls to sem_init/sem_open as unsigned,
|
||||||
the sem_getvalue gets a pointer to int to return the value. Go figure! */
|
but the sem_getvalue gets a pointer to int to return the value.
|
||||||
|
Go figure! */
|
||||||
return (*sem)->_getvalue ((int *)sval);
|
return (*sem)->_getvalue ((int *)sval);
|
||||||
|
}
|
||||||
|
__except (NO_ERROR) {}
|
||||||
|
__endtry
|
||||||
|
set_errno (EINVAL);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pthread_null */
|
/* pthread_null */
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* timer.cc
|
/* 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.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -219,17 +219,18 @@ it_bad (const timespec& t)
|
|||||||
int
|
int
|
||||||
timer_tracker::settime (int in_flags, const itimerspec *value, itimerspec *ovalue)
|
timer_tracker::settime (int in_flags, const itimerspec *value, itimerspec *ovalue)
|
||||||
{
|
{
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
__try
|
||||||
|
{
|
||||||
if (!value)
|
if (!value)
|
||||||
{
|
{
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return -1;
|
__leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
myfault efault;
|
if (it_bad (value->it_value) || it_bad (value->it_interval))
|
||||||
if (efault.faulted (EFAULT)
|
__leave;
|
||||||
|| it_bad (value->it_value)
|
|
||||||
|| it_bad (value->it_interval))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
long long now = in_flags & TIMER_ABSTIME ? 0 : gtod.usecs ();
|
long long now = in_flags & TIMER_ABSTIME ? 0 : gtod.usecs ();
|
||||||
|
|
||||||
@ -256,8 +257,11 @@ timer_tracker::settime (int in_flags, const itimerspec *value, itimerspec *ovalu
|
|||||||
ResetEvent (syncthread);
|
ResetEvent (syncthread);
|
||||||
new cygthread (timer_thread, this, "itimer", syncthread);
|
new cygthread (timer_thread, this, "itimer", syncthread);
|
||||||
}
|
}
|
||||||
|
ret = 0;
|
||||||
return 0;
|
}
|
||||||
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -280,10 +284,10 @@ timer_tracker::gettime (itimerspec *ovalue)
|
|||||||
extern "C" int
|
extern "C" int
|
||||||
timer_gettime (timer_t timerid, struct itimerspec *ovalue)
|
timer_gettime (timer_t timerid, struct itimerspec *ovalue)
|
||||||
{
|
{
|
||||||
myfault efault;
|
int ret = -1;
|
||||||
if (efault.faulted (EFAULT))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
|
__try
|
||||||
|
{
|
||||||
timer_tracker *tt = (timer_tracker *) timerid;
|
timer_tracker *tt = (timer_tracker *) timerid;
|
||||||
if (tt->magic != TT_MAGIC)
|
if (tt->magic != TT_MAGIC)
|
||||||
{
|
{
|
||||||
@ -292,17 +296,21 @@ timer_gettime (timer_t timerid, struct itimerspec *ovalue)
|
|||||||
}
|
}
|
||||||
|
|
||||||
tt->gettime (ovalue);
|
tt->gettime (ovalue);
|
||||||
return 0;
|
ret = 0;
|
||||||
|
}
|
||||||
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int
|
extern "C" int
|
||||||
timer_create (clockid_t clock_id, struct sigevent *__restrict evp,
|
timer_create (clockid_t clock_id, struct sigevent *__restrict evp,
|
||||||
timer_t *__restrict timerid)
|
timer_t *__restrict timerid)
|
||||||
{
|
{
|
||||||
myfault efault;
|
int ret = -1;
|
||||||
if (efault.faulted (EFAULT))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
|
__try
|
||||||
|
{
|
||||||
if (CLOCKID_IS_PROCESS (clock_id) || CLOCKID_IS_THREAD (clock_id))
|
if (CLOCKID_IS_PROCESS (clock_id) || CLOCKID_IS_THREAD (clock_id))
|
||||||
{
|
{
|
||||||
set_errno (ENOTSUP);
|
set_errno (ENOTSUP);
|
||||||
@ -316,7 +324,11 @@ timer_create (clockid_t clock_id, struct sigevent *__restrict evp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
*timerid = (timer_t) new timer_tracker (clock_id, evp);
|
*timerid = (timer_t) new timer_tracker (clock_id, evp);
|
||||||
return 0;
|
ret = 0;
|
||||||
|
}
|
||||||
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int
|
extern "C" int
|
||||||
@ -324,30 +336,35 @@ timer_settime (timer_t timerid, int flags,
|
|||||||
const struct itimerspec *__restrict value,
|
const struct itimerspec *__restrict value,
|
||||||
struct itimerspec *__restrict ovalue)
|
struct itimerspec *__restrict ovalue)
|
||||||
{
|
{
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
__try
|
||||||
|
{
|
||||||
timer_tracker *tt = (timer_tracker *) timerid;
|
timer_tracker *tt = (timer_tracker *) timerid;
|
||||||
myfault efault;
|
|
||||||
if (efault.faulted (EFAULT))
|
|
||||||
return -1;
|
|
||||||
if (tt->magic != TT_MAGIC)
|
if (tt->magic != TT_MAGIC)
|
||||||
{
|
{
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return -1;
|
__leave;
|
||||||
}
|
}
|
||||||
|
ret = tt->settime (flags, value, ovalue);
|
||||||
return tt->settime (flags, value, ovalue);
|
}
|
||||||
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int
|
extern "C" int
|
||||||
timer_delete (timer_t timerid)
|
timer_delete (timer_t timerid)
|
||||||
{
|
{
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
__try
|
||||||
|
{
|
||||||
timer_tracker *in_tt = (timer_tracker *) timerid;
|
timer_tracker *in_tt = (timer_tracker *) timerid;
|
||||||
myfault efault;
|
|
||||||
if (efault.faulted (EFAULT))
|
|
||||||
return -1;
|
|
||||||
if (in_tt->magic != TT_MAGIC)
|
if (in_tt->magic != TT_MAGIC)
|
||||||
{
|
{
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return -1;
|
__leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
lock_timer_tracker here;
|
lock_timer_tracker here;
|
||||||
@ -356,10 +373,15 @@ timer_delete (timer_t timerid)
|
|||||||
{
|
{
|
||||||
tt->next = in_tt->next;
|
tt->next = in_tt->next;
|
||||||
delete in_tt;
|
delete in_tt;
|
||||||
return 0;
|
ret = 0;
|
||||||
|
__leave;
|
||||||
}
|
}
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return 0;
|
ret = 0;
|
||||||
|
}
|
||||||
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -412,18 +434,13 @@ setitimer (int which, const struct itimerval *__restrict value,
|
|||||||
extern "C" int
|
extern "C" int
|
||||||
getitimer (int which, struct itimerval *ovalue)
|
getitimer (int which, struct itimerval *ovalue)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret = -1;
|
||||||
|
|
||||||
if (which != ITIMER_REAL)
|
if (which != ITIMER_REAL)
|
||||||
{
|
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
ret = -1;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EFAULT))
|
|
||||||
ret = -1;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
struct itimerspec spec_ovalue;
|
struct itimerspec spec_ovalue;
|
||||||
ret = timer_gettime ((timer_t) &ttstart, &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;
|
ovalue->it_value.tv_usec = spec_ovalue.it_value.tv_nsec / 1000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
__except (EFAULT) {}
|
||||||
|
__endtry
|
||||||
}
|
}
|
||||||
syscall_printf ("%R = getitimer()", ret);
|
syscall_printf ("%R = getitimer()", ret);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* times.cc
|
/* times.cc
|
||||||
|
|
||||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
||||||
2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -59,14 +59,13 @@ __to_clock_t (PLARGE_INTEGER src, int flag)
|
|||||||
extern "C" clock_t
|
extern "C" clock_t
|
||||||
times (struct tms *buf)
|
times (struct tms *buf)
|
||||||
{
|
{
|
||||||
myfault efault;
|
|
||||||
if (efault.faulted (EFAULT))
|
|
||||||
return ((clock_t) -1);
|
|
||||||
|
|
||||||
static SYSTEM_TIMEOFDAY_INFORMATION stodi;
|
static SYSTEM_TIMEOFDAY_INFORMATION stodi;
|
||||||
KERNEL_USER_TIMES kut;
|
KERNEL_USER_TIMES kut;
|
||||||
LARGE_INTEGER ticks;
|
LARGE_INTEGER ticks;
|
||||||
|
clock_t tc = (clock_t) -1;
|
||||||
|
|
||||||
|
__try
|
||||||
|
{
|
||||||
/* Fetch boot time if we haven't already. */
|
/* Fetch boot time if we haven't already. */
|
||||||
if (!stodi.BootTime.QuadPart)
|
if (!stodi.BootTime.QuadPart)
|
||||||
NtQuerySystemInformation (SystemTimeOfDayInformation,
|
NtQuerySystemInformation (SystemTimeOfDayInformation,
|
||||||
@ -79,7 +78,7 @@ times (struct tms *buf)
|
|||||||
/* uptime */
|
/* uptime */
|
||||||
ticks.QuadPart -= stodi.BootTime.QuadPart;
|
ticks.QuadPart -= stodi.BootTime.QuadPart;
|
||||||
/* ticks is in in 100ns, convert to clock ticks. */
|
/* ticks is in in 100ns, convert to clock ticks. */
|
||||||
clock_t tc = (clock_t) (ticks.QuadPart * CLOCKS_PER_SEC / NSPERSEC);
|
tc = (clock_t) (ticks.QuadPart * CLOCKS_PER_SEC / NSPERSEC);
|
||||||
|
|
||||||
buf->tms_stime = __to_clock_t (&kut.KernelTime, 0);
|
buf->tms_stime = __to_clock_t (&kut.KernelTime, 0);
|
||||||
buf->tms_utime = __to_clock_t (&kut.UserTime, 0);
|
buf->tms_utime = __to_clock_t (&kut.UserTime, 0);
|
||||||
@ -87,7 +86,12 @@ times (struct tms *buf)
|
|||||||
buf->tms_cstime = __to_clock_t (&kut.KernelTime, 1);
|
buf->tms_cstime = __to_clock_t (&kut.KernelTime, 1);
|
||||||
timeval_to_filetime (&myself->rusage_children.ru_utime, &kut.UserTime);
|
timeval_to_filetime (&myself->rusage_children.ru_utime, &kut.UserTime);
|
||||||
buf->tms_cutime = __to_clock_t (&kut.UserTime, 1);
|
buf->tms_cutime = __to_clock_t (&kut.UserTime, 1);
|
||||||
|
}
|
||||||
|
__except (EFAULT)
|
||||||
|
{
|
||||||
|
tc = (clock_t) -1;
|
||||||
|
}
|
||||||
|
__endtry
|
||||||
syscall_printf ("%D = times(%p)", tc, buf);
|
syscall_printf ("%D = times(%p)", tc, buf);
|
||||||
return tc;
|
return tc;
|
||||||
}
|
}
|
||||||
@ -100,12 +104,10 @@ settimeofday (const struct timeval *tv, const struct timezone *tz)
|
|||||||
{
|
{
|
||||||
SYSTEMTIME st;
|
SYSTEMTIME st;
|
||||||
struct tm *ptm;
|
struct tm *ptm;
|
||||||
int res;
|
int res = -1;
|
||||||
|
|
||||||
myfault efault;
|
|
||||||
if (efault.faulted (EFAULT))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
|
__try
|
||||||
|
{
|
||||||
if (tv->tv_usec < 0 || tv->tv_usec >= 1000000)
|
if (tv->tv_usec < 0 || tv->tv_usec >= 1000000)
|
||||||
{
|
{
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
@ -127,7 +129,12 @@ settimeofday (const struct timeval *tv, const struct timezone *tz)
|
|||||||
|
|
||||||
if (res)
|
if (res)
|
||||||
set_errno (EPERM);
|
set_errno (EPERM);
|
||||||
|
}
|
||||||
|
__except (EFAULT)
|
||||||
|
{
|
||||||
|
res = -1;
|
||||||
|
}
|
||||||
|
__endtry
|
||||||
syscall_printf ("%R = settimeofday(%p, %p)", res, tv, tz);
|
syscall_printf ("%R = settimeofday(%p, %p)", res, tv, tz);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -8,17 +8,16 @@ details. */
|
|||||||
|
|
||||||
#include <winsup.h>
|
#include <winsup.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include "cygtls.h"
|
|
||||||
#include "tls_pbuf.h"
|
#include "tls_pbuf.h"
|
||||||
|
|
||||||
#define tls_pbuf _my_tls.locals.pathbufs
|
#define tls_pbuf _my_tls.pathbufs
|
||||||
|
|
||||||
void
|
void
|
||||||
tls_pathbuf::destroy ()
|
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]);
|
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]);
|
free (w_buf[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,20 +10,20 @@ details. */
|
|||||||
|
|
||||||
class tmp_pathbuf
|
class tmp_pathbuf
|
||||||
{
|
{
|
||||||
unsigned c_buf_old;
|
uint32_t c_buf_old;
|
||||||
unsigned w_buf_old;
|
uint32_t w_buf_old;
|
||||||
public:
|
public:
|
||||||
tmp_pathbuf () __attribute__ ((always_inline))
|
tmp_pathbuf () __attribute__ ((always_inline))
|
||||||
: c_buf_old (_my_tls.locals.pathbufs.c_cnt),
|
: c_buf_old (_my_tls.pathbufs.c_cnt),
|
||||||
w_buf_old (_my_tls.locals.pathbufs.w_cnt)
|
w_buf_old (_my_tls.pathbufs.w_cnt)
|
||||||
{}
|
{}
|
||||||
~tmp_pathbuf () __attribute__ ((always_inline))
|
~tmp_pathbuf () __attribute__ ((always_inline))
|
||||||
{
|
{
|
||||||
_my_tls.locals.pathbufs.c_cnt = c_buf_old;
|
_my_tls.pathbufs.c_cnt = c_buf_old;
|
||||||
_my_tls.locals.pathbufs.w_cnt = w_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
|
return c_need + c_buf_old < TP_NUM_C_BUFS
|
||||||
&& w_need + w_buf_old < TP_NUM_W_BUFS;
|
&& w_need + w_buf_old < TP_NUM_W_BUFS;
|
||||||
|
@ -3,44 +3,46 @@
|
|||||||
//; $tls::start_offset = -12700;
|
//; $tls::start_offset = -12700;
|
||||||
//; $tls::locals = -12700;
|
//; $tls::locals = -12700;
|
||||||
//; $tls::plocals = 0;
|
//; $tls::plocals = 0;
|
||||||
//; $tls::local_clib = -10980;
|
//; $tls::local_clib = -11388;
|
||||||
//; $tls::plocal_clib = 1720;
|
//; $tls::plocal_clib = 1312;
|
||||||
//; $tls::__dontuse = -10980;
|
//; $tls::__dontuse = -11388;
|
||||||
//; $tls::p__dontuse = 1720;
|
//; $tls::p__dontuse = 1312;
|
||||||
//; $tls::func = -9892;
|
//; $tls::func = -10300;
|
||||||
//; $tls::pfunc = 2808;
|
//; $tls::pfunc = 2400;
|
||||||
//; $tls::saved_errno = -9888;
|
//; $tls::saved_errno = -10296;
|
||||||
//; $tls::psaved_errno = 2812;
|
//; $tls::psaved_errno = 2404;
|
||||||
//; $tls::sa_flags = -9884;
|
//; $tls::sa_flags = -10292;
|
||||||
//; $tls::psa_flags = 2816;
|
//; $tls::psa_flags = 2408;
|
||||||
//; $tls::oldmask = -9880;
|
//; $tls::oldmask = -10288;
|
||||||
//; $tls::poldmask = 2820;
|
//; $tls::poldmask = 2412;
|
||||||
//; $tls::deltamask = -9876;
|
//; $tls::deltamask = -10284;
|
||||||
//; $tls::pdeltamask = 2824;
|
//; $tls::pdeltamask = 2416;
|
||||||
//; $tls::errno_addr = -9872;
|
//; $tls::errno_addr = -10280;
|
||||||
//; $tls::perrno_addr = 2828;
|
//; $tls::perrno_addr = 2420;
|
||||||
//; $tls::sigmask = -9868;
|
//; $tls::sigmask = -10276;
|
||||||
//; $tls::psigmask = 2832;
|
//; $tls::psigmask = 2424;
|
||||||
//; $tls::sigwait_mask = -9864;
|
//; $tls::sigwait_mask = -10272;
|
||||||
//; $tls::psigwait_mask = 2836;
|
//; $tls::psigwait_mask = 2428;
|
||||||
//; $tls::sigwait_info = -9860;
|
//; $tls::sigwait_info = -10268;
|
||||||
//; $tls::psigwait_info = 2840;
|
//; $tls::psigwait_info = 2432;
|
||||||
//; $tls::signal_arrived = -9856;
|
//; $tls::signal_arrived = -10264;
|
||||||
//; $tls::psignal_arrived = 2844;
|
//; $tls::psignal_arrived = 2436;
|
||||||
//; $tls::will_wait_for_signal = -9852;
|
//; $tls::will_wait_for_signal = -10260;
|
||||||
//; $tls::pwill_wait_for_signal = 2848;
|
//; $tls::pwill_wait_for_signal = 2440;
|
||||||
//; $tls::thread_context = -9848;
|
//; $tls::thread_context = -10256;
|
||||||
//; $tls::pthread_context = 2852;
|
//; $tls::pthread_context = 2444;
|
||||||
//; $tls::thread_id = -9636;
|
//; $tls::thread_id = -10044;
|
||||||
//; $tls::pthread_id = 3064;
|
//; $tls::pthread_id = 2656;
|
||||||
//; $tls::infodata = -9632;
|
//; $tls::infodata = -10040;
|
||||||
//; $tls::pinfodata = 3068;
|
//; $tls::pinfodata = 2660;
|
||||||
//; $tls::tid = -9484;
|
//; $tls::tid = -9892;
|
||||||
//; $tls::ptid = 3216;
|
//; $tls::ptid = 2808;
|
||||||
//; $tls::_ctinfo = -9480;
|
//; $tls::_ctinfo = -9888;
|
||||||
//; $tls::p_ctinfo = 3220;
|
//; $tls::p_ctinfo = 2812;
|
||||||
//; $tls::andreas = -9476;
|
//; $tls::andreas = -9884;
|
||||||
//; $tls::pandreas = 3224;
|
//; $tls::pandreas = 2816;
|
||||||
|
//; $tls::pathbufs = -9880;
|
||||||
|
//; $tls::ppathbufs = 2820;
|
||||||
//; $tls::wq = -9472;
|
//; $tls::wq = -9472;
|
||||||
//; $tls::pwq = 3228;
|
//; $tls::pwq = 3228;
|
||||||
//; $tls::sig = -9444;
|
//; $tls::sig = -9444;
|
||||||
@ -61,44 +63,46 @@
|
|||||||
|
|
||||||
#define tls_locals (-12700)
|
#define tls_locals (-12700)
|
||||||
#define tls_plocals (0)
|
#define tls_plocals (0)
|
||||||
#define tls_local_clib (-10980)
|
#define tls_local_clib (-11388)
|
||||||
#define tls_plocal_clib (1720)
|
#define tls_plocal_clib (1312)
|
||||||
#define tls___dontuse (-10980)
|
#define tls___dontuse (-11388)
|
||||||
#define tls_p__dontuse (1720)
|
#define tls_p__dontuse (1312)
|
||||||
#define tls_func (-9892)
|
#define tls_func (-10300)
|
||||||
#define tls_pfunc (2808)
|
#define tls_pfunc (2400)
|
||||||
#define tls_saved_errno (-9888)
|
#define tls_saved_errno (-10296)
|
||||||
#define tls_psaved_errno (2812)
|
#define tls_psaved_errno (2404)
|
||||||
#define tls_sa_flags (-9884)
|
#define tls_sa_flags (-10292)
|
||||||
#define tls_psa_flags (2816)
|
#define tls_psa_flags (2408)
|
||||||
#define tls_oldmask (-9880)
|
#define tls_oldmask (-10288)
|
||||||
#define tls_poldmask (2820)
|
#define tls_poldmask (2412)
|
||||||
#define tls_deltamask (-9876)
|
#define tls_deltamask (-10284)
|
||||||
#define tls_pdeltamask (2824)
|
#define tls_pdeltamask (2416)
|
||||||
#define tls_errno_addr (-9872)
|
#define tls_errno_addr (-10280)
|
||||||
#define tls_perrno_addr (2828)
|
#define tls_perrno_addr (2420)
|
||||||
#define tls_sigmask (-9868)
|
#define tls_sigmask (-10276)
|
||||||
#define tls_psigmask (2832)
|
#define tls_psigmask (2424)
|
||||||
#define tls_sigwait_mask (-9864)
|
#define tls_sigwait_mask (-10272)
|
||||||
#define tls_psigwait_mask (2836)
|
#define tls_psigwait_mask (2428)
|
||||||
#define tls_sigwait_info (-9860)
|
#define tls_sigwait_info (-10268)
|
||||||
#define tls_psigwait_info (2840)
|
#define tls_psigwait_info (2432)
|
||||||
#define tls_signal_arrived (-9856)
|
#define tls_signal_arrived (-10264)
|
||||||
#define tls_psignal_arrived (2844)
|
#define tls_psignal_arrived (2436)
|
||||||
#define tls_will_wait_for_signal (-9852)
|
#define tls_will_wait_for_signal (-10260)
|
||||||
#define tls_pwill_wait_for_signal (2848)
|
#define tls_pwill_wait_for_signal (2440)
|
||||||
#define tls_thread_context (-9848)
|
#define tls_thread_context (-10256)
|
||||||
#define tls_pthread_context (2852)
|
#define tls_pthread_context (2444)
|
||||||
#define tls_thread_id (-9636)
|
#define tls_thread_id (-10044)
|
||||||
#define tls_pthread_id (3064)
|
#define tls_pthread_id (2656)
|
||||||
#define tls_infodata (-9632)
|
#define tls_infodata (-10040)
|
||||||
#define tls_pinfodata (3068)
|
#define tls_pinfodata (2660)
|
||||||
#define tls_tid (-9484)
|
#define tls_tid (-9892)
|
||||||
#define tls_ptid (3216)
|
#define tls_ptid (2808)
|
||||||
#define tls__ctinfo (-9480)
|
#define tls__ctinfo (-9888)
|
||||||
#define tls_p_ctinfo (3220)
|
#define tls_p_ctinfo (2812)
|
||||||
#define tls_andreas (-9476)
|
#define tls_andreas (-9884)
|
||||||
#define tls_pandreas (3224)
|
#define tls_pandreas (2816)
|
||||||
|
#define tls_pathbufs (-9880)
|
||||||
|
#define tls_ppathbufs (2820)
|
||||||
#define tls_wq (-9472)
|
#define tls_wq (-9472)
|
||||||
#define tls_pwq (3228)
|
#define tls_pwq (3228)
|
||||||
#define tls_sig (-9444)
|
#define tls_sig (-9444)
|
||||||
|
@ -3,44 +3,46 @@
|
|||||||
//; $tls::start_offset = -12800;
|
//; $tls::start_offset = -12800;
|
||||||
//; $tls::locals = -12800;
|
//; $tls::locals = -12800;
|
||||||
//; $tls::plocals = 0;
|
//; $tls::plocals = 0;
|
||||||
//; $tls::local_clib = -10624;
|
//; $tls::local_clib = -11432;
|
||||||
//; $tls::plocal_clib = 2176;
|
//; $tls::plocal_clib = 1368;
|
||||||
//; $tls::__dontuse = -10624;
|
//; $tls::__dontuse = -11432;
|
||||||
//; $tls::p__dontuse = 2176;
|
//; $tls::p__dontuse = 1368;
|
||||||
//; $tls::func = -8736;
|
//; $tls::func = -9544;
|
||||||
//; $tls::pfunc = 4064;
|
//; $tls::pfunc = 3256;
|
||||||
//; $tls::saved_errno = -8728;
|
//; $tls::saved_errno = -9536;
|
||||||
//; $tls::psaved_errno = 4072;
|
//; $tls::psaved_errno = 3264;
|
||||||
//; $tls::sa_flags = -8724;
|
//; $tls::sa_flags = -9532;
|
||||||
//; $tls::psa_flags = 4076;
|
//; $tls::psa_flags = 3268;
|
||||||
//; $tls::oldmask = -8720;
|
//; $tls::oldmask = -9528;
|
||||||
//; $tls::poldmask = 4080;
|
//; $tls::poldmask = 3272;
|
||||||
//; $tls::deltamask = -8712;
|
//; $tls::deltamask = -9520;
|
||||||
//; $tls::pdeltamask = 4088;
|
//; $tls::pdeltamask = 3280;
|
||||||
//; $tls::errno_addr = -8704;
|
//; $tls::errno_addr = -9512;
|
||||||
//; $tls::perrno_addr = 4096;
|
//; $tls::perrno_addr = 3288;
|
||||||
//; $tls::sigmask = -8696;
|
//; $tls::sigmask = -9504;
|
||||||
//; $tls::psigmask = 4104;
|
//; $tls::psigmask = 3296;
|
||||||
//; $tls::sigwait_mask = -8688;
|
//; $tls::sigwait_mask = -9496;
|
||||||
//; $tls::psigwait_mask = 4112;
|
//; $tls::psigwait_mask = 3304;
|
||||||
//; $tls::sigwait_info = -8680;
|
//; $tls::sigwait_info = -9488;
|
||||||
//; $tls::psigwait_info = 4120;
|
//; $tls::psigwait_info = 3312;
|
||||||
//; $tls::signal_arrived = -8672;
|
//; $tls::signal_arrived = -9480;
|
||||||
//; $tls::psignal_arrived = 4128;
|
//; $tls::psignal_arrived = 3320;
|
||||||
//; $tls::will_wait_for_signal = -8664;
|
//; $tls::will_wait_for_signal = -9472;
|
||||||
//; $tls::pwill_wait_for_signal = 4136;
|
//; $tls::pwill_wait_for_signal = 3328;
|
||||||
//; $tls::thread_context = -8656;
|
//; $tls::thread_context = -9464;
|
||||||
//; $tls::pthread_context = 4144;
|
//; $tls::pthread_context = 3336;
|
||||||
//; $tls::thread_id = -7824;
|
//; $tls::thread_id = -8632;
|
||||||
//; $tls::pthread_id = 4976;
|
//; $tls::pthread_id = 4168;
|
||||||
//; $tls::infodata = -7820;
|
//; $tls::infodata = -8628;
|
||||||
//; $tls::pinfodata = 4980;
|
//; $tls::pinfodata = 4172;
|
||||||
//; $tls::tid = -7672;
|
//; $tls::tid = -8480;
|
||||||
//; $tls::ptid = 5128;
|
//; $tls::ptid = 4320;
|
||||||
//; $tls::_ctinfo = -7664;
|
//; $tls::_ctinfo = -8472;
|
||||||
//; $tls::p_ctinfo = 5136;
|
//; $tls::p_ctinfo = 4328;
|
||||||
//; $tls::andreas = -7656;
|
//; $tls::andreas = -8464;
|
||||||
//; $tls::pandreas = 5144;
|
//; $tls::pandreas = 4336;
|
||||||
|
//; $tls::pathbufs = -8456;
|
||||||
|
//; $tls::ppathbufs = 4344;
|
||||||
//; $tls::wq = -7648;
|
//; $tls::wq = -7648;
|
||||||
//; $tls::pwq = 5152;
|
//; $tls::pwq = 5152;
|
||||||
//; $tls::sig = -7600;
|
//; $tls::sig = -7600;
|
||||||
@ -61,44 +63,46 @@
|
|||||||
|
|
||||||
#define tls_locals (-12800)
|
#define tls_locals (-12800)
|
||||||
#define tls_plocals (0)
|
#define tls_plocals (0)
|
||||||
#define tls_local_clib (-10624)
|
#define tls_local_clib (-11432)
|
||||||
#define tls_plocal_clib (2176)
|
#define tls_plocal_clib (1368)
|
||||||
#define tls___dontuse (-10624)
|
#define tls___dontuse (-11432)
|
||||||
#define tls_p__dontuse (2176)
|
#define tls_p__dontuse (1368)
|
||||||
#define tls_func (-8736)
|
#define tls_func (-9544)
|
||||||
#define tls_pfunc (4064)
|
#define tls_pfunc (3256)
|
||||||
#define tls_saved_errno (-8728)
|
#define tls_saved_errno (-9536)
|
||||||
#define tls_psaved_errno (4072)
|
#define tls_psaved_errno (3264)
|
||||||
#define tls_sa_flags (-8724)
|
#define tls_sa_flags (-9532)
|
||||||
#define tls_psa_flags (4076)
|
#define tls_psa_flags (3268)
|
||||||
#define tls_oldmask (-8720)
|
#define tls_oldmask (-9528)
|
||||||
#define tls_poldmask (4080)
|
#define tls_poldmask (3272)
|
||||||
#define tls_deltamask (-8712)
|
#define tls_deltamask (-9520)
|
||||||
#define tls_pdeltamask (4088)
|
#define tls_pdeltamask (3280)
|
||||||
#define tls_errno_addr (-8704)
|
#define tls_errno_addr (-9512)
|
||||||
#define tls_perrno_addr (4096)
|
#define tls_perrno_addr (3288)
|
||||||
#define tls_sigmask (-8696)
|
#define tls_sigmask (-9504)
|
||||||
#define tls_psigmask (4104)
|
#define tls_psigmask (3296)
|
||||||
#define tls_sigwait_mask (-8688)
|
#define tls_sigwait_mask (-9496)
|
||||||
#define tls_psigwait_mask (4112)
|
#define tls_psigwait_mask (3304)
|
||||||
#define tls_sigwait_info (-8680)
|
#define tls_sigwait_info (-9488)
|
||||||
#define tls_psigwait_info (4120)
|
#define tls_psigwait_info (3312)
|
||||||
#define tls_signal_arrived (-8672)
|
#define tls_signal_arrived (-9480)
|
||||||
#define tls_psignal_arrived (4128)
|
#define tls_psignal_arrived (3320)
|
||||||
#define tls_will_wait_for_signal (-8664)
|
#define tls_will_wait_for_signal (-9472)
|
||||||
#define tls_pwill_wait_for_signal (4136)
|
#define tls_pwill_wait_for_signal (3328)
|
||||||
#define tls_thread_context (-8656)
|
#define tls_thread_context (-9464)
|
||||||
#define tls_pthread_context (4144)
|
#define tls_pthread_context (3336)
|
||||||
#define tls_thread_id (-7824)
|
#define tls_thread_id (-8632)
|
||||||
#define tls_pthread_id (4976)
|
#define tls_pthread_id (4168)
|
||||||
#define tls_infodata (-7820)
|
#define tls_infodata (-8628)
|
||||||
#define tls_pinfodata (4980)
|
#define tls_pinfodata (4172)
|
||||||
#define tls_tid (-7672)
|
#define tls_tid (-8480)
|
||||||
#define tls_ptid (5128)
|
#define tls_ptid (4320)
|
||||||
#define tls__ctinfo (-7664)
|
#define tls__ctinfo (-8472)
|
||||||
#define tls_p_ctinfo (5136)
|
#define tls_p_ctinfo (4328)
|
||||||
#define tls_andreas (-7656)
|
#define tls_andreas (-8464)
|
||||||
#define tls_pandreas (5144)
|
#define tls_pandreas (4336)
|
||||||
|
#define tls_pathbufs (-8456)
|
||||||
|
#define tls_ppathbufs (4344)
|
||||||
#define tls_wq (-7648)
|
#define tls_wq (-7648)
|
||||||
#define tls_pwq (5152)
|
#define tls_pwq (5152)
|
||||||
#define tls_sig (-7600)
|
#define tls_sig (-7600)
|
||||||
|
@ -217,10 +217,15 @@ getlogin_r (char *name, size_t namesize)
|
|||||||
size_t len = strlen (login) + 1;
|
size_t len = strlen (login) + 1;
|
||||||
if (len > namesize)
|
if (len > namesize)
|
||||||
return ERANGE;
|
return ERANGE;
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted ())
|
{
|
||||||
return EFAULT;
|
|
||||||
strncpy (name, login, len);
|
strncpy (name, login, len);
|
||||||
|
}
|
||||||
|
__except (NO_ERROR)
|
||||||
|
{
|
||||||
|
return EFAULT;
|
||||||
|
}
|
||||||
|
__endtry
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* uname.cc
|
/* uname.cc
|
||||||
|
|
||||||
Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
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
|
Written by Steve Chamberlain of Cygnus Support, sac@cygnus.com
|
||||||
Rewritten by Geoffrey Noer of Cygnus Solutions, noer@cygnus.com
|
Rewritten by Geoffrey Noer of Cygnus Solutions, noer@cygnus.com
|
||||||
|
|
||||||
@ -22,10 +22,8 @@ uname (struct utsname *name)
|
|||||||
{
|
{
|
||||||
SYSTEM_INFO sysinfo;
|
SYSTEM_INFO sysinfo;
|
||||||
|
|
||||||
myfault efault;
|
__try
|
||||||
if (efault.faulted (EFAULT))
|
{
|
||||||
return -1;
|
|
||||||
|
|
||||||
char *snp = strstr (cygwin_version.dll_build_date, "SNP");
|
char *snp = strstr (cygwin_version.dll_build_date, "SNP");
|
||||||
|
|
||||||
memset (name, 0, sizeof (*name));
|
memset (name, 0, sizeof (*name));
|
||||||
@ -90,6 +88,11 @@ uname (struct utsname *name)
|
|||||||
strcpy (name->machine, "unknown");
|
strcpy (name->machine, "unknown");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
__except (EFAULT)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
__endtry
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user