Date: Wed, 6 Jan 1999 14:41:41 +0200 (IST) From: Eli Zaretskii X-Sender: eliz AT is To: Doug Kaufman cc: djgpp AT delorie DOT com Subject: Re: ANNOUNCE: bzip2 port to DJGPP In-Reply-To: <76ugnl$17u$1@samba.rahul.net> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII 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__.