Skip to content

Commit

Permalink
Merge SVN 4981
Browse files Browse the repository at this point in the history
  • Loading branch information
ddeclerck committed Sep 27, 2024
1 parent c693ec0 commit 86227d6
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 44 deletions.
8 changes: 8 additions & 0 deletions libcob/ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,14 @@
warnings
* cconv.c (cob_load_collation), common.c, intrinisic.c (cob_intr_random),
termio.c: minor adjustments to fix compiler warnings
* fileio.c (copy_fcd_to_file)->fextfh.c: fixed memory issues with
writing to assign and select name
* fileio.c (save_status): don't synch directly after open or close
* fileio.c (cob_file_open), (open_next): include binary in open flags if
cobsetptr->cob_unix_lf is set
* fileio.c (open_next): set binary file mode, minor refactoring
* fileio.c (cob_file_close) [_WIN32]: don't try to unlock invalid file
handles; mark file descriptor as closed when file handle was closed

2023-02-06 Simon Sobisch <[email protected]>

Expand Down
25 changes: 16 additions & 9 deletions libcob/fextfh.c
Original file line number Diff line number Diff line change
Expand Up @@ -564,8 +564,9 @@ copy_fcd_to_file (FCD3* fcd, cob_file *f, struct fcd_file *fcd_list_entry)
}
} else if(fcd->fileOrg == ORG_RELATIVE) {
f->organization = COB_ORG_RELATIVE;
if (f->keys == NULL)
if (f->keys == NULL) {
f->keys = cob_cache_malloc(sizeof(cob_file_key));
}
if (f->keys[0].field == NULL) {
f->keys[0].field = cob_cache_malloc(sizeof(cob_field));
f->keys[0].field->data = cob_cache_malloc (4);
Expand Down Expand Up @@ -628,25 +629,29 @@ copy_fcd_to_file (FCD3* fcd, cob_file *f, struct fcd_file *fcd_list_entry)
/* build select name from assign value, if missing */
if (f->select_name == NULL
&& f->assign != NULL) {
const int max_size = ((int)f->assign->size > 48)
? 48 : (int)f->assign->size;
char fdname[49];
char *origin = (char*)f->assign->data;
/* limit filename to last element after
path separator, when specified */
for (k=(int)f->assign->size - 1; k; k--) {
for (k = max_size - 1; k; k--) {
if (f->assign->data[k] == SLASH_CHAR
#ifdef _WIN32
|| f->assign->data[k] == '/'
#endif
) {
origin = (char*)&f->assign->data[k+1];
origin = (char *)f->assign->data + k + 1;
break;
}
}
/* now copy that until the first space/low-value (max 48) as upper-case */
for (k=0; origin[k] && origin[k] > ' ' && k < 48; k++) {
/* now copy that until the first space/low-value up to
max_size as upper-case */
for (k = 0; origin[k] && origin[k] > ' ' && k < max_size; k++) {
fdname[k] = (char)toupper((int)origin[k]);
}
fdname[k] = 0;
k++; /* copy with trailing NUL */
/* we don't necessarily know later if we built the name ourself,
so we need to cache the storage */
f->select_name = cob_cache_malloc (k);
Expand Down Expand Up @@ -1391,7 +1396,7 @@ EXTFH3 (unsigned char *opcode, FCD3 *fcd)

int opcd,sts,opts,eop,k;
unsigned char fnstatus[2]; /* storage for local file status field */
unsigned char keywrk[80];
unsigned char keywrk[80]; /* key data used for IDX, if not passed */
char fname[COB_FILE_MAX];
/* different cob_fields as some ABI functions operate on those */
cob_field fs[1];
Expand Down Expand Up @@ -1420,7 +1425,7 @@ EXTFH3 (unsigned char *opcode, FCD3 *fcd)
COB_MODULE_PTR = cob_malloc( sizeof(cob_module) );
COB_MODULE_PTR->module_name = "GnuCOBOL-fileio";
COB_MODULE_PTR->module_source = "GnuCOBOL-fileio";
COB_MODULE_PTR->module_formatted_date = "2021/10/03 12:01:20";
COB_MODULE_PTR->module_formatted_date = "2023/02/06 12:01:20";
}

if (*opcode == 0xFA) {
Expand Down Expand Up @@ -1482,10 +1487,12 @@ EXTFH3 (unsigned char *opcode, FCD3 *fcd)
if (opcd == OP_GETINFO) {
if (fcd->fnamePtr) {
k = strlen(fcd->fnamePtr);
if (k > LDCOMPX2(fcd->fnameLen))
if (k > LDCOMPX2(fcd->fnameLen)) {
k = LDCOMPX2(fcd->fnameLen);
while (k > 0 && fcd->fnamePtr[k-1] == ' ')
}
while (k > 0 && fcd->fnamePtr[k-1] == ' ') {
--k;
}
memcpy (fname, fcd->fnamePtr, k);
fname[k] = 0;
f->flag_auto_type = 1;
Expand Down
101 changes: 66 additions & 35 deletions libcob/fileio.c
Original file line number Diff line number Diff line change
Expand Up @@ -3428,7 +3428,9 @@ cob_file_save_status (cob_file *f, cob_field *fnstatus, const int status)
#endif
eop_status = 0;
}
if ((f->file_features & COB_FILE_SYNC)) {
if ((f->file_features & COB_FILE_SYNC)
&& f->last_operation != COB_LAST_OPEN
&& f->open_mode != COB_OPEN_CLOSED) {
cob_file_sync (f);
}
} else if (!skip_exn) {
Expand Down Expand Up @@ -4240,22 +4242,24 @@ cob_fd_file_open (cob_file *f, char *filename,
if ((ret=set_file_lock(f, filename, mode)) != 0)
return ret;
f->record_off = -1;
#if 0 /* Simon: disabled, this function is expected to not use a file */
#if 0 /* Simon: disabled, this function is expected to not use a FILE* */
{
const char *fmode;
const char *fopen_flags;
if (mode == COB_OPEN_INPUT) {
fmode = "r";
fopen_flags = "r";
} else if (mode == COB_OPEN_I_O) {
if (nonexistent)
fmode = "w+";
fopen_flags = "w+";
else
fmode = "r+";
fopen_flags = "r+";
} else if (mode == COB_OPEN_EXTEND) {
fmode = "";
fopen_flags = "";
} else {
fmode = "w";
fopen_flags = "w";
}
f->file = (void*)fdopen(f->fd, fmode);
/* note: _if_ this is activated (which likely needs adjustments in
other places) then also handle cobsetptr->cob_unix_lf */
f->file = (void*)fdopen(f->fd, fopen_flags);
}
#endif
if (f->flag_optional && nonexistent) {
Expand Down Expand Up @@ -4486,7 +4490,6 @@ cob_file_open (cob_file_api *a, cob_file *f, char *filename,
}
}

fmode = NULL;
/* Open the file */
switch (mode) {
case COB_OPEN_INPUT:
Expand Down Expand Up @@ -4544,6 +4547,7 @@ cob_file_open (cob_file_api *a, cob_file *f, char *filename,
break;
/* LCOV_EXCL_START */
default:
fmode = NULL;
cob_runtime_error (_("invalid internal call of %s"), "cob_file_open");
cob_fatal_error (COB_FERROR_CODEGEN);
/* LCOV_EXCL_STOP */
Expand Down Expand Up @@ -4688,10 +4692,10 @@ cob_file_close (cob_file_api *a, cob_file *f, const int opt)
COB_CHECKED_WRITE (f->fd, "\n", 1);
}
}
#ifdef HAVE_FCNTL
/* Unlock the file */
if (f->fd >= 0
&& !f->flag_is_pipe) {
#ifdef HAVE_FCNTL
struct flock lock;
memset ((void *)&lock, 0, sizeof (struct flock));
lock.l_type = F_UNLCK;
Expand All @@ -4702,14 +4706,13 @@ cob_file_close (cob_file_api *a, cob_file *f, const int opt)
if (fcntl (f->fd, F_SETLK, &lock) == -1) {
cob_runtime_warning ("issue during unlock (%s), errno: %d", "cob_file_close", errno);
}
}
#elif defined _WIN32
{
HANDLE osHandle = (HANDLE)_get_osfhandle (f->fd);
if (osHandle != INVALID_HANDLE_VALUE) {
{
HANDLE osHandle = (HANDLE)_get_osfhandle (f->fd);
/* CHECKME: Should this use UnlockFileEx ? */
if (!UnlockFile (osHandle, 0, 0, MAXDWORD, MAXDWORD)) {
#if 0 /* CHECKME - What is the correct thing to do here? */
if (osHandle != INVALID_HANDLE_VALUE
&& !UnlockFile (osHandle, 0, 0, MAXDWORD, MAXDWORD)) {
#if 0 /* CHECKME - What is the correct thing to do here? */
const DWORD last_error = GetLastError ();
if (last_error != 158) { /* no locked region */
/* not translated as "testing only" */
Expand All @@ -4719,16 +4722,16 @@ cob_file_close (cob_file_api *a, cob_file *f, const int opt)
#endif
}
}
}
#endif
}
/* Close the file */
if (f->organization == COB_ORG_LINE_SEQUENTIAL) {
if (f->flag_is_pipe) {
if (f->file_pid) {
if (f->file)
fclose (f->file);
if (f->fileout
&& f->fileout != f->file)
&& f->fileout != f->file)
fclose (f->fileout);
#if defined (HAVE_UNISTD_H) && !(defined (_WIN32))
{
Expand Down Expand Up @@ -4765,7 +4768,10 @@ cob_file_close (cob_file_api *a, cob_file *f, const int opt)
if (f->file != NULL) {
fclose ((FILE *)f->file);
f->file = NULL;
#ifdef _WIN32
/* at least on MSVC that closes the underlying file descriptor, too */
f->fd = -1;
#endif
}
#endif
} else {
Expand Down Expand Up @@ -4802,37 +4808,57 @@ open_next (cob_file *f)
{
if (f->flag_is_concat
&& *f->nxt_filename != 0) {
char *nx = strchr(f->nxt_filename,file_setptr->cob_concat_sep[0]);
char *nx = strchr (f->nxt_filename,file_setptr->cob_concat_sep[0]);
int fmode = O_BINARY; /* without this ftell does not work on some systems */

#ifdef _WIN32 /* win32 seems to resolve the file descriptor from the file handler
on fclose - and then aborts because it was closed directly before */
if (f->file) {
fclose (f->file);
} else {
close (f->fd);
}
#else
close (f->fd);
if (f->file) {
fclose (f->file);
}
f->fd = -1;
f->file = NULL;
#endif
if (f->open_mode == COB_OPEN_I_O) {
fmode |= O_RDWR;
} else {
fmode |= O_RDONLY;
}
if (nx) {
*nx = 0;
if (f->open_mode == COB_OPEN_I_O)
f->fd = open (f->nxt_filename, O_RDWR);
else
f->fd = open (f->nxt_filename, O_RDONLY);
f->fd = open (f->nxt_filename, fmode);
f->nxt_filename = nx + 1;
} else {
if (f->open_mode == COB_OPEN_I_O)
f->fd = open (f->nxt_filename, O_RDWR);
else
f->fd = open (f->nxt_filename, O_RDONLY);
f->fd = open (f->nxt_filename, fmode);
f->flag_is_concat = 0;
if (f->org_filename) {
cob_free (f->org_filename);
f->org_filename = NULL;
}
}
if (f->fd != -1) {
if (f->open_mode == COB_OPEN_INPUT) {
f->file = (void*)fdopen(f->fd, "r");
if (f->fd == -1) {
f->file = NULL;
} else {
const char *fopen_flags;
if (cobsetptr->cob_unix_lf) {
if (f->open_mode == COB_OPEN_INPUT) {
fopen_flags = "rb";
} else {
fopen_flags = "rb+";
}
} else {
f->file = (void*)fdopen(f->fd, "r+");
if (f->open_mode == COB_OPEN_INPUT) {
fopen_flags = "r";
} else {
fopen_flags = "r+";
}
}
f->file = (void*)fdopen(f->fd, fopen_flags);
return 1;
}
}
Expand Down Expand Up @@ -5176,6 +5202,9 @@ lineseq_read (cob_file_api *a, cob_file *f, const int read_opts)
if (!f->flag_is_pipe) {
f->record_off = ftell (fp); /* Save position at start of line */
}
/* Note: at least on Win32 the offset resolved does only return the right values
when file was opened in binary mode -> cob_unix_lf; as an alternative
we could increment the record_off field on each read/write */
for (; ;) {
n = getc (fp);
if (n == EOF) {
Expand Down Expand Up @@ -5550,6 +5579,7 @@ lineseq_rewrite (cob_file_api *a, cob_file *f, const int opt)
psize = size;
slotlen = curroff - f->record_off - 1;
if ((f->file_features & COB_FILE_LS_CRLF)) {
/* CHECKME: likely also needed if not opened with unix-lf */
slotlen--;
}
if ((f->file_features & COB_FILE_LS_NULLS)
Expand Down Expand Up @@ -9791,7 +9821,8 @@ cob_init_fileio (cob_global *lptr, cob_settings *sptr)
file_open_buff = runtime_buffer + (3 * COB_FILE_BUFF);

/* TRANSLATORS: This msgid is concatenated with a filename;
setup translation to allow this to be followed on the right side. */
setup translation to allow this to be followed on the right side,
if necessary use a colon or hyphen */
implicit_close_of_msgid = _("implicit CLOSE of ");

file_api.glbptr = file_globptr = lptr;
Expand Down

0 comments on commit 86227d6

Please sign in to comment.