Skip to content

Commit

Permalink
Add support for JOR files
Browse files Browse the repository at this point in the history
JOR files are journals of COBOL executions. This commit implements
minimalist support for JOR files with the following features:
* extensible: the format can be easily extended in the future
* compact: the format is binary and does not take too much space on disk

Currently, the JOR file contains the arguments, the execution start
and stop times and per-file statistics of opens, reads, writes, starts
and closes operations.
  • Loading branch information
lefessan committed Mar 20, 2024
1 parent 6201481 commit 5dda38e
Show file tree
Hide file tree
Showing 7 changed files with 557 additions and 9 deletions.
2 changes: 1 addition & 1 deletion libcob/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
lib_LTLIBRARIES = libcob.la
libcob_la_SOURCES = common.c move.c numeric.c strings.c \
fileio.c call.c intrinsic.c termio.c screenio.c reportio.c cobgetopt.c \
mlio.c coblocal.h cconv.c system.def profiling.c
mlio.c coblocal.h cconv.c system.def profiling.c jor.c

if LOCAL_CJSON
nodist_libcob_la_SOURCES = cJSON.c
Expand Down
4 changes: 4 additions & 0 deletions libcob/coblocal.h
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,9 @@ typedef struct __cob_settings {
FILE *cob_dump_file; /* FILE* to write DUMP information to */

char *cob_dump_filename; /* Place to write dump of variables */
char *cob_jor_filename; /* Place to write the JOR file */
int cob_jor_enable; /* Whether JOR is enabled */
int cob_jor_max_size; /* Max size of JOR buffer (4096 by default) */
char *cob_prof_filename; /* Place to write profiling data */
int cob_prof_enable; /* Whether profiling is enabled */
int cob_prof_max_depth; /* Max stack depth during profiling (255 by default) */
Expand Down Expand Up @@ -448,6 +451,7 @@ COB_HIDDEN void cob_init_move (cob_global *, cob_settings *);
COB_HIDDEN void cob_init_prof (cob_global *, cob_settings *);
COB_HIDDEN void cob_init_screenio (cob_global *, cob_settings *);
COB_HIDDEN void cob_init_mlio (cob_global * const);
COB_HIDDEN void cob_init_jor (cob_global *, cob_settings *, int, char**);

COB_HIDDEN const char *cob_statement_name[STMT_MAX_ENTRY];

Expand Down
14 changes: 13 additions & 1 deletion libcob/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,9 @@ static struct config_tbl gc_conf[] = {
{"COB_CORE_ON_ERROR", "core_on_error", "0", coeopts, GRP_MISC, ENV_UINT | ENV_ENUMVAL, SETPOS (cob_core_on_error)},
{"COB_CORE_FILENAME", "core_filename", "./core.libcob", NULL, GRP_MISC, ENV_STR, SETPOS (cob_core_filename)},
{"COB_DUMP_FILE", "dump_file", NULL, NULL, GRP_MISC, ENV_FILE, SETPOS (cob_dump_filename)},
{"COB_JOR_FILE", "jor_file", "cob-jor-$b-$$-$d-$t.jor", NULL, GRP_MISC, ENV_FILE, SETPOS (cob_jor_filename)},
{"COB_JOR_ENABLE", "jor_enable", "0", NULL, GRP_MISC, ENV_BOOL, SETPOS (cob_jor_enable)},
{"COB_JOR_MAX_SIZE", "jor_max_size", "8192", NULL, GRP_MISC, ENV_UINT, SETPOS (cob_jor_max_size)},
{"COB_PROF_FILE", "prof_file", "cob-prof-$b-$$-$d-$t.csv", NULL, GRP_MISC, ENV_FILE, SETPOS (cob_prof_filename)},
{"COB_PROF_ENABLE", "prof_enable", "0", NULL, GRP_MISC, ENV_BOOL, SETPOS (cob_prof_enable)},
{"COB_PROF_MAX_DEPTH", "prof_max_depth", "8192", NULL, GRP_MISC, ENV_UINT, SETPOS (cob_prof_max_depth)},
Expand Down Expand Up @@ -1113,6 +1116,7 @@ cob_sig_handler (int sig)

#ifdef HAVE_SIG_ATOMIC_T
if (sig_is_handled) {
cob_jor_exit (sig, "signal %d caused termination (2)", sig);
#ifdef HAVE_RAISE
raise (sig);
#else
Expand Down Expand Up @@ -1244,12 +1248,14 @@ cob_sig_handler (int sig)
sig = SIGABRT;
}
signal (sig, SIG_DFL);
cob_jor_exit (sig, "signal %d caused termination", sig);

#ifdef HAVE_RAISE
raise (sig);
#else
kill (cob_sys_getpid (), sig);
#endif

#if 0 /* we don't necessarily want the OS to handle this,
so exit in all other cases*/
exit (sig);
Expand Down Expand Up @@ -3050,6 +3056,7 @@ cob_stop_run (const int status)
longjmp (return_jmp_buf, 1);
}
#endif
cob_jor_exit (status, "STOP RUN reached");
exit (status);
}

