summaryrefslogtreecommitdiff
path: root/support/dktools/dk-blks.ctr
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/dktools/dk-blks.ctr
Initial commit
Diffstat (limited to 'support/dktools/dk-blks.ctr')
-rw-r--r--support/dktools/dk-blks.ctr959
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;
+}
+