On a UNIX system, when an application reads from a file it getsexactly what's in the file on disk and the converse is true for writing.The situation is different in the DOS/Windows world where a file canbe opened in one of two modes, binary or text. In the binary mode thesystem behaves exactly as in UNIX. However on writing in text mode, aNL (\n, ^J) is transformed into the sequence CR (\r, ^M) NL.
This can wreak havoc with the seek/fseek calls since the numberof bytes actually in the file may differ from that seen by theapplication.
The mode can be specified explicitly as explained in the Programmingsection below. In an ideal DOS/Windows world, all programs using lines asrecords (such asbash,make,sed ...) would open files (and change the mode of theirstandard input and output) as text. All other programs (such ascat,cmp,tr ...)would use binary mode. In practice with Cygwin, programs that dealexplicitly with object files specify binary mode (this is the case ofod, which is helpful to diagnose CR problems). Mostother programs (such assed,cmp,tr) use the default mode.
The Cygwin system gives us some flexibility in deciding how files are to be opened when the mode is not specified explicitly. The rules are evolving, this section gives the design goals.
If the filename is specified as a POSIX path and it appears toreside on a file system that is mounted (i.e. if its pathname startswith a directory displayed bymount), then thedefault is specified by the mount flag. If the file is a symbolic link,the mode of the target file system applies.
If the file is specified via a MS-DOS pathname (i.e., it contains abackslash or a colon), the default is binary.
Pipes, sockets and non-file devices are opened in binary mode.For pipes opened through the pipe() system call you can use the setmode()function (seethe section called “Programming” to switch to textmode.For pipes opened through popen(), you can simply specify text or binarymode just like in calls to fopen().
Sockets and other non-file devices are always opened in binary mode.
When redirecting, the Cygwin shells uses rules (a-d).Non-Cygwin shells always pipe and redirect with binary mode. Withnon-Cygwin shells the commands cat filename | programand program < filename are not equivalent whenfilename
is on a text-mounted partition.
The programsu2d andd2u canbe used to add or remove CR's from a file.u2d add's CR's before a NL.d2u removes CR's. Use the --help option to these commandsfor more information.
UNIX programs that have been written for maximum portabilitywill know the difference between text and binary files and actappropriately under Cygwin. Most programs included in the officialCygwin distributions should work well in the default mode.
Binmode is the best choice usually since it's faster andeasier to handle, unless you want to exchange files with native Win32applications. It makes most sense to keep the Cygwin distributionand your Cygwin home directory in binmode and generate text files inbinmode (with UNIX LF lineendings). Most Windows applications canhandle binmode files just fine. A notable exception is the mini-editorNotepad, which handles UNIX lineendings incorrectlyand only produces output files with DOS CRLF lineendings.
You can convert files between CRLF and LF lineendings by usingcertain tools in the Cygwin distribution likedos2unix andunix2dos from the dos2unix package. You can also specifya directory in the mount table to be mounted in textmode so you can usethat directory for exchange purposes.
As application programmer you can decide on a file by file base,or you can specify default open modes depending on the purpose for whichthe application open files. See the next section for a description ofyour choices.
In theopen()
function call, binary mode can bespecified with the flagO_BINARY
and text mode withO_TEXT
. These symbols are defined infcntl.h
.
Themkstemp()
andmkstemps()
calls force binary mode. Usemkostemp()
ormkostemps()
with the same flagsasopen()
for more control on temporary files.
In thefopen()
andpopen()
function calls, binary mode can be specified by adding ab
to the mode string. Text mode is specified by adding at
to the mode string.
The mode of a file can be changed by the callsetmode(fd,mode)
wherefd
is a filedescriptor (an integer) andmode
isO_BINARY
orO_TEXT
. The functionreturnsO_BINARY
orO_TEXT
dependingon the mode before the call, andEOF
on error.
There's also a convenient way to set the default open modes usedin an application by just linking against various object files providedby Cygwin. For instance, if you want to make sure that all files arealways opened in binary mode by an application, regardless of the modeof the underlying mount point, just add the file/lib/binmode.o
to the link stage of the applicationin your project, like this:
$ gcc my_tiny_app.c /lib/binmode.o -o my_tiny_app
Even simpler:
$ gcc my_tiny_app.c -lbinmode -o my_tiny_app
This adds code which sets the default open mode for all filesopened bymy_tiny_app to binary for reading andwriting.
Cygwin provides the following libraries and object files to set thedefault open mode just by linking an application against them:
/lib/libautomode.a - Open files for reading in textmode,/lib/automode.o open files for writing in binary mode
/lib/libbinmode.a - Open files for reading and writing in binary mode/lib/binmode.o
/lib/libtextmode.a - Open files for reading and writing in textmode/lib/textmode.o
/lib/libtextreadmode.a - Open files for reading in textmode,/lib/textreadmode.o keep default behaviour for writing.