Code

January 23, 2006

Signals, C and copyover

Moderate technical stuff ahead

I've been playing in the mud code lately, a lot of it at a signal handling and stack-frame level, which has given us a nice stack tracing function as part of the signal handler (which traps larger errors and pinpoints their location in the code).

Next was copyover, a clever command that allows you to restart the mud without disconnecting anyone. It starts a new process using execl(), handing over control, and lets it know which characters to reconnect (and how). I implemented it (well, I pasted in working copyover code from the Chuck codebase) thinking that should be fairly straight forward.

And in testing it worked fairly well. Except for the crash recovery, which for reasons that left me stumped a long while, would recover from one crash but never a second one. Ever. Further testing showed it wasn't just me - the behaviour existed in copyover previously.

Debugging was made slightly harder becuase it does create a new process - and the debugger can't follow code execution into there. The code was tweaked to start the debugger rather than the new process. It didn't help much. The signal continued to be unhandled.

The first guess was bad and wasted a bit of time wondering if the signals were somehow still hooked and locked up by the previous code. Stepping through the signal hooking code (which had always worked) showed that the new process was still hooking all the signals correctly.

Which means it was time to consult an internet reference for the details of execl() and signals. I'm glad I did it in that order.

Delving into the Single Unix Group documentation reveals some interesting bits about execl() that no printed matter I've seen mentions:


The new process also inherits at least the following attributes from the calling process image:
nice value (see nice())
semadj values (see semop())
process ID
parent process ID
process group ID
session membership
real user ID
real group ID
supplementary group IDs
time left until an alarm clock signal (see alarm())
current working directory
root directory
file mode creation mask (see umask())
file size limit (see ulimit())
process signal mask (see sigprocmask())
pending signal (see sigpending())
tms_utime, tms_stime, tms_cutime, and tms_cstime (see times())
resource limits
controlling terminal
interval timers

(my bold) When a signal is handled inside a program, that signal is masked (so it will be ignored by the error-handling code in future). So after a SIGSEGV crash-copyover, the signal mask is set to ignore SIGSEGV errors. This mask is subsequently passed on to the new copy - the second SIGSEGV was ignored by the code's error handling and crashed the mud.

The crash copyover code now passes the signal number to the new process, allowing it to unmask that signal with sigprocmask()and handle everything correctly.

Scrawled illegibly by Meathe at 03:15 PM

Code

July 29, 2005

Java Client Testing.

Testing a java telnet client for the weenend blogathon. Fingers crossed, it should be good... Maybe

Well, no colour. But otherwise it works. Trying another client.












Scrawled illegibly by Meathe at 12:58 PM

Code

July 28, 2005

The Months

This is the first stab at the new month names and hours of daylight.

(The following is a mock-up)


_________________________________________
/ /\
| ************************************** | |
| 11 OClock AM |_/
| The Month of Kali |
| The 28th, the Day of the Moon |
| ************************************** |
| System Time: Thu Jul 28 14:12:28 2005 |_
| ToD Compiled: Jul 26 15:11:44 2005 | \
| ToD Started: Wed Jul 27 23:47:35 2005 | |
\________________________________________\/

Numerical Season Month of Dawn Dusk Hours of Daylight
1 WINTER Kali 9 5 8
2 WINTER the Grand Struggle 8 6 10
3 SPRING Meathe 7 7 12
4 SPRING Navarre 7 7 12
5 SPRING Ackmon 6 8 14
6 SUMMER Morakai 6 8 14
7 SUMMER Dulthail 5 9 16
8 SUMMER the Heat 6 8 14
9 AUTUMN Ahriman 6 8 14
10 AUTUMN Oaklore 7 7 12
11 AUTUMN Coyote 7 7 12
12 WINTER Darkstar 8 6 10
13 WINTER Long Shadows 9 6 9

So, during the first month of the year, dawn would be at 9am, Dusk at 5pm, giving 8 hours of daylight.

Scrawled illegibly by Meathe at 02:16 PM

Code

July 22, 2005

Prog debuggery

It's been a hectic few days. In testing the new code for item and room progs, I find I need to completely disect the interpretter again and learn how to write mprogs. The tutorials in mprogs, (listed in reverse order, which is somewhat unfortunate), were as much me needing to discover how they worked to test the code. In doing so, Oaklore's (and Coyote's) mprog guide was indespensible, and was enthusiatically pillaged to create these tutorials. I wanted to be sure all the examples were correct, and in some cases (using wearing instead of wears) led to the discovery of new and unusual bugs that would lock up the interpretter. And here I was thinking all those were fixed.

There are also some additional features of the interpretter of which I was not aware. While they're not essential, they may prove handy. These will comprise the next tutorial, though all the bugs in the current sample code will be eliminated first (while you can write mprog code in a blog, it's hard to test it there).

