* 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);
if (dir->__d_cookie == __DIRENT_COOKIE)
return dir->__d_fd;
syscall_printf ("-1 = dirfd (%p)", dir);
return -1;
set_errno (EINVAL);
}
return dir->__d_fd;
__except (EFAULT) {}
__endtry
return -1;
}
/* Symbol kept for backward compatibility. Don't remove. Don't declare
@ -93,79 +93,86 @@ fdopendir (int fd)
static int
readdir_worker (DIR *dir, dirent *de)
{
myfault efault;
if (efault.faulted ())
return EFAULT;
int res = 0;
if (dir->__d_cookie != __DIRENT_COOKIE)
__try
{
syscall_printf ("%p = readdir (%p)", NULL, dir);
return EBADF;
}
de->d_ino = 0;
de->d_type = DT_UNKNOWN;
memset (&de->__d_unused1, 0, sizeof (de->__d_unused1));
int res = ((fhandler_base *) dir->__fh)->readdir (dir, de);
if (res == ENMFILE)
{
if (!(dir->__flags & dirent_saw_dot))
if (dir->__d_cookie != __DIRENT_COOKIE)
{
strcpy (de->d_name, ".");
dir->__flags |= dirent_saw_dot;
dir->__d_position++;
res = 0;
}
else if (!(dir->__flags & dirent_saw_dot_dot))
{
strcpy (de->d_name, "..");
dir->__flags |= dirent_saw_dot_dot;
dir->__d_position++;
res = 0;
}
}
if (!res && !de->d_ino)
{
bool is_dot = false;
bool is_dot_dot = false;
if (de->d_name[0] == '.')
{
if (de->d_name[1] == '\0')
is_dot = true;
else if (de->d_name[1] == '.' && de->d_name[2] == '\0')
is_dot_dot = true;
syscall_printf ("%p = readdir (%p)", NULL, dir);
res = EBADF;
__leave;
}
if (is_dot_dot && !(dir->__flags & dirent_isroot))
de->d_ino = readdir_get_ino (((fhandler_base *) dir->__fh)->get_name (),
true);
else
de->d_ino = 0;
de->d_type = DT_UNKNOWN;
memset (&de->__d_unused1, 0, sizeof (de->__d_unused1));
res = ((fhandler_base *) dir->__fh)->readdir (dir, de);
if (res == ENMFILE)
{
/* Compute d_ino by combining filename hash with directory hash. */
de->d_ino = ((fhandler_base *) dir->__fh)->get_ino ();
if (!is_dot && !is_dot_dot)
if (!(dir->__flags & dirent_saw_dot))
{
PUNICODE_STRING w32name =
((fhandler_base *) dir->__fh)->pc.get_nt_native_path ();
DWORD devn = ((fhandler_base *) dir->__fh)->get_device ();
/* Paths below /proc don't have a Win32 pendant. */
if (isproc_dev (devn))
de->d_ino = hash_path_name (de->d_ino, L"/");
else if (w32name->Buffer[w32name->Length / sizeof (WCHAR) - 1]
!= L'\\')
de->d_ino = hash_path_name (de->d_ino, L"\\");
de->d_ino = hash_path_name (de->d_ino, de->d_name);
strcpy (de->d_name, ".");
dir->__flags |= dirent_saw_dot;
dir->__d_position++;
res = 0;
}
else if (!(dir->__flags & dirent_saw_dot_dot))
{
strcpy (de->d_name, "..");
dir->__flags |= dirent_saw_dot_dot;
dir->__d_position++;
res = 0;
}
}
}
/* This fills out the old 32 bit d_ino field for old applications,
build under Cygwin before 1.5.x. */
de->__d_internal1 = de->d_ino;
if (!res && !de->d_ino)
{
bool is_dot = false;
bool is_dot_dot = false;
if (de->d_name[0] == '.')
{
if (de->d_name[1] == '\0')
is_dot = true;
else if (de->d_name[1] == '.' && de->d_name[2] == '\0')
is_dot_dot = true;
}
if (is_dot_dot && !(dir->__flags & dirent_isroot))
de->d_ino = readdir_get_ino (((fhandler_base *)
dir->__fh)->get_name (),
true);
else
{
/* Compute d_ino by combining filename hash with directory hash. */
de->d_ino = ((fhandler_base *) dir->__fh)->get_ino ();
if (!is_dot && !is_dot_dot)
{
PUNICODE_STRING w32name =
((fhandler_base *) dir->__fh)->pc.get_nt_native_path ();
DWORD devn = ((fhandler_base *) dir->__fh)->get_device ();
/* Paths below /proc don't have a Win32 pendant. */
if (isproc_dev (devn))
de->d_ino = hash_path_name (de->d_ino, L"/");
else if (w32name->Buffer[w32name->Length / sizeof (WCHAR) - 1]
!= L'\\')
de->d_ino = hash_path_name (de->d_ino, L"\\");
de->d_ino = hash_path_name (de->d_ino, de->d_name);
}
}
}
/* This fills out the old 32 bit d_ino field for old applications,
build under Cygwin before 1.5.x. */
de->__d_internal1 = de->d_ino;
}
__except (NO_ERROR)
{
res = EFAULT;
}
__endtry
return res;
}
@ -200,16 +207,15 @@ readdir_r (DIR *__restrict dir, dirent *__restrict de, dirent **__restrict ode)
extern "C" long
telldir (DIR *dir)
{
myfault efault;
if (efault.faulted (EFAULT))
return -1;
if (dir->__d_cookie != __DIRENT_COOKIE)
__try
{
if (dir->__d_cookie == __DIRENT_COOKIE)
return ((fhandler_base *) dir->__fh)->telldir (dir);
set_errno (EBADF);
return -1;
}
return ((fhandler_base *) dir->__fh)->telldir (dir);
__except (EFAULT) {}
__endtry
return -1;
}
/* telldir was never defined using off_t in POSIX, only in early versions
@ -225,14 +231,17 @@ telldir64 (DIR *dir)
extern "C" void
seekdir (DIR *dir, long loc)
{
myfault efault;
if (efault.faulted (EFAULT))
return;
if (dir->__d_cookie != __DIRENT_COOKIE)
return;
dir->__flags &= dirent_info_mask;
return ((fhandler_base *) dir->__fh)->seekdir (dir, loc);
__try
{
if (dir->__d_cookie == __DIRENT_COOKIE)
{
dir->__flags &= dirent_info_mask;
((fhandler_base *) dir->__fh)->seekdir (dir, loc);
}
set_errno (EINVAL); /* Diagnosis */
}
__except (EFAULT) {}
__endtry
}
/* seekdir was never defined using off_t in POSIX, only in early versions
@ -248,42 +257,45 @@ seekdir64 (DIR *dir, off_t loc)
extern "C" void
rewinddir (DIR *dir)
{
myfault efault;
if (efault.faulted (EFAULT))
return;
if (dir->__d_cookie != __DIRENT_COOKIE)
return;
dir->__flags &= dirent_info_mask;
return ((fhandler_base *) dir->__fh)->rewinddir (dir);
__try
{
if (dir->__d_cookie == __DIRENT_COOKIE)
{
dir->__flags &= dirent_info_mask;
((fhandler_base *) dir->__fh)->rewinddir (dir);
}
set_errno (EINVAL); /* Diagnosis */
}
__except (EFAULT) {}
__endtry
}
/* closedir: POSIX 5.1.2.1 */
extern "C" int
closedir (DIR *dir)
{
myfault efault;
if (efault.faulted (EFAULT))
return -1;
if (dir->__d_cookie != __DIRENT_COOKIE)
__try
{
if (dir->__d_cookie == __DIRENT_COOKIE)
{
/* Reset the marker in case the caller tries to use `dir' again. */
dir->__d_cookie = 0;
int res = ((fhandler_base *) dir->__fh)->closedir (dir);
close (dir->__d_fd);
free (dir->__d_dirname);
free (dir->__d_dirent);
free (dir);
syscall_printf ("%R = closedir(%p)", res, dir);
return res;
}
set_errno (EBADF);
syscall_printf ("%R = closedir(%p)", -1, dir);
return -1;
}
/* Reset the marker in case the caller tries to use `dir' again. */
dir->__d_cookie = 0;
int res = ((fhandler_base *) dir->__fh)->closedir (dir);
close (dir->__d_fd);
free (dir->__d_dirname);
free (dir->__d_dirent);
free (dir);
syscall_printf ("%R = closedir(%p)", res, dir);
return res;
__except (EFAULT) {}
__endtry
syscall_printf ("%R = closedir(%p)", -1, dir);
return -1;
}
/* mkdir: POSIX 5.4.1.1 */
@ -294,43 +306,42 @@ mkdir (const char *dir, mode_t mode)
fhandler_base *fh = NULL;
tmp_pathbuf tp;
myfault efault;
if (efault.faulted (EFAULT))
return -1;
/* POSIX says mkdir("symlink-to-missing/") should create the
directory "missing", but Linux rejects it with EEXIST. Copy
Linux behavior for now. */
if (!*dir)
__try
{
set_errno (ENOENT);
goto done;
}
if (isdirsep (dir[strlen (dir) - 1]))
{
/* This converts // to /, but since both give EEXIST, we're okay. */
char *buf;
char *p = stpcpy (buf = tp.c_get (), dir) - 1;
dir = buf;
while (p > dir && isdirsep (*p))
*p-- = '\0';
}
if (!(fh = build_fh_name (dir, PC_SYM_NOFOLLOW)))
goto done; /* errno already set */;
/* POSIX says mkdir("symlink-to-missing/") should create the
directory "missing", but Linux rejects it with EEXIST. Copy
Linux behavior for now. */
if (fh->error ())
{
debug_printf ("got %d error from build_fh_name", fh->error ());
set_errno (fh->error ());
}
else if (has_dot_last_component (dir, true))
set_errno (fh->exists () ? EEXIST : ENOENT);
else if (!fh->mkdir (mode))
res = 0;
delete fh;
if (!*dir)
{
set_errno (ENOENT);
__leave;
}
if (isdirsep (dir[strlen (dir) - 1]))
{
/* This converts // to /, but since both give EEXIST, we're okay. */
char *buf;
char *p = stpcpy (buf = tp.c_get (), dir) - 1;
dir = buf;
while (p > dir && isdirsep (*p))
*p-- = '\0';
}
if (!(fh = build_fh_name (dir, PC_SYM_NOFOLLOW)))
__leave; /* errno already set */;
done:
if (fh->error ())
{
debug_printf ("got %d error from build_fh_name", fh->error ());
set_errno (fh->error ());
}
else if (has_dot_last_component (dir, true))
set_errno (fh->exists () ? EEXIST : ENOENT);
else if (!fh->mkdir (mode))
res = 0;
delete fh;
}
__except (EFAULT) {}
__endtry
syscall_printf ("%R = mkdir(%s, %d)", res, dir, mode);
return res;
}
@ -342,30 +353,28 @@ rmdir (const char *dir)
int res = -1;
fhandler_base *fh = NULL;
myfault efault;
if (efault.faulted (EFAULT))
return -1;
if (!(fh = build_fh_name (dir, PC_SYM_NOFOLLOW)))
goto done; /* errno already set */;
if (fh->error ())
__try
{
debug_printf ("got %d error from build_fh_name", fh->error ());
set_errno (fh->error ());
if (!(fh = build_fh_name (dir, PC_SYM_NOFOLLOW)))
__leave; /* errno already set */;
if (fh->error ())
{
debug_printf ("got %d error from build_fh_name", fh->error ());
set_errno (fh->error ());
}
else if (!fh->exists ())
set_errno (ENOENT);
else if (has_dot_last_component (dir, false))
set_errno (EINVAL);
else if (isdev_dev (fh->dev ()))
set_errno (ENOTEMPTY);
else if (!fh->rmdir ())
res = 0;
delete fh;
}
else if (!fh->exists ())
set_errno (ENOENT);
else if (has_dot_last_component (dir, false))
set_errno (EINVAL);
else if (isdev_dev (fh->dev ()))
set_errno (ENOTEMPTY);
else if (!fh->rmdir ())
res = 0;
delete fh;
done:
__except (EFAULT) {}
__endtry
syscall_printf ("%R = rmdir(%s)", res, dir);
return res;
}

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,19 +664,22 @@ _addenv (const char *name, const char *value, int overwrite)
extern "C" int
putenv (char *str)
{
myfault efault;
if (efault.faulted (EFAULT))
return -1;
if (*str)
__try
{
char *eq = strchr (str, '=');
if (eq)
return _addenv (str, eq + 1, -1);
if (*str)
{
char *eq = strchr (str, '=');
if (eq)
return _addenv (str, eq + 1, -1);
/* Remove str from the environment. */
unsetenv (str);
/* Remove str from the environment. */
unsetenv (str);
}
return 0;
}
return 0;
__except (EFAULT) {}
__endtry
return -1;
}
/* Set the value of the environment variable "name" to be
@ -684,15 +687,18 @@ putenv (char *str)
extern "C" int
setenv (const char *name, const char *value, int overwrite)
{
myfault efault;
if (efault.faulted (EFAULT))
return -1;
if (!name || !*name || strchr (name, '='))
__try
{
set_errno (EINVAL);
return -1;
if (!name || !*name || strchr (name, '='))
{
set_errno (EINVAL);
__leave;
}
return _addenv (name, value, !!overwrite);
}
return _addenv (name, value, !!overwrite);
__except (EFAULT) {}
__endtry
return -1;
}
/* Delete environment variable "name". */
@ -701,22 +707,26 @@ unsetenv (const char *name)
{
register char **e;
int offset;
myfault efault;
if (efault.faulted (EFAULT))
return -1;
if (!name || *name == '\0' || strchr (name, '='))
__try
{
set_errno (EINVAL);
return -1;
if (!name || *name == '\0' || strchr (name, '='))
{
set_errno (EINVAL);
__leave;
}
while (my_findenv (name, &offset)) /* if set multiple times */
/* Move up the rest of the array */
for (e = cur_environ () + offset; ; e++)
if (!(*e = *(e + 1)))
break;
return 0;
}
while (my_findenv (name, &offset)) /* if set multiple times */
/* Move up the rest of the array */
for (e = cur_environ () + offset; ; e++)
if (!(*e = *(e + 1)))
break;
return 0;
__except (EFAULT) {}
__endtry
return -1;
}
/* Minimal list of Windows vars which must be converted to uppercase.
@ -822,96 +832,101 @@ environ_init (char **envp, int envc)
bool envp_passed_in;
bool got_something_from_registry;
static char NO_COPY cygterm[] = "TERM=cygwin";
myfault efault;
tmp_pathbuf tp;
if (efault.faulted ())
api_fatal ("internal error reading the windows environment - too many environment variables?");
char *tmpbuf = tp.t_get ();
got_something_from_registry = regopt (L"default", tmpbuf);
if (myself->progname[0])
got_something_from_registry = regopt (myself->progname, tmpbuf)
|| got_something_from_registry;
if (!envp)
envp_passed_in = 0;
else
__try
{
envc++;
envc *= sizeof (char *);
char **newenv = (char **) malloc (envc);
memcpy (newenv, envp, envc);
cfree (envp);
char *tmpbuf = tp.t_get ();
got_something_from_registry = regopt (L"default", tmpbuf);
if (myself->progname[0])
got_something_from_registry = regopt (myself->progname, tmpbuf)
|| got_something_from_registry;
/* Older applications relied on the fact that cygwin malloced elements of the
environment list. */
envp = newenv;
if (ENVMALLOC)
for (char **e = newenv; *e; e++)
{
char *p = *e;
*e = strdup (p);
cfree (p);
}
envp_passed_in = 1;
goto out;
if (!envp)
envp_passed_in = 0;
else
{
envc++;
envc *= sizeof (char *);
char **newenv = (char **) malloc (envc);
memcpy (newenv, envp, envc);
cfree (envp);
/* Older applications relied on the fact that cygwin malloced elements of the
environment list. */
envp = newenv;
if (ENVMALLOC)
for (char **e = newenv; *e; e++)
{
char *p = *e;
*e = strdup (p);
cfree (p);
}
envp_passed_in = 1;
goto out;
}
/* Allocate space for environment + trailing NULL + CYGWIN env. */
lastenviron = envp = (char **) malloc ((4 + (envc = 100)) * sizeof (char *));
rawenv = GetEnvironmentStringsW ();
if (!rawenv)
{
system_printf ("GetEnvironmentStrings returned NULL, %E");
return;
}
debug_printf ("GetEnvironmentStrings returned %p", rawenv);
/* Current directory information is recorded as variables of the
form "=X:=X:\foo\bar; these must be changed into something legal
(we could just ignore them but maybe an application will
eventually want to use them). */
for (i = 0, w = rawenv; *w != L'\0'; w = wcschr (w, L'\0') + 1, i++)
{
sys_wcstombs_alloc (&newp, HEAP_NOTHEAP, w);
if (i >= envc)
envp = (char **) realloc (envp, (4 + (envc += 100)) * sizeof (char *));
envp[i] = newp;
if (*newp == '=')
*newp = '!';
char *eq = strchrnul (newp, '=');
ucenv (newp, eq); /* uppercase env vars which need it */
if (*newp == 'T' && strncmp (newp, "TERM=", 5) == 0)
sawTERM = 1;
else if (*newp == 'C' && strncmp (newp, "CYGWIN=", 7) == 0)
parse_options (newp + 7);
if (*eq)
posify_maybe (envp + i, *++eq ? eq : --eq, tmpbuf);
debug_printf ("%p: %s", envp[i], envp[i]);
}
if (!sawTERM)
envp[i++] = strdup (cygterm);
envp[i] = NULL;
FreeEnvironmentStringsW (rawenv);
out:
findenv_func = (char * (*)(const char*, int*)) my_findenv;
__cygwin_environ = envp;
update_envptrs ();
if (envp_passed_in)
{
p = getenv ("CYGWIN");
if (p)
parse_options (p);
}
if (got_something_from_registry)
parse_options (NULL); /* possibly export registry settings to
environment */
MALLOC_CHECK;
}
/* Allocate space for environment + trailing NULL + CYGWIN env. */
lastenviron = envp = (char **) malloc ((4 + (envc = 100)) * sizeof (char *));
rawenv = GetEnvironmentStringsW ();
if (!rawenv)
__except (NO_ERROR)
{
system_printf ("GetEnvironmentStrings returned NULL, %E");
return;
api_fatal ("internal error reading the windows environment "
"- too many environment variables?");
}
debug_printf ("GetEnvironmentStrings returned %p", rawenv);
/* Current directory information is recorded as variables of the
form "=X:=X:\foo\bar; these must be changed into something legal
(we could just ignore them but maybe an application will
eventually want to use them). */
for (i = 0, w = rawenv; *w != L'\0'; w = wcschr (w, L'\0') + 1, i++)
{
sys_wcstombs_alloc (&newp, HEAP_NOTHEAP, w);
if (i >= envc)
envp = (char **) realloc (envp, (4 + (envc += 100)) * sizeof (char *));
envp[i] = newp;
if (*newp == '=')
*newp = '!';
char *eq = strchrnul (newp, '=');
ucenv (newp, eq); /* uppercase env vars which need it */
if (*newp == 'T' && strncmp (newp, "TERM=", 5) == 0)
sawTERM = 1;
else if (*newp == 'C' && strncmp (newp, "CYGWIN=", 7) == 0)
parse_options (newp + 7);
if (*eq)
posify_maybe (envp + i, *++eq ? eq : --eq, tmpbuf);
debug_printf ("%p: %s", envp[i], envp[i]);
}
if (!sawTERM)
envp[i++] = strdup (cygterm);
envp[i] = NULL;
FreeEnvironmentStringsW (rawenv);
out:
findenv_func = (char * (*)(const char*, int*)) my_findenv;
__cygwin_environ = envp;
update_envptrs ();
if (envp_passed_in)
{
p = getenv ("CYGWIN");
if (p)
parse_options (p);
}
if (got_something_from_registry)
parse_options (NULL); /* possibly export registry settings to
environment */
MALLOC_CHECK;
__endtry
}
/* Function called by qsort to sort environment strings. */

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,38 +341,41 @@ void
cygwin_exception::dumpstack ()
{
static bool already_dumped;
myfault efault;
if (efault.faulted ())
return;
if (already_dumped || cygheap->rlim_core == 0Ul)
return;
already_dumped = true;
open_stackdumpfile ();
if (e)
dump_exception ();
int i;
thestack.init (framep, 1, ctx); /* Initialize from the input CONTEXT */
#ifdef __x86_64__
small_printf ("Stack trace:\r\nFrame Function Args\r\n");
#else
small_printf ("Stack trace:\r\nFrame Function Args\r\n");
#endif
for (i = 0; i < 16 && thestack++; i++)
__try
{
small_printf (_AFMT " " _AFMT, thestack.sf.AddrFrame.Offset,
thestack.sf.AddrPC.Offset);
for (unsigned j = 0; j < NPARAMS; j++)
small_printf ("%s" _AFMT, j == 0 ? " (" : ", ", thestack.sf.Params[j]);
small_printf (")\r\n");
if (already_dumped || cygheap->rlim_core == 0Ul)
return;
already_dumped = true;
open_stackdumpfile ();
if (e)
dump_exception ();
int i;
thestack.init (framep, 1, ctx); /* Initialize from the input CONTEXT */
#ifdef __x86_64__
small_printf ("Stack trace:\r\nFrame Function Args\r\n");
#else
small_printf ("Stack trace:\r\nFrame Function Args\r\n");
#endif
for (i = 0; i < 16 && thestack++; i++)
{
small_printf (_AFMT " " _AFMT, thestack.sf.AddrFrame.Offset,
thestack.sf.AddrPC.Offset);
for (unsigned j = 0; j < NPARAMS; j++)
small_printf ("%s" _AFMT, j == 0 ? " (" : ", ",
thestack.sf.Params[j]);
small_printf (")\r\n");
}
small_printf ("End of stack trace%s\n",
i == 16 ? " (more stack frames may be present)" : "");
if (h)
NtClose (h);
}
small_printf ("End of stack trace%s\n",
i == 16 ? " (more stack frames may be present)" : "");
if (h)
NtClose (h);
__except (NO_ERROR) {}
__endtry
}
bool
@ -549,40 +552,24 @@ rtl_unwind (exception_list *frame, PEXCEPTION_RECORD e)
#endif /* __x86_64 */
#ifdef __x86_64__
/* myfault vectored exception handler */
LONG
exception::myfault_handle (LPEXCEPTION_POINTERS ep)
/* myfault exception handler. */
EXCEPTION_DISPOSITION
exception::myfault (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in,
PDISPATCHER_CONTEXT dispatch)
{
_cygtls& me = _my_tls;
if (me.andreas)
{
/* Only handle the minimum amount of exceptions the myfault handler
was designed for. */
switch (ep->ExceptionRecord->ExceptionCode)
{
case STATUS_ACCESS_VIOLATION:
case STATUS_DATATYPE_MISALIGNMENT:
#if 0
/* PAGE_GUARD-based stack commits are based on structured exception
handling. Short-circuiting STATUS_STACK_OVERFLOW in a vectored
exception handler disables that, which can ultimately result in
a spurious SEGV. */
case STATUS_STACK_OVERFLOW:
#endif
case STATUS_ARRAY_BOUNDS_EXCEEDED:
me.andreas->leave (); /* Return from a "san" caught fault */
default:
break;
}
}
return EXCEPTION_CONTINUE_SEARCH;
PSCOPE_TABLE table = (PSCOPE_TABLE) dispatch->HandlerData;
RtlUnwindEx (frame,
(char *) dispatch->ImageBase + table->ScopeRecord[0].JumpTarget,
e, 0, in, dispatch->HistoryTable);
/* NOTREACHED, make gcc happy. */
return ExceptionContinueSearch;
}
#endif /* __x86_64 */
#endif
/* Main exception handler. */
int
exception::handle (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in, void *)
EXCEPTION_DISPOSITION
exception::handle (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in,
PDISPATCHER_CONTEXT dispatch)
{
static bool NO_COPY debugging;
_cygtls& me = _my_tls;

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,53 +28,54 @@ fcntl64 (int fd, int cmd, ...)
pthread_testcancel ();
debug_printf ("fcntl(%d, %d, ...)", fd, cmd);
myfault efault;
if (efault.faulted (EFAULT))
return -1;
cygheap_fdget cfd (fd, true);
if (cfd < 0)
goto done;
/* FIXME? All numerical args to fcntl are defined as long on Linux.
This relies on a really dirty trick on x86_64: A 32 bit mov to
a register (e.g. mov $1, %edx) always sets the high 32 bit to 0.
We're following the Linux lead here since the third arg to any
function is in a register anyway (%r8 in MS ABI). That's the easy
case which is covered here by always reading the arg with
sizeof (intptr_t) == sizeof (long) == sizeof (void*) which matches
all targets.
However, the POSIX standard defines all numerical args as type int.
If we take that literally, we had a (small) problem on 64 bit, since
sizeof (void*) != sizeof (int). If we would like to follow POSIX
more closely than Linux, we'd have to call va_arg on a per cmd basis. */
va_start (args, cmd);
arg = va_arg (args, intptr_t);
va_end (args);
switch (cmd)
__try
{
case F_DUPFD:
case F_DUPFD_CLOEXEC:
if (arg >= 0 && arg < OPEN_MAX_MAX)
debug_printf ("fcntl(%d, %d, ...)", fd, cmd);
cygheap_fdget cfd (fd, true);
if (cfd < 0)
__leave;
/* FIXME? All numerical args to fcntl are defined as long on Linux.
This relies on a really dirty trick on x86_64: A 32 bit mov to
a register (e.g. mov $1, %edx) always sets the high 32 bit to 0.
We're following the Linux lead here since the third arg to any
function is in a register anyway (%r8 in MS ABI). That's the easy
case which is covered here by always reading the arg with
sizeof (intptr_t) == sizeof (long) == sizeof (void*) which matches
all targets.
However, the POSIX standard defines all numerical args as type int.
If we take that literally, we had a (small) problem on 64 bit, since
sizeof (void*) != sizeof (int). If we would like to follow POSIX more
closely than Linux, we'd have to call va_arg on a per cmd basis. */
va_start (args, cmd);
arg = va_arg (args, intptr_t);
va_end (args);
switch (cmd)
{
int flags = cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0;
res = cygheap->fdtab.dup3 (fd, cygheap_fdnew ((arg) - 1), flags);
case F_DUPFD:
case F_DUPFD_CLOEXEC:
if (arg >= 0 && arg < OPEN_MAX_MAX)
{
int flags = cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0;
res = cygheap->fdtab.dup3 (fd, cygheap_fdnew ((arg) - 1), flags);
}
else
{
set_errno (EINVAL);
res = -1;
}
break;
default:
res = cfd->fcntl (cmd, arg);
break;
}
else
{
set_errno (EINVAL);
res = -1;
}
break;
default:
res = cfd->fcntl (cmd, arg);
break;
}
done:
__except (EFAULT) {}
__endtry
syscall_printf ("%R = fcntl(%d, %d, %ly)", res, fd, cmd, arg);
return res;
}
@ -91,32 +92,34 @@ _fcntl (int fd, int cmd, ...)
struct __flock32 *src = NULL;
struct flock dst;
myfault efault;
if (efault.faulted (EFAULT))
return -1;
va_start (args, cmd);
arg = va_arg (args, intptr_t);
va_end (args);
if (cmd == F_GETLK || cmd == F_SETLK || cmd == F_SETLKW)
__try
{
src = (struct __flock32 *) arg;
dst.l_type = src->l_type;
dst.l_whence = src->l_whence;
dst.l_start = src->l_start;
dst.l_len = src->l_len;
dst.l_pid = src->l_pid;
arg = (intptr_t) &dst;
va_start (args, cmd);
arg = va_arg (args, intptr_t);
va_end (args);
if (cmd == F_GETLK || cmd == F_SETLK || cmd == F_SETLKW)
{
src = (struct __flock32 *) arg;
dst.l_type = src->l_type;
dst.l_whence = src->l_whence;
dst.l_start = src->l_start;
dst.l_len = src->l_len;
dst.l_pid = src->l_pid;
arg = (intptr_t) &dst;
}
int res = fcntl64 (fd, cmd, arg);
if (cmd == F_GETLK)
{
src->l_type = dst.l_type;
src->l_whence = dst.l_whence;
src->l_start = dst.l_start;
src->l_len = dst.l_len;
src->l_pid = (short) dst.l_pid;
}
return res;
}
int res = fcntl64 (fd, cmd, arg);
if (cmd == F_GETLK)
{
src->l_type = dst.l_type;
src->l_whence = dst.l_whence;
src->l_start = dst.l_start;
src->l_len = dst.l_len;
src->l_pid = (short) dst.l_pid;
}
return res;
__except (EFAULT)
__endtry
return -1;
}
#endif

