www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1999/01/06/10:05:42

Date: Wed, 6 Jan 1999 14:41:41 +0200 (IST)
From: Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
X-Sender: eliz AT is
To: Doug Kaufman <dkaufman AT rahul DOT net>
cc: djgpp AT delorie DOT com
Subject: Re: ANNOUNCE: bzip2 port to DJGPP
In-Reply-To: <76ugnl$17u$1@samba.rahul.net>
Message-ID: <Pine.SUN.3.91.990106143739.9201A-100000@is>
MIME-Version: 1.0
Reply-To: djgpp AT delorie DOT com

(Yeah, I know I should write a tutorial on porting Unix software, but 
where do I get the time??  Hopefully, this will be useful to people out 
there.)

On 6 Jan 1999, Doug Kaufman wrote:

> "http://www.rahul.net/dkaufman/bzip2-0.9.0c-DOS.zip" or
> "ftp://ftp.rahul.net/pub/dkaufman/bzip2-0.9.0c-DOS.zip"

Thanks for your efforts in porting this.

I took a quick look at this port.  Here are some comments.

> I believe that long filenames will probably be preserved under Windows9x

No, they aren't.  The ported program works on Windows 9X exactly as it
does on plain DOS.  For example, `foo.bar' is compressed into
`foo_bar.bz2', not into `foo.bar.bz2' as a Windows user would expect.

The reason for this is that your code which handles DOS 8+3 file name
limitations is compiled unconditionally:

+ #ifdef __DJGPP__
+ 		   dot=strrchr(outName, '.');
+ 		   if ((dot != NULL) && (strlen(dot) >0) && (strchr(dot, '/') == NULL) && (strchr(dot, '\\') == NULL)) {
+ 		   strncpy(outName1, outName, strlen(outName) - strlen(dot));
+ 		   if  (strlen(dot) > 1) {
+ 		   strcat (outName1, "_");
+ 		   strcat (outName1, dot+1); }
+ 		   strcpy (outName, outName1);
+ 		   }
+ #endif /*  __DJGPP__ */


If you want to have a program that behaves on Windows 9X as it does on
Unix, you need to replace the #ifdef with a run-time test.  For
example, like this:

	 if (pathconf (outName, _PC_NAME_MAX) <= 12)
	   {
	     /* put here the code for MS-DOS */
	   }

There are other problems with the handling of file names.  Here's one:

       prompt> touch foo.bar.c
       prompt> bzip2 foo.bar.c
       
       bzip2.exe: I/O or other error, bailing out.  Possible reason follows.
       bzip2.exe: Permission denied (EACCES)
               Input file = foo.bar.c, output file = foo.bar_c.bz2

I didn't have time to debug this problem, but one possible reason is
that you assume the input file has only one dot, which is not true on
Windows 9X.

+ #ifdef __DJGPP__
+ 	setmode(fileno(stdout), O_TEXT);
+ #endif /* __DJGPP__ */
     fprintf (
+ #ifdef __DJGPP__
+       stdout,
+ #else
        stderr,
+ #endif /* __DJGPP__ */

Why is this patch required?  If you needed it because DOS cannot
easily redirect stderr, then I suggest to convince the author to print
the usage information to stdout on ALL platforms.  The usual
conventions are that only error messages go to stderr, and usage info
is not an error message.

But if the author of Bzip2 is unconvinced, and feels that usage info
should be printed to stderr, it is IMHO a bad idea to make the DJGPP
version deviate from this behavior.  In my experience, platform-
dependent behavior should be avoided at all costs (for starters, it
makes the docs messy and confusing).

+ #ifndef __DJGPP__
     signal (SIGBUS,  mySIGSEGVorSIGBUScatcher);
+ #endif

It would be much cleaner if you say "#ifdef SIGBUS" instead of
"#ifndef __DJGPP__".  What if DJGPP will support SIGBUS some day?
What about other platforms which don't support SIGBUS--do they need to
add their own #ifndef's as well?

A similar consideration applies to the problem with lstat: you should
test whether the macro S_ISLNK is defined instead of testing
__DJGPP__.

The principle is to test for missing or available functionality, not
for a system- or compiler-specific symbol.

+        setmode( fileno( stdin ), O_BINARY );
+        setmode( fileno( stdout ), O_BINARY );

Now, that is an absolute no-no.  You should *never* switch
stdin/stdout to binary mode unconditionally, especially in programs
that read from stdin if invoked with no arguments.  If you need a
quick demo why this is so, save all your data, take a deep breath, and
type this from the DOS prompt:

	  bzip2 > foo

See what I mean?  You end up with a wedged machine.  This happens
because switching the console device to binary mode has a side effect
of disabling the special meaning of Ctrl-Z (so you cannot signal an
end-of-file), and it also disables SIGINT generation by Ctrl-C (so you
cannot even interrupt the sucker).  The program works perfectly, reading 
characters you type at the keyboard, but there's no eacho and no easy way 
to interrupt the program.

Most  people will at this point decide that the program is crap and 
delete it.

Even if you compress a file, not stdin, switching stdout
unconditionally to binary has nasty side effects: for example, TABs
are displayed like a single graphic character instead of 8 spaces.

Therefore, setting stdin/stdout to binary mode should only be done if
they are NOT connected to the console device, like this:

     if (!isatty (fileno (stdin)))
       setmode (fileno (stdin), O_BINARY);

Btw, here, too, you should condition this code on O_BINARY being
defined (and being non-zero) rather than on __DJGPP__.

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019