2010-02-04  Scott James Remnant  <scott@netsplit.com>

	* NEWS: Release 0.6.5

	* util/tests/test_initctl.c (test_reload_action): Don't send
	SIGHUP to the server process, it'll be terminated anyway since
	reload doesn't loop.

	* init/event_operator.c (event_operator_match): Support operator
	negation using !=
	* init/tests/test_event_operator.c (test_operator_update): Add
	test cases for negation.
	* init/man/init.5: Add negation to documentation

	* init/man/init.8: Improve reference to init(5) to make it more
	obvious that this is where documentation can be found.
	* init/man/init.5: Add Upstart to the title to make it show up
	with man -k upstart

	* init/man/init.8: Add missing OPTIONS section, documenting the
	--verbose option.

	* init/main.c (main): After resetting the system console, close it
	again and reopen /dev/null for ourselves so we don't hold the
	system console open.

	* init/job_process.c (job_process_error_abort): Free the error
	before exiting.

	* util/initctl.c (reload_action): Add a reload command, this obtains
	the pid of the main process of the given job instance and sends
	SIGHUP to it.  It might not be in its final form, but it's damned
	useful for now.
	* util/tests/test_initctl.c (test_reload_action): Add test cases.
	* util/man/initctl.8: Add documentation for the reload command,
	and missing documentation for restart.
	* util/Makefile.am (install-data-hook, install-exec-hook): Create
	additional reload symlinks.

	* util/reboot.c (main): Restore the sync() system call before
	calling reboot(); the Linux kernel says we have to do this, and I
	suspect that ext4 is no longer forcing this before power off.

	* init/main.c (hup_handler): Move call to reconnect to D-Bus system
	bus into new function
	(usr1_handler): This is because a config reload "forgets" existing
	state, such as events that were pending.
	(main): Add SIGUSR1 signal handler.

	* init/job_process.c (job_process_handler): Reduce priority of the
	stopped/continued by signal messages to informational.

2010-02-03  Scott James Remnant  <scott@netsplit.com>

	* util/shutdown.c (shutdown_now): Free error before exiting.

2010-02-03  Johan Kiviniemi  <johan@kiviniemi.name>

	* conf/rc-sysinit.conf: Don't replace DEFAULT_RUNLEVEL with an
	empty string when there is no "initdefault" line in /etc/inittab

2010-02-03  Scott James Remnant  <scott@netsplit.com>

	Update code to work with libnih 1.0.1

	* init/tests/test_event.c (test_new): Replace TEST_ALLOC_ORPHAN(env)
	with TEST_ALLOC_PARENT(env, NULL); discard environment after creating
	event from it
	* init/tests/test_event_operator.c (test_operator_new): Replace
	TEST_ALLOC_ORPHAN(env) with TEST_ALLOC_PARENT(env, NULL); discard
	environment after creating event from it
	* init/tests/test_control.c (test_emit_event): Discard event
	environment after emission
	* init/init.supp: Add nih_alloc_ref_new() to init functions

	libnih is now released as its own project, so rather than expecting
	to include it with the source we depend on it being outside of it.

	* Makefile.am (SUBDIRS): Remove m4 directory along with the nih bits.
	(EXTRA_DIST): Remove ChangeLog.nih
	* configure.ac (AM_INIT_AUTOMAKE): Remove dist-bzip2, since we don't
	actually use it; add color-tests and silent-rules.
	(AM_SILENT_RULES): Use silent rules by default
	(AM_MAINTAINER_MODE): Enable maintainer mode by default (as before),
	but allow it to be disabled
	(AM_GNU_GETTEXT_VERSION): Bump to 0.17
	(NIH_INIT): Replace with the expanded out calls that we actually need.
	(AC_CONFIG_FILES): Remove nih directories
	Add magic to allow use of a local libnih source tree.
	* init/Makefile.am (AM_CFLAGS): Add NIH_CFLAGS and NIH_DBUS_CFLAGS
	(init_LDADD, test_system_LDADD, test_environ_LDADD, test_process_LDADD)
	(test_job_class_LDADD, test_job_process_LDADD, test_job_LDADD)
	(test_event_LDADD, test_event_operator_LDADD)
	(test_blocked_LDADD, test_parse_job_LDADD)
	(test_parse_conf_LDADD, test_conf_LDADD, test_control_LDADD):
	Replace library paths with NIH_LIBS and NIH_DBUS_LIBS
	($(com_ubuntu_Upstart_OUTPUTS)),
	($(com_ubuntu_Upstart_Job_OUTPUTS)),
	($(com_ubuntu_Upstart_Instance_OUTPUTS)): Use external nih-dbus-tool
	and obey silent rules.
	(test_system_LDFLAGS, test_environ_LDFLAGS)
	(test_process_LDFLAGS, test_job_class_LDFLAGS)
	(test_job_process_LDFLAGS, test_job_LDFLAGS, test_event_LDFLAGS)
	(test_event_operator_LDFLAGS, test_blocked_LDFLAGS)
	(test_parse_job_LDFLAGS, test_parse_conf_LDFLAGS)
	(test_conf_LDFLAGS, test_control_LDFLAGS): Drop -static
	* util/Makefile.am (AM_CFLAGS): Add NIH_CFLAGS and NIH_DBUS_CFLAGS
	(initctl_LDADD, reboot_LDADD, runlevel_LDADD, shutdown_LDADD)
	(test_initctl_LDADD, test_utmp_LDADD, test_sysv_LDADD)
	(test_telinit_LDADD): Replace library paths with NIH_LIBS and
	NIH_DBUS_LIBS
	($(com_ubuntu_Upstart_OUTPUTS)):
	($(com_ubuntu_Upstart_Job_OUTPUTS)):
	($(com_ubuntu_Upstart_Instance_OUTPUTS)): Use external nih-dbus-tool
	and obey silent rules.
	(initctl_LDFLAGS, reboot_LDFLAGS, runlevel_LDFLAGS)
	(shutdown_LDFLAGS, telinit_LDFLAGS, test_initctl_LDFLAGS)
	(test_utmp_LDFLAGS, test_sysv_LDFLAGS, test_telinit_LDFLAGS): Drop
	-static
	* README: Add libnih to the dependencies.
	* HACKING: Remove the instructions for checking out libnih, replace
	with a description about how to use a libnih source tree instead of
	the installed one.

	* configure.ac: Bump version to 0.6.5, bump copyright year to 2010.
	* NEWS: Begin new release.

2009-08-02  Scott James Remnant  <scott@netsplit.com>

	* NEWS: Release 0.6.3

2009-08-01  Scott James Remnant  <scott@netsplit.com>

	* init/tests/test_job_process.c (test_handler): Add a missing test
	case for the running process exiting while we're in the stopping
	state.
	* init/job_process.c (job_process_terminated): Don't change the
	state or record failure information if we're in the stopping state
	when the main process dies, otherwise we hit an assertion later;
	just wait for the stopping event to finish and carry on as before.

2009-07-31  Scott James Remnant  <scott@netsplit.com>

	* dbus/upstart.h: Allow the service name and address to be overriden

2009-07-29  Michael Biebl  <mbiebl@gmail.com>

	* init/tests/test_job_process.c: Add missing sys/ptrace.h include

2009-07-21  Scott James Remnant  <scott@netsplit.com>

	* configure.ac: Bump version to 0.6.3
	* NEWS: Begin new release

	* NEWS: Release 0.6.2

	* init/main.c (crash_handler): Restore missing chdir ("/") call.

	* init/tests/test_job_process.c (test_handler): We should allow
	a job to exec() before it calls fork() to allow shell scripts to
	exec daemons.
	* init/job_process.c (job_process_trace_exec): Continue the traced
	process instead of detaching if it has not yet forked.

	* init/job.c (job_change_state): Obvious bug fix; the set of states
	into which we can enter JOB_STOPPING includes JOB_STARTING because
	we can get the "stop" event or command there.

2009-07-16  Scott James Remnant  <scott@netsplit.com>

	* configure.ac: Bump version to 0.6.2
	* NEWS: Begin new release

	* NEWS: Release 0.6.1

	* util/runlevel.c: Output the path before the error message,
	to make it clear that it's the utmp file missing not runlevel.

	* util/runlevel.c: If there is no current runlevel because the
	environment variable is empty, output "unknown" instead of "N N".

2009-07-15  Scott James Remnant  <scott@netsplit.com>

	* README: Now that D-Bus 1.2.16 proper has been released, update
	our requirements.

2009-07-14  Scott James Remnant  <scott@netsplit.com>

	* TODO: Update

	* init/tests/test_job_process.c (test_handler): Rework the existing
	ptrace fork handler test case to make sure we test the case where
	we get the fork event before the stopped child.  Add a second test
	case for the opposite (stopped child before the fork event) which
	we don't currently handle.
	* init/job_process.c (job_process_trace_fork): Test for the missed
	child event using ptrace(), if it succeeds the child is ready so
	we can just assume we had the event.

	* util/Makefile.am (EXTRA_DIST): Distribute the valgrind suppressions
	file

	* util/tests/test_utmp.c (test_write_shutdown): Additional instance
	of the same test.

	* util/tests/test_utmp.c (test_write_runlevel): Looks like glibc
	is fixed to return the right error code.

2009-07-11  Scott James Remnant  <scott@netsplit.com>

	* init/control.c (control_server_open): Don't hardcode the server
	address, otherwise the test suite can't test this function.
	* init/tests/test_control.c (test_server_open)
	(test_server_connect, test_server_close): Change the server
	address in the tests.

	* configure.ac: Bump version to 0.6.1
	* NEWS: Begin new release

2009-07-09  Scott James Remnant  <scott@netsplit.com>

	* NEWS: Release 0.6.0

	* README: Note that we need D-Bus GIT HEAD.
	* NEWS: Update.

	* init/man/inittab.5: People keep trying "man inittab", so explain
	that it's gone.
	* init/Makefile.am (dist_man_MANS): Install it

	* NEWS: Declare the "lacks documentation" bug fixed

	* init/man/init.8: Refresh and turn it into more of an overview
	of Upstart now that we have lots of other pages to refer to.
	* init/man/upstart.7: Since it's an overview, people might go
	"man upstart" so redirect to it.
	* init/man/init.5: Actually document the configuration format.
	* init/Makefile.am (dist_man_MANS): Install the configuration
	documentation, and the redirect.

	* util/man/runlevel.8, util/man/telinit.8, util/man/shutdown.8,
	* util/man/reboot.8: Add environment and files sections.

	* init/man/startup.7, init/man/starting.7, init/man/started.7,
	* init/man/stopping.7, init/man/stopped.7
	* init/man/control-alt-delete.7, init/man/keyboard-request.7,
	* init/man/power-status-changed.7: Write manual pages for each
	of the events generated by the init daemon by default.
	* init/Makefile.am (dist_man_MANS): Distribute and install the
	new manpages.
	* util/man/runlevel.7: Indent the example, don't boldface

	* init/job.c (job_start, job_stop, job_restart): Restructure
	slightly to avoid gcc warning
	* init/job_class.c (job_class_start, job_class_restart): Make the
	same change to these too
	* util/shutdown.c: Warn if we can't change directory
	* util/telinit.c: Assert that we don't fall out of the switch
	* init/tests/test_job_class.c (test_get_version)
	(test_get_author, test_get_description, test_get_name): Initialise
	alloc-safe variables to NULL to avoid gcc warning
	* util/tests/test_initctl.c (test_job_status, test_start_action)
	(test_stop_action, test_restart_action, test_status_action)
	(test_list_action, test_emit_action)
	(test_reload_configuration_action, test_version_action)
	(test_log_priority_action, test_upstart_open): Initialise alloc-safe
	variables to NULL and diverted return values to 0 to avoid gcc
	warnings.
	(test_start_action, test_stop_action, test_restart_action):
	Replace sigsetjmp/siglongjmp with a call to _exit() in the handler
	* util/tests/test_sysv.c (test_change_runlevel): Initialise alloc-safe
	variables to NULL to avoid gcc warnings

	* util/man/runlevel.7: Formatting fixes, and mention that rcS
	runs rc-sysinit again.
	* util/man/runlevel.8: s/utilities/tools/
	* util/man/telinit.8: s/utilities/tools/
	* util/man/shutdown.8: s/utilities/tools/
	* util/man/reboot.8: s/utilities/programs/
	* util/man/initctl.8: s/utility/tool/

	* init/job_class.h (JobClass): Drop the leader option; at the time
	it seemed to make sense that Upstart would provide a "daemon"-like
	environment, but it really doesn't in practice.  Software should
	feel safe to daemonise on its own, and I'd rather fix supervision
	of those; freeing up Upstart jobs to run as new sessions by default
	again.  This is also the only real option that would change the
	behaviour between 0.6 and 0.10 in an awkwardly compatible way.
	* init/job_class.c (job_class_new): Remove leader initialisation
	* init/tests/test_job_class.c (test_new): Drop the initialisation
	check for leader
	* init/parse_job.c (stanza_session): Drop the stanza
	* init/tests/test_parse_job.c (test_stanza_session): Drop the
	stanza test cases.
	* init/job_process.c (job_process_spawn): Drop the double-fork.
	This means we don't need to read the pid of our extra child either.
	(job_process_error_read): we no longer need a fork error.
	* init/job_process.h (JobProcessErrorType): Drop the fork error.
	* init/tests/test_job_process.c (test_spawn): Replace the simple job
	test case with the session leader test case, now that's the default.
	(test_run, test_spawn, test_kill, test_handler): Remove all the
	class->leader = TRUE from the tests, we only ever really tested
	session leaders anyway since that's all the test suite could follow
	* init/tests/test_job.c (test_change_goal, test_change_state):
	Remove the leader flag from test jobs
	* init/tests/test_event.c (test_pending, test_finished): Remove
	the leader flag from test jobs.

	* init/job_process.c (job_process_catch_runaway): Use a monotonic
	clock, not the realtime clock, for respawn interval detection.
	* init/tests/test_job_process.c (test_kill, test_handler): Use the
	monotonic clock in test cases too
	* init/Makefile.am (init_LDADD): Link with librt
	* NEWS: Update.

	* util/utmp.c (utmp_write_runlevel): Don't write 'N' to utmp or
	wtmp for the previous runlevel, this will force writing reboot
	records if prevlevel='N'/0 since read_runlevel will always return
	'N' in that case.
	* util/tests/test_utmp.c (test_write_runlevel): Add test case for
	passing 'N' and having it treated as zero
	(test_read_runlevel): Add a couple of test cases for the problems
	we found last night where shutdown and corrupt utmp records result
	in the wrong data being returned.
	* util/tests/test_sysv.c (test_change_runlevel): Add a test case
	for switching from sysinit to the first runlevel

	* init/conf.h,
	* init/control.h,
	* init/event.h,
	* init/job_class.h: Variable declarations in header files need to
	be prefixed with "extern", the NIH_BEGIN_EXTERN stuff only applies
	to C++.

	* util/reboot.c: Reboot can't write the shutdown time before
	calling shutdown, otherwise shutdown won't be able to get the
	current runlevel anymore.
	* util/man/reboot.8: Update, we don't write the shutdown time
	before calling shutdown - it's up to the shutdown scripts to
	call reboot -w before remounting the root filesystem.

	* util/tests/test_utmp.c (test_get_runlevel): Replace test case
	with one that expects 'N' rather than fall-through.
	* util/tests/test_sysv.c (test_change_runlevel): Expect N when
	there is no previous runlevel

	* util/utmp.c (utmp_read_runlevel): Also catch a zero runlevel from
	utmp, replacing with 'N' - these functions should never return 0
	* util/sysv.c (sysv_change_runlevel): Should set prevlevel to N
	when we don't find one

	* util/utmp.c (utmp_read_runlevel): Catch a negative runlevel from
	corrupt utmp data, convert to 'N'
	(utmp_get_runlevel): Return N when RUNLEVEL is set but empty,
	rather than falling through

	* util/telinit.c: Catch a missing argument separately so we don't
	output "(null)"

	* README: Update requirements.
	* TODO: Update.

	* conf/rc-sysinit.conf: Fix typo.

2009-07-08  Scott James Remnant  <scott@netsplit.com>

	* conf/rc-sysinit.conf: Michael Biebl pointed out that by setting
	the runlevel to "S" during sysinit, we end up with the runlevel
	after boot being "S 2" - and that means scripts in rc2.d that
	are also in rcS.d won't get started.  The way we had it before
	("N 2") was correct.  This happily fixes the one corner case our
	reboot handling didn't cover - crashing in single user mode and
	rebooting.

	* util/telinit.c: Fix missing ret = from kill

	* conf/rc-sysinit.conf: Ignore -s/single if we're already coming
	from single-user-mode.

	* util/telinit.c (options): Unignore the -t option
	* NEWS: Update.

	* init/main.c (hup_handler): Also try and reconnect to the message
	bus if we've lost the connection.

	* init/conf.c (conf_source_reload_dir): Don't blacklist certain
	patterns from the configuration directory, instead just filter
	to whitelist.
	(conf_dir_filter): Whitelist filter, only accept files ending
	in .conf
	(conf_reload_path): Strip .conf from the filename to generate
	the job name.
	(conf_file_filter): Add the extra is_dir argument.
	* init/tests/test_conf.c (test_source_reload_job_dir)
	(test_source_reload_conf_dir, test_source_reload_file)
	(test_source_reload): Append .conf to all our filenames
	* init/tests/test_control.c (test_reload_configuration): Append
	.conf to filenames here too
	* NEWS: Update.

	* init/job_process.c (job_process_run): Stop being stingy, the
	post-stop script can have the stop environment too
	* init/tests/test_job_process.c (test_run): Add a test case to
	make sure it is.

2009-07-08  Michael Biebl  <mbiebl@gmail.com>

	* contrib/vim/syntax/upstart.vim: Upstart job syntax highlighting
	* contrib/vim/ftdetect/upstart.vim: Use for the /etc/init directory
	* contrib/Makefile.am: Include the vim syntax files in the
	distribution
	* configure.ac (AC_CONFIG_FILES): Create contrib/Makefile
	* Makefile.am (SUBDIRS): Recurse into the contrib sub-directory

2009-07-08  Scott James Remnant  <scott@netsplit.com>

	* conf/rc.conf: This doesn't need to be an instance job, Upstart
	will do the right thing and stop the task before starting it again
	with the new environment (I spent so much time on that, you'd think
	I'd remember :p)

	* conf/control-alt-delete.conf: Default job for Control-Alt-Delete
	* conf/rc-sysinit.conf: Default job for system initialisation
	* conf/rc.conf: A fully wacky instance job that runs the rc script
	for runlevel changes
	* conf/rcS.conf: And a job for single-user-mode, which calls back
	to rc-sysinit
	* conf/Makefile.am (dist_init_DATA): Install the default files
	into the /etc/init directory
	* configure.ac (AC_CONFIG_FILES): Create conf/Makefile
	* Makefile.am (SUBDIRS): Recurse into the conf directory.

	* util/initctl.c (upstart_open, start_action, stop_action)
	(restart_action, status_action, list_action): Don't auto-start
	the init daemon, it makes no sense.
	(upstart_open): When not running from the test suite, and not as
	root, it makes sense to default to using the system bus daemon.
	* util/tests/test_initctl.c (test_upstart_open): Make sure that
	auto-start is FALSE, not TRUE.
	* NEWS: Update.

	* util/Makefile.am (dist_man_MANS): Oops, had the wrong name for
	the runlevel(7) manpage.

	* util/shutdown.c: Gets a bit of a redress, but not much of rewrite
	since this is largely just compatibility madness.
	(shutdown_now): Port to use sysv_change_runlevel()
	(warning_message): Construct plural forms a little better.
	(wall): use utmpx, rather than utmp
	* util/man/shutdown.8: Minor tweaks and improvements
	* NEWS: Update.

	* util/reboot.c: Following the pattern of the previous, remove much
	of the reboot code, but in the process adding support for reboot
	implying --force in runlevel 0 or 6, and writing the shutdown
	wtmp record.
	* util/man/reboot.8: Minor updates.
	* NEWS: Update.

	* util/telinit.c: Drop quite a bit of the code of telinit too,
	just becoming a wrapper about sysv_change_runlevel() - also support
	Qq/Uu by using kill()
	* util/tests/test_telinit.c (test_env_option): Since we have an
	env option, we should test it.	
	* util/man/telinit.8: Update the manual page.
	* util/man/runlevel.8: Typo (/var/run/wtmp -> /var/log/wtmp)
	* util/Makefile.am (TESTS): Run the new test
	(test_telinit_SOURCES, test_telinit_CFLAGS)
	(test_telinit_LDFLAGS, test_telinit_LDADD): Details for the
	test suite binary
	* NEWS: Update.

	* util/runlevel.c: Drop about 90% of the code, this just becomes
	a wrapper around utmp_get_runlevel()
	* util/man/runlevel.8: Update the runlevel manpage.
	* util/man/runlevel.7: Also put together a manual page that
	describes the runlevel event, as well as the implementation in
	Upstart.
	* util/Makefile.am (dist_man_MANS): Install the new manpage.
	* NEWS: Update.

	* util/Makefile.am (reboot_SOURCES, runlevel_SOURCES): Compile and
	link the utmp handling source, depending on the header.
	(reboot_LDADD, runlevel_LDADD): Drop dependency on libupstart
	(shutdown_SOURCES, telinit_SOURCES): Compile and link both the
	utmp handling and sysv compat source, depending on the headers
	(nodist_shutdown_SOURCES, nodist_telinit_SOURCES): Also link in
	the auto-generated bindings
	(shutdown_LDADD, telinit_LDADD): Drop dependencies on libupstart,
	replacing with dependencies on libnih-dbus and the D-Bus libs.
	(runlevel_SOURCES, runlevel_LDFLAGS, runlevel_LDADD)
	(shutdown_SOURCES, shutdown_LDFLAGS, shutdown_LDADD)
	(telinit_SOURCES, telinit_LDFLAGS, telinit_LDADD): Remove duplicate
	entries mistakenly copied from compat/sysv

	* util/sysv.c (sysv_change_runlevel): Pretty much the core compat
	function for System V, generate a runlevel event and store the
	appropriate things in utmp and wtmp.
	* util/sysv.h: Prototype.
	* util/tests/test_sysv.c: Test cases for the new function.
	* util/Makefile.am (TESTS): Run the sysv test cases
	(test_sysv_SOURCES, nodist_test_sysv_SOURCES, test_sysv_LDFLAGS)
	(test_sysv_LDADD): Details for the sysv test cases, which obviously
	depend on the auto-generated bindings code.

	* util/utmp.c (utmp_write_runlevel): Make sure that it's ok to
	have no previous runlevel.
	* util/tests/test_utmp.c (test_write_runlevel): Add no previous
	runlevel test.

	* util/utmp.c (utmp_read_runlevel): Don't call utmpxname() if we
	don't pass a utmp_file, letting glibc pick the default.
	* util/tests/test_utmp.c (test_read_runlevel): Add a test case for
	no filename.

	* util/util.supp: utmpname leaks memory, so suppress it from valgrind

	* util/utmp.c: Set of functions for dealing with utmp and wtmp
	(utmp_read_runlevel): Read the current runlevel from the file
	(utmp_get_runlevel): Obtain the current runlevel from the
	environment, or the file if not set
	(utmp_write_runlevel): Write a runlevel change record, and also
	deal with the reboot record if the utmp or wtmp files don't quite
	match.
	(utmp_write_shutdown): Write a shutdown time record
	(utmp_entry, utmp_write, wtmp_write): utility functions for creating
	and writing utmp and wtmp records.
	* util/utmp.h: Prototypes for new functions.
	* util/tests/test_utmp.c: Test cases.
	* util/Makefile.am (test_utmp_SOURCES, test_utmp_LDFLAGS)
	(test_utmp_LDADD): Details for utmp test cases
	(tests): Move to the bottom of the file and make PHONY

2009-07-07  Scott James Remnant  <scott@netsplit.com>

	* util/man/initctl.8: Improve the manpage.

2009-07-06  Scott James Remnant  <scott@netsplit.com>

	* util/initctl.c: Rewrite from scratch, utilising the current
	D-Bus API and auto-generated method functions for it.
	* util/tests/test_initctl.c: Rewrite from scratch to test all
	of the new methods.
	* util/Makefile.am (test_initctl_CFLAGS): Include AM_CFLAGS
	(install-data-hook, install-exec-hook): Install a symlink for
	"restart" as well.
	* NEWS: Update.

2009-07-03  Scott James Remnant  <scott@netsplit.com>

	* dbus/com.ubuntu.Upstart.Instance.xml (Start, Stop, Restart): add
	wait arguments to the instance commands as well.
	* init/job.c (job_start, job_stop, job_restart): Add wait arguments,
	when TRUE the functions behave as before; when FALSE the methods
	return after changing the goal and no blocked entries are created.
	* init/job.h: Amend prototypes.
	* init/tests/test_job.c (test_start, test_stop, test_restart): 
	Pass TRUE for wait and check for a blocking entry in existing tests,
	add tests for passing FALSE and making sure that there's no blocking
	but we still get the reply.

	* dbus/com.ubuntu.Upstart.Job.xml (Start, Stop, Restart): Add wait
	arguments to these too
	* init/job_class.c (job_class_start, job_class_stop)
	(job_class_restart): Add wait arguments, when TRUE the functions
	behave as before; when FALSE the methods return after changing
	the goal and no blocked entries are created.
	* init/job_class.h: Amend prototypes.
	* init/tests/test_job_class.c (test_start, test_stop, test_restart): 
	Pass TRUE for wait and check for a blocking entry in existing tests,
	add tests for passing FALSE and making sure that there's no blocking
	but we still get the reply.
	(test_get_name, test_get_description, test_get_author)
	(test_get_version): Add missing code to free the class on enomem

	* dbus/com.ubuntu.Upstart.xml (EmitEvent): Add wait argument
	* init/control.c (control_emit_event): Add wait argument, when TRUE
	this behaves as before; when FALSE the method returns after queuing
	the event and no blocked entry is created for it.
	* init/control.h: Amend prototype.
	* init/tests/test_control.c (test_emit_event): Pass TRUE for wait
	and check for a blocking entry in existing tests, add a test for
	passing FALSE and making sure that there's no blocking but we
	still get the reply.

	* dbus/com.ubuntu.Upstart.Instance.xml: Add a "processes" property
	to obtain the list of current job processes, both their type and
	their pid.
	* init/job.c (job_get_processes): Implement the new property accessor
	* init/job.h: Add prototype
	* init/tests/test_job.c (test_get_processes): Add test cases for
	returning process arrays.
	(test_get_name, test_get_goal, test_get_state): Add missing free
	for job class.

	* init/tests/test_control.c (test_emit_event): Directly acess
	the number from an NihDBusError

	* dbus/com.ubuntu.Upstart.xml: Add a "version" property to obtain
	the version of the init daemon, and a "log_priority" property to
	get and set the daemon's log priority.
	* init/control.c (control_get_version, control_get_log_priority)
	(control_set_log_priority): Methods to support the new properties
	* init/control.h: Prototypes.
	* init/tests/test_control.c (test_get_version)
	(test_get_log_priority, test_set_log_priority): Add tests for the
	property accessor functions.

2009-07-02  Scott James Remnant  <scott@netsplit.com>

	* dbus/Upstart.conf: Need to adjust the security configuration
	* dbus/upstart.h: And the constants as well.

	* dbus/com.ubuntu.Upstart.xml,
	* dbus/com.ubuntu.Upstart.Job.xml,
	* dbus/com.ubuntu.Upstart.Instance.xml: Now we don't hardcode the
	interface name anywhere, we can version it properly.
	* init/Makefile.am ($(com_ubuntu_Upstart_OUTPUTS)): 
	($(com_ubuntu_Upstart_Job_OUTPUTS)): 
	($(com_ubuntu_Upstart_Instance_OUTPUTS)): Update default interface
	names.
	* util/Makefile.am ($(com_ubuntu_Upstart_OUTPUTS)): 
	($(com_ubuntu_Upstart_Job_OUTPUTS)): 
	($(com_ubuntu_Upstart_Instance_OUTPUTS)): Update here too.

	* dbus/Makefile.am (EXTRA_DIST): Make sure we distribute it
	* dbus/upstart.h: Add a header file with the usual D-Bus constants.
	* init/control.h: Drop CONTROL_ROOT, replace with DBUS_PATH_UPSTART
	* init/control.c (control_server_open, control_bus_open)
	(control_register_all): Replace CONTROL_* constants with the new ones
	(control_get_job_by_name): Use DBUS_INTERFACE_UPSTART when constructing
	error names.
	* init/job_class.c (job_class_new, job_class_register)
	(job_class_unregister): Construct paths using DBUS_PATH_UPSTART
	(job_class_get_instance)
	(job_class_get_instance_by_name, job_class_start)
	(job_class_stop, job_class_restart): Use DBUS_INTERFACE_UPSTART to
	construct error names
	* init/job.c (job_new): Construct path using DBUS_PATH_UPSTART
	(job_finished, job_start, job_stop, job_restart): Use
	DBUS_INTERFACE_UPSTART to construct error names.
	* init/event.c (event_finished): Use DBUS_INTERFACE_UPSTART to
	construct error name.
	* init/tests/test_control.c (test_server_open): Don't hardcode
	the address, extract the abstract path from the constant.
	(test_server_connect, test_bus_open, test_emit_event): Don't
	harcode addresses, paths or interfaces - use the constants
	* init/tests/test_job_class.c (test_consider, test_reconsider)
	(test_register, test_unregister, test_start, test_stop)
	(test_restart, test_get_instance, test_get_instance_by_name):
	Use the constants instead of harcoding.
	(test_new): Derive the expected path from the constant
	* init/tests/test_job.c (test_new): Derive the paths from the
	constant, check for jobs by that interface constant.
	(test_change_state): Use DBUS_INTERFACE_UPSTART_JOB
	(test_start, test_stop, test_restart): Use DBUS_INTERFACE_UPSTART_INSTANCE,
	and generate errors from DBUS_INTERFACE_UPSTART

	* dbus/com.ubuntu.Upstart.xml,
	* dbus/com.ubuntu.Upstart.Job.xml,
	* dbus/com.ubuntu.Upstart.Instance.xml: Remove the empty symbol
	annotation for the interfaces.
	* init/Makefile.am ($(com_ubuntu_Upstart_OUTPUTS)): 
	($(com_ubuntu_Upstart_Job_OUTPUTS)): 
	($(com_ubuntu_Upstart_Instance_OUTPUTS)): Define the default
	interface and build-time instead.
	* util/Makefile.am ($(com_ubuntu_Upstart_OUTPUTS)): 
	($(com_ubuntu_Upstart_Job_OUTPUTS)): 
	($(com_ubuntu_Upstart_Instance_OUTPUTS)): Likewise for util

2009-06-30  Scott James Remnant  <scott@netsplit.com>

	* dbus/Upstart.conf: It doesn't make much sense to restrict getting
	the values of properties, or looking up jobs or interfaces, so make
	these public.

2009-06-23  Scott James Remnant  <scott@netsplit.com>

	* Makefile.am (SUBDIRS): Add util to the list of sub-directories
	again.
	* configure.ac (AC_CONFIG_FILES): Generate util/Makefile
	* util/Makefile.am (AM_CFLAGS): Append D-Bus CFLAGS
	(AM_CPPFLAGS): Make sure the build directory is also in the quoted
	include path
	(nodist_initctl_SOURCES): Build and link the generated D-Bus
	bindings, but don't distribute them
	(initctl_LDADD): Drop the libupstart dependency, instead put
	libnih-dbus and DBUS_LIBS in there.
	(com_ubuntu_Upstart_OUTPUTS, com_ubuntu_Upstart_XML)
	($(com_ubuntu_Upstart_OUTPUTS)): Auto-generate D-Bus binding code
	to proxy the manager object
	(com_ubuntu_Upstart_Job_OUTPUTS, com_ubuntu_Upstart_Job_XML)
	($(com_ubuntu_Upstart_Job_OUTPUTS)): Auto-generate D-Bus binding
	code to proxy job class objects
	(com_ubuntu_Upstart_Instance_OUTPUTS)
	(com_ubuntu_Upstart_Instance_XML)
	($(com_ubuntu_Upstart_Instance_OUTPUTS)): Auto-generate D-Bus
	binding code to proxy job instance objects
	(BUILT_SOURCES, CLEANFILES): Built sources have to come first
	and be cleaned up
	(test_initctl_LDADD): Tests need to be linked to libnih-dbus
	and the D-Bus libraries, as well as the auto-generated output
	* init/Makefile.am (EXTRA_DIST): Drop the EXTRA_DIST for the
	sources, already handled since they're in a different directory

	* COPYING: Change licence to version 2 of the GNU GPL.
	All files have been updated to reflect this.

	* init/paths.h (CONFFILE): Add new macro
	* init/Makefile.am (AM_CPPFLAGS): Add CONFFILE definition
	(install-data-local): No need to make conf.d or jobs.d
	* init/main.c: Only parse CONFFILE (/etc/init.conf) as a
	configuration file source and CONFDIR (/etc/init) as a job
	configuration source.

	* configure.ac: Bump version to 0.6.0
	* NEWS: Copy in news from 0.5.3; that release doesn't appear in
	this ChangeLog since it was made on a separate branch.  Begin
	new release.

2009-06-18  Casey Dahlin  <cdahlin@redhat.com>

	* util/man/initctl.8: Fix formatting of SYNOPSIS

2009-06-18  Scott James Remnant  <scott@netsplit.com>

	* dbus/com.ubuntu.Upstart.xml, dbus/com.ubuntu.Upstart.Job.xml,
	dbus/com.ubuntu.Upstart.Instance.xml: Add a comment to these files
	to clarify that you may communicate and interact with Upstart
	through these interfaces without restriction.  It also makes sense
	that these files be copied into software that does so to turn into
	their own bindings, so use the FSF permissive licence for them.

2009-06-17  Scott James Remnant  <scott@netsplit.com>

	* configure.ac: Bump version to 0.5.3

	* NEWS: Copy in news from 0.5.2; that release doesn't appear in
	this ChangeLog since it was made on a separate branch.

	* NEWS: Include 0.3.10 release, which happened from a separate branch.

	* init/parse_job.c (stanza_kill, stanza_respawn, stanza_nice)
	(stanza_oom): Check errno after using strtol() to avoid overflows.
	(stanza_normal, stanza_umask, stanza_limit): Also check with
	strtoul() too
	* init/tests/test_parse_job.c (test_stanza_kill)
	(test_stanza_respawn): Add test cases for the two that don't
	check for overflow already.
	(test_stanza_limit): Add test for the too large case where we don't
	already cope.

	* dbus/Upstart.conf: Allow root to obtain properties

	* dbus/com.ubuntu.Upstart.Instance.xml: Add name, goal and state
	properties to the instance
	* init/job.c (job_get_name, job_get_goal, job_get_state): Add methods
	to return the property values
	* init/job.h: Add prototypes.
	* init/tests/test_job.c (test_get_name, test_get_goal)
	(test_get_state): Test cases.

	* dbus/com.ubuntu.Upstart.Job.xml: Add name, description, author
	and version properties to the job
	* init/job_class.c (job_class_get_name)
	(job_class_get_description, job_class_get_author)
	(job_class_get_version): Add methods to return the property values.
	* init/job_class.h: Add prototypes

	* init/job_process.c (job_process_error_abort): Don't abort() from
	a child process, it confuses people; just exit with an interesting
	error code (which we ignore anyway).

	* dbus/Upstart.conf: Update the D-Bus configuration based on newer
	D-Bus recommended practice with a proper deny-by-default D-Bus,
	making sure to not use send_interface without send_destination.
	Allow introspection as well.

2009-06-17  Jeff Oliver  <Jeffrey.Oliver@panasonic.aero>

	* init/job_process.c (job_process_spawn): Only attempt to set
	the OOM adjustment if set in the class, avoiding issue where /proc
	is not mounted for the first job.
	
2009-06-17  Scott James Remnant  <scott@netsplit.com>

	* init/tests/test_job_process.c (test_handler): Add test cases for a
	respawning job failing while it's post-start or pre-stop processes
	are still running while making sure that it still respawns afterwards.
	* init/job_process.c (job_process_terminated): To fix it, check for
	a running post-start or pre-stop process before checking for a the
	respawn.  That's not enough because then we won't respawn when the
	existing process finishes, so use the goal as a hint.
	* init/job.c (job_next_state): Use that hint goal here, remembering
	to set the goal back to JOB_START afterwards.
	(job_change_goal): Nothing to do in the respawn case
	(job_goal_name, job_goal_from_name): Add the new values
	* init/job.h (job_goal): Add the respawn goal
	* init/tests/test_job.c (test_next_state): Add tests for the respawn
	goal
	(test_goal_name, test_goal_from_name): Tests for the new values

	* configure.ac (AC_CONFIG_FILES): dbus goes before init just in case
	we ever do anything to them later

	* init/job_class.c (job_class_register, job_class_unregister): Update
	name of signal functions that we call.
	(job_class_interfaces): No need to declare this separately
	* init/job.c (job_register, job_change_state): Update name of signal
	functions.
	(job_interfaces): Drop, it comes from the generated header now
	* init/control.c (manager_interfaces): Drop, comes from the header
	as control_interfaces
	(control_register_all): Change array name
	* init/tests/test_job_class.c,
	* init/tests/test_job.c,
	* init/tests/test_control.c,
	* init/tests/test_blocked.c: Rename conn member of NihDBusMessage
	to connection

	* dbus/com.ubuntu.Upstart.xml,
	* dbus/com.ubuntu.Upstart.Job.xml,
	* dbus/com.ubuntu.Upstart.Instance.xml: Use annotation to mark the
	methods as async, rather than a namespaced attribute.  Omit the
	interface symbol.
	* init/Makefile.am (AM_CPPFLAGS): Add builddir to the quoted includes
	(init_SOURCES): Don't distribute the auto-generated outputs
	($(com_ubuntu_Upstart_OUTPUTS))
	($(com_ubuntu_Upstart_Job_OUTPUTS))
	($(com_ubuntu_Upstart_Instance_OUTPUTS)): Generate using the new
	binary tool.
	(BUILT_SOURCES): Remind myself why these are BUILT_SOURCES
	(MAINTAINERCLEANFILES): Change to ordinary CLEANFILES
	(EXTRA_DIST): outputs aren't distributed

2009-05-22  Scott James Remnant  <scott@netsplit.com>

	* init/tests/test_conf.c: Remove nih/inotify.h include

	* COPYING: Change licence from GPL-2+ to GPL-3 only.

2009-05-17  Scott James Remnant  <scott@netsplit.com>

	* init/tests/test_job.c,
	* init/tests/test_job_class.c,
	* init/tests/test_control.c: Include nih-dbus/errors.h

2009-05-09  Scott James Remnant  <scott@netsplit.com>

	* init/init.supp: setenv on tls/i686/cmov

	* init/job_class.c (job_class_get_instance, job_class_start)
	(job_class_stop, job_class_restart): Clean up the code by using
	nih_error_steal()

	* init/conf.c (conf_source_reload_file, conf_source_reload_dir): 
	Steal the error that we stash instead of getting it, otherwise we'll
	fail if another one occurs.

	* init/conf.c (conf_reload_path): Simply return, no need to re-raise
	the error.
	* init/job_class.c (job_class_get_instance, job_class_start)
	(job_class_stop, job_class_restart): If not ENOMEM, we need to
	re-raise the error as a D-Bus one, that means we now have to free
	the old error first (saving the msssage)
	* init/job_process.c (job_process_error_read): Replace call to
	nih_error_raise_again() with nih_error_raise_error()

	* init/Makefile.am ($(com_ubuntu_Upstart_OUTPUTS)): 
	($(com_ubuntu_Upstart_Job_OUTPUTS)): 
	($(com_ubuntu_Upstart_Instance_OUTPUTS)): Use the Python variant
	of nih-dbus-tool for now

2009-03-27  Scott James Remnant  <scott@netsplit.com>

	* init/tests/test_process.c (test_from_name): Cast -1 to ProcessType
	* init/tests/test_job_process.c (test_kill, test_handler): Cast -1
	to ProcessType
	* init/tests/test_job.c (test_new, test_change_state): Cast -1
	to ProcessType
	(test_goal_from_name): Cast -1 to JobGoal
	(test_state_from_name): Cast -1 to JobState
	* init/tests/test_control.c (test_bus_open): Add braces

	* init/Makefile.am (tests): Add rule to build test cases
	* util/Makefile.am (tests): Likewise

	* init/job.c (job_interfaces): Put static first
	(job_emit_event): Cast -1 to ProcessType
	(job_emit_event): Cast -1 to ProcessType
	* init/job_class.c (job_class_interfaces): Put static first.
	* init/job_process.c (job_process_kill_timer): Cast -1 to ProcessType
	* init/control.c (manager_interfaces): Put static first

	* init/Makefile.am (AM_CPPFLAGS): Use -iquote$(srcdir) instead of -I
	since we only need it to pick those paths up.
	* util/Makefile.am (AM_CPPFLAGS): Likewise.

2009-02-20  Scott James Remnant  <scott@netsplit.com>

	* util/initctl.c (handle_job_instance_end, handle_job_process)
	(handle_job_status_end, handle_event),
	* util/shutdown.c (main): No need for new_* temporary variable when
	looping over nih_realloc with NIH_MUST.

	* util/initctl.c (job_info_output, output_name, handle_job_list)
	(handle_job_instance, handle_job_instance_end)
	(handle_job_status, handle_job_process, handle_job_status_end)
	(handle_event, env_option),
	* util/telinit.c (main),
	* util/shutdown.c (main, shutdown_now, timer_callback, wall): 

	* init/event.c (event_init, event_pending_handle_jobs, event_finished),
	* init/event_operator.c (event_operator_events),
	* init/job.c (job_emit_event, job_name),
	* init/job_class.c (job_class_init, job_class_start)
	(job_class_stop, job_class_restart),
	* init/job_process.c (job_process_run, job_process_error_read)
	(job_process_kill),
	* init/conf.c (conf_init, conf_source_reload_file)
	(conf_reload_path),
	* init/control.c (control_init, control_server_connect)
	(control_bus_open): Set variable outside of NIH_MUST macro.

	* init/event.c (event_pending_handle_jobs): Set variable outside
	of NIH_SHOULD macro.

	* init/Makefile.am ($(com_ubuntu_Upstart_OUTPUTS)): 
	($(com_ubuntu_Upstart_Job_OUTPUTS)): 
	($(com_ubuntu_Upstart_Instance_OUTPUTS)): Update expected path
	of nih-dbus-tool

	* configure.ac: Create nih-dbus-tool Makefile
	* Makefile.am (SUBDIRS): Build in nih-dbus-tool

2009-01-29  Scott James Remnant  <scott@netsplit.com>

	* configure.ac: Bump version to 0.5.2
	* NEWS: Begin 0.5.2

	* NEWS: Copy in news from 0.5.1; that release doesn't appear in
	this ChangeLog since it was made on a separate branch.

	* init/tests/test_blocked.c (test_new),
	* init/tests/test_control.c (test_get_job_by_name)
	(test_get_all_jobs, test_emit_event),
	* init/tests/test_event.c (test_finished),
	* init/tests/test_job.c (test_change_state),
	* init/tests/test_job_class.c (test_get_instance)
	(test_get_instance_by_name, test_get_all_instances): Continue the
	battle with the gcc optimiser which declares variables first used
	inside TEST_ALLOC_FAIL as used uninitialized.

	* init/parse_job.c (parse_exec, parse_script, stanza_instance)
	(stanza_description, stanza_author, stanza_version)
	(stanza_start, stanza_stop, stanza_chroot, stanza_chdir):
	Unreference members when replacing them instead of freeing; not
	strictly necessary but the style is the thing.

	* init/job_process.c (job_process_terminated): Unreference the
	kill timer instead of freeing

	* init/job_class.c (job_class_get_instance): Use nih_local for
	instance environment and name
	(job_class_start, job_class_stop, job_class_restart):
	Unreference job environment instead of freeing

	* init/job.c (job_change_state, job_start, job_stop, job_restart):
	Unreference job environment instead of freeing
	(job_name): Discard job name in case a reference was taken.

	* init/event.c (event_pending_handle_jobs): Unreference the job
	environment instead of freeing

	* init/environ.c (environ_add): should unreference the old environment
	string in case anyone took a ref elsewhere
	(environ_set): use nih_local for str
	(environ_expand_until): Should set *str to NULL if we free it,
	just in case.

	* init/conf.c (conf_source_reload): File should be unreferenced,
	not freed.
	(conf_source_reload_file): Use nih_local for dpath
	(conf_delete_handler): Watch and file should be unreferenced,
	not freed.
	(conf_reload_path): File should be unreferenced, not freed;
	use nih_local for file buffer

	* init/blocked.c (blocked_new),
	* init/conf.c (conf_source_new, conf_file_new),
	* init/event.c (event_new),
	* init/event_operator.c (event_operator_new),
	* init/job.c (job_new),
	* init/job_class.c (job_class_new): No need to cast function
	argument to nih_alloc_set_destructor()

	* init/tests/test_job_process.c (test_handler): We can't just
	assume that our child is sitting at the signal otherwise we might
	end up sending the CONT signal before it's even stopped.  Use
	waitid() to wait for the child to stop first.

	* init/init.supp: More expressions for environment memory which
	valgrind can't deal with

	* init/conf.c (conf_source_reload): The ConfFile destructor has
	side-effects that involve the iteration of the sources and their
	files, so we can't simply call it while iterating because of the
	cursor.  Move the sources into a deleted list first, and delete
	them from there.
	* init/conf.h: Fix prototype.
	* init/tests/test_conf.c (test_source_reload_job_dir): Test pointers
	with TEST_EQ_P not TEST_EQ

2009-01-28  Scott James Remnant  <scott@netsplit.com>

	* init/job_class.c (job_class_start): We can't create the blocked
	until we know we're going to block, otherwise we could ref and unref
	the message (freeing it).  Wait until the job is created, which
	means we can't fail to create the blocked item (we'll already have
	announced the new instance).
	(job_class_stop, job_class_restart): For consistency, don't fail
	if OOM when making blocked.

	* init/tests/test_job.c (test_new): Initialise a bunch of subsystems
	outside of TEST_ALLOC_FAIL

	* init/environ.c (environ_add): We can't allocate nih_local with
	a context, it won't be freed; so don't, but then remember to
	reference it when we do just use it.

	* init/event.c (event_pending_handle_jobs): Must reset the start_on
	operator in case of error.

	* init/job_process.c (job_process_kill_timer): Oops, move the
	assert that we have a process pid to after we know which process
	we have.
	* init/tests/test_job_process.c (test_run): Initialise the
	error context and NihIo outside of TEST_ALLOC_FAIL
	(test_kill): Initialise timers and the event system.
	* init/init.supp: Reference from the jobs hash to the bins is
	still reachable, obviously; as is the string inside job_name()
	either way it is allocated

	* init/tests/test_parse_job.c (test_parse_job): Initialise the
	error context outside of TEST_ALLOC_FAIL

	* init/init.supp: Update suppressions for new nih_alloc()

	* init/job_process.c (job_process_run): Had the shell variable
	setting round the wrong way, now it should be ok.

	* init/tests/test_blocked.c (test_new): in the case of allocation
	failure, the message should not be referenced; which we test by
	trying to discard it and seeing whether that works.

	* init/job.c (job_emit_event): event_new() only references the
	environment now, so use nih_local to make sure we clean it up
	if that doesn't happen

	* init/job.h (Job): Add kill_process member
	* init/job.c (job_new): Initialise to -1
	* init/job_process.c (job_process_kill): Store the process to be
	killed in the kill_process member for the timer, since we can't
	pass two sets of data.  Assert that it's not set to anything, this
	all needs fixing, obviously.
	(job_process_kill_timer): Take the job as the data argument,
	eliminating the need for nih_alloc_parent().  Sanity check the job
	and reset kill_timer and kill_process when done.
	(job_process_terminated): Clear the kill_process field too.
	* init/tests/test_job.c (test_new): Check it's -1
	(test_change_state): Check kill_process is set to PROCESS_MAIN
	when active, or -1 when not.
	* init/tests/test_job_process.c (test_kill): Make sure the
	kill_process member is set and cleared.
	(test_handler): Set the kill_process member for the timer and make
	sure it's cleared when appropriate.

	* init/job_class.c (job_class_start, job_class_stop)
	(job_class_restart): Use nih_local to eliminate nih_alloc_reparent,
	and to clean up some of the code too.

	* init/job_class.c: Update documentation to match new nih_alloc()

	* init/parse_job.c (parse_on_operator, parse_on_collect):
	Use an nih_ref/nih_unref pair instead of nih_alloc_reparent; this
	is not ideal, but then this code is rather messy and leaves a lot
	of allocated data attached to the object on the assumption that
	it will be thrown away.

	* init/event_operator.c: Update documentation to match new nih_alloc()
	(event_operator_match): Use nih_local on expanded value.
	(event_operator_environment): Make evlist nih_local, it will be
	referenced by the environment array on success

	* init/event_operator.c (event_operator_new): Reference the
	event instead of reparenting it.

	* init/event.c: Update documentation to match new nih_alloc()
	(event_finished): Use nih_local to tidy up a slight bit.

	* init/event.c (event_new): Reference the event, don't reparent
	(event_pending_handle_jobs): Use nih_local for environment array
	and for the job name, damn I love this thing.  Reference the array
	into the job to avoid freeing.

	* init/parse_job.c (parse_job): Update documentation to match
	new nih_alloc()
	(parse_process, parse_on_operator, stanza_start, stanza_stop)
	(stanza_expect, stanza_kill, stanza_respawn, stanza_normal)
	(stanza_session, stanza_console, stanza_nice, stanza_umask)
	(stanza_oom, stanza_limit): Use nih_local for all the temporary
	arguments where we can.

	* init/parse_job.c (parse_on_operand, stanza_env, stanza_export)
	(stanza_emits): Make temporary string variables use nih_local,
	this gives us a massive code clean-up and makes nih_str_array_addp
	safe to take a reference.

	* init/job_process.c (job_process_run): Make argv, env, script and
	cmd all use nih_local, this cleans up the code a little and makes
	nih_str_array_addp safe to take a reference.

	* init/environ.c: Update documentation to match new nih_alloc()

	* init/tests/test_job_process.c (test_run): Check that trailing
	newlines are ignored when running a script (can verify r1025 is
	fixed with gdb)

	* init/tests/test_environ.c (test_expand): Add a test case for the
	bug fixed in r1027, the implicit case of the gap in the environment
	string being the same size as the value replacing it.

	* init/environ.c (environ_add): Use nih_local for new_str, making
	the code paths a little simpler and ensuring we pass something that
	can be referenced to nih_str_array_addp()

	* init/tests/test_event.c (test_new): Make sure that env is an
	orphan with TEST_ALLOC_ORPHAN.
	* init/tests/test_event_operator.c (test_operator_new): Make sure
	that env is an orphan with TEST_ALLOC_ORPHAN.
	(test_operator_copy): Drop pointless NULL parent check.

	* init/tests/test_control.c: Include limits.h

	* init/blocked.c (blocked_new): Take a reference to the message,
	otherwise it will be freed; we free the Blocked structure when we're
	done, so will automatically unref the message.
	* init/tests/test_blocked.c (test_new): Add tests to make sure the
	reference is taken.
	* init/tests/test_job.c (test_start, test_stop, test_restart):
	Make sure the message is referenced when an error is not returned
	but not referenced when one is.
	* init/tests/test_job_class.c (test_start, test_stop)
	(test_restart): Make sure the message is referenced when an error
	is not returned but not referenced when one is.
	* init/tests/test_control.c (test_emit_event): Make sure that
	the message is referenced.

	* init/tests/test_blocked.c: Change nih/dbus.h include to
	nih-dbus/dbus_message.h
	* init/tests/test_control.c: Change nih/dbus.h include to error,
	connection and object; include D-Bus test macros.
	* init/tests/test_job.c: Change nih/dbus.h include to error, message
	and object; include D-Bus test macros
	* init/tests/test_job_class.c: Change nih/dbus.h include to error,
	message and object; include D-Bus test macros

	* init/job_class.h: Change nih/dbus.h include to
	nih-dbus/dbus_message.h and include the actual D-Bus header
	* init/job_class.c: Change nih/dbus.h include to error, message,
	object and util.

	* init/job.h: Change nih/dbus.h include to nih-dbus/dbus_message.h
	and include the actual D-Bus header
	* init/job.c: Change nih/dbus.h include to error, message, object
	and util.

	* init/control.h: Change nih/dbus.h include to nih-dbus/dbus_message.h
	and include the actual D-Bus header
	* init/control.c: Change nih/dbus.h include to error, connection,
	message and object includes.

	* init/blocked.h: Change nih/dbus.h include to nih-dbus/dbus_message.h
	* init/blocked.c: Change nih/dbus.h include to nih-dbus/dbus_message.h

2009-01-27  Scott James Remnant  <scott@netsplit.com>

	* init/Makefile.am: Update paths to libnih-dbus dependencies.

2009-01-26  Scott James Remnant  <scott@netsplit.com>

	* configure.ac (AC_CONFIG_FILES): Add nih-dbus sub-directory
	* Makefile.am (SUBDIRS): Add nih-dbus sub-directory

	* configure.ac: Bump copyright to 2009

	* configure.ac: Matching libnih, we now mandate libtool 2.2.x
	* HACKING: Update dependency requirement to 2.2.4

	* init/init.supp: Adjust suppression for glibc 2.8

	* init/tests/test_event.c (test_finished): Remove erroneous test
	of free'd memory.

	* configure.ac: Bump version to 0.5.1

	* init/tests/test_event_operator.c (test_operator_handle): Add a
	test for duplicate events when already matched.
	* init/event_operator.c (event_operator_handle): Skip if already
	matched.

	* README: Update features and requirements.
	* NEWS: Copy in news from 0.5.0; that release doesn't appear in
	this ChangeLog since it was made on a separate branch.

2009-01-26  Casey Dahlin  <cdahlin@redhat.com>

	* init/environ.c (environ_expand_until): Handle the implicit case
	of the gap in the string being the same size of the value.

	* init/job_process.c (job_process_handler): Handle the case of a
	child being continued by a signal, otherwise we'll assert.

	* init/job_process.c (job_process_run): Double-check that the
	newline(s) we see are at the end of the script before stripping,
	since we can fall through if the newline is mid-script but /dev/fd
	isn't mounted.

2008-07-05  Scott James Remnant  <scott@netsplit.com>

	* TODO: Update.

2008-07-01  Scott James Remnant  <scott@netsplit.com>

	* init/Makefile.am ($(com_ubuntu_Upstart_OUTPUTS)): 
	($(com_ubuntu_Upstart_Job_OUTPUTS)): 
	($(com_ubuntu_Upstart_Instance_OUTPUTS)): Must be newer than the
	source for the dbus tool, and ensure the dbus tool is built

2008-06-30  Scott James Remnant  <scott@netsplit.com>

	* init/Makefile.am: Update along with libnih so that we leave the
	D-Bus bindings in the dist tarball, meaning Python is no longer a
	build-dependency.

2008-06-11  Scott James Remnant  <scott@netsplit.com>

	* Makefile.am (SUBDIRS): List dbus before init in case we need to
	generate anything in that directory later on.
	
	* Makefile.am (SUBDIRS): List po last so that update-po is run after
	generating any sources.

2008-06-08  Scott James Remnant  <scott@netsplit.com>

	* init/Makefile.am (EXTRA_DIST): Ship the built sources, don't
	clean them.
	(maintainer-clean-local): Well, not unless maintainer-clean anyway

	* init/job.c, init/job_class.c: Add missing errno.h include

	* dbus/com.ubuntu.Upstart.Job.xml (GetInstance): Add method to get
	an instance name in the same basic manner as start and stop would,
	though this one's synchronous.
	* init/job_class.c (job_class_get_instance): Implementing by copying
	the relevant bit of Stop.
	* init/job_class.h: Add prototype.
	* init/tests/test_job_class.c (test_get_instance): Add tests.
	* TODO: Continue to document the C&P madness.

	* init/conf.c (conf_reload_path): Read file directly into memory,
	not using mmap.

	* compat/sysv/reboot.c, compat/sysv/runlevel.c, compat/sysv/shutdown.c,
	* compat/sysv/telinit.c: Move into the util directory; we're going
	to support limited SysV-a-like commands without full compatibility
	which is what we always did, and I'm not going to worry about adding
	others.
	* compat/sysv/man/reboot.8, compat/sysv/runlevel.8,
	* compat/sysv/man/shutdown.8, compat/sysv/telinit.8: Move as well.
	* compat/sysv/Makefile.am, util/Makefile.am: Merge.
	* configure.ac: Remove the (commented out) compat/sysv and logd
	Remove the --enable-compat option.
	* Makefile.am (SUBDIRS): Remove (commented out) compat/sysv and logd

	* logd/Makefile.am, logd/main.c, logd/man/logd.8, logd/jobs.d/logd.in:
	Consign logd to oblivion.  We haven't supported it for ages, it has
	non-working issues, and there's got to be a better way to do this.

	* TODO: Update.

	* init/job.c (job_change_goal): Adjust the documentation.  After
	careful thought, there's no way this can return after freeing the
	job, since it'll either block on an event, a process or do nothing.

	* init/job.c (job_start, job_stop, job_restart): Clear the start
	and stop environment, shouldn't necessarily make a difference, but
	it pays to be consistent.

	* dbus/com.ubuntu.Upstart.Job.xml (Start, Stop, Restart): Add methods
	to control jobs, all take an environment array and both Start and
	Restart return an instance path so properties, etc. can be obtained
	afterwards.
	* init/job_class.c (job_class_start, job_class_stop)
	(job_class_restart): Add the code for the top halves of the methods
	* init/job_class.h: Add prototypes for the new methods.
	* init/job.c (job_finished): And the bottom halves go here.
	* init/tests/test_job_class.c (test_start, test_stop)
	(test_restart): Add test cases for the methods.
	* init/blocked.h (blocked_type): Add enums for the new methods.
	* init/blocked.c (blocked_new): Handle the new methods here.
	* init/tests/test_blocked.c (test_new): Add add tests for handling.

2008-06-07  Scott James Remnant  <scott@netsplit.com>

	* init/job_process.c (job_process_terminated): Don't check the goal
	to see whether the main process was allowed to terminate, check the
	state.  A termination is only not a failure if we're on the KILLED
	state (ie. we killed it), otherwise it can still be a failure even
	if it was going to stop anyway.
	* init/tests/test_job_process.c (test_handler): Add a test case.

	* init/control.c (control_emit_event): Use environ_all_valid here(),
	also reorder the blocking stuff to be less strange, it's ok to free
	environment.
	* init/tests/test_control.c (test_emit_event): The event array should
	be a child of message, which means it doesn't matter if the function
	we call frees it.

	* init/environ.c (environ_all_valid): Add a validation function for
	external input.
	* init/environ.h: Add prototype.
	* init/tests/test_environ.c (test_all_valid): Test function.

	* init/environ.c: Note that we can call this in a loop with OOM,
	since the resulting table will always be the same.

	* init/event_operator.c (event_operator_environment): Use
	environ_append(), and while we're at it, there's no reason this should
	use NIH_MUST.
	* init/event_operator.h: Adjust prototype.
	* init/tests/test_event_operator.c (test_operator_environment): Allow
	for failure.
	* init/event.c (event_pending_handle_jobs): Call with NIH_MUST,
	which is actually safe.

	* init/job_class.c (job_class_environment): Use environ_append()

	* init/environ.c (environ_append): There are multiple cases where we
	append one environment table onto another, so we should have a
	function to do that.
	* init/environ.h: Prototype for it.
	* init/tests/test_environ.c (test_append): Test the new function.

	* init/job_process.c (job_process_run): Invert the logic; we nearly
	always want to pass the script with /dev/fd/NNN.  The only times we
	don't are if it doesn't exist, or if we're dealing with a single-line
	shell script.
	* init/tests/test_job_process.c (test_run): Update test cases to
	only expect an argv-execution for single-line scripts.

	* init/job.c (job_restart): Wrote the blocking bit slightly weirdly
	without neededing to, so leave it as it should be.

	* TODO: Update.

	* dbus/com.ubuntu.Upstart.Instance.xml (Start, Stop, Restart): Add
	simple instance control methods, these only change the goal of an
	existing instance - thus cannot pass environment.
	* init/job.c (job_start, job_stop, job_restart): Add methods, which
	look spookily similar to each other, except for the subtle yet
	important differences.
	(job_finished): Implement bottom halves.
	* init/job.h: Add prototypes.
	* init/tests/test_job.c (test_start, test_stop, test_restart): Add
	tests for the new methods.
	* init/blocked.h (blocked_type): Add enums for methods.
	* init/blocked.c (blocked_new): Handle methods here too
	* init/tests/test_blocked.c (test_new): Add tests for them.

2008-06-06  Scott James Remnant  <scott@netsplit.com>

	* init/blocked.h (blocked_type): Having a single message type won't
	work for the job cases, so expand to have many.
	* init/blocked.c (blocked_new): We'll just have to list them all here.
	* init/control.c (control_emit_event): Happily we create them
	individually anyway.
	* init/event.c (event_finished): And since we have to handle them
	individually, it'll actually protect us replying to the wrong one.

	* init/tests/test_conf.c (test_source_reload): Clean up the temporary
	directory.
	* init/tests/test_control.c (test_reload_configuration): That goes
	for this one too.

	* init/tests/test_control.c (my_connect_handler): Use TEST_DBUS_MESSAGE
	instead of a pop/read/write loop.
	(test_emit_event): Renamed TEST_DBUS_CONN to TEST_DBUS_OPEN.
	* init/tests/test_job.c (test_new, test_register)
	(test_change_state): Use TEST_DBUS_OPEN and TEST_DBUS_CLOSE to setup
	and tear down D-Bus connections and TEST_DBUS_MESSAGE instead of
	a loop.
	* init/tests/test_job_class.c (test_consider, test_reconsider)
	(test_register, test_unregister): Likewise.

	* init/control.c (control_get_job_by_name): Sanity check the name
	of a job in the same way; we don't need to sanity check the instance
	name because "" is valid (and the default for singletons).
	* init/tests/test_control.c (test_get_job_by_name): Test.

	* dbus/com.ubuntu.Upstart.xml (EmitEvent): Add an asynchronous
	method to emit an event, providing the name and accompanying
	environment.  No return value, it either works or you get an
	error.
	* init/control.c (control_emit_event): Implement top half of the
	method, blocking the message in the event.
	* init/control.h: Add prototype.
	* init/event.c (event_finished): Implement the bottom half which
	sends the reply or error, these are actually tested along with
	the top for sanity reasons.
	* init/tests/test_control.c (test_emit_event): Test the various
	ways the method may be used and abused; the async nature means
	we actually need a real D-Bus server to do this.
	* TODO: Update.

	* init/event.c (event_new): There's no reason this shouldn't be
	allowed to return insufficient memory, so do so.
	(event_finished): Wrap call.
	* init/tests/test_event.c (test_new): Add alloc failed test.
	* init/job.c (job_emit_event): Must create the event.
	* init/main.c (main, cad_handler, kbd_handler, pwr_handler): Wrap
	with NIH_MUST

2008-06-05  Scott James Remnant  <scott@netsplit.com>

	* TODO: Update.

	* init/job.c (job_unblock): Rename to job_finished, since this
	does not behave like event_unblock but more like event_finished
	(job_change_state, job_failed): Change name in call.
	* init/job.h: Update prototype.
	* init/tests/test_job.c (test_unblock): Rename to test_finished
	* init/event.c (event_pending_handle_jobs): Update calls here.

	* init/job.h (Job): Rename blocked to blocker to match event, since
	it has the same use as event->blockers except it's a toggle
	* init/job.c (job_new, job_change_state): Rename where used
	* init/event.c (event_finished): Rename here also since its reset
	* init/tests/test_job.c, init/tests/test_job_process.c,
	* init/tests/test_event.c: Rename in test cases too.

	* init/job.c (job_emit_event): Add a Blocked record to the event's
	blocking list for the starting and stopping events.
	* init/tests/test_job.c (test_emit_event): Add tests for the record
	being added to the list with the right details.
	(test_change_goal): Make sure that a Blocked record is added
	(test_change_state): Make sure that Blocked records are added
	* init/tests/test_job_process.c (test_handler): Also make sure
	that Blocked records are added.

	* init/event.c (event_finished): Clear jobs referenced in the
	blocking list, rather than iterating the entire jobs hash.
	(event_finished_handle_jobs): Drop this function.
	* init/tests/test_event.c (test_finished, test_finished_handle_jobs):
	Merge tests again and test using both the blocking list and job's
	blocked member.

	* init/event.h (event): Add blocking member.
	* init/event.c (event_new): Initialising blocking list.
	* init/tests/test_event.c (test_new): Make sure it's initialised
	to an empty list.

	* init/tests/test_job_process.c (test_handler): Update tests to use
	Blocked.

	* init/event.c (event_pending_handle_jobs): Collect environment
	and events independantly, which means we don't have to worry about
	the list contents or freeing them up in case of error.
	* init/event_operator.c (event_operator_events): Fix parent.
	* init/tests/test_event.c (test_pending_handle_jobs): Update tests.
	* init/init.supp: Update collect suppression.

	* init/event_operator.c (event_operator_collect): Break in two.
	(event_operator_environment): Collect the environment from the event,
	appending the list of event names if necessary.
	(event_operator_events): Block events and pass them to the
	given list.
	* init/event_operator.h: Update prototypes.
	* init/tests/test_event_operator.c (test_operator_collect): Also
	split into two new functions
	(test_operator_environment, test_operator_events): Adjust

	* init/event_operator.c (event_operator_collect): Placed Blocked
	structures in the list, rather than ordinary entries; I strongly
	suspect that while it's nice to iterate the operator tree only once,
	this needs to be three functions really.
	* init/tests/test_event_operator.c (test_operator_collect): Update
	test suite.

	* init/job.h (Job): Make blocking a statically defined list.
	* init/job.c (job_new): Initialise rather than setting to NULL.
	(job_unblock): Assume that blocking members are Blocked structures
	and that the list itself is always iterable.
	* init/tests/test_job.c (test_new): Check the list is empty, rather
	than NULL.
	(test_change_state, test_failed, test_unblock): Change tests cases
	to expect blocking to always be present, and create members as Blocked
	structures.

	* init/blocked.c (blocked_new): Set destructor (forgotten)

	* init/init.supp: Add setenv, which has crept in

	* init/blocked.h: Header containing enum, struct and prototype.
	* init/blocked.c (blocked_new): Function to allocate the structure
	with the right details.
	* init/tests/test_blocked.c (test_new): Tests for the new function.
	* init/Makefile.am (init_SOURCES): Compile using blocked.c and header
	(TESTS): Build blocked test suite
	(test_process_LDADD, test_job_class_LDADD)
	(test_job_process_LDADD, test_job_LDADD, test_event_LDADD)
	(test_event_operator_LDADD, test_parse_job_LDADD)
	(test_parse_conf_LDADD, test_conf_LDADD, test_control_LDADD):
	Link blocked.o to most test suites.
	(test_blocked_SOURCES, test_blocked_LDFLAGS, test_blocked_LDADD):
	Details for test suite.

	* init/main.c: Also remove SIGTERM handling, we don't re-exec
	properly and this is a dangerous signal to use anyway.
	(term_handler): Drop function.

	* init/main.c: Remove handling for stop/cont; there's no reason
	a user should be able to pause the event queue.
	(stop_handler): Drop function.
	* init/event.c (event_poll): Remove paused handling.

	* init/control.c: Fix doc string.

	* dbus/com.ubuntu.Upstart.xml (ReloadConfiguration): Add method
	that's effectively the same as the HUP signal.
	* init/control.c (control_reload_configuration): Unsurprisingly,
	the implementation is identical.
	* init/control.h: Add prototype.
	* init/tests/test_control.c (test_reload_configuration): Make sure
	the method works as expected.
	(test_get_job_by_name, test_get_all_jobs): Add missing free calls for
	message in cases of out of memory.

	* dbus/com.ubuntu.Upstart.xml (JobAdded, JobRemoved): Add signals
	for when new jobs are added to the known list and when existing jobs
	are removed, this allows GUIs to always show an up-to-date list.
	* dbus/com.ubuntu.Upstart.Job.xml (InstanceAdded, InstanceRemoved):
	Also add matching signals for when instances are added to the list
	for a job and when they're removed again.
	* init/job_class.c (job_class_register): Emit the JobAdded signal
	for this job when registering if the new signal argument is TRUE;
	pass on the signal argument to job_register()
	(job_class_add): Emit signals when registering jobs with existing
	connections.
	(job_class_unregister): Emit signals when unregistering a job.
	* init/job.c (job_register): Likewise, emit the InstanceAdded signal
	for the job class if the new signal argument is TRUE.
	(job_new): Emit signals when registering instances with existing
	connections.
	(job_change_state): Emit the instance removed signal when destroying
	an inactive instance.
	* init/job_class.h, init/job.h: Add signal argument to prototypes
	* init/control.c (control_register_all): When registering job classes
	on a new connection, do not emit a signal since they will already
	exist at the point when the name appears on the bus or the connection
	is complete.
	* init/tests/test_control.c (test_bus_open): Add comment that we
	are testing for signal non-emission already with the fake server,
	since it was this test that actually made me realise we had to
	not emit them :p
	* init/tests/test_job_class.c (test_register): Test that the signal
	is emitted when signal is TRUE and not emitted when signal is FALSE
	(test_unregister): Test that the JobRemoved signal is emitted
	(test_get_instance_by_name, test_get_all_instances): Free message
	if allocation failed.
	(test_consider, test_reconsider): Test that the JobAdded and
	JobRemoved signals are emitted (or not) when appropriate.
	* init/tests/test_job.c (test_register): Make sure that the
	InstanceAdded signal is emitted when TRUE is passed, and not when
	FALSE is passed.
	(test_new): Make sure the InstanceAdded signal is emitted when the
	job is registered on the bus.
	(test_change_state): Make sure the InstanceRemoved signal is sent
	when deleting an instance.

2008-06-02  Scott James Remnant  <scott@netsplit.com>

	* init/tests/test_job.c (test_new, test_register): Also use a private
	dbus server to avoid session bus problems.

	* init/tests/test_job_class.c (test_consider, test_reconsider)
	(test_register, test_unregister): Use a private dbus server instead
	of connecting to the session bus, which might not be there.

	* init/tests/test_control.c (test_disconnected): Simplify using a
	private dbus server rather than faking one.

	* init/tests/test_control.c (test_bus_close): Don't rely on being
	able to connect to the various buses, instead use a special private
	one.

2008-06-01  Scott James Remnant  <scott@netsplit.com>

	* dbus/com.ubuntu.Upstart.Job.xml (GetAllInstances): And also add
	a similar method to return the object path of all instances of a
	particular job.
	* init/job_class.c (job_class_get_all_instances): Implement the
	method, pretty much the same as the other.
	* init/job_class.h: Add prototype.
	* init/control.c: Fix comment.
	* init/tests/test_control.c (test_get_all_jobs): Ensure that the
	individual paths are children of the array.

	* dbus/com.ubuntu.Upstart.xml (GetAllJobs): Add method to return
	the object path of all known jobs.
	* init/control.c (control_get_all_jobs): Implement the method,
	somewhat simple happily.
	* init/control.h: Add prototype for the method.
	* init/tests/test_control.c (test_get_all_jobs): Test that the
	right data is returned.

	* dbus/com.ubuntu.Upstart.xml, dbus/com.ubuntu.Upstart.Job.xml,
	* dbus/com.ubuntu.Upstart.Instance.xml: Add libnih XML NS to the
	files so that we can tag methods as sync or async later.

	* init/control.c (control_get_job_by_name): Remove const from
	return parameter.
	* init/control.h: Update prototype.
	* init/tests/test_control.c (test_get_job_by_name): Remove const
	from path type.

	* init/job_class.c (job_class_get_instance_by_name): Remove wrong
	const from parameter now that we've fixed the bindings generator.
	* init/job_class.h: Update prototype to match.
	* init/tests/test_job_class.c (test_get_instance_by_name): Change
	type of path to match.

	* HACKING (Dependencies): clarify that autoreconf and configure need
	to be run for libnih first.

	* init/Makefile.am (test_process_LDADD, test_job_class_LDADD)
	(test_job_process_LDADD, test_job_LDADD, test_event_LDADD)
	(test_event_operator_LDADD, test_parse_job_LDADD)
	(test_parse_conf_LDADD, test_conf_LDADD, test_control_LDADD): Link
	the auto-generated D-Bus code in, otherwise the tests won't be
	complete.

2008-05-24  Scott James Remnant  <scott@netsplit.com>

	* HACKING: Changed branch location again, of both upstart and
	libnih.

2008-05-16  Scott James Remnant  <scott@netsplit.com>

	* init/job_class.c (job_class_consider, job_class_reconsider): Find
	the best class first and compare against the current class before
	acting, this avoids the re-register jump every time a job stops.
	(job_class_select): Rename to job_class_add() since this is takes
	a class and is the direct opposite to job_class_remove().

2008-05-15  Scott James Remnant  <scott@netsplit.com>

	* init/event.c (event_new): We can't rely on the event poll function
	being the last in the main loop, it's often the first, so after
	adding an event to the queue ensure the loop is iterated at least
	once so that the event poll occurs for it.

2008-05-09  Scott James Remnant  <scott@netsplit.com>

	* TODO (Anytime): Update.

	* dbus/com.ubuntu.Upstart.Instance.xml: format to match others

	* dbus/com.ubuntu.Upstart.Job.xml (GetInstanceByName): Add method
	* init/job_class.c (job_class_get_instance_by_name): Implementation.
	* init/job_class.h: Add prototype.
	* init/tests/test_job_class.c (test_get_instance_by_name): Tests
	for new method.

	* init/job_class.h (JobClass): Make instances a hash table.
	* init/job_class.c (job_class_new): Initialise instances as a hash
	table now.
	(job_class_register): Iterate instances as hash table.
	(job_class_remove): Slightly odd construct needed to return FALSE
	if there's anything in the hash table.
	(job_class_unregister): Likewise to assert on no instances.
	* init/tests/test_job_class.c (test_new): Check that instances is
	now a hash table.
	* init/job.h (Job): Make name the first member.
	* init/job.c (job_new): Add to instances as hash table.
	(job_instance): Drop entirely, replaced by a hash lookup.
	* init/tests/test_job.c (test_instance): Drop.
	* init/job_process.c (job_process_find): Iterate instances as a
	hash table.
	* init/event.c (event_pending_handle_jobs)
	(event_finished_handle_jobs): Iterate instances as hash table.
	(event_pending_handle_jobs): Replace job_instance call with an
	ordinary hash lookup.
	* init/tests/test_event.c: Update to use hash table.
	* init/tests/test_conf.c: Update instances stealing for hash table

	* init/job_class.c (job_class_new): initialise instance to the
	empty string.
	* init/tests/test_job_class.c: Update job_new() calls.
	(test_new): Check instance against the empty string.
	* init/job.c (job_new): name may no longer be NULL.
	* init/tests/test_job.c: Update job_new() calls.
	(test_instance): Reset back to "" when done.
	* init/event.c (event_pending_handle_jobs): Always expand the
	name, since the class->instance is always non-NULL.
	* init/tests/test_event.c: Update job_new calls.
	* init/tests/test_conf.c: Update job_new calls.
	* init/tests/test_job_process.c: Update job_new calls.

	* init/job.c (job_new): Singleton jobs have a fixed name of "",
	rather than a NULL name, and a D-Bus name of "_".
	(job_instance): Which rather simplifies this function (in fact,
	it makes this function look like a common one).
	(job_emit_event): Always set INSTANCE variable.
	(job_name): Still distinguish in output, to avoid ugly "()" but
	check character rather than NULL.
	* init/tests/test_job.c (test_new): Check name is set to ""
	and path to ".../_"
	(test_change_state, test_emit_event): Update test cases to assume
	an empty INSTANCE variable
	(test_instance): Update to pass "" instead of NULL.
	* init/job_process.c (job_process_run): Always set UPSTART_INSTANCE
	* init/tests/test_job_process.c (test_run): Always assume an
	UPSTART_INSTANCE variable, it may just be empty.
	* init/tests/test_event.c (test_pending_handle_jobs): Expect
	the name to be set to the empty string.

	* init/Makefile.am (com.ubuntu.Upstart.c com.ubuntu.Upstart.h)
	(com.ubuntu.Upstart.Job.c com.ubuntu.Upstart.Job.h)
	(com.ubuntu.Upstart.Instance.c com.ubuntu.Upstart.Instance.h):
	Drop setting of data-type, turns out it doesn't work anyway.

	* dbus/Upstart.conf: Add configuration file.
	* dbus/Makefile.am (dbussystemdir, dist_dbussystem_DATA): Install
	the configuration file into the right place.

	* dbus/com.ubuntu.Upstart.xml (GetJobByName): Add method
	* init/control.c (control_get_job_by_name): Implementation.
	* init/control.h: Prototype.
	* init/tests/test_control.c (test_get_job_by_name): Test the
	method using a fake message.

2008-05-08  Scott James Remnant  <scott@netsplit.com>

	* dbus/com.ubuntu.Upstart.xml, dbus/com.ubuntu.Upstart.Job.xml,
	* dbus/com.ubuntu.Upstart.Instance.xml: Add DTDs.

	* init/control.c (manager_interfaces): Export the general
	com.ubuntu.Upstart interface
	* init/job_class.c (job_class_interfaces): Export the
	com.ubuntu.Upstart.Job interface
	* init/job.c (job_interfaces): Export the
	com.ubuntu.Upstart.Instance interface

	* init/Makefile.am (BUILT_SOURCES)
	(com.ubuntu.Upstart.c com.ubuntu.Upstart.h)
	(com.ubuntu.Upstart.Job.c com.ubuntu.Upstart.Job.h)
	(com.ubuntu.Upstart.Instance.c com.ubuntu.Upstart.Instance.h):
	Generate C code and header files from the XML files which produce
	object bindings.
	(init_SOURCES): Link the built sources.
	(CLEANFILES): Clean them up afterwards

	* dbus/com.ubuntu.Upstart.xml: Initially empty description for
	manager object interface(s).
	* dbus/com.ubuntu.Upstart.Job.xml: Initially empty description
	for job class object interface(s).
	* dbus/com.ubuntu.Upstart.Instance.xml: Initially empty
	description for job instance object interface(s).
	* dbus/Makefile.am: Distribute the three interface files,
	they're used as sources elsewhere.
	* configure.ac (AC_CONFIG_FILES): Generate dbus/Makefile
	* Makefile.am (SUBDIRS): Descend into the dbus sub-directory.

	* init/job_class.c (job_class_consider, job_class_reconsider):
	Separate out the actual meat of the functions, since it's largely
	duplicated between the two.  This makes the difference between
	the two functions clearer, consider always stages an election
	no matter which is registered, reconsider only stages an election
	if the current class is registered.
	(job_class_select, job_class_remove): Functions containing the
	common code, which now also handle registering and unregistering
	the class with D-Bus.  Here is the right place, not in new, since
	we only export the current best class of a given name.
	(job_class_register, job_class_unregister): Function to register
	a job and its instances, and to unregister a job (we assert that
	there must be no instances for us to do this).
	* init/job_class.h: Add prototypes.
	* init/tests/test_job_class.c (test_consider, test_reconsider):
	Check that D-Bus registration and unregistration happens as
	expected.
	(test_register, test_unregister): test on their own.
	* init/job.c (job_new): Register instances with D-Bus, since
	instances can only ever exist for active classes, all instances
	are always registered on the bus.
	(job_register): Function to register an instance on the bus.
	* init/job.h: Add prototype.
	* init/tests/test_job.c (test_new): Test creating a job with an
	active d-bus connection, which should have it registered.
	(test_register): Test registration on its own.
	* init/control.c (control_register_all): Make this always succeed,
	and register existing jobs on the new connection.
	(control_server_connect, control_bus_open): registration is
	always successful.
	* init/tests/test_control.c (test_server_connect, test_bus_open):
	Test with existing jobs when we get a connection or create the
	bus connection, ensure that the jobs and instances are registered.

	* init/tests/test_job.c (test_change_state): Check for a bug where
	a job with multiple instances will be freed when one instance is
	deleted rather than the last instance.
	* init/job.c (job_change_state): Add debugging messages when we
	destroy a job that's no longer the current one or an instance
	that's no longer active; also ensure that we never destroy a job
	that's the current one.
	* init/event.c (event_pending_handle_jobs): Add a debugging message
	when we create a new instance of a job.
	* init/conf.c (conf_file_destroy): Add a debugging message when
	we destroy a job that's no longer the current one.

2008-05-07  Scott James Remnant  <scott@netsplit.com>

	* init/control.c (control_server_open, control_server_close)
	(control_server_connect): Create and manage a listening d-bus server
	that is used for private direct connections to Upstart for when the
	d-bus daemon is not available.  Each new connection has the same
	objects as the d-bus system bus, they only differ in their method.
	(control_conns, control_init): Cache the open connections, including
	the bus daemon and any private connections; we'll iterate this list
	when sending signals.
	(control_bus_open): Store connection in the list, don't worry about
	setting close-on-exec, we check that by test case and rely on d-bus
	to do it.
	(control_bus_disconnected): Rename to control_disconnected
	(control_disconnected): Work for system bus and private connections,
	remove from the connections list.
	* init/control.h: Add prototypes, remove global definition of bus
	name to just being private again.
	* init/tests/test_control.c (test_server_open, test_server_close)
	(test_server_connect): Test the new functions.
	(test_bus_open): add check for list entry
	(test_bus_disconnected): rename to test_disconnected
	* init/main.c: Open the listening server, warning if we're unable
	to do so (but we won't treat it as a hard error since there's the
	d-bus daemon as the default anyway).
	* init/init.supp: suppress the fact that the control connections
	list stays around.

	* init/job_process.c (job_process_run): Use NIH_ZERO instead of
	NIH_MUST and == 0

2008-05-06  Scott James Remnant  <scott@netsplit.com>

	* init/environ.c (environ_expand_until): Odd gcc optimiser warning,
	it reckons arg_start and end may be used uninitialised, but I don't
	see how they can be.

	* init/main.c (main): Warn if we can't set the root directory.
	* init/job_process.c (job_process_spawn)
	(job_process_error_abort): loop on the return of write()
	* init/tests/test_job_process.c (child, main): assert getcwd() works
	(test_handler): initialise list and entry for gcc's blind spot.
	(test_run): initialise ret for gcc's blind spot
	* init/tests/test_job.c (test_name): jump through hoops for gcc
	(test_change_state): list and entry.
	* init/tests/test_event.c (test_finished_handle_jobs, test_finished)
	(test_pending_handle_jobs, test_poll, test_pending): initialise to
	NULL and buy gcc glasses
	* init/tests/test_event_operator.c (test_operator_collect): another
	NULL to make gcc happy.

2008-05-01  Scott James Remnant  <scott@netsplit.com>

	* TODO: Update.

	* init/init.supp: Suppress a few test case artefacts caused by
	valgrind hating reachable memory at exec() time.

	* init/tests/test_job_process.c: Fix a few cases where we were
	still dup'ing the name argument to job_new().
	* init/tests/test_parse_job.c: Include missing signal.h

	* init/event.c (event_pending_handle_jobs)
	(event_finished_handle_jobs): Land the old job event handling
	functions here as static functions, right now they're immense but
	we'll actually move much of the code back out again as we go.
	* init/tests/test_event.c (test_pending_handle_jobs)
	(test_finished_handle_jobs): Also land the test cases in renamed
	and somewhat restructued functions, since we now have to do the
	testing through event_poll().
	(test_poll, test_pending, test_finished): It never hurts to improve
	test cases while you're in there.

2008-04-30  Scott James Remnant  <scott@netsplit.com>

	* init/job.c (job_change_state): Change calls to job_process_run
	and job_process_kill.
	* init/main.c: Change to job_process_handler

	* init/job_process.c, init/job_process.h: Land the code from job.c
	and defs from job.h that deal specifically with a job's processes,
	rename the functions to job_process_*() in the process.
	* init/tests/test_job_process.c: And land the test cases as well.

	* init/job.c: Strip of everything not related to creation and finding
	of instances and the core state machine; process stuff will move to
	job_process.c and event handling to event.c, class (nee config) stuff
	is already moved to job_class.c
	(job_new): Don't reparent the name, it doesn't help anything, just
	take a copy.
	(job_name, job_failed, job_unblock, job_emit_event): Make extern since
	we need to use these outside or just want to test them.
	* init/job.h: Clean out also.
	* init/tests/test_job.c: Also clean out.
	(test_name, test_failed, test_unblock, test_emit_event): Add test cases
	for newly extern functions.

	* init/main.c: Include events.h to get the ones we need.

	* init/control.c (control_job_config_path, control_job_path)
	(control_path_append): Drop these functions (replaced by the more
	generic nih_dbus_path() function)
	* init/control.h: Make CONTROL_ROOT public, and drop other prototypes.
	* init/tests/test_control.c (test_job_config_path)
	(test_job_path): Drop tests.

2008-04-29  Scott James Remnant  <scott@netsplit.com>

	* init/event.c, init/event.h, init/tests/test_event.c: Strip out the
	event operator code and events list.

	* init/job_class.c, init/job_class.h: We only need the event operator
	code here now.

	* init/events.h, init/event_operator.c, init/event_operator.h,
	init/tests/test_event_operator.c: Separate out the event operator
	code and the list of events into separate source files.
	* init/Makefile.am (init_SOURCES): Build and link event operator code
	and use the lists of events.
	(TESTS): Build and run the event operator test suite.
	(test_event_operator_SOURCES, test_event_operator_LDFLAGS)
	(test_event_operator_LDADD): Details for the event operator test
	suite.
	(test_process_LDADD, test_job_class_LDADD)
	(test_job_process_LDADD, test_job_LDADD, test_event_LDADD)
	(test_parse_job_LDADD, test_parse_conf_LDADD, test_conf_LDADD)
	(test_control_LDADD): Link the event operator code.

	* init/job_class.c, init/main.c: Correct includes and some function
	names.

	* init/process.c, init/process.h, init/tests/test_process.c: Land
	original Process code (used by job class and similar).

	* init/process.c, init/process.h, init/tests/test_process.c: Break
	into two pieces, one part becomes job_process which requires both
	job information and process information, the other becomes system
	which requires no job information.
	* init/errors.h: Update error name.
	* init/Makefile.am (init_SOURCES): Build and link job process code
	and header along with system code and header.
	(TESTS): Build and run job process and system test suites.
	(test_job_process_SOURCES, test_job_process_LDFLAGS)
	(test_job_process_LDADD): Details for job process test suite.
	(test_system_SOURCES, test_system_LDFLAGS, test_system_LDADD):
	Details for system test suite.
	(test_process_LDADD, test_job_class_LDADD, test_job_LDADD)
	(test_event_LDADD, test_parse_job_LDADD, test_parse_conf_LDADD)
	(test_conf_LDADD, test_control_LDADD): Link job process and system
	code.

	* init/parse_conf.c: Remove parse_job include.

	* init/init.supp: Update leak check for class init; remove
	valgrind workaround since it's gone away with the change of that
	function.

	* init/conf.h (ConfFile): Change type of job member, but leave name.
	Add prototype for new function.
	* init/conf.c (conf_reload_path): Somewhat simplify the case of
	having parsed a job, we only need to call job_class_consider() now
	to have it dealt with.
	(conf_file_destroy): Likewise after removing the ConfFile from the
	source (so it won't get considered) and marking the job class as
	deleted, we only need to call job_class_reconsider() and check the
	return value to see whether we've been replaced.
	(conf_select_job): In return we provide the function to decide which
	of the available job sources is the best one.
	* init/tests/test_conf.c: Update types in tests.
	(test_select_job): Test the new function.

	* init/parse_job.h: Update to include job_class.h and update prototype
	to return JobClass, we'll keep the name though since we'll never
	parse jobs and otherwise things get annoying.
	* init/parse_job.c: Update to work on job classes.
	* init/tests/test_parse_job.c: Update to match.

	* init/job_class.h (JobClass): Factor out old JobConfig object into
	a new JobClass object with the same properties, but in its own source
	file.
	(ExpectType): Rename old JobExpect to this to match other enums.
	(ConsoleType): Move along with the object that uses it.
	* init/job_class.c (job_class_init, job_class_new)
	(job_class_environment): Bring along methods that only operate on
	a JobClass, cleaning them up in the process.
	(job_class_consider, job_class_reconsider): Replace job_config_replace
	with these two functions that may be used for a new job class and
	when discarding or finishing with an old one respectively.
	* init/tests/test_job_class.c: Tests for the functions.
	* init/Makefile.am (init_SOURCES): Build and link job class source
	and header.
	(TESTS): Build and run job class test suite.
	(test_job_class_SOURCES, test_job_class_LDFLAGS)
	(test_job_class_LDADD): Details for job class test suite.
	(test_process_LDADD, test_job_LDADD, test_event_LDADD)
	(test_parse_job_LDADD, test_parse_conf_LDADD, test_conf_LDADD)
	(test_control_LDADD): Link job class code to other tests too.

2008-04-28  Scott James Remnant  <scott@netsplit.com>

	* init/control.c (control_job_config_path, control_job_path): Add
	functions to generate D-Bus object paths for jobs and instances
	(control_path_append): and a static function used by both to append
	escaped path elements.
	* init/control.h: Add prototypes.
	* init/tests/test_control.c (test_job_config_path)
	(test_job_path): Add test cases for the new functions.
	* init/job.h (JobConfig, Job): Add path member to both structures.
	* init/job.c (job_config_new, job_new): Initialise the path members.
	* init/tests/test_job.c (test_config_new, test_new): Make sure
	the path members are initialised to something sensible.
	* init/init.supp: Valgrind whines, I do not know why.

	* init/control.c (control_bus_open): Call out to register objects
	on the new bus connection.
	(control_register_all): Start off by registering the connection
	manager object, no methods/signals for now.
	* init/tests/test_control.c (test_bus_open): Make sure the manager
	object is registered.

2008-04-27  Scott James Remnant  <scott@netsplit.com>

	* init/tests/test_control.c (test_bus_open): Correct name of
	error macro.

	* init/job.c (job_emit_event): Make INSTANCE the second variable.
	* init/tests/test_job.c (test_next_state): Update tests.

2008-04-25  Scott James Remnant  <scott@netsplit.com>

	* init/tests/test_control.c (test_bus_open): Use D-bus macros for
	error strings instead of naming them by hand.

2008-04-22  Scott James Remnant  <scott@netsplit.com>

	* init/tests/test_control.c (test_bus_close): Add another missing
	call to dbus_shutdown.

2008-04-21  Scott James Remnant  <scott@netsplit.com>

	* init/tests/test_control.c (test_bus_open): Under valgrind we seem
	to get NoReply instead of Disconnected which is a wee bit odd.
	Add missing call
	(test_bus_disconnected): Add missing call to dbus_shutdown.

2008-04-19  Scott James Remnant  <scott@netsplit.com>

	* init/process.c: Add missing limits.h include

	* init/job.h (JobConfig): Merge instance and instance_name; if
	instance is set, the job is multi-instance with the name derived
	from that; if unset the job is singleton.  We will not support
	unlimited instances.
	* init/job.c (job_config_new): Initialise instance to NULL.
	(job_new): Assert that name is set for instance jobs.
	(job_instance): Alter to only deal with singleton and instance
	jobs, the unlimited instances case is gone.
	(job_handle_event): Use instance instead of instance_name
	* init/tests/test_job.c (test_config_new): Check instance is NULL
	(test_find_by_pid): Adjust the way instance jobs are made, which
	means we have to pass a name to job_config_new now.
	(test_instance): Adjust tests to remove unlmited-instance tests
	and pass name to job_config_new
	(test_change_state, test_run_process): Pass instance name to
	job_new as an allocated argument rather than waiting to set it
	until afterwards.
	(test_handle_event): Set instance instead of instance_name
	* init/parse_job.c (stanza_instance): Make the argument mandatory.
	* init/tests/test_parse_job.c (test_stanza_instance): Remove the
	checks for without argument, and make sure that without argument
	is an error.

	* init/parse_job.c (stanza_oom): Oops, forgot to free never arg.

	* init/job.h (JobConfig): NihList is rather overkill for emits,
	which is static configuration; turn into a NULL-terminated array
	which'll make it easier to turn into a D-Bus property later.
	* init/job.c (job_config_new): Initialise to NULL now.
	* init/tests/test_job.c (test_config_new): Make sure it's NULL.
	* init/parse_job.c (stanza_emits): Store in an array instead.
	* init/tests/test_parse_job.c (test_stanza_emits): Redo tests.

	* init/job.c (job_emit_event): Append exported variables to the
	job event without overwriting the builtins.
	* init/tests/test_job.c (test_change_state): Check that exported
	environment is added to the job events.

	* init/parse_job.c (stanza_export): Parse a new export stanza,
	which takes one or more environment variable names.
	* init/tests/test_parse_job.c (test_stanza_export): Test the new
	stanza.

	* init/job.h (JobConfig): Add new export member.
	* init/job.c (job_config_new): Initialise to NULL.
	* init/tests/test_job.c (test_config_new): Make sure it's NULL.

	* init/environ.c (environ_add, environ_set): Add a replace argument
	which when FALSE does not replace existing entries in the environment
	table.
	* init/environ.h: Adjust prototypes.
	* init/tests/test_environ.c (test_add): Add tests for non-replacement
	mode, including corner cases.
	(test_set): Replace should be TRUE in this test.
	* init/event.c (event_operator_collect): Always replace existing
	environment members.
	* init/job.c (job_config_environment, job_run_process): Always replace
	existing environment members.
	(job_emit_event): Always replace existing environment members, and
	rework this function to get rid of the confusing gotos.

	* init/tests/test_job.c (test_change_state): Add tests to make sure
	we include the INSTANCE variable in the event environment.

2008-04-18  Scott James Remnant  <scott@netsplit.com>

	* init/process.c (process_kill): Make sure we do send the signal to
	the process group; in practice this makes no difference, but it pays
	to be explicit in such things.
	* init/tests/test_process.c (test_kill): Add a test case for when
	the session leader is no more.

	* init/job.h (JobConfig): Another day, another obscure job config
	detail.  This one is for adjusting how likely you are to be killed
	by the OOM Killer.
	* init/job.c (job_config_new): Set to zero by default.
	* init/tests/test_job.c (test_config_new): And make sure it is zero.
	* init/parse_job.c (stanza_oom): And it helps to have a function
	to set that one.
	* init/tests/test_parse_job.c (test_stanza_oom): Test it.
	* init/errors.h: And we need an error if its out of bounds.
	* init/conf.c (conf_reload_path): Which also needs to be caught.
	* init/process.c (process_spawn): Of course, we have to do something
	with the oom adjustment.
	(process_error_read): message for failure error.
	* init/process.h (processErrorType): And need an error if it fails

	* init/main.c: Drop the legacy configuration directory, the format
	of jobs has changed sufficiently to not support it.
	* init/Makefile.am (AM_CPPFLAGS): Remove LEGACY_CONFDIR definition.
	(install-data-local): Don't create it, either.

	* init/enum.c, init/enum.h, init/tests/test_enum.c: Remove these
	source files, a hold-over from when we had them in a separate
	library and passed around the integer values.
	* init/job.c, init/job.h, init/tests/test_job.c: Restore in their
	proper place.
	* init/Makefile.am: Remove enum.* from build instructions.

	* init/main.c: Attempt to connect to the system bus on startup,
	but don't expect it to work.

	* init/control.c (control_bus_open, control_bus_disconnected)
	(control_bus_close): Functions to open a connection to the D-Bus
	system bus, clean up if disconnected or disconnect ourselves
	explicitly.
	* init/control.h: Prototypes.
	* init/tests/test_control.c (test_bus_open)
	(test_bus_disconnected, test_bus_close): Test the functions using
	a fake D-Bus system bus daemon.
	* init/errors.h: Add error for "name taken".
	* init/Makefile.am (init_SOURCES): Build and link control.c and
	control.h
	(TESTS): Build and run control test suite.
	(test_control_SOURCES, test_control_LDFLAGS, test_control_LDADD):
	Details for control test suite.
	(test_process_LDADD, test_job_LDADD, test_event_LDADD)
	(test_parse_job_LDADD, test_parse_conf_LDADD, test_conf_LDADD):
	Link control.o

2008-04-16  Scott James Remnant  <scott@netsplit.com>

	* init/job.h (JobConfig): Add leader member.
	* init/job.c (job_config_new): Initialise leader to FALSE.
	* init/tests/test_job.c (test_config_new): Make sure leader is FALSE.
	(test_change_goal, test_change_state, test_run_process)
	(test_kill_process, test_child_handler, test_handle_event)
	(test_handle_event_finished): Jobs have to be leaders now to allow
	waitpid() to work in test cases.
	* init/parse_job.c (stanza_session): Parse "session leader" stanza
	to set to TRUE.
	* init/tests/test_parse_job.c (test_stanza_session): Test new
	stanza parsing.
	(test_stanza_console): Add missing "missing argument" test.
	* init/process.c (process_error_read): Deal with new fork error.
	(process_spawn): If we're not to be a session leader, fork again and
	write the pid back on the open socket.
	* init/process.h (ProcessErrorType): Introduce new fork error.
	* init/tests/test_process.c (test_spawn): Test that we can't start
	a non-session-leader and still have process details.
	(test_spawn, test_kill): Other jobs have to be leaders now to
	allow waitpid() to work.
	* init/tests/test_event.c (test_poll): Jobs have to be leaders now
	to allow waitpid() to work.

2008-04-12  Scott James Remnant  <scott@netsplit.com>

	* configure.ac (NIH_INIT): Require that libnih build D-Bus support,
	failing configure if we can't get it.
	* init/Makefile.am (AM_CFLAGS): Build with D-Bus CFLAGS,
	(init_LDADD, test_process_LDADD, test_job_LDADD, test_event_LDADD)
	(test_parse_job_LDADD, test_parse_conf_LDADD, test_conf_LDADD): and
	link with libnih-dbus.la and D-Bus LIBS.
	(init_LDFLAGS): No need for -static now since libnih will only exist
	statically anyway.

	* init/main.c: Use a better name for kbdrequest
	* init/event.h (KBDREQUEST_EVENT): Rename event to keyboard-request

	* init/main.c: Drop the attempt to rescue a crashed system by
	carrying on with no state
	(crash_handler): After the child has core dumped, the parent will
	die and the kernel will panic.  That's the best we can do, I think.

	* init/job.c (job_change_state): Don't generate the stalled event;
	there's nothing useful you can do with it other than start a root
	shell and that's just a security hole waiting to happen.
	(job_new): Don't increment the instances counter.
	* init/job.h: Remove extern for instances counter.
	* init/tests/test_job.c (test_new): Remove the check that the
	instance counter is incremented.
	(test_change_state): Remove the test for the stalled event.
	* init/event.h (STALLED): Remove stalled event definition,
	* TODO: Update.

	* init/job.h (Job): And while we're at it, the instance name is
	guaranteed unique for a given job name, which is also guaranteed
	to be unique - so don't bother with job ids either, since they
	also get reused in bad cases.
	* init/job.c (job_next_id): Drop this function.
	(job_new): Don't assign an id anymore.
	(job_find_by_id): Drop this function.
	(job_run_process): Set UPSTART_INSTANCE to the instance name if set.
	(job_name): Function to create the string used in messages.
	(job_change_goal, job_change_state, job_run_process)
	(job_kill_process, job_kill_timer, job_child_handler)
	(job_process_terminated, job_process_trace_new)
	(job_process_trace_new_child, job_process_trace_signal)
	(job_process_trace_fork, job_process_trace_exec): Use the instance
	name in messages (if set) in place of the job id.
	* init/tests/test_job.c (test_new): Drop checks on the id field.
	(test_find_by_id): Drop test.
	(test_run_process): Check that UPSTART_INSTANCE is set only for
	named job instances, and contains the instance name.
	(test_change_state, test_run_process, test_child_handler): Remove
	id setting and update error message checks.
	* TODO: Update.

	* init/event.h (Event): We don't use the id field for anything;
	and it can't be guaranteed to be unique since it can wrap over
	and get reused.  Drop it.
	* init/event.c (event_next_id): Drop this function.
	(event_new): Don't assign an id anymore.
	(event_find_by_id): Drop this function.
	* init/tests/test_event.c (test_new): Drop checks on the id field
	(test_find_by_id): Drop test.
	(test_poll): Drop id setting which was needless anyway.

2008-04-11  Scott James Remnant  <scott@netsplit.com>

	* init/tests/test_job.c (test_child_handler): Add tests to make
	sure that respawn works for both services and tasks; the only
	difference we want for tasks is that zero is a normal exit code.
	* init/job.c (job_process_terminated): Status need not be non-zero
	if the job is not a task.

	Change the default job type from task to service, which will
	finally match people's expectations.

	* init/job.h (JobConfig): Replace service member with task
	* init/job.c (job_config_new): Initialise task to FALSE
	(job_change_state): Unblock if not a task instead of if a service
	* init/tests/test_job.c (test_config_new): Make sure task is FALSE
	(test_change_state): Check service by default, task with flag;
	this also means we expect blockers to be cleared if we end up in
	running for the other checks
	(test_child_handler): Expect blockers to be cleared if we end up
	in running now that service is the default.
	* init/tests/test_event.c (test_poll): Test with a task since
	we want to remain blocked for longer.
	* init/parse_job.c (stanza_respawn): Don't set service to TRUE
	(stanza_service): Rename to stanza_task and set task flag instead
	* init/tests/test_parse_job.c (test_stanza_respawn): Remove checks
	for setting of service flag
	(test_stanza_service): Rename to test_stanza_task and test task

	* init/job.c (job_init): Create hash using nih_hash_string_new()
	* init/conf.c (conf_source_new): Likewise.

2008-03-08  Scott James Remnant  <scott@netsplit.com>

	* HACKING: Terminology changes: Bazaar-NG is now just Bazaar;
	Malone is now just Launchpad's bug tracking system.  Update bugs
	URL to match modern form.

	* init/enum.h (JobWaitType): Rename to JobExpect
	* init/job.h (JobConfig): Rename wait_for to expect
	* init/job.c (job_config_new, job_change_state, job_run_process)
	(job_process_stopped, job_process_trace_new_child): Rename wait_for
	to expect in all occurances.
	* init/tests/test_job.c: Likewise rename all occurances.
	* init/parse_job.c (stanza_wait): Rename to stanza_expect and drop
	the intermediate argument.
	* init/tests/test_parse_job.c (test_stanza_wait): Rename to
	test_stanza_expect and adjust tests to match new syntax.
	* init/tests/test_process.c (test_spawn): Remove set of wait_for.

	* doc/states.dot: Remove the state transition from starting to
	waiting ("emit_stopped" in the graph); we don't have a "respawning
	too fast" exit here anymore, so always go to stopping.
	* doc/states.png: Regenerate.

	* TODO: Document the problems with overflowing ids and instance
	counter before I forget about them.

2008-03-07  Scott James Remnant  <scott@netsplit.com>

	* TODO: Update.

	* init/job.h (JobConfig): Add instance_name member.
	(Job): Add name member.
	* init/job.c (job_config_new): Initialise instance name to NULL.
	(job_new): Accept the name as an argument, reparenting and stealing
	(job_handle_event): Expand the instance name and pass to job_new
	(job_instance): Accept a name and look that up in the list of current
	instances returning the instance if found.
	* init/tests/test_job.c: Add extra argument to all job_new calls
	(test_config_new): Make sure instance name is initialised to NULL.
	(test_handle_event): Make sure the job name is set from the instance,
	and make sure an existing instance is reused if we can.
	(test_instance): Make sure that the existing instance is returned.
	* init/parse_job.c (stanza_instance): Check for an optional argument
	and store it in the instance_name member if it exists, otherwise
	free and reset the instance_name member.
	* init/tests/test_parse_job.c (test_stanza_instance): Check the new
	argument is handled properly and stored in the right place.
	* init/tests/test_conf.c (test_source_reload_job_dir)
	(test_file_destroy): Add extra NULL to job_new
	* init/tests/test_event.c (test_poll): Add extra NULL to job_new

	* init/event.c (event_operator_match): Accept an environment array
	and expand the operator value against it before attempting to match.
	(event_operator_handle): Also accept the environment array and pass
	through to calls to event_operator_match().
	* init/event.h: Update prototypes.
	* init/tests/test_event.c (test_operator_match): Add extra NULL
	argument to most tests, and add tests for known and unknown variable
	references.
	(test_operator_handle): Add extra NULL arguments to most tests, and
	add test for passing of environment through.
	(test_operator_reset): Add extra NULL argument to call.
	* init/job.c (job_handle_event): Pass the job environment for the
	stop event handling, but NULL for the start event.
	* init/tests/test_job.c (test_handle_event): Make sure that a stop
	operator is expanded from the job environment before being matched
	against the stop event.

	* init/event.c, init/event.h, init/environ.c: Documentation tweaks.

	* init/job.c (job_change_state): Remove the code to check for runaway
	jobs from here, we'll always let people explicitly start an instance.
	(job_process_terminated): Call job_catch_runaway when actually doing
	the respawn instead.
	* init/tests/test_job.c (test_change_state): Remove "too fast" checks,
	we're going to allow start/stop requests to restart jobs as much as
	they like since this is an external request.
	(test_handle_event, test_handle_event_finished): No need to remove
	a respawn limit with this behaviour.
	(test_child_handler): Instead check that the respawn counter is
	dealt with by the child handler.

	* TODO: Update, I found a bug with the current model.

	* init/tests/test_environ.c (test_expand): Check that a string
	without an expansion still works ok.

2008-03-06  Scott James Remnant  <scott@netsplit.com>

	* init/event.c (event_operator_collect): Just use strcat functions.

2008-03-03  Scott James Remnant  <scott@netsplit.com>

	* init/environ.c (environ_valid): New function to check the validity
	of an environment variable name, should call before accepting any.
	(environ_expand_until): New function to expand variable references
	in a string using an environment table; supports a few common
	shell-like expressions.
	(environ_getn): Change to return the value of the string, not the
	entire environment string.
	* init/environ.h: Add prototypes.
	* init/errors.h: Add errors raised by new functions.
	* init/tests/test_environ.c (test_valid, test_expand): Add test
	cases for the new functions.
	(test_get, test_getn): Change test case to check for the variable
	value instead of returning the whole string.

	* TODO: Add thoughts on blocking commands.

	* TODO: Update.

	* init/event.h (Event): Remove the refs member; we now never hold
	a reference to an event we're blocking since we always copy the
	environment out if we want to keep it.
	(EventOperator): Events are always blocked while we hold them,
	so drop the blocked member.
	(EventProgress): The done state is no longer needed, we can free
	in finished now.
	* init/event.c (event_ref, event_unref): Drop these functions.
	(event_new): Don't ininitialise the refs member since it's gone.
	(event_poll): Remove the done state since it's directly freed
	in event_finished again
	(event_finished): No done state, event is freed before return.
	(event_operator_new): No blocked member.
	(event_operator_copy): Always block the event after copying.
	(event_operator_destroy): Simply unblock.
	(event_operator_handle): Simply block the event on match.
	(event_operator_collect): Always block the copied event
	(event_operator_unblock): This function is no longer required, since
	it has an identical effect to reset.
	(event_operator_reset): Simply unblock the event.
	* init/tests/test_event.c (test_new): Drop the check for refs
	being initialised to zero.
	(test_ref, test_unref, test_operator_collect): Drop test for
	functions that have been dropped in the code.
	(test_operator_new): Drop the check for blocked being initialised
	to FALSE.
	(test_block, test_unblock, test_operator_destroy): Drop any references
	to the refs member.
	(test_operator_destroy): Actually fix the function to test things.
	(test_poll): Drop the check for remaining in the done state.
	(test_operator_new, test_operator_copy): Drop the checks for blocked.
	(test_operator_handle, test_operator_collect, test_opreator_reset):
	Drop references to refs and blocked.
	* init/job.c (job_unblock, job_handle_event): Drop the call to
	event_unref() since the next call was always event_unblock() and
	that's the one that we didn't delete.
	* init/tests/test_job.c (test_change_state, test_child_handler)
	(test_handle_event, test_handle_event_finished): Events don't
	have references anymore, so remove calls to reference, unreference
	and checks for the reference count - it's all done with blocks now.
	(test_new): Remove check that the operator is not blocked for a
	new job since there's no such thing now.
	(test_handle_event): Operators don't have a blocked member anymore,
	if there's an event, it's blocked.

	* init/job.c (job_change_state): Don't reference the event we're
	blocked on, we'll always know when it's finished.
	(job_handle_event_finished): Likewise no reason to unreference it.
	* init/tests/test_job.c (test_change_goal, test_child_handler)
	(test_handle_event, test_change_state)
	(test_handle_event_finished): Remove the expectation that the blocked
	event is referenced by the job.
	* init/tests/test_event.c (test_poll): Don't reference the event,
	since the job would not have.

	* init/job.c (job_emit_event): Use environ_add/set for style
	reasons.

	* init/job.c (job_handle_event): Reset the stop_on operator after
	processing the event, thus the expression needs to be completely
	reevaluated before the job can be stopped again by it.  At last,
	correct behaviour!
	(job_change_state): No reason to reset the stop_on operator when
	starting since it's always reset after evaluating to TRUE now;
	likewise no reason to reset on re-entering running or waiting,
	job_unblock() is sufficient.
	(job_failed): No reason to iterate stop_on to set failed, it's
	empty - job_unblock() does what we want.
	* init/tests/test_job.c (test_handle_event): Check that the operator
	is actually reset and the event not referenced when handling from
	the event.
	(test_change_state, test_child_handler): Don't put anything in stop_on
	and thus don't expect anything to come out of it -- event environment
	is all done in stop_env and blocking done in blocking.

	* init/job.c (job_handle_event): Collect the stop events and store
	them in the blocking list, unblocking any that were there before
	such as the start events.
	(job_change_state): Unblock blocking events when returning to running
	from pre-stop.
	* init/tests/test_job.c (test_handle_event): Make sure the stop
	events are collected and replace any previously blocking events.
	(test_change_state, test_child_handler): Test that stop events in
	the blocking list are kept and unblocked when necessary.

2008-03-02  Scott James Remnant  <scott@netsplit.com>

	* init/job.c (job_change_state): Shouldn't emit the started event
	on pre-stop cancellation, and shouldn't unblock the job because
	it's a service.

	* init/job.c (job_change_state): Throw away the stop environment
	when starting and returning to running.
	* init/tests/test_job.c (test_change_state): Make sure the stop
	environment is actually thrown away.

	* init/job.c (job_run_process): Append the environment from the
	stop events if given the pre-stop process to run; do this before
	the special events so they can never be overriden.
	* init/tests/test_job.c (test_run_process): Check that the stop event
	environment is included for pre-stop and not for other jobs.

	* init/job.c (job_handle_event): Remove setting of UPSTART_JOB
	and UPSTART_JOB_ID, we set that when we run the process.
	* init/tests/test_job.c (test_handle_event): Don't check for
	UPSTART_JOB and UPSTART_JOB_ID since we no longer copy it in here.

	* init/job.c (job_run_process): Copy the environment to pass it to
	the job, appending the UPSTART_JOB and UPSTART_JOB_ID variables here;
	we never want to be able to match these, etc.
	* init/tests/test_job.c (test_run_process): Add tests to make sure
	that the environment is actually set in the processes we run.

	* init/job.h (Job): Add stop_env member to store environment from
	stop events for the stop script.
	* init/job.c (job_new): Initialise stop_env to NULL.
	(job_handle_event): Copy environment from the stop_on operator into
	the stop_env member.
	* init/tests/test_job.c (test_new): Check that stop_env is NULL.
	(test_handle_event): Add lots of tests to make sure that the
	environment is collected from the events and stored in stop_env
	properly, overwriting what was there already if necessary.

	* init/init.supp (job-run-process-args): Add a suppression for the
	fact that job_run_process will leak its arguments to a new process
	assuming that it will call exec() or exit()

	* init/tests/test_job.c (test_child_handler): Remove bogus free tag
	of the list, which we don't use in this test (valgrind failure)

	* init/job.h (Job): Remove the start_on member.
	* init/job.c (job_new): Don't initialise start_on since it's gone.
	(job_change_state): Drop call to unblock the start_on operator since
	the events are already unblocked by job_unblock.
	(job_failed): Drop setting of start_on events to failed since this
	is already done by job_unblock.  This results in a slight change in
	behaviour, now when a job fails to start - the event or command will
	be immediately unblocked since there's no point waiting until it
	stops again - it was waiting for it to start.
	* init/tests/test_job.c (test_new): Remove start_on checks
	(test_change_state, test_child_handler, test_handle_event): Remove
	all references to start_on, instead relying on the blocking checks
	instead.
	* init/tests/test_event.c (test_poll): Remove solitary reference
	to job's start_on, this wasn't necessary anyway - we proved that it
	was the right event by affecting the job.  Revert previous commit
	that temporarily increased the number of references, they should be
	one again now only the blocking list holds them.

	* init/job.h (job): Add blocking member, a list of events that we're
	blocking from finishing.
	* init/job.c (job_new): Initialise blocking member to NULL.
	(job_handle_event): Collect the list of events from the operator
	and store them in the job's blocking list (unblocking any existing
	first); if the job is already running, unblock unref and discard.
	(job_unblock): New function to deal with unblocking the events we're
	holding onto and resetting the blocking list; this will be extended
	later to also unblock any command.
	(job_change_state): Unblock events in running for services and in
	waiting for everything.
	(job_failed): Unblock events and mark them as failed.
	* init/tests/test_job.c (test_new): Check that it's initialised to NULL
	(test_handle_event): Extend the test cases to check the value of the
	blocking list, and to make sure that the previous blocking list is
	overwritten when necessary.
	(test_change_state, test_child_handler): Extend test cases so that
	wherever we're had a blocked event in start_on, we also have that in
	the blocking list.
	* init/tests/test_event.c (test_poll): Temporarily increase the
	expected number of references/blockers to the event in the poll
	test.

	* init/job.h (Job): Add start_env member, this stores the environment
	to use when starting the event so it doesn't overwrite the current
	environment of a restarting job.
	* init/job.c (job_handle_event): Do the heavy lifting of starting a
	new job instance here; construct the environment from the built-ins
	and configured, append that collected from the start events, locate
	or create a new instance, add the job name and id then copy into
	the new start_env member before starting the job.  At some point
	this will probably all become a function since it'll be similar for
	the control functions.
	(job_change_state): Copy the start_env member into the env member
	when in the starting state; thus the job environment remains the same
	until restarted.
	(job_new): Remove code to initialise the environment, we now do that
	when actually starting the instance.
	* init/tests/test_job.c (test_handle_event): Add test cases for
	starting the job, making sure that the environment is correctly
	copied into the right field and also checking what happens if it's
	already stopping or running.
	(test_change_state): Make sure that start_env is correctly copied
	over into env, overwriting what is there if non-NULL or keeping it
	if NULL.
	(test_new): Remove checks for environment setup, since we don't do
	that anymore here; replace with checking for NULL and restore the
	alloc fail tests.
	* TODO: Update.

	* init/environ.c (environ_add): Allow it to accept NULL length, since
	we can't always keep that around.

	* init/process.c (process_spawn): Accept the environment list as
	a parameter, then finally we can change this function to take a
	JobConfig as the first argument.
	(process_error_read): Remove the associated error handler.
	* init/process.h: Change prototype.
	(ProcessErrorType): Remove error enum for environment.
	* init/tests/test_process.c (test_spawn): Update calls in test to
	just pass in an environment array (direct testing).
	* init/job.c (job_run_process): Pass configuration and environment
	to process_spawn.

	* init/process.c (process_spawn): Take the environment directly out
	the job structure, rather than recreating it.
	(process_environment): Drop function, absorbed elsewhere.
	* init/process.h: Remove prototype.
	* init/tests/test_process.c (test_spawn): Set the job_id variable
	before calling job_new and set config->start_on instead of
	job->start_on so that job_new can pick up both.
	(test_environment): Remove test cases.

	* init/job.h (Job): finally gains env pointer of its own.
	* init/job.c (job_new): Initialise the environment, moving the last
	of the code from process_environment -- this is only temporary
	though in the interests of refactoring, it'll move out of here again
	soon enough.
	* init/tests/test_job.c (test_new): Make sure that the environment is
	set in a manner which tests the overriding of things by other things;
	we have to temporarily comment out the alloc fail stuff though :-(

	* init/event.c (event_operator_collect): Make list the last argument
	for consistency with future functions.
	* init/event.h: Update prototype.
	* init/tests/test_event.c (test_operator_collect): Swap arguments.
	* init/process.c (process_environment): Update.

	* init/job.c (job_config_environment): Function to generate an
	environment table from a JobConfig, code largely moved from process.c
	* init/job.h: Add protoyype.
	(JOB_DEFAULT_ENVIRONMENT): List of environment variables to always
	copy from the environment (moved from process.h)
	* init/tests/test_job.c (test_config_environment): Add test case,
	again largely copied from test_process.c
	* init/process.c (process_environment): Call job_config_environment
	instead of the code moved out.
	* init/process.h (PROCESS_ENVIRONMENT): Move to job.h
	* TODO: Update.

	* TODO: Update.

2008-03-01  Scott James Remnant  <scott@netsplit.com>

	* init/event.c (event_operator_collect): Create a mega-function to
	iterate an EventOperator tree (filtering out those bits that aren't
	TRUE) and collect the events, adding them to a linked list, adding
	their environment to a table and making a string list for another
	environment variable.  Fundamentally this function marshals data
	out of the Event subsystem into the right format for the Job subsystem.
	* init/event.h: Add prototype.
	* init/tests/test_event.c (test_operator_collect): Tests for the
	collector function; some bits may seem similar to test_process.c
	* init/process.c (process_environment): Use event_operator_collect
	to gather the environment, instead of its own code (which pretty
	much got pasted into event_operator_collect anyway).  Force everything
	else to allocate matching the caller.
	* init/tests/test_process.c (test_spawn, test_environment): Had
	forgotten to set the value of the intermediate AND operator to TRUE,
	necessary now.

	* init/process.c (process_environment_add): Move and rename this
	function, since it's not really process associated
	(process_environment): Change to use environ_add or environ_setf
	instead.
	* init/process.h: Remove prototype.
	* init/environ.c (environ_add): New name/location of
	process_environment_add, modified to not take a copy of the string
	(environ_set): Wrapper for the above for common dealing with
	environment we want to set from a format string.
	(environ_get, environ_getn, environ_lookup): Functions to get an
	environment variable entry; largely cripped from event.c but
	bug-fixed at the same time.
	* init/environ.h: Function prototypes.
	* init/event.c (event_operator_match): Change to use environ_lookup
	* init/tests/test_process.c (test_environment_add): Move the tests.
	* init/tests/test_environ.c: Test suite for environment handling
	* init/Makefile.am (init_SOURCES): Build environ.c and environ.h
	(TESTS): Build environment test suite
	(test_environ_SOURCES, test_environ_LDFLAGS, test_environ_LDADD):
	Details for environment test suite
	(test_process_LDADD, test_job_LDADD, test_event_LDADD)
	(test_parse_job_LDADD, test_parse_conf_LDADD, test_conf_LDADD):
	Link environ.o to other test suites

	* init/job.c (job_new): Increment the number of instances.
	(job_instance): Simplify the function, it now only returns the
	existing instance or NULL.  This makes it easier to extend when
	we have env-limited instances later on.
	(job_handle_event): If job_instance returns NULL, create
	a new instance with job_new() and always reset the operator afterwards.
	* init/tests/test_job.c (test_new): Check that the instances variable
	is incremented when a new job is created.
	(test_instance): Change to check that it returns NULL when there is
	no active instance, or for multi-instance jobs, instead of creating
	a new one itself.
	(test_config_replace, test_find_by_pid)
	(test_find_by_id, test_change_goal, test_change_state)
	(test_next_state, test_run_process, test_kill_process)
	(test_child_handler, test_handle_event)
	(test_handle_event_finished): Call job_new to create a new instance
	from a config, instead of job_instance.

	* init/tests/test_conf.c (test_source_reload_job_dir)
	(test_file_destroy): Call job_new to create a new instance from a
	config, instead of job_instance.
	* init/tests/test_event.c (test_poll): Call job_new to create a new
	instance from a config, instead of job_instance.
	* init/tests/test_process.c (test_spawn, test_environment): Call
	job_new to create a new instance from a config, instead of job_instance

2008-02-29  Scott James Remnant  <scott@netsplit.com>

	* configure.ac: Compare the evaluated $sbindir against the common
	things we put in PATH, if it doesn't match, define EXTRA_PATH to
	contain it.
	* init/paths.h: Append EXTRA_PATH to PATH if defined.

	* init/Makefile.am (AM_CPPFLAGS): Replace TELINIT definition with
	SBINDIR, pointing at the common directory.
	* compat/sysv/Makefile.am (AM_CPPFLAGS): Replace SHUTDOWN definition
	with SBINDIR, pointing at the common directory.
	* init/paths.h (TELINIT): Redefine to be SBINDIR with "/telinit"
	on the end; define SBINDIR if necessary.
	* compat/sysv/reboot.c (SHUTDOWN): Redefine to be SBINDIR with
	"/shutdown" on the end; define SBINDIR if necessary.

2008-02-22  Scott James Remnant  <scott@netsplit.com>

	* init/event.c (event_operator_match): Rewrite to match both
	positionally and by name.
	* init/tests/test_event.c (test_operator_match): Update tests to
	check the new behaviour works.

	* init/parse_job.c (parse_on_operand): Add arguments to env list
	rather than args; sanity check afterwards to ensure that positional
	doesn't follow name-based -- when parsing the job is the right place
	to catch this.
	* init/tests/test_parse_job.c (test_stanza_start)
	(test_stanza_stop): Change args to env when checking operators.
	Check that arguments may be quoted in manners that we expect to be
	sane.  Check that positional arguments cannot follow name-based ones.
	* init/errors.h: Add new error.
	* init/conf.c (conf_reload_path): Treat expected variable as a
	permanent error.

	* init/tests/test_process.c (test_spawn, test_environment): 
	Update event_new() calls to remove extra argument.

	* init/main.c (main, cad_handler, kbd_handler, pwr_handler):
	Update event_new() calls to remove extra argument.

	* init/job.c (job_change_state): Update event_new () call.
	(job_emit_event): Update to put failure information in environment.
	* init/tests/test_job.c (test_new, test_instance)
	(test_child_handler, test_handle_event)
	(test_handle_event_finished): Remove extra argument to event_new,
	rename args to env in operator where necessary.
	(test_change_state): Update to check emitted event by full environment.

	* init/event.h (Event): Remove args member.
	(EventOperator): Rename args member to env.
	Update prototypes to match.
	* init/event.c (event_new): Remove args member.
	(event_finished): Remove copying of args member to failed event.
	(event_operator_new): Rename args member to env.
	(event_operator_copy): Rename args copying to env.
	(event_operator_match): ??
	* init/tests/test_event.c (test_new): Update test to remove args.
	(test_operator_new): Update test to rename args to env.
	(test_operator_copy): Update test to rename args to env.
	(test_operator_match): ???

	* TODO: Update with job atomicity notes.

2008-02-20  Scott James Remnant  <scott@netsplit.com>

	* init/job.c: Switch around job_find_by_pid and job_find_by_id
	* init/job.h: Likewise.

	* init/job.h: Update prototypes to match variable names in the
	code.

2008-02-17  Scott James Remnant  <scott@netsplit.com>

	* init/process.c (process_kill): Change to accept a JobConfig rather
	than a Job, since in theory this should only ever need that in a
	future where we can specify a kill signal (right now it's not used
	for anything!)
	* init/process.h: Update prototype.
	* init/tests/test_process.c (test_kill): Update test cases.
	* init/job.c (job_kill_process, job_kill_timer): Pass in JobConfig
	instead of Job.

	* init/process.c (process_spawn): Accept trace as an argument instead
	of using a random piece of job state to determine whether to trace
	or not.
	* init/process.h: Update prototype.
	* init/tests/test_process.c (test_spawn): Update tests to pass in
	via argument whether to trace the job or not.
	* init/job.c (job_run_process): Pass in the trace variable rather
	than relying on it working it out for itself; this means we don't
	need to set the state until after, therefore don't need to reset it.

	* AUTHORS, logd/jobs.d/logd.in: Update e-mail addresses.

	* README: Update kernel recommendation to 2.6.24, since that's
	the oldest version that the test suite will complete under.

2008-01-17  Scott James Remnant  <scott@netsplit.com>

	* TODO: Update.

	* init/job.c (job_run_process): Don't append the list of event
	names, they can be found in $UPSTART_EVENTS now.  This is better
	since it's consistent for exec and script.
	* init/tests/test_job.c (test_run_process): Drop test case.

	* init/process.c (process_environment): Function to build an
	environment table for a job containing built-in variables, those
	from the configuration, events and finally the upstart job ones.
	(process_environment_add): Helper function for the above that
	handles adding a variable to the array; dealing with fetching the
	value from init's environment if necessary.
	(process_setup_environment): This function now gets dropped in
	favour of the new ones.
	(process_spawn): Call the new process_environment() function and set
	the environ variable directly.
	* init/process.h (PROCESS_ENVIRONMENT): Define built-in environment
	variables that are always copied from our own environment.
	Add prototypes.
	* init/tests/test_process.c (test_environment): Check that the
	environment is built correctly and that each bit overrides the
	right other bit.
	(test_environment_add): Check that the array is built correctly.
	(test_spawn): Adjust order and values of expected environment
	to match what's now set.

2008-01-16  Scott James Remnant  <scott@netsplit.com>

	* init/job.c (job_failed): Separate the logic that marks the job
	and its associated events as failed into its own function, since
	it's a large enough amount of code that we were otherwise duplicating
	everywhere else (and in a few places, failing to mark the events as
	failed as well).
	(job_change_state, job_process_terminated): Call job_failed instead
	of doing it ourselves.
	(job_emit_event): De-nest the logic and fix so that we don't add
	environment to the failed respawn event.
	* init/tests/test_job.c (test_change_state): Add checks on whether
	the event was marked as failed or not.

	* TODO: Update.

	* configure.ac (AC_COPYRIGHT): Update copyright to 2008.

	* TODO: Update.

	* init/tests/test_job.c (test_child_handler): Don't run the signal
	and ptrace tests while in valgrind, sometimes signals (specifically
	SIGCONT after SIGSTOP) don't behave right and we kinda need that
	reliability.

	* init/tests/test_job.c (test_child_handler): After adding extra
	processes, make sure we clean up again so each test is roughly
	independant.  Fix the final test case to not rely on previous
	setup and work on its own.

	* init/tests/test_job.c (test_change_state): Remove useless check
	of job->start_on from a killed/post-stop check (noticed while
	writing the other).

	* init/job.c (job_change_state): Check the return value of
	job_run_process() and if particular processes fail, change the
	goal to stop and push the job into the next state; setting the job
	as failed along the way.
	(job_emit_event): If the exit_status is -1 then it means the job
	failed to spawn, so don't place EXIT_SIGNAL or EXIT_STATUS in the
	event environment.
	* init/tests/test_job.c (test_change_state): Check what happens when
	each process type fails, make sure that the job is stopped for
	pre-start, spawned and post-stop and the failure is ignored for
	post-start and pre-stop.

2008-01-15  Scott James Remnant  <scott@netsplit.com>

	* init/main.c: Selectively compile out certain pieces when make is
	run with CPPFLAGS=-DDEBUG, giving us a build that'll happily run from
	a user terminal.
	* init/event.h: Change the startup event to "debug" when built like
	that, so we don't accidentally do bad things.

	* init/job.c (job_run_process): Catch PROCESS_ERROR and abort the
	attempt to run the process, returning a non-temporary error condition.
	* init/tests/test_job.c (test_run_process): Add test case for
	attempting to spawn a file that doesn't exist.

	* init/process.c (process_error_read): Avoid the word process, since
	it's likely included in the higher error message.

	* init/process.c (process_spawn): Call process_error_abort() on any
	error condition.
	* init/tests/test_process.c (test_spawn): Add a test case for failing
	to spawn a process and receiving ProcessError correctly; fix other
	cases to ensure they return a pid.

	* init/errors.h: Add PROCESS_ERROR to the enum, but not to the string
	list since there's no specific defined string for this one.
	* init/process.h (ProcessError): Structure that builds on NihError
	to add additional information for a process error.
	(ProcessErrorType): enum of different process error types.
	* init/process.c (process_spawn): After forking read the error in
	the parent, returning if we raise one.
	Ensure we close the pipe if the fork fails.
	Re-order so that we set the environment, umask and priority after the
	resource limits (which should apply to them).
	(process_error_abort): New function to immediately abort with an
	error, writing it on the pipe first.
	(process_error_read): Counterpart function to read the error from
	the pipe and raise it, with appropriate error messages.

	* init/process.c (process_spawn): Create a pipe to use for
	communication with the child, ensuring its closed before the parent
	returns and ensuring that the writing end is close-on-exec in the
	child.

	* init/job.c (job_run_process): Change to return a value indicating
	whether there's been a non-temporary error (always returns zero so
	far).
	* init/job.h: Update prototype.
	* init/tests/test_job.c (test_run_process): Check that job_run_process
	always returns zero.

	* init/job.c (job_change_goal): Document in which states this function
	has unexpected side-effects such as freeing the job, since we do
	attempt to call it from within job_change_state().

	* init/process.c (process_setup_limits): Integrate this function back
	into process_spawn() since there's no reason for it to be separate.
	(process_setup_console): Alter this function so it closes the original
	console descriptors, opens the new ones and can reset them to if
	required -- in particular, this no longer takes a Job parameter.
	(process_spawn): Use the new process_setup_console function and
	integrate code from process_setup_limits().
	* init/process.h: Update function prototype.
	* init/main.c (main): Use the new process_setup_console() argument
	form.  Move syslog opening to the end of the function, rather than
	where it is now where it could be at risk of being closed again
	immediately.  Change the root directory in case we're run in some
	weird way.
	(reset_console): Remove function since the code is now in
	process_setup_console()
	* init/enum.h (console_type): Remove CONSOLE_LOGGED and make the
	CONSOLE_NONE constant be zero.
	* init/parse_job.c (stanza_console): Drop parsing of "logged"
	* init/tests/test_parse_job.c (test_stanza_console): Drop testing
	of "logged" parsing.

2008-01-14  Scott James Remnant  <scott@netsplit.com>

	* HACKING: Correct bzr URLs to trunk.

2007-12-15  Scott James Remnant  <scott@netsplit.com>

	* init/process.c (process_spawn): Fix some documentation strings.
	
	* init/process.c (process_kill): Move to beneath the process setup
	functions.
	* init/process.h: Adjust ordering here too.

	* init/process.c (process_spawn): Group console closing and setup
	together, becoming the session and process group leader first.

2007-12-07  Scott James Remnant  <scott@netsplit.com>

	* init/process.c (process_spawn): Drop the debug message since
	it's always repeated by the caller.
	* init/job.c (job_run_process): Drop the word Active which is a
	hold-over from when we had different process states.

	* TODO: Update.

	* init/job.c (job_child_handler): Add code to handle the trapped
	signal and ptrace event cases, distinguishing between a trapped
	signal and process stopped after exec or fork using our trace
	state member.  Call out to other functions to do the work.
	(job_process_trace_new): Called after the first exec to set the
	ptrace options, update the trace state and allow the process to
	continue without delivering the signal.  Also called after the
	fork to do the same.
	(job_process_trace_new_child): Called after a fork for the new child;
	increments the fork counter and if it goes over the number we want,
	detaches from the process and allows it to move to running.  Otherwise
	calls job_process_trace_new() instead.
	(job_process_trace_signal): Called when a signal is trapped, simply
	delivers it to the process unchanged.
	(job_process_trace_fork): Called before a fork for the parent, obtains
	the new child process id from the event, updating the job structure,
	and detaches from the parent which we're no longer interested in.
	(job_process_trace_exec): Called after an exec other than the first,
	assumed to be the end of forking so detaches from the process and
	allows it to move to running.
	* init/tests/test_job.c (test_child_handler): Add test cases for
	the various ptrace states.

	* init/job.c (job_run_process): Set process trace state to new for
	the main job if we need to wait for the daemon or fork; otherwise
	reset the state.
	* init/tests/test_job.c (test_run_process): Add test cases to make
	sure the trace state is set right and picked up by process_spawn.

	* init/process.c (process_spawn): Set a ptrace before execing the
	binary if the trace state is TRACE_NEW, set by the caller.
	* init/tests/test_process.c (test_spawn): Make sure that a job is
	ptraced if set up properly.
	(child): Add a simple case that just exits immediately for testing
	the above.

	* init/job.h (Job): Add new trace_forks member to keep count of how
	many forks we've seen and trace_state member to track whether we've
	just started the trace or just forked.
	* init/enum.h (TraceState): Add enumeration to keep track of ptrace
	state to differentiate between a signal and an event.
	* init/job.c (job_new): Initialise new members.
	* init/tests/test_job.c (test_new): Check new members are initialised

	* init/enum.h (JobWaitType): Add new daemon and fork wait types.
	* init/parse_job.c (stanza_wait): Add parsing for daemon and fork.
	* init/tests/test_parse_job.c (test_stanza_wait): Add tests too.

	* init/job.h (JobConfig): Remove daemon and pid members.
	(Job): Remove pid_timer member.
	(JOB_DEFAULT_PID_TIMEOUT): Remove this constant.
	* init/job.c (job_config_new, job_new): Remove initialisation of
	removed members.
	(job_change_state): Stay in spawned unless we're not waiting for
	anything -- remove the daemon flag.
	* init/tests/test_job.c (test_config_new, test_new): Remove checks
	for initialisation of removed members.
	(test_change_state): Remove daemon flag stays in spawned check since
	the daemon flag has gone.
	* init/parse_job.c (stanza_daemon, stanza_pid): Remove these
	functions since they have no members to set.
	* init/tests/test_parse_job.c (test_stanza_daemon, test_stanza_pid):
	Remove the tests for the now non-existant functions.

	* init/process.c (process_spawn): raise the system error before
	calling another syscall, in case we overwrite errno.

2007-12-06  Scott James Remnant  <scott@netsplit.com>

	* init/job.c (job_child_handler): Implement a combined child event
	handler to replace the multiple separate ones.  This handler deals
	with adding appropriate messages to the log and decoding any state
	information before calling specific action functions.
	(job_child_reaper): Remove, moving the bulk of the code into new
	(job_process_terminated): function that handles it cleanly.
	(job_child_minder): Remove, moving the bulk of the code into new
	(job_process_stopped): function that's a lot cleaner.
	* init/job.h: Update prototypes.
	* init/tests/test_job.c (test_child_reaper, test_child_minder):
	Combine unit tests from both functions into single new
	(test_child_handler): function.
	* init/main.c (main): Call the combined function on child events
	instead of separate ones.

	* init/job.c (job_child_minder): Add informational message and
	improve style and documentation.

2007-12-02  Scott James Remnant  <scott@netsplit.com>

	* init/enum.h (JobWaitType): Introduce a new enum that specifies
	how to transition the job from spawned to running; either we don't
	wait, or we wait for it to emit the stopped signal.
	* init/job.h (JobConfig): Add the wait_for member.
	Add protoype for job_child_minder.
	* init/job.c (job_config_new): Initialise to JOB_WAIT_NONE.
	(job_child_minder): New function to catch when a process is stopped
	by a signal, and move it to the next state when it does so.
	* init/tests/test_job.c (test_config_new): Check the initialisation
	of wait_for to JOB_WAIT_NONE.
	(test_child_minder): Tests for the new function.
	(test_change_state): Copy the daemon test case to refer to waiter.
	* init/main.c (main): Call job_child_minder whenever the job is
	stopped by a signal
	* init/parse_job.c (stanza_wait): Parse a new "wait" stanza that
	specifies what to wait for before leaving the spawned state.
	* init/tests/test_parse_job.c (test_stanza_wait): Check the new
	stanza.

2007-11-29  Scott James Remnant  <scott@netsplit.com>

	* init/tests/test_job.c (test_change_state): Add a few sets to NULL
	so gcc is happy.

2007-11-15  Scott James Remnant  <scott@netsplit.com>

	* init/job.c (job_child_reaper): Update argument names and types
	to match new NihChildHandler pattern; switch on event instead,
	which can now have three values not two (it always could, this was
	a bug) to output warning and assume that status is always non-zero
	if killed so no need to check that separately.
	* init/job.h: Update prototype.
	* init/tests/test_job.c (test_child_reaper): Update calls to
	job_child_reaper to pass an NihChildEvents member instead of FALSE
	or TRUE for killed.
	* init/main.c: Adjust call to nih_child_add_watch to indicate which
	events we want to pass to the reaper; we don't use NIH_CHILD_ALL
	since we're going to add ptrace stuff to a different function.

2007-11-07  Scott James Remnant  <scott@netsplit.com>

	* init/main.c (main): Tidy up.

2007-11-04  Scott James Remnant  <scott@netsplit.com>

	Complete the simplification of job config; rather than try and
	precompute job replacements, keeping them all in the same hash table
	and chaining them together, we just work it out when it's actually
	necessary based on what's in the conf_sources list.

	* init/job.h (JobConfig): Remove the replacement and replacement_for
	members and put a deleted member in instead.
	* init/job.c (job_config_new): Initialise deleted to FALSE; don't
	replace the job into the hash table, since we only want the current
	one in there now.
	(job_config_find_by_name): Now that there is only ever one job
	config in the hash table, we don't need any special function and
	can just use nih_hash_lookup directly, so drop this function.
	(job_config_should_replace): Rename to job_config_replace
	(job_config_replace): Rework, it now checks to see whether there
	are instances, and if not removes the job from the hash table
	before selecting a new one (which might be the same job).
	* init/tests/test_job.c (test_config_new): Update test to check
	deleted starts off as FALSE and that the job isn't in the hash.
	(test_config_find_by_name): Drop.
	(test_config_should_replace): Rename and rewrite to test replacement
	actually works as we expect.
	(test_change_state): Update tests for entering the waiting mode and
	replacing jobs.
	(test_find_by_pid, test_find_by_id, test_handle_event)
	(test_handle_event_finished): Add jobs to the hash table, otherwise
	we can't find them
	(test_child_reaper): Add job to the hash table, and also create a
	source for it since we end up with it in the waiting state so need
	to be able to keep it.
	* init/Makefile.am (test_process_LDADD, test_job_LDADD)
	(test_event_LDADD): Need the full .o file list now.
	* init/conf.c (conf_file_destroy): Rewrite to mark the job deleted,
	call job_config_replace if it's the current job and free it if
	it isn't the current job either before or after that call.
	(conf_reload_path): Handle job replacement here; look up the
	old job in the hash table, if it exists attempt a replacement
	otherwise add the new job to the hash table.
	* init/tests/test_conf.c (test_source_reload_job_dir)
	(test_source_reload_conf_dir, test_source_reload_file): Update
	tests to check job->deleted and use nih_hash_lookup to see whether
	it's the current job.
	(test_file_destroy): Write tests to check the common cases, we don't
	need to worry about the intermediate now since they can't happen.
	* init/parse_job.c (parse_job): Massively simplify, this only creates
	the config and parses it now.
	* init/tests/test_parse_job.c (test_parse_job): Remove the replacement
	checks.
	* init/tests/test_event.c (test_poll): Add configs to the hash
	table so they can be found.
	* TODO: Update.

2007-11-03  Scott James Remnant  <scott@netsplit.com>

	* init/conf.h (ConfSource): Remove priority, we'll place these
	in a linked list and use that order instead.
	(ConfSourcePriority): Drop accordingly.
	(ConfItem): Drop this structure; permitting jobs and states to be
	defined inside larger conf files made things complicated for no
	benefit; move the item union into
	(ConfFile): here, instead of the items list.
	(ConfItemType): Drop accordingly.
	* init/conf.c (conf_init): Store sources in a linked list, instead
	of a hash table; no idea why it ever was.
	(conf_source_new): Drop priority argument and add to list not hash.
	(conf_file_new): Set data to NULL instead of initialising items,
	set destructor to conf_file_destroy.
	(conf_item_destroy): Rename to conf_file_destroy
	(conf_file_destroy): and adjust to refer to ConfItem instead,
	getting the item type through the source.
	(conf_item_new): Drop.
	(conf_reload): Iterate as linked list not hash table.
	(conf_reload_path): Simplify handling of old files and items a
	little, just look it up and always free if it exists before parsing
	the new file.
	(conf_file_get): No longer any need for this function.
	* init/tests/test_conf.c (test_file_get, test_item_new): Drop
	test functions for those that have been removed.
	(test_item_destroy): Rename to test_file_destroy.
	(test_source_new): Don't pass or check priority, or hash lookup.
	(test_file_new): Check data is set correctly.
	(test_source_reload_job_dir, test_source_reload_conf_dir)
	(test_source_reload_file): Update tests accordingly.
	* init/parse_conf.c (stanza_job): Drop the job stanza, jobs
	may only be defined in dedicated directories.  
	* init/tests/test_parse_conf.c (test_parse_conf): Simply check to only
	make sure the file is parsed.
	(test_stanza_job): Drop function.
	* init/main.c: Update calls to conf_source_new.
	* init/init.supp: Update intermediate function in suppression.

2007-10-26  Scott James Remnant  <scott@netsplit.com>

	* init/process.c (process_spawn): Mask out all signals across the
	fork() rather than just SIGCHLD; reset the signal handlers to default
	before unmasking again.  The original rationale was we needed to
	avoid SIGCHLD occurring before we'd stashed the pid, but that's no
	longer a problem; the new rationale is that we want to avoid the
	signal handlers running in the newly forked child.

2007-10-20  Scott James Remnant  <scott@netsplit.com>

	* init/job.c (job_init): The job's name is the first item in the
	structure again, so we can use nih_hash_string_key.
	(job_config_name): Drop this function, then.

	* init/conf.h (ConfSourcePriority): Add a priority enum
	(ConfSource): Add priority member.
	* init/conf.c (conf_source_new): Take priority as an argument and
	set it in the structure.
	* init/tests/test_conf.c (test_source_new): Make sure priority
	is set from the argument.
	(test_file_new, test_file_get, test_item_new)
	(test_source_reload_job_dir, test_source_reload_conf_dir)
	(test_source_reload_file, test_source_reload, test_item_destroy):
	Pass in a priority when creating a ConfSource.
	* init/tests/test_parse_conf.c (test_parse_conf): Likewise.
	* init/main.c (main): Set relative priorities for the configuration
	directories.

	* init/conf.h (conf_file, conf_item): Add source and file members
	respectively that point to the parent structure.
	* init/conf.c (conf_file_new, conf_item_new): Set the members.
	* init/tests/test_conf.c (test_file_new, test_file_get)
	(test_item_new): Make sure the new members are set properly.

	* util/Makefile.am (install-data-hook, install-exec-hook): Apply
	transform to source and destination of both manpage and program
	symlinks.
	* compat/sysv/Makefile.am (install-data-hook, install-exec-hook): 
	Likewise for the compatibility symlinks.

	* TODO: Update.

	* init/tests/test_process.c (test_spawn): Make the event a child
	of the operator so it doesn't get freed first.

	* init/job.c (job_instance): Increment an instances counter each
	time we spawn an instance.
	(job_change_state): Decrement the instances counter again.
	(job_detect_stalled): Drop the main loop function, since we perform
	active detection of stall now.
	* init/job.h: Update header.
	* init/tests/test_job.c (test_change_state): Check that we get the
	stalled event for the last instance.
	(test_detect_stalled): Drop the test.
	* init/main.c: Remove job_detect_stalled from the main loop.

	* init/event.c (event_operator_destroy): Destructor for an
	EventOperator that unblocks and unreferences the event first.
	(event_operator_new): Set the operator.
	(event_operator_copy): Remove error handling since it's unnecessary
	with the destructor in place.
	* init/event.h: Add prototype.
	* init/tests/test_event.c (test_operator_destroy): Make sure it
	works properly.
	(test_operator_copy): Don't unblock or unref events before freeing
	them, since that's now taken care of when it's referenced.
	* init/job.c (job_new): Remove unnecessary error handling.
	* init/tests/test_job.c (test_run_process): Reference the event
	when setting it, otherwise we'll assert when we try to free it.
	* TODO: Update.

	* init/job.c (job_new): Drop the parent argument for consistency.
	(job_instance): Update call to job_new.
	* init/job.h: Update prototype.
	* init/tests/test_job.c (test_new): Adjust call, check the parent
	and make sure that start_on and stop_on are copied over properly.
	* TODO: Update.

	* init/conf.c (conf_file_get): Split out the allocation code from here
	(conf_file_new): into this new function.
	* init/conf.h: Add prototype.
	* init/tests/test_conf.c (test_file_new): New tests.
	* TODO: Update.

	* init/job.c (job_change_state): Hardcode the next state when we
	catch a runaway job to be JOB_WAITING.
	(job_next_state): Change next state for JOB_STARTING when goal is
	JOB_STOP to be JOB_STOPPING for consistency with the others; otherwise
	if our goal is stopped during our starting event, we'll never emit
	a stopping event to match it.
	* init/tests/test_job.c (test_next_state): Update test case.
	* doc/states.dot: Adjust the state transitions.
	* doc/states.png: Regenerate.
	* TODO: Update.

2007-10-19  Scott James Remnant  <scott@netsplit.com>

	Dealing with instances has always been tricky since they're copies
	that exist in the hash table; this patch changes that so the job's
	configuration is separated from its state.  The only difference
	between instance and non-instance jobs now is that non-instance
	jobs only ever have one entry in their instances list.

	* init/job.h (Job): Separate out the members that come from the
	configuration into a new JobConfig structure which can be shared
	amongst all of the instances; this means we can drop instance_of.
	(JobConfig): Add instances list.
	(JobProcess): Remove pid member, replaced by pid list in Job.
	Update prototypes of functions to match.
	* init/job.c (job_new): Split off initialisation of configuration
	pieces into new job_config_new function leaving the state here;
	copy the start_on and stop_on members from JobConfig
	(job_copy): Drop this function, we don't need to copy jobs now.
	(job_name): Rename to job_config_name.
	(job_init): Set key function to job_config_name.
	(job_process_new): Drop initialisation of pid.
	(job_process_copy): Drop this function entirely, we don't need it.
	(job_find_by_name): Rename to job_config_find_by_name; massively
	simplify now we won't find instances or deleted jobs in the list.
	(job_should_replace): Rename to job_config_should_replace; simplify
	now that we can do a simple check to see whether a job exists or not
	(job_find_by_pid, job_find_by_id): Loop through the instances after
	looping through the hash table.
	(job_instance): Simplify, now all it needs to do is call job_new()
	if there isn't anything in the instances list, or it's multi-instance.
	(job_change_goal): Document that job should not be used on return.
	No need to check for instance jobs anymore.  Place the job id in
	the output.
	(job_change_state): Document that job should not be used on return.
	Place the job id in the output.  Check for information in the job's
	config.  Merge the waiting and deleted states, so that a job instance
	is automatically deleted when it finishes.
	(job_next_state): Assert that we never call job_next_state when
	in JOB_WAITING since there's no possible next state.  Check config
	for whether a main process exists.
	(job_emit_event): Obtain config-replaced pieces from the job's config
	(job_run_process): Obtain process information from the job's config
	but store the pid in the Job.  Put job id in the output.
	(job_kill_process, job_kill_timer): We don't need to obtain the
	JobProcess just the pid from the job.  Put job id in the output.
	(job_child_reaper): Put job id in the output.  Check job config.
	(job_handle_event): Iterate job instances and process their stop_on
	operators, but process the start_on from the job configs.
	(job_handle_event_finished): Loop through the instances too.
	(job_detect_stalled): Check start_on from the config and just
	check whether there are any instances in the list.
	(job_free_deleted): No deleted state, so drop this function.
	* init/tests/test_job.c (test_new): Split into test_new and
	new test_config_new function.  Create JobConfig object and spawn
	Job instances from that.
	(test_copy): Drop the tests.
	(test_process_new): Drop check of pid.
	(test_process_copy): Drop test.
	(test_find_by_name): Rename to test_config_find_by_name.
	(test_should_replace): Rename to test_config_should_replace.
	(test_instance): Create JobConfig object, and adjust tests to ensure
	that we always get a Job object.
	(test_find_by_pid, test_find_by_id, test_change_goal): Create
	JobConfig object and spawn Job instances from that.
	(test_change_state): Create JobConfig object and spawn Job
	instances from that.  Adjust tests that previously checked for
	JOB_WAITING to check for job being freed.  Drop checks for JOB_DELETED.
	(test_next_state): Create JobConfig object and spawn Job instances
	from that.  Drop JOB_DELETED and JOB_WAITING checks.
	(test_run_process, test_kill_process, test_child_reaper)
	(test_handle_event, test_detect_stalled): Create JobConfig object
	and spawn Job instances from that.
	(test_free_deleted): Drop.
	* init/main.c: Don't add job_free_deleted to the main loop.
	* init/enum.h (JobState): Drop JOB_DELETED.
	* init/enum.c (job_state_name, job_state_from_name): Drop JOB_DELETED.
	* init/tests/test_enum.c (test_state_name, test_state_from_name):
	Drop tests that use the JOB_DELETED value.
	* init/process.c (process_spawn, process_setup_limits)
	(process_setup_environment, process_setup_console): Get details
	from the job config.  Put job id in the output.
	* init/tests/test_process.c (test_spawn, test_kill): Create
	a JobConfig object and make Job instances from that.
	* init/tests/test_event.c (test_poll): Create a JobConfig object
	and make Job instances from that.
	(test_operator_copy): Set pointers to NULL to avoid gcc complaining.
	* init/conf.h (ConfItem): Make the type for a job be JobConfig.
	* init/conf.c (conf_item_destroy): Don't attempt to replace the
	new middle-man target, if it was due to be replaced it would have
	already been.  If we can replace the config, ensure nothing points
	at it and then free it, rather than kicking state.
	* init/tests/test_conf.c (test_source_reload_job_dir)
	(test_source_reload_conf_dir, test_source_reload_file)
	(test_source_reload, test_item_destroy): Call job_config_new to
	create JobConfig objects, track when they are freed rather than
	marked in the deleted state.  Create instances with job_instance,
	and fetch from the instances list.  Expect the job to be freed
	with the item.
	* init/tests/test_parse_conf.c (test_parse_conf)
	(test_stanza_job): Change expected type from Job to JobConfig.
	* init/parse_job.c: Update prototypes of all functions to refer to
	JobConfig instead of Job.
	(parse_job): If the old job already has a replacement, remove the
	replacement from the hash table -- but don't free it because it's
	linked by a ConfItem -- this is temporary.  Likewise for when we
	replace the old job.
	* init/parse_job.h: Update prototype.
	* init/tests/test_parse_job.c: Update all functions to use JobConfig
	instead of Job.
	(test_parse_job): Create an instance.
	* doc/states.dot: Remove the deleted state.
	* doc/states.png: Regenerate.
	* TODO: Update with notes from the conversion.

2007-10-16  Scott James Remnant  <scott@netsplit.com>

	Update to catch up with changes in libnih that make code a little
	bit easier to follow (we hope).

	* init/tests/test_process.c (test_spawn, test_kill): Replace calls
	to nih_list_free() with nih_free()
	* init/event.c (event_poll): Replace nih_list_free with nih_free
	since the former function has gone from libnih.
	(event_new): Adjust setting of the destructor.
	(event_operator_new): Set destructor for the tree node.
	* init/tests/test_event.c (test_new, test_find_by_id, test_ref)
	(test_unref, test_block, test_unblock, test_poll)
	(test_operator_match): Replace nih_list_free with nih_free.
	(test_poll): Use TEST_FREE_TAG and TEST_FREE rather than abusing
	destructors.
	* init/job.c (job_new): Set destructor to nih_list_destroy.
	(job_copy, job_free_deleted): Use nih_free instead of nih_list_free
	* init/tests/test_job.c (test_new, test_copy, test_find_by_name)
	(test_find_by_pid, test_find_by_id, test_instance)
	(test_change_goal, test_change_state, test_next_state)
	(test_should_replace, test_run_process, test_kill_process)
	(test_child_reaper, test_handle_event)
	(test_handle_event_finished, test_detect_stalled)
	(test_free_deleted): Replace all uses of nih_list_free with nih_free
	(test_child_reaper, test_free_deleted): Replace destructor abuse
	with TEST_FREE, etc.
	* init/conf.c (conf_reload_path): Use nih_free instead of nih_list_free
	(conf_source_new, conf_file_get, conf_item_new): Set destructor
	(conf_source_reload, conf_delete_handler): Use nih_free not the
	custom conf_file_free() function.
	(conf_reload_path): Use nih_free not the custom conf_item_free()
	function.
	(conf_delete_handler): Use nih_free not nih_watch_free()
	(conf_source_free, conf_file_free): Drop these functions, since
	all the free chaining happens properly with destructors.
	(conf_item_free): Rename to conf_item_destroy and turn into destructor
	* init/conf.h: Update prototypes.
	* init/tests/test_conf.c (test_source_new, test_file_get)
	(test_item_new, test_source_reload_job_dir)
	(test_source_reload_conf_dir, test_source_reload_file)
	(test_item_free): Replace nih_list_free calls with nih_free
	(test_source_reload_job_dir, test_source_reload_conf_dir)
	(test_source_reload_file, test_source_reload, test_item_free): Replace
	calls to conf_source_free with nih_free
	(test_source_free, test_file_free): Drop functions.
	(test_item_free): Rename to test_item_destroy
	(test_item_new): Assign a job before freeing, otherwise the destroy
	function will foul up as it expects one.
	* init/parse_conf.c (stanza_job): Replace nih_list_free with nih_free
	* init/tests/test_parse_conf.c (test_parse_conf)
	(test_stanza_job): Replace conf_source_free() with nih_free()
	(test_parse_conf, test_stanza_job): Replace conf_item_free()
	with nih_free()
	* init/parse_job.c (parse_job, parse_on_paren, parse_on_collect):
	Replace nih_list_free with nih_free
	(parse_on): always cut out the stack head before returning (it won't
	be empty on error) otherwise we end up with a bunch of list entries
	pointing to it -- and it's way out of scope when we try and free them
	(parse_on_operator, parse_on_operand): Use the job as the context
	not the operator for consistency of freeing.
	* init/tests/test_parse_job.c: Replace all instances of nih_list_free
	with nih_free (too many functions to list).

2007-10-15  Scott James Remnant  <scott@netsplit.com>

	Strip out all of the IPC code, removing it and consigning it to the
	great revision control history in the sky.  We're going to switch
	from home-brew to D-BUS. so all this is somewhat obsolete.  Rather
	than maintain this while we carry on developing, we'll strip it out
	now and put the D-BUS code in ater once the rest of the core changes
	are done (otherwise we'd just be dragging those through maintenance
	too).

	* Makefile.am (SUBDIRS): Remove the upstart sub-directory entirely;
	comment out util, compat/sysv & logd since we'll fix them up later
	* configure.ac (AC_CONFIG_FILES): Remove from here too.
	* upstart/enum.c, upstart/enum.h, upstart/tests/test_enum.c: Move
	these files into the init/ sub-directory; strictly speaking we'll
	probably need to share them again later in some way, but for now
	they can live with the rest of the daemon code.
	* upstart/: Delete.
	* init/Makefile.am (init_SOURCES): Remove control.c, control.h,
	notify.c and notify.h;  add enum.c and enum.h
	(TESTS): Remove test_control and test_notify; add test_enum
	(test_control_SOURCES, test_control_LDFLAGS, test_control_LDADD)
	(test_notify_SOURCES, test_notify_LDADD): Remove.
	(test_enum_SOURCES, test_enum_LDFLAGS, test_enum_LDADD): Add details
	(init_LDADD): Remove libupstart
	(test_process_LDADD, test_job_LDADD, test_event_LDADD)
	(test_parse_job_LDADD, test_parse_conf_LDADD, test_conf_LDADD): Remove
	libupstart, control.o and notify.o; add enum.o
	* init/control.c, init/control.h, init/tests/test_control.c: Delete
	* init/notify.c, init/notify.h, init/tests/test_notify.c: Delete
	* init/enum.c, init/job.c, init/job.h: Update include path for enum.h
	* init/parse_job.c: Remove unnecessary enum.h include
	* init/tests/test_enum.c: Update to reflect where it is.
	* init/main.c (main): Drop control socket opening.
	* init/tests/test_job.c: Remove unnecessary control.h include
	* init/event.c (event_pending, event_finished): Remove calls to
	notify_event and notify_event_finished
	* init/job.c (job_change_goal, job_change_state): Remove calls
	to notify_job.
	* init/tests/test_parse_conf.c: Remove calls to notify_init
	* init/tests/test_parse_job.c: Remove calls to notify_init
	* init/tests/test_event.c (test_poll): Strip out the part of the
	test that checks processes are notified.
	(check_event, check_event_finished): Remove.

	* configure.ac: Bump Autoconf dependency to 2.61 to match libnih
	* HACKING: Bump dependency in docs too.

	* NEWS: Copy in news from 0.3.9; that release doesn't appear in
	this ChangeLog since it was made on a separate branch by backporting
	bug fixes made here.
	* configure.ac: Bump version to 0.5.0, which is where development
	is heading for.

2007-10-12  Scott James Remnant  <scott@netsplit.com>

	* HACKING: Change URL for libnih.

2007-10-08  Scott James Remnant  <scott@netsplit.com>

	* configure.ac (AM_GNU_GETTEXT_VERSION): Bump to 0.16.1 since this
	version of gettext is needed for compatibility with Automake 1.10
	* HACKING: Bump version in the docs too.

	* compat/sysv/Makefile.am: Only create symlinks if COMPAT_SYSV is
	enabled, otherwise we leave dangling ones.

	* Makefile.am (ACLOCAL_AMFLAGS): Specify that aclocal install
	ordinarily system-wide macros into m4 (libtool.m4, specifically).
	This makes it easier for packagers to modify autoconfery since
	aclocal is no longer a destructive event.
	* configure.ac (AM_INIT_AUTOMAKE): Increase Automake requirement to
	1.10 to ensure we have aclocal --instal
	* HACKING: Increase Automake version in the docs.

2007-09-21  Scott James Remnant  <scott@netsplit.com>

	* init/job.c (job_detect_stalled, job_free_deleted): Call job_init()
	on entry, since we don't have a Job pointer passed to us, we need
	to make sure we don't dereference a potentially NULL list.

2007-06-22  Scott James Remnant  <scott@netsplit.com>

	* TODO: Update.

	* init/job.h: Update prototype of job_change_goal.
	(Job): Remove cause member.
	* init/job.c (job_change_goal): Drop additional argument since cause
	is no longer used.
	(job_change_state, job_child_reaper, job_handle_event): Only pass
	two arguments to job_change_goal.
	* init/control.c (control_job_start, control_job_stop): Only pass
	two argumenst to job_change_goal.
	* init/tests/test_job.c (test_change_goal, test_change_state): Only
	pass two arguments to job_change_goal.

	* init/job.c (job_new): Drop setting of cause.
	(job_change_cause): Drop this function entirely.
	(job_change_goal, job_change_state): Drop calls to job_change_cause
	(job_change_state, job_child_reaper): Don't pass job->cause to
	job_change_goal calls.

	* init/tests/test_job.c: Remove all tests that checked the value of
	job->cause, since that variable is going away.
	(test_change_goal): Remove the specific tests that checked whether
	cause was updated or not.

	* init/job.c (job_run_process): Replace the arguments from the event
	with a list of event names.
	* init/tests/test_job.c (test_run_process): Update test case to
	supply arguments from the list of events.

	* init/process.c (process_setup_environment): Drop the UPSTART_EVENT
	environment variable; it doesn't make sense when you can have multiple
	events.
	(process_setup_environment): Put all variables from the job's start
	events into the job's environment; replacing the UPSTART_EVENT variable

	* init/job.c (job_change_cause): Don't notify the job event
	subscribers when changing the cause.
	* init/notify.c (notify_job_finished): Instead notify them when
	the job reaches a rest state.

	* init/notify.c (notify_job): Call notify_job_event regardless,
	since this now looks over the start_on and stop_on fields.
	(notify_job_event): Rewrite to iterate over start_on and stop_on,
	and notifying for each cause event found.
	(notify_job_event_caused): Static function that is the guts of the
	above function.
	* init/tests/test_notify.c (test_job, test_job_event): Modify tests
	to refer exclusively to the start_on/stop_on expressions rather than
	the cause.

	* init/job.c (job_change_cause): Only notify the job event and
	update the cause member, we don't need to ref or block it anymore
	since that's handled by start_on and stop_on.
	* init/tests/test_job.c (test_change_goal): Drop checks on cause
	being referenced and blocked.
	(test_change_state, test_child_reaper, test_handle_event): Update
	test cases to not reference ->cause, and not count any references
	or blockers towards it.
	* init/tests/test_event.c (test_poll): Update expected reference
	and block counts for events handled by jobs.
	
	* init/tests/test_process.c (test_kill): Make sure that all processes
	in the process group are killed, rather than just the lone one.
	* init/process.c (process_kill): Send the signal to all processes
	in the same process group as the pid.
	* init/tests/test_job.c (test_change_state, test_kill_process):
	After spawning a child, call setpgid() to put it in its own process
	group otherwise we could end up TERMing ourselves.

	* init/tests/test_job.c (test_child_reaper): Update test cases to
	include checking of the start_on and stop_on expression trees.
	* init/job.c (job_child_reaper): Mark all blocked events in the
	start_on and stop_on trees as failed; since these are copies of
	the cause event, we can drop that setting already.

	* TODO: Update again, still thinking about the atomicity of event
	expressions.

2007-06-21  Scott James Remnant  <scott@netsplit.com>

	* init/tests/test_job.c (test_change_state): Include tests on a job's
	start_on and stop_on event expression trees, and make sure that events
	are unblocked and unreferenced at the appropriate moments.
	* init/job.c (job_change_state): Unblock the events that started the
	job in running (if a service), and reset when we reach waiting (leave
	referenced otherwise so the environment is always present).
	Unblock and unreference the events that stopped the job in
	starting (for restarting), running (if coming from pre-stop) and
	waiting.
	
	* init/tests/test_job.c (test_handle_event): Rewrite tests using
	event expressions, and make sure events are referenced and blocked
	correctly matching how jobs are affected.  Include tests for correct
	instance behaviour.
	(test_instance): Make sure that instances copy across the expression
	state, and reset the parent.
	* init/job.c (job_instance): After spawning a new instance, reset
	the start_on expression of the master job.

	* init/event.c (event_operator_copy): Change to making the parent
	of copies nodes be the actual tree parent, rather than the top
	parent; otherwise you can't free an entire tree in one go.
	* init/tests/test_event.c (test_operator_copy): Check parents of
	copied nodes.
	* init/tests/test_job.c (test_copy): Update parent checks here too.

	* init/tests/test_job.c (test_copy): Make sure that the job copy
	references and blocks the event; and in the event of failure, doesn't
	* init/job.c (job_copy): Reset the start_on and stop_on expressions
	in the event of failure.

2007-06-20  Scott James Remnant  <scott@netsplit.com>

	* TODO: Update.

	* init/parse_job.c (parse_on): New generic parsing function to deal
	with event expressions, including operators, parentheses, etc.
	(parse_on_operator): Function called by parse_on() to deal with an
	operator or operand.
	(parse_on_paren): Function called by parse_on() to deal with a
	parenthesis.
	(parse_on_operand): Function called by parse_on_operator() to deal
	with a non-operator token.
	(parse_on_collect): Function called by all of the above to collect
	the operators on the stack and deposit them into the output box,
	either for collection by a later operator or for returning from
	parse_on().
	(stanza_start, stanza_stop): Call the new parse_on() function to
	deal with "start on" and "stop on", storing it in the appropriate
	part of the job.
	* init/tests/test_parse_job.c (test_parse_job): Replace list empty
	checks for start_events/stop_events with NULL checks on the new
	start_on/stop_on members.
	(test_stanza_start, test_stanza_stop): Test new stanza code.

	* init/errors.h (PARSE_EXPECTED_EVENT, PARSE_EXPECTED_OPERATOR)
	(PARSE_MISMATCHED_PARENS): Add numerics and strings for the errors
	that can be generated by parsing an event expression.
	* init/conf.c (conf_reload_path): Handle the new errors properly,
	including the line number where they occurred.
	* logd/jobs.d/logd.in: Update "stop on" to work with the new parser.

	* init/parse_job.c (stanza_emits): Each entry in the emits list
	is now an NihListEntry with the event name as the string data
	pointer, rather than an EventInfo structure (since that structure
	is gone).
	* init/tests/test_parse_job.c (test_stanza_emits): Update test
	case to check for NihListEntry structures.

	* init/parse_job.c: Where the stanza function parses an argument and
	can possibly reject it, save the position and line number and do not
	return that unless we're happy with the argument.  This ensures errors
	are raised pointing *at* the argument, rather than past it.
	* init/tests/test_parse_job.c: Fix several test case errors where
	the buffer was built incorrectly.  Pedantically check pos and lineno
	after successful parsing, and after errors, to make sure they are
	where they should be.

2007-06-18  Scott James Remnant  <scott@netsplit.com>

	* init/job.h (Job): Replace the start_events and stop_events NihLists
	with start_on and stop_on EventOperators.
	* init/job.c (job_new): Drop list initialising, and instead just set
	the new start_on/stop_on members to NULL.
	(job_copy): Copy the entire event operator tree to the new job,
	including references and blockers.  emits has changed to a list of
	NihListEntry with embedded strings, so copy them that way.
	(job_run_process): Drop "->info."
	(job_handle_event): Instead of iterating the events lists, call
	event_operator_handle and check the return value and top node value.
	(job_detect_stalled): Modify to iterate the start_on tree.
	* init/tests/test_job.c (test_change_state, test_detect_stalled): 
	Drop references to "->info." since we can get the variables directly.
	(test_new): Check that start_on and stop_on are NULL.
	(test_copy): Adjust tests of copying start_on and stop_on trees as
	well as the emits list.
	(test_handle_event, test_handle_event_finished) 
	(test_detect_stalled): Change references from start_events to start_on,
	stop_events to stop_on and construct using EventOperators instead.
	(test_handle_event): Update number of blockers now that the event
	expressions themselves will block the event.
	* init/tests/test_event.c (test_poll): Update number of blockers since
	both the events and cause will block it for now; also change
	start_events and stop_events to start_on and stop_on respectively.

	* init/event.c (event_operator_copy): Copy the children nodes as well.
	* init/tests/test_event.c (test_operator_copy): Test copying
	with children nodes.

	* init/tests/test_control.c (test_event_emit): Drop "->info."

	* init/notify.c (notify_event, notify_event_finished): Drop
	"->info." from event references.

	* init/process.c (process_setup_environment): Drop "->info." from
	cause references
	* init/tests/test_process.c (test_spawn): Likewise.

	* init/event.h (Event): Directly include the name, args and env
	fields rather than using an interim structure; this makes more sense
	since we use them differently than a match does.
	(EventOperatorType, EventOperator): New structure to build event
	expression trees that combine a match with "or" and "and" boolean
	operators; solve some problems by holding the reference and blocker
	on the matched event inside this structure directly and provide
	methods to unblock and reset them.
	(EventInfo): Drop this structure completely now that it is unused.
	* init/event.c (event_info_new): Rename this structure to
	event_operator_new() and initialise the new fields properly.
	(event_info_copy): Likewise rename to event_operator_copy and deal
	with copying event references and blockers over to the new structure,
	since the state is useful to copy.
	(event_match): Rename to event_operator_match and switch the arguments
	around since it makes slightly more sense that way.
	(event_operator_update): Function to update the value of an EVENT_OR
	or EVENT_AND operator based on the value of the two children.
	(event_operator_handle): Function to iterate an entire expression
	tree looking for a given event, and update the values of other
	operators if matched.
	(event_operator_unblock): Function to iterate an expression tree
	and release any events we're blocking.
	(event_operator_reset): Function to iterate an expression tree,
	unreferencing any events and resetting all values back to FALSE.
	(event_new, event_pending, event_finished): Update references to
	the Event structure to discard the intermediate "->info."
	* init/tests/test_event.c (test_info_new): Rename to
	test_operator_new() and test various features of the function added
	in the converstion.
	(test_info_copy): Likewise rename to test_operator_copy() and add a
	few more tests, especially that blockers and references are copied.
	(test_match): Rename to test_operator_match() and adjust argument
	order to match the change.
	(test_new) Call event_init() to avoid a valgrind error and update
	references to drop "->info."
	(test_poll): Use EventOperators in the job to test event polling,
	rather than the old structures.
	(test_operator_update, test_operator_handle, test_operator_unblock)
	(test_operator_reset): Test behaviour of the new functions.

2007-06-13  Scott James Remnant  <scott@netsplit.com>

	* TODO: Update utmp/wtmp thoughts.

2007-06-12  Scott James Remnant  <scott@netsplit.com>

	* init/paths.h: Remove extra /, oops.
	* init/Makefile.am (install-data-local): Make destination
	configuration directories as part of "make install".
	(AM_CPPFLAGS): Define LEGACY_CONFDIR to be $(sysconfdir)/event.d
	* logd/Makefile.am (jobs.d/logd): Replace mkdir_p with MKDIR_P
	* init/main.c: Use macro to pick up /etc/event.d so it can be moved
	by configure

	* TODO: Update.

	* init/Makefile.am (AM_CPPFLAGS): Define CONFDIR to be
	$(sysconfdir)/init, replacing the old CFG_DIR definition.
	* init/paths.h (CFG_DIR): Replace with CONFDIR definition,
	and set the default to /etc/init
	* init/main.c: Load configuration from /etc/init/init.conf,
	/etc/init/conf.d and /etc/init/jobs.d; retain loading from /etc/event.d
	for the time being.
	* init/man/init.8: Change reference to directory.
	* logd/Makefile.am: Replace references of eventdir with jobsdir,
	and event.d with jobs.d
	* logd/event.d: Rename to logd/jobs.d

	* init/conf.c (conf_reload): Ignore ENOENT, it's not interesting
	in the general case.

	* init/tests/test_conf.c (test_source_reload): Test the general
	reload function.

	* init/tests/test_conf.c (test_source_free): s/unlink/rmdir/
	(test_source_reload_file): Test that configuration files work, and
	are parsed with anything alongside ignored automatically.
	* init/conf.c (conf_file_filter): As well as not filtering out the
	source path itself, we also need to not filter out the path we're
	watching which is different in the case of files; we need to know
	about it because we handle its removal.
	(conf_delete_handler): Compare the path deleted against the path
	we're watching, rather than the source path, since this means the
	watch needs to be freed.

	* compat/sysv/shutdown.c: Use nih pidfile functions since they're
	more reliable than doing it ourselves.

2007-06-11  Scott James Remnant  <scott@netsplit.com>

	* init/conf.c (conf_reload_path): Call parse_conf for mixed files
	and directories.  Make a correction to the old_items code, was
	passing the wrong arguments to nih_list_add; the effect we wanted
	was that we add the old items head into the list, and remove the
	existing head (what we did was add the first item to the old_items
	list and then cut the rest out).
	* init/tests/test_conf.c (test_source_reload_dir): Rename to
	test_source_reload_job_dir, since that's what this does.
	(test_source_reload_conf_dir): Add another function that tests
	directories of mixed configuration.

	* init/parse_conf.c (parse_conf): Parse a configuration file that
	defines jobs by name.
	(stanza_job): Job stanza, slightly trickier than it would appear to
	need to be, to parse the block in-place and keep pos/lineno
	consistent.
	* init/parse_conf.h: Prototype for external function.
	* init/tests/test_parse_conf.c: Test suite for mixed configuration
	parsing.
	* init/Makefile.am (init_SOURCES): Build and link parse_conf.c and
	parse_conf.h
	(TESTS): Build and run parse_conf tests
	(test_parse_conf_SOURCES, test_parse_conf_LDFLAGS) 
	(test_parse_conf_LDADD): Details for parse_conf test suite.
	(test_conf_LDADD): Add parse_conf.o and conf.o since this calls
	them now.

	* init/conf.c (conf_source_reload, conf_source_reload) 
	(conf_reload_path): Add some debugging messages.

	* init/conf.c (conf_source_new): Add missing call to conf_init()

	* init/conf.c (conf_item_new): Drop source parameter, since it's
	unused in the function and makes it harder to call this when we
	only have one data pointer.
	(conf_reload_path): Drop source from conf_item_new() call.
	* init/conf.h: Update prototype.
	* init/tests/test_conf.c (test_item_new, test_item_free) 
	(test_file_free): Drop source parameter from calls.

2007-06-10  Scott James Remnant  <scott@netsplit.com>

	* init/main.c (main): Add a handler for the SIGHUP signal
	(hup_handler): Handler for SIGHUP, just calls conf_reload().

	* init/main.c (main): Read the configuration again.

	* TODO: Update.

	* init/tests/test_conf.c (test_source_reload_dir): Reset the priority
	and clean up consumed inotify instances.
	(test_source_free, test_file_free, test_item_free): Test the free
	functions on their own, paying special attention to conf_item_free()
	even though this really duplicates other tests.

	* init/conf.c (conf_reload_path): In the case where we fail to map
	the file into memory, we still need to purge all the items that
	previously existed.
	* init/tests/test_conf.c (test_source_reload): Rename to
	test_source_reload_dir, so that we can keep this and the file
	tests separate to make it easier to deal with.
	(test_source_reload_dir): Add tests for physical and parse errors
	when re-loading jobs with and without inotify, and for inotify-based
	modification handling of jobs.

	* init/tests/test_conf.c (test_source_reload): Add test for walk
	of non-existant directory with and without inotify; also test for
	what happens when the top-level directory is deleted, again with
	and without inotify.
	* init/conf.c (conf_delete_handler): Handle the case of the top-level
	directory being deleted by freeing the watch (so next time we asked
	to reload, we can restore it).

	* init/tests/test_conf.c (test_source_reload): Add a test for
	deletion of a running job.

	* init/conf.c (conf_item_free): Fix this up; when deleting an item
	from a source, we first mark it for deletion unless it's already
	marked for replacement.  Then if it's the replacement for something
	else, we mark that to be replaced by whatever we're being replaced
	by (so there are no references to us) and change that state if
	necessary.  Finally we replace our own item and free the record
	before returning.
	* init/tests/test_conf.c (test_source_reload): Check that we handle
	the cases of modiciation of a running job, modification of a
	replacement of a running job and deletion of a replacement for a
	running job.

	* init/parse_job.c (parse_job): Instead of freeing the previous
	replacement, which could leave invalid references to it, mark it
	for deletion and change the state.
	* init/tests/test_parse_job.c (test_parse_job): Adjust the test so
	that we hold a reference to the replacement job and make sure that
	the state is changed to deleted, rather than checking for a destructor
	being called on it.

	* init/init.supp (conf-init): Add valgrind suppression for the
	configuration sources hash table.

	* init/conf.c (conf_item_free): Don't overwrite any previous
	replacement, only mark us for deletion if we wouldn't otherwise
	be replaced.  Add some commented possible code for testing.
	* init/tests/test_conf.c (test_source_reload): Test replacement of
	jobs works properly; test modification with direct write and with
	atomic rename replace; test deletion.

	* init/conf.c (conf_reload_path): It turns out that the flag trick
	doesn't work for items since we often reparse them within the same
	file tag (it works with files because they're atomic and reparsed).
	Store the old items in a different list instead.
	(conf_source_free): We need to be careful about freeing sources,
	so have a function to do it properly.
	(conf_item_new): Since the flag member isn't useful, don't bother
	setting it.
	* init/conf.h: Add conf_source_free prototype.
	(ConfFile): Remove flag member.
	* init/tests/test_conf.c (test_source_reload): Add test for inotify
	create detection.

	* init/conf.c (conf_file_delete): Rename to conf_file_free and match
	the pattern of those kinds of functions.
	(conf_item_delete): Likewise rename to conf_item_free and match the
	pattern of these kinds of functions.
	* init/conf.h: Add prototypes.

	* init/conf.c (conf_reload_path): Fix bug with job name generation.
	Allow non-parsing errors to be returned from the function.
	(conf_item_delete): Drop all replacement management code, we'll put
	this back through testing.
	* init/tests/test_conf.c (test_source_reload): Test reloading adds
	the right inotify watch and parses the files, also check that loading
	without inotify and mandatory reloading work.

	* init/conf.c (conf_source_reload): Move the item deletion detection
	code from this function, where it would only happen on a mandatory
	reload
	(conf_reload_path): to this function, where it will happen every time
	the file is parsed; which is actually what we want.

2007-06-08  Scott James Remnant  <scott@netsplit.com>

	* init/conf.h (ConfItem): Drop the name and replace it with a type.
	(ConfItemType): Enum for different types of configuration items
	(ConfFile): Change items from a hash table to a list.
	* init/conf.c (conf_file_get): Initialise the items member as a list.
	(conf_item_set): Rename to conf_item_new again.
	(conf_item_new): Allocates a new ConfItem and adds it to the file's
	list, we won't reuse items anymore since it doesn't really make sense.
	(conf_source_reload): Adjust clean-up code now that items is a list.
	(conf_reload_path): Work out the name of jobs found by filename,
	allocate a new item for them and parse the job into it.  Perform
	handling of errors by outputting a warning.
	(conf_item_delete): Takes both source and file so we can make
	intelligent decisions.
	(conf_file_delete): Takes a source and passes it to conf_item_delete
	(conf_delete_handler): Pass both source and file to conf_file_delet
	* init/tests/test_conf.c (test_file_get): Check that the items
	list is empty; rather than the hash being unallocated.
	(test_item_set): Rename back to test_item_new and only allocate a
	single item which should get added to the list.

2007-06-06  Scott James Remnant  <scott@netsplit.com>

	* init/parse_job.c (stanza_respawn): Permit the word "unlimited",
	raise a specific error for illegal limit and illegal interval.
	(stanza_pid, stanza_kill, stanza_normal, stanza_umask) 
	(stanza_nice, stanza_limit): Raise specific errors rather than
	a generic "illegal value" error.
	* init/tests/test_parse_job.c (test_stanza_respawn): Check that
	we can use "unlimited", also check for new error return.
	(test_stanza_pid, test_stanza_kill, test_stanza_normal) 
	(test_stanza_umask, test_stanza_nice, test_stanza_limit): Check
	for new specific errors.
	* init/errors.h: Replace CFG_ILLEGAL_VALUE with a series of parse
	errors.

	* init/conf.c: Comments.

	* init/conf.c (conf_item_set): Call out to conf_item_delete() to
	handle unsetting of an item's data.
	(conf_source_reload): Add code to deal with mandatory reloading,
	calls conf_file_delete() and/or conf_item_delete() as appropriate.
	(conf_delete_handler): Call conf_file_delete() on the ConfFile that
	we find.
	(conf_file_delete): Function to delete all items in a file.
	(conf_item_delete): Placeholder function to delete an item.

	* init/conf.c (conf_file_new): Rename to conf_file_get; in practice
	we never just want to allocate one of these, we always want to
	return the existing entry if it exists.
	(conf_item_new): Rename to conf_item_set; again in practice we always
	want to update an existing item.  This function will grow the "deal
	with replacement" stuff.
	(conf_reload): Start putting in place the code that will allow
	mandatory reloads, as well as initial setup.  This function iterates
	over the sources and deals with errors.
	(conf_source_reload): Function to reload an individual source, calls
	out to one of the following two functions and will eventually perform
	the deleted items scan.
	(conf_source_reload_file): Set up a watch on a file, and reload it.
	(conf_source_reload_dir): Set up a watch on a directory and reload it.
	(conf_file_filter): Filter for watching parent directory of files.
	(conf_create_modify_handler): File creation and modification handler.
	(conf_delete_handler): File deletion handler.
	(conf_file_visitor): Tree walk handler.
	(conf_reload_path): Function that deals with files themselves,
	currently just sorts out the ConfFile structure and maps the file
	into memory.
	* init/conf.h: Add new prototypes, update existing ones.
	* init/tests/test_conf.c (test_file_new): Rename to test_file_get,
	also test repeated calls when already in the table.
	(test_item_new): Rename to test_item_set, also test repeated calls
	when already in the table.
	(test_source_reload): Start of test for reloading sources.

2007-06-05  Scott James Remnant  <scott@netsplit.com>

	* init/conf.c: Make a start on the new configuration management
	routines, which will allow finer-grained tracking of configuration
	and support mandatory reloading.
	(conf_source_new, conf_file_new, conf_item_new): Start off with the
	functions to allocate the tracking structures we need to use.
	* init/conf.h: Structures and prototypes
	* init/tests/test_conf.c: Test suite for allocation functions.
	* init/Makefile.am (init_SOURCES): Build and link conf.c and conf.h
	(TESTS): Run the conf test suite.
	(test_conf_SOURCES, test_conf_LDFLAGS, test_conf_LDADD): Details for
	the conf test suite.

2007-06-04  Scott James Remnant  <scott@netsplit.com>

	* init/parse_job.c (stanza_description, stanza_author, stanza_version)
	(stanza_chroot, stanza_chdir, stanza_pid): Instead of erroring when
	the string has already been allocated, free it and replace it with the
	new one. Attempting to forbid duplicates is just too inconsistent,
	especially for the integer ones which we compare against the default;
	using the last one allows us to be entirely consistent.
	(stanza_daemon, stanza_respawn, stanza_service, stanza_instance):
	Don't error if the flag is already set, just ignore it.
	(stanza_respawn, stanza_pid, stanza_kill, stanza_console) 
	(stanza_umask, stanza_nice): Don't compare the current value against
	the default, just overwrite it!
	(parse_exec, parse_script): Free existing process command string
	before setting a new one over the top.
	(parse_process, stanza_exec, stanza_script, stanza_limit): Instead of
	erroring if the structure is already set and allocated, just don't
	allocate a new one and allow its members to be overwritten.
	* init/tests/test_parse_job.c (test_stanza_exec) 
	(test_stanza_script, test_stanza_pre_start) 
	(test_stanza_post_start, test_stanza_pre_stop) 
	(test_stanza_post_stop, test_stanza_description) 
	(test_stanza_author, test_stanza_version, test_stanza_daemon) 
	(test_stanza_respawn, test_stanza_service, test_stanza_instance) 
	(test_stanza_pid, test_stanza_kill, test_stanza_console) 
	(test_stanza_umask, test_stanza_nice, test_stanza_limit) 
	(test_stanza_chroot, test_stanza_chdir): Replace tests that check
	for an error in the case of duplicate stanzas with tests that make
	sure the last of the duplicates is used.
	* init/errors.h (CFG_DUPLICATE_VALUE, CFG_DUPLICATE_VALUE_STR): Drop
	this error, since we don't consider this a problem anymore.

	* upstart/Makefile.am (libupstart_la_LIBADD): Add $(LTLIBINTL)
	* init/Makefile.am (init_LDADD): Reorder and add $(LTLIBINTL)
	* util/Makefile.am (initctl_LDADD): Reorder and add $(LTLIBINTL)
	* compat/sysv/Makefile.am (reboot_LDADD): Reorder and add $(LTLIBINTL)
	(runlevel_LDADD): add $(LTLIBINTL)
	(shutdown_LDADD): Reorder and add $(LTLIBINTL)
	(telinit_LDADD): Reorder and add $(LTLIBINTL)
	* logd/Makefile.am (logd_LDADD): Add $(LTLIBINTL)

2007-06-03  Scott James Remnant  <scott@netsplit.com>

	* init/tests/test_job.c (test_run_process): Add a test case for a
	crasher when the event has no arguments.
	* init/job.c (job_run_process): Fix the bug, we need to check the
	arguments before trying to append them.

	* init/cfgfile.c, init/cfgfile.h, init/tests/test_cfgfile.c: Rename
	to parse_job and strip out all functions except the parsing and stanza
	ones.
	* init/Makefile.am (init_SOURCES): Build and link parse_job.c and h
	(TESTS): Run the parse job test suite
	(test_cfgfile_SOURCES, test_cfgfile_LDFLAGS, test_cfgfile_LDADD):
	Rename and update.
	* init/parse_job.c: Rename all cfg_stanza_*() functions to just
	stanza_*(), rename all cfg_parse_*() functions to just parse_*().
	(parse_job, parse_process, stanza_exec, stanza_script, stanza_start)
	(stanza_stop, stanza_emits, stanza_normal, stanza_env, stanza_limit):
	Don't use NIH_MUST, it's fine to be out of memory and we should fail
	in that case with a useful error.  The user can always reload the
	config file.
	(cfg_read_job, cfg_watch_dir, cfg_job_name, cfg_create_modify_handler)
	(cfg_delete_handler, cfg_visitor): Drop these functions for now.
	* init/parse_job.h: Update so it just contains the one prototype.
	* init/tests/test_parse_job.c: Update all tests to pass a string
	to parse_job(), and check errors raised; rather than mucking around
	with file descriptors all of the time.  Spend the effort while we're
	in here to run TEST_ALLOC_FAIL where we can.
	* init/main.c: Drop config file loading for now since it's missing.

2007-05-27  Scott James Remnant  <scott@netsplit.com>

	* init/cfgfile.h (CFG_DIR): Drop this define, since it's in paths.h
	(CfgDirectory): 

	* init/cfgfile.c (cfg_read_job): Separate out the job-handling code
	into a new function that we could call from a stanza if we want
	later; this one now just maps the file into memory and deals with
	exceptions from the parsing.
	(cfg_parse_job): Function containing the seperated out code; parses
	a new job, marking it as a replacement for any existing job with the
	same name.  Drop the warnings for using pid options without a daemon,
	since these are actually useful for other things later.
	* init/tests/test_cfgfile.c (test_read_job): Drop the check on
	unexpected daemon options, since we don't issue these warnings
	anymore.

2007-05-20  Scott James Remnant  <scott@netsplit.com>

	* init/event.c (event_match): Change to accept Event as the first
	argument and EventInfo as the second, making it obvious that this
	matches a received Event against known EventInfo rather than just
	comparing two info structs (since the order matters).
	* init/event.h: Update prototype.
	* init/tests/test_event.c (test_match): Update test accordingly.
	(test_poll): Fix typo.
	* init/job.c (job_handle_event): Pass in the event as the first
	argument to event_match, rather than its info.
	* TODO: Update.

	* init/job.c (job_emit_event): Return the event that we emit; don't
	bother tracking block status or setting blocked, leave that to the
	state loop so things are more obvious.
	(job_change_state): Set the blocked flag here for starting and stopping
	to the return value of job_emit_event().

	* init/event.c (event_ref, event_unref): Reference counting of events
	so we don't free those we still need.
	(event_block, event_unblock): Blocker counting that replaces the
	previous jobs member.
	(event_new): Initialise refs and blockers fields.
	(event_emit_finished): Remove this function.
	(event_poll): Handle the new done state, and deal with the blockers
	and references counts; turns out that we can fall all the way through
	this switch if these are zero without needing to check again.
	(event_pending): Remove call to event_emit_finished, the event_poll()
	loop handles this case now.
	(event_finished): Set progress to done on the way out.
	* init/event.h (EventProgress): Add new done state
	(Event): Add refs and blockers members, replacing jobs
	* init/tests/test_event.c (test_new): Check refs and blockers are
	initialised to zero.
	(test_ref, test_unref, test_block, test_unblock): Check the ref
	counting function behaviours.
	(test_emit_finished): Drop this function since it's not used
	* init/job.c (job_change_cause): Reference and block the event,
	and unblock and unreference before changing.
	(job_emit_event): Reference the event that blocks the job from
	continuing.
	(job_handle_event_finished): Unreference the blocking event again.
	(job_change_state): Make sure that blocked has been cleared before
	allowing a state change.
	* init/tests/test_job.c: Change tests to use refs/blockers on the
	cause event when counting, and also to follow the status of blocked
	since that is now ref-counted as well.

2007-05-18  Scott James Remnant  <scott@netsplit.com>

	* init/main.c (main, cad_handler, kbd_handler, pwr_handler): Use
	event_new rather than event_emit.
	* init/job.h (Job): Change type of cause and blocked to Event
	* init/job.c (job_change_goal, job_change_cause, job_emit_event) 
	(job_handle_event, job_handle_event_finished): Update all references
	to EventEmission to use Event instead.
	(job_detect_stalled): Call event_new instead of event_emit
	(job_run_process): Use the info member of cause, not event member
	* init/tests/test_job.c (test_change_goal, test_change_state) 
	(test_run_process, test_child_reaper, test_handle_event) 
	(test_handle_event_finished): Update all references to EventEmission
	to use Event instead.
	(test_detect_stalled): Correct to use right structure types.
	* init/process.c (process_setup_environment): Use cause's info member,
	rather than event member.
	* init/tests/test_process.c (test_spawn): Update to use Event.
	* init/notify.h (NotifySubscription): Change member to event
	* init/notify.c (notify_subscribe_event) 
	(notify_subscription_find, notify_job_event, notify_event) 
	(notify_event_finished): Update functions to use event member and
	Event structures.
	* init/tests/test_notify.c (test_subscribe_event) 
	(test_subscription_find, test_job, test_job_event, test_event) 
	(test_event_finished): Update to use Event instead of EventEmission
	* init/control.c (control_event_emit): Update to use event_new.
	* init/tests/test_control.c (test_event_emit) 
	(test_subscribe_events, test_unsubscribe_events): Update to use
	Event rather than EventEmission.

	* init/event.h: Fix up a few references.
	* init/tests/test_event.c (test_new): Remove reference to emission.

	* init/event.h (EventEmission): Rename to Event, and rename event
	member to info.
	* init/event.c (event_emit_next_id): Rename to event_next_id
	(event_emit): Rename to event_new, and add standard parent argument.
	(event_emit_find_by_id): Rename to event_find_by_id
	(event_poll): Iterate over Events in the list
	(event_pending, event_finished): Operate on Event
	* init/tests/test_event.c (test_emit): Rename to test_new and
	adjust for names and arguments.
	(test_emit_find_by_id): Rename to test_find_by_id and adjust for
	names.
	(test_emit_finished, test_poll): Adjust names.

	* init/cfgfile.c (cfg_stanza_start, cfg_stanza_stop) 
	(cfg_stanza_emits): Convert to use EventInfo and event_info_*.
	* init/job.c (job_copy): Use EventInfo and event_info_copy.
	(job_handle_event, job_detect_stalled): Iterate EventInfo structures
	* init/tests/test_cfgfile.c (test_stanza_start, test_stanza_stop) 
	(test_stanza_emits): Update to use EventInfo
	* init/tests/test_job.c (test_copy, test_handle_event) 
	(test_handle_event_finished, test_detect_stalled): Update to use
	EventInfo and event_info_new
	* init/event.c (event_copy): Use nih_str_array_copy here, to make the
	code somewhat simpler.
	(event_finished): Copy the arguments and environment from the old
	event, rather than stealing and reparenting.
	* init/job.c (job_copy): Use nih_str_array_copy here too.
	(job_run_process): Use nih_str_array_append to add the arguments from
	the emission onto the command run.

	* init/event.h (Event): Rename to EventInfo, since this structure
	representations information about an event, rather than an actual
	event in progress.
	* init/event.c (event_new): Rename to event_info_new, also now can
	take arguments and environment like event_emit() can.
	(event_copy): Rename to event_info_copy.
	* init/tests/test_event.c (test_new): Rename to test_info_new,
	update names in test and test being given args or env.
	(test_copy): Rename to test_info_copy and update names in test.
	(test_match, test_poll): Use EventInfo.

	* TODO: Update.

2007-04-24  Scott James Remnant  <scott@netsplit.com>

	* configure.ac: Add AM_PROG_CC_C_O since we use per-target flags
	for one of the test cases.

2007-03-16  Scott James Remnant  <scott@netsplit.com>

	* upstart/message.c (upstart_message_newv): Add va_end to match
	va_copy because the standard says so.
	* upstart/wire.c (upstart_push_packv, upstart_pop_packv): Add
	va_end here as well.

2007-03-13  Scott James Remnant  <scott@netsplit.com>

	* init/main.c: Wait until we've closed inherited standard file
	descriptors and opened the console instead before trying to open the
	control socket; otherwise we end up closing it by accident if we
	weren't opened with sufficient descriptors in the first place.
	Also wait until we've set up the logger before trying to parse the
	configuration.  In fact both of these things need to be pretty low
	down the main() function.

	* init/tests/test_job.c (test_run_process): Skip /dev/fd test cases
	if that's not available.

	* init/tests/test_control.c (test_log_priority): Make sure we know
	that the message has been sent before calling the watcher.

	* init/cfgfile.c (cfg_watch_dir): We get ENOSYS for missing inotify
	support, not EOPNOTSUPP.
	* init/tests/test_cfgfile.c (test_watch_dir): Actually make the
	directory tree before testing for inotify, since we use the same
	tree there too.

	* util/initctl.c (job_info_output): Restructure so gcc doesn't think
	name can be used uninitialised.
	* init/tests/test_cfgfile.c (test_watch_dir): Correct an error where
	i wouldn't be initialised if we skipped the inotify tests.

	* util/initctl.c (job_info_output): Restructure so gcc doesn't think
	* init/process.c (process_setup_environment): job id fits inside
	a %u now

	* upstart/message.h: Style; always refer to "unsigned int" as
	"unsigned int", and never "unsigned.
	* upstart/tests/test_message.c (my_handler): Catch a stray couple
	of "unsigned"s

	* init/control.c (control_job_query, control_job_start) 
	(control_job_stop): Change type of id argument to unsigned int,
	and call printf with %u to output it.
	* init/tests/test_control.c (check_job, check_job_instance) 
	(check_job_instance_end, check_job_status__waiting) 
	(check_job_status_end__waiting, check_job_status__starting) 
	(check_job_status_end__starting, check_job_status__running) 
	(check_job_status_end__running, check_job_status__pre_stop) 
	(check_job_status_end__pre_stop, check_job_status__stopping) 
	(check_job_status_end__stopping, check_job_status__deleted) 
	(check_job_status_end__deleted, check_job_unknown) 
	(check_job_invalid, check_job_unchanged, check_event): Change
	type of id arguments to unsigned int.
	(check_list): Change type of id to unsigned int.
	* init/tests/test_notify.c (check_job_status) 
	(check_job_status_end, check_job_finished, check_event) 
	(check_event_caused, check_event_finished): Change type of id
	arguments to unsigned int.

	* init/job.h (Job): Change the type of the id to unsigned int.
	* init/job.c (job_next_id): Change ids to be unsigned ints, and now
	we can just use %u in the nih_error call.
	(job_find_by_id): Change argument to be unsigned int
	* init/tests/test_job.c (test_find_by_id): Change id type to unsigned
	int.
	* init/event.h (Event): Change the type of the id to unsigned int.
	* init/event.c (event_emit_next_id): Change ids to be unsigned ints,
	and now we can just use %u in the nih_error call.
	(event_emit_find_by_id): Change argument to be unsigned int
	* init/tests/test_event.c (test_emit, test_emit_find_by_id) 
	(check_event, check_event_finished): Change id type to unsigned int.

	* util/initctl.c (output_name): Use an unsigned int for the job id,
	which means we can use ordinary %u for the printf argument.
	(handle_job, handle_job_finished, handle_job_instance) 
	(handle_job_instance_end, handle_job_status) 
	(handle_job_status_end, handle_job_unknown, handle_job_invalid) 
	(handle_job_unchanged, handle_event, handle_event_caused) 
	(handle_event_finished): Change argument type of id from uint32_t
	to unsigned int.
	(job_info_output): Change output type of id from %zu to %u

	* upstart/message.c (upstart_message_handle): Use unsigned int for
	ids, rather than a fixed-width type.
	* upstart/tests/test_message.c (my_handler): Use unsigned int for
	the ids, and give "unsigned int" instead of "unsigned" to va_arg as
	a matter of style.

	* upstart/wire.c (upstart_push_int, upstart_pop_int): Send over the
	wire using a plain old integer type, instead of a fixed width type;
	there's no advantage to using the fixed-width type and we could hurt
	ourselves if we tried running on ILP64.
	(upstart_push_unsigned, upstart_pop_unsigned): Likewise use a plain
	unsigned int over the wire.
	(upstart_push_string, upstart_pop_string): Use an unsigned int for
	the length of the string, technically this means that we silently
	truncate any string that's greater than 4GB on 64-bit platforms;
	it's either that or make the test cases harder (we did this before
	anyway).
	(upstart_push_header, upstart_pop_header): Type is always an unsigned
	int (best conversion from an enum)

2007-03-11  Scott James Remnant  <scott@netsplit.com>

	* configure.ac: Bump version to 0.3.9

	* NEWS: Update.

	* util/man/initctl.8: Document the new commands.

	* TODO: Update.

	* init/job.c (job_handle_event): Correct the function so we don't
	try and stop the master of an instance, and cause an assertion error.

	* util/initctl.c: Oops, correct function pointers in command table

	* util/tests/test_initctl.c (test_version_action): 

	* util/initctl.c (handle_version): Handle receipt of the version
	reply.
	(version_action): Send the version-query message to the server and
	expect one response.
	(log_priority_action): Parse the single argument into an NihLogLevel
	and send it to the server.

	* init/control.c (control_version_query, control_log_priority):
	Functions to handle the new messages from the server pov
	* init/tests/test_control.c (test_version_query) 
	(test_log_priority): Test the new messages are handled properly.
	(check_version): Check the version string matches.
	* upstart/message.h: Add messages for querying the version of the
	init daemon and changing the log priority.
	* upstart/message.c (upstart_message_newv)
	(upstart_message_handle): Marshal the new messages.
	* upstart/tests/test_message.c (test_new, my_handler) 
	(test_handle): Test the marshalling of the new messages,

	* upstart/libupstart.ver: Add enum functions to the global list.

	* util/initctl.c (start_action, stop_action): Imply --no-wait if
	we take the job id or name from an environment variable, since we'd
	end up waiting for ourselves otherwise
	* util/tests/test_initctl.c (test_start_action, test_stop_action):
	Update test cases to make sure no-wait is implied.

2007-03-09  Scott James Remnant  <scott@netsplit.com>

	* configure.ac: Bump version to 0.3.8

	* NEWS: Updated.
	* configure.ac: Increase version to 0.3.7

	* init/tests/test_job.c (test_change_state): Add a test case for
	deleting the last instance of a replaced job.
	* init/job.c (job_change_state): When moving a instance of a job into
	the deleted state, check whether we should replace the job it's an
	instance of, and if so, change that job's state too.
	* TODO: Update.

	* util/initctl.c (handle_job_list): Always allocate current_list,
	since we need it to be the parent of pointers we attach to it.
	(handle_job_list_end): Always free the current list, only suppress
	output if there aren't any entries in it.
	(initctl_recv): Check the current_list pointer, no need for in_list
	(handle_job_instance, handle_job_instance_end, handle_job_status):
	Check current_list not in_list.
	* util/tests/test_initctl.c: Correct some memory leaks.

	* init/process.c (process_setup_environment): Set the UPSTART_JOB_ID
	environment variable to the job's unique id.
	* init/tests/test_process.c (test_spawn): Make sure it's set.

	* util/man/initctl.8: Update the initctl manpage.
	* compat/sysv/man/reboot.8: Correct a minor grammar error.
	* compat/sysv/man/shutdown.8: Fix reference from runlevel to telinit.

	* README: Add a README that copies the text from the web page and
	adds some notes about recommended operating system versions.

	* util/initctl.c: Completely rewrite initctl, top to bottom; handling
	of the new messages is done natively, meaning that the commands just
	vary the requests send and number of responses expected.
	* util/tests/test_initctl.c: Test all of the new code.

	* init/main.c: Improve restarting and rescuing a little; store the
	program path in a static variable so we can always access it, and
	use the exported loglevel to pass the same to the new process.
	* TODO: Update.

	* compat/sysv/shutdown.c: More error/fatal adjustments.
	* compat/sysv/telinit.c: More error/fatal adjustments.

2007-03-08  Scott James Remnant  <scott@netsplit.com>

	* init/main.c (main, crash_handler): Promote deadly errors to nih_fatal
	* logd/main.c (main): Promote deadly errors to nih_fatal
	* compat/sysv/reboot.c (main): Promote deadly errors to nih_fatal
	* compat/sysv/shutdown.c (main, shutdown_now): Promote deadly errors
	to nih_fatal
	* compat/sysv/telinit.c (main): Promote deadly errors to nih_fatal

	* init/event.c (event_pending): The message that we're handling an
	event should be logged with --verbose.

	* init/cfgfile.c (cfg_parse_script): Remove the unnecessary check for
	a token inside a script block.

	* TODO: Update.

	* init/control.c (control_watch_jobs): Rename to control_subscribe_jobs
	and update to handle new event name.
	(control_unwatch_jobs): Rename to control_unsubscribe_jobs and update
	to handle the new event name.
	(control_watch_events): Rename to control_subscribe_events and update
	to handle the new event name.
	(control_unwatch_events): Rename to control_unsubscribe_events and
	update to handle the new event name.
	* init/tests/test_control.c (test_watch_jobs): Rename to
	test_subscribe_jobs and update to new event name.
	(test_unwatch_jobs): Rename to test_unsubscribe_jobs and update to 
	new event name.
	(test_watch_events): Rename to test_subscribe_events and update to
	new event name.
	(test_unwatch_events): Rename to test_unsubscribe events and update
	to new event name.

	* upstart/message.h: Rename the watch commands to subscribe/unsubscribe
	and regroup with new message numbers.
	* upstart/message.c (upstart_message_newv) 
	(upstart_message_handle): Marshal the updated subscription messages.
	* upstart/tests/test_message.c (test_new, my_handler) 
	(test_handle): Update tests to new names and numbers.
	* TODO: Update.

	* upstart/message.c (upstart_message_handle): Raise a the unknown
	message error if the type is unknown, rather than the invalid message
	error.
	* upstart/tests/test_message.c (test_handle): Correct test case.

	* init/job.c (job_change_state): Correct a problem here too, when
	moving from pre-stop to running, we don't want to emit a started event
	since we never emitted a stopping event and never killed the process
	anyway.  We do need to notify the job as finished, since the process
	that tried to stop it will need to be told not to wait any longer.
	* init/tests/test_job.c (test_change_state): Add a test for pre-stop
	back to running.

	* doc/states.dot: Fix an error in the state diagram; when moving from
	starting back to waiting, due to a failed respawn, we need to emit
	the stopped event otherwise it will never happen.
	* doc/states.png: Update.

2007-03-05  Scott James Remnant  <scott@netsplit.com>

	* upstart/message.c (upstart_message_new): Make this a wrapper around
	(upstart_message_newv): which has all the old code, but accepts a
	va_list instead of making its own.
	* upstart/message.h: Add prototype.

	* init/main.c (crash_handler): Simply trying to leave a SEGV handler
	doesn't work so well, we end up repeating the problem instruction.
	We really can't resume from this point, and can't even jump elsewhere
	since our state is probably buggered up.  Only thing for it is to
	re-exec ourselves with a clean state.

	* init/cfgfile.c (cfg_read_job, cfg_delete_handler): Don't try and
	free the magic (void *)-1 replacement (delete).

	* util/events.c, util/events.c, util/jobs.c, util/jobs.h: With the
	new message responses, that intermix event and job information freely,
	it no longer makes sense to distinguish between them.  So fold these
	files back into the main initctl.c
	* util/initctl.h: Drop unused header.
	* util/Makefile.am (initctl_SOURCES): Update sources list.
	(TESTS): Change which tests we build
	(test_initctl_SOURCES, test_initctl_CFLAGS, test_initctl_LDFLAGS) 
	(test_initctl_LDADD): Build the new combined test case binary, use
	an automake feature to rebuild initctl.c with -DTEST and a different
	.o file, and thus be able to define out main()

	* util/tests/test_events.c, util/tests/test_jobs.c: Collapse the two
	test case files into one single
	* util/tests/test_initctl.c

	* init/control.c (control_job_find): And implement the find function
	that returns a list of jobs matching an optional pattern.
	* init/tests/test_control.c: Make sure we do send all messages.
	(check_list): Complex function to check the responses to a job list
	(test_job_find): Test a couple of job lists.
	* init/tests/test_notify.c: Make sure we do send all messages.

	* init/control.c (control_job_query): Implement the query message,
	this just needs to return the status or instance set.
	* init/tests/test_control.c (test_job_query): Test the query command.
	(check_job_status__deleted, check_job_status_end__deleted): Pair of
	functions to check we can query deleted jobs directly.

	* init/control.c (control_send_instance): Function to send an instance
	job, collating all of its instances together.
	* init/control.h: Update.
	* init/tests/test_control.c (test_send_instance): Check we receive
	the right messages.
	(check_job_instance, check_job_instance_end): Pair of functions to
	check the instance messages.

	* upstart/message.h: Add new UPSTART_JOB_INSTANCE and
	UPSTART_JOB_INSTANCE_END messages which we'll use to communicate that
	a job is an instance, and group the instances of it together.
	* upstart/message.c (upstart_message_new, upstart_message_handle):
	Marshal the new instance messages.
	* upstart/tests/test_message.c (test_new, my_handler) 
	(test_handle): Test the new message types.

	* upstart/message.h: Restore arguments to JOB_LIST, but rename to
	pattern since that's what it is.
	* upstart/message.c (upstart_message_handle): Restore arguments
	with updated name.
	* upstart/tests/test_message.c (test_new, my_handler) 
	(test_handle): Restore tests for arguments, rename and make sure we
	include a wildcard.

2007-03-04  Scott James Remnant  <scott@netsplit.com>

	* upstart/message.h: Drop arguments to JOB_LIST.
	* upstart/message.c (upstart_message_new, upstart_message_handle):
	Drop arguments to JOB_LIST.
	* upstart/tests/test_message.c (test_new, my_handler) 
	(test_handle): Drop the arguments from the test.

	* init/control.c (control_job_start): Update to return INVALID for
	instances and replacements; add the forgotten UPSTART_JOB message.
	(control_job_stop): Update to return INVALID for replacements; add
	the forgotten UPSTART_JOB message.  Deal with instance masters
	magically by iterating all instances and stopping those instead.
	* init/tests/test_control.c (check_job_deleted): Rename to 
	check_job_invalid and check that message.
	(check_job): Function to check the job we've acted upon.
	(test_job_start): Check that we get the UPSTART_JOB message first,
	restore the check on deleted jobs causing an error and add checks
	that instance and replacement jobs also cause an error.
	(test_job_stop): Check that we get the UPSTART_JOB message first,
	restore the check on deleted jobs causing an error.  Make sure
	instances are handled.

	* upstart/message.h: More message changes; add a JOB_FIND message
	and replace UPSTART_JOB_DELETED with UPSTART_JOB_INVALID since there's
	a few more problem conditions.
	* upstart/message.c (upstart_message_new, upstart_message_handle):
	Marshal the new message and update names.
	* upstart/tests/test_message.c (test_new, my_handler) 
	(test_handle): Update tests to check the new message and update the
	values and names of the existing ones.

	* init/job.h (Job): Remove the delete flag, add replacement and
	replacement_for pointers instead.
	* init/job.c (job_new): Initialise replacement and replacement_for
	pointers to NULL.
	(job_find_by_name): Update to return what job the one we found is
	a replacement for, and to skip DELETED jobs.
	(job_instance): Make it simply illegal to call this for deleted jobs,
	instances or replacements.
	(job_change_goal): Make it illegal to change the goal of a replacement
	job.
	(job_free_deleted): Remove the previous code to handle deleted instance
	masters, because it's now bogus.
	(job_should_replace): New function to determine whether a job is
	replaceable.
	* init/tests/test_job.c (test_new): Check pointers are set.
	(test_copy): Check that replacement and replacement_for are not
	copied, since their state of an individual job.
	(test_find_by_name): Update tests to make sure we ignore deleted jobs,
	instances and replacements.
	(test_instance): Remove test that will now cause an assertion,
	and no longer check delete is set.
	(test_change_goal): Remove test that will now cause an assertion.
	(test_free_deleted): Remove test cases for deleted masters.
	(test_should_replace): Test the new check function.
	(test_change_state): Make sure that we end up in deleted for instances
	and replaced jobs, and that replacements become the real job.
	* init/cfgfile.c (cfg_read_job): Update to handle replacement jobs;
	the old job's previous replacement is discarded, and set to the
	current job; and then if the job should be replaced, it's moved
	to deleted (which should promote the new job).
	(cfg_delete_handler): Handle deletion of a job in a similar manner,
	except we sent the replacement pointer to the special -1 value since
	we have no actual replacement.
	* init/tests/test_cfgfile.c (test_watch_dir): Update tests to make
	sure that deletion and modification are handled wrt replacement.
	(test_read_job): Make sure that reparsing an existing file is handled.
	* init/tests/test_control.c (test_job_start): Remove checks that
	delete gets set to true for instances.
	(test_job_stop, test_job_start): Temporarily comment out deleted
	job behaviour, since that's been somewhat changed.

	* upstart/message.h: We're not going to return JOB_LIST for JOB_STOP
	since that's just awkward for the client; just act on the master,
	and return JOB_UNCHANGED.

	* init/notify.c (notify_job_status): Move this function to
	* init/control.c (control_send_job_status): here, since we need it for
	the new control responses.
	(control_job_query): New single function to list all jobs or a
	particular job.
	* init/control.h: Add prototype.
	* init/tests/test_control.c (test_error_handler): Simplify this a
	little to just sending a NO_OP message, since we can send an entire
	stream of messages and leave them in the queue.
	(check_job_status__stopping, check_job_process) 
	(check_job_status_end__stopping): Trio of check functions for a job
	status that's stopping, with an active main process.
	(test_send_job_status): Test the now global status function.
	(check_job_status__starting, check_job_status_end__starting): Pair
	of check functions for a starting job with no process yet.
	(test_watch_jobs, test_unwatch_jobs): Update to expect the full new
	job status messages, with an optional process part as well.
	(check_event): Function to check an event.
	(test_watch_events): Minor update to use above function.
	(check_job_status__waiting, check_job_status_end__waiting): Pair of
	check functions for the first step in starting a job (goal change only)
	(check_job_unknown, check_job_deleted, check_job_unchanged): Trio
	of functions to check common error responses.
	(test_job_start): Update tests to newer behaviour.
	(check_job_status__running, check_job_status_end__running) 
	(check_job_status__pre_stop, check_job_status_end__pre_stop): Checks
	for the states we go through when stopping a job.
	(test_job_stop): Update tests to newer behaviour.
	* init/notify.c (notify_job, notify_job_event, notify_job_finished):
	Update to call the newly exported function.
	* init/job.c: Make job_id and job_id_wrapped externally available.
	* init/job.h: Update.
	* init/event.c: Make emission_id and emission_id_wrapped externally
	available.
	* init/event.h: Update.

	* upstart/message.h: Rename UPSTART_JOB_INVALID to
	UPSTART_JOB_UNCHANGED, as it's not really invalid just a no-op
	* upstart/message.c (upstart_message_new, upstart_message_handle):
	Update the constant, fields are unchanged,
	* upstart/tests/test_message.c (test_new, my_handler) 
	(test_handle): Rename constants/messages.

	* upstart/message.h: Turns out we need extra errors to indicate that
	the job was deleted or already at that goal, otherwise the client
	would sit there waiting for the finished event.	
	* upstart/message.c (upstart_message_new, upstart_message_handle):
	Marshal the new error messages.
	* upstart/tests/test_message.c (test_new, my_handler) 
	(test_handle): Test the handling of the new messages.

	* init/tests/test_job.c (test_free_deleted): Found a bug; because
	master instances never change state, they never end up in the deleted
	state so are never reaped.  Add some test cases for cleaning them up,
	but not while they have remaining instances.
	* init/job.c (job_free_deleted): Implement the bug fix.

	* init/job.c (job_instance): Split out the instance spawning code
	into its own function, as we'll frequently need a pointer to the
	instance before we try and change the goal.
	(job_change_goal): Clean this function back up again, it no longer
	needs to return values and can assert that it's never called for
	deleted jobs or instance mastersr.
	(job_handle_event): Spawn an instance when we get a start event.
	* init/job.h: Update.
	* init/tests/test_job.c (test_instance): Check instance creation.
	(test_change_goal): Update tests now that it doesn't return a value
	again, and doesn't spawn instances itself.
	(test_handle_event): Make sure instances are spawned.

	* init/tests/test_event.c (test_poll): Needs a slight fix now that
	we generate more events than we check, and that subscriptions go
	away automatically.

	* init/notify.c (notify_job_status): Static function to handle
	sending the more complicated job status message series 
	(notify_job): Call notify_job_status() to send the new-style message
	(notify_job_event): Send the new UPSTART_EVENT_CAUSED message with
	the emission id, then call notify_job_status() to send the new-style
	common status message.
	(notify_job_finished): New function to be called when we reach the
	job rest state, notifies and unsubscribes directly subscribed
	processes, and includes failed information.
	(notify_event_finished): Unsubscribe processes after sending the
	finished event, since the event has gone away.  Also don't send
	this to processes subscribed to all events, since it's not useful
	for them.
	* init/notify.h: Add prototype.
	* init/tests/test_notify.c: Update all test cases and helper
	functions to the new message types.
	(test_job_finished): Check the new finished message is sent with
	a status message preceeding it.
	* init/job.c (job_change_state, job_change_state): Notify subscribed
	processes with notify_job_finished() when in the running (for service)
	or waiting states, just before we drop the cause.

	* upstart/message.h: Add failed, failed_process and exit_status
	arguments to UPSTART_JOB_FINISHED.
	* upstart/message.c (upstart_message_new, upstart_message_handle): 
	Marshal the new arguments.
	* upstart/tests/test_message.c (test_new, my_handler) 
	(test_handle): Test the new arguments.

	* upstart/message.h: Update the message types, introducing a more
	structured job message set and replacing the UPSTART_EVENT_JOB_STATUS
	message with UPSTART_EVENT_CAUSED which will be immediately followed
	by an ordinary UPSTART_JOB_STATUS message.
	* upstart/message.c (upstart_message_new, upstart_message_handle):
	Marshal the new messages.
	* upstart/tests/test_message.c (test_new, my_handler) 
	(test_handle): Test the new message types.
	* TODO: Update.

2007-03-03  Scott James Remnant  <scott@netsplit.com>

	* TODO: Update.

	* init/cfgfile.c (cfg_parse_exec, cfg_parse_script): Separate out
	the parsing of an exec or script stanza into separate functions,
	seeing as this is quite a common operation.  This also means we
	just need to change them in one place now.
	(cfg_parse_process): Function to call either of the above depending
	on the next argument.
	(cfg_stanza_exec): Call cfg_parse_exec instead.
	(cfg_stanza_script): Call cfg_parse_script instead.
	(cfg_stanza_pre_start, cfg_stanza_post_start) 
	(cfg_stanza_pre_stop, cfg_stanza_post_stop): Call cfg_parse_process
	with the right arguments instead of doing by hand in each function.

	* init/event.c (event_emit_next_id): Split the id assigning code into
	a static inline function for easier modification.
	* init/job.c (job_next_id): Use the same style function here too.

2007-03-02  Scott James Remnant  <scott@netsplit.com>

	* init/event.c (event_emit): Port the slightly more efficient in the
	early case code from job_new.

	* init/job.h (Job): Add a unique id to the job structure.
	* init/job.c (job_new): Assign an incrementing id to each new job
	allocated.
	(job_find_by_id): Locate a job by its unique id, sadly not very
	efficient in a hash table ;-)
	(job_name): New hash key function since name isn't the first entry
	anymore.
	(job_init): Change hash key function.
	* init/tests/test_job.c (test_find_by_id): Make sure we can find a
	job by its id.

	* init/job.c (job_change_goal): Return the new instance in that
	circumstance, and clean up a little bit.
	* init/job.h: Update prototype.
	* init/tests/test_job.c (test_change_goal): Update tests.

	* init/job.c (job_find_by_name): Skip jobs marked for deletion too.
	* init/tests/test_job.c (test_find_by_name): Update test case.

	* init/event.h, init/notify.h, upstart/message.h: Provide C-level names
	for enums, this makes the compiler generate things that gdb can get.

	* init/job.c (job_run_process, job_kill_process, job_kill_timer):
	Change process argument to be a plain ProcessType, this means we
	know exactly which process we're trying to run or kill.
	(job_change_state): Update calls to job_run_process
	and job_kill_process
	* init/tests/test_job.c (test_run_process, test_kill_process): Update
	function calls to just pass a ProcessType in.

	* upstart/enum.h: Rename JobAction to ProcessType.
	* upstart/enum.c (job_action_name): Rename to process_name.
	(job_action_from_name): Rename to process_from_name.
	* upstart/tests/test_enum.c (test_action_name, test_action_from_name):
	Rename and update to match.
	* init/job.c (job_new, job_copy, job_change_state) 
	(job_next_state): Change JOB_*_ACTION constants to PROCESS_*.
	(job_find_by_pid): Change JobAction argument to ProcessType.
	(job_emit_event): Call process_name on the failed process.
	(job_child_reaper): Update to use ProcessType instead of JobAction.
	* init/job.h (Job): Change type of failed_process to ProcessType.
	* init/tests/test_job.c (test_find_by_pid): Update to use ProcessType
	instead of JobAction in tests.
	(test_new, test_copy, test_change_goal, test_change_state) 
	(test_next_state, test_run_process, test_kill_process) 
	(test_child_reaper, test_handle_event_finished): Change JOB_*_ACTION
	constants to PROCESS_*
	* init/cfgfile.c (cfg_stanza_exec, cfg_stanza_script) 
	(cfg_stanza_pre_start, cfg_stanza_post_start) 
	(cfg_stanza_pre_stop, cfg_stanza_post_stop): Change JOB_*_ACTION
	constants to PROCESS_*
	* init/tests/test_cfgfile.c (test_stanza_exec) 
	(test_stanza_script, test_stanza_pre_start) 
	(test_stanza_post_start, test_stanza_pre_stop) 
	(test_stanza_post_stop, test_read_job, test_watch_dir): Change
	JOB_*_ACTION constants to PROCESS_*
	* init/tests/test_event.c (test_poll): Change JOB_*_ACTION constants
	to PROCESS_*
	* init/tests/test_control.c (test_job_start, test_job_stop): Change
	JOB_*_ACTION constants to PROCESS_*

	* init/cfgfile.c (cfg_watch_dir): Restore the prefix argument; pass
	as the data pointer to the inotify callbacks and visitor function.
	Change the return value to be the watch structure.
	(cfg_job_name): Add prefix argument and prepend to relative path.
	(cfg_create_modify_handler, cfg_delete_handler, cfg_visitor): Get
	the prefix for the job names from the data pointer and pass to
	cfg_job_name().
	* init/cfgfile.h: Update prototypes.
	* init/tests/test_cfgfile.c (test_watch_dir): Actually test the
	watch functions.
	* init/main.c (main): Pass NULL for the prefix for the global job
	directory, compare the return value against (void *)-1.
	* TODO: Update.

	* init/cfgfile.c (cfg_stanza_on): Drop the simple on stanza.
	* init/tests/test_cfgfile.c (test_stanza_on): Remove test case.

	* TODO: Update.

2007-03-01  Scott James Remnant  <scott@netsplit.com>

	* util/jobs.c (handle_job_status): Drop the process field from the
	output for now.
	* util/events.c (handle_event_job_status): Likewise
	* util/tests/test_jobs.c (test_start_action, test_list_action) 
	(test_jobs_action): Drop pid from messages we simulate.
	* util/tests/test_events.c (test_emit_action): Likewise.

	* upstart/message.c (upstart_message_new, upstart_message_handle):
	Remove the pid field from the job status and event job status
	messages.
	* upstart/message.h: Update description of job status and event
	job status message to remove the pid field.
	* upstart/tests/test_message.c (test_new, my_handler) 
	(test_handle): Remove checks using the pid field.

	* init/control.c (control_job_start, control_job_stop) 
	(control_job_query, control_job_list): Remove the pid field from
	the messages, it'll come back later when we get better message
	formats.
	* init/tests/test_control.c (check_job_status, check_job_waiting) 
	(check_job_started, check_job_stopped): Remove checks on the process
	id, since that field is gone from the message.
	(test_job_stop): Use the pid field of the main process.
	(test_job_start): Initialise the main action process.

	* init/notify.c (notify_job, notify_job_event): Remove the pid field
	from the message, it'll come back later when we get better message
	formats.
	* init/tests/test_notify.c (check_job_status) 
	(check_event_job_status): Remove checks on the pid, since that field
	is no longer present.

	* init/job.c (job_process_copy): Use job_process_new here, oops.

	* init/cfgfile.c (cfg_stanza_exec, cfg_stanza_script) 
	(cfg_stanza_pre_start, cfg_stanza_post_start) 
	(cfg_stanza_pre_stop, cfg_stanza_post_stop): Use job_process_new
	to allocate process structures and store in the process array.
	* init/tests/test_cfgfile.c (test_read_job, test_stanza_exec) 
	(test_stanza_script, test_stanza_pre_start) 
	(test_stanza_post_start, test_stanza_pre_stop) 
	(test_stanza_post_stop): Update test cases to use process array
	member information.

	* init/tests/test_event.c (test_poll): Update to use newer job process
	array and find the pid under there.

	* init/job.h (Job): Remove the pid and aux_pid fields; replace the
	individual JobProcess pointers with an array of them of a fixed
	minimum size; replace failed_state with failed_process.
	(JobProcess): add a pid field here, so now we can obtain the pid on
	an individual process/action basis rather than global.
	* init/job.c (job_process_new): Function to create a JobProcess
	structure, setting the initial values to FALSE/NULL/0.
	(job_process_copy): Function to copy a JobProcess.
	(job_new): Don't initialise the pid or aux_pid members, initialise
	the process array to a fixed initial size and set the members to NULL,
	initialise the failed_process member to -1.
	(job_copy): Update to use job_process_copy and copy the process array.
	(job_find_by_pid): Look through the process structures in the job's
	process array to find the pid, and optionally return which action it
	was.
	(job_change_state): Call job_kill_process in the JOB_KILLED state if
	we have a main process and that has a pid, pass in the main process.
	(job_next_state): Check the process id of the main process when
	deciding what the next state is for running.
	(job_run_process): Store the process id in the process structure
	(job_kill_process): Accept a process structure and use that to obtain
	the process id we need to send TERM too.  Remove the code that forced
	a state change if kill() failed, since we will get a child signal
	anyway and should do it there.
	(job_kill_timer): Likewise, accept a process structure and don't
	forcibly change the state anymore.
	(job_child_reaper): Rewrite to switch based on the action that died,
	rather than the state we were in; assert that the state is what we
	expected.
	(job_emit_event): The argument to the failed event is now the action
	name, rather than the state name; an action of -1 indicates that
	respawn failed.
	* init/tests/test_job.c (test_process_new, test_process_copy): Make
	sure the structure is created and copied properly.
	(test_new, test_copy): Drop checks on the pid and aux_pid members,
	add checks for the process array and pid members of processes.
	(test_find_by_pid): Update test case to make sure we can find the pid
	of any process, returning the action index rather than the process
	pointer.
	(test_run_process, test_kill_process, test_change_goal)
	(test_change_state, test_next_state, test_child_reaper): Update test
	cases to use pid fields inside process structures rather than the
	pid or aux_pid members.
	(test_handle_event, test_handle_event_finished) 
	(test_free_deleted): Update to avoid pid field checks.

	* upstart/enum.h (JobAction): Enumeration of different actions.
	* upstart/enum.c (job_action_name, job_action_from_name): Enumeration
	to string conversion functions.
	* upstart/tests/test_enum.c (test_action_name) 
	(test_action_from_name): Tests for the new functions.

	* init/cfgfile.c (cfg_read_job): Instead of trying to copy over an
	old job's state and instances into the new one, mark the old job
	as deleted.  This ensures we never end up applying a new post-stop
	script to a job started with an old pre-start script, etc.  It also
	makes life so much simpler.
	* init/tests/test_cfgfile.c (test_read_job): Update tests to make
	sure the old job is marked for deletion, instead of freed.
	* TODO: Update.

	* init/notify.c (notify_job): Split out notification to processes
	subscribed to the cause event into a new function
	(notify_job_event): We can call this when we change cause.
	* init/job.c (job_change_state): Notify anyone subscribed to the
	job after we've changed the state, rather than before, otherwise
	we won't know the new pids or anything.
	(job_change_cause): Call notify_job_event before changing the cause
	so that subscribers get a final status update.
	* init/tests/test_notify.c (test_job_event): Check the new function.
	* TODO: Update.

	* init/cfgfile.c (cfg_stanza_respawn): Remove the shortcut that
	lets you specify "respawn COMMAND".  It was confusing as it hid
	the common "[when] exec"/"[when] script" syntax, made it non-obvious
	that "exec" and "respawn" were the same flag, etc.
	* init/tests/test_cfgfile.c (test_stanza_respawn): Update tests.
	(test_stanza_service): Fix test case to not use shortcut.
	* logd/event.d/logd.in: Update to not use respawn shortcut.

2007-02-25  Scott James Remnant  <scott@netsplit.com>

	* init/job.c (job_child_reaper): Shift the signal value into the
	higher byte to make it easier to detect, and not stamp over exit
	statuses between 128 and 255.
	(job_emit_event): Detect the signal stored in the new way.
	* init/cfgfile.c (cfg_stanza_normal): Store signal in the higher bytes.
	* init/tests/test_job.c (test_copy, test_change_state) 
	(test_child_reaper): Update test cases.
	* init/tests/test_cfgfile.c (test_stanza_normal): Update test.

	* TODO: Update.

	* init/event.h (PWRSTATUS_EVENT): Add new power-status-changed event.
	* init/main.c (pwd_handler): Handle the SIGPWR signal by generating
	the new event, leave it up to a job to parse the file and do
	whatever it likes.

	* TODO: Update.

2007-02-13  Scott James Remnant  <scott@netsplit.com>

	* upstart/tests/test_message.c (test_reader, test_handle_using)
	(test_handle); Usual fix for gcc optimiser thinking that fixed
	for loops might not be.
	* init/tests/test_job.c (test_run_process, test_kill_process):
	Likewise.
	* init/tests/test_notify.c (test_subscription_find): I still don't
	know what a type-punned pointer is, nor why dereferencing such a
	thing would break strict-aliasing rules.
	* init/tests/test_cfgfile.c (test_read_job): More type-punning.
	* util/tests/test_jobs.c (test_start_action): More for-loop action.
	* util/tests/test_events.c (test_emit_action): And again.

2007-02-11  Scott James Remnant  <scott@netsplit.com>

	* init/job.c (job_change_goal): We need to be able to stop a running
	job without a process, because that's what a job-as-state is!  The
	check was added because job_child_reaper calls job_change_goal and
	then job_change_state immediately after, we should fix that instead.
	(job_child_reaper): If we call job_change_goal while in the running
	state, it will call job_change_state for us; so check for that first
	and don't change the state!
	* init/tests/test_job.c (test_change_goal): Update the test to ensure
	that we can stop a job with no running process.

	* init/cfgfile.c (cfg_stanza_normalexit): normalexit is inconsistent,
	change to "normal exit"
	* init/tests/test_cfgfile.c (test_stanza_normalexit): Update.

	* init/cfgfile.c (cfg_stanza_start, cfg_stanza_stop) 
	(cfg_stanza_pre_start, cfg_stanza_post_start) 
	(cfg_stanza_pre_stop, cfg_stanza_post_stop, cfg_stanza_respawn):
	We're not going to allow stanza keywords to be quoted, since this
	gives us an easy way to allow users to make something explicitly
	not a keyword.

2007-02-10  Scott James Remnant  <scott@netsplit.com>

	* configure.ac: Bump version to 0.3.6

	* configure.ac: Increase version to 0.3.5
	* NEWS: Update.
	* TODO: Update.

	* TODO: More notes.

	* TODO: Note an issue with using JobProcess->pid

	* init/cfgfile.c (cfg_stanza_pre_start, cfg_stanza_post_start) 
	(cfg_stanza_pre_stop, cfg_stanza_post_stop): Add a needed check
	for a token when parsing "exec".  Correct line number we expect
	to see the duplicated value on.  Correct expected error for missing
	argument from "Unexpected token" to "Expected token".

	* init/tests/test_cfgfile.c (main): Actually invoke the tests for
	the scripts.

	* init/cfgfile.c (cfg_read_job): Correct type of lineno in error.

	* TOOD: Minor notify bug

	* TODO: Big update.

	* init/tests/test_job.c (test_child_reaper): Make sure that we can
	reap post-start and pre-stop processes, and have only the aux_pid
	changed.  Also make sure that if the running process dies while
	in these states, with or without an aux process, that we don't
	transition badly.

	* init/job.c (job_find_by_pid): Check aux_pid as well.
	* init/tests/test_job.c (test_find_by_pid): Make sure we can find it.

	* init/job.h (Job): Add an auxiliary pid member.
	* init/job.c (job_new): Initialise the aux_pid member.
	(job_change_state): Run the post-start and pre-stop scripts when we
	enter the state with the same name (assuming they exist).
	(job_run_process): Store the pid in aux_pid when starting the
	post-start or pre-stop processes.
	* init/tests/test_job.c (test_change_state): Add tests for running
	the new post-start and pre-stop scripts; which get their process ids
	stored in aux_pid instead of pid.
	(test_new): Make sure the aux_pid member is initialised properly.
	(test_copy): Make sure the aux_pid member is not copied.

	* TODO: Update.

	* init/tests/test_job.c (test_change_state): Add a check for the
	daemon stanza holding the job in spawned; we snuck this in a while
	back and never tested it (there's no support to get it out of
	spawned yet).

	* init/job.h (Job): Add new post_start and pre_stop scripts.
	* init/job.c (job_new): Initialise new scripts to NULL.
	(job_copy): Copy the information from the new scripts over as well.
	* init/tests/test_job.c (test_new): Check they're initialised.
	(test_copy): Check that the information is copied properly.
	* init/cfgfile.c (cfg_stanza_post_start, cfg_stanza_pre_stop): Add
	new script stanza functions for the additional two scripts that
	we want.
	* init/tests/test_cfgfile.c (test_stanza_post_start) 
	(test_stanza_pre_stop): Add tests for the new stanzas.

	* init/cfgfile.c (cfg_stanza_exec, cfg_stanza_script): Rewrite to
	allocate a JobProcess and parse the command or script into it.
	(cfg_read_job): Fix the long broken assumption that pid_file and
	pid_binary are required for respawn, when they're actually required
	for daemon.
	(cfg_stanza_start, cfg_stanza_stop): Remove script second-level.
	(cfg_stanza_respawn): Parse into the job's process.
	(cfg_stanza_pre_start, cfg_stanza_post_stop): New stanzas for the
	processes alone.
	* init/tests/test_cfgfile.c (test_read_job): Update a few test
	cases to match reality.
	(test_stanza_start, test_stanza_stop): Remove script-related checks.

2007-02-09  Scott James Remnant  <scott@netsplit.com>

	* init/tests/test_job.c (test_kill_process): Poll the event queue
	after each test to get rid of the allocated events and make valgrind
	happy.
	* init/tests/test_control.c (test_job_start, test_job_stop)
	(test_event_emit): Poll the event queue after each test to get rid
	of the allocated events, as they make valgrind complain.
	(test_event_emit): Free args and env when done.

	* init/job.h (JobName): Drop obsolete structure
	(JobProcess): Add a new structure to represent a single process
	within the job, instead of using two variables to pick either the
	script or command.
	(Job): Change command and script to a single JobProcess called process;
	change start_script and stop_script to a JobProcess called pre_start
	and post_stop respectively.
	* init/job.c (job_new): Initialise new members to NULL.
	(job_copy): Copy the process structures across, including contents.
	(job_change_state): Call job_run_process passing in the structure;
	rather than fiddling with if statements.
	(job_run_script, job_run_command, job_run_process): Combine all of
	these three functions into a single new job_run_process function.
	* init/tests/test_job.c (test_new, test_copy, test_change_goal) 
	(test_change_state, test_child_reaper) 
	(test_handle_event_finished): Change to using JobProcess for when
	we need to construct a command.
	(test_run_script, test_run_command): Merge into single new
	(test_run_process) function.
	* init/tests/test_event.c (test_poll): Replace command with process.
	* init/tests/test_control.c (test_job_start): Change to using
	JobProcess to specify the command.

	* init/main.c (main): Run job_free_deleted each time through the
	main loop.

	* init/job.c (job_change_goal): Minor tweak to the logic; we may
	have just made the job an instance, that should still let us stop
	the one underneath.

	* TODO: Update.

	* util/jobs.c (do_job): Always expect a list of replies.

	* init/control.c (control_job_status, control_job_stop)
	(control_job_query): Reply with information about all instances of
	the job.
	* init/tests/test_control.c (test_job_status, test_job_stop)
	(test_job_query): Make sure we get the list end even for a single job;
	and make sure we get details of all instances attached to the job.

	* init/tests/test_job.c (test_change_goal): Check that starting
	an instance job actually starts a new instance of it.

	* init/cfgfile.c (cfg_stanza_limit): Support the word "unlimited" in
	limit arguments for both the soft and hard values.
	* init/tests/test_cfgfile.c (test_stanza_limit): Make sure that we
	can make limits be unlimited.

	* init/event.c (event_copy): Function to copy an event structure.
	* init/event.h: Add prototype.
	* init/tests/test_event.c (test_copy): Make sure we copy the event
	correctly, with or without arguments and/or environment.
	* init/job.c (job_copy): Function to copy a job structure, leaving
	the state as it is.
	* init/job.h: Add prototype.
	* init/tests/test_job.c (test_copy): Make sure that we copy the
	job details whether they are NULL or non-NULL, but don't copy the
	state.
	* init/init.supp: Update supression.
	* init/job.c (job_find_by_name): If we get a job that's an instance,
	return what it's an instance of.
	* init/tests/test_job.c (test_find_by_name): Restore accidentally
	deleted test function; test that we get the real job, not an instance.

	* init/job.c (job_new): instance_of is initialised to NULL.
	* init/job.h: Add a new instance_of pointer, pointing to the parent
	that we're an instance of.
	* init/tests/test_job.c (test_new): Check that.
	* init/tests/test_cfgfile.c (test_read_job): Make sure instance_of
	pointers are updated.

	* init/job.c (jobs): Store jobs in a hash table.
	(job_new): Add to hash table, not to a list.
	(job_handle_event, job_handle_event_finished, job_detect_stalled) 
	(job_free_deleted): Iterate across the hash table, rather than list.
	(job_find_by_name): Use nih_hash_lookup, we keep this function because
	we'll add "is instance or not" smarts soon!
	(job_find_by_pid): Iterate across the entire hash table.
	* init/tests/test_job.c (test_find_by_name): Drop test since this
	function is now gone.
	(test_free_deleted): Can't assume things are in a line now.
	* init/control.c (control_job_list): Iterate the hash table.

	* init/event.c: Don't hide the events list anymore
	* init/event.h: Publish it and the init function.
	* init/job.c: Don't hide the jobs list anymore.
	(job_list): Since we don't hide it, we can drop this.
	* init/job.h: Publish it and the init function.
	* init/notify.c: Don't hide the subscriptions list anymore.
	* init/notify.h: Publish it and the init function.
	* init/control.c (control_job_list): Iterate the job list directly
	* init/tests/test_control.c (test_event_emit): Use the events list
	available to us.
	* init/tests/test_event.c (test_poll): Call job_init directly and
	just use the events list available to us.
	* init/tests/test_job.c (test_new): Call job_init directly.
	(test_change_state): Use the events list available to us.
	* init/tests/test_notify.c (test_unsubscribe): Use the subscriptions
	list available to us.

	* doc/states.dot: Add updated state graph.
	* doc/Makefile.am (EXTRA_DIST): Ship the states diagram.
	(states.png): Include rules to build the png, we'll put it in bzr
	anyway, but this is useful.

	* init/cfgfile.c (cfg_delete_handler): Handle deleted jobs; mark
	the job as deleted, and if it's dormant, invoke a state change.

	* upstart/enum.h: Add a new JOB_DELETED state.
	* upstart/enum.c (job_state_name, job_state_from_name): Add the new
	state to the string functions.
	* upstart/tests/test_enum.c (test_state_name) 
	(test_state_from_name): Check the enum works.
	* init/job.c (job_change_goal): New decision; we can start a waiting
	job if it's marked delete (it might be a new instance) -- we'll use
	the new deleted state to decide that we shouldn't.
	(job_change_state): Once we reach waiting, if the job is to be deleted,
	move to the next state.
	(job_next_state): The next state for a waiting job if the goal is stop
	is deleted.  We should never call job_next_state () for a deleted job.
	(job_free_deleted): Very simple function, just detects
	deleted jobs and frees them.
	* init/job.h: Add prototype for new function.
	* init/tests/test_job.c (test_change_goal): Update test to use new
	deleted state; and don't even change the goal.
	(test_change_state): Add a check to make sure we end up in deleted.
	(test_next_state): Make sure waiting goes to deleted.
	(test_free_deleted): Check the function.

	* init/job.c (job_change_goal): Don't try and start a job if it's
	marked to be deleted and is just waiting for cleanup.
	* init/tests/test_job.c (test_change_state): Make sure that the cause
	is released when we reach waiting.

	* init/tests/test_cfgfile.c (test_read_job): Make sure that a deleted
	job gets resurrected.

	* init/cfgfile.c (cfg_visitor): Correct number of arguments and call
	to cfg_job_name.

	* TODO: Update.

	* init/cfgfile.c (cfg_stanza_daemon): Don't allow arguments anymore.
	* init/tests/test_cfgfile.c (test_stanza_daemon): Update tests.

	* init/job.c (job_handle_event_finished): Function to unblock all
	jobs blocked on a given event emission.
	(job_new, job_emit_event): Rename blocker to blocked; it's useful for
	testing for truth.
	* init/job.h: Add prototype, rename member.
	* init/tests/test_job.c (test_handle_event_finished): Test it.
	(test_new, test_change_state): Update name here too.
	* init/event.c (event_finished): Call job_handle_event_finished
	function to unblock jobs.
	* init/tests/test_event.c (test_poll): Make sure the job gets
	unblocked; a few other tests have to change since running event_poll
	always unblocks the job if nothing listens to it.

	* init/job.c (job_child_reaper): Set failed back to FALSE if
	we're respawning, since we don't want to be failing.
	* init/tests/test_job.c (test_child_reaper): cause will be NULL.
	also free and poll events when done.
	(test_handle_event): pid can never be -1
	(test_change_state): poll events when done

	* init/tests/test_job.c (test_child_reaper): Process will always
	be zero on return from reaper.

	* init/tests/test_job.c (test_child_reaper): Killed doesn't go past
	stopping; it goes to waiting, which will clear the cause.

	* init/tests/test_job.c (test_child_reaper): Fill in values before
	we test against them.

	* init/tests/test_job.c (test_kill_process): Fix violated assertion

	* init/tests/test_job.c (test_change_state): This should be failed
	because nothing cleared it.

	* init/tests/test_job.c (test_change_state): Fix a couple of array
	index problems.

	* init/tests/test_job.c (test_change_state): Why set that which
	does not change?

	* init/tests/test_job.c (test_change_state): Add newline to test.

	* init/job.c (job_emit_event): Add the job name as an argument;
	oops.

	* init/tests/test_control.c (test_job_stop): Need to kill the process
	ourselves, as we're blocked on an event.
	(test_job_query): Fix wrong value in test.
	(check_job_stopped, test_job_stop, test_unwatch_jobs): Change job
	name to match the test.

	* init/job.c (job_change_state): Must only not enter some states
	with no process now; others like killed actually usually want one!

	* init/tests/test_cfgfile.c (test_read_job): Fix test case.

	* init/tests/test_job.c (test_handle_event): Clean up tests.
	(test_detect_stalled): Clean up.

	* init/job.c (job_child_reaper): Update the reaping of the child
	processes; there's a much larger state range for the main process
	now, so that needs to be taken into account.
	* init/tests/test_job.c (test_child_reaper): New test cases.

	* init/job.c (job_next_state): Encapsulate the slightly odd three
	exit states of running in this function, otherwise we'll end up
	special-casing it in places I'd rather not think about.
	(job_change_goal): Only change the state of a running job if it
	has a process.
	* init/tests/test_job.c (test_next_state): Add a test case for the
	dead running job
	(test_change_goal): Add test case for the dead running job

	* init/tests/test_job.c (test_change_state): Add test cases for
	the forgotten stopping to killed transition.

	* init/job.c (job_kill_process, job_kill_timer): Just check the pid
	and state, and no longer any need to notify jobs since we're just
	called from one state amongst many.
	(job_change_state): Skip over the killed state if there's no process.
	* init/tests/test_job.c (test_kill_process): Update test cases.

	* init/job.c (job_run_process): Simplify a little bit, no need to
	do the state assertions here, just make sure there's no already
	a process running.
	* init/tests/test_job.c (test_run_command, test_run_script): Run
	tests in the spawned state, since that's where we run the primary
	command or script.  Drop check for process state since that's no
	longer set.

	* init/job.c (job_change_state, job_next_state): Ok, here's the big
	one ... rewrite this to use the new state transitions.  This has
	suddenly got a lot simpler and easier to read, this was definitely a
	good idea.
	(job_emit_event): Function to make emission of events easier.
	(job_failed_event): replaces this one which wasn't so easy.
	* init/tests/test_job.c (test_change_state): I can't say how much I
	wasn't looking forwards to rewriting these test cases; anyway, it's
	done now and I hope they're all right;
	(test_next_state): Make sure the state transitions are correct too.

	* init/job.h: Rename is_instance to delete and spawns_instance to
	just instance.
	* init/job.c (job_new): Update.
	* init/tests/test_job.c (test_new): Update.
	* init/cfgfile.c (cfg_stanza_instance): Update.
	* init/tests/test_cfgfile.c (test_stanza_instance): Update.

	* init/event.h: Correct the event names.

	* init/job.h: Add blocker event member.
	* init/job.c (job_new): Initialise it to NULL.
	* init/tests/test_job.c (test_new): Check it.

	* init/job.c (job_change_goal): Have a stab at this function with the
	new state machine; it gets somewhat simpler (until we introduce the
	second scripts), now we just induce things by a state change.
	* init/tests/test_job.c (test_change_goal): Made easier (for now)
	because we don't need to deal with processes and can just wait to
	be blocked on an event.

2007-02-08  Scott James Remnant  <scott@netsplit.com>

	* init/cfgfile.c (cfg_read_job): Drop check for useless respawn script
	(cfg_stanza_respawn): Drop handling of "respawn script"
	* init/tests/test_cfgfile.c (test_stanza_respawn): Drop the checks
	for "respawn script"

	* init/job.h: Move things about a bit more; remove respawn_script
	since that state is going away.
	* init/job.c (job_new): Drop initialisation of process_state.
	* init/tests/test_job.c (test_new): Improve the tests.

	* init/main.c (STATE_FD): Remove this define, not used anymore.

	* init/tests/test_event.c (test_poll): Update the event checking
	to match what's likely to happen.

	* init/event.h: Remove commented out bit.

	* init/tests/test_notify.c (check_job_status, test_job): Correct
	state usage to match a possible state.

	* init/control.c (control_job_start, control_job_stop) 
	(control_job_query, control_job_list): Drop process state and
	description from the job status messages we send back.
	* init/tests/test_control.c (test_error_handler) 
	(check_job_started, test_job_start, check_job_stopped) 
	(check_job_stopping, test_job_query, check_job_starting) 
	(test_job_list, test_watch_jobs, test_unwatch_jobs): Remove
	process_state and description, and update usage of job states.

	* init/notify.c (notify_job): Don't include process state or
	description in the job status message anymore.
	* init/tests/test_notify.c (check_job_status, test_job): Update tests

	* init/cfgfile.c (cfg_read_job): Drop the copying of the process_state
	member, since it doesn't exist anymore.
	* init/tests/test_cfgfile.c (test_read_job): Drop the check too.

	* init/job.h (Job): Drop the process_state member.

	* util/jobs.c (handle_job_status): Drop the process_state and
	description arguments; output a process id only if it's greater
	than zero.
	* util/tests/test_jobs.c (test_start_action, test_list_action) 
	(test_jobs_action): Update tests to use newer states and arguments.
	* util/events.c (handle_event_job_status): Simplify in the same way

	* upstart/message.h: Remove process_state and description from the
	job status event (we already had the foresight to not put them in
	the event job status event).
	* upstart/message.c (upstart_message_new, upstart_message_handle):
	Update handling of the messages to reduce the arguments.
	* upstart/tests/test_message.c (test_new, my_handler) 
	(test_handle): Update the tests for the new job status message.

	* upstart/enum.h (JobState): Change the job states to the new set
	of states that we've planned.
	(ProcessState): Drop process state entirely; this information is now
	contained in the single JobState field.
	* upstart/enum.c (job_state_name, job_state_from_name): Update
	strings to match the new state names.
	(process_state_name, process_state_from_name): Drop these functions.
	* upstart/tests/test_enum.c (test_state_name) 
	(test_state_from_name): Update test cases to match new names.
	(test_process_state_name, test_process_state_from_name): Drop.

	* init/main.c (main): Remove the logd hack for now.
	* init/job.c (job_new): Change the default console to none for now.
	* init/tests/test_job.c (test_new): Update test.
	* init/cfgfile.c (cfg_stanza_console): Can't guard against duplicates
	for a while.
	* init/tests/test_cfgfile.c (test_stanza_console): Comment out dup test

	* init/cfgfile.c (cfg_read_job): Remove the restriction that there
	must be either an 'exec' or 'script' for a job; jobs without either
	define states others can use.
	* init/tests/test_cfgfile.c (test_read_job): Convert the test to
	a "must work".
	* init/job.c (job_change_state): Remove restriction that we must
	have either a script or a command; having neither should just wedge
	the job at the running rest state.  Note that there's no way to get
	it out yet, because we don't force that particular state change.
	* init/tests/test_job.c (test_change_state): Make sure that works.

	* init/job.c (job_change_cause): Put the knowledge about how to
	change the cause into a separate function, since it's slightly
	tricky.
	(job_change_goal, job_change_state): Set the cause using the above
	function.

	* init/job.h (Job): Rename goal_event to cause, also shuffle things
	around so that the state is mostly together.
	* init/job.c, init/process.c, init/notify.c, init/cfgfile.c: Update
	references (and comments) to match the new name.
	* init/tests/test_job.c, init/tests/test_event.c,
	init/tests/test_process.c, init/tests/test_cfgfile.c,
	init/tests/test_notify.c: Likewise.

	* init/job.c (job_child_reaper): Don't change the goal event; the
	state changes will handle this.
	(job_change_goal): Only dereference/reference the goal event if we're
	actually changing it.
	* init/tests/test_job.c (test_change_state, test_child_reaper):
	Update tests to not assume that the goal event gets changed.
	(test_kill_process): Eliminate race condition.

	* init/job.c (job_child_reaper): Correct some problems with job and
	event failure; we now don't overwrite an existing failure record,
	and don't record failure if the main process failed and the goal was
	stop; since we likely caused it.
	* init/tests/test_job.c (test_child_reaper): More test cases.

	* logd/event.d/logd.in: Stop on the new runlevel events, not the
	shutdown event.

	* compat/sysv/shutdown.c (shutdown_now): Emit an ordinary runlevel
	change event now; including the INIT_HALT environment variable
	* compat/sysv/man/shutdown.8: Update the manual

	* compat/sysv/telinit.c: Now just sends out a runlevel event with
	an argument giving the new runlevel.
	* compat/sysv/man/telinit.8: Update description of the command.

	* upstart/message.h: Remove the UPSTART_SHUTDOWN message.
	* upstart/message.c (upstart_message_new, upstart_message_handle):
	Remove handling for the shutdown message.
	* upstart/tests/test_message.c (test_new, test_handle): Remove
	tests against the shutdown message.
	* init/control.c (control_shutdown): Remove the shutdown command
	from the server.
	* init/tests/test_control.c (test_shutdown): Remove tests for it.
	* init/event.h: Remove the shutdown event.
	* util/initctl.c: Remove the shutdown command reference.
	* util/events.c (shutdown_action): Remove the command.
	* util/events.h: Update.
	* util/tests/test_events.c (test_shutdown_action): Remove tests.

	* init/job.c (job_detect_idle): Rename to job_detect_stalled
	(job_detect_stalled): Remove the idle state detection
	(job_set_idle_event): Idle event has been removed.
	* init/job.h: Update.
	* init/tests/test_job.c (test_detect_idle): Rename to
	(test_detect_stalled): and remove idle detection tests.
	* init/main.c (main): Replace job_detect_idle with job_detect_stalled
	* init/control.c (control_shutdown): Don't set the idle event.
	* init/tests/test_control.c (test_shutdown): Don't detect the idle
	event (and thus the second event)

	* init/cfgfile.c (cfg_stanza_service): Parser for service stanza.
	* init/tests/test_cfgfile.c (test_stanza_service): Test the service
	stanza.
	(test_stanza_respawn): Check that respawn implies service.
	* TODO: Update.

	* init/job.h (Job): Add a new service member.
	* init/job.c (job_new): Service starts off as false.
	(job_change_state): Check service instead of respawn.
	* init/tests/test_job.c (test_change_state): Check with service
	instead of respawn, since that's what we really mean.

	* init/cfgfile.c (cfg_read_job): Copy a whole bunch more state
	into the newly parsed job.
	* init/job.c (job_run_process): Only output the first error.
	* init/tests/test_cfgfile.c (test_read_job): Make sure important
	things are copied.
	* TODO: Update.

	* init/main.c: Restore a much simplified version of the term
	handler that doesn't try and copy across any state.

	* compat/sysv/telinit.c: Update call to event_emit; we'll revisit
	this shortly when we get rid of the shutdown event.

	* util/events.c (handle_event): Add new id field (but ignore it)
	Functio
	(handle_event_job_status): New function to handle the new event.
	(handle_event_finished): Function to handle the end of the event.
	(emit_action): Send the newer event, and loop over replies until
	we get a finished one.
	* util/tests/test_events.c (test_emit_action): Update tests cases.

	* init/control.c (control_event_emit): New function to handle the
	new-style emit message.
	* init/tests/test_control.c (test_event_emit): Make sure the new
	message function behaves.

	* init/event.c, init/job.c, init/main.c, init/tests/test_event.c,
	init/tests/test_job.c: Completely drop the serialisation code, it's
	getting out of date and in the way.

	* init/event.h: Remove compatibility macros.
	(EventEmission): Drop the callback function; it was too error prone
	to try and do it this way, and we only ever wanted to release a job
	anyway as control requests are better handled through the notify
	interface.
	(EventEmissionCb): Drop unused typedef.
	* init/event.c (event_emit): Drop callback argument.
	(event_finished): Don't call the callback
	* init/tests/test_event.c: Update to avoid callbacks.
	* init/job.c (job_change_state): Convert to using event_emit and
	EventEmission.
	(job_detect_idle): Drop extra arguments to event_emit.
	* init/main.c (main, cad_handler, kbd_handler): Drop extra arguments
	to event_emit.
	* init/control.c (control_shutdown): Use event_emit instead of
	event_queue.
	* init/tests/test_control.c (test_shutdown): Convert to using
	EventEmission.
	(test_watch_events, test_unwatch_events): Drop extra arguments to
	event_emit.
	* init/tests/test_notify.c (test_subscribe_event, test_job) 
	(test_event, test_event_finished): Drop extra arguments to event_emit
	* init/tests/test_job.c (test_change_goal, test_change_state) 
	(test_run_script, test_child_reaper, test_detect_idle): Drop
	extra arguments to event_emit.
	* init/tests/test_process.c (test_spawn): Drop extra arguments to
	event_emit.

	* TODO: Update.

	Rewrite the notification subsystem quite significantly; now we
	have individual functions to subscribe to different types of
	notification, and can even subscribe to individual jobs or events.

	* init/notify.c (notify_subscribe_job, notify_subscribe_event) 
	(notify_unsubscribe): New subscription and unsubscription functions
	that assume one record per subscription, not process.
	(notify_subscription_find): Function to find a subscription.
	(notify_job): Send a message to anything subscribed to the goal event
	as well.
	(notify_event): Use EventEmission and include the id in the event.
	(notify_event_finished): New function, sends a finished message and
	includes both the id and whether the event failed.
	* init/notify.h (NotifySubscribe): New notify structure that is
	once per subscription, rather than per-process; and allows
	subscription to individual jobs or events.
	* init/tests/test_notify.c (test_subscribe_job) 
	(test_subscribe_event, test_unsubscribe): Test the new subscription
	functions, replacing the old
	(test_subscribe): tests.
	(test_subscription_find): Check finding works
	(check_event, test_event): Update to use emissions, and check that the
	id is correct.
	(test_event_finished): Check this one works too
	(check_event_job_status, test_job): Make sure processes subscribed
	via the goal event are notified too.
	* init/event.c (event_pending): Pass the emission directly.
	(event_finished): Notify subscribers that the event has finished.
	* init/control.c (control_error_handler): Call notify_unsubscribe
	(control_watch_jobs, control_unwatch_jobs, control_watch_events) 
	(control_unwatch_events): Update to the new subscription API.
	* init/tests/test_control.c (test_error_handler): Use new API
	(test_watch_jobs, test_unwatch_jobs, test_watch_events)
	(test_unwatch_events): Also update these to the new API; use a
	destructor to make sure the subscription is freed.

	* init/tests/test_process.c: Don't use printf, use TEST_FUNCTION

2007-02-07  Scott James Remnant  <scott@netsplit.com>

	* upstart/message.h: Allocate new grouped event messages.
	* upstart/message.c (upstart_message_new, upstart_message_handle):
	Add support for the new grouped event messages.
	* upstart/tests/test_message.c (test_new, test_handle) 
	(my_handler): Make sure the new messages are passed correctly.

	* init/job.c (job_change_state): Clear the goal event whenever we
	reach the final rest state of a job (waiting for all jobs, running
	for services).
	* init/tests/test_job.c (test_change_state): Check that the goal
	event goes away at the right times.
	* TODO: Update.

	* init/tests/test_job.c (test_child_reaper): Make sure that the
	event is marked failed properly

	* init/job.c (job_start_event, job_stop_event): There's no reason
	for these to exist as seperate functions anymore, especially since
	we want to eventually have some kind of match table.
	(job_handle_event): Perform the iterations and match calls here
	instead, since we just call job_change_goal now.
	* init/job.h: Remove prototypes.
	* init/tests/test_job.c (test_start_event, test_stop_event): Fold into
	(test_handle_event): which now handles all the cases.

	* init/job.c (job_detect_idle): Call event_emit
	* init/main.c (main, cad_handler, kbd_handler): Call event_emit
	instead of event_queue.
	* init/tests/test_event.c (test_new): Call event_poll
	* init/tests/test_job.c (test_change_state, test_child_reaper) 
	(test_detect_idle, test_change_state): Update to use newer event API.
	* TODO: Update.

	* init/job.c (job_start, job_stop): Drop these functions; call
	job_change_goal instead (which is now public).
	(job_change_state, job_child_reaper): Call job_change_goal instead.
	* init/job.h: Update.
	* init/tests/test_job.c (test_start, test_stop): Merge into new
	(test_change_goal): function.
	* init/main.c (main): Call job_change_goal instead of job_start.
	* init/control.c (control_job_start, control_job_stop): Call
	job_change_goal instead.

	* init/tests/test_job.c (test_new, test_change_state) 
	(test_run_script, test_start, test_stop, test_start_event): 

	* init/job.h (Job): goal_event is now an EventEmission, and is
	a direct pointer to the one in the events queue, rather than a copy.
	* init/process.c (process_setup_environment): Reference the event
	name and environment through the goal event, not directly.
	* init/job.c (job_run_script): Reference the event name and
	environment through the goal event, not directly.
	(job_change_state, job_child_reaper): Replace direct setting of the
	job goal with a call to job_stop; the process state is always
	PROCESS_NONE in all three cases, so this is completely safe.
	(_job_start, _job_stop): Merge these two functions together into
	(job_change_goal): which behaves a lot more like job_change_state,
	except that it doesn't loop.  This handles the changing of the
	emission.
	(job_start, job_start_event, job_stop, job_stop_event): Simplify
	these functions, now they just call job_change_goal passing in
	the emission pointer (or NULL).

	* init/main.c, init/job.c, init/job.h, init/event.c, init/event.h,
	init/tests/test_job.c, init/tests/test_event.c: Remove state
	serialisation code for the time being; maintaining it is getting
	increasingly harder, and it introduces some major bugs.  It will
	get rewritten shortly.

	* init/event.c (event_pending): Pass the emission directly to
	job_handle_event now.
	* init/job.c (job_handle_event, job_start_event, job_stop_event):
	Deal with event emissions rather than just plain events, the change
	so far doesn't do anything else other than take the structure change.
	* init/job.h: Change prototypes.
	* init/tests/test_job.c (test_start_event, test_stop_event)
	(test_handle_event): Update tests to use emissions.

	* init/tests/test_event.c (test_read_state, test_write_state): Check
	the passing of the progress information.
	* init/event.c (event_read_state, event_write_state): Add progress
	field to the serialisation (oops).

	* init/event.h: Add missing attribute for event_read_state.
	* init/cfgfile.h: Add missing attributes.
	* init/main.c (read_state): Don't discard return value.
	* TODO: Update.

	* init/main.c (read_state): Handle the Emission keyword; also handle
	Event really being an EventEmission.
	* init/event.c (event_emit): Make the next emission id a static global
	(event_read_state, event_write_state): Serialise event emission
	structures, not plain events; also send over the last id we used so
	it appears seamless.  This doesn't yet handle the callback/data bit
	of the serialisation, which turns out to be a little tricky ... oops
	* init/event.h: Update.
	* init/tests/test_event.c (test_read_state, test_write_state): Check
	that serialisation is done with EventEmissions instead, and all the
	fields are passed (except callback and data which are ... tricky).

	* init/main.c (main): Call event_poll instead of event_queue_run.

	* init/event.c (event_poll): Add the new function that replaces
	event_queue_run(); handles the new-style event emission structures
	in the list and only returns when there are no non-handling events.
	(event_pending, event_finished): Handling of particular event states
	during poll; split out for readability.
	(event_queue, event_queue_run): Drop these obsolete functions.
	(event_read_state): Force type from event_queue.
	* init/event.h: Add event_poll prototype; remove prototypes of old
	functions, replacing with #defines for now so things still compile.
	* init/tests/test_event.c (test_queue): Drop tests.
	(test_read_state, test_write_state): Force type from event_queue
	Change type we check size of.
	(test_poll): Pretty thoroughly test the new poll function.
	* init/job.c (job_change_state): Force type from event_queue
	* init/control.c (control_event_queue): Force type from event queue
	* init/tests/test_job.c (test_detect_idle): Force type from event_queue
	* init/tests/test_control.c (test_event_queue, test_shutdown):
	Force type from event_queue

	* init/event.c: Revert to a single list of events with an enum
	(event_emit): Set the progress to pending initially.
	(event_emit_find_by_id): Simplify now it just checks one list
	(event_emit_finished): Function for jobs to call once they've done
	with an event; just sets the progress to finished for the event
	queue to pick up.
	* init/tests/test_event.c (test_emit_finished): Check it.

	* init/event.h: Add prototype.
	(EventProgress): Add new enum	
	(EventEmission): And add progress member to this structure
	* init/tests/test_event.c (test_emit): Make sure the event is pending

	* init/event.c (event_emit_find_by_id): Locate an event emission
	by its id in either the pending or handling queue.
	* init/event.h: Add prototype
	* init/tests/test_event.c (test_emit): Make sure that the emission
	id is unique each time.
	(test_emit_find_by_id): Test the function.

	* init/event.c (event_emit): New function to replace event_queue();
	returns an EventEmission structure with the details filled in as
	given.
	* init/event.h: Add prototype.

	* init/event.c (event_init): Rename the single events queue to
	pending and add a new handling list.

	* init/event.h (EventEmission, EventEmissionCb): Add a new emission
	structure that wraps an event, for use in the queue.

	* util/tests/test_events.c (test_events_action): Update test now
	that nih_message is more sensible.
	* util/tests/test_jobs.c (test_start_action, test_list_action) 
	(test_jobs_action): Update test

	* util/events.c (emit_action): Actually pass the emit_env array
	* util/tests/test_events.c (test_emit_action): Make sure it does.

	* util/initctl.c (main): Catch nih_command_parser() returning a
	negative value to indicate an internal error, and always exit 1.

	* util/events.c (handle_event): Build up multiple lines to describe
	the event, including its arguments and environment.
	* util/tests/test_events.c (test_events_action): Check the new output
	format is right.

	* init/main.c (main): Take out inadvertantly leaked debugging code;
	sorry about that.

	* init/job.c (job_child_reaper): Rewrite this to make the logic a
	little easier to follow, and support signals in normalexit.  This
	also now applies to deciding whether the job failed, if it did, we
	store that information in the job so the stop and stopped events
	can get it.
	* init/tests/test_job.c (test_child_reaper): Add new test cases for
	the setting of the failed flags.

	* init/cfgfile.c (cfg_stanza_normalexit): Allow signal names in the
	arguments, which are added to the normalexit array or'd with 0x80
	* init/tests/test_cfgfile.c (test_stanza_normalexit): Check that we
	can now parse signal names correctly.

	* init/job.c (job_failed_event): Change add to addp to fix leak.

	* init/job.c (job_failed_event): Function to turn an event into one
	that includes all the necessary arguments and environment.
	(job_change_state): Call job_failed_event for the stop and stopped
	events (bit hacky at the moment, will improve later).
	* init/tests/test_job.c (test_change_state): Check that the failed
	events are generated properly.

2007-02-06  Scott James Remnant  <scott@netsplit.com>

	* init/job.c (job_change_state): Reset the failed member when
	we enter the starting state.
	* init/tests/test_job.c (test_change_state): Make sure that the
	failed member is reset when we enter the starting state.

	* init/job.h (Job): Add failed, failed_state and exit_status members.
	* init/job.c (job_new): Initialise new members.

	* init/job.c (job_child_reaper): Convert signals to names when
	outputting status messages.
	* init/tests/test_job.c (test_child_reaper): Check that the signal
	name gets converted over.

	* init/event.h (CTRLALTDEL_EVENT): Now we've broken the shared
	namespace of events and jobs, rename the control-alt-delete event
	back to control-alt-delete.

	* init/job.c (job_change_state): Replace the events generated as
	part of the job state, named for the job and state, with new state
	events that have the job name as an argument.
	* init/event.h: Define new job event names.
	* init/tests/test_job.c (test_change_state): Make sure the new
	events are correct, with the job name as an argument.

	* init/job.c (job_change_state): Remove the job event; this has
	been repeatedly proved to be confusing.
	* init/tests/test_job.c (test_change_state): Remove checks for the
	job event.

	* util/events.c (emit_action): Pass in extra arguments.
	(env_option): Function to parse an option given an environment
	variable.
	* util/events.h: Add prototype.
	* util/tests/test_events.c (test_emit_action): Make sure that the
	emit action works with no arguments and with arguments.
	(test_events_action): Send back events with the right number of args.
	(test_env_option): Check the env option parser works.
	* util/initctl.c: Give shutdown its own command and options, give
	emit a new -e option.

	* util/events.c (shutdown_action): Split out from emit, seeing as
	these are going to be different from now on.
	* util/events.h: Add prototype.
	* util/tests/test_events.c (test_shutdown_action): Copy test cases.

	* init/control.c (control_event_queue): Take the arguments and
	environment from the event queue request; and reparent into the
	event.
	* init/tests/test_control.c (test_event_queue): Check that arguments
	and environment are copied across properly.

	* init/notify.c (notify_event): Pass in the arguments and environment
	for the event.
	* init/tests/test_notify.c (check_event): Check for event arguments
	and environment from the notify process.
	(test_event): Add arguments and environment to the event we test with

	* upstart/tests/test_message.c (test_new, test_handle): Send
	arguments and environment with the UPSTART_EVENT_QUEUE and
	UPSTART_EVENT messages.
	* upstart/wire.c (upstart_pop_int, upstart_pop_unsigned): Shrink
	only once.
	(upstart_pop_string): Check the length is at least one first, as
	we may just have an 'S'.

	* upstart/message.c (upstart_message_new, upstart_message_handle):
	The UPSTART_EVENT and UPSTART_EVENT_QUEUE messages gain new array
	arguments containing the arguments and environment for the event.
	* upstart/message.h: Document the new arguments.

	* util/tests/test_events.c, util/tests/test_jobs.c: Update the
	message format checks here too.

	* upstart/tests/test_wire.c (test_pop_pack): Free the array.

	* upstart/tests/test_message.c (test_new, test_handle)
	(test_handle_using, test_reader): Update tests to include and
	expect new type markers between each field.

	* upstart/wire.c (upstart_push_int, upstart_push_unsigned):
	Take out silly asserts; it must have room!

	* upstart/wire.c (upstart_push_string, upstart_pop_string): Rewrite
	to use a type like the rest of the functions; this removes the strange
	length restriction and allows us to make the pop function
	non-destructive.
	* upstart/tests/test_wire.c (test_push_string): Update.
	(test_pop_string): Update, adding in non-destructive, wrong type
	and insufficient space for type test cases.
	(test_push_array, test_pop_array): These needed updated too,
	changing the string format changed the array format.
	(test_push_pack, test_pop_pack): And obviously the pack format changed.

	* upstart/wire.c (upstart_pop_header): Make the function
	non-destructive in the face of errors.
	* upstart/tests/test_wire.c (test_pop_header): Make sure that
	invalid headers are non-destructive on error.

	* upstart/tests/test_wire.c (test_pop_int, test_pop_unsigned):
	Make sure that insufficient space is non-destructive.

	* upstart/wire.c (upstart_push_int, upstart_pop_int) 
	(upstart_push_unsigned, upstart_pop_unsigned): Convert to array-style
	type first format.
	(upstart_push_string, upstart_push_header): Write the length and
	type fields out by hand so they don't get an 'i' prefix.
	(upstart_pop_string, upstart_pop_header): Read the length and type
	fields by hand so they don't get an 'i' prefix.
	* upstart/tests/test_wire.c (test_push_int, test_pop_int) 
	(test_push_unsigned, test_pop_unsigned): Update test cases to match.
	(test_push_pack, test_pop_pack): Pack format was changed too.

	* upstart/wire.c (upstart_push_packv, upstart_pop_packv): Add calls
	to push and pop array.
	* upstart/tests/test_wire.c (test_push_pack, test_pop_pack): Test
	support for arrays.

	* upstart/wire.c (upstart_push_array, upstart_pop_array): Implement
	new array functions; note that these use a newer format that allows
	us to transmit NULL without needing to limit the size of the array.
	* upstart/wire.h: Add prototypes.
	* upstart/tests/test_wire.c (test_push_array, test_pop_array):
	Test the new array functions.

	* init/job.c (job_run_script): Build up the argument list, appending
	those from the goal event if one is set.
	(job_run_command): Use nih_str_array_add to build up the arguments,
	but don't append those from the goal event (use script).
	* init/tests/test_job.c (test_run_script): Make sure the arguments get
	passed to the running shell scripts.

	* init/job.c (job_run_script): Only use the /dev/fd trick if we can
	actually stat /dev/fd; also don't hardcode that path ...
	* init/paths.h (DEV_FD): Add here.

	* init/process.c (process_setup_environment): Copy environment
	variables from the goal event into the job's process.
	* init/tests/test_process.c (test_spawn): Make sure the environment
	reaches the job, but doesn't override that in the job already.

	* init/tests/test_job.c (test_start_event): 

	* init/job.c (job_start_event, job_stop_event): Copy the arguments
	and environment from the event into the goal event.

	* init/job.c (job_read_state, job_write_state): Read and write
	arguments and environment for goal event.
	* init/tests/test_job.c (test_read_state, test_write_state): Test
	with arguments and environment to the goal event.

	* init/event.c (event_read_state, event_write_state): Read and write
	the arguments and environment of the event.
	* init/tests/test_event.c (test_read_state, test_write_state): Make
	sure arguments and environment are correctly serialised.

	* init/cfgfile.c (cfg_stanza_console): Fix a leak of the console
	argument in the case of duplicated options.
	(cfg_stanza_env): Drop the counting now nih_str_array_addp does it;
	and be sure to use that function.
	(cfg_stanza_umask): Fix leak of umask argument
	(cfg_stanza_nice): Fix leak of nice argument
	* init/tests/test_event.c (test_new): Call event_queue_run so init
	is called outside of a TEST_ALLOC_FAIL block.

	* init/event.c (event_new): Start off with NULL args and env, to
	match job (saves a few bytes).
	(event_match): Watch for NULL arguments!
	* init/tests/test_event.c (test_new): Check for NULL not alloc'd

	* init/cfgfile.c (cfg_stanza_on, cfg_stanza_start) 
	(cfg_stanza_stop): Parse arguments to the on stanza and store them
	directly in the event.
	* init/tests/test_cfgfile.c (test_stanza_on, test_stanza_start) 
	(test_stanza_stop): Make sure arguments are parsed into the event.

	* init/event.c (event_new): Use nih_str_array_new.
	* init/cfgfile.c (cfg_stanza_env): Rewrite to use nih_str_array.

	* init/job.c (job_run_script): Check the error returned from
	nih_io_reopen; don't just loop.  We only ever expect ENOMEM (the
	other error, EBADF, is impossible).

	* init/job.c (job_change_state): Reset the goal_event to NULL when
	we catch a run-away job (as it's not stopping for the same event
	it started with).
	(job_child_reaper): Reset the goal_event to NULL after setting the
	goal to STOP.
	* init/tests/test_job.c (test_change_state, test_child_reaper):
	Check that the goal event gets reset whenever the goal gets changed.

	* init/tests/test_event.c: Use TEST_ALLOC_FAIL

	* init/event.c (event_match): Match arguments using fnmatch() and
	allow more arguments in event1 than event2 (but not the other way
	around).
	* init/tests/test_event.c (test_match): Check the new permitted
	combinations.

	* init/event.h (Event): Add args and env members to Event.
	* init/event.c (event_new): Initialise args and env members to
	zero-length arrays.
	* init/tests/test_event.c (test_new): Use TEST_ALLOC_FAIL and
	make sure args and env are both initialised to a list containing
	just NULL.

	* util/jobs.c (start_action): Get the UPSTART_JOB environment variable
	and use that if we don't have any arguments passed to us.
	(do_job): Code split from the above function that handles a named job
	* util/tests/test_jobs.c (test_start_action): Make sure UPSTART_JOB
	is picked up.

	* init/process.h: Add necessary attributes.

	* init/process.c (process_setup_environment): Set the UPSTART_JOB
	environment variable from the job, and the UPSTART_EVENT environment
	variable from the job's goal_event member (if set).
	* init/tests/test_process.c (test_spawn): Make sure we get the
	environment in the job.

	* init/job.h: Add attributes to job_new and job_read_state.
	* init/tests/test_job.c: Use CHECK_ALLOC_FAIL on the functions we
	didn't get around to touching while we were in here.

	* init/job.c (job_start_event, job_stop_event): Set the goal_event
	member to a copy of the event we found.
	(job_read_state): Use event_new instead of trying to do it by hand.
	* init/tests/test_job.c (test_start_event, test_stop_event): Use 
	CHECK_ALLOC_FAIL; and make sure the goal_event is set properly.
	(test_start, test_stop, test_write_new): Use event_new here too

	* init/job.c (job_write_state): Output a goal_event field containing
	the event name or nothing for NULL.
	(job_read_state): Parse the goal_event field
	* init/tests/test_job.c (test_write_state): Make sure the state is
	written out properly.
	(test_read_state): Make sure that the state is parsed correctly too.

	* init/job.c (job_start, job_stop): Split all of the code except
	the goal_event setting into two new static functions that this calls
	(_job_start, _job_stop): New static functions
	(job_start_event, job_stop_event): Call _job_start and _job_stop
	instead of job_start and job_stop

	* init/job.c (job_catch_runaway): Move this function up a bit.

	* init/job.c (job_start, job_stop): Clear the goal_event member,
	these functions are called for a manual start.
	* init/tests/test_job.c (test_start, test_stop): Make sure the
	goal_event member is freed and set to NULL.

	* init/job.h (Job): Add a new goal_event member
	* init/job.c (job_new): Initialise the goal_event member to NULL.
	* init/tests/test_job.c (test_new): Check with TEST_ALLOC_FAIL;
	also make sure goal_event is initialised to NULL.

2007-02-05  Scott James Remnant  <scott@netsplit.com>

	* configure.ac: Bump version to 0.3.3

	* NEWS: Update.

	* init/process.c (process_spawn): Exit with 255 so we don't clash
	with anything that uses 1 as a normal exit code.  Note why we only
	close 0..2 (everything else is FD_CLOEXEC).
	* init/cfgfile.c (cfg_watch_dir): Mark the inotify watch descriptor
	as FD_CLOEXEC.
	* init/control.c (control_open): nih_io_set_cloexec can only ever
	return EINVAL, so no point checking it.

2007-02-04  Scott James Remnant  <scott@netsplit.com>

	* init/tests/test_control.c: Remove strange old code.

2007-02-03  Scott James Remnant  <scott@netsplit.com>

	* init/control.c (control_open_sock, control_reopen)
	(control_close_handler): Drop these functions; unconnected datagram
	sockets don't close -- so why try dealing with it?
	(control_error_handler): Don't reopen the socket on error, just log
	it -- the socket should be fine, there's no remote end to be lost,
	after all.
	* init/tests/test_control.c (test_close_handler): Drop.
	(test_error_handler): Drop the reopen tests.

	* init/tests/test_job.c (test_run_script): Control socket doesn't
	get unexpectedly opened anymore; so no need to close it.

	* init/control.c (control_open): Remove the strange behaviour that
	this can be called to get the socket.  Instead make control_io
	global; we're all adults after all.
	* init/tests/test_control.c (test_open): Remove the test for the
	silly behaviour.
	* init/notify.c (notify_job, notify_event): Use the control_io
	pointer directly, and just do nothing if we lost it somehow.

	* init/main.c (main): Being unable tp open the control socket, or
	parse the configuration, should be a fatal error; stop being so
	damned liberal! <g>   Don't reset the signal state if we're
	being restarted, as this loses any pending signals -- be happy
	that our parent left them in a good state.  Set SIGCHLD to the
	standard handler, otherwise we might lose this before we start
	the main loop (which does the same anyway).
	(term_handler): Rework so we don't need to close and open the
	control socket; instead we just close it in the child that's
	going to send the state, and notify the parent that it's safe to
	exec (which will cause it to be closed so the new init can open it).

	* init/tests/test_control.c (test_open): Fix valgrind error
	* init/tests/test_notify.c (test_subscribe): Fix valgrind error

	* init/notify.c (notify_subscribe): Make safe against ENOMEM.
	* init/tests/test_notify.c (test_subscribe): Use TEST_ALLOC_FAIL

	* init/control.c: Add needed attributes; tidy up formatting.
	(control_open): Don't let ENOMEM fail opening the control socket.
	* init/control.h: Add needed attributes.
	* init/tests/test_control.c (test_open): Test for failed allocation.
	* init/main.c (term_handler): Make sure we catch failure to open
	the control socket again.

	* TODO: Update

	* init/cfgfile.c (cfg_watch_dir): Clean this up a bit; now we only
	output a warning if inotify failed for any reason other than not
	being supported AND walking worked.

	* init/cfgfile.c (cfg_watch_dir): Update to even newer watch API;
	our create_handler is now always called if inotify is successful,
	so we just need to fall back to walking the directory when it
	isn't -- if inotify isn't supported, don't even bother complaining.
	(cfg_create_modify_handler): Check the stat of the file visited to
	make sure it's a regular file.
	(cfg_visitor): Check the stat of the file visited to make sure it's
	a regular file.

	* init/cfgfile.c: Update include to upstart/enum.h
	* init/job.c: Update include to upstart/enum.h
	* init/job.h: Update include to upstart/enum.h

	* logd/main.c: Add attribute to open_logging

	* util/initctl.c: Split out the command functions into new files;
	* util/jobs.c: This gets the job-related commands
	* util/events.h: This gets the event-related commands
	* util/initctl.h, util/jobs.h, util/events.h: Headers
	* util/tests/test_jobs.c: Test suite for job-related commands.
	* util/tests/test_events.c: Test suite for event-related commands.
	* util/Makefile.am (initctl_SOURCES): Add new files.
	(TESTS): Build new test suites.
	(test_jobs_SOURCES, test_jobs_LDFLAGS, test_jobs_LDADD):
	Details for job-related commands test suite binary.
	(test_events_SOURCES, test_events_LDFLAGS, test_events_LDADD):
	Details for event-related commands test suite binary.
	* TODO: Remove item about splitting initctl now we've done it.

	* TODO: Big update; strip anything we have a spec for.

	* upstart/message.c (upstart_message_handle): Make sure that if we
	fail to parse a message, we don't leave strings around in memory.
	* upstart/tests/test_message.c (test_open): Check that we get a
	raised EADDRINUSE if we try an open a socket twice.
	(test_handle): Add lots of checks for things like NULL names and
	incomplete messages; as well as the obvious unknown message.
	(test_reader): Make sure that errors while handling messages are
	dealt with by logging it.

	* upstart/job.c, upstart/job.h, upstart/tests/test_job.c: Rename to
	enum.c, enum.h and tests/test_enum.c; since this just includes enums
	and convert functions really.
	* upstart/Makefile.am: Update.
	* upstart/libupstart.h: Update include.
	* upstart/tests/test_message.c: Update include.

2007-02-01  Scott James Remnant  <scott@netsplit.com>

	* logd/main.c (main): Ensure we error if daemonise fails.

	* compat/sysv/shutdown.c (main): Ensure that signals and timers
	are added, even if we run out of memory.

	* upstart/tests/test_message.c: Change from assert to assert0 
	* upstart/tests/test_wire.c: Change from assert to assert0
	* init/tests/test_notify.c: Change from assert to assert0
	* init/tests/test_control.c: nih_io_message_send should always return
	a value greater than zero.

	* upstart/tests/test_wire.c: Change to use assert instead of NIH_ZERO;
	the rationale here is that in test cases we just want to fail, not
	try again repeatedly.
	* upstart/tests/test_message.c: Likewise.

	* init/tests/test_control.c: Use assert to ensure we get the expected
	return values of functions that raise errors.
	* init/tests/test_notify.c: Use assert to ensure we get the expected
	return values of functions that raise errors.

	* init/cfgfile.c (cfg_watch_dir): Port to the new NihWatch API and
	use nih_dir_walk().  This also fixes the long-standing bug where we
	wouldn't watch the configuration directory if inotify was disabled.
	Drop both the parent and prefix members for now, until we clean this
	up later.
	(cfg_create_modify_handler): Wrap cfg_read_job after figuring out
	the job name.
	(cfg_job_name): Function to figure out the job name from a path.
	(cfg_visitor): Visitor function to handle initial parsing, figuring
	out the job name; otherwise identical to the standard handler.
	* init/cfgfile.h: Update prototype for cfg_watch_dir.
	* init/main.c (main): Update call to cfg_watch_dir.

2007-01-31  Scott James Remnant  <scott@netsplit.com>

	* upstart/tests/test_message.c: Use TEST_ALLOC_FAIL to make sure
	allocations are handled properly.

2007-01-30  Scott James Remnant  <scott@netsplit.com>

	* upstart/wire.c: Note that if any of the push functions fail, the
	entire buffer should be discarded.
	* upstart/tests/test_wire.c (test_push_int, test_push_unsigned) 
	(test_push_string, test_push_header, test_push_pack): Us
	TEST_ALLOC_FAIL to ensure that failing to allocate memory is caught.

	* upstart/tests/test_message.c (my_handler): Free the name and
	description after checking; they aren't otherwise.

	* upstart/wire.c (upstart_push_packv, upstart_pop_packv): Consume
	a copy of the va_list, so these can be called multiple times on the
	same list without ill effect.

	* upstart/message.h: Add warn_unused_result attributes to
	upstart_message_handle and upstart_message_handle_using as they raise
	errors.

	* upstart/wire.c: push functions return negative values to indicate
	insufficient memory.
	* upstart/wire.h: Add warn_unused_result attributes to push functions

	* upstart/tests/test_message.c: Guard calls to nih_io_buffer_push and
	nih_io_message_add_control with NIH_ZERO to ensure they succeed.
	* upstart/tests/test_wire.c: Guard calls to nih_io_buffer_push

	* HACKING: Update from libnih with new Documentation,
	Function Attributes and Test Cases sections.

2007-01-10  Scott James Remnant  <scott@netsplit.com>

	* init/main.c (crash_handler): s/SEGV/SIGSEGV/

	* init/main.c (main): Rename variable

	* TODO: Update.

	* init/main.c (main): Change the way we clear the arguments; by
	deleting just the final NULL terminator, we fool the kernel into
	only returning one argument in cmdline.

	* init/main.c (segv_handler): Rename to crash_handler and handle
	SIGABRT as well, so we can catch assertion errors.  Of course, in
	theory, with our high test converage this should never happen in
	practice <chortle>

2007-01-09  Scott James Remnant  <scott@netsplit.com>

	* init/main.c (main): Clear arguments so that upstart only ever
	appears as /sbin/init in ps, top, etc.

	* TODO: Update.

	* util/initctl.c: Add data pointer to functions and handle calls.

	* init/control.c: Add data pointer to all functions.
	* init/tests/test_control.c: Pass data pointer to
	upstart_message_handle_using()
	* init/tests/test_notify.c: Pass data pointer to
	upstart_message_handle_using()

	* upstart/message.c (upstart_message_handle) 
	(upstart_message_handle_using): Add a data pointer argument to these
	functions and pass it to the handler.
	(upstart_message_reader): Pass the io structure's data pointer.
	* upstart/message.h (UpstartMessageHandler): Add a data pointer to
	the message handler.
	* upstart/tests/test_message.c (test_handle, test_handle_using):
	Pass a data pointer to the function call and check it's passed
	to the handler correctly.
	(test_reader): Check that the io data pointer gets passed.

	* init/tests/test_cfgfile.c (test_stanza_console, test_stanza_env) 
	(test_stanza_umask, test_stanza_nice, test_stanza_limit): Finish off
	the newer style test cases.

	* init/cfgfile.c (cfg_stanza_console, cfg_stanza_umask)
	(cfg_stanza_nice, cfg_stanza_limit, cfg_stanza_chroot)
	(cfg_stanza_chdir): Guard against duplicate uses of the stanzas.
	* init/tests/test_cfgfile.c (test_stanza_daemon) 
	(test_stanza_respawn): Check that neither daemon or respawn override
	exec if they have no arguments.
	(test_stanza_script): Add missing function
	(test_stanza_chroot, test_stanza_chdir): Add tests for these simple
	stanzas.

	* init/cfgfile.c: Change remaining uses of nih_error_raise and
	return to just nih_return_error.

	* init/cfgfile.c (cfg_stanza_exec, cfg_stanza_daemon)
	(cfg_stanza_respawn, cfg_stanza_script): Disallow duplicates,
	both of command strings, scripts, limits and of just the flags.
	* init/tests/test_cfgfile.c (test_stanza_exec) 
	(test_stanza_daemon, test_stanza_respawn, test_stanza_instance):
	Check the behaviour of these stanzas.
	
	* init/cfgfile.c (cfg_stanza_start, cfg_stanza_stop): Disallow
	duplicate values for the script.
	* init/tests/test_cfgfile.c (test_stanza_start, test_stanza_stop):
	Test cases for those two functions.

	* init/cfgfile.c (cfg_stanza_description, cfg_stanza_author) 
	(cfg_stanza_version): Don't allow stanza to be duplicated anymore.
	* init/tests/test_cfgfile.c (test_stanza_description) 
	(test_stanza_author, test_stanza_version): Test cases for these
	simple stanza; making sure duplication is not permitted.
	(test_stanza_on): Add a test case for this stanza too.

	* init/cfgfile.c (cfg_stanza_kill): Guard against duplicate uses
	of the kill timeout stanza.
	* init/tests/test_cfgfile.c (test_stanza_kill): Test the complex
	kill stanza.
	(test_stanza_pid): Check duplicate usage results in an error.

	* init/job.h (Job): Rename pidfile to pid_file and binary to pid_binary
	* init/job.c (job_new): Update names here too.
	* init/errors.h: Add a new "duplicate value" error.
	* init/cfgfile.c (cfg_read_job): Change name of variables, and catch
	the duplicate value error to add the line number.
	(cfg_stanza_pid): Change variable names, and clean this function up
	a little.  Make it an error to use a stanza more than once.
	* init/tests/test_cfgfile.c (test_stanza_pid): Write a newer test
	case function for the pid stanza.

	* init/cfgfile.c (cfg_stanza_normalexit): Use do/while instead of
	while, that we don't have to test has_token first as next_arg does
	that for us.

	* init/cfgfile.c (cfg_stanza_normalexit): Change to peek at the next
	token to see whether it's missing or not, and then just fetch each
	next argument at a time.  This is more efficient than parsing them
	all in one go, and also means we can report the error in the right
	place!
	* init/tests/test_cfgfile.c (test_stanza_normalexit): Since we've
	changed the function that parses the stanza, add a proper test case
	function for it, covering all the behaviours.

	* init/job.c (job_new): Initialise the emits member to an empty list.
	* init/job.h (Job): Add the emits member as a list.
	* init/tests/test_job.c (test_new): Check the emits list starts off
	empty.
	* init/tests/test_cfgfile.c (test_stanza_emits): Test the new emits
	stanza; this function will also serve as a prototype for cleaning up
	the config tests.

	* init/cfgfile.c (cfg_stanza_emits): Add function to parse the new
	emits stanza.

	* init/cfgfile.c (cfg_stanza_depends): Remove the depends stanza
	from the configuration file.  Dependency support has never been used,
	and is to be replaced by a more flexible event/state configuration
	and blocking on the starting/stopping events.
	* init/tests/test_cfgfile.c: Remove references and tests for the
	depends stanza.
	* init/job.h: Remove the depends list from the job structure.
	* init/job.c (job_new): No depends list to initialise.
	(job_change_state): No dependencies to release
	(job_start): No dependencies to iterate; this removes a particularly
	hairy and complex interaction between state changes.  Remove the
	dependency event.
	(job_release_depends): Drop this function.
	* init/tests/test_job.c (test_start, test_stop): Massively simplify
	these tests cases now we don't have dependencies to worry about.
	(test_release_depends): Drop tests

2007-01-08  Scott James Remnant  <scott@netsplit.com>

	* init/cfgfile.c: Rewrite using the nih_config API, rather than one
	huge function we now just have seperate handler functions for each
	stanza.  We can also use more fine-grained parsing than slurping
	all args in and counting them.
	(cfg_read_job): Catch exceptions from the configuration parser and
	add the line number where the problem occurred to an output message.
	Parser errors are now fatal, and not ignored.
	* init/errors.h: Add a file containing errors raised within the init
	daemon codebase.
	* init/Makefile.am (init_SOURCES): Build with errors.h
	* init/tests/test_cfgfile.c: Update test cases now we don't expect
	a job to be returned if there's a parser error.

	* TODO: Update

2007-01-06  Scott James Remnant  <scott@netsplit.com>

	* logd/main.c (logging_reader): Fix inadvertent shadowing of the
	len parameter.

	* compat/sysv/telinit.c: Oops, nearly forgot to port this to send
	the messages in the new way.
	* compat/sysv/shutdown.c (shutdown_now): Likewise, port this too.

	* TODO: Update.

	* util/initctl.c (handle_job_status): Output the process argument,
	not the pid argument which contains the origin of the message.

	* upstart/message.c (upstart_message_handle): Raise a new unknown
	message error if we don't have a handler  and a new illegal message
	error if the source is illegal.
	* upstart/tests/test_message.c (test_handle): Adjust tests to check
	for the new errors that we raise.
	* upstart/errors.h: Define strings for new errors.

	* util/initctl.c: Yet another makeover for this little program,
	port it to the new message/control framework using handler functions
	and NihIoMessage.  This starts to make each action function look
	very similar, so there's method to this madness.

2007-01-05  Scott James Remnant  <scott@netsplit.com>

	* logd/main.c (main): Make sure that we add the SIGTERM handler.

	* init/tests/test_job.c (test_run_script): This test case relies
	on there only being one file descriptor watch, which won't be true
	if the control socket has been opened because there's a message to
	go out.  Make sure it's closed first.

	* init/init.supp: Update supressions file now that control_init
	has been renamed to notify_init

	* init/Makefile.am: Include notify.o from all tests.
	* init/job.c (job_change_state, job_kill_process, job_start) 
	(job_stop): Use the new notify_job function name.
	* init/event.c (event_queue_run): Use the new notify_event function
	name.

	* init/control.c (control_error_handler): Handle ECONNREFUSED now
	that the process id is available to us.
	* init/tests/test_control.c (test_error_handler): Make sure children
	going away is handled properly.

	* upstart/message.c (upstart_message_new): Store the process id in
	the int_data message field.
	* upstart/tests/test_message.c (test_new): Check the int_data field
	is filled in.

	* init/main.c (main): Guard against various things returning an error
	that we weren't catching.

	* init/tests/test_notify.c: Whitespace fix.

	* init/control.c (control_watch_jobs, control_unwatch_jobs) 
	(control_watch_events, control_unwatch_events): Restore functionality
	to subscribe and unsubscribe from job and event notifications.	
	* init/tests/test_control.c (test_watch_jobs, test_unwatch_jobs) 
	(test_watch_events, test_unwatch_events): Check that the subscription
	and unsubscription messages work.
	* init/Makefile.am (test_control_LDADD): Link to notify.o

	* init/control.c: Drop unused include of upstart/errors.h

	* init/notify.c: Move functions that handle subscription and
	notification from control.c.  Other than changing the names, we're
	keeping the API the same for now; expect it to change later when we
	add the ability to subscribe to individual jobs or events.
	(notify_init): initialise the subscriptions list; we don't have a
	separate send queue now that the control I/O is always asynchronous.
	* init/notify.h: Moved notification enum, structure and prototypes
	from control.h, changing the names so they match notify_* in the
	process.
	* init/Makefile.am (init_SOURCES): Build and link notify.c using
	notify.h
	(TESTS): Build the notify test suite binary.
	(test_notify_SOURCES, test_notify_LDFLAGS, test_notify_LDADD): Details
	for notify test suite binary.
	* init/tests/test_notify.c: Rewrite test cases in the manner of
	test_control.c so that we have one function for notify_job and
	one for notify_event, each of which contains the child process that
	receives the notification,

	* init/control.c (control_open): Allow this to be called to obtain
	the control socket, which means we can make it static.
	* init/tests/test_control.c (test_open): Check that it works.

	* init/control.c, init/control.h, init/tests/test_control.c: Move
	functions that handle subscription and notification to new notify.c
	(control_init): Drop completely, no need to maintain a send queue now
	(control_open): Change to return an NihIo that uses the default
	control watcher, and our error handler.  Split socket opening into
	(control_open_sock): which can be called from other functions.
	(control_close): Use nih_io_close() to close the socket and free the
	structure in one go.
	(control_reopen): Close the open control socket and open it again
	without destroying the NihIo structure, its queues or state.
	(control_close_handler): Handle the control socket going away
	(control_error_handler): Handle errors on the control socket,
	including the connection refused error that indicates a client went
	away.
	(control_handle): Split this into a miriad of small functions with
	a table to link them to the message type; this will make expanding
	each message handler much easier in future.
	* init/control.h: Update.
	* init/tests/test_control.c: Rewrite test cases to check the new
	handler functions; as a side-effect, this gets rid of the evil giant
	child/parent functions in favour of one test function per handler
	function.

	* upstart/message.c (upstart_message_handle_using): Wrapper function
	around upstart_message_handle that ensures all messages as passed to
	a single function.
	* upstart/message.h: Update.
	* upstart/tests/test_message.c (test_handle_using): Make sure it
	calls the single function.

2007-01-04  Scott James Remnant  <scott@netsplit.com>

	* upstart/message.c (upstart_message_reader): Handle any errors
	that occurred while handling the message.

2007-01-02  Scott James Remnant  <scott@netsplit.com>

	* upstart/message.c (upstart_message_handle): Check that the name
	argument is never NULL.
	(upstart_message_reader): Simple message reader function that can
	be associated with an I/O watch and handles each message received.
	* upstart/message.h: Add prototype.
	* upstart/tests/test_message.c (test_reader): Test the reader function.

	* upstart/control.c: Rename to upstart/message.c
	* upstart/control.h: Rename to upstart/message.h
	* upstart/tests/test_control.c: Rename to upstart/tests/test_message.c
	* upstart/libupstart.h: Update includes.
	* upstart/wire.c: Include message.h
	* upstart/wire.h: Update includes.
	* upstart/tests/test_wire.c: Update includes.
	* upstart/errors.h: Rename UPSTART_INVALID_MESSAGE to
	UPSTART_MESSAGE_INVALID so that it's prefixed.
	* upstart/Makefile.am (libupstart_la_SOURCES) 
	(upstartinclude_HEADERS, TESTS): Update filenames.

	* upstart/control.c (upstart_message_new): New function that
	creates an NihIoMessage directly from its arguments, which are a type
	followed by a variable number of args depending on that type.
	(upstart_message_handler): Function to find a handler function for
	a particular message type and origin process.
	(upstart_message_handle): New function that takes an NihIoMessage
	and invokes a handler function with a variable number of args
	depending on the message type.
	(upstart_send_msg, upstart_send_msg_to, upstart_recv_msg): Drop these
	functions, leave it up to the caller to decide whether to send and
	receive the messages synchronously or asynchronously; now that the
	capability is in nih_io_*.
	* upstart/control.h (UpstartMsgType): Rename to UpstartMessageType.
	(UpstartMessageHandler): Function with variable number of arguments
	that handles a message received.
	(UpstartMsg): Drop this structure entirely, we'll encode or decode
	the wire format directly from or into a function call, rather than
	use an intermediate structure to marshal it.
	(UpstartMessage): New structure to make a table that can be passed
	to upstart_message_handle to determine which handler should be called.
	* upstart/tests/test_control.c: Test new behaviour.
	* upstart/wire.c (upstart_push_header, upstart_pop_header): Change
	structure name for type parameter.
	* upstart/wire.h: Update.
	* upstart/tests/test_wire.c: Update.

	* configure.ac (AC_COPYRIGHT): Update copyright to 2007.

2006-12-29  Scott James Remnant  <scott@netsplit.com>

	* upstart/wire.c (upstart_write_int, upstart_write_unsigned) 
	(upstart_write_string, upstart_write_header, upstart_write_packv) 
	(upstart_write_pack): Rename to *_push_*
	(upstart_read_int, upstart_read_unsigned, upstart_read_string) 
	(upstart_read_header, upstart_read_packv, upstart_read_pack): Rename
	to *_pop_*.
	All of the above modified to modify an NihIoMessage structure,
	instead of trying to carry around buffers ourself.
	* upstart/wire.h: Update to match above.
	* upstart/tests/test_wire.c: Update all tests to match the above
	changes.

2006-12-21  Scott James Remnant  <scott@netsplit.com>

	* upstart/wire.c (upstart_read_packv, upstart_write_packv): Change
	nih_assert_notreached to nih_assert_not_reached.

	* init/job.c (job_run_script): Open the NihIo structure in stream mode.
	* logd/main.c (logging_watcher): Open the NihIo structure in
	stream mode.
	(logging_reader): Need to pass the length of the size_t as a pointer
	so that it can be modified if less is read.

2006-12-17  Scott James Remnant  <scott@netsplit.com>

	* upstart/wire.c (upstart_write_packv, upstart_write_pack) 
	(upstart_read_packv, upstart_read_pack): Functions to write a pack
	of different variables to the stream, or read them from it
	* upstart/wire.h: Add prototypes.
	* upstart/tests/test_wire.c (test_write_pack, test_read_pack):
	Check we can read and write a pack of variables at once.

	* upstart/wire.c (upstart_write_header, upstart_read_header): Drop
	the version from the header, we'll just keep the protocol always
	backwards compatible.
	* upstart/wire.h: Update.
	* upstart/tests/test_wire.c (test_write_header, test_read_header):
	Check that everything works.

	* upstart/wire.c (upstart_write_string, upstart_read_string):
	Transmit the length as an unsigned, and use 0xffffffff to mean NULL
	instead of zero so we can still transmit the empty string.
	* upstart/wire.h: Update.
	* upstart/tests/test_wire.c (test_write_string, test_read_string):
	Tests for the functions to make sure the wire is at it should be.

	* upstart/wire.c (upstart_read_str, upstart_write_str): Rename to
	upstart_read_string and upstart_write_string.
	* upstart/wire.h: Update.
	
	* upstart/wire.c (upstart_write_unsigned, upstart_read_unsigned):
	Functions to send unsigned values over the wire, which we'll use
	to get a bit extra for the string lengths.
	* upstart/wire.h: Update.
	* upstart/tests/test_wire.c (test_write_unsigned) 
	(test_read_unsigned): Test the new functions.

	* upstart/wire.c (upstart_write_ints, upstart_read_ints): Drop
	these functions, we'll go with something far more generic and
	useful.
	* upstart/wire.h: Remove prototypes.

	* upstart/wire.c (upstart_write_int, upstart_read_int): Transmit
	integers as signed 32-bit values in network byte order.
	* upstart/tests/test_wire.c (test_write_int, test_read_int): Test
	the functions to make sure the wire is at it should be,

	* upstart/control.c (upstart_read_int, upstart_write_int) 
	(upstart_read_ints, upstart_write_ints, upstart_read_str) 
	(upstart_write_str, upstart_read_header, upstart_write_header): Move
	functions to new wire.c file.
	* upstart/wire.c: Source file to hold wire protocol functions.
	* upstart/wire.h: Prototypes.
	* upstart/tests/test_wire.c: (empty) test suite.
	* upstart/libupstart.h: Include wire.h
	* upstart/Makefile.am (libupstart_la_SOURCES): Build and link wire.c
	(upstartinclude_HEADERS): Install wire.h
	(TESTS): Build and run wire test suite.
	(test_wire_SOURCES, test_wire_LDFLAGS, test_wire_LDADD): Details for
	wire test suite binary.

	* upstart/control.c (MAGIC): Change to "upstart\n", the final
	character was originally \0 and then was a " " for the 0.2 series.
	* upstart/tests/test_control.c (test_recv_msg): Change to match.

2006-12-15  Scott James Remnant  <scott@netsplit.com>

	* util/initctl.c, compat/sysv/telinit.c, compat/sysv/shutdown.c:
	Update all uses of the UpstartMsg structure to avoid the
	intermediate union that no longer exists.	

	* init/control.c, init/tests/test_control.c: Update all uses of
	the UpstartMsg structure to avoid the intermediate union that no
	longer exists.	

	* upstart/control.h: Combine all the previous message structures
	into just one that has all of the fields anyway.
	* upstart/control.c, upstart/tests/test_control.c: Update all uses of
	the UpstartMsg structure to avoid the intermediate union that no
	longer exists.

	* upstart/control.h (UPSTART_API_VERSION): Define API version macro
	to be public.
	* upstart/control.c (MSG_VERSION, upstart_send_msg_to): Replacing the
	previous MSG_VERSION macro here.

	* upstart/control.c (upstart_read_int, upstart_write_int) 
	(upstart_read_ints, upstart_write_ints, upstart_read_str) 
	(upstart_write_str, upstart_read_header, upstart_write_header):
	New functions to replace the old "write a struct" protocol with
	something a little more regimented and supportable.
	(IOVEC_ADD, IOVEC_READ, WireHdr, WireJobPayload, WireJobStatusPayload)
	(WireEventPayload): Remove these structures, use the functions
	instead.
	(upstart_send_msg_to): Call write functions intead of using macros,
	this makes the code somewhat neater.
	(upstart_recv_msg): Call read functions instead of using macros,
	again making the code somewhat neater.
	* upstart/tests/test_control.c (test_recv_msg): Change wire
	tests to match new protocol, and thus actually work properly,
	previously these were endian sensitive.

2006-12-14  Scott James Remnant  <scott@netsplit.com>

	* compat/sysv/shutdown.c (wall): Construct the wall message so that
	we don't put \r into a po file; for some reason, gettext hates that
	and bitches about it.  Someone's confusing internationalisation with
	operating system portability, I expect.

	* util/man/initctl.8: Drop reference to start(8), as that's just
	a symlink to initctl now.

	* init/man/init.8: Link to initctl.

	* compat/sysv/reboot.c (main): Clear up help text a little.

	* HACKING: Correct some typos.

	* configure.ac (AC_INIT): Correct bug reporting address.

2006-12-13  Scott James Remnant  <scott@netsplit.com>

	* configure.ac: Bump version to 0.3.2

	* NEWS: Update.

	* util/initctl.c (print_job_status): Drop the newline from the
	output.

2006-12-13  Alex Smith  <alex@alex-smith.me.uk>

	* util/initctl.c (print_job_status): Clean up initctl job status
	output, which was badly converted from printf to nih_message.

2006-12-13  Scott James Remnant  <scott@netsplit.com>

	* compat/sysv/man/shutdown.8: Add missing documentation on the
	format of TIME by copying it from --help output.

2006-12-13  Alex Smith  <alex@alex-smith.me.uk>

	* init/process.c (process_setup_console): Actually send output to
	/dev/null instead of /dev/console, when CONSOLE_NONE.

2006-12-13  Scott James Remnant  <scott@netsplit.com>

	* Makefile.am (EXTRA_DIST): Distribute the nih ChangeLog as well.

	* init/tests/test_job.c: Port to the new test framework.
	* init/job.c (job_set_idle_event): Fix a slight memory leak,
	repeated setting of the idle event never freed the previous one set.

2006-12-12  Scott James Remnant  <scott@netsplit.com>

	* init/tests/test_cfgfile.c: Port to the new test framework.

	* init/tests/test_control.c: Port to the new test framework.
	* init/init.supp: Suppress the list head allocated within control_init.

	* init/control.c (control_watcher): Need to save the pid when we
	get ECONNREFUSED, otherwise we lose it when we free the message.

	* init/tests/test_process.c: Port to the new test framework.
	* init/init.supp: Suppress the list head allocated within job_init.

	* init/init.supp: Include a valgrind suppressions file.
	* init/Makefile.am (EXTRA_DIST): Distribute the suppressions file.

	* init/tests/test_event.c: Port to the new test framework.

	* logd/Makefile.am, util/Makefile.am, compat/sys/Makefile.am
	(AM_CPPFLAGS): Add -I$(srcdir), necessary for testing "programs"
	that don't have usual library path semantics.

	* upstart/tests/test_control.c: Port to the new test framework.
	* upstart/control.c (upstart_free): Drop this function, while not
	exposing libnih is a valiant effort, it already slips out because
	of the error handling.

	* upstart/tests/test_job.c: Add missing include.

	* upstart/tests/test_job.c: Port to the new test framework.
	(test_process_state_name): Check that this returns NULL.

	* HACKING: Update location of download directory.  Document
	requirement that all code have test cases.

	* logd/main.c (open_logging): Likewise.

	* init/control.c (control_open): No need to set ENOMEM, errno is
	always set anyway.

	* configure.ac (AM_INIT_AUTOMAKE): Include nostdinc so we don't get
	Automake's broken default includes.
	* upstart/Makefile.am (DEFAULT_INCLUDES): Drop override now that
	we don't need it.
	(DEFS, INCLUDES): Replace these variables with the combined
	(AM_CPPFLAGS): variable that declares everything.
	* init/Makefile.am (DEFAULT_INCLUDES): Drop override now that
	we don't need it.
	(DEFS, INCLUDES): Replace these variables with the combined
	(AM_CPPFLAGS): variable that declares everything.
	* util/Makefile.am (DEFAULT_INCLUDES): Drop override now that
	we don't need it.
	(DEFS, INCLUDES): Replace these variables with the combined
	(AM_CPPFLAGS): variable that declares everything.
	* compat/sysv/Makefile.am (DEFAULT_INCLUDES): Drop override now that
	we don't need it.
	(DEFS, INCLUDES): Replace these variables with the combined
	(AM_CPPFLAGS): variable that declares everything.
	* logd/Makefile.am (DEFAULT_INCLUDES): Drop override now that
	we don't need it.
	(DEFS, INCLUDES): Replace these variables with the combined
	(AM_CPPFLAGS): variable that declares everything.

2006-11-02  Scott James Remnant  <scott@netsplit.com>

	* util/initctl.c (start_action): Remove break calls which shouldn't
	be there.

2006-10-18  Sean E. Russell  <ser@ser1.net>

	* init/main.c: Include sys/time.h
	* init/cfgfile.c: Include sys/time.h and sys/resource.h
	* init/job.c: Include sys/time.h and sys/resource.h

2006-10-17  Scott James Remnant  <scott@netsplit.com>

	* configure.ac: Bump version to 0.3.1

	* NEWS: Update.
	* TODO: Update.

	* configure.ac (AM_GNU_GETTEXT_VERSION): Quote version number.

	* logd/Makefile.am (event.d/logd): Make the event.d sub-directory
	in case we're building outside of the source tree.

	* compat/sysv/runlevel.c (store): Don't break strict-aliasing rules
	by avoiding dereferencing type-punned pointer.  Answers on a
	postcard, please.

2006-10-13  Scott James Remnant  <scott@netsplit.com>

	* util/initctl.c (start_action, emit_action): Add missing \n

	* util/initctl.c: Rewrite using nih_command_parser.
	* util/man/initctl.8: Improve.

	* util/start.c: Remove, replaced by initctl.
	* util/man/start.8: Remove, replaced by initctl.
	* util/Makefile.am (sbin_PROGRAMS): Drop start, now just a symlink
	to initctl.
	(dist_man_MANS): Drop start.8, now a symlink to initctl.8
	(install-exec-hook): Make symlinks to initctl, add start
	(install-data-hook): Make symlinks to initctl.8, add start.8

	* initctl: Rename to util again, I don't want a separate directory
	for every single little tool; and we'll be shipping more than just
	initctl (e.g. a non-compat reboot).
	* configure.ac (AC_CONFIG_FILES): Make util/Makefile instead of
	initctl/Makefile.
	* Makefile.am (SUBDIRS): Descend into util, not initctl.

	* compat/sysv/reboot.c: Remove long options where they didn't exist
	before.  Write help text.
	* compat/sysv/man/reboot.8: Update.

	* init/main.c (main): Formatting.
	* logd/main.c (main): Formatting.
	* logd/man/logd.8: Formatting.
	* compat/sysv/runlevel.c (main): Formatting.
	* compat/sysv/telinit.c (main): Formatting.
	* compat/sysv/man/shutdown.8: Remove long options.

	* compat/sysv/shutdown.c: Remove -e/--event, it has no place in a
	compatibility tool.  Get rid of long options that never existed
	before.  Specify help text to describe the options.
	* compat/sysv/man/shutdown.8: Spruce up a bit.

	* compat/sysv/telinit.c (main): Set help text to list the valid
	runlevels.
	* compat/sysv/man/telinit.8: Refine the notes to mention runlevel(8).

	* compat/sysv/runlevel.c (main): Make the help text describe the
	options, rather than the behaviour.
	* compat/sysv/man/runlevel.8: Flesh out a little more.

	* configure.ac (AC_INIT): Change bug reporting address to the
	mailing list, since Launchpad doesn't accept random bugs without
	accounts and complicated control messages.
	* init/main.c, logd/main.c: Add a period to the synopsis.

	* init/main.c (main): Set the synopsis, and direct people to look
	at telinit in the --help output.
	* init/man/init.8: Flesh this out a little more, still a lot of
	explaining to do about jobs and events, but we'll wait until we've
	changed that code before documentating the behaviour.

	* logd/main.c (main): Correct help text to describe the options,
	rather than what the program does.  As per standard style.
	Don't become a daemon until the logging socket is open, and make
	that exclusive with waiting for SIGCONT.
	* logd/man/logd.8: Write some more extensive documentation,
	including describing the startup interlock and the socket protocol.
	* TODO: Plan to get rid of the signal interlock from  logd.

2006-10-12  Scott James Remnant  <scott@netsplit.com>

	* configure.ac: Expand AC_GNU_SOURCE so we get _GNU_SOURCE and so
	that gettext doesn't complain.
	(AM_GNU_GETTEXT_VERSION): Increase to 0.15
	(AC_PREREQ): Increase to 2.60
	* HACKING: Update autoconf and gettext requirements.

2006-10-11  Scott James Remnant  <scott@netsplit.com>

	* init/control.c (control_init): Pass NULL to nih_list_new.
	Clarify list item types.
	* init/event.c (event_init): Pass NULL to nih_list_new.
	* init/job.c (job_init): Pass NULL to nih_list_new.

	* init/main.c: Change nih_signal_add_callback to nih_signal_add_handler
	and NihSignalCb to NihSignalHandler.

	* init/cfgfile.c, init/cfgfile.h, init/control.c, init/control.h,
	init/event.c, init/event.h, init/job.c, init/job.h, init/main.c,
	init/process.c: Clean up documentation strings and parent pointer
	types.

	* compat/sysv/shutdown.c: Change nih_signal_add_callback to
	nih_signal_add_handler.

	* compat/sysv/reboot.c: Set synopsis text depending on command
	used (probably should use nih_command_parser?)
	* compat/sysv/runlevel.c: Set synopsis and help text, and correct
	usage.
	* compat/sysv/shutdown.c: Set synopsis text.
	* compat/sysv/telinit.c: Set synopsis text.

	* compat/sysv/runlevel.c, compat/sysv/shutdown.c: Clean up
	documentation strings.

	* logd/main.c: Set synopsis and help text.

	* logd/main.c: Clean up documentation strings.
	Change nih_signal_add_callback to nih_signal_add_handler.

	* upstart/control.c, upstart/control.h, upstart/job.c: Clean up
	documentation strings and correct parent pointer type.

	* HACKING: Detail function documentation requirement and format.

2006-10-10  Scott James Remnant  <scott@netsplit.com>

	* event.d/logd.in: Move to logd/event.d
	* event.d/Makefile.am: Remove
	* logd/Makefile.am: Create the logd job definition and install
	* Makefile.am (SUBDIRS): event.d directory has been removed.
	* configure.ac (AC_CONFIG_FILES): No longer make event.d/Makefile

	* configure.ac: Check for --enable-compat, default to sysv if given
	or no compat if not given.
	* compat/sysv/Makefile.am: Don't build binaries or install manpages
	unless COMPAT_SYSV is defined.

2006-10-06  Scott James Remnant  <scott@netsplit.com>

	* doc/upstart-logo.svg: Include the logo Alexandre designed.
	* doc/Makefile.am (EXTRA_DIST): Ship the logo in the tarball.
	* Makefile.am (SUBDIRS): Install under doc
	* configure.ac: Generate doc/Makefile
	* AUTHORS: Ensure he's credited fully.

2006-09-27  Scott James Remnant  <scott@netsplit.com>

	* event.d/Makefile.am (do_subst): Eliminate duplicate /s

	* man/init.8: Move to init/man
	* init/Makefile.am: Update to install man page.
	* man/logd.8: Move to logd/man
	* logd/Makefile.am: Update to install man page.
	* man/initctl.8, man/start.8: Move to initctl/man
	* initctl/Makefile.am: Update to install man pages.
	* man/reboot.8, man/runlevel.8, man/shutdown.8, man/telinit.8:
	Move to compat/sysv/man
	* compat/sysv/Makefile.am: Update to install man pages.
	* man/Makefile.am: Remove
	* configure.ac (AC_CONFIG_FILES): Remove man/Makefile
	* Makefile.am (SUBDIRS): Don't build in man

	* util: Rename to initctl
	* configure.ac (AC_CONFIG_FILES): Update.
	* Makefile.am (SUBDIRS): Update.

	* util/reboot.c: Move to compat/sysv
	* util/shutdown.c: Move to compat/sysv
	* util/Makefile.am: Update.
	* compat/sysv/Makefile.am: Update.

	* configure.ac: Replace macros with single call to NIH_INIT.
	Bump version to 0.3.0 to begin new development cycle.

2006-09-21  Scott James Remnant  <scott@netsplit.com>

	* logd/main.c: Revert the change that logged to the console, in
	practice this doesn't work so well.  I want to get rid of logd
	in the long term, or at least just have it as a simple logging
	proxy, so giving it features seems wrong.

2006-09-20  Scott James Remnant  <scott@netsplit.com>

	* configure.ac: Bump version to 0.2.8
	* NEWS: Updated.

	* logd/main.c (main): Check the kernel command-line for "quiet"
	(line_reader): Write to console unless silent or a daemon

	* man/Makefile.am (dist_man_MANS): Drop sulogin.8
	* man/sulogin.8: Drop, we don't include an sulogin

2006-09-19  Michael Biebl  <mbiebl@gmail.com>

	* event.d/Makefile.am (logd): Drop $(srcdir)
	* init/Makefile.am (init_SOURCES): Distribute paths.h

2006-09-18  Michael Biebl  <mbiebl@gmail.com>

	* configure.ac: Check for sys/inotify.h

2006-09-18  Scott James Remnant  <scott@netsplit.com>

	* util/shutdown.c (warning_message): Adjust method of constructing
	the message to not confuse poor translators who think \r and \n are
	the same thing!

2006-09-14  Scott James Remnant  <scott@netsplit.com>

	* init/job.c (job_change_state): Catch runaway respawns when we
	enter the running state, so we catch stop/start loops too.
	* init/tests/test_job.c (test_change_state): Update test.

	* event.d/logd: Rename to logd.in
	* event.d/logd.in: Replace /sbin with @sbindir@ so we can transform
	* event.d/Makefile.am: Generate logd from logd.in

	* util/reboot.c: Don't hardcode the location of /sbin/shutdown
	* util/Makefile.am (DEFS): Use autoconf to seed it
	* util/shutdown.c (sysvinit_shutdown): Don't hardcode the location
	of /dev/initctl

	* init/paths.h: Create a new configuration file that can contain
	all of the path definitions, and in particular, allow them to be
	overidden elsewhere.
	* init/Makefile.am (DEFS): Override definitions of CFG_DIR and
	TELINIT using autoconf
	* init/main.c: Include paths.h.  Don't hardcode location of telinit
	* init/job.c: Include paths.h
	* init/process.c: Include paths.h
	* init/process.h: Remove definitions from here.

	* configure.ac: Bump version to 0.2.7

2006-09-13  Scott James Remnant  <scott@netsplit.com>

	* NEWS: Updated.

	* TODO: More TODO.

2006-09-10  Scott James Remnant  <scott@netsplit.com>

	* util/reboot.c (main): Don't give -H with "halt".

2006-09-09  Scott James Remnant  <scott@netsplit.com>

	* configure.ac: Bump version to 0.2.6

	* NEWS: Update.
	* TODO: Update.

	* upstart/control.c (upstart_send_msg_to, upstart_recv_msg): Change
	the magic to be the package string.
	* upstart/tests/test_control.c (test_recv_msg): Update tests.

	* util/initctl.c (main): Set the usage string.
	* util/shutdown.c (main): Set the usage string.
	* util/start.c (main): Set the usage string.
	* compat/sysv/runlevel.c (main): Set the usage string.
	* compat/sysv/telinit.c (main): Set the usage string.

	* man/Makefile.am: Use install-data-hook and $(man8dir)
	* util/Makefile.am: Also use install-exec-hook

	* Makefile.am (SUBDIRS): Install contents of the man directory
	* configure.ac (AC_CONFIG_FILES): Generate man/Makefile
	* man/Makefile.am: Install manpages in the appropriate places.
	* man/init.8, man/logd.8, man/initctl.8, man/reboot.8,
	* man/shutdown.8, man/start.8, man/sulogin.8, man/runlevel.8,
	* man/telinit.8: Include some basic manpages so we at least have
	some level of documentation.

	* init/job.c (job_child_reaper): Don't check the exit status of
	a respawning job if the goal is to stop it.

	* compat/sysv/telinit.c (main): Generate events rather than
	starting and stopping jobs directly, the events are named
	"runlevel-X".  0, 1, 6 and s/S are shutdown events.

	* logd/main.c (main): Raise SIGSTOP before entering the main loop.
	* init/main.c (main): Interlock with logd.

	* event.d/logd: Should not be a console owner, but should stop
	on shutdown.

	* init/process.c (process_setup_console): Revert part of the previous
	change, should just output to /dev/null if we don't have logd.

	* configure.ac: Bump version to 0.2.5

	* init/main.c (main): Start the logd job if it exists.

	* init/process.c (process_setup_console): Ignore ECONNREFUSED as
	that just means that logd isn't around, handle errors by falling
	back to opening the console.

	* init/process.c (process_setup_console): Implement handling for
	CONSOLE_LOGGED and generally clean up the other handling.
	* init/process.h: Update.
	* init/main.c (main): Pass NULL for the job to setup console.
	* TODO: Update.

	* logd/main.c: Implement the logging daemon, it accepts connections
	on a unix stream socket with the abstract name
	"/com/ubuntu/upstart/logd", expects the length of the name and the
	name to follow; then sequences of lines which are logged to
	/var/log/boot, or memory until that file can be opened.

2006-09-08  Scott James Remnant  <scott@netsplit.com>

	* util/shutdown.c (event_setter): Change the event names to
	distinguish between "shutdown -h" and "shutdown -h -H".

	* init/job.c (job_handle_event): Allow jobs to react to their own
	events, this is how we'll do respawn eventually.
	* init/tests/test_job.c (test_handle_event): Remove test.

	* init/main.c (cad_handler, kbd_handler): Generate the new event
	names.
	* init/event.h (CTRLALTDEL_EVENT, KBDREQUEST_EVENT): Add definitions
	of these event names, change the ctrlaltdel event to just that.

	* logd/main.c (main): Add the code to daemonise, etc.

2006-09-07  Scott James Remnant  <scott@netsplit.com>

	* TODO: Long discussion today on #upstart, many improvements to the
	job and event model that make it more elegant.
	* AUTHORS: Include a list of thanks.

	* util/shutdown.c (shutdown_now): If we get ECONNREFUSED when we
	try and send the shutdown event to init, it probably means we're
	still in sysvinit.  So try that instead.
	(sysvinit_shutdown): Function to send a hand-crafted runlevel
	change message across /dev/initctl.

	* util/initctl.c (main): Add a shutdown command that takes an
	arbitrary event name to be issued after "shutdown".  You'll
	nearly always want the /sbin/shutdown tool instead.

	* init/job.c (job_detect_idle): Only generate the stalled event
	if at least one job handles it in its start_events list.
	* init/tests/test_job.c (test_detect_idle): Make sure that works.

	* init/event.h (STARTUP_EVENT, SHUTDOWN_EVENT, STALLED_EVENT):
	Macros to define the standard event names.
	* init/main.c (main): Use STARTUP_EVENT macro instead of "startup"
	* init/control.c (control_handle): Use SHUTDOWN_EVENT macro
	instead of "shutdown".
	* init/job.c (job_detect_idle): Use STALLED_EVENT macro instead
	of "stalled".

	* init/job.c (job_detect_idle): Add some log messages for when we
	detect the idle or stalled states.
	(job_kill_process, job_kill_timer): Increase log verbosity.
	* init/event.c (event_queue_run): Log which events we're handling
	if --debug is given.

	* compat/sysv/telinit.c (main): Send a shutdown command when
	requesting to enter runlevel 0 or runlevel 6, likewise for
	runlevel 1, s or S which all run "rc1" not "rcS".
	* init/main.c (main): When called directory (pid != 1) try and
	run telinit before complaining that we're not init.  Make sure
	errors aren't lost.

2006-09-04  Johan Kiviniemi  <johan@kiviniemi.name>

	* upstart/control.c (upstart_addr): Replace use of __builtin_offsetof
	with offsetof.
	* upstart/tests/test_control.c (test_recv_msg): Likewise.

2006-09-04  Scott James Remnant  <scott@netsplit.com>
	
	* util/shutdown.c (main): Exit normally after sending the warning
	message if -k is given.

2006-09-01  Scott James Remnant  <scott@netsplit.com>

	* configure.ac: Bump version to 0.2.2

	* NEWS: Update.
	* configure.ac: Bump version to 0.2.1

	* init/process.c (process_setup_console): Ensure that the console
	is always initialised to at least /dev/null
	* init/job.c (job_change_state): Initialise event to NULL.
	* init/event.c (event_read_state): Don't mask initialisation of
	other variable.
	* init/cfgfile.c (cfg_job_stanza, cfg_parse_script, cfg_next_token): 
	Print lineno using %zi not %d
	* compat/sysv/runlevel.c (store): Cast pointer type of timeval.

	* init/main.c: Move the kernel headers include beneath the C
	library ones, so that compilation doesn't fail on !i386.
	* util/reboot.c: Likewise.

	* init/main.c (term_handler): Close the control connection if we
	re-exec init, otherwise it won't be able to bind.  Drop debugging.

	* init/main.c (term_handler): It always helps if we dup2 the
	right file descriptor.

	* init/main.c: Use the TERM signal instead of USR1, as old init
	used that for something else.  Also rather than passing across
	file descriptor numbers, use a fixed descriptor and just pass
	"--restart".  When we get that option we need to unmask signals
	otherwise we sit there looking like a lemon.

	* init/job.c (job_change_state): Don't free the event unless we
	generate one.

	* NEWS: Update.

	* init/cfgfile.c (cfg_watcher): Ignore any file with '.' or '~'

	* TODO: Update.

	* init/main.c (main): Parse command-line arguments, specifically
	look for --state-fd which we'll use for reexec.  Don't do a couple
	of things if we're passed this.
	(read_state): Parse the line-buffered state.
	* init/job.c (job_read_state, job_write_state): Job state
	serialisation so that we can re-exec ourselves.
	* init/job.h: Update.
	* init/tests/test_job.c: Test the serialisation.
	* init/event.c (event_read_state, event_write_state): And similar
	functions for serialising the event queue.
	* init/event.h: Update.
	* init/tests/test_event.c: Test the serialisation.
	* init/cfgfile.c (cfg_read_job): Fix a bug, need to subtract current
	time to get due time.

	* upstart/job.c (job_goal_from_name, job_state_from_name) 
	(process_state_from_name): Add opposite numbers that convert a
	string back into an enumeration.
	* upstart/job.h: Update.
	* upstart/tests/test_job.c: Test the new functions.

2006-08-31  Scott James Remnant  <scott@netsplit.com>

	* init/job.h (Job): Add respawn_limit, respawn_interval,
	respawn_count and respawn_time members so that we can keep track of
	runaway processes.
	* init/job.c (job_catch_runaway): Increment the respawn_count
	within respawn_interval, or reset it if we go over.
	(job_new): Initialise respawn_limit and respawn_interval to sensible
	defaults.
	* init/tests/test_job.c (test_new): Check the defaults are set.
	(test_change_state): Check the respawning code works.
	* init/cfgfile.c (cfg_job_stanza): Parse the "respawn limit" stanza.
	* init/tests/test_cfgfile.c (test_read_job): Test the new stanza.

	* init/process.c (process_setup_console): Remove the console reset
	code, it tends to just crash X and seems to do nothing interesting.
	* init/main.c (reset_console): Instead put it here and just do it
	on startup.

	* configure.ac: Bump version to 0.2.0

	* util/Makefile.am (install-exec-local): Create symbolic links,
	not hard links.

	* init/main.c: Can't catch STOP.

	* util/reboot.c: Pause init while shutting down or rebooting.

	* init/main.c (stop_handler): Catch STOP/TSTP and CONT.
	* init/event.c (event_queue_run): Don't run the event queue while
	paused.
	* init/job.c (job_detect_idle): Don't detect idle jobs while paused.

	* util/reboot.c: if we get the -w argument ("only write to wtmp")
	we need to exit, and not behave as halt normally would.

	* compat/sysv/runlevel.c (main): Add missing newline.
	* compat/sysv/telinit.c (main): And here too.

	* init/main.c (main): Check for idle after the startup event queue
	has been run, otherwise we may just sit there.

	* compat/sysv/Makefile.am (sbin_PROGRAMS): Build and install telinit
	(telinit_SOURCES, telinit_LDFLAGS, telinit_LDADD): Details for
	telinit binary.
	* compat/sysv/telinit.c: Trivial telinit program that just runs
	the appropriate rcX job.
	* compat/sysv/runlevel.c (main): Suggest help on illegal runlevel.

	* util/Makefile.am: Tidy up.

	* configure.ac (AC_CONFIG_FILES): Create compat/sysv/Makefile
	* Makefile.am (SUBDIRS): Build things found in compat/sysv
	* compat/sysv/Makefile.am (sbin_PROGRAMS): Build and install runlevel
	(runlevel_SOURCES, runlevel_LDFLAGS, runlevel_LDADD): Details for
	runlevel binary.
	* compat/sysv/runlevel.c: Helper to store and retrieve the current
	"runlevel" from utmp/wtmp; as well as the reboot time.

	* init/main.c (main): Drop debugging set.

	* init/job.c (job_change_state): As well as the job/state events,
	send the job event when a service is running or a task is stopping.
	* init/tests/test_job.c (test_change_state): Check the events get
	sent properly.

	* util/start.c: Write a simple utility to start, stop, or query
	the status of the named jobs.
	* util/Makefile.am (sbin_PROGRAMS): Build and install start
	(start_SOURCES, start_LDFLAGS, start_LDADD): Details for start
	(install-exec-local): Also install as stop and status.
	* util/reboot.c (main): Drop the debugging set.

	* init/cfgfile.c (cfg_job_stanza): Correct nih_alloc error.

	* init/process.c (process_setup_environment): Guard memory alloc.
	* init/job.c (job_set_idle_event): Likewise.
	(job_change_state): And here too.
	(job_run_command): Likewise.
	* init/control.c (control_send): Likewise.
	* init/cfgfile.c: And throughout this file.
	* upstart/control.c (upstart_recv_msg): And once here too.

	* upstart/control.h: Abolish the separate halt, reboot and poweroff
	messages and replace with a single shutdown message that takes
	an event name (for the idle event issued afterwards).
	* upstart/control.c (upstart_send_msg_to, upstart_recv_msg): Handle
	the new shutdown event type by just treating it as an event.
	* upstart/tests/test_control.c (test_messages): Update tests.
	* init/job.c (job_set_idle_event): Store a copy of the idle event
	name.
	* init/control.c (control_send): Copy the shutdown event name.
	(control_handle): Replace individual handling with the new
	single event.
	* init/tests/test_control.c (test_watcher): Update.
	* util/initctl.c: Drop handling for things that shutdown does now.
	* util/shutdown.c: Send the UPSTART_SHUTDOWN event and let the user
	specify anything they want, just give defaults.

	This is quite a big change and abolishes level events entirely,
	along with the event history.  We now just treat events as a
	transient queue of strings that go past, may cause things to change,
	but are otherwise forgotten.  This turns out to be much easier to
	understand and has no real loss of power.

	* init/event.c: Vastly simplify; gone are the separate notions of
	edge and level events, instead we just treat them as one-shot
	things that go past and are forgotten about.
	* init/event.h (Event): Remove value member.
	Update prototypes.
	* init/tests/test_event.c: Update.
	* init/job.c (job_change_state): Change the event pattern to be
	one that includes the job name and a description of the transition
	instead of the new state.
	(job_detect_idle): Call event_queue rather than event_queue_edge.
	* init/tests/test_job.c: Update.
	* init/cfgfile.c (cfg_job_stanza): Drop "when" and "while".
	* init/tests/test_cfgfile.c (test_read_job): Drop mentions of
	"when" and "while".
	* init/control.c (control_send, control_handle): Drop cases for
	level events.
	(control_handle_event): Don't include a level in the event.
	* init/tests/test_control.c: Update
	* init/main.c: Call event_queue rather than event_queue_edge.
	* upstart/control.c (upstart_send_msg_to, upstart_recv_msg): Change
	event handling so that only a name is read.
	* upstart/control.h: Remove value/level event structures.
	* upstart/tests/test_control.c (test_messages): Update.
	* upstart/job.c (process_state_name): Not used for events, adjust
	documentation so it doesn't lie.
	* util/initctl.c (main): Drop the set function, simplify trigger.
	* util/shutdown.c (shutdown_now): Call UPSTART_EVENT_QUEUE for
	shutdown into maintenance mode.

	* init/control.c (control_handle): Place a message in the syslog
	before halting, powering off or rebooting.

	* util/shutdown.c: Adjust so that the warning message is sent out
	if shutdown is immediate, and when it actually happens.  Include
	the hostname as wall does.

2006-08-30  Scott James Remnant  <scott@netsplit.com>

	* TODO: Update.

	* util/shutdown.c: Implement shutdown utility along the same lines
	as the sysvinit one, but with rather different code.

	* util/initctl.c (main): Call setuid on the effective user id so
	that we can be made setuid root and executable by a special group.
	* util/reboot.c (main): Likewise.

	* util/initctl.c (main): Check the effective rather than the real
	user id, if we're effectively root, that's good enough.

	* util/reboot.c: Implement reboot/halt/poweroff utility.
	* util/Makefile.am (sbin_PROGRAMS): Build and install reboot
	(reboot_SOURCES, reboot_LDFLAGS, reboot_LDADD): Details for reboot
	(install-exec-local): Create hardlinks to reboot for halt and poweroff.

2006-08-29  Scott James Remnant  <scott@netsplit.com>

	* init/main.c (main): Actually run the idle-detect function.
	* init/job.c (job_detect_idle): Interrupt the main loop, otherwise
	we may end up waiting for a signal before we process the event
	we just issued.

2006-08-27  Scott James Remnant  <scott@netsplit.com>

	* util/shutdown.c: Template main function.
	* util/Makefile.am (sbin_PROGRAMS): Build and install the
	shutdown binary.
	(shutdown_SOURCES, shutdown_LDFLAGS, shutdown_LDADD): Details for
	the shutdown binary

	* util/initctl.c (main): Add commands for halt, poweroff and reboot.

	* init/event.c (event_queue_run): Remove the parameters.
	* init/event.h: Update.
	* init/main.c (main): Update.
	* init/tests/test_control.c (test_watcher): Update.
	* init/tests/test_job.c (test_detect_idle): Update.

	* upstart/control.c (upstart_send_msg_to, upstart_recv_msg): Deal
	with halting, rebooting and powering off; or at least the appropriate
	messages.
	* upstart/control.h: Add control message structures for halting,
	powering off and rebooting the machine.
	* upstart/tests/test_control.c (test_messages): Run the tests.
	* init/control.c (control_handle): Add handling for halt, power off
	and reboot that issue the shutdown event and arrange for the halt,
	poweroff or reboot to be issued the next time the system is idle.
	* init/tests/test_control.c (test_watcher): Test the events.

	* TODO: Update.

	* init/job.c (job_detect_idle): Function to detect when the system is
	stalled or idle.
	* init/job.h: Update
	* init/tests/test_job.c (test_detect_idle): Test the new function.

	* util/initctl.c (main): Handle the list command.

	* TODO: Update.

	* upstart/control.c (WireJobStatusPayload): add description to the
	job status payload.
	(upstart_send_msg_to, upstart_recv_msg): Send and receieve the
	description over the wire.
	* upstart/control.h (UpstartJobStatusMsg): add a description field
	* upstart/tests/test_control.c: Update test cases.
	* init/control.c (control_handle): Include the job description in
	the message.
	(control_send): Copy the description when we put the message on
	the queue.
	(control_handle_job): Copy the description here too
	* init/tests/test_control.c: Update test cases.

	* init/job.c (job_list): Add a function to return the job list.
	* init/job.h: Update.
	* init/control.c (control_handle): Handle the JOB_LIST message
	by sending back a list of job status messages followed by the
	JOB_LIST_END message.
	* init/tests/test_control.c (test_watcher_child): Check the
	JOB_LIST message works properly.

	* upstart/control.c (upstart_send_msg_to, upstart_recv_msg): Handle
	the JOB_LIST and JOB_LIST_END messages which have no payload.
	* upstart/control.h: Add enums and structures for job list messages.
	* upstart/tests/test_control.c (test_messages): Update tests.

	* init/main.c (main): Check that we're both uid and process #1

	* init/main.c (main): Stop handling SIGTERM, we never want people
	to kill init.  Handle SIGINT and SIGWINCH through the ordinary
	handler and SIGSEGV through a direct handler.
	(segv_handler): Write a sensible core dump handler, we use a child
	to dump core while we carry on in the parent hopefully stepping over
	the bad instruction.
	(cad_handler): Generate the control-alt-delete event.
	(kbd_handler): Generate the kbdrequest event.

2006-08-25  Scott James Remnant  <scott@netsplit.com>

	* configure.ac: Bump version to 0.1.2
	* NEWS: Update.

	* TODO: Update.

	* init/process.c (process_setup_environment): Inherit the PATH
	and TERM environment variables from the init process, so the
	console works properly.
	* init/process.h (PATH): Declare a default value for this variable
	* init/main.c (main): Set the value of PATH to the default.
	* init/tests/test_process.c (child): Update test case.

	* NEWS: Update.
	* configure.ac: Bump version to 0.1.1

2006-08-24  Scott James Remnant  <scott@netsplit.com>

	* init/cfgfile.h (CFG_DIR): Change configuration directory to
	/etc/event.d -- it's not been used by anyone, but is similar to
	other directories that have which is a good precedent.
	* event.d/Makefile.am (eventdir, dist_event_DATA): Install files
	into the new directory name.
	* Makefile.am (SUBDIRS): Rename sub directory
	* configure.ac (AC_CONFIG_FILES): Rename generated Makefile

	* init/Makefile.am (DEFAULT_INCLUDES): Set to include the right
	directories so out of tree builds work.
	* logd/Makefile.am (DEFAULT_INCLUDES): Set to include the right
	directories so out of tree builds work.
	* upstart/Makefile.am (DEFAULT_INCLUDES): Set to include the right
	directories so out of tree builds work.
	(upstartinclude_HEADERS): Install errors.h
	* util/Makefile.am (DEFAULT_INCLUDES): Set to include the right
	directories so out of tree builds work.

	* Makefile.am (SUBDIRS): Add m4 to the list
	* configure.ac (AC_CONFIG_FILES): Generate m4/Makefile
	* upstart/Makefile.am (upstartinclude_HEADERS): Add errors.h

	* upstart/control.c (upstart_open): 

	* init/control.c (control_open): Raise the error before
	performing other actions so errno is not lost.

	* TODO: Update.o
	* init/cfgfile.c (cfg_next_token): Don't count quote characters
	unless we're actually planning to dequote the file, otherwise we
	end up allocating short.

	* init/control.c (control_close): Free the io_watch using list_free
	in case a destructor has been set.
	* init/tests/test_control.c: Initialise the type of the message, and
	free job correctly.

	* upstart/tests/test_control.c: Fix overwrite of buffer.
	* init/tests/test_job.c: Clean up not-freed job.

2006-08-23  Scott James Remnant  <scott@netsplit.com>

	* init/tests/test_event.c: free the entry allocated and initialise
	the return values.

	* init/cfgfile.c (cfg_skip_token): Drop this function; we'll
	make sure *pos is pointing at the start of the thing we want
	to parse, not the first token.  Update the other functions
	accordingly.
	(cfg_read_job): Implement function to look over a job file and
	parse all of the stanzas that are found.  Also sanity checks the
	job afterwards and deals with reloading existing jobs.
	(cfg_job_stanza): Function that parses an individual stanza,
	calling out to the other parse functions; this is the main config
	file parser!
	(cfg_parse_args, cfg_parse_command): Drop requirement that filename
	and lineno be passed, so we can be called to reparse arguments after
	we've already done so.
	(cfg_parse_script): Remove requirement that it be called at the
	start of the entire stanza, and instead at the start of the script.
	When hitting EOF, return the script so far, not NULL.
	(cfg_parse_args): Correct bug where we didn't check sufficient
	characters while skipping whitespace.
	(cfg_next_token): Correct bug where we didn't copy the character
	after a slash into the text, instead of just not copying the slash.
	Adjust line numbers to match the fact that it's zero based now.
	* init/cfgfile.h: Define prototype.
	* init/tests/test_cfgfile.c (test_read_job): Pretty thoroughly
	test the config file parser code.

2006-08-22  Scott James Remnant  <scott@netsplit.com>

	* init/cfgfile.c (cfg_tokenise): Rename to cfg_next_token.
	(cfg_skip_token): Code to skip whitespace, token and whitespace.
	(cfg_parse_args): Function to parse an argument list.
	(cfg_next_token): Extend to support the removal of quotes and
	slashes from the token.

	* init/cfgfile.c (cfg_parse_script): Pass filename and lineno and
	increment the latter as we go.
	(cfg_script_end): Pass and increment lineno.

	* init/cfgfile.c: Correct a missing semi-colon in prototypes.
	(cfg_parse_command): Function to parse any stanza that requires
	a command and arguments list, e.g. exec/respawn/daemon.  We don't
	want to require that the list be quoted, etc. and do want to allow
	it to be folded over lines.
	(cfg_tokenise): Function used by the above to tokenise the file,
	handling things like \, quoted strings and newlines, etc.  Can be
	used both to determine the length of the token and to copy it.

	* init/cfgfile.c (cfg_read_script): Rename to cfg_parse_script.

	* init/cfgfile.c (cfg_read_script): Function to parse a script
	fragment ("foo script\n....end script\n") from the job file, which
	is the most complex form we can find.  Write it assuming the file is
	in a character array which may not be NULL terminated (ie. a mmap'd
	file).
	(cfg_script_end): Used by the above to detect the end of the
	fragment.
	* init/cfgfile.h: Empty header file.
	* init/Makefile.am (init_SOURCES): Build and link cfgfile.c
	using the cfgfile.h header
	(TESTS): Build and run the config file test cases.
	(test_cfgfile_SOURCES, test_cfgfile_LDFLAGS, test_cfgfile_LDADD):
	Details for config file test case binary.

	* init/main.c (main): Remove the calls to the unfinished config
	file code.

2006-08-21  Scott James Remnant  <scott@netsplit.com>

	* init/main.c: Add missing include for unistd.h
	* init/process.c (process_setup_console): Drop use of job.
	* util/initctl.c (main): Check that we're run as root.

	* init/main.c (main): Write the main function

	* init/event.c (event_queue_cb): Rename to event_queue_run.
	* init/event.h: Update.

	* init/process.c (process_setup_console): Become an exported
	function that includes the code to reset a console.

2006-08-19  Scott James Remnant  <scott@netsplit.com>

	* logd/main.c (main): Write the basic main function.

	* util/initctl.c (main): Fill in the details to give us a basic
	test client.

	* TODO: Update.

	* util/initctl.c (main): Provide the most basic main function.
	* util/Makefile.am (sbin_PROGRAMS): Build the initctl binary
	* Makefile.am (SUBDIRS): Build the utilities.
	* configure.ac (AC_CONFIG_FILES): Generate the util Makefile.

2006-08-18  Scott James Remnant  <scott@netsplit.com>

	* init/Makefile.am (test_job_LDADD): Remove the duplicate link.

	* TODO: Update.

	* init/job.c (job_handle_child): Rename to job_child_reaper.
	* init/job.h: Update.
	* init/tests/test_job.c: Update function names.

	* init/control.c (control_cb): Rename to control_watcher
	* init/tests/test_control.c: Update function names.

	* TODO: Update.

	* Makefile.am (SUBDIRS): Install the rc.d files.
	* configure.ac (AC_CONFIG_FILES): Generate the rc.d Makefile.
	* rc.d/Makefile.am (rcdir): Define rcdir to be /etc/rc.d
	(dist_rc_DATA): Install the logd file into that directory.
	* rc.d/logd: Write a simple service definition for the log daemon,
	this saves us hardcoding any information about it into init; it'll
	just need to know the name.

	* Makefile.am (SUBDIRS): Build the logd daemon
	* configure.ac (AC_CONFIG_FILES): Generate the logd Makefile.
	* logd/Makefile.am (sbin_PROGRAMS): Install the logd binary into
	the sbin directory by default.
	(logd_SOURCES): Build and link main.c
	* logd/main.c (main): Add basic main function for testing purposes.

2006-08-16  Scott James Remnant  <scott@netsplit.com>

	* init/job.c (job_start): Ignore self-dependencies; over-document
	why the dependency event prodding has a surprise in its tail.
	(job_change_state): Move the job_release_depends call to here.

	* init/event.c (event_queue_cb): Add event consumer/dispatcher.
	* init/event.h: Update.

	* init/control.c (control_send): Make the event code clearer.
	(control_handle): Handle the changed event semantics.
	(control_handle_event): Issue the new event type.
	* init/tests/test_control.c: Update tests.

	* upstart/control.c (upstart_send_msg_to, upstart_recv_msg): Adjust
	marshal code to match.
	* upstart/control.h: Update all structures appropriately to the
	previous changes.
	* upstart/tests/test_control.c: Update.

	* init/job.c (job_change_state): Change call to event_trigger_level
	to event_queue_level.

	* init/event.c (event_trigger_edge, event_trigger_level): Place
	the event on the event_queue rather than directly triggering it.
	Rename to event_queue_edge and event_queue_level respectively.
	* init/event.h: Update.
	* init/tests/test_event.c: Update test cases.

	* init/job.c (job_handle_event): Add another sanity check, jobs
	should not be able to react to their own events; that's just silly.
	* init/tests/test_job.c (test_handle_event): Check that the new
	condition does the right thing.
	
	* init/job.c (job_change_state): Make it illegal for a job to exist
	without either a command or script or both.  This is for sanity
	reasons, allowing no primary process makes no sense and can lead
	to event loops if someone is feeling nefarious.
	* init/tests/test_job.c (test_change_state): Drop test on behaviour
	we've just outlawed.

	* init/job.c (job_start): Only announce the change if we're still
	in the waiting state, we could have moved on to running already.

	* init/job.c (job_start): If holding the job, at least announce
	the goal change to subscribed clients.

	* TODO: Update.

	* init/job.c (job_start): Check for dependencies before starting
	the process, if we have any that aren't running we stay in waiting
	until they are.  Any that aren't even starting get poked with a
	dependency event to see whether that wakes them up.
	* init/tests/test_job.c (test_start): Test paths through new
	dependency code.

	* init/job.c (job_run_process): Once we've got an active process
	in the running state, release our dependencies.

	* init/job.c (job_release_depends): Function to release any waiting
	dependencies on the given job.
	* init/job.h: Update.
	* init/tests/test_job.c (test_release_depends): Test the behaviour
	of the function on its own.

	* init/job.h (Job): Add depends list field
	(JobName): New structure to hold the name of a job.
	* init/job.c (job_new): Initialise the depends list.
	* init/tests/test_job.c (test_new): Make sure the depends list is
	initialised properly.

	* init/job.c (job_next_state): Return JOB_STARTING if we're in
	JOB_WAITING and the goal is JOB_START.  This is only called when
	there's some change, and I don't want to hard-code the goal there.
	(job_start): Don't hardcode JOB_STARTING, instead just use the next
	state.
	* init/tests/test_job.c (test_next_state): Adjust test case.

	* init/control.c (control_subscribe): Allow the current
	subscription to be found by passing NOTIFY_NONE.
	(control_handle): Don't remove an existing subscription to jobs,
	a GUI will probably want a permanent one to keep the status up to
	date.

	* init/job.c (job_kill_process, job_kill_timer): Don't hardcode
	JOB_STOPPING here, instead move to the next logical state. 
	(job_kill_process): Notify subscribed processes that we killed
	the job.
	(job_start, job_stop): Notify subscribed processes of a change of
	goal that doesn't result in an immediate state change.

	* init/event.c (event_trigger_edge, event_trigger_level): Swap
	order so that events are announced before processed.

	* init/control.c (control_handle): Handle requests to watch and
	unwatch jobs and events.
	* init/tests/test_control.c (test_cb_child, test_cb): Check that
	subscriptions work.

	* init/tests/test_control.c (test_cb_child): Add a sleep to avoid
	a race that upsets gdb, have tried this with a STOP/CONT interlock
	but can't seem to find where the child should reach first.

	* init/job.c (job_change_state): Notify the control handler.
	* init/event.c (event_trigger_edge, event_trigger_level): Pass
	event to the control handler.
	* init/tests/test_control.c (test_cb_child): Expect to receive
	job status events as well.
	* init/Makefile.am (test_event_LDADD, test_process_LDADD) 
	(test_job_LDADD): Add control.o to the linkage.

	* init/control.c (control_cb): Don't display an error for
	ECONNREFUSED, just remove any subscriptions.
	* init/tests/test_control.c (test_handle_job, test_handle_error):
	Clean up our subscriptions properly.

	* init/control.c (control_handle_job): Function to send out an
	UPSTART_JOB_STATUS message to subscribed processes whenever a
	job state changes.
	(control_handle_event): Function to send out an
	UPSTART_EVENT_TRIGGERED message to subscribed processes whenever
	an event is triggered.
	* init/control.h: Update.
	* init/tests/test_control.c (test_handle_job, test_handle_event):
	Check that the functions work properly.

	* init/control.c (control_handle): Handle messages that trigger
	edge and level events; subscribe the process to receive notification
	of job changes during the event.
	* init/tests/test_control.c (test_cb_child): Check that the messages
	are handled properly (without subscription check).

	* init/control.c (control_cb): Unsubscribe a process if it stops
	listening.

	* init/control.c (control_send): Copy the pointers in the new
	event messages.
	* init/tests/test_control.c (test_send): Check the pointers are
	copied across correctly.

	* init/control.c (control_subscribe): Add function to handle
	processes that want to subscribe to changes.
	(control_init): Initialise the subscriptions list.
	* init/control.h: Add structures and prototypes.
	* init/tests/test_control.c (test_subscribe): Test the function.

	* upstart/control.h (UpstartMsgType): add messages for triggering
	edge and level events, receiving the trigger for an event and for
	watching jobs and events.
	(UpstartEventTriggerEdgeMsg, UpstartEventTriggerLevelMsg)
	(UpstartEventTriggeredMsg, UpstartWatchJobsMsg)
	(UpstartUnwatchJobsMsg, UpstartWatchEventsMsg):
	(UpstartUnwatchEventsMsg): Add structures for the new messages.
	(UpstartMsg): And add them to the union.
	* upstart/control.c (WireEventPayload): The event messages can all
	share a wire payload type; the watch messages don't need any special
	payload.
	(upstart_send_msg_to): Add the payloads onto the wire.
	(upstart_recv_msg): And take the payloads back off the wire.
	* upstart/tests/test_control.c (test_messages): Test the new
	message types.

	* upstart/control.h (UpstartJobStatusMsg): add a process id.
	* upstart/control.c (WireJobStatusPayload): and here too.
	(upstart_send_msg_to): copy the process id onto the wire.
	(upstart_recv_msg): copy the process id from the wire.
	* init/control.c (control_handle): Fill in the pid from the job.
	* upstart/tests/test_control.c (test_messages): Check the pid gets
	passed across the wire properly.

	* init/control.c (control_cb): Disable the poll for write once the
	send queue becomes empty.

	* upstart/Makefile.am (libupstart_la_SOURCES): Correct ordering.

	* init/control.c (control_handle): Add missing break.

	* upstart/job.c (job_goal_name, process_state_name): For completeness
	add these two functions as well.
	* upstart/job.h: Update.
	* upstart/tests/test_job.c (test_goal_name) 
	(test_process_state_name): Test the new functions.

	* init/job.c (job_state_name): Move this utility function from here
	* upstart/job.c (job_state_name): to here so all clients can use
	it.
	* init/job.h: Update.
	* upstart/job.h: Update.
	* init/tests/test_job.c (test_state_name): Move the test case from here
	* upstart/tests/test_job.c: to here as well.
	* upstart/Makefile.am (libupstart_la_SOURCES): Build and link job.c
	(TESTS): Run the job test cases
	(test_job_SOURCES, test_job_LDFLAGS, test_job_LDADD): Details for
	job test case binary.
	* init/Makefile.am (test_job_LDADD, test_process_LDADD) 
	(test_event_LDADD): Link to libupstart.la

	* init/control.c: Code to handle the server end of the control
	socket, a bit more complex than a client as we want to avoid
	blocking on malcious clients.
	* init/control.h: Prototypes.
	* init/tests/test_control.c: Test the control code.
	* init/Makefile.am (init_SOURCES): Build and link control.c
	using the control.h header
	(init_LDADD): Link to libupstart as well
	(TESTS): Build and run the control test suite.
	(test_control_SOURCES, test_control_LDFLAGS, test_control_LDADD):
	Details for control test suite binary.

	* upstart/control.c: Add a way to disable the safety checks.
	* upstart/tests/test_control.c (test_free): Fix bad test case.

	* upstart/control.c (upstart_recv_msg): fixed bogus return type
	for recvmsg from size_t to ssize_t so we don't infiniloop on error.

	* upstart/control.c (upstart_send_msg_to, upstart_recv_msg): Avoid
	job_start as the short-cut for assigning name, as that might become
	a more complex message eventually.  Use job_query instead.

	* upstart/control.c (upstart_free): Add wrapper function around
	nih_free so we're a proper library and don't expose libnih too much
	(upstart_recv_msg): Stash the sender pid in an argument.
	* upstart/control.h: Update.
	* upstart/tests/test_control.c (test_recv_msg): Test pid is
	returned properly.
	(test_free): Test the nih_free wrapper.

	* init/job.c (job_run_script): Document future FIXME.

	* init/exent.h, init/job.h, init/process.h: Fix up headers.

	* upstart/control.c, upstart/control.h, upstart/errors.h,
	upstart/job.h, upstart/libupstart.h: Fix up headers.

	* upstart/control.c: Write the code to handle the control socket
	and communication over it; turns out this was possible to write so
	that both ends are handled in the same code.
	* upstart/control.h: Structures and prototypes.
	* upstart/tests/test_control.c: Test the new code.

	* upstart/Makefile.am (libupstart_la_LIBADD): Link to libnih

	* upstart/errors.h: Header file containing errors raised by
	libupstart.
	* upstart/libupstart.h: Include errors.h

2006-08-15  Scott James Remnant  <scott@netsplit.com>

	* init/event.h: Add missing attribute for event_new()

	* init/job.h (JobGoal, JobState, ProcessState, ConsoleType): Move
	the enums from here
	* upstart/job.h: into here so that we can use them across the
	control socket.

	* Makefile.am (SUBDIRS): Build the libupstart library
	* configure.ac (AC_CONFIG_FILES): Generate upstart/Makefile
	* upstart/Makefile.am: Makefile for sub-directory
	* upstart/libupstart.ver: Linker version script.
	* upstart/libupstart.h: "Include everything" header file.

	* TODO: Update.

	* init/job.c (job_handle_child): Warn when processes are killed
	or exit with an abnormal status.  Warn when respawning.

	* init/job.c (job_handle_child): Respawn processes that were not
	supposed to have died.
	* init/tests/test_job.c (test_handle_child): Test the respawn code.

	* TODO: Update.

	* init/event.c (event_trigger_edge, event_trigger_level): Call
	job_handle_event so that we actually do something useful.
	* init/Makefile.am (test_event_LDADD): Link to process.o and job.o
	now that event.c calls code from job.

	* init/job.c (job_start_event): Function to start a job if an event
	matches.
	(job_stop_event): Function to stop a job if an event matches.
	(job_handle_event): Iterate the job list and dispatch the given event,
	causing jobs to be stopped or started using the above two functions.
	* init/job.h: Update.
	* init/tests/test_job.c: Test the new functions.

	* init/job.c (job_new): Initialise start_events and stop_events to
	an empty list.
	* init/job.h (Job): Add start_events and stop_events list heads.
	* init/tests/test_job.c (test_new): Check the lists are initialised
	correctly to the empty list.

	* init/event.c (event_match): Function to check events for equality.
	* init/event.h: Update.
	* init/tests/test_event.c (test_match): Test function.

	* init/job.c (job_change_state): Trigger the level event with the
	same name as the job, with the value taken from the state.
	* init/tests/test_job.c (test_change_state): Check the event
	gets set to the right values as we go.
	* init/Makefile.am (test_job_LDADD, test_process_LDADD): Link to
	event.o now that job.c uses code from there.

	* init/event.c (event_change_value): Rename event_set_value to this
	as we intended in the first place; makes it more consistent with job.
	Always change the value.
	(event_trigger_edge): Add a high-level function to trigger an edge
	event.
	(event_trigger_level): And another to trigger a level event with
	a given value, this inherits the "don't change it" functionality
	that was in event_set_value.
	* init/event.h: Update.
	* init/tests/test_event.c: Test new behaviours and functions.

	* init/event.c: Add simple code to keep track of events, whether
	they have been recorded or not and their current value if any.
	* init/event.h: Structures and prototypes.
	* init/tests/test_event.c: Test cases for event code.
	* init/Makefile.am (init_SOURCES): Build and link event.c using event.h
	(TESTS): Run the event test suite.
	(test_event_SOURCES, test_event_LDFLAGS, test_event_LDADD): Details
	for event test suite binary.

	* init/job.c (job_run_process, job_kill_process, job_kill_timer):
	Downgrade error messages to warning as they're not fatal.
	(job_change_state): Change info message to be more regular.

	* init/job.c (job_start): A very simple, but very necessary, function.
	Set the goal of the given job to JOB_START and kick it off.
	(job_stop): And its companion, cause a running job to be stopped.
	* init/job.h: Update.
	* init/tests/test_job.c: Test the functions.

	* init/job.c (job_handle_child): Child handler to kick jobs into
	the next state when their process dies.
	* init/job.h: Update.
	* init/tests/test_job.c (test_handle_child): Test the handler
	directly by just invoking it with various job states.

2006-08-14  Scott James Remnant  <scott@netsplit.com>

	* init/tests/test_process.c (test_kill): Use select rather than
	poll for consistency with other test cases.

	* init/job.c (job_kill_process): Add function to send the active
	process of a job the TERM signal, and then set a timer to follow
	up with the KILL signal if the job doesn't get cleaned up in time.
	(job_kill_timer): Timer callback to send the KILL signal; this
	does the same job as the child handler and puts the job into the
	next state as there's no point waiting around now.
	* init/job.h: Update.
	* init/tests/test_job.c (test_kill_process): Test both functions
	in one test case (as one is just the bottom half of the other).

	* init/tests/test_process.c (test_spawn): Use the right thing in
	the test case filename and unlink it to make sure.

	* init/job.c (job_change_state): Write the principal state gate
	function, called once a state has been left to enter the given new
	state (which one should determine with job_next_state).  Spawns
	the necessary processes or moves to the next appropriate state.
	* init/job.h: Update.
	* init/tests/test_job.c: Test the state changes.

	* init/job.c (job_run_process): Internal function to call
	process_spawn and update the job structure.
	(job_run_command): Simple(ish) wrapper for the above to split
	a command by whitespace, or use a shell if it needs more complex
	argument processing.
	(job_run_script): More complex wrapper that uses a shell to execute
	verbatim script, either using -c or a /dev/fd/NN and feeding the
	shell down a pipe to it.
	* init/job.h: Update.
	* init/tests/test_job.c: Test the new functions.

	* init/Makefile.am (init_SOURCES, TESTS): Reorder so that process.c,
	which is arguably lower level, comes first.
	(test_job_LDADD): Link the process code.
	(test_process_LDADD): Swap the order.

	* TODO: Update.

	* init/process.c (process_spawn): Correct typo (progress -> process),
	thanks Johan.

2006-08-12  Scott James Remnant  <scott@netsplit.com>

	* init/process.c (process_spawn): Correct formatting of function.
	* init/process.h (SHELL): Define the location of the shell, all in
	the spirit of not hard-coding stuff like this.

	* init/job.c (job_new): Initialise all structure members to zero
	as this doesn't happen automatically.

2006-08-10  Scott James Remnant  <scott@netsplit.com>

	* init/job.h (job_state_name): Declare as a const function.

2006-08-09  Scott James Remnant  <scott@netsplit.com>

	* init/job.c (job_next_state): State transition logic; this uses
	our departure from the specification (the goal) so that the state
	can always be currently accurate rather than suggestive.
	(job_state_name): Cute function to convert enum into a name.
	* init/job.h: Update.
	* init/tests/test_job.c (test_next_state): Test the transitions.
	(test_state_name): And the return values.

	* TODO: Add file to keep track of things.

	* init/job.c: Include nih/macros.h and nih/list.h
	* init/process.c: Include order fixing, include nih/macros.h
	* init/tests/test_job.c: Include nih/macros.h and nih/list.h
	* init/tests/test_process.c: Include nih/list.h

	* init/job.c: Include order fixing.
	(job_find_by_name): Function to find a job by its (unique) name.
	(job_find_by_pid): Function to find a job by the pid of its process.
	* init/job.h: Update.
	* init/tests/test_job.c (test_find_by_name, test_find_by_pid): Test
	new functions.

	* init/process.c (process_spawn): Spawn a process using the job
	details to set up the environment, etc.
	(process_setup_console): Set up the console according to the job.
	(process_setup_limits): Set up the limits according to the job.
	(process_setup_environment): Set up the environment according to
	the job.
	(process_kill): Simple function to send a kill signal or raise an
	error; mostly just a wrapper without any particular logic.
	* init/process.h: Prototypes and macros.
	* init/tests/test_process.c: Test cases.
	* init/Makefile.am (init_SOURCES): Build and link process.c and
	its header file.
	(TESTS): Run the process test suite.
	(test_process_SOURCES, test_process_LDFLAGS, test_process_LDADD):
	Details for process test sutie binary.

2006-08-08  Scott James Remnant  <scott@netsplit.com>

	* init/job.c (job_new): nih_list_free is necessary.
	* init/tests/test_job.c (test_new): Free job when done.

	* init/job.h: Header file to contain the definition of the Job
	structure and associated typedefs, etc.
	(JobGoal): In a divergence from the specification, we introduced a
	"goal" for a job which tells us which way round the state machine
	we're going (towards start, or towards stop).
	(JobState): Which means this always holds the current state, even
	if we're trying to get out of this state (ie. if we've sent the TERM
	signal to the running process, we're still in the running state until
	it's actually been reaped).
	(ProcessState): And in another divergence, we keep the state of the
	process so we know whether we need to force a state transition or
	can just expect one because something transient is happening.
	* init/job.c (job_new): Function to allocate a Job structure, set
	the pointers to NULL and other important members to sensible
	defaults.
	(job_init): Initialise the list of jobs.
	* init/tests/test_job.c: Test suite.
	* init/Makefile.am (init_SOURCES): Compile and link job.c using
	its header file.
	(TESTS): Run the job test suite.
	(test_job_SOURCES, test_job_LDFLAGS, test_job_LDADD): Details for the
	job test suite binary.

2006-08-02  Scott James Remnant  <scott@netsplit.com>

	* configure.ac: Check for C99

	* HACKING: Document dependency on libnih.

2006-07-27  Scott James Remnant  <scott@netsplit.com>

	* init/Makefile.am (DEFS): Append to the default DEFS list, rather
	than overriding, otherwise we lose HAVE_CONFIG_H

2006-07-13  Scott James Remnant  <scott@netsplit.com>

	* HACKING: Correct incorrect Bazaar URL.

	* AUTHORS: Change e-mail address to ubuntu.com.
	* HACKING: Update Bazaar and Release URLS.
	* configure.ac (AC_COPYRIGHT): Change copyright to Canonical Ltd.
	(AC_INIT): Change bug submission address to Launchpad.
	* init/main.c: Update header to use Canonical copyright and
	credit me as author.

2006-05-16  Scott James Remnant  <scott@netsplit.com>

	* init/main.c: Add the simplest template main.c
	* init/Makefile.am: Add template Makefile.am that builds init from
	main.c and links to libnih statically
	* configure.ac (AC_CONFIG_FILES): Configure nih and init subdirs.
	* Makefile.am (SUBDIRS): Recurse into nih and init subdirs.

2006-05-14  Scott James Remnant  <scott@netsplit.com>

	* ChangeLog: Initial project infrastructure created.
