GnuCOBOL  2.0
A free COBOL compiler
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
fileio.c File Reference
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdarg.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "libcob.h"
#include "coblocal.h"
Include dependency graph for fileio.c:

Data Structures

struct  file_list
 
struct  cobitem
 
struct  sort_mem_struct
 
struct  queue_struct
 
struct  file_struct
 
struct  cobsort
 

Macros

#define _LFS64_LARGEFILE   1
 
#define _LFS64_STDIO   1
 
#define _FILE_OFFSET_BITS   64
 
#define _LARGEFILE64_SOURCE   1
 
#define fdcobsync   fsync
 
#define _O_TEMPORARY   0
 
#define O_BINARY   0
 
#define COB_LIB_EXPIMP
 
#define COB_MAYSWAP_16(x)   (COB_BSWAP_16((unsigned short)(x)))
 
#define COB_MAYSWAP_32(x)   (COB_BSWAP_32((unsigned int)(x)))
 
#define COBSORTEND   1
 
#define COBSORTABORT   2
 
#define COBSORTFILEERR   3
 
#define COBSORTNOTOPEN   4
 
#define NUM_PREFIX   sizeof(prefix) / sizeof(char *)
 

Functions

static int dummy_delete (cob_file *)
 
static int dummy_rnxt_rewrite (cob_file *, const int)
 
static int dummy_read (cob_file *, cob_field *, const int)
 
static int dummy_start (cob_file *, const int, cob_field *)
 
static int cob_file_open (cob_file *, char *, const int, const int)
 
static int cob_file_close (cob_file *, const int)
 
static int cob_file_write_opt (cob_file *, const int)
 
static int sequential_read (cob_file *, const int)
 
static int sequential_write (cob_file *, const int)
 
static int sequential_rewrite (cob_file *, const int)
 
static int lineseq_read (cob_file *, const int)
 
static int lineseq_write (cob_file *, const int)
 
static int relative_start (cob_file *, const int, cob_field *)
 
static int relative_read (cob_file *, cob_field *, const int)
 
static int relative_read_next (cob_file *, const int)
 
static int relative_write (cob_file *, const int)
 
static int relative_rewrite (cob_file *, const int)
 
static int relative_delete (cob_file *)
 
static int indexed_open (cob_file *, char *, const int, const int)
 
static int indexed_close (cob_file *, const int)
 
static int indexed_start (cob_file *, const int, cob_field *)
 
static int indexed_read (cob_file *, cob_field *, const int)
 
static int indexed_read_next (cob_file *, const int)
 
static int indexed_write (cob_file *, const int)
 
static int indexed_delete (cob_file *)
 
static int indexed_rewrite (cob_file *, const int)
 
static char * cob_fileio_getenv (const char *env)
 
static char * cob_chk_file_env (const char *src)
 
static void cob_chk_file_mapping (void)
 
static void cob_sync (cob_file *f)
 
static void cob_cache_file (cob_file *f)
 
static void save_status (cob_file *f, cob_field *fnstatus, const int status)
 
static size_t file_linage_check (cob_file *f)
 
static int cob_linage_write_opt (cob_file *f, const int opt)
 
static unsigned int cob_seq_write_opt (cob_file *f, const int opt)
 
static int cob_fd_file_open (cob_file *f, char *filename, const int mode, const int sharing)
 
static void indexed_file_delete (cob_file *f, const char *filename)
 
static void cob_file_unlock (cob_file *f)
 
void cob_unlock_file (cob_file *f, cob_field *fnstatus)
 
void cob_open (cob_file *f, const int mode, const int sharing, cob_field *fnstatus)
 
void cob_close (cob_file *f, cob_field *fnstatus, const int opt, const int remfil)
 
void cob_start (cob_file *f, const int cond, cob_field *key, cob_field *keysize, cob_field *fnstatus)
 
void cob_read (cob_file *f, cob_field *key, cob_field *fnstatus, const int read_opts)
 
void cob_read_next (cob_file *f, cob_field *fnstatus, const int read_opts)
 
void cob_write (cob_file *f, cob_field *rec, const int opt, cob_field *fnstatus, const unsigned int check_eop)
 
void cob_rewrite (cob_file *f, cob_field *rec, const int opt, cob_field *fnstatus)
 
void cob_delete (cob_file *f, cob_field *fnstatus)
 
void cob_commit (void)
 
void cob_rollback (void)
 
void cob_delete_file (cob_file *f, cob_field *fnstatus)
 
static void * cob_str_from_fld (const cob_field *f)
 
static int open_cbl_file (unsigned char *file_name, unsigned char *file_access, unsigned char *file_handle, const int file_flags)
 
int cob_sys_open_file (unsigned char *file_name, unsigned char *file_access, unsigned char *file_lock, unsigned char *file_dev, unsigned char *file_handle)
 
int cob_sys_create_file (unsigned char *file_name, unsigned char *file_access, unsigned char *file_lock, unsigned char *file_dev, unsigned char *file_handle)
 
int cob_sys_read_file (unsigned char *file_handle, unsigned char *file_offset, unsigned char *file_len, unsigned char *flags, unsigned char *buf)
 
int cob_sys_write_file (unsigned char *file_handle, unsigned char *file_offset, unsigned char *file_len, unsigned char *flags, unsigned char *buf)
 
int cob_sys_close_file (unsigned char *file_handle)
 
int cob_sys_flush_file (unsigned char *file_handle)
 
int cob_sys_delete_file (unsigned char *file_name)
 
int cob_sys_copy_file (unsigned char *fname1, unsigned char *fname2)
 
int cob_sys_check_file_exist (unsigned char *file_name, unsigned char *file_info)
 
int cob_sys_rename_file (unsigned char *fname1, unsigned char *fname2)
 
int cob_sys_get_current_dir (const int flags, const int dir_length, unsigned char *dir)
 
int cob_sys_create_dir (unsigned char *dir)
 
int cob_sys_change_dir (unsigned char *dir)
 
int cob_sys_delete_dir (unsigned char *dir)
 
int cob_sys_mkdir (unsigned char *dir)
 
int cob_sys_chdir (unsigned char *dir, unsigned char *status)
 
int cob_sys_copyfile (unsigned char *fname1, unsigned char *fname2, unsigned char *file_type)
 
int cob_sys_file_info (unsigned char *file_name, unsigned char *file_info)
 
int cob_sys_file_delete (unsigned char *file_name, unsigned char *file_type)
 
static int sort_cmps (const unsigned char *s1, const unsigned char *s2, const size_t size, const unsigned char *col)
 
static COB_INLINE void unique_copy (unsigned char *s1, const unsigned char *s2)
 
static int cob_file_sort_compare (struct cobitem *k1, struct cobitem *k2, void *pointer)
 
static void cob_free_list (struct cobsort *hp)
 
static struct cobitemcob_new_item (struct cobsort *hp, const size_t size)
 
static FILE * cob_srttmpfile (void)
 
static int cob_get_sort_tempfile (struct cobsort *hp, const int n)
 
static int cob_sort_queues (struct cobsort *hp)
 
static int cob_read_item (struct cobsort *hp, const int n)
 
static int cob_write_block (struct cobsort *hp, const int n)
 
static void cob_copy_check (cob_file *to, cob_file *from)
 
static int cob_file_sort_process (struct cobsort *hp)
 
static int cob_file_sort_submit (cob_file *f, const unsigned char *p)
 
static int cob_file_sort_retrieve (cob_file *f, unsigned char *p)
 
void cob_file_sort_using (cob_file *sort_file, cob_file *data_file)
 
void cob_file_sort_giving (cob_file *sort_file, const size_t varcnt,...)
 
void cob_file_sort_init (cob_file *f, const unsigned int nkeys, const unsigned char *collating_sequence, void *sort_return, cob_field *fnstatus)
 
void cob_file_sort_init_key (cob_file *f, cob_field *field, const int flag, const unsigned int offset)
 
void cob_file_sort_close (cob_file *f)
 
void cob_file_release (cob_file *f)
 
void cob_file_return (cob_file *f)
 
void cob_exit_fileio (void)
 
void cob_init_fileio (cob_global *lptr, runtime_env *runtimeptr)
 

Variables

static cob_globalcobglobptr
 
static unsigned int eop_status
 
static unsigned int check_eop_status
 
static unsigned int cob_ls_uses_cr
 
static char * cob_ls_uses_cr_env
 
static unsigned int cob_ls_nulls
 
static char * cob_ls_nulls_env
 
static unsigned int cob_ls_fixed
 
static char * cob_ls_fixed_env
 
static unsigned int cob_do_sync
 
static char * cob_do_sync_env
 
static size_t cob_vsq_len
 
static unsigned int cob_varseq_type
 
static char * cob_varseq_type_env
 
static size_t cob_sort_memory
 
static char * cob_sort_memory_env
 
static size_t cob_sort_chunk
 
static char * cob_sort_chunk_env
 
static struct file_listfile_cache
 
static char * cob_file_path
 
static char * cob_file_path_env
 
static char * file_open_env
 
static char * file_open_name
 
static char * file_open_buff
 
static char * runtime_buffer
 
static const int status_exception []
 
static const char *const prefix [] = { "DD_", "dd_", "" }
 
static struct cob_fileio_funcs indexed_funcs
 
static struct cob_fileio_funcs sequential_funcs
 
static struct cob_fileio_funcs lineseq_funcs
 
static struct cob_fileio_funcs relative_funcs
 
static struct cob_fileio_funcsfileio_funcs [COB_ORG_MAX]
 

Macro Definition Documentation

#define _FILE_OFFSET_BITS   64
#define _LARGEFILE64_SOURCE   1
#define _LFS64_LARGEFILE   1
#define _LFS64_STDIO   1
#define _O_TEMPORARY   0

Referenced by cob_srttmpfile().

#define COB_LIB_EXPIMP
#define COB_MAYSWAP_16 (   x)    (COB_BSWAP_16((unsigned short)(x)))
#define COB_MAYSWAP_32 (   x)    (COB_BSWAP_32((unsigned int)(x)))
#define COBSORTABORT   2
#define COBSORTNOTOPEN   4
#define fdcobsync   fsync
#define NUM_PREFIX   sizeof(prefix) / sizeof(char *)

Referenced by cob_chk_file_env().

Function Documentation

static void cob_cache_file ( cob_file f)
static

References cob_malloc(), file_list::file, file_cache, and file_list::next.

Referenced by cob_open().

679 {
680  struct file_list *l;
681 
682  for (l = file_cache; l; l = l->next) {
683  if (f == l->file) {
684  return;
685  }
686  }
687  l = cob_malloc (sizeof (struct file_list));
688  l->file = f;
689  l->next = file_cache;
690  file_cache = l;
691 }
static char* cob_chk_file_env ( const char *  src)
static

References __cob_global::cob_env_mangle, COB_FILE_MAX, cob_free(), cob_strdup(), file_open_env, NULL, NUM_PREFIX, p, prefix, and unlikely.

Referenced by cob_chk_file_mapping().

499 {
500  char *p;
501  char *q;
502  char *s;
503  size_t i;
504 
506  q = cob_strdup (src);
507  s = q;
508  for (i = 0; i < strlen (s); ++i) {
509  if (!isalnum ((int)s[i])) {
510  s[i] = '_';
511  }
512  }
513  } else {
514  q = NULL;
515  s = (char *)src;
516  }
517  p = NULL;
518  for (i = 0; i < NUM_PREFIX; ++i) {
519  snprintf (file_open_env, (size_t)COB_FILE_MAX, "%s%s",
520  prefix[i], s);
521  p = getenv (file_open_env);
522  if (p) {
523  break;
524  }
525  }
526  if (unlikely(q)) {
527  cob_free (q);
528  }
529  return p;
530 }
static void cob_chk_file_mapping ( void  )
static

References cob_chk_file_env(), COB_FILE_MAX, cob_file_path, cob_free(), COB_MODULE_PTR, cob_strdup(), file_open_buff, file_open_name, likely, NULL, p, SLASH_STR, and unlikely.

Referenced by cob_delete_file(), cob_fd_file_open(), cob_file_open(), and indexed_open().

534 {
535  char *p;
536  char *src;
537  char *dst;
538  char *saveptr;
539  char *orig;
540  unsigned int dollar;
541 
542  if (unlikely(!COB_MODULE_PTR->flag_filename_mapping)) {
543  return;
544  }
545 
546  /* Misuse "dollar" here to indicate a separator */
547  dollar = 0;
548  for (p = file_open_name; *p; p++) {
549  if (*p == '/' || *p == '\\') {
550  dollar = 1;
551  break;
552  }
553  }
554 
555  src = file_open_name;
556 
557  /* Simple case - No separators */
558  if (likely(dollar == 0)) {
559  /* Ignore leading dollar */
560  if (*src == '$') {
561  src++;
562  }
563  /* Check for DD_xx, dd_xx, xx environment variables */
564  /* If not found, use as is including the dollar character */
565  if ((p = cob_chk_file_env (src)) != NULL) {
566  strncpy (file_open_name, p, (size_t)COB_FILE_MAX);
567  } else if (cob_file_path) {
568  snprintf (file_open_buff, (size_t)COB_FILE_MAX, "%s%s%s",
569  cob_file_path, SLASH_STR, file_open_name);
570  strncpy (file_open_name, file_open_buff,
571  (size_t)COB_FILE_MAX);
572  }
573  return;
574  }
575 
576  /* Complex */
577  /* Isolate first element (everything before the slash) */
578  /* If it starts with a slash, it's absolute, do nothing */
579  /* Else if it starts with a $, mark and skip over the $ */
580  /* Try mapping on resultant string - DD_xx, dd_xx, xx */
581  /* If successful, use the mapping */
582  /* If not, use original element EXCEPT if we started */
583  /* with a $, in which case, we ignore the element AND */
584  /* the following slash */
585 
586  dollar = 0;
587  dst = file_open_buff;
588  *dst = 0;
589 
590  if (*src == '$') {
591  dollar = 1;
592  src++;
593  }
594 
595  orig = cob_strdup (src);
596  saveptr = orig;
597 
598  /* strtok strips leading delimiters */
599  if (*src == '/' || *src == '\\') {
600  strcpy (file_open_buff, SLASH_STR);
601  } else {
603  p = strtok (orig, "/\\");
604  orig = NULL;
605  if ((src = cob_chk_file_env (p)) != NULL) {
606  strncpy (file_open_buff, src, (size_t)COB_FILE_MAX);
607  dollar = 0;
608  } else if (!dollar) {
609  strncpy (file_open_buff, p, (size_t)COB_FILE_MAX);
610  }
611  }
612  /* First element completed, loop through remaining */
613  /* elements delimited by slash */
614  /* Check each for $ mapping */
615  for (; ;) {
616  p = strtok (orig, "/\\");
617  if (!p) {
618  break;
619  }
620  if (!orig) {
621  if (dollar) {
622  dollar = 0;
623  } else {
624  strcat (file_open_buff, SLASH_STR);
625  }
626  } else {
627  orig = NULL;
628  }
629  if (*p == '$' && (src = cob_chk_file_env (p + 1)) != NULL) {
630  strncat (file_open_buff, src, (size_t)COB_FILE_MAX);
631  } else {
632  strncat (file_open_buff, p, (size_t)COB_FILE_MAX);
633  }
634  }
635  strcpy (file_open_name, file_open_buff);
636  cob_free (saveptr);
637 }
void cob_close ( cob_file f,
cob_field fnstatus,
const int  opt,
const int  remfil 
)

References cob_fileio_funcs::close, COB_CLOSE_LOCK, COB_FILE_SPECIAL, cob_free(), COB_LOCK_OPEN_EXCLUSIVE, COB_OPEN_CLOSED, COB_OPEN_LOCKED, COB_STATUS_00_SUCCESS, COB_STATUS_42_NOT_OPEN, cob_file::fd, file_list::file, cob_file::file, file_cache, cob_file::flag_nonexistent, cob_file::flag_operation, cob_file::flag_read_done, cob_file::lock_mode, file_list::next, NULL, cob_file::open_mode, cob_file::organization, save_status(), and unlikely.

Referenced by cob_exit_fileio(), cob_file_sort_giving(), and cob_file_sort_using().

4518 {
4519  struct file_list *l;
4520  struct file_list *m;
4521  int ret;
4522 
4523  f->flag_read_done = 0;
4524  f->flag_operation = 0;
4525 
4527 
4528  if (COB_FILE_SPECIAL (f)) {
4530  f->file = NULL;
4531  f->fd = -1;
4532  save_status (f, fnstatus, COB_STATUS_00_SUCCESS);
4533  return;
4534  }
4535 
4536  if (unlikely(remfil)) {
4537  /* Remove from cache - Needed for CANCEL */
4538  /* Setting m silences false compiler warning */
4539  m = file_cache;
4540  for (l = file_cache; l; l = l->next) {
4541  if (f == l->file) {
4542  if (l == file_cache) {
4543  file_cache = l->next;
4544  } else {
4545  m->next = l->next;
4546  }
4547  cob_free (l);
4548  break;
4549  }
4550  m = l;
4551  }
4552  }
4553 
4554  if (f->open_mode == COB_OPEN_CLOSED) {
4555  save_status (f, fnstatus, COB_STATUS_42_NOT_OPEN);
4556  return;
4557  }
4558 
4559  if (f->flag_nonexistent) {
4560  ret = COB_STATUS_00_SUCCESS;
4561  } else {
4562  ret = fileio_funcs[(int)f->organization]->close (f, opt);
4563  }
4564 
4565  if (ret == COB_STATUS_00_SUCCESS) {
4566  switch (opt) {
4567  case COB_CLOSE_LOCK:
4569  break;
4570  default:
4572  break;
4573  }
4574  }
4575 
4576  save_status (f, fnstatus, ret);
4577 }
void cob_commit ( void  )

References cob_file_unlock(), file_list::file, and file_list::next.

4871 {
4872  struct file_list *l;
4873 
4874  for (l = file_cache; l; l = l->next) {
4875  if (l->file) {
4876  cob_file_unlock (l->file);
4877  }
4878  }
4879 }
static void cob_copy_check ( cob_file to,
cob_file from 
)
static

References cob_field::data, cob_file::record, cob_field::size, and unlikely.

Referenced by cob_file_sort_giving(), and cob_file_sort_using().

5869 {
5870  unsigned char *toptr;
5871  unsigned char *fromptr;
5872  size_t tosize;
5873  size_t fromsize;
5874 
5875  toptr = to->record->data;
5876  fromptr = from->record->data;
5877  tosize = to->record->size;
5878  fromsize = from->record->size;
5879  if (unlikely(tosize > fromsize)) {
5880  memcpy (toptr, fromptr, fromsize);
5881  memset (toptr + fromsize, ' ', tosize - fromsize);
5882  } else {
5883  memcpy (toptr, fromptr, tosize);
5884  }
5885 }
void cob_delete ( cob_file f,
cob_field fnstatus 
)

References cob_file::access_mode, COB_ACCESS_SEQUENTIAL, COB_OPEN_I_O, COB_STATUS_43_READ_NOT_DONE, COB_STATUS_49_I_O_DENIED, cob_fileio_funcs::fdelete, cob_file::flag_read_done, cob_file::open_mode, cob_file::organization, save_status(), and unlikely.

4849 {
4850  int read_done;
4851 
4852  read_done = f->flag_read_done;
4853  f->flag_read_done = 0;
4854 
4855  if (unlikely(f->open_mode != COB_OPEN_I_O)) {
4856  save_status (f, fnstatus, COB_STATUS_49_I_O_DENIED);
4857  return;
4858  }
4859 
4860  if (f->access_mode == COB_ACCESS_SEQUENTIAL && !read_done) {
4862  return;
4863  }
4864 
4865  save_status (f, fnstatus,
4866  fileio_funcs[(int)f->organization]->fdelete (f));
4867 }
void cob_delete_file ( cob_file f,
cob_field fnstatus 
)

References cob_file::assign, cob_chk_file_mapping(), cob_field_to_string(), COB_FILE_MAX, COB_FILE_STDIN, COB_FILE_STDOUT, COB_OPEN_CLOSED, COB_OPEN_LOCKED, COB_ORG_INDEXED, COB_ORG_SORT, COB_STATUS_00_SUCCESS, COB_STATUS_30_PERMANENT_ERROR, COB_STATUS_38_CLOSED_WITH_LOCK, COB_STATUS_41_ALREADY_OPEN, COB_STATUS_91_NOT_AVAILABLE, file_open_name, indexed_file_delete(), cob_file::open_mode, cob_file::organization, save_status(), and unlikely.

4895 {
4896  if (f->organization == COB_ORG_SORT) {
4898  return;
4899  }
4900 
4901  /* File was previously closed with lock */
4902  if (f->open_mode == COB_OPEN_LOCKED) {
4904  return;
4905  }
4906 
4907  /* File is open */
4908  if (f->open_mode != COB_OPEN_CLOSED) {
4909  save_status (f, fnstatus, COB_STATUS_41_ALREADY_OPEN);
4910  return;
4911  }
4912 
4913  if (unlikely(COB_FILE_STDIN (f))) {
4915  return;
4916  }
4917  if (unlikely(COB_FILE_STDOUT (f))) {
4919  return;
4920  }
4921 
4922  /* Obtain the file name */
4923  cob_field_to_string (f->assign, file_open_name, (size_t)COB_FILE_MAX);
4925 
4926  if (f->organization != COB_ORG_INDEXED) {
4927 #ifdef WITH_SEQRA_EXTFH
4929  return;
4930 #else
4931  unlink (file_open_name);
4932 #endif
4933  } else {
4934 #ifdef WITH_INDEX_EXTFH
4936  return;
4937 #else
4939 #endif
4940  }
4941  save_status (f, fnstatus, COB_STATUS_00_SUCCESS);
4942 }
void cob_exit_fileio ( void  )

References _, cob_file::assign, cob_close(), COB_CLOSE_NORMAL, __cob_global::cob_display_warn, cob_field_to_string(), COB_FILE_MAX, cob_file_path, COB_FILE_SPECIAL, cob_free(), COB_OPEN_CLOSED, COB_OPEN_LOCKED, file_list::file, cob_file::flag_nonexistent, file_list::next, NULL, cob_file::open_mode, p, runtime_buffer, and cob_file::select_name.

Referenced by cob_terminate_routines().

6299 {
6300  struct file_list *l;
6301  struct file_list *p;
6302 
6303  for (l = file_cache; l; l = l->next) {
6304  if (l->file && l->file->open_mode != COB_OPEN_CLOSED &&
6305  l->file->open_mode != COB_OPEN_LOCKED &&
6306  !l->file->flag_nonexistent) {
6307  if (COB_FILE_SPECIAL (l->file)) {
6308  continue;
6309  }
6310  cob_close (l->file, NULL, COB_CLOSE_NORMAL, 0);
6314  (size_t)COB_FILE_MAX);
6315  fprintf (stderr, _("WARNING - Implicit CLOSE of %s ('%s')"),
6317  putc ('\n', stderr);
6318  fflush (stderr);
6319  }
6320  }
6321  }
6322 #ifdef WITH_DB
6323  if (bdb_env) {
6324  bdb_env->lock_id_free (bdb_env, bdb_lock_id);
6325  bdb_env->close (bdb_env, 0);
6326  bdb_env = NULL;
6327  }
6328  if (record_lock_object) {
6329  cob_free (record_lock_object);
6330  record_lock_object = NULL;
6331  }
6332  if (bdb_buff) {
6333  cob_free (bdb_buff);
6334  bdb_buff = NULL;
6335  }
6336  if (bdb_home) {
6337  cob_free (bdb_home);
6338  bdb_home = NULL;
6339  }
6340 
6341 #elif defined(WITH_ANY_ISAM)
6342 #ifndef WITH_DISAM
6343  (void)iscleanup ();
6344 #endif
6345 #endif
6346 
6347 #if defined(WITH_INDEX_EXTFH) || defined(WITH_SEQRA_EXTFH)
6348  extfh_cob_exit_fileio ();
6349 #endif
6350 
6351  if (cob_file_path) {
6353  cob_file_path = NULL;
6354  }
6355 
6356  if (runtime_buffer) {
6358  runtime_buffer = NULL;
6359  }
6360 
6361  for (l = file_cache; l;) {
6362  p = l;
6363  l = l->next;
6364  cob_free (p);
6365  }
6366  file_cache = NULL;
6367 }
static int cob_fd_file_open ( cob_file f,
char *  filename,
const int  mode,
const int  sharing 
)
static

References cob_chk_file_mapping(), COB_OPEN_EXTEND, COB_OPEN_I_O, COB_OPEN_INPUT, COB_OPEN_OUTPUT, COB_ORG_RELATIVE, COB_STATUS_05_SUCCESS_OPTIONAL, COB_STATUS_30_PERMANENT_ERROR, COB_STATUS_35_NOT_EXISTS, COB_STATUS_37_PERMISSION_DENIED, COB_STATUS_61_FILE_SHARING, COB_UNUSED, F_OK, cob_file::fd, cob_file::flag_begin_of_file, cob_file::flag_end_of_file, cob_file::flag_nonexistent, cob_file::flag_optional, O_BINARY, cob_file::open_mode, and cob_file::organization.

Referenced by cob_file_open().

887 {
888  int fd;
889  int fdmode;
890  int fperms;
891  unsigned int nonexistent;
892 #ifdef HAVE_FCNTL
893  int ret;
894  struct flock lock;
895 #endif
896 
897  /* Note filename points to file_open_name */
898  /* cob_chk_file_mapping manipulates file_open_name directly */
899 
900  COB_UNUSED (sharing);
901 
903 
904  nonexistent = 0;
905  errno = 0;
906  if (access (filename, F_OK) && errno == ENOENT) {
907  if (mode != COB_OPEN_OUTPUT && f->flag_optional == 0) {
909  }
910  nonexistent = 1;
911  }
912 
913  fdmode = O_BINARY;
914  fperms = 0;
915  f->fd = -1;
916  switch (mode) {
917  case COB_OPEN_INPUT:
918  fdmode |= O_RDONLY;
919  break;
920  case COB_OPEN_OUTPUT:
921  nonexistent = 0;
922  fdmode |= O_CREAT | O_TRUNC;
923  if (f->organization == COB_ORG_RELATIVE) {
924  fdmode |= O_RDWR;
925  } else {
926  fdmode |= O_WRONLY;
927  }
928 #ifdef _WIN32
929  fperms = _S_IREAD | _S_IWRITE ;
930 #else
931  fperms = 0777;
932 #endif
933  break;
934  case COB_OPEN_I_O:
935  if (nonexistent) {
936  fdmode |= O_CREAT | O_RDWR;
937 #ifdef _WIN32
938  fperms = _S_IREAD | _S_IWRITE ;
939 #else
940  fperms = 0777;
941 #endif
942  } else {
943  fdmode |= O_RDWR;
944  }
945  break;
946  case COB_OPEN_EXTEND:
947  fdmode |= O_CREAT | O_RDWR | O_APPEND;
948 #ifdef _WIN32
949  fperms = _S_IREAD | _S_IWRITE ;
950 #else
951  fperms = 0777;
952 #endif
953  break;
954  }
955 
956  errno = 0;
957  fd = open (filename, fdmode, fperms);
958 
959  switch (errno) {
960  case 0:
961  if (mode == COB_OPEN_EXTEND && fd >= 0) {
962  lseek (fd, (off_t) 0, SEEK_END);
963  }
964  f->open_mode = mode;
965  break;
966  case ENOENT:
967  if (mode == COB_OPEN_EXTEND || mode == COB_OPEN_OUTPUT) {
969  }
970  if (f->flag_optional) {
971  f->open_mode = mode;
972  f->flag_nonexistent = 1;
973  f->flag_end_of_file = 1;
974  f->flag_begin_of_file = 1;
976  }
978  case EACCES:
979  case EISDIR:
980  case EROFS:
982  case EAGAIN:
984  default:
986  }
987  f->fd = fd;
988 
989 #ifdef HAVE_FCNTL
990  /* Lock the file */
991  if (memcmp (filename, "/dev/", (size_t)5)) {
992  memset ((void *)&lock, 0, sizeof (struct flock));
993  if (mode != COB_OPEN_INPUT) {
994  lock.l_type = F_WRLCK;
995  } else {
996  lock.l_type = F_RDLCK;
997  }
998  lock.l_whence = SEEK_SET;
999  lock.l_start = 0;
1000  lock.l_len = 0;
1001  errno = 0;
1002  if (fcntl (fd, F_SETLK, &lock) < 0) {
1003  ret = errno;
1004  close (fd);
1005  f->fd = -1;
1006  switch (ret) {
1007  case EACCES:
1008  case EAGAIN:
1009  case EDEADLK:
1011  default:
1013  }
1014  }
1015  }
1016 #endif
1017  if (f->flag_optional && nonexistent) {
1019  }
1020  return 0;
1021 }
static int cob_file_close ( cob_file f,
const int  opt 
)
static

References COB_CLOSE_LOCK, COB_CLOSE_NO_REWIND, COB_CLOSE_NORMAL, COB_OPEN_CLOSED, COB_OPEN_INPUT, COB_ORG_LINE_SEQUENTIAL, COB_SELECT_LINAGE, COB_STATUS_00_SUCCESS, COB_STATUS_07_SUCCESS_NO_UNIT, cob_file::fd, fdcobsync, cob_file::file, cob_file::flag_needs_nl, cob_file::flag_select_features, cob_file::open_mode, and cob_file::organization.

1209 {
1210 #ifdef WITH_SEQRA_EXTFH
1211  return extfh_cob_file_close (f, opt);
1212 #else
1213 
1214 #ifdef HAVE_FCNTL
1215  struct flock lock;
1216 #endif
1217 
1218  switch (opt) {
1219  case COB_CLOSE_NORMAL:
1220  case COB_CLOSE_LOCK:
1221  case COB_CLOSE_NO_REWIND:
1223  if (f->flag_needs_nl &&
1225  f->flag_needs_nl = 0;
1226  putc ('\n', (FILE *)f->file);
1227  }
1228  } else if (f->flag_needs_nl) {
1229  f->flag_needs_nl = 0;
1230  if (f->fd >= 0) {
1231  if (write (f->fd, "\n", (size_t)1) != 1) {
1232  }
1233  }
1234  }
1235 #ifdef HAVE_FCNTL
1236  /* Unlock the file */
1237  memset ((void *)&lock, 0, sizeof (struct flock));
1238  lock.l_type = F_UNLCK;
1239  lock.l_whence = SEEK_SET;
1240  lock.l_start = 0;
1241  lock.l_len = 0;
1242  if (f->fd >= 0) {
1243  fcntl (f->fd, F_SETLK, &lock);
1244  }
1245 #endif
1246  /* Close the file */
1248  if (f->file) {
1249  fclose ((FILE *)f->file);
1250  }
1251  } else {
1252  if (f->fd >= 0) {
1253  close (f->fd);
1254  }
1255  }
1256  if (opt == COB_CLOSE_NO_REWIND) {
1259  }
1260  return COB_STATUS_00_SUCCESS;
1261  default:
1262  if (f->fd >= 0 && f->open_mode != COB_OPEN_INPUT) {
1263  fdcobsync (f->fd);
1264  }
1266  }
1267 #endif
1268 }
static int cob_file_open ( cob_file f,
char *  filename,
const int  mode,
const int  sharing 
)
static

References cob_chk_file_mapping(), cob_fd_file_open(), COB_NOT_CONFIGURED, COB_OPEN_EXTEND, COB_OPEN_I_O, COB_OPEN_INPUT, COB_OPEN_OUTPUT, COB_ORG_LINE_SEQUENTIAL, COB_SELECT_LINAGE, cob_set_int(), COB_STATUS_00_SUCCESS, COB_STATUS_05_SUCCESS_OPTIONAL, COB_STATUS_30_PERMANENT_ERROR, COB_STATUS_35_NOT_EXISTS, COB_STATUS_37_PERMISSION_DENIED, COB_STATUS_57_I_O_LINAGE, COB_STATUS_61_FILE_SHARING, __cob_global::cob_unix_lf, F_OK, cob_file::fd, cob_file::file, file_linage_check(), cob_file::flag_begin_of_file, cob_file::flag_end_of_file, cob_file::flag_needs_top, cob_file::flag_nonexistent, cob_file::flag_optional, cob_file::flag_select_features, cob_linage::linage_ctr, cob_file::linorkeyptr, NULL, cob_file::open_mode, cob_file::organization, and unlikely.

1025 {
1026  /* Note filename points to file_open_name */
1027  /* cob_chk_file_mapping manipulates file_open_name directly */
1028 
1029 #ifdef WITH_SEQRA_EXTFH
1030  int ret;
1031 
1032  ret = extfh_seqra_locate (f, filename);
1033  switch (ret) {
1034  case COB_NOT_CONFIGURED:
1036  if (access (filename, F_OK) && errno == ENOENT) {
1037  if (mode != COB_OPEN_OUTPUT && f->flag_optional == 0) {
1038  return COB_STATUS_35_NOT_EXISTS;
1039  }
1040  }
1041  break;
1042  case COB_STATUS_00_SUCCESS:
1043  break;
1044  default:
1045  return ret;
1046  }
1047  ret = extfh_cob_file_open (f, filename, mode, sharing);
1048  switch (ret) {
1049  case COB_STATUS_00_SUCCESS:
1050  f->open_mode = mode;
1051  break;
1053  if (f->flag_optional) {
1054  f->open_mode = mode;
1055  f->flag_nonexistent = 1;
1056  f->flag_end_of_file = 1;
1057  f->flag_begin_of_file = 1;
1059  }
1060  break;
1061  }
1062  return ret;
1063 
1064 #else
1065 
1066  FILE *fp;
1067  const char *fmode;
1068  cob_linage *lingptr;
1069 #ifdef HAVE_FCNTL
1070  int ret;
1071  struct flock lock;
1072 #endif
1073  unsigned int nonexistent;
1074 
1076  return cob_fd_file_open (f, filename, mode, sharing);
1077  }
1078 
1080 
1081  nonexistent = 0;
1082  errno = 0;
1083  if (access (filename, F_OK) && errno == ENOENT) {
1084  nonexistent = 1;
1085  if (mode != COB_OPEN_OUTPUT && f->flag_optional == 0) {
1086  return COB_STATUS_35_NOT_EXISTS;
1087  }
1088  }
1089 
1090  fp = NULL;
1091  fmode = NULL;
1092  /* Open the file */
1093  switch (mode) {
1094  case COB_OPEN_INPUT:
1095  if (!cobglobptr->cob_unix_lf) {
1096  fmode = "r";
1097  } else {
1098  fmode = "rb";
1099  }
1100  break;
1101  case COB_OPEN_OUTPUT:
1102  if (!cobglobptr->cob_unix_lf) {
1103  fmode = "w";
1104  } else {
1105  fmode = "wb";
1106  }
1107  break;
1108  case COB_OPEN_I_O:
1110  case COB_OPEN_EXTEND:
1111  /* Problem with VC (tested MSC_VER 15) if file isn't there: */
1112  /* Both modes create the file and return a bad pointer */
1113  /* Mode "a+" sets EINVAL, further actions on the file do work */
1114  /* Mode "ab+" doesn't set errno, but we dont want a binary file */
1115  /* Possible Solutions: */
1116  /* a) Create the file and reopen it with a+ */
1117  /* b) Check this stuff in EINVAL and just go on */
1118  if (!cobglobptr->cob_unix_lf) {
1119  fmode = "a+";
1120  } else {
1121  fmode = "ab+";
1122  }
1123  break;
1124  }
1125 
1126  errno = 0;
1127  fp = fopen (filename, fmode);
1128  switch (errno) {
1129  case 0:
1130  f->open_mode = mode;
1131  break;
1132  case EINVAL:
1133  if (f->flag_optional && nonexistent) {
1134  f->open_mode = mode;
1135  } else {
1137  }
1138  break;
1139  case ENOENT:
1140  if (mode == COB_OPEN_EXTEND || mode == COB_OPEN_OUTPUT) {
1142  }
1143  if (f->flag_optional) {
1144  f->open_mode = mode;
1145  f->flag_nonexistent = 1;
1146  f->flag_end_of_file = 1;
1147  f->flag_begin_of_file = 1;
1149  }
1150  return COB_STATUS_35_NOT_EXISTS;
1151  case EACCES:
1152  case EISDIR:
1153  case EROFS:
1155  case EAGAIN:
1157  default:
1159  }
1160 
1162  if (file_linage_check (f)) {
1163  fclose (fp);
1164  return COB_STATUS_57_I_O_LINAGE;
1165  }
1166  f->flag_needs_top = 1;
1167  lingptr = f->linorkeyptr;
1168  cob_set_int (lingptr->linage_ctr, 1);
1169  }
1170  f->file = fp;
1171  f->fd = fileno (fp);
1172 
1173 #ifdef HAVE_FCNTL
1174  /* Lock the file */
1175  if (memcmp (filename, "/dev/", (size_t)5)) {
1176  memset ((void *)&lock, 0, sizeof (struct flock));
1177  if (mode != COB_OPEN_INPUT) {
1178  lock.l_type = F_WRLCK;
1179  } else {
1180  lock.l_type = F_RDLCK;
1181  }
1182  lock.l_whence = SEEK_SET;
1183  lock.l_start = 0;
1184  lock.l_len = 0;
1185  if (fcntl (fileno (fp), F_SETLK, &lock) < 0) {
1186  ret = errno;
1187  fclose (fp);
1188  switch (ret) {
1189  case EACCES:
1190  case EAGAIN:
1191  case EDEADLK:
1193  default:
1195  }
1196  }
1197  }
1198 #endif
1199  if (f->flag_optional && nonexistent) {
1201  }
1202  return 0;
1203 
1204 #endif
1205 }
void cob_file_release ( cob_file f)

References cob_file_sort_submit(), COB_STATUS_00_SUCCESS, COB_STATUS_30_PERMANENT_ERROR, cob_field::data, cob_file::file, cobsort::fnstatus, likely, NULL, cob_file::record, save_status(), and cobsort::sort_return.

6247 {
6248  struct cobsort *hp;
6250  int ret;
6251 
6252  fnstatus = NULL;
6253  hp = f->file;
6254  if (likely(hp)) {
6255  fnstatus = hp->fnstatus;
6256  }
6257  ret = cob_file_sort_submit (f, f->record->data);
6258  if (!ret) {
6259  save_status (f, fnstatus, COB_STATUS_00_SUCCESS);
6260  return;
6261  }
6262  if (likely(hp)) {
6263  *(int *)(hp->sort_return) = 16;
6264  }
6266 }
void cob_file_return ( cob_file f)

References cob_file_sort_retrieve(), COB_STATUS_00_SUCCESS, COB_STATUS_10_END_OF_FILE, COB_STATUS_30_PERMANENT_ERROR, COBSORTEND, cob_field::data, cob_file::file, cobsort::fnstatus, likely, NULL, cob_file::record, save_status(), and cobsort::sort_return.

6270 {
6271  struct cobsort *hp;
6273  int ret;
6274 
6275  fnstatus = NULL;
6276  hp = f->file;
6277  if (likely(hp)) {
6278  fnstatus = hp->fnstatus;
6279  }
6280  ret = cob_file_sort_retrieve (f, f->record->data);
6281  switch (ret) {
6282  case 0:
6283  save_status (f, fnstatus, COB_STATUS_00_SUCCESS);
6284  return;
6285  case COBSORTEND:
6286  save_status (f, fnstatus, COB_STATUS_10_END_OF_FILE);
6287  return;
6288  }
6289  if (likely(hp)) {
6290  *(int *)(hp->sort_return) = 16;
6291  }
6293 }
void cob_file_sort_close ( cob_file f)

References cob_free(), cob_free_list(), COB_STATUS_00_SUCCESS, cobsort::file, cob_file::file, cobsort::fnstatus, file_struct::fp, cob_file::keys, likely, NULL, and save_status().

6221 {
6222  struct cobsort *hp;
6224  size_t i;
6225 
6226  fnstatus = NULL;
6227  hp = f->file;
6228  if (likely(hp)) {
6229  fnstatus = hp->fnstatus;
6230  cob_free_list (hp);
6231  for (i = 0; i < 4; ++i) {
6232  if (hp->file[i].fp != NULL) {
6233  fclose (hp->file[i].fp);
6234  }
6235  }
6236  cob_free (hp);
6237  }
6238  if (f->keys) {
6239  cob_free (f->keys);
6240  }
6241  f->file = NULL;
6242  save_status (f, fnstatus, COB_STATUS_00_SUCCESS);
6243 }
static int cob_file_sort_compare ( struct cobitem k1,
struct cobitem k2,
void *  pointer 
)
static

References COB_ASCENDING, COB_FIELD_IS_NUMERIC, cob_numeric_cmp(), cob_field::data, cob_file_key::field, cob_file_key::flag, cobitem::item, cob_file::keys, cob_file::nkeys, cob_file_key::offset, cob_field::size, sort_cmps(), cob_file::sort_collating, cobitem::unique, unique_copy(), and unlikely.

Referenced by cob_file_sort_process(), cob_file_sort_retrieve(), and cob_sort_queues().

5632 {
5633  cob_file *f;
5634  size_t i;
5635  size_t u1;
5636  size_t u2;
5637  int cmp;
5638  cob_field f1;
5639  cob_field f2;
5640 
5641  f = pointer;
5642  for (i = 0; i < f->nkeys; ++i) {
5643  f1 = f2 = *(f->keys[i].field);
5644  f1.data = k1->item + f->keys[i].offset;
5645  f2.data = k2->item + f->keys[i].offset;
5646  if (unlikely(COB_FIELD_IS_NUMERIC (&f1))) {
5647  cmp = cob_numeric_cmp (&f1, &f2);
5648  } else {
5649  cmp = sort_cmps (f1.data, f2.data, f1.size,
5650  f->sort_collating);
5651  }
5652  if (cmp != 0) {
5653  return (f->keys[i].flag == COB_ASCENDING) ? cmp : -cmp;
5654  }
5655  }
5656  unique_copy ((unsigned char *)&u1, k1->unique);
5657  unique_copy ((unsigned char *)&u2, k2->unique);
5658  if (u1 < u2) {
5659  return -1;
5660  }
5661  return 1;
5662 }
void cob_file_sort_giving ( cob_file sort_file,
const size_t  varcnt,
  ... 
)

References cob_close(), COB_CLOSE_NORMAL, cob_copy_check(), cob_file_sort_retrieve(), COB_FILE_SPECIAL, cob_free(), cob_malloc(), cob_open(), COB_OPEN_OUTPUT, COB_ORG_LINE_SEQUENTIAL, cob_write(), COB_WRITE_BEFORE, COB_WRITE_LINES, COBSORTEND, cob_field::data, cob_file::file, cob_file::file_status, NULL, cob_file::organization, cob_file::record, cob_file::record_max, cob_field::size, and cobsort::sort_return.

6115 {
6116  cob_file **fbase;
6117  struct cobsort *hp;
6118  size_t i;
6119  int ret;
6120  int opt;
6121  va_list args;
6122 
6123  fbase = cob_malloc (varcnt * sizeof(cob_file *));
6124  va_start (args, varcnt);
6125  for (i = 0; i < varcnt; ++i) {
6126  fbase[i] = va_arg (args, cob_file *);
6127  }
6128  va_end (args);
6129  for (i = 0; i < varcnt; ++i) {
6130  cob_open (fbase[i], COB_OPEN_OUTPUT, 0, NULL);
6131  }
6132  for (;;) {
6133  ret = cob_file_sort_retrieve (sort_file, sort_file->record->data);
6134  if (ret) {
6135  if (ret == COBSORTEND) {
6136  sort_file->file_status[0] = '1';
6137  sort_file->file_status[1] = '0';
6138  } else {
6139  hp = sort_file->file;
6140  *(int *)(hp->sort_return) = 16;
6141  sort_file->file_status[0] = '3';
6142  sort_file->file_status[1] = '0';
6143  }
6144  break;
6145  }
6146  for (i = 0; i < varcnt; ++i) {
6147  if (COB_FILE_SPECIAL (fbase[i]) ||
6148  fbase[i]->organization == COB_ORG_LINE_SEQUENTIAL) {
6149  opt = COB_WRITE_BEFORE | COB_WRITE_LINES | 1;
6150  } else {
6151  opt = 0;
6152  }
6153  fbase[i]->record->size = fbase[i]->record_max;
6154  cob_copy_check (fbase[i], sort_file);
6155  cob_write (fbase[i], fbase[i]->record, opt, NULL, 0);
6156  }
6157  }
6158  for (i = 0; i < varcnt; ++i) {
6159  cob_close (fbase[i], NULL, COB_CLOSE_NORMAL, 0);
6160  }
6161  cob_free (fbase);
6162 }
void cob_file_sort_init ( cob_file f,
const unsigned int  nkeys,
const unsigned char *  collating_sequence,
void *  sort_return,
cob_field fnstatus 
)

References cobsort::alloc_size, cobsort::chunk_size, cob_fast_malloc(), cob_malloc(), COB_MODULE_PTR, cob_sort_chunk, COB_STATUS_00_SUCCESS, cob_file::file, cobsort::fnstatus, cob_file::keys, cobsort::mem_base, sort_mem_struct::mem_ptr, cobsort::mem_size, cobsort::mem_total, sort_mem_struct::next, cob_file::nkeys, NULL, p, cobsort::pointer, cobsort::r_size, cob_file::record_max, save_status(), cobsort::size, cob_file::sort_collating, cobsort::sort_return, and cobsort::w_size.

6168 {
6169  struct cobsort *p;
6170  size_t n;
6171 
6172  p = cob_malloc (sizeof (struct cobsort));
6173  p->fnstatus = fnstatus;
6174  p->size = f->record_max;
6175  p->r_size = f->record_max + sizeof(size_t);
6176  p->w_size = f->record_max + sizeof(size_t) + 1;
6177  n = sizeof (struct cobitem) - offsetof (struct cobitem, item);
6178  if (f->record_max <= n) {
6179  p->alloc_size = sizeof (struct cobitem);
6180  } else {
6181  p->alloc_size = offsetof (struct cobitem, item) + f->record_max;
6182  }
6183  if (p->alloc_size % sizeof(void *)) {
6184  p->alloc_size += sizeof(void *) - (p->alloc_size % sizeof(void *));
6185  }
6187  if (p->chunk_size % p->alloc_size) {
6188  p->chunk_size += p->alloc_size - (p->chunk_size % p->alloc_size);
6189  }
6190  p->pointer = f;
6191  p->sort_return = sort_return;
6192  *(int *)sort_return = 0;
6193  p->mem_base = cob_fast_malloc (sizeof (struct sort_mem_struct));
6195  p->mem_base->next = NULL;
6196  p->mem_size = p->chunk_size;
6197  p->mem_total = p->chunk_size;
6198  f->file = p;
6199  f->keys = cob_malloc (sizeof (cob_file_key) * nkeys);
6200  f->nkeys = 0;
6201  if (collating_sequence) {
6202  f->sort_collating = collating_sequence;
6203  } else {
6204  f->sort_collating = COB_MODULE_PTR->collating_sequence;
6205  }
6206  save_status (f, fnstatus, COB_STATUS_00_SUCCESS);
6207 }
void cob_file_sort_init_key ( cob_file f,
cob_field field,
const int  flag,
const unsigned int  offset 
)

References cob_file_key::field, cob_file_key::flag, cob_file::keys, cob_file::nkeys, and cob_file_key::offset.

6212 {
6213  f->keys[f->nkeys].field = field;
6214  f->keys[f->nkeys].flag = flag;
6215  f->keys[f->nkeys].offset = offset;
6216  f->nkeys++;
6217 }
static int cob_file_sort_process ( struct cobsort hp)
static

References cobitem::block_byte, cob_file_sort_compare(), cob_get_sort_tempfile(), cob_read_item(), cob_sort_queues(), cob_write_block(), COBSORTABORT, COBSORTFILEERR, file_struct::count, cobsort::empty, cobitem::end_of_block, cobsort::file, cobsort::files_used, queue_struct::first, file_struct::fp, likely, cobitem::next, NULL, cobsort::pointer, cobsort::queue, cobsort::retrieval_queue, cobsort::retrieving, unlikely, and cobsort::w_size.

Referenced by cob_file_sort_retrieve().

5889 {
5890  int i;
5891  int source;
5892  int destination;
5893  int n;
5894  int move;
5895  int res;
5896 
5897  hp->retrieving = 1;
5898  n = cob_sort_queues (hp);
5899 #if 0 /* RXWRXW - Cannot be true */
5900  if (unlikely(n < 0)) {
5901  return COBSORTABORT;
5902  }
5903 #endif
5904  if (likely(!hp->files_used)) {
5905  hp->retrieval_queue = n;
5906  return 0;
5907  }
5908  if (unlikely(cob_write_block (hp, n))) {
5909  return COBSORTFILEERR;
5910  }
5911  for (i = 0; i < 4; ++i) {
5912  hp->queue[i].first = hp->empty;
5913  hp->empty = hp->empty->next;
5914  hp->queue[i].first->next = NULL;
5915  }
5916  rewind (hp->file[0].fp);
5917  rewind (hp->file[1].fp);
5918  if (unlikely(cob_get_sort_tempfile (hp, 2))) {
5919  return COBSORTFILEERR;
5920  }
5921  if (unlikely(cob_get_sort_tempfile (hp, 3))) {
5922  return COBSORTFILEERR;
5923  }
5924  source = 0;
5925  while (hp->file[source].count > 1) {
5926  destination = source ^ 2;
5927  hp->file[destination].count = 0;
5928  hp->file[destination + 1].count = 0;
5929  while (hp->file[source].count > 0) {
5930  if (unlikely(cob_read_item (hp, source))) {
5931  return COBSORTFILEERR;
5932  }
5933  if (hp->file[source + 1].count > 0) {
5934  if (unlikely(cob_read_item (hp, source + 1))) {
5935  return COBSORTFILEERR;
5936  }
5937  } else {
5938  hp->queue[source + 1].first->end_of_block = 1;
5939  }
5940  while (!hp->queue[source].first->end_of_block ||
5941  !hp->queue[source + 1].first->end_of_block) {
5942  if (hp->queue[source].first->end_of_block) {
5943  move = 1;
5944  } else if (hp->queue[source + 1].first->end_of_block) {
5945  move = 0;
5946  } else {
5947  res = cob_file_sort_compare
5948  (hp->queue[source].first,
5949  hp->queue[source + 1].first,
5950  hp->pointer);
5951  move = res < 0 ? 0 : 1;
5952  }
5953  if (unlikely(fwrite (
5954  &(hp->queue[source + move].first->block_byte),
5955  hp->w_size, (size_t)1,
5956  hp->file[destination].fp) != 1)) {
5957  return COBSORTFILEERR;
5958  }
5959  if (unlikely(cob_read_item (hp, source + move))) {
5960  return COBSORTFILEERR;
5961  }
5962  }
5963  hp->file[destination].count++;
5964  if (unlikely(putc (1, hp->file[destination].fp) != 1)) {
5965  return COBSORTFILEERR;
5966  }
5967  hp->file[source].count--;
5968  hp->file[source + 1].count--;
5969  destination ^= 1;
5970  }
5971  source = destination & 2;
5972  rewind (hp->file[0].fp);
5973  rewind (hp->file[1].fp);
5974  rewind (hp->file[2].fp);
5975  rewind (hp->file[3].fp);
5976  }
5977  hp->retrieval_queue = source;
5978  if (unlikely(cob_read_item (hp, source))) {
5979  return COBSORTFILEERR;
5980  }
5981  if (unlikely(cob_read_item (hp, source + 1))) {
5982  return COBSORTFILEERR;
5983  }
5984  return 0;
5985 }
static int cob_file_sort_retrieve ( cob_file f,
unsigned char *  p 
)
static

References cob_file_sort_compare(), cob_file_sort_process(), cob_read_item(), COBSORTEND, COBSORTFILEERR, COBSORTNOTOPEN, cobsort::empty, cobitem::end_of_block, cob_file::file, cobsort::files_used, queue_struct::first, cobitem::item, cobitem::next, next, NULL, cobsort::pointer, cobsort::queue, cobsort::retrieval_queue, cobsort::retrieving, cobsort::size, and unlikely.

Referenced by cob_file_return(), and cob_file_sort_giving().

6042 {
6043  struct cobsort *hp;
6044  struct cobitem *next;
6045  struct queue_struct *z;
6046  int move;
6047  int source;
6048  int res;
6049 
6050  hp = f->file;
6051  if (unlikely(!hp)) {
6052  return COBSORTNOTOPEN;
6053  }
6054  if (unlikely(!hp->retrieving)) {
6055  res = cob_file_sort_process (hp);
6056  if (res) {
6057  return res;
6058  }
6059  }
6060  if (unlikely(hp->files_used)) {
6061  source = hp->retrieval_queue;
6062  if (hp->queue[source].first->end_of_block) {
6063  if (hp->queue[source + 1].first->end_of_block) {
6064  return COBSORTEND;
6065  }
6066  move = 1;
6067  } else if (hp->queue[source + 1].first->end_of_block) {
6068  move = 0;
6069  } else {
6070  res = cob_file_sort_compare (hp->queue[source].first,
6071  hp->queue[source + 1].first,
6072  hp->pointer);
6073  move = res < 0 ? 0 : 1;
6074  }
6075  memcpy (p, hp->queue[source + move].first->item, hp->size);
6076  if (unlikely(cob_read_item (hp, source + move))) {
6077  return COBSORTFILEERR;
6078  }
6079  } else {
6080  z = &hp->queue[hp->retrieval_queue];
6081  if (z->first == NULL) {
6082  return COBSORTEND;
6083  }
6084  memcpy (p, z->first->item, hp->size);
6085  next = z->first->next;
6086  z->first->next = hp->empty;
6087  hp->empty = z->first;
6088  z->first = next;
6089  }
6090  return 0;
6091 }
static int cob_file_sort_submit ( cob_file f,
const unsigned char *  p 
)
static

References cob_get_sort_tempfile(), cob_new_item(), cob_sort_queues(), cob_write_block(), COBSORTABORT, COBSORTFILEERR, COBSORTNOTOPEN, queue_struct::count, cobsort::destination_file, cobitem::end_of_block, cob_file::file, cobsort::files_used, queue_struct::first, cobitem::item, cobitem::next, cobsort::queue, cobsort::retrieving, cobsort::size, cobsort::switch_to_file, cobitem::unique, cobsort::unique, unique_copy(), and unlikely.

Referenced by cob_file_release(), and cob_file_sort_using().

5989 {
5990  struct cobsort *hp;
5991  struct cobitem *q;
5992  struct queue_struct *z;
5993  int n;
5994 
5995  hp = f->file;
5996  if (unlikely(!hp)) {
5997  return COBSORTNOTOPEN;
5998  }
5999  if (unlikely(hp->retrieving)) {
6000  return COBSORTABORT;
6001  }
6002  if (unlikely(hp->switch_to_file)) {
6003  if (!hp->files_used) {
6004  if (unlikely(cob_get_sort_tempfile (hp, 0))) {
6005  return COBSORTFILEERR;
6006  }
6007  if (unlikely(cob_get_sort_tempfile (hp, 1))) {
6008  return COBSORTFILEERR;
6009  }
6010  hp->files_used = 1;
6011  hp->destination_file = 0;
6012  }
6013  n = cob_sort_queues (hp);
6014 #if 0 /* RXWRXW - Cannot be true */
6015  if (unlikely(n < 0)) {
6016  return COBSORTABORT;
6017  }
6018 #endif
6019  if (unlikely(cob_write_block (hp, n))) {
6020  return COBSORTFILEERR;
6021  }
6022  hp->destination_file ^= 1;
6023  }
6024  q = cob_new_item (hp, sizeof (struct cobitem) + hp->size);
6025  q->end_of_block = 1;
6026  unique_copy (q->unique, (const unsigned char *)&(hp->unique));
6027  hp->unique++;
6028  memcpy (q->item, p, hp->size);
6029  if (hp->queue[0].count <= hp->queue[1].count) {
6030  z = &hp->queue[0];
6031  } else {
6032  z = &hp->queue[1];
6033  }
6034  q->next = z->first;
6035  z->first = q;
6036  z->count++;
6037  return 0;
6038 }
void cob_file_sort_using ( cob_file sort_file,
cob_file data_file 
)

References cob_close(), COB_CLOSE_NORMAL, cob_copy_check(), cob_file_sort_submit(), cob_open(), COB_OPEN_INPUT, COB_READ_NEXT, cob_read_next(), cob_field::data, cob_file::file_status, NULL, and cob_file::record.

6095 {
6096  int ret;
6097 
6098  cob_open (data_file, COB_OPEN_INPUT, 0, NULL);
6099  for (;;) {
6100  cob_read_next (data_file, NULL, COB_READ_NEXT);
6101  if (data_file->file_status[0] != '0') {
6102  break;
6103  }
6104  cob_copy_check (sort_file, data_file);
6105  ret = cob_file_sort_submit (sort_file, sort_file->record->data);
6106  if (ret) {
6107  break;
6108  }
6109  }
6110  cob_close (data_file, NULL, COB_CLOSE_NORMAL, 0);
6111 }
static void cob_file_unlock ( cob_file f)
static

References COB_FILE_EXCLUSIVE, COB_FILE_SPECIAL, COB_OPEN_CLOSED, COB_OPEN_LOCKED, COB_ORG_INDEXED, COB_ORG_SORT, cob_file::fd, fdcobsync, cob_file::file, cob_file::lock_mode, NULL, cob_file::open_mode, cob_file::organization, and p.

Referenced by cob_commit(), cob_rollback(), and cob_unlock_file().

4386 {
4387 #ifdef WITH_DB
4388  struct indexed_file *p;
4389 #elif defined(WITH_ANY_ISAM)
4390  struct indexfile *fh;
4391 #endif
4392 
4393 #ifndef WITH_SEQRA_EXTFH
4394 #ifdef HAVE_FCNTL
4395  struct flock lock;
4396 #endif
4397 #endif
4398 
4399  if (COB_FILE_SPECIAL(f)) {
4400  return;
4401  }
4402 
4403  if (f->open_mode != COB_OPEN_CLOSED &&
4404  f->open_mode != COB_OPEN_LOCKED) {
4405  if (f->organization == COB_ORG_SORT) {
4406  return;
4407  }
4408  if (f->organization != COB_ORG_INDEXED) {
4409 #ifndef WITH_SEQRA_EXTFH
4410  if (f->fd >= 0) {
4411  fdcobsync (f->fd);
4412  }
4413 #ifdef HAVE_FCNTL
4414  if (!(f->lock_mode & COB_FILE_EXCLUSIVE)) {
4415  /* Unlock the file */
4416  memset ((void *)&lock, 0, sizeof (struct flock));
4417  lock.l_type = F_UNLCK;
4418  lock.l_whence = SEEK_SET;
4419  lock.l_start = 0;
4420  lock.l_len = 0;
4421  if (f->fd >= 0) {
4422  fcntl (f->fd, F_SETLK, &lock);
4423  }
4424  }
4425 #endif
4426 
4427 #endif
4428  } else {
4429 #ifdef WITH_INDEX_EXTFH
4430  extfh_indexed_unlock (f);
4431 #elif defined(WITH_DB)
4432  p = f->file;
4433  if (bdb_env != NULL && p) {
4434  unlock_record (f);
4435  bdb_env->lock_put (bdb_env, &p->bdb_file_lock);
4436  }
4437 #elif defined(WITH_ANY_ISAM)
4438  fh = f->file;
4439  if (fh) {
4440  isrelease (fh->isfd);
4441  }
4442 #endif
4443  }
4444  }
4445 }
static int cob_file_write_opt ( cob_file f,
const int  opt 
)
static

References cob_linage_write_opt(), COB_SELECT_LINAGE, COB_WRITE_LINES, COB_WRITE_MASK, COB_WRITE_PAGE, cob_file::file, cob_file::flag_select_features, and unlikely.

Referenced by cob_init_fileio(), and lineseq_write().

863 {
864  int i;
865 
867  return cob_linage_write_opt (f, opt);
868  }
869  if (opt & COB_WRITE_LINES) {
870  i = opt & COB_WRITE_MASK;
871  if (!i) {
872  /* AFTER/BEFORE 0 */
873  putc (0x0d, (FILE *)f->file);
874  } else {
875  for (; i > 0; --i) {
876  putc ('\n', (FILE *)f->file);
877  }
878  }
879  } else if (opt & COB_WRITE_PAGE) {
880  putc ('\f', (FILE *)f->file);
881  }
882  return 0;
883 }
static char* cob_fileio_getenv ( const char *  env)
static

References cob_strdup(), NULL, and p.

Referenced by cob_init_fileio().

484 {
485  char *p;
486 
487  p = getenv (env);
488  if (!p) {
489  return NULL;
490  }
491  if (*p == 0 || *p == ' ') {
492  return NULL;
493  }
494  return cob_strdup (p);
495 }
static void cob_free_list ( struct cobsort hp)
static

References cob_free(), cobsort::mem_base, sort_mem_struct::mem_ptr, and sort_mem_struct::next.

Referenced by cob_file_sort_close().

5666 {
5667  struct sort_mem_struct *s1;
5668  struct sort_mem_struct *s2;
5669 
5670  s1 = hp->mem_base;
5671  for (; s1;) {
5672  s2 = s1;
5673  s1 = s1->next;
5674  cob_free (s2->mem_ptr);
5675  cob_free (s2);
5676  }
5677 }
static int cob_get_sort_tempfile ( struct cobsort hp,
const int  n 
)
static

References _, cob_runtime_error(), cob_srttmpfile(), cob_stop_run(), file_struct::count, cobsort::file, file_struct::fp, and NULL.

Referenced by cob_file_sort_process(), and cob_file_sort_submit().

5750 {
5751  if (hp->file[n].fp == NULL) {
5752  hp->file[n].fp = cob_srttmpfile ();
5753  if (hp->file[n].fp == NULL) {
5754  cob_runtime_error (_("SORT is unable to acquire temporary file"));
5755  cob_stop_run (1);
5756  }
5757  } else {
5758  rewind (hp->file[n].fp);
5759  }
5760  hp->file[n].count = 0;
5761  return hp->file[n].fp == NULL;
5762 }
void cob_init_fileio ( cob_global lptr,
runtime_env runtimeptr 
)

References check_eop_status, cob_check_env_true(), runtime_env::cob_do_sync, cob_do_sync, runtime_env::cob_do_sync_env, cob_do_sync_env, cob_fast_malloc(), COB_FILE_BUFF, runtime_env::cob_file_path, cob_file_path, runtime_env::cob_file_path_env, cob_file_path_env, cob_file_write_opt(), cob_fileio_getenv(), cob_free(), runtime_env::cob_ls_fixed, cob_ls_fixed, runtime_env::cob_ls_fixed_env, cob_ls_fixed_env, runtime_env::cob_ls_nulls, cob_ls_nulls, runtime_env::cob_ls_nulls_env, cob_ls_nulls_env, runtime_env::cob_ls_uses_cr, cob_ls_uses_cr, runtime_env::cob_ls_uses_cr_env, cob_ls_uses_cr_env, cob_malloc(), cob_save_env_value(), cob_sli_t, COB_SMALL_BUFF, runtime_env::cob_sort_chunk, cob_sort_chunk, COB_SORT_CHUNK, runtime_env::cob_sort_chunk_env, cob_sort_chunk_env, runtime_env::cob_sort_memory, cob_sort_memory, COB_SORT_MEMORY, runtime_env::cob_sort_memory_env, cob_sort_memory_env, runtime_env::cob_varseq_type, cob_varseq_type, runtime_env::cob_varseq_type_env, cob_varseq_type_env, cob_vsq_len, eop_status, file_open_buff, file_open_env, file_open_name, NULL, runtime_buffer, and WITH_VARSEQ.

Referenced by cob_init().

6371 {
6372  char *s;
6373  cob_sli_t memsiz;
6374  int n;
6375  struct stat st;
6376 
6377  cobglobptr = lptr;
6378  file_cache = NULL;
6379  eop_status = 0;
6380  check_eop_status = 0;
6381  cob_do_sync = 0;
6382  cob_ls_uses_cr = 0;
6383  cob_ls_nulls = 0;
6384  cob_ls_fixed = 0;
6385  if ((s = getenv ("COB_SYNC")) != NULL) {
6387 
6388  if (cob_check_env_true(s) || *s == 'P' || *s == 'p' ) {
6389  cob_do_sync = 1;
6390  }
6391  }
6392  if ((s = getenv ("COB_LS_USES_CR")) != NULL) {
6394 
6395  if (cob_check_env_true(s)) {
6396  cob_ls_uses_cr = 1;
6397  }
6398  }
6400  if ((s = getenv ("COB_SORT_MEMORY")) != NULL) {
6402 
6403  errno = 0;
6404  memsiz = strtol (s, NULL, 10);
6405  if (!errno && memsiz >= 1024 * 1024) {
6406  cob_sort_memory = (size_t)memsiz;
6407  }
6408  }
6410  if ((s = getenv ("COB_SORT_CHUNK")) != NULL) {
6412 
6413  n = atoi (s);
6414  if (n >= (128 * 1024) && n <= (16 * 1024 * 1024)) {
6415  cob_sort_chunk = (size_t)n;
6416  if (cob_sort_chunk % sizeof(void *)) {
6417  cob_sort_chunk += sizeof(void *) -
6418  (cob_sort_chunk % sizeof(void *));
6419  }
6420  }
6421  }
6422  if (cob_sort_chunk > (cob_sort_memory / 2)) {
6424  }
6425  cob_file_path = cob_fileio_getenv ("COB_FILE_PATH");
6427  if (cob_file_path) {
6428  if (stat (cob_file_path, &st) || !(S_ISDIR (st.st_mode))) {
6430  cob_file_path = NULL;
6431  }
6432  }
6433  if ((s = getenv ("COB_LS_NULLS")) != NULL) {
6435 
6436  if (cob_check_env_true(s)) {
6437  cob_ls_nulls = 1;
6438  }
6439  }
6440  if ((s = getenv ("COB_LS_FIXED")) != NULL) {
6442 
6443  if (cob_check_env_true(s)) {
6444  cob_ls_fixed = 1;
6445  }
6446  }
6447 
6448 #if WITH_VARSEQ == 3
6449  cob_vsq_len = 2;
6450 #else
6451  cob_vsq_len = 4;
6452 #endif
6454  if ((s = getenv ("COB_VARSEQ_FORMAT")) != NULL) {
6456 
6457  if (*s == '0') {
6458  cob_varseq_type = 0;
6459  cob_vsq_len = 4;
6460  } else if (*s == '1') {
6461  cob_varseq_type = 1;
6462  cob_vsq_len = 4;
6463  } else if (*s == '2') {
6464  cob_varseq_type = 2;
6465  cob_vsq_len = 4;
6466  } else if (*s == '3') {
6467  cob_varseq_type = 3;
6468  cob_vsq_len = 2;
6469  }
6470  }
6471 
6472  runtime_buffer = cob_fast_malloc ((size_t)(4 * COB_FILE_BUFF));
6474  file_open_name = runtime_buffer + (2 * COB_FILE_BUFF);
6475  file_open_buff = runtime_buffer + (3 * COB_FILE_BUFF);
6476 
6477 #ifdef WITH_DB
6478  bdb_env = NULL;
6479  bdb_data_dir = NULL;
6480  bdb_home = cob_fileio_getenv ("DB_HOME");
6481  join_environment ();
6482  record_lock_object = cob_malloc ((size_t)1024);
6483  bdb_buff = cob_malloc ((size_t)COB_SMALL_BUFF);
6484  rlo_size = 1024;
6485 #endif
6486 
6487 #if defined(WITH_INDEX_EXTFH) || defined(WITH_SEQRA_EXTFH)
6488  extfh_cob_init_fileio (&sequential_funcs, &lineseq_funcs,
6490 #endif
6491 
6492 
6493  runtimeptr->cob_do_sync = &cob_do_sync;
6494  runtimeptr->cob_do_sync_env = cob_do_sync_env;
6495  runtimeptr->cob_ls_nulls = &cob_ls_nulls;
6496  runtimeptr->cob_ls_nulls_env = cob_ls_nulls_env;
6497  runtimeptr->cob_ls_fixed = &cob_ls_fixed;
6498  runtimeptr->cob_ls_fixed_env = cob_ls_fixed_env;
6499  runtimeptr->cob_ls_uses_cr = &cob_ls_uses_cr;
6500  runtimeptr->cob_ls_uses_cr_env = cob_ls_uses_cr_env;
6501  runtimeptr->cob_file_path = cob_file_path;
6502  runtimeptr->cob_file_path_env = cob_file_path_env;
6503  runtimeptr->cob_sort_memory = &cob_sort_memory;
6505  runtimeptr->cob_sort_chunk = &cob_sort_chunk;
6506  runtimeptr->cob_sort_chunk_env = cob_sort_chunk_env;
6507  runtimeptr->cob_varseq_type = &cob_varseq_type;
6509 }
static int cob_linage_write_opt ( cob_file f,
const int  opt 
)
static

References check_eop_status, cob_add_int(), cob_get_int(), cob_set_int(), COB_STATUS_57_I_O_LINAGE, COB_WRITE_LINES, COB_WRITE_MASK, COB_WRITE_PAGE, eop_status, cob_file::file, file_linage_check(), if(), cob_linage::lin_bot, cob_linage::lin_foot, cob_linage::lin_lines, cob_linage::lin_top, cob_linage::linage_ctr, cob_file::linorkeyptr, and unlikely.

Referenced by cob_file_write_opt().

767 {
768  cob_linage *lingptr;
769  FILE *fp;
770  int i;
771  int n;
772 
773  fp = (FILE *)f->file;
774  lingptr = f->linorkeyptr;
775  if (unlikely(opt & COB_WRITE_PAGE)) {
776  i = cob_get_int (lingptr->linage_ctr);
777  if (i == 0) {
779  }
780  n = lingptr->lin_lines;
781  for (; i < n; ++i) {
782  putc ('\n', fp);
783  }
784  for (i = 0; i < lingptr->lin_bot; ++i) {
785  putc ('\n', fp);
786  }
787  if (file_linage_check (f)) {
789  }
790  for (i = 0; i < lingptr->lin_top; ++i) {
791  putc ('\n', fp);
792  }
793  cob_set_int (lingptr->linage_ctr, 1);
794  } else if (opt & COB_WRITE_LINES) {
795  n = cob_get_int (lingptr->linage_ctr);
796  if (n == 0) {
798  }
799  cob_add_int (lingptr->linage_ctr, opt & COB_WRITE_MASK, 0);
800  i = cob_get_int (lingptr->linage_ctr);
801  /* Set EOP status if requested */
802  if (check_eop_status && lingptr->lin_foot) {
803  if (i >= lingptr->lin_foot) {
804  eop_status = 1;
805  }
806  }
807  if (i > lingptr->lin_lines) {
808  /* Set EOP status if requested */
809  if (check_eop_status) {
810  eop_status = 1;
811  }
812  for (; n < lingptr->lin_lines; ++n) {
813  putc ('\n', fp);
814  }
815  for (i = 0; i < lingptr->lin_bot; ++i) {
816  putc ('\n', fp);
817  }
818  if (file_linage_check (f)) {
820  }
821  cob_set_int (lingptr->linage_ctr, 1);
822  for (i = 0; i < lingptr->lin_top; ++i) {
823  putc ('\n', fp);
824  }
825  } else {
826  for (i = (opt & COB_WRITE_MASK) - 1; i > 0; --i) {
827  putc ('\n', fp);
828  }
829  }
830  }
831  return 0;
832 }
static struct cobitem* cob_new_item ( struct cobsort hp,
const size_t  size 
)
staticread

References cobsort::alloc_size, cobitem::block_byte, cobsort::chunk_size, cob_fast_malloc(), cob_sort_memory, COB_UNUSED, cobsort::empty, cobitem::end_of_block, cobsort::mem_base, sort_mem_struct::mem_ptr, cobsort::mem_size, cobsort::mem_total, cobsort::mem_used, cobitem::next, sort_mem_struct::next, NULL, cobsort::switch_to_file, and unlikely.

Referenced by cob_file_sort_submit().

5681 {
5682  struct cobitem *q;
5683  struct sort_mem_struct *s;
5684 
5685  COB_UNUSED (size);
5686 
5687  /* Creation of an empty item */
5688  if (unlikely(hp->empty != NULL)) {
5689  q = hp->empty;
5690  hp->empty = q->next;
5691  q->block_byte = 0;
5692  q->next = NULL;
5693  q->end_of_block = 0;
5694  return (void *)q;
5695  }
5696  if (unlikely((hp->mem_used + hp->alloc_size) > hp->mem_size)) {
5697  s = cob_fast_malloc (sizeof (struct sort_mem_struct));
5698  s->mem_ptr = cob_fast_malloc (hp->chunk_size);
5699  s->next = hp->mem_base;
5700  hp->mem_base = s;
5701  hp->mem_size = hp->chunk_size;
5702  hp->mem_total += hp->chunk_size;
5703  hp->mem_used = 0;
5704  }
5705  q = (struct cobitem *)(hp->mem_base->mem_ptr + hp->mem_used);
5706  hp->mem_used += hp->alloc_size;
5707  if (unlikely(hp->mem_total >= cob_sort_memory)) {
5708  if ((hp->mem_used + hp->alloc_size) > hp->mem_size) {
5709  hp->switch_to_file = 1;
5710  }
5711  }
5712  q->block_byte = 0;
5713  q->next = NULL;
5714  q->end_of_block = 0;
5715  return q;
5716 }
void cob_open ( cob_file f,
const int  mode,
const int  sharing,
cob_field fnstatus 
)

References cob_file::assign, cob_cache_file(), cob_field_to_string(), COB_FILE_MAX, COB_FILE_STDIN, COB_FILE_STDOUT, COB_LOCK_OPEN_EXCLUSIVE, COB_OPEN_CLOSED, COB_OPEN_INPUT, COB_OPEN_LOCKED, COB_OPEN_OUTPUT, COB_STATUS_00_SUCCESS, COB_STATUS_30_PERMANENT_ERROR, COB_STATUS_38_CLOSED_WITH_LOCK, COB_STATUS_41_ALREADY_OPEN, cob_file::fd, cob_file::file, file_open_name, cob_file::flag_begin_of_file, cob_file::flag_end_of_file, cob_file::flag_first_read, cob_file::flag_nonexistent, cob_file::flag_operation, cob_file::flag_read_done, cob_file::last_open_mode, cob_file::lock_mode, cob_fileio_funcs::open, cob_file::open_mode, cob_file::organization, save_status(), and unlikely.

Referenced by cob_file_sort_giving(), and cob_file_sort_using().

4458 {
4459  f->flag_read_done = 0;
4460 
4461  /* File was previously closed with lock */
4462  if (f->open_mode == COB_OPEN_LOCKED) {
4464  return;
4465  }
4466 
4467  /* File is already open */
4468  if (f->open_mode != COB_OPEN_CLOSED) {
4469  save_status (f, fnstatus, COB_STATUS_41_ALREADY_OPEN);
4470  return;
4471  }
4472 
4473  f->last_open_mode = mode;
4474  f->flag_nonexistent = 0;
4475  f->flag_end_of_file = 0;
4476  f->flag_begin_of_file = 0;
4477  f->flag_first_read = 2;
4478  f->flag_operation = 0;
4480  f->lock_mode |= sharing;
4481 
4482  if (unlikely(COB_FILE_STDIN (f))) {
4483  if (mode != COB_OPEN_INPUT) {
4485  return;
4486  }
4487  f->file = stdin;
4488  f->fd = fileno (stdin);
4489  f->open_mode = mode;
4490  save_status (f, fnstatus, COB_STATUS_00_SUCCESS);
4491  return;
4492  }
4493  if (unlikely(COB_FILE_STDOUT (f))) {
4494  if (mode != COB_OPEN_OUTPUT) {
4496  return;
4497  }
4498  f->file = stdout;
4499  f->fd = fileno (stdout);
4500  f->open_mode = mode;
4501  save_status (f, fnstatus, COB_STATUS_00_SUCCESS);
4502  return;
4503  }
4504 
4505  /* Obtain the file name */
4506  cob_field_to_string (f->assign, file_open_name, (size_t)COB_FILE_MAX);
4507 
4508  cob_cache_file (f);
4509 
4510  /* Open the file */
4511  save_status (f, fnstatus,
4513  mode, sharing));
4514 }
void cob_read ( cob_file f,
cob_field key,
cob_field fnstatus,
const int  read_opts 
)

References COB_OPEN_I_O, COB_OPEN_INPUT, COB_READ_PREVIOUS, cob_set_int(), COB_STATUS_00_SUCCESS, COB_STATUS_02_SUCCESS_DUPLICATE, COB_STATUS_10_END_OF_FILE, COB_STATUS_23_KEY_NOT_EXISTS, COB_STATUS_46_READ_ERROR, COB_STATUS_47_INPUT_DENIED, cob_file::flag_begin_of_file, cob_file::flag_end_of_file, cob_file::flag_first_read, cob_file::flag_nonexistent, cob_file::flag_read_done, NULL, cob_file::open_mode, cob_file::organization, cob_fileio_funcs::read, cob_fileio_funcs::read_next, cob_file::record, save_status(), cob_field::size, unlikely, and cob_file::variable_record.

4653 {
4654  int ret;
4655 
4656  f->flag_read_done = 0;
4657 
4658  if (unlikely(f->open_mode != COB_OPEN_INPUT &&
4659  f->open_mode != COB_OPEN_I_O)) {
4660  save_status (f, fnstatus, COB_STATUS_47_INPUT_DENIED);
4661  return;
4662  }
4663 
4664  if (unlikely(f->flag_nonexistent)) {
4665  if (f->flag_first_read == 0) {
4667  return;
4668  }
4669  f->flag_first_read = 0;
4670  save_status (f, fnstatus, COB_STATUS_10_END_OF_FILE);
4671  return;
4672  }
4673 
4674  /* Sequential read at the end of file is an error */
4675  if (key == NULL) {
4676  if (unlikely(f->flag_end_of_file &&
4677  !(read_opts & COB_READ_PREVIOUS))) {
4678  save_status (f, fnstatus, COB_STATUS_46_READ_ERROR);
4679  return;
4680  }
4681  if (unlikely(f->flag_begin_of_file &&
4682  (read_opts & COB_READ_PREVIOUS))) {
4683  save_status (f, fnstatus, COB_STATUS_46_READ_ERROR);
4684  return;
4685  }
4686  ret = fileio_funcs[(int)f->organization]->read_next (f, read_opts);
4687  } else {
4688  ret = fileio_funcs[(int)f->organization]->read (f, key, read_opts);
4689  }
4690 
4691  switch (ret) {
4692  case COB_STATUS_00_SUCCESS:
4694  f->flag_first_read = 0;
4695  f->flag_read_done = 1;
4696  f->flag_end_of_file = 0;
4697  f->flag_begin_of_file = 0;
4698  if (f->variable_record) {
4699  cob_set_int (f->variable_record, (int) f->record->size);
4700  }
4701  break;
4703  if (read_opts & COB_READ_PREVIOUS) {
4704  f->flag_begin_of_file = 1;
4705  } else {
4706  f->flag_end_of_file = 1;
4707  }
4708  break;
4709  }
4710 
4711  save_status (f, fnstatus, ret);
4712 }
static int cob_read_item ( struct cobsort hp,
const int  n 
)
static

References cobitem::end_of_block, cobsort::file, queue_struct::first, file_struct::fp, cobsort::queue, cobsort::r_size, cobitem::unique, and unlikely.

Referenced by cob_file_sort_process(), and cob_file_sort_retrieve().

5825 {
5826  FILE *fp;
5827 
5828  fp = hp->file[n].fp;
5829  if (getc (fp) != 0) {
5830  hp->queue[n].first->end_of_block = 1;
5831  } else {
5832  hp->queue[n].first->end_of_block = 0;
5833  if (unlikely(fread (hp->queue[n].first->unique, hp->r_size, (size_t)1, fp) != 1)) {
5834  return 1;
5835  }
5836  }
5837  return 0;
5838 }
void cob_read_next ( cob_file f,
cob_field fnstatus,
const int  read_opts 
)

References COB_OPEN_I_O, COB_OPEN_INPUT, COB_READ_PREVIOUS, cob_set_int(), COB_STATUS_00_SUCCESS, COB_STATUS_02_SUCCESS_DUPLICATE, COB_STATUS_10_END_OF_FILE, COB_STATUS_23_KEY_NOT_EXISTS, COB_STATUS_46_READ_ERROR, COB_STATUS_47_INPUT_DENIED, cob_file::flag_begin_of_file, cob_file::flag_end_of_file, cob_file::flag_first_read, cob_file::flag_nonexistent, cob_file::flag_read_done, cob_file::open_mode, cob_file::organization, cob_fileio_funcs::read_next, cob_file::record, save_status(), cob_field::size, unlikely, and cob_file::variable_record.

Referenced by cob_file_sort_using().

4716 {
4717  int ret;
4718 
4719  f->flag_read_done = 0;
4720 
4721  if (unlikely(f->open_mode != COB_OPEN_INPUT &&
4722  f->open_mode != COB_OPEN_I_O)) {
4723  save_status (f, fnstatus, COB_STATUS_47_INPUT_DENIED);
4724  return;
4725  }
4726 
4727  if (unlikely(f->flag_nonexistent)) {
4728  if (f->flag_first_read == 0) {
4730  return;
4731  }
4732  f->flag_first_read = 0;
4733  save_status (f, fnstatus, COB_STATUS_10_END_OF_FILE);
4734  return;
4735  }
4736 
4737  /* Sequential read at the end of file is an error */
4738  if (unlikely(f->flag_end_of_file && !(read_opts & COB_READ_PREVIOUS))) {
4739  save_status (f, fnstatus, COB_STATUS_46_READ_ERROR);
4740  return;
4741  }
4742  if (unlikely(f->flag_begin_of_file && (read_opts & COB_READ_PREVIOUS))) {
4743  save_status (f, fnstatus, COB_STATUS_46_READ_ERROR);
4744  return;
4745  }
4746 
4747  ret = fileio_funcs[(int)f->organization]->read_next (f, read_opts);
4748 
4749  switch (ret) {
4750  case COB_STATUS_00_SUCCESS:
4752  f->flag_first_read = 0;
4753  f->flag_read_done = 1;
4754  f->flag_end_of_file = 0;
4755  f->flag_begin_of_file = 0;
4756  if (f->variable_record) {
4757  cob_set_int (f->variable_record, (int) f->record->size);
4758  }
4759  break;
4761  if (read_opts & COB_READ_PREVIOUS) {
4762  f->flag_begin_of_file = 1;
4763  } else {
4764  f->flag_end_of_file = 1;
4765  }
4766  break;
4767  }
4768 
4769  save_status (f, fnstatus, ret);
4770 }
void cob_rewrite ( cob_file f,
cob_field rec,
const int  opt,
cob_field fnstatus 
)

References cob_file::access_mode, COB_ACCESS_SEQUENTIAL, cob_get_int(), COB_OPEN_I_O, COB_ORG_SEQUENTIAL, COB_STATUS_43_READ_NOT_DONE, COB_STATUS_44_RECORD_OVERFLOW, COB_STATUS_49_I_O_DENIED, cob_file::flag_read_done, cob_file::open_mode, cob_file::organization, cob_file::record, cob_fileio_funcs::rewrite, save_status(), cob_field::size, unlikely, and cob_file::variable_record.

4813 {
4814  int read_done;
4815 
4816  read_done = f->flag_read_done;
4817  f->flag_read_done = 0;
4818 
4819  if (unlikely(f->open_mode != COB_OPEN_I_O)) {
4820  save_status (f, fnstatus, COB_STATUS_49_I_O_DENIED);
4821  return;
4822  }
4823 
4824  if (f->access_mode == COB_ACCESS_SEQUENTIAL && !read_done) {
4826  return;
4827  }
4828 
4830  if (f->record->size != rec->size) {
4832  return;
4833  }
4834 
4835  if (f->variable_record) {
4836  if (f->record->size != (size_t)cob_get_int (f->variable_record)) {
4838  return;
4839  }
4840  }
4841  }
4842 
4843  save_status (f, fnstatus,
4844  fileio_funcs[(int)f->organization]->rewrite (f, opt));
4845 }
void cob_rollback ( void  )

References cob_file_unlock(), file_list::file, and file_list::next.

4883 {
4884  struct file_list *l;
4885 
4886  for (l = file_cache; l; l = l->next) {
4887  if (l->file) {
4888  cob_file_unlock (l->file);
4889  }
4890  }
4891 }
static unsigned int cob_seq_write_opt ( cob_file f,
const int  opt 
)
static

References COB_WRITE_LINES, COB_WRITE_MASK, COB_WRITE_PAGE, and cob_file::fd.

Referenced by sequential_write().

836 {
837  int i;
838 
839  if (opt & COB_WRITE_LINES) {
840  i = opt & COB_WRITE_MASK;
841  if (!i) {
842  /* AFTER/BEFORE 0 */
843  if (write (f->fd, "\015", (size_t)1) != 1) {
844  return 1;
845  }
846  } else {
847  for (i = opt & COB_WRITE_MASK; i > 0; --i) {
848  if (write (f->fd, "\n", (size_t)1) != 1) {
849  return 1;
850  }
851  }
852  }
853  } else if (opt & COB_WRITE_PAGE) {
854  if (write (f->fd, "\f", (size_t)1) != 1) {
855  return 1;
856  }
857  }
858  return 0;
859 }
static int cob_sort_queues ( struct cobsort hp)
static

References cob_file_sort_compare(), queue_struct::count, cobitem::end_of_block, queue_struct::first, queue_struct::last, cobitem::next, NULL, cobsort::pointer, and cobsort::queue.

Referenced by cob_file_sort_process(), and cob_file_sort_submit().

5766 {
5767  struct cobitem *q;
5768  int source;
5769  int destination;
5770  int move;
5771  int n;
5772  int end_of_block[2];
5773 
5774  source = 0;
5775  while (hp->queue[source + 1].count != 0) {
5776  destination = source ^ 2;
5777  hp->queue[destination].first = NULL;
5778  hp->queue[destination].count = 0;
5779  hp->queue[destination + 1].first = NULL;
5780  hp->queue[destination + 1].count = 0;
5781  for (;;) {
5782  end_of_block[0] = hp->queue[source].count == 0;
5783  end_of_block[1] = hp->queue[source + 1].count == 0;
5784  if (end_of_block[0] && end_of_block[1]) {
5785  break;
5786  }
5787  while (!end_of_block[0] || !end_of_block[1]) {
5788  if (end_of_block[0]) {
5789  move = 1;
5790  } else if (end_of_block[1]) {
5791  move = 0;
5792  } else {
5794  (hp->queue[source].first,
5795  hp->queue[source + 1].first,
5796  hp->pointer);
5797  move = n < 0 ? 0 : 1;
5798  }
5799  q = hp->queue[source + move].first;
5800  if (q->end_of_block) {
5801  end_of_block[move] = 1;
5802  }
5803  hp->queue[source + move].first = q->next;
5804  if (hp->queue[destination].first == NULL) {
5805  hp->queue[destination].first = q;
5806  } else {
5807  hp->queue[destination].last->next = q;
5808  }
5809  hp->queue[destination].last = q;
5810  hp->queue[source + move].count--;
5811  hp->queue[destination].count++;
5812  q->next = NULL;
5813  q->end_of_block = 0;
5814  }
5815  hp->queue[destination].last->end_of_block = 1;
5816  destination ^= 1;
5817  }
5818  source = destination & 2;
5819  }
5820  return source;
5821 }
static FILE* cob_srttmpfile ( void  )
static

References _O_TEMPORARY, COB_FILE_BUFF, cob_free(), cob_incr_temp_iteration(), cob_malloc(), cob_temp_name(), NULL, and O_BINARY.

Referenced by cob_get_sort_tempfile().

5720 {
5721  FILE *fp;
5722  char *filename;
5723  int fd;
5724 
5725  filename = cob_malloc ((size_t)COB_FILE_BUFF);
5726  cob_temp_name(filename, NULL);
5728 #ifdef _WIN32
5729  fd = open (filename,
5730  _O_CREAT | _O_TRUNC | _O_RDWR | _O_BINARY | _O_TEMPORARY,
5731  _S_IREAD | _S_IWRITE);
5732 #else
5733  fd = open (filename, O_CREAT | O_TRUNC | O_RDWR | O_BINARY, 0660);
5734 #endif
5735  if (fd < 0) {
5736  cob_free (filename);
5737  return NULL;
5738  }
5739  (void)unlink (filename);
5740  fp = fdopen (fd, "w+b");
5741  if (!fp) {
5742  close (fd);
5743  }
5744  cob_free (filename);
5745  return fp;
5746 }
void cob_start ( cob_file f,
const int  cond,
cob_field key,
cob_field keysize,
cob_field fnstatus 
)

References cob_file::access_mode, COB_ACCESS_RANDOM, cob_get_int(), COB_OPEN_I_O, COB_OPEN_INPUT, COB_STATUS_00_SUCCESS, COB_STATUS_23_KEY_NOT_EXISTS, COB_STATUS_47_INPUT_DENIED, cob_file::flag_begin_of_file, cob_file::flag_end_of_file, cob_file::flag_first_read, cob_file::flag_nonexistent, cob_file::flag_read_done, cob_file::open_mode, cob_file::organization, save_status(), cob_field::size, cob_fileio_funcs::start, and unlikely.

4605 {
4606  int ret;
4607  int size;
4608  cob_field tempkey;
4609 
4610  f->flag_read_done = 0;
4611  f->flag_first_read = 0;
4612 
4613  if (unlikely(f->open_mode != COB_OPEN_I_O &&
4614  f->open_mode != COB_OPEN_INPUT)) {
4615  save_status (f, fnstatus, COB_STATUS_47_INPUT_DENIED);
4616  return;
4617  }
4618 
4619  if (unlikely(f->access_mode == COB_ACCESS_RANDOM)) {
4620  save_status (f, fnstatus, COB_STATUS_47_INPUT_DENIED);
4621  return;
4622  }
4623 
4624  if (f->flag_nonexistent) {
4626  return;
4627  }
4628 
4629  size = 0;
4630  if (unlikely(keysize)) {
4631  size = cob_get_int (keysize);
4632  if (size < 1 || size > (int)key->size) {
4634  return;
4635  }
4636  tempkey = *key;
4637  tempkey.size = (size_t)size;
4638  ret = fileio_funcs[(int)f->organization]->start (f, cond, &tempkey);
4639  } else {
4640  ret = fileio_funcs[(int)f->organization]->start (f, cond, key);
4641  }
4642  if (ret == COB_STATUS_00_SUCCESS) {
4643  f->flag_end_of_file = 0;
4644  f->flag_begin_of_file = 0;
4645  f->flag_first_read = 1;
4646  }
4647 
4648  save_status (f, fnstatus, ret);
4649 }
static void* cob_str_from_fld ( const cob_field f)
static

References cob_malloc(), cob_field::data, and cob_field::size.

Referenced by cob_sys_change_dir(), cob_sys_check_file_exist(), cob_sys_copy_file(), cob_sys_create_dir(), cob_sys_delete_dir(), cob_sys_delete_file(), cob_sys_file_info(), cob_sys_rename_file(), and open_cbl_file().

4948 {
4949  void *mptr;
4950  unsigned char *s;
4951  int i;
4952  int n;
4953  int j;
4954 #if 0 /* Quotes in file */
4955  int quote_switch;
4956 
4957  quote_switch = 0;
4958 #endif
4959 
4960  if (!f) {
4961  return cob_malloc ((size_t)1);
4962  }
4963  for (i = (int) f->size - 1; i >= 0; --i) {
4964  if (f->data[i] != ' ' && f->data[i] != 0) {
4965  break;
4966  }
4967  }
4968  i++;
4969  /* i is 0 or > 0 */
4970  mptr = cob_malloc ((size_t)(i + 1));
4971  s = mptr;
4972  j = 0;
4973  for (n = 0; n < i; ++n) {
4974  if (f->data[n] == '"') {
4975  continue;
4976  }
4977  s[j++] = f->data[n];
4978 #if 0 /* Quotes in file */
4979  if (f->data[n] == '"') {
4980  quote_switch = !quote_switch;
4981  continue;
4982  }
4983  s[j] = f->data[n];
4984  if (quote_switch) {
4985  j++;
4986  continue;
4987  }
4988  if (s[j] == ' ' || s[j] == 0) {
4989  s[j] = 0;
4990  break;
4991  }
4992  j++;
4993 #endif
4994  }
4995  return mptr;
4996 }
static void cob_sync ( cob_file f)
static

References COB_ORG_INDEXED, COB_ORG_LINE_SEQUENTIAL, COB_ORG_SORT, cob_file::fd, fdcobsync, cob_file::file, cob_file::nkeys, cob_file::organization, and p.

Referenced by save_status().

641 {
642 #ifdef WITH_DB
643  struct indexed_file *p;
644  size_t i;
645 #elif defined(WITH_ANY_ISAM)
646  struct indexfile *fh;
647 #endif
648 
649  if (f->organization == COB_ORG_INDEXED) {
650 #ifdef WITH_DB
651  p = f->file;
652  for (i = 0; i < f->nkeys; ++i) {
653  if (p->db[i]) {
654  DB_SYNC (p->db[i]);
655  }
656  }
657 #elif defined(WITH_ANY_ISAM)
658  fh = f->file;
659  if (fh) {
660  isflush (fh->isfd);
661  }
662 #endif
663  return;
664  }
665  if (f->organization != COB_ORG_SORT) {
667  if (f->file) {
668  fflush ((FILE *)f->file);
669  }
670  }
671  if (f->fd >= 0) {
672  fdcobsync (f->fd);
673  }
674  }
675 }
int cob_sys_change_dir ( unsigned char *  dir)

References COB_CHK_PARMS, cob_free(), COB_MODULE_PTR, cob_str_from_fld(), and COB_UNUSED.

Referenced by cob_sys_chdir().

5415 {
5416  char *fn;
5417  int ret;
5418 
5419  COB_UNUSED (dir);
5420 
5421  COB_CHK_PARMS (CBL_CHANGE_DIR, 1);
5422 
5423  if (!COB_MODULE_PTR->cob_procedure_params[0]) {
5424  return -1;
5425  }
5426  fn = cob_str_from_fld (COB_MODULE_PTR->cob_procedure_params[0]);
5427  ret = chdir (fn);
5428  cob_free (fn);
5429  if (ret) {
5430  return 128;
5431  }
5432  return 0;
5433 }
int cob_sys_chdir ( unsigned char *  dir,
unsigned char *  status 
)

References COB_CHK_PARMS, COB_MODULE_PTR, cob_set_int(), cob_sys_change_dir(), and COB_UNUSED.

5473 {
5474  int ret;
5475 
5476  COB_UNUSED (status);
5477 
5478  COB_CHK_PARMS (C$CHDIR, 2);
5479 
5480  ret = cob_sys_change_dir (dir);
5481  if (ret < 0) {
5482  ret = 128;
5483  }
5484  cob_set_int (COB_MODULE_PTR->cob_procedure_params[1], ret);
5485  return ret;
5486 }
int cob_sys_check_file_exist ( unsigned char *  file_name,
unsigned char *  file_info 
)

References _, COB_BSWAP_16, COB_BSWAP_64, COB_CHK_PARMS, cob_free(), COB_MODULE_PTR, cob_runtime_error(), cob_s64_t, cob_stop_run(), cob_str_from_fld(), and COB_UNUSED.

5259 {
5260  char *fn;
5261  struct tm *tm;
5262  cob_s64_t sz;
5263  struct stat st;
5264  short y;
5265  short d, m, hh, mm, ss;
5266 
5267  COB_UNUSED (file_name);
5268 
5269  COB_CHK_PARMS (CBL_CHECK_FILE_EXIST, 2);
5270 
5271  if (!COB_MODULE_PTR->cob_procedure_params[0]) {
5272  return -1;
5273  }
5274  if (!COB_MODULE_PTR->cob_procedure_params[1]) {
5275  return -1;
5276  }
5277  if (COB_MODULE_PTR->cob_procedure_params[1]->size < 16U) {
5278  cob_runtime_error (_("'CBL_CHECK_FILE_EXIST' - File detail area is too short"));
5279  cob_stop_run (1);
5280  }
5281 
5282  fn = cob_str_from_fld (COB_MODULE_PTR->cob_procedure_params[0]);
5283  if (stat (fn, &st) < 0) {
5284  cob_free (fn);
5285  return 35;
5286  }
5287  cob_free (fn);
5288  sz = (cob_s64_t)st.st_size;
5289  tm = localtime (&st.st_mtime);
5290  d = (short)tm->tm_mday;
5291  m = (short)(tm->tm_mon + 1);
5292  y = (short)(tm->tm_year + 1900);
5293  hh = (short)tm->tm_hour;
5294  mm = (short)tm->tm_min;
5295  /* Leap seconds ? */
5296  if (tm->tm_sec >= 60) {
5297  ss = 59;
5298  } else {
5299  ss = (short)tm->tm_sec;
5300  }
5301 
5302 #ifndef WORDS_BIGENDIAN
5303  sz = COB_BSWAP_64 (sz);
5304  y = COB_BSWAP_16 (y);
5305 #endif
5306  memcpy (file_info, &sz, (size_t)8);
5307  file_info[8] = (unsigned char)d;
5308  file_info[9] = (unsigned char)m;
5309  memcpy (file_info+10, &y, (size_t)2);
5310  file_info[12] = (unsigned char)hh;
5311  file_info[13] = (unsigned char)mm;
5312  file_info[14] = (unsigned char)ss;
5313  file_info[15] = 0;
5314  return 0;
5315 }
int cob_sys_close_file ( unsigned char *  file_handle)

References COB_CHK_PARMS.

5164 {
5165  int fd;
5166 
5167  COB_CHK_PARMS (CBL_CLOSE_FILE, 1);
5168 
5169  memcpy (&fd, file_handle, (size_t)4);
5170  return close (fd);
5171 }
int cob_sys_copy_file ( unsigned char *  fname1,
unsigned char *  fname2 
)

References COB_CHK_PARMS, COB_FILE_BUFF, cob_free(), COB_MODULE_PTR, cob_str_from_fld(), COB_UNUSED, file_open_buff, and O_BINARY.

Referenced by cob_sys_copyfile().

5207 {
5208  char *fn1;
5209  char *fn2;
5210  int flag = O_BINARY;
5211  int ret;
5212  int i;
5213  int fd1, fd2;
5214 
5215  COB_UNUSED (fname1);
5216  COB_UNUSED (fname2);
5217 
5218  COB_CHK_PARMS (CBL_COPY_FILE, 2);
5219 
5220  if (!COB_MODULE_PTR->cob_procedure_params[0]) {
5221  return -1;
5222  }
5223  if (!COB_MODULE_PTR->cob_procedure_params[1]) {
5224  return -1;
5225  }
5226  fn1 = cob_str_from_fld (COB_MODULE_PTR->cob_procedure_params[0]);
5227  flag |= O_RDONLY;
5228  fd1 = open (fn1, flag, 0);
5229  if (fd1 < 0) {
5230  cob_free (fn1);
5231  return -1;
5232  }
5233  cob_free (fn1);
5234  fn2 = cob_str_from_fld (COB_MODULE_PTR->cob_procedure_params[1]);
5235  flag &= ~O_RDONLY;
5236  flag |= O_CREAT | O_TRUNC | O_WRONLY;
5237  fd2 = open (fn2, flag, 0660);
5238  if (fd2 < 0) {
5239  close (fd1);
5240  cob_free (fn2);
5241  return -1;
5242  }
5243  cob_free (fn2);
5244 
5245  ret = 0;
5246  while ((i = read (fd1, file_open_buff, COB_FILE_BUFF)) > 0) {
5247  if (write (fd2, file_open_buff, (size_t)i) < 0) {
5248  ret = -1;
5249  break;
5250  }
5251  }
5252  close (fd1);
5253  close (fd2);
5254  return ret;
5255 }
int cob_sys_copyfile ( unsigned char *  fname1,
unsigned char *  fname2,
unsigned char *  file_type 
)

References __cob_global::cob_call_params, COB_CHK_PARMS, cob_sys_copy_file(), and COB_UNUSED.

5491 {
5492  int ret;
5493 
5494  /* RXW - Type is not yet evaluated */
5495  COB_UNUSED (file_type);
5496 
5497  COB_CHK_PARMS (C$COPY, 3);
5498 
5499  if (cobglobptr->cob_call_params < 3) {
5500  return 128;
5501  }
5502  ret = cob_sys_copy_file (fname1, fname2);
5503  if (ret < 0) {
5504  ret = 128;
5505  }
5506  return ret;
5507 }
int cob_sys_create_dir ( unsigned char *  dir)

References COB_CHK_PARMS, cob_free(), COB_MODULE_PTR, cob_str_from_fld(), and COB_UNUSED.

Referenced by cob_sys_mkdir().

5389 {
5390  char *fn;
5391  int ret;
5392 
5393  COB_UNUSED (dir);
5394 
5395  COB_CHK_PARMS (CBL_CREATE_DIR, 1);
5396 
5397  if (!COB_MODULE_PTR->cob_procedure_params[0]) {
5398  return -1;
5399  }
5400  fn = cob_str_from_fld (COB_MODULE_PTR->cob_procedure_params[0]);
5401 #ifdef _WIN32
5402  ret = mkdir (fn);
5403 #else
5404  ret = mkdir (fn, 0770);
5405 #endif
5406  cob_free (fn);
5407  if (ret) {
5408  return 128;
5409  }
5410  return 0;
5411 }
int cob_sys_create_file ( unsigned char *  file_name,
unsigned char *  file_access,
unsigned char *  file_lock,
unsigned char *  file_dev,
unsigned char *  file_handle 
)

References _, COB_CHK_PARMS, __cob_global::cob_display_warn, and open_cbl_file().

5061 {
5062  /*
5063  * @param: file_access : 1 (read-only), 2 (write-only), 3 (both)
5064  * @param: file_lock : not implemented, set 0
5065  * @param: file_dev : not implemented, set 0
5066  */
5067 
5068  if (*file_lock != 0 && cobglobptr->cob_display_warn) {
5069  fprintf (stderr, _("WARNING - Call to CBL_CREATE_FILE with wrong file_lock: %d"), *file_lock);
5070  putc ('\n', stderr);
5071  fflush (stderr);
5072  }
5073  if (*file_dev != 0 && cobglobptr->cob_display_warn) {
5074  fprintf (stderr, _("WARNING - Call to CBL_CREATE_FILE with wrong file_dev: %d"), *file_dev);
5075  putc ('\n', stderr);
5076  fflush (stderr);
5077  }
5078 
5079  COB_CHK_PARMS (CBL_CREATE_FILE, 5);
5080 
5081  return open_cbl_file (file_name, file_access, file_handle, O_CREAT | O_TRUNC);
5082 }
int cob_sys_delete_dir ( unsigned char *  dir)

References COB_CHK_PARMS, cob_free(), COB_MODULE_PTR, cob_str_from_fld(), and COB_UNUSED.

5437 {
5438  char *fn;
5439  int ret;
5440 
5441  COB_UNUSED (dir);
5442 
5443  COB_CHK_PARMS (CBL_DELETE_DIR, 1);
5444 
5445  if (!COB_MODULE_PTR->cob_procedure_params[0]) {
5446  return -1;
5447  }
5448  fn = cob_str_from_fld (COB_MODULE_PTR->cob_procedure_params[0]);
5449  ret = rmdir (fn);
5450  cob_free (fn);
5451  if (ret) {
5452  return 128;
5453  }
5454  return 0;
5455 }
int cob_sys_delete_file ( unsigned char *  file_name)

References COB_CHK_PARMS, cob_free(), COB_MODULE_PTR, cob_str_from_fld(), and COB_UNUSED.

Referenced by cob_sys_file_delete().

5185 {
5186  char *fn;
5187  int ret;
5188 
5189  COB_UNUSED (file_name);
5190 
5191  COB_CHK_PARMS (CBL_DELETE_FILE, 1);
5192 
5193  if (!COB_MODULE_PTR->cob_procedure_params[0]) {
5194  return -1;
5195  }
5196  fn = cob_str_from_fld (COB_MODULE_PTR->cob_procedure_params[0]);
5197  ret = unlink (fn);
5198  cob_free (fn);
5199  if (ret) {
5200  return 128;
5201  }
5202  return 0;
5203 }
int cob_sys_file_delete ( unsigned char *  file_name,
unsigned char *  file_type 
)

References __cob_global::cob_call_params, COB_CHK_PARMS, COB_MODULE_PTR, cob_sys_delete_file(), and COB_UNUSED.

5575 {
5576  int ret;
5577 
5578  /* RXW - Type is not yet evaluated */
5579  COB_UNUSED (file_type);
5580 
5581  COB_CHK_PARMS (C$DELETE, 2);
5582 
5583  if (cobglobptr->cob_call_params < 2 ||
5584  !COB_MODULE_PTR->cob_procedure_params[0]) {
5585  return 128;
5586  }
5587  ret = cob_sys_delete_file (file_name);
5588  if (ret < 0) {
5589  ret = 128;
5590  }
5591  return ret;
5592 }
int cob_sys_file_info ( unsigned char *  file_name,
unsigned char *  file_info 
)

References _, COB_BSWAP_32, COB_BSWAP_64, __cob_global::cob_call_params, COB_CHK_PARMS, cob_free(), COB_MODULE_PTR, cob_runtime_error(), cob_stop_run(), cob_str_from_fld(), cob_u64_t, and COB_UNUSED.

5511 {
5512  char *fn;
5513  struct tm *tm;
5514  cob_u64_t sz;
5515  unsigned int dt;
5516  short y;
5517  short d, m, hh, mm, ss;
5518  struct stat st;
5519 
5520  COB_UNUSED (file_name);
5521 
5522  COB_CHK_PARMS (C$FILEINFO, 2);
5523 
5524  if (cobglobptr->cob_call_params < 2 ||
5525  !COB_MODULE_PTR->cob_procedure_params[0]) {
5526  return 128;
5527  }
5528  if (!COB_MODULE_PTR->cob_procedure_params[1]) {
5529  return 128;
5530  }
5531  if (COB_MODULE_PTR->cob_procedure_params[1]->size < 16U) {
5532  cob_runtime_error (_("'C$FILEINFO' - File detail area is too short"));
5533  cob_stop_run (1);
5534  }
5535 
5536  fn = cob_str_from_fld (COB_MODULE_PTR->cob_procedure_params[0]);
5537  if (stat (fn, &st) < 0) {
5538  cob_free (fn);
5539  return 35;
5540  }
5541  cob_free (fn);
5542  sz = (cob_u64_t)st.st_size;
5543  tm = localtime (&st.st_mtime);
5544  d = (short)tm->tm_mday;
5545  m = (short)(tm->tm_mon + 1);
5546  y = (short)(tm->tm_year + 1900);
5547  hh = (short)tm->tm_hour;
5548  mm = (short)tm->tm_min;
5549  /* Leap seconds ? */
5550  if (tm->tm_sec >= 60) {
5551  ss = 59;
5552  } else {
5553  ss = (short)tm->tm_sec;
5554  }
5555 
5556 #ifndef WORDS_BIGENDIAN
5557  sz = COB_BSWAP_64 (sz);
5558 #endif
5559  memcpy (file_info, &sz, (size_t)8);
5560  dt = (y * 10000) + (m * 100) + d;
5561 #ifndef WORDS_BIGENDIAN
5562  dt = COB_BSWAP_32 (dt);
5563 #endif
5564  memcpy (file_info + 8, &dt, (size_t)4);
5565  dt = (hh * 1000000) + (mm * 10000) + (ss * 100);
5566 #ifndef WORDS_BIGENDIAN
5567  dt = COB_BSWAP_32 (dt);
5568 #endif
5569  memcpy (file_info + 12, &dt, (size_t)4);
5570  return 0;
5571 }
int cob_sys_flush_file ( unsigned char *  file_handle)

References COB_CHK_PARMS, and COB_UNUSED.

5175 {
5176  COB_UNUSED (file_handle);
5177 
5178  COB_CHK_PARMS (CBL_FLUSH_FILE, 1);
5179 
5180  return 0;
5181 }
int cob_sys_get_current_dir ( const int  flags,
const int  dir_length,
unsigned char *  dir 
)

References COB_CHK_PARMS, cob_free(), and NULL.

5349 {
5350  char *dirname;
5351  int dir_size;
5352  int has_space;
5353 
5354  COB_CHK_PARMS (CBL_GET_CURRENT_DIR, 3);
5355 
5356  if (dir_length < 1) {
5357  return 128;
5358  }
5359  if (flags) {
5360  return 129;
5361  }
5362  memset (dir, ' ', (size_t)dir_length);
5363  dirname = getcwd (NULL, (size_t)0);
5364  if (dirname == NULL) {
5365  return 128;
5366  }
5367  dir_size = (int) strlen (dirname);
5368  has_space = 0;
5369  if (strchr (dirname, ' ')) {
5370  has_space = 2;
5371  }
5372  if (dir_size + has_space > dir_length) {
5373  cob_free (dirname);
5374  return 128;
5375  }
5376  if (has_space) {
5377  *dir = '"';
5378  memcpy (&dir[1], dirname, (size_t)dir_size);
5379  dir[dir_size + 1] = '"';
5380  } else {
5381  memcpy (dir, dirname, (size_t)dir_size);
5382  }
5383  cob_free (dirname);
5384  return 0;
5385 }
int cob_sys_mkdir ( unsigned char *  dir)

References COB_CHK_PARMS, and cob_sys_create_dir().

5459 {
5460  int ret;
5461 
5462  COB_CHK_PARMS (C$MAKEDIR, 1);
5463 
5464  ret = cob_sys_create_dir (dir);
5465  if (ret < 0) {
5466  ret = 128;
5467  }
5468  return ret;
5469 }
int cob_sys_open_file ( unsigned char *  file_name,
unsigned char *  file_access,
unsigned char *  file_lock,
unsigned char *  file_dev,
unsigned char *  file_handle 
)

References COB_CHK_PARMS, COB_UNUSED, and open_cbl_file().

5048 {
5049  COB_UNUSED (file_lock);
5050  COB_UNUSED (file_dev);
5051 
5052  COB_CHK_PARMS (CBL_OPEN_FILE, 5);
5053 
5054  return open_cbl_file (file_name, file_access, file_handle, 0);
5055 }
int cob_sys_read_file ( unsigned char *  file_handle,
unsigned char *  file_offset,
unsigned char *  file_len,
unsigned char *  flags,
unsigned char *  buf 
)

References COB_BSWAP_32, COB_BSWAP_64, COB_CHK_PARMS, and cob_s64_t.

5088 {
5089  cob_s64_t off;
5090  int fd;
5091  int len;
5092  int rc;
5093  struct stat st;
5094 
5095  COB_CHK_PARMS (CBL_READ_FILE, 5);
5096 
5097  rc = 0;
5098  memcpy (&fd, file_handle, (size_t)4);
5099  memcpy (&off, file_offset, (size_t)8);
5100  memcpy (&len, file_len, (size_t)4);
5101 #ifndef WORDS_BIGENDIAN
5102  off = COB_BSWAP_64 (off);
5103  len = COB_BSWAP_32 (len);
5104 #endif
5105  if (lseek (fd, (off_t)off, SEEK_SET) == (off_t)-1) {
5106  return -1;
5107  }
5108  if (len > 0) {
5109  rc = read (fd, buf, (size_t)len);
5110  if (rc < 0) {
5111  rc = -1;
5112  } else if (rc == 0) {
5113  rc = 10;
5114  } else {
5115  rc = 0;
5116  }
5117  }
5118  if ((*flags & 0x80) != 0) {
5119  if (fstat (fd, &st) < 0) {
5120  return -1;
5121  }
5122  off = st.st_size;
5123 #ifndef WORDS_BIGENDIAN
5124  off = COB_BSWAP_64 (off);
5125 #endif
5126  memcpy (file_offset, &off, (size_t)8);
5127  }
5128  return rc;
5129 }
int cob_sys_rename_file ( unsigned char *  fname1,
unsigned char *  fname2 
)

References COB_CHK_PARMS, cob_free(), COB_MODULE_PTR, cob_str_from_fld(), and COB_UNUSED.

5319 {
5320  char *fn1;
5321  char *fn2;
5322  int ret;
5323 
5324  COB_UNUSED (fname1);
5325  COB_UNUSED (fname2);
5326 
5327  COB_CHK_PARMS (CBL_RENAME_FILE, 2);
5328 
5329  if (!COB_MODULE_PTR->cob_procedure_params[0]) {
5330  return -1;
5331  }
5332  if (!COB_MODULE_PTR->cob_procedure_params[1]) {
5333  return -1;
5334  }
5335  fn1 = cob_str_from_fld (COB_MODULE_PTR->cob_procedure_params[0]);
5336  fn2 = cob_str_from_fld (COB_MODULE_PTR->cob_procedure_params[1]);
5337  ret = rename (fn1, fn2);
5338  cob_free (fn1);
5339  cob_free (fn2);
5340  if (ret) {
5341  return 128;
5342  }
5343  return 0;
5344 }
int cob_sys_write_file ( unsigned char *  file_handle,
unsigned char *  file_offset,
unsigned char *  file_len,
unsigned char *  flags,
unsigned char *  buf 
)

References COB_BSWAP_32, COB_BSWAP_64, COB_CHK_PARMS, cob_s64_t, and COB_UNUSED.

5135 {
5136  cob_s64_t off;
5137  int fd;
5138  int len;
5139  int rc;
5140 
5141  COB_UNUSED (flags);
5142 
5143  COB_CHK_PARMS (CBL_WRITE_FILE, 5);
5144 
5145  memcpy (&fd, file_handle, (size_t)4);
5146  memcpy (&off, file_offset, (size_t)8);
5147  memcpy (&len, file_len, (size_t)4);
5148 #ifndef WORDS_BIGENDIAN
5149  off = COB_BSWAP_64 (off);
5150  len = COB_BSWAP_32 (len);
5151 #endif
5152  if (lseek (fd, (off_t)off, SEEK_SET) == (off_t)-1) {
5153  return -1;
5154  }
5155  rc = write (fd, buf, (size_t)len);
5156  if (rc < 0) {
5157  return 30;
5158  }
5159  return 0;
5160 }
void cob_unlock_file ( cob_file f,
cob_field fnstatus 
)

References cob_file_unlock(), COB_STATUS_00_SUCCESS, and save_status().

4451 {
4452  cob_file_unlock (f);
4453  save_status (f, fnstatus, COB_STATUS_00_SUCCESS);
4454 }
void cob_write ( cob_file f,
cob_field rec,
const int  opt,
cob_field fnstatus,
const unsigned int  check_eop 
)

References cob_file::access_mode, check_eop_status, COB_ACCESS_SEQUENTIAL, cob_get_int(), COB_OPEN_EXTEND, COB_OPEN_I_O, COB_OPEN_OUTPUT, COB_STATUS_44_RECORD_OVERFLOW, COB_STATUS_48_OUTPUT_DENIED, cob_file::flag_read_done, cob_file::open_mode, cob_file::organization, cob_file::record, cob_file::record_max, cob_file::record_min, save_status(), cob_field::size, unlikely, cob_file::variable_record, and cob_fileio_funcs::write.

Referenced by cob_file_sort_giving().

4775 {
4776  f->flag_read_done = 0;
4777 
4778  if (f->access_mode == COB_ACCESS_SEQUENTIAL) {
4779  if (unlikely(f->open_mode != COB_OPEN_OUTPUT &&
4780  f->open_mode != COB_OPEN_EXTEND)) {
4782  return;
4783  }
4784  } else {
4785  if (unlikely(f->open_mode != COB_OPEN_OUTPUT &&
4786  f->open_mode != COB_OPEN_I_O)) {
4788  return;
4789  }
4790  }
4791 
4792  if (f->variable_record) {
4793  f->record->size = (size_t)cob_get_int (f->variable_record);
4794  if (unlikely(f->record->size > rec->size)) {
4795  f->record->size = rec->size;
4796  }
4797  } else {
4798  f->record->size = rec->size;
4799  }
4800 
4801  if (f->record->size < f->record_min || f->record_max < f->record->size) {
4803  return;
4804  }
4805 
4806  check_eop_status = check_eop;
4807  save_status (f, fnstatus,
4808  fileio_funcs[(int)f->organization]->write (f, opt));
4809 }
static int cob_write_block ( struct cobsort hp,
const int  n 
)
static

References cobitem::block_byte, queue_struct::count, file_struct::count, cobsort::destination_file, cobsort::empty, cobsort::file, queue_struct::first, file_struct::fp, cobitem::next, NULL, cobsort::queue, unlikely, and cobsort::w_size.

Referenced by cob_file_sort_process(), and cob_file_sort_submit().

5842 {
5843  struct cobitem *q;
5844  FILE *fp;
5845 
5846  fp = hp->file[hp->destination_file].fp;
5847  for (;;) {
5848  q = hp->queue[n].first;
5849  if (q == NULL) {
5850  break;
5851  }
5852  if (unlikely(fwrite (&(q->block_byte), hp->w_size, (size_t)1, fp) != 1)) {
5853  return 1;
5854  }
5855  hp->queue[n].first = q->next;
5856  q->next = hp->empty;
5857  hp->empty = q;
5858  }
5859  hp->queue[n].count = 0;
5860  hp->file[hp->destination_file].count++;
5861  if (unlikely(putc (1, fp) != 1)) {
5862  return 1;
5863  }
5864  return 0;
5865 }
static int dummy_delete ( cob_file f)
static

References COB_STATUS_91_NOT_AVAILABLE, and COB_UNUSED.

447 {
448  COB_UNUSED (f);
449 
451 }
static int dummy_read ( cob_file f,
cob_field key,
const int  read_opts 
)
static

References COB_STATUS_91_NOT_AVAILABLE, and COB_UNUSED.

464 {
465  COB_UNUSED (f);
466  COB_UNUSED (key);
467  COB_UNUSED (read_opts);
468 
470 }
static int dummy_rnxt_rewrite ( cob_file f,
const int  opt 
)
static

References COB_STATUS_91_NOT_AVAILABLE, and COB_UNUSED.

455 {
456  COB_UNUSED (f);
457  COB_UNUSED (opt);
458 
460 }
static int dummy_start ( cob_file f,
const int  cond,
cob_field key 
)
static

References COB_STATUS_91_NOT_AVAILABLE, and COB_UNUSED.

474 {
475  COB_UNUSED (f);
476  COB_UNUSED (cond);
477  COB_UNUSED (key);
478 
480 }
static size_t file_linage_check ( cob_file f)
static

References cob_get_int(), cob_set_int(), cob_linage::latbot, cob_linage::latfoot, cob_linage::lattop, cob_linage::lin_bot, cob_linage::lin_foot, cob_linage::lin_lines, cob_linage::lin_top, cob_linage::linage, cob_linage::linage_ctr, and cob_file::linorkeyptr.

Referenced by cob_file_open(), and cob_linage_write_opt().

726 {
727  cob_linage *lingptr;
728 
729  lingptr = f->linorkeyptr;
730  lingptr->lin_lines = cob_get_int (lingptr->linage);
731  if (lingptr->lin_lines < 1) {
732  goto linerr;
733  }
734  if (lingptr->latfoot) {
735  lingptr->lin_foot = cob_get_int (lingptr->latfoot);
736  if (lingptr->lin_foot < 1 ||
737  lingptr->lin_foot > lingptr->lin_lines) {
738  goto linerr;
739  }
740  } else {
741  lingptr->lin_foot = 0;
742  }
743  if (lingptr->lattop) {
744  lingptr->lin_top = cob_get_int (lingptr->lattop);
745  if (lingptr->lin_top < 0) {
746  goto linerr;
747  }
748  } else {
749  lingptr->lin_top = 0;
750  }
751  if (lingptr->latbot) {
752  lingptr->lin_bot = cob_get_int (lingptr->latbot);
753  if (lingptr->lin_bot < 0) {
754  goto linerr;
755  }
756  } else {
757  lingptr->lin_bot = 0;
758  }
759  return 0;
760 linerr:
761  cob_set_int (lingptr->linage_ctr, 0);
762  return 1;
763 }
static int indexed_close ( cob_file f,
const int  opt 
)
static

References cob_free(), COB_STATUS_00_SUCCESS, COB_STATUS_91_NOT_AVAILABLE, COB_UNUSED, cob_file::file, cob_file::nkeys, NULL, and p.

3254 {
3255 #ifdef WITH_INDEX_EXTFH
3256 
3257  return extfh_indexed_close (f, opt);
3258 
3259 #elif defined(WITH_ANY_ISAM)
3260 
3261  struct indexfile *fh;
3262 
3263  COB_UNUSED (opt);
3264 
3265  fh = f->file;
3266  if (fh == NULL) {
3267  return COB_STATUS_00_SUCCESS;
3268  }
3269  if (fh->isfd >= 0) {
3270  isfullclose (fh->isfd);
3271  }
3272  freefh (fh);
3273  f->file = NULL;
3274  return COB_STATUS_00_SUCCESS;
3275 
3276 #elif defined(WITH_DB)
3277 
3278  struct indexed_file *p;
3279  int i;
3280 
3281  COB_UNUSED (opt);
3282 
3283  p = f->file;
3284  /* Close DB's */
3285  for (i = 0; i < (int)f->nkeys; ++i) {
3286  if (p->cursor[i]) {
3287  p->cursor[i]->c_close (p->cursor[i]);
3288  }
3289  }
3290  for (i = (int)f->nkeys - 1; i >= 0; --i) {
3291  if (p->db[i]) {
3292  DB_CLOSE (p->db[i]);
3293  }
3294  cob_free (p->last_readkey[i]);
3295  cob_free (p->last_readkey[f->nkeys + i]);
3296  }
3297 
3298  if (p->last_key) {
3299  cob_free (p->last_key);
3300  }
3301  cob_free (p->temp_key);
3302  cob_free (p->db);
3303  cob_free (p->last_readkey);
3304  cob_free (p->last_dupno);
3305  cob_free (p->rewrite_sec_key);
3306  cob_free (p->filename);
3307  cob_free (p->cursor);
3308  if (bdb_env != NULL) {
3309  unlock_record (f);
3310  bdb_env->lock_put (bdb_env, &p->bdb_file_lock);
3311  bdb_env->lock_id_free (bdb_env, p->bdb_lock_id);
3312  }
3313  cob_free (p);
3314 
3315  return COB_STATUS_00_SUCCESS;
3316 
3317 #else
3318 
3320 
3321 #endif
3322 }
static int indexed_delete ( cob_file f)
static

References COB_STATUS_00_SUCCESS, COB_STATUS_21_KEY_INVALID, COB_STATUS_49_I_O_DENIED, COB_STATUS_91_NOT_AVAILABLE, cob_field::data, cob_file::file, cob_file::flag_nonexistent, and cob_file::record.

4166 {
4167 #ifdef WITH_INDEX_EXTFH
4168 
4169  return extfh_indexed_delete (f);
4170 
4171 #elif defined(WITH_ANY_ISAM)
4172 
4173  struct indexfile *fh;
4174  int ret;
4175 
4176  fh = f->file;
4177  ret = COB_STATUS_00_SUCCESS;
4178  if (f->flag_nonexistent) {
4179  return COB_STATUS_49_I_O_DENIED;
4180  }
4181  if (fh->curkey == -1) {
4182  /* Switch to primary index */
4183  isstart (fh->isfd, &fh->key[0], 0,
4184  (void *)f->record->data, ISEQUAL);
4185  fh->curkey = 0;
4186  fh->readdir = ISNEXT;
4187  } else {
4188  savefileposition (f);
4189  if (fh->curkey != 0) {
4190  /* Switch to primary index */
4191  isstart (fh->isfd, &fh->key[0], 0,
4192  (void *)f->record->data, ISEQUAL);
4193  }
4194  }
4195  if (isread (fh->isfd, (void *)f->record->data, ISEQUAL | ISLOCK)) {
4196  ret = fisretsts (COB_STATUS_21_KEY_INVALID);
4197  } else if (isdelete (fh->isfd, (void *)f->record->data)) {
4198  ret = fisretsts (COB_STATUS_49_I_O_DENIED);
4199  }
4200  restorefileposition (f);
4201  return ret;
4202 
4203 #elif defined(WITH_DB)
4204 
4205  if (f->flag_nonexistent) {
4206  return COB_STATUS_49_I_O_DENIED;
4207  }
4208  return indexed_delete_internal (f, 0);
4209 
4210 #else
4211 
4213 #endif
4214 }
static void indexed_file_delete ( cob_file f,
const char *  filename 
)
static

References COB_FILE_MAX, COB_UNUSED, file_open_buff, and cob_file::nkeys.

Referenced by cob_delete_file().

2720 {
2721 #ifdef WITH_ANY_ISAM
2722  COB_UNUSED (f);
2723 
2724  snprintf (file_open_buff, (size_t)COB_FILE_MAX, "%s.idx", filename);
2725  unlink (file_open_buff);
2726  snprintf (file_open_buff, (size_t)COB_FILE_MAX, "%s.dat", filename);
2727  unlink (file_open_buff);
2728 #elif defined(WITH_DB)
2729  size_t i;
2730 
2731  for (i = 0; i < f->nkeys; ++i) {
2732  if (i == 0) {
2733  snprintf (file_open_buff, (size_t)COB_FILE_MAX, "%s",
2734  filename);
2735  } else {
2736  snprintf (file_open_buff, (size_t)COB_FILE_MAX, "%s.%d",
2737  filename, (int)i);
2738  }
2739  unlink (file_open_buff);
2740  }
2741 #endif
2742 }
static int indexed_open ( cob_file f,
char *  filename,
const int  mode,
const int  sharing 
)
static

References cob_chk_file_mapping(), COB_FILE_EXCLUSIVE, COB_FILE_MAX, COB_FILE_MODE, cob_free(), COB_LOCK_AUTOMATIC, cob_malloc(), COB_NOT_CONFIGURED, COB_OPEN_EXTEND, COB_OPEN_I_O, COB_OPEN_INPUT, COB_OPEN_OUTPUT, COB_STATUS_00_SUCCESS, COB_STATUS_05_SUCCESS_OPTIONAL, COB_STATUS_30_PERMANENT_ERROR, COB_STATUS_35_NOT_EXISTS, COB_STATUS_37_PERMISSION_DENIED, COB_STATUS_39_CONFLICT_ATTRIBUTE, COB_STATUS_61_FILE_SHARING, COB_STATUS_91_NOT_AVAILABLE, cob_strdup(), cob_u32_t, COB_UNUSED, F_OK, cob_file_key::field, cob_file::file, file_open_buff, cob_file_key::flag, cob_file::flag_begin_of_file, cob_file::flag_end_of_file, cob_file::flag_nonexistent, cob_file::flag_optional, cob_file::keys, cob_file::lock_mode, cob_file::nkeys, NULL, cob_file_key::offset, cob_file::open_mode, p, R_OK, cob_file::record_max, cob_file::record_min, runtime_buffer, cob_field::size, and W_OK.

2748 {
2749  /* Note filename points to file_open_name */
2750  /* cob_chk_file_mapping manipulates file_open_name directly */
2751 
2752 #ifdef WITH_INDEX_EXTFH
2753  int ret;
2754 
2755  ret = extfh_indexed_locate (f, filename);
2756  switch (ret) {
2757  case COB_NOT_CONFIGURED:
2759  if (access (filename, F_OK) && errno == ENOENT) {
2760  if (mode != COB_OPEN_OUTPUT && f->flag_optional == 0) {
2761  return COB_STATUS_35_NOT_EXISTS;
2762  }
2763  }
2764  break;
2765  case COB_STATUS_00_SUCCESS:
2766  break;
2767  default:
2768  return ret;
2769  }
2770  ret = extfh_indexed_open (f, filename, mode, sharing);
2771  switch (ret) {
2772  case COB_STATUS_00_SUCCESS:
2773  f->open_mode = mode;
2774  break;
2776  if (f->flag_optional) {
2777  f->open_mode = mode;
2778  f->flag_nonexistent = 1;
2779  f->flag_end_of_file = 1;
2780  f->flag_begin_of_file = 1;
2782  }
2783  break;
2784  }
2785  return ret;
2786 
2787 #elif defined(WITH_ANY_ISAM)
2788 
2789  struct indexfile *fh;
2790  size_t k;
2791  int ret;
2792  int omode;
2793  int lmode;
2794  int vmode;
2795  int dobld;
2796  int isfd;
2797  int checkvalue;
2798  struct dictinfo di; /* Defined in (c|d|vb)isam.h */
2799 
2800  COB_UNUSED (sharing);
2801 
2803 
2804  if (mode == COB_OPEN_INPUT) {
2805  checkvalue = R_OK;
2806  } else {
2807  checkvalue = R_OK | W_OK;
2808  }
2809 
2810  snprintf (file_open_buff, (size_t)COB_FILE_MAX, "%s.idx", filename);
2811  errno = 0;
2812  if (access (file_open_buff, checkvalue)) {
2813  if (!(errno == ENOENT &&
2814  (mode == COB_OPEN_OUTPUT || f->flag_optional == 1))) {
2815  switch (errno) {
2816  case ENOENT:
2817  return COB_STATUS_35_NOT_EXISTS;
2818  case EACCES:
2820  default:
2822  }
2823  }
2824  }
2825 
2826  snprintf (file_open_buff, (size_t)COB_FILE_MAX, "%s.dat", filename);
2827  errno = 0;
2828  if (access (file_open_buff, checkvalue)) {
2829  if (!(errno == ENOENT &&
2830  (mode == COB_OPEN_OUTPUT || f->flag_optional == 1))) {
2831  switch (errno) {
2832  case ENOENT:
2833  return COB_STATUS_35_NOT_EXISTS;
2834  case EACCES:
2836  default:
2838  }
2839  }
2840  }
2841 
2842  ret = COB_STATUS_00_SUCCESS;
2843  omode = 0;
2844  lmode = 0;
2845  vmode = 0;
2846  dobld = 0;
2847  isfd = -1;
2848 #ifdef ISVARLEN
2849  if (f->record_min != f->record_max) {
2850  vmode = ISVARLEN;
2851  isreclen = f->record_min;
2852  }
2853 #endif
2854  if (!f->lock_mode) {
2855  if (mode != COB_OPEN_INPUT) {
2856  lmode = ISEXCLLOCK;
2857  } else {
2858  lmode = ISMANULOCK;
2859  }
2860  } else if ((f->lock_mode & COB_FILE_EXCLUSIVE)) {
2861  lmode = ISEXCLLOCK;
2862  } else if ((f->lock_mode & COB_LOCK_AUTOMATIC) && mode != COB_OPEN_INPUT) {
2863  lmode = ISAUTOLOCK;
2864  } else {
2865  lmode = ISMANULOCK;
2866  }
2867  switch (mode) {
2868  case COB_OPEN_INPUT:
2869  omode = ISINPUT;
2870  break;
2871  case COB_OPEN_OUTPUT:
2872  lmode = ISEXCLLOCK;
2873  omode = ISOUTPUT;
2874  iserrno = 0;
2875  isfd = isopen ((void *)filename, ISINPUT | ISEXCLLOCK | vmode);
2876  if (iserrno == EFLOCKED) {
2878  } else {
2879  if (isfd >= 0) {
2880  isfullclose (isfd);
2881  }
2882  iserase ((void *)filename);
2883  }
2884  dobld = 1;
2885  break;
2886  case COB_OPEN_I_O:
2887  omode = ISINOUT;
2888  break;
2889  case COB_OPEN_EXTEND:
2890  lmode = ISEXCLLOCK;
2891  omode = ISINOUT;
2892  break;
2893  }
2894  fh = cob_malloc (sizeof(struct indexfile) +
2895  ((sizeof (struct keydesc)) * (f->nkeys + 1)));
2896  /* Copy index information */
2897  for (k = 0; k < f->nkeys; ++k) {
2898  fh->key[k].k_flags = f->keys[k].flag ? ISDUPS : ISNODUPS;
2899  fh->key[k].k_nparts = 1; /* Single field key */
2900  fh->key[k].k_start = f->keys[k].offset;
2901  fh->key[k].k_leng = f->keys[k].field->size;
2902  if (fh->lenkey < fh->key[k].k_leng) {
2903  fh->lenkey = fh->key[k].k_leng;
2904  }
2905  fh->key[k].k_type = CHARTYPE;
2906  }
2907  iserrno = 0;
2908  fh->lmode = 0;
2909  if (dobld) {
2910 dobuild:
2911  isfd = isbuild ((void *)filename, (int)f->record_max, &fh->key[0],
2912  vmode | ISINOUT | ISEXCLLOCK);
2913  } else {
2914  if (lmode == ISAUTOLOCK) {
2915  fh->lmode = ISLOCK;
2916  lmode = ISMANULOCK;
2917  }
2918  isfd = isopen ((void *)filename, omode | lmode | vmode);
2919  if (isfd < 0) {
2920  if (f->flag_optional) {
2921  if (mode == COB_OPEN_EXTEND ||
2922  mode == COB_OPEN_I_O) {
2923  dobld = 1;
2925  goto dobuild;
2926  }
2927 #if 0 /* RXWRXW - freefh */
2928  fh->isfd = isfd;
2929  fh->filename = cob_strdup (filename);
2930  /* Active index is unknown at this time */
2931  fh->curkey = -1;
2932  f->file = fh;
2933 #endif
2934  freefh (fh);
2935  f->open_mode = mode;
2936  f->flag_end_of_file = 1;
2937  f->flag_begin_of_file = 1;
2938  if (f->flag_nonexistent) {
2939  return COB_STATUS_00_SUCCESS;
2940  }
2941  f->flag_nonexistent = 1;
2943  }
2944  } else {
2945  memset(&di, 0, sizeof(di));
2946  isindexinfo (isfd, (void *)&di, 0);
2947  /* Mask off ISVARLEN */
2948  fh->nkeys = di.di_nkeys & 0x7F;
2949  if (fh->nkeys != f->nkeys) {
2951  }
2952  for (k = 0; k < fh->nkeys && !ret; ++k) {
2953  memset (&fh->key[k], 0, sizeof(struct keydesc));
2954  isindexinfo (isfd, &fh->key[k], (int)(k+1));
2955  if (fh->lenkey < fh->key[k].k_leng) {
2956  fh->lenkey = fh->key[k].k_leng;
2957  }
2958  /* Verify that COBOL keys match real ISAM keys */
2959  if (f->keys[k].flag) {
2960  if (!(fh->key[k].k_flags & ISDUPS)) {
2962  }
2963  } else {
2964  if (fh->key[k].k_flags & ISDUPS) {
2966  }
2967  }
2968  if (fh->key[k].k_nparts != 1 ||
2969  (int)fh->key[k].k_start != (int)f->keys[k].offset ||
2970  (int)fh->key[k].k_leng != (int)f->keys[k].field->size) {
2972  }
2973  }
2974  }
2975  }
2976  if (isfd < 0) {
2977  ret = fisretsts (COB_STATUS_30_PERMANENT_ERROR);
2978  freefh (fh);
2979  return ret;
2980  }
2981  if (ret > 9) {
2982  isfullclose (isfd);
2983  freefh (fh);
2984  return ret;
2985  }
2986  if (dobld) {
2987  for (k = 1; k < f->nkeys; ++k) {
2988  iserrno = 0;
2989  if (isaddindex (isfd, &fh->key[k])) {
2991  }
2992  }
2993  if (ret > 9) {
2994  isfullclose (isfd);
2995  iserase ((void *)filename);
2996  freefh (fh);
2997  return ret;
2998  }
2999  }
3000  f->file = fh;
3001  f->open_mode = mode;
3002  fh->isfd = isfd;
3003  fh->filename = cob_strdup (filename);
3004  fh->savekey = cob_malloc ((size_t)(fh->lenkey + 1));
3005  fh->recwrk = cob_malloc ((size_t)(f->record_max + 1));
3006  /* Active index is unknown at this time */
3007  fh->curkey = -1;
3008  f->flag_nonexistent = 0;
3009  f->flag_end_of_file = 0;
3010  f->flag_begin_of_file = 0;
3011  return ret;
3012 
3013 #elif defined(WITH_DB)
3014 
3015  struct indexed_file *p;
3016  size_t i;
3017  size_t j;
3018  size_t maxsize;
3019  db_lockmode_t lock_mode;
3020  int handle_created;
3021  cob_u32_t flags = 0;
3022  int ret = 0;
3023  int nonexistent;
3024 #if 0 /* RXWRXW - Access check BDB Human */
3025  int checkvalue;
3026 #endif
3027 
3028  COB_UNUSED (sharing);
3029 
3031 
3032 #if 0 /* RXWRXW - Access check BDB Human */
3033  if (mode == COB_OPEN_INPUT) {
3034  checkvalue = R_OK;
3035  } else {
3036  checkvalue = R_OK | W_OK;
3037  }
3038 #endif
3039 
3040  nonexistent = 0;
3041  if (bdb_nofile (filename)) {
3042  nonexistent = 1;
3043  if (mode != COB_OPEN_OUTPUT && f->flag_optional == 0) {
3044  return COB_STATUS_35_NOT_EXISTS;
3045  }
3046  }
3047 
3048  p = cob_malloc (sizeof (struct indexed_file));
3049  if (bdb_env != NULL) {
3050  if (mode == COB_OPEN_OUTPUT || mode == COB_OPEN_EXTEND ||
3051  (f->lock_mode & COB_FILE_EXCLUSIVE) ||
3052  (mode == COB_OPEN_I_O && !f->lock_mode)) {
3053  lock_mode = DB_LOCK_WRITE;
3054  } else {
3055  lock_mode = DB_LOCK_READ;
3056  }
3057  p->key.size = (cob_dbtsize_t) strlen (filename);
3058  p->key.data = filename;
3059  ret = bdb_env->lock_get (bdb_env, bdb_lock_id, DB_LOCK_NOWAIT,
3060  &p->key, lock_mode, &p->bdb_file_lock);
3061  if (ret) {
3062  cob_free (p);
3063  if (ret == DB_LOCK_NOTGRANTED) {
3065  } else {
3067  }
3068  }
3069  }
3070 
3071  switch (mode) {
3072  case COB_OPEN_INPUT:
3073  flags |= DB_RDONLY;
3074  break;
3075  case COB_OPEN_OUTPUT:
3076  flags |= DB_CREATE;
3077  break;
3078  case COB_OPEN_I_O:
3079  case COB_OPEN_EXTEND:
3080  flags |= DB_CREATE;
3081  break;
3082  }
3083 
3084  p->db = cob_malloc (sizeof (DB *) * f->nkeys);
3085  p->cursor = cob_malloc (sizeof (DBC *) * f->nkeys);
3086  p->filenamelen = (int) strlen (filename);
3087  p->last_readkey = cob_malloc (sizeof (unsigned char *) * 2 * f->nkeys);
3088  p->last_dupno = cob_malloc (sizeof (unsigned int) * f->nkeys);
3089  p->rewrite_sec_key = cob_malloc (sizeof (int) * f->nkeys);
3090  maxsize = 0;
3091  for (i = 0; i < f->nkeys; ++i) {
3092  if (f->keys[i].field->size > maxsize) {
3093  maxsize = f->keys[i].field->size;
3094  }
3095  }
3096  for (i = 0; i < f->nkeys; ++i) {
3097  /* File name */
3099  if (i == 0) {
3100  snprintf (runtime_buffer, (size_t)COB_FILE_MAX, "%s",
3101  filename);
3102  } else {
3103  snprintf (runtime_buffer, (size_t)COB_FILE_MAX, "%s.%d",
3104  filename, (int)i);
3105  }
3106 #if 0 /* RXWRXW - Access check BDB Human */
3107  ret = access (runtime_buffer, checkvalue);
3108  if (ret != 0) {
3109  if (errno == ENOENT &&
3110  (mode == COB_OPEN_OUTPUT || f->flag_optional == 1)) {
3111  ret = 0;
3112  /* Check here if the directory exists ? */
3113 #if 0 /* RXWRXW - Check dir */
3114  if (!directory exists) {
3115  ret = ENOENT;
3116  } else {
3117  ret = 0;
3118  }
3119 #endif
3120  } else {
3121  ret = errno;
3122  }
3123  if (ret != 0) {
3124  switch (ret) {
3125  case ENOENT:
3127  break;
3128  case EACCES:
3130  break;
3131  default:
3133  break;
3134  }
3135  /* FIXME: BDB cleanup is missing here */
3136  return ret;
3137  }
3138  }
3139 #endif
3140 
3141  /* btree info */
3142  ret = db_create (&p->db[i], bdb_env, 0);
3143  if (!ret) {
3144  handle_created = 1;
3145  if (mode == COB_OPEN_OUTPUT) {
3146  if (bdb_env) {
3147  bdb_env->dbremove (bdb_env, NULL, runtime_buffer, NULL, 0);
3148  } else {
3149  p->db[i]->remove (p->db[i], runtime_buffer, NULL, 0);
3150  ret = db_create (&p->db[i], bdb_env, 0);
3151  }
3152  }
3153  if (!ret) {
3154  if (f->keys[i].flag) {
3155  p->db[i]->set_flags (p->db[i], DB_DUP);
3156  }
3157  }
3158  } else {
3159  handle_created = 0;
3160  }
3161 
3162  /* Open db */
3163  if (!ret) {
3164  ret = p->db[i]->open (p->db[i], NULL, runtime_buffer, NULL,
3165  DB_BTREE, flags, COB_FILE_MODE);
3166  }
3167  if (ret) {
3168  for (j = 0; j < i; ++j) {
3169  DB_CLOSE (p->db[j]);
3170  }
3171  if (handle_created) {
3172  DB_CLOSE (p->db[i]);
3173  }
3174  cob_free (p->db);
3175  cob_free (p->last_readkey);
3176  cob_free (p->last_dupno);
3177  cob_free (p->cursor);
3178  if (bdb_env != NULL) {
3179  bdb_env->lock_put (bdb_env, &p->bdb_file_lock);
3180  }
3181  cob_free (p);
3182  switch (ret) {
3183  case DB_LOCK_NOTGRANTED:
3185  case ENOENT:
3186  if (mode == COB_OPEN_EXTEND ||
3187  mode == COB_OPEN_OUTPUT) {
3189  }
3190  if (f->flag_optional) {
3191  if (mode == COB_OPEN_I_O) {
3193  }
3194  f->open_mode = mode;
3195  f->flag_nonexistent = 1;
3196  f->flag_end_of_file = 1;
3197  f->flag_begin_of_file = 1;
3198  /* RXWRXW - Check directory exists? */
3200  }
3201  return COB_STATUS_35_NOT_EXISTS;
3202  default:
3204  }
3205 
3206  }
3207 
3208  p->last_readkey[i] = cob_malloc (maxsize);
3209  p->last_readkey[f->nkeys + i] = cob_malloc (maxsize);
3210  }
3211 
3212  p->temp_key = cob_malloc (maxsize + sizeof(unsigned int));
3213  f->file = p;
3214  p->key_index = 0;
3215  p->last_key = NULL;
3216 
3217  memset ((void *)&p->key, 0, sizeof (DBT));
3218  memset ((void *)&p->data, 0, sizeof (DBT));
3219  p->filename = cob_malloc (strlen (filename) + 1);
3220  strcpy (p->filename, filename);
3221  p->write_cursor_open = 0;
3222  p->record_locked = 0;
3223  if (bdb_env != NULL) {
3224  bdb_env->lock_id (bdb_env, &p->bdb_lock_id);
3225  }
3226 
3227  DBT_SET (p->key, f->keys[0].field);
3228  p->db[0]->cursor (p->db[0], NULL, &p->cursor[0], 0);
3229  ret = DB_SEQ (p->cursor[0], DB_FIRST);
3230  p->cursor[0]->c_close (p->cursor[0]);
3231  p->cursor[0] = NULL;
3232  if (!ret) {
3233  memcpy (p->last_readkey[0], p->key.data, (size_t)p->key.size);
3234  } else {
3235  p->data.data = NULL;
3236  }
3237 
3238  f->open_mode = mode;
3239  if (f->flag_optional && nonexistent) {
3241  }
3242  return 0;
3243 
3244 #else
3245 
3247 #endif
3248 }
static int indexed_read ( cob_file f,
cob_field key,
const int  read_opts 
)
static

