diff options
Diffstat (limited to 'winsup/cygwin')
58 files changed, 1107 insertions, 359 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index e6b69ccd2..aa9886833 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,232 @@ +2012-10-16 Corinna Vinschen <corinna@vinschen.de> + + * fhandler_floppy.cc (fhandler_dev_floppy::lseek): Remove lloffset. + Use offset directly. Add shortcut for lseek(fd, 0, SEEK_CUR) case. + (fhandler_dev_floppy::ioctl): Drop wrong RDSETBLK case. + * fhandler_raw.cc (fhandler_dev_raw::ioctl): Revamp RDSETBLK code. + +2012-10-15 Christopher Faylor <me.cygwin2012@cgf.cx> + + * fhandler_tty.cc (fhandler_pty_slave::write): Fix potential exit from + loop with write mutex held. Delete redundant mutex release. Clear tty + error once we've grabbed it. + +2012-10-15 Corinna Vinschen <corinna@vinschen.de> + + * fhandler_raw.cc (fhandler_dev_raw::fhandler_dev_raw): Drop gratuitous + initializing from previous patch. + +2012-10-15 Corinna Vinschen <corinna@vinschen.de> + + * fhandler_floppy.cc (fhandler_dev_floppy::open): Fix comment. + +2012-10-15 Christopher Faylor <me.cygwin2012@cgf.cx> + + * fhandler_tty.cc (fhandler_pty_slave::write): DWORD -> BOOL. + +2012-10-13 Corinna Vinschen <corinna@vinschen.de> + + * fhandler.h (class fhandler_dev_raw): Add members devbufalloc and + devbufalign. + (class fhandler_dev_floppy): Remove member bytes_per_sector; + * fhandler_floppy.cc (bytes_per_sector): Define as devbufalign. + (fhandler_dev_floppy::open): Set devbufalign to a multiple of the + sector size and handle devbuf allocation and alignment in !O_DIRECT + case here. Change comment accordingly. + Call FSCTL_ALLOW_EXTENDED_DASD_IO for partitions as well. + (fhandler_dev_floppy::raw_write): Fix comment. Rewrite and fix + writing behaviour when application uses read and lseek. + (fhandler_dev_floppy::lseek): Use rounddown macro. Call + SetFilePointerEx rather than the old SetFilePointer. + (fhandler_dev_floppy::ioctl): Reformat switch. Call + IOCTL_DISK_UPDATE_PROPERTIES rather than IOCTL_DISK_UPDATE_DRIVE_SIZE + in BLKRRPART case. Support BLKIOMIN, BLKIOOPT, BLKPBSZGET and + BLKALIGNOFF. + * fhandler_raw.cc (fhandler_dev_raw::fhandler_dev_raw): Initialize + all devbuf-related members. + (fhandler_dev_raw::~fhandler_dev_raw): Delete devbufalloc rather than + devbuf. + (fhandler_dev_raw::open): Drop allocating devbuf. + (fhandler_dev_raw::dup): Allocate devbufalloc and set devbuf to support + new sector-aligned devbuf handling. + (fhandler_dev_raw::fixup_after_exec): Ditto. + * fhandler_tape.cc (fhandler_dev_tape::open): Ditto, set devbufalign + to 1. + * include/cygwin/fs.h (BLKIOMIN): Define. + (BLKIOOPT): Define. + (BLKALIGNOFF): Define. + (BLKPBSZGET): Define. + +2012-10-12 Corinna Vinschen <corinna@vinschen.de> + + * fhandler_raw.cc (fhandler_dev_raw::open): Allow O_EXCL flag, as on + Linux. + +2012-10-11 Christopher Faylor <me.cygwin2012@cgf.cx> + + * fhandler_termios.cc (fhandler_termios::line_edit): Don't manipulate + output_mutex on CTRL-S/CTRL-Q to avoid a deadlock. + * fhandler_tty.cc (fhandler_pty_slave::write): Loop when output_stopped + is detected before acquiring output_mutex. Acquire output_mutex in the + loop for each write. + * tty.h: Remove some obsolete defines. + (tty_min::output_stopped): Make 'bool'. + +2012-10-10 Corinna Vinschen <corinna@vinschen.de> + + * include/cygwin/in.h (struct in_addr): Guard with s_addr to avoid + potential collision with Win32 headers. + +2012-10-09 Christopher Faylor <me.cygwin2012@cgf.cx> + + * child_info.h (child_info_spawn::has_execed): Remove unneeded + synchronization. + +2012-10-09 Christopher Faylor <me.cygwin2012@cgf.cx> + + * pinfo.cc: Remove unneeded assert.h. + +2012-09-17 Christopher Faylor <me.cygwin2012@cgf.cx> + + * pinfo.cc (pinfo::init): Detect potential race where short block has + been retrieved but PID_EXECED flag is not set. + +2012-09-13 Christopher Faylor <me.cygwin2012@cgf.cx> + + * cygthread.cc (cygthread::stub): Remove old, unnecessary, FIXMEd code. + * spawn.cc (child_info_spawn::worker): Avoid calling close_all_files() + twice. + +2012-09-02 Jin-woo Ye <jojelino@gmail.com> + Corinna Vinschen <corinna@vinschen.de> + + * pseudo-reloc.cc (auto_protect_for): New function. + (__write_memory): Call auto_protect_for to handle page protection. + (do_pseudo_reloc): Call auto_protect_for to restore old page protection. + +2012-08-26 Christopher Faylor <me.cygwin2012@cgf.cx> + + * pinfo.cc (pinfo::init): Remove assertion. + +2012-08-23 Christopher Faylor <me.cygwin2012@cgf.cx> + + * pinfo.cc (_pinfo::exists): Don't consider a process with no state to + exist. + +2012-08-21 Christopher Faylor <me.cygwin2012@cgf.cx> + + * net.cc (get_adapters_addresses): Drop FIXME part of comment. + +2012-08-17 Christopher Faylor <me.cygwin2012@cgf.cx> + + * DevNotes: Add entry cgf-000016. + * cygtls.h (_cygtls::push): Inline. + (_cygtls::interrupt_now): Change signal number argument to siginfo_t + argument. + (_cygtls::interrupt_setup): Ditto. + (_cygtls::set_siginfo): Delete declaration. + (_cygtls::reset_signal_arrived): Don't reset signal_arrived signal. + Just reset flag. + * exceptions.cc (_cygtls::interrupt_now): Reflect argument changes. + Pass si to interrupt_setup. + (_cygtls::interrupt_setup): Reflect argument changes. Fill out tls + infodata here using passed-in si. Use si.si_signo instead of sig. + (sigpacket::setup_handler): Move this function into sigpacket class. + Use si field from the class as appropriate. + (sigpacket::process): Don't call tls->set_siginfo here since + setup_handler could fail. Eliminate now-unneeded sig argument. + * sigproc.h (sigpacket::setup_handler): Move setup_handler to this + class. + +2012-08-17 Christopher Faylor <me.cygwin2012@cgf.cx> + + * exceptions.cc (sig_handle_tty_stop): Clear tls sig field. + (sigpacket::process): When continuing, set tls->sig before arming + signal_arrived. + +2012-08-17 Thomas Wolff <towo@towo.net> + + * fhandler_clipboard.cc (fhandler_dev_clipboard::read): Use + read-ahead buffer for reading Windows clipboard if caller's + buffer is too small for complete characters. + * include/limits.h: Remove outdated TODO comment. + +2012-08-16 Christopher Faylor <me.cygwin2012@cgf.cx> + + * cygtls.cc (_cygtls::operator HANDLE): Reverse '?' test stupidity. + +2012-08-16 Christopher Faylor <me.cygwin2012@cgf.cx> + + * cygheap.cc (init_cygheap::find_tls): Don't consider unitialized + threads. + * cygtls.cc (_cygtls::operator HANDLE): Return NULL when tid is not + set. + * exceptions.cc (setup_handler): Don't try to suspend a thread if it + has no handle. + +2012-08-15 Christopher Faylor <me.cygwin2012@cgf.cx> + + Rename cancelable_wait -> cygwait throughout. + * DevNotes: Add entry cgf-000015. + * cygwait.h (cygwait): Don't allow an optional PLARGE_INTEGER + argument. + +2012-08-15 Christopher Faylor <me.cygwin2012@cgf.cx> + + * cygtls.h (_cygtls::create_signal_arrived): New function. + (_cygtls::set_signal_arrived): Lock creation of signal_arrived. + * cygwait.cc (cancelable_wait): Ignore signal_arrived event if _my_tls + 'sig' element does not exist. + * exceptions.cc (_cygtls::interrupt_setup): Create signal_arrived if + recipient thread has not created it. + +2012-08-15 Christopher Faylor <me.cygwin2012@cgf.cx> + + * gendef: Tighten up whitespace detection. + +2012-08-15 Christopher Faylor <me.cygwin2012@cgf.cx> + + * gendef: Delete unneeded read from <IN> which ate an arbitrary line + from cygwin.din. + +2012-08-15 Christopher Faylor <me.cygwin2012@cgf.cx> + + * exceptions.cc (sigdelayed): Move declaration to sigproc.h. + * sigproc.h (sigdelayed): Make symbol globally available. + * gendef (sigdelayed): Specifically zero incyg and stacklock. + * signal.cc (sigwaitinfo): Lock _my_tls and try harder to clean up + signal information. + +2012-08-15 Christopher Faylor <me.cygwin2012@cgf.cx> + + * pinfo.cc (_pinfo::exists): Don't consider an execed process to exist. + +2012-08-14 Corinna Vinschen <corinna@vinschen.de> + + * gmon.c (_mcleanup): Fix scope bug when using gmon_out array. + +2012-08-14 Christopher Faylor <me.cygwin2012@cgf.cx> + + * errno.cc (errmap): Keep sorted. + +2012-08-14 Corinna Vinschen <corinna@vinschen.de> + + * thread.cc (semaphore::_fixup_after_fork): Fix Win32 error output in + api_fatal call. + +2012-08-14 Christopher Faylor <me.cygwin2012@cgf.cx> + + * errno.cc (errmap): Keep sorted. + +2012-08-14 Corinna Vinschen <corinna@vinschen.de> + + * mount.cc (fs_names): Add missing ReFS entry. Change comment. + * mount.h (enum fs_info_type): Add comment. + +2012-08-13 Christopher Faylor <me.cygwin2012@cgf.cx> + + * errno.cc (errmap): Map ERROR_SXS_CANT_GEN_ACTCTX to ELIBBAD. + 2012-08-09 Christopher Faylor <me.cygwin2012@cgf.cx> * DevNotes: Add entry cgf-000014. diff --git a/winsup/cygwin/DevNotes b/winsup/cygwin/DevNotes index 68d8320cd..aeca33076 100644 --- a/winsup/cygwin/DevNotes +++ b/winsup/cygwin/DevNotes @@ -1,3 +1,33 @@ +2012-08-17 cgf-000016 + +While debugging another problem I finally noticed that +sigpacket::process was unconditionally calling tls->set_siginfo prior to +calling setup_handler even though setup_handler could fail. In the +event of two successive signals, that would cause the second signal's +info to overwrite the first even though the signal handler for the first +would eventually be called. Doh. + +Fixing this required passing the sigpacket si field into setup_handler. +Making setup_handler part of the sigpacket class seemed to make a lot of +sense so that's what I did. Then I passed the si element into +interrupt_setup so that the infodata structure could be filled out prior +to arming the signal. + +The other changes checked in here eliminate the ResetEvent for +signal_arrived since previous changes to cygwait should handle the +case of spurious signal_arrived detection. Since signal_arrived is +not a manual-reset event, we really should just let the appropriate +WFMO handle it. Otherwise, there is a race where a signal comes in +a "split second" after WFMO responds to some other event. Resetting +the signal_arrived would cause any subsequent WFMO to never be +triggered. My current theory is that this is what is causing: + +http://cygwin.com/ml/cygwin/2012-08/msg00310.html + +2012-08-15 cgf-000015 + +RIP cancelable_wait. Yay. + 2012-08-09 cgf-000014 So, apparently I got it somewhat right before wrt signal handling. diff --git a/winsup/cygwin/child_info.h b/winsup/cygwin/child_info.h index eac40c247..13f6d6991 100644 --- a/winsup/cygwin/child_info.h +++ b/winsup/cygwin/child_info.h @@ -172,8 +172,6 @@ public: return true; if (type != _CH_EXEC) return false; - lock->acquire (); - lock->release (); return !!hExeced; } bool get_parent_handle (); diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc index 639f4e662..6c37cb510 100644 --- a/winsup/cygwin/cygheap.cc +++ b/winsup/cygwin/cygheap.cc @@ -628,14 +628,16 @@ init_cygheap::find_tls (int sig) { threadlist_ix = -1; while (++threadlist_ix < (int) nthreads) - if (sigismember (&(threadlist[threadlist_ix]->sigwait_mask), sig)) + if (threadlist[threadlist_ix]->tid + && sigismember (&(threadlist[threadlist_ix]->sigwait_mask), sig)) { t = cygheap->threadlist[threadlist_ix]; goto out; } threadlist_ix = -1; while (++threadlist_ix < (int) nthreads) - if (!sigismember (&(threadlist[threadlist_ix]->sigmask), sig)) + if (threadlist[threadlist_ix]->tid + && !sigismember (&(threadlist[threadlist_ix]->sigmask), sig)) { t = cygheap->threadlist[threadlist_ix]; break; diff --git a/winsup/cygwin/cygthread.cc b/winsup/cygwin/cygthread.cc index 5afc42954..2dbca06d4 100644 --- a/winsup/cygwin/cygthread.cc +++ b/winsup/cygwin/cygthread.cc @@ -90,12 +90,6 @@ cygthread::stub (VOID *arg) #endif else { - if (exiting) - { - info->inuse = false; // FIXME: Do we need this? - return 0; - } - info->callfunc (false); HANDLE notify = info->notify_detached; diff --git a/winsup/cygwin/cygtls.cc b/winsup/cygwin/cygtls.cc index abda77c5f..2ff22ed98 100644 --- a/winsup/cygwin/cygtls.cc +++ b/winsup/cygwin/cygtls.cc @@ -61,7 +61,7 @@ _cygtls::call2 (DWORD (*func) (void *, void *), void *arg, void *buf) /* Optional BLODA detection. The idea is that the function address is supposed to be within Cygwin itself. This is also true for pthreads, - since pthreads are always calling thread_wrapper in miscfuncs.cc. + since pthreads are always calling thread_wrapper in miscfuncs.cc. Therefore, every function call to a function outside of the Cygwin DLL is potentially a thread injected into the Cygwin process by some BLODA. @@ -196,15 +196,3 @@ _cygtls::remove (DWORD wait) cygheap->remove_tls (this, wait); remove_wq (wait); } - -void -_cygtls::push (__stack_t addr) -{ - *stackptr++ = (__stack_t) addr; -} - -void -_cygtls::set_siginfo (sigpacket *pack) -{ - infodata = pack->si; -} diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h index d683cf837..4f4f17c6b 100644 --- a/winsup/cygwin/cygtls.h +++ b/winsup/cygwin/cygtls.h @@ -207,17 +207,16 @@ public: void init_thread (void *, DWORD (*) (void *, void *)); static void call (DWORD (*) (void *, void *), void *); void remove (DWORD); - void push (__stack_t) __attribute__ ((regparm (2))); + void push (__stack_t addr) {*stackptr++ = (__stack_t) addr;} __stack_t pop () __attribute__ ((regparm (1))); __stack_t retaddr () {return stackptr[-1];} bool isinitialized () const { return initialized == CYGTLS_INITIALIZED; } - bool interrupt_now (CONTEXT *, int, void *, struct sigaction&) + bool interrupt_now (CONTEXT *, siginfo_t&, void *, struct sigaction&) __attribute__((regparm(3))); - void __stdcall interrupt_setup (int sig, void *handler, - struct sigaction& siga) + void __stdcall interrupt_setup (siginfo_t&, void *, struct sigaction&) __attribute__((regparm(3))); bool inside_kernel (CONTEXT *); @@ -226,15 +225,18 @@ public: void signal_debugger (int) __attribute__ ((regparm(2))); #ifdef CYGTLS_HANDLE - operator HANDLE () const {return tid->win32_obj_id;} + operator HANDLE () const {return tid ? tid->win32_obj_id : NULL;} #endif - void set_siginfo (struct sigpacket *) __attribute__ ((regparm (3))); int call_signal_handler () __attribute__ ((regparm (1))); void remove_wq (DWORD) __attribute__ ((regparm (1))); void fixup_after_fork () __attribute__ ((regparm (1))); void lock () __attribute__ ((regparm (1))); void unlock () __attribute__ ((regparm (1))); bool locked () __attribute__ ((regparm (1))); + void create_signal_arrived () + { + signal_arrived = CreateEvent (&sec_none_nih, false, false, NULL); + } void set_signal_arrived (bool setit, HANDLE& h) { if (!setit) @@ -242,17 +244,16 @@ public: else { if (!signal_arrived) - signal_arrived = CreateEvent (&sec_none_nih, false, false, NULL); + { + lock (); + create_signal_arrived (); + unlock (); + } h = signal_arrived; signal_waiting = true; } } - void reset_signal_arrived () - { - if (signal_arrived) - ResetEvent (signal_arrived); - signal_waiting = false; - } + void reset_signal_arrived () { signal_waiting = false; } private: void call2 (DWORD (*) (void *, void *), void *, void *) __attribute__ ((regparm (3))); /*gentls_offsets*/ diff --git a/winsup/cygwin/cygwait.cc b/winsup/cygwin/cygwait.cc index ee7a705ef..b0476660c 100644 --- a/winsup/cygwin/cygwait.cc +++ b/winsup/cygwin/cygwait.cc @@ -24,7 +24,7 @@ LARGE_INTEGER cw_nowait_storage; DWORD -cancelable_wait (HANDLE object, PLARGE_INTEGER timeout, unsigned mask) +cygwait (HANDLE object, PLARGE_INTEGER timeout, unsigned mask) { DWORD res; DWORD num = 0; @@ -79,10 +79,18 @@ cancelable_wait (HANDLE object, PLARGE_INTEGER timeout, unsigned mask) res = WAIT_TIMEOUT; else if (res != sig_n) /* all set */; - else if (is_cw_sig_eintr) - res = WAIT_SIGNALED; /* caller will deal with signals */ - else if (_my_tls.call_signal_handler ()) - continue; + else + { + _my_tls.lock (); + int sig = _my_tls.sig; + _my_tls.unlock (); + if (!sig) + continue; + if (is_cw_sig_eintr) + res = WAIT_SIGNALED; /* caller will deal with signals */ + else if (_my_tls.call_signal_handler ()) + continue; + } break; } diff --git a/winsup/cygwin/cygwait.h b/winsup/cygwin/cygwait.h index d52a145ae..7c1e59c00 100644 --- a/winsup/cygwin/cygwait.h +++ b/winsup/cygwin/cygwait.h @@ -28,12 +28,12 @@ extern LARGE_INTEGER cw_nowait_storage; const unsigned cw_std_mask = cw_cancel | cw_cancel_self | cw_sig; -DWORD cancelable_wait (HANDLE, PLARGE_INTEGER timeout = NULL, +DWORD cygwait (HANDLE, PLARGE_INTEGER timeout, unsigned = cw_std_mask) __attribute__ ((regparm (3))); extern inline DWORD __attribute__ ((always_inline)) -cancelable_wait (HANDLE h, DWORD howlong, unsigned mask) +cygwait (HANDLE h, DWORD howlong, unsigned mask) { LARGE_INTEGER li_howlong; PLARGE_INTEGER pli_howlong; @@ -44,13 +44,13 @@ cancelable_wait (HANDLE h, DWORD howlong, unsigned mask) li_howlong.QuadPart = -(10000ULL * howlong); pli_howlong = &li_howlong; } - return cancelable_wait (h, pli_howlong, mask); + return cygwait (h, pli_howlong, mask); } static inline DWORD __attribute__ ((always_inline)) cygwait (HANDLE h, DWORD howlong = INFINITE) { - return cancelable_wait (h, howlong, cw_cancel | cw_sig); + return cygwait (h, howlong, cw_cancel | cw_sig); } static inline DWORD __attribute__ ((always_inline)) diff --git a/winsup/cygwin/dll_init.cc b/winsup/cygwin/dll_init.cc index 420f0d8f2..bd6e74a73 100644 --- a/winsup/cygwin/dll_init.cc +++ b/winsup/cygwin/dll_init.cc @@ -132,10 +132,10 @@ dll::init () following fix: Check if the path is preceeded by a long pathname prefix, and, if so, drop it forthwith so that subsequent full path comparisons work as expected. - + At least that was the original idea. In fact there are two case, linked and runtime loaded DLLs, which have to be distinguished: - + - Linked DLLs are loaded by only specifying the basename of the DLL and searching it using the system DLL search order as given in the aforementioned MSDN URL. diff --git a/winsup/cygwin/errno.cc b/winsup/cygwin/errno.cc index 44d9dc1bc..e71863d87 100644 --- a/winsup/cygwin/errno.cc +++ b/winsup/cygwin/errno.cc @@ -140,6 +140,7 @@ static NO_COPY struct X (PIPE_LISTENING, ECOMM), X (PIPE_NOT_CONNECTED, ECOMM), X (POSSIBLE_DEADLOCK, EDEADLOCK), + X (PRIVILEGE_NOT_HELD, EPERM), X (PROCESS_ABORTED, EFAULT), X (PROC_NOT_FOUND, ESRCH), X (REM_NOT_LIST, ENONET), @@ -150,13 +151,13 @@ static NO_COPY struct X (SHARING_VIOLATION, EBUSY), X (SIGNAL_PENDING, EBUSY), X (SIGNAL_REFUSED, EIO), + X (SXS_CANT_GEN_ACTCTX, ELIBBAD), X (THREAD_1_INACTIVE, EINVAL), X (TOO_MANY_LINKS, EMLINK), X (TOO_MANY_OPEN_FILES, EMFILE), X (WAIT_NO_CHILDREN, ECHILD), X (WORKING_SET_QUOTA, EAGAIN), X (WRITE_PROTECT, EROFS), - X (PRIVILEGE_NOT_HELD, EPERM), { 0, NULL, 0} }; diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 649574fc2..aa3032816 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -37,8 +37,6 @@ details. */ char debugger_command[2 * NT_MAX_PATH + 20]; -extern "C" void sigdelayed (); - static BOOL WINAPI ctrl_c_handler (DWORD); /* This is set to indicate that we have already exited. */ @@ -710,7 +708,7 @@ handle_sigsuspend (sigset_t tempmask) sigproc_printf ("oldmask %p, newmask %p", oldmask, tempmask); pthread_testcancel (); - cancelable_wait (NULL, cw_infinite, cw_cancel | cw_cancel_self | cw_sig_eintr); + cygwait (NULL, cw_infinite, cw_cancel | cw_cancel_self | cw_sig_eintr); set_sig_errno (EINTR); // Per POSIX @@ -741,10 +739,11 @@ sig_handle_tty_stop (int sig) sigproc_printf ("process %d stopped by signal %d", myself->pid, sig); /* FIXME! This does nothing to suspend anything other than the main thread. */ - DWORD res = cancelable_wait (NULL, cw_infinite, cw_sig_eintr); + DWORD res = cygwait (NULL, cw_infinite, cw_sig_eintr); switch (res) { case WAIT_SIGNALED: + _my_tls.sig = 0; myself->stopsig = SIGCONT; myself->alert_parent (SIGCONT); break; @@ -758,7 +757,7 @@ sig_handle_tty_stop (int sig) } /* end extern "C" */ bool -_cygtls::interrupt_now (CONTEXT *cx, int sig, void *handler, +_cygtls::interrupt_now (CONTEXT *cx, siginfo_t& si, void *handler, struct sigaction& siga) { bool interrupted; @@ -772,7 +771,7 @@ _cygtls::interrupt_now (CONTEXT *cx, int sig, void *handler, else { push ((__stack_t) cx->Eip); - interrupt_setup (sig, handler, siga); + interrupt_setup (si, handler, siga); cx->Eip = pop (); SetThreadContext (*this, cx); /* Restart the thread in a new location */ interrupted = true; @@ -781,7 +780,7 @@ _cygtls::interrupt_now (CONTEXT *cx, int sig, void *handler, } void __stdcall -_cygtls::interrupt_setup (int sig, void *handler, struct sigaction& siga) +_cygtls::interrupt_setup (siginfo_t& si, void *handler, struct sigaction& siga) { push ((__stack_t) sigdelayed); deltamask = siga.sa_mask & ~SIG_NONMASKABLE; @@ -796,13 +795,18 @@ _cygtls::interrupt_setup (int sig, void *handler, struct sigaction& siga) myself->process_state |= PID_STOPPED; } - this->sig = sig; // Should always be last thing set to avoid a race + infodata = si; + this->sig = si.si_signo; // Should always be last thing set to avoid a race - if (incyg && signal_arrived) - SetEvent (signal_arrived); + if (incyg) + { + if (!signal_arrived) + create_signal_arrived (); + SetEvent (signal_arrived); + } proc_subproc (PROC_CLEARWAIT, 1); - sigproc_printf ("armed signal_arrived %p, signal %d", signal_arrived, sig); + sigproc_printf ("armed signal_arrived %p, signal %d", signal_arrived, si.si_signo); } extern "C" void __stdcall @@ -812,10 +816,8 @@ set_sig_errno (int e) _my_tls.saved_errno = e; } -static int setup_handler (int, void *, struct sigaction&, _cygtls *tls) - __attribute__((regparm(3))); -static int -setup_handler (int sig, void *handler, struct sigaction& siga, _cygtls *tls) +int +sigpacket::setup_handler (void *handler, struct sigaction& siga, _cygtls *tls) { CONTEXT cx; bool interrupted = false; @@ -823,7 +825,7 @@ setup_handler (int sig, void *handler, struct sigaction& siga, _cygtls *tls) if (tls->sig) { sigproc_printf ("trying to send signal %d but signal %d already armed", - sig, tls->sig); + si.si_signo, tls->sig); goto out; } @@ -836,7 +838,7 @@ setup_handler (int sig, void *handler, struct sigaction& siga, _cygtls *tls) { sigproc_printf ("controlled interrupt. stackptr %p, stack %p, stackptr[-1] %p", tls->stackptr, tls->stack, tls->stackptr[-1]); - tls->interrupt_setup (sig, handler, siga); + tls->interrupt_setup (si, handler, siga); interrupted = true; tls->unlock (); goto out; @@ -844,30 +846,34 @@ setup_handler (int sig, void *handler, struct sigaction& siga, _cygtls *tls) DWORD res; HANDLE hth = (HANDLE) *tls; - - /* Suspend the thread which will receive the signal. - If one of these conditions is not true we loop. - If the thread is already suspended (which can occur when a program - has called SuspendThread on itself) then just queue the signal. */ - - sigproc_printf ("suspending thread, tls %p, _main_tls %p", tls, _main_tls); - res = SuspendThread (hth); - /* Just set pending if thread is already suspended */ - if (res) + if (!hth) + sigproc_printf ("thread handle NULL, not set up yet?"); + else { + /* Suspend the thread which will receive the signal. + If one of these conditions is not true we loop. + If the thread is already suspended (which can occur when a program + has called SuspendThread on itself) then just queue the signal. */ + + sigproc_printf ("suspending thread, tls %p, _main_tls %p", tls, _main_tls); + res = SuspendThread (hth); + /* Just set pending if thread is already suspended */ + if (res) + { + ResumeThread (hth); + goto out; + } + cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER; + if (!GetThreadContext (hth, &cx)) + sigproc_printf ("couldn't get context of thread, %E"); + else + interrupted = tls->interrupt_now (&cx, si, handler, siga); + + tls->unlock (); ResumeThread (hth); - goto out; + if (interrupted) + goto out; } - cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER; - if (!GetThreadContext (hth, &cx)) - sigproc_printf ("couldn't get context of thread, %E"); - else - interrupted = tls->interrupt_now (&cx, sig, handler, siga); - - tls->unlock (); - ResumeThread (hth); - if (interrupted) - goto out; sigproc_printf ("couldn't interrupt. trying again."); yield (); @@ -878,7 +884,7 @@ setup_handler (int sig, void *handler, struct sigaction& siga, _cygtls *tls) } out: - sigproc_printf ("signal %d %sdelivered", sig, interrupted ? "" : "not "); + sigproc_printf ("signal %d %sdelivered", si.si_signo, interrupted ? "" : "not "); return interrupted; } @@ -1227,16 +1233,18 @@ dosig: rc = -1; /* No signals delivered if stopped */ else { - tls->set_siginfo (this); /* Dispatch to the appropriate function. */ sigproc_printf ("signal %d, signal handler %p", si.si_signo, handler); - rc = setup_handler (si.si_signo, handler, thissig, tls); + rc = setup_handler (handler, thissig, tls); continue_now = false; } done: if (continue_now) - SetEvent (tls->signal_arrived); + { + tls->sig = SIGCONT; + SetEvent (tls->signal_arrived); + } sigproc_printf ("returning %d", rc); return rc; diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index 55a73b66e..b84263db5 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -1222,7 +1222,7 @@ fhandler_base_overlapped::close () else { /* Cancelling seems to be necessary for cases where a reader is - still executing when a signal handler performs a close. */ + still executing when a signal handler performs a close. */ if (!writer) CancelIo (get_io_handle ()); destroy_overlapped (); diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 39e1e7573..e2db959e5 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -183,7 +183,7 @@ class fhandler_base public: long inc_refcnt () {return InterlockedIncrement (&_refcnt);} - long dec_refcnt () {return InterlockedDecrement (&_refcnt);} + long dec_refcnt () {return InterlockedDecrement (&_refcnt);} class fhandler_base *archetype; int usecount; @@ -798,7 +798,9 @@ class fhandler_mailslot : public fhandler_base_overlapped class fhandler_dev_raw: public fhandler_base { protected: + char *devbufalloc; char *devbuf; + size_t devbufalign; size_t devbufsiz; size_t devbufstart; size_t devbufend; @@ -856,7 +858,6 @@ class fhandler_dev_floppy: public fhandler_dev_raw { private: _off64_t drive_size; - unsigned long bytes_per_sector; part_t *partitions; struct status_flags { diff --git a/winsup/cygwin/fhandler_clipboard.cc b/winsup/cygwin/fhandler_clipboard.cc index 86f126c24..ad802953c 100644 --- a/winsup/cygwin/fhandler_clipboard.cc +++ b/winsup/cygwin/fhandler_clipboard.cc @@ -222,6 +222,7 @@ fhandler_dev_clipboard::read (void *ptr, size_t& len) UINT formatlist[2]; int format; LPVOID cb_data; + int rach; if (!OpenClipboard (NULL)) { @@ -243,12 +244,24 @@ fhandler_dev_clipboard::read (void *ptr, size_t& len) cygcb_t *clipbuf = (cygcb_t *) cb_data; if (pos < clipbuf->len) - { + { ret = ((len > (clipbuf->len - pos)) ? (clipbuf->len - pos) : len); memcpy (ptr, clipbuf->data + pos , ret); pos += ret; } } + else if ((rach = get_readahead ()) >= 0) + { + /* Deliver from read-ahead buffer. */ + char * out_ptr = (char *) ptr; + * out_ptr++ = rach; + ret = 1; + while (ret < len && (rach = get_readahead ()) >= 0) + { + * out_ptr++ = rach; + ret++; + } + } else { wchar_t *buf = (wchar_t *) cb_data; @@ -256,25 +269,54 @@ fhandler_dev_clipboard::read (void *ptr, size_t& len) size_t glen = GlobalSize (hglb) / sizeof (WCHAR) - 1; if (pos < glen) { + /* If caller's buffer is too small to hold at least one + max-size character, redirect algorithm to local + read-ahead buffer, finally fill class read-ahead buffer + with result and feed caller from there. */ + char *conv_ptr = (char *) ptr; + size_t conv_len = len; +#define cprabuf_len MB_LEN_MAX /* max MB_CUR_MAX of all encodings */ + char cprabuf [cprabuf_len]; + if (len < cprabuf_len) + { + conv_ptr = cprabuf; + conv_len = cprabuf_len; + } + /* Comparing apples and oranges here, but the below loop could become extremly slow otherwise. We rather return a few bytes less than possible instead of being even more slow than usual... */ - if (glen > pos + len) - glen = pos + len; + if (glen > pos + conv_len) + glen = pos + conv_len; /* This loop is necessary because the number of bytes returned by sys_wcstombs does not indicate the number of wide chars used for it, so we could potentially drop wide chars. */ while ((ret = sys_wcstombs (NULL, 0, buf + pos, glen - pos)) != (size_t) -1 - && ret > len) + && (ret > conv_len + /* Skip separated high surrogate: */ + || ((buf [pos + glen - 1] & 0xFC00) == 0xD800 && glen - pos > 1))) --glen; if (ret == (size_t) -1) ret = 0; else { - ret = sys_wcstombs ((char *) ptr, (size_t) -1, + ret = sys_wcstombs ((char *) conv_ptr, (size_t) -1, buf + pos, glen - pos); pos = glen; + /* If using read-ahead buffer, copy to class read-ahead buffer + and deliver first byte. */ + if (conv_ptr == cprabuf) + { + puts_readahead (cprabuf, ret); + char *out_ptr = (char *) ptr; + ret = 0; + while (ret < len && (rach = get_readahead ()) >= 0) + { + * out_ptr++ = rach; + ret++; + } + } } } } diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc index 0dcd1262b..faedd8ab4 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -591,7 +591,7 @@ fhandler_console::read (void *pv, size_t& buflen) if (dev_state.ext_mouse_mode6 /* distinguish release */ && mouse_event.dwButtonState < dev_state.dwLastButtonState) - mode6_term = 'm'; + mode6_term = 'm'; dev_state.last_button_code = b; @@ -646,7 +646,7 @@ fhandler_console::read (void *pv, size_t& buflen) __small_sprintf (tmp, "\033[M%c", b + ' '); nread = 4; - /* the neat nested encoding function of mintty + /* the neat nested encoding function of mintty does not compile in g++, so let's unfold it: */ if (xcode < 0x80) tmp [nread++] = xcode; @@ -692,9 +692,9 @@ fhandler_console::read (void *pv, size_t& buflen) if (dev_state.use_focus) { if (input_rec.Event.FocusEvent.bSetFocus) - __small_sprintf (tmp, "\033[I"); + __small_sprintf (tmp, "\033[I"); else - __small_sprintf (tmp, "\033[O"); + __small_sprintf (tmp, "\033[O"); toadd = tmp; nread = 3; diff --git a/winsup/cygwin/fhandler_floppy.cc b/winsup/cygwin/fhandler_floppy.cc index 0caca96e8..eaa7f6a2e 100644 --- a/winsup/cygwin/fhandler_floppy.cc +++ b/winsup/cygwin/fhandler_floppy.cc @@ -28,6 +28,8 @@ details. */ || (err) == ERROR_SEEK \ || (err) == ERROR_SECTOR_NOT_FOUND) +#define bytes_per_sector devbufalign + /**********************************************************************/ /* fhandler_dev_floppy */ @@ -355,16 +357,6 @@ fhandler_dev_floppy::write_file (const void *buf, DWORD to_write, int fhandler_dev_floppy::open (int flags, mode_t) { - /* The correct size of the buffer would be 512 bytes, which is the atomic - size, supported by WinNT. Unfortunately, the performance is worse than - access to file system on same device! Setting buffer size to a - relatively big value increases performance by means. The new ioctl call - with 'rdevio.h' header file supports changing this value. - - As default buffer size, we're using some value which is a multiple of - the typical tar and cpio buffer sizes, Except O_DIRECT is set, in which - case we're not buffering at all. */ - devbufsiz = (flags & O_DIRECT) ? 0L : 61440L; int ret = fhandler_dev_raw::open (flags); if (ret) @@ -376,11 +368,22 @@ fhandler_dev_floppy::open (int flags, mode_t) close (); return 0; } - /* If we're trying to access a CD/DVD drive, or an entire disk, - make sure we're actually allowed to read *all* of the device. - This is actually documented in the MSDN CreateFile man page. */ + if (!(flags & O_DIRECT)) + { + /* Create sector-aligned buffer. As default buffer size, we're using + some big, sector-aligned value. Since direct blockdev IO is + usually non-buffered and non-cached, the performance without + buffering is worse than access to a file system on same device. + Whoever uses O_DIRECT has my condolences. */ + devbufsiz = MAX (16 * bytes_per_sector, 65536); + devbufalloc = new char [devbufsiz + devbufalign]; + devbuf = (char *) roundup2 ((uintptr_t) devbufalloc, devbufalign); + } + + /* If we're not trying to access a floppy disk, make sure we're actually + allowed to read *all* of the device or volume. This is actually + documented in the MSDN CreateFile man page. */ if (get_major () != DEV_FLOPPY_MAJOR - && (get_major () == DEV_CDROM_MAJOR || get_minor () % 16 == 0) && !DeviceIoControl (get_handle (), FSCTL_ALLOW_EXTENDED_DASD_IO, NULL, 0, NULL, 0, &bytes_read, NULL)) debug_printf ("DeviceIoControl (FSCTL_ALLOW_EXTENDED_DASD_IO) " @@ -562,58 +565,130 @@ fhandler_dev_floppy::raw_write (const void *ptr, size_t len) char *p = (char *) ptr; int ret; - /* Checking a previous end of media on tape */ + /* Checking a previous end of media */ if (eom_detected ()) { set_errno (ENOSPC); return -1; } - /* Invalidate buffer. */ - devbufstart = devbufend = 0; + if (!len) + return 0; - if (len > 0) + if (devbuf) { - if (!write_file (p, len, &bytes_written, &ret)) - { - if (!IS_EOM (ret)) + DWORD cplen, written; + + /* First check if we have an active read buffer. If so, try to fit in + the start of the input buffer and write out the entire result. + This also covers the situation after lseek since lseek fills the read + buffer in case we seek to an address which is not sector aligned. */ + if (devbufend && devbufstart < devbufend) + { + _off64_t current_pos = get_current_position (); + cplen = MIN (len, devbufend - devbufstart); + memcpy (devbuf + devbufstart, p, cplen); + LARGE_INTEGER off = { QuadPart:current_pos - devbufend }; + if (!SetFilePointerEx (get_handle (), off, NULL, FILE_BEGIN)) { + devbufstart = devbufend = 0; __seterrno (); return -1; } - eom_detected (true); - if (!bytes_written) + if (!write_file (devbuf, devbufend, &written, &ret)) { - set_errno (ENOSPC); - return -1; + devbufstart = devbufend = 0; + goto err; } + /* Align pointers, lengths, etc. */ + cplen = MIN (cplen, written); + devbufstart += cplen; + p += cplen; + len -= cplen; + bytes_written += cplen; + if (len) + devbufstart = devbufend = 0; } + /* As long as there's still something left in the input buffer ... */ + while (len) + { + /* Compute the length to write. The problem is that the underlying + driver may require sector aligned read/write. So we copy the data + over to devbuf, which is guaranteed to be sector aligned. */ + cplen = MIN (len, devbufsiz); + if (cplen >= bytes_per_sector) + /* If the remaining len is >= sector size, write out the maximum + possible multiple of the sector size which fits into devbuf. */ + cplen = rounddown (cplen, bytes_per_sector); + else + { + /* If len < sector size, read in the next sector, seek back, + and just copy the new data over the old one before writing. */ + LARGE_INTEGER off = { QuadPart:get_current_position () }; + if (!read_file (devbuf, bytes_per_sector, &written, &ret)) + goto err; + if (!SetFilePointerEx (get_handle (), off, NULL, FILE_BEGIN)) + { + __seterrno (); + return -1; + } + } + memcpy (devbuf, p, cplen); + if (!write_file (devbuf, MAX (cplen, bytes_per_sector), &written, + &ret)) + { + bytes_written += MIN (cplen, written); + goto err; + } + cplen = MIN (cplen, written); + p += cplen; + len -= cplen; + bytes_written += cplen; + } + return bytes_written; } - return bytes_written; + + /* In O_DIRECT case, just write. */ + if (write_file (p, len, &bytes_written, &ret)) + return bytes_written; + +err: + if (IS_EOM (ret)) + { + eom_detected (true); + if (!bytes_written) + set_errno (ENOSPC); + } + else if (!bytes_written) + __seterrno (); + return bytes_written ?: -1; } _off64_t fhandler_dev_floppy::lseek (_off64_t offset, int whence) { char buf[bytes_per_sector]; - _off64_t lloffset = offset; _off64_t current_pos = (_off64_t) -1; LARGE_INTEGER sector_aligned_offset; size_t bytes_left; if (whence == SEEK_END) { - lloffset += drive_size; + offset += drive_size; whence = SEEK_SET; } else if (whence == SEEK_CUR) { current_pos = get_current_position (); - lloffset += current_pos - (devbufend - devbufstart); + _off64_t exact_pos = current_pos - (devbufend - devbufstart); + /* Shortcut when used to get current position. */ + if (offset == 0) + return exact_pos; + offset += exact_pos; whence = SEEK_SET; } - if (whence != SEEK_SET || lloffset < 0 || lloffset > drive_size) + if (whence != SEEK_SET || offset < 0 || offset > drive_size) { set_errno (EINVAL); return -1; @@ -624,27 +699,21 @@ fhandler_dev_floppy::lseek (_off64_t offset, int whence) { if (current_pos == (_off64_t) -1) current_pos = get_current_position (); - if (current_pos - devbufend <= lloffset && lloffset <= current_pos) + if (current_pos - devbufend <= offset && offset <= current_pos) { - devbufstart = devbufend - (current_pos - lloffset); - return lloffset; + devbufstart = devbufend - (current_pos - offset); + return offset; } } - sector_aligned_offset.QuadPart = (lloffset / bytes_per_sector) - * bytes_per_sector; - bytes_left = lloffset - sector_aligned_offset.QuadPart; + sector_aligned_offset.QuadPart = rounddown (offset, bytes_per_sector); + bytes_left = offset - sector_aligned_offset.QuadPart; /* Invalidate buffer. */ devbufstart = devbufend = 0; - sector_aligned_offset.LowPart = - SetFilePointer (get_handle (), - sector_aligned_offset.LowPart, - §or_aligned_offset.HighPart, - FILE_BEGIN); - if (sector_aligned_offset.LowPart == INVALID_SET_FILE_POINTER - && GetLastError ()) + if (!SetFilePointerEx (get_handle (), sector_aligned_offset, NULL, + FILE_BEGIN)) { __seterrno (); return -1; @@ -665,59 +734,58 @@ fhandler_dev_floppy::lseek (_off64_t offset, int whence) int fhandler_dev_floppy::ioctl (unsigned int cmd, void *buf) { - DISK_GEOMETRY di; + int ret = 0; DWORD bytes_read; + switch (cmd) { case HDIO_GETGEO: - { - debug_printf ("HDIO_GETGEO"); - return get_drive_info ((struct hd_geometry *) buf); - } + debug_printf ("HDIO_GETGEO"); + ret = get_drive_info ((struct hd_geometry *) buf); + break; case BLKGETSIZE: case BLKGETSIZE64: - { - debug_printf ("BLKGETSIZE"); - if (cmd == BLKGETSIZE) - *(long *)buf = drive_size >> 9UL; - else - *(_off64_t *)buf = drive_size; - return 0; - } + debug_printf ("BLKGETSIZE"); + if (cmd == BLKGETSIZE) + *(long *)buf = drive_size >> 9UL; + else + *(_off64_t *)buf = drive_size; + break; case BLKRRPART: - { - debug_printf ("BLKRRPART"); - if (!DeviceIoControl (get_handle (), - IOCTL_DISK_UPDATE_DRIVE_SIZE, - NULL, 0, - &di, sizeof (di), - &bytes_read, NULL)) - { - __seterrno (); - return -1; - } - get_drive_info (NULL); - return 0; - } - case BLKSSZGET: - { - debug_printf ("BLKSSZGET"); - *(int *)buf = bytes_per_sector; - return 0; - } - case RDSETBLK: - /* Just check the restriction that blocksize must be a multiple - of the sector size of the underlying volume sector size, - then fall through to fhandler_dev_raw::ioctl. */ - if (((struct rdop *) buf)->rd_parm % bytes_per_sector) + debug_printf ("BLKRRPART"); + if (!DeviceIoControl (get_handle (), IOCTL_DISK_UPDATE_PROPERTIES, + NULL, 0, NULL, 0, &bytes_read, NULL)) { - SetLastError (ERROR_INVALID_PARAMETER); __seterrno (); - return -1; + ret = -1; } - /*FALLTHRU*/ + else + get_drive_info (NULL); + break; + case BLKSSZGET: + debug_printf ("BLKSSZGET"); + *(int *)buf = bytes_per_sector; + break; + case BLKIOMIN: + debug_printf ("BLKIOMIN"); + *(int *)buf = bytes_per_sector; + break; + case BLKIOOPT: + debug_printf ("BLKIOOPT"); + *(int *)buf = bytes_per_sector; + break; + case BLKPBSZGET: + debug_printf ("BLKPBSZGET"); + *(int *)buf = bytes_per_sector; + break; + case BLKALIGNOFF: + debug_printf ("BLKALIGNOFF"); + *(int *)buf = 0; + break; default: - return fhandler_dev_raw::ioctl (cmd, buf); + ret = fhandler_dev_raw::ioctl (cmd, buf); + break; } + return ret; } diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc index 42beef0e2..8fe2b16df 100644 --- a/winsup/cygwin/fhandler_process.cc +++ b/winsup/cygwin/fhandler_process.cc @@ -1205,7 +1205,7 @@ format_process_mountstuff (void *data, char *&destbuf, bool mountinfo) { WCHAR drive[3] = { mnt->mnt_fsname[0], L':', L'\0' }; disk_type dt = get_disk_type (drive); - + if (dt == DT_SHARE_SMB || dt == DT_SHARE_NFS) continue; } diff --git a/winsup/cygwin/fhandler_raw.cc b/winsup/cygwin/fhandler_raw.cc index 3419be375..cb8829559 100644 --- a/winsup/cygwin/fhandler_raw.cc +++ b/winsup/cygwin/fhandler_raw.cc @@ -1,7 +1,7 @@ /* fhandler_raw.cc. See fhandler.h for a description of the fhandler classes. - Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2011 - Red Hat, Inc. + Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2011, + 2012 Red Hat, Inc. This file is part of Cygwin. @@ -11,8 +11,10 @@ #include "winsup.h" +#include <unistd.h> #include <cygwin/rdevio.h> #include <sys/mtio.h> +#include <sys/param.h> #include "cygerrno.h" #include "path.h" #include "fhandler.h" @@ -21,7 +23,8 @@ /* fhandler_dev_raw */ fhandler_dev_raw::fhandler_dev_raw () - : fhandler_base (), status () + : fhandler_base (), + status () { need_fork_fixup (true); } @@ -29,7 +32,7 @@ fhandler_dev_raw::fhandler_dev_raw () fhandler_dev_raw::~fhandler_dev_raw () { if (devbufsiz > 1L) - delete [] devbuf; + delete [] devbufalloc; } int __stdcall @@ -59,7 +62,7 @@ int fhandler_dev_raw::open (int flags, mode_t) { /* Check for illegal flags. */ - if (get_major () != DEV_TAPE_MAJOR && (flags & (O_APPEND | O_EXCL))) + if (get_major () != DEV_TAPE_MAJOR && (flags & O_APPEND)) { set_errno (EINVAL); return 0; @@ -74,8 +77,6 @@ fhandler_dev_raw::open (int flags, mode_t) flags = ((flags & ~O_WRONLY) | O_RDWR); int res = fhandler_base::open (flags, 0); - if (res && devbufsiz > 1L) - devbuf = new char [devbufsiz]; return res; } @@ -90,7 +91,12 @@ fhandler_dev_raw::dup (fhandler_base *child, int flags) fhandler_dev_raw *fhc = (fhandler_dev_raw *) child; if (devbufsiz > 1L) - fhc->devbuf = new char [devbufsiz]; + { + /* Create sector-aligned buffer */ + fhc->devbufalloc = new char [devbufsiz + devbufalign]; + fhc->devbuf = (char *) roundup2 ((uintptr_t) fhc->devbufalloc, + devbufalign); + } fhc->devbufstart = 0; fhc->devbufend = 0; fhc->lastblk_to_read (false); @@ -112,7 +118,11 @@ fhandler_dev_raw::fixup_after_exec () if (!close_on_exec ()) { if (devbufsiz > 1L) - devbuf = new char [devbufsiz]; + { + /* Create sector-aligned buffer */ + devbufalloc = new char [devbufsiz + devbufalign]; + devbuf = (char *) roundup2 ((uintptr_t) devbufalloc, devbufalign); + } devbufstart = 0; devbufend = 0; lastblk_to_read (false); @@ -142,36 +152,32 @@ fhandler_dev_raw::ioctl (unsigned int cmd, void *buf) mop.mt_count = op->rd_parm; ret = ioctl (MTIOCTOP, &mop); } - else if ((devbuf && ((op->rd_parm <= 1 && (devbufend - devbufstart)) - || op->rd_parm < devbufend - devbufstart)) - || (op->rd_parm > 1 && (op->rd_parm % 512)) + else if ((op->rd_parm <= 1 && get_major () != DEV_TAPE_MAJOR) + || (op->rd_parm > 1 && (op->rd_parm % devbufalign)) || (get_flags () & O_DIRECT)) - /* The conditions for a *valid* parameter are these: - - If there's still data in the current buffer, it must - fit in the new buffer. - - The new size is either 0 or 1, both indicating unbufferd - I/O, or the new buffersize must be a multiple of 512. + /* The conditions for a valid parameter are: + - The new size is either 0 or 1, both indicating unbuffered + I/O, and the device is a tape device. + - Or, the new buffersize must be a multiple of the + required buffer alignment. - In the O_DIRECT case, the whole request is invalid. */ ret = ERROR_INVALID_PARAMETER; else if (!devbuf || op->rd_parm != devbufsiz) { char *buf = NULL; + _off64_t curpos = lseek (0, SEEK_CUR); + if (op->rd_parm > 1L) - buf = new char [op->rd_parm]; - if (buf && devbufsiz > 1L) - { - memcpy (buf, devbuf + devbufstart, devbufend - devbufstart); - devbufend -= devbufstart; - } - else - devbufend = 0; + buf = new char [op->rd_parm + devbufalign]; if (devbufsiz > 1L) - delete [] devbuf; + delete [] devbufalloc; - devbufstart = 0; - devbuf = buf; + devbufalloc = buf; + devbuf = (char *) roundup2 ((uintptr_t) buf, devbufalign); devbufsiz = op->rd_parm ?: 1L; + devbufstart = devbufend = 0; + lseek (curpos, SEEK_SET); } break; default: diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc index a11c7efbe..b2816278f 100644 --- a/winsup/cygwin/fhandler_socket.cc +++ b/winsup/cygwin/fhandler_socket.cc @@ -125,7 +125,7 @@ get_inet_addr (const struct sockaddr *in, int inlen, some greedy Win32 application. Therefore we should never wait endlessly without checking for signals and thread cancel event. */ pthread_testcancel (); - if (cancelable_wait (NULL, cw_nowait, cw_sig_eintr) == WAIT_SIGNALED + if (cygwait (NULL, cw_nowait, cw_sig_eintr) == WAIT_SIGNALED && !_my_tls.call_signal_handler ()) { set_errno (EINTR); diff --git a/winsup/cygwin/fhandler_tape.cc b/winsup/cygwin/fhandler_tape.cc index 855fd5dfd..67d6f5c8d 100644 --- a/winsup/cygwin/fhandler_tape.cc +++ b/winsup/cygwin/fhandler_tape.cc @@ -1150,7 +1150,7 @@ fhandler_dev_tape::_lock (bool cancelable) /* O_NONBLOCK is only valid in a read or write call. Only those are cancelable. */ DWORD timeout = cancelable && is_nonblocking () ? 0 : INFINITE; - switch (cancelable_wait (mt_mtx, timeout, cw_sig | cw_cancel | cw_cancel_self)) + switch (cygwait (mt_mtx, timeout, cw_sig | cw_cancel | cw_cancel_self)) { case WAIT_OBJECT_0: return true; @@ -1214,9 +1214,9 @@ fhandler_dev_tape::open (int flags, mode_t) if (!(flags & O_DIRECT)) { devbufsiz = mt.drive (driveno ())->dp ()->MaximumBlockSize; - devbuf = new char [devbufsiz]; + devbufalign = 1; + devbufalloc = devbuf = new char [devbufsiz]; } - devbufstart = devbufend = 0; } else ReleaseMutex (mt_mtx); diff --git a/winsup/cygwin/fhandler_termios.cc b/winsup/cygwin/fhandler_termios.cc index 18afacf1d..956786fae 100644 --- a/winsup/cygwin/fhandler_termios.cc +++ b/winsup/cygwin/fhandler_termios.cc @@ -286,17 +286,13 @@ fhandler_termios::line_edit (const char *rptr, int nread, termios& ti) if (CCEQ (ti.c_cc[VSTOP], c)) { if (!tc ()->output_stopped) - { - tc ()->output_stopped = 1; - acquire_output_mutex (INFINITE); - } + tc ()->output_stopped = true; continue; } else if (CCEQ (ti.c_cc[VSTART], c)) { restart_output: - tc ()->output_stopped = 0; - release_output_mutex (); + tc ()->output_stopped = false; continue; } else if ((ti.c_iflag & IXANY) && tc ()->output_stopped) diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc index c5b65c5b8..6bb389f38 100644 --- a/winsup/cygwin/fhandler_tty.cc +++ b/winsup/cygwin/fhandler_tty.cc @@ -91,7 +91,7 @@ static int osi; void fhandler_pty_master::flush_to_slave () -{ +{ if (get_readahead_valid () && !(get_ttyp ()->ti.c_lflag & ICANON)) accept_input (); } @@ -281,7 +281,7 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on goto out; } pthread_testcancel (); - if (cancelable_wait (NULL, 10, cw_sig_eintr) == WAIT_SIGNALED + if (cygwait (NULL, 10, cw_sig_eintr) == WAIT_SIGNALED && !_my_tls.call_signal_handler ()) { set_errno (EINTR); @@ -645,8 +645,6 @@ fhandler_pty_slave::write (const void *ptr, size_t len) push_process_state process_state (PID_TTYOU); - acquire_output_mutex (INFINITE); - while (len) { n = MIN (OUT_BUFFER_SIZE, len); @@ -654,6 +652,10 @@ fhandler_pty_slave::write (const void *ptr, size_t len) ptr = (char *) ptr + n; len -= n; + while (tc ()->output_stopped) + cygwait (10); + acquire_output_mutex (INFINITE); + /* Previous write may have set write_error to != 0. Check it here. This is less than optimal, but the alternative slows down pty writes enormously. */ @@ -661,10 +663,14 @@ fhandler_pty_slave::write (const void *ptr, size_t len) { set_errno (get_ttyp ()->write_error); towrite = (DWORD) -1; + get_ttyp ()->write_error = 0; + release_output_mutex (); break; } - if (WriteFile (get_output_handle (), buf, n, &n, NULL) == FALSE) + BOOL res = WriteFile (get_output_handle (), buf, n, &n, NULL); + release_output_mutex (); + if (!res) { DWORD err = GetLastError (); termios_printf ("WriteFile failed, %E"); @@ -680,7 +686,6 @@ fhandler_pty_slave::write (const void *ptr, size_t len) break; } } - release_output_mutex (); return towrite; } diff --git a/winsup/cygwin/flock.cc b/winsup/cygwin/flock.cc index 4d683cfd4..0a2ff9ea2 100644 --- a/winsup/cygwin/flock.cc +++ b/winsup/cygwin/flock.cc @@ -250,7 +250,7 @@ class lockf_t uint16_t lf_type; /* Lock type: F_RDLCK, F_WRLCK */ _off64_t lf_start; /* Byte # of the start of the lock */ _off64_t lf_end; /* Byte # of the end of the lock (-1=EOF) */ - int64_t lf_id; /* Cygwin PID for POSIX locks, a unique id per + int64_t lf_id; /* Cygwin PID for POSIX locks, a unique id per file table entry for BSD flock locks. */ DWORD lf_wid; /* Win PID of the resource holding the lock */ uint16_t lf_ver; /* Version number of the lock. If a released diff --git a/winsup/cygwin/gendef b/winsup/cygwin/gendef index 5cc06f76c..1e2d117c7 100755 --- a/winsup/cygwin/gendef +++ b/winsup/cygwin/gendef @@ -1,5 +1,5 @@ #!/usr/bin/perl -# Copyright 2003, 2004, 2005, 2006, 2008, 2009, 2010 Red Hat, Inc. +# Copyright 2003, 2004, 2005, 2006, 2008, 2009, 2010, 2011, 2012 Red Hat, Inc. # # This file is part of Cygwin. # @@ -26,9 +26,8 @@ open(IN, $in) or die "$0: couldn't open \"$in\" - $!\n"; my @top = (); while (<IN>) { push(@top, cleanup $_); - last if /^\s*exports\s*$/i; + last if /^\s*exports$/i; } -my $libline = cleanup scalar(<IN>); my @in = cleanup <IN>; close(IN); @@ -38,14 +37,14 @@ my @nosigfuncs = (); my @text = (); for (@in) { chomp; - s/\sDATA$//o and do { + s/\s+DATA$//o and do { push @data, $_; next; }; if (/=/o) { if (s/\s+NOSIGFE\s*$//) { # nothing - } elsif (s/ SIGFE(_MAYBE)?$//) { + } elsif (s/\s+SIGFE(_MAYBE)?$//) { my $func = (split(' '))[2]; my $maybe = lc $1 . '_'; $sigfe{$func} = '_sigfe' . $maybe . $func; @@ -68,7 +67,7 @@ for (@in) { } for (@text) { - my ($alias, $func) = /^(\S+) = (\S+)\s*$/o; + my ($alias, $func) = /^(\S+)\s+=\s+(\S+)\s*$/o; $_ = $alias . ' = ' . $sigfe{$func} if defined($func) && $sigfe{$func}; } @@ -196,8 +195,9 @@ _sigdelayed: xorl %ebp,%ebp xchgl %ebp,-4(%eax) # get return address from signal stack xchgl %ebp,28(%esp) # store real return address -leave: decl $tls::incyg(%ebx) - decl $tls::stacklock(%ebx) # unlock +leave: xorl %eax,%eax + movl %eax,$tls::incyg(%ebx) + movl %eax,$tls::stacklock(%ebx) # unlock popl %eax popl %ebx diff --git a/winsup/cygwin/glob.cc b/winsup/cygwin/glob.cc index 4cc442eab..3b9267694 100644 --- a/winsup/cygwin/glob.cc +++ b/winsup/cygwin/glob.cc @@ -178,7 +178,7 @@ static int glob1(Char *, glob_t *, size_t *); static int glob2(Char *, Char *, Char *, Char *, glob_t *, size_t *); static int glob3(Char *, Char *, Char *, Char *, Char *, glob_t *, size_t *); static int globextend(const Char *, glob_t *, size_t *); -static const Char * +static const Char * globtilde(const Char *, Char *, size_t, glob_t *); static int globexp1(const Char *, glob_t *, size_t *); static int globexp2(const Char *, const Char *, glob_t *, int *, size_t *); @@ -399,8 +399,8 @@ globtilde(const Char *pattern, Char *patbuf, size_t patbuf_len, glob_t *pglob) if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE)) return pattern; - /* - * Copy up to the end of the string or / + /* + * Copy up to the end of the string or / */ eb = &patbuf[patbuf_len - 1]; for (p = pattern + 1, h = (char *) patbuf; diff --git a/winsup/cygwin/globals.cc b/winsup/cygwin/globals.cc index 05a3c390b..387515851 100644 --- a/winsup/cygwin/globals.cc +++ b/winsup/cygwin/globals.cc @@ -57,7 +57,7 @@ bool allow_glob = true; bool ignore_case_with_glob = false; bool dos_file_warning = true; bool allow_winsymlinks = false; -bool reset_com = false; +bool reset_com = false; bool pipe_byte = false; bool detect_bloda = false; diff --git a/winsup/cygwin/gmon.c b/winsup/cygwin/gmon.c index 13342eb7d..56f9440dd 100644 --- a/winsup/cygwin/gmon.c +++ b/winsup/cygwin/gmon.c @@ -146,6 +146,9 @@ _mcleanup() struct gmonparam *p = &_gmonparam; struct gmonhdr gmonhdr, *hdr; char *proffile; +#ifndef nope + char gmon_out[] = "gmon.out"; +#endif #ifdef DEBUG int log, len; char dbuf[200]; @@ -203,10 +206,7 @@ _mcleanup() proffile = "gmon.out"; } #else - { - char gmon_out[] = "gmon.out"; - proffile = gmon_out; - } + proffile = gmon_out; #endif fd = open(proffile , O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, 0666); diff --git a/winsup/cygwin/hookapi.cc b/winsup/cygwin/hookapi.cc index 83e9f498a..0c3494d3f 100644 --- a/winsup/cygwin/hookapi.cc +++ b/winsup/cygwin/hookapi.cc @@ -329,7 +329,7 @@ hook_or_detect_cygwin (const char *name, const void *fn, WORD& subsys, HANDLE h) return NULL; pdfirst = rva (PIMAGE_IMPORT_DESCRIPTOR, map, importRVA - offset); /* ... carefully check the required size to fit the string table into - the map as well. Allow NAME_MAX bytes for the DLL name, but don't + the map as well. Allow NAME_MAX bytes for the DLL name, but don't go beyond the remainder of the section. */ if (importRVAMaxSize - importRVASize > wincap.allocation_granularity ()) { diff --git a/winsup/cygwin/include/cygwin/fs.h b/winsup/cygwin/include/cygwin/fs.h index eb8c7e3d1..509b9c555 100644 --- a/winsup/cygwin/include/cygwin/fs.h +++ b/winsup/cygwin/include/cygwin/fs.h @@ -1,6 +1,6 @@ /* cygwin/fs.h - Copyright 2002, 2003 Red Hat Inc. + Copyright 2002, 2003, 2012 Red Hat Inc. Written by Chris January <chris@atomice.net> This file is part of Cygwin. @@ -12,9 +12,13 @@ details. */ #ifndef _CYGWIN_FS_H_ #define _CYGWIN_FS_H_ -#define BLKRRPART 0x0000125f -#define BLKGETSIZE 0x00001260 -#define BLKSSZGET 0x00001268 +#define BLKRRPART 0x0000125f +#define BLKGETSIZE 0x00001260 +#define BLKSSZGET 0x00001268 +#define BLKIOMIN 0x00001278 +#define BLKIOOPT 0x00001279 +#define BLKALIGNOFF 0x0000127a +#define BLKPBSZGET 0x0000127b #define BLKGETSIZE64 0x00041268 #endif diff --git a/winsup/cygwin/include/cygwin/in.h b/winsup/cygwin/include/cygwin/in.h index 49957293d..a64160e8f 100644 --- a/winsup/cygwin/include/cygwin/in.h +++ b/winsup/cygwin/include/cygwin/in.h @@ -112,11 +112,15 @@ enum IPPORT_USERRESERVED = 5000 }; +/* Avoid collision with Mingw64 headers. */ +#ifndef s_addr /* Internet address. */ struct in_addr { in_addr_t s_addr; }; +#define s_addr s_addr +#endif /* Request struct for IPv4 multicast socket ops */ diff --git a/winsup/cygwin/include/limits.h b/winsup/cygwin/include/limits.h index 61d6ae542..58368ed1f 100644 --- a/winsup/cygwin/include/limits.h +++ b/winsup/cygwin/include/limits.h @@ -36,8 +36,7 @@ details. */ /* Maximum length of a multibyte character. */ #ifndef MB_LEN_MAX -/* TODO: This is newlib's max value. We should probably rather define our - own _mbtowc_r and _wctomb_r functions which are only codepage dependent. */ +/* Use value from newlib. */ #define MB_LEN_MAX 8 #endif diff --git a/winsup/cygwin/miscfuncs.cc b/winsup/cygwin/miscfuncs.cc index 10bf4f7e9..5f0625447 100644 --- a/winsup/cygwin/miscfuncs.cc +++ b/winsup/cygwin/miscfuncs.cc @@ -516,33 +516,33 @@ thread_wrapper (VOID *arg) } __asm__ ("\n\ - movl %[WRAPPER_ARG], %%ebx # Load &wrapper_arg into ebx \n\ - movl (%%ebx), %%eax # Load thread func into eax \n\ - movl 4(%%ebx), %%ecx # Load thread arg into ecx \n\ - movl 8(%%ebx), %%edx # Load stackaddr into edx \n\ - movl 12(%%ebx), %%ebx # Load stackbase into ebx \n\ - subl %[CYGTLS], %%ebx # Subtract CYGTLS_PADSIZE \n\ - subl $4, %%ebx # Subtract another 4 bytes \n\ - movl %%ebx, %%esp # Set esp \n\ - xorl %%ebp, %%ebp # Set ebp to 0 \n\ - # Make gcc 3.x happy and align the stack so that it is \n\ - # 16 byte aligned right before the final call opcode. \n\ - andl $-16, %%esp # 16 byte align \n\ - addl $-12, %%esp # 12 bytes + 4 byte arg = 16 \n\ - # Now we moved to the new stack. Save thread func address\n\ - # and thread arg on new stack \n\ - pushl %%ecx # Push thread arg onto stack \n\ - pushl %%eax # Push thread func onto stack \n\ - # Now it's safe to release the OS stack. \n\ - pushl $0x8000 # dwFreeType: MEM_RELEASE \n\ - pushl $0x0 # dwSize: 0 \n\ - pushl %%edx # lpAddress: stackaddr \n\ - call _VirtualFree@12 # Shoot \n\ - # All set. We can pop the thread function address from \n\ - # the stack and call it. The thread arg is still on the \n\ - # stack in the expected spot. \n\ - popl %%eax # Pop thread_func address \n\ - call *%%eax # Call thread func \n" + movl %[WRAPPER_ARG], %%ebx # Load &wrapper_arg into ebx \n\ + movl (%%ebx), %%eax # Load thread func into eax \n\ + movl 4(%%ebx), %%ecx # Load thread arg into ecx \n\ + movl 8(%%ebx), %%edx # Load stackaddr into edx \n\ + movl 12(%%ebx), %%ebx # Load stackbase into ebx \n\ + subl %[CYGTLS], %%ebx # Subtract CYGTLS_PADSIZE \n\ + subl $4, %%ebx # Subtract another 4 bytes \n\ + movl %%ebx, %%esp # Set esp \n\ + xorl %%ebp, %%ebp # Set ebp to 0 \n\ + # Make gcc 3.x happy and align the stack so that it is \n\ + # 16 byte aligned right before the final call opcode. \n\ + andl $-16, %%esp # 16 byte align \n\ + addl $-12, %%esp # 12 bytes + 4 byte arg = 16 \n\ + # Now we moved to the new stack. Save thread func address \n\ + # and thread arg on new stack \n\ + pushl %%ecx # Push thread arg onto stack \n\ + pushl %%eax # Push thread func onto stack \n\ + # Now it's safe to release the OS stack. \n\ + pushl $0x8000 # dwFreeType: MEM_RELEASE \n\ + pushl $0x0 # dwSize: 0 \n\ + pushl %%edx # lpAddress: stackaddr \n\ + call _VirtualFree@12 # Shoot \n\ + # All set. We can pop the thread function address from \n\ + # the stack and call it. The thread arg is still on the \n\ + # stack in the expected spot. \n\ + popl %%eax # Pop thread_func address \n\ + call *%%eax # Call thread func \n" : : [WRAPPER_ARG] "r" (&wrapper_arg), [CYGTLS] "i" (CYGTLS_PADSIZE)); /* Never return from here. */ diff --git a/winsup/cygwin/mount.cc b/winsup/cygwin/mount.cc index 125f248e4..70603d7ed 100644 --- a/winsup/cygwin/mount.cc +++ b/winsup/cygwin/mount.cc @@ -97,11 +97,11 @@ win32_device_name (const char *src_path, char *win32_path, device& dev) #define SAMBA_EXTENDED_INFO_VERSION_STRING_LENGTH 28 #pragma pack(push,4) struct smb_extended_info { - DWORD samba_magic; /* Always SAMBA_EXTENDED_INFO_MAGIC */ - DWORD samba_version; /* Major/Minor/Release/Revision */ - DWORD samba_subversion; /* Prerelease/RC/Vendor patch */ + DWORD samba_magic; /* Always SAMBA_EXTENDED_INFO_MAGIC */ + DWORD samba_version; /* Major/Minor/Release/Revision */ + DWORD samba_subversion; /* Prerelease/RC/Vendor patch */ LARGE_INTEGER samba_gitcommitdate; - char samba_version_string[SAMBA_EXTENDED_INFO_VERSION_STRING_LENGTH]; + char samba_version_string[SAMBA_EXTENDED_INFO_VERSION_STRING_LENGTH]; }; #pragma pack(pop) @@ -1572,11 +1572,13 @@ mount_info::del_item (const char *path, unsigned flags) /************************* mount_item class ****************************/ -/* Order must be identical to mount.h, enum fs_info_type. */ +/* Don't add new fs types without adding them to fs_info_type in mount.h! + Don't reorder without reordering fs_info_type in mount.h!*/ fs_names_t fs_names[] = { { "none", false }, { "vfat", true }, { "ntfs", true }, + { "refs", true }, { "smbfs", false }, { "nfs", false }, { "netapp", false }, diff --git a/winsup/cygwin/mount.h b/winsup/cygwin/mount.h index 1d3b7451b..e010c72c8 100644 --- a/winsup/cygwin/mount.h +++ b/winsup/cygwin/mount.h @@ -24,6 +24,8 @@ enum disk_type disk_type get_disk_type (LPCWSTR); +/* Don't add new fs types without adding them to fs_names in mount.cc! + Don't reorder without reordering fs_names in mount.cc! */ enum fs_info_type { none = 0, diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc index 8b91e940a..1aa6b1c36 100644 --- a/winsup/cygwin/net.cc +++ b/winsup/cygwin/net.cc @@ -15,7 +15,7 @@ details. */ #define USE_SYS_TYPES_FD_SET #define __WSA_ERR_MACROS_DEFINED /* FIXME: Collision with different declarations of if_nametoindex and - if_indextoname functions in iphlpapi.h since Vista. + if_indextoname functions in iphlpapi.h since Vista. TODO: Convert if_nametoindex to cygwin_if_nametoindex and call system functions on Vista and later. */ #define _INC_NETIOAPI @@ -1696,9 +1696,7 @@ get_adapters_addresses (PIP_ADAPTER_ADDRESSES *pa_ret, ULONG family) area. So, if we're running in a pthread with such a stack, we call GetAdaptersAddresses in a child thread with an OS-allocated stack. The OS allocates stacks bottom up, so chances are good that the new - stack will be located in the lower address area. - FIXME: The problem is fixed in W8CP, but needs testing before W8 goes - gold. */ + stack will be located in the lower address area. */ HANDLE thr = CreateThread (NULL, 0, call_gaa, ¶m, 0, NULL); if (!thr) { diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index d1a881c39..41f320af9 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -892,7 +892,7 @@ is_virtual_symlink: else if (isdev_dev (dev)) { /* If we're looking for a file below /dev, which doesn't exist, - make sure that the device type is converted to FH_FS, so that + make sure that the device type is converted to FH_FS, so that subsequent code handles the file correctly. Unless /dev itself doesn't exist on disk. In that case /dev is handled as virtual filesystem, and virtual filesystems are @@ -3704,7 +3704,7 @@ find_fast_cwd_pointer () if (movedi[0] == 0x8b && movedi[1] == 0xff) /* mov edi,edi -> W8 */ { /* Windows 8 CP 32 bit (after a Windows Update?) does not call - RtlEnterCriticalSection. For some reason the function manipulates + RtlEnterCriticalSection. For some reason the function manipulates the FastPebLock manually, kind of like RtlEnterCriticalSection has been converted to an inline function. diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index eb4923e9b..ecd0f6cce 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -21,7 +21,6 @@ details. */ #include "pinfo.h" #include "perprocess.h" #include "environ.h" -#include <assert.h> #include "ntdll.h" #include "shared_info.h" #include "cygheap.h" @@ -299,12 +298,21 @@ pinfo::init (pid_t n, DWORD flag, HANDLE h0) bool created = shloc != SH_JUSTOPEN; + /* Detect situation where a transitional memory block is being retrieved. + If the block has been allocated with PINFO_REDIR_SIZE but not yet + updated with a PID_EXECED state then we'll retry. */ + MEMORY_BASIC_INFORMATION mbi; + if (!created && procinfo->exists () + && VirtualQuery (procinfo, &mbi, sizeof (mbi)) + && mbi.RegionSize < sizeof (_pinfo)) + goto loop; + if (!created && createit && (procinfo->process_state & PID_REAPED)) { memset (procinfo, 0, sizeof (*procinfo)); created = true; /* Lie that we created this - just reuse old shared memory */ - } + } if ((procinfo->process_state & PID_REAPED) || ((procinfo->process_state & PID_INITIALIZING) && (flag & PID_NOREDIR) @@ -316,7 +324,6 @@ pinfo::init (pid_t n, DWORD flag, HANDLE h0) if (procinfo->process_state & PID_EXECED) { - assert (i == 0); pid_t realpid = procinfo->pid; debug_printf ("execed process windows pid %d, cygwin pid %d", n, realpid); if (realpid == n) @@ -488,7 +495,7 @@ _pinfo::set_ctty (fhandler_termios *fh, int flags) bool __stdcall _pinfo::exists () { - return this && !(process_state & (PID_EXITED | PID_REAPED)); + return this && process_state && !(process_state & (PID_EXITED | PID_REAPED | PID_EXECED)); } bool diff --git a/winsup/cygwin/posix_ipc.cc b/winsup/cygwin/posix_ipc.cc index d09abf190..6af0fd8ca 100644 --- a/winsup/cygwin/posix_ipc.cc +++ b/winsup/cygwin/posix_ipc.cc @@ -119,7 +119,7 @@ ipc_mutex_init (HANDLE *pmtx, const char *name) static int ipc_mutex_lock (HANDLE mtx) { - switch (cancelable_wait (mtx, cw_infinite, cw_sig_eintr | cw_cancel | cw_cancel_self)) + switch (cygwait (mtx, cw_infinite, cw_sig_eintr | cw_cancel | cw_cancel_self)) { case WAIT_OBJECT_0: case WAIT_ABANDONED_0: diff --git a/winsup/cygwin/pseudo-reloc.cc b/winsup/cygwin/pseudo-reloc.cc index 04d5d9862..df91e5889 100644 --- a/winsup/cygwin/pseudo-reloc.cc +++ b/winsup/cygwin/pseudo-reloc.cc @@ -126,6 +126,49 @@ __report_error (const char *msg, ...) #endif } +/* + * This function automatically sets addr as PAGE_EXECUTE_READWRITE + * by deciding whether VirtualQuery for the addr is actually needed. + * And it assumes that it is called in LdrpCallInitRoutine. + * Hence not thread safe. + */ +static void +auto_protect_for (void* addr) +{ + static MEMORY_BASIC_INFORMATION mbi; + static bool state = false; + static DWORD oldprot; + + if (!addr) + { + /* Restore original protection. */ + if (!(mbi.Protect & (PAGE_EXECUTE_READWRITE | PAGE_READWRITE))) + VirtualProtect (mbi.BaseAddress, mbi.RegionSize, oldprot, &oldprot); + state = false; + return; + } + if (state) + { + /* We have valid region information. Are we still within this region? + If so, just leave. */ + void *ptr = ((void*) ((ptrdiff_t) mbi.BaseAddress + mbi.RegionSize)); + if (addr >= mbi.BaseAddress && addr < ptr) + return; + /* Otherwise, restore original protection and fall through to querying + and potentially changing next region. */ + if (!(mbi.Protect & (PAGE_EXECUTE_READWRITE | PAGE_READWRITE))) + VirtualProtect (mbi.BaseAddress, mbi.RegionSize, oldprot, &oldprot); + } + else + state = true; + /* Query region and temporarily allow write access to read-only protected + memory. */ + VirtualQuery (addr, &mbi, sizeof mbi); + if (!(mbi.Protect & (PAGE_EXECUTE_READWRITE | PAGE_READWRITE))) + VirtualProtect (mbi.BaseAddress, mbi.RegionSize, + PAGE_EXECUTE_READWRITE, &oldprot); +} + /* This function temporarily marks the page containing addr * writable, before copying len bytes from *src to *addr, and * then restores the original protection settings to the page. @@ -142,27 +185,12 @@ __report_error (const char *msg, ...) static void __write_memory (void *addr, const void *src, size_t len) { - MEMORY_BASIC_INFORMATION b; - DWORD oldprot; - if (!len) return; - - if (!VirtualQuery (addr, &b, sizeof (b))) - { - __report_error (" VirtualQuery failed for %d bytes at address %p", - (int) sizeof (b), addr); - } - - /* Temporarily allow write access to read-only protected memory. */ - if (b.Protect != PAGE_EXECUTE_READWRITE && b.Protect != PAGE_READWRITE) - VirtualProtect (b.BaseAddress, b.RegionSize, PAGE_EXECUTE_READWRITE, - &oldprot); + /* Fix page protection for writing. */ + auto_protect_for (addr); /* write the data. */ memcpy (addr, src, len); - /* Restore original protection. */ - if (b.Protect != PAGE_EXECUTE_READWRITE && b.Protect != PAGE_READWRITE) - VirtualProtect (b.BaseAddress, b.RegionSize, oldprot, &oldprot); } #define RP_VERSION_V1 0 @@ -188,7 +216,7 @@ do_pseudo_reloc (void * start, void * end, void * base) * 1) With a (v2-style) version header. In this case, the * first entry in the list is a 3-DWORD structure, with * value: - * { 0, 0, RP_VERSION_V1 } + * { 0, 0, RP_VERSION_V1 } * In this case, we skip to the next entry in the list, * knowing that all elements after the head item can * be cast to runtime_pseudo_reloc_item_v1. @@ -232,6 +260,8 @@ do_pseudo_reloc (void * start, void * end, void * base) newval = (*((DWORD*) reloc_target)) + o->addend; __write_memory ((void *) reloc_target, &newval, sizeof (DWORD)); } + /* Restore original protection. */ + auto_protect_for (NULL); return; } @@ -322,7 +352,9 @@ do_pseudo_reloc (void * start, void * end, void * base) break; #endif } - } + } + /* Restore original protection. */ + auto_protect_for (NULL); } #ifdef __CYGWIN__ diff --git a/winsup/cygwin/release/1.7.10 b/winsup/cygwin/release/1.7.10 new file mode 100644 index 000000000..33a2f20dd --- /dev/null +++ b/winsup/cygwin/release/1.7.10 @@ -0,0 +1,126 @@ +What's new: +----------- + +- New getconf tool for querying confstr(3), pathconf(3), sysconf(3), and + limits.h configuration. + +- New tzset utility to generate a POSIX-compatible TZ environment + variable from the Windows timezone settings. + +- The passwd tool now allows an administrator to use the -R command for + other user accounts: passwd -R username. + +- Experimental: Change the way sockets are created so that Cygwin always + circumvents so-called "layered service providers" (LSPs) starting with + Windows Vista. + +- signal handler functions are now dispatched in threads other than the + main thread. + +- Support NcFsd filesystem. + +- clock_gettime(3) and clock_getres(3) accept per-process and per-thread + CPU-time clocks, including CLOCK_PROCESS_CPUTIME_ID and + CLOCK_THREAD_CPUTIME_ID. + +- New pthread functions: + + - Spin Locks: pthread_spin_destroy, pthread_spin_init, pthread_spin_lock, + pthread_spin_trylock, pthread_spin_unlock. + + - Stack management: pthread_attr_getstack, pthread_attr_getstackaddr, + pthread_attr_getguardsize, pthread_attr_setstack, pthread_attr_setstackaddr, + pthread_attr_setguardsize, pthread_getattr_np. + + - Clock Selection: pthread_getcpuclockid, pthread_condattr_getclock, + pthread_condattr_setclock. + + - Scheduling: pthread_setschedprio. + + - Signalling: pthread_sigqueue. + +- Add /proc/devices, /proc/misc, /proc/sysvipc, /proc/swaps. + +- Make various system functions thread cancelation points per POSIX. + +- Add ioctl FIONREAD handling for non-sockets. + +- dlopen now supports the Glibc-specific RTLD_NODELETE and RTLD_NOOPEN flags. + +- The printf and wprintf families of functions now support the %m conversion + flag. + +- Execed processes now inherit the children of their predecessor. + +- Fifos have been rewritten and should now be more reliable. + +- GNU/glibc error.h error reporting functions: error, error_at_line, + error_message_count, error_one_per_line, error_print_progname. + +- C99 <tgmath.h> type-generic macros. + +- Other new API: clock_getcpuclockid, clock_nanosleep, clock_settime, __fpurge, + get_current_dir_name, getgrouplist, getpt, ppoll, psiginfo, psignal, + ptsname_r, sys_siglist, sysinfo. + +- cygwin_conv_path_list finally supports CCP_WIN_W_TO_POSIX and + CCP_POSIX_TO_WIN_W conversions. + + +What changed: +------------- + +- Drop support for Windows NT4. + +- The CYGWIN=tty mode using pipes to communicate with the console in a pseudo + tty-like mode has been removed. Either just use the normal Windows console + as is, or use a terminal application like mintty. + +- The CYGWIN environment variable options "envcache", "strip_title", "title", + "tty", and "upcaseenv" have been removed. + +- New heap management. Drop registry setting "heap_chunk_in_mb" in favor of + a new per-executable setting in the executable file header which can be set + using the peflags tool. Drop registry setting "heap_slop_in_mb" entirely. + +- Revamp console and pseudo tty handling. Rename /dev/ttyX to /dev/consX, + /dev/ttyX to /dev/ptyX. + +- Improve fork/exec performance on 64 bit systems. + +- Improve Ctrl-C handling in console. + +- Try harder to let fork not fail if DLLs are moved in memory which should, + in some cases, minimize the need for rebaseall. + +- Try harder to send SIGHUP to children when process group leader fails. + +- Deal with Windows problem where non-blocking pipe I/O was not flushed + properly on close. + +- Attempt to regularize most syscall-related strace output. + +- Improve behavior of Cygwin when started from a 64-bit process, especially + under Windows 2003. + +- Improve multi-thread/reentrancy safety with syscalls that deal with fds. + +- dlopen can now find "cygFOO.dll", even if the caller specified "libFOO.so". + This is supposed to support applications which are no aware of Windows DLLs. + +- Make accept(2), poll(2) and shutdown(2) behave more like on Linux. + +- Raise max number of mount points from 30 to 64. + +- Output of /proc/maps is closer to what Linux prints and much more useful to + examine process VM layout. + +- /proc/loadavg now shows the number of currently running processes and the + total number of processes. + +- /proc/version now shows the username of whomever compiled the Cygwin DLL + as well as the version of GCC used when compiling. + +- Various assorted bugfixes and improvements. + +- Preliminary, no guarantee, may be broken in subtle ways, Windows 8 support. diff --git a/winsup/cygwin/release/1.7.11 b/winsup/cygwin/release/1.7.11 new file mode 100644 index 000000000..d4e0911d2 --- /dev/null +++ b/winsup/cygwin/release/1.7.11 @@ -0,0 +1,29 @@ +What's new: +----------- + +- New pldd command for listing DLLs loaded by a process. + +- New API: scandirat. + + +What changed: +------------- + +- Fixed problem where background Cygwin processes kept the windows + console window from exiting. + +- Change the way remote shares mapped to drive letters are recognized + when creating the cygdrive directory. If Windows claims the drive + is unavailable, don't show it in the cygdrive directory listing. + +- Lower the stack pressure in some Cygwin calls by reducing the buffer + space allocated on the stack. + +- Raise default stacksize of pthreads from 512K to 1 Meg. It can still + be changed using the pthread_attr_setstacksize call. + +- process.h header has been moved back from /usr/include/cygwin to + /usr/include. + +- Make <sys/wait.h> header C++ clean. + diff --git a/winsup/cygwin/release/1.7.12 b/winsup/cygwin/release/1.7.12 new file mode 100644 index 000000000..641e73062 --- /dev/null +++ b/winsup/cygwin/release/1.7.12 @@ -0,0 +1,21 @@ +What's new: +----------- + +- Cygwin now automatically populates the /dev directory with all + existing POSIX devices. + +- Add virtual /proc/PID/mountinfo file. + +- flock now additionally supports the following scenario, which requires + to propagate locks to the parent process: + + ( + flock -n 9 || exit 1 + # ... commands executed under lock ... + } 9>/var/lock/mylockfile + + Only propagation to the direct parent process is supported so far, + not to grand parents or sibling processes. + +- Add a "detect_bloda" setting for the CYGWIN environment variable to help + finding potential BLODAs. diff --git a/winsup/cygwin/release/1.7.13 b/winsup/cygwin/release/1.7.13 new file mode 100644 index 000000000..23db7b553 --- /dev/null +++ b/winsup/cygwin/release/1.7.13 @@ -0,0 +1,8 @@ +What's new: +----------- + +- mkpasswd and mkgroup now try to print an entry for the TrustedInstaller + account existing since Windows Vista/Server 2008. + +- Terminal typeahead when switching from canonical to non-canonical mode + is now properly flushed. diff --git a/winsup/cygwin/release/1.7.14 b/winsup/cygwin/release/1.7.14 new file mode 100644 index 000000000..02042c1d2 --- /dev/null +++ b/winsup/cygwin/release/1.7.14 @@ -0,0 +1,21 @@ +What's new: +----------- + +- Add mouse reporting mode 1005, 1006 and 1015 to console. + +Bug fixes: +---------- + +- Allow access of /dev/conin, /dev/conout, and /dev/console if a console + device is detected. + +- Always allow nonexistent on-disk devices to be referenced even if they + can't be open. + +- Allow inheritance of special types like /dev/clipboard or /dev/urandom + which do not have actual handles associated with them. + +- Fix inode numbers of non-device files in virtual filesystems. + +- Fix reporting large mouse coordinates in console window mouse reporting mode. + diff --git a/winsup/cygwin/release/1.7.15 b/winsup/cygwin/release/1.7.15 new file mode 100644 index 000000000..4e9e64090 --- /dev/null +++ b/winsup/cygwin/release/1.7.15 @@ -0,0 +1,29 @@ +What's new: +----------- + +- Add CYGWIN=pipe_byte option to force opening of pipes in byte mode + rather than message mode. + +Bug fixes: +---------- + +- Fix output of mkpasswd -c option in case $HOME is set at the time. + Fixes: http://cygwin.com/ml/cygwin/2012-05/msg00094.html + +- Fix problem where too much input was attempted to be read from a + pty slave. Fixes: http://cygwin.com/ml/cygwin/2012-05/msg00049.html + +- Fix problem setting parent pid to 1 when process with children execs + itself. Fixes: http://cygwin.com/ml/cygwin/2012-05/msg00009.html + +- Fix fesetround and fesetprec to allow all valid input parameters. + Fixes: http://cygwin.com/ml/cygwin/2012-05/msg00010.html + +- Avoid "WARNING: Couldn't compute FAST_CWD pointer." message on + Windows 8 Customer Preview 32 bit. + Fixes: http://cygwin.com/ml/cygwin/2012-04/msg00616.html + +- Don't make Cygwin wait for all children of a non-cygwin child program. + Fixes: http://cygwin.com/ml/cygwin/2012-05/msg00063.html, + http://cygwin.com/ml/cygwin/2012-05/msg00075.html + diff --git a/winsup/cygwin/release/1.7.16 b/winsup/cygwin/release/1.7.16 new file mode 100644 index 000000000..c955cfe44 --- /dev/null +++ b/winsup/cygwin/release/1.7.16 @@ -0,0 +1,39 @@ +What's new: +----------- + +- New API: getmntent_r, memrchr. + +- Support ReFS. + +Bug fixes: +---------- + +- Fix pipe creation problem which manifested as a problem creating a + fifo. Fixes: http://cygwin.com/ml/cygwin/2012-05/msg00253.html + +- Fix hang when calling pthread_testcancel in a canceled thread. + Fixes some of: http://cygwin.com/ml/cygwin/2012-05/msg00186.html + +- Fix invocation of strace from a cygwin process. Fixes: + http://cygwin.com/ml/cygwin/2012-05/msg00292.html + +- Fix hang when zero bytes are written to a pty using + Windows WriteFile or equivalent. Fixes: + http://cygwin.com/ml/cygwin/2012-05/msg00323.html + +- Fix recv, recvfrom, recvmsg behaviour if a 0 bytes buffer is given + as argument. Fixes: http://cygwin.com/ml/cygwin/2012-05/msg00332.html + +- Handle inode numbers returned by Samba >= 3.5.4. + Fixes: http://cygwin.com/ml/cygwin/2012-05/msg00236.html + +- Fix emacs problem which exposed an issue with Cygwin's select() function. + If a signal arrives while select is blocking and the program longjmps + out of the signal handler then threads and memory may be left hanging. + Fixes: http://cygwin.com/ml/cygwin/2012-05/threads.html#00275 + +- Fix fileno(3) to return -1/EBADF if stream is closed. + Fixes: http://cygwin.com/ml/cygwin/2012-07/msg00083.html + +- Fix clipboard handling, at least partially: + http://cygwin.com/ml/cygwin/2012-06/msg00521.html diff --git a/winsup/cygwin/release/1.7.17 b/winsup/cygwin/release/1.7.17 new file mode 100644 index 000000000..c8442ee5d --- /dev/null +++ b/winsup/cygwin/release/1.7.17 @@ -0,0 +1,43 @@ +What's new: +----------- + +- Support the "e" flag to fopen(3). This is a Glibc extension which + allows to fopen the file with the O_CLOEXEC flag set. + +- Support the "x" flag to fopen(3). This is a Glibc/C11 extension which + allows to open the file with the O_EXCL flag set. + + +Bug fixes: +---------- + +- Prevent CTRL-S hang. + Fixes: http://cygwin.com/ml/cygwin/2012-10/threads.html#00089 + +- Revamp signals so that signals-to-threads more closely mimic Linux + operation. + First step of fix for: http://cygwin.com/ml/cygwin/2012-05/msg00186.html + as well as observed Linux behavior. + +- Revert to only creating a new session leader when we know that a + console process is started in the background. + Should fix: http://cygwin.com/ml/cygwin/2012-08/threads.html#00062 + +- Fix mysterious crashes when accessing /etc. + Fixes: http://cygwin.com/ml/cygwin/2012-07/threads.html#00613 and others. + +- Fix a potential race condition starting multiple "first" Cygwin processes + concurrently. + Should fix: http://cygwin.com/ml/cygwin/2012-07/msg00531.html + +- Fix a bug in unlink/rmdir which could result in removing non-empty + directories on network drives. Also fix problems trying to rename files + under newer Samba versions. + Fixes: http://cygwin.com/ml/cygwin/2012-07/threads.html#00477 + +- Prefer to call WSARecvMsg from recvmsg if possible. + Fixes: http://cygwin.com/ml/cygwin/2012-07/msg00662.html + +- Correct hang typified by running "procps" after Cygwin has started a + Windows process. + Fixes: http://cygwin.com/ml/cygwin/2012-05/threads.html#00349 diff --git a/winsup/cygwin/sec_helper.cc b/winsup/cygwin/sec_helper.cc index 0b505a7e8..8ee979ba9 100644 --- a/winsup/cygwin/sec_helper.cc +++ b/winsup/cygwin/sec_helper.cc @@ -595,7 +595,7 @@ _recycler_sd (void *buf, bool users, bool dir) { NTSTATUS status; PISECURITY_DESCRIPTOR psd = (PISECURITY_DESCRIPTOR) buf; - + if (!psd) return NULL; RtlCreateSecurityDescriptor (psd, SECURITY_DESCRIPTOR_REVISION); @@ -614,7 +614,7 @@ _recycler_sd (void *buf, bool users, bool dir) dir ? CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE : NO_INHERITANCE, FILE_ALL_ACCESS, well_known_system_sid); - if (users) + if (users) RtlAddAccessAllowedAceEx (dacl, ACL_REVISION, NO_PROPAGATE_INHERIT_ACE, FILE_GENERIC_READ | FILE_GENERIC_EXECUTE | FILE_APPEND_DATA | FILE_WRITE_ATTRIBUTES, diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc index f3a3a3a07..333b1d461 100644 --- a/winsup/cygwin/signal.cc +++ b/winsup/cygwin/signal.cc @@ -120,7 +120,7 @@ clock_nanosleep (clockid_t clk_id, int flags, const struct timespec *rqtp, syscall_printf ("clock_nanosleep (%ld.%09ld)", rqtp->tv_sec, rqtp->tv_nsec); - int rc = cancelable_wait (NULL, &timeout, cw_sig_eintr | cw_cancel | cw_cancel_self); + int rc = cygwait (NULL, &timeout, cw_sig_eintr | cw_cancel | cw_cancel_self); if (rc == WAIT_SIGNALED) res = EINTR; @@ -580,7 +580,7 @@ sigwaitinfo (const sigset_t *set, siginfo_t *info) sig_dispatch_pending (true); int res; - switch (cancelable_wait (NULL, cw_infinite, cw_sig_eintr | cw_cancel | cw_cancel_self)) + switch (cygwait (NULL, cw_infinite, cw_sig_eintr | cw_cancel | cw_cancel_self)) { case WAIT_SIGNALED: if (!sigismember (set, _my_tls.infodata.si_signo)) @@ -590,10 +590,14 @@ sigwaitinfo (const sigset_t *set, siginfo_t *info) } else { + _my_tls.lock (); if (info) *info = _my_tls.infodata; res = _my_tls.infodata.si_signo; - InterlockedExchange ((LONG *) &_my_tls.sig, (LONG) 0); + _my_tls.sig = 0; + if (_my_tls.retaddr () == (__stack_t) sigdelayed) + _my_tls.pop (); + _my_tls.unlock (); } break; default: diff --git a/winsup/cygwin/sigproc.h b/winsup/cygwin/sigproc.h index 06ebd68d8..d442232e9 100644 --- a/winsup/cygwin/sigproc.h +++ b/winsup/cygwin/sigproc.h @@ -56,6 +56,8 @@ struct sigpacket struct sigpacket *next; }; int __stdcall process () __attribute__ ((regparm (1))); + int setup_handler (void *handler, struct sigaction& siga, _cygtls *tls) + __attribute__ ((regparm (3))); }; void __stdcall sig_dispatch_pending (bool fast = false) @@ -86,6 +88,8 @@ void __stdcall sigalloc (); int kill_pgrp (pid_t, siginfo_t&); int killsys (pid_t, int); +extern "C" void sigdelayed (); + extern char myself_nowait_dummy[]; extern struct sigaction *global_sigs; diff --git a/winsup/cygwin/smallprint.cc b/winsup/cygwin/smallprint.cc index fa7706b47..f0ce7e74b 100644 --- a/winsup/cygwin/smallprint.cc +++ b/winsup/cygwin/smallprint.cc @@ -1,7 +1,7 @@ /* smallprint.cc: small print routines for WIN32 Copyright 1996, 1998, 2000, 2001, 2002, 2003, 2005, 2006, - 2007, 2008, 2009, 2012 + 2007, 2008, 2009, 2012 Red Hat, Inc. This file is part of Cygwin. @@ -147,15 +147,15 @@ __small_vsprintf (char *dst, const char *fmt, va_list ap) continue; case 'c': { - unsigned char c = (va_arg (ap, int) & 0xff); + unsigned char c = (va_arg (ap, int) & 0xff); if (isprint (c) || pad != '0') *dst++ = c; else - { - *dst++ = '0'; - *dst++ = 'x'; - dst = __rn (dst, 16, 0, c, len, pad, LMASK); - } + { + *dst++ = '0'; + *dst++ = 'x'; + dst = __rn (dst, 16, 0, c, len, pad, LMASK); + } } break; case 'C': diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index 8a82f8a11..5d60823b3 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -465,7 +465,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, PCA service. However, a process which is controlled by PCA is part of a compatibility job, which allows child processes to break away from the job. This helps to avoid this issue. - + (*) Note that this is not mintty's fault. It has just been observed with mintty in the first place. See the archives for more info: http://cygwin.com/ml/cygwin-developers/2012-02/msg00018.html */ @@ -746,7 +746,7 @@ loop: /* Reset handle inheritance to default when the execution of a non-Cygwin process fails. Only need to do this for _P_OVERLAY since the handle will be closed otherwise. Don't need to do this for 'parent' since it will - be closed in every case. See FIXME above. */ + be closed in every case. See FIXME above. */ if (!iscygwin () && mode == _P_OVERLAY) SetHandleInformation (wr_proc_pipe, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT); if (wr_proc_pipe == my_wr_proc_pipe) @@ -867,7 +867,8 @@ loop: } else { - close_all_files (true); + if (iscygwin ()) + close_all_files (true); if (!my_wr_proc_pipe && WaitForSingleObject (pi.hProcess, 0) == WAIT_TIMEOUT) wait_for_myself (); diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 1b047aaff..43ecf3a0f 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -731,8 +731,8 @@ unlink_nt (path_conv &pc) debug_printf ("Sharing violation when opening %S", pc.get_nt_native_path ()); /* We never call try_to_bin on NFS and NetApp for the follwing reasons: - - NFS implements its own mechanism to remove in-use files, which looks + + NFS implements its own mechanism to remove in-use files, which looks quite similar to what we do in try_to_bin for remote files. Netapp filesystems don't understand the "move and delete" method diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc index aefab24cd..eacf26741 100644 --- a/winsup/cygwin/thread.cc +++ b/winsup/cygwin/thread.cc @@ -575,17 +575,17 @@ pthread::cancel () GetThreadContext (win32_obj_id, &context); /* The OS is not foolproof in terms of asynchronous thread cancellation and tends to hang infinitely if we change the instruction pointer. - So just don't cancel asynchronously if the thread is currently + So just don't cancel asynchronously if the thread is currently executing Windows code. Rely on deferred cancellation in this case. */ if (!cygtls->inside_kernel (&context)) - { - context.Eip = (DWORD) pthread::static_cancel_self; - SetThreadContext (win32_obj_id, &context); - } + { + context.Eip = (DWORD) pthread::static_cancel_self; + SetThreadContext (win32_obj_id, &context); + } } mutex.unlock (); /* See above. For instance, a thread which waits for a semaphore in sem_wait - will call cancelable_wait which in turn calls WFMO. While this WFMO call + will call cygwait which in turn calls WFMO. While this WFMO call is cancelable by setting the thread's cancel_event object, the OS apparently refuses to set the thread's context and continues to wait for the WFMO conditions. This is *not* reflected in the return value of @@ -1228,7 +1228,7 @@ pthread_cond::wait (pthread_mutex_t mutex, PLARGE_INTEGER timeout) ++mutex->condwaits; mutex->unlock (); - rv = cancelable_wait (sem_wait, timeout, cw_cancel | cw_sig_eintr); + rv = cygwait (sem_wait, timeout, cw_cancel | cw_sig_eintr); mtx_out.lock (); @@ -1744,7 +1744,7 @@ pthread_mutex::lock () || !pthread::equal (owner, self)) { /* FIXME: no cancel? */ - cancelable_wait (win32_obj_id, cw_infinite, cw_sig); + cygwait (win32_obj_id, cw_infinite, cw_sig); set_owner (self); } else @@ -1885,7 +1885,7 @@ pthread_spinlock::lock () LARGE_INTEGER timeout; timeout.QuadPart = -10000LL; /* FIXME: no cancel? */ - cancelable_wait (win32_obj_id, &timeout, cw_sig); + cygwait (win32_obj_id, &timeout, cw_sig); } } while (result == -1); @@ -2364,7 +2364,7 @@ pthread::join (pthread_t *thread, void **return_val) (*thread)->attr.joinable = PTHREAD_CREATE_DETACHED; (*thread)->mutex.unlock (); - switch (cancelable_wait ((*thread)->win32_obj_id, cw_infinite, cw_sig | cw_cancel)) + switch (cygwait ((*thread)->win32_obj_id, cw_infinite, cw_sig | cw_cancel)) { case WAIT_OBJECT_0: if (return_val) @@ -3476,7 +3476,7 @@ semaphore::_timedwait (const struct timespec *abstime) timeout.QuadPart = abstime->tv_sec * NSPERSEC + (abstime->tv_nsec + 99) / 100 + FACTOR; - switch (cancelable_wait (win32_obj_id, &timeout, cw_cancel | cw_cancel_self | cw_sig_eintr)) + switch (cygwait (win32_obj_id, &timeout, cw_cancel | cw_cancel_self | cw_sig_eintr)) { case WAIT_OBJECT_0: currentvalue--; @@ -3488,7 +3488,7 @@ semaphore::_timedwait (const struct timespec *abstime) set_errno (ETIMEDOUT); return -1; default: - pthread_printf ("cancelable_wait failed. %E"); + pthread_printf ("cygwait failed. %E"); __seterrno (); return -1; } @@ -3498,7 +3498,7 @@ semaphore::_timedwait (const struct timespec *abstime) int semaphore::_wait () { - switch (cancelable_wait (win32_obj_id, cw_infinite, cw_cancel | cw_cancel_self | cw_sig_eintr)) + switch (cygwait (win32_obj_id, cw_infinite, cw_cancel | cw_cancel_self | cw_sig_eintr)) { case WAIT_OBJECT_0: currentvalue--; @@ -3507,7 +3507,7 @@ semaphore::_wait () set_errno (EINTR); return -1; default: - pthread_printf ("cancelable_wait failed. %E"); + pthread_printf ("cygwait failed. %E"); break; } return 0; @@ -3523,7 +3523,7 @@ semaphore::_fixup_after_fork () this->win32_obj_id = ::CreateSemaphore (&sec_none_nih, currentvalue, LONG_MAX, NULL); if (!win32_obj_id) - api_fatal ("failed to create new win32 semaphore, error %d"); + api_fatal ("failed to create new win32 semaphore, %E"); } } diff --git a/winsup/cygwin/thread.h b/winsup/cygwin/thread.h index 141100714..07652758c 100644 --- a/winsup/cygwin/thread.h +++ b/winsup/cygwin/thread.h @@ -60,7 +60,7 @@ public: void lock () { if (InterlockedIncrement ((long *) &lock_counter) != 1) - cancelable_wait (win32_obj_id, cw_infinite, cw_sig); + cygwait (win32_obj_id, cw_infinite, cw_sig); } void unlock () diff --git a/winsup/cygwin/tty.h b/winsup/cygwin/tty.h index 4dc0395f5..65f184997 100644 --- a/winsup/cygwin/tty.h +++ b/winsup/cygwin/tty.h @@ -19,12 +19,10 @@ details. */ /* Input/Output/ioctl events */ -#define RESTART_OUTPUT_EVENT "cygtty.output.restart" #define INPUT_AVAILABLE_EVENT "cygtty.input.avail" #define OUTPUT_MUTEX "cygtty.output.mutex" #define INPUT_MUTEX "cygtty.input.mutex" #define TTY_SLAVE_ALIVE "cygtty.slave_alive" -#define TTY_MASTER_ALIVE "cygtty.master_alive" #include <sys/termios.h> @@ -38,15 +36,15 @@ class tty_min pid_t sid; /* Session ID of tty */ struct status_flags { - unsigned initialized : 1; /* Set if tty is initialized */ - unsigned rstcons : 1; /* Set if console needs to be set to "non-cooked" */ + unsigned initialized : 1; /* Set if tty is initialized */ + unsigned rstcons : 1; /* Set if console needs to be set to "non-cooked" */ } status; public: pid_t pgid; - int output_stopped; + bool output_stopped; /* FIXME: Maybe do this with a mutex someday? */ fh_devices ntty; - DWORD last_ctrl_c; /* tick count of last ctrl-c */ + DWORD last_ctrl_c; /* tick count of last ctrl-c */ bool is_console; IMPLEMENT_STATUS_FLAG (bool, initialized) diff --git a/winsup/cygwin/wait.cc b/winsup/cygwin/wait.cc index ae0403194..b92257154 100644 --- a/winsup/cygwin/wait.cc +++ b/winsup/cygwin/wait.cc @@ -80,9 +80,9 @@ wait4 (int intpid, int *status, int options, struct rusage *r) if ((waitfor = w->ev) == NULL) goto nochildren; - res = cancelable_wait (waitfor, cw_infinite, cw_cancel | cw_cancel_self); + res = cygwait (waitfor, cw_infinite, cw_cancel | cw_cancel_self); - sigproc_printf ("%d = cancelable_wait (...)", res); + sigproc_printf ("%d = cygwait (...)", res); if (w->ev == NULL) { |