⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 overview2.sgml

📁 cygwin, 著名的在win32下模拟unix操作系统的东东
💻 SGML
📖 第 1 页 / 共 2 页
字号:
</sect2><sect2 id="ov-hi-textvsbinary"><title>Text Mode vs. Binary Mode</title><para>Interoperability with other Win32 programs such as text editors wascritical to the success of the port of the development tools.  Most Red Hatcustomers upgrading from the older DOS-hosted toolchains expected the newWin32-hosted ones to continue to work with their old developmentsources.</para><para>Unfortunately, UNIX and Win32 use different end-of-line terminators intext files.  Consequently, carriage-return newlines have to be translated onthe fly by Cygwin into a single newline when reading in text mode.  Thecontrol-z character is interpreted as a valid end-of-file character for asimilar reason.</para><para>This solution addresses the compatibility requirement at the expense ofviolating the POSIX standard that states that text and binary mode will beidentical. Consequently, processes that attempt to lseek through text files canno longer rely on the number of bytes read as an accurate indicator of positionin the file.  For this reason, the CYGWIN environment variable can beset to override this behavior.</para></sect2><sect2 id="ov-hi-ansiclib"><title>ANSI C Library</title><para>We chose to include Red Hat's own existing ANSI C library"newlib" as part of the library, rather than write all of the lib Cand math calls from scratch.  Newlib is a BSD-derived ANSI C library,previously only used by cross-compilers for embedded systemsdevelopment.</para><para>The reuse of existing free implementations of such thingsas the glob, regexp, and getopt libraries saved us considerableeffort.  In addition, Cygwin uses Doug Lea's free mallocimplementation that successfully balances speed and compactness.  Thelibrary accesses the malloc calls via an exported function pointer.This makes it possible for a Cygwin process to provide its ownmalloc if it so desires.</para></sect2><sect2 id="ov-hi-process"><title>Process Creation</title><para>The fork call in Cygwin is particularly interesting because itdoes not map well on top of the Win32 API.  This makes it verydifficult to implement correctly.  Currently, the Cygwin fork is anon-copy-on-write implementation similar to what was present in earlyflavors of UNIX.</para><para>The first thing that happens when a parent processforks a child process is that the parent initializes a space in theCygwin process table for the child.  It then creates a suspendedchild process using the Win32 CreateProcess call.  Next, the parentprocess calls setjmp to save its own context and sets a pointer tothis in a Cygwin shared memory area (shared among all Cygwintasks).  It then fills in the child's .data and .bss sections bycopying from its own address space into the suspended child's addressspace.  After the child's address space is initialized, the child isrun while the parent waits on a mutex.  The child discovers it hasbeen forked and longjumps using the saved jump buffer.  The child thensets the mutex the parent is waiting on and blocks on another mutex.This is the signal for the parent to copy its stack and heap into thechild, after which it releases the mutex the child is waiting on andreturns from the fork call.  Finally, the child wakes from blocking onthe last mutex, recreates any memory-mapped areas passed to it via theshared area, and returns from fork itself.</para><para>While we have someideas as to how to speed up our fork implementation by reducing thenumber of context switches between the parent and child process, forkwill almost certainly always be inefficient under Win32.  Fortunately,in most circumstances the spawn family of calls provided by Cygwincan be substituted for a fork/exec pair with only a little effort.These calls map cleanly on top of the Win32 API.  As a result, theyare much more efficient.  Changing the compiler's driver program tocall spawn instead of fork was a trivial change and increasedcompilation speeds by twenty to thirty percent in ourtests.</para><para>However, spawn and exec present their own set ofdifficulties.  Because there is no way to do an actual exec underWin32, Cygwin has to invent its own Process IDs (PIDs).  As aresult, when a process performs multiple exec calls, there will bemultiple Windows PIDs associated with a single Cygwin PID.  In somecases, stubs of each of these Win32 processes may linger, waiting fortheir exec'd Cygwin process to exit.</para></sect2><sect2 id="ov-hi-signals"><title>Signals</title><para>Whena Cygwin process starts, the library starts a secondary thread foruse in signal handling.  This thread waits for Windows events used topass signals to the process.  When a process notices it has a signal,it scans its signal bitmask and handles the signal in the appropriatefashion.</para><para>Several complications in the implementation arise from thefact that the signal handler operates in the same address space as theexecuting program.  The immediate consequence is that Cygwin systemfunctions are interruptible unless special care is taken to avoidthis.   We go to some lengths to prevent the sig_send function thatsends signals from being interrupted.  In the case of a processsending a signal to another process, we place a mutex around sig_sendsuch that sig_send will not be interrupted until it has completelyfinished sending the signal.</para><para>In the case of a process sendingitself a signal, we use a separate semaphore/event pair instead of themutex.  sig_send starts by resetting the event and incrementing thesemaphore that flags the signal handler to process the signal.  Afterthe signal is processed, the signal handler signals the event that itis done.  This process keeps intraprocess signals synchronous, asrequired by POSIX.</para><para>Most standard UNIX signals are provided.  Jobcontrol works as expected in shells that supportit.</para></sect2><sect2 id="ov-hi-sockets"><title>Sockets</title><para>Socket-related calls in Cygwin simplycall the functions by the same name in Winsock, Microsoft'simplementation of Berkeley sockets.  Only a few changes were needed tomatch the expected UNIX semantics - one of the most troublesomedifferences was that Winsock must be initialized before the firstsocket function is called.  As a result, Cygwin has to perform thisinitialization when appropriate.  In order to support sockets acrossfork calls, child processes initialize Winsock if any inherited filedescriptor is a socket.</para><para>Unfortunately, implicitly loading DLLsat process startup is usually a slow affair.  Because many processesdo not use sockets, Cygwin explicitly loads the Winsock DLL thefirst time it calls the Winsock initialization routine.  This singlechange sped up GNU configure times by thirtypercent.</para></sect2><sect2 id="ov-hi-select"><title>Select</title><para>The UNIX select function is anothercall that does not map cleanly on top of the Win32 API.  Much to ourdismay, we discovered that the Win32 select in Winsock only worked onsocket handles.  Our implementation allows select to function normallywhen given different types of file descriptors (sockets, pipes,handles, and a custom /dev/windows Windows messagespseudo-device).</para><para>Upon entry into the select function, the firstoperation is to sort the file descriptors into the different types.There are then two cases to consider.  The simple case is when atleast one file descriptor is a type that is always known to be ready(such as a disk file).  In that case, select returns immediately assoon as it has polled each of the other types to see if they areready.  The more complex case involves waiting for socket or pipe filedescriptors to be ready.  This is accomplished by the main threadsuspending itself, after starting one thread for each type of filedescriptor present.  Each thread polls the file descriptors of itsrespective type with the appropriate Win32 API call.  As soon as athread identifies a ready descriptor, that thread signals the mainthread to wake up.  This case is now the same as the first one sincewe know at least one descriptor is ready.  So select returns, afterpolling all of the file descriptors one last time.</para></sect2>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -