OSDN Git Service

* Makefile.common: Change method for finding current directory.
[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).  Cygwin maps Win32 file ownership and permissions to the
71 more standard, older UNIX model by default.  Cygwin version 1.1 introduces
72 support for ACLs according to the system calls used on newer versions of
73 Solaris. This ability is used when the `ntsec' feature is switched on which
74 is described in another chapter.
75 The chmod call maps UNIX-style permissions
76 back to the Win32 equivalents.  Because many programs expect to be able to find
77 the /etc/passwd and /etc/group files, we provide utilities that can be used to
78 construct them from the user and group information provided by the operating
79 system.</para>
80
81 <para>Under Windows NT, the administrator is permitted to chown files.  There
82 is no mechanism to support the setuid concept or API call since Cygwin version
83 1.1.2.  With version 1.1.3 Cygwin introduces a mechanism for setting real
84 and effective UIDs under Windows NT/W2K. This is described in the ntsec
85 section.</para>
86
87 <para>Under Windows 9x, the situation is considerably different.  Since a
88 security model is not provided, Cygwin fakes file ownership by making all
89 files look like they are owned by a default user and group id.  As under NT,
90 file permissions can still be determined by examining their read/write/execute
91 status.  Rather than return an unimplemented error, under Windows 9x, the
92 chown call succeeds immediately without actually performing any action
93 whatsoever.  This is appropriate since essentially all users jointly own the
94 files when no concept of file ownership exists.</para>
95
96 <para>It is important that we discuss the implications of our "kernel" using
97 shared memory areas to store information about Cygwin processes.  Because
98 these areas are not yet protected in any way, in principle a malicious user
99 could modify them to cause unexpected behavior in Cygwin processes.  While
100 this is not a new problem under Windows 9x (because of the lack of operating
101 system security), it does constitute a security hole under Windows NT.
102 This is because one user could affect the Cygwin programs run by
103 another user by changing the shared memory information in ways that
104 they could not in a more typical WinNT program.  For this reason, it
105 is not appropriate to use Cygwin in high-security applications.  In
106 practice, this will not be a major problem for most uses of the
107 library.</para>
108 </sect2>
109
110 <sect2 id="ov-hi-files"><title>File Access</title> <para>Cygwin supports
111 both Win32- and POSIX-style paths, using either forward or back slashes as the
112 directory delimiter.  Paths coming into the DLL are translated from Win32 to
113 POSIX as needed.  As a result, the library believes that the file system is a
114 POSIX-compliant one, translating paths back to Win32 paths whenever it calls a
115 Win32 API function.  UNC pathnames (starting with two slashes) are
116 supported.</para>
117
118 <para>The layout of this POSIX view of the Windows file system space is stored
119 in the Windows registry.  While the slash ('/') directory points to the system
120 partition by default, this is easy to change with the Cygwin mount utility.
121 In addition to selecting the slash partition, it allows mounting arbitrary
122 Win32 paths into the POSIX file system space.  Many people use the utility to
123 mount each drive letter under the slash partition (e.g. C:\ to /c, D:\ to /d,
124 etc...).</para>
125
126 <para>The library exports several Cygwin-specific functions that can be used
127 by external programs to convert a path or path list from Win32 to POSIX or vice
128 versa.  Shell scripts and Makefiles cannot call these functions directly.
129 Instead, they can do the same path translations by executing the cygpath
130 utility program that we provide with Cygwin.</para>
131
132 <para>Win32 file systems are case preserving but case insensitive.  Cygwin
133 does not currently support case distinction because, in practice, few UNIX
134 programs actually rely on it.  While we could mangle file names to support case
135 distinction, this would add unnecessary overhead to the library and make it
136 more difficult for non-Cygwin applications to access those files.</para>
137
138 <para>Symbolic links are emulated by files containing a magic cookie followed
139 by the path to which the link points.  They are marked with the System
140 attribute so that only files with that attribute have to be read to determine
141 whether or not the file is a symbolic link.  Hard links are fully supported
142 under Windows NT on NTFS file systems.  On a FAT file system, the call falls
143 back to simply copying the file, a strategy that works in many cases.</para>
144
145 <para>The inode number for a file is calculated by hashing its full Win32 path.
146 The inode number generated by the stat call always matches the one returned in
147 d_ino of the dirent structure.  It is worth noting that the number produced by
148 this method is not guaranteed to be unique.  However, we have not found this to
149 be a significant problem because of the low probability of generating a
150 duplicate inode number.</para>
151
152 <para>Chroot is supported since release 1.1.3. Note that chroot isn't
153 supported native by Windows. This implies some restrictions. First of all,
154 the chroot call isn't a privileged call. Each user may call it. Second, the
155 chroot environment isn't safe against native windows processes. If you
156 want to support a chroot environment as, for example, by allowing an
157 anonymous ftp with restricted access, you'll have to care that only
158 native Cygwin applications are accessible inside of the chroot environment.
159 Since that applications are only using the Cygwin POSIX API to access the
160 file system their access can be restricted as it is intended. This includes
161 not only POSIX paths but Win32 paths (containing drive letter and/or
162 backslashes) and CIFS paths (//server/share or \\server\share) as well.</para>
163 </sect2>
164
165 <sect2 id="ov-hi-textvsbinary"><title>Text Mode vs. Binary Mode</title>
166 <para>Interoperability with other Win32 programs such as text editors was
167 critical to the success of the port of the development tools.  Most Cygnus
168 customers upgrading from the older DOS-hosted toolchains expected the new
169 Win32-hosted ones to continue to work with their old development
170 sources.</para>
171
172 <para>Unfortunately, UNIX and Win32 use different end-of-line terminators in
173 text files.  Consequently, carriage-return newlines have to be translated on
174 the fly by Cygwin into a single newline when reading in text mode.  The
175 control-z character is interpreted as a valid end-of-file character for a
176 similar reason.</para>
177
178 <para>This solution addresses the compatibility requirement at the expense of
179 violating the POSIX standard that states that text and binary mode will be
180 identical. Consequently, processes that attempt to lseek through text files can
181 no longer rely on the number of bytes read as an accurate indicator of position
182 in the file.  For this reason, the CYGWIN environment variable can be
183 set to override this behavior.</para>
184 </sect2>
185
186 <sect2 id="ov-hi-ansiclib"><title>ANSI C Library</title>
187 <para>We chose to include
188 Cygnus' own existing ANSI C library
189 "newlib" as part of the library, rather than write all of the lib C
190 and math calls from scratch.  Newlib is a BSD-derived ANSI C library,
191 previously only used by cross-compilers for embedded systems
192 development.</para>
193
194 <para>The reuse of existing free implementations of such things
195 as the glob, regexp, and getopt libraries saved us considerable
196 effort.  In addition, Cygwin uses Doug Lea's free malloc
197 implementation that successfully balances speed and compactness.  The
198 library accesses the malloc calls via an exported function pointer.
199 This makes it possible for a Cygwin process to provide its own
200 malloc if it so desires.</para>
201 </sect2>
202
203 <sect2 id="ov-hi-process"><title>Process Creation</title>
204 <para>The fork call in Cygwin is particularly interesting because it
205 does not map well on top of the Win32 API.  This makes it very
206 difficult to implement correctly.  Currently, the Cygwin fork is a
207 non-copy-on-write implementation similar to what was present in early
208 flavors of UNIX.</para>
209
210 <para>The first thing that happens when a parent process
211 forks a child process is that the parent initializes a space in the
212 Cygwin process table for the child.  It then creates a suspended
213 child process using the Win32 CreateProcess call.  Next, the parent
214 process calls setjmp to save its own context and sets a pointer to
215 this in a Cygwin shared memory area (shared among all Cygwin
216 tasks).  It then fills in the child's .data and .bss sections by
217 copying from its own address space into the suspended child's address
218 space.  After the child's address space is initialized, the child is
219 run while the parent waits on a mutex.  The child discovers it has
220 been forked and longjumps using the saved jump buffer.  The child then
221 sets the mutex the parent is waiting on and blocks on another mutex.
222 This is the signal for the parent to copy its stack and heap into the
223 child, after which it releases the mutex the child is waiting on and
224 returns from the fork call.  Finally, the child wakes from blocking on
225 the last mutex, recreates any memory-mapped areas passed to it via the
226 shared area, and returns from fork itself.</para>
227
228 <para>While we have some
229 ideas as to how to speed up our fork implementation by reducing the
230 number of context switches between the parent and child process, fork
231 will almost certainly always be inefficient under Win32.  Fortunately,
232 in most circumstances the spawn family of calls provided by Cygwin
233 can be substituted for a fork/exec pair with only a little effort.
234 These calls map cleanly on top of the Win32 API.  As a result, they
235 are much more efficient.  Changing the compiler's driver program to
236 call spawn instead of fork was a trivial change and increased
237 compilation speeds by twenty to thirty percent in our
238 tests.</para>
239
240 <para>However, spawn and exec present their own set of
241 difficulties.  Because there is no way to do an actual exec under
242 Win32, Cygwin has to invent its own Process IDs (PIDs).  As a
243 result, when a process performs multiple exec calls, there will be
244 multiple Windows PIDs associated with a single Cygwin PID.  In some
245 cases, stubs of each of these Win32 processes may linger, waiting for
246 their exec'd Cygwin process to exit.</para>
247 </sect2>
248
249 <sect2 id="ov-hi-signals"><title>Signals</title>
250 <para>When
251 a Cygwin process starts, the library starts a secondary thread for
252 use in signal handling.  This thread waits for Windows events used to
253 pass signals to the process.  When a process notices it has a signal,
254 it scans its signal bitmask and handles the signal in the appropriate
255 fashion.</para>
256
257 <para>Several complications in the implementation arise from the
258 fact that the signal handler operates in the same address space as the
259 executing program.  The immediate consequence is that Cygwin system
260 functions are interruptible unless special care is taken to avoid
261 this.   We go to some lengths to prevent the sig_send function that
262 sends signals from being interrupted.  In the case of a process
263 sending a signal to another process, we place a mutex around sig_send
264 such that sig_send will not be interrupted until it has completely
265 finished sending the signal.</para>
266
267 <para>In the case of a process sending
268 itself a signal, we use a separate semaphore/event pair instead of the
269 mutex.  sig_send starts by resetting the event and incrementing the
270 semaphore that flags the signal handler to process the signal.  After
271 the signal is processed, the signal handler signals the event that it
272 is done.  This process keeps intraprocess signals synchronous, as
273 required by POSIX.</para>
274
275 <para>Most standard UNIX signals are provided.  Job
276 control works as expected in shells that support
277 it.</para>
278 </sect2>
279
280 <sect2 id="ov-hi-sockets"><title>Sockets</title>
281 <para>Socket-related calls in Cygwin simply
282 call the functions by the same name in Winsock, Microsoft's
283 implementation of Berkeley sockets.  Only a few changes were needed to
284 match the expected UNIX semantics - one of the most troublesome
285 differences was that Winsock must be initialized before the first
286 socket function is called.  As a result, Cygwin has to perform this
287 initialization when appropriate.  In order to support sockets across
288 fork calls, child processes initialize Winsock if any inherited file
289 descriptor is a socket.</para>
290
291 <para>Unfortunately, implicitly loading DLLs
292 at process startup is usually a slow affair.  Because many processes
293 do not use sockets, Cygwin explicitly loads the Winsock DLL the
294 first time it calls the Winsock initialization routine.  This single
295 change sped up GNU configure times by thirty
296 percent.</para>
297 </sect2>
298
299 <sect2 id="ov-hi-select"><title>Select</title>
300 <para>The UNIX select function is another
301 call that does not map cleanly on top of the Win32 API.  Much to our
302 dismay, we discovered that the Win32 select in Winsock only worked on
303 socket handles.  Our implementation allows select to function normally
304 when given different types of file descriptors (sockets, pipes,
305 handles, and a custom /dev/windows Windows messages
306 pseudo-device).</para>
307
308 <para>Upon entry into the select function, the first
309 operation is to sort the file descriptors into the different types.
310 There are then two cases to consider.  The simple case is when at
311 least one file descriptor is a type that is always known to be ready
312 (such as a disk file).  In that case, select returns immediately as
313 soon as it has polled each of the other types to see if they are
314 ready.  The more complex case involves waiting for socket or pipe file
315 descriptors to be ready.  This is accomplished by the main thread
316 suspending itself, after starting one thread for each type of file
317 descriptor present.  Each thread polls the file descriptors of its
318 respective type with the appropriate Win32 API call.  As soon as a
319 thread identifies a ready descriptor, that thread signals the main
320 thread to wake up.  This case is now the same as the first one since
321 we know at least one descriptor is ready.  So select returns, after
322 polling all of the file descriptors one last time.</para>
323 </sect2>