0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #include <stdio.h>
0038 #include <stdarg.h>
0039 #include <memory.h>
0040 #include <stdlib.h>
0041 #include <atmi.h>
0042 #include <ndebug.h>
0043 #include <nerror.h>
0044 #include <tperror.h>
0045 #include <Exfields.h>
0046
0047 #include <xa.h>
0048 #include <atmi_int.h>
0049 #include <atmi_tls.h>
0050
0051
0052
0053
0054
0055
0056 #define ATMI_ERROR_DESCRIPTION(X) (M_atmi_error_defs[X<TPMINVAL?TPMINVAL:(X>TPMAXVAL?TPMAXVAL:X)].msg)
0057 #define TP_ERROR(X) X, #X
0058
0059
0060
0061
0062
0063
0064
0065
0066 struct err_msg
0067 {
0068 int id;
0069 char *msg;
0070 } M_atmi_error_defs [] =
0071 {
0072 {TP_ERROR(TPMINVAL)},
0073 {TP_ERROR(TPEABORT)},
0074 {TP_ERROR(TPEBADDESC)},
0075 {TP_ERROR(TPEBLOCK)},
0076 {TP_ERROR(TPEINVAL)},
0077 {TP_ERROR(TPELIMIT)},
0078 {TP_ERROR(TPENOENT)},
0079 {TP_ERROR(TPEOS)},
0080 {TP_ERROR(TPEPERM)},
0081 {TP_ERROR(TPEPROTO)},
0082 {TP_ERROR(TPESVCERR)},
0083 {TP_ERROR(TPESVCFAIL)},
0084 {TP_ERROR(TPESYSTEM)},
0085 {TP_ERROR(TPETIME)},
0086 {TP_ERROR(TPETRAN)},
0087 {TP_ERROR(TPGOTSIG)},
0088 {TP_ERROR(TPERMERR)},
0089 {TP_ERROR(TPEITYPE)},
0090 {TP_ERROR(TPEOTYPE)},
0091 {TP_ERROR(TPERELEASE)},
0092 {TP_ERROR(TPEHAZARD)},
0093 {TP_ERROR(TPEHEURISTIC)},
0094 {TP_ERROR(TPEEVENT)},
0095 {TP_ERROR(TPEMATCH)},
0096 {TP_ERROR(TPEDIAGNOSTIC)},
0097 {TP_ERROR(TPEMIB)},
0098 {TP_ERROR(TPERFU26)},
0099 {TP_ERROR(TPERFU27)},
0100 {TP_ERROR(TPERFU28)},
0101 {TP_ERROR(TPERFU29)},
0102 {TP_ERROR(TPINITFAIL)},
0103 {TP_ERROR(TPMAXVAL)}
0104 };
0105
0106
0107
0108
0109 struct err_msg_xa
0110 {
0111 short errcode;
0112 char *msg;
0113 } M_atmi_xa_error_defs [] =
0114 {
0115 {XA_RBBASE, "the inclusive lower bound of the rollback codes"},
0116 {XA_RBROLLBACK, "the rollback was caused by an unspecified reason"},
0117 {XA_RBCOMMFAIL, "the rollback was caused by a communication failure"},
0118 {XA_RBDEADLOCK, "a deadlock was detected"},
0119 {XA_RBINTEGRITY, "a condition that violates the integrity of the resources was detected"},
0120 {XA_RBOTHER, "the resource manager rolled back the transaction branch for a reason not on this list"},
0121 {XA_RBPROTO, "a protocol error occurred in the resource manager"},
0122 {XA_RBTIMEOUT, "a transaction branch took too long"},
0123 {XA_RBTRANSIENT, "may retry the transaction branch"},
0124 {XA_RBEND, " the inclusive upper bound of the rollback codes"},
0125 {XA_NOMIGRATE, "resumption must occur where suspension occurred"},
0126 {XA_HEURHAZ, "the transaction branch may have been heuristically completed"},
0127 {XA_HEURCOM, "the transaction branch has been heuristically committed"},
0128 {XA_HEURRB, "the transaction branch has been heuristically rolled back"},
0129 {XA_HEURMIX, "the transaction branch has been heuristically committed and rolled back"},
0130 {XA_RETRY, "routine returned with no effect and may be reissued"},
0131 {XA_RDONLY, "the transaction branch was read-only and has been committed"},
0132 {XA_OK, "normal execution"},
0133 {XAER_ASYNC, "asynchronous operation already outstanding"},
0134 {XAER_RMERR, "a resource manager error occurred in the transaction branch"},
0135 {XAER_NOTA, "the XID is not valid"},
0136 {XAER_INVAL, "invalid arguments were given"},
0137 {XAER_PROTO, "routine invoked in an improper context"},
0138 {XAER_RMFAIL, "resource manager unavailable"},
0139 {XAER_DUPID, "the XID already exists"},
0140 {XAER_OUTSIDE, "resource manager doing work outside global transaction"},
0141 };
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151 expublic char * tpecodestr(int err)
0152 {
0153 return ATMI_ERROR_DESCRIPTION(err);
0154 }
0155
0156
0157
0158
0159
0160
0161 expublic void TP_error (char *str)
0162 {
0163 ATMI_TLS_ENTRY;
0164
0165 if (EXEOS!=G_atmi_tls->M_atmi_error_msg_buf[0])
0166 {
0167 fprintf(stderr, "%s:%d:%s (%s)\n", str,
0168 G_atmi_tls->M_atmi_error,
0169 ATMI_ERROR_DESCRIPTION(G_atmi_tls->M_atmi_error),
0170 G_atmi_tls->M_atmi_error_msg_buf);
0171 }
0172 else
0173 {
0174 fprintf(stderr, "%s:%d:%s\n", str, G_atmi_tls->M_atmi_error,
0175 ATMI_ERROR_DESCRIPTION(G_atmi_tls->M_atmi_error));
0176 }
0177 }
0178
0179
0180
0181
0182
0183
0184 expublic char * tpstrerror (int err)
0185 {
0186 ATMI_TLS_ENTRY;
0187 if (EXEOS!=G_atmi_tls->M_atmi_error_msg_buf[0])
0188 {
0189 snprintf(G_atmi_tls->errbuf, sizeof(G_atmi_tls->errbuf),
0190 "%d:%s (last error %d: %s)",
0191 err,
0192 ATMI_ERROR_DESCRIPTION(err),
0193 G_atmi_tls->M_atmi_error,
0194 G_atmi_tls->M_atmi_error_msg_buf);
0195 }
0196 else
0197 {
0198 snprintf(G_atmi_tls->errbuf, sizeof(G_atmi_tls->errbuf), "%d:%s",
0199 err, ATMI_ERROR_DESCRIPTION(err));
0200 }
0201
0202 return G_atmi_tls->errbuf;
0203 }
0204
0205
0206
0207
0208
0209 expublic int * _exget_tperrno_addr (void)
0210 {
0211 ATMI_TLS_ENTRY;
0212 return &G_atmi_tls->M_atmi_error;
0213 }
0214
0215
0216
0217
0218
0219
0220
0221 expublic void ndrx_TPset_error(int error_code)
0222 {
0223 ATMI_TLS_ENTRY;
0224
0225 NDRX_LOG(log_warn, "%s: %d (%s)",
0226 __func__, error_code, ATMI_ERROR_DESCRIPTION(error_code));
0227
0228 G_atmi_tls->M_atmi_error_msg_buf[0] = EXEOS;
0229 G_atmi_tls->M_atmi_error = error_code;
0230 }
0231
0232
0233
0234
0235 expublic void ndrx_TPset_error_nstd(void)
0236 {
0237 int err = _Nis_error();
0238
0239 if (err)
0240 {
0241 NDRX_STRCPY_SAFE(G_atmi_tls->M_atmi_error_msg_buf, ndrx_Nemsg_buf());
0242 }
0243
0244
0245 switch (err)
0246 {
0247 case NEINVALKEY:
0248 case NEMANDATORY:
0249 case NEFORMAT:
0250 case NEINVAL:
0251 case NEINVALINI:
0252 err=TPEINVAL;
0253 break;
0254 case NEMALLOC:
0255 case NEUNIX:
0256 err=TPEOS;
0257 break;
0258 case NEPLUGIN:
0259 case NESYSTEM:
0260 err=TPESYSTEM;
0261 break;
0262 case NETOUT:
0263 err=TPETIME;
0264 break;
0265 case NENOCONN:
0266 err=TPENOENT;
0267 break;
0268 case NENOSPACE:
0269 case NELIMIT:
0270 err=TPELIMIT;
0271 break;
0272 default:
0273 err=TPESYSTEM;
0274 break;
0275 }
0276
0277 G_atmi_tls->M_atmi_error=err;
0278 }
0279
0280
0281
0282
0283
0284
0285
0286 expublic void ndrx_TPset_error_msg(int error_code, char *msg)
0287 {
0288 int msg_len;
0289 int err_len;
0290 ATMI_TLS_ENTRY;
0291
0292 if (!G_atmi_tls->M_atmi_error)
0293 {
0294 msg_len = strlen(msg);
0295 err_len = (msg_len>MAX_TP_ERROR_LEN)?MAX_TP_ERROR_LEN:msg_len;
0296
0297
0298 NDRX_LOG(log_warn, "_TPset_error_msg: %d (%s) [%s]", error_code,
0299 ATMI_ERROR_DESCRIPTION(error_code), msg);
0300 G_atmi_tls->M_atmi_error_msg_buf[0] = EXEOS;
0301 strncat(G_atmi_tls->M_atmi_error_msg_buf, msg, err_len);
0302 G_atmi_tls->M_atmi_error = error_code;
0303 }
0304 }
0305
0306
0307
0308
0309
0310
0311 expublic void ndrx_TPoverride_code(int error_code)
0312 {
0313 ATMI_TLS_ENTRY;
0314 G_atmi_tls->M_atmi_error = error_code;
0315 }
0316
0317
0318
0319
0320
0321
0322
0323
0324 expublic void ndrx_TPset_error_fmt(int error_code, const char *fmt, ...)
0325 {
0326 char msg[MAX_TP_ERROR_LEN+1] = {EXEOS};
0327 va_list ap;
0328 ATMI_TLS_ENTRY;
0329
0330 if (!G_atmi_tls->M_atmi_error)
0331 {
0332 va_start(ap, fmt);
0333 (void) vsnprintf(msg, sizeof(msg), fmt, ap);
0334 va_end(ap);
0335
0336 NDRX_STRCPY_SAFE(G_atmi_tls->M_atmi_error_msg_buf, msg);
0337 G_atmi_tls->M_atmi_error = error_code;
0338
0339 NDRX_LOG(log_warn, "%s: %d (%s) [%s]", __func__,
0340 error_code, ATMI_ERROR_DESCRIPTION(error_code),
0341 G_atmi_tls->M_atmi_error_msg_buf);
0342 }
0343 }
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353 expublic void ndrx_TPset_error_fmt_rsn_silent(int error_code,
0354 short reason, const char *fmt, ...)
0355 {
0356 char msg[MAX_TP_ERROR_LEN+1] = {EXEOS};
0357 va_list ap;
0358 ATMI_TLS_ENTRY;
0359
0360 if (!G_atmi_tls->M_atmi_error)
0361 {
0362 va_start(ap, fmt);
0363 (void) vsnprintf(msg, sizeof(msg), fmt, ap);
0364 va_end(ap);
0365
0366 NDRX_STRCPY_SAFE(G_atmi_tls->M_atmi_error_msg_buf, msg);
0367 G_atmi_tls->M_atmi_error = error_code;
0368 G_atmi_tls->M_atmi_reason = reason;
0369 }
0370 }
0371
0372
0373
0374
0375
0376
0377
0378
0379 expublic void ndrx_TPset_error_fmt_rsn(int error_code, short reason, const char *fmt, ...)
0380 {
0381 char msg[MAX_TP_ERROR_LEN+1] = {EXEOS};
0382 va_list ap;
0383 int lev = log_warn;
0384 ATMI_TLS_ENTRY;
0385
0386 if (!G_atmi_tls->M_atmi_error)
0387 {
0388 va_start(ap, fmt);
0389 (void) vsnprintf(msg, sizeof(msg), fmt, ap);
0390 va_end(ap);
0391
0392
0393 if (XA_RDONLY==reason)
0394 {
0395 lev = log_debug;
0396 }
0397
0398 NDRX_STRCPY_SAFE(G_atmi_tls->M_atmi_error_msg_buf, msg);
0399 G_atmi_tls->M_atmi_error = error_code;
0400 G_atmi_tls->M_atmi_reason = reason;
0401
0402 NDRX_LOG(lev, "%s: %d (%s) reason: %d [%s]", __func__,
0403 error_code, ATMI_ERROR_DESCRIPTION(error_code), reason,
0404 G_atmi_tls->M_atmi_error_msg_buf);
0405 }
0406 }
0407
0408
0409
0410
0411 expublic void ndrx_TPunset_error(void)
0412 {
0413 ATMI_TLS_ENTRY;
0414
0415 G_atmi_tls->M_atmi_error_msg_buf[0]=EXEOS;
0416 G_atmi_tls->M_atmi_error = BMINVAL;
0417 G_atmi_tls->M_atmi_reason = NDRX_XA_ERSN_NONE;
0418 }
0419
0420
0421
0422
0423 expublic int ndrx_TPis_error(void)
0424 {
0425 ATMI_TLS_ENTRY;
0426 return G_atmi_tls->M_atmi_error;
0427 }
0428
0429
0430
0431
0432
0433 expublic void ndrx_TPappend_error_msg(char *msg)
0434 {
0435 int free_space;
0436 int app_error_len = strlen(msg);
0437 int n;
0438
0439 ATMI_TLS_ENTRY;
0440
0441 free_space = MAX_TP_ERROR_LEN-strlen(G_atmi_tls->M_atmi_error_msg_buf);
0442
0443 n = free_space<app_error_len?free_space:app_error_len;
0444 strncat(G_atmi_tls->M_atmi_error_msg_buf, msg, n);
0445 }
0446
0447
0448
0449
0450
0451
0452
0453 expublic short atmi_xa_get_reason(void)
0454 {
0455 ATMI_TLS_ENTRY;
0456 return G_atmi_tls->M_atmi_reason;
0457 }
0458
0459
0460
0461
0462
0463
0464
0465 expublic void atmi_xa_set_error(UBFH *p_ub, short error_code, short reason)
0466 {
0467 if (!atmi_xa_is_error(p_ub))
0468 {
0469 NDRX_LOG(log_warn, "%s: %d (%s)", __func__,
0470 error_code, ATMI_ERROR_DESCRIPTION(error_code));
0471 Bchg(p_ub, TMERR_CODE, 0, (char *)&error_code, 0L);
0472 Bchg(p_ub, TMERR_REASON, 0, (char *)&reason, 0L);
0473 }
0474 }
0475
0476
0477
0478
0479
0480
0481
0482 expublic void atmi_xa_set_error_msg(UBFH *p_ub, short error_code, short reason, char *msg)
0483 {
0484 if (!atmi_xa_is_error(p_ub))
0485 {
0486 int lev;
0487 if (TPMINVAL==error_code)
0488 {
0489 lev = log_debug;
0490 }
0491 else
0492 {
0493 lev = log_warn;
0494 }
0495 NDRX_LOG(lev, "%s: %d (%s) [%s]", __func__, error_code,
0496 ATMI_ERROR_DESCRIPTION(error_code), msg);
0497
0498 Bchg(p_ub, TMERR_CODE, 0, (char *)&error_code, 0L);
0499 Bchg(p_ub, TMERR_REASON, 0, (char *)&reason, 0L);
0500 Bchg(p_ub, TMERR_MSG, 0, msg, 0L);
0501 }
0502 }
0503
0504
0505
0506
0507
0508
0509
0510
0511 expublic void atmi_xa_set_error_fmt(UBFH *p_ub, short error_code, short reason,
0512 const char *fmt, ...)
0513 {
0514 char msg[MAX_TP_ERROR_LEN+1] = {EXEOS};
0515 va_list ap;
0516
0517 if (!atmi_xa_is_error(p_ub))
0518 {
0519 va_start(ap, fmt);
0520 (void) vsnprintf(msg, sizeof(msg), fmt, ap);
0521 va_end(ap);
0522
0523 NDRX_LOG(log_warn, "atmi_xa_set_error_fmt: %d (%s) [%s]",
0524 error_code, ATMI_ERROR_DESCRIPTION(error_code),
0525 msg);
0526 Bchg(p_ub, TMERR_CODE, 0, (char *)&error_code, 0L);
0527 Bchg(p_ub, TMERR_REASON, 0, (char *)&reason, 0L);
0528 Bchg(p_ub, TMERR_MSG, 0, msg, 0L);
0529 }
0530 }
0531
0532
0533
0534
0535
0536 expublic void ndrx_TPset_error_ubf(UBFH *p_ub)
0537 {
0538 short error_code;
0539 short reason;
0540
0541 error_code = (short)G_atmi_tls->M_atmi_error;
0542 reason = (short)G_atmi_tls->M_atmi_reason;
0543
0544 Bchg(p_ub, TMERR_CODE, 0, (char *)&error_code, 0L);
0545 Bchg(p_ub, TMERR_REASON, 0, (char *)&reason, 0L);
0546 Bchg(p_ub, TMERR_MSG, 0, G_atmi_tls->M_atmi_error_msg_buf, 0L);
0547 }
0548
0549
0550
0551
0552
0553
0554 expublic void atmi_xa_override_error(UBFH *p_ub, short error_code)
0555 {
0556 NDRX_LOG(log_warn, "atmi_xa_override_error: %d (%s)",
0557 error_code, ATMI_ERROR_DESCRIPTION(error_code));
0558 Bchg(p_ub, TMERR_CODE, 0, (char *)&error_code, 0L);
0559 }
0560
0561
0562
0563
0564
0565 expublic void atmi_xa_unset_error(UBFH *p_ub)
0566 {
0567 Bdel(p_ub, TMERR_CODE, 0);
0568 Bdel(p_ub, TMERR_REASON, 0);
0569 Bdel(p_ub, TMERR_MSG, 0);
0570 }
0571
0572
0573
0574
0575 expublic int atmi_xa_is_error(UBFH *p_ub)
0576 {
0577 short errcode = TPMINVAL;
0578 Bget(p_ub, TMERR_CODE, 0, (char *)&errcode, 0L);
0579
0580 return (int)errcode;
0581 }
0582
0583
0584
0585
0586
0587 expublic void atmi_xa_error_msg(UBFH *p_ub, char *msg)
0588 {
0589 char tmp[MAX_TP_ERROR_LEN+1] = {EXEOS};
0590
0591 Bget(p_ub, TMERR_MSG, 0, tmp, 0L);
0592
0593 int free_space = MAX_TP_ERROR_LEN-strlen(tmp);
0594 int app_error_len = strlen(msg);
0595 int n;
0596 n = free_space<app_error_len?free_space:app_error_len;
0597 strncat(tmp, msg, n);
0598
0599 Bchg(p_ub, TMERR_MSG, 0, tmp, 0L);
0600 }
0601
0602
0603
0604
0605
0606 expublic void atmi_xa2tperr(UBFH *p_ub)
0607 {
0608 char msg[MAX_TP_ERROR_LEN+1] = {EXEOS};
0609 short code;
0610 short reason = 0;
0611 ATMI_TLS_ENTRY;
0612
0613
0614 if (Bpres(p_ub, TMERR_CODE, 0))
0615 {
0616 ndrx_TPunset_error();
0617
0618 Bget(p_ub, TMERR_CODE, 0, (char *)&code, 0L);
0619 Bget(p_ub, TMERR_MSG, 0, msg, 0L);
0620 Bget(p_ub, TMERR_REASON, 0, (char *)&reason, 0L);
0621
0622 ndrx_TPset_error_msg((int)code, msg);
0623
0624
0625 if (!G_atmi_tls->M_atmi_reason)
0626 {
0627 G_atmi_tls->M_atmi_reason = reason;
0628 }
0629
0630 }
0631 }
0632
0633
0634
0635
0636
0637
0638 expublic char *atmi_xa_geterrstr(int code)
0639 {
0640 int i;
0641 static char* unknown_err = "Unknown error";
0642 char *ret = unknown_err;
0643
0644 for (i=0; i<N_DIM(M_atmi_xa_error_defs); i++)
0645 {
0646 if (code == M_atmi_xa_error_defs[i].errcode)
0647 {
0648 ret= M_atmi_xa_error_defs[i].msg;
0649 goto out;
0650 }
0651 }
0652
0653 out:
0654
0655 return ret;
0656 }
0657
0658
0659
0660
0661
0662
0663 expublic void atmi_xa_approve(UBFH *p_ub)
0664 {
0665 atmi_xa_set_error_msg(p_ub, 0, NDRX_XA_ERSN_NONE, "Success");
0666 }
0667
0668
0669
0670
0671
0672
0673
0674
0675 expublic void ndrx_TPsave_error(atmi_error_t *p_err)
0676 {
0677 ATMI_TLS_ENTRY;
0678
0679 p_err->atmi_error = G_atmi_tls->M_atmi_error;
0680 p_err->atmi_reason = G_atmi_tls->M_atmi_reason;
0681 NDRX_STRCPY_SAFE(p_err->atmi_error_msg_buf, G_atmi_tls->M_atmi_error_msg_buf);
0682 }
0683
0684
0685
0686
0687
0688 expublic void ndrx_TPrestore_error(atmi_error_t *p_err)
0689 {
0690 ATMI_TLS_ENTRY;
0691 G_atmi_tls->M_atmi_error = p_err->atmi_error;
0692 G_atmi_tls->M_atmi_reason = p_err->atmi_reason;
0693 NDRX_STRCPY_SAFE(G_atmi_tls->M_atmi_error_msg_buf, p_err->atmi_error_msg_buf);
0694 }
0695