Expand Down Expand Up @@ -3104,6 +3111,8 @@ cob_hard_failure ()
longjmp (return_jmp_buf, -1);
}
#endif
cob_jor_exit (EXIT_FAILURE, "hard failure");

/* if explicit requested for errors or
an explicit manual coredump creation did
not work raise an abort here */
Expand Down Expand Up @@ -3139,6 +3148,8 @@ cob_hard_failure_internal (const char *prefix)
longjmp (return_jmp_buf, -2);
}
#endif
cob_jor_exit (EXIT_FAILURE, "hard failure (%s)", prefix);

/* if explicit requested for errors or
an explicit manual coredump creation did
not work raise an abort here */
Expand Down Expand Up @@ -10352,6 +10363,7 @@ cob_init (const int argc, char **argv)

/* Call inits with cobsetptr to get the addresses of all */
/* Screen-IO might be needed for error outputs */
cob_init_jor (cobglobptr, cobsetptr, cob_argc, cob_argv);
cob_init_screenio (cobglobptr, cobsetptr);
cob_init_cconv (cobglobptr);
cob_init_numeric (cobglobptr);
Expand Down
38 changes: 38 additions & 0 deletions libcob/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -1379,6 +1379,12 @@ typedef struct __cob_file_key {
/* File version (likely can be removed from cob_file in the future) */
#define COB_FILE_VERSION 1


#define COB_JOR_FILE_OPERATIONS 10
typedef struct __cob_file_jor {
cob_u32_t *ops [COB_JOR_FILE_OPERATIONS] ;
} cob_file_jor;

/* File structure */

/*NOTE: *** Add new fields to end ***
Expand Down Expand Up @@ -1435,6 +1441,7 @@ typedef struct __cob_file {
const unsigned char* code_set_read; /* CODE-SET conversion for READs */
size_t nconvert_fields; /* Number of logical fields to convert */
cob_field *convert_field; /* logical fields to convert for CODE-SET */
cob_file_jor *jor; /* job occurrence report */
} cob_file;


Expand Down Expand Up @@ -2864,6 +2871,37 @@ COB_EXPIMP cob_field *cob_intr_bit_to_char (cob_field *);
COB_EXPIMP cob_field* cob_intr_hex_of (cob_field*);
COB_EXPIMP cob_field* cob_intr_hex_to_char (cob_field*);



/************************/
/* Functions in jor.c */
/************************/

enum cob_jor_file_operation {
/* order must match field_file_op_name[] in jor.c */
COB_JOR_WRITE_TRY = 0,
COB_JOR_WRITE_OK,
COB_JOR_READ_TRY,
COB_JOR_READ_OK,
COB_JOR_START_TRY,
COB_JOR_START_OK,
COB_JOR_OPEN_TRY,
COB_JOR_OPEN_OK,
COB_JOR_CLOSE_TRY,
COB_JOR_CLOSE_OK,
COB_JOR_AFTER_LAST_OPERATION
};

COB_EXPIMP void cob_jor_exit (int, const char*, ...);
COB_EXPIMP void cob_jor_file_operation (cob_file*, enum cob_jor_file_operation);

/* For extensions to update the way JOR are allocated and saved/sent. */
struct cob_jor_funcs {
void (*save) (const char* filename, char* buffer, int len);
char* (*allocate)(int *size);
};
COB_EXPIMP void cob_jor_set_funcs (struct cob_jor_funcs *);

