First, signal() is deprecated, it's better to use sigaction(). I don't think fork() is in danger of vanishing altogether since so many things use it, but sigaction() does provide a much nicer interface.
The behavior you are experiencing is commonly caused by calling fork() from within a thread. POSIX addresses this specifically:
A process shall be created with a
single thread. If a multi-threaded
process calls fork(), the new process
shall contain a replica of the calling
thread and its entire address space,
possibly including the states of
mutexes and other resources.
Consequently, to avoid errors, the
child process may only execute
async-signal-safe operations until
such time as one of the exec functions
is called. [THR] Fork handlers may
be established by means of the
pthread_atfork() function in order to
maintain application invariants across
fork() calls.
When the application calls fork() from
a signal handler and any of the fork
handlers registered by
pthread_atfork() calls a function that
is not asynch-signal-safe, the
behavior is undefined.
This means, rather than inheriting a copy of the parent's entire address space, you inherit only a copy of the calling threads address space, which doesn't contain your handlers. It might be conceivable that you are, indeed (perhaps even unwittingly) calling fork() from within a thread.
A child process gets a carbon copy of the parent's address space. The only difference with signals would be pending signals, which the child will not receive as it gets a signal set initialized to zero. But yes, it does get a copy of the handlers.