* 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:
Corinna Vinschen 2014-08-22 09:21:33 +00:00
parent 33ed7bb5bc
commit 3f3bd10104
41 changed files with 6383 additions and 5924 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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
{

View File

@ -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. */

View File

@ -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;
@ -284,6 +289,13 @@ closedir (DIR *dir)
free (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 */
@ -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;
}

View File

@ -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, '=');
@ -677,6 +676,10 @@ putenv (char *str)
unsetenv (str);
}
return 0;
}
__except (EFAULT) {}
__endtry
return -1;
}
/* Set the value of the environment variable "name" to be
@ -684,15 +687,18 @@ putenv (char *str)
extern "C" int
setenv (const char *name, const char *value, int overwrite)
{
myfault efault;
if (efault.faulted (EFAULT))
return -1;
__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". */
@ -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 */
@ -717,6 +723,10 @@ unsetenv (const char *name)
break;
return 0;
}
__except (EFAULT) {}
__endtry
return -1;
}
/* Minimal list of Windows vars which must be converted to uppercase.
@ -822,12 +832,10 @@ environ_init (char **envp, int envc)
bool envp_passed_in;
bool 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])
@ -897,7 +905,7 @@ environ_init (char **envp, int envc)
envp[i] = NULL;
FreeEnvironmentStringsW (rawenv);
out:
out:
findenv_func = (char * (*)(const char*, int*)) my_findenv;
__cygwin_environ = envp;
update_envptrs ();
@ -912,6 +920,13 @@ out:
parse_options (NULL); /* possibly export registry settings to
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. */

View File

@ -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 = &el;
};
~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 = &el;
#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;

View File

@ -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,13 +365,17 @@ 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",
i == 16 ? " (more stack frames may be present)" : "");
if (h)
NtClose (h);
}
__except (NO_ERROR) {}
__endtry
}
bool
@ -549,40 +552,24 @@ rtl_unwind (exception_list *frame, PEXCEPTION_RECORD e)
#endif /* __x86_64 */
#ifdef __x86_64__
/* myfault vectored exception handler */
LONG
exception::myfault_handle (LPEXCEPTION_POINTERS ep)
/* myfault exception handler. */
EXCEPTION_DISPOSITION
exception::myfault (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in,
PDISPATCHER_CONTEXT dispatch)
{
_cygtls& me = _my_tls;
if (me.andreas)
{
/* Only handle the minimum amount of exceptions the myfault handler
was designed for. */
switch (ep->ExceptionRecord->ExceptionCode)
{
case STATUS_ACCESS_VIOLATION:
case STATUS_DATATYPE_MISALIGNMENT:
#if 0
/* PAGE_GUARD-based stack commits are based on structured exception
handling. Short-circuiting STATUS_STACK_OVERFLOW in a vectored
exception handler disables that, which can ultimately result in
a spurious SEGV. */
case STATUS_STACK_OVERFLOW:
#endif
case STATUS_ARRAY_BOUNDS_EXCEEDED:
me.andreas->leave (); /* Return from a "san" caught fault */
default:
break;
}
}
return EXCEPTION_CONTINUE_SEARCH;
PSCOPE_TABLE table = (PSCOPE_TABLE) dispatch->HandlerData;
RtlUnwindEx (frame,
(char *) dispatch->ImageBase + table->ScopeRecord[0].JumpTarget,
e, 0, in, dispatch->HistoryTable);
/* NOTREACHED, make gcc happy. */
return ExceptionContinueSearch;
}
#endif /* __x86_64 */
#endif
/* Main exception handler. */
int
exception::handle (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in, void *)
EXCEPTION_DISPOSITION
exception::handle (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in,
PDISPATCHER_CONTEXT dispatch)
{
static bool NO_COPY debugging;
_cygtls& me = _my_tls;

View File

@ -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);
@ -118,5 +117,9 @@ _fcntl (int fd, int cmd, ...)
src->l_pid = (short) dst.l_pid;
}
return res;
}
__except (EFAULT)
__endtry
return -1;
}
#endif