View File

@ -2293,14 +2293,17 @@ fhandler_socket::getpeereid (pid_t *pid, uid_t *euid, gid_t *egid)
return -1;
}
myfault efault;
if (efault.faulted (EFAULT))
return -1;
if (pid)
*pid = sec_peer_pid;
if (euid)
*euid = sec_peer_uid;
if (egid)
*egid = sec_peer_gid;
return 0;
__try
{
if (pid)
*pid = sec_peer_pid;
if (euid)
*euid = sec_peer_uid;
if (egid)
*egid = sec_peer_gid;
return 0;
}
__except (EFAULT) {}
__endtry
return -1;
}

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,159 +977,163 @@ mtinfo_drive::set_options (HANDLE mt, int32_t options)
int
mtinfo_drive::ioctl (HANDLE mt, unsigned int cmd, void *buf)
{
myfault efault;
if (efault.faulted ())
return ERROR_NOACCESS;
if (cmd == MTIOCTOP)
__try
{
struct mtop *op = (struct mtop *) buf;
if (lasterr == ERROR_BUS_RESET)
if (cmd == MTIOCTOP)
{
/* If a bus reset occurs, block further access to this device
until the user rewinds, unloads or in any other way tries
to maintain a well-known tape position. */
if (op->mt_op != MTREW && op->mt_op != MTOFFL
&& op->mt_op != MTRETEN && op->mt_op != MTERASE
&& op->mt_op != MTSEEK && op->mt_op != MTEOM)
return ERROR_BUS_RESET;
/* Try to maintain last lock state after bus reset. */
if (lock >= auto_locked && PrepareTape (mt, TAPE_LOCK, FALSE))
struct mtop *op = (struct mtop *) buf;
if (lasterr == ERROR_BUS_RESET)
{
debug_printf ("Couldn't relock drive after bus reset.");
lock = unlocked;
/* If a bus reset occurs, block further access to this device
until the user rewinds, unloads or in any other way tries
to maintain a well-known tape position. */
if (op->mt_op != MTREW && op->mt_op != MTOFFL
&& op->mt_op != MTRETEN && op->mt_op != MTERASE
&& op->mt_op != MTSEEK && op->mt_op != MTEOM)
return ERROR_BUS_RESET;
/* Try to maintain last lock state after bus reset. */
if (lock >= auto_locked && PrepareTape (mt, TAPE_LOCK, FALSE))
{
debug_printf ("Couldn't relock drive after bus reset.");
lock = unlocked;
}
}
}
switch (op->mt_op)
{
case MTRESET:
break;
case MTFSF:
set_pos (mt, TAPE_SPACE_FILEMARKS, op->mt_count, false);
break;
case MTBSF:
set_pos (mt, TAPE_SPACE_FILEMARKS, -op->mt_count, false);
break;
case MTFSR:
set_pos (mt, TAPE_SPACE_RELATIVE_BLOCKS, op->mt_count, false);
break;
case MTBSR:
set_pos (mt, TAPE_SPACE_RELATIVE_BLOCKS, -op->mt_count, false);
break;
case MTWEOF:
write_marks (mt, TAPE_FILEMARKS, op->mt_count);
break;
case MTREW:
set_pos (mt, TAPE_REWIND, 0, false);
break;
case MTOFFL:
case MTUNLOAD:
prepare (mt, TAPE_UNLOAD);
break;
case MTNOP:
lasterr = 0;
break;
case MTRETEN:
if (!get_feature (TAPE_DRIVE_TENSION))
lasterr = ERROR_INVALID_PARAMETER;
else if (!set_pos (mt, TAPE_REWIND, 0, false))
prepare (mt, TAPE_TENSION);
break;
case MTBSFM:
set_pos (mt, TAPE_SPACE_FILEMARKS, -op->mt_count, true);
break;
case MTFSFM:
set_pos (mt, TAPE_SPACE_FILEMARKS, op->mt_count, true);
break;
case MTEOM:
if (fast_eom () && get_feature (TAPE_DRIVE_END_OF_DATA))
set_pos (mt, TAPE_SPACE_END_OF_DATA, 0, false);
else
set_pos (mt, TAPE_SPACE_FILEMARKS, 32767, false);
break;
case MTERASE:
erase (mt, TAPE_ERASE_LONG);
break;
case MTRAS1:
case MTRAS2:
case MTRAS3:
lasterr = ERROR_INVALID_PARAMETER;
break;
case MTSETBLK:
if (!get_feature (TAPE_DRIVE_SET_BLOCK_SIZE))
{
lasterr = ERROR_INVALID_PARAMETER;
switch (op->mt_op)
{
case MTRESET:
break;
}
if ((DWORD) op->mt_count == mp ()->BlockSize)
{
/* Nothing has changed. */
case MTFSF:
set_pos (mt, TAPE_SPACE_FILEMARKS, op->mt_count, false);
break;
case MTBSF:
set_pos (mt, TAPE_SPACE_FILEMARKS, -op->mt_count, false);
break;
case MTFSR:
set_pos (mt, TAPE_SPACE_RELATIVE_BLOCKS, op->mt_count, false);
break;
case MTBSR:
set_pos (mt, TAPE_SPACE_RELATIVE_BLOCKS, -op->mt_count, false);
break;
case MTWEOF:
write_marks (mt, TAPE_FILEMARKS, op->mt_count);
break;
case MTREW:
set_pos (mt, TAPE_REWIND, 0, false);
break;
case MTOFFL:
case MTUNLOAD:
prepare (mt, TAPE_UNLOAD);
break;
case MTNOP:
lasterr = 0;
break;
}
if ((op->mt_count == 0 && !get_feature (TAPE_DRIVE_VARIABLE_BLOCK))
|| (op->mt_count > 0
&& ((DWORD) op->mt_count < dp ()->MinimumBlockSize
|| (DWORD) op->mt_count > dp ()->MaximumBlockSize)))
{
case MTRETEN:
if (!get_feature (TAPE_DRIVE_TENSION))
lasterr = ERROR_INVALID_PARAMETER;
else if (!set_pos (mt, TAPE_REWIND, 0, false))
prepare (mt, TAPE_TENSION);
break;
case MTBSFM:
set_pos (mt, TAPE_SPACE_FILEMARKS, -op->mt_count, true);
break;
case MTFSFM:
set_pos (mt, TAPE_SPACE_FILEMARKS, op->mt_count, true);
break;
case MTEOM:
if (fast_eom () && get_feature (TAPE_DRIVE_END_OF_DATA))
set_pos (mt, TAPE_SPACE_END_OF_DATA, 0, false);
else
set_pos (mt, TAPE_SPACE_FILEMARKS, 32767, false);
break;
case MTERASE:
erase (mt, TAPE_ERASE_LONG);
break;
case MTRAS1:
case MTRAS2:
case MTRAS3:
lasterr = ERROR_INVALID_PARAMETER;
break;
}
if (set_blocksize (mt, op->mt_count)
&& lasterr == ERROR_INVALID_FUNCTION)
lasterr = ERROR_INVALID_BLOCK_LENGTH;
break;
case MTSEEK:
if (get_feature (TAPE_DRIVE_LOGICAL_BLK))
set_pos (mt, TAPE_LOGICAL_BLOCK, op->mt_count, false);
else if (!get_pos (mt))
set_pos (mt, TAPE_SPACE_RELATIVE_BLOCKS,
op->mt_count - block, false);
break;
case MTTELL:
if (!get_pos (mt))
op->mt_count = (int) block;
break;
case MTFSS:
set_pos (mt, TAPE_SPACE_SETMARKS, op->mt_count, false);
break;
case MTBSS:
set_pos (mt, TAPE_SPACE_SETMARKS, -op->mt_count, false);
break;
case MTWSM:
write_marks (mt, TAPE_SETMARKS, op->mt_count);
break;
case MTLOCK:
prepare (mt, TAPE_LOCK);
break;
case MTUNLOCK:
prepare (mt, TAPE_UNLOCK);
break;
case MTLOAD:
prepare (mt, TAPE_LOAD);
break;
case MTCOMPRESSION:
set_compression (mt, op->mt_count);
break;
case MTSETPART:
set_partition (mt, op->mt_count);
break;
case MTMKPART:
create_partitions (mt, op->mt_count);
break;
case MTSETDRVBUFFER:
set_options (mt, op->mt_count);
break;
case MTSETDENSITY:
default:
lasterr = ERROR_INVALID_PARAMETER;
break;
case MTSETBLK:
if (!get_feature (TAPE_DRIVE_SET_BLOCK_SIZE))
{
lasterr = ERROR_INVALID_PARAMETER;
break;
}
if ((DWORD) op->mt_count == mp ()->BlockSize)
{
/* Nothing has changed. */
lasterr = 0;
break;
}
if ((op->mt_count == 0 && !get_feature (TAPE_DRIVE_VARIABLE_BLOCK))
|| (op->mt_count > 0
&& ((DWORD) op->mt_count < dp ()->MinimumBlockSize
|| (DWORD) op->mt_count > dp ()->MaximumBlockSize)))
{
lasterr = ERROR_INVALID_PARAMETER;
break;
}
if (set_blocksize (mt, op->mt_count)
&& lasterr == ERROR_INVALID_FUNCTION)
lasterr = ERROR_INVALID_BLOCK_LENGTH;
break;
case MTSEEK:
if (get_feature (TAPE_DRIVE_LOGICAL_BLK))
set_pos (mt, TAPE_LOGICAL_BLOCK, op->mt_count, false);
else if (!get_pos (mt))
set_pos (mt, TAPE_SPACE_RELATIVE_BLOCKS,
op->mt_count - block, false);
break;
case MTTELL:
if (!get_pos (mt))
op->mt_count = (int) block;
break;
case MTFSS:
set_pos (mt, TAPE_SPACE_SETMARKS, op->mt_count, false);
break;
case MTBSS:
set_pos (mt, TAPE_SPACE_SETMARKS, -op->mt_count, false);
break;
case MTWSM:
write_marks (mt, TAPE_SETMARKS, op->mt_count);
break;
case MTLOCK:
prepare (mt, TAPE_LOCK);
break;
case MTUNLOCK:
prepare (mt, TAPE_UNLOCK);
break;
case MTLOAD:
prepare (mt, TAPE_LOAD);
break;
case MTCOMPRESSION:
set_compression (mt, op->mt_count);
break;
case MTSETPART:
set_partition (mt, op->mt_count);
break;
case MTMKPART:
create_partitions (mt, op->mt_count);
break;
case MTSETDRVBUFFER:
set_options (mt, op->mt_count);
break;
case MTSETDENSITY:
default:
lasterr = ERROR_INVALID_PARAMETER;
break;
}
}
else if (cmd == MTIOCGET)
get_status (mt, (struct mtget *) buf);
else if (cmd == MTIOCPOS && !get_pos (mt))
((struct mtpos *) buf)->mt_blkno = (long) block;
}
else if (cmd == MTIOCGET)
get_status (mt, (struct mtget *) buf);
else if (cmd == MTIOCPOS && !get_pos (mt))
((struct mtpos *) buf)->mt_blkno = (long) block;
__except (NO_ERROR)
{
lasterr = ERROR_NOACCESS;
}
__endtry
return lasterr;
}

