Player input may overtake batch file contents (well-known protocol
flaw, see doc/clients-howto for details). This includes EOF. When
that happens, the client closes standard input, sends an EOF cookie,
and continues reading output until the server closes the connection.
When it gets C_EXECUTE, it redirects input to the batch file. But it
then failed to read the batch file. The server waited forever for the
execute's EOF cookie, the client waited forever for the server closing
the connection.
Fix by stopping only reading from standard input. Broken in 8b7d0b91,
v4.3.11.
Note that the EOF cookie still overtakes the batch file contents,
which makes the server interpret the input between the execute command
and the EOF as batch file, and the batch file contents as ordinary
input.
This is for consistency with aerial mining. Seamines don't work under
bridges anyway (they did a long time ago, until Empire 2).
Making seamines work under bridges again wouldn't be hard, but it
would make the 'X' in bmaps ambiguous.
Seamines and landmines share storage. Sea and bridge span sectors can
hold only sea mines, other sector types only landmines. Sector type
checks were missing or incorrect in several places:
* Seamines under bridge spans were mistaken for landmines in several
places:
- ground combat mine defense bonus, in get_mine_dsupport() and
stre(),
- land units retreating from bombs, in retreat_land1(),
- non-land unit ground movement (commands explore, move, transport,
and INTERDICT_ATT of military), in check_lmines(),
Fix them to check the sector type with new SCT_MINES_ARE_SEAMINES(),
SCT_LANDMINES().
* plane_sweep() mistook landmines for seamines in harbors. Bug could
not bite, because it's only called for sea sectors. Drop the bogus
check for harbor.
* Collapsing a bridge tower magically converted landmines into
seamines. Make knockdown() clear landmines.
Also use SCT_MINES_ARE_SEAMINES() and SCT_LANDMINES() in mine(),
landmine(), lnd_sweep() and lnd_check_mines(). No functional change
there.
Keep checking only for sea in pln_mine(), plane_sweep(),
retreat_ship1(), shp_sweep() and shp_check_one_mines(). This means
seamines continue not to work under bridges. Making them work there
is tempting, but as long as finding seamines clobbers the sector
designation in the bmap, it's better to have them in sea sectors only.
Historical notes:
Mines started out simple enough: you could mine sea and bridge spans,
and ships hit and swept mines in foreign sectors.
Chainsaw 2 introduced aerial mining and sweeping. Unlike ships,
planes could not mine bridge spans. plane_sweep() could sweep
harbors, which was wrong, but it was never called there, so the bug
could not bite.
Chainsaw 3 introduced landmines. The idea was to permit only seamines
in some sector types, and only landmines in the others, so they can
share storage. To figure out whether a sector has a particular kind
of mines, you need to check the sector type. Such checks already
existed in mine, drop and sweep, and they were kept unchanged. The
new lmine command also got the check. Everything else did not.
Ground movement and combat could hit and sweep seamines in bridge
spans. Ships could hit and sweep landmines in harbors.
Empire 2 fixed land unit movement (march, INTERDICT_ATT) not to
mistake seamines for landmines on bridge spans. It fixed ships not to
mistake landmines for seamines. The fix also neutered seamines under
bridge spans: ships could neither hit nor sweep them anymore. Both
fixes missed retreat.
Commit 5663713b (v4.3.1) made ship retreat consistent with other ship
movement.
Commit fbf9f15b removed SO, SE, but left their declarations behind.
Ditto commit 3aea20e1 for bigcity_dchr, and commit 08b94556 for
player_kill_idle.
Commit afa65c8f accidentally added a declaration for xedit().
Pinpointed assignments within if conditionals with spatch -sp_file
tests/bad_assign.cocci (from coccinelle-0.1.4). Cherry-picked diff
hunks affecting conditionals split over multiple lines, and cleaned
them up.
Crash dump forks a child to call abort(). abort() may flush or close
streams. This is unwelcome, because it can mess up streams in the
parent. Observed with the journal. Could theoretically also affect
commands info, read, turn, and wire; announcement expiry, and reading
of econfig and schedule.
Fix by using SIGABRT instead.
Note that flushing streams before fork() is not a sufficient fix,
because closing a stream can still move the file descriptor's file
position. Do it anyway, to ensure any buffered output is visible to
post_crash_dump_hook.
The commands to fly planes read the planes into a plane list, and
write them back when they land. If a plane changes in the file while
it is in that plane list, the changes get wiped out when the plane
lands, triggering a seqno oops.
This is not an issue as long as the complete sortie runs
uninterrupted, because that code takes care to update flying planes
only through the appropriate plane list.
However, the bomb command suspends the planes on a pinpoint bombing
run mid-air over the target sector to let the player choose targets.
This lets code run that *can* update flying planes, for instance the
edit command.
Fix by aborting changed planes, taking care not to clobber the
changes.
When bombing ships with a force containing both planes with and
without capability ASW, pin_bomb() could fail to report presence of
submarines, and could refuse to bomb ships when there were only
submarines. The culprit is pin_bomb()'s check for capability ASW: it
checked whether the first plane in the plane list was capable instead
of checking whether any plane in the list was capable.
A victorious attacker can move attacking land units into the newly
conquered sector or leave them behind. Normally, the player is asked
what to do, but when the land unit's army has already been told to
stay behind, or the command has been aborted, the land unit stays
behind without asking. In that case, a copy of the land unit made
right after the victory was written back. Any updates since the
victory were wiped out, triggering a seqno mismatch oops.
Fix by moving the re-read of the land unit in ask_move_in() out of the
prompt conditional.
check_loan_ok(), check_comm_ok() and check_trade_ok() should have been
changed to ignore timestamps when timestamps were added to their files
in commit a680c811, v4.3.12.
pthread.c's empth_select() returned -1 when empth_wakeup() interrupted
select(). The failure then got propagated all the way up, and the
player got logged out. Fix by returning 0 in that case. While there,
retry on EINTR, to match LWP. Also clarify comments.
Unused since 4.3.10. Can be used safely only in very special
circumstances.
Removal allows simplifying pthread.c and ntthread.c some. liblwp left
alone.
Make didn't remake sources.mk even though it was a phony target. I
don't understand why. But we can just as well create it in its only
user, dist-source.
Change s_commod() not to use the supply sink as source. As explained
in the message of the commit before the previous one, using the sink
as source makes it impossible for callers to safely keep a copy of the
sink across a supply call. All current users do that. Some were safe
anyway, some were not:
* fort_fire() was safe, because a fort draws shells only when it has
none.
* shp_fire() was unsafe for ships with capability supply and ammo use
greater than 1. No such ship exists in the stock game.
* shp_dchrg() was unsafe for ships with both capabilities dchrg and
supply. Same for shp_torp() and capability torp, and
shp_missile_defense() and capability anti-missile. No such ship
exists in the stock game.
* lnd_fire(), supp() and get_dlist() were safe, because they draw
shells only when they have less than their ammo need, and then they
don't supply any.
* mission_pln_equip() was unsafe when equipping planes with shells in
supply sources.
* landmine() was unsafe for land units with both capability engineer
and supply. No such land units exist in the stock game.
* load() and lload() were unsafe for loadable supply units, but the
supply use there was disabled in commit 65410d16 because of another
bug.
* ask_olist() and att_reacting_units() were safe, because
lnd_can_attack() excludes supply units.
In the stock game, planes flying interception or support missions,
abms intercepting ballistic missiles, launch of missiles or anti-sats
could conjure up shells, triggering a seqno mismatch oops.
In games with unusual customizations, this could also happen with
supply ships firing guns or torpedoes, dropping depth charges, or
shooting down marine missiles, and in the lmine command.
To implement the supply from self avoidance described in the previous
commit's message, s_commod() needs to be redesigned along the same
principles: take the sink as argument, update and put it. Also take
an item limit argument, and return whether supply request was fully
met.
Update sct_supply(), shp_supply(), lnd_supply() and
lnd_could_be_supplied(). The former three become straighforward
wrappers.
supply_commod() and try_supply_commod() are now unused, remove them.