View File

@ -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)
@ -2303,4 +2302,8 @@ fhandler_socket::getpeereid (pid_t *pid, uid_t *euid, gid_t *egid)
if (egid)
*egid = sec_peer_gid;
return 0;
}
__except (EFAULT) {}
__endtry
return -1;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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;
@ -231,6 +230,10 @@ check_iovec (const struct iovec *iov, int iovcnt, bool forwrite)
assert (tot <= SSIZE_MAX);
return (ssize_t) tot;
}
__except (EFAULT)
__endtry
return -1;
}
/* Try hard to schedule another thread.
@ -512,18 +515,23 @@ slashify (const char *src, char *dst, bool trailing_slash_p)
void * __reg1
__import_address (void *imp)
{
myfault efault;
if (efault.faulted ())
return NULL;
if (*((uint16_t *) imp) != 0x25ff)
return NULL;
__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.

View File

@ -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,15 +1759,18 @@ mount (const char *win32_path, const char *posix_path, unsigned flags)
extern "C" int
umount (const char *path)
{
myfault efault;
if (efault.faulted (EFAULT))
return -1;
__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

View File

@ -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,9 +118,13 @@ 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
@ -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,9 +158,13 @@ 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
@ -167,9 +172,8 @@ msgsnd (int msqid, const void *msgp, size_t msgsz, int msgflg)
{
syscall_printf ("msgsnd (msqid = %d, msgp = %p, msgsz = %ld, msgflg = %y)",
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

View File

@ -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

View File

@ -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)",

View File

@ -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;
@ -886,11 +885,11 @@ path_conv::check (const char *src, unsigned opt,
if (is_msdos)
sym.pflags |= PATH_NOPOSIX | PATH_NOACL;
is_fs_via_procsys:
is_fs_via_procsys:
symlen = sym.check (full_path, suff, fs, conv_handle);
is_virtual_symlink:
is_virtual_symlink:
if (sym.isdevice)
{
@ -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. */
@ -994,7 +995,7 @@ is_virtual_symlink:
}
/* No existing file found. */
virtual_component_retry:
virtual_component_retry:
/* Find the new "tail" of the path, e.g. in '/for/bar/baz',
/baz is the tail. */
if (tail != path_end)
@ -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;;
@ -1070,7 +1073,7 @@ virtual_component_retry:
if (!(opt & PC_SYM_CONTENTS))
add_ext = true;
out:
out:
set_path (THIS_path);
if (add_ext)
add_ext_from_sym (sym);
@ -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. */
@ -1206,6 +1213,12 @@ out:
strcpy (last_src, src);
}
#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;
}

View File

@ -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);
@ -155,4 +154,8 @@ ppoll (struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts,
if (sigmask)
set_signal_mask (_my_tls.sigmask, oldset);
return ret;
}
__except (EFAULT) {}
__endtry
return -1;
}

View File

@ -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,18 +433,13 @@ 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:
again:
if (oflag & O_CREAT)
{
va_start (ap, oflag); /* init ap to final named argument */
@ -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,30 +522,36 @@ 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);
}
exists:
exists:
/* Open the file then memory map */
if ((fd = open (mqname, O_RDWR | O_CLOEXEC)) < 0)
{
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,29 +573,29 @@ 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)
{
system_printf (
"Old message queue \"%s\" detected!\n"
"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);
"Old message queue \"%s\" detected!\n"
"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 */
@ -668,6 +674,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
@ -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)
@ -711,6 +719,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
@ -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;
@ -760,6 +770,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
@ -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);
@ -1032,6 +1046,10 @@ mq_close (mqd_t mqd)
ipc_mutex_close (mqinfo->mqi_lock);
free (mqinfo);
return 0;
}
__except (EBADF) {}
__endtry
return -1;
}
extern "C" int
@ -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,14 +1096,11 @@ 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:
again:
if (oflag & O_CREAT)
{
va_start (ap, oflag); /* init ap to final named argument */
@ -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,24 +1123,25 @@ 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;
}
exists:
exists:
/* Open the file and fetch the semaphore name. */
if ((fd = open (semname, O_RDWR | O_CLOEXEC)) < 0)
{
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);