View File

@ -1761,37 +1761,37 @@ flock (int fd, int operation)
int cmd;
struct flock fl = { 0, SEEK_SET, 0, 0, 0 };
myfault efault;
if (efault.faulted (EFAULT))
return -1;
cygheap_fdget cfd (fd, true);
if (cfd < 0)
goto done;
cmd = (operation & LOCK_NB) ? F_SETLK : F_SETLKW;
switch (operation & (~LOCK_NB))
__try
{
case LOCK_EX:
fl.l_type = F_WRLCK;
break;
case LOCK_SH:
fl.l_type = F_RDLCK;
break;
case LOCK_UN:
fl.l_type = F_UNLCK;
break;
default:
set_errno (EINVAL);
goto done;
cygheap_fdget cfd (fd, true);
if (cfd < 0)
__leave;
cmd = (operation & LOCK_NB) ? F_SETLK : F_SETLKW;
switch (operation & (~LOCK_NB))
{
case LOCK_EX:
fl.l_type = F_WRLCK;
break;
case LOCK_SH:
fl.l_type = F_RDLCK;
break;
case LOCK_UN:
fl.l_type = F_UNLCK;
break;
default:
set_errno (EINVAL);
__leave;
}
if (!cfd->mandatory_locking ())
fl.l_type |= F_FLOCK;
res = cfd->mandatory_locking () ? cfd->mand_lock (cmd, &fl)
: cfd->lock (cmd, &fl);
if ((res == -1) && ((get_errno () == EAGAIN) || (get_errno () == EACCES)))
set_errno (EWOULDBLOCK);
}
if (!cfd->mandatory_locking ())
fl.l_type |= F_FLOCK;
res = cfd->mandatory_locking () ? cfd->mand_lock (cmd, &fl)
: cfd->lock (cmd, &fl);
if ((res == -1) && ((get_errno () == EAGAIN) || (get_errno () == EACCES)))
set_errno (EWOULDBLOCK);
done:
__except (EFAULT) {}
__endtry
syscall_printf ("%R = flock(%d, %d)", res, fd, operation);
return res;
}
@ -1805,50 +1805,50 @@ lockf (int filedes, int function, off_t size)
pthread_testcancel ();
myfault efault;
if (efault.faulted (EFAULT))
return -1;
cygheap_fdget cfd (filedes, true);
if (cfd < 0)
goto done;
fl.l_start = 0;
fl.l_len = size;
fl.l_whence = SEEK_CUR;
switch (function)
__try
{
case F_ULOCK:
cmd = F_SETLK;
fl.l_type = F_UNLCK;
break;
case F_LOCK:
cmd = F_SETLKW;
fl.l_type = F_WRLCK;
break;
case F_TLOCK:
cmd = F_SETLK;
fl.l_type = F_WRLCK;
break;
case F_TEST:
fl.l_type = F_WRLCK;
if (cfd->lock (F_GETLK, &fl) == -1)
goto done;
if (fl.l_type == F_UNLCK || fl.l_pid == getpid ())
res = 0;
else
errno = EAGAIN;
goto done;
/* NOTREACHED */
default:
errno = EINVAL;
goto done;
/* NOTREACHED */
cygheap_fdget cfd (filedes, true);
if (cfd < 0)
__leave;
fl.l_start = 0;
fl.l_len = size;
fl.l_whence = SEEK_CUR;
switch (function)
{
case F_ULOCK:
cmd = F_SETLK;
fl.l_type = F_UNLCK;
break;
case F_LOCK:
cmd = F_SETLKW;
fl.l_type = F_WRLCK;
break;
case F_TLOCK:
cmd = F_SETLK;
fl.l_type = F_WRLCK;
break;
case F_TEST:
fl.l_type = F_WRLCK;
if (cfd->lock (F_GETLK, &fl) == -1)
__leave;
if (fl.l_type == F_UNLCK || fl.l_pid == getpid ())
res = 0;
else
errno = EAGAIN;
__leave;
/* NOTREACHED */
default:
errno = EINVAL;
__leave;
/* NOTREACHED */
}
res = cfd->mandatory_locking () ? cfd->mand_lock (cmd, &fl)
: cfd->lock (cmd, &fl);
}
res = cfd->mandatory_locking () ? cfd->mand_lock (cmd, &fl)
: cfd->lock (cmd, &fl);
done:
__except (EFAULT) {}
__endtry
syscall_printf ("%R = lockf(%d, %d, %D)", res, filedes, function, size);
return res;
}

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
@ -366,7 +368,7 @@ stabilize_sig_stack:
movq %gs:8,%r12
1: movl \$1,%r10d
xchgl %r10d,$tls::stacklock(%r12)
movl %r10d,$tls::spinning(%r12) # flag if we are waiting for lock
movl %r10d,$tls::spinning(%r12) # flag if we are waiting for lock
testl %r10d,%r10d
jz 2f
pause
@ -374,14 +376,14 @@ stabilize_sig_stack:
2: incl $tls::incyg(%r12)
cmpl \$0,$tls::sig(%r12)
jz 3f
decl $tls::stacklock(%r12) # unlock
movq \$$tls::start_offset,%rcx # point to beginning
addq %r12,%rcx # of tls block
decl $tls::stacklock(%r12) # unlock
movq \$$tls::start_offset,%rcx # point to beginning
addq %r12,%rcx # of tls block
call _ZN7_cygtls19call_signal_handlerEv
jmp 1b
3: decl $tls::incyg(%r12)
addq \$0x20,%rsp
movq %r12,%r11 # return tls addr in r11
movq %r12,%r11 # return tls addr in r11
popq %r12
ret
.seh_endproc
@ -393,13 +395,13 @@ EOF
__sigfe_maybe:
pushl %ebx
pushl %edx
movl %fs:4,%ebx # location of bottom of stack
addl \$$tls::initialized,%ebx # where we will be looking
cmpl %ebx,%esp # stack loc > than tls
jge 0f # yep. we don't have a tls.
subl \$$tls::initialized,%ebx # where we will be looking
movl %fs:4,%ebx # location of bottom of stack
addl \$$tls::initialized,%ebx # where we will be looking
cmpl %ebx,%esp # stack loc > than tls
jge 0f # yep. we don't have a tls.
subl \$$tls::initialized,%ebx # where we will be looking
movl $tls::initialized(%ebx),%eax
cmpl \$0xc763173f,%eax # initialized?
cmpl \$0xc763173f,%eax # initialized?
je 1f
0: popl %edx
popl %ebx
@ -408,43 +410,46 @@ __sigfe_maybe:
__sigfe:
pushl %ebx
pushl %edx
movl %fs:4,%ebx # location of bottom of stack
1: movl \$1,%eax # potential lock value
xchgl %eax,$tls::stacklock(%ebx) # see if we can grab it
movl %eax,$tls::spinning(%ebx) # flag if we are waiting for lock
testl %eax,%eax # it will be zero
jz 2f # if so
call _yield # should be a short-time thing, so
jmp 1b # sleep and loop
2: movl \$4,%eax # have the lock, now increment the
xadd %eax,$tls::stackptr(%ebx) # stack pointer and get pointer
leal __sigbe,%edx # new place to return to
xchgl %edx,12(%esp) # exchange with real return value
movl %edx,(%eax) # store real return value on alt stack
movl %fs:4,%ebx # location of bottom of stack
1: movl \$1,%eax # potential lock value
xchgl %eax,$tls::stacklock(%ebx) # see if we can grab it
movl %eax,$tls::spinning(%ebx) # flag if we are waiting for lock
testl %eax,%eax # it will be zero
jz 2f # if so
call _yield # should be a short-time thing, so
jmp 1b # sleep and loop
2: movl \$4,%eax # have the lock, now increment the
xadd %eax,$tls::stackptr(%ebx) # stack pointer and get pointer
leal __sigbe,%edx # new place to return to
xchgl %edx,12(%esp) # exchange with real return value
movl %edx,(%eax) # store real return value on alt stack
incl $tls::incyg(%ebx)
decl $tls::stacklock(%ebx) # remove lock
popl %edx # restore saved value
decl $tls::stacklock(%ebx) # remove lock
popl %edx # restore saved value
popl %ebx
ret
.global __sigbe
__sigbe: # return here after cygwin syscall
pushl %eax # don't clobber
pushl %ebx # tls pointer
1: movl %fs:4,%ebx # address of bottom of tls
movl \$1,%eax # potential lock value
xchgl %eax,$tls::stacklock(%ebx) # see if we can grab it
movl %eax,$tls::spinning(%ebx) # flag if we are waiting for lock
testl %eax,%eax # it will be zero
jz 2f # if so
call _yield # sleep
jmp 1b # and loop
2: movl \$-4,%eax # now decrement aux stack
xadd %eax,$tls::stackptr(%ebx) # and get pointer
movl -4(%eax),%eax # get return address from signal stack
xchgl %eax,4(%esp) # swap return address with saved eax
__sigbe: # return here after cygwin syscall
pushl %eax # don't clobber
pushl %ebx # tls pointer
1: movl %fs:4,%ebx # address of bottom of tls
movl \$1,%eax # potential lock value
xchgl %eax,$tls::stacklock(%ebx) # see if we can grab it
movl %eax,$tls::spinning(%ebx) # flag if we are waiting for lock
testl %eax,%eax # it will be zero
jz 2f # if so
call _yield # sleep
jmp 1b # and loop
2: movl \$-4,%eax # now decrement aux stack
xadd %eax,$tls::stackptr(%ebx) # and get pointer
movl -4(%eax),%eax # get return address from signal stack
xchgl %eax,4(%esp) # swap return address with saved eax
decl $tls::incyg(%ebx)
decl $tls::stacklock(%ebx) # release lock
decl $tls::stacklock(%ebx) # release lock
leal $tls::pathbufs(%ebx),%ebx # Address of tls_pathbufs
movl \$0,(%ebx) # Set c_cnt to 0
movl \$0,4(%ebx) # Set w_cnt to 0
popl %ebx
ret

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