References COB_EQ, COB_FILE_EXCLUSIVE, COB_LOCK_AUTOMATIC, COB_LOCK_MULTIPLE, COB_OPEN_I_O, COB_OPEN_INPUT, COB_READ_LOCK, COB_READ_NO_LOCK, COB_READ_WAIT_LOCK, COB_STATUS_00_SUCCESS, COB_STATUS_21_KEY_INVALID, COB_STATUS_23_KEY_NOT_EXISTS, COB_STATUS_91_NOT_AVAILABLE, cob_field::data, cob_file_key::field, cob_file::file, cob_file::flag_begin_of_file, cob_file::flag_end_of_file, cob_file::flag_first_read, cob_file::flag_nonexistent, cob_file::flag_read_done, cob_file::keys, cob_file::lock_mode, cob_file::nkeys, NULL, cob_file::open_mode, p, cob_file::record, cob_file::record_max, cob_file::record_min, cob_field::size, and unlikely.

3440 {
3441 #ifdef WITH_INDEX_EXTFH
3442 
3443  return extfh_indexed_read (f, key, read_opts);
3444 
3445 #elif defined(WITH_ANY_ISAM)
3446 
3447  struct indexfile *fh;
3448  size_t k;
3449  int ret;
3450  int lmode;
3451 
3452  fh = f->file;
3453  fh->eofpending = 0;
3454  fh->startiscur = 0;
3455  fh->wrkhasrec = 0;
3456  if (f->flag_nonexistent) {
3458  }
3459  for (k = 0; k < f->nkeys; ++k) {
3460  if (f->keys[k].field->data == key->data) {
3461  break;
3462  }
3463  }
3464  if (fh->curkey != (int)k) {
3465  /* Switch to this index */
3466  isstart (fh->isfd, &fh->key[k], 0,
3467  (void *)f->record->data, ISEQUAL);
3468  fh->curkey = k;
3469  fh->wrkhasrec = 0;
3470  }
3471  fh->startcond = -1;
3472  lmode = 0;
3473  if (read_opts & COB_READ_LOCK) {
3474  lmode = ISLOCK;
3475  } else if (read_opts & COB_READ_WAIT_LOCK) {
3476  lmode = ISLCKW;
3477  } else if ((f->lock_mode & COB_LOCK_AUTOMATIC)) {
3478  if (f->open_mode != COB_OPEN_INPUT) {
3479  if (!(read_opts & COB_READ_IGNORE_LOCK)) {
3480  lmode = ISLOCK;
3481  }
3482  }
3483  }
3484 #ifdef ISSKIPLOCK
3485  if (read_opts & COB_READ_IGNORE_LOCK) {
3486  lmode = ISSKIPLOCK;
3487  }
3488 #endif
3489  if ((fh->lmode & ISLOCK) && !(f->lock_mode & COB_LOCK_MULTIPLE)) {
3490  isrelease (fh->isfd);
3491  }
3492  iserrno = 0;
3493  fh->readdir = -1;
3494  ret = COB_STATUS_00_SUCCESS;
3495  if (isread (fh->isfd, (void *)f->record->data, ISEQUAL | lmode)) {
3496  ret = fisretsts (COB_STATUS_21_KEY_INVALID);
3497  }
3498  if (unlikely(ret != 0)) {
3499  memset (fh->savekey, 0, (size_t)fh->key[0].k_leng);
3500  fh->recnum = 0;
3501  fh->readdone = 0;
3502  return ret;
3503  }
3504  f->flag_first_read = 0;
3505  f->flag_read_done = 1;
3506  fh->readdone = 1;
3507  f->flag_end_of_file = 0;
3508  f->flag_begin_of_file = 0;
3509  memcpy (fh->savekey, f->record->data + fh->key[0].k_start,
3510  (size_t)fh->key[0].k_leng);
3511  fh->recnum = isrecnum;
3512 #ifdef ISVARLEN
3513  if (f->record_min != f->record_max) {
3514  f->record->size = isreclen;
3515  }
3516 #endif
3517  return 0;
3518 
3519 #elif defined(WITH_DB)
3520 
3521  struct indexed_file *p;
3522  int ret;
3523  int bdb_opts;
3524  int test_lock;
3525 
3526  p = f->file;
3527  test_lock = 0;
3528  bdb_opts = read_opts;
3529  if (bdb_env != NULL) {
3530  if (f->open_mode != COB_OPEN_I_O ||
3531  (f->lock_mode & COB_FILE_EXCLUSIVE)) {
3532  bdb_opts &= ~COB_READ_LOCK;
3533  } else if ((f->lock_mode & COB_LOCK_AUTOMATIC) &&
3534  !(bdb_opts & COB_READ_NO_LOCK)) {
3535  bdb_opts |= COB_READ_LOCK;
3536  }
3537  unlock_record (f);
3538  test_lock = 1;
3539  } else {
3540  bdb_opts &= ~COB_READ_LOCK;
3541  }
3542 
3543  ret = indexed_start_internal (f, COB_EQ, key, bdb_opts, test_lock);
3544  if (ret != COB_STATUS_00_SUCCESS) {
3545  return ret;
3546  }
3547 
3548  f->record->size = p->data.size;
3549  memcpy (f->record->data, p->data.data, (size_t)p->data.size);
3550 
3551  return COB_STATUS_00_SUCCESS;
3552 
3553 #else
3554 
3556 #endif
3557 }
static int indexed_read_next ( cob_file f,
const int  read_opts 
)
static

References COB_FI, COB_FILE_EXCLUSIVE, COB_GE, COB_GT, COB_LA, COB_LE, COB_LOCK_AUTOMATIC, COB_LOCK_MULTIPLE, COB_LT, COB_OPEN_I_O, COB_OPEN_INPUT, COB_READ_FIRST, COB_READ_LAST, COB_READ_LOCK, COB_READ_MASK, COB_READ_NEXT, COB_READ_NO_LOCK, COB_READ_PREVIOUS, COB_READ_WAIT_LOCK, COB_STATUS_00_SUCCESS, COB_STATUS_02_SUCCESS_DUPLICATE, COB_STATUS_10_END_OF_FILE, COB_STATUS_23_KEY_NOT_EXISTS, COB_STATUS_51_RECORD_LOCKED, COB_STATUS_91_NOT_AVAILABLE, cob_u32_t, cob_u8_ptr, cob_field::data, cob_file_key::field, cob_file::file, cob_file_key::flag, cob_file::flag_begin_of_file, cob_file::flag_end_of_file, cob_file::flag_first_read, cob_file::flag_nonexistent, cob_file::flag_read_done, cob_file::keys, cob_file::lock_mode, cob_file::nkeys, NULL, cob_file::open_mode, p, cob_file::record, cob_file::record_max, cob_file::record_min, cob_field::size, and unlikely.

3563 {
3564 #ifdef WITH_INDEX_EXTFH
3565 
3566  return extfh_indexed_read_next (f, read_opts);
3567 
3568 #elif defined(WITH_ANY_ISAM)
3569 
3570  struct indexfile *fh;
3571  int ret;
3572  int lmode;
3573  int domoveback;
3574 
3575  fh = f->file;
3576  ret = COB_STATUS_00_SUCCESS;
3577  lmode = 0;
3578 
3579  if (f->flag_nonexistent) {
3580  if (f->flag_first_read == 0) {
3582  }
3583  f->flag_first_read = 0;
3585  }
3586 
3587  if (fh->curkey == -1) {
3588  /* Switch to primary index */
3589  isstart (fh->isfd, &fh->key[0], 0, NULL, ISFIRST);
3590  fh->curkey = 0;
3591  fh->readdir = ISNEXT;
3592  fh->startcond = -1;
3593  fh->startiscur = 0;
3594  fh->wrkhasrec = 0;
3595  }
3596  if (read_opts & COB_READ_LOCK) {
3597  lmode = ISLOCK;
3598  } else if (read_opts & COB_READ_WAIT_LOCK) {
3599  lmode = ISLCKW;
3600  } else if ((f->lock_mode & COB_LOCK_AUTOMATIC) &&
3601  f->open_mode != COB_OPEN_INPUT) {
3602  if (!(read_opts & COB_READ_IGNORE_LOCK)) {
3603  lmode = ISLOCK;
3604  }
3605  }
3606 #ifdef ISSKIPLOCK
3607  if (read_opts & COB_READ_IGNORE_LOCK) {
3608  lmode |= ISSKIPLOCK;
3609  }
3610 #endif
3611  if ((fh->lmode & ISLOCK) && !(f->lock_mode & COB_LOCK_MULTIPLE)) {
3612  isrelease (fh->isfd);
3613  }
3614  iserrno = 0;
3615  switch (read_opts & COB_READ_MASK) {
3616  case COB_READ_NEXT:
3617  fh->readdir = ISNEXT;
3618  if (fh->eofpending == ISNEXT) {
3619  fh->eofpending = 0;
3620  fh->wrkhasrec = 0;
3622  }
3623  if (fh->startiscur) {
3624  if (fh->startcond == COB_LA) {
3625  if (isread (fh->isfd, (void *)f->record->data, ISLAST | lmode)) {
3626  ret = fisretsts (COB_STATUS_10_END_OF_FILE);
3627  }
3628  } else if (fh->startcond == COB_FI) {
3629  if (isread (fh->isfd, (void *)f->record->data, ISFIRST | lmode)) {
3630  ret = fisretsts (COB_STATUS_10_END_OF_FILE);
3631  }
3632  } else if (isread (fh->isfd, (void *)f->record->data, ISCURR)) {
3633  ret = fisretsts (COB_STATUS_10_END_OF_FILE);
3634  } else {
3635  switch (fh->startcond) {
3636  case COB_GE:
3637  domoveback = 0;
3638  while (iserrno == 0
3639  && memcmp (f->record->data + fh->key[fh->curkey].k_start, fh->savekey, (size_t)fh->key[fh->curkey].k_leng) == 0) {
3640  isread (fh->isfd, (void *)f->record->data, ISPREV);
3641  domoveback = 1;
3642  }
3643  if (domoveback) {
3644  isread (fh->isfd, (void *)f->record->data, iserrno == 0 ? ISNEXT : ISFIRST);
3645  }
3646  break;
3647  case COB_LE:
3648  domoveback = 0;
3649  while (iserrno == 0
3650  && memcmp (f->record->data + fh->key[fh->curkey].k_start, fh->savekey, (size_t)fh->key[fh->curkey].k_leng) == 0) {
3651  isread (fh->isfd, (void *)f->record->data, ISNEXT);
3652  domoveback = 1;
3653  }
3654  if (domoveback) {
3655  isread (fh->isfd, (void *)f->record->data, iserrno == 0 ? ISPREV : ISLAST);
3656  }
3657  break;
3658  case COB_LT:
3659  while (iserrno == 0
3660  && memcmp (f->record->data + fh->key[fh->curkey].k_start, fh->savekey, (size_t)fh->key[fh->curkey].k_leng) >= 0) {
3661  isread (fh->isfd, (void *)f->record->data, ISPREV);
3662  }
3663  break;
3664  case COB_GT:
3665  while (iserrno == 0
3666  && memcmp (f->record->data + fh->key[fh->curkey].k_start, fh->savekey, (size_t)fh->key[fh->curkey].k_leng) <= 0) {
3667  isread (fh->isfd, (void *)f->record->data, ISNEXT);
3668  }
3669  break;
3670  }
3671  if (isread (fh->isfd, (void *)f->record->data, ISCURR | lmode)) {
3672  ret = fisretsts (COB_STATUS_10_END_OF_FILE);
3673  }
3674  }
3675  fh->startcond = -1;
3676  fh->startiscur = 0;
3677  } else if (fh->wrkhasrec == ISNEXT) {
3678  memcpy (f->record->data, fh->recwrk, f->record_max);
3679  if (fh->lmode & ISLOCK) {
3680  /* Now lock 'peek ahead' record */
3681  if (isread (fh->isfd, (void *)f->record->data,
3682  ISCURR | fh->lmode)) {
3683  ret = fisretsts (COB_STATUS_10_END_OF_FILE);
3684  }
3685  }
3686  } else {
3687  if (fh->wrkhasrec == ISPREV) {
3688  isread (fh->isfd, (void *)f->record->data, ISNEXT);
3689  fh->wrkhasrec = 0;
3690  }
3691  if (isread (fh->isfd, (void *)f->record->data, ISNEXT | lmode)) {
3692  ret = fisretsts (COB_STATUS_10_END_OF_FILE);
3693  }
3694  }
3695  break;
3696  case COB_READ_PREVIOUS:
3697  fh->readdir = ISPREV;
3698  if (fh->eofpending == ISPREV) {
3699  fh->eofpending = 0;
3700  fh->wrkhasrec = 0;
3702  }
3703  if (fh->startiscur) {
3704  if (fh->startcond == COB_FI) {
3705  if (isread (fh->isfd, (void *)f->record->data, ISFIRST | lmode)) {
3706  ret = fisretsts (COB_STATUS_10_END_OF_FILE);
3707  }
3708  } else if (fh->startcond == COB_LA) {
3709  if (isread (fh->isfd, (void *)f->record->data, ISLAST | lmode)) {
3710  ret = fisretsts (COB_STATUS_10_END_OF_FILE);
3711  }
3712  } else if (isread (fh->isfd, (void *)f->record->data, ISCURR | lmode)) {
3713  ret = fisretsts (COB_STATUS_10_END_OF_FILE);
3714  } else {
3715  switch (fh->startcond) {
3716  case COB_LE:
3717  domoveback = 0;
3718  while (iserrno == 0
3719  && memcmp (f->record->data + fh->key[fh->curkey].k_start, fh->savekey, (size_t)fh->key[fh->curkey].k_leng) == 0) {
3720  isread (fh->isfd, (void *)f->record->data, ISNEXT);
3721  domoveback = 1;
3722  }
3723  if (domoveback) {
3724  isread (fh->isfd, (void *)f->record->data, ISPREV);
3725  }
3726  break;
3727  case COB_LT:
3728  while (iserrno == 0
3729  && memcmp (f->record->data + fh->key[fh->curkey].k_start, fh->savekey, (size_t)fh->key[fh->curkey].k_leng) >= 0) {
3730  isread (fh->isfd, (void *)f->record->data, ISPREV);
3731  }
3732  break;
3733  case COB_GT:
3734  while (iserrno == 0
3735  && memcmp (f->record->data + fh->key[fh->curkey].k_start, fh->savekey, (size_t)fh->key[fh->curkey].k_leng) <= 0) {
3736  isread (fh->isfd, (void *)f->record->data, ISNEXT);
3737  }
3738  break;
3739  case COB_GE:
3740  while (iserrno == 0
3741  && memcmp (f->record->data + fh->key[fh->curkey].k_start, fh->savekey, (size_t)fh->key[fh->curkey].k_leng) < 0) {
3742  isread (fh->isfd, (void *)f->record->data, ISNEXT);
3743  }
3744  break;
3745  }
3746  if (isread (fh->isfd, (void *)f->record->data, ISCURR | lmode)) {
3747  ret = fisretsts (COB_STATUS_10_END_OF_FILE);
3748  }
3749  }
3750  fh->startcond = -1;
3751  fh->startiscur = 0;
3752  } else if (fh->wrkhasrec == ISPREV) {
3753  memcpy (f->record->data, fh->recwrk, f->record_max);
3754  if (fh->lmode & ISLOCK) {
3755  /* Now lock 'peek ahead' record */
3756  if (isread (fh->isfd, (void *)f->record->data,
3757  ISCURR | fh->lmode)) {
3758  ret = fisretsts (COB_STATUS_10_END_OF_FILE);
3759  }
3760  }
3761  } else {
3762  if (fh->wrkhasrec == ISNEXT) {
3763  isread (fh->isfd, (void *)f->record->data, ISPREV);
3764  fh->wrkhasrec = 0;
3765  }
3766  if (isread (fh->isfd, (void *)f->record->data, ISPREV | lmode)) {
3767  ret = fisretsts (COB_STATUS_10_END_OF_FILE);
3768  }
3769  }
3770  break;
3771  case COB_READ_FIRST:
3772  fh->readdir = ISNEXT;
3773  if (isread (fh->isfd, (void *)f->record->data, ISFIRST | lmode)) {
3774  ret = fisretsts (COB_STATUS_10_END_OF_FILE);
3775  }
3776  break;
3777  case COB_READ_LAST:
3778  fh->readdir = ISPREV;
3779  if (isread (fh->isfd, (void *)f->record->data, ISLAST | lmode)) {
3780  ret = fisretsts (COB_STATUS_10_END_OF_FILE);
3781  }
3782  break;
3783  default:
3784  fh->readdir = ISNEXT;
3785  if (isread (fh->isfd, (void *)f->record->data, ISNEXT | lmode)) {
3786  ret = fisretsts (COB_STATUS_10_END_OF_FILE);
3787  }
3788  break;
3789  }
3790  if (unlikely(ret != 0)) {
3791  memset (fh->savekey, 0, (size_t)fh->key[0].k_leng);
3792  fh->recnum = 0;
3793  fh->readdone = 0;
3794  fh->wrkhasrec = 0;
3795  return ret;
3796  }
3797  fh->eofpending = 0;
3798  f->flag_first_read = 0;
3799  f->flag_read_done = 1;
3800  fh->readdone = 1;
3801  f->flag_end_of_file = 0;
3802  f->flag_begin_of_file = 0;
3803  memcpy (fh->savekey, f->record->data + fh->key[0].k_start,
3804  (size_t)fh->key[0].k_leng);
3805  fh->recnum = isrecnum;
3806 #ifdef ISVARLEN
3807  if (f->record_min != f->record_max) {
3808  f->record->size = isreclen;
3809  }
3810 #endif
3811 
3812 #ifdef COB_WITH_STATUS_02
3813  if((isstat1 == '0') && (isstat2 == '2')) {
3815  }
3816 #endif
3817  return 0;
3818 
3819 #elif defined(WITH_DB)
3820 
3821  struct indexed_file *p;
3822  int ret;
3823  int read_nextprev;
3824  cob_u32_t nextprev;
3825  int file_changed;
3826  int bdb_opts;
3827  unsigned int dupno;
3828 
3829  p = f->file;
3830  nextprev = DB_NEXT;
3831  dupno = 0;
3832  file_changed = 0;
3833 
3834  dupno = 0;
3835 
3836  bdb_opts = read_opts;
3837  if (bdb_env != NULL) {
3838  if (f->open_mode != COB_OPEN_I_O ||
3839  (f->lock_mode & COB_FILE_EXCLUSIVE)) {
3840  bdb_opts &= ~COB_READ_LOCK;
3841  } else if ((f->lock_mode & COB_LOCK_AUTOMATIC) &&
3842  !(bdb_opts & COB_READ_NO_LOCK)) {
3843  bdb_opts |= COB_READ_LOCK;
3844  }
3845  unlock_record (f);
3846  } else {
3847  bdb_opts &= ~COB_READ_LOCK;
3848  }
3849 
3850  if (unlikely(bdb_opts & COB_READ_PREVIOUS)) {
3851  if (f->flag_end_of_file) {
3852  nextprev = DB_LAST;
3853  } else {
3854  nextprev = DB_PREV;
3855  }
3856  } else if (f->flag_begin_of_file) {
3857  nextprev = DB_FIRST;
3858  }
3859  /* The open cursor makes this function atomic */
3860  if (p->key_index != 0) {
3861  p->db[0]->cursor (p->db[0], NULL, &p->cursor[0], 0);
3862  }
3863  p->db[p->key_index]->cursor (p->db[p->key_index], NULL, &p->cursor[p->key_index], 0);
3864 
3865  if (f->flag_first_read) {
3866  /* Data is read in indexed_open or indexed_start */
3867  if (p->data.data == NULL || (f->flag_first_read == 2 &&
3868  nextprev == DB_PREV)) {
3869  p->cursor[p->key_index]->c_close (p->cursor[p->key_index]);
3870  p->cursor[p->key_index] = NULL;
3871  if (p->key_index != 0) {
3872  p->cursor[0]->c_close (p->cursor[0]);
3873  p->cursor[0] = NULL;
3874  }
3876  }
3877  /* Check if previously read data still exists */
3878  p->key.size = (cob_dbtsize_t) f->keys[p->key_index].field->size;
3879  p->key.data = p->last_readkey[p->key_index];
3880  ret = DB_SEQ (p->cursor[p->key_index], DB_SET);
3881  if (!ret && p->key_index > 0) {
3882  if (f->keys[p->key_index].flag) {
3883  memcpy (&dupno, (cob_u8_ptr)p->data.data + f->keys[0].field->size, sizeof(unsigned int));
3884  while (ret == 0 &&
3885  memcmp (p->key.data, p->last_readkey[p->key_index], (size_t)p->key.size) == 0 &&
3886  dupno < p->last_dupno[p->key_index]) {
3887  ret = DB_SEQ (p->cursor[p->key_index], DB_NEXT);
3888  memcpy (&dupno, (cob_u8_ptr)p->data.data + f->keys[0].field->size, sizeof(unsigned int));
3889  }
3890  if (ret == 0 &&
3891  memcmp (p->key.data, p->last_readkey[p->key_index], (size_t)p->key.size) == 0 &&
3892  dupno == p->last_dupno[p->key_index]) {
3893  ret = memcmp (p->last_readkey[p->key_index + f->nkeys], p->data.data, f->keys[0].field->size);
3894  } else {
3895  ret = 1;
3896  }
3897  } else {
3898  ret = memcmp (p->last_readkey[p->key_index + f->nkeys], p->data.data, f->keys[0].field->size);
3899  }
3900  if (!ret) {
3901  p->key.size = (cob_dbtsize_t) f->keys[0].field->size;
3902  p->key.data = p->last_readkey[p->key_index + f->nkeys];
3903  ret = DB_GET (p->db[0], 0);
3904  }
3905  }
3906  file_changed = ret;
3907  if (bdb_env != NULL && !file_changed) {
3908  if (!(bdb_opts & COB_READ_IGNORE_LOCK)) {
3909  ret = test_record_lock (f, p->key.data, p->key.size);
3910  if (ret) {
3911  p->cursor[p->key_index]->c_close (p->cursor[p->key_index]);
3912  p->cursor[p->key_index] = NULL;
3913  if (p->key_index != 0) {
3914  p->cursor[0]->c_close (p->cursor[0]);
3915  p->cursor[0] = NULL;
3916  }
3918  }
3919  }
3920  if (bdb_opts & COB_READ_LOCK) {
3921  ret = lock_record (f, p->key.data, p->key.size);
3922  if (ret) {
3923  p->cursor[p->key_index]->c_close (p->cursor[p->key_index]);
3924  p->cursor[p->key_index] = NULL;
3925  if (p->key_index != 0) {
3926  p->cursor[0]->c_close (p->cursor[0]);
3927  p->cursor[0] = NULL;
3928  }
3930  }
3931  }
3932  }
3933  }
3934  if (!f->flag_first_read || file_changed) {
3935  if (nextprev == DB_FIRST || nextprev == DB_LAST) {
3936  read_nextprev = 1;
3937  } else {
3938  p->key.size = (cob_dbtsize_t) f->keys[p->key_index].field->size;
3939  p->key.data = p->last_readkey[p->key_index];
3940  ret = DB_SEQ (p->cursor[p->key_index], DB_SET_RANGE);
3941  /* ret != 0 possible, records may be deleted since last read */
3942  if (ret != 0) {
3943  if (nextprev == DB_PREV) {
3944  nextprev = DB_LAST;
3945  read_nextprev = 1;
3946  } else {
3947  p->cursor[p->key_index]->c_close (p->cursor[p->key_index]);
3948  p->cursor[p->key_index] = NULL;
3949  if (p->key_index != 0) {
3950  p->cursor[0]->c_close (p->cursor[0]);
3951  p->cursor[0] = NULL;
3952  }
3954  }
3955  } else {
3956  if (memcmp (p->key.data, p->last_readkey[p->key_index], (size_t)p->key.size) == 0) {
3957  if (p->key_index > 0 && f->keys[p->key_index].flag) {
3958  memcpy (&dupno, (cob_u8_ptr)p->data.data + f->keys[0].field->size, sizeof(unsigned int));
3959  while (ret == 0 &&
3960  memcmp (p->key.data, p->last_readkey[p->key_index], (size_t)p->key.size) == 0 &&
3961  dupno < p->last_dupno[p->key_index]) {
3962  ret = DB_SEQ (p->cursor[p->key_index], DB_NEXT);
3963  memcpy (&dupno, (cob_u8_ptr)p->data.data + f->keys[0].field->size, sizeof(unsigned int));
3964  }
3965  if (ret != 0) {
3966  if (nextprev == DB_PREV) {
3967  nextprev = DB_LAST;
3968  read_nextprev = 1;
3969  } else {
3970  p->cursor[p->key_index]->c_close (p->cursor[p->key_index]);
3971  p->cursor[p->key_index] = NULL;
3972  if (p->key_index != 0) {
3973  p->cursor[0]->c_close (p->cursor[0]);
3974  p->cursor[0] = NULL;
3975  }
3977  }
3978  } else {
3979  if (memcmp (p->key.data, p->last_readkey[p->key_index], (size_t)p->key.size) == 0 &&
3980  dupno == p->last_dupno[p->key_index]) {
3981  read_nextprev = 1;
3982  } else {
3983  if (nextprev == DB_PREV) {
3984  read_nextprev = 1;
3985  } else {
3986  read_nextprev = 0;
3987  }
3988  }
3989  }
3990  } else {
3991  read_nextprev = 1;
3992  }
3993  } else {
3994  if (nextprev == DB_PREV) {
3995  read_nextprev = 1;
3996  } else {
3997  read_nextprev = 0;
3998  }
3999  }
4000  }
4001  }
4002  if (read_nextprev) {
4003  ret = DB_SEQ (p->cursor[p->key_index], nextprev);
4004  if (ret != 0) {
4005  p->cursor[p->key_index]->c_close (p->cursor[p->key_index]);
4006  p->cursor[p->key_index] = NULL;
4007  if (p->key_index != 0) {
4008  p->cursor[0]->c_close (p->cursor[0]);
4009  p->cursor[0] = NULL;
4010  }
4012  }
4013  }
4014 
4015  if (p->key_index > 0) {
4016  /* Temporarily save alternate key */
4017  memcpy (p->temp_key, p->key.data, (size_t)p->key.size);
4018  if (f->keys[p->key_index].flag) {
4019  memcpy (&dupno, (cob_u8_ptr)p->data.data + f->keys[0].field->size, sizeof(unsigned int));
4020  }
4021  p->key.data = p->data.data;
4022  p->key.size = f->keys[0].field->size;
4023  if (DB_GET (p->db[0], 0) != 0) {
4024  p->cursor[p->key_index]->c_close (p->cursor[p->key_index]);
4025  p->cursor[p->key_index] = NULL;
4026  p->cursor[0]->c_close (p->cursor[0]);
4027  p->cursor[0] = NULL;
4029  }
4030  }
4031  if (bdb_env != NULL) {
4032  if (!(bdb_opts & COB_READ_IGNORE_LOCK)) {
4033  ret = test_record_lock (f, p->key.data, p->key.size);
4034  if (ret) {
4035  p->cursor[p->key_index]->c_close (p->cursor[p->key_index]);
4036  p->cursor[p->key_index] = NULL;
4037  if (p->key_index != 0) {
4038  p->cursor[0]->c_close (p->cursor[0]);
4039  p->cursor[0] = NULL;
4040  }
4042  }
4043  }
4044  if (bdb_opts & COB_READ_LOCK) {
4045  ret = lock_record (f, p->key.data, p->key.size);
4046  if (ret) {
4047  p->cursor[p->key_index]->c_close (p->cursor[p->key_index]);
4048  p->cursor[p->key_index] = NULL;
4049  if (p->key_index != 0) {
4050  p->cursor[0]->c_close (p->cursor[0]);
4051  p->cursor[0] = NULL;
4052  }
4054  }
4055  }
4056  }
4057  if (p->key_index == 0) {
4058  memcpy (p->last_readkey[0], p->key.data, (size_t)p->key.size);
4059  } else {
4060  memcpy (p->last_readkey[p->key_index], p->temp_key,
4061  f->keys[p->key_index].field->size);
4062  memcpy (p->last_readkey[p->key_index + f->nkeys], p->key.data, f->keys[0].field->size);
4063  if (f->keys[p->key_index].flag) {
4064  p->last_dupno[p->key_index] = dupno;
4065  }
4066  }
4067  }
4068 
4069  p->cursor[p->key_index]->c_close (p->cursor[p->key_index]);
4070  p->cursor[p->key_index] = NULL;
4071  if (p->key_index != 0) {
4072  p->cursor[0]->c_close (p->cursor[0]);
4073  p->cursor[0] = NULL;
4074  }
4075 
4076  f->record->size = p->data.size;
4077  memcpy (f->record->data, p->data.data, (size_t)p->data.size);
4078 
4079  return COB_STATUS_00_SUCCESS;
4080 
4081 #else
4082 
4084 #endif
4085 }
static int indexed_rewrite ( cob_file f,
const int  opt 
)
static