View File

@ -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;
}

View File

@ -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;
@ -245,6 +244,10 @@ pselect(int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
if (set)
set_signal_mask (_my_tls.sigmask, oldset);
return ret;
}
__except (EFAULT) {}
__endtry
return -1;
}
/* Call cleanup functions for all inspected fds. Gets rid of any

View File

@ -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,9 +94,13 @@ 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
@ -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;
}

View File

@ -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;
}
@ -295,6 +295,10 @@ shmctl (int shmid, int cmd, struct shmid_ds *buf)
SLIST_UNLOCK ();
}
return request.retval ();
}
__except (EFAULT) {}
__endtry
return -1;
}
extern "C" int

View File

@ -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;
}

View File

@ -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;
@ -600,7 +592,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
SetHandleInformation (my_wr_proc_pipe, HANDLE_FLAG_INHERIT, 0);
parent_winpid = GetCurrentProcessId ();
loop:
loop:
/* When ruid != euid we create the new process under the current original
account and impersonate in child, this way maintaining the different
effective vs. real ids.
@ -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

View File

@ -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);
@ -2786,6 +2787,10 @@ pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
break;
}
return (*cond)->wait (*mutex, &timeout);
}
__except (NO_ERROR) {}
__endtry
return EINVAL;
}
extern "C" int
@ -2910,18 +2915,20 @@ pthread_rwlock::init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr
return EAGAIN;
}
myfault efault;
if (efault.faulted ())
int ret = 0;
__try
{
*rwlock = new_rwlock;
}
__except (NO_ERROR)
{
delete new_rwlock;
rwlock_initialization_lock.unlock ();
return EINVAL;
ret = EINVAL;
}
*rwlock = new_rwlock;
__endtry
rwlock_initialization_lock.unlock ();
return 0;
return ret;
}
extern "C" int
@ -3133,15 +3140,17 @@ pthread_mutex::init (pthread_mutex_t *mutex,
new_mutex->type = PTHREAD_MUTEX_ERRORCHECK;
}
myfault efault;
if (efault.faulted ())
__try
{
*mutex = new_mutex;
}
__except (NO_ERROR)
{
delete new_mutex;
mutex_initialization_lock.unlock ();
return EINVAL;
}
*mutex = new_mutex;
__endtry
}
mutex_initialization_lock.unlock ();
pthread_printf ("*mutex %p, attr %p, initializer %p", *mutex, attr, initializer);
@ -3230,16 +3239,17 @@ pthread_spinlock::init (pthread_spinlock_t *spinlock, int pshared)
return EAGAIN;
}
myfault efault;
if (efault.faulted ())
__try
{
*spinlock = new_spinlock;
}
__except (NO_ERROR)
{
delete new_spinlock;
return EINVAL;
}
*spinlock = new_spinlock;
__endtry
pthread_printf ("*spinlock %p, pshared %d", *spinlock, pshared);
return 0;
}
@ -3502,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,36 +3774,38 @@ semaphore::post (sem_t *sem)
int
semaphore::getvalue (sem_t *sem, int *sval)
{
myfault efault;
if (efault.faulted () || !is_good_object (sem))
__try
{
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 */

View File

@ -1,6 +1,6 @@
/* timer.cc
Copyright 2004, 2005, 2006, 2008, 2010, 2011, 2012, 2013 Red Hat, Inc.
Copyright 2004, 2005, 2006, 2008, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
This file is part of Cygwin.
@ -219,17 +219,18 @@ 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,7 +324,11 @@ 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
@ -324,30 +336,35 @@ 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;

View File

@ -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;
}

View File

@ -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]);
}

View File

@ -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;

View File

@ -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)

View File

@ -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)

View File

@ -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;
}

View File

@ -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;
}