Other oddities: "IF class" was not coded at all. "IF has" and "IF uses" were very buggy, sometimes working, sometimes firing if the character had an item of any type. Determining the monetary worth of a character was bugged beyond recognition.

The testing phase of all of this is proving vast in scope, as many progs need to be specifically written for objects and rooms in order to test the functionality. The current count of mprogs I've written in the last two days is well into the mid hundreds, fully a third of these as examples in the IF-THEN-ELSE tutorial. Due to the inherent number of permutations, I am sure I will miss something. However, tests thus far have been encouraging.

Back to the code pool for me.

Kali, you were absolutely right. This is a big, big project. I suspect weather and corrosion might even prove simpler, but I'll surely need the month you thought this would occupy.

Scrawled illegibly by Meathe at 09:37 AM

Code

July 18, 2005

Tightening the screws

Every program starts off with bugs. Many programs end up with bugs as well. There are two corollaries to this: first, you must test all your programs straight away. And second, there's no point in losing your temper every time they don't work.

Z80 Users Manual

A continuation of previous messages.

Nearing the final round of testing of new code before it is ready to go live.

The mob program interpretter has been oiled, tightened and generally improved. Several crash bugs in it have been isolated and removed. Notably, a mob may now purge itself, or may call another mob to purge it without crashing the mud. Once a mob is purged, the remainder of it's mprog will not be executed.

A small bug was discovered in the clan stone code. This has been fixed.

Items and rooms will now work with mob remember/forget commands.

Delay does not work on rooms or items.

greet/grall/entry are functionally equivilant for rooms and items. Grall!

The exlist command is complete, more or less as described in the previous entry, showing immortals how, where and in what direction the area links with others. Aparently, it also underwent a name change, as it was exarea originally.

In mprogs, there is a new function available: block $_, allowing you to block characters travel. This is used in conjunction with exit triggers.

[ 0] 160 exit 0
mpdump 160
if carries $n 62
say Go in peace.
else
mob block $n
endif

All mprog triggers are implemented and working. Further detail is available on the bugtracker, however, a more exhaustive write up will be made available for immortals.

Scrawled illegibly by Meathe at 03:17 PM

Code

July 14, 2005

Mud programming

All parts should go together without forcing. You must remember that the parts you are reassembling were disassembled by you. Therefore, if you can't get them together again, there must be a reason. By all means, do not use a hammer.

IBM Maintenence Manual, 1925

For the last two weeks, I've been working on extending the mobile programs to also work for objects and rooms. By and large, Coyote had already completed the hard yards in Chuck, creating a brilliant system that allows them to run mobprogs without alteration by some very clever sleight of hand. Kudos!