References cob_file::access_mode, COB_ACCESS_SEQUENTIAL, COB_LOCK_AUTOMATIC, COB_LOCK_MULTIPLE, COB_STATUS_00_SUCCESS, COB_STATUS_02_SUCCESS_DUPLICATE, COB_STATUS_21_KEY_INVALID, COB_STATUS_22_KEY_EXISTS, COB_STATUS_49_I_O_DENIED, COB_STATUS_91_NOT_AVAILABLE, cob_u32_t, COB_UNUSED, cob_field::data, cob_file_key::field, cob_file::file, cob_file::flag_nonexistent, cob_file::keys, cob_file::lock_mode, cob_file::nkeys, NULL, p, cob_file::record, cob_file::record_max, cob_file::record_min, and cob_field::size.

4220 {
4221 #ifdef WITH_INDEX_EXTFH
4222 
4223  return extfh_indexed_rewrite (f, opt);
4224 
4225 #elif defined(WITH_ANY_ISAM)
4226 
4227  struct indexfile *fh;
4228  size_t k;
4229  int ret;
4230 
4231  COB_UNUSED (opt);
4232 
4233  fh = f->file;
4234  ret = COB_STATUS_00_SUCCESS;
4235  if (f->flag_nonexistent) {
4236  return COB_STATUS_49_I_O_DENIED;
4237  }
4238 
4239  if (f->access_mode == COB_ACCESS_SEQUENTIAL &&
4240  memcmp (fh->savekey, f->record->data + fh->key[0].k_start,
4241  (size_t)fh->key[0].k_leng) != 0) {
4243  }
4244  if (fh->curkey >= 0) {
4245  /* Index is active */
4246  /* Save record data */
4247  memcpy (fh->recwrk, f->record->data, f->record_max);
4248 /* RXWRXW - readdir */
4249  fh->readdir = ISNEXT;
4250  savefileposition (f);
4251  memcpy (fh->recwrk, f->record->data, f->record_max);
4252  if (fh->curkey != 0) {
4253  /* Activate primary index */
4254  isstart (fh->isfd, &fh->key[0], 0, (void *)fh->recwrk,
4255  ISEQUAL);
4256  }
4257  /* Verify record exists */
4258  if (isread (fh->isfd, (void *)fh->recwrk, ISEQUAL)) {
4259  restorefileposition (f);
4261  }
4262  for (k = 1; k < f->nkeys && ret == COB_STATUS_00_SUCCESS; ++k) {
4263  if (fh->key[k].k_flags & ISDUPS) {
4264  continue;
4265  }
4266  memcpy (fh->recwrk, f->record->data, f->record_max);
4267  isstart (fh->isfd, &fh->key[k], fh->key[k].k_leng,
4268  (void *)fh->recwrk, ISEQUAL);
4269  if (!isread (fh->isfd, (void *)fh->recwrk, ISEQUAL) &&
4270  isrecnum != fh->recnum) {
4272  break;
4273  }
4274  }
4275  if (ret == COB_STATUS_00_SUCCESS) {
4276  memcpy (fh->recwrk, f->record->data, f->record_max);
4277  isstart (fh->isfd, &fh->key[0], 0, (void *)fh->recwrk,
4278  ISEQUAL);
4279  if (isread (fh->isfd, (void *)fh->recwrk, ISEQUAL | ISLOCK)) {
4280  ret = fisretsts (COB_STATUS_49_I_O_DENIED);
4281  } else {
4282 #ifdef ISVARLEN
4283  if (f->record_min != f->record_max) {
4284  isreclen = f->record->size;
4285  }
4286 #endif
4287  if (isrewcurr (fh->isfd, (void *)f->record->data)) {
4288  ret = fisretsts (COB_STATUS_49_I_O_DENIED);
4289  }
4290  }
4291  }
4292  restorefileposition (f);
4293 
4294 #ifdef COB_WITH_STATUS_02
4295  if(!ret && (isstat1 == '0') && (isstat2 == '2')) {
4297  }
4298 #endif
4299 
4300  return ret;
4301  }
4302 
4303  memcpy (fh->recwrk, f->record->data, f->record_max);
4304  if (isread (fh->isfd, (void *)fh->recwrk, ISEQUAL | ISLOCK)) {
4305  ret = fisretsts (COB_STATUS_49_I_O_DENIED);
4306  } else {
4307 #ifdef ISVARLEN
4308  if (f->record_min != f->record_max) {
4309  isreclen = f->record->size;
4310  }
4311 #endif
4312  if (isrewrite (fh->isfd, (void *)f->record->data)) {
4313  ret = fisretsts (COB_STATUS_49_I_O_DENIED);
4314  }
4315  }
4316  if (!ret) {
4317  if ((f->lock_mode & COB_LOCK_AUTOMATIC) &&
4318  !(f->lock_mode & COB_LOCK_MULTIPLE)) {
4319  isrelease (fh->isfd);
4320  }
4321 #ifdef COB_WITH_STATUS_02
4322  if((isstat1 == '0') && (isstat2 == '2')) {
4324  }
4325 #endif
4326  }
4327  return ret;
4328 
4329 #elif defined(WITH_DB)
4330 
4331  struct indexed_file *p;
4332  int ret;
4333  cob_u32_t flags;
4334 
4335  if (f->flag_nonexistent) {
4336  return COB_STATUS_49_I_O_DENIED;
4337  }
4338  p = f->file;
4339  if (bdb_env) {
4340  flags = DB_WRITECURSOR;
4341  } else {
4342  flags = 0;
4343  }
4344  p->db[0]->cursor (p->db[0], NULL, &p->cursor[0], flags);
4345  p->write_cursor_open = 1;
4346  if (bdb_env != NULL) {
4347  unlock_record (f);
4348  }
4349 
4350  /* Check duplicate alternate keys */
4351  if (check_alt_keys (f, 1)) {
4352  p->cursor[0]->c_close (p->cursor[0]);
4353  p->cursor[0] = NULL;
4354  p->write_cursor_open = 0;
4355  return COB_STATUS_22_KEY_EXISTS;
4356  }
4357 
4358  /* Delete the current record */
4359  ret = indexed_delete_internal (f, 1);
4360 
4361  if (ret != COB_STATUS_00_SUCCESS) {
4362  p->cursor[0]->c_close (p->cursor[0]);
4363  p->cursor[0] = NULL;
4364  p->write_cursor_open = 0;
4365  return ret;
4366  }
4367 
4368  /* Write data */
4369  DBT_SET (p->key, f->keys[0].field);
4370  ret = indexed_write_internal (f, 1, opt);
4371 
4372  p->cursor[0]->c_close (p->cursor[0]);
4373  p->cursor[0] = NULL;
4374  p->write_cursor_open = 0;
4375  return ret;
4376 
4377 #else
4378 
4380 #endif
4381 }
static int indexed_start ( cob_file f,
const int  cond,
cob_field key 
)
static

References COB_EQ, COB_FI, COB_GE, COB_GT, COB_LA, COB_LE, COB_LT, COB_STATUS_00_SUCCESS, COB_STATUS_21_KEY_INVALID, COB_STATUS_23_KEY_NOT_EXISTS, COB_STATUS_91_NOT_AVAILABLE, cob_field::data, cob_file_key::field, cob_file::file, cob_file::flag_begin_of_file, cob_file::flag_end_of_file, cob_file::flag_first_read, cob_file::flag_nonexistent, cob_file::flag_read_done, cob_file::keys, cob_file::nkeys, cob_file::record, and cob_field::size.

3329 {
3330 #ifdef WITH_INDEX_EXTFH
3331 
3332  return extfh_indexed_start (f, cond, key);
3333 
3334 #elif defined(WITH_ANY_ISAM)
3335 
3336  struct indexfile *fh;
3337  size_t k;
3338  int mode;
3339  int klen;
3340  int savecond;
3341 
3342  fh = f->file;
3343  f->flag_read_done = 0;
3344  f->flag_first_read = 0;
3345  fh->readdone = 0;
3346  fh->eofpending = 0;
3347  fh->startiscur = 0;
3348  fh->wrkhasrec = 0;
3349  if (f->flag_nonexistent) {
3351  }
3352  for (k = 0; k < f->nkeys; ++k) {
3353  if (f->keys[k].field->data == key->data) {
3354  break;
3355  }
3356  }
3357  /* Use size of data field; This may indicate a partial key */
3358  klen = key->size;
3359  if (klen < 1 || klen > fh->key[k].k_leng) {
3360  /* Max key length for this index */
3361  klen = fh->key[k].k_leng;
3362  }
3363  mode = ISGTEQ;
3364  fh->startiscur = 1;
3365  savecond = cond;
3366  switch (cond) {
3367  case COB_EQ:
3368  mode = ISEQUAL;
3369  fh->readdir = ISNEXT;
3370  break;
3371  case COB_GE:
3372  mode = ISGTEQ;
3373  fh->readdir = ISNEXT;
3374  break;
3375  case COB_GT:
3376  mode = ISGREAT;
3377  fh->readdir = ISNEXT;
3378  break;
3379  case COB_LE:
3380  mode = ISGTEQ;
3381  fh->readdir = ISPREV;
3382  break;
3383  case COB_LT:
3384  mode = ISGTEQ;
3385  fh->readdir = ISPREV;
3386  break;
3387  case COB_FI:
3388  mode = ISFIRST;
3389  fh->readdir = ISNEXT;
3390  break;
3391  case COB_LA:
3392  mode = ISLAST;
3393  fh->readdir = ISPREV;
3394  break;
3395  default:
3397  }
3398  if (isstart (fh->isfd, &fh->key[k], klen, (void *)f->record->data, mode)) {
3399  if (cond == COB_LE || cond == COB_LT) {
3400  if (isstart (fh->isfd, &fh->key[k], klen, (void *)f->record->data, ISLAST)) {
3401  fh->curkey = -1;
3402  fh->startcond = -1;
3403  fh->readdir = -1;
3404  fh->startiscur = 0;
3405  return fisretsts (COB_STATUS_23_KEY_NOT_EXISTS);
3406  } else {
3407  savecond = COB_LA;
3408  }
3409  } else {
3410  fh->curkey = -1;
3411  fh->startcond = -1;
3412  fh->readdir = -1;
3413  fh->startiscur = 0;
3414  return fisretsts (COB_STATUS_23_KEY_NOT_EXISTS);
3415  }
3416  }
3417  fh->startcond = savecond;
3418  memcpy (fh->savekey, f->record->data + fh->key[k].k_start,
3419  (size_t)fh->key[k].k_leng);
3420  fh->curkey = k;
3421  f->flag_end_of_file = 0;
3422  f->flag_begin_of_file = 0;
3423  f->flag_first_read = 1;
3424  return COB_STATUS_00_SUCCESS;
3425 
3426 #elif defined(WITH_DB)
3427 
3428  return indexed_start_internal (f, cond, key, 0, 0);
3429 
3430 #else
3431 
3433 #endif
3434 }
static int indexed_write ( cob_file f,
const int  opt 
)
static

References cob_file::access_mode, COB_ACCESS_SEQUENTIAL, cob_malloc(), COB_STATUS_02_SUCCESS_DUPLICATE, COB_STATUS_21_KEY_INVALID, COB_STATUS_48_OUTPUT_DENIED, COB_STATUS_49_I_O_DENIED, COB_STATUS_91_NOT_AVAILABLE, COB_UNUSED, cob_field::data, cob_file_key::field, cob_file::file, cob_file::flag_nonexistent, cob_file::keys, NULL, p, cob_file::record, cob_file::record_max, cob_file::record_min, cob_field::size, and unlikely.

4092 {
4093 #ifdef WITH_INDEX_EXTFH
4094 
4095  return extfh_indexed_write (f, opt);
4096 
4097 #elif defined(WITH_ANY_ISAM)
4098 
4099  struct indexfile *fh;
4100 
4101  COB_UNUSED (opt);
4102 
4103  fh = f->file;
4104  if (f->flag_nonexistent) {
4106  }
4107  if (f->access_mode == COB_ACCESS_SEQUENTIAL &&
4108  memcmp (fh->savekey, f->record->data + fh->key[0].k_start,
4109  (size_t)fh->key[0].k_leng) > 0) {
4111  }
4112 
4113 #ifdef ISVARLEN
4114  if (f->record_min != f->record_max) {
4115  isreclen = f->record->size;
4116  }
4117 #endif
4118  if (unlikely(iswrite (fh->isfd, (void *)f->record->data))) {
4119  return fisretsts (COB_STATUS_49_I_O_DENIED);
4120  }
4121  memcpy (fh->savekey, f->record->data + fh->key[0].k_start,
4122  (size_t)fh->key[0].k_leng);
4123 
4124 #ifdef COB_WITH_STATUS_02
4125  if((isstat1 == '0') && (isstat2 == '2')) {
4127  }
4128 #endif
4129  return 0;
4130 
4131 #elif defined(WITH_DB)
4132 
4133  struct indexed_file *p;
4134 
4135  if (f->flag_nonexistent) {
4137  }
4138  p = f->file;
4139  if (bdb_env != NULL) {
4140  unlock_record (f);
4141  }
4142 
4143  /* Check record key */
4144  DBT_SET (p->key, f->keys[0].field);
4145  if (!p->last_key) {
4146  p->last_key = cob_malloc ((size_t)p->key.size);
4147  } else if (f->access_mode == COB_ACCESS_SEQUENTIAL &&
4148  memcmp (p->last_key, p->key.data, (size_t)p->key.size) > 0) {
4150  }
4151  memcpy (p->last_key, p->key.data, (size_t)p->key.size);
4152 
4153  return indexed_write_internal (f, 0, opt);
4154 
4155 #else
4156 
4158 #endif
4159 }
static int lineseq_read ( cob_file f,
const int  read_opts 
)
static

References cob_ls_nulls, COB_NOT_CONFIGURED, COB_STATUS_00_SUCCESS, COB_STATUS_10_END_OF_FILE, COB_STATUS_30_PERMANENT_ERROR, COB_UNUSED, cob_field::data, cob_file::file, likely, cob_file::record, cob_file::record_max, cob_field::size, and unlikely.

1433 {
1434  unsigned char *dataptr;
1435  size_t i = 0;
1436  int n;
1437 
1438 #ifdef WITH_SEQRA_EXTFH
1439  int extfh_ret;
1440 
1441  extfh_ret = extfh_sequential_read (f, read_opts);
1442  if (extfh_ret != COB_NOT_CONFIGURED) {
1443  return extfh_ret;
1444  }
1445 #else
1446  COB_UNUSED (read_opts);
1447 #endif
1448 
1449  dataptr = f->record->data;
1450  for (; ;) {
1451  n = getc ((FILE *)f->file);
1452  if (unlikely(n == EOF)) {
1453  if (!i) {
1455  } else {
1456  break;
1457  }
1458  }
1459  if (unlikely(n == 0 && cob_ls_nulls != 0)) {
1460  n = getc ((FILE *)f->file);
1461  if (n == EOF) {
1463  }
1464  } else {
1465  if (n == '\r') {
1466  continue;
1467  }
1468  if (n == '\n') {
1469  break;
1470  }
1471  }
1472  if (likely(i < f->record_max)) {
1473  *dataptr++ = (unsigned char)n;
1474  i++;
1475  }
1476  }
1477  if (i < f->record_max) {
1478  /* Fill the record with spaces */
1479  memset ((unsigned char *)f->record->data + i, ' ',
1480  f->record_max - i);
1481  }
1482  f->record->size = i;
1483  return COB_STATUS_00_SUCCESS;
1484 }
static int lineseq_write ( cob_file f,
const int  opt 
)
static

References cob_file_write_opt(), cob_ls_fixed, cob_ls_nulls, cob_ls_uses_cr, COB_NOT_CONFIGURED, COB_SELECT_LINAGE, COB_STATUS_00_SUCCESS, COB_STATUS_30_PERMANENT_ERROR, COB_WRITE_AFTER, COB_WRITE_BEFORE, COB_WRITE_PAGE, cob_field::data, cob_file::file, cob_file::flag_needs_nl, cob_file::flag_needs_top, cob_file::flag_select_features, cob_linage::lin_top, cob_file::linorkeyptr, p, cob_file::record, cob_field::size, and unlikely.

1488 {
1489  unsigned char *p;
1490  cob_linage *lingptr;
1491  size_t size;
1492  int i;
1493  int ret;
1494 
1495 #ifdef WITH_SEQRA_EXTFH
1496  int extfh_ret;
1497 
1498  extfh_ret = extfh_sequential_write (f, opt);
1499  if (extfh_ret != COB_NOT_CONFIGURED) {
1500  return extfh_ret;
1501  }
1502 #endif
1503 
1504  /* Determine the size to be written */
1505  if (unlikely(cob_ls_fixed != 0)) {
1506  size = f->record->size;
1507  } else {
1508  for (i = (int)f->record->size - 1; i >= 0; --i) {
1509  if (f->record->data[i] != ' ') {
1510  break;
1511  }
1512  }
1513  size = i + 1;
1514  }
1515 
1517  if (f->flag_needs_top) {
1518  f->flag_needs_top = 0;
1519  lingptr = f->linorkeyptr;
1520  for (i = 0; i < lingptr->lin_top; ++i) {
1521  putc ('\n', (FILE *)f->file);
1522  }
1523  }
1524  }
1525  /* WRITE AFTER */
1526  if (opt & COB_WRITE_AFTER) {
1527  ret = cob_file_write_opt (f, opt);
1528  if (ret) {
1529  return ret;
1530  }
1531  f->flag_needs_nl = 1;
1532  }
1533 
1534  /* Write to the file */
1535  if (size) {
1536  if (unlikely(cob_ls_nulls != 0)) {
1537  p = f->record->data;
1538  for (i = 0; i < (int)size; ++i, ++p) {
1539  if (*p < ' ') {
1540  putc (0, (FILE *)f->file);
1541  }
1542  putc ((int)(*p), (FILE *)f->file);
1543  }
1544  } else {
1545  if (unlikely(fwrite (f->record->data, size, (size_t)1,
1546  (FILE *)f->file) != 1)) {
1548  }
1549  }
1550  }
1551 
1553  putc ('\n', (FILE *)f->file);
1554  } else if (cob_ls_uses_cr) {
1555  if (opt & COB_WRITE_PAGE) {
1556  putc ('\r', (FILE *)f->file);
1557  } else if ((opt & COB_WRITE_BEFORE) && f->flag_needs_nl) {
1558  putc ('\r', (FILE *)f->file);
1559  }
1560  }
1561 
1562  /* WRITE BEFORE */
1563  if (opt & COB_WRITE_BEFORE) {
1564  ret = cob_file_write_opt (f, opt);
1565  if (ret) {
1566  return ret;
1567  }
1568  f->flag_needs_nl = 0;
1569  }
1570 
1571  return COB_STATUS_00_SUCCESS;
1572 }
static int open_cbl_file ( unsigned char *  file_name,
unsigned char *  file_access,
unsigned char *  file_handle,
const int  file_flags 
)
static

