arogue5: fix some daemon-related pointer/int casting.

Daemons and fuses take a single argument, nominally an int but either
ignored or unsafely cast to a pointer.  Its type has now been changed
to void*.

The save/restore code no longer tries to store this argument in the
savefile.  For doctor(), this is not a problem, because player is the
only argument it is ever given as a daemon.  However, alchemy() will
fail to do anything when passed NULL.  Fixing this would be complicated
but possible.

Summary: the code is slightly safer, but alchemy jugs are guaranteed to
stop working after save and restore, instead of just extremely likely.
This commit is contained in:
John "Elwin" Edwards 2014-03-28 10:57:03 -07:00
parent dff96acf36
commit 7b0ec1230e
3 changed files with 9 additions and 10 deletions

View file

@ -87,8 +87,7 @@ reg int (*func)();
* start_daemon: * start_daemon:
* Start a daemon, takes a function. * Start a daemon, takes a function.
*/ */
start_daemon(func, arg, type) start_daemon(int (*func)(), void *arg, int type)
reg int arg, type, (*func)();
{ {
reg struct delayed_action *dev; reg struct delayed_action *dev;
@ -122,7 +121,7 @@ reg int (*func)();
* Take it out of the list * Take it out of the list
*/ */
dev->d_type = EMPTY; dev->d_type = EMPTY;
dev->d_arg = 0; dev->d_arg = NULL;
dev->d_func = NULL; dev->d_func = NULL;
dev->d_time = 0; dev->d_time = 0;
demoncnt -= 1; /* update count */ demoncnt -= 1; /* update count */
@ -155,8 +154,7 @@ reg int flag;
* fuse: * fuse:
* Start a fuse to go off in a certain number of turns * Start a fuse to go off in a certain number of turns
*/ */
fuse(func, arg, time, type) fuse(int (*func)(), void *arg, int time, int type)
reg int (*func)(), arg, time, type;
{ {
reg struct delayed_action *wire; reg struct delayed_action *wire;
@ -199,7 +197,7 @@ reg int (*func)();
return; return;
wire->d_type = EMPTY; wire->d_type = EMPTY;
wire->d_func = NULL; wire->d_func = NULL;
wire->d_arg = 0; wire->d_arg = NULL;
wire->d_time = 0; wire->d_time = 0;
fusecnt -= 1; fusecnt -= 1;
} }

View file

@ -725,7 +725,7 @@
struct delayed_action { struct delayed_action {
int d_type; int d_type;
int (*d_func)(); int (*d_func)();
int d_arg; void *d_arg;
int d_time; int d_time;
}; };

View file

@ -1420,7 +1420,8 @@ rs_write_daemons(FILE *savef, struct delayed_action *d_list, int count)
rs_write_int(savef, d_list[i].d_type); rs_write_int(savef, d_list[i].d_type);
rs_write_int(savef, func); rs_write_int(savef, func);
rs_write_int(savef, d_list[i].d_arg); /* d_arg is a pointer and can't actually be saved and restored. */
rs_write_int(savef, 0);
rs_write_int(savef, d_list[i].d_time); rs_write_int(savef, d_list[i].d_time);
} }
@ -1517,7 +1518,8 @@ rs_read_daemons(int inf, struct delayed_action *d_list, int count)
break; break;
} }
rs_read_int(inf, &d_list[i].d_arg); rs_read_int(inf, &dummy);
d_list[i].d_arg = NULL;
if (func == 2) if (func == 2)
d_list[i].d_arg = &player; d_list[i].d_arg = &player;
rs_read_int(inf, &d_list[i].d_time); rs_read_int(inf, &d_list[i].d_time);
@ -1525,7 +1527,6 @@ rs_read_daemons(int inf, struct delayed_action *d_list, int count)
if (d_list[i].d_func == NULL) if (d_list[i].d_func == NULL)
{ {
d_list[i].d_time = 0; d_list[i].d_time = 0;
d_list[i].d_arg = 0;
d_list[i].d_type = 0; d_list[i].d_type = 0;
} }
} }