@ -312,100 +312,101 @@ extern "C" int
cygwin_rexec (char **ahost, unsigned short rport, char *name, char *pass,
char *cmd, int *fd2p)
{
struct sockaddr_in sin, sin2, from;
struct hostent *hp;
u_short port = 0;
int s, timo = 1, s3;
char c;
static char ahostbuf[INTERNET_MAX_HOST_NAME_LENGTH + 1];
struct sockaddr_in sin, sin2, from;
struct hostent *hp;
u_short port = 0;
int s, timo = 1, s3;
char c;
static char ahostbuf[INTERNET_MAX_HOST_NAME_LENGTH + 1];
myfault efault;
if (efault.faulted (EFAULT))
return -1;
hp = cygwin_gethostbyname(*ahost);
if (hp == 0) {
cygwin_herror(*ahost);
return (-1);
}
*ahost = strcpy (ahostbuf, hp->h_name);
ruserpass(hp->h_name, &name, &pass, NULL);
if (!name)
name = getlogin ();
if (!pass)
pass = almost_null;
__try
{
hp = cygwin_gethostbyname(*ahost);
if (hp == 0) {
cygwin_herror(*ahost);
return (-1);
}
*ahost = strcpy (ahostbuf, hp->h_name);
ruserpass(hp->h_name, &name, &pass, NULL);
if (!name)
name = getlogin ();
if (!pass)
pass = almost_null;
retry:
s = cygwin_socket(AF_INET, SOCK_STREAM, 0);
if (s < 0) {
perror("rexec: socket");
return (-1);
}
sin.sin_family = hp->h_addrtype;
sin.sin_port = rport;
bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length);
if (cygwin_connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
if (errno == ECONNREFUSED && timo <= 16) {
(void) close(s);
sleep(timo);
timo *= 2;
goto retry;
}
perror(hp->h_name);
return (-1);
}
if (fd2p == 0) {
(void) write(s, "", 1);
} else {
char num[8];
int s2, sin2len;
s = cygwin_socket(AF_INET, SOCK_STREAM, 0);
if (s < 0) {
perror("rexec: socket");
return (-1);
}
sin.sin_family = hp->h_addrtype;
sin.sin_port = rport;
bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length);
if (cygwin_connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
if (errno == ECONNREFUSED && timo <= 16) {
(void) close(s);
sleep(timo);
timo *= 2;
goto retry;
}
perror(hp->h_name);
return (-1);
}
if (fd2p == 0) {
(void) write(s, "", 1);
} else {
char num[8];
int s2, sin2len;
s2 = cygwin_socket(AF_INET, SOCK_STREAM, 0);
if (s2 < 0) {
(void) close(s);
return (-1);
s2 = cygwin_socket(AF_INET, SOCK_STREAM, 0);
if (s2 < 0) {
(void) close(s);
return (-1);
}
cygwin_listen(s2, 1);
sin2len = sizeof (sin2);
if (cygwin_getsockname(s2, (struct sockaddr *)&sin2, &sin2len) < 0 ||
sin2len != sizeof (sin2)) {
perror("getsockname");
(void) close(s2);
goto bad;
}
port = ntohs((u_short)sin2.sin_port);
(void) sprintf(num, "%u", port);
(void) write(s, num, strlen(num)+1);
{ int len = sizeof (from);
s3 = cygwin_accept(s2, (struct sockaddr *)&from, &len);
close(s2);
if (s3 < 0) {
perror("accept");
port = 0;
goto bad;
}
cygwin_listen(s2, 1);
sin2len = sizeof (sin2);
if (cygwin_getsockname(s2, (struct sockaddr *)&sin2, &sin2len) < 0 ||
sin2len != sizeof (sin2)) {
perror("getsockname");
(void) close(s2);
goto bad;
}
port = ntohs((u_short)sin2.sin_port);
(void) sprintf(num, "%u", port);
(void) write(s, num, strlen(num)+1);
{ int len = sizeof (from);
s3 = cygwin_accept(s2, (struct sockaddr *)&from, &len);
close(s2);
if (s3 < 0) {
perror("accept");
port = 0;
goto bad;
}
}
*fd2p = s3;
}
(void) write(s, name, strlen(name) + 1);
/* should public key encypt the password here */
(void) write(s, pass, strlen(pass) + 1);
(void) write(s, cmd, strlen(cmd) + 1);
if (read(s, &c, 1) != 1) {
perror(*ahost);
goto bad;
}
if (c != 0) {
while (read(s, &c, 1) == 1) {
(void) write(2, &c, 1);
if (c == '\n')
break;
}
goto bad;
}
return (s);
}
*fd2p = s3;
}
(void) write(s, name, strlen(name) + 1);
/* should public key encypt the password here */
(void) write(s, pass, strlen(pass) + 1);
(void) write(s, cmd, strlen(cmd) + 1);
if (read(s, &c, 1) != 1) {
perror(*ahost);
goto bad;
}
if (c != 0) {
while (read(s, &c, 1) == 1) {
(void) write(2, &c, 1);
if (c == '\n')
break;
}
goto bad;
}
return (s);
bad:
if (port)
(void) close(*fd2p);
(void) close(s);
return (-1);
if (port)
(void) close(*fd2p);
(void) close(s);
}
__except (EFAULT) {}
__endtry
return (-1);
}

View File

