static void program_scheduler_handle_error(ProgramScheduler *program_scheduler, bool log_as_error, const char *format, ...) { va_list arguments; char buffer[1024]; Program *program = containerof(program_scheduler, Program, scheduler); String *message; va_start(arguments, format); vsnprintf(buffer, sizeof(buffer), format, arguments); va_end(arguments); if (log_as_error) { log_error("Scheduler error for program object (identifier: %s) occurred: %s", program->identifier->buffer, buffer); } else { log_debug("Scheduler error for program object (identifier: %s) occurred: %s", program->identifier->buffer, buffer); } if (string_wrap(buffer, NULL, OBJECT_CREATE_FLAG_INTERNAL | OBJECT_CREATE_FLAG_LOCKED, NULL, &message) != API_E_SUCCESS) { message = NULL; } program_scheduler_stop(program_scheduler, message); }
APIE inventory_get_stock_string(const char *buffer, String **string) { int i; String *candidate; APIE error_code; String **string_ptr; for (i = 0; i < _stock_strings.count; ++i) { candidate = *(String **)array_get(&_stock_strings, i); if (strcmp(candidate->buffer, buffer) == 0) { string_acquire_and_lock(candidate); *string = candidate; return API_E_SUCCESS; } } error_code = string_wrap(buffer, NULL, OBJECT_CREATE_FLAG_INTERNAL | OBJECT_CREATE_FLAG_LOCKED, NULL, string); if (error_code != API_E_SUCCESS) { return error_code; } string_ptr = array_append(&_stock_strings); if (string_ptr == NULL) { error_code = api_get_error_code_from_errno(); log_error("Could not append to stock string array: %s (%d)", get_errno_name(errno), errno); string_unlock_and_release(*string); return error_code; } *string_ptr = *string; string_acquire_and_lock(*string); return API_E_SUCCESS; }
static File *program_scheduler_prepare_continuous_log(ProgramScheduler *program_scheduler, struct timeval timestamp, const char *suffix) { struct tm localized_timestamp; char iso8601dt[64] = "unknown"; char iso8601usec[16] = ""; char iso8601tz[16] = ""; char buffer[1024]; APIE error_code; String *name; File *file; // format ISO 8601 date, time and timezone offset if (localtime_r(×tamp.tv_sec, &localized_timestamp) != NULL) { // can use common ISO 8601 format YYYY-MM-DDThh:mm:ss.uuuuuu±hhmm // because this timestamp is not part of a filename strftime(iso8601dt, sizeof(iso8601dt), "%Y-%m-%dT%H:%M:%S", &localized_timestamp); snprintf(iso8601usec, sizeof(iso8601usec), ".%06d", (int)timestamp.tv_usec); strftime(iso8601tz, sizeof(iso8601tz), "%z", &localized_timestamp); } // format log filename if (robust_snprintf(buffer, sizeof(buffer), "%s/continuous_%s.log", program_scheduler->log_directory, suffix) < 0) { program_scheduler_handle_error(program_scheduler, true, "Could not format %s log file name: %s (%d)", suffix, get_errno_name(errno), errno); return NULL; } error_code = string_wrap(buffer, NULL, OBJECT_CREATE_FLAG_INTERNAL | OBJECT_CREATE_FLAG_LOCKED, NULL, &name); if (error_code != API_E_SUCCESS) { program_scheduler_handle_error(program_scheduler, true, "Could not wrap %s log file name into string object: %s (%d)", suffix, api_get_error_code_name(error_code), error_code); return NULL; } // open log file error_code = file_open(name->base.id, FILE_FLAG_WRITE_ONLY | FILE_FLAG_CREATE | FILE_FLAG_APPEND, 0644, 1000, 1000, NULL, OBJECT_CREATE_FLAG_INTERNAL, NULL, &file); string_unlock_and_release(name); if (error_code != API_E_SUCCESS) { program_scheduler_handle_error(program_scheduler, true, "Could not open/create %s log file: %s (%d)", suffix, api_get_error_code_name(error_code), error_code); return NULL; } // format header if (robust_snprintf(buffer, sizeof(buffer), "\n\n%s%s%s\n-------------------------------------------------------------------------------\n", iso8601dt, iso8601usec, iso8601tz) < 0) { program_scheduler_handle_error(program_scheduler, true, "Could not format timestamp for %s log file: %s (%d)", suffix, get_errno_name(errno), errno); file_release(file); return NULL; } // write header if (write(file->fd, buffer, strlen(buffer)) < 0) { program_scheduler_handle_error(program_scheduler, true, "Could not write timestamp to %s log file: %s (%d)", suffix, get_errno_name(errno), errno); file_release(file); return NULL; } return file; }
static File *program_scheduler_prepare_individual_log(ProgramScheduler *program_scheduler, struct timeval timestamp, const char *suffix) { uint64_t microseconds = (uint64_t)timestamp.tv_sec * 1000000 + (uint64_t)timestamp.tv_usec; struct tm localized_timestamp; char iso8601[128] = "unknown"; char buffer[1024]; struct stat st; APIE error_code; int counter = 0; String *name; File *file; // format ISO 8601 date, time and timezone offset if (localtime_r(×tamp.tv_sec, &localized_timestamp) != NULL) { // use ISO 8601 format YYYYMMDDThhmmss±hhmm instead of the common // YYYY-MM-DDThh:mm:ss±hhmm because the colons in there can create // problems on Windows which does not allow colons in filenames strftime(iso8601, sizeof(iso8601), "%Y%m%dT%H%M%S%z", &localized_timestamp); } // create log file, include microsecond timestamp to reduce the chance for // file name collisions and as easy-to-parse timestamp for brickv if (robust_snprintf(buffer, sizeof(buffer), "%s/%s_%"PRIu64"_%s.log", program_scheduler->log_directory, iso8601, microseconds, suffix) < 0) { program_scheduler_handle_error(program_scheduler, true, "Could not format %s log file name: %s (%d)", suffix, get_errno_name(errno), errno); return NULL; } while (counter < 1000) { // only try to create the log file if it's not already existing if (lstat(buffer, &st) < 0) { error_code = string_wrap(buffer, NULL, OBJECT_CREATE_FLAG_INTERNAL | OBJECT_CREATE_FLAG_LOCKED, NULL, &name); if (error_code != API_E_SUCCESS) { program_scheduler_handle_error(program_scheduler, true, "Could not wrap %s log file name into string object: %s (%d)", suffix, api_get_error_code_name(error_code), error_code); return NULL; } error_code = file_open(name->base.id, FILE_FLAG_WRITE_ONLY | FILE_FLAG_CREATE | FILE_FLAG_EXCLUSIVE, 0644, 1000, 1000, NULL, OBJECT_CREATE_FLAG_INTERNAL, NULL, &file); string_unlock_and_release(name); if (error_code == API_E_SUCCESS) { return file; } // if file_open failed with an error different from API_E_ALREADY_EXISTS // then give up, there is no point trying to recover this situation if (error_code != API_E_ALREADY_EXISTS) { program_scheduler_handle_error(program_scheduler, true, "Could not create %s log file: %s (%d)", suffix, api_get_error_code_name(error_code), error_code); return NULL; } } if (robust_snprintf(buffer, sizeof(buffer), "%s/%s_%"PRIu64"+%03d_%s.log", program_scheduler->log_directory, iso8601, microseconds, ++counter, suffix) < 0) { program_scheduler_handle_error(program_scheduler, true, "Could not format %s log file name: %s (%d)", suffix, get_errno_name(errno), errno); return NULL; } } program_scheduler_handle_error(program_scheduler, true, "Could not create %s log file within 1000 attempts", suffix); return NULL; }
/** Sets the item's message text. */ void LogTreeItem::setMessage(const QString &message) { setText(COL_MESG, message); setToolTip(COL_MESG, string_wrap(message, 80, " ", "\r\n")); }