Don't set IO_EOF when writev() returns zero. I don't think this could
happen, but it's wrong anyway, because a short write should not stop
future reads.
The blocking I/O option makes no sense in the server, because it
blocks the server process instead of the thread. In fact, it's been
unused since Empire 2, except for one place, where it was used
incorrectly, and got removed in the previous commit.
Make I/O non-blocking in io_open() unconditionally. Remove IO_NBLOCK
and io_noblocking().
The call switched the connection with the player to blocking I/O for
draining of output before closing the connection. Looks scary,
because blocking on I/O blocks the complete server process, not just
the player thread. But we don't do input, and we do output only with
IO_WAIT, which can't block. So this has no effect.
Chainsaw used this together with the notify callback to make the iop
data type usable for sockets it listened on, so that io_select() could
multiplex them along with the sockets used for actual I/O.
io_select() became unused in Empire 2, and finally got removed in
commit 875d72a0, v4.2.13. That made the IO_NEWSOCK and the notify
callback defunct. The latter got removed in commit 7d5a6b81, v4.3.1.
Fix empth_sleep() for argument in the past and pthreads
Calculation of sleep duration suffered integer underflow for unsigned
time_t and arguments in the past. This made empth_sleep() sleep for
"a few" years instead of not at all.
F_GETFL always failed with WSAEINVAL. io_noblocking() always failed
without doing anything. Callers didn't check for failure, and newly
opened sockets remained blocking. But because because
WSAEventSelect() makes sockets non-blocking automatically, they became
non-blocking soon enough to keep things working.
Remove the broken code to query the non-blocking state, and just
return 0. Document why this works.
While there, simplify the F_SETFL case by using ioctlsocket() instead
of WSAIoctl().
Replace the fixed $1 per ETU maintenance for capital/city sectors that
are at least 60% efficient by a configurable maintenance cost, payable
regardless of efficiency. The only change in the default
configuration is that inefficient capitals now pay maintenance.
Charging sector maintenance regardless of efficiency is consistent
with unit maintenance.
New struct dchrstr member d_maint and sector-chr selector maint. Make
show_sect_build() show it. Change produce_sect() to record
maintenance in new slot p_sect[SCT_MAINT] instead of abusing
p_sect[SCT_CAPIT]. Replace the "Capital maintenance" line in budget
by "Sector maintenance".
Print sector type mnemonic and name, like show sect s and c. Print
"can't" instead of negative number for sectors players can't designate
(this was not an issue before the previous commit). Show build cost
per 100%, like show ship, land, plane and nuke. Size the columns more
sensibly.
Fix show sect b not to omit undesignatable sectors
show sect b needs to explain any sector players can build.
show_sect_build() omitted sectors players can't designate. That's
wrong, because players can certainly own and thus build sectors they
can't designate. Test for infinite mobility cost instead, like
show_sect_stats().
Clean up automatic supply leftovers in ship update
Commit 7da69c92 (v4.3.20) removed use of automatic supply from
prod_ship(). It removed bp_enable_cachepath(), but left behind the
final bp_disable_cachepath(); bp_clear_cachepath(). Clean that up.
Fix mine production resource limit for peffic != 100%
With etu_per_update large and resource depletion quick, a sector can
produce more work than is required to fully deplete a mine. In that
case, produce() and prod() limit production to what is actually in the
ground. Except produce() got it wrong for sector types with
production efficiency other than 100%.
This affects mountains in the stock game, but only with impractically
large etu_per_update.
configure checked for library functions with LIBS instead of
LIBS_server, which could break detection of getaddrinfo() on systems
where LIB_SOCKET isn't empty.
GNUmakefile put @PTHREAD_LIBS@ only in LDLIBS, which breaks linking of
server and possibly client on systems where it is not empty.
We use the C run-time, so we better use its _beginthread(), too.
CreateThread() can lead to deadlocks, at least with some versions of
the C run-time. Broken in commit f082ef9f, v4.3.11.
Fix Windows client's stdin read thread's error handling
stdin_read_thread() zeroed bounce_status on failure, effectifely
treating it like EOF. Fix by setting to -1.
It treated main thread termination like failure, and set bounce_error
to a bogus value. Can't happen, because the program terminates when
the main thread terminates, and the only user of bounce_error is the
main thread anyway. Regardless, handle the case by terminating,
because that's more obviously correct.
Make Windows client read password without echo again
Commit 8c3b8d10 replaced the getpass() for Windows by a generic
ersatz_getpass(). This lost the "switch off echo" feature, with the
excuse that it doesn't work for me (MinGW & Wine). Turns out it works
under real Windows. Restore the feature.
The old upstream version carries the original BSD license, which is
incompatible with the GPL. Fix by rebasing to a version that is
licensed under the 2-clause BSD license.
Fix return value of s_commod() when it can't draw enough
s_commod() could incorrectly claim success when the sink ended up with
at least as many supplies than were missing initially. This caused a
number of problems:
* shp_torp() let a ship with two shells fire a torpedo, resulting in
-1 shells, which then made item_prewrite() oops. Affected missions
and return fire, but not the torpedo command.
* shp_missile_defense() let a ship with one shell use missile defense,
resulting in -1 shells, and the same item_prewrite() oops.
* Land units were considered in supply even when they had not quite
enough supplies. Such land units could defend without penalty,
attack and react. Commands load and lload weren't affected, because
they use lnd_in_supply(), which doesn't use s_commod().
upd_plane() upd_land() and left planes and land units lost to lack of
maintenance on their carriers. Cargo lists were fine anyway, because
unit_cargo_init() ignored dead units. But when the dead unit got
reused for building a new one, pln_prewrite() / lnd_prewrite() got
confused and attempted to take it off its carrier, which made
clink_rem() oops, because the unit wasn't on the cargo list. No real
harm done, as oops recovery was fine.
Fix upd_plane() and upd_land() to clear the carrier. Make
unit_cargo_init() oops when it finds dead units on carriers.
Checking Windows libraries with autoconf is cumbersome, because
linking often fails unless you include the header, and AC_SEARCH_LIBS
doesn't permit that.
Just detect the Windows API instead, with new MY_WINDOWS_API.
Should be more portable to modern systems and could be less portable
to obsolete systems than the traditional sys/time.h sys/types.h
unistd.h incantation.
getpass() is traditional Unix, but has been withdrawn from POSIX. As
such, it may be missing. Check for that, and provide ersatz. It's
not a real replacement, because it doesn't do the special magic
getpass() is supposed to do: read from /dev/tty without echo.
This bypasses our existing getpass() for Windows. In contrast to the
portable getpass(), the Windows one tries to turn off echo, but that
doesn't work for me (MinGW & Wine). Remove it.
Fix client not to hang when EOF on stdin overtakes C_EXECUTE
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.
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.
Clean up unreadable assignments within if conditionals
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.
Fix bomb not to wipe out plane updates while asking for targets
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.
Fix a bug in attack that could wipe out land unit updates
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.
Don't log out player when update aborts a command with pthreads
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.
Fix make dist in a separate build directory without git, really
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.
The automatic supply interface has design flaws that make it hard to
use correctly. Its current uses are in fact all wrong (until commit 0179fd86, the update had a few uses that might have been correct).
Some of the bugs can only bite with land unit capability combinations
that don't exist in the stock game, though.
Automatic supply draws supplies from supply sources in range. Since
that can update any supply source in range, all copies of potential
supply sources a caller may keep can get invalidated. Writing back
such an invalid copy wipes out the deduction of supplies and mobility
from a source, triggering a seqno mismatch oops.
This commit redesigns the interface so that callers can safely keep a
copy of the object drawing the supplies (the "supply sink"). The idea
is to pass the sink to the supply code, so it can avoid using it as
source. The actual avoiding will be implemented in a later commit.
Copies other than the supply sink still need to be eliminated. See
commit 65410d16 for an example.
Other improvements to help avoid common errors:
* Supply functions are commonly used to ensure the sink has a certain
amount of supplies. A common error is to fetch that amount
regardless of how many the sink already has. It's more convenient
for such users to pass how many they need to have instead of how
many to get.
* A common use of supply functions is to get supplies for immediate
use. If that use turns out not to be possible after all, the
supplies need to be added somewhere, which is all too easy to
forget. Many bugs of this kind have been fixed over time, and there
are still some left. This class of bugs can be avoided by adding
the supplies to the sink automatically.
In fact, this commit fixes precisely such bugs in mission_pln_equip()
and shp_missile_defense(): plane interception and support missions,
missile interception (abms), launch of ballistic missiles and
anti-sats could all lose shells, or supply more than needed.
Replace supply_commod() by new sct_supply(), shp_supply(),
lnd_supply(), and resupply_all() by new lnd_supply_all(). Simplify
users accordingly.
There's just one use of resupply_commod() left, in landmine(). Use
lnd_supply_all() there, and remove resupply_commod().
Don't let automatic supply starve the sector containing the sink
Automatic supply always leaves enough food to avoid starvation in
supply sources, except for one case: when drawing supplies from the
sector containing the sink.
This behavior contradicted info supply. However, do_feed() used to
rely on it (it would have wiped out food without it). Supply use
there was removed in commit 7da69c92, so we can now fix this.
Affected by this is the automatic food supply of land units in combat,
and the food supply in commands supply, load and lload. Except supply
is disabled due to bugs in the last two.