void PAR_warning(const Arg::StatusVector& v) { /************************************** * * P A R _ w a r n i n g * ************************************** * * Functional description * This is for GBAK so that we can pass warning messages * back to the client. DO NOT USE this function until we * fully implement warning at the engine level. * * We will use the status vector like a warning vector. What * we are going to do is leave the [1] position of the vector * as 0 so that this will not be treated as an error, and we * will place our warning message in the consecutive positions. * It will be up to the caller to check these positions for * the message. * **************************************/ fb_assert(v.value()[0] == isc_arg_warning); thread_db* tdbb = JRD_get_thread_data(); // Make sure that the [1] position is 0 indicating that no error has occurred Arg::Gds p(FB_SUCCESS); // Now place your warning messages p.append(v); // Save into tdbb p.copyTo(tdbb->tdbb_status_vector); }
//____________________________________________________________ // // Post an error sequence to the status vector. Since an error // sequence can, in theory, be arbitrarily lock, pull a cheap // trick to get the address of the argument vector. // // this is a copy of the routine found in err.c with the // exception that it uses a different error block - one which // is local to the V3 DSQL routines... // static void error_post(const Arg::StatusVector& v) { // Save status vector in appropriate place v.copyTo(UDSQL_error->dsql_status); // Give up whatever we were doing and return to the user. Firebird::status_exception::raise(UDSQL_error->dsql_status); }
void ERR_post_nothrow(const Arg::StatusVector& v) /************************************** * * E R R _ p o s t _ n o t h r o w * ************************************** * * Functional description * Create a status vector. * **************************************/ { fb_assert(v.value()[0] == isc_arg_gds); ISC_STATUS_ARRAY vector; v.copyTo(vector); ERR_make_permanent(vector); internal_post(vector); }
bool ERR_post_warning(const Arg::StatusVector& v) { /************************************** * * E R R _ p o s t _ w a r n i n g * ************************************** * * Functional description * Post a warning to the current status vector. * **************************************/ fb_assert(v.value()[0] == isc_arg_warning); size_t indx = 0, warning_indx = 0; ISC_STATUS* const status_vector = JRD_get_thread_data()->tdbb_status_vector; if (status_vector[0] != isc_arg_gds || (status_vector[0] == isc_arg_gds && status_vector[1] == 0 && status_vector[2] != isc_arg_warning)) { // this is a blank status vector fb_utils::init_status(status_vector); indx = 2; } else { // find end of a status vector PARSE_STATUS(status_vector, indx, warning_indx); if (indx) --indx; } // stuff the warning if (indx + v.length() + 1 < ISC_STATUS_LENGTH) { memcpy(&status_vector[indx], v.value(), sizeof(ISC_STATUS) * (v.length() + 1)); ERR_make_permanent(&status_vector[indx]); return true; } // not enough free space return false; }
void UserManagement::checkSecurityResult(int errcode, IStatus* status, const char* userName, int operation) { if (!errcode) { return; } errcode = Auth::setGsecCode(errcode, operation); Arg::StatusVector tmp; tmp << Arg::Gds(ENCODE_ISC_MSG(errcode, GSEC_MSG_FAC)); if (errcode == GsecMsg22) { tmp << userName; } tmp.append(Arg::StatusVector(status)); tmp.raise(); }
// We've got a blr error other than a syntax error. Handle it. static void par_error(BlrReader& blrReader, const Arg::StatusVector& v, bool isSyntaxError) { fb_assert(v.value()[0] == isc_arg_gds); // Don't bother to pass tdbb for error handling thread_db* tdbb = JRD_get_thread_data(); if (isSyntaxError) { blrReader.seekBackward(1); Arg::Gds p(isc_invalid_blr); p << Arg::Num(blrReader.getOffset()); p.append(v); p.copyTo(tdbb->tdbb_status_vector); } else v.copyTo(tdbb->tdbb_status_vector); // Give up whatever we were doing and return to the user. ERR_punt(); }
static ISC_STATUS error(ISC_STATUS* status, const Arg::StatusVector& v) { /************************************** * * e r r o r * ************************************** * * Functional description * Stuff a status vector. * **************************************/ return v.copyTo(status); }
void ERR_make_permanent(Arg::StatusVector& v) /************************************** * * E R R _ m a k e _ p e r m a n e n t * ************************************** * * Functional description * Make strings in vector permanent * **************************************/ { ERR_make_permanent(const_cast<ISC_STATUS*>(v.value())); }
void ERR_build_status(ISC_STATUS* status_vector, const Arg::StatusVector& v) { /************************************** * * E R R _ a p p e n d _ s t a t u s * ************************************** * * Functional description * Append the given status vector with the passed arguments. * **************************************/ v.copyTo(status_vector); ERR_make_permanent(status_vector); }
void UserManagement::execute(USHORT id) { #if (defined BOOT_BUILD || defined EMBEDDED) status_exception::raise(Arg::Gds(isc_wish_list)); #else if (!transaction || !commands[id]) { // Already executed return; } if (id >= commands.getCount()) { status_exception::raise(Arg::Gds(isc_random) << "Wrong job id passed to UserManagement::execute()"); } ISC_STATUS_ARRAY status; int errcode = (!commands[id]->user_name_entered) ? GsecMsg18 : SECURITY_exec_line(status, database, transaction, commands[id], NULL, NULL); switch (errcode) { case 0: // nothing break; case GsecMsg22: { Arg::StatusVector tmp; tmp << Arg::Gds(ENCODE_ISC_MSG(errcode, GSEC_MSG_FAC)) << Arg::Str(commands[id]->user_name); tmp.append(Arg::StatusVector(&status[0])); tmp.raise(); } default: { Arg::StatusVector tmp; tmp << Arg::Gds(ENCODE_ISC_MSG(errcode, GSEC_MSG_FAC)); tmp.append(Arg::StatusVector(&status[0])); tmp.raise(); } } delete commands[id]; commands[id] = NULL; #endif }
void ERR_warning(const Arg::StatusVector& v) { /************************************** * * E R R _ w a r n i n g * ************************************** * * Functional description * Write an error out to the status vector but * don't throw an exception. This allows * sending a warning message back to the user * without stopping execution of a request. Note * that subsequent errors can supersede this one. * **************************************/ thread_db* tdbb = JRD_get_thread_data(); ISC_STATUS* s = tdbb->tdbb_status_vector; v.copyTo(s); ERR_make_permanent(s); DEBUG; tdbb->getRequest()->req_flags |= req_warning; }
void Jrd::Attachment::resetSession(thread_db* tdbb, jrd_tra** traHandle) { jrd_tra* oldTran = traHandle ? *traHandle : nullptr; if (att_transactions) { int n = 0; bool err = false; for (const jrd_tra* tra = att_transactions; tra; tra = tra->tra_next) { n++; if (tra != oldTran && !(tra->tra_flags & TRA_prepared)) err = true; } // Cannot reset user session // There are open transactions (@1 active) if (err) { ERR_post(Arg::Gds(isc_ses_reset_err) << Arg::Gds(isc_ses_reset_open_trans) << Arg::Num(n)); } } // TODO: trigger before reset ULONG oldFlags = 0; SSHORT oldTimeout = 0; if (oldTran) { oldFlags = oldTran->tra_flags; oldTimeout = oldTran->tra_lock_timeout; try { // It will also run run ON TRANSACTION ROLLBACK triggers JRD_rollback_transaction(tdbb, oldTran); *traHandle = nullptr; } catch (const Exception& ex) { Arg::StatusVector error; error.assign(ex); error.prepend(Arg::Gds(isc_ses_reset_err)); error.raise(); } // Session was reset with warning(s) // Transaction is rolled back due to session reset, all changes are lost if (oldFlags & TRA_write) { ERR_post_warning(Arg::Warning(isc_ses_reset_warn) << Arg::Gds(isc_ses_reset_tran_rollback)); } } // reset DecFloat att_dec_status = DecimalStatus::DEFAULT; att_dec_binding = DecimalBinding::DEFAULT; // reset timeouts setIdleTimeout(0); setStatementTimeout(0); // reset context variables att_context_vars.clear(); // reset role if (att_user->resetRole()) SCL_release_all(att_security_classes); // reset GTT's releaseGTTs(tdbb); if (oldTran) { try { jrd_tra* newTran = TRA_start(tdbb, oldFlags, oldTimeout); // run ON TRANSACTION START triggers JRD_run_trans_start_triggers(tdbb, newTran); tdbb->setTransaction(newTran); *traHandle = newTran; } catch (const Exception& ex) { Arg::StatusVector error; error.assign(ex); error.prepend(Arg::Gds(isc_ses_reset_err)); error.raise(); } } // TODO: trigger after reset }