# TIP 183: Add a Binary Flag to [open]
	Author:         Andreas Leitgeb <avl@logic.at>
	Author:         Don Porter <dgp@users.sf.net>
	State:          Final
	Type:           Project
	Vote:           Done
	Created:        24-Mar-2004
	Post-History:   
	Keywords:       Tcl
	Tcl-Version:    8.5
-----

# Abstract

To handle binary files, one currently has to open the file, and then
in a second step **fconfigure** it with **-translation binary**.
This TIP proposes to add a flag "b" to open's _access_-argument to
set initial translation to binary \(rather than auto\).

# Rationale

ANSI-C _fopen\(\)_ supports an additional flag "b" in the _mode_
parameter especially for non-POSIX platforms, where it makes sure that
no conversion takes place at reading or writing.  The manual page for
open mentions that **fconfigure** should be used as a substitute for
the missing "b"-flag but I don't see anything wrong with a "b" flag as
a possible shortcut for this **fconfigure**-call, so this TIP proposes
that the _access_ argument to **open** should support **b** as
an additional letter \(anywhere within the argument when used in the
first form documented on the manual page\) which will cause the initial
configuration of the channel to be suitable for reading and/or writing
binary data.

Thus, for an expectedly very little implementation effort, we can
simplify:

	  set fd [open $fname "w"]; fconfigure $fd -translation binary

to:

	  set fd [open $fname "wb"]

which looks much more concise for such a common task.

This extra flag would only affect the initial translation state.

# Enhancement

Tcl's **open** also tries to adopt the POSIX _open\(\)_ parameters
\(i.e. the second form documented for the _access_ parameter on the
manual page.\)  POSIX's _open\(\)_ doesn't know about binary or
non-binary files, but Tcl does, so a new keyword "BINARY" could be
introduced to offer this feature also to those who prefer
list-of-flags syntax.

# Implementation

A patch attached to Tcl Feature Request 577093 implements
this proposal.  The public Tcl C routine
**Tcl\_FSOpenFileChannel** is amended to accept the
**b** and **BINARY** substrings in its parsing
of the _modeString_ argument.  If this proposal
is accepted, additional work will be performed to
add the required test and documentation changes to the
patch.

# Compatibility

Any remaining callers of the obsolete private interface
**TclOpenFileChannelInsertProc** need to be aware
that the _\(TclOpenFileChannelProc\_ \*\)_ function\(s\)
it registers will now possibly be passed a _modeString_
argument that includes the newly supported **b**
and **BINARY** substrings.  Some updating will be
required to handle this situation.  Ideally, the updating
will take the form of leaving behind use of this obsolete,
unsupported, private interface, and migrating to the
public support for virtual filesystems.

Other than that, this proposal is a completely
compatible extension of existing interfaces.

# Discussion

There have been comments that the C-like version of access is
just legacy, hard to grok/remember and other general bad things
about even the existing things. Those who don't like/use "r","w",
"r\+", anyway, \(and who always use \{WRITE CREAT TRUNC\} instead of 
just "w"\) are not affected by any additional "b". There is no
**need** to use it that way.  fconfigure still remains.
\(Partially I agree with them, the "r\+" and "w\+" are indeed
lousy, and "a" is just a legacy design-bug -- seeks to end
just once instead of before each write. Using that is like begging
for race-conditions to bite. -- On the other hand "r" and "w", with
or without "b" are unbeatably concise and still self-explaining.\)

Some proposed adding -options for all kinds of things. Specifying
the access-options as -read or -write ...   My comment to this:
If you like it verbose, use list-syntax for access-flags. This
TIP is **not** about getting rid of legacy-C-syntax for flags.

Some said, that if "b" \(BINARY\) is added, then sooner or 
later every fconfigure option would have to be added to "open",
\(and some even proposed that\). Thats beside the point. Does
anybody really doubt that "-translation binary" is by far
the most common option used with fconfigure? And open does
really ask for that but not for any other one \(at least not 
as loudly :-\).

Another comment was about difficulties to implement "b", because
lower-level functions \(Tcl\_FSOpenFileChannelProc was mentioned\)
would have to be changed for that.  That is not true, because 
the "b" could be recognized at top level \(Tcl\_OpenObjCmd\)
and trigger the call to Tcl\_SetChannelOption after returning
from the lower levels. \("b" is valid already, just currently 
ignored at all levels\).

"open binaryfile r -translation binary" is not really any convenience.
It's almost as verbose as calling fconfigure explicitly.

Two positive comments appeared: First by Vince Darley: Having
the Tcl C-Api for open accept the "b" makes it easier for foreign
libraries \(that open binary files\) to be integrated as far as
exposing them to Tcl's VFS, by \#define'ing fopen to the 
Tcl-C-Api function.

Another, by DKF: The reasons of the current status quo are 
historical: the flags-argument for open was defined when Tcl
was only \(officially\) available on Unix-platforms \(where "b"
is ignored\) and didn't even support binary data \(nor any
translations\). Both of these historical reasons are obsolete
by now.

To sum up: yes, "b" is a C-ism, but open is, too. Also it's
not a feature that someone would be required to use.

# Copyright

This document has been placed in the public domain.

