$* Copyright (c) 2006-2010, 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 opyright 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. $* /** @file edbp.c The edbp program. */ #include #include #if DK_HAVE_SYS_TYPES_H #include #endif #if DK_HAVE_STDLIB_H #include #endif #if DK_HAVE_UNISTD_H #include #endif #if DK_HAVE_SIGNAL_H #include #endif #if DK_HAVE_STRING_H #include #endif #if DK_HAVE_STRINGS_H #include #endif #include $(trace-include) /** Flag: Can continue. */ static #if DK_HAVE_VOLATILE volatile #endif int cc = 1; /** SIGHUP handler. @param signo Signal number (SIGHUP). */ dk_signal_ret_t handler_sighup DK_P1(int, signo) { dksignal_refresh(signo, handler_sighup); cc = 0; fprintf( stderr, "SIGHUP received.\n" ); fflush(stderr); } /** SIGINT handler. @param signo Signal number (SIGINT). */ dk_signal_ret_t handler_sigint DK_P1(int, signo) { dksignal_refresh(signo, handler_sigint); cc = 0; fprintf( stderr, "SIGINT received.\n" ); fflush(stderr); } /** SIGTERM handler. @param signo Signal number (SIGTERM). */ dk_signal_ret_t handler_sigterm DK_P1(int, signo) { dksignal_refresh(signo, handler_sigterm); cc = 0; fprintf( stderr, "SIGTERM received.\n" ); fflush(stderr); } /** SIGPIPE handler. @param signo Signal number (SIGPIPE). */ dk_signal_ret_t handler_sigpipe DK_P1(int, signo) { dksignal_refresh(signo, handler_sigpipe); cc = 0; fprintf( stderr, "SIGPIPE received.\n" ); fflush(stderr); } /** The buffer to store the bit patterns. */ static char buffer[16384]; /** Size of buffer. */ static size_t sz_buffer = sizeof(buffer); /** Buffer size for write operations. */ static size_t bs = 512; /** The pattern number. 0 <= patno <= 7. */ static unsigned patno = 0; /** Fallback implementation of memset(). @param ptr Destination buffer. @param c Byte. @param sz Size of \a ptr. */ static void my_memset DK_P3(char *,ptr, char,c, size_t,sz) { #if DK_HAVE_MEMSET memset((void *)ptr, c, sz); #else char *cptr; size_t i; cptr = ptr; for(i = 0; i < sz; i++) { *(cptr++) = c; } #endif } /** The main() function of the edbp program. @param argc Number of command line arguments. @param argv Command line arguments array. @return 0 on success, any other value indicates an error. */ #if DK_HAVE_PROTOTYPES int main(int argc, char *argv[]) #else int main(argc, argv) int argc; char *argv[]; #endif { unsigned newbs = 512; unsigned long ul1 = 0UL, ul2 = 0UL, ul3 = 0UL; #ifdef SIGHUP dk_signal_disp_t disp_hup; #endif #ifdef SIGINT dk_signal_disp_t disp_int; #endif #ifdef SIGTERM dk_signal_disp_t disp_term; #endif #ifdef SIGPIPE dk_signal_disp_t disp_pipe; #endif if(argc > 1) { if(sscanf(argv[1], "%u", &newbs) == 1) { patno = newbs; if(patno > 7) { patno = 7; fprintf( stderr, "ERROR: Pattern number must be in range 0 ... 7!\n" ); fflush(stderr); } } else { fprintf( stderr, "ERROR: Pattern number must be in range 0 ... 7!\n" ); fflush(stderr); } } if(argc > 2) { if(sscanf(argv[2], "%u", &newbs) == 1) { bs = newbs; if(bs > sz_buffer) { fprintf( stderr, "ERROR: Blocksize must be in range 1 ... 16384!\n" ); fflush(stderr); bs = sz_buffer; } } else { fprintf( stderr, "ERROR: Blocksize must be in range 1 ... 16384!\n" ); fflush(stderr); } } switch((int)patno) { case 7: { my_memset(buffer, (char)0xAA, sz_buffer); } break; case 6: { my_memset(buffer, (char)0x55, sz_buffer); } break; case 5: { my_memset(buffer, (char)0xCC, sz_buffer); } break; case 4: { my_memset(buffer, (char)0x33, sz_buffer); } break; case 3: { my_memset(buffer, (char)0xF0, sz_buffer); } break; case 2: { my_memset(buffer, (char)0x0F, sz_buffer); } break; case 1: { my_memset(buffer, (char)0xFF, sz_buffer); } break; case 0: { my_memset(buffer, (char)0x00, sz_buffer); } break; } cc = 1; ul1 = ul2 = ul3 = 0UL; #ifdef SIGHUP disp_hup = dksignal_set(SIGHUP,handler_sighup); #endif #ifdef SIGINT disp_int = dksignal_set(SIGINT,handler_sigint); #endif #ifdef SIGTERM disp_term = dksignal_set(SIGTERM,handler_sigterm); #endif #ifdef SIGPIPE disp_pipe = dksignal_set(SIGPIPE,handler_sigpipe); #endif while(cc) { if(write(1, buffer, bs) < bs) { cc = 0; fprintf( stderr, "ERROR: Failed to write %lu bytes!\n", (unsigned long)bs ); fflush(stderr); } else { ul1++; if(ul1 == 0UL) { ul2++; if(ul2 == 0UL) { ul3++; } } } } #ifdef SIGPIPE if(disp_pipe) { dksignal_set(SIGPIPE,disp_pipe); } #endif #ifdef SIGTERM if(disp_term) { dksignal_set(SIGTERM,disp_term); } #endif #ifdef SIGINT if(disp_int) { dksignal_set(SIGINT,disp_int); } #endif #ifdef SIGHUP if(disp_hup) { dksignal_set(SIGHUP,disp_hup); } #endif fprintf( stderr, "Finished after writing %lu:%lu:%lu blocks.\n", ul3, ul2, ul1 ); fflush(stderr); exit(0); return 0; }