\documentclass[]{article}
\usepackage{amsmath,graphicx,supertabular,hyperref,tabularx,ifthen}
\title{TIP \#183: Add a Binary Flag to [open]}
\date{March 24, 2004}
\author{Andreas Leitgeb, Don Porter}
\urlstyle{sf}
\setlength{\parskip}{1ex}
\setlength{\parindent}{0pt}
\def\tipversion$#1${\texttt{\$#1\$}}
\def\tiplangle#1{\ensuremath{<}}
\def\tiprangle#1{\ensuremath{>}}
\def\tipbar#1{\ensuremath{|}}
\def\tipmail#1#2{\(\langle\){\small\expandafter\url{#1@#2}}\(\rangle\)}
\ifx\pdfoutput\undefined
\newcommand{\tipimage}[2]{\typeout{Make sure you download #1.eps}\ifthenelse{\lengthtest{0.8\textwidth>#2}\and\lengthtest{0pt<#2}}{\includegraphics{#1.eps}}{\includegraphics[width=0.8\textwidth]{#1.eps}}}
\newcommand{\tipxref}[1]{}
\newcommand{\tipxrefend}{}
\else
\newcommand{\tipimage}[2]{\typeout{Make sure you create #1.pdf}\ifthenelse{\lengthtest{0.8\textwidth>#2}\and\lengthtest{0pt<#2}}{\includegraphics{#1.pdf}}{\includegraphics[width=0.8\textwidth]{#1.pdf}}}
\pdfcatalog{/PageMode /UseOutlines}
\newcommand{\tipxref}[1]{\pdfannotlink attr {/C [0.5 0.5 1.0] /Border [0 0 1]} goto name {#1}}
\newcommand{\tipxrefend}{\pdfendlink}
\fi
\newenvironment{tipabstract}{\begin{abstract}}{\end{abstract}}
\begin{document}\maketitle
\begin{center}\begin{tabularx}{\linewidth}{|r@{: }X|}\hline
\textbf{TIP \#183}&\textbf{Add a Binary Flag to [open]}\\\hline
Author&

Andreas Leitgeb \tipmail{avl}{logic.at}
\par
Don Porter \tipmail{dgp}{users.sf.net}
\\
Created&Wednesday, \(\text{24}^{\text{th}}\) March 2004\\
Type&Project\\
Tcl Version&\(8.5\)\\
State&Final\\
Vote&Done\\
Version&\tipversion$Revision: 1.10 $\\
Keywords&Tcl\\
Post History&\\
\hline\end{tabularx}\end{center}
\thispagestyle{empty}\pagestyle{empty}
\begin{tipabstract}

To handle binary files, one currently has to open the file, and then in a second step \textbf{fconfigure} it with \textbf{-translation binary}. This TIP proposes to add a flag ``b'' to open's \textit{access}-argument to set initial translation to binary (rather than auto).
\end{tipabstract}
\tableofcontents\setcounter{page}{0}\clearpage\pagestyle{plain}

\section{Rationale}

ANSI-C \textit{fopen()} supports an additional flag ``b'' in the \textit{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 \textbf{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 \textbf{fconfigure}-call, so this TIP proposes that the \textit{access} argument to \textbf{open} should support \textbf{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:
\begingroup\small\begin{verbatim}
  set fd [open $fname "w"]; fconfigure $fd -translation binary
\end{verbatim}
\endgroup

to:
\begingroup\small\begin{verbatim}
  set fd [open $fname "wb"]
\end{verbatim}
\endgroup

which looks much more concise for such a common task.

This extra flag would only affect the initial translation state.

\section{Enhancement}

Tcl's \textbf{open} also tries to adopt the POSIX \textit{open()} parameters (i.e. the second form documented for the \textit{access} parameter on the manual page.) POSIX's \textit{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.

\section{Implementation}

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

\section{Compatibility}

Any remaining callers of the obsolete private interface \textbf{TclOpenFileChannelInsertProc} need to be aware that the \textit{(TclOpenFileChannelProc\_ *)} function(s) it registers will now possibly be passed a \textit{modeString} argument that includes the newly supported \textbf{b} and \textbf{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.

\section{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 \textbf{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 \textbf{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.

\section{Copyright}

This document has been placed in the public domain.

\section{Colophon}

\textit{TIP AutoGenerator --- written by Donal K. Fellows}
\end{document}
