1 2 /* rlwrap.h: includes, definitions, declarations */ 3 4 /* This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 2 of the License , or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program; see the file COPYING. If not, write to 16 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 17 18 You may contact the author by: 19 e-mail: hanslub42@gmail.com 20 */ 21 22 23 #include "../config.h" 24 #include <sys/types.h> 25 #if HAVE_SYS_WAIT_H 26 # include <sys/wait.h> 27 #endif 28 29 #ifndef WEXITSTATUS 30 # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) 31 #endif 32 33 34 35 #include <sys/stat.h> 36 #include <sys/ioctl.h> 37 #include <sys/resource.h> 38 #include <fcntl.h> 39 #include <unistd.h> 40 #include <signal.h> 41 #include <stdio.h> 42 #include <ctype.h> 43 #include <inttypes.h> /* stdint.h is not on AIX, inttypes.h is in ISO C 1999 */ 44 45 #include <errno.h> 46 #include <stdarg.h> 47 48 #if defined(__DragonFly__) 49 #include <stdbool.h> 50 #endif 51 52 /* #define __USE_XOPEN 53 #define __USE_GNU */ 54 55 #include <stdlib.h> 56 #include <locale.h> 57 58 59 #include <sched.h> 60 61 62 63 64 #if TIME_WITH_SYS_TIME 65 # include <sys/time.h> 66 # include <time.h> 67 #else 68 # if HAVE_SYS_TIME_H 69 # include <sys/time.h> 70 # else 71 # include <time.h> 72 # endif 73 #endif 74 75 #if HAVE_SYS_FILE_H 76 #include <sys/file.h> 77 #endif 78 79 #ifdef HAVE_GETOPT_H 80 # include <getopt.h> 81 #endif 82 83 #ifdef HAVE_STROPTS_H 84 # include <stropts.h> 85 #endif 86 87 88 89 #ifdef HAVE_LIBGEN_H 90 # include <libgen.h> 91 #endif 92 93 #ifdef HAVE_CURSES_H 94 # include <curses.h> 95 # ifdef HAVE_TERM_H 96 # include <term.h> 97 # else 98 # ifdef HAVE_NCURSES_TERM_H /* cygwin? AIX? */ 99 # include <ncurses/term.h> 100 # endif 101 # endif 102 #else 103 # ifdef HAVE_TERMCAP_H 104 # include <termcap.h> 105 # endif 106 #endif 107 108 #include <termios.h> 109 110 111 #ifdef HAVE_REGEX_H 112 # include <regex.h> 113 #endif 114 115 #if STDC_HEADERS 116 # include <string.h> 117 #else 118 # ifndef HAVE_STRRCHR 119 # define strrchr rindex 120 # endif 121 char *strchr(), *strrchr(); 122 123 # ifndef HAVE_MEMMOVE 124 # define memmove(d, s, n) bcopy ((s), (d), (n)) 125 # endif 126 #endif 127 128 129 #ifdef HAVE_PTY_H /* glibc (even if BSD) */ 130 # include <pty.h> 131 #elif HAVE_LIBUTIL_H /* BSD, non-glibc */ 132 # include <libutil.h> 133 #elif HAVE_UTIL_H /* BSD, other varriants */ 134 # include <util.h> 135 #endif 136 137 138 #if HAVE_DECL_PROC_PIDVNODEPATHINFO 139 # include <libproc.h> 140 #endif 141 142 #if HAVE_FREEBSD_LIBPROCSTAT 143 # include <sys/param.h> 144 # include <sys/queue.h> 145 # include <sys/socket.h> 146 # include <libprocstat.h> 147 # include <sys/sysctl.h> 148 #endif 149 150 #if HAVE_PROC_PID_CWD || HAVE_DECL_PROC_PIDVNODEPATHINFO || HAVE_FREEBSD_LIBPROCSTAT 151 # define CAN_FOLLOW_COMMANDS_CWD 1 152 #endif 153 154 #define BUFFSIZE 2048 155 156 #ifndef MAXPATHLEN 157 #define MAXPATHLEN 512 158 #endif 159 160 161 #ifdef HAVE_SNPRINTF /* don't rely on the compiler understanding variadic macros */ 162 # define snprintf0(buf,bufsize,format) snprintf(buf,bufsize,format) 163 # define snprintf1(buf,bufsize,format,arg1) snprintf(buf,bufsize,format,arg1) 164 # define snprintf2(buf,bufsize,format,arg1,arg2) snprintf(buf,bufsize,format,arg1,arg2) 165 # define snprintf3(buf,bufsize,format,arg1,arg2,arg3) snprintf(buf,bufsize,format,arg1,arg2,arg3) 166 # define snprintf4(buf,bufsize,format,arg1,arg2,arg3,arg4) snprintf(buf,bufsize,format,arg1,arg2,arg3,arg4) 167 # define snprintf5(buf,bufsize,format,arg1,arg2,arg3,arg4,arg5) snprintf(buf,bufsize,format,arg1,arg2,arg3,arg4,arg5) 168 # define snprintf6(buf,bufsize,format,arg1,arg2,arg3,arg4,arg5,arg6) snprintf(buf,bufsize,format,arg1,arg2,arg3,arg4,arg5,arg6) 169 170 #else 171 # define snprintf0(buf,bufsize,format) sprintf(buf,format) 172 # define snprintf1(buf,bufsize,format,arg1) sprintf(buf,format,arg1) 173 # define snprintf2(buf,bufsize,format,arg1,arg2) sprintf(buf,format,arg1,arg2) 174 # define snprintf3(buf,bufsize,format,arg1,arg2,arg3) sprintf(buf,format,arg1,arg2,arg3) 175 # define snprintf4(buf,bufsize,format,arg1,arg2,arg3,arg4) sprintf(buf,format,arg1,arg2,arg3,arg4) 176 # define snprintf5(buf,bufsize,format,arg1,arg2,arg3,arg4,arg5) sprintf(buf,format,arg1,arg2,arg3,arg4,arg5) 177 # define snprintf6(buf,bufsize,format,arg1,arg2,arg3,arg4,arg5,arg6) sprintf(buf,format,arg1,arg2,arg3,arg4,arg5,arg6) 178 # define vsnprintf(buf,bufsize,format,ap) vsprintf(buf,format,ap) 179 #endif 180 181 182 #ifndef HAVE_STRNLEN 183 # define strnlen(s,l) strlen(s) 184 #endif 185 186 187 188 #include <readline/readline.h> 189 #include <readline/history.h> 190 191 192 #ifndef HAVE_RL_VARIABLE_VALUE 193 # define rl_variable_value(s) "off" 194 #endif 195 196 #ifndef HAVE_RL_READLINE_VERSION 197 # define rl_readline_version 0xbaddef 198 #endif 199 200 #if defined(SPY_ON_READLINE) 201 extern int _rl_eof_char; /* Spying on readline's private life .... */ 202 extern int _rl_horizontal_scroll_mode; 203 # if !defined(HOMEGROWN_REDISPLAY) 204 # define MAYBE_MULTILINE 1 205 # endif 206 #else 207 # define _rl_eof_char 0 208 #endif 209 210 #ifdef MAYBE_MULTILINE 211 # define redisplay_multiple_lines (!_rl_horizontal_scroll_mode) 212 #else 213 # define redisplay_multiple_lines (strncmp(rl_variable_value("horizontal-scroll-mode"),"off",3) == 0) 214 #endif 215 216 217 218 219 220 221 extern void test_main(void); 222 223 /* in main.c: */ 224 extern int master_pty_fd; 225 extern int slave_pty_sensing_fd; 226 extern FILE *debug_fp; 227 extern char *program_name, *command_name; 228 extern int always_readline; 229 extern int always_echo; 230 extern int complete_filenames; 231 extern int within_line_edit; 232 extern int screen_is_alternate; 233 extern pid_t command_pid; 234 extern char *rlwrap_command_line; 235 extern int unit_test_argc; 236 extern char **unit_test_argv; 237 extern char *command_line; 238 extern char *extra_char_after_completion; 239 extern int i_am_child; 240 extern int i_am_filter; 241 extern int nowarn; 242 extern int debug; 243 extern char *password_prompt_search_string; 244 extern int one_shot_rlwrap; 245 extern char *substitute_prompt; 246 extern char *history_format; 247 extern char *forget_regexp; 248 extern char *multi_line_tmpfile_ext; 249 extern char *prompt_regexp; 250 extern int renice; 251 extern int ignore_queued_input; 252 extern int history_duplicate_avoidance_policy; 253 extern int pass_on_sigINT_as_sigTERM; 254 /* now follow the possible values for history_duplicate_avoidance_policy: */ 255 #define KEEP_ALL_DOUBLES 0 256 #define ELIMINATE_SUCCESIVE_DOUBLES 1 257 #define ELIMINATE_ALL_DOUBLES 2 258 extern int one_shot_rlwrap; 259 extern int ansi_colour_aware; 260 extern int bleach_the_prompt; 261 extern int colour_the_prompt; 262 extern int received_WINCH; 263 extern int prompt_is_still_uncooked; 264 extern int mirror_arguments; 265 extern int impatient_prompt; 266 extern int we_just_got_a_signal_or_EOF; 267 extern int remember_for_completion; 268 extern int commands_children_not_wrapped; 269 extern int accepted_lines; 270 extern char *filter_command; 271 extern int polling; 272 273 void cleanup_rlwrap_and_exit(int status); 274 void put_in_output_queue(char *stuff); 275 int output_queue_is_nonempty(void); 276 void flush_output_queue(void); 277 278 /* in readline.c: */ 279 extern struct rl_state 280 { /* struct to save readline state while we're processing output from slave command*/ 281 char *input_buffer; /* current input buffer */ 282 char *raw_prompt; /* current prompt */ 283 char *cooked_prompt; /* ditto redefined by user, or with colour added */ 284 int point; /* cursor position within input buffer */ 285 int already_saved; /* flag set when saved, cleared when restored */ 286 } saved_rl_state; 287 288 void save_rl_state(void); 289 void restore_rl_state(void); 290 void message_in_echo_area(char *message); 291 void init_readline(char *); 292 void my_redisplay(void); 293 void initialise_colour_codes(char *colour); 294 void reprint_prompt(int coloured); 295 char *colourise (const char *prompt); 296 void move_cursor_to_start_of_prompt(int erase); 297 #define ERASE 1 298 #define DONT_ERASE 0 299 int prompt_is_single_line(void); 300 char *process_new_output(const char* buffer, struct rl_state* state); 301 int cook_prompt_if_necessary (void); 302 303 extern int transparent; 304 extern char *multiline_separator; 305 extern char *pre_given; 306 extern int leave_prompt_alone; 307 extern bool bracketed_paste_enabled; 308 309 310 /* in signals.c */ 311 extern volatile int command_is_dead; 312 extern int commands_exit_status; 313 extern int filter_is_dead; 314 extern int filters_exit_status; 315 extern int sigterm_received; 316 extern int deferred_adapt_commands_window_size; 317 extern int signal_handlers_were_installed; 318 extern int received_sigALRM; 319 320 #ifndef RETSIGTYPE 321 #define RETSIGTYPE void /* systems where RETSIGTYPE = int have died out, apparently */ 322 #endif 323 typedef RETSIGTYPE (*sighandler_type)(int); 324 325 /* we'll install signal handlers with mysignal(SIGBLAH, HANDLER(handler)), to improve debug log readabilty */ 326 void mysignal(int sig, sighandler_type handler, const char *handler_name); 327 #define HANDLER(f) &f, #f 328 329 void install_signal_handlers(void); 330 void block_signals(int *sigs); 331 void unblock_signals(int *sigs); 332 void block_all_passed_on_signals(void); 333 void block_all_signals(void); 334 void unblock_all_signals(void); 335 void ignore_sigchld(void); 336 void suicide_by(int sig, int status); 337 int adapt_tty_winsize(int from_fd, int to_fd); 338 void myalarm(int msec); 339 void handle_sigALRM(int signo); 340 char *signal_name(int signal); 341 342 343 /* in utils.c */ 344 void yield(void); 345 void zero_select_timeout(void); 346 int my_pselect(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *ptimeout_ts, const sigset_t *sigmask); 347 struct termios *my_tcgetattr(int fd, char *which); 348 int read_patiently(int fd, void *buffer, int count, char *whence); 349 int write_patiently(int fd, const void *buffer, int count, const char *whither); 350 void read_patiently2(int fd, void *buffer, int count, int uninterruptible_msec, const char *whence); 351 void write_patiently2(int fd, const void *buffer, int count, int uninterruptible_msec, const char *whither); 352 void mysetenv(const char *name, const char *value); 353 void set_ulimit(int resource, long value); 354 void usage(int status); 355 int open_unique_tempfile(const char *suffix, char **tmpfile_name); 356 void mirror_args_init(char **argv); 357 void mirror_args(pid_t command_pid); 358 359 /* flags to use for the error_flags argument to myerror */ 360 #define FATAL 2 361 #define WARNING 0 362 #define USE_ERRNO 1 363 #define NOERRNO 0 364 365 /* constant to signify the end of a free_multiple() argument list (NULL would't work) */ 366 #define FMEND ((void *) -1) 367 368 void myerror(int error_flags, const char *message, ...); 369 void *mymalloc(size_t size); 370 void free_multiple(void *ptr, ...); 371 void mysetsid(void); 372 void close_open_files_without_writing_buffers(void); 373 size_t filesize(const char *filename); 374 void my_fopen(FILE **pfp, const char *path, const char *mode, const char *description); 375 void open_logfile(const char *filename); 376 void write_logfile(const char *str); 377 void close_logfile(void); 378 void timestamp(char *buf, int size); 379 unsigned long hash_multiple(int n, ...); 380 int killed_by(int status); 381 void change_working_directory(void); 382 void log_terminal_settings(struct termios *terminal_settings); 383 void log_fd_info(int fd); 384 void last_minute_checks(void); 385 void mymicrosleep(int msec); 386 void do_nothing(int unused); 387 388 389 /* in string_utils.c */ 390 char *mybasename(const char *filename); 391 char *mydirname(const char *filename); 392 void mystrlcpy(char *dst, const char *src, size_t size); 393 void mystrlcat(char *dst, const char *src, size_t size); 394 bool strings_are_equal(const char *s1, const char *s2); 395 char *mystrstr(const char *haystack, const char *needle); 396 char *mysavestring(const char *string); 397 char *strifnull(char *string); 398 char *add3strings(const char *str1, const char *str2, const char *str3); 399 #define add2strings(a,b) add3strings(a,b,"") 400 int my_atoi(const char *nptr); 401 char *mystrtok(const char *s, const char *delim); 402 char **split_with(const char *string, const char *delim); 403 char *unsplit_with(int n, char ** strings, const char *delim); 404 char **split_on_single_char(const char *string, char c, int expected_count); 405 int scan_metacharacters(const char* string, const char *metacharacters); 406 char **list4 (char *el0, char *el1, char *el2, char *el3); 407 void free_splitlist (char **list); 408 char *append_and_free_old(char *str1, const char *str2); 409 char *mangle_char_for_debug_log(char c, int quote_me); 410 char *mangle_string_for_debug_log(const char *string, int maxlen); 411 char *mangle_buffer_for_debug_log(const char *buffer, int length); 412 char *mem2str(const char *mem, int size); 413 char *search_and_replace(char *patt, const char *repl, const char *string, 414 int cursorpos, int *line, int *col); 415 char *first_of(char **strings); 416 char *as_string(int i); 417 char *append_and_expand_history_format(char *line); 418 void remove_padding_and_terminate(char *buf, int length); 419 void unbackspace(char* buf); 420 char *mark_invisible(const char *buf); 421 char *copy_and_unbackspace(const char *original); 422 int colourless_strlen(const char *str, char **pcopy_without_ignore_markers, int termwidth); 423 int colourless_strlen_unmarked (const char *str, int termwidth); 424 char *get_last_screenline(char *long_line, int termwidth); 425 char *lowercase(const char *str); 426 char *colour_name_to_ansi_code(const char *colour_name); 427 int match_regexp(const char *string, const char *regexp, int case_insensitive); 428 int isnumeric(char *string); 429 #define END_FIELD (char*)NULL /* marker object to terminate vargs */ 430 char *append_field_and_free_old(char *message, const char *field); 431 char *merge_fields(char *field, ...); 432 char **split_filter_message(char *message, int *count); 433 char *protect_or_cleanup(char *prompt, bool free_prompt); 434 void check_cupcodes(const char *client_output); 435 436 /* in pty.c: */ 437 pid_t my_pty_fork(int *, const struct termios *, const struct winsize *); 438 int slave_is_in_raw_mode(void); 439 struct termios *get_pterm_slave(void); 440 void mirror_slaves_echo_mode(void); 441 void completely_mirror_slaves_terminal_settings(void); 442 void completely_mirror_slaves_output_settings(void); 443 void completely_mirror_slaves_special_characters(void); 444 void write_EOF_to_master_pty(void); 445 void write_EOL_to_master_pty(char *); 446 int dont_wrap_command_waits(void); 447 int skip_rlwrap(void); 448 449 /* in ptytty.c: */ 450 int ptytty_get_pty(int *fd_tty, const char **ttydev); 451 int ptytty_get_tty(const char *ttydev); 452 int ptytty_control_tty(int fd_tty, const char *ttydev); 453 int ptytty_openpty(int *amaster, int *aslave, const char **name); 454 455 /* in completion.rb: */ 456 void init_completer(void); 457 void feed_file_into_completion_list(const char *completions_file); 458 void feed_line_into_completion_list(const char *line); 459 void add_word_to_completions(const char *word); 460 void remove_word_from_completions(const char *word); 461 char *my_completion_function(char *prefix, int state); 462 463 extern int completion_is_case_sensitive; 464 465 466 /* in term.c: */ 467 extern int redisplay; /* TRUE when user input should be readable (instead of *******) */ 468 void init_terminal(void); 469 void set_echo(int); 470 void prepare_terminal(void); 471 void cr(void); 472 void backspace(int); 473 void clear_line(void); 474 void clear_the_screen(void); 475 void curs_up(void); 476 void curs_down(void); 477 void curs_left(void); 478 void test_terminal(void); 479 int my_putchar(TPUTS_PUTC_ARGTYPE c); 480 void my_putstr(const char *string); 481 int cursor_hpos(int col); 482 extern struct termios saved_terminal_settings; 483 extern int terminal_settings_saved; 484 extern struct winsize winsize; 485 extern char *term_name; 486 extern char *term_backspace, term_eof, term_stop, *term_cursor_hpos, 487 *term_cursor_up, *term_cursor_down, *term_cursor_left, *term_smcup, 488 *term_rmcup, *term_rmkx, *term_enable_bracketed_paste, *term_disable_bracketed_paste; 489 extern int term_has_colours; 490 extern int newline_came_last; 491 492 /* in filter.c */ 493 494 #define MAX_TAG 255 495 #define TAG_INPUT 0 496 #define TAG_OUTPUT 1 497 #define TAG_HISTORY 2 498 #define TAG_COMPLETION 3 499 #define TAG_PROMPT 4 500 #define TAG_HOTKEY 5 501 #define TAG_SIGNAL 6 502 #define MAX_INTERESTING_TAG 6 /* max tag for which the filter can have a handler */ 503 504 #define TAG_WHAT_ARE_YOUR_INTERESTS 127 505 506 507 #define TAG_IGNORE 251 508 #define TAG_ADD_TO_COMPLETION_LIST 252 509 #define TAG_REMOVE_FROM_COMPLETION_LIST 253 510 #define TAG_OUTPUT_OUT_OF_BAND 254 511 #define TAG_ERROR 255 512 513 #define out_of_band(tag) (tag & 128) 514 515 516 extern pid_t filter_pid; 517 extern int filter_is_dead; 518 void spawn_filter(const char *filter_command); 519 void kill_filter(void); 520 int filter_is_interested_in(int tag); 521 char *pass_through_filter(int tag, const char *buffer); 522 char *filters_last_words(void); 523 void filter_test(void); 524 525 526 527 /* in multibyte.c: */ 528 529 #ifdef MULTIBYTE_AWARE /* i.e. if configured with --enable-multibyte-aware */ 530 #include <wchar.h> 531 #define MBSTATE mbstate_t 532 #else 533 #define MBSTATE int 534 #endif 535 536 MBSTATE * mbc_initstate(MBSTATE *st); 537 MBSTATE *mbc_copystate(MBSTATE st, MBSTATE *stc); 538 int mbc_is_valid(const char *mb_string, const MBSTATE *st); 539 const char * mbc_next(const char *mb_string, MBSTATE *st); 540 int mbc_charwidth(const char *p, MBSTATE *st); 541 char *mbc_first(const char *mb_string, const MBSTATE *st); 542 int is_multibyte(const char *mb_char, const MBSTATE *st); 543 const char *mbc_inc(const char **mbc, MBSTATE *st); 544 void mbc_copy(const char *p, char **q, MBSTATE *st); 545 size_t mbc_strnlen(const char *mb_string, size_t maxlen, MBSTATE *st); 546 547 548 549 /* some handy macros */ 550 551 #ifndef TRUE 552 # define TRUE 1 553 #endif 554 555 #ifndef FALSE 556 # define FALSE 0 557 #endif 558 559 560 #ifndef min 561 # define min(a,b) ((a) < (b) ? (a) : (b)) 562 #endif 563 564 #ifndef max 565 # define max(a,b) ((a) < (b) ? (b) : (a)) 566 #endif 567 568 569 /* macros for writing unit tests */ 570 typedef enum {TEST_AT_PROGRAM_START, TEST_AFTER_OPTION_PARSING, TEST_AFTER_SPAWNING_SLAVE_COMMAND,TEST_AFTER_READLINE_INIT} test_stage; 571 #define TESTFUNC(f, argc, argv, stage) void f(int argc, char **argv, test_stage stage) 572 #define ONLY_AT_STAGE(s) if(stage != s) return 573 574 575 576 #include "malloc_debug.h" /* malloc_debug.{c,h} not ready for prime time */ 577 578 #define DEBUG_FILENAME "/tmp/rlwrap.debug" 579 #define KA_BOOM {char *p = (char *) 1; *p = 'c';} /* dump core right here */ 580 #define KA_SCRUNCH {volatile int x=1, y=0; x = x/y;} /* force a SIGFPE */ 581 #define KA_SCREECH kill(getpid(),SIGTRAP); /* enter the debugger - use it to set (conditional) breakpoints from within C code: if (condition) KA_SCREECH; */ 582 583 /* DPRINTF0 and its ilk doesn't produce any output except when DEBUG is #defined (via --enable-debug configure option) */ 584 585 /* Use a superfluous "break" (withn a switch) to prevent "this statement may fall through" warnings when we know that a statement will end the program anyway */ 586 #define WONTRETURN(statement) statement;break 587 588 589 # ifdef __GNUC__ 590 # define __MYFUNCTION__ __extension__ __FUNCTION__ 591 # define UNUSED(x) UNUSED_ ## x __attribute__((__unused__)) 592 # define UNUSED_FUNCTION(f) __attribute__((__unused__)) UNUSED_ ## f 593 # else 594 # define __MYFUNCTION__ "" 595 # define UNUSED(x) UNUSED_ ## x 596 # define UNUSED_FUNCTION(f) UNUSED_ ## f 597 # endif 598 599 600 #define MAYBE_UNUSED(x) (void) (x) 601 602 #ifdef DEBUG 603 604 605 # define DEBUG_TERMIO 1 606 # define DEBUG_SIGNALS 2 607 # define DEBUG_READLINE 4 608 # define DEBUG_MEMORY_MANAGEMENT 8 /* used with malloc_debug.c */ 609 # define DEBUG_FILTERING 16 610 # define DEBUG_COMPLETION 32 611 # define DEBUG_AD_HOC 64 /* only used during rlwrap development */ 612 # define DEBUG_WITH_TIMESTAMPS 128 /* add timestamps to every line in debug log */ 613 # define FORCE_HOMEGROWN_REDISPLAY 256 /* force use of my_homegrown_redisplay() */ 614 # define DEBUG_LONG_STRINGS 512 /* log all strings completely, however long they are */ 615 # define DEBUG_RACES 1024 /* introduce random delays */ 616 # define DEBUG_RANDOM_FAIL 2048 /* fail tests randomly */ 617 # define DEBUG_SHOWCURSOR 4096 /* run test_main and exit */ 618 619 # define DEBUG_MAX DEBUG_SHOWCURSOR 620 # define MANGLE_LENGTH ((debug_saved & DEBUG_LONG_STRINGS) ? 0 : 20) /* debug_saved is defined within DPRINTF macro */ 621 # define DEBUG_DEFAULT (DEBUG_TERMIO | DEBUG_SIGNALS | DEBUG_READLINE) 622 # define DEBUG_ALL (2*DEBUG_MAX-1) 623 624 # define M(x) mangle_string_for_debug_log(x, MANGLE_LENGTH) 625 626 627 # define ONLY_USED_FOR_DEBUGGING(x) x 628 629 630 # ifndef HAVE_FLOCK 631 # define flock(x,y) 632 # endif 633 634 635 # define WHERE_AND_WHEN \ 636 int debug_saved = debug; char file_line[100], when[100]; \ 637 if(debug & DEBUG_WITH_TIMESTAMPS) timestamp(when, sizeof(when)); else *when='\0'; \ 638 debug = 0; /* don't debug while evaluating the DPRINTF arguments */ \ 639 snprintf2(file_line, sizeof(file_line), "%.15s:%d:", __FILE__, __LINE__); \ 640 flock(fileno(debug_fp), LOCK_EX); \ 641 fseek(debug_fp, 0, SEEK_END); \ 642 fprintf(debug_fp, "%-20s %s %-7s %-25.25s ", file_line, when, (i_am_child ? "child" : i_am_filter? "filter" :"parent"), __MYFUNCTION__); 643 644 645 # define NL_AND_FLUSH fputc('\n', debug_fp) ; fflush(debug_fp); flock(fileno(debug_fp), LOCK_UN); debug = debug_saved 646 647 # define DPRINTF0(mask, format) \ 648 do {if ((debug & mask) && debug_fp) {WHERE_AND_WHEN; fprintf(debug_fp, format); NL_AND_FLUSH; }} while(FALSE) 649 650 # define DPRINTF1(mask, format,arg) \ 651 do {if ((debug & mask) && debug_fp) {WHERE_AND_WHEN; fprintf(debug_fp, format, arg); NL_AND_FLUSH; }} while(FALSE) 652 653 # define DPRINTF2(mask, format,arg1, arg2) \ 654 do {if ((debug & mask) && debug_fp) {WHERE_AND_WHEN; fprintf(debug_fp, format, arg1, arg2); NL_AND_FLUSH; }} while (FALSE) 655 656 # define DPRINTF3(mask, format,arg1, arg2, arg3) \ 657 do {if ((debug & mask) && debug_fp) {WHERE_AND_WHEN; fprintf(debug_fp, format, arg1, arg2, arg3); NL_AND_FLUSH; }} while (FALSE) 658 659 # define DPRINTF4(mask, format,arg1, arg2, arg3, arg4) \ 660 do {if ((debug & mask) && debug_fp) {WHERE_AND_WHEN; fprintf(debug_fp, format, arg1, arg2, arg3, arg4); NL_AND_FLUSH; }} while (FALSE) 661 662 # define DPRINTF5(mask, format,arg1, arg2, arg3, arg4, arg5) \ 663 do {if ((debug & mask) && debug_fp) {WHERE_AND_WHEN; fprintf(debug_fp, format, arg1, arg2, arg3, arg4, arg5); NL_AND_FLUSH; }} while (FALSE) 664 665 666 # define ERRMSG(b) (b && (errno != 0) ? add3strings("(", strerror(errno), ")") : "" ) 667 668 # define SHOWCURSOR(c) if (debug & DEBUG_SHOWCURSOR) {my_putchar(c); mymicrosleep(1000); curs_left();} /* (may work incorrectly at last column!)*/ 669 670 # define DEBUG_RANDOM_SLEEP if (debug & DEBUG_RACES) {int sleeptime=rand()&31; DPRINTF1(DEBUG_RACES,"sleeping for %d msecs", sleeptime); mymicrosleep(sleeptime);} 671 672 673 #else 674 # define ONLY_USED_FOR_DEBUGGING(x) UNUSED(x) 675 # define MANGLE_LENGTH 0 676 # define DPRINTF0(mask, format) do {;} while(FALSE) 677 # define DPRINTF1(mask, format,arg) do {;} while(FALSE) 678 # define DPRINTF2(mask, format,arg1, arg2) do {;} while(FALSE) 679 # define DPRINTF3(mask, format,arg1, arg2, arg3) do {;} while(FALSE) 680 # define DPRINTF4(mask, format,arg1, arg2, arg3, arg4) do {;} while(FALSE) 681 # define DPRINTF5(mask, format,arg1, arg2, arg3, arg4, arg5) do {;} while(FALSE) 682 # define ERRMSG(b) 683 # define SHOWCURSOR 684 # define DEBUG_RANDOM_SLEEP 685 686 /* Don't #define NDEBUG! There are assertions that cannot be skipped, as in assert(important_function_call()) */ 687 /* Todo (maybe) #define myassert(x) if(DEBUG){assert(x)} for the other (skippable) assertions */ 688 689 #endif 690 691 #include <assert.h> 692