[Patch, fortran]: prevent clobbered by 'longjmp' or 'vfork
Jack Howarth
howarth@bromo.msbb.uc.edu
Mon Oct 2 00:55:00 GMT 2006
Andrew,
I thought the problem is that once setjmp() is called, any additional
calls to longjump or vfork would leave type with an indeterminate value.
The code in question has a lot of subroutine calls between the setjmp()
and the later uses of type....
static void
list_formatted_read_scalar (st_parameter_dt *dtp, bt type, void *p, int kind,
size_t size)
{
char c;
int m;
jmp_buf eof_jump;
dtp->u.p.namelist_mode = 0;
dtp->u.p.eof_jump = &eof_jump;
if (setjmp (eof_jump))
{
generate_error (&dtp->common, ERROR_END, NULL);
goto cleanup;
}
if (dtp->u.p.first_item)
{
dtp->u.p.first_item = 0;
dtp->u.p.input_complete = 0;
dtp->u.p.repeat_count = 1;
dtp->u.p.at_eol = 0;
c = eat_spaces (dtp);
if (is_separator (c))
{ /* Found a null value. */
eat_separator (dtp);
dtp->u.p.repeat_count = 0;
/* eat_separator sets this flag if the separator was a comma */
if (dtp->u.p.comma_flag)
goto cleanup;
/* eat_separator sets this flag if the separator was a \n or \r */
if (dtp->u.p.at_eol)
finish_separator (dtp);
else
goto cleanup;
}
}
else
{
if (dtp->u.p.input_complete)
goto cleanup;
if (dtp->u.p.repeat_count > 0)
{
if (check_type (dtp, type, kind))
return;
goto set_value;
}
if (dtp->u.p.at_eol)
finish_separator (dtp);
else
{
eat_spaces (dtp);
/* trailing spaces prior to end of line */
if (dtp->u.p.at_eol)
finish_separator (dtp);
}
dtp->u.p.saved_type = BT_NULL;
dtp->u.p.repeat_count = 1;
}
switch (type)
{
case BT_INTEGER:
read_integer (dtp, kind);
break;
case BT_LOGICAL:
read_logical (dtp, kind);
break;
case BT_CHARACTER:
read_character (dtp, kind);
break;
case BT_REAL:
read_real (dtp, kind);
break;
case BT_COMPLEX:
read_complex (dtp, kind, size);
break;
default:
internal_error (&dtp->common, "Bad type for list read");
}
if (dtp->u.p.saved_type != BT_CHARACTER && dtp->u.p.saved_type != BT_NULL)
dtp->u.p.saved_length = size;
if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
goto cleanup;
set_value:
switch (dtp->u.p.saved_type)
{
case BT_COMPLEX:
case BT_INTEGER:
case BT_REAL:
case BT_LOGICAL:
memcpy (p, dtp->u.p.value, size);
break;
case BT_CHARACTER:
if (dtp->u.p.saved_string)
{
m = ((int) size < dtp->u.p.saved_used)
? (int) size : dtp->u.p.saved_used;
memcpy (p, dtp->u.p.saved_string, m);
}
else
/* Just delimiters encountered, nothing to copy but SPACE. */
m = 0;
if (m < (int) size)
memset (((char *) p) + m, ' ', size - m);
break;
case BT_NULL:
break;
}
if (--dtp->u.p.repeat_count <= 0)
free_saved (dtp);
cleanup:
dtp->u.p.eof_jump = NULL;
}
Can you really be sure that neither longjmp or vfork will be invoked
in those subroutine calls?
Jack
ps I also found another discussion of this at...
http://mail.python.org/pipermail/python-dev/2000-July/005432.html
More information about the Fortran
mailing list