~pbzip2/pbzip2/1.1

« back to all changes in this revision

Viewing changes to pbzip2.cpp

  • Committer: Yavor Nikolov
  • Date: 2014-04-13 20:13:34 UTC
  • mfrom: (35.2.7 1.1.9-dev)
  • Revision ID: nikolov.javor@gmail.com-20140413201334-ov3iynehwngnflng
Tags: pbzip2-1.1.9
Release 1.1.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 *      File  : pbzip2.cpp
3
 
 *
4
 
 *      Title : Parallel BZIP2 (pbzip2)
5
 
 *
6
 
 *      Author: Jeff Gilchrist (http://gilchrist.ca/jeff/)
 
2
 *  File  : pbzip2.cpp
 
3
 *
 
4
 *  Title : Parallel BZIP2 (pbzip2)
 
5
 *
 
6
 *  Author: Jeff Gilchrist (http://gilchrist.ca/jeff/)
7
7
 *           - Modified producer/consumer threading code from
8
8
 *             Andrae Muys <andrae@humbug.org.au.au>
9
9
 *           - uses libbzip2 by Julian Seward (http://sources.redhat.com/bzip2/)
10
10
 *           - Major contributions by Yavor Nikolov <nikolov.javor+pbzip2@gmail.com>
11
11
 *
12
 
 *      Date  : Jun 10, 2012
13
 
 *
14
 
 *  TODO
15
 
 *  Known Issues
16
 
 *   - direct decompress: (bzerr == BZ_DATA_ERROR_MAGIC) - on rewrite mode
17
 
 *     is handled as cat which is counter-intuitive (though similar to bzip2 handling).
18
 
 *   - some functions are too-long -> harder to maintain (e.g. main)
19
 
 *
20
 
 *  Contributions
21
 
 *  -------------
22
 
 *  Bryan Stillwell <bryan@bokeoa.com> - code cleanup, RPM spec, prep work
23
 
 *                                                   for inclusion in Fedora Extras
24
 
 *  Dru Lemley [http://lemley.net/smp.html] - help with large file support
25
 
 *  Kir Kolyshkin <kir@sacred.ru> - autodetection for # of CPUs
26
 
 *  Joergen Ramskov <joergen@ramskov.org> - initial version of man page
27
 
 *  Peter Cordes <peter@cordes.ca> - code cleanup
28
 
 *  Kurt Fitzner <kfitzner@excelcia.org> - port to Windows compilers and
29
 
 *                                         decompression throttling
30
 
 *  Oliver Falk <oliver@linux-kernel.at> - RPM spec update
31
 
 *  Jindrich Novy <jnovy@redhat.com> - code cleanup and bug fixes
32
 
 *  Benjamin Reed <ranger@befunk.com> - autodetection for # of CPUs in OSX
33
 
 *  Chris Dearman <chris@mips.com> - fixed pthreads race condition
34
 
 *  Richard Russon <ntfs@flatcap.org> - help fix decompression bug
35
 
 *  Paul Pluzhnikov <paul@parasoft.com> - fixed minor memory leak
36
 
 *  Aníbal Monsalve Salazar <anibal@debian.org> - creates and maintains Debian packages
37
 
 *  Steve Christensen - creates and maintains Solaris packages (sunfreeware.com)
38
 
 *  Alessio Cervellin - creates and maintains Solaris packages (blastwave.org)
39
 
 *  Ying-Chieh Liao - created the FreeBSD port
40
 
 *  Andrew Pantyukhin <sat@FreeBSD.org> - maintains the FreeBSD ports and willing to
41
 
 *                                        resolve any FreeBSD-related problems
42
 
 *  Roland Illig <rillig@NetBSD.org> - creates and maintains NetBSD packages
43
 
 *  Matt Turner <mattst88@gmail.com> - code cleanup
44
 
 *  Álvaro Reguly <alvaro@reguly.com> - RPM spec update to support SUSE Linux
45
 
 *  Ivan Voras <ivoras@freebsd.org> - support for stdin and pipes during compression and
46
 
 *                                    CPU detect changes
47
 
 *  John Dalton <john@johndalton.info> - code cleanup and bug fixes for stdin support
48
 
 *  Rene Georgi <rene.georgi@online.de> - code and Makefile cleanup, support for direct
49
 
 *                                        decompress and bzcat
50
 
 *  René Rhéaume & Jeroen Roovers <jer@xs4all.nl> - patch to support uclibc's lack of
51
 
 *                                                  a getloadavg function
52
 
 *  Reinhard Schiedermeier <rs@cs.hm.edu> - support for tar --use-compress-prog=pbzip2
53
 
 *  Elbert Pol - creates and maintains OS/2 packages
54
 
 *  Nico Vrouwe <nico@gojelly.com> - support for CPU detection on Win32
55
 
 *  Eduardo Terol <EduardoTerol@gmx.net> - creates and maintains Windows 32bit package
56
 
 *  Nikita Zhuk <nikita@zhuk.fi> - creates and maintains Mac OS X Automator action and
57
 
 *                                 workflow/service
58
 
 *  Jari Aalto <jari.aalto@cante.net> - Add long options to -h output.
59
 
 *                                      Add --loadavg, --read long options.
60
 
 *  Scott Emery <emery@sgi.com> - ignore fwrite return and pass chown errors in
61
 
 *                                writeFileMetaData if effective uid root
62
 
 *  Steven Chamberlain <steven@pyro.eu.org> - code to support throttling compression to
63
 
 *                                            prevent memory exhaustion with slow output
64
 
 *                                            pipe
65
 
 *  Yavor Nikolov <nikolov.javor+pbzip2@gmail.com> - code to support throttling compression to
66
 
 *                      prevent memory exhaustion with slow output, cleanup of debug output
67
 
 *                    - fixed infinite loop on when fileWriter fails to create output file
68
 
 *                      at start
69
 
 *                    - allDone renamed to producerDone and added mutex synchronized-access
70
 
 *                    - Changed fileWriter loop exit condition: now protected from
71
 
 *                      simultaneous access
72
 
 *                    - Mutex initialization/disposal refactored
73
 
 *                    - Throttling loops using thread condition wait
74
 
 *                    - Fatal error handling refactored
75
 
 *                    - Removed allDone checks used to signal error (now handled by
76
 
 *                      handle_error function)
77
 
 *                    - Prevented dangling threads on switch from Multi to Single threaded
78
 
 *                    - Inline hint added on a few functions
79
 
 *                    - Some additional error_handlers placed instead of returns (kill any
80
 
 *                      dangling threads)
81
 
 *                    - Cleanup and termination changed in attempt to prevent
82
 
 *                      signal-handling issues in mulit-threaded environment (still some
83
 
 *                      problems are observed on signalling e.g. with Ctrl+C)
84
 
 *                    - Signal-handling in child threads disabled. The goal is to have
85
 
 *                      single thread only which accepts signals
86
 
 *                    - Using abort instead of exit on error termination
87
 
 *                    - Fixed command-line parsing problem (e.g. -m100 -p12 -> 120 CPUs)
88
 
 *                      (Problem was unterminated strings afer strncpy).
89
 
 *                    - Signal handlers setup refactored to separate function and
90
 
 *                      switched from signal to sigaction as per POSIX recommendations
91
 
 *                    - Added mutexes unlocking before error-termination.
92
 
 *                    - Termination flag introduced (terminateFlag) to indicate abrupt
93
 
 *                      termination and facilitate thread finishing in error conditon.
94
 
 *                    - fileWriter: error_handler instead of exit on write error.
95
 
 *                    - percentComplete progress printed only if changed.
96
 
 *                    - signal handling redesigned: using sigwait in separate thread.
97
 
 *                    - Makefile: -D_POSIX_PTHREAD_SEMANTICS (used in Solaris).
98
 
 *                    - CHAR_BIT instead of 8 used in a warning message.
99
 
 *                    - SIGUSR1 signal handling added and used to terminate signal handling
100
 
 *                      thread. (Resolved issue with pthread_cancel on Windows-Cygwin)
101
 
 *                    - Fixed wrongly issued exit code 1 instead of 0.
102
 
 *                    - Corrected some error messages and added a few new ones at signal and
103
 
 *                      terminator threads join.
104
 
 *                    - Added support for thread stack size customization (-S# option)
105
 
 *                      Needs USE_STACKSIZE_CUSTOMIZATION to be defined to enable that option
106
 
 *                    - Added define of PTHREAD_STACK_MIN if such is not available in
107
 
 *                      standard headers.
108
 
 *                    - OutputBuffer usage redesigned as fixed-size circular buffer. Adding
109
 
 *                      new elements to it refactored as separate function.
110
 
 *                    - OutputBuffer resizing removed from producer_decompress since now
111
 
 *                      buffer should be with fixed size.
112
 
 *                    - Fixed debug print of OutputBuffer now referencing OutputBuffer in
113
 
 *                      old-style absolute index (in fileWriter and others).
114
 
 *                    - memstr function implementation simplified (delegated to standard
115
 
 *                      library function which is doing the same more efficiently).
116
 
 *                    - Changed some variables from int to size_t to get rid of compiler
117
 
 *                      warnings (signed + unsigned expressions).
118
 
 *                    - Sequential processing of input file/pipe/redirect implemented (capsulated
119
 
 *                      as separate class: BZ2StreamScanner)
120
 
 *                    - Parallel decompression enabled (now possible with the sequential in)
121
 
 *                    - Refactored declarations moved to separate header file (pbzip2.h) to
122
 
 *                      make global definitions available to other source modules
123
 
 *                    - Progress reporting modified since we don't have number of
124
 
 *                      blocks up-front with sequential input read (now based on bytes). fileSize
125
 
 *                      moved as InFileSize global variable for that purpose
126
 
 *                    - Progress computation in fileWriter moved to QuietMode != 0
127
 
 *                      (not needed to do it if we won't print it)
128
 
 *                    - disposeMemory helper function implemented to ease memory disposal
129
 
 *                    - Processing functions of threads declared as extern "C" since pthread_t
130
 
 *                      requires plain "C" calling convention instead of the default "C++"
131
 
 *                    - pthread_mutex_{lock|unlock} replaced with safe_mutex_{lock|unlock}
132
 
 *                      where appropriate (to prevent from issues like out of sys mutexes)
133
 
 *                    - Makefile modified to include the new source files for BZ2StreamScanner
134
 
 *                    - Makefile refined (library flags specified in LDFLAGS variable)
135
 
 *                    - Makefile.solaris.sunstudio included as example makefile for Solaris
136
 
 *                      and SunStudio 12 C++ compiler
137
 
 *                    - bz2HeaderZero in main initialized to value 0x90 > 127 which is in general
138
 
 *                      out of char type range. Changed to unsigned along with tmpBuff to avoid
139
 
 *                      some compiler(e.g. c++0x)/runtime warnings/errors.
140
 
 *                    - Some thread conditions signalling added on termination requested to ease
141
 
 *                      termination of blocked on conditions threads
142
 
 *                    - Other pthread_* calls (signal, wait) migrated to safe_* wrappers to
143
 
 *                      handle error return codes (and simplify code where already handled)
144
 
 *                    - Timed pthread cond waits refactored to separate function and moved to
145
 
 *                      debug sections only; non-timed wait used in non-debug mode. Signalling
146
 
 *                      consitions to wake threads waiting on these conditions guaranteed.
147
 
 *                    - memstr function templetized to allow working with other data types but
148
 
 *                      not only char * (e.g. unsigned char *)
149
 
 *                    - safe_cond_broadcast implemented and additional signalling added at
150
 
 *                      fileWriter end to prevent consumers blocking at end.
151
 
 *                    - Signal error when the input file doesn't contain any bzip2 headers.
152
 
 *                    - Fixed problems with not-handling zero-file length special header on compression
153
 
 *                      and decompression.
154
 
 *                    - Signalling error on stdin decompression when file doesn't start with
155
 
 *                      correct bzip2 magic header.
156
 
 *                    - Implemented outputBufferInit(size_t size) utility function for output
157
 
 *                      buffer initialization/resetting.
158
 
 *                    - Plain C headers moved to extern "C" section.
159
 
 *                    - Modified file-names handling to avoid issues with file-sizes > 2040
160
 
 *                    - Fixed out of array pointer for OutFilename in strncasecmp calls
161
 
 *                    - A few other minor modifications
162
 
 *                                - consumer_decompress using low-level API now to improve performance of
163
 
 *                                      long bzip2 streams
164
 
 *                                - Fixed issue in safe_cond_timed_wait which caused segmentation fault
165
 
 *                                      when compiled in DEBUG mode
166
 
 *                                - Handle decompression of very long bz2 streams incrementally instead of
167
 
 *                                      loading whole streams in memory at once
168
 
 *                                - Progress calculation changed: fixed issue when large file support is
169
 
 *                                      disabled and enabled monitoring of segmented long bzip2 streams
170
 
 *                                - Fixed issue with Sun Studio compiler - required explicit declaration
171
 
 *                                      of static const members in .cpp.
172
 
 *                                - consumer_decompress throttling loosed a bit to prevent potential
173
 
 *                                      deadlock/infinite loop in certain situations. (Addition to all-empty-block
174
 
 *                                      tails in OutputBuffer is non-blocking now).
175
 
 *                                - fixed error message for block size range (max size was wrong)
176
 
 *                                - consumer_decompress: fixed bug which caused hang while decompressing
177
 
 *                                      prematurely truncated bzip2 stream.
178
 
 *                                - modified fileWriter to prevent from throttling when output buffers are full
179
 
 *                                      (condition signalling added when block is ready to wake up sleeping writer early)
180
 
 *                                - Fixed deadlock bug possible with stuck consumers waiting for other one
181
 
 *                                      on long multi-segment sequence.
182
 
 *                                - Resolved performance issue: all have been waiting for any consumer
183
 
 *                                      working on long-sequence until it's finished even when there were enough
184
 
 *                                      free slots in the input queue.
185
 
 *                    - Debug print bug fixed in queue::remove.
186
 
 *                    - Debuging and error handling improvements and refactoring.
187
 
 *                    - Fixed hang on decompress of some truncated archives (bug #590225).
188
 
 *                    - Implemented --ignore-trailing-garbage feature (bug #594868)
189
 
 *                    - Fixed hang on decompress of some truncated archives (bug #590225)
190
 
 *                    - Fixed hang on decompress with --ignore-trailing-garbage=1 and higher
191
 
 *                      numCPU (e.g. > 2) (bug #740502)
192
 
 *                    - Default extension on decompress of .tbz2 changed to .tar for 
193
 
 *                      bzip2 compatibility (bug #743639)
194
 
 *                    - Print trailing garbage errors even when in quiet mode (bug #743635)
195
 
 *                    - Fixed hang on decompress with --ignore-trailing-garbage=1 when
196
 
 *                      producer is interrupted on trailing garbage (bug #762464)
197
 
 *                    - Fixed excessive output permissions while compress/decompress
198
 
 *                      is in progress (bug #807536)
199
 
 *                    - Prevent deletion of input files on error (bug #874543)
200
 
 *                    - Add more detailed kernel error messages - inspired by 
201
 
 *                      Gordon's patch (bug #874605)
202
 
 *                    - Error-handling improvements - mainly for multi-archive
203
 
 *                      scenarios (bug #883782)
204
 
 *                    - Fixed occasional failure on decompress with --ignore-trailing-garbage=1 
205
 
 *                      with multiple bad blocks in the archive (bug #886625)
206
 
 *                    - Fixed refusal to write to stdout on -dc from stdin (bug #886628)
207
 
 *                    - Fix of metadata unpreserved on empty files compress (bug #1011021)
208
 
 *  David James - provided patch to fix deadlock due to unsynchronized broadcast (bug #876686)
209
 
 *  Gordon - provided patch for improving I/O error messages (bug #874605)
210
 
 *
211
 
 *
212
 
 *
213
 
 *  Specials thanks for suggestions and testing:  Phillippe Welsh,
214
 
 *  James Terhune, Dru Lemley, Bryan Stillwell, George Chalissery,
215
 
 *  Kir Kolyshkin, Madhu Kangara, Mike Furr, Joergen Ramskov, Kurt Fitzner,
216
 
 *  Peter Cordes, Oliver Falk, Jindrich Novy, Benjamin Reed, Chris Dearman,
217
 
 *  Richard Russon, Aníbal Monsalve Salazar, Jim Leonard, Paul Pluzhnikov,
218
 
 *  Coran Fisher, Ken Takusagawa, David Pyke, Matt Turner, Damien Ancelin,
219
 
 *  Álvaro Reguly, Ivan Voras, John Dalton, Sami Liedes, Rene Georgi,
220
 
 *  René Rhéaume, Jeroen Roovers, Reinhard Schiedermeier, Kari Pahula,
221
 
 *  Elbert Pol, Nico Vrouwe, Eduardo Terol, Samuel Thibault, Michael Fuereder,
222
 
 *  Jari Aalto, Scott Emery, Steven Chamberlain, Yavor Nikolov, Nikita Zhuk,
223
 
 *  Joao Seabra, Conn Clark, Mark A. Haun, Tim Bielawa, Michal Gorny,
224
 
 *  Mikolaj Habdank, Christian Kujau, Marc-Christian Petersen, Piero Ottuzzi,
225
 
 *  Ephraim Ofir, Laszlo Ersek, Dima Tisnek, Tanguy Fautre.
 
12
 *  Date  : Apr 13, 2014
226
13
 *
227
14
 *
228
15
 * This program, "pbzip2" is copyright (C) 2003-2011 Jeff Gilchrist.
264
51
 *
265
52
 * Jeff Gilchrist, Ottawa, Canada.
266
53
 * pbzip2@compression.ca
267
 
 * pbzip2 version 1.1.9 of Mon dd, yyyy (NOT RELEASED YET)
 
54
 * pbzip2 version 1.1.9 of Apr 13, 2014
268
55
 *
269
56
 */
 
57
 
270
58
#include "pbzip2.h"
271
59
#include "BZ2StreamScanner.h"
272
60
#include "ErrorContext.h"
1135
923
        if ( hasTrailingGarbage( bzret, fileData, strm ) )
1136
924
        {
1137
925
                // Potential trailing garbage
1138
 
                return decompressErrCheckSingle(bzret, fileData, outSequenceNumber,     strm,
 
926
                return decompressErrCheckSingle(bzret, fileData, outSequenceNumber, strm,
1139
927
                                "*ERROR during BZ2_bzDecompress - trailing garbage", true);
1140
928
        }
1141
929
        else if ( (bzret != BZ_STREAM_END) && (bzret != BZ_OK) )
1142
930
        {
1143
 
                return decompressErrCheckSingle(bzret, fileData, outSequenceNumber,     strm,
 
931
                return decompressErrCheckSingle(bzret, fileData, outSequenceNumber, strm,
1144
932
                                "*ERROR during BZ2_bzDecompress - failure exit code", false);
1145
933
        }
1146
934
        else if ( strm.avail_in != 0 )
1867
1655
        char *OutFilename;
1868
1656
        OFF_T CompressedSize = 0;
1869
1657
        int percentComplete = 0;
1870
 
        int hOutfile = 1;  // default to stdout
 
1658
        int hOutfile = STDOUT_FILENO;  // default to stdout
1871
1659
        int currBlock = 0;
1872
1660
        size_t outBufferPos = 0;
1873
1661
        int ret = -1;
2084
1872
                {
2085
1873
                        ErrorContext::getInstance()->saveError();
2086
1874
                        handle_error(EF_EXIT, -1, "pbzip2: *ERROR: Could not close output file!  Aborting...\n");
2087
 
                        return (NULL);                  
 
1875
                        return (NULL);
2088
1876
                }
2089
1877
        }
2090
1878
        
2140
1928
        OFF_T inSize = 0;
2141
1929
        unsigned int outSize = 0;
2142
1930
        int percentComplete = 0;
2143
 
        int hOutfile = 1;  // default to stdout
 
1931
        int hOutfile = STDOUT_FILENO;  // default to stdout
2144
1932
        int currBlock = 0;
2145
1933
        int rret = 0;
2146
1934
        int ret = 0;
2479
2267
                                                ungetc(c,zStream);
2480
2268
                                         
2481
2269
                                                nread = fread(obuf, sizeof(unsigned char), sizeof(obuf), zStream );
2482
 
                                        if (ferror(zStream))
 
2270
                                                if (ferror(zStream))
2483
2271
                                                {
2484
2272
                                                        ret = testBZ2ErrorHandling(bzerr, bzf, streamNo);
2485
2273
                                                        if (zStream != stdin)
2507
2295
                                                        if (ret != 0)
2508
2296
                                                        {
2509
2297
                                                                syncSetTerminateFlag(1);
2510
 
                                                        }                       
 
2298
                                                        }
2511
2299
                                                        
2512
2300
                                                        return ret;
2513
2301
                                                }
2599
2387
        if (ferror(stream))
2600
2388
        {
2601
2389
                if (stream != stdout)
2602
 
                        fclose(stream); 
 
2390
                        fclose(stream);
2603
2391
                handle_error(EF_EXIT, -1, "pbzip2: *ERROR: Problem with output stream of file [%s]!  Skipping...\n", InFilename);
2604
2392
                
2605
2393
                return -1;
3226
3014
                        return 1;
3227
3015
                        break;
3228
3016
                case BZ_DATA_ERROR:
3229
 
                        fprintf(stderr, "pbzip2: *ERROR: Data integrity (CRC) error in data!  Skipping...\n");
 
3017
                        fprintf(stderr, "pbzip2: *ERROR: Data integrity (CRC) error in data!  Skipping...\n");
3230
3018
                        return -1;
3231
3019
                        break;
3232
3020
                case BZ_MEM_ERROR:
3234
3022
                        return 1;
3235
3023
                        break;
3236
3024
                case BZ_UNEXPECTED_EOF:
3237
 
                        fprintf(stderr, "pbzip2: *ERROR: File ends unexpectedly!  Skipping...\n");
 
3025
                        fprintf(stderr, "pbzip2: *ERROR: File ends unexpectedly!  Skipping...\n");
3238
3026
                        return -1;
3239
3027
                        break;
3240
3028
                case BZ_DATA_ERROR_MAGIC:
3289
3077
                }
3290
3078
        }
3291
3079
        else
 
3080
        {
3292
3081
                zStream = stdin;
 
3082
        }
3293
3083
 
3294
3084
        // check file stream for errors
3295
3085
        if (ferror(zStream))
3479
3269
 */
3480
3270
void banner()
3481
3271
{
3482
 
        fprintf(stderr, "Parallel BZIP2 v1.1.9dev1 - by: Jeff Gilchrist [http://compression.ca]\n");
3483
 
        fprintf(stderr, "[Jun. 10, 2012]               (uses libbzip2 by Julian Seward)\n");
3484
 
        fprintf(stderr, "                              (unstable development revision)\n");     
 
3272
        fprintf(stderr, "Parallel BZIP2 v1.1.9     - by: Jeff Gilchrist [http://compression.ca]\n");
 
3273
        fprintf(stderr, "[Apr. 13, 2014]               (uses libbzip2 by Julian Seward)\n");
3485
3274
        fprintf(stderr, "Major contributions: Yavor Nikolov <nikolov.javor+pbzip2@gmail.com>\n");
3486
3275
 
3487
3276
        return;
3598
3387
        int fileLoop;
3599
3388
        size_t i, j, k;
3600
3389
        bool switchedMtToSt = false; // switched from multi- to single-thread
3601
 
        
 
3390
 
3602
3391
        // Initialize error context
3603
3392
        if (ErrorContext::getInstance() == NULL)
3604
3393
        {
3605
3394
                return 1;
3606
 
        }       
3607
 
        
 
3395
        }
 
3396
 
3608
3397
        // get current time for benchmark reference
3609
3398
        #ifndef WIN32
3610
3399
        gettimeofday(&tvStartTime, &tz);
4028
3817
                        fprintf(stderr, "Load Avg1: %f  Avg5: %f  Avg15: %f\n", loadAvgArray[0], loadAvgArray[1], loadAvgArray[2]);
4029
3818
                        #endif
4030
3819
                        // use 1 min load average to adjust number of processors used
4031
 
                        loadAverage = loadAvgArray[0];  // use [1] for 5 min average and [2] for 15 min average
 
3820
                        loadAverage = loadAvgArray[0]; // use [1] for 5 min average and [2] for 15 min average
4032
3821
                        // total number processors minus load average rounded up
4033
3822
                        numCPUidle = numCPUtotal - (int)(loadAverage + 0.5);
4034
3823
                        // if user asked for a specific # processors and they are idle, use all requested
4309
4098
                                zeroByteFile = 1;
4310
4099
                        }
4311
4100
                        else
 
4101
                        {
4312
4102
                                zeroByteFile = 0;
 
4103
                        }
4313
4104
 
4314
4105
                        // get file meta data to write to output file
4315
4106
                        if (getFileMetaData(InFilename) != 0)
4322
4113
                }
4323
4114
                else
4324
4115
                {
4325
 
                        hInfile = 0;    // stdin
4326
 
                        InFileSize = -1;        // fake it
 
4116
                        hInfile = STDIN_FILENO; // stdin
 
4117
                        InFileSize = -1; // fake it
4327
4118
                }
4328
4119
 
4329
4120
                // check to see if output file exists
4330
4121
                if ((OutputStdOut == 0) && check_file_exists(outFilename.c_str()))
4331
 
                {       
 
4122
                {
4332
4123
                        if (force != 1)
4333
4124
                        {
4334
4125
                                fprintf(stderr, "pbzip2: *ERROR: Output file [%s] already exists!  Use -f to overwrite...\n", outFilename.c_str());
4344
4135
 
4345
4136
                if (readEntireFile == 1)
4346
4137
                {
4347
 
                        if (hInfile == 0) 
 
4138
                        if (hInfile == STDIN_FILENO) 
4348
4139
                        {
4349
4140
                                if (QuietMode != 1)
4350
4141
                                        fprintf(stderr, " *Warning: Ignoring -r switch since input is stdin.\n");
4360
4151
                if (QuietMode != 1)
4361
4152
                {
4362
4153
                        fprintf(stderr, "         File #: %d of %d\n", fileLoop+1, FileListCount);
4363
 
                        fprintf(stderr, "     Input Name: %s\n", hInfile != 0 ? InFilename : "<stdin>");
 
4154
                        fprintf(stderr, "     Input Name: %s\n", hInfile != STDIN_FILENO ? InFilename : "<stdin>");
4364
4155
 
4365
4156
                        if (OutputStdOut == 0)
4366
4157
                                fprintf(stderr, "    Output Name: %s\n\n", outFilename.c_str());
4408
4199
                        // write special compressed data for special 0 byte input file case
4409
4200
                        if (zeroByteFile == 1)
4410
4201
                        {
4411
 
                                hOutfile = 1;
 
4202
                                hOutfile = STDOUT_FILENO;
4412
4203
                                // write to file instead of stdout
4413
4204
                                if (OutputStdOut == 0)
4414
4205
                                {
4462
4253
                                                if (do_remove(InFilename) == -1)
4463
4254
                                                {
4464
4255
                                                        handle_error(EF_NOQUIT, 1, "Can't remove input file [%s]!", InFilename);
4465
 
                                                }       
 
4256
                                                }
4466
4257
                                        }
4467
4258
                                }
4468
4259
                                continue;
4552
4343
                                                handle_error(EF_EXIT, 1,
4553
4344
                                                                "pbzip2: *ERROR: Error joining fileWriter thread (code = %d)  Aborting...\n", ret);
4554
4345
                                                errLevelCurrentFile = errLevel = 1;
4555
 
                                                ret = pthread_join(TerminatorThread, NULL);                                             
4556
 
                                                return 1;                                               
 
4346
                                                ret = pthread_join(TerminatorThread, NULL);
 
4347
                                                return 1;
4557
4348
                                        }
4558
4349
                                }
4559
4350
                                else if (ret != 0)
4631
4422
                        // wait for fileWriter thread to exit
4632
4423
                        ret = pthread_join(output, NULL);
4633
4424
                        if (ret != 0)
4634
 
                        {       
 
4425
                        {
4635
4426
                                ErrorContext::printErrnoMsg(stderr, errno);
4636
4427
                                errLevelCurrentFile = errLevel = 1;
4637
4428
                        }
4649
4440
                                        errLevelCurrentFile = errLevel = 1;
4650
4441
                                }
4651
4442
                        }
4652
 
                }
 
4443
                }
4653
4444
 
4654
4445
                if (syncGetTerminateFlag() != 0)
4655
4446
                {
4680
4471
                                if (do_remove(InFilename) == -1)
4681
4472
                                {
4682
4473
                                        handle_error(EF_NOQUIT, 1, "Can't remove input file [%s]!", InFilename);
4683
 
                                }       
 
4474
                                }
4684
4475
                        }
4685
4476
                }
4686
4477