This is the mail archive of the cygwin@sourceware.cygnus.com mailing list for the Cygwin project. See the Cygwin home page for more information.
[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index] [Subject Index] [Author Index] [Thread Index]

setmode (long)



I have written an application in C++ which is supposed to compile
and run on any platform including UNIX, DOS and Windows 95/98/NT.
It reads and writes text as well as binary data from files and
standard input and output.  It uses the line feed (newline) character
to mark the end of a line and the carriage return line feed sequence
to mark the end of a paragraph.  It reads and writes text files
in binary mode and converts \r\n to \n on input and \n to \r\n
on output for DOS (and Windows 95/98/NT) systems so that the user
can read, edit and print them using native tools.

On DOS and Windows 95/98/NT systems, the C preprocessor includes code
which uses setmode to change the default I/O mode from text to binary.
This worked just fine with older versions of DJGPP on DOS
but I have just downloaded and installed the most recent versions
of DJGPP, Cygwin and mingw32 and I am experiencing some problems.
I wrote a short program, `test.cc', to help illustrate them.
----------------------------------------------------------------------

// test.cc

#include<fstream.h>
#include<io.h>
#include<fcntl.h>

int
main() {
  int   oldmode = 0;
  cout << "default mode:\n";
  cout << "  0 carriage returns\n";
  cout << "  1 carriage returns\r\n";
  cout << "  2 carriage returns\r\r\n";
  cout << "  3 carriage returns\r\r\r\n";
  oldmode = setmode(1, O_TEXT);
  cout << hex << oldmode <<
    " = setmode(1, " << hex << O_TEXT   << "):\n";
  cout << "  0 carriage returns\n";
  cout << "  1 carriage returns\r\n";
  cout << "  2 carriage returns\r\r\n";
  cout << "  3 carriage returns\r\r\r\n";
  oldmode = setmode(1, O_BINARY);
  cout << hex << oldmode <<
    " = setmode(1, " << hex << O_BINARY << "):\n";
  cout << "  0 carriage returns\n";
  cout << "  1 carriage returns\r\n";
  cout << "  2 carriage returns\r\r\n";
  cout << "  3 carriage returns\r\r\r\n";
  oldmode = setmode(1, O_TEXT);
  cout << hex << oldmode <<
    " = setmode(1, " << hex << O_TEXT   << "):\n";
  cout << "  0 carriage returns\n";
  cout << "  1 carriage returns\r\n";
  cout << "  2 carriage returns\r\r\n";
  cout << "  3 carriage returns\r\r\r\n";

  ofstream      test_out("test.out", ios::out);
  test_out << "default mode:\n";
  test_out << "  0 carriage returns\n";
  test_out << "  1 carriage returns\r\n";
  test_out << "  2 carriage returns\r\r\n";
  test_out << "  3 carriage returns\r\r\r\n";
  oldmode = setmode((test_out.rdbuf())->fd(), O_TEXT);
  test_out << hex << oldmode <<
    " = setmode((test_out.rdbuf())->fd(), " << hex << O_TEXT   << "):\n";
  test_out << "  0 carriage returns\n";
  test_out << "  1 carriage returns\r\n";
  test_out << "  2 carriage returns\r\r\n";
  test_out << "  3 carriage returns\r\r\r\n";
  oldmode = setmode((test_out.rdbuf())->fd(), O_BINARY);
  test_out << hex << oldmode <<
    " = setmode((test_out.rdbuf())->fd(), " << hex << O_BINARY << "):\n";
  test_out << "  0 carriage returns\n";
  test_out << "  1 carriage returns\r\n";
  test_out << "  2 carriage returns\r\r\n";
  test_out << "  3 carriage returns\r\r\r\n";
  oldmode = setmode((test_out.rdbuf())->fd(), O_TEXT);
  test_out << hex << oldmode <<
    " = setmode((test_out.rdbuf())->fd(), " << hex << O_TEXT   << "):\n";
  test_out << "  0 carriage returns\n";
  test_out << "  1 carriage returns\r\n";
  test_out << "  2 carriage returns\r\r\n";
  test_out << "  3 carriage returns\r\r\r\n";
  return 0;
  }
----------------------------------------------------------------------

I compiled under Windows 98 using DJGPP and a DOS shell (MS-DOS Prompt)

        >gxx -v -w -O2 -o test test.cc -lgpp

and I ran the test program

        >.\test > test.dos

I started a Cygwin-b20 bash shell and examined the results:

        $ vi test.dos
        default mode:^M
          0 carriage returns^M
          1 carriage returns^M^M
          2 carriage returns^M^M^M
          3 carriage returns^M^M^M^M
        8 = setmode(1, 8):^M
          0 carriage returns^M
          1 carriage returns^M^M
          2 carriage returns^M^M^M
          3 carriage returns^M^M^M^M
        8 = setmode(1, 4):
          0 carriage returns
          1 carriage returns^M
          2 carriage returns^M^M
          3 carriage returns^M^M^M
        4 = setmode(1, 8):^M
          0 carriage returns^M
          1 carriage returns^M^M
          2 carriage returns^M^M^M
          3 carriage returns^M^M^M^M

appears to be correct but

        $ vi test.out
        default mode:
          0 carriage returns
          1 carriage returns^M
          2 carriage returns^M^M
          3 carriage returns^M^M^M
        8 = setmode((test_out.rdbuf())->fd(), 8):
          0 carriage returns
          1 carriage returns^M
          2 carriage returns^M^M
          3 carriage returns^M^M^M
        8 = setmode((test_out.rdbuf())->fd(), 4):
          0 carriage returns
          1 carriage returns^M
          2 carriage returns^M^M
          3 carriage returns^M^M^M
        4 = setmode((test_out.rdbuf())->fd(), 8):
          0 carriage returns
          1 carriage returns^M
          2 carriage returns^M^M
          3 carriage returns^M^M^M

shows that test.out was opened in binary mode
and setmode didn't switch to text mode.

----------------------------------------------------------------------

I compiled under Windows 98 using EGCS Cygwin-b20 and a bash shell

        $ g++ -v -Wall -O2 -o test test.cc

ran the test program

        $ ./test > test.cyg

and examined the results:

        $ vi test.cyg
        default mode:^M
          0 carriage returns^M
          1 carriage returns^M^M
          2 carriage returns^M^M^M
          3 carriage returns^M^M^M^M
        20000 = setmode(1, 20000):^M
          0 carriage returns^M
          1 carriage returns^M^M
          2 carriage returns^M^M^M
          3 carriage returns^M^M^M^M
        20000 = setmode(1, 10000):
          0 carriage returns
          1 carriage returns^M
          2 carriage returns^M^M
          3 carriage returns^M^M^M
        10000 = setmode(1, 20000):^M
          0 carriage returns^M
          1 carriage returns^M^M
          2 carriage returns^M^M^M
          3 carriage returns^M^M^M^M

appears to be correct but

        $ vi test.out
        default mode:
          0 carriage returns
          1 carriage returns^M
          2 carriage returns^M^M
          3 carriage returns^M^M^M
        20000 = setmode((test_out.rdbuf())->fd(), 20000):
          0 carriage returns
          1 carriage returns^M
          2 carriage returns^M^M
          3 carriage returns^M^M^M
        20000 = setmode((test_out.rdbuf())->fd(), 10000):
          0 carriage returns
          1 carriage returns^M
          2 carriage returns^M^M
          3 carriage returns^M^M^M
        10000 = setmode((test_out.rdbuf())->fd(), 20000):
          0 carriage returns
          1 carriage returns^M
          2 carriage returns^M^M
          3 carriage returns^M^M^M

shows that test.out was opened in binary mode
and setmode didn't switch to text mode.

----------------------------------------------------------------------

I re-compiled under Windows 98 using EGCS Cygwin-b20 with mingw32

        $ g++ -L/mingw32/lib -L/mingw32/i386-mingw32/lib \
        -L/mingw32/lib/gcc-lib/i386-mingw32/egcs-2.91.60 \
        -v -Wall -O2 -mno-cygwin -o test test.cc -lstdc++ -liberty

and ran the test program using and a DOS shell (MS-DOS Prompt)

        >.\test > test.win

I used the Cygwin-b20 bash shell to examine the results:

        $ vi test.win
        default mode:
          0 carriage returns
          1 carriage returns
          2 carriage returns
          3 carriage returns
        4000 = setmode(1, 4000):
          0 carriage returns
          1 carriage returns
          2 carriage returns
          3 carriage returns
        4000 = setmode(1, 8000):
          0 carriage returns
          1 carriage returns
          2 carriage returns
          3 carriage returns
        8000 = setmode(1, 4000):
          0 carriage returns
          1 carriage returns
          2 carriage returns
          3 carriage returns

contains no carriage returns and

       $ vi test.out
        default mode:
          0 carriage returns
          1 carriage returns^M
          2 carriage returns^M^M
          3 carriage returns^M^M^M
        4000 = setmode((test_out.rdbuf())->fd(), 4000):
          0 carriage returns
          1 carriage returns^M
          2 carriage returns^M^M
          3 carriage returns^M^M^M
        4000 = setmode((test_out.rdbuf())->fd(), 8000):
          0 carriage returns
          1 carriage returns^M
          2 carriage returns^M^M
          3 carriage returns^M^M^M
        8000 = setmode((test_out.rdbuf())->fd(), 4000):
          0 carriage returns
          1 carriage returns^M
          2 carriage returns^M^M
          3 carriage returns^M^M^M

shows that test.out was opened in binary mode
and setmode didn't switch to text mode.

----------------------------------------------------------------------

I didn't change any of the default settings when I installed Cygwin.
I didn't mount any file systems as binary only or define binmode.
I've read the FAQs and searched the mailing list archives.

It appears to me that there are still very serious problems
with text and binary I/O in DJGPP, Cygwin-b20 and mingw32
using Cygwin-b20 bash and MS-DOS Prompt under Windows 98.

Also, all the information regarding text and binary I/O
seems to be scattered across many different documents.
I think it would help me and other portable application
programmers if someone could put it all together
in one place with expicit references to the specific
operating system, compiler and shell to which it applies.

Thanks in advance, E. Robert Tisdale <edwin@netwood.net>

NOTE:   My editor, `vi', displays a carriage return as ^M
        but the line feed at the end of the line is invisible.
        My DOS shell is C:\WINDOWS\COMMAND.COM



--
Want to unsubscribe from this list?
Send a message to cygwin-unsubscribe@sourceware.cygnus.com