* Throughout, use __try/__except/__endtry blocks, rather than myfault
handler. * cygtls.cc (_cygtls::remove): Accommodate the fact that pathbufs has been moved from _local_storage to _cygtls. * cygtls.h (class tls_pathbuf): Add comment to hint to gendef usage of counters. Change type of counters to uint32_t for clarity. Remove _cygtls as friend class. (struct _local_storage): Move pathbufs from here... (struct _cygtls): ...to here, allowing to access it from _sigbe. (class san): Only define on 32 bit. Remove errno, _c_cnt and _w_cnt members. (san::setup): Drop parameter. Don't initialize removed members. (san::leave): Don't set removed members. (class myfault): Only define on 32 bit. (myfault::faulted): Only keep implementation not taking any parameter. Drop argument in call to sebastian.setup. (__try/__leave/__except/__endtry): Implement to support real SEH. For now stick to SJLJ on 32 bit. * dcrt0.cc (dll_crt0_0): Drop 64 bit call to exception::install_myfault_handler. * exception.h (exception_handler): Define with EXCEPTION_DISPOSITION as return type. (PDISPATCHER_CONTEXT): Define as void * on 32 bit. Define as pointer to _DISPATCHER_CONTEXT on 64 bit. (class exception): Define separately for 32 and 64 bit. (exception::myfault): Add handler for myfault SEH handling on 64 bit. (exception::exception): Fix mangled method name to account for change in type of last parameter. (exception::install_myfault_handler): Remove. * exceptions.cc (exception::myfault_handle): Remove. (exception::myfault): New SEH handler for 64 bit. * gendef (_sigbe): Set tls_pathbuf counters to 0 explicitely when returning to the caller. * ntdll.h: Move a comment to a better place. (struct _SCOPE_TABLE): Define on 64 bit. * thread.cc (verifyable_object_isvalid): Remove gcc 4.7 workaround. * tls_pbuf.cc (tls_pbuf): Fix to accommodate new place of pathbufs. (tls_pathbuf::destroy): Change type of loop variables to uint32_t. * tls_pbuf.h (class tmp_pathbuf): Change type of buffer counters to uint32_t. Accommodate new place of pathbufs. * tlsoffsets.h: Regenerate. * tlsoffsets64.h: Regenerate.
This commit is contained in:
parent
33ed7bb5bc
commit
3f3bd10104
|
@ -1,3 +1,48 @@
|
|||
2014-08-21 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* Throughout, use __try/__except/__endtry blocks, rather than myfault
|
||||
handler.
|
||||
* cygtls.cc (_cygtls::remove): Accommodate the fact that pathbufs
|
||||
has been moved from _local_storage to _cygtls.
|
||||
* cygtls.h (class tls_pathbuf): Add comment to hint to gendef usage
|
||||
of counters. Change type of counters to uint32_t for clarity.
|
||||
Remove _cygtls as friend class.
|
||||
(struct _local_storage): Move pathbufs from here...
|
||||
(struct _cygtls): ...to here, allowing to access it from _sigbe.
|
||||
(class san): Only define on 32 bit. Remove errno, _c_cnt and _w_cnt
|
||||
members.
|
||||
(san::setup): Drop parameter. Don't initialize removed members.
|
||||
(san::leave): Don't set removed members.
|
||||
(class myfault): Only define on 32 bit.
|
||||
(myfault::faulted): Only keep implementation not taking any parameter.
|
||||
Drop argument in call to sebastian.setup.
|
||||
(__try/__leave/__except/__endtry): Implement to support real SEH. For
|
||||
now stick to SJLJ on 32 bit.
|
||||
* dcrt0.cc (dll_crt0_0): Drop 64 bit call to
|
||||
exception::install_myfault_handler.
|
||||
* exception.h (exception_handler): Define with EXCEPTION_DISPOSITION
|
||||
as return type.
|
||||
(PDISPATCHER_CONTEXT): Define as void * on 32 bit. Define as pointer
|
||||
to _DISPATCHER_CONTEXT on 64 bit.
|
||||
(class exception): Define separately for 32 and 64 bit.
|
||||
(exception::myfault): Add handler for myfault SEH handling on 64 bit.
|
||||
(exception::exception): Fix mangled method name to account for change
|
||||
in type of last parameter.
|
||||
(exception::install_myfault_handler): Remove.
|
||||
* exceptions.cc (exception::myfault_handle): Remove.
|
||||
(exception::myfault): New SEH handler for 64 bit.
|
||||
* gendef (_sigbe): Set tls_pathbuf counters to 0 explicitely when
|
||||
returning to the caller.
|
||||
* ntdll.h: Move a comment to a better place.
|
||||
(struct _SCOPE_TABLE): Define on 64 bit.
|
||||
* thread.cc (verifyable_object_isvalid): Remove gcc 4.7 workaround.
|
||||
* tls_pbuf.cc (tls_pbuf): Fix to accommodate new place of pathbufs.
|
||||
(tls_pathbuf::destroy): Change type of loop variables to uint32_t.
|
||||
* tls_pbuf.h (class tmp_pathbuf): Change type of buffer counters to
|
||||
uint32_t. Accommodate new place of pathbufs.
|
||||
* tlsoffsets.h: Regenerate.
|
||||
* tlsoffsets64.h: Regenerate.
|
||||
|
||||
2014-08-21 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* miscfuncs.cc (__import_address): Cover the first dereference to imp
|
||||
|
|
|
@ -638,10 +638,7 @@ init_cygheap::find_tls (int sig, bool& issig_wait)
|
|||
_cygtls *t = NULL;
|
||||
issig_wait = false;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
threadlist[ix]->remove (INFINITE);
|
||||
else
|
||||
__try
|
||||
{
|
||||
ix = -1;
|
||||
/* Scan thread list looking for valid signal-delivery candidates */
|
||||
|
@ -652,11 +649,15 @@ init_cygheap::find_tls (int sig, bool& issig_wait)
|
|||
{
|
||||
t = cygheap->threadlist[ix];
|
||||
issig_wait = true;
|
||||
goto out;
|
||||
__leave;
|
||||
}
|
||||
else if (!t && !sigismember (&(threadlist[ix]->sigmask), sig))
|
||||
t = cygheap->threadlist[ix];
|
||||
}
|
||||
out:
|
||||
__except (NO_ERROR)
|
||||
{
|
||||
threadlist[ix]->remove (INFINITE);
|
||||
}
|
||||
__endtry
|
||||
return t;
|
||||
}
|
||||
|
|
|
@ -193,7 +193,7 @@ _cygtls::remove (DWORD wait)
|
|||
free_local (servent_buf);
|
||||
free_local (hostent_buf);
|
||||
/* Free temporary TLS path buffers. */
|
||||
locals.pathbufs.destroy ();
|
||||
pathbufs.destroy ();
|
||||
/* Close timer handle. */
|
||||
if (locals.cw_timer)
|
||||
NtClose (locals.cw_timer);
|
||||
|
|
|
@ -44,18 +44,21 @@ details. */
|
|||
#else
|
||||
#pragma pack(push,4)
|
||||
#endif
|
||||
|
||||
/* Defined here to support auto rebuild of tlsoffsets.h. */
|
||||
class tls_pathbuf
|
||||
{
|
||||
int c_cnt;
|
||||
int w_cnt;
|
||||
/* Make sure that c_cnt and w_cnt are always the first two members of this
|
||||
class, and never change the size (32 bit), unless you also change the
|
||||
mov statements in sigbe! */
|
||||
uint32_t c_cnt;
|
||||
uint32_t w_cnt;
|
||||
char *c_buf[TP_NUM_C_BUFS];
|
||||
WCHAR *w_buf[TP_NUM_W_BUFS];
|
||||
|
||||
public:
|
||||
void destroy ();
|
||||
friend class tmp_pathbuf;
|
||||
friend class _cygtls;
|
||||
friend class san;
|
||||
};
|
||||
|
||||
|
@ -129,8 +132,6 @@ struct _local_storage
|
|||
/* thread.cc */
|
||||
HANDLE cw_timer;
|
||||
|
||||
/* All functions requiring temporary path buffers. */
|
||||
tls_pathbuf pathbufs;
|
||||
char ttybuf[32];
|
||||
};
|
||||
|
||||
|
@ -188,6 +189,7 @@ public:
|
|||
struct pthread *tid;
|
||||
class cygthread *_ctinfo;
|
||||
class san *andreas;
|
||||
tls_pathbuf pathbufs;
|
||||
waitq wq;
|
||||
int sig;
|
||||
unsigned incyg;
|
||||
|
@ -281,34 +283,25 @@ const int CYGTLS_PADSIZE = 12700;
|
|||
extern PVOID _tlsbase __asm__ ("%fs:4");
|
||||
extern PVOID _tlstop __asm__ ("%fs:8");
|
||||
#endif
|
||||
|
||||
#define _my_tls (*((_cygtls *) ((char *)_tlsbase - CYGTLS_PADSIZE)))
|
||||
extern _cygtls *_main_tls;
|
||||
extern _cygtls *_sig_tls;
|
||||
|
||||
#ifndef __x86_64__
|
||||
class san
|
||||
{
|
||||
san *_clemente;
|
||||
jmp_buf _context;
|
||||
int _errno;
|
||||
unsigned _c_cnt;
|
||||
unsigned _w_cnt;
|
||||
public:
|
||||
int setup (int myerrno = 0) __attribute__ ((always_inline))
|
||||
int setup () __attribute__ ((always_inline))
|
||||
{
|
||||
_clemente = _my_tls.andreas;
|
||||
_my_tls.andreas = this;
|
||||
_errno = myerrno;
|
||||
_c_cnt = _my_tls.locals.pathbufs.c_cnt;
|
||||
_w_cnt = _my_tls.locals.pathbufs.w_cnt;
|
||||
return __sjfault (_context);
|
||||
}
|
||||
void leave () __attribute__ ((always_inline))
|
||||
{
|
||||
if (_errno)
|
||||
set_errno (_errno);
|
||||
/* Restore tls_pathbuf counters in case of error. */
|
||||
_my_tls.locals.pathbufs.c_cnt = _c_cnt;
|
||||
_my_tls.locals.pathbufs.w_cnt = _w_cnt;
|
||||
__ljfault (_context, 1);
|
||||
}
|
||||
void reset () __attribute__ ((always_inline))
|
||||
|
@ -324,17 +317,73 @@ public:
|
|||
~myfault () __attribute__ ((always_inline)) { sebastian.reset (); }
|
||||
inline int faulted () __attribute__ ((always_inline))
|
||||
{
|
||||
return sebastian.setup (0);
|
||||
}
|
||||
inline int faulted (void const *obj, int myerrno = 0) __attribute__ ((always_inline))
|
||||
{
|
||||
return !obj || !(*(const char **) obj) || sebastian.setup (myerrno);
|
||||
}
|
||||
inline int faulted (int myerrno) __attribute__ ((always_inline))
|
||||
{
|
||||
return sebastian.setup (myerrno);
|
||||
return sebastian.setup ();
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Exception handling macros. These are required because SEH differs a lot
|
||||
between 32 and 64 bit. Essentially, on 64 bit, we have to create compile
|
||||
time SEH tables which define the handler and try/except labels, while on
|
||||
32 bit we can simply set up an SJLJ handler within the myfault class. */
|
||||
#define __mem_barrier __asm__ __volatile__ ("" ::: "memory")
|
||||
#ifdef __x86_64__
|
||||
#define __try \
|
||||
{ \
|
||||
__label__ __l_try, __l_except, __l_endtry; \
|
||||
__mem_barrier; \
|
||||
__asm__ goto ("\n" \
|
||||
" .seh_handler _ZN9exception7myfaultEP17_EXCEPTION_RECORDPvP8_CONTEXTP19_DISPATCHER_CONTEXT, @except \n" \
|
||||
" .seh_handlerdata \n" \
|
||||
" .long 1 \n" \
|
||||
" .rva %l[__l_try],%l[__l_endtry],%l[__l_except],%l[__l_except] \n" \
|
||||
" .seh_code \n" \
|
||||
: : : : __l_try, __l_endtry, __l_except); \
|
||||
{ \
|
||||
__l_try: \
|
||||
__mem_barrier;
|
||||
|
||||
#define __leave \
|
||||
goto __l_endtry
|
||||
|
||||
#define __except(__errno) \
|
||||
goto __l_endtry; \
|
||||
} \
|
||||
{ \
|
||||
__l_except: \
|
||||
__mem_barrier; \
|
||||
if (__errno) \
|
||||
set_errno (__errno);
|
||||
|
||||
#define __endtry \
|
||||
} \
|
||||
__l_endtry: \
|
||||
__mem_barrier; \
|
||||
}
|
||||
|
||||
#else /* !__x86_64__ */
|
||||
#define __try \
|
||||
{ \
|
||||
myfault efault; \
|
||||
if (!efault.faulted ()) \
|
||||
{
|
||||
|
||||
#define __leave \
|
||||
goto __l_endtry
|
||||
|
||||
#define __except(__errno) \
|
||||
goto __l_endtry; \
|
||||
} \
|
||||
{ \
|
||||
if (__errno) \
|
||||
set_errno (__errno);
|
||||
|
||||
#define __endtry \
|
||||
} \
|
||||
__l_endtry: \
|
||||
__mem_barrier; \
|
||||
}
|
||||
#endif /* __x86_64__ */
|
||||
|
||||
class set_signal_arrived
|
||||
{
|
||||
|
|
|
@ -796,10 +796,6 @@ dll_crt0_0 ()
|
|||
|
||||
_main_tls = &_my_tls;
|
||||
|
||||
#ifdef __x86_64__
|
||||
exception::install_myfault_handler ();
|
||||
#endif
|
||||
|
||||
/* Initialize signal processing here, early, in the hopes that the creation
|
||||
of a thread early in the process will cause more predictability in memory
|
||||
layout for the main thread. */
|
||||
|
|
|
@ -28,16 +28,16 @@ details. */
|
|||
extern "C" int
|
||||
dirfd (DIR *dir)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
if (dir->__d_cookie != __DIRENT_COOKIE)
|
||||
__try
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
syscall_printf ("-1 = dirfd (%p)", dir);
|
||||
return -1;
|
||||
}
|
||||
if (dir->__d_cookie == __DIRENT_COOKIE)
|
||||
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
|
||||
|
@ -93,21 +93,22 @@ fdopendir (int fd)
|
|||
static int
|
||||
readdir_worker (DIR *dir, dirent *de)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
return EFAULT;
|
||||
int res = 0;
|
||||
|
||||
__try
|
||||
{
|
||||
if (dir->__d_cookie != __DIRENT_COOKIE)
|
||||
{
|
||||
syscall_printf ("%p = readdir (%p)", NULL, dir);
|
||||
return EBADF;
|
||||
res = EBADF;
|
||||
__leave;
|
||||
}
|
||||
|
||||
de->d_ino = 0;
|
||||
de->d_type = DT_UNKNOWN;
|
||||
memset (&de->__d_unused1, 0, sizeof (de->__d_unused1));
|
||||
|
||||
int res = ((fhandler_base *) dir->__fh)->readdir (dir, de);
|
||||
res = ((fhandler_base *) dir->__fh)->readdir (dir, de);
|
||||
|
||||
if (res == ENMFILE)
|
||||
{
|
||||
|
@ -141,7 +142,8 @@ readdir_worker (DIR *dir, dirent *de)
|
|||
}
|
||||
|
||||
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);
|
||||
else
|
||||
{
|
||||
|
@ -165,7 +167,12 @@ readdir_worker (DIR *dir, dirent *de)
|
|||
/* This fills out the old 32 bit d_ino field for old applications,
|
||||
build under Cygwin before 1.5.x. */
|
||||
de->__d_internal1 = de->d_ino;
|
||||
|
||||
}
|
||||
__except (NO_ERROR)
|
||||
{
|
||||
res = EFAULT;
|
||||
}
|
||||
__endtry
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -200,16 +207,15 @@ readdir_r (DIR *__restrict dir, dirent *__restrict de, dirent **__restrict ode)
|
|||
extern "C" long
|
||||
telldir (DIR *dir)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
if (dir->__d_cookie != __DIRENT_COOKIE)
|
||||
__try
|
||||
{
|
||||
set_errno (EBADF);
|
||||
return -1;
|
||||
}
|
||||
if (dir->__d_cookie == __DIRENT_COOKIE)
|
||||
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
|
||||
|
@ -225,14 +231,17 @@ telldir64 (DIR *dir)
|
|||
extern "C" void
|
||||
seekdir (DIR *dir, long loc)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return;
|
||||
|
||||
if (dir->__d_cookie != __DIRENT_COOKIE)
|
||||
return;
|
||||
__try
|
||||
{
|
||||
if (dir->__d_cookie == __DIRENT_COOKIE)
|
||||
{
|
||||
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
|
||||
|
@ -248,31 +257,27 @@ seekdir64 (DIR *dir, off_t loc)
|
|||
extern "C" void
|
||||
rewinddir (DIR *dir)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return;
|
||||
|
||||
if (dir->__d_cookie != __DIRENT_COOKIE)
|
||||
return;
|
||||
__try
|
||||
{
|
||||
if (dir->__d_cookie == __DIRENT_COOKIE)
|
||||
{
|
||||
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 */
|
||||
extern "C" int
|
||||
closedir (DIR *dir)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
if (dir->__d_cookie != __DIRENT_COOKIE)
|
||||
__try
|
||||
{
|
||||
if (dir->__d_cookie == __DIRENT_COOKIE)
|
||||
{
|
||||
set_errno (EBADF);
|
||||
syscall_printf ("%R = closedir(%p)", -1, dir);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Reset the marker in case the caller tries to use `dir' again. */
|
||||
dir->__d_cookie = 0;
|
||||
|
||||
|
@ -285,6 +290,13 @@ closedir (DIR *dir)
|
|||
syscall_printf ("%R = closedir(%p)", res, dir);
|
||||
return res;
|
||||
}
|
||||
set_errno (EBADF);
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
syscall_printf ("%R = closedir(%p)", -1, dir);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* mkdir: POSIX 5.4.1.1 */
|
||||
extern "C" int
|
||||
|
@ -294,10 +306,8 @@ mkdir (const char *dir, mode_t mode)
|
|||
fhandler_base *fh = NULL;
|
||||
tmp_pathbuf tp;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
__try
|
||||
{
|
||||
/* POSIX says mkdir("symlink-to-missing/") should create the
|
||||
directory "missing", but Linux rejects it with EEXIST. Copy
|
||||
Linux behavior for now. */
|
||||
|
@ -305,7 +315,7 @@ mkdir (const char *dir, mode_t mode)
|
|||
if (!*dir)
|
||||
{
|
||||
set_errno (ENOENT);
|
||||
goto done;
|
||||
__leave;
|
||||
}
|
||||
if (isdirsep (dir[strlen (dir) - 1]))
|
||||
{
|
||||
|
@ -317,7 +327,7 @@ mkdir (const char *dir, mode_t mode)
|
|||
*p-- = '\0';
|
||||
}
|
||||
if (!(fh = build_fh_name (dir, PC_SYM_NOFOLLOW)))
|
||||
goto done; /* errno already set */;
|
||||
__leave; /* errno already set */;
|
||||
|
||||
if (fh->error ())
|
||||
{
|
||||
|
@ -329,8 +339,9 @@ mkdir (const char *dir, mode_t mode)
|
|||
else if (!fh->mkdir (mode))
|
||||
res = 0;
|
||||
delete fh;
|
||||
|
||||
done:
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
syscall_printf ("%R = mkdir(%s, %d)", res, dir, mode);
|
||||
return res;
|
||||
}
|
||||
|
@ -342,12 +353,10 @@ rmdir (const char *dir)
|
|||
int res = -1;
|
||||
fhandler_base *fh = NULL;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
__try
|
||||
{
|
||||
if (!(fh = build_fh_name (dir, PC_SYM_NOFOLLOW)))
|
||||
goto done; /* errno already set */;
|
||||
__leave; /* errno already set */;
|
||||
|
||||
if (fh->error ())
|
||||
{
|
||||
|
@ -362,10 +371,10 @@ rmdir (const char *dir)
|
|||
set_errno (ENOTEMPTY);
|
||||
else if (!fh->rmdir ())
|
||||
res = 0;
|
||||
|
||||
delete fh;
|
||||
|
||||
done:
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
syscall_printf ("%R = rmdir(%s)", res, dir);
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
process's environment.
|
||||
|
||||
Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
|
||||
2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||
2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
This software is a copyrighted work licensed under the terms of the
|
||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||
|
@ -664,9 +664,8 @@ _addenv (const char *name, const char *value, int overwrite)
|
|||
extern "C" int
|
||||
putenv (char *str)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
__try
|
||||
{
|
||||
if (*str)
|
||||
{
|
||||
char *eq = strchr (str, '=');
|
||||
|
@ -678,22 +677,29 @@ putenv (char *str)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set the value of the environment variable "name" to be
|
||||
"value". If overwrite is set, replace any current value. */
|
||||
extern "C" int
|
||||
setenv (const char *name, const char *value, int overwrite)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
__try
|
||||
{
|
||||
if (!name || !*name || strchr (name, '='))
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
__leave;
|
||||
}
|
||||
return _addenv (name, value, !!overwrite);
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Delete environment variable "name". */
|
||||
extern "C" int
|
||||
|
@ -701,13 +707,13 @@ unsetenv (const char *name)
|
|||
{
|
||||
register char **e;
|
||||
int offset;
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
__try
|
||||
{
|
||||
if (!name || *name == '\0' || strchr (name, '='))
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
__leave;
|
||||
}
|
||||
|
||||
while (my_findenv (name, &offset)) /* if set multiple times */
|
||||
|
@ -718,6 +724,10 @@ unsetenv (const char *name)
|
|||
|
||||
return 0;
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Minimal list of Windows vars which must be converted to uppercase.
|
||||
Either for POSIX compatibility of for backward compatibility with
|
||||
|
@ -822,12 +832,10 @@ environ_init (char **envp, int envc)
|
|||
bool envp_passed_in;
|
||||
bool got_something_from_registry;
|
||||
static char NO_COPY cygterm[] = "TERM=cygwin";
|
||||
myfault efault;
|
||||
tmp_pathbuf tp;
|
||||
|
||||
if (efault.faulted ())
|
||||
api_fatal ("internal error reading the windows environment - too many environment variables?");
|
||||
|
||||
__try
|
||||
{
|
||||
char *tmpbuf = tp.t_get ();
|
||||
got_something_from_registry = regopt (L"default", tmpbuf);
|
||||
if (myself->progname[0])
|
||||
|
@ -913,6 +921,13 @@ out:
|
|||
environment */
|
||||
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. */
|
||||
static int
|
||||
|
|
|
@ -94,8 +94,10 @@ to install your own exception filter. This one is documented.
|
|||
a teensy bit of detail of the innards of exception handling (i.e. what we
|
||||
have to do). */
|
||||
|
||||
typedef int (exception_handler) (EXCEPTION_RECORD *, struct _exception_list *,
|
||||
CONTEXT *, void *);
|
||||
typedef EXCEPTION_DISPOSITION (exception_handler) (EXCEPTION_RECORD *,
|
||||
struct _exception_list *,
|
||||
CONTEXT *,
|
||||
void *);
|
||||
|
||||
typedef struct _exception_list
|
||||
{
|
||||
|
@ -104,70 +106,53 @@ typedef struct _exception_list
|
|||
} exception_list;
|
||||
|
||||
extern exception_list *_except_list asm ("%fs:0");
|
||||
#else
|
||||
typedef void exception_list;
|
||||
#endif /* !__x86_64 */
|
||||
typedef void *PDISPATCHER_CONTEXT;
|
||||
|
||||
class exception
|
||||
{
|
||||
#ifdef __x86_64__
|
||||
static LONG myfault_handle (LPEXCEPTION_POINTERS ep);
|
||||
#else
|
||||
exception_list el;
|
||||
exception_list *save;
|
||||
#endif /* __x86_64__ */
|
||||
static int handle (EXCEPTION_RECORD *, exception_list *, CONTEXT *, void *);
|
||||
static EXCEPTION_DISPOSITION handle (EXCEPTION_RECORD *, exception_list *,
|
||||
CONTEXT *, PDISPATCHER_CONTEXT);
|
||||
public:
|
||||
exception () __attribute__ ((always_inline))
|
||||
{
|
||||
/* Install SEH handler. */
|
||||
save = _except_list;
|
||||
el.handler = handle;
|
||||
el.prev = _except_list;
|
||||
_except_list = ⪙
|
||||
};
|
||||
~exception () __attribute__ ((always_inline)) { _except_list = save; }
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
#define exception_list void
|
||||
typedef struct _DISPATCHER_CONTEXT *PDISPATCHER_CONTEXT;
|
||||
|
||||
class exception
|
||||
{
|
||||
#ifdef __x86_64__
|
||||
static EXCEPTION_DISPOSITION myfault (EXCEPTION_RECORD *, exception_list *,
|
||||
CONTEXT *, PDISPATCHER_CONTEXT);
|
||||
#endif
|
||||
static EXCEPTION_DISPOSITION handle (EXCEPTION_RECORD *, exception_list *,
|
||||
CONTEXT *, PDISPATCHER_CONTEXT);
|
||||
public:
|
||||
exception () __attribute__ ((always_inline))
|
||||
{
|
||||
/* Install SEH handler. */
|
||||
asm volatile ("\n\
|
||||
1: \n\
|
||||
.seh_handler \
|
||||
_ZN9exception6handleEP17_EXCEPTION_RECORDPvP8_CONTEXTS2_, \
|
||||
_ZN9exception6handleEP17_EXCEPTION_RECORDPvP8_CONTEXTP19_DISPATCHER_CONTEXT, \
|
||||
@except \n\
|
||||
.seh_handlerdata \n\
|
||||
.long 1 \n\
|
||||
.rva 1b, 2f, 2f, 2f \n\
|
||||
.seh_code \n");
|
||||
#else
|
||||
save = _except_list;
|
||||
el.handler = handle;
|
||||
el.prev = _except_list;
|
||||
_except_list = ⪙
|
||||
#endif /* __x86_64__ */
|
||||
};
|
||||
#ifdef __x86_64__
|
||||
static void install_myfault_handler () __attribute__ ((always_inline))
|
||||
{
|
||||
/* Install myfault exception handler as VEH. Here's what happens:
|
||||
Some Windows DLLs (advapi32, for instance) are using SEH to catch
|
||||
exceptions inside its own functions. If we install a VEH handler
|
||||
to catch all exceptions, our Cygwin VEH handler would illegitimatly
|
||||
handle exceptions inside of Windows DLLs which are usually handled
|
||||
by its own SEH handler. So, for standard exceptions we use an SEH
|
||||
handler as installed in the constructor above so as not to override
|
||||
the SEH handlers in Windows DLLs.
|
||||
But we have a special case, myfault handling. The myfault handling
|
||||
catches exceptions inside of the Cygwin DLL, some of them entirely
|
||||
expected as in verifyable_object_isvalid. The ultimately right thing
|
||||
to do would be to install SEH handlers for each of these cases.
|
||||
But there are two problems with that:
|
||||
|
||||
1. It would be a massive and, partially unreliable change in the
|
||||
calling functions due to the incomplete SEH support in GCC.
|
||||
|
||||
2. It doesn't always work. Certain DLLs appear to call Cygwin
|
||||
functions during DLL initialization while the SEH handler is
|
||||
not installed in the active call frame. For these cases we
|
||||
need a more generic approach.
|
||||
|
||||
So, what we do here is to install a myfault VEH handler. This
|
||||
function is called from dll_crt0_0, so the myfault handler is
|
||||
available very early. */
|
||||
AddVectoredExceptionHandler (1, myfault_handle);
|
||||
}
|
||||
~exception () __attribute__ ((always_inline))
|
||||
{
|
||||
asm volatile ("\n\
|
||||
|
@ -175,11 +160,10 @@ public:
|
|||
2: \n\
|
||||
nop \n");
|
||||
}
|
||||
#else
|
||||
~exception () __attribute__ ((always_inline)) { _except_list = save; }
|
||||
#endif /* !__x86_64__ */
|
||||
};
|
||||
|
||||
#endif /* !__x86_64 */
|
||||
|
||||
class cygwin_exception
|
||||
{
|
||||
PUINT_PTR framep;
|
||||
|
|
|
@ -341,10 +341,9 @@ void
|
|||
cygwin_exception::dumpstack ()
|
||||
{
|
||||
static bool already_dumped;
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
return;
|
||||
|
||||
__try
|
||||
{
|
||||
if (already_dumped || cygheap->rlim_core == 0Ul)
|
||||
return;
|
||||
already_dumped = true;
|
||||
|
@ -366,7 +365,8 @@ cygwin_exception::dumpstack ()
|
|||
small_printf (_AFMT " " _AFMT, thestack.sf.AddrFrame.Offset,
|
||||
thestack.sf.AddrPC.Offset);
|
||||
for (unsigned j = 0; j < NPARAMS; j++)
|
||||
small_printf ("%s" _AFMT, j == 0 ? " (" : ", ", thestack.sf.Params[j]);
|
||||
small_printf ("%s" _AFMT, j == 0 ? " (" : ", ",
|
||||
thestack.sf.Params[j]);
|
||||
small_printf (")\r\n");
|
||||
}
|
||||
small_printf ("End of stack trace%s\n",
|
||||
|
@ -374,6 +374,9 @@ cygwin_exception::dumpstack ()
|
|||
if (h)
|
||||
NtClose (h);
|
||||
}
|
||||
__except (NO_ERROR) {}
|
||||
__endtry
|
||||
}
|
||||
|
||||
bool
|
||||
_cygtls::inside_kernel (CONTEXT *cx)
|
||||
|
@ -549,40 +552,24 @@ rtl_unwind (exception_list *frame, PEXCEPTION_RECORD e)
|
|||
#endif /* __x86_64 */
|
||||
|
||||
#ifdef __x86_64__
|
||||
/* myfault vectored exception handler */
|
||||
LONG
|
||||
exception::myfault_handle (LPEXCEPTION_POINTERS ep)
|
||||
/* myfault exception handler. */
|
||||
EXCEPTION_DISPOSITION
|
||||
exception::myfault (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in,
|
||||
PDISPATCHER_CONTEXT dispatch)
|
||||
{
|
||||
_cygtls& me = _my_tls;
|
||||
|
||||
if (me.andreas)
|
||||
{
|
||||
/* Only handle the minimum amount of exceptions the myfault handler
|
||||
was designed for. */
|
||||
switch (ep->ExceptionRecord->ExceptionCode)
|
||||
{
|
||||
case STATUS_ACCESS_VIOLATION:
|
||||
case STATUS_DATATYPE_MISALIGNMENT:
|
||||
#if 0
|
||||
/* PAGE_GUARD-based stack commits are based on structured exception
|
||||
handling. Short-circuiting STATUS_STACK_OVERFLOW in a vectored
|
||||
exception handler disables that, which can ultimately result in
|
||||
a spurious SEGV. */
|
||||
case STATUS_STACK_OVERFLOW:
|
||||
PSCOPE_TABLE table = (PSCOPE_TABLE) dispatch->HandlerData;
|
||||
RtlUnwindEx (frame,
|
||||
(char *) dispatch->ImageBase + table->ScopeRecord[0].JumpTarget,
|
||||
e, 0, in, dispatch->HistoryTable);
|
||||
/* NOTREACHED, make gcc happy. */
|
||||
return ExceptionContinueSearch;
|
||||
}
|
||||
#endif
|
||||
case STATUS_ARRAY_BOUNDS_EXCEEDED:
|
||||
me.andreas->leave (); /* Return from a "san" caught fault */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
#endif /* __x86_64 */
|
||||
|
||||
/* Main exception handler. */
|
||||
int
|
||||
exception::handle (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in, void *)
|
||||
EXCEPTION_DISPOSITION
|
||||
exception::handle (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in,
|
||||
PDISPATCHER_CONTEXT dispatch)
|
||||
{
|
||||
static bool NO_COPY debugging;
|
||||
_cygtls& me = _my_tls;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* fcntl.cc: fcntl syscall
|
||||
|
||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2008, 2009,
|
||||
2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||
2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -28,14 +28,13 @@ fcntl64 (int fd, int cmd, ...)
|
|||
|
||||
pthread_testcancel ();
|
||||
|
||||
debug_printf ("fcntl(%d, %d, ...)", fd, cmd);
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
__try
|
||||
{
|
||||
|
||||
debug_printf ("fcntl(%d, %d, ...)", fd, cmd);
|
||||
cygheap_fdget cfd (fd, true);
|
||||
if (cfd < 0)
|
||||
goto done;
|
||||
__leave;
|
||||
|
||||
/* FIXME? All numerical args to fcntl are defined as long on Linux.
|
||||
This relies on a really dirty trick on x86_64: A 32 bit mov to
|
||||
|
@ -48,8 +47,8 @@ fcntl64 (int fd, int cmd, ...)
|
|||
|
||||
However, the POSIX standard defines all numerical args as type int.
|
||||
If we take that literally, we had a (small) problem on 64 bit, since
|
||||
sizeof (void*) != sizeof (int). If we would like to follow POSIX
|
||||
more closely than Linux, we'd have to call va_arg on a per cmd basis. */
|
||||
sizeof (void*) != sizeof (int). If we would like to follow POSIX more
|
||||
closely than Linux, we'd have to call va_arg on a per cmd basis. */
|
||||
|
||||
va_start (args, cmd);
|
||||
arg = va_arg (args, intptr_t);
|
||||
|
@ -74,7 +73,9 @@ fcntl64 (int fd, int cmd, ...)
|
|||
res = cfd->fcntl (cmd, arg);
|
||||
break;
|
||||
}
|
||||
done:
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
syscall_printf ("%R = fcntl(%d, %d, %ly)", res, fd, cmd, arg);
|
||||
return res;
|
||||
}
|
||||
|
@ -91,10 +92,8 @@ _fcntl (int fd, int cmd, ...)
|
|||
struct __flock32 *src = NULL;
|
||||
struct flock dst;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
__try
|
||||
{
|
||||
va_start (args, cmd);
|
||||
arg = va_arg (args, intptr_t);
|
||||
va_end (args);
|
||||
|
@ -119,4 +118,8 @@ _fcntl (int fd, int cmd, ...)
|
|||
}
|
||||
return res;
|
||||
}
|
||||
__except (EFAULT)
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -2293,9 +2293,8 @@ fhandler_socket::getpeereid (pid_t *pid, uid_t *euid, gid_t *egid)
|
|||
return -1;
|
||||
}
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
__try
|
||||
{
|
||||
if (pid)
|
||||
*pid = sec_peer_pid;
|
||||
if (euid)
|
||||
|
@ -2304,3 +2303,7 @@ fhandler_socket::getpeereid (pid_t *pid, uid_t *euid, gid_t *egid)
|
|||
*egid = sec_peer_gid;
|
||||
return 0;
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
classes.
|
||||
|
||||
Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
|
||||
2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||
2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -977,9 +977,8 @@ mtinfo_drive::set_options (HANDLE mt, int32_t options)
|
|||
int
|
||||
mtinfo_drive::ioctl (HANDLE mt, unsigned int cmd, void *buf)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
return ERROR_NOACCESS;
|
||||
__try
|
||||
{
|
||||
if (cmd == MTIOCTOP)
|
||||
{
|
||||
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);
|
||||
else if (cmd == MTIOCPOS && !get_pos (mt))
|
||||
((struct mtpos *) buf)->mt_blkno = (long) block;
|
||||
|
||||
}
|
||||
__except (NO_ERROR)
|
||||
{
|
||||
lasterr = ERROR_NOACCESS;
|
||||
}
|
||||
__endtry
|
||||
return lasterr;
|
||||
}
|
||||
|
||||
|
|
|
@ -1761,13 +1761,11 @@ flock (int fd, int operation)
|
|||
int cmd;
|
||||
struct flock fl = { 0, SEEK_SET, 0, 0, 0 };
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
__try
|
||||
{
|
||||
cygheap_fdget cfd (fd, true);
|
||||
if (cfd < 0)
|
||||
goto done;
|
||||
__leave;
|
||||
|
||||
cmd = (operation & LOCK_NB) ? F_SETLK : F_SETLKW;
|
||||
switch (operation & (~LOCK_NB))
|
||||
|
@ -1783,7 +1781,7 @@ flock (int fd, int operation)
|
|||
break;
|
||||
default:
|
||||
set_errno (EINVAL);
|
||||
goto done;
|
||||
__leave;
|
||||
}
|
||||
if (!cfd->mandatory_locking ())
|
||||
fl.l_type |= F_FLOCK;
|
||||
|
@ -1791,7 +1789,9 @@ flock (int fd, int operation)
|
|||
: cfd->lock (cmd, &fl);
|
||||
if ((res == -1) && ((get_errno () == EAGAIN) || (get_errno () == EACCES)))
|
||||
set_errno (EWOULDBLOCK);
|
||||
done:
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
syscall_printf ("%R = flock(%d, %d)", res, fd, operation);
|
||||
return res;
|
||||
}
|
||||
|
@ -1805,13 +1805,11 @@ lockf (int filedes, int function, off_t size)
|
|||
|
||||
pthread_testcancel ();
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
__try
|
||||
{
|
||||
cygheap_fdget cfd (filedes, true);
|
||||
if (cfd < 0)
|
||||
goto done;
|
||||
__leave;
|
||||
|
||||
fl.l_start = 0;
|
||||
fl.l_len = size;
|
||||
|
@ -1834,21 +1832,23 @@ lockf (int filedes, int function, off_t size)
|
|||
case F_TEST:
|
||||
fl.l_type = F_WRLCK;
|
||||
if (cfd->lock (F_GETLK, &fl) == -1)
|
||||
goto done;
|
||||
__leave;
|
||||
if (fl.l_type == F_UNLCK || fl.l_pid == getpid ())
|
||||
res = 0;
|
||||
else
|
||||
errno = EAGAIN;
|
||||
goto done;
|
||||
__leave;
|
||||
/* NOTREACHED */
|
||||
default:
|
||||
errno = EINVAL;
|
||||
goto done;
|
||||
__leave;
|
||||
/* NOTREACHED */
|
||||
}
|
||||
res = cfd->mandatory_locking () ? cfd->mand_lock (cmd, &fl)
|
||||
: cfd->lock (cmd, &fl);
|
||||
done:
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
syscall_printf ("%R = lockf(%d, %d, %D)", res, filedes, function, size);
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#!/usr/bin/perl
|
||||
# Copyright 2003, 2004, 2005, 2006, 2008, 2009, 2010, 2011, 2012, 2013
|
||||
# Copyright 2003, 2004, 2005, 2006, 2008, 2009, 2010, 2011, 2012, 2013, 2014
|
||||
# Red Hat, Inc.
|
||||
#
|
||||
# This file is part of Cygwin.
|
||||
|
@ -181,6 +181,8 @@ _sigbe: # return here after cygwin syscall
|
|||
movq -8(%r11),%r11 # get return address from signal stack
|
||||
decl $tls::incyg(%r10)
|
||||
decl $tls::stacklock(%r10) # release lock
|
||||
leaq $tls::pathbufs(%r10),%r10 # Address of tls_pathbufs
|
||||
movq \$0,(%r10) # Set c_cnt and w_cnt to 0
|
||||
jmp *%r11 # "return" to caller
|
||||
.seh_endproc
|
||||
|
||||
|
@ -445,6 +447,9 @@ __sigbe: # return here after cygwin syscall
|
|||
xchgl %eax,4(%esp) # swap return address with saved eax
|
||||
decl $tls::incyg(%ebx)
|
||||
decl $tls::stacklock(%ebx) # release lock
|
||||
leal $tls::pathbufs(%ebx),%ebx # Address of tls_pathbufs
|
||||
movl \$0,(%ebx) # Set c_cnt to 0
|
||||
movl \$0,4(%ebx) # Set w_cnt to 0
|
||||
popl %ebx
|
||||
ret
|
||||
|
||||
|
|
|
@ -249,8 +249,7 @@ getprogname (void)
|
|||
extern "C" void
|
||||
setprogname (const char *newprogname)
|
||||
{
|
||||
myfault efault;
|
||||
if (!efault.faulted (EFAULT))
|
||||
__try
|
||||
{
|
||||
/* Per BSD man page, setprogname keeps a pointer to the last
|
||||
path component of the argument. It does *not* copy the
|
||||
|
@ -261,6 +260,8 @@ setprogname (const char *newprogname)
|
|||
else
|
||||
__progname = (char *)newprogname;
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
|
|
|
@ -319,10 +319,8 @@ cygwin_rexec (char **ahost, unsigned short rport, char *name, char *pass,
|
|||
char c;
|
||||
static char ahostbuf[INTERNET_MAX_HOST_NAME_LENGTH + 1];
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
__try
|
||||
{
|
||||
hp = cygwin_gethostbyname(*ahost);
|
||||
if (hp == 0) {
|
||||
cygwin_herror(*ahost);
|
||||
|
@ -407,5 +405,8 @@ bad:
|
|||
if (port)
|
||||
(void) close(*fd2p);
|
||||
(void) close(s);
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return (-1);
|
||||
}
|
||||
|
|
|
@ -202,9 +202,8 @@ check_iovec (const struct iovec *iov, int iovcnt, bool forwrite)
|
|||
return -1;
|
||||
}
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
__try
|
||||
{
|
||||
|
||||
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)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
__leave;
|
||||
}
|
||||
|
||||
volatile char *p = ((char *) iov->iov_base) + iov->iov_len - 1;
|
||||
|
@ -232,6 +231,10 @@ check_iovec (const struct iovec *iov, int iovcnt, bool forwrite)
|
|||
|
||||
return (ssize_t) tot;
|
||||
}
|
||||
__except (EFAULT)
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Try hard to schedule another thread.
|
||||
Remember not to call this in a lock condition or you'll potentially
|
||||
|
@ -512,19 +515,24 @@ slashify (const char *src, char *dst, bool trailing_slash_p)
|
|||
void * __reg1
|
||||
__import_address (void *imp)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
return NULL;
|
||||
if (*((uint16_t *) imp) != 0x25ff)
|
||||
return NULL;
|
||||
__try
|
||||
{
|
||||
if (*((uint16_t *) imp) == 0x25ff)
|
||||
{
|
||||
const char *ptr = (const char *) imp;
|
||||
#ifdef __x86_64__
|
||||
const uintptr_t *jmpto = (uintptr_t *) (ptr + 6 + *(int32_t *)(ptr + 2));
|
||||
const uintptr_t *jmpto = (uintptr_t *)
|
||||
(ptr + 6 + *(int32_t *)(ptr + 2));
|
||||
#else
|
||||
const uintptr_t *jmpto = (uintptr_t *) *((uintptr_t *) (ptr + 2));
|
||||
#endif
|
||||
return (void *) *jmpto;
|
||||
}
|
||||
}
|
||||
__except (NO_ERROR) {}
|
||||
__endtry
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* CygwinCreateThread.
|
||||
|
||||
|
|
|
@ -1700,10 +1700,9 @@ mount (const char *win32_path, const char *posix_path, unsigned flags)
|
|||
isn't really supported except from fstab? */
|
||||
int res = -1;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
/* errno set */;
|
||||
else if (!*posix_path)
|
||||
__try
|
||||
{
|
||||
if (!*posix_path)
|
||||
set_errno (EINVAL);
|
||||
else if (strpbrk (posix_path, "\\:"))
|
||||
set_errno (EINVAL);
|
||||
|
@ -1738,12 +1737,17 @@ mount (const char *win32_path, const char *posix_path, unsigned flags)
|
|||
flags = (MOUNT_BIND | conv_flags)
|
||||
& ~(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;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1755,16 +1759,19 @@ mount (const char *win32_path, const char *posix_path, unsigned flags)
|
|||
extern "C" int
|
||||
umount (const char *path)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
__try
|
||||
{
|
||||
if (!*path)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
__leave;
|
||||
}
|
||||
return cygwin_umount (path, 0);
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* cygwin_umount: This is like umount but takes an additional flags
|
||||
parameter that specifies whether to umount from the user or system-wide
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* msg.cc: XSI IPC interface for Cygwin.
|
||||
|
||||
Copyright 2002, 2003, 2004, 2005, 2008, 2009 Red Hat, Inc.
|
||||
Copyright 2002, 2003, 2004, 2005, 2008, 2009, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -91,11 +91,9 @@ client_request_msg::client_request_msg (int msqid,
|
|||
extern "C" int
|
||||
msgctl (int msqid, int cmd, struct msqid_ds *buf)
|
||||
{
|
||||
syscall_printf ("msgctl (msqid = %d, cmd = %y, buf = %p)",
|
||||
msqid, cmd, buf);
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
syscall_printf ("msgctl (msqid = %d, cmd = %y, buf = %p)", msqid, cmd, buf);
|
||||
__try
|
||||
{
|
||||
switch (cmd)
|
||||
{
|
||||
case IPC_STAT:
|
||||
|
@ -111,7 +109,7 @@ msgctl (int msqid, int cmd, struct msqid_ds *buf)
|
|||
default:
|
||||
syscall_printf ("-1 [%d] = msgctl ()", EINVAL);
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
__leave;
|
||||
}
|
||||
client_request_msg request (msqid, cmd, buf);
|
||||
if (request.make_request () == -1 || request.retval () == -1)
|
||||
|
@ -120,10 +118,14 @@ msgctl (int msqid, int cmd, struct msqid_ds *buf)
|
|||
set_errno (request.error_code ());
|
||||
if (request.error_code () == ENOSYS)
|
||||
raise (SIGSYS);
|
||||
return -1;
|
||||
__leave;
|
||||
}
|
||||
return request.retval ();
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
msgget (key_t key, int msgflg)
|
||||
|
@ -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, "
|
||||
"msgtyp = %d, msgflg = %y)",
|
||||
msqid, msgp, msgsz, msgtyp, msgflg);
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
__try
|
||||
{
|
||||
client_request_msg request (msqid, msgp, msgsz, msgtyp, msgflg);
|
||||
if (request.make_request () == -1 || request.rcvval () == -1)
|
||||
{
|
||||
|
@ -157,19 +158,22 @@ msgrcv (int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg)
|
|||
set_errno (request.error_code ());
|
||||
if (request.error_code () == ENOSYS)
|
||||
raise (SIGSYS);
|
||||
return -1;
|
||||
__leave;
|
||||
}
|
||||
return request.rcvval ();
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
msgsnd (int msqid, const void *msgp, size_t msgsz, int msgflg)
|
||||
{
|
||||
syscall_printf ("msgsnd (msqid = %d, msgp = %p, msgsz = %ld, msgflg = %y)",
|
||||
msqid, msgp, msgsz, msgflg);
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
__try
|
||||
{
|
||||
client_request_msg request (msqid, msgp, msgsz, msgflg);
|
||||
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 ());
|
||||
if (request.error_code () == ENOSYS)
|
||||
raise (SIGSYS);
|
||||
return -1;
|
||||
__leave;
|
||||
}
|
||||
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.
|
||||
|
||||
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||
2011, 2012, 2013 Red Hat, Inc.
|
||||
2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -1180,8 +1180,19 @@ typedef enum _SECTION_INHERIT
|
|||
|
||||
typedef VOID (APIENTRY *PTIMER_APC_ROUTINE)(PVOID, ULONG, ULONG);
|
||||
|
||||
/* Function declarations for ntdll.dll. These don't appear in any
|
||||
standard Win32 header. */
|
||||
#ifdef __x86_64__
|
||||
typedef struct _SCOPE_TABLE
|
||||
{
|
||||
ULONG Count;
|
||||
struct
|
||||
{
|
||||
ULONG BeginAddress;
|
||||
ULONG EndAddress;
|
||||
ULONG HandlerAddress;
|
||||
ULONG JumpTarget;
|
||||
} ScopeRecord[1];
|
||||
} SCOPE_TABLE, *PSCOPE_TABLE;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* This is the mapping of the KUSER_SHARED_DATA structure into the user
|
||||
|
@ -1190,6 +1201,9 @@ typedef VOID (APIENTRY *PTIMER_APC_ROUTINE)(PVOID, ULONG, ULONG);
|
|||
static volatile KUSER_SHARED_DATA &SharedUserData
|
||||
= *(volatile KUSER_SHARED_DATA *) 0x7ffe0000;
|
||||
|
||||
/* Function declarations for ntdll.dll. These don't appear in any
|
||||
standard Win32 header. */
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
|
|
@ -60,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. */
|
||||
char lastname[MAX_EA_NAME_LEN];
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
goto out;
|
||||
|
||||
__try
|
||||
{
|
||||
pc.get_object_attr (attr, sec_none_nih);
|
||||
|
||||
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)
|
||||
{
|
||||
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))
|
||||
{
|
||||
__seterrno_from_nt_status (status);
|
||||
goto out;
|
||||
__leave;
|
||||
}
|
||||
hdl = NULL;
|
||||
}
|
||||
|
@ -97,7 +96,7 @@ read_ea (HANDLE hdl, path_conv &pc, const char *name, char *value, size_t size)
|
|||
else
|
||||
{
|
||||
set_errno (ENOTSUP);
|
||||
goto out;
|
||||
__leave;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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))
|
||||
break;
|
||||
hdl = NULL;
|
||||
|
@ -140,23 +140,25 @@ read_ea (HANDLE hdl, path_conv &pc, const char *name, char *value, size_t size)
|
|||
break;
|
||||
case STATUS_NOT_FOUND:
|
||||
/* STATUS_NOT_FOUND is returned when calling NtQueryEaFile on NFS.
|
||||
In theory this should mean that the file just has no EAs, but in
|
||||
fact NFS doesn't support EAs, other than the EAs which are used
|
||||
for NFS requests. We're playing safe and convert STATUS_NOT_FOUND
|
||||
to ENOATTR, unless we're on NFS, where we convert it to ENOTSUP. */
|
||||
In theory this should mean that the file just has no EAs, but
|
||||
in fact NFS doesn't support EAs, other than the EAs which are
|
||||
used for NFS requests. We're playing safe and convert
|
||||
STATUS_NOT_FOUND to ENOATTR, unless we're on NFS, where we
|
||||
convert it to ENOTSUP. */
|
||||
set_errno (pc.fs_is_nfs () ? ENOTSUP : ENOATTR);
|
||||
break;
|
||||
case STATUS_NONEXISTENT_EA_ENTRY:
|
||||
/* Actually STATUS_NONEXISTENT_EA_ENTRY is either never generated, or
|
||||
it was only generated in some old and long forgotton NT version.
|
||||
See below. For safty reasons, we handle it here, nevertheless. */
|
||||
/* Actually STATUS_NONEXISTENT_EA_ENTRY is either never generated,
|
||||
or it was only generated in some old and long forgotton NT
|
||||
version. See below. For safty reasons, we handle it here,
|
||||
nevertheless. */
|
||||
set_errno (ENOATTR);
|
||||
break;
|
||||
default:
|
||||
__seterrno_from_nt_status (status);
|
||||
break;
|
||||
}
|
||||
goto out;
|
||||
__leave;
|
||||
}
|
||||
if (name)
|
||||
{
|
||||
|
@ -168,14 +170,14 @@ read_ea (HANDLE hdl, path_conv &pc, const char *name, char *value, size_t size)
|
|||
if (!fea->EaValueLength)
|
||||
{
|
||||
set_errno (ENOATTR);
|
||||
goto out;
|
||||
__leave;
|
||||
}
|
||||
if (size > 0)
|
||||
{
|
||||
if (size < fea->EaValueLength)
|
||||
{
|
||||
set_errno (ERANGE);
|
||||
goto out;
|
||||
__leave;
|
||||
}
|
||||
memcpy (value, fea->EaName + fea->EaNameLength + 1,
|
||||
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)
|
||||
{
|
||||
set_errno (ERANGE);
|
||||
goto out;
|
||||
__leave;
|
||||
}
|
||||
/* For compatibility with Linux, we always prepend "user." to
|
||||
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 *tp = stpcpy (tmpbuf, "user.");
|
||||
stpcpy (tp, fea->EaName);
|
||||
/* NTFS stores all EA names in uppercase unfortunately. To keep
|
||||
compatibility with ext/xfs EA namespaces and accompanying
|
||||
tools, which expect the namespaces to be lower case, we return
|
||||
EA names in lowercase if the file is on a native NTFS. */
|
||||
/* NTFS stores all EA names in uppercase unfortunately. To
|
||||
keep compatibility with ext/xfs EA namespaces and
|
||||
accompanying tools, which expect the namespaces to be
|
||||
lower case, we return EA names in lowercase if the file
|
||||
is on a native NTFS. */
|
||||
if (pc.fs_is_ntfs ())
|
||||
strlwr (tp);
|
||||
tp = stpcpy (value, tmpbuf) + 1;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
out:
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
if (!hdl)
|
||||
CloseHandle (h);
|
||||
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;
|
||||
size_t nlen;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
goto out;
|
||||
|
||||
__try
|
||||
{
|
||||
pc.get_object_attr (attr, sec_none_nih);
|
||||
|
||||
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)
|
||||
{
|
||||
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))
|
||||
{
|
||||
__seterrno_from_nt_status (status);
|
||||
goto out;
|
||||
__leave;
|
||||
}
|
||||
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))
|
||||
{
|
||||
set_errno (ENOTSUP);
|
||||
goto out;
|
||||
__leave;
|
||||
}
|
||||
|
||||
/* removexattr is supposed to fail with ENOATTR if the requested EA is not
|
||||
available. This is equivalent to the XATTR_REPLACE flag for setxattr. */
|
||||
/* removexattr is supposed to fail with ENOATTR if the requested EA is
|
||||
not available. This is equivalent to XATTR_REPLACE for setxattr. */
|
||||
if (!value)
|
||||
flags = XATTR_REPLACE;
|
||||
|
||||
|
@ -283,16 +286,16 @@ write_ea (HANDLE hdl, path_conv &pc, const char *name, const char *value,
|
|||
if (flags != XATTR_CREATE && flags != XATTR_REPLACE)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
goto out;
|
||||
__leave;
|
||||
}
|
||||
ssize_t rret = read_ea (hdl, pc, name, NULL, 0);
|
||||
if (flags == XATTR_CREATE && rret > 0)
|
||||
{
|
||||
set_errno (EEXIST);
|
||||
goto out;
|
||||
__leave;
|
||||
}
|
||||
if (flags == XATTR_REPLACE && rret < 0)
|
||||
goto out;
|
||||
__leave;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
goto out;
|
||||
__leave;
|
||||
}
|
||||
flen = sizeof (FILE_FULL_EA_INFORMATION) + nlen + 1 + size;
|
||||
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;
|
||||
}
|
||||
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))
|
||||
break;
|
||||
hdl = NULL;
|
||||
|
@ -332,15 +336,15 @@ write_ea (HANDLE hdl, path_conv &pc, const char *name, const char *value,
|
|||
switch (status)
|
||||
{
|
||||
case STATUS_EA_TOO_LARGE:
|
||||
/* STATUS_EA_TOO_LARGE has a matching Win32 error ERROR_EA_TABLE_FULL.
|
||||
For some unknown reason RtlNtStatusToDosError does not translate
|
||||
STATUS_EA_TOO_LARGE to ERROR_EA_TABLE_FULL, but instead to
|
||||
ERROR_EA_LIST_INCONSISTENT. This error code is also returned for
|
||||
STATUS_EA_LIST_INCONSISTENT, which means the incoming EA list is...
|
||||
inconsistent. For obvious reasons we translate
|
||||
ERROR_EA_LIST_INCONSISTENT to EINVAL, so we have to handle
|
||||
STATUS_EA_TOO_LARGE explicitely here, to get the correct mapping
|
||||
to ENOSPC. */
|
||||
/* STATUS_EA_TOO_LARGE has a matching Win32 error code
|
||||
ERROR_EA_TABLE_FULL. For some reason RtlNtStatusToDosError
|
||||
does not translate STATUS_EA_TOO_LARGE to ERROR_EA_TABLE_FULL,
|
||||
but instead to ERROR_EA_LIST_INCONSISTENT. This error code is
|
||||
also returned for STATUS_EA_LIST_INCONSISTENT, which means the
|
||||
incoming EA list is... inconsistent. For obvious reasons we
|
||||
translate ERROR_EA_LIST_INCONSISTENT to EINVAL, so we have to
|
||||
handle STATUS_EA_TOO_LARGE explicitely here, to get the correct
|
||||
mapping to ENOSPC. */
|
||||
set_errno (ENOSPC);
|
||||
break;
|
||||
case STATUS_INVALID_DEVICE_REQUEST:
|
||||
|
@ -353,8 +357,9 @@ write_ea (HANDLE hdl, path_conv &pc, const char *name, const char *value,
|
|||
}
|
||||
else
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
if (!hdl)
|
||||
CloseHandle (h);
|
||||
debug_printf ("%d = write_ea(%S, %s, %p, %lu, %d)",
|
||||
|
|
|
@ -651,12 +651,8 @@ path_conv::check (const char *src, unsigned opt,
|
|||
}
|
||||
#endif
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
__try
|
||||
{
|
||||
error = EFAULT;
|
||||
return;
|
||||
}
|
||||
int loop = 0;
|
||||
path_flags = 0;
|
||||
known_suffix = NULL;
|
||||
|
@ -706,9 +702,9 @@ path_conv::check (const char *src, unsigned opt,
|
|||
error = 0;
|
||||
}
|
||||
|
||||
/* Detect if the user was looking for a directory. We have to strip the
|
||||
trailing slash initially while trying to add extensions but take it
|
||||
into account during processing */
|
||||
/* Detect if the user was looking for a directory. We have to strip
|
||||
the trailing slash initially while trying to add extensions but
|
||||
take it into account during processing */
|
||||
if (tail > path_copy + 2 && isslash (tail[-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. */
|
||||
error = mount_table->conv_to_win32_path (path_copy, full_path, dev,
|
||||
&sym.pflags);
|
||||
error = mount_table->conv_to_win32_path (path_copy, full_path,
|
||||
dev, &sym.pflags);
|
||||
|
||||
if (error)
|
||||
return;
|
||||
|
@ -765,7 +761,8 @@ path_conv::check (const char *src, unsigned opt,
|
|||
if (iscygdrive_dev (dev))
|
||||
{
|
||||
if (!component)
|
||||
fileattr = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_READONLY;
|
||||
fileattr = FILE_ATTRIBUTE_DIRECTORY
|
||||
| FILE_ATTRIBUTE_READONLY;
|
||||
else
|
||||
{
|
||||
fileattr = getfileattr (THIS_path,
|
||||
|
@ -776,12 +773,14 @@ path_conv::check (const char *src, unsigned opt,
|
|||
}
|
||||
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))
|
||||
{
|
||||
/* FIXME: Calling build_fhandler here is not the right way to handle this. */
|
||||
fhandler_virtual *fh = (fhandler_virtual *) build_fh_dev (dev, path_copy);
|
||||
/* FIXME: Calling build_fhandler here is not the right way to
|
||||
handle this. */
|
||||
fhandler_virtual *fh = (fhandler_virtual *)
|
||||
build_fh_dev (dev, path_copy);
|
||||
virtual_ftype_t file_type;
|
||||
if (!fh)
|
||||
file_type = virt_none;
|
||||
|
@ -832,8 +831,8 @@ path_conv::check (const char *src, unsigned opt,
|
|||
case virt_blk:
|
||||
/* Block special device. If the trailing slash has been
|
||||
requested, the target is the root directory of the
|
||||
filesystem on this block device. So we convert this to
|
||||
a real file and attach the backslash. */
|
||||
filesystem on this block device. So we convert this
|
||||
to a real file and attach the backslash. */
|
||||
if (component == 0 && need_directory)
|
||||
{
|
||||
dev.parse (FH_FS);
|
||||
|
@ -856,7 +855,7 @@ path_conv::check (const char *src, unsigned opt,
|
|||
path_flags |= PATH_RO;
|
||||
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)
|
||||
{
|
||||
fileattr = 0;
|
||||
|
@ -928,15 +927,15 @@ is_virtual_symlink:
|
|||
}
|
||||
else if (isdev_dev (dev))
|
||||
{
|
||||
/* If we're looking for a file below /dev, which doesn't exist,
|
||||
make sure that the device type is converted to FH_FS, so that
|
||||
subsequent code handles the file correctly.
|
||||
Unless /dev itself doesn't exist on disk. In that case /dev
|
||||
is handled as virtual filesystem, and virtual filesystems are
|
||||
read-only. The PC_KEEP_HANDLE check allows to check for
|
||||
a call from an informational system call. In that case we
|
||||
just stick to ENOENT, and the device type doesn't matter
|
||||
anyway. */
|
||||
/* If we're looking for a non-existing file below /dev,
|
||||
make sure that the device type is converted to FH_FS, so
|
||||
that subsequent code handles the file correctly. Unless
|
||||
/dev itself doesn't exist on disk. In that case /dev
|
||||
is handled as virtual filesystem, and virtual filesystems
|
||||
are read-only. The PC_KEEP_HANDLE check allows to check
|
||||
for a call from an informational system call. In that
|
||||
case we just stick to ENOENT, and the device type doesn't
|
||||
matter anyway. */
|
||||
if (sym.error == ENOENT && !(opt & PC_KEEP_HANDLE))
|
||||
sym.error = EROFS;
|
||||
else
|
||||
|
@ -968,9 +967,11 @@ is_virtual_symlink:
|
|||
saw_symlinks = 1;
|
||||
if (component == 0 && !need_directory
|
||||
&& (!(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)
|
||||
{
|
||||
strcpy (THIS_path, sym.contents);
|
||||
|
@ -979,8 +980,8 @@ is_virtual_symlink:
|
|||
add_ext = true;
|
||||
goto out;
|
||||
}
|
||||
/* Following a symlink we can't trust the collected filesystem
|
||||
information any longer. */
|
||||
/* Following a symlink we can't trust the collected
|
||||
filesystem information any longer. */
|
||||
fs.clear ();
|
||||
/* Close handle, if we have any. Otherwise we're collecting
|
||||
handles while following symlinks. */
|
||||
|
@ -1021,14 +1022,16 @@ virtual_component_retry:
|
|||
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;
|
||||
if (isabspath (sym.contents))
|
||||
headptr = tmp_buf; /* absolute path */
|
||||
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;
|
||||
while (--prevtail > path_copy && *prevtail != '/') {}
|
||||
int headlen = prevtail - path_copy + 1;;
|
||||
|
@ -1098,7 +1101,8 @@ out:
|
|||
else if (!need_directory || error)
|
||||
/* nothing to do */;
|
||||
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)
|
||||
path_flags &= ~PATH_SYMLINK;
|
||||
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))
|
||||
{
|
||||
/* Incoming DOS paths are treated like DOS paths in native
|
||||
Windows applications. No ACLs, just default settings. */
|
||||
if (is_msdos)
|
||||
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
|
||||
we don't forget that the PATH_NOACL flag must be taken into
|
||||
account here. */
|
||||
if (!(path_flags & PATH_NOACL) && fs.has_acls ())
|
||||
set_exec (0); /* We really don't know if this is executable or not here
|
||||
but set it to not executable since it will be figured out
|
||||
later by anything which cares about this. */
|
||||
set_exec (0); /* We really don't know if this is executable or
|
||||
not here but set it to not executable since
|
||||
it will be figured out later by anything
|
||||
which cares about this. */
|
||||
}
|
||||
/* If the FS has been found to have unrelibale inodes, note
|
||||
that in path_flags. */
|
||||
|
@ -1207,6 +1214,12 @@ out:
|
|||
}
|
||||
#endif
|
||||
}
|
||||
__except (NO_ERROR)
|
||||
{
|
||||
error = EFAULT;
|
||||
}
|
||||
__endtry
|
||||
}
|
||||
|
||||
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
|
||||
'oldpath' is valid -- it's symlink resolver job to verify if
|
||||
symlink contents point to existing filesystem object */
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
goto done;
|
||||
__try
|
||||
{
|
||||
if (!*oldpath || !*newpath)
|
||||
{
|
||||
set_errno (ENOENT);
|
||||
goto done;
|
||||
__leave;
|
||||
}
|
||||
|
||||
if (strlen (oldpath) > SYMLINK_MAX)
|
||||
{
|
||||
set_errno (ENAMETOOLONG);
|
||||
goto done;
|
||||
__leave;
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
win32_newpath.check (newpath, check_opt, stat_suffixes);
|
||||
|
||||
/* Default symlink type is determined by global allow_winsymlinks variable.
|
||||
Device files are always shortcuts. */
|
||||
/* Default symlink type is determined by global allow_winsymlinks
|
||||
variable. Device files are always shortcuts. */
|
||||
wsym_type = isdevice ? WSYM_lnk : allow_winsymlinks;
|
||||
/* NFS has its own, dedicated way to create symlinks. */
|
||||
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)
|
||||
{
|
||||
set_errno (EPERM);
|
||||
goto done;
|
||||
__leave;
|
||||
}
|
||||
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)
|
||||
&& !(win32_newpath.fs_flags () & FILE_SUPPORTS_REPARSE_POINTS))
|
||||
wsym_type = WSYM_sysfile;
|
||||
|
@ -1754,7 +1766,7 @@ symlink_worker (const char *oldpath, const char *newpath, bool isdevice)
|
|||
if (win32_newpath.error)
|
||||
{
|
||||
set_errno (win32_newpath.error);
|
||||
goto done;
|
||||
__leave;
|
||||
}
|
||||
|
||||
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 ())
|
||||
{
|
||||
set_errno (EEXIST);
|
||||
goto done;
|
||||
__leave;
|
||||
}
|
||||
if (has_trailing_dirsep && !win32_newpath.exists ())
|
||||
{
|
||||
set_errno (ENOENT);
|
||||
goto done;
|
||||
__leave;
|
||||
}
|
||||
|
||||
/* 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:
|
||||
res = symlink_nfs (oldpath, win32_newpath);
|
||||
goto done;
|
||||
__leave;
|
||||
case WSYM_native:
|
||||
case WSYM_nativestrict:
|
||||
res = symlink_native (oldpath, win32_newpath);
|
||||
if (!res)
|
||||
goto done;
|
||||
__leave;
|
||||
/* Strictly native? Too bad. */
|
||||
if (wsym_type == WSYM_nativestrict)
|
||||
{
|
||||
__seterrno ();
|
||||
goto done;
|
||||
__leave;
|
||||
}
|
||||
/* Otherwise, fall back to default symlink type. */
|
||||
wsym_type = WSYM_sysfile;
|
||||
|
@ -1810,9 +1822,9 @@ symlink_worker (const char *oldpath, const char *newpath, bool isdevice)
|
|||
going to be. */
|
||||
IShellFolder *psl;
|
||||
|
||||
/* The symlink target is relative to the directory in which
|
||||
the symlink gets created, not relative to the cwd. Therefore
|
||||
we have to mangle the path quite a bit before calling path_conv. */
|
||||
/* The symlink target is relative to the directory in which the
|
||||
symlink gets created, not relative to the cwd. Therefore we
|
||||
have to mangle the path quite a bit before calling path_conv.*/
|
||||
if (isabspath (oldpath))
|
||||
win32_oldpath.check (oldpath,
|
||||
PC_SYM_NOFOLLOW,
|
||||
|
@ -1822,9 +1834,11 @@ symlink_worker (const char *oldpath, const char *newpath, bool isdevice)
|
|||
len = strrchr (win32_newpath.normalized_path, '/')
|
||||
- win32_newpath.normalized_path + 1;
|
||||
char *absoldpath = tp.t_get ();
|
||||
stpcpy (stpncpy (absoldpath, win32_newpath.normalized_path, len),
|
||||
stpcpy (stpncpy (absoldpath, win32_newpath.normalized_path,
|
||||
len),
|
||||
oldpath);
|
||||
win32_oldpath.check (absoldpath, PC_SYM_NOFOLLOW, stat_suffixes);
|
||||
win32_oldpath.check (absoldpath, PC_SYM_NOFOLLOW,
|
||||
stat_suffixes);
|
||||
}
|
||||
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 */
|
||||
*(wc += 2) = L'\\';
|
||||
HRESULT res;
|
||||
if (SUCCEEDED (res = psl->ParseDisplayName (NULL, NULL, wc, NULL,
|
||||
&pidl, NULL)))
|
||||
if (SUCCEEDED (res = psl->ParseDisplayName (NULL, NULL, wc,
|
||||
NULL, &pidl,
|
||||
NULL)))
|
||||
{
|
||||
ITEMIDLIST *p;
|
||||
|
||||
|
@ -1924,7 +1939,8 @@ symlink_worker (const char *oldpath, const char *newpath, bool isdevice)
|
|||
cp += 2;
|
||||
*(PWCHAR) cp = 0xfeff; /* BOM */
|
||||
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;
|
||||
}
|
||||
else
|
||||
|
@ -1935,7 +1951,8 @@ symlink_worker (const char *oldpath, const char *newpath, bool isdevice)
|
|||
*(PWCHAR) cp = 0xfeff; /* BOM */
|
||||
cp += 2;
|
||||
/* 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;
|
||||
|
@ -1948,22 +1965,24 @@ symlink_worker (const char *oldpath, const char *newpath, bool isdevice)
|
|||
if (isdevice && win32_newpath.exists ())
|
||||
{
|
||||
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);
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
__seterrno_from_nt_status (status);
|
||||
goto done;
|
||||
__leave;
|
||||
}
|
||||
status = NtSetAttributesFile (fh, FILE_ATTRIBUTE_NORMAL);
|
||||
NtClose (fh);
|
||||
if (!NT_SUCCESS (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
|
||||
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
|
||||
|
@ -1986,13 +2005,14 @@ symlink_worker (const char *oldpath, const char *newpath, bool isdevice)
|
|||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
__seterrno_from_nt_status (status);
|
||||
goto done;
|
||||
__leave;
|
||||
}
|
||||
if (win32_newpath.has_acls ())
|
||||
set_file_attribute (fh, win32_newpath, ILLEGAL_UID, ILLEGAL_GID,
|
||||
(io.Information == FILE_CREATED ? S_JUSTCREATED : 0)
|
||||
| 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))
|
||||
{
|
||||
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,
|
||||
FileDispositionInformation);
|
||||
if (!NT_SUCCESS (status))
|
||||
debug_printf ("Setting delete dispostion failed, status = %y", status);
|
||||
debug_printf ("Setting delete dispostion failed, status = %y",
|
||||
status);
|
||||
}
|
||||
NtClose (fh);
|
||||
|
||||
done:
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
syscall_printf ("%d = symlink_worker(%s, %s, %d)",
|
||||
res, oldpath, newpath, isdevice);
|
||||
if (has_trailing_dirsep)
|
||||
|
@ -3109,13 +3132,16 @@ extern "C" char *
|
|||
getcwd (char *buf, size_t ulen)
|
||||
{
|
||||
char* res = NULL;
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
/* errno set */;
|
||||
else if (ulen == 0 && buf)
|
||||
|
||||
__try
|
||||
{
|
||||
if (ulen == 0 && buf)
|
||||
set_errno (EINVAL);
|
||||
else
|
||||
res = cygheap->cwd.get (buf, 1, 1, ulen);
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -3150,28 +3176,28 @@ get_current_dir_name (void)
|
|||
extern "C" int
|
||||
chdir (const char *in_dir)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
int res = -1;
|
||||
|
||||
__try
|
||||
{
|
||||
if (!*in_dir)
|
||||
{
|
||||
set_errno (ENOENT);
|
||||
return -1;
|
||||
__leave;
|
||||
}
|
||||
|
||||
syscall_printf ("dir '%s'", in_dir);
|
||||
|
||||
/* Convert path. First argument ensures that we don't check for NULL/empty/invalid
|
||||
again. */
|
||||
/* Convert path. First argument ensures that we don't check for
|
||||
NULL/empty/invalid again. */
|
||||
path_conv path (PC_NONULLEMPTY, in_dir, PC_SYM_FOLLOW | PC_POSIX);
|
||||
if (path.error)
|
||||
{
|
||||
set_errno (path.error);
|
||||
syscall_printf ("-1 = chdir (%s)", in_dir);
|
||||
return -1;
|
||||
__leave;
|
||||
}
|
||||
|
||||
int res = -1;
|
||||
const char *posix_cwd = NULL;
|
||||
dev_t devn = path.get_device ();
|
||||
if (!path.exists ())
|
||||
|
@ -3198,10 +3224,16 @@ chdir (const char *in_dir)
|
|||
if (!res)
|
||||
res = cygheap->cwd.set (&path, posix_cwd);
|
||||
|
||||
/* Note that we're accessing cwd.posix without a lock here. I didn't think
|
||||
it was worth locking just for strace. */
|
||||
/* Note that we're accessing cwd.posix without a lock here.
|
||||
I didn't think it was worth locking just for strace. */
|
||||
syscall_printf ("%R = chdir() cygheap->cwd.posix '%s' native '%S'", res,
|
||||
cygheap->cwd.get_posix (), path.get_nt_native_path ());
|
||||
}
|
||||
__except (EFAULT)
|
||||
{
|
||||
res = -1;
|
||||
}
|
||||
__endtry
|
||||
MALLOC_CHECK;
|
||||
return res;
|
||||
}
|
||||
|
@ -3239,10 +3271,6 @@ cygwin_conv_path (cygwin_conv_path_t what, const void *from, void *to,
|
|||
size_t size)
|
||||
{
|
||||
tmp_pathbuf tp;
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
path_conv p;
|
||||
size_t lsiz = 0;
|
||||
char *buf = NULL;
|
||||
|
@ -3250,11 +3278,14 @@ cygwin_conv_path (cygwin_conv_path_t what, const void *from, void *to,
|
|||
int error = 0;
|
||||
bool relative = !!(what & CCP_RELATIVE);
|
||||
what &= CCP_CONVTYPE_MASK;
|
||||
int ret = -1;
|
||||
|
||||
__try
|
||||
{
|
||||
if (!from)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
__leave;
|
||||
}
|
||||
|
||||
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_NO_ACCESS_CHECK | PC_NOWARN | (relative ? PC_NOFULL : 0));
|
||||
if (p.error)
|
||||
return_with_errno (p.error);
|
||||
{
|
||||
set_errno (p.error);
|
||||
__leave;
|
||||
}
|
||||
PUNICODE_STRING up = p.get_nt_native_path ();
|
||||
buf = tp.c_get ();
|
||||
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_NO_ACCESS_CHECK | PC_NOWARN | (relative ? PC_NOFULL : 0));
|
||||
if (p.error)
|
||||
return_with_errno (p.error);
|
||||
{
|
||||
set_errno (p.error);
|
||||
__leave;
|
||||
}
|
||||
/* Relative Windows paths are always restricted to MAX_PATH chars. */
|
||||
if (relative && !isabspath (p.get_win32 ())
|
||||
&& 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
|
||||
| PC_NO_ACCESS_CHECK | PC_NOWARN);
|
||||
if (p.error)
|
||||
return_with_errno (p.error);
|
||||
{
|
||||
set_errno (p.error);
|
||||
__leave;
|
||||
}
|
||||
}
|
||||
lsiz = p.get_wide_win32_path_len () + 1;
|
||||
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,
|
||||
relative);
|
||||
if (error)
|
||||
return_with_errno (error);
|
||||
{
|
||||
set_errno (p.error);
|
||||
__leave;
|
||||
}
|
||||
lsiz = strlen (buf) + 1;
|
||||
break;
|
||||
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,
|
||||
relative);
|
||||
if (error)
|
||||
return_with_errno (error);
|
||||
{
|
||||
set_errno (error);
|
||||
__leave;
|
||||
}
|
||||
lsiz = strlen (buf) + 1;
|
||||
break;
|
||||
default:
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
__leave;
|
||||
}
|
||||
if (!size)
|
||||
return lsiz;
|
||||
{
|
||||
ret = lsiz;
|
||||
__leave;
|
||||
}
|
||||
if (size < lsiz)
|
||||
{
|
||||
set_errno (ENOSPC);
|
||||
return -1;
|
||||
__leave;
|
||||
}
|
||||
switch (what)
|
||||
{
|
||||
|
@ -3395,7 +3444,11 @@ cygwin_conv_path (cygwin_conv_path_t what, const void *from, void *to,
|
|||
wcpcpy ((PWCHAR) to, path);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
ret = 0;
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" void *
|
||||
|
@ -3454,6 +3507,9 @@ cygwin_conv_to_full_posix_path (const char *path, char *posix_path)
|
|||
extern "C" char *
|
||||
realpath (const char *__restrict path, char *__restrict resolved)
|
||||
{
|
||||
tmp_pathbuf tp;
|
||||
char *tpath;
|
||||
|
||||
/* Make sure the right errno is returned if path is NULL. */
|
||||
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
|
||||
potentially invalid resolved. */
|
||||
tmp_pathbuf tp;
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return NULL;
|
||||
|
||||
__try
|
||||
{
|
||||
/* Win32 drive letter paths have to be converted to a POSIX path first,
|
||||
because path_conv leaves the incoming path untouched except for
|
||||
converting backslashes to forward slashes. */
|
||||
char *tpath;
|
||||
if (isdrive (path))
|
||||
{
|
||||
tpath = tp.c_get ();
|
||||
|
@ -3491,7 +3543,8 @@ realpath (const char *__restrict path, char *__restrict resolved)
|
|||
{
|
||||
if (!resolved)
|
||||
{
|
||||
resolved = (char *) malloc (strlen (real_path.normalized_path) + 1);
|
||||
resolved = (char *)
|
||||
malloc (strlen (real_path.normalized_path) + 1);
|
||||
if (!resolved)
|
||||
return NULL;
|
||||
}
|
||||
|
@ -3505,6 +3558,9 @@ realpath (const char *__restrict path, char *__restrict resolved)
|
|||
if (resolved)
|
||||
resolved[0] = '\0';
|
||||
set_errno (real_path.error ?: ENOENT);
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* poll.cc. Implements poll(2) via usage of select(2) call.
|
||||
|
||||
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011,
|
||||
2012 Red Hat, Inc.
|
||||
2012, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -143,9 +143,8 @@ ppoll (struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts,
|
|||
int timeout;
|
||||
sigset_t oldset = _my_tls.sigmask;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
__try
|
||||
{
|
||||
timeout = (timeout_ts == NULL)
|
||||
? -1
|
||||
: (timeout_ts->tv_sec * 1000 + timeout_ts->tv_nsec / 1000000);
|
||||
|
@ -156,3 +155,7 @@ ppoll (struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts,
|
|||
set_signal_mask (_my_tls.sigmask, oldset);
|
||||
return ret;
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* 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.
|
||||
|
||||
|
@ -414,17 +414,17 @@ extern "C" void *mmap64 (void *, size_t, int, int, int, off_t);
|
|||
extern "C" mqd_t
|
||||
mq_open (const char *name, int oflag, ...)
|
||||
{
|
||||
int i, fd = -1, nonblock, created;
|
||||
int i, fd = -1, nonblock, created = 0;
|
||||
long msgsize, index;
|
||||
off_t filesize = 0;
|
||||
va_list ap;
|
||||
mode_t mode;
|
||||
int8_t *mptr;
|
||||
int8_t *mptr = (int8_t *) MAP_FAILED;
|
||||
struct stat statbuff;
|
||||
struct mq_hdr *mqhdr;
|
||||
struct msg_hdr *msghdr;
|
||||
struct mq_attr *attr;
|
||||
struct mq_info *mqinfo;
|
||||
struct mq_info *mqinfo = NULL;
|
||||
LUID luid;
|
||||
|
||||
size_t len = strlen (name);
|
||||
|
@ -433,16 +433,11 @@ mq_open (const char *name, int oflag, ...)
|
|||
if (!check_path (mqname, mqueue, name, len))
|
||||
return (mqd_t) -1;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return (mqd_t) -1;
|
||||
|
||||
__try
|
||||
{
|
||||
oflag &= (O_CREAT | O_EXCL | O_NONBLOCK);
|
||||
created = 0;
|
||||
nonblock = oflag & O_NONBLOCK;
|
||||
oflag &= ~O_NONBLOCK;
|
||||
mptr = (int8_t *) MAP_FAILED;
|
||||
mqinfo = NULL;
|
||||
|
||||
again:
|
||||
if (oflag & O_CREAT)
|
||||
|
@ -453,7 +448,8 @@ again:
|
|||
va_end (ap);
|
||||
|
||||
/* 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 (errno == EEXIST && (oflag & O_EXCL) == 0)
|
||||
|
@ -472,26 +468,28 @@ again:
|
|||
|| attr->mq_msgsize <= 0 || attr->mq_msgsize > 1048576)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
goto err;
|
||||
__leave;
|
||||
}
|
||||
/* Calculate and set the file size */
|
||||
msgsize = MSGSIZE (attr->mq_msgsize);
|
||||
filesize = sizeof (struct mq_hdr)
|
||||
+ (attr->mq_maxmsg * (sizeof (struct msg_hdr) + msgsize));
|
||||
if (lseek64 (fd, filesize - 1, SEEK_SET) == -1)
|
||||
goto err;
|
||||
__leave;
|
||||
if (write (fd, "", 1) == -1)
|
||||
goto err;
|
||||
__leave;
|
||||
|
||||
/* 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);
|
||||
if (mptr == (int8_t *) MAP_FAILED)
|
||||
goto err;
|
||||
__leave;
|
||||
|
||||
/* Allocate one mq_info{} for the queue */
|
||||
if (!(mqinfo = (struct mq_info *) calloc (1, sizeof (struct mq_info))))
|
||||
goto err;
|
||||
if (!(mqinfo = (struct mq_info *)
|
||||
calloc (1, sizeof (struct mq_info))))
|
||||
__leave;
|
||||
mqinfo->mqi_hdr = mqhdr = (struct mq_hdr *) mptr;
|
||||
mqinfo->mqi_magic = MQI_MAGIC;
|
||||
mqinfo->mqi_flags = nonblock;
|
||||
|
@ -524,19 +522,25 @@ again:
|
|||
/* Initialize mutex & condition variables */
|
||||
i = ipc_mutex_init (&mqinfo->mqi_lock, mqhdr->mqh_uname);
|
||||
if (i != 0)
|
||||
goto pthreaderr;
|
||||
|
||||
{
|
||||
set_errno (i);
|
||||
__leave;
|
||||
}
|
||||
i = ipc_cond_init (&mqinfo->mqi_waitsend, mqhdr->mqh_uname, 'S');
|
||||
if (i != 0)
|
||||
goto pthreaderr;
|
||||
|
||||
{
|
||||
set_errno (i);
|
||||
__leave;
|
||||
}
|
||||
i = ipc_cond_init (&mqinfo->mqi_waitrecv, mqhdr->mqh_uname, 'R');
|
||||
if (i != 0)
|
||||
goto pthreaderr;
|
||||
|
||||
{
|
||||
set_errno (i);
|
||||
__leave;
|
||||
}
|
||||
/* Initialization complete, turn off user-execute bit */
|
||||
if (fchmod (fd, mode) == -1)
|
||||
goto err;
|
||||
__leave;
|
||||
close (fd);
|
||||
return ((mqd_t) mqinfo);
|
||||
}
|
||||
|
@ -547,7 +551,7 @@ exists:
|
|||
{
|
||||
if (errno == ENOENT && (oflag & O_CREAT))
|
||||
goto again;
|
||||
goto err;
|
||||
__leave;
|
||||
}
|
||||
/* Make certain initialization is complete */
|
||||
for (i = 0; i < MAX_TRIES; i++)
|
||||
|
@ -560,7 +564,7 @@ exists:
|
|||
fd = -1;
|
||||
goto again;
|
||||
}
|
||||
goto err;
|
||||
__leave;
|
||||
}
|
||||
if ((statbuff.st_mode & S_IXUSR) == 0)
|
||||
break;
|
||||
|
@ -569,20 +573,20 @@ exists:
|
|||
if (i == MAX_TRIES)
|
||||
{
|
||||
set_errno (ETIMEDOUT);
|
||||
goto err;
|
||||
__leave;
|
||||
}
|
||||
|
||||
filesize = statbuff.st_size;
|
||||
mptr = (int8_t *) mmap64 (NULL, (size_t) filesize, PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED, fd, 0);
|
||||
if (mptr == (int8_t *) MAP_FAILED)
|
||||
goto err;
|
||||
__leave;
|
||||
close (fd);
|
||||
fd = -1;
|
||||
|
||||
/* Allocate one mq_info{} for each open */
|
||||
if (!(mqinfo = (struct mq_info *) calloc (1, sizeof (struct mq_info))))
|
||||
goto err;
|
||||
__leave;
|
||||
mqinfo->mqi_hdr = mqhdr = (struct mq_hdr *) mptr;
|
||||
if (mqhdr->mqh_magic != MQI_MAGIC)
|
||||
{
|
||||
|
@ -591,7 +595,7 @@ exists:
|
|||
"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);
|
||||
set_errno (EACCES);
|
||||
goto err;
|
||||
__leave;
|
||||
}
|
||||
mqinfo->mqi_magic = MQI_MAGIC;
|
||||
mqinfo->mqi_flags = nonblock;
|
||||
|
@ -599,24 +603,28 @@ exists:
|
|||
/* Initialize mutex & condition variable */
|
||||
i = ipc_mutex_init (&mqinfo->mqi_lock, mqhdr->mqh_uname);
|
||||
if (i != 0)
|
||||
goto pthreaderr;
|
||||
|
||||
{
|
||||
set_errno (i);
|
||||
__leave;
|
||||
}
|
||||
i = ipc_cond_init (&mqinfo->mqi_waitsend, mqhdr->mqh_uname, 'S');
|
||||
if (i != 0)
|
||||
goto pthreaderr;
|
||||
|
||||
{
|
||||
set_errno (i);
|
||||
__leave;
|
||||
}
|
||||
i = ipc_cond_init (&mqinfo->mqi_waitrecv, mqhdr->mqh_uname, 'R');
|
||||
if (i != 0)
|
||||
goto pthreaderr;
|
||||
|
||||
{
|
||||
set_errno (i);
|
||||
__leave;
|
||||
}
|
||||
return (mqd_t) mqinfo;
|
||||
|
||||
pthreaderr:
|
||||
errno = i;
|
||||
err:
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
/* Don't let following function calls change errno */
|
||||
save_errno save;
|
||||
|
||||
if (created)
|
||||
unlink (mqname);
|
||||
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_info *mqinfo;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EBADF))
|
||||
return -1;
|
||||
|
||||
__try
|
||||
{
|
||||
mqinfo = (struct mq_info *) mqd;
|
||||
if (mqinfo->mqi_magic != MQI_MAGIC)
|
||||
{
|
||||
set_errno (EBADF);
|
||||
return -1;
|
||||
__leave;
|
||||
}
|
||||
mqhdr = mqinfo->mqi_hdr;
|
||||
attr = &mqhdr->mqh_attr;
|
||||
if ((n = ipc_mutex_lock (mqinfo->mqi_lock)) != 0)
|
||||
{
|
||||
errno = n;
|
||||
return -1;
|
||||
__leave;
|
||||
}
|
||||
mqstat->mq_flags = mqinfo->mqi_flags; /* per-open */
|
||||
mqstat->mq_maxmsg = attr->mq_maxmsg; /* remaining three per-queue */
|
||||
|
@ -669,6 +675,10 @@ mq_getattr (mqd_t mqd, struct mq_attr *mqstat)
|
|||
ipc_mutex_unlock (mqinfo->mqi_lock);
|
||||
return 0;
|
||||
}
|
||||
__except (EBADF) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
mq_setattr (mqd_t mqd, const struct mq_attr *mqstat, struct mq_attr *omqstat)
|
||||
|
@ -678,22 +688,20 @@ mq_setattr (mqd_t mqd, const struct mq_attr *mqstat, struct mq_attr *omqstat)
|
|||
struct mq_fattr *attr;
|
||||
struct mq_info *mqinfo;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EBADF))
|
||||
return -1;
|
||||
|
||||
__try
|
||||
{
|
||||
mqinfo = (struct mq_info *) mqd;
|
||||
if (mqinfo->mqi_magic != MQI_MAGIC)
|
||||
{
|
||||
set_errno (EBADF);
|
||||
return -1;
|
||||
__leave;
|
||||
}
|
||||
mqhdr = mqinfo->mqi_hdr;
|
||||
attr = &mqhdr->mqh_attr;
|
||||
if ((n = ipc_mutex_lock (mqinfo->mqi_lock)) != 0)
|
||||
{
|
||||
errno = n;
|
||||
return -1;
|
||||
__leave;
|
||||
}
|
||||
|
||||
if (omqstat != NULL)
|
||||
|
@ -712,6 +720,10 @@ mq_setattr (mqd_t mqd, const struct mq_attr *mqstat, struct mq_attr *omqstat)
|
|||
ipc_mutex_unlock (mqinfo->mqi_lock);
|
||||
return 0;
|
||||
}
|
||||
__except (EBADF) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
mq_notify (mqd_t mqd, const struct sigevent *notification)
|
||||
|
@ -721,21 +733,19 @@ mq_notify (mqd_t mqd, const struct sigevent *notification)
|
|||
struct mq_hdr *mqhdr;
|
||||
struct mq_info *mqinfo;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EBADF))
|
||||
return -1;
|
||||
|
||||
__try
|
||||
{
|
||||
mqinfo = (struct mq_info *) mqd;
|
||||
if (mqinfo->mqi_magic != MQI_MAGIC)
|
||||
{
|
||||
set_errno (EBADF);
|
||||
return -1;
|
||||
__leave;
|
||||
}
|
||||
mqhdr = mqinfo->mqi_hdr;
|
||||
if ((n = ipc_mutex_lock (mqinfo->mqi_lock)) != 0)
|
||||
{
|
||||
errno = n;
|
||||
return -1;
|
||||
__leave;
|
||||
}
|
||||
|
||||
pid = getpid ();
|
||||
|
@ -752,7 +762,7 @@ mq_notify (mqd_t mqd, const struct sigevent *notification)
|
|||
{
|
||||
set_errno (EBUSY);
|
||||
ipc_mutex_unlock (mqinfo->mqi_lock);
|
||||
return -1;
|
||||
__leave;
|
||||
}
|
||||
}
|
||||
mqhdr->mqh_pid = pid;
|
||||
|
@ -761,6 +771,10 @@ mq_notify (mqd_t mqd, const struct sigevent *notification)
|
|||
ipc_mutex_unlock (mqinfo->mqi_lock);
|
||||
return 0;
|
||||
}
|
||||
__except (EBADF) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
_mq_send (mqd_t mqd, const char *ptr, size_t len, unsigned int prio,
|
||||
|
@ -773,24 +787,24 @@ _mq_send (mqd_t mqd, const char *ptr, size_t len, unsigned int prio,
|
|||
struct mq_hdr *mqhdr;
|
||||
struct mq_fattr *attr;
|
||||
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 ();
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EBADF))
|
||||
return -1;
|
||||
|
||||
__try
|
||||
{
|
||||
mqinfo = (struct mq_info *) mqd;
|
||||
if (mqinfo->mqi_magic != MQI_MAGIC)
|
||||
{
|
||||
set_errno (EBADF);
|
||||
return -1;
|
||||
__leave;
|
||||
}
|
||||
if (prio > MQ_PRIO_MAX)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
__leave;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
errno = n;
|
||||
return -1;
|
||||
__leave;
|
||||
}
|
||||
|
||||
ipc_mutex_locked = true;
|
||||
if (len > (size_t) attr->mq_msgsize)
|
||||
{
|
||||
set_errno (EMSGSIZE);
|
||||
goto err;
|
||||
__leave;
|
||||
}
|
||||
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;
|
||||
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 */
|
||||
}
|
||||
}
|
||||
|
@ -823,17 +838,17 @@ _mq_send (mqd_t mqd, const char *ptr, size_t len, unsigned int prio,
|
|||
if (mqinfo->mqi_flags & O_NONBLOCK)
|
||||
{
|
||||
set_errno (EAGAIN);
|
||||
goto err;
|
||||
__leave;
|
||||
}
|
||||
/* Wait for room for one message on the queue */
|
||||
while (attr->mq_curmsgs >= attr->mq_maxmsg)
|
||||
{
|
||||
int ret = ipc_cond_timedwait (mqinfo->mqi_waitsend, mqinfo->mqi_lock,
|
||||
abstime);
|
||||
int ret = ipc_cond_timedwait (mqinfo->mqi_waitsend,
|
||||
mqinfo->mqi_lock, abstime);
|
||||
if (ret != 0)
|
||||
{
|
||||
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++;
|
||||
|
||||
ipc_mutex_unlock (mqinfo->mqi_lock);
|
||||
return 0;
|
||||
|
||||
err:
|
||||
ret = 0;
|
||||
}
|
||||
__except (EBADF) {}
|
||||
__endtry
|
||||
if (ipc_mutex_locked)
|
||||
ipc_mutex_unlock (mqinfo->mqi_lock);
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
|
@ -902,23 +919,21 @@ _mq_receive (mqd_t mqd, char *ptr, size_t maxlen, unsigned int *priop,
|
|||
int n;
|
||||
long index;
|
||||
int8_t *mptr;
|
||||
ssize_t len;
|
||||
ssize_t len = -1;
|
||||
struct mq_hdr *mqhdr;
|
||||
struct mq_fattr *attr;
|
||||
struct msg_hdr *msghdr;
|
||||
struct mq_info *mqinfo;
|
||||
struct mq_info *mqinfo = (struct mq_info *) mqd;
|
||||
bool ipc_mutex_locked = false;
|
||||
|
||||
pthread_testcancel ();
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EBADF))
|
||||
return -1;
|
||||
|
||||
mqinfo = (struct mq_info *) mqd;
|
||||
__try
|
||||
{
|
||||
if (mqinfo->mqi_magic != MQI_MAGIC)
|
||||
{
|
||||
set_errno (EBADF);
|
||||
return -1;
|
||||
__leave;
|
||||
}
|
||||
mqhdr = mqinfo->mqi_hdr; /* struct 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)
|
||||
{
|
||||
errno = n;
|
||||
return -1;
|
||||
__leave;
|
||||
}
|
||||
|
||||
ipc_mutex_locked = true;
|
||||
if (maxlen < (size_t) attr->mq_msgsize)
|
||||
{
|
||||
set_errno (EMSGSIZE);
|
||||
goto err;
|
||||
__leave;
|
||||
}
|
||||
if (attr->mq_curmsgs == 0) /* queue is empty */
|
||||
{
|
||||
if (mqinfo->mqi_flags & O_NONBLOCK)
|
||||
{
|
||||
set_errno (EAGAIN);
|
||||
goto err;
|
||||
__leave;
|
||||
}
|
||||
/* Wait for a message to be placed onto queue */
|
||||
mqhdr->mqh_nwait++;
|
||||
while (attr->mq_curmsgs == 0)
|
||||
{
|
||||
int ret = ipc_cond_timedwait (mqinfo->mqi_waitrecv, mqinfo->mqi_lock,
|
||||
abstime);
|
||||
int ret = ipc_cond_timedwait (mqinfo->mqi_waitrecv,
|
||||
mqinfo->mqi_lock, abstime);
|
||||
if (ret != 0)
|
||||
{
|
||||
set_errno (ret);
|
||||
return -1;
|
||||
__leave;
|
||||
}
|
||||
}
|
||||
mqhdr->mqh_nwait--;
|
||||
|
@ -976,11 +991,12 @@ _mq_receive (mqd_t mqd, char *ptr, size_t maxlen, unsigned int *priop,
|
|||
attr->mq_curmsgs--;
|
||||
|
||||
ipc_mutex_unlock (mqinfo->mqi_lock);
|
||||
return len;
|
||||
|
||||
err:
|
||||
}
|
||||
__except (EBADF) {}
|
||||
__endtry
|
||||
if (ipc_mutex_locked)
|
||||
ipc_mutex_unlock (mqinfo->mqi_lock);
|
||||
return -1;
|
||||
return len;
|
||||
}
|
||||
|
||||
extern "C" ssize_t
|
||||
|
@ -1004,27 +1020,25 @@ mq_close (mqd_t mqd)
|
|||
struct mq_fattr *attr;
|
||||
struct mq_info *mqinfo;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EBADF))
|
||||
return -1;
|
||||
|
||||
__try
|
||||
{
|
||||
mqinfo = (struct mq_info *) mqd;
|
||||
if (mqinfo->mqi_magic != MQI_MAGIC)
|
||||
{
|
||||
set_errno (EBADF);
|
||||
return -1;
|
||||
__leave;
|
||||
}
|
||||
mqhdr = mqinfo->mqi_hdr;
|
||||
attr = &mqhdr->mqh_attr;
|
||||
|
||||
if (mq_notify (mqd, NULL)) /* unregister calling process */
|
||||
return -1;
|
||||
__leave;
|
||||
|
||||
msgsize = MSGSIZE (attr->mq_msgsize);
|
||||
filesize = sizeof (struct mq_hdr)
|
||||
+ (attr->mq_maxmsg * (sizeof (struct msg_hdr) + msgsize));
|
||||
if (munmap (mqinfo->mqi_hdr, filesize) == -1)
|
||||
return -1;
|
||||
__leave;
|
||||
|
||||
mqinfo->mqi_magic = 0; /* just in case */
|
||||
ipc_cond_close (mqinfo->mqi_waitsend);
|
||||
|
@ -1033,6 +1047,10 @@ mq_close (mqd_t mqd)
|
|||
free (mqinfo);
|
||||
return 0;
|
||||
}
|
||||
__except (EBADF) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
mq_unlink (const char *name)
|
||||
|
@ -1062,7 +1080,7 @@ struct sem_finfo
|
|||
extern "C" sem_t *
|
||||
sem_open (const char *name, int oflag, ...)
|
||||
{
|
||||
int i, fd = -1, created;
|
||||
int i, fd = -1, created = 0;
|
||||
va_list ap;
|
||||
mode_t mode = 0;
|
||||
unsigned int value = 0;
|
||||
|
@ -1078,11 +1096,8 @@ sem_open (const char *name, int oflag, ...)
|
|||
if (!check_path (semname, semaphore, name, len))
|
||||
return SEM_FAILED;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return SEM_FAILED;
|
||||
|
||||
created = 0;
|
||||
__try
|
||||
{
|
||||
oflag &= (O_CREAT | O_EXCL);
|
||||
|
||||
again:
|
||||
|
@ -1094,7 +1109,8 @@ again:
|
|||
va_end (ap);
|
||||
|
||||
/* 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 (errno == EEXIST && (oflag & O_EXCL) == 0)
|
||||
|
@ -1107,13 +1123,14 @@ again:
|
|||
sf.value = value;
|
||||
sf.hash = hash_path_name (0, semname);
|
||||
if (write (fd, &sf, sizeof sf) != sizeof sf)
|
||||
goto err;
|
||||
sem = semaphore::open (sf.hash, sf.luid, fd, oflag, mode, value, wasopen);
|
||||
__leave;
|
||||
sem = semaphore::open (sf.hash, sf.luid, fd, oflag, mode, value,
|
||||
wasopen);
|
||||
if (sem == SEM_FAILED)
|
||||
goto err;
|
||||
__leave;
|
||||
/* Initialization complete, turn off user-execute bit */
|
||||
if (fchmod (fd, mode) == -1)
|
||||
goto err;
|
||||
__leave;
|
||||
/* Don't close (fd); */
|
||||
return sem;
|
||||
}
|
||||
|
@ -1124,7 +1141,7 @@ exists:
|
|||
{
|
||||
if (errno == ENOENT && (oflag & O_CREAT))
|
||||
goto again;
|
||||
goto err;
|
||||
__leave;
|
||||
}
|
||||
/* Make certain initialization is complete */
|
||||
for (i = 0; i < MAX_TRIES; i++)
|
||||
|
@ -1137,7 +1154,7 @@ exists:
|
|||
fd = -1;
|
||||
goto again;
|
||||
}
|
||||
goto err;
|
||||
__leave;
|
||||
}
|
||||
if ((statbuff.st_mode & S_IXUSR) == 0)
|
||||
break;
|
||||
|
@ -1146,16 +1163,17 @@ exists:
|
|||
if (i == MAX_TRIES)
|
||||
{
|
||||
set_errno (ETIMEDOUT);
|
||||
goto err;
|
||||
__leave;
|
||||
}
|
||||
if (file.lock (fd, sizeof sf))
|
||||
goto err;
|
||||
__leave;
|
||||
if (read (fd, &sf, sizeof sf) != sizeof sf)
|
||||
goto err;
|
||||
sem = semaphore::open (sf.hash, sf.luid, fd, oflag, mode, sf.value, wasopen);
|
||||
__leave;
|
||||
sem = semaphore::open (sf.hash, sf.luid, fd, oflag, mode, sf.value,
|
||||
wasopen);
|
||||
file.unlock (fd);
|
||||
if (sem == SEM_FAILED)
|
||||
goto err;
|
||||
__leave;
|
||||
/* 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
|
||||
close the file descriptor created in this call. It won't be stored
|
||||
|
@ -1163,11 +1181,13 @@ exists:
|
|||
if (wasopen)
|
||||
close (fd);
|
||||
return sem;
|
||||
|
||||
err:
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
/* Don't let following function calls change errno */
|
||||
save_errno save;
|
||||
|
||||
if (fd >= 0)
|
||||
file.unlock (fd);
|
||||
if (created)
|
||||
unlink (semname);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* resource.cc: getrusage () and friends.
|
||||
|
||||
Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2005, 2008, 2009, 2010,
|
||||
2011, 2012, 2013 Red Hat, Inc.
|
||||
2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
Written by Steve Chamberlain (sac@cygnus.com), Doug Evans (dje@cygnus.com),
|
||||
Geoffrey Noer (noer@cygnus.com) of Cygnus Support.
|
||||
|
@ -116,10 +116,8 @@ getrlimit (int resource, struct rlimit *rlp)
|
|||
{
|
||||
MEMORY_BASIC_INFORMATION m;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
__try
|
||||
{
|
||||
rlp->rlim_cur = RLIM_INFINITY;
|
||||
rlp->rlim_max = RLIM_INFINITY;
|
||||
|
||||
|
@ -151,18 +149,18 @@ getrlimit (int resource, struct rlimit *rlp)
|
|||
break;
|
||||
default:
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
__leave;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
setrlimit (int resource, const struct rlimit *rlp)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
struct rlimit oldlimits;
|
||||
|
||||
/* Check if the request is to actually change the resource settings.
|
||||
|
@ -170,6 +168,8 @@ setrlimit (int resource, const struct rlimit *rlp)
|
|||
if (getrlimit (resource, &oldlimits) < 0)
|
||||
return -1;
|
||||
|
||||
__try
|
||||
{
|
||||
if (oldlimits.rlim_cur == rlp->rlim_cur &&
|
||||
oldlimits.rlim_max == rlp->rlim_max)
|
||||
/* 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)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
__leave;
|
||||
}
|
||||
|
||||
switch (resource)
|
||||
|
@ -192,7 +192,11 @@ setrlimit (int resource, const struct rlimit *rlp)
|
|||
break;
|
||||
default:
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
__leave;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
__except (EFAULT)
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* select.cc
|
||||
|
||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
||||
2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||
2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -230,9 +230,8 @@ pselect(int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
|||
struct timeval tv;
|
||||
sigset_t oldset = _my_tls.sigmask;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
__try
|
||||
{
|
||||
if (ts)
|
||||
{
|
||||
tv.tv_sec = ts->tv_sec;
|
||||
|
@ -246,6 +245,10 @@ pselect(int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
|||
set_signal_mask (_my_tls.sigmask, oldset);
|
||||
return ret;
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Call cleanup functions for all inspected fds. Gets rid of any
|
||||
executing threads. */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* sem.cc: XSI IPC interface for Cygwin.
|
||||
|
||||
Copyright 2002, 2003, 2004, 2005, 2008, 2009, 2012 Red Hat, Inc.
|
||||
Copyright 2002, 2003, 2004, 2005, 2008, 2009, 2012, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -85,9 +85,8 @@ semctl (int semid, int semnum, int cmd, ...)
|
|||
}
|
||||
syscall_printf ("semctl (semid = %d, semnum = %d, cmd = %d, arg = %p)",
|
||||
semid, semnum, cmd, arg.buf);
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
__try
|
||||
{
|
||||
client_request_sem request (semid, semnum, cmd, &arg);
|
||||
if (request.make_request () == -1 || request.retval () == -1)
|
||||
{
|
||||
|
@ -95,10 +94,14 @@ semctl (int semid, int semnum, int cmd, ...)
|
|||
set_errno (request.error_code ());
|
||||
if (request.error_code () == ENOSYS)
|
||||
raise (SIGSYS);
|
||||
return -1;
|
||||
__leave;
|
||||
}
|
||||
return request.retval ();
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
semget (key_t key, int nsems, int semflg)
|
||||
|
@ -122,9 +125,8 @@ semop (int semid, struct sembuf *sops, size_t nsops)
|
|||
{
|
||||
syscall_printf ("semop (semid = %d, sops = %p, nsops = %ld)",
|
||||
semid, sops, nsops);
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
__try
|
||||
{
|
||||
client_request_sem request (semid, sops, nsops);
|
||||
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 ());
|
||||
if (request.error_code () == ENOSYS)
|
||||
raise (SIGSYS);
|
||||
return -1;
|
||||
__leave;
|
||||
}
|
||||
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)",
|
||||
shmid, cmd, buf);
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
__try
|
||||
{
|
||||
client_request_shm request (shmid, cmd, buf);
|
||||
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 ());
|
||||
if (request.error_code () == ENOSYS)
|
||||
raise (SIGSYS);
|
||||
return -1;
|
||||
__leave;
|
||||
}
|
||||
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. */
|
||||
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);
|
||||
delete ssh_entry;
|
||||
}
|
||||
|
@ -296,6 +296,10 @@ shmctl (int shmid, int cmd, struct shmid_ds *buf)
|
|||
}
|
||||
return request.retval ();
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
shmdt (const void *shmaddr)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* signal.cc
|
||||
|
||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
||||
2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||
2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
Written by Steve Chamberlain of Cygnus Support, sac@cygnus.com
|
||||
Significant changes by Sergey Okhapkin <sos@prospect.com.ru>
|
||||
|
@ -197,10 +197,8 @@ handle_sigprocmask (int how, const sigset_t *set, sigset_t *oldset, sigset_t& op
|
|||
return EINVAL;
|
||||
}
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return EFAULT;
|
||||
|
||||
__try
|
||||
{
|
||||
if (oldset)
|
||||
*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);
|
||||
}
|
||||
}
|
||||
__except (EFAULT)
|
||||
{
|
||||
return EFAULT;
|
||||
}
|
||||
__endtry
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -382,8 +386,7 @@ sigaction_worker (int sig, const struct sigaction *newact,
|
|||
struct sigaction *oldact, bool isinternal)
|
||||
{
|
||||
int res = -1;
|
||||
myfault efault;
|
||||
if (!efault.faulted (EFAULT))
|
||||
__try
|
||||
{
|
||||
sig_dispatch_pending ();
|
||||
/* check that sig is in right range */
|
||||
|
@ -394,14 +397,17 @@ sigaction_worker (int sig, const struct sigaction *newact,
|
|||
struct sigaction oa = global_sigs[sig];
|
||||
|
||||
if (!newact)
|
||||
sigproc_printf ("signal %d, newact %p, oa %p", sig, newact, oa, oa.sa_handler);
|
||||
sigproc_printf ("signal %d, newact %p, oa %p",
|
||||
sig, newact, oa, oa.sa_handler);
|
||||
else
|
||||
{
|
||||
sigproc_printf ("signal %d, newact %p (handler %p), oa %p", sig, newact, newact->sa_handler, oa, oa.sa_handler);
|
||||
sigproc_printf ("signal %d, newact %p (handler %p), oa %p",
|
||||
sig, newact, newact->sa_handler, oa,
|
||||
oa.sa_handler);
|
||||
if (sig == SIGKILL || sig == SIGSTOP)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
goto out;
|
||||
__leave;
|
||||
}
|
||||
struct sigaction na = *newact;
|
||||
struct sigaction& gs = global_sigs[sig];
|
||||
|
@ -430,8 +436,8 @@ sigaction_worker (int sig, const struct sigaction *newact,
|
|||
res = 0;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -560,24 +566,20 @@ sigwait (const sigset_t *set, int *sig_ptr)
|
|||
extern "C" int
|
||||
sigwaitinfo (const sigset_t *set, siginfo_t *info)
|
||||
{
|
||||
int res = -1;
|
||||
|
||||
pthread_testcancel ();
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
__try
|
||||
{
|
||||
set_signal_mask (_my_tls.sigwait_mask, *set);
|
||||
sig_dispatch_pending (true);
|
||||
|
||||
int res;
|
||||
switch (cygwait (NULL, cw_infinite, cw_sig_eintr | cw_cancel | cw_cancel_self))
|
||||
{
|
||||
case WAIT_SIGNALED:
|
||||
if (!sigismember (set, _my_tls.infodata.si_signo))
|
||||
{
|
||||
set_errno (EINTR);
|
||||
res = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
_my_tls.lock ();
|
||||
|
@ -592,9 +594,13 @@ sigwaitinfo (const sigset_t *set, siginfo_t *info)
|
|||
break;
|
||||
default:
|
||||
__seterrno ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
__except (EFAULT) {
|
||||
res = -1;
|
||||
}
|
||||
|
||||
__endtry
|
||||
sigproc_printf ("returning signal %d", res);
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* spawn.cc
|
||||
|
||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
||||
2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||
2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -330,18 +330,10 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
|
|||
STARTUPINFOW si = {};
|
||||
int looped = 0;
|
||||
|
||||
myfault efault;
|
||||
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;
|
||||
if (mode == _P_OVERLAY)
|
||||
chtype = _CH_EXEC;
|
||||
|
@ -363,13 +355,13 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
|
|||
{
|
||||
set_errno (err);
|
||||
res = -1;
|
||||
goto out;
|
||||
__leave;
|
||||
}
|
||||
|
||||
res = newargv.setup (prog_arg, real_path, ext, ac, argv, p_type_exec);
|
||||
|
||||
if (res)
|
||||
goto out;
|
||||
__leave;
|
||||
|
||||
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 ());
|
||||
set_errno (::cygheap->cwd.get_error ());
|
||||
res = -1;
|
||||
goto out;
|
||||
__leave;
|
||||
}
|
||||
|
||||
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 ()))
|
||||
{
|
||||
res = -1;
|
||||
goto out;
|
||||
__leave;
|
||||
}
|
||||
|
||||
|
||||
|
@ -530,7 +522,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
|
|||
{
|
||||
set_errno (ENAMETOOLONG);
|
||||
res = -1;
|
||||
goto out;
|
||||
__leave;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -545,7 +537,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
|
|||
{
|
||||
set_errno (E2BIG);
|
||||
res = -1;
|
||||
goto out;
|
||||
__leave;
|
||||
}
|
||||
set (chtype, real_path.iscygexec ());
|
||||
__stdin = in__stdin;
|
||||
|
@ -737,7 +729,7 @@ loop:
|
|||
::cygheap->user.reimpersonate ();
|
||||
|
||||
res = -1;
|
||||
goto out;
|
||||
__leave;
|
||||
}
|
||||
|
||||
/* The CREATE_SUSPENDED case is handled below */
|
||||
|
@ -783,7 +775,7 @@ loop:
|
|||
if (get_errno () != ENOMEM)
|
||||
set_errno (EAGAIN);
|
||||
res = -1;
|
||||
goto out;
|
||||
__leave;
|
||||
}
|
||||
child->dwProcessId = pi.dwProcessId;
|
||||
child.hProcess = pi.hProcess;
|
||||
|
@ -805,7 +797,7 @@ loop:
|
|||
CloseHandle (pi.hProcess);
|
||||
ForceCloseHandle (pi.hThread);
|
||||
res = -1;
|
||||
goto out;
|
||||
__leave;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -874,8 +866,16 @@ loop:
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
}
|
||||
__except (NO_ERROR)
|
||||
{
|
||||
if (get_errno () == ENOMEM)
|
||||
set_errno (E2BIG);
|
||||
else
|
||||
set_errno (EFAULT);
|
||||
res = -1;
|
||||
}
|
||||
__endtry
|
||||
this->cleanup ();
|
||||
if (envblock)
|
||||
free (envblock);
|
||||
|
@ -1137,14 +1137,8 @@ av::setup (const char *prog_arg, path_conv& real_path, const char *ext,
|
|||
}
|
||||
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
__try
|
||||
{
|
||||
UnmapViewOfFile (buf);
|
||||
CloseHandle (hm);
|
||||
real_path.set_cygexec (false);
|
||||
break;
|
||||
}
|
||||
if (buf[0] == 'M' && buf[1] == 'Z')
|
||||
{
|
||||
WORD subsys;
|
||||
|
@ -1160,6 +1154,15 @@ av::setup (const char *prog_arg, path_conv& real_path, const char *ext,
|
|||
break;
|
||||
}
|
||||
}
|
||||
__except (NO_ERROR)
|
||||
{
|
||||
UnmapViewOfFile (buf);
|
||||
CloseHandle (hm);
|
||||
real_path.set_cygexec (false);
|
||||
break;
|
||||
}
|
||||
__endtry
|
||||
}
|
||||
CloseHandle (hm);
|
||||
|
||||
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
|
||||
|
||||
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
|
||||
2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||
2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -122,28 +122,29 @@ __cygwin_lock_unlock (_LOCK_T *lock)
|
|||
paranoid_printf ("threadcount %d. unlocked", MT_INTERFACE->threadcount);
|
||||
}
|
||||
|
||||
#if __GNUC__ == 4 && __GNUC_MINOR__ >= 7
|
||||
/* FIXME: Temporarily workaround gcc 4.7+ bug. */
|
||||
static verifyable_object_state
|
||||
#else
|
||||
static inline verifyable_object_state
|
||||
#endif
|
||||
verifyable_object_isvalid (void const *objectptr, thread_magic_t magic, void *static_ptr1,
|
||||
void *static_ptr2, void *static_ptr3)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (objectptr))
|
||||
return INVALID_OBJECT;
|
||||
verifyable_object_state state = INVALID_OBJECT;
|
||||
|
||||
__try
|
||||
{
|
||||
if (!objectptr || !(*(const char **) objectptr))
|
||||
__leave;
|
||||
|
||||
verifyable_object **object = (verifyable_object **) objectptr;
|
||||
|
||||
if ((static_ptr1 && *object == static_ptr1) ||
|
||||
(static_ptr2 && *object == static_ptr2) ||
|
||||
(static_ptr3 && *object == static_ptr3))
|
||||
return VALID_STATIC_OBJECT;
|
||||
if ((*object)->magic != magic)
|
||||
return INVALID_OBJECT;
|
||||
return VALID_OBJECT;
|
||||
state = VALID_STATIC_OBJECT;
|
||||
else if ((*object)->magic == magic)
|
||||
state = VALID_OBJECT;
|
||||
}
|
||||
__except (NO_ERROR) {}
|
||||
__endtry
|
||||
return state;
|
||||
}
|
||||
|
||||
/* static members */
|
||||
|
@ -2684,18 +2685,20 @@ pthread_cond::init (pthread_cond_t *cond, const pthread_condattr_t *attr)
|
|||
return EAGAIN;
|
||||
}
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
int ret = 0;
|
||||
|
||||
__try
|
||||
{
|
||||
*cond = new_cond;
|
||||
}
|
||||
__except (NO_ERROR)
|
||||
{
|
||||
delete new_cond;
|
||||
cond_initialization_lock.unlock ();
|
||||
return EINVAL;
|
||||
ret = EINVAL;
|
||||
}
|
||||
|
||||
*cond = new_cond;
|
||||
__endtry
|
||||
cond_initialization_lock.unlock ();
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
|
@ -2747,12 +2750,10 @@ pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
|||
struct timespec tp;
|
||||
LARGE_INTEGER timeout;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
return EINVAL;
|
||||
|
||||
pthread_testcancel ();
|
||||
|
||||
__try
|
||||
{
|
||||
int err = __pthread_cond_wait_init (cond, mutex);
|
||||
if (err)
|
||||
return err;
|
||||
|
@ -2761,7 +2762,7 @@ pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
|||
if (abstime->tv_sec < 0
|
||||
|| abstime->tv_nsec < 0
|
||||
|| abstime->tv_nsec > 999999999)
|
||||
return EINVAL;
|
||||
__leave;
|
||||
|
||||
clock_gettime ((*cond)->clock_id, &tp);
|
||||
|
||||
|
@ -2787,6 +2788,10 @@ pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
|||
}
|
||||
return (*cond)->wait (*mutex, &timeout);
|
||||
}
|
||||
__except (NO_ERROR) {}
|
||||
__endtry
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex)
|
||||
|
@ -2910,18 +2915,20 @@ pthread_rwlock::init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr
|
|||
return EAGAIN;
|
||||
}
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
int ret = 0;
|
||||
|
||||
__try
|
||||
{
|
||||
*rwlock = new_rwlock;
|
||||
}
|
||||
__except (NO_ERROR)
|
||||
{
|
||||
delete new_rwlock;
|
||||
rwlock_initialization_lock.unlock ();
|
||||
return EINVAL;
|
||||
ret = EINVAL;
|
||||
}
|
||||
|
||||
*rwlock = new_rwlock;
|
||||
__endtry
|
||||
rwlock_initialization_lock.unlock ();
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
|
@ -3133,15 +3140,17 @@ pthread_mutex::init (pthread_mutex_t *mutex,
|
|||
new_mutex->type = PTHREAD_MUTEX_ERRORCHECK;
|
||||
}
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
__try
|
||||
{
|
||||
*mutex = new_mutex;
|
||||
}
|
||||
__except (NO_ERROR)
|
||||
{
|
||||
delete new_mutex;
|
||||
mutex_initialization_lock.unlock ();
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
*mutex = new_mutex;
|
||||
__endtry
|
||||
}
|
||||
mutex_initialization_lock.unlock ();
|
||||
pthread_printf ("*mutex %p, attr %p, initializer %p", *mutex, attr, initializer);
|
||||
|
@ -3230,16 +3239,17 @@ pthread_spinlock::init (pthread_spinlock_t *spinlock, int pshared)
|
|||
return EAGAIN;
|
||||
}
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
__try
|
||||
{
|
||||
*spinlock = new_spinlock;
|
||||
}
|
||||
__except (NO_ERROR)
|
||||
{
|
||||
delete new_spinlock;
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
*spinlock = new_spinlock;
|
||||
__endtry
|
||||
pthread_printf ("*spinlock %p, pshared %d", *spinlock, pshared);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3502,17 +3512,8 @@ semaphore::_timedwait (const struct timespec *abstime)
|
|||
{
|
||||
LARGE_INTEGER timeout;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
__try
|
||||
{
|
||||
/* According to SUSv3, abstime need not be checked for validity,
|
||||
if the semaphore can be locked immediately. */
|
||||
if (!_trywait ())
|
||||
return 0;
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
timeout.QuadPart = abstime->tv_sec * NSPERSEC
|
||||
+ (abstime->tv_nsec + 99) / 100 + FACTOR;
|
||||
|
||||
|
@ -3531,6 +3532,18 @@ semaphore::_timedwait (const struct timespec *abstime)
|
|||
__seterrno ();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
__except (NO_ERROR)
|
||||
{
|
||||
/* According to SUSv3, abstime need not be checked for validity,
|
||||
if the semaphore can be locked immediately. */
|
||||
if (_trywait ())
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
__endtry
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3761,37 +3774,39 @@ semaphore::post (sem_t *sem)
|
|||
int
|
||||
semaphore::getvalue (sem_t *sem, int *sval)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted () || !is_good_object (sem))
|
||||
__try
|
||||
{
|
||||
if (is_good_object (sem))
|
||||
return (*sem)->_getvalue (sval);
|
||||
}
|
||||
__except (NO_ERROR) {}
|
||||
__endtry
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (*sem)->_getvalue (sval);
|
||||
}
|
||||
|
||||
int
|
||||
semaphore::getinternal (sem_t *sem, int *sfd, unsigned long long *shash,
|
||||
LUID *sluid, unsigned int *sval)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted () || !is_good_object (sem))
|
||||
__try
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
if (!is_good_object (sem))
|
||||
__leave;
|
||||
if ((*sfd = (*sem)->fd) < 0)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
__leave;
|
||||
*shash = (*sem)->hash;
|
||||
*sluid = (*sem)->luid;
|
||||
/* POSIX defines the value in calls to sem_init/sem_open as unsigned, but
|
||||
the sem_getvalue gets a pointer to int to return the value. Go figure! */
|
||||
/* POSIX defines the value in calls to sem_init/sem_open as unsigned,
|
||||
but the sem_getvalue gets a pointer to int to return the value.
|
||||
Go figure! */
|
||||
return (*sem)->_getvalue ((int *)sval);
|
||||
}
|
||||
__except (NO_ERROR) {}
|
||||
__endtry
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* pthread_null */
|
||||
pthread *
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* timer.cc
|
||||
|
||||
Copyright 2004, 2005, 2006, 2008, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||
Copyright 2004, 2005, 2006, 2008, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -218,18 +218,19 @@ it_bad (const timespec& t)
|
|||
|
||||
int
|
||||
timer_tracker::settime (int in_flags, const itimerspec *value, itimerspec *ovalue)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
__try
|
||||
{
|
||||
if (!value)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
__leave;
|
||||
}
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT)
|
||||
|| it_bad (value->it_value)
|
||||
|| it_bad (value->it_interval))
|
||||
return -1;
|
||||
if (it_bad (value->it_value) || it_bad (value->it_interval))
|
||||
__leave;
|
||||
|
||||
long long now = in_flags & TIMER_ABSTIME ? 0 : gtod.usecs ();
|
||||
|
||||
|
@ -256,8 +257,11 @@ timer_tracker::settime (int in_flags, const itimerspec *value, itimerspec *ovalu
|
|||
ResetEvent (syncthread);
|
||||
new cygthread (timer_thread, this, "itimer", syncthread);
|
||||
}
|
||||
|
||||
return 0;
|
||||
ret = 0;
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -280,10 +284,10 @@ timer_tracker::gettime (itimerspec *ovalue)
|
|||
extern "C" int
|
||||
timer_gettime (timer_t timerid, struct itimerspec *ovalue)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
int ret = -1;
|
||||
|
||||
__try
|
||||
{
|
||||
timer_tracker *tt = (timer_tracker *) timerid;
|
||||
if (tt->magic != TT_MAGIC)
|
||||
{
|
||||
|
@ -292,17 +296,21 @@ timer_gettime (timer_t timerid, struct itimerspec *ovalue)
|
|||
}
|
||||
|
||||
tt->gettime (ovalue);
|
||||
return 0;
|
||||
ret = 0;
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
timer_create (clockid_t clock_id, struct sigevent *__restrict evp,
|
||||
timer_t *__restrict timerid)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
int ret = -1;
|
||||
|
||||
__try
|
||||
{
|
||||
if (CLOCKID_IS_PROCESS (clock_id) || CLOCKID_IS_THREAD (clock_id))
|
||||
{
|
||||
set_errno (ENOTSUP);
|
||||
|
@ -316,38 +324,47 @@ timer_create (clockid_t clock_id, struct sigevent *__restrict evp,
|
|||
}
|
||||
|
||||
*timerid = (timer_t) new timer_tracker (clock_id, evp);
|
||||
return 0;
|
||||
ret = 0;
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
timer_settime (timer_t timerid, int flags,
|
||||
const struct itimerspec *__restrict value,
|
||||
struct itimerspec *__restrict ovalue)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
__try
|
||||
{
|
||||
timer_tracker *tt = (timer_tracker *) timerid;
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
if (tt->magic != TT_MAGIC)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
__leave;
|
||||
}
|
||||
|
||||
return tt->settime (flags, value, ovalue);
|
||||
ret = tt->settime (flags, value, ovalue);
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
timer_delete (timer_t timerid)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
__try
|
||||
{
|
||||
timer_tracker *in_tt = (timer_tracker *) timerid;
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
if (in_tt->magic != TT_MAGIC)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
__leave;
|
||||
}
|
||||
|
||||
lock_timer_tracker here;
|
||||
|
@ -356,10 +373,15 @@ timer_delete (timer_t timerid)
|
|||
{
|
||||
tt->next = in_tt->next;
|
||||
delete in_tt;
|
||||
return 0;
|
||||
ret = 0;
|
||||
__leave;
|
||||
}
|
||||
set_errno (EINVAL);
|
||||
return 0;
|
||||
ret = 0;
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -412,18 +434,13 @@ setitimer (int which, const struct itimerval *__restrict value,
|
|||
extern "C" int
|
||||
getitimer (int which, struct itimerval *ovalue)
|
||||
{
|
||||
int ret;
|
||||
int ret = -1;
|
||||
|
||||
if (which != ITIMER_REAL)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
ret = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
ret = -1;
|
||||
else
|
||||
__try
|
||||
{
|
||||
struct itimerspec spec_ovalue;
|
||||
ret = timer_gettime ((timer_t) &ttstart, &spec_ovalue);
|
||||
|
@ -435,6 +452,8 @@ getitimer (int which, struct itimerval *ovalue)
|
|||
ovalue->it_value.tv_usec = spec_ovalue.it_value.tv_nsec / 1000;
|
||||
}
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
}
|
||||
syscall_printf ("%R = getitimer()", ret);
|
||||
return ret;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* times.cc
|
||||
|
||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
||||
2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||
2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -59,14 +59,13 @@ __to_clock_t (PLARGE_INTEGER src, int flag)
|
|||
extern "C" clock_t
|
||||
times (struct tms *buf)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return ((clock_t) -1);
|
||||
|
||||
static SYSTEM_TIMEOFDAY_INFORMATION stodi;
|
||||
KERNEL_USER_TIMES kut;
|
||||
LARGE_INTEGER ticks;
|
||||
clock_t tc = (clock_t) -1;
|
||||
|
||||
__try
|
||||
{
|
||||
/* Fetch boot time if we haven't already. */
|
||||
if (!stodi.BootTime.QuadPart)
|
||||
NtQuerySystemInformation (SystemTimeOfDayInformation,
|
||||
|
@ -79,7 +78,7 @@ times (struct tms *buf)
|
|||
/* uptime */
|
||||
ticks.QuadPart -= stodi.BootTime.QuadPart;
|
||||
/* ticks is in in 100ns, convert to clock ticks. */
|
||||
clock_t tc = (clock_t) (ticks.QuadPart * CLOCKS_PER_SEC / NSPERSEC);
|
||||
tc = (clock_t) (ticks.QuadPart * CLOCKS_PER_SEC / NSPERSEC);
|
||||
|
||||
buf->tms_stime = __to_clock_t (&kut.KernelTime, 0);
|
||||
buf->tms_utime = __to_clock_t (&kut.UserTime, 0);
|
||||
|
@ -87,7 +86,12 @@ times (struct tms *buf)
|
|||
buf->tms_cstime = __to_clock_t (&kut.KernelTime, 1);
|
||||
timeval_to_filetime (&myself->rusage_children.ru_utime, &kut.UserTime);
|
||||
buf->tms_cutime = __to_clock_t (&kut.UserTime, 1);
|
||||
|
||||
}
|
||||
__except (EFAULT)
|
||||
{
|
||||
tc = (clock_t) -1;
|
||||
}
|
||||
__endtry
|
||||
syscall_printf ("%D = times(%p)", tc, buf);
|
||||
return tc;
|
||||
}
|
||||
|
@ -100,12 +104,10 @@ settimeofday (const struct timeval *tv, const struct timezone *tz)
|
|||
{
|
||||
SYSTEMTIME st;
|
||||
struct tm *ptm;
|
||||
int res;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
int res = -1;
|
||||
|
||||
__try
|
||||
{
|
||||
if (tv->tv_usec < 0 || tv->tv_usec >= 1000000)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
|
@ -127,7 +129,12 @@ settimeofday (const struct timeval *tv, const struct timezone *tz)
|
|||
|
||||
if (res)
|
||||
set_errno (EPERM);
|
||||
|
||||
}
|
||||
__except (EFAULT)
|
||||
{
|
||||
res = -1;
|
||||
}
|
||||
__endtry
|
||||
syscall_printf ("%R = settimeofday(%p, %p)", res, tv, tz);
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -8,17 +8,16 @@ details. */
|
|||
|
||||
#include <winsup.h>
|
||||
#include <malloc.h>
|
||||
#include "cygtls.h"
|
||||
#include "tls_pbuf.h"
|
||||
|
||||
#define tls_pbuf _my_tls.locals.pathbufs
|
||||
#define tls_pbuf _my_tls.pathbufs
|
||||
|
||||
void
|
||||
tls_pathbuf::destroy ()
|
||||
{
|
||||
for (unsigned i = 0; i < TP_NUM_C_BUFS && c_buf[i]; ++i)
|
||||
for (uint32_t i = 0; i < TP_NUM_C_BUFS && c_buf[i]; ++i)
|
||||
free (c_buf[i]);
|
||||
for (unsigned i = 0; i < TP_NUM_W_BUFS && w_buf[i]; ++i)
|
||||
for (uint32_t i = 0; i < TP_NUM_W_BUFS && w_buf[i]; ++i)
|
||||
free (w_buf[i]);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,20 +10,20 @@ details. */
|
|||
|
||||
class tmp_pathbuf
|
||||
{
|
||||
unsigned c_buf_old;
|
||||
unsigned w_buf_old;
|
||||
uint32_t c_buf_old;
|
||||
uint32_t w_buf_old;
|
||||
public:
|
||||
tmp_pathbuf () __attribute__ ((always_inline))
|
||||
: c_buf_old (_my_tls.locals.pathbufs.c_cnt),
|
||||
w_buf_old (_my_tls.locals.pathbufs.w_cnt)
|
||||
: c_buf_old (_my_tls.pathbufs.c_cnt),
|
||||
w_buf_old (_my_tls.pathbufs.w_cnt)
|
||||
{}
|
||||
~tmp_pathbuf () __attribute__ ((always_inline))
|
||||
{
|
||||
_my_tls.locals.pathbufs.c_cnt = c_buf_old;
|
||||
_my_tls.locals.pathbufs.w_cnt = w_buf_old;
|
||||
_my_tls.pathbufs.c_cnt = c_buf_old;
|
||||
_my_tls.pathbufs.w_cnt = w_buf_old;
|
||||
}
|
||||
|
||||
inline bool check_usage (unsigned c_need, unsigned w_need)
|
||||
inline bool check_usage (uint32_t c_need, uint32_t w_need)
|
||||
{
|
||||
return c_need + c_buf_old < TP_NUM_C_BUFS
|
||||
&& w_need + w_buf_old < TP_NUM_W_BUFS;
|
||||
|
|
|
@ -3,44 +3,46 @@
|
|||
//; $tls::start_offset = -12700;
|
||||
//; $tls::locals = -12700;
|
||||
//; $tls::plocals = 0;
|
||||
//; $tls::local_clib = -10980;
|
||||
//; $tls::plocal_clib = 1720;
|
||||
//; $tls::__dontuse = -10980;
|
||||
//; $tls::p__dontuse = 1720;
|
||||
//; $tls::func = -9892;
|
||||
//; $tls::pfunc = 2808;
|
||||
//; $tls::saved_errno = -9888;
|
||||
//; $tls::psaved_errno = 2812;
|
||||
//; $tls::sa_flags = -9884;
|
||||
//; $tls::psa_flags = 2816;
|
||||
//; $tls::oldmask = -9880;
|
||||
//; $tls::poldmask = 2820;
|
||||
//; $tls::deltamask = -9876;
|
||||
//; $tls::pdeltamask = 2824;
|
||||
//; $tls::errno_addr = -9872;
|
||||
//; $tls::perrno_addr = 2828;
|
||||
//; $tls::sigmask = -9868;
|
||||
//; $tls::psigmask = 2832;
|
||||
//; $tls::sigwait_mask = -9864;
|
||||
//; $tls::psigwait_mask = 2836;
|
||||
//; $tls::sigwait_info = -9860;
|
||||
//; $tls::psigwait_info = 2840;
|
||||
//; $tls::signal_arrived = -9856;
|
||||
//; $tls::psignal_arrived = 2844;
|
||||
//; $tls::will_wait_for_signal = -9852;
|
||||
//; $tls::pwill_wait_for_signal = 2848;
|
||||
//; $tls::thread_context = -9848;
|
||||
//; $tls::pthread_context = 2852;
|
||||
//; $tls::thread_id = -9636;
|
||||
//; $tls::pthread_id = 3064;
|
||||
//; $tls::infodata = -9632;
|
||||
//; $tls::pinfodata = 3068;
|
||||
//; $tls::tid = -9484;
|
||||
//; $tls::ptid = 3216;
|
||||
//; $tls::_ctinfo = -9480;
|
||||
//; $tls::p_ctinfo = 3220;
|
||||
//; $tls::andreas = -9476;
|
||||
//; $tls::pandreas = 3224;
|
||||
//; $tls::local_clib = -11388;
|
||||
//; $tls::plocal_clib = 1312;
|
||||
//; $tls::__dontuse = -11388;
|
||||
//; $tls::p__dontuse = 1312;
|
||||
//; $tls::func = -10300;
|
||||
//; $tls::pfunc = 2400;
|
||||
//; $tls::saved_errno = -10296;
|
||||
//; $tls::psaved_errno = 2404;
|
||||
//; $tls::sa_flags = -10292;
|
||||
//; $tls::psa_flags = 2408;
|
||||
//; $tls::oldmask = -10288;
|
||||
//; $tls::poldmask = 2412;
|
||||
//; $tls::deltamask = -10284;
|
||||
//; $tls::pdeltamask = 2416;
|
||||
//; $tls::errno_addr = -10280;
|
||||
//; $tls::perrno_addr = 2420;
|
||||
//; $tls::sigmask = -10276;
|
||||
//; $tls::psigmask = 2424;
|
||||
//; $tls::sigwait_mask = -10272;
|
||||
//; $tls::psigwait_mask = 2428;
|
||||
//; $tls::sigwait_info = -10268;
|
||||
//; $tls::psigwait_info = 2432;
|
||||
//; $tls::signal_arrived = -10264;
|
||||
//; $tls::psignal_arrived = 2436;
|
||||
//; $tls::will_wait_for_signal = -10260;
|
||||
//; $tls::pwill_wait_for_signal = 2440;
|
||||
//; $tls::thread_context = -10256;
|
||||
//; $tls::pthread_context = 2444;
|
||||
//; $tls::thread_id = -10044;
|
||||
//; $tls::pthread_id = 2656;
|
||||
//; $tls::infodata = -10040;
|
||||
//; $tls::pinfodata = 2660;
|
||||
//; $tls::tid = -9892;
|
||||
//; $tls::ptid = 2808;
|
||||
//; $tls::_ctinfo = -9888;
|
||||
//; $tls::p_ctinfo = 2812;
|
||||
//; $tls::andreas = -9884;
|
||||
//; $tls::pandreas = 2816;
|
||||
//; $tls::pathbufs = -9880;
|
||||
//; $tls::ppathbufs = 2820;
|
||||
//; $tls::wq = -9472;
|
||||
//; $tls::pwq = 3228;
|
||||
//; $tls::sig = -9444;
|
||||
|
@ -61,44 +63,46 @@
|
|||
|
||||
#define tls_locals (-12700)
|
||||
#define tls_plocals (0)
|
||||
#define tls_local_clib (-10980)
|
||||
#define tls_plocal_clib (1720)
|
||||
#define tls___dontuse (-10980)
|
||||
#define tls_p__dontuse (1720)
|
||||
#define tls_func (-9892)
|
||||
#define tls_pfunc (2808)
|
||||
#define tls_saved_errno (-9888)
|
||||
#define tls_psaved_errno (2812)
|
||||
#define tls_sa_flags (-9884)
|
||||
#define tls_psa_flags (2816)
|
||||
#define tls_oldmask (-9880)
|
||||
#define tls_poldmask (2820)
|
||||
#define tls_deltamask (-9876)
|
||||
#define tls_pdeltamask (2824)
|
||||
#define tls_errno_addr (-9872)
|
||||
#define tls_perrno_addr (2828)
|
||||
#define tls_sigmask (-9868)
|
||||
#define tls_psigmask (2832)
|
||||
#define tls_sigwait_mask (-9864)
|
||||
#define tls_psigwait_mask (2836)
|
||||
#define tls_sigwait_info (-9860)
|
||||
#define tls_psigwait_info (2840)
|
||||
#define tls_signal_arrived (-9856)
|
||||
#define tls_psignal_arrived (2844)
|
||||
#define tls_will_wait_for_signal (-9852)
|
||||
#define tls_pwill_wait_for_signal (2848)
|
||||
#define tls_thread_context (-9848)
|
||||
#define tls_pthread_context (2852)
|
||||
#define tls_thread_id (-9636)
|
||||
#define tls_pthread_id (3064)
|
||||
#define tls_infodata (-9632)
|
||||
#define tls_pinfodata (3068)
|
||||
#define tls_tid (-9484)
|
||||
#define tls_ptid (3216)
|
||||
#define tls__ctinfo (-9480)
|
||||
#define tls_p_ctinfo (3220)
|
||||
#define tls_andreas (-9476)
|
||||
#define tls_pandreas (3224)
|
||||
#define tls_local_clib (-11388)
|
||||
#define tls_plocal_clib (1312)
|
||||
#define tls___dontuse (-11388)
|
||||
#define tls_p__dontuse (1312)
|
||||
#define tls_func (-10300)
|
||||
#define tls_pfunc (2400)
|
||||
#define tls_saved_errno (-10296)
|
||||
#define tls_psaved_errno (2404)
|
||||
#define tls_sa_flags (-10292)
|
||||
#define tls_psa_flags (2408)
|
||||
#define tls_oldmask (-10288)
|
||||
#define tls_poldmask (2412)
|
||||
#define tls_deltamask (-10284)
|
||||
#define tls_pdeltamask (2416)
|
||||
#define tls_errno_addr (-10280)
|
||||
#define tls_perrno_addr (2420)
|
||||
#define tls_sigmask (-10276)
|
||||
#define tls_psigmask (2424)
|
||||
#define tls_sigwait_mask (-10272)
|
||||
#define tls_psigwait_mask (2428)
|
||||
#define tls_sigwait_info (-10268)
|
||||
#define tls_psigwait_info (2432)
|
||||
#define tls_signal_arrived (-10264)
|
||||
#define tls_psignal_arrived (2436)
|
||||
#define tls_will_wait_for_signal (-10260)
|
||||
#define tls_pwill_wait_for_signal (2440)
|
||||
#define tls_thread_context (-10256)
|
||||
#define tls_pthread_context (2444)
|
||||
#define tls_thread_id (-10044)
|
||||
#define tls_pthread_id (2656)
|
||||
#define tls_infodata (-10040)
|
||||
#define tls_pinfodata (2660)
|
||||
#define tls_tid (-9892)
|
||||
#define tls_ptid (2808)
|
||||
#define tls__ctinfo (-9888)
|
||||
#define tls_p_ctinfo (2812)
|
||||
#define tls_andreas (-9884)
|
||||
#define tls_pandreas (2816)
|
||||
#define tls_pathbufs (-9880)
|
||||
#define tls_ppathbufs (2820)
|
||||
#define tls_wq (-9472)
|
||||
#define tls_pwq (3228)
|
||||
#define tls_sig (-9444)
|
||||
|
|
|
@ -3,44 +3,46 @@
|
|||
//; $tls::start_offset = -12800;
|
||||
//; $tls::locals = -12800;
|
||||
//; $tls::plocals = 0;
|
||||
//; $tls::local_clib = -10624;
|
||||
//; $tls::plocal_clib = 2176;
|
||||
//; $tls::__dontuse = -10624;
|
||||
//; $tls::p__dontuse = 2176;
|
||||
//; $tls::func = -8736;
|
||||
//; $tls::pfunc = 4064;
|
||||
//; $tls::saved_errno = -8728;
|
||||
//; $tls::psaved_errno = 4072;
|
||||
//; $tls::sa_flags = -8724;
|
||||
//; $tls::psa_flags = 4076;
|
||||
//; $tls::oldmask = -8720;
|
||||
//; $tls::poldmask = 4080;
|
||||
//; $tls::deltamask = -8712;
|
||||
//; $tls::pdeltamask = 4088;
|
||||
//; $tls::errno_addr = -8704;
|
||||
//; $tls::perrno_addr = 4096;
|
||||
//; $tls::sigmask = -8696;
|
||||
//; $tls::psigmask = 4104;
|
||||
//; $tls::sigwait_mask = -8688;
|
||||
//; $tls::psigwait_mask = 4112;
|
||||
//; $tls::sigwait_info = -8680;
|
||||
//; $tls::psigwait_info = 4120;
|
||||
//; $tls::signal_arrived = -8672;
|
||||
//; $tls::psignal_arrived = 4128;
|
||||
//; $tls::will_wait_for_signal = -8664;
|
||||
//; $tls::pwill_wait_for_signal = 4136;
|
||||
//; $tls::thread_context = -8656;
|
||||
//; $tls::pthread_context = 4144;
|
||||
//; $tls::thread_id = -7824;
|
||||
//; $tls::pthread_id = 4976;
|
||||
//; $tls::infodata = -7820;
|
||||
//; $tls::pinfodata = 4980;
|
||||
//; $tls::tid = -7672;
|
||||
//; $tls::ptid = 5128;
|
||||
//; $tls::_ctinfo = -7664;
|
||||
//; $tls::p_ctinfo = 5136;
|
||||
//; $tls::andreas = -7656;
|
||||
//; $tls::pandreas = 5144;
|
||||
//; $tls::local_clib = -11432;
|
||||
//; $tls::plocal_clib = 1368;
|
||||
//; $tls::__dontuse = -11432;
|
||||
//; $tls::p__dontuse = 1368;
|
||||
//; $tls::func = -9544;
|
||||
//; $tls::pfunc = 3256;
|
||||
//; $tls::saved_errno = -9536;
|
||||
//; $tls::psaved_errno = 3264;
|
||||
//; $tls::sa_flags = -9532;
|
||||
//; $tls::psa_flags = 3268;
|
||||
//; $tls::oldmask = -9528;
|
||||
//; $tls::poldmask = 3272;
|
||||
//; $tls::deltamask = -9520;
|
||||
//; $tls::pdeltamask = 3280;
|
||||
//; $tls::errno_addr = -9512;
|
||||
//; $tls::perrno_addr = 3288;
|
||||
//; $tls::sigmask = -9504;
|
||||
//; $tls::psigmask = 3296;
|
||||
//; $tls::sigwait_mask = -9496;
|
||||
//; $tls::psigwait_mask = 3304;
|
||||
//; $tls::sigwait_info = -9488;
|
||||
//; $tls::psigwait_info = 3312;
|
||||
//; $tls::signal_arrived = -9480;
|
||||
//; $tls::psignal_arrived = 3320;
|
||||
//; $tls::will_wait_for_signal = -9472;
|
||||
//; $tls::pwill_wait_for_signal = 3328;
|
||||
//; $tls::thread_context = -9464;
|
||||
//; $tls::pthread_context = 3336;
|
||||
//; $tls::thread_id = -8632;
|
||||
//; $tls::pthread_id = 4168;
|
||||
//; $tls::infodata = -8628;
|
||||
//; $tls::pinfodata = 4172;
|
||||
//; $tls::tid = -8480;
|
||||
//; $tls::ptid = 4320;
|
||||
//; $tls::_ctinfo = -8472;
|
||||
//; $tls::p_ctinfo = 4328;
|
||||
//; $tls::andreas = -8464;
|
||||
//; $tls::pandreas = 4336;
|
||||
//; $tls::pathbufs = -8456;
|
||||
//; $tls::ppathbufs = 4344;
|
||||
//; $tls::wq = -7648;
|
||||
//; $tls::pwq = 5152;
|
||||
//; $tls::sig = -7600;
|
||||
|
@ -61,44 +63,46 @@
|
|||
|
||||
#define tls_locals (-12800)
|
||||
#define tls_plocals (0)
|
||||
#define tls_local_clib (-10624)
|
||||
#define tls_plocal_clib (2176)
|
||||
#define tls___dontuse (-10624)
|
||||
#define tls_p__dontuse (2176)
|
||||
#define tls_func (-8736)
|
||||
#define tls_pfunc (4064)
|
||||
#define tls_saved_errno (-8728)
|
||||
#define tls_psaved_errno (4072)
|
||||
#define tls_sa_flags (-8724)
|
||||
#define tls_psa_flags (4076)
|
||||
#define tls_oldmask (-8720)
|
||||
#define tls_poldmask (4080)
|
||||
#define tls_deltamask (-8712)
|
||||
#define tls_pdeltamask (4088)
|
||||
#define tls_errno_addr (-8704)
|
||||
#define tls_perrno_addr (4096)
|
||||
#define tls_sigmask (-8696)
|
||||
#define tls_psigmask (4104)
|
||||
#define tls_sigwait_mask (-8688)
|
||||
#define tls_psigwait_mask (4112)
|
||||
#define tls_sigwait_info (-8680)
|
||||
#define tls_psigwait_info (4120)
|
||||
#define tls_signal_arrived (-8672)
|
||||
#define tls_psignal_arrived (4128)
|
||||
#define tls_will_wait_for_signal (-8664)
|
||||
#define tls_pwill_wait_for_signal (4136)
|
||||
#define tls_thread_context (-8656)
|
||||
#define tls_pthread_context (4144)
|
||||
#define tls_thread_id (-7824)
|
||||
#define tls_pthread_id (4976)
|
||||
#define tls_infodata (-7820)
|
||||
#define tls_pinfodata (4980)
|
||||
#define tls_tid (-7672)
|
||||
#define tls_ptid (5128)
|
||||
#define tls__ctinfo (-7664)
|
||||
#define tls_p_ctinfo (5136)
|
||||
#define tls_andreas (-7656)
|
||||
#define tls_pandreas (5144)
|
||||
#define tls_local_clib (-11432)
|
||||
#define tls_plocal_clib (1368)
|
||||
#define tls___dontuse (-11432)
|
||||
#define tls_p__dontuse (1368)
|
||||
#define tls_func (-9544)
|
||||
#define tls_pfunc (3256)
|
||||
#define tls_saved_errno (-9536)
|
||||
#define tls_psaved_errno (3264)
|
||||
#define tls_sa_flags (-9532)
|
||||
#define tls_psa_flags (3268)
|
||||
#define tls_oldmask (-9528)
|
||||
#define tls_poldmask (3272)
|
||||
#define tls_deltamask (-9520)
|
||||
#define tls_pdeltamask (3280)
|
||||
#define tls_errno_addr (-9512)
|
||||
#define tls_perrno_addr (3288)
|
||||
#define tls_sigmask (-9504)
|
||||
#define tls_psigmask (3296)
|
||||
#define tls_sigwait_mask (-9496)
|
||||
#define tls_psigwait_mask (3304)
|
||||
#define tls_sigwait_info (-9488)
|
||||
#define tls_psigwait_info (3312)
|
||||
#define tls_signal_arrived (-9480)
|
||||
#define tls_psignal_arrived (3320)
|
||||
#define tls_will_wait_for_signal (-9472)
|
||||
#define tls_pwill_wait_for_signal (3328)
|
||||
#define tls_thread_context (-9464)
|
||||
#define tls_pthread_context (3336)
|
||||
#define tls_thread_id (-8632)
|
||||
#define tls_pthread_id (4168)
|
||||
#define tls_infodata (-8628)
|
||||
#define tls_pinfodata (4172)
|
||||
#define tls_tid (-8480)
|
||||
#define tls_ptid (4320)
|
||||
#define tls__ctinfo (-8472)
|
||||
#define tls_p_ctinfo (4328)
|
||||
#define tls_andreas (-8464)
|
||||
#define tls_pandreas (4336)
|
||||
#define tls_pathbufs (-8456)
|
||||
#define tls_ppathbufs (4344)
|
||||
#define tls_wq (-7648)
|
||||
#define tls_pwq (5152)
|
||||
#define tls_sig (-7600)
|
||||
|
|
|
@ -217,10 +217,15 @@ getlogin_r (char *name, size_t namesize)
|
|||
size_t len = strlen (login) + 1;
|
||||
if (len > namesize)
|
||||
return ERANGE;
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
return EFAULT;
|
||||
__try
|
||||
{
|
||||
strncpy (name, login, len);
|
||||
}
|
||||
__except (NO_ERROR)
|
||||
{
|
||||
return EFAULT;
|
||||
}
|
||||
__endtry
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* uname.cc
|
||||
|
||||
Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
||||
2006, 2007, 2008, 2013 Red Hat, Inc.
|
||||
2006, 2007, 2008, 2013, 2014 Red Hat, Inc.
|
||||
Written by Steve Chamberlain of Cygnus Support, sac@cygnus.com
|
||||
Rewritten by Geoffrey Noer of Cygnus Solutions, noer@cygnus.com
|
||||
|
||||
|
@ -22,10 +22,8 @@ uname (struct utsname *name)
|
|||
{
|
||||
SYSTEM_INFO sysinfo;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
__try
|
||||
{
|
||||
char *snp = strstr (cygwin_version.dll_build_date, "SNP");
|
||||
|
||||
memset (name, 0, sizeof (*name));
|
||||
|
@ -90,6 +88,11 @@ uname (struct utsname *name)
|
|||
strcpy (name->machine, "unknown");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
__except (EFAULT)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
__endtry
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue