1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
|
/****************************************************************
* *
* Copyright (c) 2001-2022 Fidelity National Information *
* Services, Inc. and/or its subsidiaries. All rights reserved. *
* *
* This source code contains the intellectual property *
* of its copyright holder(s), and is made available *
* under a license. If you do not know the terms of *
* the license, please stop and do not read further. *
* *
****************************************************************/
#include "mdef.h"
#include <stdarg.h>
#include "gtm_stdio.h"
#include "gtm_multi_thread.h"
#include "fao_parm.h"
#include "error.h"
#include "util.h"
#include "util_format.h"
#include "util_out_print_vaparm.h"
#include "gtmmsg.h"
#include "gtm_putmsg_list.h"
#include "gtmimagename.h" /* needed for IS_GTM_IMAGE macro */
#include "gtmio.h" /* needed for FFLUSH macro */
#include "io.h"
/* database/replication related includes due to anticipatory freeze */
#include "gdsroot.h"
#include "gdsbt.h"
#include "gdsfhead.h"
#include "filestruct.h"
#include "anticipatory_freeze.h" /* for SET_ANTICIPATORY_FREEZE_IF_NEEDED */
#include "restrict.h" /* For GTM-7759 logging control */
#define COLON_SEPARATOR " : "
/*
* ----------------------------------------------------------------------------------------
* WARNING: For chained error messages, all messages MUST be followed by an fao count;
* ======= zero MUST be specified if there are no parameters.
* ----------------------------------------------------------------------------------------
*/
/* #GTM_THREAD_SAFE : The below function (gtm_putmsg_list) is thread-safe because caller ensures serialization with locks */
void gtm_putmsg_list(void *csa, int arg_count, va_list var)
{
GBLREF boolean_t gtm_dist_ok_to_use;
int i, msg_id, fao_actual, fao_count, dummy, freeze_msg_id;
char msg_buffer[PUT_BUFF_SIZE];
mstr msg_string;
const err_msg *msg;
const err_ctl *ctl;
boolean_t freeze_needed = FALSE;
char *rname;
jnlpool_addrs_ptr_t local_jnlpool; /* used by CHECK_IF_FREEZE_ON_ERROR_NEEDED and FREEZE_INSTANCE_IF_NEEDED */
boolean_t mustlog;
va_list var_sav;
char fmt_buf[2048];
char *fmt_ptr;
int f_actual, f_count;
DCL_THREADGBL_ACCESS;
SETUP_THREADGBL_ACCESS;
if (!IS_GTMSECSHR_IMAGE)
{ /* Note gtmsecshr does no stdout/stderr IO - everything goes to operator log so this doesn't apply */
util_out_print(NULL, RESET);
}
assert(0 < arg_count);
assert(IS_PTHREAD_LOCKED_AND_HOLDER);
# ifdef GTM_PTHREAD
if (INSIDE_THREADED_CODE(rname)) /* Note: "rname" is not initialized if macro returns FALSE */
{ /* If running with threads, identify which thread is generating this message with a prefix using
* thread-specific-key (which points to the region name for mur* related threads). This helps decipher
* the output of a mupip journal command where the region specific output might be intermixed.
*/
assert((NULL != rname) && ('\0' != rname[0]));
util_out_print(rname, NOFLUSH_OUT);
util_out_print(COLON_SEPARATOR, NOFLUSH_OUT);
}
# endif
for (; ; )
{
msg_id = va_arg(var, int);
mustlog = ( gtm_dist_ok_to_use && (!(RESTRICTED(logdenials))) &&
(MSGFLAG(msg_id) & MSGMUSTLOG) ); /* GTM-7759 logging unless restricted */
CHECK_IF_FREEZE_ON_ERROR_NEEDED(csa, msg_id, freeze_needed, freeze_msg_id, local_jnlpool);
--arg_count;
if (NULL == (ctl = err_check(msg_id)))
msg = NULL;
else
GET_MSG_INFO(msg_id, ctl, msg);
msg_string.addr = msg_buffer;
msg_string.len = SIZEOF(msg_buffer);
gtm_getmsg(msg_id, &msg_string);
if (mustlog)
{ /* If this message must be sysloged for GTM-7759, do it here */
va_copy(var_sav, var);
fmt_ptr = &fmt_buf[0];
if ((0 < arg_count) && msg)
{ /* We don't consume arg_count here */
f_actual = va_arg(var_sav, int);
f_count = f_actual < msg->parm_count ? f_actual : msg->parm_count;
if (MAX_FAO_PARMS < f_count)
f_count = MAX_FAO_PARMS;
} else
f_actual = f_count = 0;
fmt_ptr = util_format(msg_string.addr, var_sav, fmt_ptr, SIZEOF(fmt_buf) - 1, f_count);
*fmt_ptr = '\0';
send_msg_csa(CSA_ARG(csa) VARLSTCNT(4) ERR_TEXT, 2, LEN_AND_STR(fmt_buf));
va_end(var_sav);
}
if (NULL == msg)
{
util_out_print(msg_string.addr, NOFLUSH_OUT, msg_id);
if (0 < arg_count)
{
/* --------------------------
* Print the message to date
* --------------------------
*/
util_out_print(NULL, FLUSH);
/* ---------------------------------------
* Chained error; scan off the fao count
* (it should be zero)
* ---------------------------------------
*/
i = va_arg(var, int);
--arg_count;
assert(0 == i);
}
} else
{
if (0 < arg_count)
{
fao_actual = va_arg(var, int);
--arg_count;
fao_count = fao_actual < msg->parm_count ? fao_actual : msg->parm_count;
if (MAX_FAO_PARMS < fao_count)
fao_count = MAX_FAO_PARMS;
} else
fao_actual = fao_count = 0;
util_out_print_vaparm(msg_string.addr, NOFLUSH_OUT, var, fao_count);
va_end(var); /* needed before used as dest in copy */
VAR_COPY(var, TREF(last_va_list_ptr)); /* How much we unwound */
arg_count -= fao_count;
/* ------------------------------
* Skim off any extra parameters
* ------------------------------
*/
for (i = fao_count; i < fao_actual; ++i)
{
dummy = va_arg(var, int);
--arg_count;
}
va_end(TREF(last_va_list_ptr));
}
if (0 == arg_count)
break;
if (!IS_GTMSECSHR_IMAGE)
util_out_print("!/", NOFLUSH_OUT);
}
FREEZE_INSTANCE_IF_NEEDED(csa, freeze_needed, freeze_msg_id, local_jnlpool);
}
|