diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/dktools/dk-blks.ctr |
Initial commit
Diffstat (limited to 'support/dktools/dk-blks.ctr')
-rw-r--r-- | support/dktools/dk-blks.ctr | 959 |
1 files changed, 959 insertions, 0 deletions
diff --git a/support/dktools/dk-blks.ctr b/support/dktools/dk-blks.ctr new file mode 100644 index 0000000000..12829bc381 --- /dev/null +++ b/support/dktools/dk-blks.ctr @@ -0,0 +1,959 @@ +%% options + +copyright owner = Dirk Krause +copyright year = 2015-xxxx +license = bsd + + + +%% module + +/** @file dk-blks.c The dk-blks program. + the help_text array below shows details. +*/ + + + +#include "dk4conf.h" + +#include <stdio.h> +#if DK4_HAVE_STDLIB_H +#ifndef STDLIB_H_INCLUDED +#include <stdlib.h> +#define STDLIB_H_INCLUDED 1 +#endif +#endif + +#if DK4_HAVE_IO_H +#ifndef IO_H_INCLUDED +#include <io.h> +#define IO_H_INCLUDED 1 +#endif +#endif + +#if DK4_HAVE_UNISTD_H +#ifndef UNISTD_H_INCLUDED +#include <unistd.h> +#define UNISTD_H_INCLUDED 1 +#endif +#endif + +#if DK4_HAVE_PROCESS_H +#ifndef PROCESS_H_INCLUDED +#include <process.h> +#define PROCESS_H_INCLUDED 1 +#endif +#endif + +#if DK4_HAVE_SYS_TYPES_H +#ifndef SYS_TYPES_H_INCLUDED +#include <sys/types.h> +#define SYS_TYPES_H_INCLUDED 1 +#endif +#endif + +#if DK4_HAVE_SIGNAL_H +#ifndef SIGNAL_H_INCLUDED +#include <signal.h> +#define SIGNAL_H_INCLUDED 1 +#endif +#endif + +#if DK4_HAVE_ERRNO_H +#ifndef ERRNO_H_INCLUDED +#include <errno.h> +#define ERRNO_H_INCLUDED 1 +#endif +#endif + +#if DK4_HAVE_FCNTL_H +#ifndef FCNTL_H_INCLUDED +#include <fcntl.h> +#define FCNTL_H_INCLUDED 1 +#endif +#endif + +#if DK4_HAVE_STRING_H +#ifndef STRING_H_INCLUDED +#include <string.h> +#define STRING_H_INCLUDED 1 +#endif +#endif + +#include "dk4types.h" +#include "dk4const.h" +#include "dk4vers.h" +#include "dk4app.h" +#include "dk4aopt.h" +#include "dk4mem.h" +#include "dk4mema.h" +#include "dk4memrs.h" +#include "dk4numco.h" +#include "dk4fdrde.h" +#include "dk4fdwre.h" + + + +$!trace-include + + + +#ifndef DK_BLKS_DEFAULT_BLOCK_SIZE +/** Default suitable for hard disks. +*/ +#define DK_BLKS_DEFAULT_BLOCK_SIZE 4096 +#endif + + + +/** Default help text, shown if help text file is not found. +*/ +static const dkChar * const help_text[] = { +$!text macro=dkT,preprocessor + +Create sequence of fixed size blocks. + +dk-blks [<options>] + +Options: +-b <size> Block size, positive integer number. + You can append `k', `m', `g', or `t' for multiples of 1024 + or powers of it (i.e. 4k = 4096 bytes, 1m = 1048576 bytes...). + +--help Show this short help text. +--manual *** SHOW FULL MANUAL. *** +--version Show version information. +--license Show license information. + +http://dktools.sourceforge.net + +$!end +}; + + +/** License conditions. +*/ +static const dkChar * const license_text[] = { +$!text macro=dkT,preprocessor +This software uses code from the following projects, either directly or as +a library: + +dktools Dirk Krause's tools and libraries. + See http://dktools.sourceforge.net/ for more information. +#if DK4_HAVE_ZLIB_H + +zlib Data compression library. + See http://www.zlib.net/ for more information. +#endif +#if DK4_HAVE_BZLIB_H + +bzip2 Data compression program and library. + See http://www.bzip.org/ for more information. +#endif + +All the licenses below apply to the program. +Licenses for used libraries are shown as found on my Scientific Linux 6.x +computer in the /usr/share/doc directory on 2015-04-01. Check the project +homepages of the used libraries for additional information and/or updated +license terms. + + +DK tools and libraries license +============================== +Copyright (c) 2015-2016, Dirk Krause +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of the Dirk Krause nor the names of contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. + +IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#if DK4_HAVE_ZLIB_H + + +Zlib license +============ +(C) 1995-2004 Jean-loup Gailly and Mark Adler + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +Jean-loup Gailly Mark Adler +jloup@gzip.org madler@alumni.caltech.edu +#endif +#if DK4_HAVE_BZLIB_H + + +Bzip2 and libbzip2 library license +================================== +This program, "bzip2", the associated library "libbzip2", and all +documentation, are copyright (C) 1996-2007 Julian R Seward. All +rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. The origin of this software must not be misrepresented; you must + not claim that you wrote the original software. If you use this + software in a product, an acknowledgment in the product + documentation would be appreciated but is not required. + +3. Altered source versions must be plainly marked as such, and must + not be misrepresented as being the original software. + +4. The name of the author may not be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Julian Seward, jseward@bzip.org +bzip2/libbzip2 version 1.0.5 of 10 December 2007 +#endif + +$!end +}; + + + +/** Options used by program. +*/ +static const dk4_option_specification_t options[] = { + { dkT('b'), dkT("block-size"), DK4_OPT_ARG_SIZE } +}; + +/** Number of elements in options array. +*/ +static const size_t sz_options = +sizeof(options)/sizeof(dk4_option_specification_t); + + + +/** Keywords used by the program, not localized. +*/ +static const dkChar * const kwnl[] = { +$!string-table macro=dkT +# +# 0 Program group name +# +dktools +# +# 1 Help text file name +# +dk-blks.txt +# +# 2 String table file name +# +dk-blks.str +# +# 3 4 File names for reporting read and write errors +# +stdin +stdout +$!end +}; + + + +/** Constant texts used by the program, replaced by localized texts + if available. +*/ +static const dkChar * const kw_def[] = { +$!string-table macro=dkT +# +# 0 Error message: Not all bytes written +# +Write operation partially failed! +# +# 1 Error message: Failed to clean up buffer +# +Failed to cleanup buffer! +# +# 2 Error message: Block size too large! +# +Block size too large! +# +# 3 Error message: Block size must not be 0! +# +Block size must not be 0! +# +# 4 Error message: Failed to set up signal handlers! +# +Failed to set up signal handlers! +# +# 5 Error message: Failed to restore signal handlers! +# +Failed to restore signal handlers! +# +# 6 Error message: Signal SIGPIPE received! +# +Signal SIGPIPE received, write operation failed! +# +# 7 Error message: Signal SIGINT received! +# +Signal SIGINT received, program aborted! +# +# 8 9 Error message: Unexpected command line argument ... ignored! +# +Unexpected command line argument " +" ignored! +$!end +}; + + + +/** Message texts, localized texts are used if available. +*/ +static const dkChar * const *dk_blks_msg = kw_def; + + + +/** Number of elements in dk_blks_msg array. +*/ +static size_t sz_msg = +sizeof(kw_def)/sizeof(DK4_PCDKCHAR) - 1; + + + +/** Exit status code. +*/ +static int exval = EXIT_FAILURE; + + + +/** Application structure. +*/ +static dk4_app_t *app = NULL; + + + +/** Input buffer for buffer sizes up to DK_BLKS_DEFAULT_BLOCK_SIZE. +*/ +static char default_input_buffer[DK_BLKS_DEFAULT_BLOCK_SIZE]; + + + +/** Output buffer for buffer sizes up to DK_BLKS_DEFAULT_BLOCK_SIZE. +*/ +static char default_output_buffer[sizeof(default_input_buffer)]; + + + +#ifdef RW_MAX +#undef RW_MAX +#endif + +#if DK4_ON_WINDOWS +/** Maximum number of bytes for read or write operation. +*/ +#define RW_MAX (INT_MAX) +#else +/** Maximum number of bytes for read or write operation. +*/ +#define RW_MAX ((SIZE_MAX) / 2U) +#endif + + + +#ifdef SIGPIPE +/** Indicator: SIGPIPE signal received. +*/ +static +DK4_VOLATILE +dk4_sig_atomic_t sig_had_pipe = 0; +#endif + +/** Indicator: SIGINT signal received. +*/ +static +DK4_VOLATILE +dk4_sig_atomic_t sig_had_int = 0; + +/** Indicator: SIGTERM signal received. +*/ +static +DK4_VOLATILE +dk4_sig_atomic_t sig_had_term = 0; + +static +DK4_VOLATILE +dk4_sig_atomic_t * +sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr) +{ + return ptr; +} + +#ifdef SIGPIPE +/** Handler for SIGPIPE signal. + @param signo Signal number (always SIGPIPE, ignored). +*/ +static +void +sig_handler_pipe(int signo) +{ + *sig_pass_pointer(&sig_had_pipe) = 1; +} +#endif + +/** Handler for SIGINT signal. + @param signo Signal number (always SIGINT, ignored). +*/ +static +void +sig_handler_int(int signo) +{ + *sig_pass_pointer(&sig_had_int) = 1; +} + +/** Handler for SIGTERM signal. + @param signo Signal number (always SIGTERM, ignored). +*/ +static +void +sig_handler_term(int signo) +{ + *sig_pass_pointer(&sig_had_term) = 1; +} + +/** Read value from volatile atomic type. + This function is necessary as some compilers mis-optimize + direct access to volatile variables (at least if you believe + one of the coding standards). + @param ap Pointer to volatile atomic variable. + @return Contents of the variable. +*/ +static +dk4_sig_atomic_t +sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap) +{ + return (*ap); +} + +/** Check whether we can continue or if a signal was received. + @param check_pipe Flag: Check for occured SIGPIPE signal too. + @return 1 if the program can continue, 0 if a signal was received. +*/ +static +int +sig_can_continue(int check_pipe) +{ + int back = 1; +#ifdef SIGPIPE + if (0 != check_pipe) { + if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; } + } +#endif + if (0 != sig_read_atomic(&sig_had_int )) { back = 0; } + if (0 != sig_read_atomic(&sig_had_term)) { back = 0; } + return back; +} + + + +static +void +dk_blks_transfer(char *ib, char *ob, size_t bs) +{ + int cc = 1; /* Flag: Can continue */ + size_t irdb = 0; /* Bytes in input buffer */ + size_t iused = 0; /* Input bytes used */ + size_t oused = 0; /* Output bytes used */ + size_t iavail; /* Input bytes available */ + size_t oavail; /* Output bytes available */ + size_t bcp; /* Bytes to copy */ +#if DK4_ON_WINDOWS + int rdres; /* Number of bytes read */ + int wrres; /* Number of bytes written */ +#else + ssize_t rdres; /* Number of bytes read */ + ssize_t wrres; /* Number of bytes written */ +#endif + dk4_sig_atomic_t shp; /* Had pipe */ + $? "+ dk_blks_transfer" + /* Process input + */ + exval = EXIT_SUCCESS; + do { + if (1 == sig_can_continue(0)) { + errno = 0; $? ". attempt to read" +#if DK4_ON_WINDOWS + rdres = _read(0, ib, (unsigned)bs); +#else + rdres = read(0, ib, bs); +#endif + if (0 < rdres) { $? ". bytes found %u", (unsigned)rdres + irdb = rdres; + iused = 0; + while(iused < irdb) { + /* Find number of bytes we can add to output buffer */ + iavail = irdb - iused; + oavail = bs - oused; + if (iavail < oavail) { + bcp = iavail; + } else { + bcp = oavail; + } + /* Add bytes to output buffer */ + DK4_MEMCPY(&(ob[oused]), &(ib[iused]), bcp); + /* Increased number of used bytes for both input and output */ + oused += bcp; + iused += bcp; + /* Flush output buffer when full */ + if (oused >= bs) { +#ifdef SIGPIPE + shp = sig_read_atomic(&sig_had_pipe); +#else + shp = 0; +#endif + if (0 == shp) { + errno = 0; +#if DK4_ON_WINDOWS + wrres = _write(1, ob, (unsigned)bs); +#else + wrres = write(1, ob, bs); +#endif + if (0 <= wrres) { + if (wrres < bs) { + /* ERROR: Not all bytes written */ + dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 0); + exval = EXIT_FAILURE; + cc = -1; + } + } else { + /* ERROR Write attempt failed */ + dk4fd_write_error_msg(app, kwnl[4], errno); + exval = EXIT_FAILURE; + cc = -1; + } + } + oused = 0; + } + } + } else { + if (0 == rdres) { $? ". end of input" + cc = 0; + } else { $? ". read error" + /* ERROR: Read operation failed */ + dk4fd_read_error_msg(app, kwnl[3], errno); + cc = 0; + exval = EXIT_FAILURE; + } + } +#if DK4_ON_WINDOWS + if (_eof(0)) { + cc = 0; + } +#endif + } else { + cc = -1; + } + } while (1 == cc); + + /* Flush output buffer */ + if (0 == cc) { + if (0 < oused) { +#ifdef SIGPIPE + shp = sig_read_atomic(&sig_had_pipe); +#else + shp = 0; +#endif + if (0 == shp) { + errno = 0; +#if DK4_ON_WINDOWS + wrres = _write(1, ob, (unsigned)oused); +#else + wrres = write(1, ob, oused); +#endif + if (0 <= wrres) { + if (wrres < oused) { + /* ERROR: Not all bytes written */ + dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 0); + exval = EXIT_FAILURE; + } + } else { + /* ERROR: Write attempt failed */ + dk4fd_write_error_msg(app, kwnl[4], errno); + exval = EXIT_FAILURE; + } + } + } + } + + /* Finally zero-fill used buffers. + */ + if (0 == dk4mem_reset_secure(ib, bs, NULL)) { + /* ERROR: Secure memory reset failed */ + dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 1); + exval = EXIT_FAILURE; + } + if (0 == dk4mem_reset_secure(ob, bs, NULL)) { + /* ERROR: Secure memory reset failed */ + dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 1); + exval = EXIT_FAILURE; + } + + $? "- dk_blks_transfer" +} + + + +static +void +dk_blks_with_buffers(char *ib, char *ob, size_t bs) +{ +#if DK4_ON_WINDOWS + int oldinmode = 0; + int oldoutmode = 0; +#endif + if ((dk4_um_t)RW_MAX >= (dk4_um_t)bs) { +#if DK4_ON_WINDOWS + oldinmode = _setmode(0, _O_BINARY); + oldoutmode = _setmode(1, _O_BINARY); +#endif + dk_blks_transfer(ib, ob, bs); +#if DK4_ON_WINDOWS + _setmode(1, oldoutmode); + _setmode(0, oldinmode); +#endif + } else { + /* ERROR: Block size too large */ + dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 2); + } +} + + + +/** Run normally. +*/ +static +void +dk_blks_normal_run(void) +{ + char *myib; + char *myob; + size_t mybs = DK_BLKS_DEFAULT_BLOCK_SIZE; + int res = 0; + $? "+ dk_blks_normal_run" + if (0 != dk4app_opt_is_set_short(app, dkT('b'), NULL)) { + res = dk4app_opt_get_size_short(&mybs, app, dkT('b'), NULL); + if (0 == res) { + mybs = DK_BLKS_DEFAULT_BLOCK_SIZE; + } + } + if ((0 < mybs) && (mybs <= DK_BLKS_DEFAULT_BLOCK_SIZE)) { + dk_blks_with_buffers( + default_input_buffer, + default_output_buffer, + mybs + ); + } else { + if (0 < mybs) { + myib = (char *)dk4mem_calloc_app(1, mybs, app); + if (NULL != myib) { + myob = (char *)dk4mem_calloc_app(1, mybs, app); + if (NULL != myob) { + dk_blks_with_buffers(myib, myob, mybs); + dk4mem_free(myob); + } + dk4mem_free(myib); + } + } else { + /* ERROR: Illegal block size */ + dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 3); + } + } + $? "- dk_blks_normal_run" +} + + + +#if DK4_HAVE_SIGACTION +/** Set signal handlers and run. +*/ +static +void +run_with_signals(void) +{ +#ifdef SIGPIPE + struct sigaction opipe; +#endif + struct sigaction oint; + struct sigaction oterm; +#ifdef SIGPIPE + struct sigaction npipe; +#endif + struct sigaction nint; + struct sigaction nterm; + int success = 0; + +#ifdef SIGPIPE + /* Set up signal handling for SIGPIPE. + */ + DK4_MEMRES(&npipe, sizeof(npipe)); + npipe.sa_handler = sig_handler_pipe; + npipe.sa_flags = 0; + if (0 != sigemptyset(&npipe.sa_mask)) { + /* ERROR: Failed to set up masked signal set for SIGPIPE */ + dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 4); + goto finished; + } + if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) { + /* ERROR: Failed to set up masked signal set for SIGPIPE */ + dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 4); + goto finished; + } + if (0 != sigaction(SIGPIPE, &npipe, &opipe)) { + /* ERROR: Failed to set up signal handler for SIGPIPE */ + dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 4); + goto finished; + } +#endif + + /* Set up signal handling for SIGINT. + */ + DK4_MEMRES(&nint, sizeof(nint)); + nint.sa_handler = sig_handler_int; + nint.sa_flags = 0; + if (0 != sigemptyset(&nint.sa_mask)) { + /* ERROR: Failed to set up masked signal set for SIGINT */ + dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 4); + goto restore_old_pipe; + } + if (0 != sigaddset(&nint.sa_mask, SIGINT)) { + /* ERROR: Failed to set up masked signal set for SIGINT */ + dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 4); + goto restore_old_pipe; + } + if (0 != sigaction(SIGINT, &nint, &oint)) { + /* ERROR: Failed to set up signal handler for SIGINT */ + dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 4); + goto restore_old_pipe; + } + + /* Set up signal handling for SIGTERM + */ + DK4_MEMRES(&nterm, sizeof(nterm)); + nterm.sa_handler = sig_handler_term; + nterm.sa_flags = 0; + if (0 != sigemptyset(&nterm.sa_mask)) { + /* ERROR: Failed to set up masked signal set for SIGTERM */ + dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 4); + goto restore_old_int; + } + if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) { + /* ERROR: Failed to set up masked signal set for SIGTERM */ + dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 4); + goto restore_old_int; + } + if (0 != sigaction(SIGTERM, &nterm, &oterm)) { + /* ERROR: Failed to set up signal handler for SIGTERM */ + dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 4); + goto restore_old_int; + } + + success = 1; + dk_blks_normal_run(); + + /* Restore signal handling for SIGTERM. + */ + if (0 != sigaction(SIGTERM, &oterm, NULL)) { + /* ERROR: Failed to restore old SIGTERM settings */ + dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 5); + success = 0; + } + + /* Restore signal handling for SIGINT. + */ + restore_old_int: + if (0 != sigaction(SIGINT, &oint, NULL)) { + /* ERROR: Failed to restore old SIGPIPE settings */ + dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 5); + success = 0; + } + +#ifdef SIGPIPE + /* Restore signal handling for SIGPIPE. + */ + restore_old_pipe: + if (0 != sigaction(SIGPIPE, &opipe, NULL)) { + /* ERROR: Failed to restore old SIGPIPE settings */ + dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 5); + success = 0; + } +#endif + + /* Set exit status code if error occured. + */ + finished: + if (0 == success) { exval = EXIT_FAILURE; } +} +#else +#if DK4_HAVE_SIGSET +/** Set signal handlers and run. +*/ +static +void +run_with_signals(void) +{ +#ifdef SIGPIPE + dk4_sig_handler_t *oldpipe = NULL; +#endif + dk4_sig_handler_t *oldint = NULL; + dk4_sig_handler_t *oldterm = NULL; + +#ifdef SIGPIPE + oldpipe = sigset(SIGPIPE, sig_handler_pipe); +#endif + oldint = sigset(SIGINT, sig_handler_int); + oldterm = sigset(SIGTERM, sig_handler_term); + dk_blks_normal_run(); + sigset(SIGTERM, oldterm); + sigset(SIGINT, oldint); +#ifdef SIGPIPE + sigset(SIGPIPE, oldpipe); +#endif +} +#else +#if DK4_HAVE_SIGNAL +/** Set signal handlers and run. +*/ +static +void +run_with_signals(void) +{ +#ifdef SIGPIPE + dk4_sig_handler_t *oldpipe = NULL; +#endif + dk4_sig_handler_t *oldint = NULL; + dk4_sig_handler_t *oldterm = NULL; + +#ifdef SIGPIPE + oldpipe = signal(SIGPIPE, sig_handler_pipe); +#endif + oldint = signal(SIGINT, sig_handler_int); + oldterm = signal(SIGTERM, sig_handler_term); + dk_blks_normal_run(); + signal(SIGTERM, oldterm); + signal(SIGINT, oldint); +#ifdef SIGPIPE + signal(SIGPIPE, oldpipe); +#endif +} +#else +/** Set signal handlers and run. +*/ +static +void +run_with_signals(void) +{ + dk_blks_normal_run(); +} +#endif +#endif +#endif + + +/** Main function. + @param argc Number of command line arguments. + @param argv Command line arguments array. + @return 0 on success, all other values indicate errors. +*/ +#if DK4_CHAR_SIZE > 1 +int wmain(int argc, wchar_t *argv[]) +#else +int main(int argc, char *argv[]) +#endif +{ + dkChar const *xargv; + int xargc; + int i; + $!trace-init dk-blks.deb + $? "+ main" + app = dk4app_open_cmd( + argc, argv, options, sz_options, kwnl[0], DKT_VERSION_DK, + kwnl[1], help_text, license_text + ); + if (NULL != app) { + sz_msg = dk4app_string_table_size(kw_def); + dk_blks_msg = dk4app_string_table(app, kwnl[2], kw_def); + if (0 != dk4app_can_run_normally(app)) { + run_with_signals(); + xargc = dk4app_get_argc(app); + if (0 < xargc) { + for (i = 0; i < xargc; i++) { + xargv = dk4app_get_argv(app, i); + if (NULL != xargv) { + dk4app_log_3(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 8, 9, xargv); + exval = EXIT_FAILURE; + } + } + } +#ifdef SIGPIPE + if (0 != sig_read_atomic(&sig_had_pipe)) { + dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 6); + exval = EXIT_FAILURE; + } +#endif + if (0 != sig_read_atomic(&sig_had_int)) { + dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 7); + exval = EXIT_FAILURE; + } + } else { + if (0 != dk4app_help_version_license(app)) { + exval = EXIT_SUCCESS; + } + } + dk4app_close(app); app = NULL; + } else { + } + $? "- main %d", exval + $!trace-end + exit(exval); return exval; +} + |