References _, __cob_global::cob_display_warn, cob_free(), COB_MODULE_PTR, cob_str_from_fld(), COB_UNUSED, and O_BINARY.

Referenced by cob_sys_create_file(), and cob_sys_open_file().

5001 {
5002  char *fn;
5003  int flag = O_BINARY;
5004  int fd;
5005 
5006  COB_UNUSED (file_name);
5007 
5008  if (!COB_MODULE_PTR->cob_procedure_params[0]) {
5009  memset (file_handle, -1, (size_t)4);
5010  return -1;
5011  }
5012  flag |= file_flags;
5013  switch (*file_access & 0x3F) {
5014  case 1:
5015  flag |= O_RDONLY;
5016  break;
5017  case 2:
5018  flag |= O_CREAT | O_TRUNC | O_WRONLY;
5019  break;
5020  case 3:
5021  flag |= O_RDWR;
5022  break;
5023  default:
5025  fprintf (stderr, _("WARNING - Call to CBL_OPEN_FILE with wrong access mode: %d"), *file_access & 0x3F);
5026  putc ('\n', stderr);
5027  fflush (stderr);
5028  }
5029  memset (file_handle, -1, (size_t)4);
5030  return -1;
5031  }
5032  fn = cob_str_from_fld (COB_MODULE_PTR->cob_procedure_params[0]);
5033  fd = open (fn, flag, 0660);
5034  if (fd < 0) {
5035  cob_free (fn);
5036  memset (file_handle, -1, (size_t)4);
5037  return 35;
5038  }
5039  cob_free (fn);
5040  memcpy (file_handle, &fd, (size_t)4);
5041  return 0;
5042 }
static int relative_delete ( cob_file f)
static

References cob_get_int(), COB_NOT_CONFIGURED, COB_STATUS_00_SUCCESS, COB_STATUS_23_KEY_NOT_EXISTS, COB_STATUS_24_KEY_BOUNDARY, COB_STATUS_30_PERMANENT_ERROR, cob_file::fd, cob_file_key::field, cob_file::flag_operation, cob_file::keys, cob_file::record, cob_file::record_max, and cob_field::size.

1952 {
1953  off_t off;
1954  size_t relsize;
1955  int relnum;
1956 #ifdef WITH_SEQRA_EXTFH
1957  int extfh_ret;
1958 
1959  extfh_ret = extfh_relative_delete (f);
1960  if (extfh_ret != COB_NOT_CONFIGURED) {
1961  return extfh_ret;
1962  }
1963 #endif
1964 
1965  f->flag_operation = 1;
1966  relnum = cob_get_int (f->keys[0].field) - 1;
1967  if (relnum < 0) {
1969  }
1970  relsize = f->record_max + sizeof (f->record->size);
1971  off = relnum * relsize;
1972  if (lseek (f->fd, off, SEEK_SET) == (off_t)-1 ||
1973  read (f->fd, &f->record->size, sizeof (f->record->size))
1974  != sizeof (f->record->size)) {
1976  }
1977  lseek (f->fd, off, SEEK_SET);
1978 
1979  f->record->size = 0;
1980  if (write (f->fd, &f->record->size, sizeof (f->record->size)) != sizeof (f->record->size)) {
1982  }
1983  lseek (f->fd, (off_t) f->record_max, SEEK_CUR);
1984  return COB_STATUS_00_SUCCESS;
1985 }
static int relative_read ( cob_file f,
cob_field k,
const int  read_opts 
)
static

References cob_get_int(), COB_NOT_CONFIGURED, COB_STATUS_00_SUCCESS, COB_STATUS_23_KEY_NOT_EXISTS, COB_STATUS_30_PERMANENT_ERROR, COB_UNUSED, cob_field::data, cob_file::fd, cob_file::flag_operation, cob_file::record, cob_file::record_max, cob_field::size, and unlikely.

1700 {
1701  off_t off;
1702  size_t relsize;
1703  int relnum;
1704 #ifdef WITH_SEQRA_EXTFH
1705  int extfh_ret;
1706 
1707  extfh_ret = extfh_relative_read (f, k, read_opts);
1708  if (extfh_ret != COB_NOT_CONFIGURED) {
1709  return extfh_ret;
1710  }
1711 #else
1712  COB_UNUSED (read_opts);
1713 #endif
1714 
1715  if (unlikely(f->flag_operation != 0)) {
1716  f->flag_operation = 0;
1717  lseek (f->fd, (off_t)0, SEEK_CUR);
1718  }
1719 
1720  relnum = cob_get_int (k) - 1;
1721  if (relnum < 0) {
1723  }
1724  relsize = f->record_max + sizeof (f->record->size);
1725  off = relnum * relsize;
1726  if (lseek (f->fd, off, SEEK_SET) == (off_t)-1 ||
1727  read (f->fd, &f->record->size, sizeof (f->record->size))
1728  != sizeof (f->record->size)) {
1730  }
1731 
1732  if (f->record->size == 0) {
1733  lseek (f->fd, off, SEEK_SET);
1735  }
1736 
1737  if (read (f->fd, f->record->data, f->record_max) != (int)f->record_max) {
1739  }
1740  return COB_STATUS_00_SUCCESS;
1741 }
static int relative_read_next ( cob_file f,
const int  read_opts 
)
static

References cob_add_int(), COB_NOT_CONFIGURED, COB_READ_FIRST, COB_READ_LAST, COB_READ_MASK, COB_READ_NEXT, COB_READ_PREVIOUS, cob_s64_t, cob_set_int(), COB_STATUS_00_SUCCESS, COB_STATUS_10_END_OF_FILE, COB_STATUS_14_OUT_OF_KEY_RANGE, COB_STATUS_30_PERMANENT_ERROR, COB_STORE_KEEP_ON_OVERFLOW, cob_u32_t, cob_field::data, cob_file::fd, cob_file_key::field, cob_file::flag_first_read, cob_file::flag_operation, cob_file::keys, cob_file::record, cob_file::record_max, cob_field::size, and unlikely.

1745 {
1746  off_t curroff;
1747  cob_s64_t relsize;
1748  int relnum;
1749  int bytesread;
1750  cob_u32_t moveback;
1751  struct stat st;
1752 
1753 #ifdef WITH_SEQRA_EXTFH
1754  int extfh_ret;
1755 
1756  extfh_ret = extfh_relative_read_next (f, read_opts);
1757  if (extfh_ret != COB_NOT_CONFIGURED) {
1758  return extfh_ret;
1759  }
1760 #endif
1761 
1762  if (unlikely(f->flag_operation != 0)) {
1763  f->flag_operation = 0;
1764  lseek (f->fd, (off_t)0, SEEK_CUR);
1765  }
1766 
1767  relsize = f->record_max + sizeof (f->record->size);
1768  if (fstat (f->fd, &st) != 0 || st.st_size == 0) {
1770  }
1771  if (st.st_size < relsize) {
1773  }
1774 
1775  curroff = lseek (f->fd, (off_t)0, SEEK_CUR);
1776  moveback = 0;
1777 
1778  switch (read_opts & COB_READ_MASK) {
1779  case COB_READ_FIRST:
1780  curroff = lseek (f->fd, (off_t)0, SEEK_SET);
1781  break;
1782  case COB_READ_LAST:
1783  curroff = st.st_size - relsize;
1784  curroff = lseek (f->fd, curroff, SEEK_SET);
1785  moveback = 1;
1786  break;
1787  case COB_READ_PREVIOUS:
1788  if (f->flag_first_read) {
1789  break;
1790  } else if (curroff > relsize) {
1791  curroff -= (relsize * 2);
1792  curroff = lseek (f->fd, curroff, SEEK_SET);
1793  } else {
1795  }
1796  moveback = 1;
1797  break;
1798  case COB_READ_NEXT:
1799  default:
1800  break;
1801  }
1802 
1803  for (;;) {
1804  bytesread = read (f->fd, &f->record->size, sizeof (f->record->size));
1805  if (bytesread != sizeof (f->record->size)) {
1806  if (bytesread != 0) {
1808  } else {
1809  break;
1810  }
1811  }
1812 
1813  if (f->record->size > 0) {
1814  if (read (f->fd, f->record->data, f->record_max) != (int)f->record_max) {
1816  }
1817  if (f->keys[0].field) {
1818  relnum = (int)((curroff / relsize) + 1);
1819  cob_set_int (f->keys[0].field, 0);
1820  if (cob_add_int (f->keys[0].field, relnum,
1822  lseek (f->fd, curroff, SEEK_SET);
1824  }
1825  }
1826  if (moveback) {
1827  curroff -= relsize;
1828  curroff = lseek (f->fd, curroff, SEEK_SET);
1829  }
1830  return COB_STATUS_00_SUCCESS;
1831  }
1832  if (moveback) {
1833  if (curroff > relsize) {
1834  curroff -= (relsize * 2);
1835  curroff = lseek (f->fd, curroff, SEEK_SET);
1836  } else {
1837  break;
1838  }
1839  } else {
1840  curroff = lseek (f->fd, (off_t) f->record_max, SEEK_CUR);
1841  }
1842  }
1844 }
static int relative_rewrite ( cob_file f,
const int  opt 
)
static

References cob_file::access_mode, COB_ACCESS_SEQUENTIAL, cob_get_int(), COB_NOT_CONFIGURED, COB_STATUS_00_SUCCESS, COB_STATUS_23_KEY_NOT_EXISTS, COB_STATUS_24_KEY_BOUNDARY, COB_STATUS_30_PERMANENT_ERROR, COB_UNUSED, cob_field::data, cob_file::fd, cob_file_key::field, cob_file::flag_operation, cob_file::keys, cob_file::record, cob_file::record_max, and cob_field::size.

1911 {
1912  off_t off;
1913  size_t relsize;
1914  int relnum;
1915 #ifdef WITH_SEQRA_EXTFH
1916  int extfh_ret;
1917 
1918  extfh_ret = extfh_relative_rewrite (f, opt);
1919  if (extfh_ret != COB_NOT_CONFIGURED) {
1920  return extfh_ret;
1921  }
1922 #else
1923  COB_UNUSED (opt);
1924 #endif
1925 
1926  f->flag_operation = 1;
1927  if (f->access_mode == COB_ACCESS_SEQUENTIAL) {
1928  lseek (f->fd, -(off_t) f->record_max, SEEK_CUR);
1929  } else {
1930  relsize = f->record_max + sizeof (f->record->size);
1931  relnum = cob_get_int (f->keys[0].field) - 1;
1932  if (relnum < 0) {
1934  }
1935  off = relnum * relsize;
1936  if (lseek (f->fd, off, SEEK_SET) == (off_t)-1 ||
1937  read (f->fd, &f->record->size, sizeof (f->record->size))
1938  != sizeof (f->record->size)) {
1940  }
1941  lseek (f->fd, (off_t)0, SEEK_CUR);
1942  }
1943 
1944  if (write (f->fd, f->record->data, f->record_max) != (int)f->record_max) {
1946  }
1947  return COB_STATUS_00_SUCCESS;
1948 }
static int relative_start ( cob_file f,
const int  cond,
cob_field k 
)
static

References COB_EQ, COB_FI, COB_GE, cob_get_int(), COB_GT, COB_LA, COB_LE, COB_LT, COB_NOT_CONFIGURED, cob_set_int(), COB_STATUS_00_SUCCESS, COB_STATUS_23_KEY_NOT_EXISTS, cob_file::fd, cob_file::flag_operation, cob_file::record, cob_file::record_max, and cob_field::size.

1578 {
1579  off_t off;
1580  size_t relsize;
1581  int kindex;
1582  int ksindex;
1583  int kcond;
1584  struct stat st;
1585 
1586 #ifdef WITH_SEQRA_EXTFH
1587  int extfh_ret;
1588 
1589  extfh_ret = extfh_relative_start (f, cond, k);
1590  if (extfh_ret != COB_NOT_CONFIGURED) {
1591  return extfh_ret;
1592  }
1593 #endif
1594 
1595  if (fstat (f->fd, &st) != 0 || st.st_size == 0) {
1597  }
1598 
1599  relsize = f->record_max + sizeof (f->record->size);
1600 
1601  /* Get the index */
1602  switch (cond) {
1603  case COB_FI:
1604  kcond = COB_GE;
1605  kindex = 0;
1606  break;
1607  case COB_LA:
1608  kcond = COB_LE;
1609  kindex = st.st_size / relsize;
1610  kindex--;
1611  break;
1612  case COB_LT:
1613  case COB_LE:
1614  kcond = cond;
1615  kindex = cob_get_int (k) - 1;
1616  /* Check against current file size */
1617  ksindex = st.st_size / relsize;
1618  ksindex--;
1619  if (kindex > ksindex) {
1620  kindex = ksindex;
1621  if (cond == COB_LT) {
1622  /* Cater for decrement below */
1623  kindex++;
1624  }
1625  }
1626  break;
1627  default:
1628  kcond = cond;
1629  kindex = cob_get_int (k) - 1;
1630  break;
1631  }
1632 
1633  if (kindex < 0) {
1634  /* Only valid ops are GE and GT in this case */
1635  switch (kcond) {
1636  case COB_GE:
1637  kindex = 0;
1638  break;
1639  case COB_GT:
1640  /* Set to cater for increment below */
1641  kindex = -1;
1642  break;
1643  default:
1645  }
1646  }
1647 
1648  if (kcond == COB_LT) {
1649  kindex--;
1650  if (kindex < 0) {
1652  }
1653  } else if (kcond == COB_GT) {
1654  kindex++;
1655  }
1656 
1657  f->flag_operation = 0;
1658 
1659  /* Seek index */
1660  for (;;) {
1661  if (kindex < 0) {
1662  break;
1663  }
1664  off = kindex * relsize;
1665  if (off >= st.st_size) {
1666  break;
1667  }
1668  if (lseek (f->fd, off, SEEK_SET) == (off_t)-1) {
1669  break;
1670  }
1671 
1672  /* Check if a valid record */
1673  if (read (f->fd, &f->record->size, sizeof (f->record->size))
1674  == sizeof (f->record->size) && f->record->size > 0) {
1675 #if 0 /* RXWRXW - Set key - COBOL standards */
1676  cob_set_int (k, kindex + 1);
1677 #endif
1678  lseek (f->fd, off, SEEK_SET);
1679  return COB_STATUS_00_SUCCESS;
1680  }
1681 
1682  switch (kcond) {
1683  case COB_EQ:
1685  case COB_LT:
1686  case COB_LE:
1687  kindex--;
1688  break;
1689  case COB_GT:
1690  case COB_GE:
1691  kindex++;
1692  break;
1693  }
1694  }
1696 }
static int relative_write ( cob_file f,
const int  opt 
)
static

References cob_file::access_mode, COB_ACCESS_SEQUENTIAL, cob_get_int(), COB_NOT_CONFIGURED, cob_set_int(), COB_STATUS_00_SUCCESS, COB_STATUS_22_KEY_EXISTS, COB_STATUS_24_KEY_BOUNDARY, COB_STATUS_30_PERMANENT_ERROR, COB_UNUSED, cob_field::data, cob_file::fd, cob_file_key::field, cob_file::flag_operation, cob_file::keys, cob_file::record, cob_file::record_max, cob_field::size, and unlikely.

1848 {
1849  off_t off;
1850  size_t size;
1851  size_t relsize;
1852  int i;
1853  int kindex;
1854 #ifdef WITH_SEQRA_EXTFH
1855  int extfh_ret;
1856 
1857  extfh_ret = extfh_relative_write (f, opt);
1858  if (extfh_ret != COB_NOT_CONFIGURED) {
1859  return extfh_ret;
1860  }
1861 #else
1862  COB_UNUSED (opt);
1863 #endif
1864 
1865  if (unlikely(f->flag_operation == 0)) {
1866  f->flag_operation = 1;
1867  lseek (f->fd, (off_t)0, SEEK_CUR);
1868  }
1869 
1870  relsize = f->record_max + sizeof (f->record->size);
1871  if (f->access_mode != COB_ACCESS_SEQUENTIAL) {
1872  kindex = cob_get_int (f->keys[0].field) - 1;
1873  if (kindex < 0) {
1875  }
1876  off = (off_t) (relsize * kindex);
1877  if (lseek (f->fd, off, SEEK_SET) == (off_t)-1) {
1879  }
1880  if (read (f->fd, &size, sizeof (size)) > 0) {
1881  if (size > 0) {
1882  return COB_STATUS_22_KEY_EXISTS;
1883  }
1884  }
1885  } else {
1886  off = lseek (f->fd, (off_t)0, SEEK_CUR);
1887  }
1888  lseek (f->fd, off, SEEK_SET);
1889 
1890  if (write (f->fd, &f->record->size, sizeof (f->record->size)) != sizeof (f->record->size)) {
1892  }
1893  if (write (f->fd, f->record->data, f->record_max) != (int)f->record_max) {
1895  }
1896 
1897  /* Update RELATIVE KEY */
1898  if (f->access_mode == COB_ACCESS_SEQUENTIAL) {
1899  if (f->keys[0].field) {
1900  off += relsize;
1901  i = (int)(off / relsize);
1902  cob_set_int (f->keys[0].field, i);
1903  }
1904  }
1905 
1906  return COB_STATUS_00_SUCCESS;
1907 }
static void save_status ( cob_file f,
cob_field fnstatus,
const int  status 
)
static

References cob_do_sync, COB_EC_I_O_EOP, __cob_global::cob_error_file, COB_I2D, cob_set_exception(), cob_sync(), cob_field::data, eop_status, cob_file::file_status, likely, status_exception, and unlikely.

Referenced by cob_close(), cob_delete(), cob_delete_file(), cob_file_release(), cob_file_return(), cob_file_sort_close(), cob_file_sort_init(), cob_open(), cob_read(), cob_read_next(), cob_rewrite(), cob_start(), cob_unlock_file(), and cob_write().

695 {
697  if (likely(status == 0)) {
698  memset (f->file_status, '0', (size_t)2);
699  if (fnstatus) {
700  memset (fnstatus->data, '0', (size_t)2);
701  }
702  /* EOP is non-fatal therefore 00 status but needs exception */
703  if (unlikely(eop_status)) {
704  eop_status = 0;
706  } else {
707  cob_set_exception (0);
708  }
709  if (unlikely(cob_do_sync)) {
710  cob_sync (f);
711  }
712  return;
713  }
714  cob_set_exception (status_exception[status / 10]);
715  f->file_status[0] = (unsigned char)COB_I2D (status / 10);
716  f->file_status[1] = (unsigned char)COB_I2D (status % 10);
717  if (fnstatus) {
718  memcpy (fnstatus->data, f->file_status, (size_t)2);
719  }
720 }
static int sequential_read ( cob_file f,
const int  read_opts 
)
static

References COB_MAYSWAP_16, COB_MAYSWAP_32, COB_NOT_CONFIGURED, COB_STATUS_00_SUCCESS, COB_STATUS_04_SUCCESS_INCOMPLETE, COB_STATUS_10_END_OF_FILE, COB_STATUS_30_PERMANENT_ERROR, COB_UNUSED, cob_varseq_type, cob_vsq_len, cob_field::data, cob_file::fd, cob_file::flag_operation, cob_file::record, cob_file::record_max, cob_file::record_min, cob_field::size, and unlikely.

1274 {
1275  int bytesread;
1276  union {
1277  unsigned char sbuff[4];
1278  unsigned short sshort[2];
1279  unsigned int sint;
1280  } recsize;
1281 
1282 #ifdef WITH_SEQRA_EXTFH
1283  int extfh_ret;
1284 
1285  extfh_ret = extfh_sequential_read (f, read_opts);
1286  if (extfh_ret != COB_NOT_CONFIGURED) {
1287  return extfh_ret;
1288  }
1289 #else
1290  COB_UNUSED (read_opts);
1291 #endif
1292 
1293  if (unlikely(f->flag_operation != 0)) {
1294  f->flag_operation = 0;
1295  lseek (f->fd, (off_t)0, SEEK_CUR);
1296  }
1297 
1298  if (unlikely(f->record_min != f->record_max)) {
1299  /* Read record size */
1300 
1301  bytesread = read (f->fd, recsize.sbuff, cob_vsq_len);
1302  if (unlikely (bytesread != (int)cob_vsq_len)) {
1303  if (bytesread == 0) {
1305  } else {
1307  }
1308  }
1309  switch (cob_varseq_type) {
1310  case 1:
1311  f->record->size = COB_MAYSWAP_32 (recsize.sint);
1312  break;
1313  case 2:
1314  f->record->size = recsize.sint;
1315  break;
1316  default:
1317  f->record->size = COB_MAYSWAP_16 (recsize.sshort[0]);
1318  break;
1319  }
1320  }
1321 
1322  /* Read record */
1323  bytesread = read (f->fd, f->record->data, f->record->size);
1324  if (unlikely(bytesread != (int)f->record->size)) {
1325  if (bytesread == 0) {
1327  } else if (bytesread < 0) {
1329  } else {
1331  }
1332  }
1333  return COB_STATUS_00_SUCCESS;
1334 }
static int sequential_rewrite ( cob_file f,
const int  opt 
)
static

References COB_NOT_CONFIGURED, COB_STATUS_00_SUCCESS, COB_STATUS_30_PERMANENT_ERROR, COB_UNUSED, cob_field::data, cob_file::fd, cob_file::flag_operation, cob_file::record, and cob_field::size.

1408 {
1409 #ifdef WITH_SEQRA_EXTFH
1410  int extfh_ret;
1411 
1412  extfh_ret = extfh_sequential_rewrite (f, opt);
1413  if (extfh_ret != COB_NOT_CONFIGURED) {
1414  return extfh_ret;
1415  }
1416 #else
1417  COB_UNUSED (opt);
1418 #endif
1419  f->flag_operation = 1;
1420  if (lseek (f->fd, -(off_t) f->record->size, SEEK_CUR) == (off_t)-1) {
1422  }
1423  if (write (f->fd, f->record->data, f->record->size) != (int)f->record->size) {
1425  }
1426  return COB_STATUS_00_SUCCESS;
1427 }
static int sequential_write ( cob_file f,
const int  opt 
)
static

References COB_MAYSWAP_16, COB_MAYSWAP_32, COB_NOT_CONFIGURED, cob_seq_write_opt(), COB_STATUS_00_SUCCESS, COB_STATUS_30_PERMANENT_ERROR, cob_varseq_type, cob_vsq_len, COB_WRITE_AFTER, COB_WRITE_BEFORE, cob_field::data, cob_file::fd, cob_file::flag_needs_nl, cob_file::flag_operation, cob_file::record, cob_file::record_max, cob_file::record_min, cob_field::size, and unlikely.

1338 {
1339  union {
1340  unsigned char sbuff[4];
1341  unsigned short sshort[2];
1342  unsigned int sint;
1343  } recsize;
1344 
1345 #ifdef WITH_SEQRA_EXTFH
1346  int extfh_ret;
1347 
1348  extfh_ret = extfh_sequential_write (f, opt);
1349  if (extfh_ret != COB_NOT_CONFIGURED) {
1350  return extfh_ret;
1351  }
1352 #endif
1353 
1354  if (unlikely(f->flag_operation == 0)) {
1355  f->flag_operation = 1;
1356  lseek (f->fd, (off_t)0, SEEK_CUR);
1357  }
1358 
1359  /* WRITE AFTER */
1360  if (unlikely(opt & COB_WRITE_AFTER)) {
1361  if (cob_seq_write_opt (f, opt)) {
1363  }
1364  f->flag_needs_nl = 1;
1365  }
1366 
1367  if (unlikely(f->record_min != f->record_max)) {
1368  /* Write record size */
1369 
1370  switch (cob_varseq_type) {
1371  case 1:
1372  recsize.sint = COB_MAYSWAP_32 (f->record->size);
1373  break;
1374  case 2:
1375  recsize.sint = f->record->size;
1376  break;
1377  default:
1378  recsize.sint = 0;
1379  recsize.sshort[0] = COB_MAYSWAP_16 (f->record->size);
1380  break;
1381  }
1382 
1383  if (unlikely(write (f->fd, recsize.sbuff, cob_vsq_len) !=
1384  (int)cob_vsq_len)) {
1386  }
1387  }
1388 
1389  /* Write record */
1390  if (unlikely(write (f->fd, f->record->data, f->record->size) !=
1391  (int)f->record->size)) {
1393  }
1394 
1395  /* WRITE BEFORE */
1396  if (unlikely(opt & COB_WRITE_BEFORE)) {
1397  if (cob_seq_write_opt (f, opt)) {
1399  }
1400  f->flag_needs_nl = 0;
1401  }
1402 
1403  return COB_STATUS_00_SUCCESS;
1404 }
static int sort_cmps ( const unsigned char *  s1,
const unsigned char *  s2,
const size_t  size,
const unsigned char *  col 
)
static

References unlikely.

Referenced by cob_file_sort_compare().

5599 {
5600  size_t i;
5601  int ret;
5602 
5603  if (unlikely(col)) {
5604  for (i = 0; i < size; ++i) {
5605  if ((ret = col[s1[i]] - col[s2[i]]) != 0) {
5606  return ret;
5607  }
5608  }
5609  } else {
5610  for (i = 0; i < size; ++i) {
5611  if ((ret = s1[i] - s2[i]) != 0) {
5612  return ret;
5613  }
5614  }
5615  }
5616  return 0;
5617 }
static COB_INLINE void unique_copy ( unsigned char *  s1,
const unsigned char *  s2 
)
static

Referenced by cob_file_sort_compare(), and cob_file_sort_submit().

5621 {
5622  size_t size;
5623 
5624  size = sizeof(size_t);
5625  do {
5626  *s1++ = *s2++;
5627  } while (--size);
5628 }

Variable Documentation

unsigned int check_eop_status
static
unsigned int cob_do_sync
static

Referenced by cob_init_fileio(), and save_status().

char* cob_do_sync_env
static

Referenced by cob_init_fileio().

char* cob_file_path
static
char* cob_file_path_env
static

Referenced by cob_init_fileio().

unsigned int cob_ls_fixed
static

Referenced by cob_init_fileio(), and lineseq_write().

char* cob_ls_fixed_env
static

Referenced by cob_init_fileio().

unsigned int cob_ls_nulls
static
char* cob_ls_nulls_env
static

Referenced by cob_init_fileio().

unsigned int cob_ls_uses_cr
static

Referenced by cob_init_fileio(), and lineseq_write().

char* cob_ls_uses_cr_env
static

Referenced by cob_init_fileio().

size_t cob_sort_chunk
static
char* cob_sort_chunk_env
static

Referenced by cob_init_fileio().

size_t cob_sort_memory
static

Referenced by cob_init_fileio(), and cob_new_item().

char* cob_sort_memory_env
static

Referenced by cob_init_fileio().

unsigned int cob_varseq_type
static
char* cob_varseq_type_env
static

Referenced by cob_init_fileio().

size_t cob_vsq_len
static
cob_global* cobglobptr
static
unsigned int eop_status
static
struct file_list* file_cache
static

Referenced by cob_cache_file(), and cob_close().

char* file_open_env
static
char* file_open_name
static
struct cob_fileio_funcs* fileio_funcs[COB_ORG_MAX]
static
const char* const prefix[] = { "DD_", "dd_", "" }
static
char* runtime_buffer
static
const int status_exception[]
static
Initial value:
= {
0,
COB_EC_I_O_AT_END,
COB_EC_I_O_PERMANENT_ERROR,
COB_EC_I_O_IMP
}

Referenced by save_status().