OSDN Git Service

* new-features.sgml (ov-new1.7.2): Accommodate name change of getlocale
[pf3gnuchains/pf3gnuchains4x.git] / winsup / doc / textbinary.sgml
1 <sect1 id="using-textbinary"><title>Text and Binary modes</title>
2
3 <sect2 id="textbin-issue"> <title>The Issue</title>
4
5 <para>On a UNIX system, when an application reads from a file it gets
6 exactly what's in the file on disk and the converse is true for writing.
7 The situation is different in the DOS/Windows world where a file can
8 be opened in one of two modes, binary or text.  In the binary mode the
9 system behaves exactly as in UNIX.  However on writing in text mode, a
10 NL (\n, ^J) is transformed into the sequence CR (\r, ^M) NL.
11 </para>
12
13 <para>This can wreak havoc with the seek/fseek calls since the number
14 of bytes actually in the file may differ from that seen by the
15 application.</para>
16
17 <para>The mode can be specified explicitly as explained in the Programming
18 section below.  In an ideal DOS/Windows world, all programs using lines as
19 records (such as <command>bash</command>, <command>make</command>,
20 <command>sed</command> ...) would open files (and change the mode of their
21 standard input and output) as text.  All other programs (such as
22 <command>cat</command>, <command>cmp</command>, <command>tr</command> ...)
23 would use binary mode.  In practice with Cygwin, programs that deal
24 explicitly with object files specify binary mode (this is the case of
25 <command>od</command>, which is helpful to diagnose CR problems).  Most
26 other programs (such as <command>cat</command>, <command>cmp</command>,
27 <command>tr</command>) use the default mode.</para>
28
29 </sect2>
30
31 <sect2 id="textbin-default"><title>The default Cygwin behavior</title>
32
33 <para>The Cygwin system gives us some flexibility in deciding how files 
34 are to be opened when the mode is not specified explicitly. 
35 The rules are evolving, this section gives the design goals.</para>
36
37 <orderedlist numeration="loweralpha">
38 <listitem>
39 <para>If the filename is specified as a POSIX path and it appears to
40 reside on a file system that is mounted (i.e.  if its pathname starts
41 with a directory displayed by <command>mount</command>), then the
42 default is specified by the mount flag.  If the file is a symbolic link,
43 the mode of the target file system applies.</para>
44 </listitem>
45
46 <listitem>
47 <para>If the file is specified via a MS-DOS pathname (i.e., it contains a
48 backslash or a colon), the default is binary.
49 </para>
50 </listitem>
51
52 <listitem>
53 <para>Pipes, sockets and non-file devices are opened in binary mode.
54 For pipes opened through the pipe() system call you can use the setmode()
55 function (see <xref linkend="textbin-devel"></xref> to switch to textmode.
56 For pipes opened through popen(), you can simply specify text or binary
57 mode just like in calls to fopen().</para>
58 </listitem>
59
60 <listitem>
61 <para>Sockets and other non-file devices are always opened in binary mode.
62 </para>
63 </listitem>
64
65 <listitem>
66 <para> When redirecting, the Cygwin shells uses rules (a-d).
67 Non-Cygwin shells always pipe and redirect with binary mode. With
68 non-Cygwin shells the commands <command> cat filename | program </command>
69 and <command> program &lt; filename </command> are not equivalent when
70 <filename>filename</filename> is on a text-mounted partition. </para>
71 </listitem>
72 </orderedlist>
73 </sect2>
74
75 <sect2 id="textbin-example"><title>Example</title>
76 <para>To illustrate the various rules, we provide scripts to delete CRs
77 from files by using the <command>tr</command> program, which can only write
78 to standard output. 
79 The script</para>
80 <screen>
81 <![CDATA[
82 #!/bin/sh
83 # Remove \r from the file given as argument
84 tr -d '\r' < "$1" > "$1".nocr
85 ]]>
86 </screen>
87 <para> will not work on a text mounted systems because the \r will be 
88 reintroduced on writing. However scripts such as </para>
89 <screen>
90 <![CDATA[
91 #!/bin/sh
92 # Remove \r from the file given as argument
93 tr -d '\r' | gzip | gunzip > "$1".nocr
94 ]]>
95 </screen>
96 <para>and the .bat file</para>
97 <screen>
98 <![CDATA[
99 REM Remove \r from the file given as argument
100 @echo off
101 tr -d \r < %1 > %1.nocr
102 ]]>
103 </screen>
104 <para> work fine. In the first case we rely on <command>gunzip</command> to
105 set its output to binary mode, possibly overriding the mode used by the shell.
106 In the second case we rely on the DOS shell to redirect in binary mode.
107 </para>
108 </sect2>
109
110 <sect2 id="textbin-question"><title>Binary or text?</title>
111
112 <para>UNIX programs that have been written for maximum portability
113 will know the difference between text and binary files and act
114 appropriately under Cygwin.  Most programs included in the official
115 Cygwin distributions should work well in the default mode. </para>
116
117 <para>Binmode is the best choice usually since it's faster and
118 easier to handle, unless you want to exchange files with native Win32
119 applications.  It makes most sense to keep the Cygwin distribution
120 and your Cygwin home directory in binmode and generate text files in
121 binmode (with UNIX LF lineendings).  Most Windows applications can
122 handle binmode files just fine.  A notable exception is the mini-editor
123 <command>Notepad</command>, which handles UNIX lineendings incorrectly
124 and only produces output files with DOS CRLF lineendings.</para>
125
126 <para>You can convert files between CRLF and LF lineendings by using
127 certain tools in the Cygwin distribution like <command>d2u</command> and
128 <command>u2d</command> from the cygutils package.  You can also specify
129 a directory in the mount table to be mounted in textmode so you can use
130 that directory for exchange purposes.</para>
131
132 <para>As application programmer you can decide on a file by file base,
133 or you can specify default open modes depending on the purpose for which
134 the application open files.  See the next section for a description of
135 your choices.</para>
136
137 </sect2>
138
139 <sect2 id="textbin-devel"><title>Programming</title>
140
141 <para>In the <function>open()</function> function call, binary mode can be
142 specified with the flag <literal>O_BINARY</literal> and text mode with
143 <literal>O_TEXT</literal>. These symbols are defined in
144 <filename>fcntl.h</filename>.</para>
145
146 <para>In the <function>fopen()</function> and <function>popen()</function>
147 function calls, binary mode can be specified by adding a <literal>b</literal>
148 to the mode string. Text mode is specified by adding a <literal>t</literal>
149 to the mode string.</para>
150
151 <para>The mode of a file can be changed by the call
152 <function>setmode(fd,mode)</function> where <literal>fd</literal> is a file
153 descriptor (an integer) and <literal>mode</literal> is
154 <literal>O_BINARY</literal> or <literal>O_TEXT</literal>. The function
155 returns <literal>O_BINARY</literal> or <literal>O_TEXT</literal> depending
156 on the mode before the call, and <literal>EOF</literal> on error.</para>
157
158 <para>There's also a convenient way to set the default open modes used
159 in an application by just linking against various object files provided
160 by Cygwin.  For instance, if you want to make sure that all files are
161 always opened in binary mode by an application, regardless of the mode
162 of the underlying mount point, just add the file
163 <filename>/lib/binmode.o</filename> to the link stage of the application
164 in your project, like this:</para>
165
166 <screen>
167   $ gcc my_tiny_app.c /lib/binmode.o -o my_tiny_app
168 </screen>
169
170 <para>This adds code which sets the default open mode for all files
171 opened by <command>my_tiny_app</command> to binary for reading and
172 writing.</para>
173
174 <para>Cygwin provides the following object files to set the default open mode
175 just by linking an application against them:</para>
176
177 <itemizedlist mark="bullet">
178
179 <listitem>
180 <screen>
181 /lib/automode.o      -  Open files for reading in textmode
182                         Open files for writing in binary mode
183 </screen>
184 </listitem>
185
186 <listitem>
187 <screen>
188 /lib/binmode.o       -  Open files for reading and writing in binary mode
189 </screen>
190 </listitem>
191
192 <listitem>
193 <screen>
194 /lib/textmode.o      -  Open files for reading and writing in textmode
195 </screen>
196 </listitem>
197
198 <listitem>
199 <screen>
200 /lib/textreadmode.o  -  Open files for reading in textmode
201                         Keep default behaviour for writing.
202 </screen>
203 </listitem>
204
205 </itemizedlist>
206
207 </sect2>
208
209 </sect1>