@ -202,35 +202,38 @@ check_iovec (const struct iovec *iov, int iovcnt, bool forwrite)
return -1;
}
myfault efault;
if (efault.faulted (EFAULT))
return -1;
size_t tot = 0;
while (iovcnt != 0)
__try
{
if (iov->iov_len > SSIZE_MAX || (tot += iov->iov_len) > SSIZE_MAX)
size_t tot = 0;
while (iovcnt != 0)
{
set_errno (EINVAL);
return -1;
if (iov->iov_len > SSIZE_MAX || (tot += iov->iov_len) > SSIZE_MAX)
{
set_errno (EINVAL);
__leave;
}
volatile char *p = ((char *) iov->iov_base) + iov->iov_len - 1;
if (!iov->iov_len)
/* nothing to do */;
else if (!forwrite)
*p = dummytest (p);
else
dummytest (p);
iov++;
iovcnt--;
}
volatile char *p = ((char *) iov->iov_base) + iov->iov_len - 1;
if (!iov->iov_len)
/* nothing to do */;
else if (!forwrite)
*p = dummytest (p);
else
dummytest (p);
assert (tot <= SSIZE_MAX);
iov++;
iovcnt--;
return (ssize_t) tot;
}
assert (tot <= SSIZE_MAX);
return (ssize_t) tot;
__except (EFAULT)
__endtry
return -1;
}
/* Try hard to schedule another thread.
@ -512,18 +515,23 @@ slashify (const char *src, char *dst, bool trailing_slash_p)
void * __reg1
__import_address (void *imp)
{
myfault efault;
if (efault.faulted ())
return NULL;
if (*((uint16_t *) imp) != 0x25ff)
return NULL;
const char *ptr = (const char *) imp;
__try
{
if (*((uint16_t *) imp) == 0x25ff)
{
const char *ptr = (const char *) imp;
#ifdef __x86_64__
const uintptr_t *jmpto = (uintptr_t *) (ptr + 6 + *(int32_t *)(ptr + 2));
const uintptr_t *jmpto = (uintptr_t *)
(ptr + 6 + *(int32_t *)(ptr + 2));
#else
const uintptr_t *jmpto = (uintptr_t *) *((uintptr_t *) (ptr + 2));
const uintptr_t *jmpto = (uintptr_t *) *((uintptr_t *) (ptr + 2));
#endif
return (void *) *jmpto;
return (void *) *jmpto;
}
}
__except (NO_ERROR) {}
__endtry
return NULL;
}
/* CygwinCreateThread.

View File

@ -1700,50 +1700,54 @@ mount (const char *win32_path, const char *posix_path, unsigned flags)
isn't really supported except from fstab? */
int res = -1;
myfault efault;
if (efault.faulted (EFAULT))
/* errno set */;
else if (!*posix_path)
set_errno (EINVAL);
else if (strpbrk (posix_path, "\\:"))
set_errno (EINVAL);
else if (flags & MOUNT_CYGDRIVE) /* normal mount */
__try
{
/* When flags include MOUNT_CYGDRIVE, take this to mean that
we actually want to change the cygdrive prefix and flags
without actually mounting anything. */
res = mount_table->write_cygdrive_info (posix_path, flags);
win32_path = NULL;
}
else if (!*win32_path)
set_errno (EINVAL);
else
{
char *w32_path = (char *) win32_path;
if (flags & MOUNT_BIND)
if (!*posix_path)
set_errno (EINVAL);
else if (strpbrk (posix_path, "\\:"))
set_errno (EINVAL);
else if (flags & MOUNT_CYGDRIVE) /* normal mount */
{
/* Prepend root path to bound path. */
tmp_pathbuf tp;
device dev;
unsigned conv_flags = 0;
const char *bound_path = w32_path;
w32_path = tp.c_get ();
int error = mount_table->conv_to_win32_path (bound_path, w32_path,
dev, &conv_flags);
if (error || strlen (w32_path) >= MAX_PATH)
return true;
if ((flags & ~MOUNT_SYSTEM) == (MOUNT_BIND | MOUNT_BINARY))
flags = (MOUNT_BIND | conv_flags)
& ~(MOUNT_IMMUTABLE | MOUNT_AUTOMATIC);
/* When flags include MOUNT_CYGDRIVE, take this to mean that
we actually want to change the cygdrive prefix and flags
without actually mounting anything. */
res = mount_table->write_cygdrive_info (posix_path, flags);
win32_path = NULL;
}
/* Make sure all mounts are user mounts, even those added via mount -a. */
flags &= ~MOUNT_SYSTEM;
res = mount_table->add_item (w32_path, posix_path, flags);
}
else if (!*win32_path)
set_errno (EINVAL);
else
{
char *w32_path = (char *) win32_path;
if (flags & MOUNT_BIND)
{
/* Prepend root path to bound path. */
tmp_pathbuf tp;
device dev;
syscall_printf ("%R = mount(%s, %s, %y)", res, win32_path, posix_path, flags);
unsigned conv_flags = 0;
const char *bound_path = w32_path;
w32_path = tp.c_get ();
int error = mount_table->conv_to_win32_path (bound_path, w32_path,
dev, &conv_flags);
if (error || strlen (w32_path) >= MAX_PATH)
return true;
if ((flags & ~MOUNT_SYSTEM) == (MOUNT_BIND | MOUNT_BINARY))
flags = (MOUNT_BIND | conv_flags)
& ~(MOUNT_IMMUTABLE | MOUNT_AUTOMATIC);
}
/* Make sure all mounts are user mounts, even those added via
mount -a. */
flags &= ~MOUNT_SYSTEM;
res = mount_table->add_item (w32_path, posix_path, flags);
}
syscall_printf ("%R = mount(%s, %s, %y)",
res, win32_path, posix_path, flags);
}
__except (EFAULT) {}
__endtry
return res;
}
@ -1755,15 +1759,18 @@ mount (const char *win32_path, const char *posix_path, unsigned flags)
extern "C" int
umount (const char *path)
{
myfault efault;
if (efault.faulted (EFAULT))
return -1;
if (!*path)
__try
{
set_errno (EINVAL);
return -1;
if (!*path)
{
set_errno (EINVAL);
__leave;
}
return cygwin_umount (path, 0);
}
return cygwin_umount (path, 0);
__except (EFAULT) {}
__endtry
return -1;
}
/* cygwin_umount: This is like umount but takes an additional flags

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,38 +91,40 @@ client_request_msg::client_request_msg (int msqid,
extern "C" int
msgctl (int msqid, int cmd, struct msqid_ds *buf)
{
syscall_printf ("msgctl (msqid = %d, cmd = %y, buf = %p)",
msqid, cmd, buf);
myfault efault;
if (efault.faulted (EFAULT))
return -1;
switch (cmd)
syscall_printf ("msgctl (msqid = %d, cmd = %y, buf = %p)", msqid, cmd, buf);
__try
{
case IPC_STAT:
break;
case IPC_SET:
break;
case IPC_RMID:
break;
case IPC_INFO:
break;
case MSG_INFO:
break;
default:
syscall_printf ("-1 [%d] = msgctl ()", EINVAL);
set_errno (EINVAL);
return -1;
switch (cmd)
{
case IPC_STAT:
break;
case IPC_SET:
break;
case IPC_RMID:
break;
case IPC_INFO:
break;
case MSG_INFO:
break;
default:
syscall_printf ("-1 [%d] = msgctl ()", EINVAL);
set_errno (EINVAL);
__leave;
}
client_request_msg request (msqid, cmd, buf);
if (request.make_request () == -1 || request.retval () == -1)
{
syscall_printf ("-1 [%d] = msgctl ()", request.error_code ());
set_errno (request.error_code ());
if (request.error_code () == ENOSYS)
raise (SIGSYS);
__leave;
}
return request.retval ();
}
client_request_msg request (msqid, cmd, buf);
if (request.make_request () == -1 || request.retval () == -1)
{
syscall_printf ("-1 [%d] = msgctl ()", request.error_code ());
set_errno (request.error_code ());
if (request.error_code () == ENOSYS)
raise (SIGSYS);
return -1;
}
return request.retval ();
__except (EFAULT) {}
__endtry
return -1;
}
extern "C" int
@ -147,19 +149,22 @@ msgrcv (int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg)
syscall_printf ("msgrcv (msqid = %d, msgp = %p, msgsz = %ld, "
"msgtyp = %d, msgflg = %y)",
msqid, msgp, msgsz, msgtyp, msgflg);
myfault efault;
if (efault.faulted (EFAULT))
return -1;
client_request_msg request (msqid, msgp, msgsz, msgtyp, msgflg);
if (request.make_request () == -1 || request.rcvval () == -1)
__try
{
syscall_printf ("-1 [%d] = msgrcv ()", request.error_code ());
set_errno (request.error_code ());
if (request.error_code () == ENOSYS)
raise (SIGSYS);
return -1;
client_request_msg request (msqid, msgp, msgsz, msgtyp, msgflg);
if (request.make_request () == -1 || request.rcvval () == -1)
{
syscall_printf ("-1 [%d] = msgrcv ()", request.error_code ());
set_errno (request.error_code ());
if (request.error_code () == ENOSYS)
raise (SIGSYS);
__leave;
}
return request.rcvval ();
}
return request.rcvval ();
__except (EFAULT) {}
__endtry
return -1;
}
extern "C" int
@ -167,17 +172,20 @@ msgsnd (int msqid, const void *msgp, size_t msgsz, int msgflg)
{
syscall_printf ("msgsnd (msqid = %d, msgp = %p, msgsz = %ld, msgflg = %y)",
msqid, msgp, msgsz, msgflg);
myfault efault;
if (efault.faulted (EFAULT))
return -1;
client_request_msg request (msqid, msgp, msgsz, msgflg);
if (request.make_request () == -1 || request.retval () == -1)
__try
{
syscall_printf ("-1 [%d] = msgsnd ()", request.error_code ());
set_errno (request.error_code ());
if (request.error_code () == ENOSYS)
raise (SIGSYS);
return -1;
client_request_msg request (msqid, msgp, msgsz, msgflg);
if (request.make_request () == -1 || request.retval () == -1)
{
syscall_printf ("-1 [%d] = msgsnd ()", request.error_code ());
set_errno (request.error_code ());
if (request.error_code () == ENOSYS)
raise (SIGSYS);
__leave;
}
return request.retval ();
}
return request.retval ();
__except (EFAULT) {}
__endtry
return -1;
}

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,167 +60,171 @@ read_ea (HANDLE hdl, path_conv &pc, const char *name, char *value, size_t size)
EA in the file is returned twice. */
char lastname[MAX_EA_NAME_LEN];
myfault efault;
if (efault.faulted (EFAULT))
goto out;
pc.get_object_attr (attr, sec_none_nih);
debug_printf ("read_ea (%S, %s, %p, %lu)",
attr.ObjectName, name, value, size);
/* Early open if handle is NULL. This allows to return error codes like
ENOENT before we actually check for the correctness of the EA name and
stuff like that. */
if (!hdl)
__try
{
status = NtOpenFile (&h, READ_CONTROL | FILE_READ_EA, &attr, &io,
FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT);
if (!NT_SUCCESS (status))
{
__seterrno_from_nt_status (status);
goto out;
}
hdl = NULL;
}
pc.get_object_attr (attr, sec_none_nih);
fea = (PFILE_FULL_EA_INFORMATION) tp.w_get ();
debug_printf ("read_ea (%S, %s, %p, %lu)",
attr.ObjectName, name, value, size);
if (name)
{
size_t nlen;
/* For compatibility with Linux, we only allow user xattrs and
return ENOTSUP otherwise. */
if (ascii_strncasematch (name, "user.", 5))
name += 5;
else
/* Early open if handle is NULL. This allows to return error codes like
ENOENT before we actually check for the correctness of the EA name and
stuff like that. */
if (!hdl)
{
set_errno (ENOTSUP);
goto out;
}
if ((nlen = strlen (name)) >= MAX_EA_NAME_LEN)
{
set_errno (EINVAL);
return -1;
}
glen = sizeof (FILE_GET_EA_INFORMATION) + nlen;
gea = (PFILE_GET_EA_INFORMATION) alloca (glen);
gea->NextEntryOffset = 0;
gea->EaNameLength = nlen;
strcpy (gea->EaName, name);
}
while (true)
{
if (h)
{
status = NtQueryEaFile (h, &io, fea, EA_BUFSIZ, TRUE, gea, glen,
NULL, TRUE);
if (status != STATUS_ACCESS_DENIED || !hdl)
break;
}
status = NtOpenFile (&h, READ_CONTROL | FILE_READ_EA, &attr, &io,
FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT);
if (!NT_SUCCESS (status))
break;
hdl = NULL;
}
if (!NT_SUCCESS (status))
{
switch (status)
{
case STATUS_NO_EAS_ON_FILE:
ret = 0;
break;
case STATUS_INVALID_DEVICE_REQUEST:
set_errno (ENOTSUP);
break;
case STATUS_NOT_FOUND:
/* STATUS_NOT_FOUND is returned when calling NtQueryEaFile on NFS.
In theory this should mean that the file just has no EAs, but in
fact NFS doesn't support EAs, other than the EAs which are used
for NFS requests. We're playing safe and convert STATUS_NOT_FOUND
to ENOATTR, unless we're on NFS, where we convert it to ENOTSUP. */
set_errno (pc.fs_is_nfs () ? ENOTSUP : ENOATTR);
break;
case STATUS_NONEXISTENT_EA_ENTRY:
/* Actually STATUS_NONEXISTENT_EA_ENTRY is either never generated, or
it was only generated in some old and long forgotton NT version.
See below. For safty reasons, we handle it here, nevertheless. */
set_errno (ENOATTR);
break;
default:
__seterrno_from_nt_status (status);
break;
}
goto out;
}
if (name)
{
/* Another weird behaviour of NtQueryEaFile. If you ask for a
specific EA which is not present in the file's EA list, you don't
get a useful error code like STATUS_NONEXISTENT_EA_ENTRY. Rather
NtQueryEaFile returns success with the entry's EaValueLength
set to 0. */
if (!fea->EaValueLength)
{
set_errno (ENOATTR);
goto out;
}
if (size > 0)
{
if (size < fea->EaValueLength)
status = NtOpenFile (&h, READ_CONTROL | FILE_READ_EA, &attr, &io,
FILE_SHARE_VALID_FLAGS,
FILE_OPEN_FOR_BACKUP_INTENT);
if (!NT_SUCCESS (status))
{
set_errno (ERANGE);
goto out;
__seterrno_from_nt_status (status);
__leave;
}
memcpy (value, fea->EaName + fea->EaNameLength + 1,
fea->EaValueLength);
hdl = NULL;
}
ret = fea->EaValueLength;
}
else
{
ret = 0;
do
fea = (PFILE_FULL_EA_INFORMATION) tp.w_get ();
if (name)
{
fea->EaNameLength += 5; /* "user." */
size_t nlen;
/* For compatibility with Linux, we only allow user xattrs and
return ENOTSUP otherwise. */
if (ascii_strncasematch (name, "user.", 5))
name += 5;
else
{
set_errno (ENOTSUP);
__leave;
}
if ((nlen = strlen (name)) >= MAX_EA_NAME_LEN)
{
set_errno (EINVAL);
return -1;
}
glen = sizeof (FILE_GET_EA_INFORMATION) + nlen;
gea = (PFILE_GET_EA_INFORMATION) alloca (glen);
gea->NextEntryOffset = 0;
gea->EaNameLength = nlen;
strcpy (gea->EaName, name);
}
while (true)
{
if (h)
{
status = NtQueryEaFile (h, &io, fea, EA_BUFSIZ, TRUE, gea, glen,
NULL, TRUE);
if (status != STATUS_ACCESS_DENIED || !hdl)
break;
}
status = NtOpenFile (&h, READ_CONTROL | FILE_READ_EA, &attr, &io,
FILE_SHARE_VALID_FLAGS,
FILE_OPEN_FOR_BACKUP_INTENT);
if (!NT_SUCCESS (status))
break;
hdl = NULL;
}
if (!NT_SUCCESS (status))
{
switch (status)
{
case STATUS_NO_EAS_ON_FILE:
ret = 0;
break;
case STATUS_INVALID_DEVICE_REQUEST:
set_errno (ENOTSUP);
break;
case STATUS_NOT_FOUND:
/* STATUS_NOT_FOUND is returned when calling NtQueryEaFile on NFS.
In theory this should mean that the file just has no EAs, but
in fact NFS doesn't support EAs, other than the EAs which are
used for NFS requests. We're playing safe and convert
STATUS_NOT_FOUND to ENOATTR, unless we're on NFS, where we
convert it to ENOTSUP. */
set_errno (pc.fs_is_nfs () ? ENOTSUP : ENOATTR);
break;
case STATUS_NONEXISTENT_EA_ENTRY:
/* Actually STATUS_NONEXISTENT_EA_ENTRY is either never generated,
or it was only generated in some old and long forgotton NT
version. See below. For safty reasons, we handle it here,
nevertheless. */
set_errno (ENOATTR);
break;
default:
__seterrno_from_nt_status (status);
break;
}
__leave;
}
if (name)
{
/* Another weird behaviour of NtQueryEaFile. If you ask for a
specific EA which is not present in the file's EA list, you don't
get a useful error code like STATUS_NONEXISTENT_EA_ENTRY. Rather
NtQueryEaFile returns success with the entry's EaValueLength
set to 0. */
if (!fea->EaValueLength)
{
set_errno (ENOATTR);
__leave;
}
if (size > 0)
{
if ((size_t) ret + fea->EaNameLength + 1 > size)
if (size < fea->EaValueLength)
{
set_errno (ERANGE);
goto out;
__leave;
}
/* For compatibility with Linux, we always prepend "user." to
the attribute name, so effectively we only support user
attributes from a application point of view. */
char tmpbuf[MAX_EA_NAME_LEN * 2];
char *tp = stpcpy (tmpbuf, "user.");
stpcpy (tp, fea->EaName);
/* NTFS stores all EA names in uppercase unfortunately. To keep
compatibility with ext/xfs EA namespaces and accompanying
tools, which expect the namespaces to be lower case, we return
EA names in lowercase if the file is on a native NTFS. */
if (pc.fs_is_ntfs ())
strlwr (tp);
tp = stpcpy (value, tmpbuf) + 1;
ret += tp - value;
value = tp;
memcpy (value, fea->EaName + fea->EaNameLength + 1,
fea->EaValueLength);
}
else
ret += fea->EaNameLength + 1;
strcpy (lastname, fea->EaName);
status = NtQueryEaFile (h, &io, fea, EA_BUFSIZ, TRUE, NULL, 0,
NULL, FALSE);
ret = fea->EaValueLength;
}
else
{
ret = 0;
do
{
fea->EaNameLength += 5; /* "user." */
if (size > 0)
{
if ((size_t) ret + fea->EaNameLength + 1 > size)
{
set_errno (ERANGE);
__leave;
}
/* For compatibility with Linux, we always prepend "user." to
the attribute name, so effectively we only support user
attributes from a application point of view. */
char tmpbuf[MAX_EA_NAME_LEN * 2];
char *tp = stpcpy (tmpbuf, "user.");
stpcpy (tp, fea->EaName);
/* NTFS stores all EA names in uppercase unfortunately. To
keep compatibility with ext/xfs EA namespaces and
accompanying tools, which expect the namespaces to be
lower case, we return EA names in lowercase if the file
is on a native NTFS. */
if (pc.fs_is_ntfs ())
strlwr (tp);
tp = stpcpy (value, tmpbuf) + 1;
ret += tp - value;
value = tp;
}
else
ret += fea->EaNameLength + 1;
strcpy (lastname, fea->EaName);
status = NtQueryEaFile (h, &io, fea, EA_BUFSIZ, TRUE, NULL, 0,
NULL, FALSE);
}
while (NT_SUCCESS (status) && strcmp (lastname, fea->EaName) != 0);
}
while (NT_SUCCESS (status) && strcmp (lastname, fea->EaName) != 0);
}
out:
__except (EFAULT) {}
__endtry
if (!hdl)
CloseHandle (h);
debug_printf ("%d = read_ea(%S, %s, %p, %lu)",
@ -241,120 +245,121 @@ write_ea (HANDLE hdl, path_conv &pc, const char *name, const char *value,
ULONG flen;
size_t nlen;
myfault efault;
if (efault.faulted (EFAULT))
goto out;
pc.get_object_attr (attr, sec_none_nih);
debug_printf ("write_ea (%S, %s, %p, %lu, %d)",
attr.ObjectName, name, value, size, flags);
/* Early open if handle is NULL. This allows to return error codes like
ENOENT before we actually check for the correctness of the EA name and
stuff like that. */
if (!hdl)
__try
{
status = NtOpenFile (&h, READ_CONTROL | FILE_WRITE_EA, &attr, &io,
FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT);
if (!NT_SUCCESS (status))
pc.get_object_attr (attr, sec_none_nih);
debug_printf ("write_ea (%S, %s, %p, %lu, %d)",
attr.ObjectName, name, value, size, flags);
/* Early open if handle is NULL. This allows to return error codes like
ENOENT before we actually check for the correctness of the EA name and
stuff like that. */
if (!hdl)
{
__seterrno_from_nt_status (status);
goto out;
status = NtOpenFile (&h, READ_CONTROL | FILE_WRITE_EA, &attr, &io,
FILE_SHARE_VALID_FLAGS,
FILE_OPEN_FOR_BACKUP_INTENT);
if (!NT_SUCCESS (status))
{
__seterrno_from_nt_status (status);
__leave;
}
hdl = NULL;
}
hdl = NULL;
}
/* For compatibility with Linux, we only allow user xattrs and
return ENOTSUP otherwise. */
if (!ascii_strncasematch (name, "user.", 5))
{
set_errno (ENOTSUP);
goto out;
}
/* For compatibility with Linux, we only allow user xattrs and
return ENOTSUP otherwise. */
if (!ascii_strncasematch (name, "user.", 5))
{
set_errno (ENOTSUP);
__leave;
}
/* removexattr is supposed to fail with ENOATTR if the requested EA is not
available. This is equivalent to the XATTR_REPLACE flag for setxattr. */
if (!value)
flags = XATTR_REPLACE;
/* removexattr is supposed to fail with ENOATTR if the requested EA is
not available. This is equivalent to XATTR_REPLACE for setxattr. */
if (!value)
flags = XATTR_REPLACE;
if (flags)
{
if (flags != XATTR_CREATE && flags != XATTR_REPLACE)
if (flags)
{
if (flags != XATTR_CREATE && flags != XATTR_REPLACE)
{
set_errno (EINVAL);
__leave;
}
ssize_t rret = read_ea (hdl, pc, name, NULL, 0);
if (flags == XATTR_CREATE && rret > 0)
{
set_errno (EEXIST);
__leave;
}
if (flags == XATTR_REPLACE && rret < 0)
__leave;
}
/* Skip "user." prefix. */
name += 5;
if ((nlen = strlen (name)) >= MAX_EA_NAME_LEN)
{
set_errno (EINVAL);
goto out;
__leave;
}
ssize_t rret = read_ea (hdl, pc, name, NULL, 0);
if (flags == XATTR_CREATE && rret > 0)
flen = sizeof (FILE_FULL_EA_INFORMATION) + nlen + 1 + size;
fea = (PFILE_FULL_EA_INFORMATION) alloca (flen);
fea->NextEntryOffset = 0;
fea->Flags = 0;
fea->EaNameLength = nlen;
fea->EaValueLength = size;
strcpy (fea->EaName, name);
if (value)
memcpy (fea->EaName + fea->EaNameLength + 1, value, size);
while (true)
{
set_errno (EEXIST);
goto out;
}
if (flags == XATTR_REPLACE && rret < 0)
goto out;
}
/* Skip "user." prefix. */
name += 5;
if ((nlen = strlen (name)) >= MAX_EA_NAME_LEN)
{
set_errno (EINVAL);
goto out;
}
flen = sizeof (FILE_FULL_EA_INFORMATION) + nlen + 1 + size;
fea = (PFILE_FULL_EA_INFORMATION) alloca (flen);
fea->NextEntryOffset = 0;
fea->Flags = 0;
fea->EaNameLength = nlen;
fea->EaValueLength = size;
strcpy (fea->EaName, name);
if (value)
memcpy (fea->EaName + fea->EaNameLength + 1, value, size);
while (true)
{
if (h)
{
status = NtSetEaFile (h, &io, fea, flen);
if (status != STATUS_ACCESS_DENIED || !hdl)
if (h)
{
status = NtSetEaFile (h, &io, fea, flen);
if (status != STATUS_ACCESS_DENIED || !hdl)
break;
}
status = NtOpenFile (&h, READ_CONTROL | FILE_WRITE_EA, &attr, &io,
FILE_SHARE_VALID_FLAGS,
FILE_OPEN_FOR_BACKUP_INTENT);
if (!NT_SUCCESS (status))
break;
hdl = NULL;
}
status = NtOpenFile (&h, READ_CONTROL | FILE_WRITE_EA, &attr, &io,
FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT);
if (!NT_SUCCESS (status))
break;
hdl = NULL;
}
if (!NT_SUCCESS (status))
{
switch (status)
{
case STATUS_EA_TOO_LARGE:
/* STATUS_EA_TOO_LARGE has a matching Win32 error ERROR_EA_TABLE_FULL.
For some unknown reason RtlNtStatusToDosError does not translate
STATUS_EA_TOO_LARGE to ERROR_EA_TABLE_FULL, but instead to
ERROR_EA_LIST_INCONSISTENT. This error code is also returned for
STATUS_EA_LIST_INCONSISTENT, which means the incoming EA list is...
inconsistent. For obvious reasons we translate
ERROR_EA_LIST_INCONSISTENT to EINVAL, so we have to handle
STATUS_EA_TOO_LARGE explicitely here, to get the correct mapping
to ENOSPC. */
set_errno (ENOSPC);
break;
case STATUS_INVALID_DEVICE_REQUEST:
set_errno (ENOTSUP);
break;
default:
__seterrno_from_nt_status (status);
break;
switch (status)
{
case STATUS_EA_TOO_LARGE:
/* STATUS_EA_TOO_LARGE has a matching Win32 error code
ERROR_EA_TABLE_FULL. For some reason RtlNtStatusToDosError
does not translate STATUS_EA_TOO_LARGE to ERROR_EA_TABLE_FULL,
but instead to ERROR_EA_LIST_INCONSISTENT. This error code is
also returned for STATUS_EA_LIST_INCONSISTENT, which means the
incoming EA list is... inconsistent. For obvious reasons we
translate ERROR_EA_LIST_INCONSISTENT to EINVAL, so we have to
handle STATUS_EA_TOO_LARGE explicitely here, to get the correct
mapping to ENOSPC. */
set_errno (ENOSPC);
break;
case STATUS_INVALID_DEVICE_REQUEST:
set_errno (ENOTSUP);
break;
default:
__seterrno_from_nt_status (status);
break;
}
}
else
ret = 0;
}
else
ret = 0;
out:
__except (EFAULT) {}
__endtry
if (!hdl)
CloseHandle (h);
debug_printf ("%d = write_ea(%S, %s, %p, %lu, %d)",

File diff suppressed because it is too large Load Diff

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,16 +143,19 @@ ppoll (struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts,
int timeout;
sigset_t oldset = _my_tls.sigmask;
myfault efault;
if (efault.faulted (EFAULT))
return -1;
timeout = (timeout_ts == NULL)
? -1
: (timeout_ts->tv_sec * 1000 + timeout_ts->tv_nsec / 1000000);
if (sigmask)
set_signal_mask (_my_tls.sigmask, *sigmask);
int ret = poll (fds, nfds, timeout);
if (sigmask)
set_signal_mask (_my_tls.sigmask, oldset);
return ret;
__try
{
timeout = (timeout_ts == NULL)
? -1
: (timeout_ts->tv_sec * 1000 + timeout_ts->tv_nsec / 1000000);
if (sigmask)
set_signal_mask (_my_tls.sigmask, *sigmask);
int ret = poll (fds, nfds, timeout);
if (sigmask)
set_signal_mask (_my_tls.sigmask, oldset);
return ret;
}
__except (EFAULT) {}
__endtry
return -1;
}

File diff suppressed because it is too large Load Diff

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,53 +116,51 @@ getrlimit (int resource, struct rlimit *rlp)
{
MEMORY_BASIC_INFORMATION m;
myfault efault;
if (efault.faulted (EFAULT))
return -1;
rlp->rlim_cur = RLIM_INFINITY;
rlp->rlim_max = RLIM_INFINITY;
switch (resource)
__try
{
case RLIMIT_CPU:
case RLIMIT_FSIZE:
case RLIMIT_DATA:
case RLIMIT_AS:
break;
case RLIMIT_STACK:
if (!VirtualQuery ((LPCVOID) &m, &m, sizeof m))
debug_printf ("couldn't get stack info, returning def.values. %E");
else
rlp->rlim_cur = RLIM_INFINITY;
rlp->rlim_max = RLIM_INFINITY;
switch (resource)
{
rlp->rlim_cur = (rlim_t) &m - (rlim_t) m.AllocationBase;
rlp->rlim_max = (rlim_t) m.BaseAddress + m.RegionSize
- (rlim_t) m.AllocationBase;
case RLIMIT_CPU:
case RLIMIT_FSIZE:
case RLIMIT_DATA:
case RLIMIT_AS:
break;
case RLIMIT_STACK:
if (!VirtualQuery ((LPCVOID) &m, &m, sizeof m))
debug_printf ("couldn't get stack info, returning def.values. %E");
else
{
rlp->rlim_cur = (rlim_t) &m - (rlim_t) m.AllocationBase;
rlp->rlim_max = (rlim_t) m.BaseAddress + m.RegionSize
- (rlim_t) m.AllocationBase;
}
break;
case RLIMIT_NOFILE:
rlp->rlim_cur = getdtablesize ();
if (rlp->rlim_cur < OPEN_MAX)
rlp->rlim_cur = OPEN_MAX;
rlp->rlim_max = OPEN_MAX_MAX;
break;
case RLIMIT_CORE:
rlp->rlim_cur = cygheap->rlim_core;
break;
default:
set_errno (EINVAL);
__leave;
}
break;
case RLIMIT_NOFILE:
rlp->rlim_cur = getdtablesize ();
if (rlp->rlim_cur < OPEN_MAX)
rlp->rlim_cur = OPEN_MAX;
rlp->rlim_max = OPEN_MAX_MAX;
break;
case RLIMIT_CORE:
rlp->rlim_cur = cygheap->rlim_core;
break;
default:
set_errno (EINVAL);
return -1;
return 0;
}
return 0;
__except (EFAULT) {}
__endtry
return -1;
}
extern "C" int
setrlimit (int resource, const struct rlimit *rlp)
{
myfault efault;
if (efault.faulted (EFAULT))
return -1;
struct rlimit oldlimits;
/* Check if the request is to actually change the resource settings.
@ -170,29 +168,35 @@ setrlimit (int resource, const struct rlimit *rlp)
if (getrlimit (resource, &oldlimits) < 0)
return -1;
if (oldlimits.rlim_cur == rlp->rlim_cur &&
oldlimits.rlim_max == rlp->rlim_max)
/* No change in resource requirements, succeed immediately */
return 0;
if (rlp->rlim_cur > rlp->rlim_max)
__try
{
set_errno (EINVAL);
return -1;
}
if (oldlimits.rlim_cur == rlp->rlim_cur &&
oldlimits.rlim_max == rlp->rlim_max)
/* No change in resource requirements, succeed immediately */
return 0;
switch (resource)
{
case RLIMIT_CORE:
cygheap->rlim_core = rlp->rlim_cur;
break;
case RLIMIT_NOFILE:
if (rlp->rlim_cur != RLIM_INFINITY)
return setdtablesize (rlp->rlim_cur);
break;
default:
set_errno (EINVAL);
return -1;
if (rlp->rlim_cur > rlp->rlim_max)
{
set_errno (EINVAL);
__leave;
}
switch (resource)
{
case RLIMIT_CORE:
cygheap->rlim_core = rlp->rlim_cur;
break;
case RLIMIT_NOFILE:
if (rlp->rlim_cur != RLIM_INFINITY)
return setdtablesize (rlp->rlim_cur);
break;
default:
set_errno (EINVAL);
__leave;
}
return 0;
}
return 0;
__except (EFAULT)
__endtry
return -1;
}

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,21 +230,24 @@ pselect(int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
struct timeval tv;
sigset_t oldset = _my_tls.sigmask;
myfault efault;
if (efault.faulted (EFAULT))
return -1;
if (ts)
__try
{
tv.tv_sec = ts->tv_sec;
tv.tv_usec = ts->tv_nsec / 1000;
if (ts)
{
tv.tv_sec = ts->tv_sec;
tv.tv_usec = ts->tv_nsec / 1000;
}
if (set)
set_signal_mask (_my_tls.sigmask, *set);
int ret = cygwin_select (maxfds, readfds, writefds, exceptfds,
ts ? &tv : NULL);
if (set)
set_signal_mask (_my_tls.sigmask, oldset);
return ret;
}
if (set)
set_signal_mask (_my_tls.sigmask, *set);
int ret = cygwin_select (maxfds, readfds, writefds, exceptfds,
ts ? &tv : NULL);
if (set)
set_signal_mask (_my_tls.sigmask, oldset);
return ret;
__except (EFAULT) {}
__endtry
return -1;
}
/* Call cleanup functions for all inspected fds. Gets rid of any

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,19 +85,22 @@ semctl (int semid, int semnum, int cmd, ...)
}
syscall_printf ("semctl (semid = %d, semnum = %d, cmd = %d, arg = %p)",
semid, semnum, cmd, arg.buf);
myfault efault;
if (efault.faulted (EFAULT))
return -1;
client_request_sem request (semid, semnum, cmd, &arg);
if (request.make_request () == -1 || request.retval () == -1)
__try
{
syscall_printf ("-1 [%d] = semctl ()", request.error_code ());
set_errno (request.error_code ());
if (request.error_code () == ENOSYS)
raise (SIGSYS);
return -1;
client_request_sem request (semid, semnum, cmd, &arg);
if (request.make_request () == -1 || request.retval () == -1)
{
syscall_printf ("-1 [%d] = semctl ()", request.error_code ());
set_errno (request.error_code ());
if (request.error_code () == ENOSYS)
raise (SIGSYS);
__leave;
}
return request.retval ();
}
return request.retval ();
__except (EFAULT) {}
__endtry
return -1;
}
extern "C" int
@ -122,17 +125,20 @@ semop (int semid, struct sembuf *sops, size_t nsops)
{
syscall_printf ("semop (semid = %d, sops = %p, nsops = %ld)",
semid, sops, nsops);
myfault efault;
if (efault.faulted (EFAULT))
return -1;
client_request_sem request (semid, sops, nsops);
if (request.make_request () == -1 || request.retval () == -1)
__try
{
syscall_printf ("-1 [%d] = semop ()", request.error_code ());
set_errno (request.error_code ());
if (request.error_code () == ENOSYS)
raise (SIGSYS);
return -1;
client_request_sem request (semid, sops, nsops);
if (request.make_request () == -1 || request.retval () == -1)
{
syscall_printf ("-1 [%d] = semop ()", request.error_code ());
set_errno (request.error_code ());
if (request.error_code () == ENOSYS)
raise (SIGSYS);
__leave;
}
return request.retval ();
}
return request.retval ();
__except (EFAULT) {}
__endtry
return -1;
}

View File

@ -260,41 +260,45 @@ shmctl (int shmid, int cmd, struct shmid_ds *buf)
{
syscall_printf ("shmctl (shmid = %d, cmd = %d, buf = %p)",
shmid, cmd, buf);
myfault efault;
if (efault.faulted (EFAULT))
return -1;
client_request_shm request (shmid, cmd, buf);
if (request.make_request () == -1 || request.retval () == -1)
__try
{
syscall_printf ("-1 [%d] = shmctl ()", request.error_code ());
set_errno (request.error_code ());
if (request.error_code () == ENOSYS)
raise (SIGSYS);
return -1;
}
if (cmd == IPC_RMID)
{
/* Cleanup */
shm_shmid_list *ssh_entry, *ssh_next_entry;
SLIST_LOCK ();
SLIST_FOREACH_SAFE (ssh_entry, &ssh_list, ssh_next, ssh_next_entry)
client_request_shm request (shmid, cmd, buf);
if (request.make_request () == -1 || request.retval () == -1)
{
if (ssh_entry->shmid == shmid)
{
/* Remove this entry from the list and close the handle
only if it's not in use anymore. */
if (ssh_entry->ref_count <= 0)
{
SLIST_REMOVE (&ssh_list, ssh_entry, shm_shmid_list, ssh_next);
CloseHandle (ssh_entry->hdl);
delete ssh_entry;
}
break;
}
syscall_printf ("-1 [%d] = shmctl ()", request.error_code ());
set_errno (request.error_code ());
if (request.error_code () == ENOSYS)
raise (SIGSYS);
__leave;
}
SLIST_UNLOCK ();
if (cmd == IPC_RMID)
{
/* Cleanup */
shm_shmid_list *ssh_entry, *ssh_next_entry;
SLIST_LOCK ();
SLIST_FOREACH_SAFE (ssh_entry, &ssh_list, ssh_next, ssh_next_entry)
{
if (ssh_entry->shmid == shmid)
{
/* Remove this entry from the list and close the handle
only if it's not in use anymore. */
if (ssh_entry->ref_count <= 0)
{
SLIST_REMOVE (&ssh_list, ssh_entry, shm_shmid_list,
ssh_next);
CloseHandle (ssh_entry->hdl);
delete ssh_entry;
}
break;
}
}
SLIST_UNLOCK ();
}
return request.retval ();
}
return request.retval ();
__except (EFAULT) {}
__endtry
return -1;
}
extern "C" int

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,33 +197,37 @@ handle_sigprocmask (int how, const sigset_t *set, sigset_t *oldset, sigset_t& op
return EINVAL;
}
myfault efault;
if (efault.faulted (EFAULT))
return EFAULT;
if (oldset)
*oldset = opmask;
if (set)
{
sigset_t newmask = opmask;
switch (how)
__try
{
case SIG_BLOCK:
/* add set to current mask */
newmask |= *set;
break;
case SIG_UNBLOCK:
/* remove set from current mask */
newmask &= ~*set;
break;
case SIG_SETMASK:
/* just set it */
newmask = *set;
break;
if (oldset)
*oldset = opmask;
if (set)
{
sigset_t newmask = opmask;
switch (how)
{
case SIG_BLOCK:
/* add set to current mask */
newmask |= *set;
break;
case SIG_UNBLOCK:
/* remove set from current mask */
newmask &= ~*set;
break;
case SIG_SETMASK:
/* just set it */
newmask = *set;
break;
}
set_signal_mask (opmask, newmask);
}
set_signal_mask (opmask, newmask);
}
__except (EFAULT)
{
return EFAULT;
}
__endtry
return 0;
}
@ -382,8 +386,7 @@ sigaction_worker (int sig, const struct sigaction *newact,
struct sigaction *oldact, bool isinternal)
{
int res = -1;
myfault efault;
if (!efault.faulted (EFAULT))
__try
{
sig_dispatch_pending ();
/* check that sig is in right range */
@ -394,14 +397,17 @@ sigaction_worker (int sig, const struct sigaction *newact,
struct sigaction oa = global_sigs[sig];
if (!newact)
sigproc_printf ("signal %d, newact %p, oa %p", sig, newact, oa, oa.sa_handler);
sigproc_printf ("signal %d, newact %p, oa %p",
sig, newact, oa, oa.sa_handler);
else
{
sigproc_printf ("signal %d, newact %p (handler %p), oa %p", sig, newact, newact->sa_handler, oa, oa.sa_handler);
sigproc_printf ("signal %d, newact %p (handler %p), oa %p",
sig, newact, newact->sa_handler, oa,
oa.sa_handler);
if (sig == SIGKILL || sig == SIGSTOP)
{
set_errno (EINVAL);
goto out;
__leave;
}
struct sigaction na = *newact;
struct sigaction& gs = global_sigs[sig];
@ -430,8 +436,8 @@ sigaction_worker (int sig, const struct sigaction *newact,
res = 0;
}
}
out:
__except (EFAULT) {}
__endtry
return res;
}
@ -560,41 +566,41 @@ sigwait (const sigset_t *set, int *sig_ptr)
extern "C" int
sigwaitinfo (const sigset_t *set, siginfo_t *info)
{
int res = -1;
pthread_testcancel ();
myfault efault;
if (efault.faulted (EFAULT))
return -1;
set_signal_mask (_my_tls.sigwait_mask, *set);
sig_dispatch_pending (true);
int res;
switch (cygwait (NULL, cw_infinite, cw_sig_eintr | cw_cancel | cw_cancel_self))
__try
{
case WAIT_SIGNALED:
if (!sigismember (set, _my_tls.infodata.si_signo))
{
set_errno (EINTR);
res = -1;
}
else
{
_my_tls.lock ();
if (info)
*info = _my_tls.infodata;
res = _my_tls.infodata.si_signo;
_my_tls.sig = 0;
if (_my_tls.retaddr () == (__stack_t) sigdelayed)
_my_tls.pop ();
_my_tls.unlock ();
}
break;
default:
__seterrno ();
res = -1;
}
set_signal_mask (_my_tls.sigwait_mask, *set);
sig_dispatch_pending (true);
switch (cygwait (NULL, cw_infinite, cw_sig_eintr | cw_cancel | cw_cancel_self))
{
case WAIT_SIGNALED:
if (!sigismember (set, _my_tls.infodata.si_signo))
set_errno (EINTR);
else
{
_my_tls.lock ();
if (info)
*info = _my_tls.infodata;
res = _my_tls.infodata.si_signo;
_my_tls.sig = 0;
if (_my_tls.retaddr () == (__stack_t) sigdelayed)
_my_tls.pop ();
_my_tls.unlock ();
}
break;
default:
__seterrno ();
break;
}
}
__except (EFAULT) {
res = -1;
}
__endtry
sigproc_printf ("returning signal %d", res);
return res;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

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;
verifyable_object **object = (verifyable_object **) objectptr;
__try
{
if (!objectptr || !(*(const char **) objectptr))
__leave;
if ((static_ptr1 && *object == static_ptr1) ||
(static_ptr2 && *object == static_ptr2) ||
(static_ptr3 && *object == static_ptr3))
return VALID_STATIC_OBJECT;
if ((*object)->magic != magic)
return INVALID_OBJECT;
return VALID_OBJECT;
verifyable_object **object = (verifyable_object **) objectptr;
if ((static_ptr1 && *object == static_ptr1) ||
(static_ptr2 && *object == static_ptr2) ||
(static_ptr3 && *object == static_ptr3))
state = VALID_STATIC_OBJECT;
else if ((*object)->magic == magic)
state = VALID_OBJECT;
}
__except (NO_ERROR) {}
__endtry
return state;
}
/* static members */
@ -2684,18 +2685,20 @@ pthread_cond::init (pthread_cond_t *cond, const pthread_condattr_t *attr)
return EAGAIN;
}
myfault efault;
if (efault.faulted ())
int ret = 0;
__try
{
*cond = new_cond;
}
__except (NO_ERROR)
{
delete new_cond;
cond_initialization_lock.unlock ();
return EINVAL;
ret = EINVAL;
}
*cond = new_cond;
__endtry
cond_initialization_lock.unlock ();
return 0;
return ret;
}
extern "C" int
@ -2747,45 +2750,47 @@ pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
struct timespec tp;
LARGE_INTEGER timeout;
myfault efault;
if (efault.faulted ())
return EINVAL;
pthread_testcancel ();
int err = __pthread_cond_wait_init (cond, mutex);
if (err)
return err;
/* According to SUSv3, the abstime value must be checked for validity. */
if (abstime->tv_sec < 0
|| abstime->tv_nsec < 0
|| abstime->tv_nsec > 999999999)
return EINVAL;
clock_gettime ((*cond)->clock_id, &tp);
/* Check for immediate timeout before converting */
if (tp.tv_sec > abstime->tv_sec
|| (tp.tv_sec == abstime->tv_sec
&& tp.tv_nsec > abstime->tv_nsec))
return ETIMEDOUT;
timeout.QuadPart = abstime->tv_sec * NSPERSEC
+ (abstime->tv_nsec + 99LL) / 100LL;
switch ((*cond)->clock_id)
__try
{
case CLOCK_REALTIME:
timeout.QuadPart += FACTOR;
break;
default:
/* other clocks must be handled as relative timeout */
timeout.QuadPart -= tp.tv_sec * NSPERSEC + tp.tv_nsec / 100LL;
timeout.QuadPart *= -1LL;
break;
int err = __pthread_cond_wait_init (cond, mutex);
if (err)
return err;
/* According to SUSv3, the abstime value must be checked for validity. */
if (abstime->tv_sec < 0
|| abstime->tv_nsec < 0
|| abstime->tv_nsec > 999999999)
__leave;
clock_gettime ((*cond)->clock_id, &tp);
/* Check for immediate timeout before converting */
if (tp.tv_sec > abstime->tv_sec
|| (tp.tv_sec == abstime->tv_sec
&& tp.tv_nsec > abstime->tv_nsec))
return ETIMEDOUT;
timeout.QuadPart = abstime->tv_sec * NSPERSEC
+ (abstime->tv_nsec + 99LL) / 100LL;
switch ((*cond)->clock_id)
{
case CLOCK_REALTIME:
timeout.QuadPart += FACTOR;
break;
default:
/* other clocks must be handled as relative timeout */
timeout.QuadPart -= tp.tv_sec * NSPERSEC + tp.tv_nsec / 100LL;
timeout.QuadPart *= -1LL;
break;
}
return (*cond)->wait (*mutex, &timeout);
}
return (*cond)->wait (*mutex, &timeout);
__except (NO_ERROR) {}
__endtry
return EINVAL;
}
extern "C" int
@ -2910,18 +2915,20 @@ pthread_rwlock::init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr
return EAGAIN;
}
myfault efault;
if (efault.faulted ())
int ret = 0;
__try
{
*rwlock = new_rwlock;
}
__except (NO_ERROR)
{
delete new_rwlock;
rwlock_initialization_lock.unlock ();
return EINVAL;
ret = EINVAL;
}
*rwlock = new_rwlock;
__endtry
rwlock_initialization_lock.unlock ();
return 0;
return ret;
}
extern "C" int
@ -3133,15 +3140,17 @@ pthread_mutex::init (pthread_mutex_t *mutex,
new_mutex->type = PTHREAD_MUTEX_ERRORCHECK;
}
myfault efault;
if (efault.faulted ())
__try
{
*mutex = new_mutex;
}
__except (NO_ERROR)
{
delete new_mutex;
mutex_initialization_lock.unlock ();
return EINVAL;
}
*mutex = new_mutex;
__endtry
}
mutex_initialization_lock.unlock ();
pthread_printf ("*mutex %p, attr %p, initializer %p", *mutex, attr, initializer);
@ -3230,16 +3239,17 @@ pthread_spinlock::init (pthread_spinlock_t *spinlock, int pshared)
return EAGAIN;
}
myfault efault;
if (efault.faulted ())
__try
{
*spinlock = new_spinlock;
}
__except (NO_ERROR)
{
delete new_spinlock;
return EINVAL;
}
*spinlock = new_spinlock;
__endtry
pthread_printf ("*spinlock %p, pshared %d", *spinlock, pshared);
return 0;
}
@ -3502,35 +3512,38 @@ semaphore::_timedwait (const struct timespec *abstime)
{
LARGE_INTEGER timeout;
myfault efault;
if (efault.faulted ())
__try
{
timeout.QuadPart = abstime->tv_sec * NSPERSEC
+ (abstime->tv_nsec + 99) / 100 + FACTOR;
switch (cygwait (win32_obj_id, &timeout, cw_cancel | cw_cancel_self | cw_sig_eintr))
{
case WAIT_OBJECT_0:
break;
case WAIT_SIGNALED:
set_errno (EINTR);
return -1;
case WAIT_TIMEOUT:
set_errno (ETIMEDOUT);
return -1;
default:
pthread_printf ("cygwait failed. %E");
__seterrno ();
return -1;
}
}
__except (NO_ERROR)
{
/* According to SUSv3, abstime need not be checked for validity,
if the semaphore can be locked immediately. */
if (!_trywait ())
return 0;
set_errno (EINVAL);
return -1;
}
timeout.QuadPart = abstime->tv_sec * NSPERSEC
+ (abstime->tv_nsec + 99) / 100 + FACTOR;
switch (cygwait (win32_obj_id, &timeout, cw_cancel | cw_cancel_self | cw_sig_eintr))
{
case WAIT_OBJECT_0:
break;
case WAIT_SIGNALED:
set_errno (EINTR);
return -1;
case WAIT_TIMEOUT:
set_errno (ETIMEDOUT);
return -1;
default:
pthread_printf ("cygwait failed. %E");
__seterrno ();
return -1;
if (_trywait ())
{
set_errno (EINVAL);
return -1;
}
}
__endtry
return 0;
}
@ -3761,36 +3774,38 @@ semaphore::post (sem_t *sem)
int
semaphore::getvalue (sem_t *sem, int *sval)
{
myfault efault;
if (efault.faulted () || !is_good_object (sem))
__try
{
set_errno (EINVAL);
return -1;
if (is_good_object (sem))
return (*sem)->_getvalue (sval);
}
return (*sem)->_getvalue (sval);
__except (NO_ERROR) {}
__endtry
set_errno (EINVAL);
return -1;
}
int
semaphore::getinternal (sem_t *sem, int *sfd, unsigned long long *shash,
LUID *sluid, unsigned int *sval)
{
myfault efault;
if (efault.faulted () || !is_good_object (sem))
__try
{
set_errno (EINVAL);
return -1;
if (!is_good_object (sem))
__leave;
if ((*sfd = (*sem)->fd) < 0)
__leave;
*shash = (*sem)->hash;
*sluid = (*sem)->luid;
/* POSIX defines the value in calls to sem_init/sem_open as unsigned,
but the sem_getvalue gets a pointer to int to return the value.
Go figure! */
return (*sem)->_getvalue ((int *)sval);
}
if ((*sfd = (*sem)->fd) < 0)
{
set_errno (EINVAL);
return -1;
}
*shash = (*sem)->hash;
*sluid = (*sem)->luid;
/* POSIX defines the value in calls to sem_init/sem_open as unsigned, but
the sem_getvalue gets a pointer to int to return the value. Go figure! */
return (*sem)->_getvalue ((int *)sval);
__except (NO_ERROR) {}
__endtry
set_errno (EINVAL);
return -1;
}
/* pthread_null */

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,45 +219,49 @@ it_bad (const timespec& t)
int
timer_tracker::settime (int in_flags, const itimerspec *value, itimerspec *ovalue)
{
if (!value)
int ret = -1;
__try
{
set_errno (EINVAL);
return -1;
}
if (!value)
{
set_errno (EINVAL);
__leave;
}
myfault efault;
if (efault.faulted (EFAULT)
|| it_bad (value->it_value)
|| it_bad (value->it_interval))
return -1;
if (it_bad (value->it_value) || it_bad (value->it_interval))
__leave;
long long now = in_flags & TIMER_ABSTIME ? 0 : gtod.usecs ();
long long now = in_flags & TIMER_ABSTIME ? 0 : gtod.usecs ();
lock_timer_tracker here;
cancel ();
lock_timer_tracker here;
cancel ();
if (ovalue)
gettime (ovalue);
if (ovalue)
gettime (ovalue);
if (!value->it_value.tv_sec && !value->it_value.tv_nsec)
interval_us = sleepto_us = 0;
else
{
sleepto_us = now + to_us (value->it_value);
interval_us = to_us (value->it_interval);
it_interval = value->it_interval;
if (!hcancel)
hcancel = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
if (!value->it_value.tv_sec && !value->it_value.tv_nsec)
interval_us = sleepto_us = 0;
else
ResetEvent (hcancel);
if (!syncthread)
syncthread = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
else
ResetEvent (syncthread);
new cygthread (timer_thread, this, "itimer", syncthread);
{
sleepto_us = now + to_us (value->it_value);
interval_us = to_us (value->it_interval);
it_interval = value->it_interval;
if (!hcancel)
hcancel = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
else
ResetEvent (hcancel);
if (!syncthread)
syncthread = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
else
ResetEvent (syncthread);
new cygthread (timer_thread, this, "itimer", syncthread);
}
ret = 0;
}
return 0;
__except (EFAULT) {}
__endtry
return ret;
}
void
@ -280,43 +284,51 @@ timer_tracker::gettime (itimerspec *ovalue)
extern "C" int
timer_gettime (timer_t timerid, struct itimerspec *ovalue)
{
myfault efault;
if (efault.faulted (EFAULT))
return -1;
int ret = -1;
timer_tracker *tt = (timer_tracker *) timerid;
if (tt->magic != TT_MAGIC)
__try
{
set_errno (EINVAL);
return -1;
}
timer_tracker *tt = (timer_tracker *) timerid;
if (tt->magic != TT_MAGIC)
{
set_errno (EINVAL);
return -1;
}
tt->gettime (ovalue);
return 0;
tt->gettime (ovalue);
ret = 0;
}
__except (EFAULT) {}
__endtry
return ret;
}
extern "C" int
timer_create (clockid_t clock_id, struct sigevent *__restrict evp,
timer_t *__restrict timerid)
{
myfault efault;
if (efault.faulted (EFAULT))
return -1;
int ret = -1;
if (CLOCKID_IS_PROCESS (clock_id) || CLOCKID_IS_THREAD (clock_id))
__try
{
set_errno (ENOTSUP);
return -1;
}
if (CLOCKID_IS_PROCESS (clock_id) || CLOCKID_IS_THREAD (clock_id))
{
set_errno (ENOTSUP);
return -1;
}
if (clock_id != CLOCK_REALTIME)
{
set_errno (EINVAL);
return -1;
}
if (clock_id != CLOCK_REALTIME)
{
set_errno (EINVAL);
return -1;
}
*timerid = (timer_t) new timer_tracker (clock_id, evp);
return 0;
*timerid = (timer_t) new timer_tracker (clock_id, evp);
ret = 0;
}
__except (EFAULT) {}
__endtry
return ret;
}
extern "C" int
@ -324,42 +336,52 @@ timer_settime (timer_t timerid, int flags,
const struct itimerspec *__restrict value,
struct itimerspec *__restrict ovalue)
{
timer_tracker *tt = (timer_tracker *) timerid;
myfault efault;
if (efault.faulted (EFAULT))
return -1;
if (tt->magic != TT_MAGIC)
{
set_errno (EINVAL);
return -1;
}
int ret = -1;
return tt->settime (flags, value, ovalue);
__try
{
timer_tracker *tt = (timer_tracker *) timerid;
if (tt->magic != TT_MAGIC)
{
set_errno (EINVAL);
__leave;
}
ret = tt->settime (flags, value, ovalue);
}
__except (EFAULT) {}
__endtry
return ret;
}
extern "C" int
timer_delete (timer_t timerid)
{
timer_tracker *in_tt = (timer_tracker *) timerid;
myfault efault;
if (efault.faulted (EFAULT))
return -1;
if (in_tt->magic != TT_MAGIC)
{
set_errno (EINVAL);
return -1;
}
int ret = -1;
lock_timer_tracker here;
for (timer_tracker *tt = &ttstart; tt->next != NULL; tt = tt->next)
if (tt->next == in_tt)
{
tt->next = in_tt->next;
delete in_tt;
return 0;
}
set_errno (EINVAL);
return 0;
__try
{
timer_tracker *in_tt = (timer_tracker *) timerid;
if (in_tt->magic != TT_MAGIC)
{
set_errno (EINVAL);
__leave;
}
lock_timer_tracker here;
for (timer_tracker *tt = &ttstart; tt->next != NULL; tt = tt->next)
if (tt->next == in_tt)
{
tt->next = in_tt->next;
delete in_tt;
ret = 0;
__leave;
}
set_errno (EINVAL);
ret = 0;
}
__except (EFAULT) {}
__endtry
return ret;
}
void
@ -412,18 +434,13 @@ setitimer (int which, const struct itimerval *__restrict value,
extern "C" int
getitimer (int which, struct itimerval *ovalue)
{
int ret;
int ret = -1;
if (which != ITIMER_REAL)
{
set_errno (EINVAL);
ret = -1;
}
set_errno (EINVAL);
else
{
myfault efault;
if (efault.faulted (EFAULT))
ret = -1;
else
__try
{
struct itimerspec spec_ovalue;
ret = timer_gettime ((timer_t) &ttstart, &spec_ovalue);
@ -435,6 +452,8 @@ getitimer (int which, struct itimerval *ovalue)
ovalue->it_value.tv_usec = spec_ovalue.it_value.tv_nsec / 1000;
}
}
__except (EFAULT) {}
__endtry
}
syscall_printf ("%R = getitimer()", ret);
return ret;

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,35 +59,39 @@ __to_clock_t (PLARGE_INTEGER src, int flag)
extern "C" clock_t
times (struct tms *buf)
{
myfault efault;
if (efault.faulted (EFAULT))
return ((clock_t) -1);
static SYSTEM_TIMEOFDAY_INFORMATION stodi;
KERNEL_USER_TIMES kut;
LARGE_INTEGER ticks;
clock_t tc = (clock_t) -1;
/* Fetch boot time if we haven't already. */
if (!stodi.BootTime.QuadPart)
NtQuerySystemInformation (SystemTimeOfDayInformation,
&stodi, sizeof stodi, NULL);
__try
{
/* Fetch boot time if we haven't already. */
if (!stodi.BootTime.QuadPart)
NtQuerySystemInformation (SystemTimeOfDayInformation,
&stodi, sizeof stodi, NULL);
NtQueryInformationProcess (NtCurrentProcess (), ProcessTimes,
&kut, sizeof kut, NULL);
get_system_time (&ticks);
NtQueryInformationProcess (NtCurrentProcess (), ProcessTimes,
&kut, sizeof kut, NULL);
get_system_time (&ticks);
/* uptime */
ticks.QuadPart -= stodi.BootTime.QuadPart;
/* ticks is in in 100ns, convert to clock ticks. */
clock_t tc = (clock_t) (ticks.QuadPart * CLOCKS_PER_SEC / NSPERSEC);
buf->tms_stime = __to_clock_t (&kut.KernelTime, 0);
buf->tms_utime = __to_clock_t (&kut.UserTime, 0);
timeval_to_filetime (&myself->rusage_children.ru_stime, &kut.KernelTime);
buf->tms_cstime = __to_clock_t (&kut.KernelTime, 1);
timeval_to_filetime (&myself->rusage_children.ru_utime, &kut.UserTime);
buf->tms_cutime = __to_clock_t (&kut.UserTime, 1);
/* uptime */
ticks.QuadPart -= stodi.BootTime.QuadPart;
/* ticks is in in 100ns, convert to clock ticks. */
tc = (clock_t) (ticks.QuadPart * CLOCKS_PER_SEC / NSPERSEC);
buf->tms_stime = __to_clock_t (&kut.KernelTime, 0);
buf->tms_utime = __to_clock_t (&kut.UserTime, 0);
timeval_to_filetime (&myself->rusage_children.ru_stime, &kut.KernelTime);
buf->tms_cstime = __to_clock_t (&kut.KernelTime, 1);
timeval_to_filetime (&myself->rusage_children.ru_utime, &kut.UserTime);
buf->tms_cutime = __to_clock_t (&kut.UserTime, 1);
}
__except (EFAULT)
{
tc = (clock_t) -1;
}
__endtry
syscall_printf ("%D = times(%p)", tc, buf);
return tc;
}
@ -100,34 +104,37 @@ settimeofday (const struct timeval *tv, const struct timezone *tz)
{
SYSTEMTIME st;
struct tm *ptm;
int res;
int res = -1;
myfault efault;
if (efault.faulted (EFAULT))
return -1;
if (tv->tv_usec < 0 || tv->tv_usec >= 1000000)
__try
{
set_errno (EINVAL);
return -1;
if (tv->tv_usec < 0 || tv->tv_usec >= 1000000)
{
set_errno (EINVAL);
return -1;
}
ptm = gmtime (&tv->tv_sec);
st.wYear = ptm->tm_year + 1900;
st.wMonth = ptm->tm_mon + 1;
st.wDayOfWeek = ptm->tm_wday;
st.wDay = ptm->tm_mday;
st.wHour = ptm->tm_hour;
st.wMinute = ptm->tm_min;
st.wSecond = ptm->tm_sec;
st.wMilliseconds = tv->tv_usec / 1000;
res = -!SetSystemTime (&st);
gtod.reset ();
if (res)
set_errno (EPERM);
}
ptm = gmtime (&tv->tv_sec);
st.wYear = ptm->tm_year + 1900;
st.wMonth = ptm->tm_mon + 1;
st.wDayOfWeek = ptm->tm_wday;
st.wDay = ptm->tm_mday;
st.wHour = ptm->tm_hour;
st.wMinute = ptm->tm_min;
st.wSecond = ptm->tm_sec;
st.wMilliseconds = tv->tv_usec / 1000;
res = -!SetSystemTime (&st);
gtod.reset ();
if (res)
set_errno (EPERM);
__except (EFAULT)
{
res = -1;
}
__endtry
syscall_printf ("%R = settimeofday(%p, %p)", res, tv, tz);
return res;
}

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;
strncpy (name, login, len);
__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,74 +22,77 @@ uname (struct utsname *name)
{
SYSTEM_INFO sysinfo;
myfault efault;
if (efault.faulted (EFAULT))
return -1;
char *snp = strstr (cygwin_version.dll_build_date, "SNP");
memset (name, 0, sizeof (*name));
__small_sprintf (name->sysname, "CYGWIN_%s", wincap.osname ());
/* Add a hint to the sysname, that we're running under WOW64. This might
give an early clue if somebody encounters problems. */
if (wincap.is_wow64 ())
strncat (name->sysname, "-WOW64",
sizeof name->sysname - strlen (name->sysname) - 1);
GetSystemInfo (&sysinfo);
/* Computer name */
cygwin_gethostname (name->nodename, sizeof (name->nodename) - 1);
/* Cygwin dll release */
__small_sprintf (name->release, "%d.%d.%d%s(%d.%d/%d/%d)",
cygwin_version.dll_major / 1000,
cygwin_version.dll_major % 1000,
cygwin_version.dll_minor,
snp ? "s" : "",
cygwin_version.api_major,
cygwin_version.api_minor,
cygwin_version.shared_data,
cygwin_version.mount_registry);
/* Cygwin "version" aka build date */
strcpy (name->version, cygwin_version.dll_build_date);
if (snp)
name->version[snp - cygwin_version.dll_build_date] = '\0';
/* CPU type */
switch (sysinfo.wProcessorArchitecture)
__try
{
case PROCESSOR_ARCHITECTURE_INTEL:
unsigned int ptype;
if (sysinfo.wProcessorLevel < 3) /* Shouldn't happen. */
ptype = 3;
else if (sysinfo.wProcessorLevel > 9) /* P4 */
ptype = 6;
else
ptype = sysinfo.wProcessorLevel;
__small_sprintf (name->machine, "i%d86", ptype);
break;
case PROCESSOR_ARCHITECTURE_IA64:
strcpy (name->machine, "ia64");
break;
case PROCESSOR_ARCHITECTURE_AMD64:
strcpy (name->machine, "x86_64");
break;
case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64:
strcpy (name->machine, "ia32-win64");
break;
case PROCESSOR_ARCHITECTURE_ALPHA:
strcpy (name->machine, "alpha");
break;
case PROCESSOR_ARCHITECTURE_MIPS:
strcpy (name->machine, "mips");
break;
default:
strcpy (name->machine, "unknown");
break;
}
char *snp = strstr (cygwin_version.dll_build_date, "SNP");
memset (name, 0, sizeof (*name));
__small_sprintf (name->sysname, "CYGWIN_%s", wincap.osname ());
/* Add a hint to the sysname, that we're running under WOW64. This might
give an early clue if somebody encounters problems. */
if (wincap.is_wow64 ())
strncat (name->sysname, "-WOW64",
sizeof name->sysname - strlen (name->sysname) - 1);
GetSystemInfo (&sysinfo);
/* Computer name */
cygwin_gethostname (name->nodename, sizeof (name->nodename) - 1);
/* Cygwin dll release */
__small_sprintf (name->release, "%d.%d.%d%s(%d.%d/%d/%d)",
cygwin_version.dll_major / 1000,
cygwin_version.dll_major % 1000,
cygwin_version.dll_minor,
snp ? "s" : "",
cygwin_version.api_major,
cygwin_version.api_minor,
cygwin_version.shared_data,
cygwin_version.mount_registry);
/* Cygwin "version" aka build date */
strcpy (name->version, cygwin_version.dll_build_date);
if (snp)
name->version[snp - cygwin_version.dll_build_date] = '\0';
/* CPU type */
switch (sysinfo.wProcessorArchitecture)
{
case PROCESSOR_ARCHITECTURE_INTEL:
unsigned int ptype;
if (sysinfo.wProcessorLevel < 3) /* Shouldn't happen. */
ptype = 3;
else if (sysinfo.wProcessorLevel > 9) /* P4 */
ptype = 6;
else
ptype = sysinfo.wProcessorLevel;
__small_sprintf (name->machine, "i%d86", ptype);
break;
case PROCESSOR_ARCHITECTURE_IA64:
strcpy (name->machine, "ia64");
break;
case PROCESSOR_ARCHITECTURE_AMD64:
strcpy (name->machine, "x86_64");
break;
case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64:
strcpy (name->machine, "ia32-win64");
break;
case PROCESSOR_ARCHITECTURE_ALPHA:
strcpy (name->machine, "alpha");
break;
case PROCESSOR_ARCHITECTURE_MIPS:
strcpy (name->machine, "mips");
break;
default:
strcpy (name->machine, "unknown");
break;
}
}
__except (EFAULT)
{
return -1;
}
__endtry
return 0;
}