Some repairs have been made to non-functioning mob triggers (exit, exall). Triggers have been extended and will restrict you to putting appropriate triggers on mobs/items/rooms (you can't put a 'use' trigger on a mob, or a bribe trigger on a room).

New commands have been added for immortals, all pertaining to programs:

alist Ported from Chuck, coded by Coyote
opstat
rpstat
Function like mpstat for mobs.
opdump
rpdump
Aliases to mpdump, and are completely interchangeable. Added for the sake of completeness.
proglist <area> At Navarre's request, this command functions much like "list" in mpedit, listing all the progs in the current area. If you do not specify an area, it defaults to the one you're standing in.
exarea <area>Lists the exits and entrances to and from an area (not within it) - showing how it is attached to the world. This is in early stages of coding at the moment. It's something I found myself wanting as I was debugging code, and builders will hopefully find it of value.

A small example would be something like this (these are bogus numbers and links)

exarea limbo
Area   Dir   Type    Vnum  Dir  Area 
1      (N)   both    103   (S)  Feline Village
5      (-)   from    32234 (D)  Isle of Misfit Toys
14     (E)    to     32240 (-)  Isle of Misfit Toys

This is still being plotted out, and is subject to change.

There are also a few bug fixes coming up:
Mprogs should no longer lock up and stop working. The problem was traced to a counter that was meant to measure the recursion depth and stop when it hit five. However, if it did hit five, it didn't decrement correctly. This will hopefully prevent a few frustration inspired feather plucking incidents.

Switch was responsible for a good many crashes. The code has been extended a little to stave these off.

Remaining: Item programs require another round of testing, as does the mob exit/exall trigger. Also extend out progs to allow them to block movement. Room programs are complete for OLC and nearing completion for play and thorough testing. Then it shall be time to enjoy the weather...

Scrawled illegibly by Meathe at 11:58 AM

Code

July 12, 2005

How to: Transparencies in webpages

This wiser effort would have been, to diffuse thought and imagination through the opaque substance of to-day, and thus make it a bright transparency...

Nathaniel Hawthorne, The Scarlet Letter

As some have noted, I like transparencies in web pages. Quite possibly too much, as all my pages appear to have them, from Layil to the Time of Darkness Bugtracker and this blog.

This is not purely for Movable Type, it can easily be added to any page that uses stylesheets. If you're not comfortable editing stylesheets, this is not a complex project. Honest.

Inside the stylesheet, usually right at the top, there is a body tag, which will look somewhat like this:


body {
margin: 0px 0px 20px 0px;
background-color: #8FABBE;
text-align: center;
}

This is a simple body tag, taken from the default Gettysburg CSS, offered by SixApart. Yours may be more complex.

To this is added a background image (so you actaully see the opacity setting work), and the opacity settings themselves.


background-image: url(http://www.layil.org/images/MTBackgrounds/rotator.php);
background-repeat: no-repeat ;
background-position: bottom left ;
background-attachment: fixed;
filter: Alpha(Opacity=75);
-moz-opacity: .75;

The background image and it's position are set (fixed on the lower left so it won't scroll, does not reapeat the image to fill up the screen) and, more importantly, where the (two) opacity filters are configured. These two values are the more or less the same thing, they simply target different browsers so that it should work with IE and Firefox/Mozilla. Safari does not work with these. May I suggest using Firefox or Camino instead?

Increasing the number will make it less transparent, lowering it will make it more so. I find 75 (and .75) pleasant, your mileage may vary.

Combining them, the result is:


body {
margin: 0px 0px 20px 0px;
background-color: #8FABBE;
text-align: center;
background-image: url(http://www.layil.org/images/MTBackgrounds/rotator.php);
background-repeat: no-repeat ;
background-position: bottom left ;
background-attachment: fixed;
filter: Alpha(Opacity=75);
-moz-opacity: .75;
}

After saving and rebuilding the stylesheet, you now have a page that you can see through.

Scrawled illegibly by Meathe at 12:41 PM

Code

July 03, 2005

Get thee to a ... monestary

It's official, I'm joining a monestary.

Perl has been refered to as a 'write only' language, in as much as it can be completely impenatrable. But then so can C. The regular expressions have a lot of appeal. Thus far, it seems readable, though I rather suspect this is because the programmers I've been reading have stuck to a convention. Perl will let you get away with all sorts of things that would make a maintenance programmer weep (yes, so does C).

I don't think Perl will displace C (and offshoots) as my favourite language. You must run horses for courses, and there are some things that it is perfect for. I find it impossible not to warm to a programming language where the following is valid and runs:


#!/usr/bin/perl
APPEAL:
listen (please, please);
open yourself, wide;
join (you, me),
connect (us,together),
tell me.
do something if distressed;
@dawn, dance;
@evening, sing;
read (books,$poems,stories) until peaceful;
study if able;
write me if-you-please;
sort your feelings, reset goals, seek (friends, family, anyone);
do*not*die (like this)
if sin abounds;
keys (hidden), open (locks, doors), tell secrets;
do not, I-beg-you, close them, yet.
accept (yourself, changes),
bind (grief, despair);
require truth, goodness if-you-will, each moment;
select (always), length(of-days)


# listen (a perl poem)
# Sharon Hopkins
# rev. June 19, 1995

Scrawled illegibly by Meathe at 12:08 AM

Code

June 27, 2005

Self reproducing programs.

A little bored during my luncheon break, so I thought I'd try my hand at a quine using the C preprocessor.


#define A(B) main(){printf("#define A(B) %s\nA(%s)\n",#A,#A);}
A(main(){printf("#define A(B) %s\nA(%s)\n",#A,#A);})

Running the program produces:
#define A(B) main(){printf("#define A(B) %s\nA(%s)\n",#A,#A);}
A(main(){printf("#define A(B) %s\nA(%s)\n",#A,#A);})

And looking at the Wiki page linked about, it's been done in a neater fashion by someone else. Still, not too bad for 20 minutes messing about.

Scrawled illegibly by Meathe at 03:38 PM