/************************/
/* Functions in cconv.c */
/************************/
Expand Down
42 changes: 35 additions & 7 deletions libcob/fileio.c
Original file line number Diff line number Diff line change
Expand Up @@ -6148,6 +6148,10 @@ cob_open (cob_file *f, const int mode, const int sharing, cob_field *fnstatus)
{
/*: GC4: mode as cob_open_mode */

int ret;

cob_jor_file_operation (f, COB_JOR_OPEN_TRY);

last_operation_open = 1;

/* File was previously closed with lock */
Expand Down Expand Up @@ -6274,9 +6278,13 @@ cob_open (cob_file *f, const int mode, const int sharing, cob_field *fnstatus)
#endif

/* Open the file */
save_status (f, fnstatus,
fileio_funcs[(int)f->organization]->open (f, file_open_name,
mode, sharing));
ret = fileio_funcs[(int)f->organization]->open (f, file_open_name,
mode, sharing);

if ( ret == COB_STATUS_00_SUCCESS )
cob_jor_file_operation (f, COB_JOR_OPEN_OK);

save_status (f, fnstatus, ret);
}

void
Expand All @@ -6286,6 +6294,8 @@ cob_close (cob_file *f, cob_field *fnstatus, const int opt, const int remfil)
struct file_list *m;
int ret;

cob_jor_file_operation (f, COB_JOR_CLOSE_TRY);

f->flag_read_done = 0;
f->flag_operation = 0;

Expand Down Expand Up @@ -6331,6 +6341,7 @@ cob_close (cob_file *f, cob_field *fnstatus, const int opt, const int remfil)

ret = fileio_funcs[(int)f->organization]->close (f, opt);
if (ret == COB_STATUS_00_SUCCESS) {
cob_jor_file_operation (f, COB_JOR_CLOSE_OK);
switch (opt) {
case COB_CLOSE_LOCK:
f->open_mode = COB_OPEN_LOCKED;
Expand Down Expand Up @@ -6374,6 +6385,8 @@ cob_start (cob_file *f, const int cond, cob_field *key,
int ret;
cob_field tempkey;

cob_jor_file_operation (f, COB_JOR_START_TRY);

f->flag_read_done = 0;
f->flag_first_read = 0;

Expand Down Expand Up @@ -6406,6 +6419,8 @@ cob_start (cob_file *f, const int cond, cob_field *key,
ret = fileio_funcs[(int)f->organization]->start (f, cond, key);
}
if (ret == COB_STATUS_00_SUCCESS) {
cob_jor_file_operation (f, COB_JOR_START_OK);

f->flag_end_of_file = 0;
f->flag_begin_of_file = 0;
f->flag_first_read = 1;
Expand All @@ -6423,6 +6438,8 @@ cob_read (cob_file *f, cob_field *key, cob_field *fnstatus, const int read_opts)
{
int ret;

cob_jor_file_operation (f, COB_JOR_READ_TRY);

f->flag_read_done = 0;

if (unlikely (f->open_mode != COB_OPEN_INPUT
Expand Down Expand Up @@ -6467,6 +6484,8 @@ cob_read (cob_file *f, cob_field *key, cob_field *fnstatus, const int read_opts)
#if defined (COB_EXPERIMENTAL)
case COB_STATUS_0P_NOT_PRINTABLE:
#endif
cob_jor_file_operation (f, COB_JOR_READ_OK);

f->flag_first_read = 0;
f->flag_read_done = 1;
f->flag_end_of_file = 0;
Expand Down Expand Up @@ -6635,6 +6654,10 @@ void
cob_write (cob_file *f, cob_field *rec, const int opt, cob_field *fnstatus,
const unsigned int check_eop)
{
int status;

cob_jor_file_operation (f, COB_JOR_WRITE_TRY);

f->flag_read_done = 0;

if (f->access_mode == COB_ACCESS_SEQUENTIAL) {
Expand Down Expand Up @@ -6726,15 +6749,20 @@ cob_write (cob_file *f, cob_field *rec, const int opt, cob_field *fnstatus,
return;
}
f->record->data = converted_copy;
save_status (f, fnstatus,
fileio_funcs[(int)f->organization]->write (f, opt));
status = fileio_funcs[(int)f->organization]->write (f, opt);
if (status == COB_STATUS_00_SUCCESS)
cob_jor_file_operation (f, COB_JOR_WRITE_OK);
save_status (f, fnstatus, status);

f->record->data = real_rec_data;
cob_free (converted_copy);
return;
}

save_status (f, fnstatus,
fileio_funcs[(int)f->organization]->write (f, opt));
status = fileio_funcs[(int)f->organization]->write (f, opt);
if (status == COB_STATUS_00_SUCCESS)
cob_jor_file_operation (f, COB_JOR_WRITE_OK);
save_status (f, fnstatus, status);
}

void
Expand Down
Loading

0 comments on commit 5dda38e

Please sign in to comment.