may not end up in the pool.
(cygthread::new): Avoid race when checking for initialized. Add debugging
code.
* fhandler.cc (fhandler_base::raw_read): Add case for ERROR_INVALID_HANDLE due
to Win95 directories.
(fhandler_base::open): Handle errors due to Win95 directories.
(fhandler_base::close): Add get_nohandle () test.
(fhandler_base::set_close_on_exec): Ditto.
(fhandler_base::fork_fixup): Ditto.
(fhandler_base::lock): Change error code to Posix EINVAL.
(fhandler_base::dup): If get_nohandle (), set new value to INVALID_HANDLE_VALUE
instead of NULL.
* fhandler_disk_file.cc (fhandler_disk_file::fstat): Call fstat_by_name if
get_nohandle (). Remove extraneous element from strpbrk.
(fhandler_disk_file::open): Remove test for Win95 directory.
* fhandler_random.cc (fhandler_dev_random::open): Add set_nohandle ().
* fhandler_clipboard.cc (fhandler_dev_clipboard::open): Ditto.
* fhandler_zero.cc (fhandler_dev_zero::open): Ditto.
(fhandler_dev_zero::close): Delete.
* fhandler.h (class fhandler_dev_zero): Ditto.
+2002-09-18 Christopher Faylor <cgf@redhat.com>
+
+ * cygthread.cc (cygthread::initialized): Avoid copying on fork or some
+ threads may not end up in the pool.
+ (cygthread::new): Avoid race when checking for initialized. Add
+ debugging code.
+
+2002-09-18 Pierre Humblet <pierre.humblet@ieee.org>
+
+ * fhandler.cc (fhandler_base::raw_read): Add case for
+ ERROR_INVALID_HANDLE due to Win95 directories.
+ (fhandler_base::open): Handle errors due to Win95 directories.
+ (fhandler_base::close): Add get_nohandle () test.
+ (fhandler_base::set_close_on_exec): Ditto.
+ (fhandler_base::fork_fixup): Ditto.
+ (fhandler_base::lock): Change error code to Posix EINVAL.
+ (fhandler_base::dup): If get_nohandle (), set new value to
+ INVALID_HANDLE_VALUE instead of NULL.
+ * fhandler_disk_file.cc (fhandler_disk_file::fstat): Call fstat_by_name
+ if get_nohandle (). Remove extraneous element from strpbrk.
+ (fhandler_disk_file::open): Remove test for Win95 directory.
+
+ * fhandler_random.cc (fhandler_dev_random::open): Add set_nohandle ().
+ * fhandler_clipboard.cc (fhandler_dev_clipboard::open): Ditto.
+ * fhandler_zero.cc (fhandler_dev_zero::open): Ditto.
+ (fhandler_dev_zero::close): Delete.
+ * fhandler.h (class fhandler_dev_zero): Ditto.
+
2002-09-17 Robert Collins <rbtcollins@hotmail.com>
* thread.cc (pthread_key::set): Preserve GetLastError(). Reported
#define NTHREADS (sizeof (threads) / sizeof (threads[0]))
DWORD NO_COPY cygthread::main_thread_id;
-bool cygthread::initialized;
+bool NO_COPY cygthread::initialized;
/* Initial stub called by cygthread constructor. Performs initial
per-thread initialization and loops waiting for new thread functions
for (;;)
{
+ bool was_initialized = initialized;
/* Search the threads array for an empty slot to use */
- for (info = threads; info < threads + NTHREADS; info++)
+ for (info = threads + NTHREADS - 1; info >= threads; info--)
if ((id = (DWORD) InterlockedExchange ((LPLONG) &info->avail, 0)))
{
info->id = id;
return info;
}
- if (!initialized)
- Sleep (0); /* thread_runner is not be finished yet. */
+ if (!was_initialized)
+ Sleep (0); /* thread_runner is not finished yet. */
else
- return freerange ();
+ {
+#ifdef DEBUGGING
+ char buf[1024];
+ if (GetEnvironmentVariable ("CYGWIN_NOFREERANGE", buf, sizeof (buf)))
+ api_fatal ("Overflowed cygwin thread pool");
+#endif
+ return freerange ();
+ }
}
}
if (!strncasematch (win32_fn, DEVICE_PREFIX, DEVICE_PREFIX_LEN)
|| !QueryDosDevice (NULL, fnbuf, sizeof (fnbuf)))
return strcpy (posix_fn, win32_fn);
-
+
char *p = strchr (win32_fn + DEVICE_PREFIX_LEN, '\\');
if (!p)
p = strchr (win32_fn + DEVICE_PREFIX_LEN, '\0');
{
tl = new_tl + 100;
char *new_envblock =
- (char *) realloc (envblock, 2 + tl);
+ (char *) realloc (envblock, 2 + tl);
/* If realloc moves the block, move `s' with it. */
if (new_envblock != envblock)
- {
+ {
s += new_envblock - envblock;
envblock = new_envblock;
}
else if (supplied_bin)
bin = supplied_bin;
else
- bin = get_w_binary () || get_r_binary () || (binmode != O_TEXT) ?
- O_BINARY : O_TEXT;
+ bin = get_w_binary () || get_r_binary () || (binmode != O_TEXT)
+ ? O_BINARY : O_TEXT;
openflags = flags | bin;
return 0;
case ERROR_INVALID_FUNCTION:
case ERROR_INVALID_PARAMETER:
+ case ERROR_INVALID_HANDLE:
if (openflags & O_DIROPEN)
{
set_errno (EISDIR);
if (x == INVALID_HANDLE_VALUE)
{
- if (GetLastError () == ERROR_INVALID_HANDLE)
+ if (pc->isdir () && !wincap.can_open_directories ())
+ {
+ if (mode & (O_CREAT | O_EXCL) == (O_CREAT | O_EXCL))
+ set_errno (EEXIST);
+ else if (mode & (O_WRONLY | O_RDWR))
+ set_errno (EISDIR);
+ else
+ set_nohandle (true);
+ }
+ else if (GetLastError () == ERROR_INVALID_HANDLE)
set_errno (ENOENT);
else
__seterrno ();
- goto done;
+ if (!get_nohandle ())
+ goto done;
}
/* Attributes may be set only if a file is _really_ created.
{
tot = 0;
const struct iovec *iovptr = iov + iovcnt;
- do
+ do
{
iovptr -= 1;
tot += iovptr->iov_len;
{
tot = 0;
const struct iovec *iovptr = iov + iovcnt;
- do
+ do
{
iovptr -= 1;
tot += iovptr->iov_len;
int res = -1;
syscall_printf ("closing '%s' handle %p", get_name (), get_handle());
- if (CloseHandle (get_handle()))
+ if (get_nohandle () || CloseHandle (get_handle()))
res = 0;
else
{
int
fhandler_base::lock (int, struct flock *)
{
- set_errno (ENOSYS);
+ set_errno (EINVAL);
return -1;
}
HANDLE nh;
if (get_nohandle ())
- nh = NULL;
+ nh = INVALID_HANDLE_VALUE;
else if (!DuplicateHandle (hMainProc, get_handle(), hMainProc, &nh, 0, TRUE,
DUPLICATE_SAME_ACCESS))
{
void
fhandler_base::set_close_on_exec (int val)
{
- set_inheritance (io_handle, val);
+ if (!get_nohandle ())
+ set_inheritance (io_handle, val);
set_close_on_exec_flag (val);
debug_printf ("set close_on_exec for %s to %d", get_name (), val);
}
fhandler_base::fixup_after_fork (HANDLE parent)
{
debug_printf ("inheriting '%s' from parent", get_name ());
- fork_fixup (parent, io_handle, "io_handle");
+ if (!get_nohandle ())
+ fork_fixup (parent, io_handle, "io_handle");
}
bool
int write (const void *ptr, size_t len);
int __stdcall read (void *ptr, size_t len) __attribute__ ((regparm (3)));
__off64_t lseek (__off64_t offset, int whence);
- int close (void);
void dump ();
};
membuffer = NULL;
if (!cygnativeformat)
cygnativeformat = RegisterClipboardFormat (CYGWIN_NATIVE);
+ set_nohandle (true);
set_open_status ();
return 1;
}
SHORT y = info.dwWinSize.Y;
SHORT x = info.dwWinSize.X;
fillin_info ();
-
+
if (y != info.dwWinSize.Y || x != info.dwWinSize.X)
tc->kill_pgrp (SIGWINCH);
}
bool query_open_already;
if (get_io_handle ())
- return fstat_by_handle (buf, pc);
-
+ {
+ if (get_nohandle ())
+ return fstat_by_name (buf, pc);
+ else
+ return fstat_by_handle (buf, pc);
+ }
/* If we don't care if the file is executable or we already know if it is,
then just do a "query open" as it is apparently much faster. */
if (pc->exec_state () != dont_know_if_executable)
query_open_already = false;
if (query_open_already && strncasematch (pc->volname (), "FAT", 3)
- && !strpbrk (get_win32_name (), "?*|<>|"))
+ && !strpbrk (get_win32_name (), "?*|<>"))
oret = 0;
else if (!(oret = open (pc, open_flags, 0)))
{
}
}
- if (!oret)
+ if (!oret || get_nohandle ())
res = fstat_by_name (buf, pc);
else
{
set_has_acls (real_path->has_acls ());
set_isremote (real_path->isremote ());
- int res;
- if (!real_path->isdir () || wincap.can_open_directories ())
- res = this->fhandler_base::open (real_path, flags | O_DIROPEN, mode);
- else
- {
- set_errno (EISDIR);
- res = 0;
- }
-
+ int res = this->fhandler_base::open (real_path, flags | O_DIROPEN, mode);
if (!res)
goto out;
dir->__d_position++;
pdrive = strchr (pdrive, '\0') + 1;
syscall_printf ("%p = readdir (%p) (%s)", &dir->__d_dirent, dir,
- dir->__d_dirent->d_name);
+ dir->__d_dirent->d_name);
return dir->__d_dirent;
}
fileid = process_file_no;
if (!fill_filebuf ())
- {
+ {
res = 0;
goto out;
}
utime = put.UserTime.QuadPart * HZ / 10000000ULL;
stime = put.KernelTime.QuadPart * HZ / 10000000ULL;
if (stodi.CurrentTime.QuadPart > put.CreateTime.QuadPart)
- start_time = (spt.KernelTime.QuadPart + spt.UserTime.QuadPart -
- stodi.CurrentTime.QuadPart + put.CreateTime.QuadPart) * HZ / 10000000ULL;
+ start_time = (spt.KernelTime.QuadPart + spt.UserTime.QuadPart -
+ stodi.CurrentTime.QuadPart + put.CreateTime.QuadPart) * HZ / 10000000ULL;
else
/*
* sometimes stodi.CurrentTime is a bit behind
format_process_statm (_pinfo *p, char *destbuf, size_t maxsize)
{
unsigned long vmsize = 0UL, vmrss = 0UL, vmtext = 0UL, vmdata = 0UL,
- vmlib = 0UL, vmshare = 0UL;
+ vmlib = 0UL, vmshare = 0UL;
if (wincap.is_winnt ())
{
if (!get_mem_values (p->dwProcessId, &vmsize, &vmrss, &vmtext, &vmdata,
fhandler_dev_random::open (path_conv *, int flags, mode_t)
{
set_flags ((flags & ~O_TEXT) | O_BINARY);
+ set_nohandle (true);
set_open_status ();
return 1;
}
{
#define un_addr ((struct sockaddr_un *) name)
struct sockaddr_in sin;
- int len = sizeof sin;
+ int len = sizeof sin;
int fd;
if (strlen (un_addr->sun_path) >= UNIX_PATH_LEN)
int wait_result;
wait_result = WSAWaitForMultipleEvents (2, ev, FALSE, WSA_INFINITE,
- FALSE);
- if (wait_result == WSA_WAIT_EVENT_0)
- WSAEnumNetworkEvents (get_socket (), ev[0], &sock_event);
+ FALSE);
+ if (wait_result == WSA_WAIT_EVENT_0)
+ WSAEnumNetworkEvents (get_socket (), ev[0], &sock_event);
- /* Unset events for listening socket and
- switch back to blocking mode */
- WSAEventSelect (get_socket (), ev[0], 0);
+ /* Unset events for listening socket and
+ switch back to blocking mode */
+ WSAEventSelect (get_socket (), ev[0], 0);
unsigned long nonblocking = 0;
- ioctlsocket (get_socket (), FIONBIO, &nonblocking);
-
- switch (wait_result)
- {
- case WSA_WAIT_EVENT_0:
- if (sock_event.lNetworkEvents & FD_ACCEPT)
- {
- if (sock_event.iErrorCode[FD_ACCEPT_BIT])
- {
- WSASetLastError (sock_event.iErrorCode[FD_ACCEPT_BIT]);
- set_winsock_errno ();
- res = -1;
- goto done;
- }
- }
- /* else; : Should never happen since FD_ACCEPT is the only event
- that has been selected */
- break;
- case WSA_WAIT_EVENT_0 + 1:
- debug_printf ("signal received during accept");
- set_errno (EINTR);
- res = -1;
- goto done;
- case WSA_WAIT_FAILED:
- default: /* Should never happen */
- WSASetLastError (WSAEFAULT);
- set_winsock_errno ();
- res = -1;
- goto done;
- }
- }
+ ioctlsocket (get_socket (), FIONBIO, &nonblocking);
+
+ switch (wait_result)
+ {
+ case WSA_WAIT_EVENT_0:
+ if (sock_event.lNetworkEvents & FD_ACCEPT)
+ {
+ if (sock_event.iErrorCode[FD_ACCEPT_BIT])
+ {
+ WSASetLastError (sock_event.iErrorCode[FD_ACCEPT_BIT]);
+ set_winsock_errno ();
+ res = -1;
+ goto done;
+ }
+ }
+ /* else; : Should never happen since FD_ACCEPT is the only event
+ that has been selected */
+ break;
+ case WSA_WAIT_EVENT_0 + 1:
+ debug_printf ("signal received during accept");
+ set_errno (EINTR);
+ res = -1;
+ goto done;
+ case WSA_WAIT_FAILED:
+ default: /* Should never happen */
+ WSASetLastError (WSAEFAULT);
+ set_winsock_errno ();
+ res = -1;
+ goto done;
+ }
+ }
}
res = ::accept (get_socket (), peer, len);
{
if (!create_secret_event ())
secret_check_failed = TRUE;
- else if (in_progress)
+ else if (in_progress)
signal_secret_event ();
}
set_winsock_errno ();
else
{
- fhandler_socket* res_fh = fdsock (res_fd, get_name (), res);
- if (get_addr_family () == AF_LOCAL)
- res_fh->set_sun_path (get_sun_path ());
- res_fh->set_addr_family (get_addr_family ());
- res_fh->set_socket_type (get_socket_type ());
- res = res_fd;
+ fhandler_socket* res_fh = fdsock (res_fd, get_name (), res);
+ if (get_addr_family () == AF_LOCAL)
+ res_fh->set_sun_path (get_sun_path ());
+ res_fh->set_addr_family (get_addr_family ());
+ res_fh->set_socket_type (get_socket_type ());
+ res = res_fd;
}
}
{
tot = 0;
const struct iovec *iovptr = iov + iovcnt;
- do
+ do
{
iovptr -= 1;
tot += iovptr->iov_len;
{
set_errno (EPIPE);
if (! (flags & MSG_NOSIGNAL))
- _raise (SIGPIPE);
+ _raise (SIGPIPE);
}
return res;
{
tot = 0;
const struct iovec *iovptr = iov + iovcnt;
- do
+ do
{
iovptr -= 1;
tot += iovptr->iov_len;
* the contents of the file are updated.
*/
if (!fill_filebuf ())
- return (__off64_t) -1;
+ return (__off64_t) -1;
switch (whence)
{
case SEEK_SET:
fhandler_dev_zero::open (path_conv *, int flags, mode_t)
{
set_flags ((flags & ~O_TEXT) | O_BINARY);
+ set_nohandle (true);
set_open_status ();
return 1;
}
return 0;
}
-int
-fhandler_dev_zero::close (void)
-{
- return 0;
-}
-
void
fhandler_dev_zero::dump ()
{
{
char strbuf[100];
snprintf (linebuf, sizeof (linebuf), "%s:%s:%lu:",
- group_name,
+ group_name,
tg.string (strbuf),
*GetSidSubAuthority(tg,
- *GetSidSubAuthorityCount(tg) - 1));
+ *GetSidSubAuthorityCount(tg) - 1));
debug_printf ("Emulating /etc/group: %s", linebuf);
add_grp_line (linebuf);
group_state = emulated;
for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx)
if (sid.getfromgr (gr))
for (DWORD pg = 0; pg < groups->GroupCount; ++pg)
- if (sid == groups->Groups[pg].Sid &&
+ if (sid == groups->Groups[pg].Sid &&
sid != well_known_world_sid)
{
if (cnt < gidsetsize)
if (grouplist32 == NULL)
return -1;
for (int i = 0; i < ngroups; i++)
- grouplist32[i] = grouplist[i];
+ grouplist32[i] = grouplist[i];
}
return setgroups32 (ngroups, grouplist32);
}
else
{
res = getsockopt (fh->get_socket (), level, optname, (char *) optval,
- (int *) optlen);
+ (int *) optlen);
if (optname == SO_ERROR)
{
(unsigned) msg->msg_namelen))
|| !fh)
res = -1;
- else
+ else
{
res = check_iovec_for_write (msg->msg_iov, msg->msg_iovlen);
if (res > 0)
/* Accept a token if
- the requested usersid matches the TokenUser and
- if setgroups has been called:
- the token groups that are listed in /etc/group match the union of
+ the token groups that are listed in /etc/group match the union of
the requested primary and supplementary groups in gsids.
- else the (unknown) implicitly requested supplementary groups and those
- in the token are the groups associated with the usersid. We assume
+ in the token are the groups associated with the usersid. We assume
they match and verify only the primary groups.
The requested primary group must appear in the token.
The primary group in the token is a group associated with the usersid,
saw[pos] = TRUE;
else if (groups.pgsid == gsid)
sawpg = TRUE;
- else if (gsid != well_known_world_sid &&
+ else if (gsid != well_known_world_sid &&
gsid != usersid)
goto done;
}
for (int gidx = 0; gidx < groups.sgsids.count; gidx++)
if (!saw[gidx])
goto done;
- if (sawpg ||
+ if (sawpg ||
groups.sgsids.contains (groups.pgsid) ||
groups.pgsid == usersid)
ret = TRUE;
else
{
/* Switching user context to SYSTEM doesn't inherit the authentication
- id of the user account running current process. */
+ id of the user account running current process. */
if (usersid != well_known_system_sid)
if (!GetTokenInformation (my_token, TokenStatistics,
&stats, sizeof stats, &size))
auth_luid = stats.AuthenticationId;
/* Retrieving current processes group list to be able to inherit
- some important well known group sids. */
+ some important well known group sids. */
if (!GetTokenInformation (my_token, TokenGroups, NULL, 0, &size) &&
GetLastError () != ERROR_INSUFFICIENT_BUFFER)
debug_printf ("GetTokenInformation(my_token, TokenGroups): %E\n");
&bytes_written, FALSE, TRUE, &context))
{
/* Samba returns ERROR_NOT_SUPPORTED.
- FAT returns ERROR_INVALID_SECURITY_DESCR.
- This shouldn't return as error, but better be ignored. */
+ FAT returns ERROR_INVALID_SECURITY_DESCR.
+ This shouldn't return as error, but better be ignored. */
DWORD ret = GetLastError ();
if (ret != ERROR_NOT_SUPPORTED && ret != ERROR_INVALID_SECURITY_DESCR)
{
if (allow_ntsec)
{
int res = get_nt_object_attribute (handle, object_type, attribute,
- uidret, gidret);
+ uidret, gidret);
if (attribute && (*attribute & S_IFLNK) == S_IFLNK)
*attribute |= S_IRWXU | S_IRWXG | S_IRWXO;
return res;
static NO_COPY int nonewline = FALSE;
DWORD err = GetLastError ();
const char *tn = cygthread::name ();
- char *pn = __progname ?: myself->progname;
+ char *pn = __progname ?: (myself ? myself->progname : NULL);
int microsec = microseconds ();
lmicrosec = microsec;
/* member methods */
pthread::pthread ():verifyable_object (PTHREAD_MAGIC), win32_obj_id (0),
cancelstate (0), canceltype (0), cancel_event (0),
- joiner (NULL), cleanup_stack (NULL)
+ joiner (NULL), cleanup_stack (NULL)
{
}
if (newhomedrive && newhomedrive != homedrive)
cfree_and_set (homedrive, (newhomedrive == almost_null)
- ? almost_null : cstrdup (newhomedrive));
+ ? almost_null : cstrdup (newhomedrive));
if (newhomepath && newhomepath != homepath)
cfree_and_set (homepath, cstrdup (newhomepath));