OSDN Git Service

Initial revision
[pf3gnuchains/pf3gnuchains3x.git] / winsup / doc / overview2.sgml
1 <sect1 id="ov-ex-unix"><title>Expectations for UNIX Programmers</title>
2
3 <para>Developers coming from a UNIX background will find a set of utilities
4 they are already comfortable using, including a working UNIX shell.  The
5 compiler tools are the standard GNU compilers most people will have previously
6 used under UNIX, only ported to the Windows host.  Programmers wishing to port
7 UNIX software to Windows NT or 9x will find that the Cygwin library provides
8 an easy way to port many UNIX packages, with only minimal source code
9 changes.</para>
10 </sect1>
11
12 <sect1 id="ov-ex-win"><title>Expectations for Windows Programmers</title>
13 <para>Developers coming from a Windows background will find a set of tools capable
14 of writing console or GUI executables that rely on the Microsoft Win32 API.
15 The linker and dlltool utility may be used to write Windows Dynamically Linked
16 Libraries (DLLs).  The resource compiler "windres" is also provided with the
17 native Windows GNUPro tools.  All tools may be used from the Microsoft command
18 line prompt, with full support for normal Windows pathnames.</para>
19 </sect1>
20
21 <sect2 id="ov-hi-intro"><title>Introduction</title> <para>When a binary linked
22 against the library is executed, the Cygwin DLL is loaded into the
23 application's text segment.  Because we are trying to emulate a UNIX kernel
24 which needs access to all processes running under it, the first Cygwin DLL to
25 run creates shared memory areas that other processes using separate instances
26 of the DLL can access.  This is used to keep track of open file descriptors and
27 assist fork and exec, among other purposes.  In addition to the shared memory
28 regions, every process also has a per_process structure that contains
29 information such as process id, user id, signal masks, and other similar
30 process-specific information.</para>
31
32 <para>The DLL is implemented using the Win32 API, which allows it to run on all
33 Win32 hosts.  Because processes run under the standard Win32 subsystem, they
34 can access both the UNIX compatibility calls provided by Cygwin as well as
35 any of the Win32 API calls.  This gives the programmer complete flexibility in
36 designing the structure of their program in terms of the APIs used.  For
37 example, they could write a Win32-specific GUI using Win32 API calls on top of
38 a UNIX back-end that uses Cygwin.</para>
39
40 <para>Early on in the development process, we made the important design
41 decision that it would not be necessary to strictly adhere to existing UNIX
42 standards like POSIX.1 if it was not possible or if it would significantly
43 diminish the usability of the tools on the Win32 platform.  In many cases, an
44 environment variable can be set to override the default behavior and force
45 standards compliance.</para>
46 </sect2>
47
48 <sect2 id="ov-hi-win9xnt"><title>Supporting both Windows NT and 9x</title>
49 <para>While Windows 95 and Windows 98 are similar enough to each other that we
50 can safely ignore the distinction when implementing Cygwin, Windows NT is an
51 extremely different operating system.  For this reason, whenever the DLL is
52 loaded, the library checks which operating system is active so that it can act
53 accordingly.</para>
54
55 <para>In some cases, the Win32 API is only different for
56 historical reasons.  In this situation, the same basic functionality is
57 available under Windows 9x and NT but the method used to gain this
58 functionality differs.  A trivial example: in our implementation of
59 uname, the library examines the sysinfo.dwProcessorType structure
60 member to figure out the processor type under Windows 9x.  This field
61 is not supported in NT, which has its own operating system-specific
62 structure member called sysinfo.wProcessorLevel.</para>
63
64 <para>Other differences between NT and 9x are much more fundamental in
65 nature.  The best example is that only NT provides a security model.</para>
66 </sect2>
67
68 <sect2 id="ov-hi-perm"><title>Permissions and Security</title>
69 <para>Windows NT includes a sophisticated security model based on Access
70 Control Lists (ACLs).  Although some modern UNIX operating systems include
71 support for ACLs, Cygwin maps Win32 file ownership and permissions to the
72 more standard, older UNIX model.  The chmod call maps UNIX-style permissions
73 back to the Win32 equivalents.  Because many programs expect to be able to find
74 the /etc/passwd and /etc/group files, we provide utilities that can be used to
75 construct them from the user and group information provided by the operating
76 system.</para>
77
78 <para>Under Windows NT, the administrator is permitted to chown files.  There
79 is currently no mechanism to support the setuid concept or API call.  Although
80 we hope to support this functionality at some point in the future, in practice,
81 the programs we have ported have not needed it.</para>
82
83 <para>Under Windows 9x, the situation is considerably different.  Since a
84 security model is not provided, Cygwin fakes file ownership by making all
85 files look like they are owned by a default user and group id.  As under NT,
86 file permissions can still be determined by examining their read/write/execute
87 status.  Rather than return an unimplemented error, under Windows 9x, the
88 chown call succeeds immediately without actually performing any action
89 whatsoever.  This is appropriate since essentially all users jointly own the
90 files when no concept of file ownership exists.</para>
91
92 <para>It is important that we discuss the implications of our "kernel" using
93 shared memory areas to store information about Cygwin processes.  Because
94 these areas are not yet protected in any way, in principle a malicious user
95 could modify them to cause unexpected behavior in Cygwin processes.  While
96 this is not a new problem under Windows 9x (because of the lack of operating
97 system security), it does constitute a security hole under Windows NT.
98 This is because one user could affect the Cygwin programs run by
99 another user by changing the shared memory information in ways that
100 they could not in a more typical WinNT program.  For this reason, it
101 is not appropriate to use Cygwin in high-security applications.  In
102 practice, this will not be a major problem for most uses of the
103 library.</para>
104 </sect2>
105
106 <sect2 id="ov-hi-files"><title>File Access</title> <para>Cygwin supports
107 both Win32- and POSIX-style paths, using either forward or back slashes as the
108 directory delimiter.  Paths coming into the DLL are translated from Win32 to
109 POSIX as needed.  As a result, the library believes that the file system is a
110 POSIX-compliant one, translating paths back to Win32 paths whenever it calls a
111 Win32 API function.  UNC pathnames (starting with two slashes) are
112 supported.</para>
113
114 <para>The layout of this POSIX view of the Windows file system space is stored
115 in the Windows registry.  While the slash ('/') directory points to the system
116 partition by default, this is easy to change with the Cygwin mount utility.
117 In addition to selecting the slash partition, it allows mounting arbitrary
118 Win32 paths into the POSIX file system space.  Many people use the utility to
119 mount each drive letter under the slash partition (e.g. C:\ to /c, D:\ to /d,
120 etc...).</para>
121
122 <para>The library exports several Cygwin-specific functions that can be used
123 by external programs to convert a path or path list from Win32 to POSIX or vice
124 versa.  Shell scripts and Makefiles cannot call these functions directly.
125 Instead, they can do the same path translations by executing the cygpath
126 utility program that we provide with Cygwin.</para>
127
128 <para>Win32 file systems are case preserving but case insensitive.  Cygwin
129 does not currently support case distinction because, in practice, few UNIX
130 programs actually rely on it.  While we could mangle file names to support case
131 distinction, this would add unnecessary overhead to the library and make it
132 more difficult for non-Cygwin applications to access those files.</para>
133
134 <para>Symbolic links are emulated by files containing a magic cookie followed
135 by the path to which the link points.  They are marked with the System
136 attribute so that only files with that attribute have to be read to determine
137 whether or not the file is a symbolic link.  Hard links are fully supported
138 under Windows NT on NTFS file systems.  On a FAT file system, the call falls
139 back to simply copying the file, a strategy that works in many cases.</para>
140
141 <para>The inode number for a file is calculated by hashing its full Win32 path.
142 The inode number generated by the stat call always matches the one returned in
143 d_ino of the dirent structure.  It is worth noting that the number produced by
144 this method is not guaranteed to be unique.  However, we have not found this to
145 be a significant problem because of the low probability of generating a
146 duplicate inode number.</para>
147 </sect2>
148
149 <sect2 id="ov-hi-textvsbinary"><title>Text Mode vs. Binary Mode</title>
150 <para>Interoperability with other Win32 programs such as text editors was
151 critical to the success of the port of the development tools.  Most Cygnus
152 customers upgrading from the older DOS-hosted toolchains expected the new
153 Win32-hosted ones to continue to work with their old development
154 sources.</para>
155
156 <para>Unfortunately, UNIX and Win32 use different end-of-line terminators in
157 text files.  Consequently, carriage-return newlines have to be translated on
158 the fly by Cygwin into a single newline when reading in text mode.  The
159 control-z character is interpreted as a valid end-of-file character for a
160 similar reason.</para>
161
162 <para>This solution addresses the compatibility requirement at the expense of
163 violating the POSIX standard that states that text and binary mode will be
164 identical. Consequently, processes that attempt to lseek through text files can
165 no longer rely on the number of bytes read as an accurate indicator of position
166 in the file.  For this reason, the CYGWIN environment variable can be
167 set to override this behavior.</para>
168 </sect2>
169
170 <sect2 id="ov-hi-ansiclib"><title>ANSI C Library</title>
171 <para>We chose to include
172 Cygnus' own existing ANSI C library
173 "newlib" as part of the library, rather than write all of the lib C
174 and math calls from scratch.  Newlib is a BSD-derived ANSI C library,
175 previously only used by cross-compilers for embedded systems
176 development.</para>
177
178 <para>The reuse of existing free implementations of such things
179 as the glob, regexp, and getopt libraries saved us considerable
180 effort.  In addition, Cygwin uses Doug Lea's free malloc
181 implementation that successfully balances speed and compactness.  The
182 library accesses the malloc calls via an exported function pointer.
183 This makes it possible for a Cygwin process to provide its own
184 malloc if it so desires.</para>
185 </sect2>
186
187 <sect2 id="ov-hi-process"><title>Process Creation</title>
188 <para>The fork call in Cygwin is particularly interesting because it
189 does not map well on top of the Win32 API.  This makes it very
190 difficult to implement correctly.  Currently, the Cygwin fork is a
191 non-copy-on-write implementation similar to what was present in early
192 flavors of UNIX.</para>
193
194 <para>The first thing that happens when a parent process
195 forks a child process is that the parent initializes a space in the
196 Cygwin process table for the child.  It then creates a suspended
197 child process using the Win32 CreateProcess call.  Next, the parent
198 process calls setjmp to save its own context and sets a pointer to
199 this in a Cygwin shared memory area (shared among all Cygwin
200 tasks).  It then fills in the child's .data and .bss sections by
201 copying from its own address space into the suspended child's address
202 space.  After the child's address space is initialized, the child is
203 run while the parent waits on a mutex.  The child discovers it has
204 been forked and longjumps using the saved jump buffer.  The child then
205 sets the mutex the parent is waiting on and blocks on another mutex.
206 This is the signal for the parent to copy its stack and heap into the
207 child, after which it releases the mutex the child is waiting on and
208 returns from the fork call.  Finally, the child wakes from blocking on
209 the last mutex, recreates any memory-mapped areas passed to it via the
210 shared area, and returns from fork itself.</para>
211
212 <para>While we have some
213 ideas as to how to speed up our fork implementation by reducing the
214 number of context switches between the parent and child process, fork
215 will almost certainly always be inefficient under Win32.  Fortunately,
216 in most circumstances the spawn family of calls provided by Cygwin
217 can be substituted for a fork/exec pair with only a little effort.
218 These calls map cleanly on top of the Win32 API.  As a result, they
219 are much more efficient.  Changing the compiler's driver program to
220 call spawn instead of fork was a trivial change and increased
221 compilation speeds by twenty to thirty percent in our
222 tests.</para>
223
224 <para>However, spawn and exec present their own set of
225 difficulties.  Because there is no way to do an actual exec under
226 Win32, Cygwin has to invent its own Process IDs (PIDs).  As a
227 result, when a process performs multiple exec calls, there will be
228 multiple Windows PIDs associated with a single Cygwin PID.  In some
229 cases, stubs of each of these Win32 processes may linger, waiting for
230 their exec'd Cygwin process to exit.</para>
231 </sect2>
232
233 <sect2 id="ov-hi-signals"><title>Signals</title>
234 <para>When
235 a Cygwin process starts, the library starts a secondary thread for
236 use in signal handling.  This thread waits for Windows events used to
237 pass signals to the process.  When a process notices it has a signal,
238 it scans its signal bitmask and handles the signal in the appropriate
239 fashion.</para>
240
241 <para>Several complications in the implementation arise from the
242 fact that the signal handler operates in the same address space as the
243 executing program.  The immediate consequence is that Cygwin system
244 functions are interruptible unless special care is taken to avoid
245 this.   We go to some lengths to prevent the sig_send function that
246 sends signals from being interrupted.  In the case of a process
247 sending a signal to another process, we place a mutex around sig_send
248 such that sig_send will not be interrupted until it has completely
249 finished sending the signal.</para>
250
251 <para>In the case of a process sending
252 itself a signal, we use a separate semaphore/event pair instead of the
253 mutex.  sig_send starts by resetting the event and incrementing the
254 semaphore that flags the signal handler to process the signal.  After
255 the signal is processed, the signal handler signals the event that it
256 is done.  This process keeps intraprocess signals synchronous, as
257 required by POSIX.</para>
258
259 <para>Most standard UNIX signals are provided.  Job
260 control works as expected in shells that support
261 it.</para>
262 </sect2>
263
264 <sect2 id="ov-hi-sockets"><title>Sockets</title>
265 <para>Socket-related calls in Cygwin simply
266 call the functions by the same name in Winsock, Microsoft's
267 implementation of Berkeley sockets.  Only a few changes were needed to
268 match the expected UNIX semantics - one of the most troublesome
269 differences was that Winsock must be initialized before the first
270 socket function is called.  As a result, Cygwin has to perform this
271 initialization when appropriate.  In order to support sockets across
272 fork calls, child processes initialize Winsock if any inherited file
273 descriptor is a socket.</para>
274
275 <para>Unfortunately, implicitly loading DLLs
276 at process startup is usually a slow affair.  Because many processes
277 do not use sockets, Cygwin explicitly loads the Winsock DLL the
278 first time it calls the Winsock initialization routine.  This single
279 change sped up GNU configure times by thirty
280 percent.</para>
281 </sect2>
282
283 <sect2 id="ov-hi-select"><title>Select</title>
284 <para>The UNIX select function is another
285 call that does not map cleanly on top of the Win32 API.  Much to our
286 dismay, we discovered that the Win32 select in Winsock only worked on
287 socket handles.  Our implementation allows select to function normally
288 when given different types of file descriptors (sockets, pipes,
289 handles, and a custom /dev/windows Windows messages
290 pseudo-device).</para>
291
292 <para>Upon entry into the select function, the first
293 operation is to sort the file descriptors into the different types.
294 There are then two cases to consider.  The simple case is when at
295 least one file descriptor is a type that is always known to be ready
296 (such as a disk file).  In that case, select returns immediately as
297 soon as it has polled each of the other types to see if they are
298 ready.  The more complex case involves waiting for socket or pipe file
299 descriptors to be ready.  This is accomplished by the main thread
300 suspending itself, after starting one thread for each type of file
301 descriptor present.  Each thread polls the file descriptors of its
302 respective type with the appropriate Win32 API call.  As soon as a
303 thread identifies a ready descriptor, that thread signals the main
304 thread to wake up.  This case is now the same as the first one since
305 we know at least one descriptor is ready.  So select returns, after
306 polling all of the file descriptors one last time.</para>
307 </sect2>