As besides the entries that are not supposed to compile/cannot compile
due to architectural limitations all the entries can compile in macOS
(though some do not work - yet(? I have plans to work on more later)) it
was not necessary to not silence the warnings after all as the entries
that don't work will be easy to identify ('they don't work' :-) ) so I
can just do make CSILENCE= all in the directory of those entries which
solves the problem I had originally thought of.
Some of the Makefiles have retained other changes I had to make
yesterday to get the entries to work with clang in linux but most of
them were either not changed or were made better with the rollback of
the commit that originally silenced warnings.
Now work on silencing warnings for linux can be done.
Due to the fact we now have .orig.c files and thus the possibility of
winner.orig or prog.orig being built I have updated all the .gitignore
files so that these files ignored. This was done with the following
shell commands, for reference:
for i in $(find 19* 200* 201[0123] -mindepth 2 -maxdepth 2 -name .gitignore) ; do echo $(dirname "$i"|sed -e 's,[0-9]\{4\}/,,g').orig >> "$i"; done
for i in $(find 201[4-9] 2020 -mindepth 2 -maxdepth 2 -name .gitignore) ; do echo prog.orig >> "$i"; done
and the two commands is because it was only in 2014 that the winning
entries were renamed to prog so prog.orig is the correct glob.
Used the following script to check for warnings
not silenced via ${CSILENCE}:
```sh
find ???? -mindepth 1 -maxdepth 1 -type d | while read dir; do
(cd "$dir"; echo =-=-= "$dir" =-=-= ; csilence -v 1 clobber all ; echo ; csilence -v 1 clobber alt)
done 2>&1 | less
```
The fix thank you's have been moved from `README.md` to
`thanks-for-fixes.md`.
**WARNING**: Some mistakes may have been made in doing this.
We presume later changes by others will correct any issues.
The `CONTRIBUTING.md` was renamed `how-to-enter.md`.
A 3rd line of links was added to top level html such as
`contact.html`, `index.html`, `judges.html`, `winners.html`,
and `years.html`.
Improved blank line use in a number (but not all) `README.md` files.
This sings a different counting song, Ten in the Bed. It uses another C
feature (a char *[]) that the Ten Green Bottles does not use. This is
for fun as well as to show another program (with a different C feature)
that the program works on, again assuming -m32 is allowed.
Instead of using numbers it uses strings (as expected with a char *[])
in the singing.
This was for fun (and to see if the program would work on arrays) after
I remembered the song in a comment on GitHub - about the Ten Green
Bottles song.
Running make alt will compile the anonymous.ten.c without specifying
-m32: whether it'll end up being 64-bit or not would depend on the
system but it'll be saved as anonymous.ten.64 anyway.
The try.me.sh script will run this program directly, skipping the entry
itself, if the anonymous.ten.c cannot be compiled as a 32-bit binary.
Updated .gitignore.
Added a couple git diff commands to try and moved the INABIAF and the
warning from the author to below the judges' comments as already most
people probably will want to skip past long before to the next section.
Perhaps the fix should be moved to under the judges' comments as well
but I don't know.
There is one exception that I'm aware of and that is the U macro (U is
referenced only in strings) and this is because it segfaulted and it was
a minor change so didn't seem worth investigating further, at least for
now (if not for ever).
This feels like a new pull request is appropriate here so although it's
technically the same idea of the previous pull request this is what
should be the final revision (again unless I figure out why U
segfaulted).
Although the 'p' macro was used in other places too now it's used in one
place that had been changed to the translation. More will follow in
coming commits soon or if not hopefully later on in the day.
It now uses the G macro that was unused in the fix. I plan to look at
the other macros that were changed to be unused as well. The hope is I
can make it look much more like it originally looked but still let it
work. Last I remember unfortunately it's not simply a matter of changing
that function that uses the macros but it might be worth trying that
again.
Also in this commit I changed the literal "anonymous.c" to be __FILE__
like it was before.
In other words try and make it so that the munmap(),close(),execv() is
like how it was before (comma operator in succession) though of course
the munmap() and close() were not there until yesterday's fix as text
file busy error (ETXTBSY) was not a problem in the past with this entry.
These were part of debugging the reason execv() did not run the target
program but I forgot to remove them once I found out it was a text file
busy error.
Also added to README.md another git diff to try as it might be
instructive.
I can now report happily that the program works as it was thought to -
both modify the binary and run it. A problem was that it used to call
main() infinitely (seemingly) call main() recursively but this was
causing a problem. It had to be (as I did some while back) moved to a
new function which is not recursive. My guess is that in the past it was
okay due to exit() but I don't know if this is true or not. So what
could be done?
We have to make sure we have BOTH the file descriptor AND the mmap()d
memory close()d and munmap()d as otherwise we would get a text file busy
error. Then we simply call execv() again. I didn't change it so that the
earlier call to execv() is no longer called because I didn't want to
break anything even though at that point M is actually empty.
The astute programmer would observe that the execv() call is slightly
different: don't use M as the path but rather k[1]. Why? Because
initially M is empty but after the function is called it ends up being
something like '.anonymous.ten134517173' but this file never exists. If
you observe even no file is created (or so it seems) as only cpp is
used, not cc (I'm not actually clear what the purpose of that is). The
mmap() call is important of course as is the open() call as one of the
parameters of mmap().
Is this a workaround? Perhaps in a way but it's the only way it'll work
that I can think of as munmap() and close() must be called lest we get a
text file busy error and only then can we call execv().
Removed cpp.c and cpp make rule.
Add back cpp.c which is a C pre-processed version of anonymous.c. Added
comments and tried to format it some. Perhaps I should use a formatted /
de-obfuscator from some years ago in the IOCCC (by Dave Burton) but I
didn't think of that until much later on: I'll consider it another time.
The Makefile builds cpp by default. Works as well as anonymous.c: will
modify 32-bit ELF binaries in the right systems (it won't touch them in
macOS - I pre-compiled anonymous.ten.c as 32-bit ELF in linux and added
it to the repo as anonymous.ten.32 mostly for those who might be able to
run 32-bit ELF binaries but have no way to compile them though maybe no
system has that but it also allows for partly 'testing' the program in
macOS).
Change main target to compile to anonymous and not anonymous_tmp. This
is because otherwise running make would repeatedly try and build it. I
did try changing the target but that didn't want to work possibly due to
the cp updating the timestamp though that's a quick thought in the head
of someone who's been awake too long at the hour.
Instead anonymous.sh is the script to run to 'emulate' the running of
the target program (again assuming that's correct which does seem likely
but is still unconfirmed).
The anonymous.sh script now checks for compiling anonymous.ten.c but
uses anonymous.ten.32 as a backup if it exists.
Update bugs.md and README.md.
Anything else I'm afraid I've forgotten.
For some reason the check that exists has opposite meanings in macOS and
linux so instead of checking the status of make I check if the file
exists after a make clobber all.
Using a script running ./anonymous will run the program after modifying
it. This is a temporary workaround and it's not certain when this will
be changed back or fixed if it even can be. I am aware of some things
that might make it work IF it actually IS supposed to run the program
that it's run on (an additional reading of README.md suggests this might
indeed be the case). In any event the entry DOES modify 32-bit binaries
(bit twiddling) and then running the script (made a copy of
anonymous.sh where anonymous.c is compiled to anonymous_tmp) it will run
the program after doing this, assuming that the program to modify
actually exists.
It should be noted that because things have changed so much it is hard
to know if the modifications to 32-bit ELF binaries are correct but if
nothing else the binary will not crash on 32-bit ELF binaries and it
will modify it but still let it run (though from the author's comments
this might not be possible; this cannot yet be confirmed). Leo it
appears wrote the judges' comments so I will try and get more
information from him later on.
As it's uncertain (both to Landon and me) whether it's supposed to
execute programs it is run on or only modify it which it does (if 32-bit
ELF - which is the only kind it's supposed to act on) with my fix (see
README.md for commit ids) I have added a new bug status:
STATUS: might not be completely functional - can you confirm?
and added this new status to this entry. When or if we figure out the
functional status we will remove (if completely functional or we figure
out what's wrong and fix it which of course is the ideal case) or change
(if it is not completely functional) the status. If anyone knows the
functionality status *please* let us know!
I also updated the try.me.sh script to be quiet on make clobber so that
if -m32 does not work nothing but the error message will be shown and if
it does work only the commands and output of the commands will be shown.
In other words make commands are not shown.
Fix typo fix and format fix in 2001/anonymous/README.md.
Improve try.me.sh: test compile as 32-bit anonymous.ten.c and exit if it
cannot be done as it will otherwise not truly work right.
I also observed that this _might_ not be fixed completely. The binary
_is_ modified and _does_ run after execution, will crash on 64-bit
binaries (and it's not supposed to work on 64-bit binaries and probably
anything other than 32-bit ELF binaries) but the author comments are not
entirely clear to me. It might be that the program is supposed to be
run. At the same time though the compilation is unclear to me too: the
entry itself need not be compiled and the binary isn't compiled either
(is it supposed to be?) so why is it there? The program is at least
partially fixed in that it used to crash no matter what and it does in
any case modify the binary which was supposed to be done (and this is
why I'm still unsure about why it does anything with compilation).
Perhaps it's time to bring back the C pre-processed code but I will find
more out in the coming days I hope and if necessary I will add this
entry back to bugs.md and then look at fixing it after some higher
priority things are finished. The higher priority thing in particular
has to do with issue #4 but I have a number of already modified files
that I would like to get committed before I continue on that to make my
repo a clean state. I might or might not do that before but it might be
that there are numerous commits prior to the CSV file being worked on
again.
This was done quite easily with a bit of thought. I generated a script
that could be modified in vim if necessary (as it turned out to be
though some of it could have been generated too but I did not think of
everything at once and it is a hack).
This is how I generated it:
echo '#!/bin/bash' > bin/check_awards.sh ; ( while read -r g ; do echo grep "$g"; done < <(sed -e 's,_,/,g' -e 's/"/\\"/g' tmp/year-auth-prize.csv | awk -F, '{print grep "\x22" $2 "\x22" " " $1 "/" "README.md"}' ); ) >> bin/check_awards.sh
Then I I modified the file (again this was a hack to make it easier and
quicker and better for being tired too) in vim to make the grep use -Hc
so I could pipe it to 'grep :0'. This found the files without the right
award. So the final command was:
sh bin/check_awards.sh |grep :0
though I did have to edit some files several times.
For reference the script has been added to the repo too but with +x
permissions.
This change also required updating the CSV file in tmp/.
At the request of Landon all Makefiles have had trailing spaces removed.
The request also included README.md files but this is more complicated
as some lines have to end in spaces in order to force line breaks. For
Makefiles it's fine though. Tested the Makefiles by doing 'make clobber
all everything' from the root directory and all appears to be fine. This
testing is important because depending on how this process (removal of
trailing spaces) was done it could break the Makefiles; for instance
trying something like:
sgit -e 's/\s.*$//g' '*Makefile'
would rather break the Makefiles. This makes sense to anyone who knows
my script (and obviously sed :-) ) as long as they're not also tired but
I AM tired and so it was the first thing I tried (without thinking of
course ... though I had first thought of the correct way :-) ).
But what happens to the universes (yes I at least want to believe in the
multiverse theory and I hope it's true :-) ) when trailing spaces are
removed? :-)
As it turns out the only Makefiles touched were:
modified: 1987/wall/Makefile
modified: 1992/adrian/Makefile
modified: 1994/ldb/Makefile
modified: 2000/anderson/Makefile
modified: 2001/anonymous/Makefile
modified: 2001/bellard/Makefile
modified: 2004/kopczynski/Makefile
modified: 2015/howe/spoiler/Makefile
modified: 2019/karns/Makefile
and most of them were my fault.
In order to know what had to change exactly I tested this out (though
it's possible I forgot to initially document changes and so I did not
test everything) and I have documented it in the README.md. The required
changes:
- remove infinite recursion from main(): move the body of main() to
another function.
- add #include <sys/mman.h> for mmap().
Without either this did not work. I also changed (in case of
non-standardised constants) '3' in the call to mmap() to be
PROT_READ|PROT_WRITE but this appears to not be strictly required.
I added the script try.me.sh which has more commands than the previous
try section to show how it works and what changes etc.
Updated .gitignore as the above script creates some.
Make make all attempt to compile anonymous.ten.c: it's an important part
of the program though it can work on other 32-bit ELF binaries.
Update bugs.md explaining why this won't work with macOS.
In try section added some things to try.
In INABIAF I noted that the program will also very likely crash if the
program is not given a file name and that it will likely :-) do
something funny if used on itself (at least if compiled with 64-bit -
not sure about 32-bit).
This was a fun one to figure out. There were a few steps. Amongst them
was adding the include for mmap(). Another part that might or might not
be relevant was having main() call a new function rather than main()
itself. This seemingly solved an infinite recursion call to main()
(according to gcc).
I changed the third arg in the call to mmap() to be
PROT_READ|PROT_WRITE. This might not have been necessary as it might
evaluate to 3 which is what it was.
I regret that some macros were removed and some formatting was changed.
This was not intentional but I want to get the fix in and then I can fix
the formatting and macros (or try to - some of it might or might not
cause a problem).
Note that it will crash on any binary that's not 32-bit/x86. In other
words this won't work in macOS unless you have an old enough Mac that
supports 32-bit binaries. With gcc (which is clang in macOS so that
won't work either) one can do -m32 and that's what is done for
anonymous.ten. It probably should be built by default but it's currently
not.
This compiles the C pre-processed version as it seems like this will be
useful to any person crazy (by which I mean bold) enough to try and fix
it (and I give much respect to them!).
It is compiled by make all: maybe this is a mistake but it seems like
it's going to be useful if anyone is to fix it. This part can be undone
of course.
Format fix in README.md.
Add cpp.c which is the C pre-processed version cleaned up and somewhat
commented as it heavily (ab)uses the ternary operator and recursion.
Probably futile but it gave me something to do even if it was a waste of
time (could have worked on other README.md files or a host of other
things). This did indeed take a long time and a lot of effort!
Updated bugs.md with more hints about this entry. I explained here how I
came up with the C pre-processed version as it involves something of a
hack because of the complicated build instructions.
Updated anonymous.ten.c: #include <stdio.h>
Added anonymous.ten rule to Makefile.
Also disabled optimising level as the author stated that this makes it
slower.
I observed that the author is anonymous and yet the author information
shows the country. I'm not sure if this is intended or not.
There were many many README.md files with the wrong heading level for
different sections. These have been changed.
To help go through the changes it should be noted I used sgit and also
here is what is changed:
The 'Try', 'To build' and 'To run' lines have two '#'s. Some had one and
others had three.
An exception is that in 1984/anonymous/README.md for the alternative
code that had three '#'s. This is not consistent yet and it might be
that only two are desired. But for now that one at least has three.