From 5b0a4722f2ef1eac59c9650b37b29ac8b34a160e Mon Sep 17 00:00:00 2001 From: Apple Date: Mon, 1 Oct 2007 15:20:34 +0000 Subject: [PATCH] launchd-257.tar.gz --- Makefile | 8 + launchd/Makefile.in | 469 +- launchd/TODO | 20 - launchd/aclocal.m4 | 1214 +-- launchd/configure | 7286 +++++++++-------- launchd/configure.ac | 1 + launchd/src/IPC.c | 253 +- launchd/src/IPC.h | 5 - launchd/src/Makefile.am | 82 +- launchd/src/Makefile.in | 1177 +-- launchd/src/StartupItemContext | 2 +- launchd/src/StartupItems.c | 38 +- launchd/src/StartupItems/AppleShare | 29 - launchd/src/StartupItems/AppleShare.plist | 5 - launchd/src/StartupItems/Disks | 33 - launchd/src/StartupItems/Disks.plist | 6 - launchd/src/StartupItems/IPServices | 30 - launchd/src/StartupItems/IPServices.plist | 5 - launchd/src/StartupItems/NIS | 79 - launchd/src/StartupItems/NIS.plist | 4 - launchd/src/SystemStarter.c | 175 +- launchd/src/bootstrap_private.h | 55 - launchd/src/bootstrap_public.c | 285 - launchd/src/com.apple.SystemStarter.plist | 27 + launchd/src/init.c | 789 -- launchd/src/launchctl.1 | 36 +- launchd/src/launchctl.c | 1160 ++- launchd/src/launchd.8 | 4 - launchd/src/launchd.c | 623 +- launchd/src/launchd.h | 56 +- launchd/src/launchd.plist.5 | 79 +- launchd/src/launchd_core_logic.c | 6017 +++++++++++--- launchd/src/launchd_core_logic.h | 80 +- launchd/src/launchd_mach_ipc.c | 916 --- launchd/src/launchd_mig_types.defs | 42 + launchd/src/launchd_runtime.c | 1449 ++++ launchd/src/launchd_runtime.h | 118 + launchd/src/launchd_runtime_kill.c | 44 + launchd/src/launchd_runtime_kill.h | 28 + launchd/src/launchd_unix_ipc.c | 202 +- launchd/src/launchd_unix_ipc.h | 16 +- launchd/src/launchproxy.c | 34 +- launchd/src/libbootstrap.c | 207 + launchd/src/libbootstrap_private.h | 45 + ...otstrap_public.h => libbootstrap_public.h} | 34 +- launchd/src/liblaunch.c | 311 +- launchd/src/liblaunch_internal.h | 30 + .../{launch_priv.h => liblaunch_private.h} | 52 +- launchd/src/{launch.h => liblaunch_public.h} | 21 +- launchd/src/libvproc.c | 596 ++ launchd/src/libvproc_internal.h | 92 + launchd/src/libvproc_private.h | 80 + launchd/src/libvproc_public.h | 41 + launchd/src/protocol_job.defs | 168 + ...mpm_reply.defs => protocol_job_reply.defs} | 37 +- .../{bootstrap.defs => protocol_jobmgr.defs} | 77 +- launchd/src/rc.8 | 2 +- launchd/src/rc.shutdown | 14 - launchd/src/reboot2.h | 35 + launchd/src/service | 167 - launchd/src/service.8 | 29 - launchd/src/wait4path.c | 10 +- ...4\261c\304\270s\304\261lv\316\265\312\200" | 3 - launchd/testing/missed-EVFILT_TIMER.c | 58 + launchd/testing/vproc_gsk_test.c | 27 + launchd/testing/vproc_swap_complex.c | 28 + 66 files changed, 15265 insertions(+), 9880 deletions(-) delete mode 100644 launchd/src/StartupItems/AppleShare delete mode 100644 launchd/src/StartupItems/AppleShare.plist delete mode 100644 launchd/src/StartupItems/Disks delete mode 100644 launchd/src/StartupItems/Disks.plist delete mode 100644 launchd/src/StartupItems/IPServices delete mode 100644 launchd/src/StartupItems/IPServices.plist delete mode 100644 launchd/src/StartupItems/NIS delete mode 100644 launchd/src/StartupItems/NIS.plist delete mode 100644 launchd/src/bootstrap_private.h delete mode 100644 launchd/src/bootstrap_public.c create mode 100644 launchd/src/com.apple.SystemStarter.plist delete mode 100644 launchd/src/init.c delete mode 100644 launchd/src/launchd_mach_ipc.c create mode 100644 launchd/src/launchd_mig_types.defs create mode 100644 launchd/src/launchd_runtime.c create mode 100644 launchd/src/launchd_runtime.h create mode 100644 launchd/src/launchd_runtime_kill.c create mode 100644 launchd/src/launchd_runtime_kill.h create mode 100644 launchd/src/libbootstrap.c create mode 100644 launchd/src/libbootstrap_private.h rename launchd/src/{bootstrap_public.h => libbootstrap_public.h} (92%) create mode 100644 launchd/src/liblaunch_internal.h rename launchd/src/{launch_priv.h => liblaunch_private.h} (69%) rename launchd/src/{launch.h => liblaunch_public.h} (91%) create mode 100644 launchd/src/libvproc.c create mode 100644 launchd/src/libvproc_internal.h create mode 100644 launchd/src/libvproc_private.h create mode 100644 launchd/src/libvproc_public.h create mode 100644 launchd/src/protocol_job.defs rename launchd/src/{mpm_reply.defs => protocol_job_reply.defs} (63%) rename launchd/src/{bootstrap.defs => protocol_jobmgr.defs} (68%) delete mode 100644 launchd/src/rc.shutdown create mode 100644 launchd/src/reboot2.h delete mode 100755 launchd/src/service delete mode 100644 launchd/src/service.8 delete mode 100755 "launchd/testing/Qu\304\261c\304\270s\304\261lv\316\265\312\200" create mode 100644 launchd/testing/missed-EVFILT_TIMER.c create mode 100644 launchd/testing/vproc_gsk_test.c create mode 100644 launchd/testing/vproc_swap_complex.c diff --git a/Makefile b/Makefile index 6cbc3ea..17244dd 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,15 @@ ifeq ($(RC_ProjectName),launchd_libs) else mkdir -p $(DSTROOT)/Library/StartupItems chmod 755 $(DSTROOT)/Library/StartupItems + mkdir -p $(DSTROOT)/System/Library/StartupItems + chmod 755 $(DSTROOT)/System/Library/StartupItems rm -rf $(DSTROOT)/usr/local/lib/system + cp $(OBJROOT)/src/launchd $(SYMROOT) + cp $(OBJROOT)/src/launchctl $(SYMROOT) + cp $(OBJROOT)/src/launchproxy $(SYMROOT) + dsymutil $(SYMROOT)/launchd + dsymutil $(SYMROOT)/launchctl + dsymutil $(SYMROOT)/launchproxy endif launchd_libs:: install diff --git a/launchd/Makefile.in b/launchd/Makefile.in index 613b3bf..8e37b95 100644 --- a/launchd/Makefile.in +++ b/launchd/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.6.3 from Makefile.am. +# Makefile.in generated by automake 1.10 from Makefile.am. # @configure_input@ -# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 -# Free Software Foundation, Inc. +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -13,104 +13,184 @@ # PARTICULAR PURPOSE. @SET_MAKE@ -SHELL = @SHELL@ - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ VPATH = @srcdir@ -prefix = @prefix@ -exec_prefix = @exec_prefix@ - -bindir = @bindir@ -sbindir = @sbindir@ -libexecdir = @libexecdir@ -datadir = @datadir@ -sysconfdir = @sysconfdir@ -sharedstatedir = @sharedstatedir@ -localstatedir = @localstatedir@ -libdir = @libdir@ -infodir = @infodir@ -mandir = @mandir@ -includedir = @includedir@ -oldincludedir = /usr/include pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ -top_builddir = . - -ACLOCAL = @ACLOCAL@ -AUTOCONF = @AUTOCONF@ -AUTOMAKE = @AUTOMAKE@ -AUTOHEADER = @AUTOHEADER@ - am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -INSTALL = @INSTALL@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_DATA = @INSTALL_DATA@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c -INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_HEADER = $(INSTALL_DATA) -transform = @program_transform_name@ +transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : - -EXEEXT = @EXEEXT@ -OBJEXT = @OBJEXT@ -PATH_SEPARATOR = @PATH_SEPARATOR@ +subdir = . +DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(top_srcdir)/configure AUTHORS COPYING \ + ChangeLog INSTALL NEWS TODO compile depcomp install-sh missing \ + mkinstalldirs +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/src/config.h +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + { test ! -d $(distdir) \ + || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -fr $(distdir); }; } +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ +am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host_alias = @host_alias@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ SUBDIRS = src -subdir = . -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/src/config.h -CONFIG_CLEAN_FILES = -DIST_SOURCES = - -RECURSIVE_TARGETS = info-recursive dvi-recursive install-info-recursive \ - uninstall-info-recursive all-recursive install-data-recursive \ - install-exec-recursive installdirs-recursive install-recursive \ - uninstall-recursive check-recursive installcheck-recursive -DIST_COMMON = README AUTHORS COPYING ChangeLog INSTALL Makefile.am \ - Makefile.in NEWS TODO aclocal.m4 compile configure configure.ac \ - depcomp install-sh missing mkinstalldirs -DIST_SUBDIRS = $(SUBDIRS) all: all-recursive .SUFFIXES: - -am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ - configure.lineno -$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4) +am--refresh: + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --gnu '; \ + cd $(srcdir) && $(AUTOMAKE) --gnu \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe) - -$(top_builddir)/config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck -$(srcdir)/configure: $(srcdir)/configure.ac $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) - cd $(srcdir) && $(AUTOCONF) -$(ACLOCAL_M4): configure.ac +$(top_srcdir)/configure: $(am__configure_deps) + cd $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) -uninstall-info-am: # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. @@ -119,7 +199,13 @@ uninstall-info-am: # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): - @set fnord $$MAKEFLAGS; amf=$$2; \ + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ @@ -131,15 +217,20 @@ $(RECURSIVE_TARGETS): local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" -mostlyclean-recursive clean-recursive distclean-recursive \ -maintainer-clean-recursive: - @set fnord $$MAKEFLAGS; amf=$$2; \ +$(RECURSIVE_CLEAN_TARGETS): + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ @@ -160,17 +251,16 @@ maintainer-clean-recursive: local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done - -ETAGS = etags -ETAGSFLAGS = - -tags: TAGS +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ @@ -180,14 +270,23 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique +tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ - test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ + test ! -f $$subdir/TAGS || \ + tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ @@ -196,8 +295,24 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ - test -z "$(ETAGS_ARGS)$$tags$$unique" \ - || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: @@ -206,33 +321,26 @@ GTAGS: && gtags -i $(GTAGS_ARGS) $$here distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) - -top_distdir = . -distdir = $(PACKAGE)-$(VERSION) - -am__remove_distdir = \ - { test ! -d $(distdir) \ - || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ - && rm -fr $(distdir); }; } - -GZIP_ENV = --best -distcleancheck_listfiles = find . -type f -print + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) $(am__remove_distdir) - mkdir $(distdir) - @list='$(DISTFILES)'; for file in $$list; do \ + test -d $(distdir) || mkdir $(distdir) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test "$$dir" != "$$file" && test "$$dir" != "."; then \ - dir="/$$dir"; \ - $(mkinstalldirs) "$(distdir)$$dir"; \ - else \ - dir=''; \ - fi; \ if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ @@ -243,15 +351,19 @@ distdir: $(DISTFILES) || exit 1; \ fi; \ done - list='$(SUBDIRS)'; for subdir in $$list; do \ + list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ - test -d $(distdir)/$$subdir \ - || mkdir $(distdir)/$$subdir \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ + distdir=`$(am__cd) $(distdir) && pwd`; \ + top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ - top_distdir="$(top_distdir)" \ - distdir=../$(distdir)/$$subdir \ + top_distdir="$$top_distdir" \ + distdir="$$distdir/$$subdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ distdir) \ || exit 1; \ fi; \ @@ -259,29 +371,57 @@ distdir: $(DISTFILES) -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r $(distdir) dist-gzip: distdir - $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) $(am__remove_distdir) dist dist-all: distdir - $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist - $(am__remove_distdir) - GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(AMTAR) xf - + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac chmod -R a-w $(distdir); chmod a+w $(distdir) - mkdir $(distdir)/=build - mkdir $(distdir)/=inst + mkdir $(distdir)/_build + mkdir $(distdir)/_inst chmod a-w $(distdir) - dc_install_base=`$(am__cd) $(distdir)/=inst && pwd` \ - && cd $(distdir)/=build \ - && ../configure --srcdir=.. --prefix=$$dc_install_base \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && cd $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ @@ -289,23 +429,40 @@ distcheck: dist && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ - && (test `find $$dc_install_base -type f -print | wc -l` -le 1 \ - || { echo "ERROR: files left after uninstall:" ; \ - find $$dc_install_base -type f -print ; \ - exit 1; } >&2 ) \ - && $(MAKE) $(AM_MAKEFLAGS) dist-gzip \ - && rm -f $(distdir).tar.gz \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck $(am__remove_distdir) - @echo "$(distdir).tar.gz is ready for distribution" | \ - sed 'h;s/./=/g;p;x;p;x' + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @cd $(distuninstallcheck_dir) \ + && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 distcleancheck: distclean - if test '$(srcdir)' = . ; then \ + @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi - test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ - || { echo "ERROR: files left after distclean:" ; \ + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am @@ -313,7 +470,6 @@ check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: - install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive @@ -325,7 +481,7 @@ install-am: all-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - INSTALL_STRIP_FLAG=-s \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: @@ -333,7 +489,7 @@ mostlyclean-generic: clean-generic: distclean-generic: - -rm -f Makefile $(CONFIG_CLEAN_FILES) + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @@ -344,53 +500,74 @@ clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: +html: html-recursive + info: info-recursive info-am: install-data-am: +install-dvi: install-dvi-recursive + install-exec-am: +install-html: install-html-recursive + install-info: install-info-recursive install-man: +install-pdf: install-pdf-recursive + +install-ps: install-ps-recursive + installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf autom4te.cache + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic -uninstall-am: uninstall-info-am +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: -uninstall-info: uninstall-info-recursive +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \ + install-strip -.PHONY: $(RECURSIVE_TARGETS) GTAGS all all-am check check-am clean \ - clean-generic clean-recursive dist dist-all dist-gzip distcheck \ - distclean distclean-generic distclean-recursive distclean-tags \ - distcleancheck distdir dvi dvi-am dvi-recursive info info-am \ - info-recursive install install-am install-data install-data-am \ - install-data-recursive install-exec install-exec-am \ - install-exec-recursive install-info install-info-am \ - install-info-recursive install-man install-recursive \ +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am am--refresh check check-am clean clean-generic \ + ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \ + dist-shar dist-tarZ dist-zip distcheck distclean \ + distclean-generic distclean-tags distcleancheck distdir \ + distuninstallcheck dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ - installdirs-am installdirs-recursive maintainer-clean \ - maintainer-clean-generic maintainer-clean-recursive mostlyclean \ - mostlyclean-generic mostlyclean-recursive tags tags-recursive \ - uninstall uninstall-am uninstall-info-am \ - uninstall-info-recursive uninstall-recursive + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic pdf pdf-am ps ps-am tags \ + tags-recursive uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/launchd/TODO b/launchd/TODO index d739d48..e69de29 100644 --- a/launchd/TODO +++ b/launchd/TODO @@ -1,20 +0,0 @@ -per user support -\_ job mgmt -\_ tmp dir -job exponential backoff and recursion prevention - - - -file system events -mach events -cron -at -legacy parsers -monitor -\_ cocoa -\_ cli -documentation -code audit -init support -anacron support -sample dameon diff --git a/launchd/aclocal.m4 b/launchd/aclocal.m4 index c6cc64e..d898164 100644 --- a/launchd/aclocal.m4 +++ b/launchd/aclocal.m4 @@ -1,7 +1,7 @@ -# aclocal.m4t generated automatically by aclocal 1.6.3 -*- Autoconf -*- +# generated automatically by aclocal 1.10 -*- Autoconf -*- -# Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 -# Free Software Foundation, Inc. +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -11,307 +11,52 @@ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. -# Do all the work for Automake. -*- Autoconf -*- - -# This macro actually does too much some checks are only needed if -# your package does certain things. But this isn't really a big deal. - -# Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 -# Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# serial 8 - -# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be -# written in clear, in which case automake, when reading aclocal.m4, -# will think it sees a *use*, and therefore will trigger all it's -# C support machinery. Also note that it means that autoscan, seeing -# CC etc. in the Makefile, will ask for an AC_PROG_CC use... - - -AC_PREREQ([2.52]) - -# Autoconf 2.50 wants to disallow AM_ names. We explicitly allow -# the ones we care about. -m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl - -# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) -# AM_INIT_AUTOMAKE([OPTIONS]) -# ----------------------------------------------- -# The call with PACKAGE and VERSION arguments is the old style -# call (pre autoconf-2.50), which is being phased out. PACKAGE -# and VERSION should now be passed to AC_INIT and removed from -# the call to AM_INIT_AUTOMAKE. -# We support both call styles for the transition. After -# the next Automake release, Autoconf can make the AC_INIT -# arguments mandatory, and then we can depend on a new Autoconf -# release and drop the old call support. -AC_DEFUN([AM_INIT_AUTOMAKE], -[AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl - AC_REQUIRE([AC_PROG_INSTALL])dnl -# test to see if srcdir already configured -if test "`cd $srcdir && pwd`" != "`pwd`" && - test -f $srcdir/config.status; then - AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) -fi - -# Define the identity of the package. -dnl Distinguish between old-style and new-style calls. -m4_ifval([$2], -[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl - AC_SUBST([PACKAGE], [$1])dnl - AC_SUBST([VERSION], [$2])], -[_AM_SET_OPTIONS([$1])dnl - AC_SUBST([PACKAGE], [AC_PACKAGE_TARNAME])dnl - AC_SUBST([VERSION], [AC_PACKAGE_VERSION])])dnl - -_AM_IF_OPTION([no-define],, -[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) - AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl - -# Some tools Automake needs. -AC_REQUIRE([AM_SANITY_CHECK])dnl -AC_REQUIRE([AC_ARG_PROGRAM])dnl -AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) -AM_MISSING_PROG(AUTOCONF, autoconf) -AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) -AM_MISSING_PROG(AUTOHEADER, autoheader) -AM_MISSING_PROG(MAKEINFO, makeinfo) -AM_MISSING_PROG(AMTAR, tar) -AM_PROG_INSTALL_SH -AM_PROG_INSTALL_STRIP -# We need awk for the "check" target. The system "awk" is bad on -# some platforms. -AC_REQUIRE([AC_PROG_AWK])dnl -AC_REQUIRE([AC_PROG_MAKE_SET])dnl - -_AM_IF_OPTION([no-dependencies],, -[AC_PROVIDE_IFELSE([AC_PROG_][CC], - [_AM_DEPENDENCIES(CC)], - [define([AC_PROG_][CC], - defn([AC_PROG_][CC])[_AM_DEPENDENCIES(CC)])])dnl -AC_PROVIDE_IFELSE([AC_PROG_][CXX], - [_AM_DEPENDENCIES(CXX)], - [define([AC_PROG_][CXX], - defn([AC_PROG_][CXX])[_AM_DEPENDENCIES(CXX)])])dnl -]) -]) - -# Copyright 2002 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +m4_if(m4_PACKAGE_VERSION, [2.61],, +[m4_fatal([this file was generated for autoconf 2.61. +You have another version of autoconf. If you want to use that, +you should regenerate the build system entirely.], [63])]) -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# Copyright (C) 2002, 2003, 2005, 2006 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. -AC_DEFUN([AM_AUTOMAKE_VERSION],[am__api_version="1.6"]) +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.10' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.10], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- -# Call AM_AUTOMAKE_VERSION so it can be traced. +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AC_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], - [AM_AUTOMAKE_VERSION([1.6.3])]) - -# Helper functions for option handling. -*- Autoconf -*- - -# Copyright 2001, 2002 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# serial 2 - -# _AM_MANGLE_OPTION(NAME) -# ----------------------- -AC_DEFUN([_AM_MANGLE_OPTION], -[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) - -# _AM_SET_OPTION(NAME) -# ------------------------------ -# Set option NAME. Presently that only means defining a flag for this option. -AC_DEFUN([_AM_SET_OPTION], -[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) - -# _AM_SET_OPTIONS(OPTIONS) -# ---------------------------------- -# OPTIONS is a space-separated list of Automake options. -AC_DEFUN([_AM_SET_OPTIONS], -[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) +[AM_AUTOMAKE_VERSION([1.10])dnl +_AM_AUTOCONF_VERSION(m4_PACKAGE_VERSION)]) -# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) -# ------------------------------------------- -# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. -AC_DEFUN([_AM_IF_OPTION], -[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) +# AM_AUX_DIR_EXPAND -*- Autoconf -*- +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # -# Check to make sure that the build environment is sane. -# - -# Copyright 1996, 1997, 2000, 2001 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# serial 3 - -# AM_SANITY_CHECK -# --------------- -AC_DEFUN([AM_SANITY_CHECK], -[AC_MSG_CHECKING([whether build environment is sane]) -# Just in case -sleep 1 -echo timestamp > conftest.file -# Do `set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` - if test "$[*]" = "X"; then - # -L didn't work. - set X `ls -t $srcdir/configure conftest.file` - fi - rm -f conftest.file - if test "$[*]" != "X $srcdir/configure conftest.file" \ - && test "$[*]" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken -alias in your environment]) - fi - - test "$[2]" = conftest.file - ) -then - # Ok. - : -else - AC_MSG_ERROR([newly created file is older than distributed files! -Check your system clock]) -fi -AC_MSG_RESULT(yes)]) - -# -*- Autoconf -*- - - -# Copyright 1997, 1999, 2000, 2001 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# serial 3 - -# AM_MISSING_PROG(NAME, PROGRAM) -# ------------------------------ -AC_DEFUN([AM_MISSING_PROG], -[AC_REQUIRE([AM_MISSING_HAS_RUN]) -$1=${$1-"${am_missing_run}$2"} -AC_SUBST($1)]) - - -# AM_MISSING_HAS_RUN -# ------------------ -# Define MISSING if not defined so far and test if it supports --run. -# If it does, set am_missing_run to use it, otherwise, to nothing. -AC_DEFUN([AM_MISSING_HAS_RUN], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" -# Use eval to expand $SHELL -if eval "$MISSING --run true"; then - am_missing_run="$MISSING --run " -else - am_missing_run= - AC_MSG_WARN([`missing' script is too old or missing]) -fi -]) - -# AM_AUX_DIR_EXPAND - -# Copyright 2001 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to @@ -351,126 +96,84 @@ fi # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. -# Rely on autoconf to set up CDPATH properly. -AC_PREREQ([2.50]) - -AC_DEFUN([AM_AUX_DIR_EXPAND], [ +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) -# AM_PROG_INSTALL_SH -# ------------------ -# Define $install_sh. - -# Copyright 2001 Free Software Foundation, Inc. +# AM_CONDITIONAL -*- Autoconf -*- -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# serial 8 -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) -AC_DEFUN([AM_PROG_INSTALL_SH], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -install_sh=${install_sh-"$am_aux_dir/install-sh"} -AC_SUBST(install_sh)]) +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. -# AM_PROG_INSTALL_STRIP +# serial 9 -# Copyright 2001 Free Software Foundation, Inc. +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# One issue with vendor `install' (even GNU) is that you can't -# specify the program used to strip binaries. This is especially -# annoying in cross-compiling environments, where the build's strip -# is unlikely to handle the host's binaries. -# Fortunately install-sh will honor a STRIPPROG variable, so we -# always use install-sh in `make install-strip', and initialize -# STRIPPROG with the value of the STRIP variable (set by the user). -AC_DEFUN([AM_PROG_INSTALL_STRIP], -[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -# Installed binaries are usually stripped using `strip' when the user -# run `make install-strip'. However `strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the `STRIP' environment variable to overrule this program. -dnl Don't test for $cross_compiling = yes, because it might be `maybe'. -if test "$cross_compiling" != no; then - AC_CHECK_TOOL([STRIP], [strip], :) -fi -INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" -AC_SUBST([INSTALL_STRIP_PROGRAM])]) - -# serial 4 -*- Autoconf -*- - -# Copyright 1999, 2000, 2001 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - - -# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be -# written in clear, in which case automake, when reading aclocal.m4, -# will think it sees a *use*, and therefore will trigger all it's -# C support machinery. Also note that it means that autoscan, seeing -# CC etc. in the Makefile, will ask for an AC_PROG_CC use... - - - -# _AM_DEPENDENCIES(NAME) -# ---------------------- -# See how the compiler implements dependency checking. -# NAME is "CC", "CXX", "GCJ", or "OBJC". -# We try a few techniques and use that to set a single cache variable. -# -# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was -# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular -# dependency, and given that the user is not expected to run this macro, -# just rely on AC_PROG_CC. -AC_DEFUN([_AM_DEPENDENCIES], -[AC_REQUIRE([AM_SET_DEPDIR])dnl -AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl -AC_REQUIRE([AM_MAKE_INCLUDE])dnl -AC_REQUIRE([AM_DEP_TRACK])dnl +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl ifelse([$1], CC, [depcc="$CC" am_compiler_list=], [$1], CXX, [depcc="$CXX" am_compiler_list=], [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], UPC, [depcc="$UPC" am_compiler_list=], [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) @@ -487,18 +190,34 @@ AC_CACHE_CHECK([dependency style of $depcc], # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. - echo '#include "conftest.h"' > conftest.c - echo 'int i;' > conftest.h - echo "${am__include} ${am__quote}conftest.Po${am__quote}" > confmf + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in nosideeffect) @@ -516,13 +235,26 @@ AC_CACHE_CHECK([dependency style of $depcc], # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. if depmode=$depmode \ - source=conftest.c object=conftest.o \ - depfile=conftest.Po tmpdepfile=conftest.TPo \ - $SHELL ./depcomp $depcc -c conftest.c -o conftest.o >/dev/null 2>&1 && - grep conftest.h conftest.Po > /dev/null 2>&1 && + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - am_cv_$1_dependencies_compiler_type=$depmode - break + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi fi done @@ -533,6 +265,9 @@ else fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) @@ -541,16 +276,8 @@ AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES AC_DEFUN([AM_SET_DEPDIR], -[rm -f .deps 2>/dev/null -mkdir .deps 2>/dev/null -if test -d .deps; then - DEPDIR=.deps -else - # MS-DOS does not allow filenames that begin with a dot. - DEPDIR=_deps -fi -rmdir .deps 2>/dev/null -AC_SUBST([DEPDIR]) +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) @@ -558,36 +285,27 @@ AC_SUBST([DEPDIR]) # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE(dependency-tracking, -[ --disable-dependency-tracking Speeds up one-time builds - --enable-dependency-tracking Do not reject slow dependency extractors]) +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) -AC_SUBST([AMDEPBACKSLASH]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl ]) -# Generate code to set up dependency tracking. -*- Autoconf -*- +# Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. -#serial 2 +#serial 3 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ @@ -600,33 +318,28 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. - # So let's grep whole file. - if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed 10q "$mf" | grep '^#.*generated by automake' > /dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi - grep '^DEP_FILES *= *[[^ @%:@]]' < "$mf" > /dev/null || continue - # Extract the definition of DEP_FILES from the Makefile without - # running `make'. - DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"` + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it - U=`sed -n -e '/^U = / s///p' < "$mf"` - test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR" - # We invoke sed twice because it is the simplest approach to - # changing $(DEPDIR) to its actual value in the expansion. - for file in `sed -n -e ' - /^DEP_FILES = .*\\\\$/ { - s/^DEP_FILES = // - :loop - s/\\\\$// - p - n - /\\\\$/ b loop - p - } - /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \ + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue @@ -652,33 +365,197 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) -# Copyright 2001 Free Software Foundation, Inc. -*- Autoconf -*- +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 8 -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. +# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS. +AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)]) -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# Do all the work for Automake. -*- Autoconf -*- -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 12 + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.60])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AM_PROG_INSTALL_SH +AM_PROG_INSTALL_STRIP +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES(OBJC)], + [define([AC_PROG_OBJC], + defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl +]) +]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $1 | $1:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"} +AC_SUBST(install_sh)]) + +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. # serial 2 +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 3 + # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' -doit: +am__doit: @echo done +.PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) @@ -692,7 +569,7 @@ echo "include confinc" > confmf # In particular we don't look at `^make:' because GNU make might # be invoked under some other name (usually "gmake"), in which # case it prints its new name instead of `make'. -if test "`$am_make -s -f confmf 2> /dev/null | fgrep -v 'ing directory'`" = "done"; then +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then am__include=include am__quote= _am_result=GNU @@ -706,131 +583,326 @@ if test "$am__include" = "#"; then _am_result=BSD fi fi -AC_SUBST(am__include) -AC_SUBST(am__quote) -AC_MSG_RESULT($_am_result) +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) -# AM_CONDITIONAL -*- Autoconf -*- +# Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. -# Copyright 1997, 2000, 2001 Free Software Foundation, Inc. +# serial 5 -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. +# AM_PROG_CC_C_O +# -------------- +# Like AC_PROG_CC_C_O, but changed for automake. +AC_DEFUN([AM_PROG_CC_C_O], +[AC_REQUIRE([AC_PROG_CC_C_O])dnl +AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +# FIXME: we rely on the cache variable name because +# there is no other way. +set dummy $CC +ac_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']` +if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" != yes"; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +dnl Make sure AC_PROG_CC is never called again, or it will override our +dnl setting of CC. +m4_define([AC_PROG_CC], + [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])]) +]) -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. # serial 5 -AC_PREREQ(2.52) +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) -# AM_CONDITIONAL(NAME, SHELL-CONDITION) -# ------------------------------------- -# Define a conditional. -AC_DEFUN([AM_CONDITIONAL], -[ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], - [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl -AC_SUBST([$1_TRUE]) -AC_SUBST([$1_FALSE]) -if $2; then - $1_TRUE= - $1_FALSE='#' + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " else - $1_TRUE='#' - $1_FALSE= + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) fi -AC_CONFIG_COMMANDS_PRE( -[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then - AC_MSG_ERROR([conditional \"$1\" was never defined. -Usually this means the macro was only invoked conditionally.]) -fi])]) +]) -# Like AC_CONFIG_HEADER, but automatically create stamp file. -*- Autoconf -*- +# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. -# Copyright 1996, 1997, 2000, 2001 Free Software Foundation, Inc. +# AM_PROG_MKDIR_P +# --------------- +# Check for `mkdir -p'. +AC_DEFUN([AM_PROG_MKDIR_P], +[AC_PREREQ([2.60])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, +dnl while keeping a definition of mkdir_p for backward compatibility. +dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. +dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of +dnl Makefile.ins that do not define MKDIR_P, so we do our own +dnl adjustment using top_builddir (which is defined more often than +dnl MKDIR_P). +AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl +case $mkdir_p in + [[\\/$]]* | ?:[[\\/]]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac +]) -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. +# Helper functions for option handling. -*- Autoconf -*- -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. +# serial 3 -AC_PREREQ([2.52]) +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) -# serial 6 +# _AM_SET_OPTION(NAME) +# ------------------------------ +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) -# When config.status generates a header, we must update the stamp-h file. -# This file resides in the same directory as the config header -# that is generated. We must strip everything past the first ":", -# and everything past the last "/". +# _AM_SET_OPTIONS(OPTIONS) +# ---------------------------------- +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) -# _AM_DIRNAME(PATH) -# ----------------- -# Like AS_DIRNAME, only do it during macro expansion -AC_DEFUN([_AM_DIRNAME], - [m4_if(regexp([$1], [^.*[^/]//*[^/][^/]*/*$]), -1, - m4_if(regexp([$1], [^//\([^/]\|$\)]), -1, - m4_if(regexp([$1], [^/.*]), -1, - [.], - patsubst([$1], [^\(/\).*], [\1])), - patsubst([$1], [^\(//\)\([^/].*\|$\)], [\1])), - patsubst([$1], [^\(.*[^/]\)//*[^/][^/]*/*$], [\1]))[]dnl -])# _AM_DIRNAME +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) +# Check to make sure that the build environment is sane. -*- Autoconf -*- -# The stamp files are numbered to have different names. -# We could number them on a directory basis, but that's additional -# complications, let's have a unique counter. -m4_define([_AM_STAMP_Count], [0]) +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. +# serial 4 -# _AM_STAMP(HEADER) -# ----------------- -# The name of the stamp file for HEADER. -AC_DEFUN([_AM_STAMP], -[m4_define([_AM_STAMP_Count], m4_incr(_AM_STAMP_Count))dnl -AS_ESCAPE(_AM_DIRNAME(patsubst([$1], - [:.*])))/stamp-h[]_AM_STAMP_Count]) - - -# _AM_CONFIG_HEADER(HEADER[:SOURCES], COMMANDS, INIT-COMMANDS) -# ------------------------------------------------------------ -# We used to try to get a real timestamp in stamp-h. But the fear is that -# that will cause unnecessary cvs conflicts. -AC_DEFUN([_AM_CONFIG_HEADER], -[# Add the stamp file to the list of files AC keeps track of, -# along with our hook. -AC_CONFIG_HEADERS([$1], - [# update the timestamp -echo 'timestamp for $1' >"_AM_STAMP([$1])" -$2], - [$3]) -])# _AM_CONFIG_HEADER - - -# AM_CONFIG_HEADER(HEADER[:SOURCES]..., COMMANDS, INIT-COMMANDS) -# -------------------------------------------------------------- -AC_DEFUN([AM_CONFIG_HEADER], -[AC_FOREACH([_AM_File], [$1], [_AM_CONFIG_HEADER(_AM_File, [$2], [$3])]) -])# AM_CONFIG_HEADER +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputing VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. +AM_MISSING_PROG([AMTAR], [tar]) +m4_if([$1], [v7], + [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR diff --git a/launchd/configure b/launchd/configure index 3fa2943..029a88c 100755 --- a/launchd/configure +++ b/launchd/configure @@ -1,27 +1,56 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.59 for launchd 1.0. +# Generated by GNU Autoconf 2.61 for launchd 1.0. # # Report bugs to . # -# Copyright (C) 2003 Free Software Foundation, Inc. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## -# Be Bourne compatible +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' -elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then - set -o posix + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh fi -DUALCASE=1; export DUALCASE # for MKS sh # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then @@ -31,8 +60,43 @@ else fi +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + # Work around bugs in pre-3.0 UWIN ksh. -$as_unset ENV MAIL MAILPATH +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done PS1='$ ' PS2='> ' PS4='+ ' @@ -46,18 +110,19 @@ do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else - $as_unset $as_var + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var fi done # Required to use basename. -if expr a : '\(a\)' >/dev/null 2>&1; then +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi -if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false @@ -65,157 +130,388 @@ fi # Name of the executable. -as_me=`$as_basename "$0" || +as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)$' \| \ - . : '\(.\)' 2>/dev/null || + X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } - /^X\/\(\/\/\)$/{ s//\1/; q; } - /^X\/\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` +# CDPATH. +$as_unset CDPATH -# PATH needs CR, and LINENO needs CR and PATH. -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh +if test "x$CONFIG_SHELL" = x; then + if (eval ":") 2>/dev/null; then + as_have_required=yes +else + as_have_required=no fi + if test $as_have_required = yes && (eval ": +(as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" || { - # Find who we are. Look in the path if we contain no path at all - # relative or not. - case $0 in - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break -done +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi - ;; - esac - # We did not find ourselves, most probably we were run as `sh COMMAND' - # in which case we are not to be found in the path. - if test "x$as_myself" = x; then - as_myself=$0 - fi - if test ! -f "$as_myself"; then - { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 - { (exit 1); exit 1; }; } - fi - case $CONFIG_SHELL in - '') +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=\$LINENO + as_lineno_2=\$LINENO + test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && + test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } +") 2> /dev/null; then + : +else + as_candidate_shells= as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for as_base in sh bash ksh sh5; do - case $as_dir in + case $as_dir in /*) - if ("$as_dir/$as_base" -c ' + for as_base in sh bash ksh sh5; do + as_candidate_shells="$as_candidate_shells $as_dir/$as_base" + done;; + esac +done +IFS=$as_save_IFS + + + for as_shell in $as_candidate_shells $SHELL; do + # Try only shells that exist, to save several forks. + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { ("$as_shell") 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +_ASEOF +}; then + CONFIG_SHELL=$as_shell + as_have_required=yes + if { "$as_shell" 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +(as_func_return () { + (exit $1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = "$1" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test $exitcode = 0) || { (exit 1); exit 1; } + +( as_lineno_1=$LINENO as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then - $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } - $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } - CONFIG_SHELL=$as_dir/$as_base - export CONFIG_SHELL - exec "$CONFIG_SHELL" "$0" ${1+"$@"} - fi;; - esac - done -done -;; - esac + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } + +_ASEOF +}; then + break +fi + +fi + + done + + if test "x$CONFIG_SHELL" != x; then + for as_var in BASH_ENV ENV + do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + done + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} +fi + + + if test $as_have_required = no; then + echo This script requires a shell more modern than all the + echo shells that I found on your system. Please install a + echo modern shell, or manually run the script under such a + echo shell if you do have one. + { (exit 1); exit 1; } +fi + + +fi + +fi + + + +(eval "as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0") || { + echo No shell found that supports shell functions. + echo Please tell autoconf@gnu.org about your system, + echo including any error possibly output before this + echo message +} + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a - # line-number line before each line; the second 'sed' does the real - # work. The second script uses 'N' to pair each line-number line - # with the numbered line, and appends trailing '-' during - # substitution so that $LINENO is not a special case at line end. + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the - # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) - sed '=' <$as_myself | + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno N - s,$,-, - : loop - s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop - s,-$,, - s,^['$as_cr_digits']*\n,, + s/-\n.*// ' >$as_me.lineno && - chmod +x $as_me.lineno || + chmod +x "$as_me.lineno" || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensible to this). - . ./$as_me.lineno + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" # Exit status is that of the last command. exit } -case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in - *c*,-n*) ECHO_N= ECHO_C=' -' ECHO_T=' ' ;; - *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; - *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; esac -if expr a : '\(a\)' >/dev/null 2>&1; then +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then - # We could just check for DJGPP; but this test a) works b) is more generic - # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). - if test -f conf$$.exe; then - # Don't use ln at all; we don't have any links + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' - else - as_ln_s='ln -s' - fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi -rm -f conf$$ conf$$.exe conf$$.file +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p=: @@ -224,7 +520,28 @@ else as_mkdir_p=false fi -as_executable_p="test -f" +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -233,39 +550,27 @@ as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" -# IFS -# We need space, tab and new line, in precisely that order. -as_nl=' -' -IFS=" $as_nl" - -# CDPATH. -$as_unset CDPATH +exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` -exec 6>&1 - # # Initializations. # ac_default_prefix=/usr/local +ac_clean_files= ac_config_libobj_dir=. +LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} -# Maximum number of lines to put in a shell here document. -# This variable seems obsolete. It should probably be removed, and -# only ac_max_sed_lines should be used. -: ${ac_max_here_lines=38} - # Identity of this package. PACKAGE_NAME='launchd' PACKAGE_TARNAME='launchd' @@ -277,42 +582,136 @@ ac_unique_file="src/launchd.c" # Factoring default headers for most tests. ac_includes_default="\ #include -#if HAVE_SYS_TYPES_H +#ifdef HAVE_SYS_TYPES_H # include #endif -#if HAVE_SYS_STAT_H +#ifdef HAVE_SYS_STAT_H # include #endif -#if STDC_HEADERS +#ifdef STDC_HEADERS # include # include #else -# if HAVE_STDLIB_H +# ifdef HAVE_STDLIB_H # include # endif #endif -#if HAVE_STRING_H -# if !STDC_HEADERS && HAVE_MEMORY_H +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif -#if HAVE_STRINGS_H +#ifdef HAVE_STRINGS_H # include #endif -#if HAVE_INTTYPES_H +#ifdef HAVE_INTTYPES_H # include -#else -# if HAVE_STDINT_H -# include -# endif #endif -#if HAVE_UNISTD_H +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H # include #endif" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM AWK SET_MAKE CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE RANLIB ac_ct_RANLIB CPP EGREP ALLOCA LIBOBJS LIBS_ONLY_TRUE LIBS_ONLY_FALSE LTLIBOBJS' +ac_header_list= +ac_func_list= +ac_subst_vars='SHELL +PATH_SEPARATOR +PACKAGE_NAME +PACKAGE_TARNAME +PACKAGE_VERSION +PACKAGE_STRING +PACKAGE_BUGREPORT +exec_prefix +prefix +program_transform_name +bindir +sbindir +libexecdir +datarootdir +datadir +sysconfdir +sharedstatedir +localstatedir +includedir +oldincludedir +docdir +infodir +htmldir +dvidir +pdfdir +psdir +libdir +localedir +mandir +DEFS +ECHO_C +ECHO_N +ECHO_T +LIBS +build_alias +host_alias +target_alias +INSTALL_PROGRAM +INSTALL_SCRIPT +INSTALL_DATA +am__isrc +CYGPATH_W +PACKAGE +VERSION +ACLOCAL +AUTOCONF +AUTOMAKE +AUTOHEADER +MAKEINFO +install_sh +STRIP +INSTALL_STRIP_PROGRAM +mkdir_p +AWK +SET_MAKE +am__leading_dot +AMTAR +am__tar +am__untar +CC +CFLAGS +LDFLAGS +CPPFLAGS +ac_ct_CC +EXEEXT +OBJEXT +DEPDIR +am__include +am__quote +AMDEP_TRUE +AMDEP_FALSE +AMDEPBACKSLASH +CCDEPMODE +am__fastdepCC_TRUE +am__fastdepCC_FALSE +RANLIB +CPP +GREP +EGREP +ALLOCA +LIBOBJS +LIBS_ONLY_TRUE +LIBS_ONLY_FALSE +LTLIBOBJS' ac_subst_files='' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP' + # Initialize some variables set by options. ac_init_help= @@ -339,34 +738,48 @@ x_libraries=NONE # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' -datadir='${prefix}/share' +datarootdir='${prefix}/share' +datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' -libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' -infodir='${prefix}/info' -mandir='${prefix}/man' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' ac_prev= +ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then - eval "$ac_prev=\$ac_option" + eval $ac_prev=\$ac_option ac_prev= continue fi - ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` + case $ac_option in + *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *) ac_optarg=yes ;; + esac # Accept the important Cygnus configure options, so we can diagnose typos. - case $ac_option in + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; @@ -388,33 +801,45 @@ do --config-cache | -C) cache_file=config.cache ;; - -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ - | --da=*) + -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + -disable-* | --disable-*) ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/-/_/g'` - eval "enable_$ac_feature=no" ;; + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/-/_/g'` - case $ac_option in - *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; - *) ac_optarg=yes ;; - esac - eval "enable_$ac_feature='$ac_optarg'" ;; + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ @@ -441,6 +866,12 @@ do -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; @@ -465,13 +896,16 @@ do | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst \ - | --locals | --local | --loca | --loc | --lo) + | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* \ - | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) @@ -536,6 +970,16 @@ do | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; @@ -588,24 +1032,20 @@ do -with-* | --with-*) ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } - ac_package=`echo $ac_package| sed 's/-/_/g'` - case $ac_option in - *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; - *) ac_optarg=yes ;; - esac - eval "with_$ac_package='$ac_optarg'" ;; + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=\$ac_optarg ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } - ac_package=`echo $ac_package | sed 's/-/_/g'` - eval "with_$ac_package=no" ;; + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=no ;; --x) # Obsolete; use --with-x. @@ -636,8 +1076,7 @@ Try \`$0 --help' for more information." >&2 expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } - ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` - eval "$ac_envvar='$ac_optarg'" + eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) @@ -657,27 +1096,19 @@ if test -n "$ac_prev"; then { (exit 1); exit 1; }; } fi -# Be sure to have absolute paths. -for ac_var in exec_prefix prefix -do - eval ac_val=$`echo $ac_var` - case $ac_val in - [\\/$]* | ?:[\\/]* | NONE | '' ) ;; - *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 - { (exit 1); exit 1; }; };; - esac -done - -# Be sure to have absolute paths. -for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ - localstatedir libdir includedir oldincludedir infodir mandir +# Be sure to have absolute directory names. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir do - eval ac_val=$`echo $ac_var` + eval ac_val=\$$ac_var case $ac_val in - [\\/$]* | ?:[\\/]* ) ;; - *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 - { (exit 1); exit 1; }; };; + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac + { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; } done # There might be people who depend on the old broken behavior: `$host' @@ -704,74 +1135,76 @@ test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then its parent. - ac_confdir=`(dirname "$0") 2>/dev/null || +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + { echo "$as_me: error: Working directory cannot be determined" >&2 + { (exit 1); exit 1; }; } +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + { echo "$as_me: error: pwd does not report name of working directory" >&2 + { (exit 1); exit 1; }; } + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$0" || $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$0" : 'X\(//\)[^/]' \| \ X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || + X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X"$0" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` srcdir=$ac_confdir - if test ! -r $srcdir/$ac_unique_file; then + if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi -if test ! -r $srcdir/$ac_unique_file; then - if test "$ac_srcdir_defaulted" = yes; then - { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 - { (exit 1); exit 1; }; } - else - { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } - fi fi -(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || - { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 { (exit 1); exit 1; }; } -srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` -ac_env_build_alias_set=${build_alias+set} -ac_env_build_alias_value=$build_alias -ac_cv_env_build_alias_set=${build_alias+set} -ac_cv_env_build_alias_value=$build_alias -ac_env_host_alias_set=${host_alias+set} -ac_env_host_alias_value=$host_alias -ac_cv_env_host_alias_set=${host_alias+set} -ac_cv_env_host_alias_value=$host_alias -ac_env_target_alias_set=${target_alias+set} -ac_env_target_alias_value=$target_alias -ac_cv_env_target_alias_set=${target_alias+set} -ac_cv_env_target_alias_value=$target_alias -ac_env_CC_set=${CC+set} -ac_env_CC_value=$CC -ac_cv_env_CC_set=${CC+set} -ac_cv_env_CC_value=$CC -ac_env_CFLAGS_set=${CFLAGS+set} -ac_env_CFLAGS_value=$CFLAGS -ac_cv_env_CFLAGS_set=${CFLAGS+set} -ac_cv_env_CFLAGS_value=$CFLAGS -ac_env_LDFLAGS_set=${LDFLAGS+set} -ac_env_LDFLAGS_value=$LDFLAGS -ac_cv_env_LDFLAGS_set=${LDFLAGS+set} -ac_cv_env_LDFLAGS_value=$LDFLAGS -ac_env_CPPFLAGS_set=${CPPFLAGS+set} -ac_env_CPPFLAGS_value=$CPPFLAGS -ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} -ac_cv_env_CPPFLAGS_value=$CPPFLAGS -ac_env_CPP_set=${CPP+set} -ac_env_CPP_value=$CPP -ac_cv_env_CPP_set=${CPP+set} -ac_cv_env_CPP_value=$CPP + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done # # Report the --help message. @@ -800,9 +1233,6 @@ Configuration: -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] -_ACEOF - - cat <<_ACEOF Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] @@ -820,15 +1250,22 @@ Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] - --datadir=DIR read-only architecture-independent data [PREFIX/share] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] - --infodir=DIR info documentation [PREFIX/info] - --mandir=DIR man documentation [PREFIX/man] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/launchd] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF @@ -849,16 +1286,17 @@ if test -n "$ac_init_help"; then Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --disable-dependency-tracking Speeds up one-time builds - --enable-dependency-tracking Do not reject slow dependency extractors + --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory - CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have - headers in a nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if + you have headers in a nonstandard directory CPP C preprocessor Use these variables to override the choices made by `configure' or to help @@ -866,120 +1304,86 @@ it to find libraries and programs with nonstandard names/locations. Report bugs to . _ACEOF +ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. - ac_popdir=`pwd` for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d $ac_dir || continue + test -d "$ac_dir" || continue ac_builddir=. -if test "$ac_dir" != .; then +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A "../" for each directory in $ac_dir_suffix. - ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` -else - ac_dir_suffix= ac_top_builddir= -fi + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix case $srcdir in - .) # No --srcdir option. We are building in place. + .) # We are building in place. ac_srcdir=. - if test -z "$ac_top_builddir"; then - ac_top_srcdir=. - else - ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` - fi ;; - [\\/]* | ?:[\\/]* ) # Absolute path. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir ;; - *) # Relative path. - ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_builddir$srcdir ;; -esac - -# Do not use `cd foo && pwd` to compute absolute paths, because -# the directories may not exist. -case `pwd` in -.) ac_abs_builddir="$ac_dir";; -*) - case "$ac_dir" in - .) ac_abs_builddir=`pwd`;; - [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; - *) ac_abs_builddir=`pwd`/"$ac_dir";; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_builddir=${ac_top_builddir}.;; -*) - case ${ac_top_builddir}. in - .) ac_abs_top_builddir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; - *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_srcdir=$ac_srcdir;; -*) - case $ac_srcdir in - .) ac_abs_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; - *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_srcdir=$ac_top_srcdir;; -*) - case $ac_top_srcdir in - .) ac_abs_top_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; - *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; - esac;; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac - - cd $ac_dir - # Check for guested configure; otherwise get Cygnus style configure. - if test -f $ac_srcdir/configure.gnu; then - echo - $SHELL $ac_srcdir/configure.gnu --help=recursive - elif test -f $ac_srcdir/configure; then - echo - $SHELL $ac_srcdir/configure --help=recursive - elif test -f $ac_srcdir/configure.ac || - test -f $ac_srcdir/configure.in; then - echo - $ac_configure --help +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive else echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 - fi - cd $ac_popdir + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } done fi -test -n "$ac_init_help" && exit 0 +test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF launchd configure 1.0 -generated by GNU Autoconf 2.59 +generated by GNU Autoconf 2.61 -Copyright (C) 2003 Free Software Foundation, Inc. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF - exit 0 + exit fi -exec 5>config.log -cat >&5 <<_ACEOF +cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by launchd $as_me 1.0, which was -generated by GNU Autoconf 2.59. Invocation command line was +generated by GNU Autoconf 2.61. Invocation command line was $ $0 $@ _ACEOF +exec 5>>config.log { cat <<_ASUNAME ## --------- ## @@ -998,7 +1402,7 @@ uname -v = `(uname -v) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` -hostinfo = `(hostinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` @@ -1012,6 +1416,7 @@ do test -z "$as_dir" && as_dir=. echo "PATH: $as_dir" done +IFS=$as_save_IFS } >&5 @@ -1033,7 +1438,6 @@ _ACEOF ac_configure_args= ac_configure_args0= ac_configure_args1= -ac_sep= ac_must_keep_next=false for ac_pass in 1 2 do @@ -1044,7 +1448,7 @@ do -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; - *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + *\'*) ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in @@ -1066,9 +1470,7 @@ do -* ) ac_must_keep_next=true ;; esac fi - ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" - # Get rid of the leading space. - ac_sep=" " + ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac done @@ -1079,8 +1481,8 @@ $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_ # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. -# WARNING: Be sure not to use single quotes in there, as some shells, -# such as our DU 5.0 friend, will then `close' the trap. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { @@ -1093,20 +1495,34 @@ trap 'exit_status=$? _ASBOX echo # The following way of writing the cache mishandles newlines in values, -{ +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done (set) 2>&1 | - case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in - *ac_space=\ *) + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) sed -n \ - "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" - ;; + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( *) - sed -n \ - "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; - esac; -} + esac | + sort +) echo cat <<\_ASBOX @@ -1117,22 +1533,28 @@ _ASBOX echo for ac_var in $ac_subst_vars do - eval ac_val=$`echo $ac_var` - echo "$ac_var='"'"'$ac_val'"'"'" + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX -## ------------- ## -## Output files. ## -## ------------- ## +## ------------------- ## +## File substitutions. ## +## ------------------- ## _ASBOX echo for ac_var in $ac_subst_files do - eval ac_val=$`echo $ac_var` - echo "$ac_var='"'"'$ac_val'"'"'" + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" done | sort echo fi @@ -1144,26 +1566,24 @@ _ASBOX ## ----------- ## _ASBOX echo - sed "/^$/d" confdefs.h | sort + cat confdefs.h echo fi test "$ac_signal" != 0 && echo "$as_me: caught signal $ac_signal" echo "$as_me: exit $exit_status" } >&5 - rm -f core *.core && - rm -rf conftest* confdefs* conf$$* $ac_clean_files && + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status - ' 0 +' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -rf conftest* confdefs.h -# AIX cpp loses on an empty file, so make sure it contains at least a newline. -echo >confdefs.h +rm -f -r conftest* confdefs.h # Predefined preprocessor variables. @@ -1194,14 +1614,17 @@ _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer explicitly selected file to automatically selected ones. -if test -z "$CONFIG_SITE"; then - if test "x$prefix" != xNONE; then - CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" - else - CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" - fi +if test -n "$CONFIG_SITE"; then + set x "$CONFIG_SITE" +elif test "x$prefix" != xNONE; then + set x "$prefix/share/config.site" "$prefix/etc/config.site" +else + set x "$ac_default_prefix/share/config.site" \ + "$ac_default_prefix/etc/config.site" fi -for ac_site_file in $CONFIG_SITE; do +shift +for ac_site_file +do if test -r "$ac_site_file"; then { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 echo "$as_me: loading site script $ac_site_file" >&6;} @@ -1217,8 +1640,8 @@ if test -r "$cache_file"; then { echo "$as_me:$LINENO: loading cache $cache_file" >&5 echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in - [\\/]* | ?:[\\/]* ) . $cache_file;; - *) . ./$cache_file;; + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; esac fi else @@ -1227,15 +1650,17 @@ echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi +ac_header_list="$ac_header_list sys/time.h" +ac_header_list="$ac_header_list unistd.h" +ac_func_list="$ac_func_list alarm" # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false -for ac_var in `(set) 2>&1 | - sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do +for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set - eval ac_old_val="\$ac_cv_env_${ac_var}_value" - eval ac_new_val="\$ac_env_${ac_var}_value" + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 @@ -1260,8 +1685,7 @@ echo "$as_me: current value: $ac_new_val" >&2;} # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in - *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) - ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in @@ -1278,11 +1702,6 @@ echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start ov { (exit 1); exit 1; }; } fi -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu @@ -1307,35 +1726,46 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +am__api_version='1.10' -am__api_version="1.6" ac_aux_dir= -for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do - if test -f $ac_dir/install-sh; then +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break - elif test -f $ac_dir/install.sh; then + elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break - elif test -f $ac_dir/shtool; then + elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then - { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 -echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 +echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} { (exit 1); exit 1; }; } fi -ac_config_guess="$SHELL $ac_aux_dir/config.guess" -ac_config_sub="$SHELL $ac_aux_dir/config.sub" -ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or @@ -1350,8 +1780,8 @@ ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. -echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 -echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 @@ -1373,7 +1803,7 @@ case $as_dir/ in # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. @@ -1392,21 +1822,22 @@ case $as_dir/ in ;; esac done +IFS=$as_save_IFS fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else - # As a last resort, use the slow shell script. We don't cache a - # path for INSTALL within a source directory, because that will + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is - # removed, or if the path is relative. + # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi -echo "$as_me:$LINENO: result: $INSTALL" >&5 -echo "${ECHO_T}$INSTALL" >&6 +{ echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. @@ -1416,8 +1847,8 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' -echo "$as_me:$LINENO: checking whether build environment is sane" >&5 -echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking whether build environment is sane" >&5 +echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6; } # Just in case sleep 1 echo timestamp > conftest.file @@ -1459,21 +1890,20 @@ echo "$as_me: error: newly created file is older than distributed files! Check your system clock" >&2;} { (exit 1); exit 1; }; } fi -echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } test "$program_prefix" != NONE && - program_transform_name="s,^,$program_prefix,;$program_transform_name" + program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && - program_transform_name="s,\$,$program_suffix,;$program_transform_name" + program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. echo might interpret backslashes. # By default was `s,x,x', remove it if useless. cat <<\_ACEOF >conftest.sed s/[\\$]/&&/g;s/;s,x,x,$// _ACEOF program_transform_name=`echo $program_transform_name | sed -f conftest.sed` -rm conftest.sed - +rm -f conftest.sed # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` @@ -1488,12 +1918,60 @@ else echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi +{ echo "$as_me:$LINENO: checking for a thread-safe mkdir -p" >&5 +echo $ECHO_N "checking for a thread-safe mkdir -p... $ECHO_C" >&6; } +if test -z "$MKDIR_P"; then + if test "${ac_cv_path_mkdir+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done +done +IFS=$as_save_IFS + +fi + + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + test -d ./--version && rmdir ./--version + MKDIR_P="$ac_install_sh -d" + fi +fi +{ echo "$as_me:$LINENO: result: $MKDIR_P" >&5 +echo "${ECHO_T}$MKDIR_P" >&6; } + +mkdir_p="$MKDIR_P" +case $mkdir_p in + [\\/$]* | ?:[\\/]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac + for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_AWK+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -1506,68 +1984,94 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AWK="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done +IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then - echo "$as_me:$LINENO: result: $AWK" >&5 -echo "${ECHO_T}$AWK" >&6 + { echo "$as_me:$LINENO: result: $AWK" >&5 +echo "${ECHO_T}$AWK" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } fi + test -n "$AWK" && break done -echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 -echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6 -set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'` -if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then +{ echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; } +set x ${MAKE-make}; ac_make=`echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.make <<\_ACEOF +SHELL = /bin/sh all: - @echo 'ac_maketemp="$(MAKE)"' + @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. -eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` -if test -n "$ac_maketemp"; then - eval ac_cv_prog_make_${ac_make}_set=yes -else - eval ac_cv_prog_make_${ac_make}_set=no -fi +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac rm -f conftest.make fi -if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } SET_MAKE= else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi - # test to see if srcdir already configured -if test "`cd $srcdir && pwd`" != "`pwd`" && - test -f $srcdir/config.status; then - { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} { (exit 1); exit 1; }; } + fi fi +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + # Define the identity of the package. - PACKAGE=launchd - VERSION=1.0 + PACKAGE='launchd' + VERSION='1.0' cat >>confdefs.h <<_ACEOF @@ -1595,10 +2099,7 @@ AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} - -AMTAR=${AMTAR-"${am_missing_run}tar"} - -install_sh=${install_sh-"$am_aux_dir/install-sh"} +install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"} # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right @@ -1608,8 +2109,8 @@ if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_STRIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -1622,32 +2123,34 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done +IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then - echo "$as_me:$LINENO: result: $STRIP" >&5 -echo "${ECHO_T}$STRIP" >&6 + { echo "$as_me:$LINENO: result: $STRIP" >&5 +echo "${ECHO_T}$STRIP" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } fi + fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -1660,45 +2163,62 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done +IFS=$as_save_IFS - test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":" fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then - echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 -echo "${ECHO_T}$ac_ct_STRIP" >&6 + { echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 +echo "${ECHO_T}$ac_ct_STRIP" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } fi - STRIP=$ac_ct_STRIP + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi else STRIP="$ac_cv_prog_STRIP" fi fi -INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" # We need awk for the "check" target. The system "awk" is bad on # some platforms. +# Always define AMTAR for backward compatibility. +AMTAR=${AMTAR-"${am_missing_run}tar"} + +am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' -# Add the stamp file to the list of files AC keeps track of, -# along with our hook. - ac_config_headers="$ac_config_headers src/config.h" +ac_config_headers="$ac_config_headers src/config.h" + # Checks for programs. ac_ext=c @@ -1709,8 +2229,8 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -1723,32 +2243,34 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done +IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } fi + fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -1761,36 +2283,51 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done +IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then - echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6 + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } fi - CC=$ac_ct_CC + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -1803,74 +2340,34 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done +IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6 + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } fi - CC=$ac_ct_CC -else - CC="$ac_cv_prog_CC" -fi + fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -1884,7 +2381,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue @@ -1895,6 +2392,7 @@ do fi done done +IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. @@ -1912,22 +2410,23 @@ fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } fi + fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then - for ac_prog in cl + for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -1940,36 +2439,38 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done +IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } fi + test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC - for ac_prog in cl + for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -1982,29 +2483,45 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done +IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then - echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6 + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } fi + test -n "$ac_ct_CC" && break done - CC=$ac_ct_CC + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi fi fi @@ -2017,21 +2534,35 @@ See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } # Provide some information about the compiler. -echo "$as_me:$LINENO:" \ - "checking for C compiler version" >&5 +echo "$as_me:$LINENO: checking for C compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` -{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 - (eval $ac_compiler --version &5) 2>&5 +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } -{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 - (eval $ac_compiler -v &5) 2>&5 +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } -{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 - (eval $ac_compiler -V &5) 2>&5 +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } @@ -2056,47 +2587,77 @@ ac_clean_files="$ac_clean_files a.out a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. -echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 -echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; } ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` -if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 - (eval $ac_link_default) 2>&5 +# +# List of possible output files, starting from the most likely. +# The algorithm is not robust to junk in `.', hence go to wildcards (a.*) +# only as a last resort. b.out is created by i960 compilers. +ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' +# +# The IRIX 6 linker writes into existing files which may not be +# executable, retaining their permissions. Remove them first so a +# subsequent execution test works. +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { (ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link_default") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then - # Find the output, starting from the most likely. This scheme is -# not robust to junk in `.', hence go to wildcards (a.*) only as a last -# resort. - -# Be careful to initialize this variable, since it used to be cached. -# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. -ac_cv_exeext= -# b.out is created by i960 compilers. -for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) - ;; - conftest.$ac_ext ) - # This is the source file. + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) - ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - # FIXME: I believe we export ac_cv_exeext for Libtool, - # but it would be cool to find out if it's true. Does anybody - # maintain Libtool? --akim. - export ac_cv_exeext + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. break;; * ) break;; esac done +test "$ac_cv_exeext" = no && ac_cv_exeext= + else + ac_file='' +fi + +{ echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6; } +if test -z "$ac_file"; then echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 @@ -2108,19 +2669,21 @@ See \`config.log' for more details." >&2;} fi ac_exeext=$ac_cv_exeext -echo "$as_me:$LINENO: result: $ac_file" >&5 -echo "${ECHO_T}$ac_file" >&6 -# Check the compiler produces executables we can run. If not, either +# Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. -echo "$as_me:$LINENO: checking whether the C compiler works" >&5 -echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; } # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then @@ -2139,22 +2702,27 @@ See \`config.log' for more details." >&2;} fi fi fi -echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } rm -f a.out a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save -# Check the compiler produces executables we can run. If not, either +# Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. -echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 -echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 -echo "$as_me:$LINENO: result: $cross_compiling" >&5 -echo "${ECHO_T}$cross_compiling" >&6 - -echo "$as_me:$LINENO: checking for suffix of executables" >&5 -echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 +{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } +{ echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6; } + +{ echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then @@ -2165,9 +2733,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - export ac_cv_exeext break;; * ) break;; esac @@ -2181,14 +2748,14 @@ See \`config.log' for more details." >&2;} fi rm -f conftest$ac_cv_exeext -echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 -echo "${ECHO_T}$ac_cv_exeext" >&6 +{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT -echo "$as_me:$LINENO: checking for suffix of object files" >&5 -echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } if test "${ac_cv_objext+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -2208,14 +2775,20 @@ main () } _ACEOF rm -f conftest.o conftest.obj -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then - for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac @@ -2233,12 +2806,12 @@ fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 -echo "${ECHO_T}$ac_cv_objext" >&6 +{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT -echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 -echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } if test "${ac_cv_c_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -2261,50 +2834,49 @@ main () } _ACEOF rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -ac_compiler_gnu=no + ac_compiler_gnu=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi -echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 -echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 +{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } GCC=`test $ac_compiler_gnu = yes && echo yes` ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS -CFLAGS="-g" -echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 -echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } if test "${ac_cv_prog_cc_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else - cat >conftest.$ac_ext <<_ACEOF + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -2320,38 +2892,118 @@ main () } _ACEOF rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -ac_cv_prog_cc_g=no + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag fi -echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 -echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 +{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then @@ -2367,12 +3019,12 @@ else CFLAGS= fi fi -echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 -echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 -if test "${ac_cv_prog_cc_stdc+set}" = set; then +{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 +echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else - ac_cv_prog_cc_stdc=no + ac_cv_prog_cc_c89=no ac_save_CC=$CC cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ @@ -2406,12 +3058,17 @@ static char *f (char * (*g) (char **, int), char **p, ...) /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std1 is added to get + as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std1. */ + that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; @@ -2426,232 +3083,76 @@ return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; return 0; } _ACEOF -# Don't try gcc -ansi; that turns off useful extensions and -# breaks some systems' header files. -# AIX -qlanglvl=ansi -# Ultrix and OSF/1 -std1 -# HP-UX 10.20 and later -Ae -# HP-UX older versions -Aa -D_HPUX_SOURCE -# SVR4 -Xc -D__EXTENSIONS__ -for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_cc_stdc=$ac_arg -break + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_c89=$ac_arg else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 + fi -rm -f conftest.err conftest.$ac_objext + +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break done -rm -f conftest.$ac_ext conftest.$ac_objext +rm -f conftest.$ac_ext CC=$ac_save_CC fi - -case "x$ac_cv_prog_cc_stdc" in - x|xno) - echo "$as_me:$LINENO: result: none needed" >&5 -echo "${ECHO_T}none needed" >&6 ;; +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6; } ;; + xno) + { echo "$as_me:$LINENO: result: unsupported" >&5 +echo "${ECHO_T}unsupported" >&6; } ;; *) - echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 -echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 - CC="$CC $ac_cv_prog_cc_stdc" ;; + CC="$CC $ac_cv_prog_cc_c89" + { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; esac -# Some people use a C++ compiler to compile C. Since we use `exit', -# in C++ we need to declare it. In case someone uses the same compiler -# for both compiling C and C++ we need to have the C++ compiler decide -# the declaration of exit, since it's the most demanding environment. -cat >conftest.$ac_ext <<_ACEOF -#ifndef __cplusplus - choke me -#endif -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - for ac_declaration in \ - '' \ - 'extern "C" void std::exit (int) throw (); using std::exit;' \ - 'extern "C" void std::exit (int); using std::exit;' \ - 'extern "C" void exit (int) throw ();' \ - 'extern "C" void exit (int);' \ - 'void exit (int);' -do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_declaration -#include -int -main () -{ -exit (42); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -continue -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_declaration -int -main () -{ -exit (42); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -done -rm -f conftest* -if test -n "$ac_declaration"; then - echo '#ifdef __cplusplus' >>confdefs.h - echo $ac_declaration >>confdefs.h - echo '#endif' >>confdefs.h -fi - -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu -rm -f .deps 2>/dev/null -mkdir .deps 2>/dev/null -if test -d .deps; then - DEPDIR=.deps -else - # MS-DOS does not allow filenames that begin with a dot. - DEPDIR=_deps -fi -rmdir .deps 2>/dev/null +DEPDIR="${am__leading_dot}deps" - - ac_config_commands="$ac_config_commands depfiles" +ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' -doit: +am__doit: @echo done +.PHONY: am__doit END # If we don't find an include directive, just comment out the code. -echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 -echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 +echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6; } am__include="#" am__quote= _am_result=none @@ -2662,7 +3163,7 @@ echo "include confinc" > confmf # In particular we don't look at `^make:' because GNU make might # be invoked under some other name (usually "gmake"), in which # case it prints its new name instead of `make'. -if test "`$am_make -s -f confmf 2> /dev/null | fgrep -v 'ing directory'`" = "done"; then +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then am__include=include am__quote= _am_result=GNU @@ -2678,22 +3179,20 @@ if test "$am__include" = "#"; then fi -echo "$as_me:$LINENO: result: $_am_result" >&5 -echo "${ECHO_T}$_am_result" >&6 +{ echo "$as_me:$LINENO: result: $_am_result" >&5 +echo "${ECHO_T}$_am_result" >&6; } rm -f confinc confmf -# Check whether --enable-dependency-tracking or --disable-dependency-tracking was given. +# Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then - enableval="$enable_dependency_tracking" + enableval=$enable_dependency_tracking; +fi -fi; if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi - - -if test "x$enable_dependency_tracking" != xno; then + if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else @@ -2703,11 +3202,10 @@ fi - depcc="$CC" am_compiler_list= -echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 -echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6; } if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -2722,18 +3220,34 @@ else # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. - echo '#include "conftest.h"' > conftest.c - echo 'int i;' > conftest.h - echo "${am__include} ${am__quote}conftest.Po${am__quote}" > confmf + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in nosideeffect) @@ -2751,13 +3265,26 @@ else # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. if depmode=$depmode \ - source=conftest.c object=conftest.o \ - depfile=conftest.Po tmpdepfile=conftest.TPo \ - $SHELL ./depcomp $depcc -c conftest.c -o conftest.o >/dev/null 2>&1 && - grep conftest.h conftest.Po > /dev/null 2>&1 && + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - am_cv_CC_dependencies_compiler_type=$depmode - break + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi fi done @@ -2768,16 +3295,26 @@ else fi fi -echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 -echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6 +{ echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 +echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -2790,32 +3327,34 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done +IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then - echo "$as_me:$LINENO: result: $RANLIB" >&5 -echo "${ECHO_T}$RANLIB" >&6 + { echo "$as_me:$LINENO: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } fi + fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -2828,31 +3367,171 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_RANLIB="ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done +IFS=$as_save_IFS - test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then - echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 -echo "${ECHO_T}$ac_ct_RANLIB" >&6 + { echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } fi - RANLIB=$ac_ct_RANLIB + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi else RANLIB="$ac_cv_prog_RANLIB" fi +if test "x$CC" != xcc; then + { echo "$as_me:$LINENO: checking whether $CC and cc understand -c and -o together" >&5 +echo $ECHO_N "checking whether $CC and cc understand -c and -o together... $ECHO_C" >&6; } +else + { echo "$as_me:$LINENO: checking whether cc understands -c and -o together" >&5 +echo $ECHO_N "checking whether cc understands -c and -o together... $ECHO_C" >&6; } +fi +set dummy $CC; ac_cc=`echo $2 | + sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` +if { as_var=ac_cv_prog_cc_${ac_cc}_c_o; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +# Make sure it works both with $CC and with simple cc. +# We do the test twice because some compilers refuse to overwrite an +# existing .o file with -o, though they will create one. +ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5' +rm -f conftest2.* +if { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + test -f conftest2.$ac_objext && { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; +then + eval ac_cv_prog_cc_${ac_cc}_c_o=yes + if test "x$CC" != xcc; then + # Test first that cc exists at all. + if { ac_try='cc -c conftest.$ac_ext >&5' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5' + rm -f conftest2.* + if { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + test -f conftest2.$ac_objext && { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; + then + # cc works too. + : + else + # cc exists but doesn't like -o. + eval ac_cv_prog_cc_${ac_cc}_c_o=no + fi + fi + fi +else + eval ac_cv_prog_cc_${ac_cc}_c_o=no +fi +rm -f core conftest* + +fi +if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + +cat >>confdefs.h <<\_ACEOF +#define NO_MINUS_C_MINUS_O 1 +_ACEOF + +fi + +# FIXME: we rely on the cache variable name because +# there is no other way. +set dummy $CC +ac_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` +if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" != yes"; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi + + # Checks for header files. @@ -2864,9 +3543,9 @@ fi ac_header_dirent=no for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do as_ac_Header=`echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_hdr that defines DIR" >&5 -echo $ECHO_N "checking for $ac_hdr that defines DIR... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then +{ echo "$as_me:$LINENO: checking for $ac_hdr that defines DIR" >&5 +echo $ECHO_N "checking for $ac_hdr that defines DIR... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF @@ -2888,38 +3567,35 @@ return 0; } _ACEOF rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -eval "$as_ac_Header=no" + eval "$as_ac_Header=no" fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 @@ -2931,13 +3607,12 @@ fi done # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. if test $ac_header_dirent = dirent.h; then - echo "$as_me:$LINENO: checking for library containing opendir" >&5 -echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6 + { echo "$as_me:$LINENO: checking for library containing opendir" >&5 +echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6; } if test "${ac_cv_search_opendir+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS -ac_cv_search_opendir=no cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -2945,126 +3620,83 @@ cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -/* Override any gcc2 internal prototype to avoid an error. */ +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ char opendir (); int main () { -opendir (); +return opendir (); ; return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 +for ac_lib in '' dir; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_search_opendir="none required" + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_search_opendir=$ac_res else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -if test "$ac_cv_search_opendir" = no; then - for ac_lib in dir; do - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char opendir (); -int -main () -{ -opendir (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_search_opendir="-l$ac_lib" -break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 +fi +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext + if test "${ac_cv_search_opendir+set}" = set; then + break fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - done +done +if test "${ac_cv_search_opendir+set}" = set; then + : +else + ac_cv_search_opendir=no fi +rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi -echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5 -echo "${ECHO_T}$ac_cv_search_opendir" >&6 -if test "$ac_cv_search_opendir" != no; then - test "$ac_cv_search_opendir" = "none required" || LIBS="$ac_cv_search_opendir $LIBS" +{ echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5 +echo "${ECHO_T}$ac_cv_search_opendir" >&6; } +ac_res=$ac_cv_search_opendir +if test "$ac_res" != no; then + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi else - echo "$as_me:$LINENO: checking for library containing opendir" >&5 -echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6 + { echo "$as_me:$LINENO: checking for library containing opendir" >&5 +echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6; } if test "${ac_cv_search_opendir+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS -ac_cv_search_opendir=no cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -3072,115 +3704,73 @@ cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -/* Override any gcc2 internal prototype to avoid an error. */ +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ char opendir (); int main () { -opendir (); +return opendir (); ; return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 +for ac_lib in '' x; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_search_opendir="none required" + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_search_opendir=$ac_res else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 + fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -if test "$ac_cv_search_opendir" = no; then - for ac_lib in x; do - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char opendir (); -int -main () -{ -opendir (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_search_opendir="-l$ac_lib" -break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext + if test "${ac_cv_search_opendir+set}" = set; then + break fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - done +done +if test "${ac_cv_search_opendir+set}" = set; then + : +else + ac_cv_search_opendir=no fi +rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi -echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5 -echo "${ECHO_T}$ac_cv_search_opendir" >&6 -if test "$ac_cv_search_opendir" != no; then - test "$ac_cv_search_opendir" = "none required" || LIBS="$ac_cv_search_opendir $LIBS" +{ echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5 +echo "${ECHO_T}$ac_cv_search_opendir" >&6; } +ac_res=$ac_cv_search_opendir +if test "$ac_res" != no; then + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi @@ -3191,8 +3781,8 @@ ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu -echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 -echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= @@ -3226,24 +3816,22 @@ cat >>conftest.$ac_ext <<_ACEOF #endif Syntax error _ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : else echo "$as_me: failed program was:" >&5 @@ -3252,9 +3840,10 @@ sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi + rm -f conftest.err conftest.$ac_ext - # OK, works on sane cases. Now check whether non-existent headers + # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ @@ -3264,24 +3853,22 @@ cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then # Broken: success on invalid input. continue else @@ -3292,6 +3879,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_preproc_ok=: break fi + rm -f conftest.err conftest.$ac_ext done @@ -3309,8 +3897,8 @@ fi else ac_cv_prog_CPP=$CPP fi -echo "$as_me:$LINENO: result: $CPP" >&5 -echo "${ECHO_T}$CPP" >&6 +{ echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do @@ -3333,24 +3921,22 @@ cat >>conftest.$ac_ext <<_ACEOF #endif Syntax error _ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : else echo "$as_me: failed program was:" >&5 @@ -3359,9 +3945,10 @@ sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi + rm -f conftest.err conftest.$ac_ext - # OK, works on sane cases. Now check whether non-existent headers + # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ @@ -3371,24 +3958,22 @@ cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then # Broken: success on invalid input. continue else @@ -3399,6 +3984,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_preproc_ok=: break fi + rm -f conftest.err conftest.$ac_ext done @@ -3421,23 +4007,170 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $ ac_compiler_gnu=$ac_cv_c_compiler_gnu -echo "$as_me:$LINENO: checking for egrep" >&5 -echo $ECHO_N "checking for egrep... $ECHO_C" >&6 -if test "${ac_cv_prog_egrep+set}" = set; then +{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 +echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Extract the first word of "grep ggrep" to use in msg output +if test -z "$GREP"; then +set dummy grep ggrep; ac_prog_name=$2 +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_path_GREP_found=false +# Loop through the user's path and test for each of PROGNAME-LIST +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue + # Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + + $ac_path_GREP_found && break 3 + done +done + +done +IFS=$as_save_IFS + + +fi + +GREP="$ac_cv_path_GREP" +if test -z "$GREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_GREP=$GREP +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 +echo "${ECHO_T}$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } +if test "${ac_cv_path_EGREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else - if echo a | (grep -E '(a|b)') >/dev/null 2>&1 - then ac_cv_prog_egrep='grep -E' - else ac_cv_prog_egrep='egrep' + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + # Extract the first word of "egrep" to use in msg output +if test -z "$EGREP"; then +set dummy egrep; ac_prog_name=$2 +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_path_EGREP_found=false +# Loop through the user's path and test for each of PROGNAME-LIST +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue + # Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + + $ac_path_EGREP_found && break 3 + done +done + +done +IFS=$as_save_IFS + + +fi + +EGREP="$ac_cv_path_EGREP" +if test -z "$EGREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_EGREP=$EGREP +fi + + + fi fi -echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 -echo "${ECHO_T}$ac_cv_prog_egrep" >&6 - EGREP=$ac_cv_prog_egrep +{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 +echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" -echo "$as_me:$LINENO: checking for ANSI C header files" >&5 -echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } if test "${ac_cv_header_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -3461,35 +4194,31 @@ main () } _ACEOF rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -ac_cv_header_stdc=no + ac_cv_header_stdc=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. @@ -3545,6 +4274,7 @@ cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include +#include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) @@ -3564,18 +4294,27 @@ main () for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) - exit(2); - exit (0); + return 2; + return 0; } _ACEOF rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then @@ -3588,12 +4327,14 @@ sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi + + fi fi -echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 -echo "${ECHO_T}$ac_cv_header_stdc" >&6 +{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF @@ -3602,8 +4343,8 @@ _ACEOF fi -echo "$as_me:$LINENO: checking for sys/wait.h that is POSIX.1 compatible" >&5 -echo $ECHO_N "checking for sys/wait.h that is POSIX.1 compatible... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for sys/wait.h that is POSIX.1 compatible" >&5 +echo $ECHO_N "checking for sys/wait.h that is POSIX.1 compatible... $ECHO_C" >&6; } if test "${ac_cv_header_sys_wait_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -3616,7 +4357,7 @@ cat >>conftest.$ac_ext <<_ACEOF #include #include #ifndef WEXITSTATUS -# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) +# define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8) #endif #ifndef WIFEXITED # define WIFEXITED(stat_val) (((stat_val) & 255) == 0) @@ -3633,38 +4374,34 @@ main () } _ACEOF rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_header_sys_wait_h=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -ac_cv_header_sys_wait_h=no + ac_cv_header_sys_wait_h=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5 -echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6 +{ echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5 +echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6; } if test $ac_cv_header_sys_wait_h = yes; then cat >>confdefs.h <<\_ACEOF @@ -3687,9 +4424,9 @@ for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF @@ -3703,38 +4440,35 @@ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -eval "$as_ac_Header=no" + eval "$as_ac_Header=no" fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 @@ -3765,18 +4499,19 @@ done for ac_header in fcntl.h limits.h mach/mach.h netdb.h netinet/in.h paths.h stddef.h stdlib.h string.h sys/ioctl.h sys/mount.h sys/param.h sys/socket.h sys/time.h syslog.h termios.h unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? -echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -3787,41 +4522,37 @@ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -ac_header_compiler=no + ac_header_compiler=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? -echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -3830,24 +4561,22 @@ cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -3855,9 +4584,10 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi + rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in @@ -3881,25 +4611,24 @@ echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\ echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX + ( cat <<\_ASBOX ## -------------------------------------------------- ## ## Report this to launchd-bug-reports@group.apple.com ## ## -------------------------------------------------- ## _ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 + ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then @@ -3913,8 +4642,8 @@ done # Checks for typedefs, structures, and compiler characteristics. -echo "$as_me:$LINENO: checking for stdbool.h that conforms to C99" >&5 -echo $ECHO_N "checking for stdbool.h that conforms to C99... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for stdbool.h that conforms to C99" >&5 +echo $ECHO_N "checking for stdbool.h that conforms to C99... $ECHO_C" >&6; } if test "${ac_cv_header_stdbool_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -3927,22 +4656,22 @@ cat >>conftest.$ac_ext <<_ACEOF #include #ifndef bool -# error bool is not defined + "error: bool is not defined" #endif #ifndef false -# error false is not defined + "error: false is not defined" #endif #if false -# error false is not 0 + "error: false is not 0" #endif #ifndef true -# error true is not defined + "error: true is not defined" #endif #if true != 1 -# error true is not 1 + "error: true is not 1" #endif #ifndef __bool_true_false_are_defined -# error __bool_true_false_are_defined is not defined + "error: __bool_true_false_are_defined is not defined" #endif struct s { _Bool s: 1; _Bool t; } s; @@ -3950,56 +4679,87 @@ cat >>conftest.$ac_ext <<_ACEOF char a[true == 1 ? 1 : -1]; char b[false == 0 ? 1 : -1]; char c[__bool_true_false_are_defined == 1 ? 1 : -1]; - char d[(bool) -0.5 == true ? 1 : -1]; + char d[(bool) 0.5 == true ? 1 : -1]; bool e = &s; - char f[(_Bool) -0.0 == false ? 1 : -1]; + char f[(_Bool) 0.0 == false ? 1 : -1]; char g[true]; char h[sizeof (_Bool)]; char i[sizeof s.t]; + enum { j = false, k = true, l = false * true, m = true * 256 }; + _Bool n[m]; + char o[sizeof n == m * sizeof n[0] ? 1 : -1]; + char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1]; +# if defined __xlc__ || defined __GNUC__ + /* Catch a bug in IBM AIX xlc compiler version 6.0.0.0 + reported by James Lemley on 2005-10-05; see + http://lists.gnu.org/archive/html/bug-coreutils/2005-10/msg00086.html + This test is not quite right, since xlc is allowed to + reject this program, as the initializer for xlcbug is + not one of the forms that C requires support for. + However, doing the test right would require a runtime + test, and that would make cross-compilation harder. + Let us hope that IBM fixes the xlc bug, and also adds + support for this kind of constant expression. In the + meantime, this test will reject xlc, which is OK, since + our stdbool.h substitute should suffice. We also test + this with GCC, where it should work, to detect more + quickly whether someone messes up the test in the + future. */ + char digs[] = "0123456789"; + int xlcbug = 1 / (&(digs + 5)[-2 + (bool) 1] == &digs[4] ? 1 : -1); +# endif + /* Catch a bug in an HP-UX C compiler. See + http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html + http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html + */ + _Bool q = true; + _Bool *pq = &q; int main () { - return !a + !b + !c + !d + !e + !f + !g + !h + !i; + + *pq |= q; + *pq |= ! q; + /* Refer to every declared value, to avoid compiler optimizations. */ + return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l + + !m + !n + !o + !p + !q + !pq); + ; return 0; } _ACEOF rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_header_stdbool_h=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -ac_cv_header_stdbool_h=no + ac_cv_header_stdbool_h=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $ac_cv_header_stdbool_h" >&5 -echo "${ECHO_T}$ac_cv_header_stdbool_h" >&6 -echo "$as_me:$LINENO: checking for _Bool" >&5 -echo $ECHO_N "checking for _Bool... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: result: $ac_cv_header_stdbool_h" >&5 +echo "${ECHO_T}$ac_cv_header_stdbool_h" >&6; } +{ echo "$as_me:$LINENO: checking for _Bool" >&5 +echo $ECHO_N "checking for _Bool... $ECHO_C" >&6; } if test "${ac_cv_type__Bool+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -4010,50 +4770,47 @@ cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default +typedef _Bool ac__type_new_; int main () { -if ((_Bool *) 0) +if ((ac__type_new_ *) 0) return 0; -if (sizeof (_Bool)) +if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_type__Bool=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -ac_cv_type__Bool=no + ac_cv_type__Bool=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $ac_cv_type__Bool" >&5 -echo "${ECHO_T}$ac_cv_type__Bool" >&6 +{ echo "$as_me:$LINENO: result: $ac_cv_type__Bool" >&5 +echo "${ECHO_T}$ac_cv_type__Bool" >&6; } if test $ac_cv_type__Bool = yes; then cat >>confdefs.h <<_ACEOF @@ -4071,8 +4828,8 @@ _ACEOF fi -echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 -echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 +echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6; } if test "${ac_cv_c_const+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -4090,10 +4847,10 @@ main () #ifndef __cplusplus /* Ultrix mips cc rejects this. */ typedef int charset[2]; - const charset x; + const charset cs; /* SunOS 4.1.1 cc rejects this. */ - char const *const *ccp; - char **p; + char const *const *pcpcc; + char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; @@ -4102,16 +4859,17 @@ main () an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; - ccp = &g + (g ? g-g : 0); + pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ - ++ccp; - p = (char**) ccp; - ccp = (char const *const *) p; + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this. */ char *t; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; + if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; @@ -4130,7 +4888,9 @@ main () } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; + if (!foo) return 0; } + return !cs[0] && !zero.x; #endif ; @@ -4138,38 +4898,34 @@ main () } _ACEOF rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_c_const=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -ac_cv_c_const=no + ac_cv_c_const=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 -echo "${ECHO_T}$ac_cv_c_const" >&6 +{ echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 +echo "${ECHO_T}$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then cat >>confdefs.h <<\_ACEOF @@ -4178,8 +4934,8 @@ _ACEOF fi -echo "$as_me:$LINENO: checking for uid_t in sys/types.h" >&5 -echo $ECHO_N "checking for uid_t in sys/types.h... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for uid_t in sys/types.h" >&5 +echo $ECHO_N "checking for uid_t in sys/types.h... $ECHO_C" >&6; } if test "${ac_cv_type_uid_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -4201,8 +4957,8 @@ fi rm -f conftest* fi -echo "$as_me:$LINENO: result: $ac_cv_type_uid_t" >&5 -echo "${ECHO_T}$ac_cv_type_uid_t" >&6 +{ echo "$as_me:$LINENO: result: $ac_cv_type_uid_t" >&5 +echo "${ECHO_T}$ac_cv_type_uid_t" >&6; } if test $ac_cv_type_uid_t = no; then cat >>confdefs.h <<\_ACEOF @@ -4216,8 +4972,8 @@ _ACEOF fi -echo "$as_me:$LINENO: checking for mode_t" >&5 -echo $ECHO_N "checking for mode_t... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for mode_t" >&5 +echo $ECHO_N "checking for mode_t... $ECHO_C" >&6; } if test "${ac_cv_type_mode_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -4228,50 +4984,47 @@ cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default +typedef mode_t ac__type_new_; int main () { -if ((mode_t *) 0) +if ((ac__type_new_ *) 0) return 0; -if (sizeof (mode_t)) +if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_type_mode_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -ac_cv_type_mode_t=no + ac_cv_type_mode_t=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $ac_cv_type_mode_t" >&5 -echo "${ECHO_T}$ac_cv_type_mode_t" >&6 +{ echo "$as_me:$LINENO: result: $ac_cv_type_mode_t" >&5 +echo "${ECHO_T}$ac_cv_type_mode_t" >&6; } if test $ac_cv_type_mode_t = yes; then : else @@ -4282,8 +5035,8 @@ _ACEOF fi -echo "$as_me:$LINENO: checking for off_t" >&5 -echo $ECHO_N "checking for off_t... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for off_t" >&5 +echo $ECHO_N "checking for off_t... $ECHO_C" >&6; } if test "${ac_cv_type_off_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -4294,62 +5047,59 @@ cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default +typedef off_t ac__type_new_; int main () { -if ((off_t *) 0) +if ((ac__type_new_ *) 0) return 0; -if (sizeof (off_t)) +if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_type_off_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -ac_cv_type_off_t=no + ac_cv_type_off_t=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $ac_cv_type_off_t" >&5 -echo "${ECHO_T}$ac_cv_type_off_t" >&6 +{ echo "$as_me:$LINENO: result: $ac_cv_type_off_t" >&5 +echo "${ECHO_T}$ac_cv_type_off_t" >&6; } if test $ac_cv_type_off_t = yes; then : else cat >>confdefs.h <<_ACEOF -#define off_t long +#define off_t long int _ACEOF fi -echo "$as_me:$LINENO: checking for pid_t" >&5 -echo $ECHO_N "checking for pid_t... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for pid_t" >&5 +echo $ECHO_N "checking for pid_t... $ECHO_C" >&6; } if test "${ac_cv_type_pid_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -4360,50 +5110,47 @@ cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default +typedef pid_t ac__type_new_; int main () { -if ((pid_t *) 0) +if ((ac__type_new_ *) 0) return 0; -if (sizeof (pid_t)) +if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_type_pid_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -ac_cv_type_pid_t=no + ac_cv_type_pid_t=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5 -echo "${ECHO_T}$ac_cv_type_pid_t" >&6 +{ echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5 +echo "${ECHO_T}$ac_cv_type_pid_t" >&6; } if test $ac_cv_type_pid_t = yes; then : else @@ -4414,8 +5161,8 @@ _ACEOF fi -echo "$as_me:$LINENO: checking for size_t" >&5 -echo $ECHO_N "checking for size_t... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for size_t" >&5 +echo $ECHO_N "checking for size_t... $ECHO_C" >&6; } if test "${ac_cv_type_size_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -4426,62 +5173,59 @@ cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default +typedef size_t ac__type_new_; int main () { -if ((size_t *) 0) +if ((ac__type_new_ *) 0) return 0; -if (sizeof (size_t)) +if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_type_size_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -ac_cv_type_size_t=no + ac_cv_type_size_t=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 -echo "${ECHO_T}$ac_cv_type_size_t" >&6 +{ echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 +echo "${ECHO_T}$ac_cv_type_size_t" >&6; } if test $ac_cv_type_size_t = yes; then : else cat >>confdefs.h <<_ACEOF -#define size_t unsigned +#define size_t unsigned int _ACEOF fi -echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5 -echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5 +echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6; } if test "${ac_cv_header_time+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -4505,38 +5249,34 @@ return 0; } _ACEOF rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_header_time=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -ac_cv_header_time=no + ac_cv_header_time=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5 -echo "${ECHO_T}$ac_cv_header_time" >&6 +{ echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5 +echo "${ECHO_T}$ac_cv_header_time" >&6; } if test $ac_cv_header_time = yes; then cat >>confdefs.h <<\_ACEOF @@ -4545,8 +5285,8 @@ _ACEOF fi -echo "$as_me:$LINENO: checking whether struct tm is in sys/time.h or time.h" >&5 -echo $ECHO_N "checking whether struct tm is in sys/time.h or time.h... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking whether struct tm is in sys/time.h or time.h" >&5 +echo $ECHO_N "checking whether struct tm is in sys/time.h or time.h... $ECHO_C" >&6; } if test "${ac_cv_struct_tm+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -4562,44 +5302,42 @@ cat >>conftest.$ac_ext <<_ACEOF int main () { -struct tm *tp; tp->tm_sec; +struct tm tm; + int *p = &tm.tm_sec; + return !p; ; return 0; } _ACEOF rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_struct_tm=time.h else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -ac_cv_struct_tm=sys/time.h + ac_cv_struct_tm=sys/time.h fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $ac_cv_struct_tm" >&5 -echo "${ECHO_T}$ac_cv_struct_tm" >&6 +{ echo "$as_me:$LINENO: result: $ac_cv_struct_tm" >&5 +echo "${ECHO_T}$ac_cv_struct_tm" >&6; } if test $ac_cv_struct_tm = sys/time.h; then cat >>confdefs.h <<\_ACEOF @@ -4612,8 +5350,8 @@ fi # Checks for library functions. # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! -echo "$as_me:$LINENO: checking for working alloca.h" >&5 -echo $ECHO_N "checking for working alloca.h... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for working alloca.h" >&5 +echo $ECHO_N "checking for working alloca.h... $ECHO_C" >&6; } if test "${ac_cv_working_alloca_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -4628,44 +5366,42 @@ int main () { char *p = (char *) alloca (2 * sizeof (int)); + if (p) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_working_alloca_h=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -ac_cv_working_alloca_h=no + ac_cv_working_alloca_h=no fi -rm -f conftest.err conftest.$ac_objext \ + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $ac_cv_working_alloca_h" >&5 -echo "${ECHO_T}$ac_cv_working_alloca_h" >&6 +{ echo "$as_me:$LINENO: result: $ac_cv_working_alloca_h" >&5 +echo "${ECHO_T}$ac_cv_working_alloca_h" >&6; } if test $ac_cv_working_alloca_h = yes; then cat >>confdefs.h <<\_ACEOF @@ -4674,8 +5410,8 @@ _ACEOF fi -echo "$as_me:$LINENO: checking for alloca" >&5 -echo $ECHO_N "checking for alloca... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for alloca" >&5 +echo $ECHO_N "checking for alloca... $ECHO_C" >&6; } if test "${ac_cv_func_alloca_works+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -4692,7 +5428,7 @@ cat >>conftest.$ac_ext <<_ACEOF # include # define alloca _alloca # else -# if HAVE_ALLOCA_H +# ifdef HAVE_ALLOCA_H # include # else # ifdef _AIX @@ -4710,44 +5446,42 @@ int main () { char *p = (char *) alloca (1); + if (p) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_func_alloca_works=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -ac_cv_func_alloca_works=no + ac_cv_func_alloca_works=no fi -rm -f conftest.err conftest.$ac_objext \ + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $ac_cv_func_alloca_works" >&5 -echo "${ECHO_T}$ac_cv_func_alloca_works" >&6 +{ echo "$as_me:$LINENO: result: $ac_cv_func_alloca_works" >&5 +echo "${ECHO_T}$ac_cv_func_alloca_works" >&6; } if test $ac_cv_func_alloca_works = yes; then @@ -4761,15 +5495,15 @@ else # contain a buggy version. If you still want to use their alloca, # use ar to extract alloca.o from them instead of compiling alloca.c. -ALLOCA=alloca.$ac_objext +ALLOCA=\${LIBOBJDIR}alloca.$ac_objext cat >>confdefs.h <<\_ACEOF #define C_ALLOCA 1 _ACEOF -echo "$as_me:$LINENO: checking whether \`alloca.c' needs Cray hooks" >&5 -echo $ECHO_N "checking whether \`alloca.c' needs Cray hooks... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking whether \`alloca.c' needs Cray hooks" >&5 +echo $ECHO_N "checking whether \`alloca.c' needs Cray hooks... $ECHO_C" >&6; } if test "${ac_cv_os_cray+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -4779,7 +5513,7 @@ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -#if defined(CRAY) && ! defined(CRAY2) +#if defined CRAY && ! defined CRAY2 webecray #else wenotbecray @@ -4795,14 +5529,14 @@ fi rm -f conftest* fi -echo "$as_me:$LINENO: result: $ac_cv_os_cray" >&5 -echo "${ECHO_T}$ac_cv_os_cray" >&6 +{ echo "$as_me:$LINENO: result: $ac_cv_os_cray" >&5 +echo "${ECHO_T}$ac_cv_os_cray" >&6; } if test $ac_cv_os_cray = yes; then for ac_func in _getb67 GETB67 getb67; do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF @@ -4828,68 +5562,60 @@ cat >>conftest.$ac_ext <<_ACEOF #undef $ac_func -/* Override any gcc2 internal prototype to avoid an error. */ +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" -{ #endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +#if defined __stub_$ac_func || defined __stub___$ac_func choke me -#else -char (*f) () = $ac_func; -#endif -#ifdef __cplusplus -} #endif int main () { -return f != $ac_func; +return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -eval "$as_ac_var=no" + eval "$as_ac_var=no" fi -rm -f conftest.err conftest.$ac_objext \ + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF @@ -4902,8 +5628,8 @@ fi done fi -echo "$as_me:$LINENO: checking stack direction for C alloca" >&5 -echo $ECHO_N "checking stack direction for C alloca... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking stack direction for C alloca" >&5 +echo $ECHO_N "checking stack direction for C alloca... $ECHO_C" >&6; } if test "${ac_cv_c_stack_direction+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -4916,6 +5642,7 @@ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ +$ac_includes_default int find_stack_direction () { @@ -4933,17 +5660,26 @@ find_stack_direction () int main () { - exit (find_stack_direction () < 0); + return find_stack_direction () < 0; } _ACEOF rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then @@ -4956,11 +5692,13 @@ sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_c_stack_direction=-1 fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi + + fi -echo "$as_me:$LINENO: result: $ac_cv_c_stack_direction" >&5 -echo "${ECHO_T}$ac_cv_c_stack_direction" >&6 +{ echo "$as_me:$LINENO: result: $ac_cv_c_stack_direction" >&5 +echo "${ECHO_T}$ac_cv_c_stack_direction" >&6; } cat >>confdefs.h <<_ACEOF #define STACK_DIRECTION $ac_cv_c_stack_direction @@ -4969,8 +5707,8 @@ _ACEOF fi -echo "$as_me:$LINENO: checking whether closedir returns void" >&5 -echo $ECHO_N "checking whether closedir returns void... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking whether closedir returns void" >&5 +echo $ECHO_N "checking whether closedir returns void... $ECHO_C" >&6; } if test "${ac_cv_func_closedir_void+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -4992,19 +5730,28 @@ int closedir (); int main () { -exit (closedir (opendir (".")) != 0); +return closedir (opendir (".")) != 0; ; return 0; } _ACEOF rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then @@ -5017,11 +5764,13 @@ sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_func_closedir_void=yes fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi + + fi -echo "$as_me:$LINENO: result: $ac_cv_func_closedir_void" >&5 -echo "${ECHO_T}$ac_cv_func_closedir_void" >&6 +{ echo "$as_me:$LINENO: result: $ac_cv_func_closedir_void" >&5 +echo "${ECHO_T}$ac_cv_func_closedir_void" >&6; } if test $ac_cv_func_closedir_void = yes; then cat >>confdefs.h <<\_ACEOF @@ -5031,22 +5780,22 @@ _ACEOF fi - -for ac_header in unistd.h vfork.h +for ac_header in vfork.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? -echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -5057,41 +5806,37 @@ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -ac_header_compiler=no + ac_header_compiler=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? -echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -5100,24 +5845,22 @@ cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -5125,9 +5868,10 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi + rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in @@ -5151,25 +5895,24 @@ echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\ echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX + ( cat <<\_ASBOX ## -------------------------------------------------- ## ## Report this to launchd-bug-reports@group.apple.com ## ## -------------------------------------------------- ## _ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 + ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then @@ -5186,9 +5929,9 @@ done for ac_func in fork vfork do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF @@ -5214,68 +5957,60 @@ cat >>conftest.$ac_ext <<_ACEOF #undef $ac_func -/* Override any gcc2 internal prototype to avoid an error. */ +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" -{ #endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +#if defined __stub_$ac_func || defined __stub___$ac_func choke me -#else -char (*f) () = $ac_func; -#endif -#ifdef __cplusplus -} #endif int main () { -return f != $ac_func; +return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -eval "$as_ac_var=no" + eval "$as_ac_var=no" fi -rm -f conftest.err conftest.$ac_objext \ + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 @@ -5285,8 +6020,8 @@ fi done if test "x$ac_cv_func_fork" = xyes; then - echo "$as_me:$LINENO: checking for working fork" >&5 -echo $ECHO_N "checking for working fork... $ECHO_C" >&6 + { echo "$as_me:$LINENO: checking for working fork" >&5 +echo $ECHO_N "checking for working fork... $ECHO_C" >&6; } if test "${ac_cv_func_fork_works+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -5294,27 +6029,40 @@ else ac_cv_func_fork_works=cross else cat >conftest.$ac_ext <<_ACEOF -/* By Ruediger Kuhlmann. */ - #include - #if HAVE_UNISTD_H - # include - #endif - /* Some systems only have a dummy stub for fork() */ - int main () - { - if (fork() < 0) - exit (1); - exit (0); - } +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* By Ruediger Kuhlmann. */ + return fork () < 0; + + ; + return 0; +} _ACEOF rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then @@ -5327,11 +6075,13 @@ sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_func_fork_works=no fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi + + fi -echo "$as_me:$LINENO: result: $ac_cv_func_fork_works" >&5 -echo "${ECHO_T}$ac_cv_func_fork_works" >&6 +{ echo "$as_me:$LINENO: result: $ac_cv_func_fork_works" >&5 +echo "${ECHO_T}$ac_cv_func_fork_works" >&6; } else ac_cv_func_fork_works=$ac_cv_func_fork @@ -5351,8 +6101,8 @@ echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross co fi ac_cv_func_vfork_works=$ac_cv_func_vfork if test "x$ac_cv_func_vfork" = xyes; then - echo "$as_me:$LINENO: checking for working vfork" >&5 -echo $ECHO_N "checking for working vfork... $ECHO_C" >&6 + { echo "$as_me:$LINENO: checking for working vfork" >&5 +echo $ECHO_N "checking for working vfork... $ECHO_C" >&6; } if test "${ac_cv_func_vfork_works+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -5366,15 +6116,9 @@ cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Thanks to Paul Eggert for this test. */ -#include -#include -#include -#include +$ac_includes_default #include -#if HAVE_UNISTD_H -# include -#endif -#if HAVE_VFORK_H +#ifdef HAVE_VFORK_H # include #endif /* On some sparc systems, changes by the child to local and incoming @@ -5445,7 +6189,7 @@ main () while (wait(&status) != child) ; - exit( + return ( /* Was there some problem with vforking? */ child < 0 @@ -5462,13 +6206,22 @@ main () } _ACEOF rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then @@ -5481,11 +6234,13 @@ sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_func_vfork_works=no fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi + + fi -echo "$as_me:$LINENO: result: $ac_cv_func_vfork_works" >&5 -echo "${ECHO_T}$ac_cv_func_vfork_works" >&6 +{ echo "$as_me:$LINENO: result: $ac_cv_func_vfork_works" >&5 +echo "${ECHO_T}$ac_cv_func_vfork_works" >&6; } fi; if test "x$ac_cv_func_fork_works" = xcross; then @@ -5516,8 +6271,8 @@ _ACEOF fi if test $ac_cv_c_compiler_gnu = yes; then - echo "$as_me:$LINENO: checking whether $CC needs -traditional" >&5 -echo $ECHO_N "checking whether $CC needs -traditional... $ECHO_C" >&6 + { echo "$as_me:$LINENO: checking whether $CC needs -traditional" >&5 +echo $ECHO_N "checking whether $CC needs -traditional... $ECHO_C" >&6; } if test "${ac_cv_prog_gcc_traditional+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -5558,15 +6313,15 @@ rm -f conftest* fi fi -echo "$as_me:$LINENO: result: $ac_cv_prog_gcc_traditional" >&5 -echo "${ECHO_T}$ac_cv_prog_gcc_traditional" >&6 +{ echo "$as_me:$LINENO: result: $ac_cv_prog_gcc_traditional" >&5 +echo "${ECHO_T}$ac_cv_prog_gcc_traditional" >&6; } if test $ac_cv_prog_gcc_traditional = yes; then CC="$CC -traditional" fi fi -echo "$as_me:$LINENO: checking whether lstat dereferences a symlink specified with a trailing slash" >&5 -echo $ECHO_N "checking whether lstat dereferences a symlink specified with a trailing slash... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking whether lstat dereferences a symlink specified with a trailing slash" >&5 +echo $ECHO_N "checking whether lstat dereferences a symlink specified with a trailing slash... $ECHO_C" >&6; } if test "${ac_cv_func_lstat_dereferences_slashed_symlink+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -5590,19 +6345,28 @@ struct stat sbuf; /* Linux will dereference the symlink and fail. That is better in the sense that it means we will not have to compile and use the lstat wrapper. */ - exit (lstat ("conftest.sym/", &sbuf) ? 0 : 1); + return lstat ("conftest.sym/", &sbuf) == 0; ; return 0; } _ACEOF rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then @@ -5615,8 +6379,10 @@ sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_func_lstat_dereferences_slashed_symlink=no fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi + + else # If the `ln -s' command failed, then we probably don't even # have an lstat function. @@ -5625,8 +6391,8 @@ fi rm -f conftest.sym conftest.file fi -echo "$as_me:$LINENO: result: $ac_cv_func_lstat_dereferences_slashed_symlink" >&5 -echo "${ECHO_T}$ac_cv_func_lstat_dereferences_slashed_symlink" >&6 +{ echo "$as_me:$LINENO: result: $ac_cv_func_lstat_dereferences_slashed_symlink" >&5 +echo "${ECHO_T}$ac_cv_func_lstat_dereferences_slashed_symlink" >&6; } test $ac_cv_func_lstat_dereferences_slashed_symlink = yes && @@ -5636,18 +6402,16 @@ _ACEOF if test $ac_cv_func_lstat_dereferences_slashed_symlink = no; then - case $LIBOBJS in - "lstat.$ac_objext" | \ - *" lstat.$ac_objext" | \ - "lstat.$ac_objext "* | \ + case " $LIBOBJS " in *" lstat.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS lstat.$ac_objext" ;; + *) LIBOBJS="$LIBOBJS lstat.$ac_objext" + ;; esac fi -echo "$as_me:$LINENO: checking whether lstat accepts an empty string" >&5 -echo $ECHO_N "checking whether lstat accepts an empty string... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking whether lstat accepts an empty string" >&5 +echo $ECHO_N "checking whether lstat accepts an empty string... $ECHO_C" >&6; } if test "${ac_cv_func_lstat_empty_string_bug+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -5665,43 +6429,52 @@ int main () { struct stat sbuf; - exit (lstat ("", &sbuf) ? 1 : 0); + return lstat ("", &sbuf) == 0; ; return 0; } _ACEOF rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then - ac_cv_func_lstat_empty_string_bug=yes + ac_cv_func_lstat_empty_string_bug=no else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) -ac_cv_func_lstat_empty_string_bug=no +ac_cv_func_lstat_empty_string_bug=yes fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi + + fi -echo "$as_me:$LINENO: result: $ac_cv_func_lstat_empty_string_bug" >&5 -echo "${ECHO_T}$ac_cv_func_lstat_empty_string_bug" >&6 +{ echo "$as_me:$LINENO: result: $ac_cv_func_lstat_empty_string_bug" >&5 +echo "${ECHO_T}$ac_cv_func_lstat_empty_string_bug" >&6; } if test $ac_cv_func_lstat_empty_string_bug = yes; then - case $LIBOBJS in - "lstat.$ac_objext" | \ - *" lstat.$ac_objext" | \ - "lstat.$ac_objext "* | \ + case " $LIBOBJS " in *" lstat.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS lstat.$ac_objext" ;; + *) LIBOBJS="$LIBOBJS lstat.$ac_objext" + ;; esac @@ -5711,8 +6484,8 @@ _ACEOF fi -echo "$as_me:$LINENO: checking whether lstat dereferences a symlink specified with a trailing slash" >&5 -echo $ECHO_N "checking whether lstat dereferences a symlink specified with a trailing slash... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking whether lstat dereferences a symlink specified with a trailing slash" >&5 +echo $ECHO_N "checking whether lstat dereferences a symlink specified with a trailing slash... $ECHO_C" >&6; } if test "${ac_cv_func_lstat_dereferences_slashed_symlink+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -5736,19 +6509,28 @@ struct stat sbuf; /* Linux will dereference the symlink and fail. That is better in the sense that it means we will not have to compile and use the lstat wrapper. */ - exit (lstat ("conftest.sym/", &sbuf) ? 0 : 1); + return lstat ("conftest.sym/", &sbuf) == 0; ; return 0; } _ACEOF rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then @@ -5761,8 +6543,10 @@ sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_func_lstat_dereferences_slashed_symlink=no fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi + + else # If the `ln -s' command failed, then we probably don't even # have an lstat function. @@ -5771,8 +6555,8 @@ fi rm -f conftest.sym conftest.file fi -echo "$as_me:$LINENO: result: $ac_cv_func_lstat_dereferences_slashed_symlink" >&5 -echo "${ECHO_T}$ac_cv_func_lstat_dereferences_slashed_symlink" >&6 +{ echo "$as_me:$LINENO: result: $ac_cv_func_lstat_dereferences_slashed_symlink" >&5 +echo "${ECHO_T}$ac_cv_func_lstat_dereferences_slashed_symlink" >&6; } test $ac_cv_func_lstat_dereferences_slashed_symlink = yes && @@ -5782,12 +6566,10 @@ _ACEOF if test $ac_cv_func_lstat_dereferences_slashed_symlink = no; then - case $LIBOBJS in - "lstat.$ac_objext" | \ - *" lstat.$ac_objext" | \ - "lstat.$ac_objext "* | \ + case " $LIBOBJS " in *" lstat.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS lstat.$ac_objext" ;; + *) LIBOBJS="$LIBOBJS lstat.$ac_objext" + ;; esac fi @@ -5796,18 +6578,19 @@ fi for ac_header in stdlib.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? -echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -5818,41 +6601,37 @@ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -ac_header_compiler=no + ac_header_compiler=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? -echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -5861,24 +6640,22 @@ cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -5886,9 +6663,10 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi + rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in @@ -5912,25 +6690,24 @@ echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\ echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX + ( cat <<\_ASBOX ## -------------------------------------------------- ## ## Report this to launchd-bug-reports@group.apple.com ## ## -------------------------------------------------- ## _ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 + ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then @@ -5942,8 +6719,8 @@ fi done -echo "$as_me:$LINENO: checking for GNU libc compatible malloc" >&5 -echo $ECHO_N "checking for GNU libc compatible malloc... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for GNU libc compatible malloc" >&5 +echo $ECHO_N "checking for GNU libc compatible malloc... $ECHO_C" >&6; } if test "${ac_cv_func_malloc_0_nonnull+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -5956,7 +6733,7 @@ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -#if STDC_HEADERS || HAVE_STDLIB_H +#if defined STDC_HEADERS || defined HAVE_STDLIB_H # include #else char *malloc (); @@ -5965,19 +6742,28 @@ char *malloc (); int main () { -exit (malloc (0) ? 0 : 1); +return ! malloc (0); ; return 0; } _ACEOF rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then @@ -5990,11 +6776,13 @@ sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_func_malloc_0_nonnull=no fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi + + fi -echo "$as_me:$LINENO: result: $ac_cv_func_malloc_0_nonnull" >&5 -echo "${ECHO_T}$ac_cv_func_malloc_0_nonnull" >&6 +{ echo "$as_me:$LINENO: result: $ac_cv_func_malloc_0_nonnull" >&5 +echo "${ECHO_T}$ac_cv_func_malloc_0_nonnull" >&6; } if test $ac_cv_func_malloc_0_nonnull = yes; then cat >>confdefs.h <<\_ACEOF @@ -6006,12 +6794,10 @@ else #define HAVE_MALLOC 0 _ACEOF - case $LIBOBJS in - "malloc.$ac_objext" | \ - *" malloc.$ac_objext" | \ - "malloc.$ac_objext "* | \ + case " $LIBOBJS " in *" malloc.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS malloc.$ac_objext" ;; + *) LIBOBJS="$LIBOBJS malloc.$ac_objext" + ;; esac @@ -6026,21 +6812,23 @@ fi -for ac_header in stdlib.h sys/time.h unistd.h + +for ac_header in $ac_header_list do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? -echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -6051,41 +6839,37 @@ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -ac_header_compiler=no + ac_header_compiler=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? -echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -6094,24 +6878,22 @@ cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -6119,9 +6901,10 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi + rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in @@ -6145,25 +6928,24 @@ echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\ echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX + ( cat <<\_ASBOX ## -------------------------------------------------- ## ## Report this to launchd-bug-reports@group.apple.com ## ## -------------------------------------------------- ## _ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 + ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then @@ -6176,12 +6958,19 @@ fi done -for ac_func in alarm + + + + + + + +for ac_func in $ac_func_list do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF @@ -6207,68 +6996,60 @@ cat >>conftest.$ac_ext <<_ACEOF #undef $ac_func -/* Override any gcc2 internal prototype to avoid an error. */ +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" -{ #endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +#if defined __stub_$ac_func || defined __stub___$ac_func choke me -#else -char (*f) () = $ac_func; -#endif -#ifdef __cplusplus -} #endif int main () { -return f != $ac_func; +return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -eval "$as_ac_var=no" + eval "$as_ac_var=no" fi -rm -f conftest.err conftest.$ac_objext \ + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 @@ -6277,8 +7058,24 @@ _ACEOF fi done -echo "$as_me:$LINENO: checking for working mktime" >&5 -echo $ECHO_N "checking for working mktime... $ECHO_C" >&6 + + + + + + + + + + + + + + + + +{ echo "$as_me:$LINENO: checking for working mktime" >&5 +echo $ECHO_N "checking for working mktime... $ECHO_C" >&6; } if test "${ac_cv_func_working_mktime+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -6292,26 +7089,24 @@ cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Test program from Paul Eggert and Tony Leneis. */ -#if TIME_WITH_SYS_TIME +#ifdef TIME_WITH_SYS_TIME # include # include #else -# if HAVE_SYS_TIME_H +# ifdef HAVE_SYS_TIME_H # include # else # include # endif #endif -#if HAVE_STDLIB_H -# include -#endif +#include -#if HAVE_UNISTD_H +#ifdef HAVE_UNISTD_H # include #endif -#if !HAVE_ALARM +#ifndef HAVE_ALARM # define alarm(X) /* empty */ #endif @@ -6328,9 +7123,9 @@ static char *tz_strings[] = { }; #define N_STRINGS (sizeof (tz_strings) / sizeof (tz_strings[0])) -/* Fail if mktime fails to convert a date in the spring-forward gap. +/* Return 0 if mktime fails to convert a date in the spring-forward gap. Based on a problem report from Andreas Jaeger. */ -static void +static int spring_forward_gap () { /* glibc (up to about 1998-10-07) failed this test. */ @@ -6349,29 +7144,27 @@ spring_forward_gap () tm.tm_min = 0; tm.tm_sec = 0; tm.tm_isdst = -1; - if (mktime (&tm) == (time_t)-1) - exit (1); + return mktime (&tm) != (time_t) -1; } -static void +static int mktime_test1 (now) time_t now; { struct tm *lt; - if ((lt = localtime (&now)) && mktime (lt) != now) - exit (1); + return ! (lt = localtime (&now)) || mktime (lt) == now; } -static void +static int mktime_test (now) time_t now; { - mktime_test1 (now); - mktime_test1 ((time_t) (time_t_max - now)); - mktime_test1 ((time_t) (time_t_min + now)); + return (mktime_test1 (now) + && mktime_test1 ((time_t) (time_t_max - now)) + && mktime_test1 ((time_t) (time_t_min + now))); } -static void +static int irix_6_4_bug () { /* Based on code from Ariel Faigon. */ @@ -6384,11 +7177,10 @@ irix_6_4_bug () tm.tm_sec = 0; tm.tm_isdst = -1; mktime (&tm); - if (tm.tm_mon != 2 || tm.tm_mday != 31) - exit (1); + return tm.tm_mon == 2 && tm.tm_mday == 31; } -static void +static int bigtime_test (j) int j; { @@ -6410,8 +7202,39 @@ bigtime_test (j) && lt->tm_wday == tm.tm_wday && ((lt->tm_isdst < 0 ? -1 : 0 < lt->tm_isdst) == (tm.tm_isdst < 0 ? -1 : 0 < tm.tm_isdst)))) - exit (1); + return 0; } + return 1; +} + +static int +year_2050_test () +{ + /* The correct answer for 2050-02-01 00:00:00 in Pacific time, + ignoring leap seconds. */ + unsigned long int answer = 2527315200UL; + + struct tm tm; + time_t t; + tm.tm_year = 2050 - 1900; + tm.tm_mon = 2 - 1; + tm.tm_mday = 1; + tm.tm_hour = tm.tm_min = tm.tm_sec = 0; + tm.tm_isdst = -1; + + /* Use the portable POSIX.1 specification "TZ=PST8PDT,M4.1.0,M10.5.0" + instead of "TZ=America/Vancouver" in order to detect the bug even + on systems that don't support the Olson extension, or don't have the + full zoneinfo tables installed. */ + putenv ("TZ=PST8PDT,M4.1.0,M10.5.0"); + + t = mktime (&tm); + + /* Check that the result is either a failure, or close enough + to the correct answer that we can assume the discrepancy is + due to leap seconds. */ + return (t == (time_t) -1 + || (0 < t && answer - 120 <= t && t <= answer + 120)); } int @@ -6438,28 +7261,39 @@ main () putenv (tz_strings[i]); for (t = 0; t <= time_t_max - delta; t += delta) - mktime_test (t); - mktime_test ((time_t) 1); - mktime_test ((time_t) (60 * 60)); - mktime_test ((time_t) (60 * 60 * 24)); + if (! mktime_test (t)) + return 1; + if (! (mktime_test ((time_t) 1) + && mktime_test ((time_t) (60 * 60)) + && mktime_test ((time_t) (60 * 60 * 24)))) + return 1; for (j = 1; 0 < j; j *= 2) - bigtime_test (j); - bigtime_test (j - 1); + if (! bigtime_test (j)) + return 1; + if (! bigtime_test (j - 1)) + return 1; } - irix_6_4_bug (); - spring_forward_gap (); - exit (0); + return ! (irix_6_4_bug () && spring_forward_gap () && year_2050_test ()); } _ACEOF rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then @@ -6472,18 +7306,18 @@ sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_func_working_mktime=no fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi + + fi -echo "$as_me:$LINENO: result: $ac_cv_func_working_mktime" >&5 -echo "${ECHO_T}$ac_cv_func_working_mktime" >&6 +{ echo "$as_me:$LINENO: result: $ac_cv_func_working_mktime" >&5 +echo "${ECHO_T}$ac_cv_func_working_mktime" >&6; } if test $ac_cv_func_working_mktime = no; then - case $LIBOBJS in - "mktime.$ac_objext" | \ - *" mktime.$ac_objext" | \ - "mktime.$ac_objext "* | \ + case " $LIBOBJS " in *" mktime.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS mktime.$ac_objext" ;; + *) LIBOBJS="$LIBOBJS mktime.$ac_objext" + ;; esac fi @@ -6493,18 +7327,19 @@ fi for ac_header in stdlib.h unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? -echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -6515,41 +7350,37 @@ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -ac_header_compiler=no + ac_header_compiler=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? -echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -6558,24 +7389,22 @@ cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -6583,9 +7412,10 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi + rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in @@ -6609,25 +7439,24 @@ echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\ echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX + ( cat <<\_ASBOX ## -------------------------------------------------- ## ## Report this to launchd-bug-reports@group.apple.com ## ## -------------------------------------------------- ## _ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 + ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then @@ -6643,9 +7472,9 @@ done for ac_func in getpagesize do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF @@ -6671,68 +7500,60 @@ cat >>conftest.$ac_ext <<_ACEOF #undef $ac_func -/* Override any gcc2 internal prototype to avoid an error. */ +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" -{ #endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +#if defined __stub_$ac_func || defined __stub___$ac_func choke me -#else -char (*f) () = $ac_func; -#endif -#ifdef __cplusplus -} #endif int main () { -return f != $ac_func; +return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -eval "$as_ac_var=no" + eval "$as_ac_var=no" fi -rm -f conftest.err conftest.$ac_objext \ + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 @@ -6741,8 +7562,8 @@ _ACEOF fi done -echo "$as_me:$LINENO: checking for working mmap" >&5 -echo $ECHO_N "checking for working mmap... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for working mmap" >&5 +echo $ECHO_N "checking for working mmap... $ECHO_C" >&6; } if test "${ac_cv_func_mmap_fixed_mapped+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -6784,21 +7605,21 @@ $ac_includes_default #include #include -#if !STDC_HEADERS && !HAVE_STDLIB_H +#if !defined STDC_HEADERS && !defined HAVE_STDLIB_H char *malloc (); #endif /* This mess was copied from the GNU getpagesize.h. */ -#if !HAVE_GETPAGESIZE +#ifndef HAVE_GETPAGESIZE /* Assume that all systems that can run configure have sys/param.h. */ -# if !HAVE_SYS_PARAM_H +# ifndef HAVE_SYS_PARAM_H # define HAVE_SYS_PARAM_H 1 # endif # ifdef _SC_PAGESIZE # define getpagesize() sysconf(_SC_PAGESIZE) # else /* no _SC_PAGESIZE */ -# if HAVE_SYS_PARAM_H +# ifdef HAVE_SYS_PARAM_H # include # ifdef EXEC_PAGESIZE # define getpagesize() EXEC_PAGESIZE @@ -6837,15 +7658,15 @@ main () /* First, make a file with some known garbage in it. */ data = (char *) malloc (pagesize); if (!data) - exit (1); + return 1; for (i = 0; i < pagesize; ++i) *(data + i) = rand (); umask (0); fd = creat ("conftest.mmap", 0600); if (fd < 0) - exit (1); + return 1; if (write (fd, data, pagesize) != pagesize) - exit (1); + return 1; close (fd); /* Next, try to mmap the file at a fixed address which already has @@ -6853,17 +7674,17 @@ main () we see the same garbage. */ fd = open ("conftest.mmap", O_RDWR); if (fd < 0) - exit (1); + return 1; data2 = (char *) malloc (2 * pagesize); if (!data2) - exit (1); - data2 += (pagesize - ((long) data2 & (pagesize - 1))) & (pagesize - 1); + return 1; + data2 += (pagesize - ((long int) data2 & (pagesize - 1))) & (pagesize - 1); if (data2 != mmap (data2, pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fd, 0L)) - exit (1); + return 1; for (i = 0; i < pagesize; ++i) if (*(data + i) != *(data2 + i)) - exit (1); + return 1; /* Finally, make sure that changes to the mapped area do not percolate back to the file as seen by read(). (This is a bug on @@ -6872,24 +7693,33 @@ main () *(data2 + i) = *(data2 + i) + 1; data3 = (char *) malloc (pagesize); if (!data3) - exit (1); + return 1; if (read (fd, data3, pagesize) != pagesize) - exit (1); + return 1; for (i = 0; i < pagesize; ++i) if (*(data + i) != *(data3 + i)) - exit (1); + return 1; close (fd); - exit (0); + return 0; } _ACEOF rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then @@ -6902,11 +7732,13 @@ sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_func_mmap_fixed_mapped=no fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi + + fi -echo "$as_me:$LINENO: result: $ac_cv_func_mmap_fixed_mapped" >&5 -echo "${ECHO_T}$ac_cv_func_mmap_fixed_mapped" >&6 +{ echo "$as_me:$LINENO: result: $ac_cv_func_mmap_fixed_mapped" >&5 +echo "${ECHO_T}$ac_cv_func_mmap_fixed_mapped" >&6; } if test $ac_cv_func_mmap_fixed_mapped = yes; then cat >>confdefs.h <<\_ACEOF @@ -6920,18 +7752,19 @@ rm -f conftest.mmap for ac_header in stdlib.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? -echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -6942,41 +7775,37 @@ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -ac_header_compiler=no + ac_header_compiler=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? -echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -6985,24 +7814,22 @@ cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -7010,9 +7837,10 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi + rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in @@ -7036,25 +7864,24 @@ echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\ echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX + ( cat <<\_ASBOX ## -------------------------------------------------- ## ## Report this to launchd-bug-reports@group.apple.com ## ## -------------------------------------------------- ## _ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 + ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then @@ -7066,8 +7893,8 @@ fi done -echo "$as_me:$LINENO: checking for GNU libc compatible realloc" >&5 -echo $ECHO_N "checking for GNU libc compatible realloc... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for GNU libc compatible realloc" >&5 +echo $ECHO_N "checking for GNU libc compatible realloc... $ECHO_C" >&6; } if test "${ac_cv_func_realloc_0_nonnull+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -7080,7 +7907,7 @@ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -#if STDC_HEADERS || HAVE_STDLIB_H +#if defined STDC_HEADERS || defined HAVE_STDLIB_H # include #else char *realloc (); @@ -7089,19 +7916,28 @@ char *realloc (); int main () { -exit (realloc (0, 0) ? 0 : 1); +return ! realloc (0, 0); ; return 0; } _ACEOF rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then @@ -7114,11 +7950,13 @@ sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_func_realloc_0_nonnull=no fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi + + fi -echo "$as_me:$LINENO: result: $ac_cv_func_realloc_0_nonnull" >&5 -echo "${ECHO_T}$ac_cv_func_realloc_0_nonnull" >&6 +{ echo "$as_me:$LINENO: result: $ac_cv_func_realloc_0_nonnull" >&5 +echo "${ECHO_T}$ac_cv_func_realloc_0_nonnull" >&6; } if test $ac_cv_func_realloc_0_nonnull = yes; then cat >>confdefs.h <<\_ACEOF @@ -7130,12 +7968,10 @@ else #define HAVE_REALLOC 0 _ACEOF - case $LIBOBJS in - "realloc.$ac_objext" | \ - *" realloc.$ac_objext" | \ - "realloc.$ac_objext "* | \ + case " $LIBOBJS " in *" realloc.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS realloc.$ac_objext" ;; + *) LIBOBJS="$LIBOBJS realloc.$ac_objext" + ;; esac @@ -7152,18 +7988,19 @@ fi for ac_header in sys/select.h sys/socket.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? -echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -7174,41 +8011,37 @@ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -ac_header_compiler=no + ac_header_compiler=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? -echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -7217,24 +8050,22 @@ cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -7242,9 +8073,10 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi + rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in @@ -7268,25 +8100,24 @@ echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\ echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX + ( cat <<\_ASBOX ## -------------------------------------------------- ## ## Report this to launchd-bug-reports@group.apple.com ## ## -------------------------------------------------- ## _ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 + ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then @@ -7298,13 +8129,13 @@ fi done -echo "$as_me:$LINENO: checking types of arguments for select" >&5 -echo $ECHO_N "checking types of arguments for select... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking types of arguments for select" >&5 +echo $ECHO_N "checking types of arguments for select... $ECHO_C" >&6; } if test "${ac_cv_func_select_args+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else for ac_arg234 in 'fd_set *' 'int *' 'void *'; do - for ac_arg1 in 'int' 'size_t' 'unsigned long' 'unsigned'; do + for ac_arg1 in 'int' 'size_t' 'unsigned long int' 'unsigned int'; do for ac_arg5 in 'struct timeval *' 'const struct timeval *'; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ @@ -7313,10 +8144,10 @@ cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default -#if HAVE_SYS_SELECT_H +#ifdef HAVE_SYS_SELECT_H # include #endif -#if HAVE_SYS_SOCKET_H +#ifdef HAVE_SYS_SOCKET_H # include #endif @@ -7331,34 +8162,31 @@ extern int select ($ac_arg1, } _ACEOF rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_func_select_args="$ac_arg1,$ac_arg234,$ac_arg5"; break 3 else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 + fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done done done @@ -7366,8 +8194,8 @@ done : ${ac_cv_func_select_args='int,int *,struct timeval *'} fi -echo "$as_me:$LINENO: result: $ac_cv_func_select_args" >&5 -echo "${ECHO_T}$ac_cv_func_select_args" >&6 +{ echo "$as_me:$LINENO: result: $ac_cv_func_select_args" >&5 +echo "${ECHO_T}$ac_cv_func_select_args" >&6; } ac_save_IFS=$IFS; IFS=',' set dummy `echo "$ac_cv_func_select_args" | sed 's/\*/\*/g'` IFS=$ac_save_IFS @@ -7389,8 +8217,8 @@ _ACEOF rm -f conftest* -echo "$as_me:$LINENO: checking return type of signal handlers" >&5 -echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking return type of signal handlers" >&5 +echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6; } if test "${ac_cv_type_signal+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -7402,64 +8230,52 @@ cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include -#ifdef signal -# undef signal -#endif -#ifdef __cplusplus -extern "C" void (*signal (int, void (*)(int)))(int); -#else -void (*signal ()) (); -#endif int main () { -int i; +return *(signal (0, 0)) (0) == 1; ; return 0; } _ACEOF rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_signal=void + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_signal=int else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -ac_cv_type_signal=int + ac_cv_type_signal=void fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5 -echo "${ECHO_T}$ac_cv_type_signal" >&6 +{ echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5 +echo "${ECHO_T}$ac_cv_type_signal" >&6; } cat >>confdefs.h <<_ACEOF #define RETSIGTYPE $ac_cv_type_signal _ACEOF -echo "$as_me:$LINENO: checking whether stat accepts an empty string" >&5 -echo $ECHO_N "checking whether stat accepts an empty string... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking whether stat accepts an empty string" >&5 +echo $ECHO_N "checking whether stat accepts an empty string... $ECHO_C" >&6; } if test "${ac_cv_func_stat_empty_string_bug+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -7477,43 +8293,52 @@ int main () { struct stat sbuf; - exit (stat ("", &sbuf) ? 1 : 0); + return stat ("", &sbuf) == 0; ; return 0; } _ACEOF rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then - ac_cv_func_stat_empty_string_bug=yes + ac_cv_func_stat_empty_string_bug=no else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) -ac_cv_func_stat_empty_string_bug=no +ac_cv_func_stat_empty_string_bug=yes fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi + + fi -echo "$as_me:$LINENO: result: $ac_cv_func_stat_empty_string_bug" >&5 -echo "${ECHO_T}$ac_cv_func_stat_empty_string_bug" >&6 +{ echo "$as_me:$LINENO: result: $ac_cv_func_stat_empty_string_bug" >&5 +echo "${ECHO_T}$ac_cv_func_stat_empty_string_bug" >&6; } if test $ac_cv_func_stat_empty_string_bug = yes; then - case $LIBOBJS in - "stat.$ac_objext" | \ - *" stat.$ac_objext" | \ - "stat.$ac_objext "* | \ + case " $LIBOBJS " in *" stat.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS stat.$ac_objext" ;; + *) LIBOBJS="$LIBOBJS stat.$ac_objext" + ;; esac @@ -7545,9 +8370,9 @@ fi for ac_func in atexit dup2 gethostname gettimeofday memmove memset mkdir munmap rmdir select setenv socket strcasecmp strchr strdup strerror strrchr strstr strtol do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF @@ -7573,68 +8398,60 @@ cat >>conftest.$ac_ext <<_ACEOF #undef $ac_func -/* Override any gcc2 internal prototype to avoid an error. */ +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" -{ #endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +#if defined __stub_$ac_func || defined __stub___$ac_func choke me -#else -char (*f) () = $ac_func; -#endif -#ifdef __cplusplus -} #endif int main () { -return f != $ac_func; +return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -eval "$as_ac_var=no" + eval "$as_ac_var=no" fi -rm -f conftest.err conftest.$ac_objext \ + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 @@ -7644,12 +8461,10 @@ fi done - ac_config_files="$ac_config_files Makefile src/Makefile" - +ac_config_files="$ac_config_files Makefile src/Makefile" - -if test "$RC_ProjectName" = launchd_libs; then + if test "$RC_ProjectName" = launchd_libs; then LIBS_ONLY_TRUE= LIBS_ONLY_FALSE='#' else @@ -7676,39 +8491,58 @@ _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. -# So, don't put newlines in cache variables' values. +# So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. -{ +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + (set) 2>&1 | - case `(ac_space=' '; set | grep ac_space) 2>&1` in - *ac_space=\ *) + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote # substitution turns \\\\ into \\, and sed turns \\ into \). sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; + ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n \ - "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; - esac; -} | + esac | + sort +) | sed ' + /^ac_cv_env_/b end t clear - : clear + :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end - /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - : end' >>confcache -if diff $cache_file confcache >/dev/null 2>&1; then :; else - if test -w $cache_file; then - test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + test "x$cache_file" != "x/dev/null" && + { echo "$as_me:$LINENO: updating cache $cache_file" >&5 +echo "$as_me: updating cache $cache_file" >&6;} cat confcache >$cache_file else - echo "not updating unwritable cache $cache_file" + { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 +echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache @@ -7717,32 +8551,18 @@ test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' -# VPATH may cause trouble with some makes, so we remove $(srcdir), -# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=/{ -s/:*\$(srcdir):*/:/; -s/:*\${srcdir}:*/:/; -s/:*@srcdir@:*/:/; -s/^\([^=]*=[ ]*\):*/\1/; -s/:*$//; -s/^[^=]*=[ ]*$//; -}' -fi - DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. - ac_i=`echo "$ac_i" | - sed 's/\$U\././;s/\.o$//;s/\.obj$//'` - # 2. Add them. - ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" - ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs @@ -7756,6 +8576,13 @@ echo "$as_me: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi if test -z "${LIBS_ONLY_TRUE}" && test -z "${LIBS_ONLY_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"LIBS_ONLY\" was never defined. Usually this means the macro was only invoked conditionally." >&5 @@ -7787,17 +8614,45 @@ cat >>$CONFIG_STATUS <<\_ACEOF ## M4sh Initialization. ## ## --------------------- ## -# Be Bourne compatible +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' -elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then - set -o posix + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh fi -DUALCASE=1; export DUALCASE # for MKS sh # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then @@ -7807,8 +8662,43 @@ else fi +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + # Work around bugs in pre-3.0 UWIN ksh. -$as_unset ENV MAIL MAILPATH +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done PS1='$ ' PS2='> ' PS4='+ ' @@ -7822,18 +8712,19 @@ do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else - $as_unset $as_var + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var fi done # Required to use basename. -if expr a : '\(a\)' >/dev/null 2>&1; then +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi -if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false @@ -7841,159 +8732,120 @@ fi # Name of the executable. -as_me=`$as_basename "$0" || +as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)$' \| \ - . : '\(.\)' 2>/dev/null || + X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } - /^X\/\(\/\/\)$/{ s//\1/; q; } - /^X\/\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` +# CDPATH. +$as_unset CDPATH -# PATH needs CR, and LINENO needs CR and PATH. -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh -fi as_lineno_1=$LINENO as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" || { - # Find who we are. Look in the path if we contain no path at all - # relative or not. - case $0 in - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break -done - - ;; - esac - # We did not find ourselves, most probably we were run as `sh COMMAND' - # in which case we are not to be found in the path. - if test "x$as_myself" = x; then - as_myself=$0 - fi - if test ! -f "$as_myself"; then - { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 -echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} - { (exit 1); exit 1; }; } - fi - case $CONFIG_SHELL in - '') - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for as_base in sh bash ksh sh5; do - case $as_dir in - /*) - if ("$as_dir/$as_base" -c ' - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then - $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } - $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } - CONFIG_SHELL=$as_dir/$as_base - export CONFIG_SHELL - exec "$CONFIG_SHELL" "$0" ${1+"$@"} - fi;; - esac - done -done -;; - esac + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a - # line-number line before each line; the second 'sed' does the real - # work. The second script uses 'N' to pair each line-number line - # with the numbered line, and appends trailing '-' during - # substitution so that $LINENO is not a special case at line end. + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the - # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) - sed '=' <$as_myself | + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno N - s,$,-, - : loop - s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop - s,-$,, - s,^['$as_cr_digits']*\n,, + s/-\n.*// ' >$as_me.lineno && - chmod +x $as_me.lineno || - { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 -echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensible to this). - . ./$as_me.lineno + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" # Exit status is that of the last command. exit } -case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in - *c*,-n*) ECHO_N= ECHO_C=' -' ECHO_T=' ' ;; - *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; - *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; esac -if expr a : '\(a\)' >/dev/null 2>&1; then +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then - # We could just check for DJGPP; but this test a) works b) is more generic - # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). - if test -f conf$$.exe; then - # Don't use ln at all; we don't have any links + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' - else - as_ln_s='ln -s' - fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi -rm -f conf$$ conf$$.exe conf$$.file +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p=: @@ -8002,7 +8854,28 @@ else as_mkdir_p=false fi -as_executable_p="test -f" +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -8011,31 +8884,14 @@ as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" -# IFS -# We need space, tab and new line, in precisely that order. -as_nl=' -' -IFS=" $as_nl" - -# CDPATH. -$as_unset CDPATH - exec 6>&1 -# Open the log real soon, to keep \$[0] and so on meaningful, and to +# Save the log message, to keep $[0] and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. Logging --version etc. is OK. -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX -} >&5 -cat >&5 <<_CSEOF - +# values after options handling. +ac_log=" This file was extended by launchd $as_me 1.0, which was -generated by GNU Autoconf 2.59. Invocation command line was +generated by GNU Autoconf 2.61. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -8043,30 +8899,20 @@ generated by GNU Autoconf 2.59. Invocation command line was CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ -_CSEOF -echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 -echo >&5 +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + _ACEOF +cat >>$CONFIG_STATUS <<_ACEOF # Files that config.status was made for. -if test -n "$ac_config_files"; then - echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS -fi - -if test -n "$ac_config_headers"; then - echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS -fi +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" -if test -n "$ac_config_links"; then - echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS -fi - -if test -n "$ac_config_commands"; then - echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS -fi +_ACEOF cat >>$CONFIG_STATUS <<\_ACEOF - ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. @@ -8074,7 +8920,7 @@ current configuration. Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit - -V, --version print version number, then exit + -V, --version print version number and configuration settings, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions @@ -8093,19 +8939,22 @@ Configuration commands: $config_commands Report bugs to ." -_ACEOF +_ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ launchd config.status 1.0 -configured by $0, generated by GNU Autoconf 2.59, - with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" +configured by $0, generated by GNU Autoconf 2.61, + with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" -Copyright (C) 2003 Free Software Foundation, Inc. +Copyright (C) 2006 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." -srcdir=$srcdir -INSTALL="$INSTALL" + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF @@ -8116,39 +8965,24 @@ while test $# != 0 do case $1 in --*=*) - ac_option=`expr "x$1" : 'x\([^=]*\)='` - ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; - -*) + *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; - *) # This is not an option, so the user has probably given explicit - # arguments. - ac_option=$1 - ac_need_defaults=false;; esac case $ac_option in # Handling of the options. -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; - --version | --vers* | -V ) - echo "$ac_cs_version"; exit 0 ;; - --he | --h) - # Conflict between --help and --header - { { echo "$as_me:$LINENO: error: ambiguous option: $1 -Try \`$0 --help' for more information." >&5 -echo "$as_me: error: ambiguous option: $1 -Try \`$0 --help' for more information." >&2;} - { (exit 1); exit 1; }; };; - --help | --hel | -h ) - echo "$ac_cs_usage"; exit 0 ;; - --debug | --d* | -d ) + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + echo "$ac_cs_version"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift @@ -8158,18 +8992,24 @@ Try \`$0 --help' for more information." >&2;} $ac_shift CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + { echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. - -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 -Try \`$0 --help' for more information." >&5 -echo "$as_me: error: unrecognized option: $1 -Try \`$0 --help' for more information." >&2;} + -*) { echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; - *) ac_config_targets="$ac_config_targets $1" ;; + *) ac_config_targets="$ac_config_targets $1" + ac_need_defaults=false ;; esac shift @@ -8185,38 +9025,50 @@ fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF if \$ac_cs_recheck; then - echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 - exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + CONFIG_SHELL=$SHELL + export CONFIG_SHELL + exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion fi _ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + echo "$ac_log" +} >&5 +_ACEOF cat >>$CONFIG_STATUS <<_ACEOF # -# INIT-COMMANDS section. +# INIT-COMMANDS # - AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" _ACEOF - - cat >>$CONFIG_STATUS <<\_ACEOF + +# Handling of arguments. for ac_config_target in $ac_config_targets do - case "$ac_config_target" in - # Handling of arguments. - "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; - "src/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; - "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; - "src/config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS src/config.h" ;; + case $ac_config_target in + "src/config.h") CONFIG_HEADERS="$CONFIG_HEADERS src/config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; esac done + # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely @@ -8228,324 +9080,403 @@ if $ac_need_defaults; then fi # Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason to put it here, and in addition, +# simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. -# Create a temporary directory, and hook for its removal unless debugging. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. $debug || { - trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } - # Create a (secure) tmp directory for tmp files. { - tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { - tmp=./confstat$$-$RANDOM - (umask 077 && mkdir $tmp) + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") } || { echo "$me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } -_ACEOF - -cat >>$CONFIG_STATUS <<_ACEOF - # -# CONFIG_FILES section. +# Set up the sed scripts for CONFIG_FILES section. # # No need to generate the scripts if there are no CONFIG_FILES. # This happens for instance when ./config.status config.h -if test -n "\$CONFIG_FILES"; then - # Protect against being on the right side of a sed subst in config.status. - sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; - s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF -s,@SHELL@,$SHELL,;t t -s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t -s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t -s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t -s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t -s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t -s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t -s,@exec_prefix@,$exec_prefix,;t t -s,@prefix@,$prefix,;t t -s,@program_transform_name@,$program_transform_name,;t t -s,@bindir@,$bindir,;t t -s,@sbindir@,$sbindir,;t t -s,@libexecdir@,$libexecdir,;t t -s,@datadir@,$datadir,;t t -s,@sysconfdir@,$sysconfdir,;t t -s,@sharedstatedir@,$sharedstatedir,;t t -s,@localstatedir@,$localstatedir,;t t -s,@libdir@,$libdir,;t t -s,@includedir@,$includedir,;t t -s,@oldincludedir@,$oldincludedir,;t t -s,@infodir@,$infodir,;t t -s,@mandir@,$mandir,;t t -s,@build_alias@,$build_alias,;t t -s,@host_alias@,$host_alias,;t t -s,@target_alias@,$target_alias,;t t -s,@DEFS@,$DEFS,;t t -s,@ECHO_C@,$ECHO_C,;t t -s,@ECHO_N@,$ECHO_N,;t t -s,@ECHO_T@,$ECHO_T,;t t -s,@LIBS@,$LIBS,;t t -s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t -s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t -s,@INSTALL_DATA@,$INSTALL_DATA,;t t -s,@PACKAGE@,$PACKAGE,;t t -s,@VERSION@,$VERSION,;t t -s,@ACLOCAL@,$ACLOCAL,;t t -s,@AUTOCONF@,$AUTOCONF,;t t -s,@AUTOMAKE@,$AUTOMAKE,;t t -s,@AUTOHEADER@,$AUTOHEADER,;t t -s,@MAKEINFO@,$MAKEINFO,;t t -s,@AMTAR@,$AMTAR,;t t -s,@install_sh@,$install_sh,;t t -s,@STRIP@,$STRIP,;t t -s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t -s,@INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t -s,@AWK@,$AWK,;t t -s,@SET_MAKE@,$SET_MAKE,;t t -s,@CC@,$CC,;t t -s,@CFLAGS@,$CFLAGS,;t t -s,@LDFLAGS@,$LDFLAGS,;t t -s,@CPPFLAGS@,$CPPFLAGS,;t t -s,@ac_ct_CC@,$ac_ct_CC,;t t -s,@EXEEXT@,$EXEEXT,;t t -s,@OBJEXT@,$OBJEXT,;t t -s,@DEPDIR@,$DEPDIR,;t t -s,@am__include@,$am__include,;t t -s,@am__quote@,$am__quote,;t t -s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t -s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t -s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t -s,@CCDEPMODE@,$CCDEPMODE,;t t -s,@RANLIB@,$RANLIB,;t t -s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t -s,@CPP@,$CPP,;t t -s,@EGREP@,$EGREP,;t t -s,@ALLOCA@,$ALLOCA,;t t -s,@LIBOBJS@,$LIBOBJS,;t t -s,@LIBS_ONLY_TRUE@,$LIBS_ONLY_TRUE,;t t -s,@LIBS_ONLY_FALSE@,$LIBS_ONLY_FALSE,;t t -s,@LTLIBOBJS@,$LTLIBOBJS,;t t -CEOF - -_ACEOF - - cat >>$CONFIG_STATUS <<\_ACEOF - # Split the substitutions into bite-sized pieces for seds with - # small command number limits, like on Digital OSF/1 and HP-UX. - ac_max_sed_lines=48 - ac_sed_frag=1 # Number of current file. - ac_beg=1 # First line for current file. - ac_end=$ac_max_sed_lines # Line after last line for current file. - ac_more_lines=: - ac_sed_cmds= - while $ac_more_lines; do - if test $ac_beg -gt 1; then - sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag - else - sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag - fi - if test ! -s $tmp/subs.frag; then - ac_more_lines=false - else - # The purpose of the label and of the branching condition is to - # speed up the sed processing (if there are no `@' at all, there - # is no need to browse any of the substitutions). - # These are the two extra sed commands mentioned above. - (echo ':t - /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed - if test -z "$ac_sed_cmds"; then - ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" - else - ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" - fi - ac_sed_frag=`expr $ac_sed_frag + 1` - ac_beg=$ac_end - ac_end=`expr $ac_end + $ac_max_sed_lines` - fi - done - if test -z "$ac_sed_cmds"; then - ac_sed_cmds=cat +if test -n "$CONFIG_FILES"; then + +_ACEOF + + + +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + cat >conf$$subs.sed <<_ACEOF +SHELL!$SHELL$ac_delim +PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim +PACKAGE_NAME!$PACKAGE_NAME$ac_delim +PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim +PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim +PACKAGE_STRING!$PACKAGE_STRING$ac_delim +PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim +exec_prefix!$exec_prefix$ac_delim +prefix!$prefix$ac_delim +program_transform_name!$program_transform_name$ac_delim +bindir!$bindir$ac_delim +sbindir!$sbindir$ac_delim +libexecdir!$libexecdir$ac_delim +datarootdir!$datarootdir$ac_delim +datadir!$datadir$ac_delim +sysconfdir!$sysconfdir$ac_delim +sharedstatedir!$sharedstatedir$ac_delim +localstatedir!$localstatedir$ac_delim +includedir!$includedir$ac_delim +oldincludedir!$oldincludedir$ac_delim +docdir!$docdir$ac_delim +infodir!$infodir$ac_delim +htmldir!$htmldir$ac_delim +dvidir!$dvidir$ac_delim +pdfdir!$pdfdir$ac_delim +psdir!$psdir$ac_delim +libdir!$libdir$ac_delim +localedir!$localedir$ac_delim +mandir!$mandir$ac_delim +DEFS!$DEFS$ac_delim +ECHO_C!$ECHO_C$ac_delim +ECHO_N!$ECHO_N$ac_delim +ECHO_T!$ECHO_T$ac_delim +LIBS!$LIBS$ac_delim +build_alias!$build_alias$ac_delim +host_alias!$host_alias$ac_delim +target_alias!$target_alias$ac_delim +INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim +INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim +INSTALL_DATA!$INSTALL_DATA$ac_delim +am__isrc!$am__isrc$ac_delim +CYGPATH_W!$CYGPATH_W$ac_delim +PACKAGE!$PACKAGE$ac_delim +VERSION!$VERSION$ac_delim +ACLOCAL!$ACLOCAL$ac_delim +AUTOCONF!$AUTOCONF$ac_delim +AUTOMAKE!$AUTOMAKE$ac_delim +AUTOHEADER!$AUTOHEADER$ac_delim +MAKEINFO!$MAKEINFO$ac_delim +install_sh!$install_sh$ac_delim +STRIP!$STRIP$ac_delim +INSTALL_STRIP_PROGRAM!$INSTALL_STRIP_PROGRAM$ac_delim +mkdir_p!$mkdir_p$ac_delim +AWK!$AWK$ac_delim +SET_MAKE!$SET_MAKE$ac_delim +am__leading_dot!$am__leading_dot$ac_delim +AMTAR!$AMTAR$ac_delim +am__tar!$am__tar$ac_delim +am__untar!$am__untar$ac_delim +CC!$CC$ac_delim +CFLAGS!$CFLAGS$ac_delim +LDFLAGS!$LDFLAGS$ac_delim +CPPFLAGS!$CPPFLAGS$ac_delim +ac_ct_CC!$ac_ct_CC$ac_delim +EXEEXT!$EXEEXT$ac_delim +OBJEXT!$OBJEXT$ac_delim +DEPDIR!$DEPDIR$ac_delim +am__include!$am__include$ac_delim +am__quote!$am__quote$ac_delim +AMDEP_TRUE!$AMDEP_TRUE$ac_delim +AMDEP_FALSE!$AMDEP_FALSE$ac_delim +AMDEPBACKSLASH!$AMDEPBACKSLASH$ac_delim +CCDEPMODE!$CCDEPMODE$ac_delim +am__fastdepCC_TRUE!$am__fastdepCC_TRUE$ac_delim +am__fastdepCC_FALSE!$am__fastdepCC_FALSE$ac_delim +RANLIB!$RANLIB$ac_delim +CPP!$CPP$ac_delim +GREP!$GREP$ac_delim +EGREP!$EGREP$ac_delim +ALLOCA!$ALLOCA$ac_delim +LIBOBJS!$LIBOBJS$ac_delim +LIBS_ONLY_TRUE!$LIBS_ONLY_TRUE$ac_delim +LIBS_ONLY_FALSE!$LIBS_ONLY_FALSE$ac_delim +LTLIBOBJS!$LTLIBOBJS$ac_delim +_ACEOF + + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 84; then + break + elif $ac_last_try; then + { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi -fi # test -n "$CONFIG_FILES" +done +ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` +if test -n "$ac_eof"; then + ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` + ac_eof=`expr $ac_eof + 1` +fi + +cat >>$CONFIG_STATUS <<_ACEOF +cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end +_ACEOF +sed ' +s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g +s/^/s,@/; s/!/@,|#_!!_#|/ +:n +t n +s/'"$ac_delim"'$/,g/; t +s/$/\\/; p +N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n +' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF +:end +s/|#_!!_#|//g +CEOF$ac_eof _ACEOF + + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ +s/:*$// +s/^[^=]*=[ ]*$// +}' +fi + cat >>$CONFIG_STATUS <<\_ACEOF -for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue - # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". - case $ac_file in - - | *:- | *:-:* ) # input from stdin - cat >$tmp/stdin - ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; - *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; - * ) ac_file_in=$ac_file.in ;; +fi # test -n "$CONFIG_FILES" + + +for ac_tag in :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 +echo "$as_me: error: Invalid tag $ac_tag." >&2;} + { (exit 1); exit 1; }; };; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 +echo "$as_me: error: cannot find input file: $ac_f" >&2;} + { (exit 1); exit 1; }; };; + esac + ac_file_inputs="$ac_file_inputs $ac_f" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input="Generated from "`IFS=: + echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + fi + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin";; + esac + ;; esac - # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. - ac_dir=`(dirname "$ac_file") 2>/dev/null || + ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - { if $as_mkdir_p; then - mkdir -p "$ac_dir" - else - as_dir="$ac_dir" + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir="$ac_dir" + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { as_dirs= - while test ! -d "$as_dir"; do - as_dirs="$as_dir $as_dirs" - as_dir=`(dirname "$as_dir") 2>/dev/null || + while :; do + case $as_dir in #( + *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break done - test ! -n "$as_dirs" || mkdir $as_dirs - fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 -echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } - ac_builddir=. -if test "$ac_dir" != .; then +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A "../" for each directory in $ac_dir_suffix. - ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` -else - ac_dir_suffix= ac_top_builddir= -fi + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix case $srcdir in - .) # No --srcdir option. We are building in place. + .) # We are building in place. ac_srcdir=. - if test -z "$ac_top_builddir"; then - ac_top_srcdir=. - else - ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` - fi ;; - [\\/]* | ?:[\\/]* ) # Absolute path. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir ;; - *) # Relative path. - ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_builddir$srcdir ;; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix -# Do not use `cd foo && pwd` to compute absolute paths, because -# the directories may not exist. -case `pwd` in -.) ac_abs_builddir="$ac_dir";; -*) - case "$ac_dir" in - .) ac_abs_builddir=`pwd`;; - [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; - *) ac_abs_builddir=`pwd`/"$ac_dir";; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_builddir=${ac_top_builddir}.;; -*) - case ${ac_top_builddir}. in - .) ac_abs_top_builddir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; - *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_srcdir=$ac_srcdir;; -*) - case $ac_srcdir in - .) ac_abs_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; - *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_srcdir=$ac_top_srcdir;; -*) - case $ac_top_srcdir in - .) ac_abs_top_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; - *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; - esac;; -esac + case $ac_mode in + :F) + # + # CONFIG_FILE + # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; - *) ac_INSTALL=$ac_top_builddir$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac +_ACEOF - if test x"$ac_file" != x-; then - { echo "$as_me:$LINENO: creating $ac_file" >&5 -echo "$as_me: creating $ac_file" >&6;} - rm -f "$ac_file" - fi - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - if test x"$ac_file" = x-; then - configure_input= - else - configure_input="$ac_file. " - fi - configure_input=$configure_input"Generated from `echo $ac_file_in | - sed 's,.*/,,'` by configure." - - # First look for the input files in the build tree, otherwise in the - # src tree. - ac_file_inputs=`IFS=: - for f in $ac_file_in; do - case $f in - -) echo $tmp/stdin ;; - [\\/$]*) - # Absolute (can't be DOS-style, as IFS=:) - test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 -echo "$as_me: error: cannot find input file: $f" >&2;} - { (exit 1); exit 1; }; } - echo "$f";; - *) # Relative - if test -f "$f"; then - # Build tree - echo "$f" - elif test -f "$srcdir/$f"; then - # Source tree - echo "$srcdir/$f" - else - # /dev/null tree - { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 -echo "$as_me: error: cannot find input file: $f" >&2;} - { (exit 1); exit 1; }; } - fi;; - esac - done` || { (exit 1); exit 1; } +cat >>$CONFIG_STATUS <<\_ACEOF +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= + +case `sed -n '/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p +' $ac_file_inputs` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF sed "$ac_vpsub $extrasub @@ -8553,371 +9484,174 @@ _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s,@configure_input@,$configure_input,;t t -s,@srcdir@,$ac_srcdir,;t t -s,@abs_srcdir@,$ac_abs_srcdir,;t t -s,@top_srcdir@,$ac_top_srcdir,;t t -s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t -s,@builddir@,$ac_builddir,;t t -s,@abs_builddir@,$ac_abs_builddir,;t t -s,@top_builddir@,$ac_top_builddir,;t t -s,@abs_top_builddir@,$ac_abs_top_builddir,;t t -s,@INSTALL@,$ac_INSTALL,;t t -" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out - rm -f $tmp/stdin - if test x"$ac_file" != x-; then - mv $tmp/out $ac_file - else - cat $tmp/out - rm -f $tmp/out - fi - -done -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF - -# -# CONFIG_HEADER section. -# - -# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where -# NAME is the cpp macro being defined and VALUE is the value it is being given. -# -# ac_d sets the value in "#define NAME VALUE" lines. -ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)' -ac_dB='[ ].*$,\1#\2' -ac_dC=' ' -ac_dD=',;t' -# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". -ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' -ac_uB='$,\1#\2define\3' -ac_uC=' ' -ac_uD=',;t' - -for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue - # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". +s&@configure_input@&$configure_input&;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&2;} + + rm -f "$tmp/stdin" case $ac_file in - - | *:- | *:-:* ) # input from stdin - cat >$tmp/stdin - ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; - *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; - * ) ac_file_in=$ac_file.in ;; + -) cat "$tmp/out"; rm -f "$tmp/out";; + *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; esac - - test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5 -echo "$as_me: creating $ac_file" >&6;} - - # First look for the input files in the build tree, otherwise in the - # src tree. - ac_file_inputs=`IFS=: - for f in $ac_file_in; do - case $f in - -) echo $tmp/stdin ;; - [\\/$]*) - # Absolute (can't be DOS-style, as IFS=:) - test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 -echo "$as_me: error: cannot find input file: $f" >&2;} - { (exit 1); exit 1; }; } - # Do quote $f, to prevent DOS paths from being IFS'd. - echo "$f";; - *) # Relative - if test -f "$f"; then - # Build tree - echo "$f" - elif test -f "$srcdir/$f"; then - # Source tree - echo "$srcdir/$f" - else - # /dev/null tree - { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 -echo "$as_me: error: cannot find input file: $f" >&2;} - { (exit 1); exit 1; }; } - fi;; - esac - done` || { (exit 1); exit 1; } - # Remove the trailing spaces. - sed 's/[ ]*$//' $ac_file_inputs >$tmp/in - -_ACEOF - -# Transform confdefs.h into two sed scripts, `conftest.defines' and -# `conftest.undefs', that substitutes the proper values into -# config.h.in to produce config.h. The first handles `#define' -# templates, and the second `#undef' templates. -# And first: Protect against being on the right side of a sed subst in -# config.status. Protect against being in an unquoted here document -# in config.status. -rm -f conftest.defines conftest.undefs -# Using a here document instead of a string reduces the quoting nightmare. -# Putting comments in sed scripts is not portable. -# -# `end' is used to avoid that the second main sed command (meant for -# 0-ary CPP macros) applies to n-ary macro definitions. -# See the Autoconf documentation for `clear'. -cat >confdef2sed.sed <<\_ACEOF -s/[\\&,]/\\&/g -s,[\\$`],\\&,g -t clear -: clear -s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp -t end -s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp -: end -_ACEOF -# If some macros were called several times there might be several times -# the same #defines, which is useless. Nevertheless, we may not want to -# sort them, since we want the *last* AC-DEFINE to be honored. -uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines -sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs -rm -f confdef2sed.sed - -# This sed command replaces #undef with comments. This is necessary, for + ;; + :H) + # + # CONFIG_HEADER + # +_ACEOF + +# Transform confdefs.h into a sed script `conftest.defines', that +# substitutes the proper values into config.h.in to produce config.h. +rm -f conftest.defines conftest.tail +# First, append a space to every undef/define line, to ease matching. +echo 's/$/ /' >conftest.defines +# Then, protect against being on the right side of a sed subst, or in +# an unquoted here document, in config.status. If some macros were +# called several times there might be several #defines for the same +# symbol, which is useless. But do not sort them, since the last +# AC_DEFINE must be honored. +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +# These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where +# NAME is the cpp macro being defined, VALUE is the value it is being given. +# PARAMS is the parameter list in the macro definition--in most cases, it's +# just an empty string. +ac_dA='s,^\\([ #]*\\)[^ ]*\\([ ]*' +ac_dB='\\)[ (].*,\\1define\\2' +ac_dC=' ' +ac_dD=' ,' + +uniq confdefs.h | + sed -n ' + t rset + :rset + s/^[ ]*#[ ]*define[ ][ ]*// + t ok + d + :ok + s/[\\&,]/\\&/g + s/^\('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p + s/^\('"$ac_word_re"'\)[ ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p + ' >>conftest.defines + +# Remove the space that was appended to ease matching. +# Then replace #undef with comments. This is necessary, for # example, in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. -cat >>conftest.undefs <<\_ACEOF -s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, -_ACEOF - -# Break up conftest.defines because some shells have a limit on the size -# of here documents, and old seds have small limits too (100 cmds). -echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS -echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS -echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS -echo ' :' >>$CONFIG_STATUS -rm -f conftest.tail -while grep . conftest.defines >/dev/null +# (The regexp can be short, since the line contains either #define or #undef.) +echo 's/ $// +s,^[ #]*u.*,/* & */,' >>conftest.defines + +# Break up conftest.defines: +ac_max_sed_lines=50 + +# First sed command is: sed -f defines.sed $ac_file_inputs >"$tmp/out1" +# Second one is: sed -f defines.sed "$tmp/out1" >"$tmp/out2" +# Third one will be: sed -f defines.sed "$tmp/out2" >"$tmp/out1" +# et cetera. +ac_in='$ac_file_inputs' +ac_out='"$tmp/out1"' +ac_nxt='"$tmp/out2"' + +while : do - # Write a limited-size here document to $tmp/defines.sed. - echo ' cat >$tmp/defines.sed <>$CONFIG_STATUS - # Speed up: don't consider the non `#define' lines. - echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS - # Work around the forget-to-reset-the-flag bug. - echo 't clr' >>$CONFIG_STATUS - echo ': clr' >>$CONFIG_STATUS - sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS + # Write a here document: + cat >>$CONFIG_STATUS <<_ACEOF + # First, check the format of the line: + cat >"\$tmp/defines.sed" <<\\CEOF +/^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def +/^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def +b +:def +_ACEOF + sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS echo 'CEOF - sed -f $tmp/defines.sed $tmp/in >$tmp/out - rm -f $tmp/in - mv $tmp/out $tmp/in -' >>$CONFIG_STATUS - sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail + sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS + ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in + sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail + grep . conftest.tail >/dev/null || break rm -f conftest.defines mv conftest.tail conftest.defines done -rm -f conftest.defines -echo ' fi # grep' >>$CONFIG_STATUS -echo >>$CONFIG_STATUS - -# Break up conftest.undefs because some shells have a limit on the size -# of here documents, and old seds have small limits too (100 cmds). -echo ' # Handle all the #undef templates' >>$CONFIG_STATUS -rm -f conftest.tail -while grep . conftest.undefs >/dev/null -do - # Write a limited-size here document to $tmp/undefs.sed. - echo ' cat >$tmp/undefs.sed <>$CONFIG_STATUS - # Speed up: don't consider the non `#undef' - echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS - # Work around the forget-to-reset-the-flag bug. - echo 't clr' >>$CONFIG_STATUS - echo ': clr' >>$CONFIG_STATUS - sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS - echo 'CEOF - sed -f $tmp/undefs.sed $tmp/in >$tmp/out - rm -f $tmp/in - mv $tmp/out $tmp/in -' >>$CONFIG_STATUS - sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail - rm -f conftest.undefs - mv conftest.tail conftest.undefs -done -rm -f conftest.undefs +rm -f conftest.defines conftest.tail +echo "ac_result=$ac_in" >>$CONFIG_STATUS cat >>$CONFIG_STATUS <<\_ACEOF - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - if test x"$ac_file" = x-; then - echo "/* Generated by configure. */" >$tmp/config.h - else - echo "/* $ac_file. Generated by configure. */" >$tmp/config.h - fi - cat $tmp/in >>$tmp/config.h - rm -f $tmp/in if test x"$ac_file" != x-; then - if diff $ac_file $tmp/config.h >/dev/null 2>&1; then + echo "/* $configure_input */" >"$tmp/config.h" + cat "$ac_result" >>"$tmp/config.h" + if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 echo "$as_me: $ac_file is unchanged" >&6;} else - ac_dir=`(dirname "$ac_file") 2>/dev/null || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - { if $as_mkdir_p; then - mkdir -p "$ac_dir" - else - as_dir="$ac_dir" - as_dirs= - while test ! -d "$as_dir"; do - as_dirs="$as_dir $as_dirs" - as_dir=`(dirname "$as_dir") 2>/dev/null || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - done - test ! -n "$as_dirs" || mkdir $as_dirs - fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 -echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} - { (exit 1); exit 1; }; }; } - rm -f $ac_file - mv $tmp/config.h $ac_file + mv "$tmp/config.h" $ac_file fi else - cat $tmp/config.h - rm -f $tmp/config.h + echo "/* $configure_input */" + cat "$ac_result" fi - # Run the commands associated with the file. - case $ac_file in - src/config.h ) # update the timestamp -echo 'timestamp for src/config.h' >"src/stamp-h1" - ;; + rm -f "$tmp/out12" +# Compute $ac_file's index in $config_headers. +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $ac_file | $ac_file:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF - -# -# CONFIG_COMMANDS section. -# -for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue - ac_dest=`echo "$ac_file" | sed 's,:.*,,'` - ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_dir=`(dirname "$ac_dest") 2>/dev/null || -$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_dest" : 'X\(//\)[^/]' \| \ - X"$ac_dest" : 'X\(//\)$' \| \ - X"$ac_dest" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$ac_dest" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - { if $as_mkdir_p; then - mkdir -p "$ac_dir" - else - as_dir="$ac_dir" - as_dirs= - while test ! -d "$as_dir"; do - as_dirs="$as_dir $as_dirs" - as_dir=`(dirname "$as_dir") 2>/dev/null || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - done - test ! -n "$as_dirs" || mkdir $as_dirs - fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 -echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} - { (exit 1); exit 1; }; }; } - - ac_builddir=. - -if test "$ac_dir" != .; then - ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A "../" for each directory in $ac_dir_suffix. - ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` -else - ac_dir_suffix= ac_top_builddir= -fi - -case $srcdir in - .) # No --srcdir option. We are building in place. - ac_srcdir=. - if test -z "$ac_top_builddir"; then - ac_top_srcdir=. - else - ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` - fi ;; - [\\/]* | ?:[\\/]* ) # Absolute path. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir ;; - *) # Relative path. - ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_builddir$srcdir ;; -esac +echo "timestamp for $ac_file" >`$as_dirname -- $ac_file || +$as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X$ac_file : 'X\(//\)[^/]' \| \ + X$ac_file : 'X\(//\)$' \| \ + X$ac_file : 'X\(/\)' \| . 2>/dev/null || +echo X$ac_file | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; -# Do not use `cd foo && pwd` to compute absolute paths, because -# the directories may not exist. -case `pwd` in -.) ac_abs_builddir="$ac_dir";; -*) - case "$ac_dir" in - .) ac_abs_builddir=`pwd`;; - [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; - *) ac_abs_builddir=`pwd`/"$ac_dir";; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_builddir=${ac_top_builddir}.;; -*) - case ${ac_top_builddir}. in - .) ac_abs_top_builddir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; - *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_srcdir=$ac_srcdir;; -*) - case $ac_srcdir in - .) ac_abs_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; - *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_srcdir=$ac_top_srcdir;; -*) - case $ac_top_srcdir in - .) ac_abs_top_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; - *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; - esac;; -esac + :C) { echo "$as_me:$LINENO: executing $ac_file commands" >&5 +echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac - { echo "$as_me:$LINENO: executing $ac_dest commands" >&5 -echo "$as_me: executing $ac_dest commands" >&6;} - case $ac_dest in - depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. @@ -8925,94 +9659,126 @@ echo "$as_me: executing $ac_dest commands" >&6;} # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. - # So let's grep whole file. - if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then - dirpart=`(dirname "$mf") 2>/dev/null || + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed 10q "$mf" | grep '^#.*generated by automake' > /dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ - X"$mf" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || + X"$mf" : 'X\(/\)' \| . 2>/dev/null || echo X"$mf" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` else continue fi - grep '^DEP_FILES *= *[^ #]' < "$mf" > /dev/null || continue - # Extract the definition of DEP_FILES from the Makefile without - # running `make'. - DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"` + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it - U=`sed -n -e '/^U = / s///p' < "$mf"` - test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR" - # We invoke sed twice because it is the simplest approach to - # changing $(DEPDIR) to its actual value in the expansion. - for file in `sed -n -e ' - /^DEP_FILES = .*\\\\$/ { - s/^DEP_FILES = // - :loop - s/\\\\$// - p - n - /\\\\$/ b loop - p - } - /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \ + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue - fdir=`(dirname "$file") 2>/dev/null || + fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ - X"$file" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || + X"$file" : 'X\(/\)' \| . 2>/dev/null || echo X"$file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - { if $as_mkdir_p; then - mkdir -p $dirpart/$fdir - else - as_dir=$dirpart/$fdir + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir=$dirpart/$fdir + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { as_dirs= - while test ! -d "$as_dir"; do - as_dirs="$as_dir $as_dirs" - as_dir=`(dirname "$as_dir") 2>/dev/null || + while :; do + case $as_dir in #( + *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break done - test ! -n "$as_dirs" || mkdir $as_dirs - fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5 -echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;} + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } - # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done ;; + esac -done -_ACEOF +done # for ac_tag -cat >>$CONFIG_STATUS <<\_ACEOF { (exit 0); exit 0; } _ACEOF diff --git a/launchd/configure.ac b/launchd/configure.ac index dc665cd..69f4e00 100644 --- a/launchd/configure.ac +++ b/launchd/configure.ac @@ -11,6 +11,7 @@ AM_CONFIG_HEADER([src/config.h]) # Checks for programs. AC_PROG_CC AC_PROG_RANLIB +AM_PROG_CC_C_O # Checks for header files. AC_HEADER_DIRENT diff --git a/launchd/src/IPC.c b/launchd/src/IPC.c index c82b1f0..003318a 100644 --- a/launchd/src/IPC.c +++ b/launchd/src/IPC.c @@ -30,7 +30,8 @@ #include #include -#include "bootstrap_public.h" +#include "libbootstrap_public.h" + #include "IPC.h" #include "StartupItems.h" #include "SystemStarter.h" @@ -142,253 +143,3 @@ out_bad: startupItemTerminated(NULL, aTerminationContext); } } - -/** - * Returns a reference to an item based on tokens passed in an IPC message. - * This is useful for figuring out which item the message came from. - * - * Currently two tokens are supported: - * kIPCProcessIDKey - the pid of the running startup script - * kIPCServiceNameKey - a name of a service that the item provides. This - * takes precedence over the pid key when both are present. - **/ -static CFMutableDictionaryRef -itemFromIPCMessage(StartupContext aStartupContext, CFDictionaryRef anIPCMessage) -{ - CFMutableDictionaryRef anItem = NULL; - - if (aStartupContext && anIPCMessage) { - CFStringRef aServiceName = CFDictionaryGetValue(anIPCMessage, kIPCServiceNameKey); - CFIndex aPID = 0; - CFNumberRef aPIDNumber = CFDictionaryGetValue(anIPCMessage, kIPCProcessIDKey); - - if (aServiceName && CFGetTypeID(aServiceName) == CFStringGetTypeID()) { - anItem = StartupItemListGetProvider(aStartupContext->aWaitingList, aServiceName); - } else if (aPIDNumber && - CFGetTypeID(aPIDNumber) == CFNumberGetTypeID() && - CFNumberGetValue(aPIDNumber, kCFNumberCFIndexType, &aPID)) { - anItem = StartupItemWithPID(aStartupContext->aWaitingList, aPID); - } - } - return anItem; -} - -/** - * Displays a message on the console. - * aConsoleMessage will be localized according to the dictionary in the specified item. - * Running tems may be specified by their current process id. Items may also be specified - * by one of the service names they provide. - **/ -static void -consoleMessage(StartupContext aStartupContext, CFDictionaryRef anIPCMessage) -{ - if (aStartupContext && anIPCMessage) { - CFStringRef aConsoleMessage = CFDictionaryGetValue(anIPCMessage, kIPCConsoleMessageKey); - - if (aConsoleMessage && CFGetTypeID(aConsoleMessage) == CFStringGetTypeID()) { - CF_syslog(LOG_INFO, CFSTR("%@"), aConsoleMessage); - } - } -} - -/** - * Records the success or failure or a particular service. - * If no service name is specified, but a pid is, then all services provided - * by the item are flagged. - **/ -static void -statusMessage(StartupContext aStartupContext, CFDictionaryRef anIPCMessage) -{ - if (anIPCMessage && aStartupContext && aStartupContext->aStatusDict) { - CFMutableDictionaryRef anItem = itemFromIPCMessage(aStartupContext, anIPCMessage); - CFStringRef aServiceName = CFDictionaryGetValue(anIPCMessage, kIPCServiceNameKey); - CFBooleanRef aStatus = CFDictionaryGetValue(anIPCMessage, kIPCStatusKey); - - if (anItem && aStatus && - CFGetTypeID(aStatus) == CFBooleanGetTypeID() && - (!aServiceName || CFGetTypeID(aServiceName) == CFStringGetTypeID())) { - StartupItemSetStatus(aStartupContext->aStatusDict, anItem, aServiceName, CFBooleanGetValue(aStatus), TRUE); - } - } -} - -/** - * Queries one of several configuration settings. - */ -static CFDataRef -queryConfigSetting(StartupContext aStartupContext, CFDictionaryRef anIPCMessage) -{ - char *aValue = ""; - - if (anIPCMessage) { - CFStringRef aSetting = CFDictionaryGetValue(anIPCMessage, kIPCConfigSettingKey); - - if (aSetting && CFGetTypeID(aSetting) == CFStringGetTypeID()) { - if (CFEqual(aSetting, kIPCConfigSettingVerboseFlag)) { - aValue = gVerboseFlag ? "-YES-" : "-NO-"; - } else if (CFEqual(aSetting, kIPCConfigSettingNetworkUp)) { - Boolean aNetworkUpFlag = FALSE; - if (aStartupContext && aStartupContext->aStatusDict) { - aNetworkUpFlag = CFDictionaryContainsKey(aStartupContext->aStatusDict, CFSTR("Network")); - } - aValue = aNetworkUpFlag ? "-YES-" : "-NO-"; - } - } - } - return CFDataCreate(NULL, (const UInt8 *)aValue, strlen(aValue) + 1); /* aValue + null */ -} - -static void *handleIPCMessage(void *aMsgParam, CFIndex aMessageSize __attribute__((unused)), CFAllocatorRef anAllocator __attribute__((unused)), void *aMachPort) { - SystemStarterIPCMessage *aMessage = (SystemStarterIPCMessage *) aMsgParam; - SystemStarterIPCMessage *aReplyMessage = NULL; - - CFDataRef aResult = NULL; - CFDataRef aData = NULL; - - if (aMessage->aHeader.msgh_bits & MACH_MSGH_BITS_COMPLEX) { - syslog(LOG_WARNING, "Ignoring out-of-line IPC message"); - return NULL; - } else { - mach_msg_security_trailer_t *aSecurityTrailer = (mach_msg_security_trailer_t *) - ((uint8_t *) aMessage + round_msg(sizeof(SystemStarterIPCMessage) + aMessage->aByteLength)); - - /* - * CFRunLoop includes the format 0 message trailer with the - * passed message. - */ - if (aSecurityTrailer->msgh_trailer_type == MACH_MSG_TRAILER_FORMAT_0 && - aSecurityTrailer->msgh_sender.val[0] != 0) { - syslog(LOG_WARNING, "Ignoring IPC message sent from uid %d", aSecurityTrailer->msgh_sender.val[0]); - return NULL; - } - } - - if (aMessage->aProtocol != kIPCProtocolVersion) { - syslog(LOG_WARNING, "Unsupported IPC protocol version number: %d. Message ignored", aMessage->aProtocol); - return NULL; - } - aData = CFDataCreateWithBytesNoCopy(NULL, - (uint8_t *) aMessage + sizeof(SystemStarterIPCMessage), - aMessage->aByteLength, - kCFAllocatorNull); - /* - * Dispatch the IPC message. - */ - if (aData) { - StartupContext aStartupContext = NULL; - CFStringRef anErrorString = NULL; - CFDictionaryRef anIPCMessage = (CFDictionaryRef) CFPropertyListCreateFromXMLData(NULL, aData, kCFPropertyListImmutable, &anErrorString); - - CF_syslog(LOG_DEBUG, CFSTR("IPC message = %@"), anIPCMessage); - - if (aMachPort) { - CFMachPortContext aMachPortContext; - CFMachPortGetContext((CFMachPortRef) aMachPort, &aMachPortContext); - aStartupContext = (StartupContext) aMachPortContext.info; - } - if (anIPCMessage && CFGetTypeID(anIPCMessage) == CFDictionaryGetTypeID()) { - /* switch on the type of the IPC message */ - CFStringRef anIPCMessageType = CFDictionaryGetValue(anIPCMessage, kIPCMessageKey); - if (anIPCMessageType && CFGetTypeID(anIPCMessageType) == CFStringGetTypeID()) { - if (CFEqual(anIPCMessageType, kIPCConsoleMessage)) { - consoleMessage(aStartupContext, anIPCMessage); - } else if (CFEqual(anIPCMessageType, kIPCStatusMessage)) { - statusMessage(aStartupContext, anIPCMessage); - } else if (CFEqual(anIPCMessageType, kIPCQueryMessage)) { - aResult = queryConfigSetting(aStartupContext, anIPCMessage); - } - } - } else { - CF_syslog(LOG_ERR, CFSTR("Unable to parse IPC message: %@"), anErrorString); - } - CFRelease(aData); - } else { - syslog(LOG_ERR, "Out of memory. Could not allocate space for IPC message"); - } - - /* - * Generate a Mach message for the result data. - */ - if (!aResult) - aResult = CFDataCreateWithBytesNoCopy(NULL, (const UInt8 *)"", 1, kCFAllocatorNull); - if (aResult) { - CFIndex aDataSize = CFDataGetLength(aResult); - CFIndex aReplyMessageSize = round_msg(sizeof(SystemStarterIPCMessage) + aDataSize + 3); - aReplyMessage = CFAllocatorAllocate(kCFAllocatorSystemDefault, aReplyMessageSize, 0); - if (aReplyMessage) { - aReplyMessage->aHeader.msgh_id = -1 * (SInt32) aMessage->aHeader.msgh_id; - aReplyMessage->aHeader.msgh_size = aReplyMessageSize; - aReplyMessage->aHeader.msgh_remote_port = aMessage->aHeader.msgh_remote_port; - aReplyMessage->aHeader.msgh_local_port = MACH_PORT_NULL; - aReplyMessage->aHeader.msgh_reserved = 0; - aReplyMessage->aHeader.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE, 0); - aReplyMessage->aBody.msgh_descriptor_count = 0; - aReplyMessage->aProtocol = kIPCProtocolVersion; - aReplyMessage->aByteLength = CFDataGetLength(aResult); - memmove((uint8_t *) aReplyMessage + sizeof(SystemStarterIPCMessage), - CFDataGetBytePtr(aResult), - CFDataGetLength(aResult)); - } - CFRelease(aResult); - } - if (!aReplyMessage) { - syslog(LOG_ERR, "Out of memory. Could not allocate IPC result"); - } - return aReplyMessage; -} - - -static mach_port_t -getIPCPort(void *anInfo) -{ - return anInfo ? CFMachPortGetPort((CFMachPortRef) anInfo) : MACH_PORT_NULL; -} - -CFRunLoopSourceRef -CreateIPCRunLoopSource(CFStringRef aPortName, StartupContext aStartupContext) -{ - CFRunLoopSourceRef aSource = NULL; - CFMachPortRef aMachPort = NULL; - CFMachPortContext aContext; - kern_return_t aKernReturn = KERN_FAILURE; - - aContext.version = 0; - aContext.info = (void *) aStartupContext; - aContext.retain = 0; - aContext.release = 0; - aContext.copyDescription = 0; - aMachPort = CFMachPortCreate(NULL, NULL, &aContext, NULL); - - if (aMachPort && aPortName) { - CFIndex aPortNameLength = CFStringGetLength(aPortName); - CFIndex aPortNameSize = CFStringGetMaximumSizeForEncoding(aPortNameLength, kCFStringEncodingUTF8) + 1; - char *aBuffer = CFAllocatorAllocate(NULL, aPortNameSize, 0); - if (aBuffer && CFStringGetCString(aPortName, - aBuffer, - aPortNameSize, - kCFStringEncodingUTF8)) { - aKernReturn = bootstrap_register(bootstrap_port, aBuffer, CFMachPortGetPort(aMachPort)); - } - if (aBuffer) - CFAllocatorDeallocate(NULL, aBuffer); - } - if (aMachPort && aKernReturn == KERN_SUCCESS) { - CFRunLoopSourceContext1 aSourceContext; - aSourceContext.version = 1; - aSourceContext.info = aMachPort; - aSourceContext.retain = CFRetain; - aSourceContext.release = CFRelease; - aSourceContext.copyDescription = CFCopyDescription; - aSourceContext.equal = CFEqual; - aSourceContext.hash = CFHash; - aSourceContext.getPort = getIPCPort; - aSourceContext.perform = (void *) handleIPCMessage; - aSource = CFRunLoopSourceCreate(NULL, 0, (CFRunLoopSourceContext *) & aSourceContext); - } - if (aMachPort && (!aSource || aKernReturn != KERN_SUCCESS)) { - CFMachPortInvalidate(aMachPort); - CFRelease(aMachPort); - aMachPort = NULL; - } - return aSource; -} diff --git a/launchd/src/IPC.h b/launchd/src/IPC.h index 1670e02..d85a482 100644 --- a/launchd/src/IPC.h +++ b/launchd/src/IPC.h @@ -35,9 +35,4 @@ **/ void MonitorStartupItem (StartupContext aStartupContext, CFMutableDictionaryRef anItem); -/** - * Creates a named mach port and run loop source. The name is encoded using UTF-8. - **/ -CFRunLoopSourceRef CreateIPCRunLoopSource(CFStringRef aPortName, StartupContext aStartupContext); - #endif /* _IPC_H_ */ diff --git a/launchd/src/Makefile.am b/launchd/src/Makefile.am index a2d51ee..788b6f2 100644 --- a/launchd/src/Makefile.am +++ b/launchd/src/Makefile.am @@ -1,20 +1,29 @@ -AM_CFLAGS = -no-cpp-precomp -F/System/Library/PrivateFrameworks -Wall -W -Wshadow -Wmissing-prototypes -Wmissing-declarations -Werror -D__MigTypeCheck=1 +AM_CFLAGS = -no-cpp-precomp -F/System/Library/PrivateFrameworks -Wall -Wextra -Waggregate-return -Wshadow -Wmissing-prototypes -Wmissing-declarations -Werror -D__MigTypeCheck=1 -fvisibility=hidden -Dmig_external=__private_extern__ -CLEANFILES = bootstrap.h bootstrapServer.c bootstrapUser.c bootstrapServer.h notifyServer.c notifyServer.h mpm_replyUser.c mpm_reply.h +CLEANFILES = protocol_vproc.h protocol_vprocServer.c protocol_vprocUser.c protocol_vprocServer.h \ + launchd_internal.h launchd_internalServer.h launchd_internalServer.c launchd_internalUser.c \ + notifyServer.c notifyServer.h job_replyUser.c job_reply.h __version.c -bootstrap.h bootstrapServer.c bootstrapUser.c bootstrapServer.h: $(srcdir)/bootstrap.defs - mig $(MIGFLAGS) -sheader bootstrapServer.h $(srcdir)/bootstrap.defs +protocol_vproc.h protocol_vprocServer.c protocol_vprocUser.c protocol_vprocServer.h: $(srcdir)/protocol_job.defs + mig $(MIGFLAGS) -sheader protocol_vprocServer.h $(srcdir)/protocol_job.defs if LIBS_ONLY noinst_LIBRARIES = liblaunch.a liblaunch_profile.a -liblaunch_a_SOURCES = liblaunch.c bootstrap_public.c +liblaunch_a_CFLAGS = -D__DARWIN_NON_CANCELABLE=1 $(AM_CFLAGS) +liblaunch_a_SOURCES = liblaunch.c libvproc.c libbootstrap.c protocol_vprocUser.c __version.c -liblaunch_profile_a_CFLAGS = -pg $(AM_CFLAGS) -liblaunch_profile_a_SOURCES = liblaunch.c bootstrap_public.c +liblaunch_profile_a_CFLAGS = -pg -D__DARWIN_NON_CANCELABLE=1 $(AM_CFLAGS) +liblaunch_profile_a_SOURCES = liblaunch.c libvproc.c libbootstrap.c protocol_vprocUser.c __version.c + +$(srcdir)/libvproc.c:: protocol_vproc.h + +$(srcdir)/protocol_vprocUser.c:: protocol_vproc.h + +__version.c: + /Developer/Makefiles/bin/version.pl launchd_libs > $@ -bootstrap_public.c:: bootstrap.h install-data-hook: mkdir -p $(DESTDIR)/usr/local/lib/system @@ -24,36 +33,33 @@ install-data-hook: else -sbin_SCRIPTS = service - bin_PROGRAMS = launchctl wait4path sbin_PROGRAMS = launchd SystemStarter libexec_PROGRAMS = launchproxy -sysconf_DATA = hostconfig rc.common rc.netboot rc.shutdown +sysconf_DATA = hostconfig rc.common rc.netboot -launchctl_CFLAGS = $(AM_CFLAGS) -fvisibility=hidden -launchctl_LDFLAGS = -framework CoreFoundation -weak_library /usr/lib/libedit.dylib +launchctl_CFLAGS = $(AM_CFLAGS) -I/System/Library/Frameworks/System.framework/PrivateHeaders +launchctl_LDFLAGS = -framework CoreFoundation -framework IOKit -framework Security -weak_library /usr/lib/libedit.dylib -SystemStarter_CFLAGS = -mdynamic-no-pic $(AM_CFLAGS) -fvisibility=hidden -SystemStarter_LDFLAGS = -framework CoreFoundation +SystemStarter_CFLAGS = -mdynamic-no-pic $(AM_CFLAGS) +SystemStarter_LDFLAGS = -framework CoreFoundation -framework IOKit SystemStarter_SOURCES = StartupItems.c IPC.c SystemStarter.c -launchd_CFLAGS = -mdynamic-no-pic $(AM_CFLAGS) -Wno-unused-parameter -fvisibility=hidden +launchd_CFLAGS = -mdynamic-no-pic $(AM_CFLAGS) -Wno-unused-parameter launchd_LDFLAGS = -lbsm -launchd_SOURCES = launchd.c launchd_core_logic.c launchd_unix_ipc.c launchd_mach_ipc.c init.c bootstrapServer.c notifyServer.c launchd_internalUser.c launchd_internalServer.c mpm_replyUser.c +launchd_SOURCES = launchd.c launchd_core_logic.c launchd_unix_ipc.c protocol_vprocServer.c notifyServer.c launchd_internalUser.c launchd_internalServer.c job_replyUser.c launchd_runtime.c launchd_runtime_kill.c -launchd_mach_ipc.c:: bootstrap.h bootstrapServer.h notifyServer.h launchd_internal.h -launchd_core_logic.c:: bootstrap.h mpm_reply.h -launchd.c:: bootstrap.h launchd_internalServer.h launchd_internal.h notifyServer.h bootstrapServer.h +launchd_runtime.c:: notifyServer.h launchd_internal.h +launchd_core_logic.c:: protocol_vproc.h job_reply.h protocol_vprocServer.h launchproxy_LDFLAGS = -weak_framework Security notifyServer.c notifyServer.h: /usr/include/mach/notify.defs mig $(MIGFLAGS) -header /dev/null -user /dev/null -sheader notifyServer.h /usr/include/mach/notify.defs -mpm_replyUser.c mpm_reply.h: $(srcdir)/mpm_reply.defs - mig $(MIGFLAGS) -sheader /dev/null -server /dev/null $(srcdir)/mpm_reply.defs +job_replyUser.c job_reply.h: $(srcdir)/protocol_job_reply.defs + mig $(MIGFLAGS) -sheader /dev/null -server /dev/null $(srcdir)/protocol_job_reply.defs launchd_internal.h launchd_internalServer.c launchd_internalUser.c launchd_internalServer.h: $(srcdir)/launchd_internal.defs mig $(MIGFLAGS) -sheader launchd_internalServer.h $(srcdir)/launchd_internal.defs @@ -63,32 +69,28 @@ man1_MANS = wait4path.1 launchctl.1 man5_MANS = launchd.plist.5 launchd.conf.5 -man8_MANS = StartupItemContext.8 SystemStarter.8 rc.8 launchd.8 service.8 launchproxy.8 - -STARTUPITEMS = $(basename $(notdir $(wildcard $(srcdir)/StartupItems/*.plist))) - -$(addprefix $(DESTDIR)/System/Library/StartupItems/, $(STARTUPITEMS)): - mkdir -p $@ - cp $(srcdir)/StartupItems/$(notdir $@) $@ - chmod 755 $@/$(notdir $@) - cp $(srcdir)/StartupItems/$(notdir $@).plist $@/StartupParameters.plist +man8_MANS = StartupItemContext.8 SystemStarter.8 rc.8 launchd.8 launchproxy.8 -install-startupitems: $(addprefix $(DESTDIR)/System/Library/StartupItems/, $(STARTUPITEMS)) - -install-data-hook: install-startupitems +install-data-hook: mkdir -p $(DESTDIR)/usr/libexec - cp $(srcdir)/StartupItemContext $(DESTDIR)/usr/libexec mkdir -p $(DESTDIR)/usr/include/servers - cp $(srcdir)/launch.h $(DESTDIR)/usr/include - cp $(srcdir)/bootstrap_public.h $(DESTDIR)/usr/include/servers/bootstrap.h - cp $(srcdir)/bootstrap_public.h $(DESTDIR)/usr/include/servers/bootstrap_defs.h mkdir -p $(DESTDIR)/usr/local/include - cp $(srcdir)/launch_priv.h $(DESTDIR)/usr/local/include mkdir -p $(DESTDIR)/$(sysconfdir)/mach_init.d mkdir -p $(DESTDIR)/$(sysconfdir)/mach_init_per_user.d + mkdir -p $(DESTDIR)/$(sysconfdir)/mach_init_per_login_session.d mkdir -p $(DESTDIR)/Library/LaunchDaemons mkdir -p $(DESTDIR)/Library/LaunchAgents - mkdir -p $(DESTDIR)/System/Library/LaunchDaemons mkdir -p $(DESTDIR)/System/Library/LaunchAgents + mkdir -p $(DESTDIR)/System/Library/LaunchDaemons + cp $(srcdir)/StartupItemContext $(DESTDIR)/usr/libexec + cp $(srcdir)/liblaunch_public.h $(DESTDIR)/usr/include/launch.h + cp $(srcdir)/libvproc_public.h $(DESTDIR)/usr/include/vproc.h + cp $(srcdir)/libbootstrap_public.h $(DESTDIR)/usr/include/servers/bootstrap.h + cp $(srcdir)/libbootstrap_public.h $(DESTDIR)/usr/include/servers/bootstrap_defs.h + cp $(srcdir)/libbootstrap_private.h $(DESTDIR)/usr/local/include/bootstrap_priv.h + cp $(srcdir)/liblaunch_private.h $(DESTDIR)/usr/local/include/launch_priv.h + cp $(srcdir)/libvproc_private.h $(DESTDIR)/usr/local/include/vproc_priv.h + cp $(srcdir)/reboot2.h $(DESTDIR)/usr/local/include/reboot2.h + cp $(srcdir)/com.apple.SystemStarter.plist $(DESTDIR)/System/Library/LaunchDaemons endif diff --git a/launchd/src/Makefile.in b/launchd/src/Makefile.in index a93b435..8df6891 100644 --- a/launchd/src/Makefile.in +++ b/launchd/src/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.6.3 from Makefile.am. +# Makefile.in generated by automake 1.10 from Makefile.am. # @configure_input@ -# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 -# Free Software Foundation, Inc. +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -13,263 +13,323 @@ # PARTICULAR PURPOSE. @SET_MAKE@ -SHELL = @SHELL@ -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ -prefix = @prefix@ -exec_prefix = @exec_prefix@ -bindir = @bindir@ -sbindir = @sbindir@ -libexecdir = @libexecdir@ -datadir = @datadir@ -sysconfdir = @sysconfdir@ -sharedstatedir = @sharedstatedir@ -localstatedir = @localstatedir@ -libdir = @libdir@ -infodir = @infodir@ -mandir = @mandir@ -includedir = @includedir@ -oldincludedir = /usr/include + +VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ -top_builddir = .. - -ACLOCAL = @ACLOCAL@ -AUTOCONF = @AUTOCONF@ -AUTOMAKE = @AUTOMAKE@ -AUTOHEADER = @AUTOHEADER@ - am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -INSTALL = @INSTALL@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_DATA = @INSTALL_DATA@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c -INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_HEADER = $(INSTALL_DATA) -transform = @program_transform_name@ +transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : - -EXEEXT = @EXEEXT@ -OBJEXT = @OBJEXT@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -AMTAR = @AMTAR@ -AWK = @AWK@ -CC = @CC@ -DEPDIR = @DEPDIR@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -PACKAGE = @PACKAGE@ -RANLIB = @RANLIB@ -STRIP = @STRIP@ -VERSION = @VERSION@ -am__include = @am__include@ -am__quote = @am__quote@ -install_sh = @install_sh@ -AM_CFLAGS = -no-cpp-precomp -F/System/Library/PrivateFrameworks -Wall -W -Wshadow -Wmissing-prototypes -Wmissing-declarations -Werror -D__MigTypeCheck=1 - -CLEANFILES = bootstrap.h bootstrapServer.c bootstrapUser.c bootstrapServer.h notifyServer.c notifyServer.h mpm_replyUser.c mpm_reply.h - -@LIBS_ONLY_TRUE@noinst_LIBRARIES = liblaunch.a liblaunch_profile.a - -@LIBS_ONLY_TRUE@liblaunch_a_SOURCES = liblaunch.c bootstrap_public.c - -@LIBS_ONLY_TRUE@liblaunch_profile_a_CFLAGS = -pg $(AM_CFLAGS) -@LIBS_ONLY_TRUE@liblaunch_profile_a_SOURCES = liblaunch.c bootstrap_public.c - -@LIBS_ONLY_FALSE@sbin_SCRIPTS = service - -@LIBS_ONLY_FALSE@bin_PROGRAMS = launchctl wait4path -@LIBS_ONLY_FALSE@sbin_PROGRAMS = launchd SystemStarter -@LIBS_ONLY_FALSE@libexec_PROGRAMS = launchproxy - -@LIBS_ONLY_FALSE@sysconf_DATA = hostconfig rc.common rc.netboot rc.shutdown - -@LIBS_ONLY_FALSE@launchctl_CFLAGS = $(AM_CFLAGS) -fvisibility=hidden -@LIBS_ONLY_FALSE@launchctl_LDFLAGS = -framework CoreFoundation -weak_library /usr/lib/libedit.dylib - -@LIBS_ONLY_FALSE@SystemStarter_CFLAGS = -mdynamic-no-pic $(AM_CFLAGS) -fvisibility=hidden -@LIBS_ONLY_FALSE@SystemStarter_LDFLAGS = -framework CoreFoundation -@LIBS_ONLY_FALSE@SystemStarter_SOURCES = StartupItems.c IPC.c SystemStarter.c - -@LIBS_ONLY_FALSE@launchd_CFLAGS = -mdynamic-no-pic $(AM_CFLAGS) -Wno-unused-parameter -fvisibility=hidden -@LIBS_ONLY_FALSE@launchd_LDFLAGS = -lbsm -@LIBS_ONLY_FALSE@launchd_SOURCES = launchd.c launchd_core_logic.c launchd_unix_ipc.c launchd_mach_ipc.c init.c bootstrapServer.c notifyServer.c launchd_internalUser.c launchd_internalServer.c mpm_replyUser.c - -@LIBS_ONLY_FALSE@launchproxy_LDFLAGS = -weak_framework Security - -@LIBS_ONLY_FALSE@man1_MANS = wait4path.1 launchctl.1 - -@LIBS_ONLY_FALSE@man5_MANS = launchd.plist.5 launchd.conf.5 - -@LIBS_ONLY_FALSE@man8_MANS = StartupItemContext.8 SystemStarter.8 rc.8 launchd.8 service.8 launchproxy.8 - -@LIBS_ONLY_FALSE@STARTUPITEMS = $(basename $(notdir $(wildcard $(srcdir)/StartupItems/*.plist))) +@LIBS_ONLY_FALSE@bin_PROGRAMS = launchctl$(EXEEXT) wait4path$(EXEEXT) +@LIBS_ONLY_FALSE@sbin_PROGRAMS = launchd$(EXEEXT) \ +@LIBS_ONLY_FALSE@ SystemStarter$(EXEEXT) +@LIBS_ONLY_FALSE@libexec_PROGRAMS = launchproxy$(EXEEXT) subdir = src +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(srcdir)/config.h.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) - -liblaunch_a_AR = $(AR) cru +AR = ar +ARFLAGS = cru +liblaunch_a_AR = $(AR) $(ARFLAGS) liblaunch_a_LIBADD = -@LIBS_ONLY_TRUE@am_liblaunch_a_OBJECTS = liblaunch.$(OBJEXT) \ -@LIBS_ONLY_TRUE@ bootstrap_public.$(OBJEXT) +am__liblaunch_a_SOURCES_DIST = liblaunch.c libvproc.c libbootstrap.c \ + protocol_vprocUser.c __version.c +@LIBS_ONLY_TRUE@am_liblaunch_a_OBJECTS = \ +@LIBS_ONLY_TRUE@ liblaunch_a-liblaunch.$(OBJEXT) \ +@LIBS_ONLY_TRUE@ liblaunch_a-libvproc.$(OBJEXT) \ +@LIBS_ONLY_TRUE@ liblaunch_a-libbootstrap.$(OBJEXT) \ +@LIBS_ONLY_TRUE@ liblaunch_a-protocol_vprocUser.$(OBJEXT) \ +@LIBS_ONLY_TRUE@ liblaunch_a-__version.$(OBJEXT) liblaunch_a_OBJECTS = $(am_liblaunch_a_OBJECTS) -liblaunch_profile_a_AR = $(AR) cru +liblaunch_profile_a_AR = $(AR) $(ARFLAGS) liblaunch_profile_a_LIBADD = -@LIBS_ONLY_TRUE@am_liblaunch_profile_a_OBJECTS = \ +am__liblaunch_profile_a_SOURCES_DIST = liblaunch.c libvproc.c \ + libbootstrap.c protocol_vprocUser.c __version.c +@LIBS_ONLY_TRUE@am_liblaunch_profile_a_OBJECTS = \ @LIBS_ONLY_TRUE@ liblaunch_profile_a-liblaunch.$(OBJEXT) \ -@LIBS_ONLY_TRUE@ liblaunch_profile_a-bootstrap_public.$(OBJEXT) +@LIBS_ONLY_TRUE@ liblaunch_profile_a-libvproc.$(OBJEXT) \ +@LIBS_ONLY_TRUE@ liblaunch_profile_a-libbootstrap.$(OBJEXT) \ +@LIBS_ONLY_TRUE@ liblaunch_profile_a-protocol_vprocUser.$(OBJEXT) \ +@LIBS_ONLY_TRUE@ liblaunch_profile_a-__version.$(OBJEXT) liblaunch_profile_a_OBJECTS = $(am_liblaunch_profile_a_OBJECTS) -@LIBS_ONLY_TRUE@bin_PROGRAMS = -@LIBS_ONLY_FALSE@bin_PROGRAMS = launchctl$(EXEEXT) wait4path$(EXEEXT) -@LIBS_ONLY_TRUE@libexec_PROGRAMS = -@LIBS_ONLY_FALSE@libexec_PROGRAMS = launchproxy$(EXEEXT) -@LIBS_ONLY_TRUE@sbin_PROGRAMS = -@LIBS_ONLY_FALSE@sbin_PROGRAMS = launchd$(EXEEXT) SystemStarter$(EXEEXT) +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libexecdir)" \ + "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man1dir)" \ + "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)" \ + "$(DESTDIR)$(sysconfdir)" +binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) +libexecPROGRAMS_INSTALL = $(INSTALL_PROGRAM) +sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM) PROGRAMS = $(bin_PROGRAMS) $(libexec_PROGRAMS) $(sbin_PROGRAMS) - -@LIBS_ONLY_FALSE@am_SystemStarter_OBJECTS = \ +am__SystemStarter_SOURCES_DIST = StartupItems.c IPC.c SystemStarter.c +@LIBS_ONLY_FALSE@am_SystemStarter_OBJECTS = \ @LIBS_ONLY_FALSE@ SystemStarter-StartupItems.$(OBJEXT) \ @LIBS_ONLY_FALSE@ SystemStarter-IPC.$(OBJEXT) \ @LIBS_ONLY_FALSE@ SystemStarter-SystemStarter.$(OBJEXT) SystemStarter_OBJECTS = $(am_SystemStarter_OBJECTS) SystemStarter_LDADD = $(LDADD) -SystemStarter_DEPENDENCIES = +SystemStarter_LINK = $(CCLD) $(SystemStarter_CFLAGS) $(CFLAGS) \ + $(SystemStarter_LDFLAGS) $(LDFLAGS) -o $@ launchctl_SOURCES = launchctl.c launchctl_OBJECTS = launchctl-launchctl.$(OBJEXT) launchctl_LDADD = $(LDADD) -launchctl_DEPENDENCIES = +launchctl_LINK = $(CCLD) $(launchctl_CFLAGS) $(CFLAGS) \ + $(launchctl_LDFLAGS) $(LDFLAGS) -o $@ +am__launchd_SOURCES_DIST = launchd.c launchd_core_logic.c \ + launchd_unix_ipc.c protocol_vprocServer.c notifyServer.c \ + launchd_internalUser.c launchd_internalServer.c \ + job_replyUser.c launchd_runtime.c launchd_runtime_kill.c @LIBS_ONLY_FALSE@am_launchd_OBJECTS = launchd-launchd.$(OBJEXT) \ @LIBS_ONLY_FALSE@ launchd-launchd_core_logic.$(OBJEXT) \ @LIBS_ONLY_FALSE@ launchd-launchd_unix_ipc.$(OBJEXT) \ -@LIBS_ONLY_FALSE@ launchd-launchd_mach_ipc.$(OBJEXT) \ -@LIBS_ONLY_FALSE@ launchd-init.$(OBJEXT) \ -@LIBS_ONLY_FALSE@ launchd-bootstrapServer.$(OBJEXT) \ +@LIBS_ONLY_FALSE@ launchd-protocol_vprocServer.$(OBJEXT) \ @LIBS_ONLY_FALSE@ launchd-notifyServer.$(OBJEXT) \ @LIBS_ONLY_FALSE@ launchd-launchd_internalUser.$(OBJEXT) \ @LIBS_ONLY_FALSE@ launchd-launchd_internalServer.$(OBJEXT) \ -@LIBS_ONLY_FALSE@ launchd-mpm_replyUser.$(OBJEXT) +@LIBS_ONLY_FALSE@ launchd-job_replyUser.$(OBJEXT) \ +@LIBS_ONLY_FALSE@ launchd-launchd_runtime.$(OBJEXT) \ +@LIBS_ONLY_FALSE@ launchd-launchd_runtime_kill.$(OBJEXT) launchd_OBJECTS = $(am_launchd_OBJECTS) launchd_LDADD = $(LDADD) -launchd_DEPENDENCIES = +launchd_LINK = $(CCLD) $(launchd_CFLAGS) $(CFLAGS) $(launchd_LDFLAGS) \ + $(LDFLAGS) -o $@ launchproxy_SOURCES = launchproxy.c launchproxy_OBJECTS = launchproxy.$(OBJEXT) launchproxy_LDADD = $(LDADD) -launchproxy_DEPENDENCIES = +launchproxy_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(launchproxy_LDFLAGS) $(LDFLAGS) -o $@ wait4path_SOURCES = wait4path.c wait4path_OBJECTS = wait4path.$(OBJEXT) wait4path_LDADD = $(LDADD) -wait4path_DEPENDENCIES = -wait4path_LDFLAGS = -SCRIPTS = $(sbin_SCRIPTS) - - -DEFS = @DEFS@ -DEFAULT_INCLUDES = -I. -I$(srcdir) -I. -CPPFLAGS = @CPPFLAGS@ -LDFLAGS = @LDFLAGS@ -LIBS = @LIBS@ +DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles -@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/SystemStarter-IPC.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/SystemStarter-StartupItems.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/SystemStarter-SystemStarter.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/bootstrap_public.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/launchctl-launchctl.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/launchd-bootstrapServer.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/launchd-init.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/launchd-launchd.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/launchd-launchd_core_logic.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/launchd-launchd_internalServer.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/launchd-launchd_internalUser.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/launchd-launchd_mach_ipc.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/launchd-launchd_unix_ipc.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/launchd-mpm_replyUser.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/launchd-notifyServer.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/launchproxy.Po ./$(DEPDIR)/liblaunch.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/liblaunch_profile_a-bootstrap_public.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/liblaunch_profile_a-liblaunch.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/wait4path.Po COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -CFLAGS = @CFLAGS@ -DIST_SOURCES = $(liblaunch_a_SOURCES) $(liblaunch_profile_a_SOURCES) \ +SOURCES = $(liblaunch_a_SOURCES) $(liblaunch_profile_a_SOURCES) \ $(SystemStarter_SOURCES) launchctl.c $(launchd_SOURCES) \ launchproxy.c wait4path.c - +DIST_SOURCES = $(am__liblaunch_a_SOURCES_DIST) \ + $(am__liblaunch_profile_a_SOURCES_DIST) \ + $(am__SystemStarter_SOURCES_DIST) launchctl.c \ + $(am__launchd_SOURCES_DIST) launchproxy.c wait4path.c +man1dir = $(mandir)/man1 +man5dir = $(mandir)/man5 +man8dir = $(mandir)/man8 NROFF = nroff MANS = $(man1_MANS) $(man5_MANS) $(man8_MANS) +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +sysconfDATA_INSTALL = $(INSTALL_DATA) DATA = $(sysconf_DATA) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host_alias = @host_alias@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CFLAGS = -no-cpp-precomp -F/System/Library/PrivateFrameworks -Wall -Wextra -Waggregate-return -Wshadow -Wmissing-prototypes -Wmissing-declarations -Werror -D__MigTypeCheck=1 -fvisibility=hidden -Dmig_external=__private_extern__ +CLEANFILES = protocol_vproc.h protocol_vprocServer.c protocol_vprocUser.c protocol_vprocServer.h \ + launchd_internal.h launchd_internalServer.h launchd_internalServer.c launchd_internalUser.c \ + notifyServer.c notifyServer.h job_replyUser.c job_reply.h __version.c -DIST_COMMON = Makefile.am Makefile.in config.h.in -SOURCES = $(liblaunch_a_SOURCES) $(liblaunch_profile_a_SOURCES) $(SystemStarter_SOURCES) launchctl.c $(launchd_SOURCES) launchproxy.c wait4path.c - +@LIBS_ONLY_TRUE@noinst_LIBRARIES = liblaunch.a liblaunch_profile.a +@LIBS_ONLY_TRUE@liblaunch_a_CFLAGS = -D__DARWIN_NON_CANCELABLE=1 $(AM_CFLAGS) +@LIBS_ONLY_TRUE@liblaunch_a_SOURCES = liblaunch.c libvproc.c libbootstrap.c protocol_vprocUser.c __version.c +@LIBS_ONLY_TRUE@liblaunch_profile_a_CFLAGS = -pg -D__DARWIN_NON_CANCELABLE=1 $(AM_CFLAGS) +@LIBS_ONLY_TRUE@liblaunch_profile_a_SOURCES = liblaunch.c libvproc.c libbootstrap.c protocol_vprocUser.c __version.c +@LIBS_ONLY_FALSE@sysconf_DATA = hostconfig rc.common rc.netboot +@LIBS_ONLY_FALSE@launchctl_CFLAGS = $(AM_CFLAGS) -I/System/Library/Frameworks/System.framework/PrivateHeaders +@LIBS_ONLY_FALSE@launchctl_LDFLAGS = -framework CoreFoundation -framework IOKit -framework Security -weak_library /usr/lib/libedit.dylib +@LIBS_ONLY_FALSE@SystemStarter_CFLAGS = -mdynamic-no-pic $(AM_CFLAGS) +@LIBS_ONLY_FALSE@SystemStarter_LDFLAGS = -framework CoreFoundation -framework IOKit +@LIBS_ONLY_FALSE@SystemStarter_SOURCES = StartupItems.c IPC.c SystemStarter.c +@LIBS_ONLY_FALSE@launchd_CFLAGS = -mdynamic-no-pic $(AM_CFLAGS) -Wno-unused-parameter +@LIBS_ONLY_FALSE@launchd_LDFLAGS = -lbsm +@LIBS_ONLY_FALSE@launchd_SOURCES = launchd.c launchd_core_logic.c launchd_unix_ipc.c protocol_vprocServer.c notifyServer.c launchd_internalUser.c launchd_internalServer.c job_replyUser.c launchd_runtime.c launchd_runtime_kill.c +@LIBS_ONLY_FALSE@launchproxy_LDFLAGS = -weak_framework Security +@LIBS_ONLY_FALSE@man1_MANS = wait4path.1 launchctl.1 +@LIBS_ONLY_FALSE@man5_MANS = launchd.plist.5 launchd.conf.5 +@LIBS_ONLY_FALSE@man8_MANS = StartupItemContext.8 SystemStarter.8 rc.8 launchd.8 launchproxy.8 all: config.h $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: .SUFFIXES: .c .o .obj -$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4) +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh config.h: stamp-h1 @if test ! -f $@; then \ rm -f stamp-h1; \ - $(MAKE) stamp-h1; \ + $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \ else :; fi stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status src/config.h - -$(srcdir)/config.h.in: $(top_srcdir)/configure.ac $(ACLOCAL_M4) +$(srcdir)/config.h.in: $(am__configure_deps) cd $(top_srcdir) && $(AUTOHEADER) - touch $(srcdir)/config.h.in + rm -f stamp-h1 + touch $@ distclean-hdr: -rm -f config.h stamp-h1 -AR = ar - clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) liblaunch.a: $(liblaunch_a_OBJECTS) $(liblaunch_a_DEPENDENCIES) -rm -f liblaunch.a $(liblaunch_a_AR) liblaunch.a $(liblaunch_a_OBJECTS) $(liblaunch_a_LIBADD) $(RANLIB) liblaunch.a -liblaunch_profile_a-liblaunch.$(OBJEXT): liblaunch.c -liblaunch_profile_a-bootstrap_public.$(OBJEXT): bootstrap_public.c liblaunch_profile.a: $(liblaunch_profile_a_OBJECTS) $(liblaunch_profile_a_DEPENDENCIES) -rm -f liblaunch_profile.a $(liblaunch_profile_a_AR) liblaunch_profile.a $(liblaunch_profile_a_OBJECTS) $(liblaunch_profile_a_LIBADD) $(RANLIB) liblaunch_profile.a -binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(bindir) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @list='$(bin_PROGRAMS)'; for p in $$list; do \ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ if test -f $$p \ ; then \ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ - echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f"; \ - $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f; \ + echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \ else :; fi; \ done @@ -277,23 +337,22 @@ uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; for p in $$list; do \ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ - echo " rm -f $(DESTDIR)$(bindir)/$$f"; \ - rm -f $(DESTDIR)$(bindir)/$$f; \ + echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ + rm -f "$(DESTDIR)$(bindir)/$$f"; \ done clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) -libexecPROGRAMS_INSTALL = $(INSTALL_PROGRAM) install-libexecPROGRAMS: $(libexec_PROGRAMS) @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(libexecdir) + test -z "$(libexecdir)" || $(MKDIR_P) "$(DESTDIR)$(libexecdir)" @list='$(libexec_PROGRAMS)'; for p in $$list; do \ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ if test -f $$p \ ; then \ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ - echo " $(INSTALL_PROGRAM_ENV) $(libexecPROGRAMS_INSTALL) $$p $(DESTDIR)$(libexecdir)/$$f"; \ - $(INSTALL_PROGRAM_ENV) $(libexecPROGRAMS_INSTALL) $$p $(DESTDIR)$(libexecdir)/$$f; \ + echo " $(INSTALL_PROGRAM_ENV) $(libexecPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(libexecdir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(libexecPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(libexecdir)/$$f" || exit 1; \ else :; fi; \ done @@ -301,23 +360,22 @@ uninstall-libexecPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(libexec_PROGRAMS)'; for p in $$list; do \ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ - echo " rm -f $(DESTDIR)$(libexecdir)/$$f"; \ - rm -f $(DESTDIR)$(libexecdir)/$$f; \ + echo " rm -f '$(DESTDIR)$(libexecdir)/$$f'"; \ + rm -f "$(DESTDIR)$(libexecdir)/$$f"; \ done clean-libexecPROGRAMS: -test -z "$(libexec_PROGRAMS)" || rm -f $(libexec_PROGRAMS) -sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM) install-sbinPROGRAMS: $(sbin_PROGRAMS) @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(sbindir) + test -z "$(sbindir)" || $(MKDIR_P) "$(DESTDIR)$(sbindir)" @list='$(sbin_PROGRAMS)'; for p in $$list; do \ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ if test -f $$p \ ; then \ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ - echo " $(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) $$p $(DESTDIR)$(sbindir)/$$f"; \ - $(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) $$p $(DESTDIR)$(sbindir)/$$f; \ + echo " $(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \ else :; fi; \ done @@ -325,64 +383,30 @@ uninstall-sbinPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(sbin_PROGRAMS)'; for p in $$list; do \ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ - echo " rm -f $(DESTDIR)$(sbindir)/$$f"; \ - rm -f $(DESTDIR)$(sbindir)/$$f; \ + echo " rm -f '$(DESTDIR)$(sbindir)/$$f'"; \ + rm -f "$(DESTDIR)$(sbindir)/$$f"; \ done clean-sbinPROGRAMS: -test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS) -SystemStarter-StartupItems.$(OBJEXT): StartupItems.c -SystemStarter-IPC.$(OBJEXT): IPC.c -SystemStarter-SystemStarter.$(OBJEXT): SystemStarter.c SystemStarter$(EXEEXT): $(SystemStarter_OBJECTS) $(SystemStarter_DEPENDENCIES) @rm -f SystemStarter$(EXEEXT) - $(LINK) $(SystemStarter_LDFLAGS) $(SystemStarter_OBJECTS) $(SystemStarter_LDADD) $(LIBS) -launchctl-launchctl.$(OBJEXT): launchctl.c + $(SystemStarter_LINK) $(SystemStarter_OBJECTS) $(SystemStarter_LDADD) $(LIBS) launchctl$(EXEEXT): $(launchctl_OBJECTS) $(launchctl_DEPENDENCIES) @rm -f launchctl$(EXEEXT) - $(LINK) $(launchctl_LDFLAGS) $(launchctl_OBJECTS) $(launchctl_LDADD) $(LIBS) -launchd-launchd.$(OBJEXT): launchd.c -launchd-launchd_core_logic.$(OBJEXT): launchd_core_logic.c -launchd-launchd_unix_ipc.$(OBJEXT): launchd_unix_ipc.c -launchd-launchd_mach_ipc.$(OBJEXT): launchd_mach_ipc.c -launchd-init.$(OBJEXT): init.c -launchd-bootstrapServer.$(OBJEXT): bootstrapServer.c -launchd-notifyServer.$(OBJEXT): notifyServer.c -launchd-launchd_internalUser.$(OBJEXT): launchd_internalUser.c -launchd-launchd_internalServer.$(OBJEXT): launchd_internalServer.c -launchd-mpm_replyUser.$(OBJEXT): mpm_replyUser.c + $(launchctl_LINK) $(launchctl_OBJECTS) $(launchctl_LDADD) $(LIBS) launchd$(EXEEXT): $(launchd_OBJECTS) $(launchd_DEPENDENCIES) @rm -f launchd$(EXEEXT) - $(LINK) $(launchd_LDFLAGS) $(launchd_OBJECTS) $(launchd_LDADD) $(LIBS) + $(launchd_LINK) $(launchd_OBJECTS) $(launchd_LDADD) $(LIBS) launchproxy$(EXEEXT): $(launchproxy_OBJECTS) $(launchproxy_DEPENDENCIES) @rm -f launchproxy$(EXEEXT) - $(LINK) $(launchproxy_LDFLAGS) $(launchproxy_OBJECTS) $(launchproxy_LDADD) $(LIBS) + $(launchproxy_LINK) $(launchproxy_OBJECTS) $(launchproxy_LDADD) $(LIBS) wait4path$(EXEEXT): $(wait4path_OBJECTS) $(wait4path_DEPENDENCIES) @rm -f wait4path$(EXEEXT) - $(LINK) $(wait4path_LDFLAGS) $(wait4path_OBJECTS) $(wait4path_LDADD) $(LIBS) -sbinSCRIPT_INSTALL = $(INSTALL_SCRIPT) -install-sbinSCRIPTS: $(sbin_SCRIPTS) - @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(sbindir) - @list='$(sbin_SCRIPTS)'; for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - if test -f $$d$$p; then \ - f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ - echo " $(sbinSCRIPT_INSTALL) $$d$$p $(DESTDIR)$(sbindir)/$$f"; \ - $(sbinSCRIPT_INSTALL) $$d$$p $(DESTDIR)$(sbindir)/$$f; \ - else :; fi; \ - done - -uninstall-sbinSCRIPTS: - @$(NORMAL_UNINSTALL) - @list='$(sbin_SCRIPTS)'; for p in $$list; do \ - f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ - echo " rm -f $(DESTDIR)$(sbindir)/$$f"; \ - rm -f $(DESTDIR)$(sbindir)/$$f; \ - done + $(LINK) $(wait4path_OBJECTS) $(wait4path_LDADD) $(LIBS) mostlyclean-compile: - -rm -f *.$(OBJEXT) core *.core + -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @@ -390,237 +414,382 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SystemStarter-IPC.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SystemStarter-StartupItems.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SystemStarter-SystemStarter.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bootstrap_public.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/launchctl-launchctl.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/launchd-bootstrapServer.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/launchd-init.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/launchd-job_replyUser.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/launchd-launchd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/launchd-launchd_core_logic.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/launchd-launchd_internalServer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/launchd-launchd_internalUser.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/launchd-launchd_mach_ipc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/launchd-launchd_runtime.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/launchd-launchd_runtime_kill.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/launchd-launchd_unix_ipc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/launchd-mpm_replyUser.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/launchd-notifyServer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/launchd-protocol_vprocServer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/launchproxy.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblaunch.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblaunch_profile_a-bootstrap_public.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblaunch_a-__version.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblaunch_a-libbootstrap.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblaunch_a-liblaunch.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblaunch_a-libvproc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblaunch_a-protocol_vprocUser.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblaunch_profile_a-__version.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblaunch_profile_a-libbootstrap.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblaunch_profile_a-liblaunch.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblaunch_profile_a-libvproc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblaunch_profile_a-protocol_vprocUser.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wait4path.Po@am__quote@ -distclean-depend: - -rm -rf ./$(DEPDIR) - .c.o: -@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$< +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: -@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(COMPILE) -c `cygpath -w $<` +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +liblaunch_a-liblaunch.o: liblaunch.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_a_CFLAGS) $(CFLAGS) -MT liblaunch_a-liblaunch.o -MD -MP -MF $(DEPDIR)/liblaunch_a-liblaunch.Tpo -c -o liblaunch_a-liblaunch.o `test -f 'liblaunch.c' || echo '$(srcdir)/'`liblaunch.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/liblaunch_a-liblaunch.Tpo $(DEPDIR)/liblaunch_a-liblaunch.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='liblaunch.c' object='liblaunch_a-liblaunch.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_a_CFLAGS) $(CFLAGS) -c -o liblaunch_a-liblaunch.o `test -f 'liblaunch.c' || echo '$(srcdir)/'`liblaunch.c + +liblaunch_a-liblaunch.obj: liblaunch.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_a_CFLAGS) $(CFLAGS) -MT liblaunch_a-liblaunch.obj -MD -MP -MF $(DEPDIR)/liblaunch_a-liblaunch.Tpo -c -o liblaunch_a-liblaunch.obj `if test -f 'liblaunch.c'; then $(CYGPATH_W) 'liblaunch.c'; else $(CYGPATH_W) '$(srcdir)/liblaunch.c'; fi` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/liblaunch_a-liblaunch.Tpo $(DEPDIR)/liblaunch_a-liblaunch.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='liblaunch.c' object='liblaunch_a-liblaunch.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_a_CFLAGS) $(CFLAGS) -c -o liblaunch_a-liblaunch.obj `if test -f 'liblaunch.c'; then $(CYGPATH_W) 'liblaunch.c'; else $(CYGPATH_W) '$(srcdir)/liblaunch.c'; fi` + +liblaunch_a-libvproc.o: libvproc.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_a_CFLAGS) $(CFLAGS) -MT liblaunch_a-libvproc.o -MD -MP -MF $(DEPDIR)/liblaunch_a-libvproc.Tpo -c -o liblaunch_a-libvproc.o `test -f 'libvproc.c' || echo '$(srcdir)/'`libvproc.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/liblaunch_a-libvproc.Tpo $(DEPDIR)/liblaunch_a-libvproc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libvproc.c' object='liblaunch_a-libvproc.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_a_CFLAGS) $(CFLAGS) -c -o liblaunch_a-libvproc.o `test -f 'libvproc.c' || echo '$(srcdir)/'`libvproc.c + +liblaunch_a-libvproc.obj: libvproc.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_a_CFLAGS) $(CFLAGS) -MT liblaunch_a-libvproc.obj -MD -MP -MF $(DEPDIR)/liblaunch_a-libvproc.Tpo -c -o liblaunch_a-libvproc.obj `if test -f 'libvproc.c'; then $(CYGPATH_W) 'libvproc.c'; else $(CYGPATH_W) '$(srcdir)/libvproc.c'; fi` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/liblaunch_a-libvproc.Tpo $(DEPDIR)/liblaunch_a-libvproc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libvproc.c' object='liblaunch_a-libvproc.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_a_CFLAGS) $(CFLAGS) -c -o liblaunch_a-libvproc.obj `if test -f 'libvproc.c'; then $(CYGPATH_W) 'libvproc.c'; else $(CYGPATH_W) '$(srcdir)/libvproc.c'; fi` + +liblaunch_a-libbootstrap.o: libbootstrap.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_a_CFLAGS) $(CFLAGS) -MT liblaunch_a-libbootstrap.o -MD -MP -MF $(DEPDIR)/liblaunch_a-libbootstrap.Tpo -c -o liblaunch_a-libbootstrap.o `test -f 'libbootstrap.c' || echo '$(srcdir)/'`libbootstrap.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/liblaunch_a-libbootstrap.Tpo $(DEPDIR)/liblaunch_a-libbootstrap.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libbootstrap.c' object='liblaunch_a-libbootstrap.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_a_CFLAGS) $(CFLAGS) -c -o liblaunch_a-libbootstrap.o `test -f 'libbootstrap.c' || echo '$(srcdir)/'`libbootstrap.c + +liblaunch_a-libbootstrap.obj: libbootstrap.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_a_CFLAGS) $(CFLAGS) -MT liblaunch_a-libbootstrap.obj -MD -MP -MF $(DEPDIR)/liblaunch_a-libbootstrap.Tpo -c -o liblaunch_a-libbootstrap.obj `if test -f 'libbootstrap.c'; then $(CYGPATH_W) 'libbootstrap.c'; else $(CYGPATH_W) '$(srcdir)/libbootstrap.c'; fi` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/liblaunch_a-libbootstrap.Tpo $(DEPDIR)/liblaunch_a-libbootstrap.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libbootstrap.c' object='liblaunch_a-libbootstrap.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_a_CFLAGS) $(CFLAGS) -c -o liblaunch_a-libbootstrap.obj `if test -f 'libbootstrap.c'; then $(CYGPATH_W) 'libbootstrap.c'; else $(CYGPATH_W) '$(srcdir)/libbootstrap.c'; fi` + +liblaunch_a-protocol_vprocUser.o: protocol_vprocUser.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_a_CFLAGS) $(CFLAGS) -MT liblaunch_a-protocol_vprocUser.o -MD -MP -MF $(DEPDIR)/liblaunch_a-protocol_vprocUser.Tpo -c -o liblaunch_a-protocol_vprocUser.o `test -f 'protocol_vprocUser.c' || echo '$(srcdir)/'`protocol_vprocUser.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/liblaunch_a-protocol_vprocUser.Tpo $(DEPDIR)/liblaunch_a-protocol_vprocUser.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='protocol_vprocUser.c' object='liblaunch_a-protocol_vprocUser.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_a_CFLAGS) $(CFLAGS) -c -o liblaunch_a-protocol_vprocUser.o `test -f 'protocol_vprocUser.c' || echo '$(srcdir)/'`protocol_vprocUser.c + +liblaunch_a-protocol_vprocUser.obj: protocol_vprocUser.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_a_CFLAGS) $(CFLAGS) -MT liblaunch_a-protocol_vprocUser.obj -MD -MP -MF $(DEPDIR)/liblaunch_a-protocol_vprocUser.Tpo -c -o liblaunch_a-protocol_vprocUser.obj `if test -f 'protocol_vprocUser.c'; then $(CYGPATH_W) 'protocol_vprocUser.c'; else $(CYGPATH_W) '$(srcdir)/protocol_vprocUser.c'; fi` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/liblaunch_a-protocol_vprocUser.Tpo $(DEPDIR)/liblaunch_a-protocol_vprocUser.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='protocol_vprocUser.c' object='liblaunch_a-protocol_vprocUser.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_a_CFLAGS) $(CFLAGS) -c -o liblaunch_a-protocol_vprocUser.obj `if test -f 'protocol_vprocUser.c'; then $(CYGPATH_W) 'protocol_vprocUser.c'; else $(CYGPATH_W) '$(srcdir)/protocol_vprocUser.c'; fi` + +liblaunch_a-__version.o: __version.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_a_CFLAGS) $(CFLAGS) -MT liblaunch_a-__version.o -MD -MP -MF $(DEPDIR)/liblaunch_a-__version.Tpo -c -o liblaunch_a-__version.o `test -f '__version.c' || echo '$(srcdir)/'`__version.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/liblaunch_a-__version.Tpo $(DEPDIR)/liblaunch_a-__version.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='__version.c' object='liblaunch_a-__version.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_a_CFLAGS) $(CFLAGS) -c -o liblaunch_a-__version.o `test -f '__version.c' || echo '$(srcdir)/'`__version.c + +liblaunch_a-__version.obj: __version.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_a_CFLAGS) $(CFLAGS) -MT liblaunch_a-__version.obj -MD -MP -MF $(DEPDIR)/liblaunch_a-__version.Tpo -c -o liblaunch_a-__version.obj `if test -f '__version.c'; then $(CYGPATH_W) '__version.c'; else $(CYGPATH_W) '$(srcdir)/__version.c'; fi` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/liblaunch_a-__version.Tpo $(DEPDIR)/liblaunch_a-__version.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='__version.c' object='liblaunch_a-__version.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_a_CFLAGS) $(CFLAGS) -c -o liblaunch_a-__version.obj `if test -f '__version.c'; then $(CYGPATH_W) '__version.c'; else $(CYGPATH_W) '$(srcdir)/__version.c'; fi` liblaunch_profile_a-liblaunch.o: liblaunch.c -@AMDEP_TRUE@ source='liblaunch.c' object='liblaunch_profile_a-liblaunch.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/liblaunch_profile_a-liblaunch.Po' tmpdepfile='$(DEPDIR)/liblaunch_profile_a-liblaunch.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_profile_a_CFLAGS) $(CFLAGS) -c -o liblaunch_profile_a-liblaunch.o `test -f 'liblaunch.c' || echo '$(srcdir)/'`liblaunch.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_profile_a_CFLAGS) $(CFLAGS) -MT liblaunch_profile_a-liblaunch.o -MD -MP -MF $(DEPDIR)/liblaunch_profile_a-liblaunch.Tpo -c -o liblaunch_profile_a-liblaunch.o `test -f 'liblaunch.c' || echo '$(srcdir)/'`liblaunch.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/liblaunch_profile_a-liblaunch.Tpo $(DEPDIR)/liblaunch_profile_a-liblaunch.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='liblaunch.c' object='liblaunch_profile_a-liblaunch.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_profile_a_CFLAGS) $(CFLAGS) -c -o liblaunch_profile_a-liblaunch.o `test -f 'liblaunch.c' || echo '$(srcdir)/'`liblaunch.c liblaunch_profile_a-liblaunch.obj: liblaunch.c -@AMDEP_TRUE@ source='liblaunch.c' object='liblaunch_profile_a-liblaunch.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/liblaunch_profile_a-liblaunch.Po' tmpdepfile='$(DEPDIR)/liblaunch_profile_a-liblaunch.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_profile_a_CFLAGS) $(CFLAGS) -c -o liblaunch_profile_a-liblaunch.obj `cygpath -w liblaunch.c` - -liblaunch_profile_a-bootstrap_public.o: bootstrap_public.c -@AMDEP_TRUE@ source='bootstrap_public.c' object='liblaunch_profile_a-bootstrap_public.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/liblaunch_profile_a-bootstrap_public.Po' tmpdepfile='$(DEPDIR)/liblaunch_profile_a-bootstrap_public.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_profile_a_CFLAGS) $(CFLAGS) -c -o liblaunch_profile_a-bootstrap_public.o `test -f 'bootstrap_public.c' || echo '$(srcdir)/'`bootstrap_public.c - -liblaunch_profile_a-bootstrap_public.obj: bootstrap_public.c -@AMDEP_TRUE@ source='bootstrap_public.c' object='liblaunch_profile_a-bootstrap_public.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/liblaunch_profile_a-bootstrap_public.Po' tmpdepfile='$(DEPDIR)/liblaunch_profile_a-bootstrap_public.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_profile_a_CFLAGS) $(CFLAGS) -c -o liblaunch_profile_a-bootstrap_public.obj `cygpath -w bootstrap_public.c` +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_profile_a_CFLAGS) $(CFLAGS) -MT liblaunch_profile_a-liblaunch.obj -MD -MP -MF $(DEPDIR)/liblaunch_profile_a-liblaunch.Tpo -c -o liblaunch_profile_a-liblaunch.obj `if test -f 'liblaunch.c'; then $(CYGPATH_W) 'liblaunch.c'; else $(CYGPATH_W) '$(srcdir)/liblaunch.c'; fi` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/liblaunch_profile_a-liblaunch.Tpo $(DEPDIR)/liblaunch_profile_a-liblaunch.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='liblaunch.c' object='liblaunch_profile_a-liblaunch.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_profile_a_CFLAGS) $(CFLAGS) -c -o liblaunch_profile_a-liblaunch.obj `if test -f 'liblaunch.c'; then $(CYGPATH_W) 'liblaunch.c'; else $(CYGPATH_W) '$(srcdir)/liblaunch.c'; fi` + +liblaunch_profile_a-libvproc.o: libvproc.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_profile_a_CFLAGS) $(CFLAGS) -MT liblaunch_profile_a-libvproc.o -MD -MP -MF $(DEPDIR)/liblaunch_profile_a-libvproc.Tpo -c -o liblaunch_profile_a-libvproc.o `test -f 'libvproc.c' || echo '$(srcdir)/'`libvproc.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/liblaunch_profile_a-libvproc.Tpo $(DEPDIR)/liblaunch_profile_a-libvproc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libvproc.c' object='liblaunch_profile_a-libvproc.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_profile_a_CFLAGS) $(CFLAGS) -c -o liblaunch_profile_a-libvproc.o `test -f 'libvproc.c' || echo '$(srcdir)/'`libvproc.c + +liblaunch_profile_a-libvproc.obj: libvproc.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_profile_a_CFLAGS) $(CFLAGS) -MT liblaunch_profile_a-libvproc.obj -MD -MP -MF $(DEPDIR)/liblaunch_profile_a-libvproc.Tpo -c -o liblaunch_profile_a-libvproc.obj `if test -f 'libvproc.c'; then $(CYGPATH_W) 'libvproc.c'; else $(CYGPATH_W) '$(srcdir)/libvproc.c'; fi` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/liblaunch_profile_a-libvproc.Tpo $(DEPDIR)/liblaunch_profile_a-libvproc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libvproc.c' object='liblaunch_profile_a-libvproc.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_profile_a_CFLAGS) $(CFLAGS) -c -o liblaunch_profile_a-libvproc.obj `if test -f 'libvproc.c'; then $(CYGPATH_W) 'libvproc.c'; else $(CYGPATH_W) '$(srcdir)/libvproc.c'; fi` + +liblaunch_profile_a-libbootstrap.o: libbootstrap.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_profile_a_CFLAGS) $(CFLAGS) -MT liblaunch_profile_a-libbootstrap.o -MD -MP -MF $(DEPDIR)/liblaunch_profile_a-libbootstrap.Tpo -c -o liblaunch_profile_a-libbootstrap.o `test -f 'libbootstrap.c' || echo '$(srcdir)/'`libbootstrap.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/liblaunch_profile_a-libbootstrap.Tpo $(DEPDIR)/liblaunch_profile_a-libbootstrap.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libbootstrap.c' object='liblaunch_profile_a-libbootstrap.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_profile_a_CFLAGS) $(CFLAGS) -c -o liblaunch_profile_a-libbootstrap.o `test -f 'libbootstrap.c' || echo '$(srcdir)/'`libbootstrap.c + +liblaunch_profile_a-libbootstrap.obj: libbootstrap.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_profile_a_CFLAGS) $(CFLAGS) -MT liblaunch_profile_a-libbootstrap.obj -MD -MP -MF $(DEPDIR)/liblaunch_profile_a-libbootstrap.Tpo -c -o liblaunch_profile_a-libbootstrap.obj `if test -f 'libbootstrap.c'; then $(CYGPATH_W) 'libbootstrap.c'; else $(CYGPATH_W) '$(srcdir)/libbootstrap.c'; fi` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/liblaunch_profile_a-libbootstrap.Tpo $(DEPDIR)/liblaunch_profile_a-libbootstrap.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libbootstrap.c' object='liblaunch_profile_a-libbootstrap.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_profile_a_CFLAGS) $(CFLAGS) -c -o liblaunch_profile_a-libbootstrap.obj `if test -f 'libbootstrap.c'; then $(CYGPATH_W) 'libbootstrap.c'; else $(CYGPATH_W) '$(srcdir)/libbootstrap.c'; fi` + +liblaunch_profile_a-protocol_vprocUser.o: protocol_vprocUser.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_profile_a_CFLAGS) $(CFLAGS) -MT liblaunch_profile_a-protocol_vprocUser.o -MD -MP -MF $(DEPDIR)/liblaunch_profile_a-protocol_vprocUser.Tpo -c -o liblaunch_profile_a-protocol_vprocUser.o `test -f 'protocol_vprocUser.c' || echo '$(srcdir)/'`protocol_vprocUser.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/liblaunch_profile_a-protocol_vprocUser.Tpo $(DEPDIR)/liblaunch_profile_a-protocol_vprocUser.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='protocol_vprocUser.c' object='liblaunch_profile_a-protocol_vprocUser.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_profile_a_CFLAGS) $(CFLAGS) -c -o liblaunch_profile_a-protocol_vprocUser.o `test -f 'protocol_vprocUser.c' || echo '$(srcdir)/'`protocol_vprocUser.c + +liblaunch_profile_a-protocol_vprocUser.obj: protocol_vprocUser.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_profile_a_CFLAGS) $(CFLAGS) -MT liblaunch_profile_a-protocol_vprocUser.obj -MD -MP -MF $(DEPDIR)/liblaunch_profile_a-protocol_vprocUser.Tpo -c -o liblaunch_profile_a-protocol_vprocUser.obj `if test -f 'protocol_vprocUser.c'; then $(CYGPATH_W) 'protocol_vprocUser.c'; else $(CYGPATH_W) '$(srcdir)/protocol_vprocUser.c'; fi` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/liblaunch_profile_a-protocol_vprocUser.Tpo $(DEPDIR)/liblaunch_profile_a-protocol_vprocUser.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='protocol_vprocUser.c' object='liblaunch_profile_a-protocol_vprocUser.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_profile_a_CFLAGS) $(CFLAGS) -c -o liblaunch_profile_a-protocol_vprocUser.obj `if test -f 'protocol_vprocUser.c'; then $(CYGPATH_W) 'protocol_vprocUser.c'; else $(CYGPATH_W) '$(srcdir)/protocol_vprocUser.c'; fi` + +liblaunch_profile_a-__version.o: __version.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_profile_a_CFLAGS) $(CFLAGS) -MT liblaunch_profile_a-__version.o -MD -MP -MF $(DEPDIR)/liblaunch_profile_a-__version.Tpo -c -o liblaunch_profile_a-__version.o `test -f '__version.c' || echo '$(srcdir)/'`__version.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/liblaunch_profile_a-__version.Tpo $(DEPDIR)/liblaunch_profile_a-__version.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='__version.c' object='liblaunch_profile_a-__version.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_profile_a_CFLAGS) $(CFLAGS) -c -o liblaunch_profile_a-__version.o `test -f '__version.c' || echo '$(srcdir)/'`__version.c + +liblaunch_profile_a-__version.obj: __version.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_profile_a_CFLAGS) $(CFLAGS) -MT liblaunch_profile_a-__version.obj -MD -MP -MF $(DEPDIR)/liblaunch_profile_a-__version.Tpo -c -o liblaunch_profile_a-__version.obj `if test -f '__version.c'; then $(CYGPATH_W) '__version.c'; else $(CYGPATH_W) '$(srcdir)/__version.c'; fi` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/liblaunch_profile_a-__version.Tpo $(DEPDIR)/liblaunch_profile_a-__version.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='__version.c' object='liblaunch_profile_a-__version.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblaunch_profile_a_CFLAGS) $(CFLAGS) -c -o liblaunch_profile_a-__version.obj `if test -f '__version.c'; then $(CYGPATH_W) '__version.c'; else $(CYGPATH_W) '$(srcdir)/__version.c'; fi` SystemStarter-StartupItems.o: StartupItems.c -@AMDEP_TRUE@ source='StartupItems.c' object='SystemStarter-StartupItems.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/SystemStarter-StartupItems.Po' tmpdepfile='$(DEPDIR)/SystemStarter-StartupItems.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(SystemStarter_CFLAGS) $(CFLAGS) -c -o SystemStarter-StartupItems.o `test -f 'StartupItems.c' || echo '$(srcdir)/'`StartupItems.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(SystemStarter_CFLAGS) $(CFLAGS) -MT SystemStarter-StartupItems.o -MD -MP -MF $(DEPDIR)/SystemStarter-StartupItems.Tpo -c -o SystemStarter-StartupItems.o `test -f 'StartupItems.c' || echo '$(srcdir)/'`StartupItems.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/SystemStarter-StartupItems.Tpo $(DEPDIR)/SystemStarter-StartupItems.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='StartupItems.c' object='SystemStarter-StartupItems.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(SystemStarter_CFLAGS) $(CFLAGS) -c -o SystemStarter-StartupItems.o `test -f 'StartupItems.c' || echo '$(srcdir)/'`StartupItems.c SystemStarter-StartupItems.obj: StartupItems.c -@AMDEP_TRUE@ source='StartupItems.c' object='SystemStarter-StartupItems.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/SystemStarter-StartupItems.Po' tmpdepfile='$(DEPDIR)/SystemStarter-StartupItems.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(SystemStarter_CFLAGS) $(CFLAGS) -c -o SystemStarter-StartupItems.obj `cygpath -w StartupItems.c` +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(SystemStarter_CFLAGS) $(CFLAGS) -MT SystemStarter-StartupItems.obj -MD -MP -MF $(DEPDIR)/SystemStarter-StartupItems.Tpo -c -o SystemStarter-StartupItems.obj `if test -f 'StartupItems.c'; then $(CYGPATH_W) 'StartupItems.c'; else $(CYGPATH_W) '$(srcdir)/StartupItems.c'; fi` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/SystemStarter-StartupItems.Tpo $(DEPDIR)/SystemStarter-StartupItems.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='StartupItems.c' object='SystemStarter-StartupItems.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(SystemStarter_CFLAGS) $(CFLAGS) -c -o SystemStarter-StartupItems.obj `if test -f 'StartupItems.c'; then $(CYGPATH_W) 'StartupItems.c'; else $(CYGPATH_W) '$(srcdir)/StartupItems.c'; fi` SystemStarter-IPC.o: IPC.c -@AMDEP_TRUE@ source='IPC.c' object='SystemStarter-IPC.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/SystemStarter-IPC.Po' tmpdepfile='$(DEPDIR)/SystemStarter-IPC.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(SystemStarter_CFLAGS) $(CFLAGS) -c -o SystemStarter-IPC.o `test -f 'IPC.c' || echo '$(srcdir)/'`IPC.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(SystemStarter_CFLAGS) $(CFLAGS) -MT SystemStarter-IPC.o -MD -MP -MF $(DEPDIR)/SystemStarter-IPC.Tpo -c -o SystemStarter-IPC.o `test -f 'IPC.c' || echo '$(srcdir)/'`IPC.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/SystemStarter-IPC.Tpo $(DEPDIR)/SystemStarter-IPC.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='IPC.c' object='SystemStarter-IPC.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(SystemStarter_CFLAGS) $(CFLAGS) -c -o SystemStarter-IPC.o `test -f 'IPC.c' || echo '$(srcdir)/'`IPC.c SystemStarter-IPC.obj: IPC.c -@AMDEP_TRUE@ source='IPC.c' object='SystemStarter-IPC.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/SystemStarter-IPC.Po' tmpdepfile='$(DEPDIR)/SystemStarter-IPC.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(SystemStarter_CFLAGS) $(CFLAGS) -c -o SystemStarter-IPC.obj `cygpath -w IPC.c` +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(SystemStarter_CFLAGS) $(CFLAGS) -MT SystemStarter-IPC.obj -MD -MP -MF $(DEPDIR)/SystemStarter-IPC.Tpo -c -o SystemStarter-IPC.obj `if test -f 'IPC.c'; then $(CYGPATH_W) 'IPC.c'; else $(CYGPATH_W) '$(srcdir)/IPC.c'; fi` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/SystemStarter-IPC.Tpo $(DEPDIR)/SystemStarter-IPC.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='IPC.c' object='SystemStarter-IPC.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(SystemStarter_CFLAGS) $(CFLAGS) -c -o SystemStarter-IPC.obj `if test -f 'IPC.c'; then $(CYGPATH_W) 'IPC.c'; else $(CYGPATH_W) '$(srcdir)/IPC.c'; fi` SystemStarter-SystemStarter.o: SystemStarter.c -@AMDEP_TRUE@ source='SystemStarter.c' object='SystemStarter-SystemStarter.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/SystemStarter-SystemStarter.Po' tmpdepfile='$(DEPDIR)/SystemStarter-SystemStarter.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(SystemStarter_CFLAGS) $(CFLAGS) -c -o SystemStarter-SystemStarter.o `test -f 'SystemStarter.c' || echo '$(srcdir)/'`SystemStarter.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(SystemStarter_CFLAGS) $(CFLAGS) -MT SystemStarter-SystemStarter.o -MD -MP -MF $(DEPDIR)/SystemStarter-SystemStarter.Tpo -c -o SystemStarter-SystemStarter.o `test -f 'SystemStarter.c' || echo '$(srcdir)/'`SystemStarter.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/SystemStarter-SystemStarter.Tpo $(DEPDIR)/SystemStarter-SystemStarter.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='SystemStarter.c' object='SystemStarter-SystemStarter.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(SystemStarter_CFLAGS) $(CFLAGS) -c -o SystemStarter-SystemStarter.o `test -f 'SystemStarter.c' || echo '$(srcdir)/'`SystemStarter.c SystemStarter-SystemStarter.obj: SystemStarter.c -@AMDEP_TRUE@ source='SystemStarter.c' object='SystemStarter-SystemStarter.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/SystemStarter-SystemStarter.Po' tmpdepfile='$(DEPDIR)/SystemStarter-SystemStarter.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(SystemStarter_CFLAGS) $(CFLAGS) -c -o SystemStarter-SystemStarter.obj `cygpath -w SystemStarter.c` +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(SystemStarter_CFLAGS) $(CFLAGS) -MT SystemStarter-SystemStarter.obj -MD -MP -MF $(DEPDIR)/SystemStarter-SystemStarter.Tpo -c -o SystemStarter-SystemStarter.obj `if test -f 'SystemStarter.c'; then $(CYGPATH_W) 'SystemStarter.c'; else $(CYGPATH_W) '$(srcdir)/SystemStarter.c'; fi` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/SystemStarter-SystemStarter.Tpo $(DEPDIR)/SystemStarter-SystemStarter.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='SystemStarter.c' object='SystemStarter-SystemStarter.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(SystemStarter_CFLAGS) $(CFLAGS) -c -o SystemStarter-SystemStarter.obj `if test -f 'SystemStarter.c'; then $(CYGPATH_W) 'SystemStarter.c'; else $(CYGPATH_W) '$(srcdir)/SystemStarter.c'; fi` launchctl-launchctl.o: launchctl.c -@AMDEP_TRUE@ source='launchctl.c' object='launchctl-launchctl.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/launchctl-launchctl.Po' tmpdepfile='$(DEPDIR)/launchctl-launchctl.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchctl_CFLAGS) $(CFLAGS) -c -o launchctl-launchctl.o `test -f 'launchctl.c' || echo '$(srcdir)/'`launchctl.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchctl_CFLAGS) $(CFLAGS) -MT launchctl-launchctl.o -MD -MP -MF $(DEPDIR)/launchctl-launchctl.Tpo -c -o launchctl-launchctl.o `test -f 'launchctl.c' || echo '$(srcdir)/'`launchctl.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/launchctl-launchctl.Tpo $(DEPDIR)/launchctl-launchctl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='launchctl.c' object='launchctl-launchctl.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchctl_CFLAGS) $(CFLAGS) -c -o launchctl-launchctl.o `test -f 'launchctl.c' || echo '$(srcdir)/'`launchctl.c launchctl-launchctl.obj: launchctl.c -@AMDEP_TRUE@ source='launchctl.c' object='launchctl-launchctl.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/launchctl-launchctl.Po' tmpdepfile='$(DEPDIR)/launchctl-launchctl.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchctl_CFLAGS) $(CFLAGS) -c -o launchctl-launchctl.obj `cygpath -w launchctl.c` +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchctl_CFLAGS) $(CFLAGS) -MT launchctl-launchctl.obj -MD -MP -MF $(DEPDIR)/launchctl-launchctl.Tpo -c -o launchctl-launchctl.obj `if test -f 'launchctl.c'; then $(CYGPATH_W) 'launchctl.c'; else $(CYGPATH_W) '$(srcdir)/launchctl.c'; fi` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/launchctl-launchctl.Tpo $(DEPDIR)/launchctl-launchctl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='launchctl.c' object='launchctl-launchctl.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchctl_CFLAGS) $(CFLAGS) -c -o launchctl-launchctl.obj `if test -f 'launchctl.c'; then $(CYGPATH_W) 'launchctl.c'; else $(CYGPATH_W) '$(srcdir)/launchctl.c'; fi` launchd-launchd.o: launchd.c -@AMDEP_TRUE@ source='launchd.c' object='launchd-launchd.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/launchd-launchd.Po' tmpdepfile='$(DEPDIR)/launchd-launchd.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-launchd.o `test -f 'launchd.c' || echo '$(srcdir)/'`launchd.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -MT launchd-launchd.o -MD -MP -MF $(DEPDIR)/launchd-launchd.Tpo -c -o launchd-launchd.o `test -f 'launchd.c' || echo '$(srcdir)/'`launchd.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/launchd-launchd.Tpo $(DEPDIR)/launchd-launchd.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='launchd.c' object='launchd-launchd.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-launchd.o `test -f 'launchd.c' || echo '$(srcdir)/'`launchd.c launchd-launchd.obj: launchd.c -@AMDEP_TRUE@ source='launchd.c' object='launchd-launchd.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/launchd-launchd.Po' tmpdepfile='$(DEPDIR)/launchd-launchd.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-launchd.obj `cygpath -w launchd.c` +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -MT launchd-launchd.obj -MD -MP -MF $(DEPDIR)/launchd-launchd.Tpo -c -o launchd-launchd.obj `if test -f 'launchd.c'; then $(CYGPATH_W) 'launchd.c'; else $(CYGPATH_W) '$(srcdir)/launchd.c'; fi` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/launchd-launchd.Tpo $(DEPDIR)/launchd-launchd.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='launchd.c' object='launchd-launchd.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-launchd.obj `if test -f 'launchd.c'; then $(CYGPATH_W) 'launchd.c'; else $(CYGPATH_W) '$(srcdir)/launchd.c'; fi` launchd-launchd_core_logic.o: launchd_core_logic.c -@AMDEP_TRUE@ source='launchd_core_logic.c' object='launchd-launchd_core_logic.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/launchd-launchd_core_logic.Po' tmpdepfile='$(DEPDIR)/launchd-launchd_core_logic.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-launchd_core_logic.o `test -f 'launchd_core_logic.c' || echo '$(srcdir)/'`launchd_core_logic.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -MT launchd-launchd_core_logic.o -MD -MP -MF $(DEPDIR)/launchd-launchd_core_logic.Tpo -c -o launchd-launchd_core_logic.o `test -f 'launchd_core_logic.c' || echo '$(srcdir)/'`launchd_core_logic.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/launchd-launchd_core_logic.Tpo $(DEPDIR)/launchd-launchd_core_logic.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='launchd_core_logic.c' object='launchd-launchd_core_logic.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-launchd_core_logic.o `test -f 'launchd_core_logic.c' || echo '$(srcdir)/'`launchd_core_logic.c launchd-launchd_core_logic.obj: launchd_core_logic.c -@AMDEP_TRUE@ source='launchd_core_logic.c' object='launchd-launchd_core_logic.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/launchd-launchd_core_logic.Po' tmpdepfile='$(DEPDIR)/launchd-launchd_core_logic.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-launchd_core_logic.obj `cygpath -w launchd_core_logic.c` +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -MT launchd-launchd_core_logic.obj -MD -MP -MF $(DEPDIR)/launchd-launchd_core_logic.Tpo -c -o launchd-launchd_core_logic.obj `if test -f 'launchd_core_logic.c'; then $(CYGPATH_W) 'launchd_core_logic.c'; else $(CYGPATH_W) '$(srcdir)/launchd_core_logic.c'; fi` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/launchd-launchd_core_logic.Tpo $(DEPDIR)/launchd-launchd_core_logic.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='launchd_core_logic.c' object='launchd-launchd_core_logic.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-launchd_core_logic.obj `if test -f 'launchd_core_logic.c'; then $(CYGPATH_W) 'launchd_core_logic.c'; else $(CYGPATH_W) '$(srcdir)/launchd_core_logic.c'; fi` launchd-launchd_unix_ipc.o: launchd_unix_ipc.c -@AMDEP_TRUE@ source='launchd_unix_ipc.c' object='launchd-launchd_unix_ipc.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/launchd-launchd_unix_ipc.Po' tmpdepfile='$(DEPDIR)/launchd-launchd_unix_ipc.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-launchd_unix_ipc.o `test -f 'launchd_unix_ipc.c' || echo '$(srcdir)/'`launchd_unix_ipc.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -MT launchd-launchd_unix_ipc.o -MD -MP -MF $(DEPDIR)/launchd-launchd_unix_ipc.Tpo -c -o launchd-launchd_unix_ipc.o `test -f 'launchd_unix_ipc.c' || echo '$(srcdir)/'`launchd_unix_ipc.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/launchd-launchd_unix_ipc.Tpo $(DEPDIR)/launchd-launchd_unix_ipc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='launchd_unix_ipc.c' object='launchd-launchd_unix_ipc.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-launchd_unix_ipc.o `test -f 'launchd_unix_ipc.c' || echo '$(srcdir)/'`launchd_unix_ipc.c launchd-launchd_unix_ipc.obj: launchd_unix_ipc.c -@AMDEP_TRUE@ source='launchd_unix_ipc.c' object='launchd-launchd_unix_ipc.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/launchd-launchd_unix_ipc.Po' tmpdepfile='$(DEPDIR)/launchd-launchd_unix_ipc.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-launchd_unix_ipc.obj `cygpath -w launchd_unix_ipc.c` - -launchd-launchd_mach_ipc.o: launchd_mach_ipc.c -@AMDEP_TRUE@ source='launchd_mach_ipc.c' object='launchd-launchd_mach_ipc.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/launchd-launchd_mach_ipc.Po' tmpdepfile='$(DEPDIR)/launchd-launchd_mach_ipc.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-launchd_mach_ipc.o `test -f 'launchd_mach_ipc.c' || echo '$(srcdir)/'`launchd_mach_ipc.c - -launchd-launchd_mach_ipc.obj: launchd_mach_ipc.c -@AMDEP_TRUE@ source='launchd_mach_ipc.c' object='launchd-launchd_mach_ipc.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/launchd-launchd_mach_ipc.Po' tmpdepfile='$(DEPDIR)/launchd-launchd_mach_ipc.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-launchd_mach_ipc.obj `cygpath -w launchd_mach_ipc.c` - -launchd-init.o: init.c -@AMDEP_TRUE@ source='init.c' object='launchd-init.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/launchd-init.Po' tmpdepfile='$(DEPDIR)/launchd-init.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-init.o `test -f 'init.c' || echo '$(srcdir)/'`init.c - -launchd-init.obj: init.c -@AMDEP_TRUE@ source='init.c' object='launchd-init.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/launchd-init.Po' tmpdepfile='$(DEPDIR)/launchd-init.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-init.obj `cygpath -w init.c` - -launchd-bootstrapServer.o: bootstrapServer.c -@AMDEP_TRUE@ source='bootstrapServer.c' object='launchd-bootstrapServer.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/launchd-bootstrapServer.Po' tmpdepfile='$(DEPDIR)/launchd-bootstrapServer.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-bootstrapServer.o `test -f 'bootstrapServer.c' || echo '$(srcdir)/'`bootstrapServer.c - -launchd-bootstrapServer.obj: bootstrapServer.c -@AMDEP_TRUE@ source='bootstrapServer.c' object='launchd-bootstrapServer.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/launchd-bootstrapServer.Po' tmpdepfile='$(DEPDIR)/launchd-bootstrapServer.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-bootstrapServer.obj `cygpath -w bootstrapServer.c` +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -MT launchd-launchd_unix_ipc.obj -MD -MP -MF $(DEPDIR)/launchd-launchd_unix_ipc.Tpo -c -o launchd-launchd_unix_ipc.obj `if test -f 'launchd_unix_ipc.c'; then $(CYGPATH_W) 'launchd_unix_ipc.c'; else $(CYGPATH_W) '$(srcdir)/launchd_unix_ipc.c'; fi` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/launchd-launchd_unix_ipc.Tpo $(DEPDIR)/launchd-launchd_unix_ipc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='launchd_unix_ipc.c' object='launchd-launchd_unix_ipc.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-launchd_unix_ipc.obj `if test -f 'launchd_unix_ipc.c'; then $(CYGPATH_W) 'launchd_unix_ipc.c'; else $(CYGPATH_W) '$(srcdir)/launchd_unix_ipc.c'; fi` + +launchd-protocol_vprocServer.o: protocol_vprocServer.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -MT launchd-protocol_vprocServer.o -MD -MP -MF $(DEPDIR)/launchd-protocol_vprocServer.Tpo -c -o launchd-protocol_vprocServer.o `test -f 'protocol_vprocServer.c' || echo '$(srcdir)/'`protocol_vprocServer.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/launchd-protocol_vprocServer.Tpo $(DEPDIR)/launchd-protocol_vprocServer.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='protocol_vprocServer.c' object='launchd-protocol_vprocServer.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-protocol_vprocServer.o `test -f 'protocol_vprocServer.c' || echo '$(srcdir)/'`protocol_vprocServer.c + +launchd-protocol_vprocServer.obj: protocol_vprocServer.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -MT launchd-protocol_vprocServer.obj -MD -MP -MF $(DEPDIR)/launchd-protocol_vprocServer.Tpo -c -o launchd-protocol_vprocServer.obj `if test -f 'protocol_vprocServer.c'; then $(CYGPATH_W) 'protocol_vprocServer.c'; else $(CYGPATH_W) '$(srcdir)/protocol_vprocServer.c'; fi` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/launchd-protocol_vprocServer.Tpo $(DEPDIR)/launchd-protocol_vprocServer.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='protocol_vprocServer.c' object='launchd-protocol_vprocServer.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-protocol_vprocServer.obj `if test -f 'protocol_vprocServer.c'; then $(CYGPATH_W) 'protocol_vprocServer.c'; else $(CYGPATH_W) '$(srcdir)/protocol_vprocServer.c'; fi` launchd-notifyServer.o: notifyServer.c -@AMDEP_TRUE@ source='notifyServer.c' object='launchd-notifyServer.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/launchd-notifyServer.Po' tmpdepfile='$(DEPDIR)/launchd-notifyServer.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-notifyServer.o `test -f 'notifyServer.c' || echo '$(srcdir)/'`notifyServer.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -MT launchd-notifyServer.o -MD -MP -MF $(DEPDIR)/launchd-notifyServer.Tpo -c -o launchd-notifyServer.o `test -f 'notifyServer.c' || echo '$(srcdir)/'`notifyServer.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/launchd-notifyServer.Tpo $(DEPDIR)/launchd-notifyServer.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='notifyServer.c' object='launchd-notifyServer.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-notifyServer.o `test -f 'notifyServer.c' || echo '$(srcdir)/'`notifyServer.c launchd-notifyServer.obj: notifyServer.c -@AMDEP_TRUE@ source='notifyServer.c' object='launchd-notifyServer.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/launchd-notifyServer.Po' tmpdepfile='$(DEPDIR)/launchd-notifyServer.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-notifyServer.obj `cygpath -w notifyServer.c` +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -MT launchd-notifyServer.obj -MD -MP -MF $(DEPDIR)/launchd-notifyServer.Tpo -c -o launchd-notifyServer.obj `if test -f 'notifyServer.c'; then $(CYGPATH_W) 'notifyServer.c'; else $(CYGPATH_W) '$(srcdir)/notifyServer.c'; fi` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/launchd-notifyServer.Tpo $(DEPDIR)/launchd-notifyServer.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='notifyServer.c' object='launchd-notifyServer.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-notifyServer.obj `if test -f 'notifyServer.c'; then $(CYGPATH_W) 'notifyServer.c'; else $(CYGPATH_W) '$(srcdir)/notifyServer.c'; fi` launchd-launchd_internalUser.o: launchd_internalUser.c -@AMDEP_TRUE@ source='launchd_internalUser.c' object='launchd-launchd_internalUser.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/launchd-launchd_internalUser.Po' tmpdepfile='$(DEPDIR)/launchd-launchd_internalUser.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-launchd_internalUser.o `test -f 'launchd_internalUser.c' || echo '$(srcdir)/'`launchd_internalUser.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -MT launchd-launchd_internalUser.o -MD -MP -MF $(DEPDIR)/launchd-launchd_internalUser.Tpo -c -o launchd-launchd_internalUser.o `test -f 'launchd_internalUser.c' || echo '$(srcdir)/'`launchd_internalUser.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/launchd-launchd_internalUser.Tpo $(DEPDIR)/launchd-launchd_internalUser.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='launchd_internalUser.c' object='launchd-launchd_internalUser.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-launchd_internalUser.o `test -f 'launchd_internalUser.c' || echo '$(srcdir)/'`launchd_internalUser.c launchd-launchd_internalUser.obj: launchd_internalUser.c -@AMDEP_TRUE@ source='launchd_internalUser.c' object='launchd-launchd_internalUser.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/launchd-launchd_internalUser.Po' tmpdepfile='$(DEPDIR)/launchd-launchd_internalUser.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-launchd_internalUser.obj `cygpath -w launchd_internalUser.c` +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -MT launchd-launchd_internalUser.obj -MD -MP -MF $(DEPDIR)/launchd-launchd_internalUser.Tpo -c -o launchd-launchd_internalUser.obj `if test -f 'launchd_internalUser.c'; then $(CYGPATH_W) 'launchd_internalUser.c'; else $(CYGPATH_W) '$(srcdir)/launchd_internalUser.c'; fi` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/launchd-launchd_internalUser.Tpo $(DEPDIR)/launchd-launchd_internalUser.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='launchd_internalUser.c' object='launchd-launchd_internalUser.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-launchd_internalUser.obj `if test -f 'launchd_internalUser.c'; then $(CYGPATH_W) 'launchd_internalUser.c'; else $(CYGPATH_W) '$(srcdir)/launchd_internalUser.c'; fi` launchd-launchd_internalServer.o: launchd_internalServer.c -@AMDEP_TRUE@ source='launchd_internalServer.c' object='launchd-launchd_internalServer.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/launchd-launchd_internalServer.Po' tmpdepfile='$(DEPDIR)/launchd-launchd_internalServer.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-launchd_internalServer.o `test -f 'launchd_internalServer.c' || echo '$(srcdir)/'`launchd_internalServer.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -MT launchd-launchd_internalServer.o -MD -MP -MF $(DEPDIR)/launchd-launchd_internalServer.Tpo -c -o launchd-launchd_internalServer.o `test -f 'launchd_internalServer.c' || echo '$(srcdir)/'`launchd_internalServer.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/launchd-launchd_internalServer.Tpo $(DEPDIR)/launchd-launchd_internalServer.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='launchd_internalServer.c' object='launchd-launchd_internalServer.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-launchd_internalServer.o `test -f 'launchd_internalServer.c' || echo '$(srcdir)/'`launchd_internalServer.c launchd-launchd_internalServer.obj: launchd_internalServer.c -@AMDEP_TRUE@ source='launchd_internalServer.c' object='launchd-launchd_internalServer.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/launchd-launchd_internalServer.Po' tmpdepfile='$(DEPDIR)/launchd-launchd_internalServer.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-launchd_internalServer.obj `cygpath -w launchd_internalServer.c` - -launchd-mpm_replyUser.o: mpm_replyUser.c -@AMDEP_TRUE@ source='mpm_replyUser.c' object='launchd-mpm_replyUser.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/launchd-mpm_replyUser.Po' tmpdepfile='$(DEPDIR)/launchd-mpm_replyUser.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-mpm_replyUser.o `test -f 'mpm_replyUser.c' || echo '$(srcdir)/'`mpm_replyUser.c - -launchd-mpm_replyUser.obj: mpm_replyUser.c -@AMDEP_TRUE@ source='mpm_replyUser.c' object='launchd-mpm_replyUser.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@ depfile='$(DEPDIR)/launchd-mpm_replyUser.Po' tmpdepfile='$(DEPDIR)/launchd-mpm_replyUser.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-mpm_replyUser.obj `cygpath -w mpm_replyUser.c` -CCDEPMODE = @CCDEPMODE@ -uninstall-info-am: - -man1dir = $(mandir)/man1 +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -MT launchd-launchd_internalServer.obj -MD -MP -MF $(DEPDIR)/launchd-launchd_internalServer.Tpo -c -o launchd-launchd_internalServer.obj `if test -f 'launchd_internalServer.c'; then $(CYGPATH_W) 'launchd_internalServer.c'; else $(CYGPATH_W) '$(srcdir)/launchd_internalServer.c'; fi` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/launchd-launchd_internalServer.Tpo $(DEPDIR)/launchd-launchd_internalServer.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='launchd_internalServer.c' object='launchd-launchd_internalServer.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-launchd_internalServer.obj `if test -f 'launchd_internalServer.c'; then $(CYGPATH_W) 'launchd_internalServer.c'; else $(CYGPATH_W) '$(srcdir)/launchd_internalServer.c'; fi` + +launchd-job_replyUser.o: job_replyUser.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -MT launchd-job_replyUser.o -MD -MP -MF $(DEPDIR)/launchd-job_replyUser.Tpo -c -o launchd-job_replyUser.o `test -f 'job_replyUser.c' || echo '$(srcdir)/'`job_replyUser.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/launchd-job_replyUser.Tpo $(DEPDIR)/launchd-job_replyUser.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='job_replyUser.c' object='launchd-job_replyUser.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-job_replyUser.o `test -f 'job_replyUser.c' || echo '$(srcdir)/'`job_replyUser.c + +launchd-job_replyUser.obj: job_replyUser.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -MT launchd-job_replyUser.obj -MD -MP -MF $(DEPDIR)/launchd-job_replyUser.Tpo -c -o launchd-job_replyUser.obj `if test -f 'job_replyUser.c'; then $(CYGPATH_W) 'job_replyUser.c'; else $(CYGPATH_W) '$(srcdir)/job_replyUser.c'; fi` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/launchd-job_replyUser.Tpo $(DEPDIR)/launchd-job_replyUser.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='job_replyUser.c' object='launchd-job_replyUser.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-job_replyUser.obj `if test -f 'job_replyUser.c'; then $(CYGPATH_W) 'job_replyUser.c'; else $(CYGPATH_W) '$(srcdir)/job_replyUser.c'; fi` + +launchd-launchd_runtime.o: launchd_runtime.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -MT launchd-launchd_runtime.o -MD -MP -MF $(DEPDIR)/launchd-launchd_runtime.Tpo -c -o launchd-launchd_runtime.o `test -f 'launchd_runtime.c' || echo '$(srcdir)/'`launchd_runtime.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/launchd-launchd_runtime.Tpo $(DEPDIR)/launchd-launchd_runtime.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='launchd_runtime.c' object='launchd-launchd_runtime.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-launchd_runtime.o `test -f 'launchd_runtime.c' || echo '$(srcdir)/'`launchd_runtime.c + +launchd-launchd_runtime.obj: launchd_runtime.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -MT launchd-launchd_runtime.obj -MD -MP -MF $(DEPDIR)/launchd-launchd_runtime.Tpo -c -o launchd-launchd_runtime.obj `if test -f 'launchd_runtime.c'; then $(CYGPATH_W) 'launchd_runtime.c'; else $(CYGPATH_W) '$(srcdir)/launchd_runtime.c'; fi` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/launchd-launchd_runtime.Tpo $(DEPDIR)/launchd-launchd_runtime.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='launchd_runtime.c' object='launchd-launchd_runtime.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-launchd_runtime.obj `if test -f 'launchd_runtime.c'; then $(CYGPATH_W) 'launchd_runtime.c'; else $(CYGPATH_W) '$(srcdir)/launchd_runtime.c'; fi` + +launchd-launchd_runtime_kill.o: launchd_runtime_kill.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -MT launchd-launchd_runtime_kill.o -MD -MP -MF $(DEPDIR)/launchd-launchd_runtime_kill.Tpo -c -o launchd-launchd_runtime_kill.o `test -f 'launchd_runtime_kill.c' || echo '$(srcdir)/'`launchd_runtime_kill.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/launchd-launchd_runtime_kill.Tpo $(DEPDIR)/launchd-launchd_runtime_kill.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='launchd_runtime_kill.c' object='launchd-launchd_runtime_kill.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-launchd_runtime_kill.o `test -f 'launchd_runtime_kill.c' || echo '$(srcdir)/'`launchd_runtime_kill.c + +launchd-launchd_runtime_kill.obj: launchd_runtime_kill.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -MT launchd-launchd_runtime_kill.obj -MD -MP -MF $(DEPDIR)/launchd-launchd_runtime_kill.Tpo -c -o launchd-launchd_runtime_kill.obj `if test -f 'launchd_runtime_kill.c'; then $(CYGPATH_W) 'launchd_runtime_kill.c'; else $(CYGPATH_W) '$(srcdir)/launchd_runtime_kill.c'; fi` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/launchd-launchd_runtime_kill.Tpo $(DEPDIR)/launchd-launchd_runtime_kill.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='launchd_runtime_kill.c' object='launchd-launchd_runtime_kill.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(launchd_CFLAGS) $(CFLAGS) -c -o launchd-launchd_runtime_kill.obj `if test -f 'launchd_runtime_kill.c'; then $(CYGPATH_W) 'launchd_runtime_kill.c'; else $(CYGPATH_W) '$(srcdir)/launchd_runtime_kill.c'; fi` install-man1: $(man1_MANS) $(man_MANS) @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(man1dir) + test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)" @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ for i in $$l2; do \ @@ -639,8 +808,8 @@ install-man1: $(man1_MANS) $(man_MANS) inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ inst=`echo $$inst | sed -e 's/^.*\///'`; \ inst=`echo $$inst | sed '$(transform)'`.$$ext; \ - echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst"; \ - $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst; \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst"; \ done uninstall-man1: @$(NORMAL_UNINSTALL) @@ -653,17 +822,19 @@ uninstall-man1: done; \ for i in $$list; do \ ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + case "$$ext" in \ + 1*) ;; \ + *) ext='1' ;; \ + esac; \ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ inst=`echo $$inst | sed -e 's/^.*\///'`; \ inst=`echo $$inst | sed '$(transform)'`.$$ext; \ - echo " rm -f $(DESTDIR)$(man1dir)/$$inst"; \ - rm -f $(DESTDIR)$(man1dir)/$$inst; \ + echo " rm -f '$(DESTDIR)$(man1dir)/$$inst'"; \ + rm -f "$(DESTDIR)$(man1dir)/$$inst"; \ done - -man5dir = $(mandir)/man5 install-man5: $(man5_MANS) $(man_MANS) @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(man5dir) + test -z "$(man5dir)" || $(MKDIR_P) "$(DESTDIR)$(man5dir)" @list='$(man5_MANS) $(dist_man5_MANS) $(nodist_man5_MANS)'; \ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ for i in $$l2; do \ @@ -682,8 +853,8 @@ install-man5: $(man5_MANS) $(man_MANS) inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ inst=`echo $$inst | sed -e 's/^.*\///'`; \ inst=`echo $$inst | sed '$(transform)'`.$$ext; \ - echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man5dir)/$$inst"; \ - $(INSTALL_DATA) $$file $(DESTDIR)$(man5dir)/$$inst; \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst"; \ done uninstall-man5: @$(NORMAL_UNINSTALL) @@ -696,17 +867,19 @@ uninstall-man5: done; \ for i in $$list; do \ ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + case "$$ext" in \ + 5*) ;; \ + *) ext='5' ;; \ + esac; \ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ inst=`echo $$inst | sed -e 's/^.*\///'`; \ inst=`echo $$inst | sed '$(transform)'`.$$ext; \ - echo " rm -f $(DESTDIR)$(man5dir)/$$inst"; \ - rm -f $(DESTDIR)$(man5dir)/$$inst; \ + echo " rm -f '$(DESTDIR)$(man5dir)/$$inst'"; \ + rm -f "$(DESTDIR)$(man5dir)/$$inst"; \ done - -man8dir = $(mandir)/man8 install-man8: $(man8_MANS) $(man_MANS) @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(man8dir) + test -z "$(man8dir)" || $(MKDIR_P) "$(DESTDIR)$(man8dir)" @list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ for i in $$l2; do \ @@ -725,8 +898,8 @@ install-man8: $(man8_MANS) $(man_MANS) inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ inst=`echo $$inst | sed -e 's/^.*\///'`; \ inst=`echo $$inst | sed '$(transform)'`.$$ext; \ - echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst"; \ - $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst; \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst"; \ done uninstall-man8: @$(NORMAL_UNINSTALL) @@ -739,36 +912,34 @@ uninstall-man8: done; \ for i in $$list; do \ ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + case "$$ext" in \ + 8*) ;; \ + *) ext='8' ;; \ + esac; \ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ inst=`echo $$inst | sed -e 's/^.*\///'`; \ inst=`echo $$inst | sed '$(transform)'`.$$ext; \ - echo " rm -f $(DESTDIR)$(man8dir)/$$inst"; \ - rm -f $(DESTDIR)$(man8dir)/$$inst; \ + echo " rm -f '$(DESTDIR)$(man8dir)/$$inst'"; \ + rm -f "$(DESTDIR)$(man8dir)/$$inst"; \ done -sysconfDATA_INSTALL = $(INSTALL_DATA) install-sysconfDATA: $(sysconf_DATA) @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(sysconfdir) + test -z "$(sysconfdir)" || $(MKDIR_P) "$(DESTDIR)$(sysconfdir)" @list='$(sysconf_DATA)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - f="`echo $$p | sed -e 's|^.*/||'`"; \ - echo " $(sysconfDATA_INSTALL) $$d$$p $(DESTDIR)$(sysconfdir)/$$f"; \ - $(sysconfDATA_INSTALL) $$d$$p $(DESTDIR)$(sysconfdir)/$$f; \ + f=$(am__strip_dir) \ + echo " $(sysconfDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(sysconfdir)/$$f'"; \ + $(sysconfDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(sysconfdir)/$$f"; \ done uninstall-sysconfDATA: @$(NORMAL_UNINSTALL) @list='$(sysconf_DATA)'; for p in $$list; do \ - f="`echo $$p | sed -e 's|^.*/||'`"; \ - echo " rm -f $(DESTDIR)$(sysconfdir)/$$f"; \ - rm -f $(DESTDIR)$(sysconfdir)/$$f; \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(sysconfdir)/$$f'"; \ + rm -f "$(DESTDIR)$(sysconfdir)/$$f"; \ done -ETAGS = etags -ETAGSFLAGS = - -tags: TAGS - ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ @@ -777,6 +948,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique +tags: TAGS TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) @@ -788,8 +960,24 @@ TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ - test -z "$(ETAGS_ARGS)$$tags$$unique" \ - || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: @@ -798,23 +986,24 @@ GTAGS: && gtags -i $(GTAGS_ARGS) $$here distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) - -top_distdir = .. -distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) - @list='$(DISTFILES)'; for file in $$list; do \ + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test "$$dir" != "$$file" && test "$$dir" != "."; then \ - dir="/$$dir"; \ - $(mkinstalldirs) "$(distdir)$$dir"; \ - else \ - dir=''; \ - fi; \ if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ @@ -827,12 +1016,11 @@ distdir: $(DISTFILES) done check-am: all-am check: check-am -all-am: Makefile $(LIBRARIES) $(PROGRAMS) $(SCRIPTS) $(MANS) $(DATA) \ - config.h - +all-am: Makefile $(LIBRARIES) $(PROGRAMS) $(MANS) $(DATA) config.h installdirs: - $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(libexecdir) $(DESTDIR)$(sbindir) $(DESTDIR)$(sbindir) $(DESTDIR)$(man1dir) $(DESTDIR)$(man5dir) $(DESTDIR)$(man8dir) $(DESTDIR)$(sysconfdir) - + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(sysconfdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done install: install-am install-exec: install-exec-am install-data: install-data-am @@ -844,7 +1032,7 @@ install-am: all-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - INSTALL_STRIP_FLAG=-s \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: @@ -853,7 +1041,7 @@ clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: - -rm -f Makefile $(CONFIG_CLEAN_FILES) + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @@ -864,14 +1052,17 @@ clean-am: clean-binPROGRAMS clean-generic clean-libexecPROGRAMS \ clean-noinstLIBRARIES clean-sbinPROGRAMS mostlyclean-am distclean: distclean-am - -distclean-am: clean-am distclean-compile distclean-depend \ - distclean-generic distclean-hdr distclean-tags + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-hdr distclean-tags dvi: dvi-am dvi-am: +html: html-am + info: info-am info-am: @@ -880,51 +1071,76 @@ install-data-am: install-man @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-data-hook +install-dvi: install-dvi-am + install-exec-am: install-binPROGRAMS install-libexecPROGRAMS \ - install-sbinPROGRAMS install-sbinSCRIPTS install-sysconfDATA + install-sbinPROGRAMS install-sysconfDATA + +install-html: install-html-am install-info: install-info-am install-man: install-man1 install-man5 install-man8 +install-pdf: install-pdf-am + +install-ps: install-ps-am + installcheck-am: maintainer-clean: maintainer-clean-am - + -rm -rf ./$(DEPDIR) + -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic -uninstall-am: uninstall-binPROGRAMS uninstall-info-am \ - uninstall-libexecPROGRAMS uninstall-man uninstall-sbinPROGRAMS \ - uninstall-sbinSCRIPTS uninstall-sysconfDATA +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-libexecPROGRAMS \ + uninstall-man uninstall-sbinPROGRAMS uninstall-sysconfDATA uninstall-man: uninstall-man1 uninstall-man5 uninstall-man8 -.PHONY: GTAGS all all-am check check-am clean clean-binPROGRAMS \ +.MAKE: install-am install-data-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ clean-generic clean-libexecPROGRAMS clean-noinstLIBRARIES \ - clean-sbinPROGRAMS distclean distclean-compile distclean-depend \ + clean-sbinPROGRAMS ctags distclean distclean-compile \ distclean-generic distclean-hdr distclean-tags distdir dvi \ - dvi-am info info-am install install-am install-binPROGRAMS \ - install-data install-data-am install-exec install-exec-am \ - install-info install-info-am install-libexecPROGRAMS \ - install-man install-man1 install-man5 install-man8 \ - install-sbinPROGRAMS install-sbinSCRIPTS install-strip \ - install-sysconfDATA installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic tags uninstall \ - uninstall-am uninstall-binPROGRAMS uninstall-info-am \ + dvi-am html html-am info info-am install install-am \ + install-binPROGRAMS install-data install-data-am \ + install-data-hook install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-libexecPROGRAMS install-man \ + install-man1 install-man5 install-man8 install-pdf \ + install-pdf-am install-ps install-ps-am install-sbinPROGRAMS \ + install-strip install-sysconfDATA installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ + ps ps-am tags uninstall uninstall-am uninstall-binPROGRAMS \ uninstall-libexecPROGRAMS uninstall-man uninstall-man1 \ uninstall-man5 uninstall-man8 uninstall-sbinPROGRAMS \ - uninstall-sbinSCRIPTS uninstall-sysconfDATA + uninstall-sysconfDATA + + +protocol_vproc.h protocol_vprocServer.c protocol_vprocUser.c protocol_vprocServer.h: $(srcdir)/protocol_job.defs + mig $(MIGFLAGS) -sheader protocol_vprocServer.h $(srcdir)/protocol_job.defs +@LIBS_ONLY_TRUE@$(srcdir)/libvproc.c:: protocol_vproc.h -bootstrap.h bootstrapServer.c bootstrapUser.c bootstrapServer.h: $(srcdir)/bootstrap.defs - mig $(MIGFLAGS) -sheader bootstrapServer.h $(srcdir)/bootstrap.defs +@LIBS_ONLY_TRUE@$(srcdir)/protocol_vprocUser.c:: protocol_vproc.h -@LIBS_ONLY_TRUE@bootstrap_public.c:: bootstrap.h +@LIBS_ONLY_TRUE@__version.c: +@LIBS_ONLY_TRUE@ /Developer/Makefiles/bin/version.pl launchd_libs > $@ @LIBS_ONLY_TRUE@install-data-hook: @LIBS_ONLY_TRUE@ mkdir -p $(DESTDIR)/usr/local/lib/system @@ -932,42 +1148,39 @@ bootstrap.h bootstrapServer.c bootstrapUser.c bootstrapServer.h: $(srcdir)/boots @LIBS_ONLY_TRUE@ cp liblaunch.a $(DESTDIR)/usr/local/lib/system/liblaunch_debug.a @LIBS_ONLY_TRUE@ cp liblaunch_profile.a $(DESTDIR)/usr/local/lib/system/liblaunch_profile.a -@LIBS_ONLY_FALSE@launchd_mach_ipc.c:: bootstrap.h bootstrapServer.h notifyServer.h launchd_internal.h -@LIBS_ONLY_FALSE@launchd_core_logic.c:: bootstrap.h mpm_reply.h -@LIBS_ONLY_FALSE@launchd.c:: bootstrap.h launchd_internalServer.h launchd_internal.h notifyServer.h bootstrapServer.h +@LIBS_ONLY_FALSE@launchd_runtime.c:: notifyServer.h launchd_internal.h +@LIBS_ONLY_FALSE@launchd_core_logic.c:: protocol_vproc.h job_reply.h protocol_vprocServer.h @LIBS_ONLY_FALSE@notifyServer.c notifyServer.h: /usr/include/mach/notify.defs @LIBS_ONLY_FALSE@ mig $(MIGFLAGS) -header /dev/null -user /dev/null -sheader notifyServer.h /usr/include/mach/notify.defs -@LIBS_ONLY_FALSE@mpm_replyUser.c mpm_reply.h: $(srcdir)/mpm_reply.defs -@LIBS_ONLY_FALSE@ mig $(MIGFLAGS) -sheader /dev/null -server /dev/null $(srcdir)/mpm_reply.defs +@LIBS_ONLY_FALSE@job_replyUser.c job_reply.h: $(srcdir)/protocol_job_reply.defs +@LIBS_ONLY_FALSE@ mig $(MIGFLAGS) -sheader /dev/null -server /dev/null $(srcdir)/protocol_job_reply.defs @LIBS_ONLY_FALSE@launchd_internal.h launchd_internalServer.c launchd_internalUser.c launchd_internalServer.h: $(srcdir)/launchd_internal.defs @LIBS_ONLY_FALSE@ mig $(MIGFLAGS) -sheader launchd_internalServer.h $(srcdir)/launchd_internal.defs -@LIBS_ONLY_FALSE@$(addprefix $(DESTDIR)/System/Library/StartupItems/, $(STARTUPITEMS)): -@LIBS_ONLY_FALSE@ mkdir -p $@ -@LIBS_ONLY_FALSE@ cp $(srcdir)/StartupItems/$(notdir $@) $@ -@LIBS_ONLY_FALSE@ chmod 755 $@/$(notdir $@) -@LIBS_ONLY_FALSE@ cp $(srcdir)/StartupItems/$(notdir $@).plist $@/StartupParameters.plist - -@LIBS_ONLY_FALSE@install-startupitems: $(addprefix $(DESTDIR)/System/Library/StartupItems/, $(STARTUPITEMS)) - -@LIBS_ONLY_FALSE@install-data-hook: install-startupitems +@LIBS_ONLY_FALSE@install-data-hook: @LIBS_ONLY_FALSE@ mkdir -p $(DESTDIR)/usr/libexec -@LIBS_ONLY_FALSE@ cp $(srcdir)/StartupItemContext $(DESTDIR)/usr/libexec @LIBS_ONLY_FALSE@ mkdir -p $(DESTDIR)/usr/include/servers -@LIBS_ONLY_FALSE@ cp $(srcdir)/launch.h $(DESTDIR)/usr/include -@LIBS_ONLY_FALSE@ cp $(srcdir)/bootstrap_public.h $(DESTDIR)/usr/include/servers/bootstrap.h -@LIBS_ONLY_FALSE@ cp $(srcdir)/bootstrap_public.h $(DESTDIR)/usr/include/servers/bootstrap_defs.h @LIBS_ONLY_FALSE@ mkdir -p $(DESTDIR)/usr/local/include -@LIBS_ONLY_FALSE@ cp $(srcdir)/launch_priv.h $(DESTDIR)/usr/local/include @LIBS_ONLY_FALSE@ mkdir -p $(DESTDIR)/$(sysconfdir)/mach_init.d @LIBS_ONLY_FALSE@ mkdir -p $(DESTDIR)/$(sysconfdir)/mach_init_per_user.d +@LIBS_ONLY_FALSE@ mkdir -p $(DESTDIR)/$(sysconfdir)/mach_init_per_login_session.d @LIBS_ONLY_FALSE@ mkdir -p $(DESTDIR)/Library/LaunchDaemons @LIBS_ONLY_FALSE@ mkdir -p $(DESTDIR)/Library/LaunchAgents -@LIBS_ONLY_FALSE@ mkdir -p $(DESTDIR)/System/Library/LaunchDaemons @LIBS_ONLY_FALSE@ mkdir -p $(DESTDIR)/System/Library/LaunchAgents +@LIBS_ONLY_FALSE@ mkdir -p $(DESTDIR)/System/Library/LaunchDaemons +@LIBS_ONLY_FALSE@ cp $(srcdir)/StartupItemContext $(DESTDIR)/usr/libexec +@LIBS_ONLY_FALSE@ cp $(srcdir)/liblaunch_public.h $(DESTDIR)/usr/include/launch.h +@LIBS_ONLY_FALSE@ cp $(srcdir)/libvproc_public.h $(DESTDIR)/usr/include/vproc.h +@LIBS_ONLY_FALSE@ cp $(srcdir)/libbootstrap_public.h $(DESTDIR)/usr/include/servers/bootstrap.h +@LIBS_ONLY_FALSE@ cp $(srcdir)/libbootstrap_public.h $(DESTDIR)/usr/include/servers/bootstrap_defs.h +@LIBS_ONLY_FALSE@ cp $(srcdir)/libbootstrap_private.h $(DESTDIR)/usr/local/include/bootstrap_priv.h +@LIBS_ONLY_FALSE@ cp $(srcdir)/liblaunch_private.h $(DESTDIR)/usr/local/include/launch_priv.h +@LIBS_ONLY_FALSE@ cp $(srcdir)/libvproc_private.h $(DESTDIR)/usr/local/include/vproc_priv.h +@LIBS_ONLY_FALSE@ cp $(srcdir)/reboot2.h $(DESTDIR)/usr/local/include/reboot2.h +@LIBS_ONLY_FALSE@ cp $(srcdir)/com.apple.SystemStarter.plist $(DESTDIR)/System/Library/LaunchDaemons # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/launchd/src/StartupItemContext b/launchd/src/StartupItemContext index 502cd14..15d0d35 100755 --- a/launchd/src/StartupItemContext +++ b/launchd/src/StartupItemContext @@ -2,4 +2,4 @@ unset LAUNCHD_SOCKET -exec launchctl bsexec / $@ +exec launchctl bsexec / "$@" diff --git a/launchd/src/StartupItems.c b/launchd/src/StartupItems.c index 7dff051..3fbd269 100644 --- a/launchd/src/StartupItems.c +++ b/launchd/src/StartupItems.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -158,6 +159,8 @@ static void SpecialCasesStartupItemHandler(CFMutableDictionaryRef aConfig) CFSTR("Core Services"), CFSTR("Network"), CFSTR("TIM"), + CFSTR("Disks"), + CFSTR("NIS"), NULL }; CFMutableArrayRef aList, aNewList; @@ -215,21 +218,45 @@ CFIndex StartupItemListCountServices(CFArrayRef anItemList) static bool StartupItemSecurityCheck(const char *aPath) { + static struct timeval boot_time; struct stat aStatBuf; bool r = true; + if (boot_time.tv_sec == 0) { + int mib[] = { CTL_KERN, KERN_BOOTTIME }; + size_t boot_time_sz = sizeof(boot_time); + int rv; + + rv = sysctl(mib, sizeof(mib) / sizeof(mib[0]), &boot_time, &boot_time_sz, NULL, 0); + + assert(rv != -1); + assert(boot_time_sz == sizeof(boot_time)); + } + /* should use lstatx_np() on Tiger? */ if (lstat(aPath, &aStatBuf) == -1) { if (errno != ENOENT) syslog(LOG_ERR, "lstat(\"%s\"): %m", aPath); return false; } + /* + * We check the boot time because of 5409386. + * We ignore the boot time if PPID != 1 because of 5503536. + */ + if ((aStatBuf.st_ctimespec.tv_sec > boot_time.tv_sec) && (getppid() == 1)) { + syslog(LOG_WARNING, "\"%s\" failed sanity check: path was created after boot up", aPath); + return false; + } if (!(S_ISREG(aStatBuf.st_mode) || S_ISDIR(aStatBuf.st_mode))) { syslog(LOG_WARNING, "\"%s\" failed security check: not a directory or regular file", aPath); r = false; } - if ((aStatBuf.st_mode & ALLPERMS) & ~(S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { - syslog(LOG_WARNING, "\"%s\" failed security check: permissions", aPath); + if (aStatBuf.st_mode & S_IWOTH) { + syslog(LOG_WARNING, "\"%s\" failed security check: world writable", aPath); + r = false; + } + if (aStatBuf.st_mode & S_IWGRP) { + syslog(LOG_WARNING, "\"%s\" failed security check: group writable", aPath); r = false; } if (aStatBuf.st_uid != 0) { @@ -262,6 +289,12 @@ CFMutableArrayRef StartupItemListCreateWithMask(NSSearchPathDomainMask aMask) strcpy(aPath + strlen(aPath), kStartupItemsPath); ++aDomainIndex; + /* 5485016 + * + * Just in case... + */ + mkdir(aPath, S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH); + if (!StartupItemSecurityCheck(aPath)) continue; @@ -959,7 +992,6 @@ int StartupItemRun(CFMutableDictionaryRef aStatusDict, CFMutableDictionaryRef an case 0: /* Child */ { - setpriority(PRIO_PROCESS, 0, 0); if (setsid() == -1) syslog(LOG_WARNING, "Unable to create session for item %s: %m", anExecutable); diff --git a/launchd/src/StartupItems/AppleShare b/launchd/src/StartupItems/AppleShare deleted file mode 100644 index 429e6be..0000000 --- a/launchd/src/StartupItems/AppleShare +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/sh - -## -# Apple File Protocol -## - -[ -f /System/Library/LaunchDaemons/com.apple.AppleFileServer.plist ] && exit 0 - -. /etc/rc.common - -StartService () -{ - if [ "${AFPSERVER:=-NO-}" = "-YES-" ]; then - echo "Starting Apple File Service" - /usr/sbin/AppleFileServer - fi -} - -StopService () -{ - return 0 -} - -RestartService () -{ - return 0 -} - -RunService "$1" diff --git a/launchd/src/StartupItems/AppleShare.plist b/launchd/src/StartupItems/AppleShare.plist deleted file mode 100644 index 4dda863..0000000 --- a/launchd/src/StartupItems/AppleShare.plist +++ /dev/null @@ -1,5 +0,0 @@ -{ - Description = "Apple File Service"; - Provides = ("Apple File Service"); - Requires = ("Disks"); -} diff --git a/launchd/src/StartupItems/Disks b/launchd/src/StartupItems/Disks deleted file mode 100644 index 86c00e3..0000000 --- a/launchd/src/StartupItems/Disks +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/sh - -## -# Local filesystems -## - -. /etc/rc.common - -StartService () -{ - if [ ! -f /var/db/volinfo.database ]; then Uninitialized_VSDB=-YES-; fi - - echo "Checking disks" - /sbin/autodiskmount -va - - if [ "${Uninitialized_VSDB:=-NO-}" = "-YES-" ]; then - if [ -x /usr/sbin/vsdbutil ]; then - /usr/sbin/vsdbutil -i - fi - fi -} - -StopService () -{ - return 0; -} - -RestartService () -{ - return 0; -} - -RunService "$1" diff --git a/launchd/src/StartupItems/Disks.plist b/launchd/src/StartupItems/Disks.plist deleted file mode 100644 index d4046b0..0000000 --- a/launchd/src/StartupItems/Disks.plist +++ /dev/null @@ -1,6 +0,0 @@ -{ - Description = "local disks"; - Provides = ("Disks"); - Uses = ("System Tuning"); - Requires = ("SecurityServer"); -} diff --git a/launchd/src/StartupItems/IPServices b/launchd/src/StartupItems/IPServices deleted file mode 100644 index 658aafe..0000000 --- a/launchd/src/StartupItems/IPServices +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/sh - -## -# IP Services -## - -[ -f /System/Library/LaunchDaemons/com.apache.httpd.plist ] && exit 0 - -. /etc/rc.common - -StartService () -{ - if [ -a /etc/com.apple.named.conf.proxy ] - then - echo "Starting Internet address sharing" - /usr/libexec/InternetSharing - fi -} - -StopService () -{ - return 0 -} - -RestartService () -{ - return 0 -} - -RunService "$1" diff --git a/launchd/src/StartupItems/IPServices.plist b/launchd/src/StartupItems/IPServices.plist deleted file mode 100644 index ffb68b0..0000000 --- a/launchd/src/StartupItems/IPServices.plist +++ /dev/null @@ -1,5 +0,0 @@ -{ - Description = "Internet services"; - Provides = ("Super Server", "Config Server"); - Uses = ("mDNSResponder", "Portmap"); -} diff --git a/launchd/src/StartupItems/NIS b/launchd/src/StartupItems/NIS deleted file mode 100644 index 9eaddb9..0000000 --- a/launchd/src/StartupItems/NIS +++ /dev/null @@ -1,79 +0,0 @@ -#!/bin/sh - -## -# Network Information Service -## - -. /etc/rc.common - - -Startyppasswdd() -{ - # rpc.yppasswdd is run on NIS masters - if [ -f "${VARYP}/${NISDOMAIN}/ypservers.db" ]; then - NISMASTER=$(makedbm -U "${VARYP}/${NISDOMAIN}/ypservers" | sed -n '/YP_MASTER_NAME/p' | awk '{print $2}') - if [ "$NISMASTER" = "$(hostname)" ]; then - rpc.yppasswdd - fi - fi -} - -StartService () -{ - ## - # Network Information Service. - ## - CheckForNetwork - if [ -f /var/run/NIS.StartupItem -o "${NETWORKUP}" = "-NO-" ]; then exit; fi - touch /var/run/NIS.StartupItem - - if [ "${NISDOMAIN:=-NO-}" != "-NO-" ]; then - - VARYP=/var/yp - - echo "Starting Network Information Service" - - echo "Setting NIS domainname to ${NISDOMAIN}" - domainname "${NISDOMAIN}" - - # ypserv is run on NIS servers - machines with an ${VARYP}/${NISDOMAIN} dir - if [ -d "${VARYP}/${NISDOMAIN}" ]; then - if ! pid=$(GetPID ypserv); then - ypserv - fi - fi - - Startyppasswdd - - # ypbind is run on all NIS clients - ypbind - fi -} - -StopService () -{ - echo "Stopping Network Information Service" - killall -TERM ypbind > /dev/null 2>&1 - killall -TERM rpc.yppasswdd > /dev/null 2>&1 - - if pid=$(GetPID ypserv); then - kill -TERM "${pid}" - fi -} - -RestartService () -{ - echo "Restarting Network Information Service" - killall -TERM ypbind > /dev/null 2>&1 - killall -TERM rpc.yppasswdd > /dev/null 2>&1 - - if pid=$(GetPID ypserv); then - kill -HUP "${pid}" - Startyppasswdd - ypbind - else - StartService - fi -} - -RunService "$1" diff --git a/launchd/src/StartupItems/NIS.plist b/launchd/src/StartupItems/NIS.plist deleted file mode 100644 index 9c7ba6f..0000000 --- a/launchd/src/StartupItems/NIS.plist +++ /dev/null @@ -1,4 +0,0 @@ -{ - Description = "Network Information Service"; - Provides = ("NIS"); -} diff --git a/launchd/src/SystemStarter.c b/launchd/src/SystemStarter.c index 0e8ea54..5c445cc 100644 --- a/launchd/src/SystemStarter.c +++ b/launchd/src/SystemStarter.c @@ -22,10 +22,16 @@ * @APPLE_APACHE_LICENSE_HEADER_END@ **/ +#include +#include +#include +#include +#include #include #include #include #include +#include #include #include #include "IPC.h" @@ -40,14 +46,24 @@ bool gNoRunFlag = false; static void usage(void) __attribute__((noreturn)); static int system_starter(Action anAction, const char *aService); static void displayErrorMessages(StartupContext aStartupContext); -static void doCFnote(void); +static pid_t fwexec(const char *cmd, ...) __attribute__((sentinel)); +static void dummy_sig(int signo __attribute__((unused))) +{ +} int main(int argc, char *argv[]) { + struct kevent kev; Action anAction = kActionStart; - char *aService = NULL; - int ch; + int ch, r, kq = kqueue(); + + assert(kq != -1); + + EV_SET(&kev, SIGTERM, EVFILT_SIGNAL, EV_ADD, 0, 0, 0); + r = kevent(kq, &kev, 1, NULL, 0, NULL); + assert(r != -1); + signal(SIGTERM, dummy_sig); while ((ch = getopt(argc, argv, "gvxirdDqn?")) != -1) { switch (ch) { @@ -75,15 +91,18 @@ main(int argc, char *argv[]) argc -= optind; argv += optind; - if (argc > 2) + if (argc > 2) { usage(); + } openlog(getprogname(), LOG_PID|LOG_CONS|(gDebugFlag ? LOG_PERROR : 0), LOG_DAEMON); - setlogmask(LOG_UPTO(LOG_NOTICE)); - if (gVerboseFlag) - setlogmask(LOG_UPTO(LOG_INFO)); - if (gDebugFlag) + if (gDebugFlag) { setlogmask(LOG_UPTO(LOG_DEBUG)); + } else if (gVerboseFlag) { + setlogmask(LOG_UPTO(LOG_INFO)); + } else { + setlogmask(LOG_UPTO(LOG_NOTICE)); + } if (!gNoRunFlag && (getuid() != 0)) { syslog(LOG_ERR, "must be root to run"); @@ -102,52 +121,54 @@ main(int argc, char *argv[]) } } - atexit(doCFnote); + if (argc == 2) { + exit(system_starter(anAction, argv[1])); + } unlink(kFixerPath); - if (argc == 2) { - aService = argv[1]; - } else if (!gDebugFlag && anAction != kActionStop) { - pid_t ipwa; - int status; - - setpriority(PRIO_PROCESS, 0, 20); - - /* Too many old StartupItems had implicit dependancies on - * "Network" via other StartupItems that are now no-ops. - * - * SystemStarter is not on the critical path for boot up, - * so we'll stall here to deal with this legacy dependancy - * problem. - */ - switch ((ipwa = fork())) { - case -1: - syslog(LOG_WARNING, "fork(): %m"); - break; - case 0: - execl("/usr/sbin/ipconfig", "ipconfig", "waitall", NULL); - syslog(LOG_WARNING, "execl(): %m"); - exit(EXIT_FAILURE); - default: - if (waitpid(ipwa, &status, 0) == -1) { - syslog(LOG_WARNING, "waitpid(): %m"); - break; - } else if (WIFEXITED(status)) { - if (WEXITSTATUS(status) == 0) { - break; - } else { - syslog(LOG_WARNING, "ipconfig waitall exit status: %d", WEXITSTATUS(status)); - } - } else { - /* must have died due to signal */ - syslog(LOG_WARNING, "ipconfig waitall: %s", strsignal(WTERMSIG(status))); - } - break; - } + mach_timespec_t w = { 600, 0 }; + kern_return_t kr; + struct stat sb; + + /* + * Too many old StartupItems had implicit dependancies on "Network" via + * other StartupItems that are now no-ops. + * + * SystemStarter is not on the critical path for boot up, so we'll + * stall here to deal with this legacy dependancy problem. + */ + + if ((kr = IOKitWaitQuiet(kIOMasterPortDefault, &w)) != kIOReturnSuccess) { + syslog(LOG_NOTICE, "IOKitWaitQuiet: %d\n", kr); } - exit(system_starter(anAction, aService)); + fwexec("/usr/sbin/ipconfig", "waitall", NULL); + fwexec("/sbin/autodiskmount", "-va", NULL); + + system_starter(kActionStart, NULL); + + if (stat("/etc/rc.local", &sb) != -1) { + fwexec(_PATH_BSHELL, "/etc/rc.local", NULL); + } + + CFNotificationCenterPostNotificationWithOptions( + CFNotificationCenterGetDistributedCenter(), + CFSTR("com.apple.startupitems.completed"), + NULL, NULL, + kCFNotificationDeliverImmediately | kCFNotificationPostToAllSessions); + + r = kevent(kq, NULL, 0, &kev, 1, NULL); + assert(r != -1); + assert(kev.filter == EVFILT_SIGNAL && kev.ident == SIGTERM); + + if (stat("/etc/rc.shutdown.local", &sb) != -1) { + fwexec(_PATH_BSHELL, "/etc/rc.shutdown.local", NULL); + } + + system_starter(kActionStop, NULL); + + exit(EXIT_SUCCESS); } @@ -237,7 +258,6 @@ displayErrorMessages(StartupContext aStartupContext) static int system_starter(Action anAction, const char *aService_cstr) { - CFRunLoopSourceRef anIPCSource = NULL; CFStringRef aService = NULL; NSSearchPathDomainMask aMask; @@ -252,18 +272,6 @@ system_starter(Action anAction, const char *aService_cstr) if (gDebugFlag && gNoRunFlag) sleep(1); - /** - * Create the IPC port - **/ - anIPCSource = CreateIPCRunLoopSource(CFSTR(kSystemStarterMessagePort), aStartupContext); - if (anIPCSource) { - CFRunLoopAddSource(CFRunLoopGetCurrent(), anIPCSource, kCFRunLoopCommonModes); - CFRelease(anIPCSource); - } else { - syslog(LOG_ERR, "Could not create IPC bootstrap port: %s", kSystemStarterMessagePort); - return (1); - } - /** * Get a list of Startup Items which are in /Local and /System. * We can't search /Network yet because the network isn't up. @@ -388,11 +396,42 @@ usage(void) exit(EXIT_FAILURE); } -static void doCFnote(void) +pid_t +fwexec(const char *cmd, ...) { - CFNotificationCenterPostNotificationWithOptions( - CFNotificationCenterGetDistributedCenter(), - CFSTR("com.apple.startupitems.completed"), - NULL, NULL, - kCFNotificationDeliverImmediately | kCFNotificationPostToAllSessions); + const char *argv[100] = { cmd }; + va_list ap; + int wstatus, i = 1; + pid_t p; + + va_start(ap, cmd); + do { + argv[i] = va_arg(ap, char *); + } while (argv[i++]); + va_end(ap); + + switch ((p = fork())) { + case -1: + return -1; + case 0: + execvp(argv[0], (char *const *)argv); + _exit(EXIT_FAILURE); + break; + default: + if (waitpid(p, &wstatus, 0) == -1) { + return -1; + } else if (WIFEXITED(wstatus)) { + if (WEXITSTATUS(wstatus) == 0) { + return 0; + } else { + syslog(LOG_WARNING, "%s exit status: %d", argv[0], WEXITSTATUS(wstatus)); + } + } else { + /* must have died due to signal */ + syslog(LOG_WARNING, "%s died: %s", argv[0], strsignal(WTERMSIG(wstatus))); + } + break; + } + + return -1; } diff --git a/launchd/src/bootstrap_private.h b/launchd/src/bootstrap_private.h deleted file mode 100644 index a2dace1..0000000 --- a/launchd/src/bootstrap_private.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef _BOOTSTRAP_PRIVATE_H_ -#define _BOOTSTRAP_PRIVATE_H_ -/* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_APACHE_LICENSE_HEADER_START@ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * @APPLE_APACHE_LICENSE_HEADER_END@ - */ - -typedef char *_internal_string_t; -#define SPAWN_HAS_PATH 0x0001 -#define SPAWN_HAS_WDIR 0x0002 -#define SPAWN_HAS_UMASK 0x0004 -#define SPAWN_WANTS_WAIT4DEBUGGER 0x0008 -#define SPAWN_WANTS_FORCE_PPC 0x0010 - -kern_return_t -_launchd_to_launchd(mach_port_t bp, mach_port_t *reqport, mach_port_t *rcvright, - name_array_t *service_names, mach_msg_type_number_t *service_namesCnt, - mach_port_array_t *ports, mach_msg_type_number_t *portCnt); - -kern_return_t bootstrap_getsocket(mach_port_t bp, name_t); - - -kern_return_t -bootstrap_look_up_array( - mach_port_t bp, - name_array_t service_names, - mach_msg_type_number_t service_namesCnt, - mach_port_array_t *sps, - mach_msg_type_number_t *service_portsCnt, - boolean_t *all_services_known); - -kern_return_t -bootstrap_info( - mach_port_t bp, - name_array_t *service_names, - mach_msg_type_number_t *service_namesCnt, - bootstrap_status_array_t *service_active, - mach_msg_type_number_t *service_activeCnt); - -#endif diff --git a/launchd/src/bootstrap_public.c b/launchd/src/bootstrap_public.c deleted file mode 100644 index 1845ed6..0000000 --- a/launchd/src/bootstrap_public.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Copyright (c) 1999-2005 Apple Computer, Inc. All rights reserved. - * - * @APPLE_APACHE_LICENSE_HEADER_START@ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * @APPLE_APACHE_LICENSE_HEADER_END@ - */ - -#include -#include - -#include "bootstrap_public.h" -#include "bootstrap_private.h" -#include "launch.h" -#include "launch_priv.h" - -#define mig_external static -#include "bootstrap.h" -#include "bootstrapUser.c" - -#include -#include -#include - -kern_return_t -_launchd_to_launchd(mach_port_t bp, mach_port_t *reqport, mach_port_t *rcvright, - name_array_t *service_names, mach_msg_type_number_t *service_namesCnt, - mach_port_array_t *ports, mach_msg_type_number_t *portCnt) -{ - return raw_bootstrap_transfer_subset(bp, reqport, rcvright, service_names, service_namesCnt, ports, portCnt); -} - -pid_t -_spawn_via_launchd(const char *label, const char *const *argv, const struct spawn_via_launchd_attr *spawn_attrs, int struct_version) -{ - kern_return_t kr; - const char *const *tmpp; - size_t len, buf_len = strlen(label) + 1; - char *buf = strdup(label); - uint64_t flags = 0; - uint32_t argc = 0; - uint32_t envc = 0; - pid_t p = -1; - mode_t u_mask = CMASK; - mach_port_t obsvr_port = MACH_PORT_NULL; - - for (tmpp = argv; *tmpp; tmpp++) { - argc++; - len = strlen(*tmpp) + 1; - buf = reallocf(buf, buf_len + len); - strcpy(buf + buf_len, *tmpp); - buf_len += len; - } - - if (spawn_attrs) switch (struct_version) { - case 0: - if (spawn_attrs->spawn_flags & SPAWN_VIA_LAUNCHD_STOPPED) { - flags |= SPAWN_WANTS_WAIT4DEBUGGER; - } - if (spawn_attrs->spawn_flags & SPAWN_VIA_LAUNCHD_FORCE_PPC) { - flags |= SPAWN_WANTS_FORCE_PPC; - } - - if (spawn_attrs->spawn_env) { - for (tmpp = spawn_attrs->spawn_env; *tmpp; tmpp++) { - envc++; - len = strlen(*tmpp) + 1; - buf = reallocf(buf, buf_len + len); - strcpy(buf + buf_len, *tmpp); - buf_len += len; - } - } - - if (spawn_attrs->spawn_path) { - flags |= SPAWN_HAS_PATH; - len = strlen(spawn_attrs->spawn_path) + 1; - buf = reallocf(buf, buf_len + len); - strcpy(buf + buf_len, spawn_attrs->spawn_path); - buf_len += len; - } - - if (spawn_attrs->spawn_chdir) { - flags |= SPAWN_HAS_WDIR; - len = strlen(spawn_attrs->spawn_chdir) + 1; - buf = reallocf(buf, buf_len + len); - strcpy(buf + buf_len, spawn_attrs->spawn_chdir); - buf_len += len; - } - - if (spawn_attrs->spawn_umask) { - flags |= SPAWN_HAS_UMASK; - u_mask = *spawn_attrs->spawn_umask; - } - - break; - default: - break; - } - - kr = raw_mpm_spawn(bootstrap_port, buf, buf_len, argc, envc, flags, u_mask, &p, &obsvr_port); - - free(buf); - - if (kr == BOOTSTRAP_SUCCESS) { - if (spawn_attrs && spawn_attrs->spawn_observer_port) { - *spawn_attrs->spawn_observer_port = obsvr_port; - } else { - mach_port_deallocate(mach_task_self(), obsvr_port); - } - return p; - } - - switch (kr) { - case BOOTSTRAP_NOT_PRIVILEGED: - errno = EPERM; break; - case BOOTSTRAP_NO_MEMORY: - errno = ENOMEM; break; - default: - errno = EINVAL; break; - } - return -1; -} - -kern_return_t -mpm_wait(mach_port_t ajob, int *wstatus) -{ - return raw_mpm_wait(ajob, wstatus); -} - -kern_return_t -mpm_uncork_fork(mach_port_t ajob) -{ - return raw_mpm_uncork_fork(ajob); -} - -kern_return_t -bootstrap_create_server(mach_port_t bp, cmd_t server_cmd, uid_t server_uid, boolean_t on_demand, mach_port_t *server_port) -{ - return raw_bootstrap_create_server(bp, server_cmd, server_uid, on_demand, server_port); -} - -kern_return_t -bootstrap_subset(mach_port_t bp, mach_port_t requestor_port, mach_port_t *subset_port) -{ - return raw_bootstrap_subset(bp, requestor_port, subset_port); -} - -kern_return_t -bootstrap_unprivileged(mach_port_t bp, mach_port_t *unpriv_port) -{ - return raw_bootstrap_unprivileged(bp, unpriv_port); -} - -kern_return_t -bootstrap_getsocket(mach_port_t bp, name_t sockpath) -{ - return raw_bootstrap_getsocket(bp, sockpath); -} - -kern_return_t -bootstrap_parent(mach_port_t bp, mach_port_t *parent_port) -{ - return raw_bootstrap_parent(bp, parent_port); -} - -kern_return_t -bootstrap_register(mach_port_t bp, name_t service_name, mach_port_t sp) -{ - return raw_bootstrap_register(bp, service_name, sp); -} - -kern_return_t -bootstrap_create_service(mach_port_t bp, name_t service_name, mach_port_t *sp) -{ - return raw_bootstrap_create_service(bp, service_name, sp); -} - -kern_return_t -bootstrap_check_in(mach_port_t bp, name_t service_name, mach_port_t *sp) -{ - return raw_bootstrap_check_in(bp, service_name, sp); -} - -kern_return_t -bootstrap_look_up(mach_port_t bp, name_t service_name, mach_port_t *sp) -{ - return raw_bootstrap_look_up(bp, service_name, sp); -} - -kern_return_t -bootstrap_look_up_array(mach_port_t bp, - name_array_t names, mach_msg_type_number_t name_cnt, - mach_port_array_t *ports, mach_msg_type_number_t *port_cnt, - boolean_t *all) -{ - unsigned int i; - kern_return_t r; - - if (name_cnt > BOOTSTRAP_MAX_LOOKUP_COUNT) - return BOOTSTRAP_BAD_COUNT; - - *port_cnt = name_cnt; - - r = vm_allocate(mach_task_self(), (vm_address_t *)&ports, name_cnt * sizeof(mach_port_t), true); - - if (r != KERN_SUCCESS) - return r; - - *all = true; - - for (i = 0; i < name_cnt; i++) { - if (bootstrap_look_up(bp, names[i], &((*ports)[i])) == BOOTSTRAP_SUCCESS) - continue; - *all = false; - ports[i] = MACH_PORT_NULL; - } - - return BOOTSTRAP_SUCCESS; -} - -kern_return_t -bootstrap_status(mach_port_t bp, name_t service_name, bootstrap_status_t *service_active) -{ - mach_port_t p; - - if (bootstrap_check_in(bp, service_name, &p) == BOOTSTRAP_SUCCESS) { - mach_port_mod_refs(mach_task_self(), p, MACH_PORT_RIGHT_RECEIVE, -1); - *service_active = BOOTSTRAP_STATUS_ON_DEMAND; - if (raw_bootstrap_unprivileged(bp, &p) == BOOTSTRAP_SUCCESS) { - if (bp == p) - *service_active = BOOTSTRAP_STATUS_INACTIVE; - mach_port_deallocate(mach_task_self(), p); - } - return BOOTSTRAP_SUCCESS; - } else if (bootstrap_look_up(bp, service_name, &p) == BOOTSTRAP_SUCCESS) { - mach_port_deallocate(mach_task_self(), p); - *service_active = BOOTSTRAP_STATUS_ACTIVE; - return BOOTSTRAP_SUCCESS; - } - - return BOOTSTRAP_UNKNOWN_SERVICE; -} - -kern_return_t -bootstrap_info(mach_port_t bp, - name_array_t *service_names, mach_msg_type_number_t *service_namesCnt, - bootstrap_status_array_t *service_active, mach_msg_type_number_t *service_activeCnt) -{ - return raw_bootstrap_info(bp, service_names, service_namesCnt, - service_active, service_activeCnt); -} - -const char * -bootstrap_strerror(kern_return_t r) -{ - switch (r) { - case BOOTSTRAP_SUCCESS: - return "Success"; - case BOOTSTRAP_NOT_PRIVILEGED: - return "Permission denied"; - case BOOTSTRAP_NAME_IN_USE: - case BOOTSTRAP_SERVICE_ACTIVE: - return "Service name already exists"; - case BOOTSTRAP_UNKNOWN_SERVICE: - return "Unknown service name"; - case BOOTSTRAP_BAD_COUNT: - return "Too many lookups were requested in one request"; - case BOOTSTRAP_NO_MEMORY: - return "Out of memory"; - default: - return mach_error_string(r); - } -} diff --git a/launchd/src/com.apple.SystemStarter.plist b/launchd/src/com.apple.SystemStarter.plist new file mode 100644 index 0000000..ffac1a3 --- /dev/null +++ b/launchd/src/com.apple.SystemStarter.plist @@ -0,0 +1,27 @@ + + + + + Label + com.apple.SystemStarter + Program + /sbin/SystemStarter + KeepAlive + + PathState + + /etc/rc.local + + /etc/rc.shutdown.local + + + + QueueDirectories + + /Library/StartupItems + /System/Library/StartupItems + + HopefullyExitsFirst + + + diff --git a/launchd/src/init.c b/launchd/src/init.c deleted file mode 100644 index 83be58a..0000000 --- a/launchd/src/init.c +++ /dev/null @@ -1,789 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_APACHE_LICENSE_HEADER_START@ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * @APPLE_APACHE_LICENSE_HEADER_END@ - */ -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Donn Seeley at Berkeley Software Design, Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -static const char *const __rcs_file_version__ = "$Revision: 1.38 $"; - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "launchd.h" - -#define _PATH_RUNCOM "/etc/rc" - -/* - * Sleep times; used to prevent thrashing. - */ -#define GETTY_SPACING 5 /* N secs minimum getty spacing */ -#define GETTY_SLEEP 30 /* sleep N secs after spacing problem */ -#define STALL_TIMEOUT 30 /* wait N secs after warning */ -#define DEATH_WATCH 10 /* wait N secs for procs to die */ -#define FAILED_HW_PASS 5 /* wait N secs before croaking user */ - -static void stall(char *, ...); - -static void single_user_callback(void *, struct kevent *); -static kq_callback kqsingle_user_callback = single_user_callback; -static void runcom_callback(void *, struct kevent *); -static kq_callback kqruncom_callback = runcom_callback; - -static void single_user(void); -static void runcom(void); - -static bool runcom_safe = false; -static bool runcom_netboot = false; -static bool single_user_mode = false; -static bool run_runcom = true; -static pid_t single_user_pid = 0; -static pid_t runcom_pid = 0; - -static void setctty(const char *, int); - -// gvdl@next.com 14 Aug 1995 -// - from ~apps/loginwindow_proj/loginwindow/common.h -#define REALLY_EXIT_TO_CONSOLE 229 - -// From old init.c -// These flags are used in the se_flags field of the init_session structure -#define SE_SHUTDOWN 0x1 /* session won't be restarted */ - -// The flags below control what sort of getty is launched. -#define SE_GETTY_LAUNCH 0x30 /* What type of getty to launch */ -#define SE_COMMON 0x00 /* Usual command that is run - getty */ -#define SE_ONERROR 0x10 /* Command to run if error condition occurs. - * This will almost always be the windowserver - * and loginwindow. This is so if the w.s. - * ever dies, that the naive user (stan) - * doesn't ever see the console window. */ -#define SE_ONOPTION 0x20 /* Command to run when loginwindow exits with - * special error code (229). This signifies - * that the user typed "console" at l.w. and - * l.w. wants to exit and have init run getty - * which will then put up a console window. */ - -typedef struct _se_command { - char *path; /* what to run on that port */ - char **argv; /* pre-parsed argument array */ -} se_cmd_t; - -typedef struct init_session { - kq_callback se_callback; /* run loop callback */ - int se_index; /* index of entry in ttys file */ - pid_t se_process; /* controlling process */ - time_t se_started; /* used to avoid thrashing */ - int se_flags; /* status of session */ - char *se_device; /* filename of port */ - se_cmd_t se_getty; /* what to run on that port */ - se_cmd_t se_onerror; /* See SE_ONERROR above */ - se_cmd_t se_onoption; /* See SE_ONOPTION above */ - TAILQ_ENTRY(init_session) tqe; -} *session_t; - -static TAILQ_HEAD(sessionshead, init_session) sessions = TAILQ_HEAD_INITIALIZER(sessions); - -static void session_new(int, struct ttyent *); -static void session_free(session_t); -static void session_launch(session_t); -static void session_reap(session_t); -static void session_callback(void *, struct kevent *); - -static char **construct_argv(char *); -static void setsecuritylevel(int); -static int getsecuritylevel(void); -static int setupargv(session_t, struct ttyent *); -static bool should_fsck(void); - -void -init_boot(bool sflag) -{ - int nbmib[2] = { CTL_KERN, KERN_NETBOOT }; - int sbmib[2] = { CTL_KERN, KERN_SAFEBOOT }; - uint32_t v = 0; - size_t vsz = sizeof(v); - - if (sflag) { - single_user_mode = true; - run_runcom = false; - } - - if (launchd_assumes(sysctl(nbmib, 2, &v, &vsz, NULL, 0) != -1)) { - if (v != 0) - runcom_netboot = true; - } - if (launchd_assumes(sysctl(sbmib, 2, &v, &vsz, NULL, 0) != -1)) { - if (v != 0) - runcom_safe = true; - } - -} - -void -init_pre_kevent(void) -{ - session_t s; - - if (single_user_pid || runcom_pid) - return; - - if (single_user_mode) - return single_user(); - - if (run_runcom) - return runcom(); - - /* - * If the administrator has not set the security level to -1 - * to indicate that the kernel should not run multiuser in secure - * mode, and the run script has not set a higher level of security - * than level 1, then put the kernel into secure mode. - */ - if (getsecuritylevel() == 0) - setsecuritylevel(1); - - TAILQ_FOREACH(s, &sessions, tqe) { - if (s->se_process == 0) - session_launch(s); - } -} - -static void -stall(char *message, ...) -{ - va_list ap; - va_start(ap, message); - - vsyslog(LOG_ALERT, message, ap); - va_end(ap); - sleep(STALL_TIMEOUT); -} - -static int -getsecuritylevel(void) -{ - int name[2], curlevel; - size_t len; - - name[0] = CTL_KERN; - name[1] = KERN_SECURELVL; - len = sizeof (curlevel); - if (sysctl(name, 2, &curlevel, &len, NULL, 0) == -1) { - syslog(LOG_ALERT, "cannot get kernel security level: %m"); - return -1; - } - return curlevel; -} - -static void -setsecuritylevel(int newlevel) -{ - int name[2], curlevel; - - curlevel = getsecuritylevel(); - if (newlevel == curlevel) - return; - name[0] = CTL_KERN; - name[1] = KERN_SECURELVL; - if (sysctl(name, 2, NULL, NULL, &newlevel, sizeof newlevel) == -1) { - syslog(LOG_ALERT, "cannot change kernel security level from %d to %d: %m", - curlevel, newlevel); - return; - } - syslog(LOG_INFO, "kernel security level changed from %d to %d", - curlevel, newlevel); -} - -/* - * Start a session and allocate a controlling terminal. - * Only called by children of init after forking. - */ -static void -setctty(const char *name, int flags) -{ - int fd; - - revoke(name); - if ((fd = open(name, flags | O_RDWR)) == -1) { - stall("can't open %s: %m", name); - exit(EXIT_FAILURE); - } - if (login_tty(fd) == -1) { - stall("can't get %s for controlling terminal: %m", name); - exit(EXIT_FAILURE); - } -} - -static void -single_user(void) -{ - bool runcom_fsck = should_fsck(); - char *argv[2]; - - if (getsecuritylevel() > 0) - setsecuritylevel(0); - - if ((single_user_pid = launchd_fork()) == -1) { - syslog(LOG_ERR, "can't fork single-user shell, trying again: %m"); - return; - } else if (single_user_pid == 0) { - setctty(_PATH_CONSOLE, O_POPUP); - - setenv("TERM", "vt100", 1); - setenv("SafeBoot", runcom_safe ? "-x" : "", 1); - setenv("VerboseFlag", "-v", 1); /* single user mode implies verbose mode */ - setenv("FsckSlash", runcom_fsck ? "-F" : "", 1); - setenv("NetBoot", runcom_netboot ? "-N" : "", 1); - - if (runcom_fsck) { - fprintf(stdout, "Singleuser boot -- fsck not done\n"); - fprintf(stdout, "Root device is mounted read-only\n\n"); - fprintf(stdout, "If you want to make modifications to files:\n"); - fprintf(stdout, "\t/sbin/fsck -fy\n\t/sbin/mount -uw /\n\n"); - fprintf(stdout, "If you wish to boot the system:\n"); - fprintf(stdout, "\texit\n\n"); - fflush(stdout); - } - - argv[0] = "-sh"; - argv[1] = NULL; - execv(_PATH_BSHELL, argv); - syslog(LOG_ERR, "can't exec %s for single user: %m", _PATH_BSHELL); - sleep(STALL_TIMEOUT); - exit(EXIT_FAILURE); - } else { - if (kevent_mod(single_user_pid, EVFILT_PROC, EV_ADD, - NOTE_EXIT, 0, &kqsingle_user_callback) == -1) - single_user_callback(NULL, NULL); - } -} - -static void -single_user_callback(void *obj __attribute__((unused)), struct kevent *kev __attribute__((unused))) -{ - int status; - - if (!launchd_assumes(waitpid(single_user_pid, &status, 0) == single_user_pid)) - return; - - if (WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS) { - syslog(LOG_INFO, "single user shell terminated, restarting"); - run_runcom = true; - single_user_mode = false; - } else { - syslog(LOG_INFO, "single user shell terminated."); - run_runcom = false; - if (WTERMSIG(status) != SIGKILL) - single_user_mode = true; - } - - single_user_pid = 0; -} - -static struct timeval runcom_start_tv = { 0, 0 }; -/* - * Run the system startup script. - */ -static void -runcom(void) -{ - bool runcom_fsck = should_fsck(); - char *argv[] = { "/bin/launchctl", "bootstrap", NULL }; - struct termios term; - int vdisable; - - gettimeofday(&runcom_start_tv, NULL); - - if ((runcom_pid = launchd_fork()) == -1) { - syslog(LOG_ERR, "can't fork for %s on %s: %m", _PATH_BSHELL, _PATH_RUNCOM); - sleep(STALL_TIMEOUT); - runcom_pid = 0; - single_user_mode = true; - return; - } else if (runcom_pid > 0) { - run_runcom = false; - if (kevent_mod(runcom_pid, EVFILT_PROC, EV_ADD, - NOTE_EXIT, 0, &kqruncom_callback) == -1) { - runcom_callback(NULL, NULL); - } - return; - } - - setctty(_PATH_CONSOLE, 0); - - if ((vdisable = fpathconf(STDIN_FILENO, _PC_VDISABLE)) == -1) { - syslog(LOG_WARNING, "fpathconf(\"%s\") %m", _PATH_CONSOLE); - } else if (tcgetattr(STDIN_FILENO, &term) == -1) { - syslog(LOG_WARNING, "tcgetattr(\"%s\") %m", _PATH_CONSOLE); - } else { - term.c_cc[VINTR] = vdisable; - term.c_cc[VKILL] = vdisable; - term.c_cc[VQUIT] = vdisable; - term.c_cc[VSUSP] = vdisable; - term.c_cc[VSTART] = vdisable; - term.c_cc[VSTOP] = vdisable; - term.c_cc[VDSUSP] = vdisable; - - if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &term) == -1) - syslog(LOG_WARNING, "tcsetattr(\"%s\") %m", _PATH_CONSOLE); - } - - setenv("SafeBoot", runcom_safe ? "-x" : "", 1); - setenv("FsckSlash", runcom_fsck ? "-F" : "", 1); - setenv("NetBoot", runcom_netboot ? "-N" : "", 1); - - execv(argv[0], argv); - stall("can't exec %s for %s: %m", _PATH_BSHELL, _PATH_RUNCOM); - exit(EXIT_FAILURE); -} - -static void -runcom_callback(void *obj __attribute__((unused)), struct kevent *kev __attribute__((unused))) -{ - int status; - struct timeval runcom_end_tv, runcom_total_tv; - double sec; - - gettimeofday(&runcom_end_tv, NULL); - timersub(&runcom_end_tv, &runcom_start_tv, &runcom_total_tv); - sec = runcom_total_tv.tv_sec; - sec += (double)runcom_total_tv.tv_usec / (double)1000000; - syslog(LOG_INFO, "%s finished in: %.3f seconds", _PATH_RUNCOM, sec); - - if (launchd_assumes(waitpid(runcom_pid, &status, 0) == runcom_pid)) { - runcom_pid = 0; - } else { - syslog(LOG_ERR, "going to single user mode"); - single_user_mode = true; - return; - } - - if (WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS) { - logwtmp("~", "reboot", ""); - return; - } else if (WIFSIGNALED(status) && (WTERMSIG(status) == SIGTERM || WTERMSIG(status) == SIGKILL)) { - return; - } - - syslog(LOG_ERR, "%s on %s terminated abnormally, going to single user mode", - _PATH_BSHELL, _PATH_RUNCOM); - single_user_mode = true; -} - -/* - * Construct an argument vector from a command line. - */ -char ** -construct_argv(command) - char *command; -{ - int argc = 0; - char **argv = (char **) malloc(((strlen(command) + 1) / 2 + 1) - * sizeof (char *)); - static const char separators[] = " \t"; - - if ((argv[argc++] = strtok(command, separators)) == 0) - return 0; - while ((argv[argc++] = strtok(NULL, separators))) - continue; - return argv; -} - -/* - * Deallocate a session descriptor. - */ - -static void free_command(se_cmd_t *se_cmd) -{ - if (se_cmd->path) { - free(se_cmd->path); - free(se_cmd->argv); - } -} - -void -session_free(session_t s) -{ - TAILQ_REMOVE(&sessions, s, tqe); - if (s->se_process) { - if (kevent_mod(s->se_process, EVFILT_PROC, EV_ADD, - NOTE_EXIT, 0, &kqsimple_zombie_reaper) == -1) - session_reap(s); - else - kill(s->se_process, SIGHUP); - } - free(s->se_device); - free_command(&s->se_getty); - free_command(&s->se_onerror); - free_command(&s->se_onoption); - free(s); -} - -static int setup_command(se_cmd_t *se_cmd, char *command, char *arg ) -{ - char *commandWithArg; - - asprintf(&commandWithArg, "%s %s", command, arg); - - free_command(se_cmd); - - se_cmd->path = commandWithArg; - se_cmd->argv = construct_argv(commandWithArg); - if (se_cmd->argv == NULL) { - free(se_cmd->path); - se_cmd->path = NULL; - return 0; - } - return 1; -} - -/* - * Calculate getty and if useful window argv vectors. - */ -static int -setupargv(sp, typ) - session_t sp; - struct ttyent *typ; -{ - char *type; - - if ( !setup_command(&sp->se_getty, typ->ty_getty, typ->ty_name) ) - { - type = "getty"; - goto bad_args; - } - - if (typ->ty_onerror - && !setup_command(&sp->se_onerror, typ->ty_onerror, typ->ty_name) ) - { - type = "onerror"; - goto bad_args; - } - - if (typ->ty_onoption - && !setup_command(&sp->se_onoption, typ->ty_onoption, typ->ty_name) ) - { - type = "onoption"; - goto bad_args; - } - - return 1; - -bad_args: - syslog(LOG_WARNING, "can't parse %s for port %s", type, sp->se_device); - return 0; -} - - -/* - * Allocate a new session descriptor. - */ -void -session_new(session_index, typ) - int session_index; - struct ttyent *typ; -{ - session_t s; - - if ((typ->ty_status & TTY_ON) == 0 || - typ->ty_name == 0 || - typ->ty_getty == 0) - return; - - s = calloc(1, sizeof(struct init_session)); - - s->se_callback = session_callback; - s->se_index = session_index; - - TAILQ_INSERT_TAIL(&sessions, s, tqe); - - asprintf(&s->se_device, "%s%s", _PATH_DEV, typ->ty_name); - - if (setupargv(s, typ) == 0) - session_free(s); -} - -static void -session_launch(session_t s) -{ - pid_t pid; - sigset_t mask; - se_cmd_t *se_cmd; - const char *session_type = NULL; - time_t current_time = time(NULL); - bool is_loginwindow = false; - - // Setup the default values; - switch (s->se_flags & SE_GETTY_LAUNCH) { - case SE_ONOPTION: - if (s->se_onoption.path) { - se_cmd = &s->se_onoption; - session_type = "onoption"; - break; - } - /* No break */ - case SE_ONERROR: - if (s->se_onerror.path) { - se_cmd = &s->se_onerror; - session_type = "onerror"; - break; - } - /* No break */ - case SE_COMMON: - default: - se_cmd = &s->se_getty; - session_type = "getty"; - break; - } - - if (strcmp(se_cmd->argv[0], "/System/Library/CoreServices/loginwindow.app/Contents/MacOS/loginwindow") == 0) - is_loginwindow = true; - - pid = launchd_fork(); - - if (pid == -1) { - syslog(LOG_ERR, "can't fork for %s on port %s: %m", - session_type, s->se_device); - return; - } - - if (pid) { - s->se_process = pid; - s->se_started = time(NULL); - s->se_flags &= ~SE_GETTY_LAUNCH; // clear down getty launch type - if (kevent_mod(pid, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, &s->se_callback) == -1) - session_reap(s); - return; - } - - if (current_time > s->se_started && - current_time - s->se_started < GETTY_SPACING) { - syslog(LOG_WARNING, "%s repeating too quickly on port %s, sleeping", - session_type, s->se_device); - sleep(GETTY_SLEEP); - } - - sigemptyset(&mask); - sigprocmask(SIG_SETMASK, &mask, NULL); - - - if (!is_loginwindow) - launchd_SessionCreate(); - - execv(se_cmd->argv[0], se_cmd->argv); - stall("can't exec %s '%s' for port %s: %m", session_type, - se_cmd->argv[0], s->se_device); - exit(EXIT_FAILURE); -} - -static void -session_callback(void *obj, struct kevent *kev __attribute__((unused))) -{ - session_t s = obj; - - session_reap(s); - if (s->se_flags & SE_SHUTDOWN) { - session_free(s); - } else { - session_launch(s); - } -} - -static void -session_reap(session_t s) -{ - char *line; - int status; - - if (!launchd_assumes(waitpid(s->se_process, &status, 0) == s->se_process)) - return; - - if (WIFSIGNALED(status)) { - syslog(LOG_WARNING, "%s port %s exited abnormally: %s", - s->se_getty.path, s->se_device, strsignal(WTERMSIG(status))); - s->se_flags |= SE_ONERROR; - } else if (WEXITSTATUS(status) == REALLY_EXIT_TO_CONSOLE) { - /* WIFEXITED(status) assumed */ - s->se_flags |= SE_ONOPTION; - } else { - s->se_flags |= SE_ONERROR; - } - - s->se_process = 0; - line = s->se_device + sizeof(_PATH_DEV) - 1; - - if (logout(line)) - logwtmp(line, "", ""); -} - -/* - * This is an n-squared algorithm. We hope it isn't run often... - */ -void -update_ttys(void) -{ - session_t sp; - struct ttyent *typ; - int session_index = 0; - int devlen; - - devlen = sizeof(_PATH_DEV) - 1; - while ((typ = getttyent())) { - ++session_index; - - TAILQ_FOREACH(sp, &sessions, tqe) { - if (strcmp(typ->ty_name, sp->se_device + devlen) == 0) - break; - } - - if (sp == NULL) { - session_new(session_index, typ); - continue; - } - - if (sp->se_index != session_index) { - syslog(LOG_INFO, "port %s changed utmp index from %d to %d", - sp->se_device, sp->se_index, - session_index); - sp->se_index = session_index; - } - - if ((typ->ty_status & TTY_ON) == 0 || - typ->ty_getty == 0) { - session_free(sp); - continue; - } - - sp->se_flags &= ~SE_SHUTDOWN; - - if (setupargv(sp, typ) == 0) { - syslog(LOG_WARNING, "can't parse getty for port %s", - sp->se_device); - session_free(sp); - } - } - - endttyent(); -} - -/* - * Block further logins. - */ -void -catatonia(void) -{ - session_t s; - - TAILQ_FOREACH(s, &sessions, tqe) - s->se_flags |= SE_SHUTDOWN; -} - -bool init_check_pid(pid_t p) -{ - session_t s; - - TAILQ_FOREACH(s, &sessions, tqe) { - if (s->se_process == p) - return true; - } - - if (single_user_pid == p) - return true; - - if (runcom_pid == p) - return true; - - return false; -} - -bool -should_fsck(void) -{ - struct statfs sfs; - bool r = true; - - if (launchd_assumes(statfs("/", &sfs) != -1)) { - if (!(sfs.f_flags & MNT_RDONLY)) { - r = false; - } - } - - return r; -} diff --git a/launchd/src/launchctl.1 b/launchd/src/launchctl.1 index 4645525..3ff49bd 100644 --- a/launchd/src/launchctl.1 +++ b/launchd/src/launchctl.1 @@ -43,7 +43,7 @@ Some jobs only make sense in certain contexts. This flag instructs to look for jobs in a different location when using the -D flag, and allows .Nm launchctl to restrict which jobs are loaded into which session types. Currently known -session types include: Aqua, X11 and tty. +session types include: Aqua, LoginWindow, Background, StandardIO and System. .It Fl D Ar domain Look for .Xr plist 5 files ending in *.plist in the domain given. Valid domains include @@ -53,6 +53,8 @@ domain is available for use called "user." For example, without a session type g With a session type passed, it would load from /System/Library/LaunchAgents. .El .It Xo Ar unload Op Fl w +.Op Fl S Ar sessiontype +.Op Fl D Ar domain .Ar paths ... .Xc Unload the specified configuration files or directories of configuration files. @@ -60,6 +62,20 @@ This will also stop the job if it is running. .Bl -tag -width -indent .It Fl w Add the disabled key and write the configuration files back out to disk. +.It Fl S Ar sessiontype +Some jobs only make sense in certain contexts. This flag instructs +.Nm launchctl +to look for jobs in a different location when using the -D flag, and allows +.Nm launchctl +to restrict which jobs are loaded into which session types. Currently known +session types include: Aqua, LoginWindow, Background, StandardIO and System. +.It Fl D Ar domain +Look for +.Xr plist 5 files ending in *.plist in the domain given. Valid domains include +"system," "local," "network" and "all." When providing a session type, an additional +domain is available for use called "user." For example, without a session type given, +"-D system" would load from property list files from /System/Library/LaunchDaemons. +With a session type passed, it would load from /System/Library/LaunchAgents. .El .It Xo Ar submit Fl l Ar label .Op Fl p Ar executable @@ -80,12 +96,12 @@ Where to send the stdout of the program. Where to send the stderr of the program. .El .It Ar remove Ar job_label -Remove the jobs from launchd by label. +Remove the job from launchd by label. .It Ar start Ar job_label -Start the specified jobs by label. The expected use of this subcommand is for +Start the specified job by label. The expected use of this subcommand is for debugging and testing so that one can manually kick-start an on-demand server. .It Ar stop Ar job_label -Stop the specified jobs by label. If a job is on-demand, launchd may immediately +Stop the specified job by label. If a job is on-demand, launchd may immediately restart the job if launchd finds any criteria that is satisfied. Non-demand based jobs will always be restarted. Use of this subcommand is discouraged. Jobs should ideally idle timeout by themselves. @@ -130,20 +146,10 @@ With a third argument, it sets both the hard and soft limits to that value. With four arguments, the third and forth argument represent the soft and hard limits respectively. See .Xr setrlimit 2 . -.It Ar stdout path -Set the standard out file descriptor to the given path. -.Nm launchd -.It Ar stderr path -Set the standard error file descriptor to the given path. -.Nm launchd .It Ar shutdown Tell .Nm launchd to prepare for shutdown by removing all jobs. -.It Ar reloadttys -Tell -.Nm launchd -to reread /etc/ttys. This option may go away in a future release. .It Ar umask Op Ar newmask Get or optionally set the .Xr umask 2 @@ -153,7 +159,7 @@ of This prints out Mach bootstrap services and their respective states. While the namespace appears flat, it is in fact hierarchical, thus allowing for certain services to be only available to a subset of processes. The three states a -service can be in are active ("A"), in-active ("I") and on-demand ("D"). +service can be in are active ("A"), inactive ("I") and on-demand ("D"). .It Ar bsexec Ar PID command Op Ar args This executes the given command in the same Mach bootstrap namespace hierachy as the given PID. diff --git a/launchd/src/launchctl.c b/launchd/src/launchctl.c index a3b78d2..f238119 100644 --- a/launchd/src/launchctl.c +++ b/launchd/src/launchctl.c @@ -18,10 +18,23 @@ * @APPLE_APACHE_LICENSE_HEADER_END@ */ -static const char *const __rcs_file_version__ = "$Revision: 1.88 $"; +static const char *const __rcs_file_version__ = "$Revision: 23400 $"; + +#include "liblaunch_public.h" +#include "liblaunch_private.h" +#include "libbootstrap_public.h" +#include "libvproc_public.h" +#include "libvproc_private.h" +#include "libvproc_internal.h" #include #include +#include +#if !TARGET_OS_EMBEDDED +#include +#include +#endif +#include #include #include #include @@ -58,11 +71,10 @@ static const char *const __rcs_file_version__ = "$Revision: 1.88 $"; #include #include #include +#include +#include +#include -#include "bootstrap_public.h" -#include "bootstrap_private.h" -#include "launch.h" -#include "launch_priv.h" #define LAUNCH_SECDIR "/tmp/launch-XXXXXX" @@ -72,8 +84,8 @@ static const char *const __rcs_file_version__ = "$Revision: 1.88 $"; #define MACHINIT_JOBKEY_SERVERPORT "ServerPort" #define MACHINIT_JOBKEY_SERVICEPORT "ServicePort" -#define assumes(e) \ - (__builtin_expect(!(e), 0) ? _log_launchctl_bug(__rcs_file_version__, __FILE__, __LINE__, #e), false : true) +#define assumes(e) \ + (__builtin_expect(!(e), 0) ? _log_launchctl_bug(__rcs_file_version__, __FILE__, __LINE__, #e), false : true) struct load_unload_state { @@ -105,7 +117,7 @@ static void submit_mach_jobs(launch_data_t jobs); static void let_go_of_mach_jobs(launch_data_t jobs); static void do_mgroup_join(int fd, int family, int socktype, int protocol, const char *mgroup); static mach_port_t str2bsport(const char *s); -static void print_jobs(launch_data_t j); +static void print_jobs(launch_data_t j, const char *key, void *context); static void print_obj(launch_data_t obj, const char *key, void *context); static bool is_legacy_mach_job(launch_data_t obj); static bool delay_to_second_pass(launch_data_t o); @@ -125,12 +137,25 @@ static void do_potential_fsck(void); static bool path_check(const char *path); static bool is_safeboot(void); static bool is_netboot(void); -static void apply_func_to_dir(const char *thedir, void (*thefunc)(const char *)); static void apply_sysctls_from_file(const char *thefile); -static void empty_dir(const char *path); +static void empty_dir(const char *thedir, struct stat *psb); static int touch_file(const char *path, mode_t m); static void do_sysversion_sysctl(void); -static void workaround4465949(void); +static void do_application_firewall_magic(int sfd, launch_data_t thejob); +static void preheat_page_cache_hack(void); +static void do_bootroot_magic(void); +static void do_single_user_mode(bool); +static bool do_single_user_mode2(void); +static void read_launchd_conf(void); +static bool job_disabled_logic(launch_data_t obj); + +typedef enum { + BOOTCACHE_START = 1, + BOOTCACHE_TAG, + BOOTCACHE_STOP, +} BootCache_action_t; + +static void do_BootCache_magic(BootCache_action_t what); static int bootstrap_cmd(int argc, char *const argv[]); static int load_and_unload_cmd(int argc, char *const argv[]); @@ -178,7 +203,6 @@ static const struct { { "stderr", stdio_cmd, "Redirect launchd's standard error to the given path" }, { "shutdown", fyi_cmd, "Prepare for system shutdown" }, { "singleuser", fyi_cmd, "Switch to single-user mode" }, - { "reloadttys", fyi_cmd, "Reload /etc/ttys" }, { "getrusage", getrusage_cmd, "Get resource usage statistics from launchd" }, { "log", logupdate_cmd, "Adjust the logging level or mask of launchd" }, { "umask", umask_cmd, "Change launchd's umask" }, @@ -189,15 +213,26 @@ static const struct { { "help", help_cmd, "This help output" }, }; -static bool istty = false; -static bool verbose = false; +static bool istty; +static bool verbose; +static bool is_managed; int main(int argc, char *const argv[]) { + int64_t is_managed_val = 0; char *l; - do_sysversion_sysctl(); + if (vproc_swap_integer(NULL, VPROC_GSK_IS_MANAGED, NULL, &is_managed_val) == NULL && is_managed_val) { + is_managed = true; + } + + if (getuid() == 0 && !is_managed) { + mach_port_t root_bs = str2bsport("/"); + task_set_bootstrap_port(mach_task_self(), root_bs); + mach_port_deallocate(mach_task_self(), bootstrap_port); + bootstrap_port = root_bs; + } istty = isatty(STDIN_FILENO); @@ -236,8 +271,9 @@ main(int argc, char *const argv[]) } } - if (i > 0) + if (i > 0) { demux_cmd(i, argv2); + } free(l); } @@ -263,14 +299,48 @@ demux_cmd(int argc, char *const argv[]) optreset = 1; for (i = 0; i < (sizeof cmds / sizeof cmds[0]); i++) { - if (!strcmp(cmds[i].name, argv[0])) + if (!strcmp(cmds[i].name, argv[0])) { return cmds[i].func(argc, argv); + } } fprintf(stderr, "%s: unknown subcommand \"%s\"\n", getprogname(), argv[0]); return 1; } +void +read_launchd_conf(void) +{ + char s[1000], *c, *av[100]; + size_t len, i; + FILE *f; + + if (!(f = fopen("/etc/launchd.conf", "r"))) { + return; + } + + while ((c = fgets(s, sizeof(s), f))) { + len = strlen(c); + if (len && c[len - 1] == '\n') { + c[len - 1] = '\0'; + } + + i = 0; + + while ((av[i] = strsep(&c, " \t"))) { + if (*(av[i]) != '\0') { + i++; + } + } + + if (i > 0) { + demux_cmd(i, av); + } + } + + fclose(f); +} + int unsetenv_cmd(int argc, char *const argv[]) { @@ -334,10 +404,11 @@ print_launchd_env(launch_data_t obj, const char *key, void *context) bool *is_csh = context; /* XXX escape the double quotes */ - if (*is_csh) + if (*is_csh) { fprintf(stdout, "setenv %s \"%s\";\n", key, launch_data_get_string(obj)); - else + } else { fprintf(stdout, "%s=\"%s\"; export %s;\n", key, launch_data_get_string(obj), key); + } } void @@ -345,21 +416,23 @@ print_key_value(launch_data_t obj, const char *key, void *context) { const char *k = context; - if (!strcmp(key, k)) + if (!strcmp(key, k)) { fprintf(stdout, "%s\n", launch_data_get_string(obj)); + } } int -getenv_and_export_cmd(int argc, char *const argv[] __attribute__((unused))) +getenv_and_export_cmd(int argc, char *const argv[]) { - launch_data_t resp, msg; + launch_data_t resp; bool is_csh = false; char *k; if (!strcmp(argv[0], "export")) { char *s = getenv("SHELL"); - if (s) + if (s) { is_csh = strstr(s, "csh") ? true : false; + } } else if (argc != 2) { fprintf(stderr, "%s usage: getenv \n", getprogname()); return 1; @@ -367,31 +440,26 @@ getenv_and_export_cmd(int argc, char *const argv[] __attribute__((unused))) k = argv[1]; - msg = launch_data_new_string(LAUNCH_KEY_GETUSERENVIRONMENT); - - resp = launch_msg(msg); - launch_data_free(msg); - - if (resp) { - if (!strcmp(argv[0], "export")) + if (vproc_swap_complex(NULL, VPROC_GSK_ENVIRONMENT, NULL, &resp) == NULL) { + if (!strcmp(argv[0], "export")) { launch_data_dict_iterate(resp, print_launchd_env, &is_csh); - else + } else { launch_data_dict_iterate(resp, print_key_value, k); + } launch_data_free(resp); + return 0; } else { - fprintf(stderr, "launch_msg(\"" LAUNCH_KEY_GETUSERENVIRONMENT "\"): %s\n", strerror(errno)); + return 1; } + return 0; } void unloadjob(launch_data_t job) { - launch_data_t resp, tmp, tmps, msg; - int e; + launch_data_t tmps; - msg = launch_data_alloc(LAUNCH_DATA_DICTIONARY); - tmp = launch_data_alloc(LAUNCH_DATA_STRING); tmps = launch_data_dict_lookup(job, LAUNCH_JOBKEY_LABEL); if (!tmps) { @@ -399,19 +467,9 @@ unloadjob(launch_data_t job) return; } - launch_data_set_string(tmp, launch_data_get_string(tmps)); - launch_data_dict_insert(msg, tmp, LAUNCH_KEY_REMOVEJOB); - resp = launch_msg(msg); - launch_data_free(msg); - if (!resp) { - fprintf(stderr, "%s: Error: launch_msg(): %s\n", getprogname(), strerror(errno)); - return; + if (_vproc_send_signal_by_label(launch_data_get_string(tmps), VPROC_MAGIC_UNLOAD_SIGNAL) != NULL) { + fprintf(stderr, "%s: Error unloading: %s\n", getprogname(), launch_data_get_string(tmps)); } - if (LAUNCH_DATA_ERRNO == launch_data_get_type(resp)) { - if ((e = launch_data_get_errno(resp))) - fprintf(stderr, "%s\n", strerror(e)); - } - launch_data_free(resp); } launch_data_t @@ -426,10 +484,11 @@ read_plist_file(const char *file, bool editondisk, bool load) } if (editondisk) { - if (load) + if (load) { CFDictionaryRemoveValue((CFMutableDictionaryRef)plist, CFSTR(LAUNCH_JOBKEY_DISABLED)); - else + } else { CFDictionarySetValue((CFMutableDictionaryRef)plist, CFSTR(LAUNCH_JOBKEY_DISABLED), kCFBooleanTrue); + } WriteMyPropertyListToFile(plist, file); } @@ -456,8 +515,9 @@ delay_to_second_pass2(launch_data_t o, const char *key, void *context) launch_data_dict_iterate(o, delay_to_second_pass2, context); break; case LAUNCH_DATA_ARRAY: - for (i = 0; i < launch_data_array_get_count(o); i++) + for (i = 0; i < launch_data_array_get_count(o); i++) { delay_to_second_pass2(launch_data_array_get_index(o, i), NULL, context); + } break; default: break; @@ -471,8 +531,9 @@ delay_to_second_pass(launch_data_t o) launch_data_t socks = launch_data_dict_lookup(o, LAUNCH_JOBKEY_SOCKETS); - if (NULL == socks) + if (NULL == socks) { return false; + } delay_to_second_pass2(socks, NULL, &res); @@ -510,8 +571,9 @@ readfile(const char *what, struct load_unload_state *lus) for (i = 0; i < c; i++) { launch_data_t oai = launch_data_array_get_index(tmpa, i); - if (!strcasecmp(ourhostname, launch_data_get_string(oai))) + if (!strcasecmp(ourhostname, launch_data_get_string(oai))) { goto out_bad; + } } } @@ -520,12 +582,19 @@ readfile(const char *what, struct load_unload_state *lus) for (i = 0; i < c; i++) { launch_data_t oai = launch_data_array_get_index(tmpa, i); - if (!strcasecmp(ourhostname, launch_data_get_string(oai))) + if (!strcasecmp(ourhostname, launch_data_get_string(oai))) { break; + } } - if (i == c) + if (i == c) { goto out_bad; + } + } + + if (lus->session_type && !(tmpa = launch_data_dict_lookup(thejob, LAUNCH_JOBKEY_LIMITLOADTOSESSIONTYPE))) { + tmpa = launch_data_new_string("Aqua"); + launch_data_dict_insert(thejob, tmpa, LAUNCH_JOBKEY_LIMITLOADTOSESSIONTYPE); } if ((tmpa = launch_data_dict_lookup(thejob, LAUNCH_JOBKEY_LIMITLOADTOSESSIONTYPE))) { @@ -540,6 +609,9 @@ readfile(const char *what, struct load_unload_state *lus) allowed_session = launch_data_get_string(tmps); if (strcasecmp(lus->session_type, allowed_session) == 0) { skipjob = false; + /* we have to do the following so job_reparent_hack() works within launchd */ + tmpa = launch_data_new_string(lus->session_type); + launch_data_dict_insert(thejob, tmpa, LAUNCH_JOBKEY_LIMITLOADTOSESSIONTYPE); break; } } @@ -559,30 +631,91 @@ readfile(const char *what, struct load_unload_state *lus) } } - if ((tmpd = launch_data_dict_lookup(thejob, LAUNCH_JOBKEY_DISABLED))) - job_disabled = launch_data_get_bool(tmpd); + if ((tmpd = launch_data_dict_lookup(thejob, LAUNCH_JOBKEY_DISABLED))) { + job_disabled = job_disabled_logic(tmpd); + } - if (lus->forceload) + if (lus->forceload) { job_disabled = false; + } - if (job_disabled && lus->load) + if (job_disabled && lus->load) { goto out_bad; + } - if (delay_to_second_pass(thejob)) + if (delay_to_second_pass(thejob)) { launch_data_array_append(lus->pass2, thejob); - else + } else { launch_data_array_append(lus->pass1, thejob); + } - if (verbose) + if (verbose) { fprintf(stdout, "Will load: %s\n", what); + } return; out_bad: - if (verbose) + if (verbose) { fprintf(stdout, "Ignored: %s\n", what); + } launch_data_free(thejob); } +static bool +sysctl_hw_streq(int mib_slot, const char *str) +{ + char buf[1000]; + size_t bufsz = sizeof(buf); + int mib[] = { CTL_HW, mib_slot }; + + if (sysctl(mib, 2, buf, &bufsz, NULL, 0) != -1) { + if (strcmp(buf, str) == 0) { + return true; + } + } + + return false; +} + +static void +job_disabled_dict_logic(launch_data_t obj, const char *key, void *context) +{ + bool *r = context; + + if (launch_data_get_type(obj) != LAUNCH_DATA_STRING) { + return; + } + + if (strcasecmp(key, LAUNCH_JOBKEY_DISABLED_MACHINETYPE) == 0) { + if (sysctl_hw_streq(HW_MACHINE, launch_data_get_string(obj))) { + *r = true; + } + } else if (strcasecmp(key, LAUNCH_JOBKEY_DISABLED_MODELNAME) == 0) { + if (sysctl_hw_streq(HW_MODEL, launch_data_get_string(obj))) { + *r = true; + } + } +} + +bool +job_disabled_logic(launch_data_t obj) +{ + bool r = false; + + switch (launch_data_get_type(obj)) { + case LAUNCH_DATA_DICTIONARY: + launch_data_dict_iterate(obj, job_disabled_dict_logic, &r); + break; + case LAUNCH_DATA_BOOL: + r = launch_data_get_bool(obj); + break; + default: + break; + } + + return r; +} + bool path_goodness_check(const char *path, bool forceload) { @@ -593,8 +726,9 @@ path_goodness_check(const char *path, bool forceload) return false; } - if (forceload) + if (forceload) { return true; + } if (sb.st_mode & (S_IWOTH|S_IWGRP)) { fprintf(stderr, "%s: Dubious permissions on file (skipping): %s\n", getprogname(), path); @@ -607,7 +741,7 @@ path_goodness_check(const char *path, bool forceload) } if (!(S_ISREG(sb.st_mode) || S_ISDIR(sb.st_mode))) { - fprintf(stderr, "%s: Dubious path. Not a regular file or directory (skipping): %s\n", getprogname(), path); + fprintf(stderr, "%s: Dubious path. Not a regular file or directory (skipping): %s\n", getprogname(), path); return false; } @@ -622,11 +756,13 @@ readpath(const char *what, struct load_unload_state *lus) struct dirent *de; DIR *d; - if (!path_goodness_check(what, lus->forceload)) + if (!path_goodness_check(what, lus->forceload)) { return; + } - if (stat(what, &sb) == -1) + if (stat(what, &sb) == -1) { return; + } if (S_ISREG(sb.st_mode)) { readfile(what, lus); @@ -637,12 +773,14 @@ readpath(const char *what, struct load_unload_state *lus) } while ((de = readdir(d))) { - if ((de->d_name[0] == '.')) + if ((de->d_name[0] == '.')) { continue; + } snprintf(buf, sizeof(buf), "%s/%s", what, de->d_name); - if (!path_goodness_check(buf, lus->forceload)) + if (!path_goodness_check(buf, lus->forceload)) { continue; + } readfile(buf, lus); } @@ -715,8 +853,9 @@ sock_dict_edit_entry(launch_data_t tmp, const char *key, launch_data_t fdarray, } } - if ((val = launch_data_dict_lookup(tmp, LAUNCH_JOBSOCKETKEY_PASSIVE))) + if ((val = launch_data_dict_lookup(tmp, LAUNCH_JOBSOCKETKEY_PASSIVE))) { passive = launch_data_get_bool(val); + } if ((val = launch_data_dict_lookup(tmp, LAUNCH_JOBSOCKETKEY_SECUREWITHKEY))) { char secdir[] = LAUNCH_SECDIR, buf[1024]; @@ -749,17 +888,18 @@ sock_dict_edit_entry(launch_data_t tmp, const char *key, launch_data_t fdarray, strncpy(sun.sun_path, launch_data_get_string(val), sizeof(sun.sun_path)); - if ((sfd = _fd(socket(AF_UNIX, st, 0))) == -1) + if ((sfd = _fd(socket(AF_UNIX, st, 0))) == -1) { return; + } if ((val = launch_data_dict_lookup(tmp, LAUNCH_JOBSOCKETKEY_PATHMODE))) { sun_mode = (mode_t)launch_data_get_integer(val); setm = true; } - if (passive) { + if (passive) { if (unlink(sun.sun_path) == -1 && errno != ENOENT) { - close(sfd); + close(sfd); return; } oldmask = umask(S_IRWXG|S_IRWXO); @@ -772,8 +912,7 @@ sock_dict_edit_entry(launch_data_t tmp, const char *key, launch_data_t fdarray, if (setm) { chmod(sun.sun_path, sun_mode); } - if ((st == SOCK_STREAM || st == SOCK_SEQPACKET) - && listen(sfd, SOMAXCONN) == -1) { + if ((st == SOCK_STREAM || st == SOCK_SEQPACKET) && listen(sfd, SOMAXCONN) == -1) { close(sfd); return; } @@ -795,13 +934,16 @@ sock_dict_edit_entry(launch_data_t tmp, const char *key, launch_data_t fdarray, memset(&hints, 0, sizeof(hints)); hints.ai_socktype = st; - if (passive) + if (passive) { hints.ai_flags |= AI_PASSIVE; + } - if ((val = launch_data_dict_lookup(tmp, LAUNCH_JOBSOCKETKEY_NODENAME))) + if ((val = launch_data_dict_lookup(tmp, LAUNCH_JOBSOCKETKEY_NODENAME))) { node = launch_data_get_string(val); - if ((val = launch_data_dict_lookup(tmp, LAUNCH_JOBSOCKETKEY_MULTICASTGROUP))) + } + if ((val = launch_data_dict_lookup(tmp, LAUNCH_JOBSOCKETKEY_MULTICASTGROUP))) { mgroup = launch_data_get_string(val); + } if ((val = launch_data_dict_lookup(tmp, LAUNCH_JOBSOCKETKEY_SERVICENAME))) { if (LAUNCH_DATA_INTEGER == launch_data_get_type(val)) { sprintf(servnbuf, "%lld", launch_data_get_integer(val)); @@ -811,14 +953,18 @@ sock_dict_edit_entry(launch_data_t tmp, const char *key, launch_data_t fdarray, } } if ((val = launch_data_dict_lookup(tmp, LAUNCH_JOBSOCKETKEY_FAMILY))) { - if (!strcasecmp("IPv4", launch_data_get_string(val))) + if (!strcasecmp("IPv4", launch_data_get_string(val))) { hints.ai_family = AF_INET; - else if (!strcasecmp("IPv6", launch_data_get_string(val))) + } else if (!strcasecmp("IPv6", launch_data_get_string(val))) { hints.ai_family = AF_INET6; + } } if ((val = launch_data_dict_lookup(tmp, LAUNCH_JOBSOCKETKEY_PROTOCOL))) { - if (!strcasecmp("TCP", launch_data_get_string(val))) + if (!strcasecmp("TCP", launch_data_get_string(val))) { hints.ai_protocol = IPPROTO_TCP; + } else if (!strcasecmp("UDP", launch_data_get_string(val))) { + hints.ai_protocol = IPPROTO_UDP; + } } if ((rnames = launch_data_dict_lookup(tmp, LAUNCH_JOBSOCKETKEY_BONJOUR))) { rendezvous = true; @@ -839,6 +985,9 @@ sock_dict_edit_entry(launch_data_t tmp, const char *key, launch_data_t fdarray, fprintf(stderr, "socket(): %s\n", strerror(errno)); return; } + + do_application_firewall_magic(sfd, thejob); + if (hints.ai_flags & AI_PASSIVE) { if (AF_INET6 == res->ai_family && -1 == setsockopt(sfd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&sock_opt, sizeof(sock_opt))) { @@ -860,12 +1009,18 @@ sock_dict_edit_entry(launch_data_t tmp, const char *key, launch_data_t fdarray, fprintf(stderr, "bind(): %s\n", strerror(errno)); return; } + /* The kernel may have dynamically assigned some part of the + * address. (The port being a common example.) + */ + if (getsockname(sfd, res->ai_addr, &res->ai_addrlen) == -1) { + fprintf(stderr, "getsockname(): %s\n", strerror(errno)); + return; + } if (mgroup) { do_mgroup_join(sfd, res->ai_family, res->ai_socktype, res->ai_protocol, mgroup); } - if ((res->ai_socktype == SOCK_STREAM || res->ai_socktype == SOCK_SEQPACKET) - && listen(sfd, SOMAXCONN) == -1) { + if ((res->ai_socktype == SOCK_STREAM || res->ai_socktype == SOCK_SEQPACKET) && listen(sfd, SOMAXCONN) == -1) { fprintf(stderr, "listen(): %s\n", strerror(errno)); return; } @@ -878,12 +1033,14 @@ sock_dict_edit_entry(launch_data_t tmp, const char *key, launch_data_t fdarray, } if (NULL == rnames) { rvs_fd = do_rendezvous_magic(res, serv); - if (rvs_fd) + if (rvs_fd) { launch_data_array_append(rvs_fds, rvs_fd); + } } else if (LAUNCH_DATA_STRING == launch_data_get_type(rnames)) { rvs_fd = do_rendezvous_magic(res, launch_data_get_string(rnames)); - if (rvs_fd) + if (rvs_fd) { launch_data_array_append(rvs_fds, rvs_fd); + } } else if (LAUNCH_DATA_ARRAY == launch_data_get_type(rnames)) { size_t rn_i, rn_ac = launch_data_array_get_count(rnames); @@ -891,8 +1048,9 @@ sock_dict_edit_entry(launch_data_t tmp, const char *key, launch_data_t fdarray, launch_data_t rn_tmp = launch_data_array_get_index(rnames, rn_i); rvs_fd = do_rendezvous_magic(res, launch_data_get_string(rn_tmp)); - if (rvs_fd) + if (rvs_fd) { launch_data_array_append(rvs_fds, rvs_fd); + } } } } @@ -970,23 +1128,27 @@ do_rendezvous_magic(const struct addrinfo *res, const char *serv) short port; static int statres = 1; - if (1 == statres) + if (1 == statres) { statres = stat("/usr/sbin/mDNSResponder", &sb); + } - if (-1 == statres) + if (-1 == statres) { return NULL; + } sprintf(rvs_buf, "_%s._%s.", serv, res->ai_socktype == SOCK_STREAM ? "tcp" : "udp"); - if (res->ai_family == AF_INET) + if (res->ai_family == AF_INET) { port = ((struct sockaddr_in *)res->ai_addr)->sin_port; - else + } else { port = ((struct sockaddr_in6 *)res->ai_addr)->sin6_port; + } error = DNSServiceRegister(&service, 0, 0, NULL, rvs_buf, NULL, NULL, port, 0, NULL, NULL, NULL); - if (error == kDNSServiceErr_NoError) + if (error == kDNSServiceErr_NoError) { return launch_data_new_fd(DNSServiceRefSockFD(service)); + } fprintf(stderr, "DNSServiceRegister(\"%s\"): %d\n", serv, error); return NULL; @@ -1002,13 +1164,16 @@ CreateMyPropertyListFromFile(const char *posixfile) CFURLRef fileURL; fileURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8 *)posixfile, strlen(posixfile), false); - if (!fileURL) + if (!fileURL) { fprintf(stderr, "%s: CFURLCreateFromFileSystemRepresentation(%s) failed\n", getprogname(), posixfile); - if (!CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault, fileURL, &resourceData, NULL, NULL, &errorCode)) + } + if (!CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault, fileURL, &resourceData, NULL, NULL, &errorCode)) { fprintf(stderr, "%s: CFURLCreateDataAndPropertiesFromResource(%s) failed: %d\n", getprogname(), posixfile, (int)errorCode); + } propertyList = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, resourceData, kCFPropertyListMutableContainers, &errorString); - if (!propertyList) + if (!propertyList) { fprintf(stderr, "%s: propertyList is NULL\n", getprogname()); + } return propertyList; } @@ -1021,13 +1186,16 @@ WriteMyPropertyListToFile(CFPropertyListRef plist, const char *posixfile) SInt32 errorCode; fileURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8 *)posixfile, strlen(posixfile), false); - if (!fileURL) + if (!fileURL) { fprintf(stderr, "%s: CFURLCreateFromFileSystemRepresentation(%s) failed\n", getprogname(), posixfile); + } resourceData = CFPropertyListCreateXMLData(kCFAllocatorDefault, plist); - if (resourceData == NULL) + if (resourceData == NULL) { fprintf(stderr, "%s: CFPropertyListCreateXMLData(%s) failed", getprogname(), posixfile); - if (!CFURLWriteDataAndPropertiesToResource(fileURL, resourceData, NULL, &errorCode)) + } + if (!CFURLWriteDataAndPropertiesToResource(fileURL, resourceData, NULL, &errorCode)) { fprintf(stderr, "%s: CFURLWriteDataAndPropertiesToResource(%s) failed: %d\n", getprogname(), posixfile, (int)errorCode); + } } void @@ -1126,8 +1294,9 @@ help_cmd(int argc, char *const argv[]) cmdwidth = l; } - for (i = 0; i < (sizeof cmds / sizeof cmds[0]); i++) + for (i = 0; i < (sizeof cmds / sizeof cmds[0]); i++) { fprintf(where, "\t%-*s\t%s\n", cmdwidth, cmds[i].name, cmds[i].desc); + } return 0; } @@ -1146,42 +1315,101 @@ _fd(int fd) return fd; } -int -bootstrap_cmd(int argc __attribute__((unused)), char *const argv[] __attribute__((unused))) +void +do_single_user_mode(bool sflag) { - int memmib[] = { CTL_HW, HW_MEMSIZE }; - int mvnmib[] = { CTL_KERN, KERN_MAXVNODES }; - int hnmib[] = { CTL_KERN, KERN_HOSTNAME }; - uint64_t mem = 0; - uint32_t mvn; - size_t memsz = sizeof(mem); - struct group *tfp_gr; - - if (assumes((tfp_gr = getgrnam("procview")) != NULL)) { - int tfp_r_mib[3] = { CTL_KERN, KERN_TFP, KERN_TFP_READ_GROUP }; - gid_t tfp_r_gid = tfp_gr->gr_gid; - assumes(sysctl(tfp_r_mib, 3, NULL, NULL, &tfp_r_gid, sizeof(tfp_r_gid)) != -1); + if (sflag) { + while (!do_single_user_mode2()) { + sleep(1); + } } +} - if (assumes((tfp_gr = getgrnam("procmod")) != NULL)) { - int tfp_rw_mib[3] = { CTL_KERN, KERN_TFP, KERN_TFP_RW_GROUP }; - gid_t tfp_rw_gid = tfp_gr->gr_gid; - assumes(sysctl(tfp_rw_mib, 3, NULL, NULL, &tfp_rw_gid, sizeof(tfp_rw_gid)) != -1); +bool +do_single_user_mode2(void) +{ + bool runcom_fsck = true; /* should_fsck(); */ + int wstatus; + int fd; + pid_t p; + + switch ((p = fork())) { + case -1: + syslog(LOG_ERR, "can't fork single-user shell, trying again: %m"); + return false; + case 0: + break; + default: + assumes(waitpid(p, &wstatus, 0) != -1); + if (WIFEXITED(wstatus)) { + if (WEXITSTATUS(wstatus) == EXIT_SUCCESS) { + return true; + } else { + fprintf(stdout, "single user mode: exit status: %d\n", WEXITSTATUS(wstatus)); + } + } else { + fprintf(stdout, "single user mode shell: %s\n", strsignal(WTERMSIG(wstatus))); + } + return false; } - if (assumes(sysctl(memmib, 2, &mem, &memsz, NULL, 0) != -1)) { - mvn = mem / (64 * 1024) + 1024; - assumes(sysctl(mvnmib, 2, NULL, NULL, &mvn, sizeof(mvn)) != -1); + revoke(_PATH_CONSOLE); + if (!assumes((fd = open(_PATH_CONSOLE, O_RDWR)) != -1)) { + _exit(EXIT_FAILURE); + } + if (!assumes(login_tty(fd) != -1)) { + _exit(EXIT_FAILURE); } + setenv("TERM", "vt100", 1); + if (runcom_fsck) { + fprintf(stdout, "Singleuser boot -- fsck not done\n"); + fprintf(stdout, "Root device is mounted read-only\n\n"); + fprintf(stdout, "If you want to make modifications to files:\n"); + fprintf(stdout, "\t/sbin/fsck -fy\n\t/sbin/mount -uw /\n\n"); + fprintf(stdout, "If you wish to boot the system:\n"); + fprintf(stdout, "\texit\n\n"); + fflush(stdout); + } + + execl(_PATH_BSHELL, "-sh", NULL); + syslog(LOG_ERR, "can't exec %s for single user: %m", _PATH_BSHELL); + _exit(EXIT_FAILURE); +} + +static void +system_specific_bootstrap(bool sflag) +{ + int hnmib[] = { CTL_KERN, KERN_HOSTNAME }; + struct kevent kev; + int kq; + + + do_sysversion_sysctl(); + + do_single_user_mode(sflag); + + assumes((kq = kqueue()) != -1); + + EV_SET(&kev, 0, EVFILT_TIMER, EV_ADD|EV_ONESHOT, NOTE_SECONDS, 60, 0); + assumes(kevent(kq, &kev, 1, NULL, 0, NULL) != -1); + + EV_SET(&kev, SIGTERM, EVFILT_SIGNAL, EV_ADD, 0, 0, 0); + assumes(kevent(kq, &kev, 1, NULL, 0, NULL) != -1); + assumes(signal(SIGTERM, SIG_IGN) != SIG_ERR); + assumes(sysctl(hnmib, 2, NULL, NULL, "localhost", sizeof("localhost")) != -1); loopback_setup_ipv4(); loopback_setup_ipv6(); - apply_sysctls_from_file("/etc/sysctl-macosxserver.conf"); + if (path_check("/etc/rc.server")) { + const char *rcserver_tool[] = { _PATH_BSHELL, "/etc/rc.server", NULL }; + assumes(fwexec(rcserver_tool, true) != -1); + } + apply_sysctls_from_file("/etc/sysctl.conf"); - if (path_check("/System/Installation") && path_check("/etc/rc.cdrom")) { + if (path_check("/etc/rc.cdrom")) { const char *rccdrom_tool[] = { _PATH_BSHELL, "/etc/rc.cdrom", "multiuser", NULL }; assumes(fwexec(rccdrom_tool, true) != -1); assumes(reboot(RB_HALT) != -1); @@ -1196,6 +1424,8 @@ bootstrap_cmd(int argc __attribute__((unused)), char *const argv[] __attribute__ do_potential_fsck(); } + read_launchd_conf(); + if (path_check("/var/account/acct")) { assumes(acct("/var/account/acct") != -1); } @@ -1210,93 +1440,193 @@ bootstrap_cmd(int argc __attribute__((unused)), char *const argv[] __attribute__ assumes(fwexec(rccleanup_tool, true) != -1); } - apply_func_to_dir(_PATH_VARRUN, empty_dir); - apply_func_to_dir(_PATH_TMP, empty_dir); + empty_dir(_PATH_VARRUN, NULL); + empty_dir(_PATH_TMP, NULL); remove(_PATH_NOLOGIN); - // XXX --> RMRF_ITEMS="/var/tmp/folders.* - - // 775 www:www /var/run/davlocks 4489695 - // 775 root:daemon /var/run/StartupItems + if (path_check("/usr/libexec/dirhelper")) { + const char *dirhelper_tool[] = { "/usr/libexec/dirhelper", "-machineBoot", NULL }; + assumes(fwexec(dirhelper_tool, true) != -1); + } - assumes(touch_file(_PATH_UTMP, DEFFILEMODE) != -1); assumes(touch_file(_PATH_UTMPX, DEFFILEMODE) != -1); assumes(touch_file(_PATH_VARRUN "/.systemStarterRunning", DEFFILEMODE) != -1); - if (!path_check("/var/db/netinfo/local.nidb.migrated") && !path_check("/var/db/netinfo/local.nidb")) { - const char *create_nidb_tool[] = { "/usr/libexec/create_nidb", NULL }; - - fprintf(stderr, "NetInfo database missing. Creating...\n"); - - mkdir("/var/db/netinfo", ACCESSPERMS); - remove("/var/db/.AppleSetupDone"); - assumes(fwexec(create_nidb_tool, true) != -1); - } - if (path_check("/etc/security/rc.audit")) { const char *audit_tool[] = { _PATH_BSHELL, "/etc/security/rc.audit", NULL }; assumes(fwexec(audit_tool, true) != -1); } - if (path_check("/Library/Preferences/com.apple.sharing.firewall.plist")) { - const char *fw_tool[] = { "/usr/libexec/FirewallTool", NULL }; - assumes(fwexec(fw_tool, true) != -1); - } + do_BootCache_magic(BOOTCACHE_START); - const char *bcc_tool[] = { "BootCacheControl", "start", NULL }; - assumes(fwexec(bcc_tool, true) != -1); + preheat_page_cache_hack(); + + _vproc_set_global_on_demand(true); char *load_launchd_items[] = { "load", "-D", "all", "/etc/mach_init.d", NULL }; - if (is_safeboot()) + + if (is_safeboot()) { load_launchd_items[2] = "system"; + } + assumes(load_and_unload_cmd(4, load_launchd_items) == 0); - const char *bcc_tag_tool[] = { "BootCacheControl", "tag", NULL }; - assumes(fwexec(bcc_tag_tool, true) != -1); + /* + * 5066316 + * + * We need to revisit this after Leopard ships. + * + * I want a plist defined knob for jobs to give advisory hints that + * will "hopefully" serialize bootstrap. Reasons for doing so include + * pragmatic performance optimizations and attempts to workaround bugs + * in jobs. My current thought is something like what follows. + * + * The BootCache would switch to launchd and add this to the plist: + * + * HopefullyStartsSerially + * + * ReadyTimeout + * 2 + * + * + * And kextd would add the following: + * + * HopefullyStartsSerially + * + * ReadyTimeout + * 5 + * HopefullyStartsAfter + * com.apple.BootCache.daemon + * + * + * + * Then both the BootCache and kextd could call something like: + * + * vproc_declare_ready_state(); + * + * To tell launchd to short circuit the readiness timeout and let the + * next wave of jobs start. + * + * Yes, this mechanism smells a lot like SystemStarter, rc.d and + * friends. I think as long as we document that artificial + * serialization is only advisory and not guaranteed, we should be + * fine. Remember: IPC is the preferred way to serialize operations. + * + */ + mach_timespec_t w = { 5, 0 }; + IOKitWaitQuiet(kIOMasterPortDefault, &w); - const char *SystemStarter_tool[] = { "SystemStarter", NULL }; - assumes(fwexec(SystemStarter_tool, false) != -1); + do_BootCache_magic(BOOTCACHE_TAG); - workaround4465949(); + do_bootroot_magic(); - if (path_check("/etc/rc.local")) { - const char *rc_local_tool[] = { _PATH_BSHELL, "/etc/rc.local", NULL }; - assumes(fwexec(rc_local_tool, false) != -1); - } + _vproc_set_global_on_demand(false); - return 0; + assumes(kevent(kq, NULL, 0, &kev, 1, NULL) == 1); + + do_BootCache_magic(BOOTCACHE_STOP); + + assumes(close(kq) != -1); } void -workaround4465949(void) +do_BootCache_magic(BootCache_action_t what) { - const char *pbs_tool[] = { "/System/Library/CoreServices/pbs", NULL }; - const char *lca_tool[] = { "/System/Library/CoreServices/Language Chooser.app/Contents/MacOS/Language Chooser", NULL}; - char *const reloadttys_argv[] = { "reloadttys", NULL }; - int wstatus; - pid_t pbs_p; + const char *bcc_tool[] = { "BootCacheControl", "-f", "/var/db/BootCache.playlist", NULL, NULL }; - if (path_check("/System/Library/LaunchDaemons/com.apple.loginwindow.plist")) { + if (is_safeboot()) { return; } - if (path_check(pbs_tool[0]) && path_check(lca_tool[0]) && - !path_check("/var/db/.AppleSetupDone") && - path_check("/var/db/.RunLanguageChooserToo")) { - if (assumes((pbs_p = fwexec(pbs_tool, false)) != -1)) { - assumes(fwexec(lca_tool, true) != -1); - assumes(kill(pbs_p, SIGTERM) != -1); - assumes(waitpid(pbs_p, &wstatus, 0) != -1); + switch (what) { + case BOOTCACHE_START: + bcc_tool[3] = "start"; + break; + case BOOTCACHE_TAG: + bcc_tool[3] = "tag"; + break; + case BOOTCACHE_STOP: + bcc_tool[3] = "stop"; + break; + default: + assumes(false); + return; + } + + fwexec(bcc_tool, true); +} + +int +bootstrap_cmd(int argc, char *const argv[]) +{ + char *session_type = NULL; + bool sflag = false; + int ch; + + while ((ch = getopt(argc, argv, "sS:")) != -1) { + switch (ch) { + case 's': + sflag = true; + break; + case 'S': + session_type = optarg; + break; + case '?': + default: + break; + } + } + + optind = 1; + optreset = 1; + + if (!session_type) { + fprintf(stderr, "usage: %s bootstrap [-s] -S \n", getprogname()); + return 1; + } + + if (strcasecmp(session_type, "System") == 0) { + system_specific_bootstrap(sflag); + } else { + char *load_launchd_items[] = { "load", "-S", session_type, "-D", "all", NULL, NULL, NULL, NULL }; + int the_argc = 5; + + if (is_safeboot()) { + load_launchd_items[4] = "system"; + } + + if (strcasecmp(session_type, VPROCMGR_SESSION_BACKGROUND) == 0 || strcasecmp(session_type, VPROCMGR_SESSION_LOGINWINDOW) == 0) { + load_launchd_items[4] = "system"; + if (!is_safeboot()) { + load_launchd_items[5] = "-D"; + load_launchd_items[6] = "local"; + the_argc += 2; + } + if (strcasecmp(session_type, VPROCMGR_SESSION_LOGINWINDOW) == 0) { + load_launchd_items[the_argc] = "/etc/mach_init_per_login_session.d"; + the_argc += 1; + } + } else if (strcasecmp(session_type, VPROCMGR_SESSION_AQUA) == 0) { + load_launchd_items[5] = "/etc/mach_init_per_user.d"; + the_argc += 1; } + +#if !TARGET_OS_EMBEDDED + if (strcasecmp(session_type, VPROCMGR_SESSION_BACKGROUND) == 0) { + assumes(SessionCreate(sessionKeepCurrentBootstrap, 0) == 0); + } +#endif + + return load_and_unload_cmd(the_argc, load_launchd_items); } - assumes(fyi_cmd(1, reloadttys_argv) == 0); + return 0; } int load_and_unload_cmd(int argc, char *const argv[]) { - NSSearchPathEnumerationState es = 0; + NSSearchPathEnumerationState es = 0; char nspath[PATH_MAX * 2]; /* safe side, we need to append */ bool badopts = false; struct load_unload_state lus; @@ -1305,8 +1635,9 @@ load_and_unload_cmd(int argc, char *const argv[]) memset(&lus, 0, sizeof(lus)); - if (!strcmp(argv[0], "load")) + if (strcmp(argv[0], "load") == 0) { lus.load = true; + } while ((ch = getopt(argc, argv, "wFS:D:")) != -1) { switch (ch) { @@ -1320,20 +1651,20 @@ load_and_unload_cmd(int argc, char *const argv[]) lus.session_type = optarg; break; case 'D': - if (strcasecmp(optarg, "all") == 0) { - es |= NSAllDomainsMask; - } else if (strcasecmp(optarg, "user") == 0) { - es |= NSUserDomainMask; - } else if (strcasecmp(optarg, "local") == 0) { - es |= NSLocalDomainMask; - } else if (strcasecmp(optarg, "network") == 0) { - es |= NSNetworkDomainMask; - } else if (strcasecmp(optarg, "system") == 0) { - es |= NSSystemDomainMask; - } else { + if (strcasecmp(optarg, "all") == 0) { + es |= NSAllDomainsMask; + } else if (strcasecmp(optarg, "user") == 0) { + es |= NSUserDomainMask; + } else if (strcasecmp(optarg, "local") == 0) { + es |= NSLocalDomainMask; + } else if (strcasecmp(optarg, "network") == 0) { + es |= NSNetworkDomainMask; + } else if (strcasecmp(optarg, "system") == 0) { + es |= NSSystemDomainMask; + } else { badopts = true; - } - break; + } + break; case '?': default: badopts = true; @@ -1343,11 +1674,13 @@ load_and_unload_cmd(int argc, char *const argv[]) argc -= optind; argv += optind; - if (lus.session_type == NULL) + if (lus.session_type == NULL) { es &= ~NSUserDomainMask; + } - if (argc == 0 && es == 0) + if (argc == 0 && es == 0) { badopts = true; + } if (badopts) { fprintf(stderr, "usage: %s load [-wF] [-D ] paths...\n", getprogname()); @@ -1386,17 +1719,20 @@ load_and_unload_cmd(int argc, char *const argv[]) } } - for (i = 0; i < (size_t)argc; i++) + for (i = 0; i < (size_t)argc; i++) { readpath(argv[i], &lus); + } if (launch_data_array_get_count(lus.pass0) == 0 && launch_data_array_get_count(lus.pass1) == 0 && launch_data_array_get_count(lus.pass2) == 0) { - fprintf(stderr, "nothing found to %s\n", lus.load ? "load" : "unload"); + if (!is_managed) { + fprintf(stderr, "nothing found to %s\n", lus.load ? "load" : "unload"); + } launch_data_free(lus.pass0); launch_data_free(lus.pass1); launch_data_free(lus.pass2); - return 1; + return is_managed ? 0 : 1; } if (lus.load) { @@ -1407,10 +1743,12 @@ load_and_unload_cmd(int argc, char *const argv[]) distill_jobs(lus.pass2); submit_job_pass(lus.pass2); } else { - for (i = 0; i < launch_data_array_get_count(lus.pass1); i++) + for (i = 0; i < launch_data_array_get_count(lus.pass1); i++) { unloadjob(launch_data_array_get_index(lus.pass1, i)); - for (i = 0; i < launch_data_array_get_count(lus.pass2); i++) + } + for (i = 0; i < launch_data_array_get_count(lus.pass2); i++) { unloadjob(launch_data_array_get_index(lus.pass2, i)); + } } return 0; @@ -1570,15 +1908,14 @@ start_stop_remove_cmd(int argc, char *const argv[]) } void -print_jobs(launch_data_t j) +print_jobs(launch_data_t j, const char *key __attribute__((unused)), void *context __attribute__((unused))) { static size_t depth = 0; launch_data_t lo = launch_data_dict_lookup(j, LAUNCH_JOBKEY_LABEL); launch_data_t pido = launch_data_dict_lookup(j, LAUNCH_JOBKEY_PID); launch_data_t stato = launch_data_dict_lookup(j, LAUNCH_JOBKEY_LASTEXITSTATUS); - launch_data_t sjobs = launch_data_dict_lookup(j, LAUNCH_JOBKEY_SUBJOBS); const char *label = launch_data_get_string(lo); - size_t i, c; + size_t i; if (pido) { fprintf(stdout, "%lld\t-\t", launch_data_get_integer(pido)); @@ -1598,19 +1935,6 @@ print_jobs(launch_data_t j) fprintf(stdout, "\t"); fprintf(stdout, "%s\n", label); - - if (sjobs) { - launch_data_t oai; - - c = launch_data_array_get_count(sjobs); - - depth++; - for (i = 0; i < c; i++) { - oai = launch_data_array_get_index(sjobs, i); - print_jobs(oai); - } - depth--; - } } void @@ -1673,16 +1997,22 @@ print_obj(launch_data_t obj, const char *key, void *context __attribute__((unuse int list_cmd(int argc, char *const argv[]) { - launch_data_t resp, msg = launch_data_alloc(LAUNCH_DATA_DICTIONARY); + launch_data_t resp, msg; int r = 0; if (argc > 2) { fprintf(stderr, "usage: %s list [label]\n", getprogname()); return 1; } else if (argc == 2) { + msg = launch_data_alloc(LAUNCH_DATA_DICTIONARY); launch_data_dict_insert(msg, launch_data_new_string(argv[1]), LAUNCH_KEY_GETJOB); + } else if (vproc_swap_complex(NULL, VPROC_GSK_ALLJOBS, NULL, &resp) == NULL) { + fprintf(stdout, "PID\tStatus\tLabel\n"); + launch_data_dict_iterate(resp, print_jobs, NULL); + launch_data_free(resp); + return 0; } else { - launch_data_dict_insert(msg, launch_data_new_string(""), LAUNCH_KEY_GETJOB); + return 1; } resp = launch_msg(msg); @@ -1692,12 +2022,7 @@ list_cmd(int argc, char *const argv[]) fprintf(stderr, "launch_msg(): %s\n", strerror(errno)); return 1; } else if (launch_data_get_type(resp) == LAUNCH_DATA_DICTIONARY) { - if (argc == 1) { - fprintf(stdout, "PID\tStatus\tLabel\n"); - print_jobs(resp); - } else { - print_obj(resp, NULL, NULL); - } + print_obj(resp, NULL, NULL); } else { fprintf(stderr, "%s %s returned unknown response\n", getprogname(), argv[0]); r = 1; @@ -1709,61 +2034,17 @@ list_cmd(int argc, char *const argv[]) } int -stdio_cmd(int argc, char *const argv[]) +stdio_cmd(int argc __attribute__((unused)), char *const argv[]) { - launch_data_t resp, msg, tmp; - int e, fd = -1, r = 0; - - if (argc != 2) { - fprintf(stderr, "usage: %s %s \n", getprogname(), argv[0]); - return 1; - } - - fd = open(argv[1], O_CREAT|O_APPEND|O_WRONLY|O_NOCTTY, DEFFILEMODE); - - msg = launch_data_alloc(LAUNCH_DATA_DICTIONARY); - - if (fd == -1) { - tmp = launch_data_new_string(argv[1]); - } else { - tmp = launch_data_new_fd(fd); - } - - if (!strcmp(argv[0], "stdout")) { - launch_data_dict_insert(msg, tmp, LAUNCH_KEY_SETSTDOUT); - } else { - launch_data_dict_insert(msg, tmp, LAUNCH_KEY_SETSTDERR); - } - - resp = launch_msg(msg); - launch_data_free(msg); - - if (resp == NULL) { - fprintf(stderr, "launch_msg(): %s\n", strerror(errno)); - return 1; - } else if (launch_data_get_type(resp) == LAUNCH_DATA_ERRNO) { - if ((e = launch_data_get_errno(resp))) { - fprintf(stderr, "%s %s error: %s\n", getprogname(), argv[0], strerror(e)); - r = 1; - } - } else { - fprintf(stderr, "%s %s returned unknown response\n", getprogname(), argv[0]); - r = 1; - } - - if (fd != -1) - close(fd); - - launch_data_free(resp); - - return r; + fprintf(stderr, "%s %s: This sub-command no longer does anything\n", getprogname(), argv[0]); + return 1; } int fyi_cmd(int argc, char *const argv[]) { launch_data_t resp, msg; - const char *lmsgk = LAUNCH_KEY_RELOADTTYS; + const char *lmsgk = NULL; int e, r = 0; if (argc != 1) { @@ -1775,6 +2056,8 @@ fyi_cmd(int argc, char *const argv[]) lmsgk = LAUNCH_KEY_SHUTDOWN; } else if (!strcmp(argv[0], "singleuser")) { lmsgk = LAUNCH_KEY_SINGLEUSER; + } else { + return 1; } msg = launch_data_new_string(lmsgk); @@ -1802,10 +2085,9 @@ fyi_cmd(int argc, char *const argv[]) int logupdate_cmd(int argc, char *const argv[]) { - launch_data_t resp, msg; - int e, i, j, r = 0, m = 0; + int64_t inval, outval; + int i, j, m = 0; bool badargs = false, maskmode = false, onlymode = false, levelmode = false; - const char *whichcmd = LAUNCH_KEY_SETLOGMASK; static const struct { const char *name; int level; @@ -1860,9 +2142,7 @@ logupdate_cmd(int argc, char *const argv[]) } if (j == logtblsz) badargs = true; - } else if (argc == 1) { - whichcmd = LAUNCH_KEY_GETLOGMASK; - } else { + } else if (argc != 1) { badargs = true; } @@ -1871,41 +2151,21 @@ logupdate_cmd(int argc, char *const argv[]) return 1; } - if (whichcmd == LAUNCH_KEY_SETLOGMASK) { - msg = launch_data_alloc(LAUNCH_DATA_DICTIONARY); - launch_data_dict_insert(msg, launch_data_new_integer(m), whichcmd); - } else { - msg = launch_data_new_string(whichcmd); - } - - resp = launch_msg(msg); - launch_data_free(msg); + inval = m; - if (resp == NULL) { - fprintf(stderr, "launch_msg(): %s\n", strerror(errno)); - return 1; - } else if (launch_data_get_type(resp) == LAUNCH_DATA_ERRNO) { - if ((e = launch_data_get_errno(resp))) { - fprintf(stderr, "%s %s error: %s\n", getprogname(), argv[0], strerror(e)); - r = 1; - } - } else if (launch_data_get_type(resp) == LAUNCH_DATA_INTEGER) { - if (whichcmd == LAUNCH_KEY_GETLOGMASK) { - m = launch_data_get_integer(resp); + if (vproc_swap_integer(NULL, VPROC_GSK_GLOBAL_LOG_MASK, argc != 1 ? &inval : NULL, &outval) == NULL) { + if (argc == 1) { for (j = 0; j < logtblsz; j++) { - if (m & LOG_MASK(logtbl[j].level)) + if (outval & LOG_MASK(logtbl[j].level)) { fprintf(stdout, "%s ", logtbl[j].name); + } } fprintf(stdout, "\n"); } + return 0; } else { - fprintf(stderr, "%s %s returned unknown response\n", getprogname(), argv[0]); - r = 1; + return 1; } - - launch_data_free(resp); - - return r; } static const struct { @@ -2072,11 +2332,10 @@ limit_cmd(int argc __attribute__((unused)), char *const argv[]) int umask_cmd(int argc, char *const argv[]) { - launch_data_t resp, msg; bool badargs = false; char *endptr; long m = 0; - int r = 0; + int64_t inval, outval; if (argc == 2) { m = strtol(argv[1], &endptr, 8); @@ -2089,32 +2348,16 @@ umask_cmd(int argc, char *const argv[]) return 1; } + inval = m; - if (argc == 1) { - msg = launch_data_new_string(LAUNCH_KEY_GETUMASK); + if (vproc_swap_integer(NULL, VPROC_GSK_GLOBAL_UMASK, argc == 2 ? &inval : NULL, &outval) == NULL) { + if (argc == 1) { + fprintf(stdout, "%o\n", (unsigned int)outval); + } + return 0; } else { - msg = launch_data_alloc(LAUNCH_DATA_DICTIONARY); - launch_data_dict_insert(msg, launch_data_new_integer(m), LAUNCH_KEY_SETUMASK); - } - resp = launch_msg(msg); - launch_data_free(msg); - - if (resp == NULL) { - fprintf(stderr, "launch_msg(): %s\n", strerror(errno)); return 1; - } else if (launch_data_get_type(resp) == LAUNCH_DATA_STRING) { - fprintf(stderr, "%s %s error: %s\n", getprogname(), argv[0], launch_data_get_string(resp)); - r = 1; - } else if (launch_data_get_type(resp) != LAUNCH_DATA_INTEGER) { - fprintf(stderr, "%s %s returned unknown response\n", getprogname(), argv[0]); - r = 1; - } else if (argc == 1) { - fprintf(stdout, "%o\n", (unsigned int)launch_data_get_integer(resp)); } - - launch_data_free(resp); - - return r; } int @@ -2313,9 +2556,12 @@ bsexec_cmd(int argc, char *const argv[]) setgid(getgid()); setuid(getuid()); - execvp(argv[2], argv + 2); - fprintf(stderr, "execvp(): %s\n", strerror(errno)); - return 1; + if (fwexec((const char *const *)argv + 2, true) == -1) { + fprintf(stderr, "%s bsexec failed: %s\n", getprogname(), strerror(errno)); + return 1; + } + + return 0; } int @@ -2354,7 +2600,7 @@ bool is_legacy_mach_job(launch_data_t obj) { bool has_servicename = launch_data_dict_lookup(obj, MACHINIT_JOBKEY_SERVICENAME); - bool has_command = launch_data_dict_lookup(obj, MACHINIT_JOBKEY_COMMAND); + bool has_command = launch_data_dict_lookup(obj, MACHINIT_JOBKEY_COMMAND); bool has_label = launch_data_dict_lookup(obj, LAUNCH_JOBKEY_LABEL); return has_command && has_servicename && !has_label; @@ -2466,7 +2712,9 @@ fwexec(const char *const *argv, bool _wait) case -1: break; case 0: - setsid(); + if (!_wait) { + setsid(); + } execvp(argv[0], (char *const *)argv); _exit(EXIT_FAILURE); break; @@ -2491,16 +2739,25 @@ do_potential_fsck(void) const char *remount_tool[] = { "mount", "-uw", "/", NULL }; struct statfs sfs; - if (assumes(statfs("/", &sfs) != -1)) { - if (!(sfs.f_flags & MNT_RDONLY)) { - fprintf(stdout, "Root file system is read-write, skipping fsck.\n"); - return; - } + if (!assumes(statfs("/", &sfs) != -1)) { + return; + } + + if (!(sfs.f_flags & MNT_RDONLY)) { + return; } if (!is_safeboot()) { - if (fwexec(fsck_tool, true) != -1) +#if 0 + /* We have disabled this block for now. We need to revisit this optimization after Leopard. */ + if (sfs.f_flags & MNT_JOURNALED) { goto out; + } +#endif + + if (fwexec(fsck_tool, true) != -1) { + goto out; + } } if (fwexec(safe_fsck_tool, true) != -1) { @@ -2511,6 +2768,16 @@ do_potential_fsck(void) return; out: + /* + * Once this is fixed: + * + * Mount flag updates should be possible with NULL as the forth argument to mount() + * + * We can then do this one system call instead of calling out a full blown process. + * + * assumes(mount(sfs.f_fstypename, "/", MNT_UPDATE, NULL) != -1); + */ + assumes(fwexec(remount_tool, true) != -1); } @@ -2551,34 +2818,66 @@ is_netboot(void) } void -apply_func_to_dir(const char *thedir, void (*thefunc)(const char *)) +empty_dir(const char *thedir, struct stat *psb) { struct dirent *de; + struct stat psb2; DIR *od; int currend_dir_fd; - if (!assumes((currend_dir_fd = open(".", 0)) != -1)) + if (!psb) { + psb = &psb2; + if (!assumes(lstat(thedir, psb) != -1)) { + return; + } + } + + if (!assumes((currend_dir_fd = open(".", 0)) != -1)) { return; + } - if (!assumes(chdir(thedir) != -1)) + if (!assumes(chdir(thedir) != -1)) { goto out; + } - if (!assumes(od = opendir("."))) + if (!assumes(od = opendir("."))) { goto out; + } while ((de = readdir(od))) { struct stat sb; - if (strcmp(de->d_name, ".") == 0) + if (strcmp(de->d_name, ".") == 0) { continue; - if (strcmp(de->d_name, "..") == 0) + } + + if (strcmp(de->d_name, "..") == 0) { continue; + } - if (assumes(stat(de->d_name, &sb) != -1)) { - if (S_ISDIR(sb.st_mode)) - apply_func_to_dir(de->d_name, thefunc); - thefunc(de->d_name); + if (!assumes(lstat(de->d_name, &sb) != -1)) { + continue; } + + if (psb->st_dev != sb.st_dev) { + assumes(unmount(de->d_name, MNT_FORCE) != -1); + + /* Let's lstat() again to see if the unmount() worked and what was under it */ + if (!assumes(lstat(de->d_name, &sb) != -1)) { + continue; + } + + if (!assumes(psb->st_dev == sb.st_dev)) { + continue; + } + } + + if (S_ISDIR(sb.st_mode)) { + empty_dir(de->d_name, &sb); + } + + assumes(lchflags(de->d_name, 0) != -1); + assumes(remove(de->d_name) != -1); } assumes(closedir(od) != -1); @@ -2588,13 +2887,6 @@ out: assumes(close(currend_dir_fd) != -1); } -void -empty_dir(const char *path) -{ - assumes(chflags(path, 0) != -1); - assumes(remove(path) != -1); -} - int touch_file(const char *path, mode_t m) { @@ -2618,18 +2910,25 @@ apply_sysctls_from_file(const char *thefile) return; while ((val = fgetln(sf, &ln_len))) { - if (ln_len == 0) + if (ln_len == 0) { continue; - if (!assumes((tmpstr = malloc(ln_len + 1)) != NULL)) + } + if (!assumes((tmpstr = malloc(ln_len + 1)) != NULL)) { continue; + } memcpy(tmpstr, val, ln_len); tmpstr[ln_len] = 0; val = tmpstr; + if (val[ln_len - 1] == '\n' || val[ln_len - 1] == '\r') { + val[ln_len - 1] = '\0'; + } + while (*val && isspace(*val)) val++; - if (*val == '\0' || *val == '#') + if (*val == '\0' || *val == '#') { goto skip_sysctl_tool; + } sysctl_tool[2] = val; assumes(fwexec(sysctl_tool, true) != -1); skip_sysctl_tool: @@ -2650,24 +2949,163 @@ do_sysversion_sysctl(void) /* ER: launchd should set kern.osversion very early in boot */ - if (getuid() != 0) - return; - if (sysctl(mib, 2, buf, &bufsz, NULL, 0) == -1) { fprintf(stderr, "sysctl(): %s\n", strerror(errno)); return; } - if (buf[0] != '\0') + if (buf[0] != '\0') { return; + } - versdict = _CFCopySystemVersionDictionary(); - buildvers = CFDictionaryGetValue(versdict, _kCFSystemVersionBuildVersionKey); - CFStringGetCString(buildvers, buf, sizeof(buf), kCFStringEncodingUTF8); + if (!assumes((versdict = _CFCopySystemVersionDictionary()))) { + return; + } - if (sysctl(mib, 2, NULL, 0, buf, strlen(buf) + 1) == -1) { - fprintf(stderr, "sysctl(): %s\n", strerror(errno)); + if (assumes((buildvers = CFDictionaryGetValue(versdict, _kCFSystemVersionBuildVersionKey)))) { + CFStringGetCString(buildvers, buf, sizeof(buf), kCFStringEncodingUTF8); + + assumes(sysctl(mib, 2, NULL, 0, buf, strlen(buf) + 1) != -1); } CFRelease(versdict); } + +void +do_application_firewall_magic(int sfd, launch_data_t thejob) +{ + const char *prog = NULL, *partialprog = NULL; + char *path, *pathtmp, **pathstmp; + char *paths[100]; + launch_data_t tmp; + + /* + * Sigh... + * setsockopt() with the executable path as the argument + */ + + if ((tmp = launch_data_dict_lookup(thejob, LAUNCH_JOBKEY_PROGRAM))) { + prog = launch_data_get_string(tmp); + } + + if (!prog) { + if ((tmp = launch_data_dict_lookup(thejob, LAUNCH_JOBKEY_PROGRAMARGUMENTS))) { + if ((tmp = launch_data_array_get_index(tmp, 0))) { + if (assumes((partialprog = launch_data_get_string(tmp)) != NULL)) { + if (partialprog[0] == '/') { + prog = partialprog; + } + } + } + } + } + + if (!prog) { + pathtmp = path = strdup(getenv("PATH")); + + pathstmp = paths; + + while ((*pathstmp = strsep(&pathtmp, ":"))) { + if (**pathstmp != '\0') { + pathstmp++; + } + } + + free(path); + pathtmp = alloca(MAXPATHLEN); + + pathstmp = paths; + + for (; *pathstmp; pathstmp++) { + snprintf(pathtmp, MAXPATHLEN, "%s/%s", *pathstmp, partialprog); + if (path_check(pathtmp)) { + prog = pathtmp; + break; + } + } + } + + if (assumes(prog != NULL)) { + /* The networking team has asked us to ignore the failure of this API if errno == ENOPROTOOPT */ + assumes(setsockopt(sfd, SOL_SOCKET, SO_EXECPATH, prog, strlen(prog) + 1) != -1 || errno == ENOPROTOOPT); + } +} + + +void +preheat_page_cache_hack(void) +{ + struct dirent *de; + DIR *thedir; + + /* Disable this hack for now */ + return; + + if ((thedir = opendir("/etc/preheat_at_boot")) == NULL) { + return; + } + + while ((de = readdir(thedir))) { + struct stat sb; + void *junkbuf; + int fd; + + if (de->d_name[0] == '.') { + continue; + } + + if ((fd = open(de->d_name, O_RDONLY)) == -1) { + continue; + } + + if (fstat(fd, &sb) != -1) { + if ((sb.st_size < 10*1024*1024) && (junkbuf = malloc((size_t)sb.st_size)) != NULL) { + assumes(read(fd, junkbuf, (size_t)sb.st_size) == (ssize_t)sb.st_size); + free(junkbuf); + } + } + + close(fd); + } + + closedir(thedir); +} + + +void +do_bootroot_magic(void) +{ + const char *kextcache_tool[] = { "kextcache", "-U", "/", NULL }; + CFTypeRef bootrootProp; + io_service_t chosen; + int wstatus; + pid_t p; + + chosen = IORegistryEntryFromPath(kIOMasterPortDefault, "IODeviceTree:/chosen"); + + if (!assumes(chosen)) { + return; + } + + bootrootProp = IORegistryEntryCreateCFProperty(chosen, CFSTR(kBootRootActiveKey), kCFAllocatorDefault, 0); + + IOObjectRelease(chosen); + + if (!bootrootProp) { + return; + } + + CFRelease(bootrootProp); + + if (!assumes((p = fwexec(kextcache_tool, false)) != -1)) { + return; + } + + if (!assumes(waitpid(p, &wstatus, 0) != -1)) { + return; + } + + if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus) == EX_OSFILE) { + assumes(reboot(RB_AUTOBOOT) != -1); + } +} diff --git a/launchd/src/launchd.8 b/launchd/src/launchd.8 index 30e9145..315b255 100644 --- a/launchd/src/launchd.8 +++ b/launchd/src/launchd.8 @@ -37,14 +37,10 @@ During boot is invoked by the kernel to run as the first process on the system and to further bootstrap the rest of the system. .Sh OPTIONS .Bl -tag -width -indent -.It Fl d -Daemonize. Useful when passing a command to launchd on the command line. .It Fl D Debug. Prints syslog messages to stderr and adjusts logging via .Xr syslog 3 to LOG_DEBUG. -.It Fl S Ar SessionType -Instruct launchd to which session type it is. .El .Sh OPTIONS WHEN RUN AS PID 1 .Bl -tag -width -indent diff --git a/launchd/src/launchd.c b/launchd/src/launchd.c index e7acf68..955bdd0 100644 --- a/launchd/src/launchd.c +++ b/launchd/src/launchd.c @@ -18,7 +18,10 @@ * @APPLE_APACHE_LICENSE_HEADER_END@ */ -static const char *const __rcs_file_version__ = "$Revision: 1.217 $"; +static const char *const __rcs_file_version__ = "$Revision: 23408 $"; + +#include "config.h" +#include "launchd.h" #include #include @@ -38,6 +41,7 @@ static const char *const __rcs_file_version__ = "$Revision: 1.217 $"; #include #include #include +#include #include #include #include @@ -46,7 +50,6 @@ static const char *const __rcs_file_version__ = "$Revision: 1.217 $"; #include #include #include -#include #include #include #include @@ -59,478 +62,222 @@ static const char *const __rcs_file_version__ = "$Revision: 1.217 $"; #include #include #include -#include +#include +#include +#include -#include "bootstrap_public.h" -#include "bootstrap_private.h" -#include "launch.h" -#include "launch_priv.h" -#include "launchd.h" +#include "libbootstrap_public.h" +#include "libvproc_public.h" +#include "libvproc_internal.h" +#include "liblaunch_public.h" + +#include "launchd_runtime.h" #include "launchd_core_logic.h" #include "launchd_unix_ipc.h" -#include "launchd_internalServer.h" -#include "launchd_internal.h" -#include "notifyServer.h" -#include "bootstrapServer.h" - -union MaxRequestSize { - union __RequestUnion__do_notify_subsystem req; - union __ReplyUnion__do_notify_subsystem rep; - union __RequestUnion__x_launchd_internal_subsystem req2; - union __ReplyUnion__x_launchd_internal_subsystem rep2; - union __RequestUnion__x_bootstrap_subsystem req3; - union __ReplyUnion__x_bootstrap_subsystem rep3; -}; - -static boolean_t launchd_internal_demux(mach_msg_header_t *Request, mach_msg_header_t *Reply); - -#define PID1LAUNCHD_CONF "/etc/launchd.conf" #define LAUNCHD_CONF ".launchd.conf" -#define LAUNCHCTL_PATH "/bin/launchctl" #define SECURITY_LIB "/System/Library/Frameworks/Security.framework/Versions/A/Security" +#define SHUTDOWN_LOG_DIR "/var/log/shutdown" + extern char **environ; -static void async_callback(void); -static void signal_callback(void *, struct kevent *); -static void fs_callback(void); -static void ppidexit_callback(void); static void pfsystem_callback(void *, struct kevent *); -static kq_callback kqasync_callback = (kq_callback)async_callback; -static kq_callback kqsignal_callback = signal_callback; -static kq_callback kqfs_callback = (kq_callback)fs_callback; -static kq_callback kqppidexit_callback = (kq_callback)ppidexit_callback; static kq_callback kqpfsystem_callback = pfsystem_callback; -static void pid1_magic_init(bool sflag); - -static void usage(FILE *where); +static void pid1_magic_init(void); static void testfd_or_openfd(int fd, const char *path, int flags); static bool get_network_state(void); static void monitor_networking_state(void); -static void *kqueue_demand_loop(void *arg); +static void fatal_signal_handler(int sig, siginfo_t *si, void *uap); +static void handle_pid1_crashes_separately(void); +static void prep_shutdown_log_dir(void); -static pthread_t kqueue_demand_thread; -static int mainkq = 0; -static int asynckq = 0; static bool re_exec_in_single_user_mode = false; -static char *pending_stdout = NULL; -static char *pending_stderr = NULL; -static struct jobcb *rlcj = NULL; +static void *crash_addr; +static pid_t crash_pid; -sigset_t blocked_signals = 0; -bool shutdown_in_progress = false; +static bool shutdown_in_progress = false; +bool debug_shutdown_hangs = false; bool network_up = false; -int batch_disabler_count = 0; -mach_port_t launchd_internal_port = MACH_PORT_NULL; -mach_port_t ipc_port_set = MACH_PORT_NULL; int main(int argc, char *const *argv) { - static const int sigigns[] = { SIGHUP, SIGINT, SIGPIPE, SIGALRM, - SIGTERM, SIGURG, SIGTSTP, SIGTSTP, SIGCONT, /*SIGCHLD,*/ - SIGTTIN, SIGTTOU, SIGIO, SIGXCPU, SIGXFSZ, SIGVTALRM, SIGPROF, - SIGWINCH, SIGINFO, SIGUSR1, SIGUSR2 - }; - bool sflag = false, dflag = false, Dflag = false; - mach_msg_type_number_t l2l_name_cnt = 0, l2l_port_cnt = 0; - name_array_t l2l_names = NULL; - mach_port_array_t l2l_ports = NULL; - char ldconf[PATH_MAX] = PID1LAUNCHD_CONF; - const char *h = getenv("HOME"); - const char *session_type = NULL; - const char *optargs = NULL; - launch_data_t ldresp, ldmsg = launch_data_new_string(LAUNCH_KEY_CHECKIN); - struct jobcb *fbj = NULL; - struct stat sb; - size_t i, checkin_fdcnt = 0; - int *checkin_fds = NULL; - mach_port_t req_mport = MACH_PORT_NULL; - mach_port_t checkin_mport = MACH_PORT_NULL; - int ch, ker, logopts; - - /* main() phase one: sanitize the process */ - - if (getpid() != 1 && (ldresp = launch_msg(ldmsg)) && launch_data_get_type(ldresp) == LAUNCH_DATA_DICTIONARY) { - const char *ldlabel = launch_data_get_string(launch_data_dict_lookup(ldresp, LAUNCH_JOBKEY_LABEL)); - launch_data_t tmp; - - if ((tmp = launch_data_dict_lookup(ldresp, LAUNCH_JOBKEY_SOCKETS))) { - if ((tmp = launch_data_dict_lookup(tmp, "LaunchIPC"))) { - checkin_fdcnt = launch_data_array_get_count(tmp); - checkin_fds = alloca(sizeof(int) * checkin_fdcnt); - for (i = 0; i < checkin_fdcnt; i++) { - checkin_fds[i] = _fd(launch_data_get_fd(launch_data_array_get_index(tmp, i))); - } - } - } - if ((tmp = launch_data_dict_lookup(ldresp, LAUNCH_JOBKEY_MACHSERVICES))) { - if ((tmp = launch_data_dict_lookup(tmp, ldlabel))) { - checkin_mport = launch_data_get_machport(tmp); - } - } - launch_data_free(ldresp); - } else { - int sigi, fdi, dts = getdtablesize(); - sigset_t emptyset; - - for (fdi = STDERR_FILENO + 1; fdi < dts; fdi++) - close(fdi); - for (sigi = 1; sigi < NSIG; sigi++) - launchd_assumes(signal(sigi, SIG_DFL) != SIG_ERR); - sigemptyset(&emptyset); - launchd_assumes(sigprocmask(SIG_SETMASK, &emptyset, NULL) == 0); - } - - launch_data_free(ldmsg); + bool sflag = false; + int ch; - testfd_or_openfd(STDIN_FILENO, _PATH_DEVNULL, O_RDONLY|O_NOCTTY); - testfd_or_openfd(STDOUT_FILENO, _PATH_DEVNULL, O_WRONLY|O_NOCTTY); - testfd_or_openfd(STDERR_FILENO, _PATH_DEVNULL, O_WRONLY|O_NOCTTY); - - /* main phase two: parse arguments */ - - if (getpid() == 1) { - optargs = "s"; - } else { - optargs = "DS:dh"; - } + testfd_or_openfd(STDIN_FILENO, _PATH_DEVNULL, O_RDONLY); + testfd_or_openfd(STDOUT_FILENO, _PATH_DEVNULL, O_WRONLY); + testfd_or_openfd(STDERR_FILENO, _PATH_DEVNULL, O_WRONLY); - while ((ch = getopt(argc, argv, optargs)) != -1) { + while ((ch = getopt(argc, argv, "s")) != -1) { switch (ch) { - case 'S': session_type = optarg; break; /* what type of session we're creating */ - case 'D': Dflag = true; break; /* debug */ - case 'd': dflag = true; break; /* daemonize */ - case 's': sflag = true; break; /* single user */ - case 'h': usage(stdout); break; /* help */ + case 's': sflag = true; break; /* single user */ case '?': /* we should do something with the global optopt variable here */ default: - fprintf(stderr, "ignoring unknown arguments\n"); - usage(stderr); + fprintf(stderr, "%s: ignoring unknown arguments\n", getprogname()); break; } } - argc -= optind; - argv += optind; - /* main phase three: get the party started */ - - if (dflag) - launchd_assumes(daemon(0, 0) == 0); - - launchd_assert((errno = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_PORT_SET, &ipc_port_set)) == KERN_SUCCESS); - launchd_assert(launchd_mport_create_recv(&launchd_internal_port) == KERN_SUCCESS); - launchd_assert(launchd_mport_make_send(launchd_internal_port) == KERN_SUCCESS); - launchd_assert((errno = mach_port_move_member(mach_task_self(), launchd_internal_port, ipc_port_set)) == KERN_SUCCESS); - - logopts = LOG_PID|LOG_CONS; - if (Dflag) - logopts |= LOG_PERROR; - - openlog(getprogname(), logopts, LOG_LAUNCHD); - setlogmask(LOG_UPTO(Dflag ? LOG_DEBUG : LOG_NOTICE)); - - launchd_assert((mainkq = kqueue()) != -1); - - launchd_assert((asynckq = kqueue()) != -1); - - launchd_assert(kevent_mod(asynckq, EVFILT_READ, EV_ADD, 0, 0, &kqasync_callback) != -1); - - sigemptyset(&blocked_signals); - - for (i = 0; i < (sizeof(sigigns) / sizeof(int)); i++) { - launchd_assumes(kevent_mod(sigigns[i], EVFILT_SIGNAL, EV_ADD, 0, 0, &kqsignal_callback) != -1); - sigaddset(&blocked_signals, sigigns[i]); - launchd_assumes(signal(sigigns[i], SIG_IGN) != SIG_ERR); + if (getpid() != 1 && getppid() != 1) { + fprintf(stderr, "%s: This program is not meant to be run directly.\n", getprogname()); + exit(EXIT_FAILURE); } - /* sigh... ignoring SIGCHLD has side effects: we can't call wait*() */ - launchd_assert(kevent_mod(SIGCHLD, EVFILT_SIGNAL, EV_ADD, 0, 0, &kqsignal_callback) != -1); - - if (session_type && strcmp(session_type, "Aqua") == 0) { - mach_port_t newparent; - - launchd_assert(bootstrap_parent(bootstrap_port, &newparent) == BOOTSTRAP_SUCCESS); + launchd_runtime_init(); - launchd_assert(_launchd_to_launchd(bootstrap_port, &req_mport, &checkin_mport, - &l2l_names, &l2l_name_cnt, &l2l_ports, &l2l_port_cnt) == BOOTSTRAP_SUCCESS); - - launchd_assert(l2l_name_cnt == l2l_port_cnt); - - task_set_bootstrap_port(mach_task_self(), newparent); - launchd_assumes(mach_port_deallocate(mach_task_self(), bootstrap_port) == KERN_SUCCESS); - bootstrap_port = newparent; - } - - mach_init_init(req_mport, checkin_mport, l2l_names, l2l_ports, l2l_name_cnt); - - if (h) - sprintf(ldconf, "%s/%s", h, LAUNCHD_CONF); - - rlcj = job_new(root_job, READCONF_LABEL, LAUNCHCTL_PATH, NULL, ldconf, MACH_PORT_NULL); - launchd_assert(rlcj != NULL); - - if (argv[0]) - fbj = job_new(root_job, FIRSTBORN_LABEL, NULL, (const char *const *)argv, NULL, MACH_PORT_NULL); - - if (NULL == getenv("PATH")) + if (NULL == getenv("PATH")) { setenv("PATH", _PATH_STDPATH, 1); + } if (getpid() == 1) { - pid1_magic_init(sflag); + pid1_magic_init(); } else { - ipc_server_init(checkin_fds, checkin_fdcnt); + ipc_server_init(); } monitor_networking_state(); - /* do this after pid1_magic_init() to not catch ourselves mounting stuff */ - launchd_assumes(kevent_mod(0, EVFILT_FS, EV_ADD, 0, 0, &kqfs_callback) != -1); - - if (session_type) { - pid_t pp = getppid(); - - /* As a per session launchd, we need to exit if our parent dies. - * - * Normally, in Unix, SIGHUP would cause us to exit, but we're a - * daemon, and daemons use SIGHUP to signal the need to reread - * configuration files. "Weee." - */ - - if (pp == 1) - exit(EXIT_SUCCESS); - - ker = kevent_mod(pp, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, &kqppidexit_callback); - - if (ker == -1) - exit(launchd_assumes(errno == ESRCH) ? EXIT_SUCCESS : EXIT_FAILURE); + if (getpid() == 1) { + handle_pid1_crashes_separately(); } - if (stat(ldconf, &sb) == 0) - job_start(rlcj); - - if (fbj) - job_start(fbj); - - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); - pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN); - launchd_assert(pthread_create(&kqueue_demand_thread, &attr, kqueue_demand_loop, NULL) == 0); - pthread_attr_destroy(&attr); - - mach_msg_return_t msgr; - mach_msg_size_t mxmsgsz = sizeof(union MaxRequestSize) + MAX_TRAILER_SIZE; + jobmgr_init(sflag); - if (getpid() == 1 && !job_active(rlcj)) - init_pre_kevent(); + launchd_runtime_init2(); - for (;;) { - msgr = mach_msg_server(launchd_internal_demux, mxmsgsz, ipc_port_set, - MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT) | - MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0)); - launchd_assumes(msgr == MACH_MSG_SUCCESS); - } + launchd_runtime(); } -void * -kqueue_demand_loop(void *arg __attribute__((unused))) +void +handle_pid1_crashes_separately(void) { - fd_set rfds; + struct sigaction fsa; - for (;;) { - FD_ZERO(&rfds); - FD_SET(mainkq, &rfds); - if (launchd_assumes(select(mainkq + 1, &rfds, NULL, NULL, NULL) == 1)) - launchd_assumes(handle_kqueue(launchd_internal_port, mainkq) == 0); - } + fsa.sa_sigaction = fatal_signal_handler; + fsa.sa_flags = SA_SIGINFO; + sigemptyset(&fsa.sa_mask); - return NULL; + launchd_assumes(sigaction(SIGILL, &fsa, NULL) != -1); + launchd_assumes(sigaction(SIGFPE, &fsa, NULL) != -1); + launchd_assumes(sigaction(SIGBUS, &fsa, NULL) != -1); + launchd_assumes(sigaction(SIGSEGV, &fsa, NULL) != -1); } -kern_return_t -x_handle_kqueue(mach_port_t junk __attribute__((unused)), integer_t fd) -{ - struct timespec ts = { 0, 0 }; - struct kevent kev; - int kevr; +#define PID1_CRASH_LOGFILE "/var/log/launchd-pid1.crash" - launchd_assumes((kevr = kevent(fd, NULL, 0, &kev, 1, &ts)) != -1); +/* This hack forces the dynamic linker to resolve these symbols ASAP */ +static __attribute__((unused)) typeof(sync) *__junk_dyld_trick1 = sync; +static __attribute__((unused)) typeof(sleep) *__junk_dyld_trick2 = sleep; +static __attribute__((unused)) typeof(reboot) *__junk_dyld_trick3 = reboot; - if (kevr == 1) - (*((kq_callback *)kev.udata))(kev.udata, &kev); +void +fatal_signal_handler(int sig, siginfo_t *si, void *uap) +{ + const char *doom_why = "at instruction"; + char *sample_args[] = { "/usr/bin/sample", "1", "1", "-file", PID1_CRASH_LOGFILE, NULL }; + pid_t sample_p; + int wstatus; - if (shutdown_in_progress && total_children == 0) { - mach_init_reap(); + crash_addr = si->si_addr; + crash_pid = si->si_pid; - shutdown_in_progress = false; + unlink(PID1_CRASH_LOGFILE); - if (getpid() != 1) { - exit(EXIT_SUCCESS); - } else if (re_exec_in_single_user_mode) { - re_exec_in_single_user_mode = false; - launchd_assumes(execl("/sbin/launchd", "/sbin/launchd", "-s", NULL) != -1); - } + switch ((sample_p = vfork())) { + case 0: + execve(sample_args[0], sample_args, environ); + _exit(EXIT_FAILURE); + break; + default: + waitpid(sample_p, &wstatus, 0); + break; + case -1: + break; } - if (getpid() == 1) { - if (rlcj && job_active(rlcj)) - goto out; - init_pre_kevent(); + switch (sig) { + default: + case 0: + break; + case SIGBUS: + case SIGSEGV: + doom_why = "trying to read/write"; + case SIGILL: + case SIGFPE: + runtime_syslog(LOG_EMERG, "We crashed %s: %p (sent by PID %u)", doom_why, crash_addr, crash_pid); + sync(); + sleep(3); + reboot(0); + break; } - -out: - return 0; } void -pid1_magic_init(bool sflag) +pid1_magic_init(void) { launchd_assumes(setsid() != -1); launchd_assumes(chdir("/") != -1); launchd_assumes(setlogin("root") != -1); launchd_assumes(mount("fdesc", "/dev", MNT_UNION, NULL) != -1); - - init_boot(sflag); -} - - -void -usage(FILE *where) -{ - const char *opts = "[-d]"; - - if (getuid() == 0) - opts = "[-d] [-S -U ]"; - - fprintf(where, "%s: %s [-- command [args ...]]\n", getprogname(), opts); - - fprintf(where, "\t-d Daemonize.\n"); - fprintf(where, "\t-h This usage statement.\n"); - - if (getuid() == 0) { - fprintf(where, "\t-S What type of session to create (Aqua, tty or X11).\n"); - fprintf(where, "\t-U Which user to create the session as.\n"); - } - - if (where == stdout) - exit(EXIT_SUCCESS); } -int -kevent_mod(uintptr_t ident, short filter, u_short flags, u_int fflags, intptr_t data, void *udata) -{ - struct kevent kev; - int q = mainkq; - - if (EVFILT_TIMER == filter || EVFILT_VNODE == filter) - q = asynckq; - - if (flags & EV_ADD && !launchd_assumes(udata != NULL)) { - errno = EINVAL; - return -1; - } - - EV_SET(&kev, ident, filter, flags, fflags, data, udata); - return kevent(q, &kev, 1, NULL, 0, NULL); -} int _fd(int fd) { - if (fd >= 0) + if (fd >= 0) { launchd_assumes(fcntl(fd, F_SETFD, 1) != -1); + } return fd; } void -ppidexit_callback(void) +prep_shutdown_log_dir(void) { - launchd_shutdown(); - - /* Let's just bail for now. We should really try to wait for jobs to exit first. */ - exit(EXIT_SUCCESS); + launchd_assumes(mkdir(SHUTDOWN_LOG_DIR, S_IRWXU) != -1 || errno == EEXIST); } void launchd_shutdown(void) { - shutdown_in_progress = true; + struct stat sb; + + if (shutdown_in_progress) { + return; + } - launchd_assumes(close(asynckq) != -1); - - rlcj = NULL; + shutdown_in_progress = true; - job_remove_all_inactive(root_job); + if (getpid() == 1 && stat("/var/db/debugShutdownHangs", &sb) != -1) { + /* + * When this changes to a more sustainable API, update this: + * http://howto.apple.com/db.cgi?Debugging_Apps_Non-Responsive_At_Shutdown + */ + runtime_setlogmask(LOG_UPTO(LOG_DEBUG)); + prep_shutdown_log_dir(); + debug_shutdown_hangs = true; + } - if (getpid() == 1) - catatonia(); + launchd_assert(jobmgr_shutdown(root_jobmgr) != NULL); } void launchd_single_user(void) { - int tries; - - launchd_shutdown(); + runtime_syslog(LOG_NOTICE, "Going to single-user mode"); - kill(-1, SIGTERM); - - for (tries = 0; tries < 10; tries++) { - sleep(1); - if (kill(-1, 0) == -1 && errno == ESRCH) - goto out; - } - - syslog(LOG_WARNING, "Gave up waiting for processes to exit while going to single user mode, sending SIGKILL"); - kill(-1, SIGKILL); - -out: re_exec_in_single_user_mode = true; -} -static void signal_callback(void *obj __attribute__((unused)), struct kevent *kev) -{ - switch (kev->ident) { - case SIGHUP: - if (rlcj) - job_start(rlcj); - break; - case SIGTERM: - launchd_shutdown(); - break; - default: - break; - } -} + launchd_shutdown(); -void -fs_callback(void) -{ - if (pending_stdout) { - int fd = open(pending_stdout, O_CREAT|O_APPEND|O_WRONLY|O_NOCTTY, DEFFILEMODE); - if (fd != -1) { - launchd_assumes(dup2(fd, STDOUT_FILENO) != -1); - launchd_assumes(close(fd) == 0); - free(pending_stdout); - pending_stdout = NULL; - } - } - if (pending_stderr) { - int fd = open(pending_stderr, O_CREAT|O_APPEND|O_WRONLY|O_NOCTTY, DEFFILEMODE); - if (fd != -1) { - launchd_assumes(dup2(fd, STDERR_FILENO) != -1); - launchd_assumes(close(fd) == 0); - free(pending_stderr); - pending_stderr = NULL; - } - } + sleep(3); - ipc_server_init(NULL, 0); + runtime_kill(-1, SIGKILL); } void @@ -540,93 +287,57 @@ launchd_SessionCreate(void) void *seclib; if (launchd_assumes((seclib = dlopen(SECURITY_LIB, RTLD_LAZY)) != NULL)) { - if (launchd_assumes((sescr = dlsym(seclib, "SessionCreate")) != NULL)) + if (launchd_assumes((sescr = dlsym(seclib, "SessionCreate")) != NULL)) { launchd_assumes(sescr(0, 0) == noErr); + } launchd_assumes(dlclose(seclib) != -1); } } -void -async_callback(void) -{ - struct timespec timeout = { 0, 0 }; - struct kevent kev; - - if (launchd_assumes(kevent(asynckq, NULL, 0, &kev, 1, &timeout) == 1)) - (*((kq_callback *)kev.udata))(kev.udata, &kev); -} - void testfd_or_openfd(int fd, const char *path, int flags) { int tmpfd; if (-1 != (tmpfd = dup(fd))) { - launchd_assumes(close(tmpfd) == 0); + launchd_assumes(runtime_close(tmpfd) == 0); } else { - if (-1 == (tmpfd = open(path, flags))) { - syslog(LOG_ERR, "open(\"%s\", ...): %m", path); + if (-1 == (tmpfd = open(path, flags | O_NOCTTY, DEFFILEMODE))) { + runtime_syslog(LOG_ERR, "open(\"%s\", ...): %m", path); } else if (tmpfd != fd) { launchd_assumes(dup2(tmpfd, fd) != -1); - launchd_assumes(close(tmpfd) == 0); + launchd_assumes(runtime_close(tmpfd) == 0); } } } -launch_data_t -launchd_setstdio(int d, launch_data_t o) -{ - launch_data_t resp = launch_data_new_errno(0); - - if (launch_data_get_type(o) == LAUNCH_DATA_STRING) { - char **where = &pending_stderr; - - if (d == STDOUT_FILENO) - where = &pending_stdout; - if (*where) - free(*where); - *where = strdup(launch_data_get_string(o)); - } else if (launch_data_get_type(o) == LAUNCH_DATA_FD) { - launchd_assumes(dup2(launch_data_get_fd(o), d) != -1); - } else { - launch_data_set_errno(resp, EINVAL); - } - - return resp; -} - -void -batch_job_enable(bool e, struct conncb *c) -{ - if (e && c->disabled_batch) { - batch_disabler_count--; - c->disabled_batch = 0; - if (batch_disabler_count == 0) - kevent_mod(asynckq, EVFILT_READ, EV_ENABLE, 0, 0, &kqasync_callback); - } else if (!e && !c->disabled_batch) { - if (batch_disabler_count == 0) - kevent_mod(asynckq, EVFILT_READ, EV_DISABLE, 0, 0, &kqasync_callback); - batch_disabler_count++; - c->disabled_batch = 1; - } -} - bool get_network_state(void) { struct ifaddrs *ifa, *ifai; bool up = false; + int r; + + /* Workaround 4978696: getifaddrs() reports false ENOMEM */ + while ((r = getifaddrs(&ifa)) == -1 && errno == ENOMEM) { + runtime_syslog(LOG_DEBUG, "Worked around bug: 4978696"); + launchd_assumes(sched_yield() != -1); + } - if (!launchd_assumes(getifaddrs(&ifa) != -1)) + if (!launchd_assumes(r != -1)) { return network_up; + } for (ifai = ifa; ifai; ifai = ifai->ifa_next) { - if (!(ifai->ifa_flags & IFF_UP)) + if (!(ifai->ifa_flags & IFF_UP)) { continue; - if (ifai->ifa_flags & IFF_LOOPBACK) + } + if (ifai->ifa_flags & IFF_LOOPBACK) { continue; - if (ifai->ifa_addr->sa_family != AF_INET && ifai->ifa_addr->sa_family != AF_INET6) + } + if (ifai->ifa_addr->sa_family != AF_INET && ifai->ifa_addr->sa_family != AF_INET6) { continue; + } up = true; break; } @@ -644,15 +355,16 @@ monitor_networking_state(void) network_up = get_network_state(); - if (!launchd_assumes(pfs != -1)) + if (!launchd_assumes(pfs != -1)) { return; + } memset(&kev_req, 0, sizeof(kev_req)); kev_req.vendor_code = KEV_VENDOR_APPLE; kev_req.kev_class = KEV_NETWORK_CLASS; if (!launchd_assumes(ioctl(pfs, SIOCSKEVFILT, &kev_req) != -1)) { - close(pfs); + runtime_close(pfs); return; } @@ -671,7 +383,7 @@ pfsystem_callback(void *obj, struct kevent *kev) if (new_networking_state != network_up) { network_up = new_networking_state; - job_dispatch_all_other_semaphores(root_job, NULL); + jobmgr_dispatch_all_semaphores(root_jobmgr); } } @@ -694,53 +406,10 @@ _log_launchd_bug(const char *rcs_rev, const char *path, unsigned int line, const } else { strlcpy(buf, rcs_rev_tmp + 1, sizeof(buf)); rcs_rev_tmp = strchr(buf, ' '); - if (rcs_rev_tmp) + if (rcs_rev_tmp) { *rcs_rev_tmp = '\0'; - } - - syslog(LOG_NOTICE, "Bug: %s:%u (%s):%u: %s", file, line, buf, saved_errno, test); -} - -bool -progeny_check(pid_t p) -{ - pid_t selfpid = getpid(); - - while (p != selfpid && p != 1) { - int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, p }; - size_t miblen = sizeof(mib) / sizeof(mib[0]); - struct kinfo_proc kp; - size_t kplen = sizeof(kp); - - if (launchd_assumes(sysctl(mib, miblen, &kp, &kplen, NULL, 0) != -1) - && launchd_assumes(kplen == sizeof(kp))) { - p = kp.kp_eproc.e_ppid; - } else { - return false; } } - if (p == selfpid) - return true; - - return false; -} - -boolean_t -launchd_internal_demux(mach_msg_header_t *Request, mach_msg_header_t *Reply) -{ - if (gc_this_job) { - job_remove(gc_this_job); - gc_this_job = NULL; - } - - if (Request->msgh_local_port == launchd_internal_port) { - if (launchd_internal_server_routine(Request)) - return launchd_internal_server(Request, Reply); - } else { - if (bootstrap_server_routine(Request)) - return bootstrap_server(Request, Reply); - } - - return notify_server(Request, Reply); + runtime_syslog(LOG_NOTICE, "Bug: %s:%u (%s):%u: %s", file, line, buf, saved_errno, test); } diff --git a/launchd/src/launchd.h b/launchd/src/launchd.h index cfc0c55..9aa37db 100644 --- a/launchd/src/launchd.h +++ b/launchd/src/launchd.h @@ -22,74 +22,28 @@ #include #include -#include "launch.h" -#include "bootstrap_public.h" +#include "liblaunch_public.h" +#include "libbootstrap_public.h" +#include "launchd_runtime.h" -/* - * Use launchd_assumes() when we can recover, even if it means we leak or limp along. - * - * Use launchd_assert() for core initialization routines. - */ -#define launchd_assumes(e) \ - (__builtin_expect(!(e), 0) ? _log_launchd_bug(__rcs_file_version__, __FILE__, __LINE__, #e), false : true) - -#define launchd_blame(e, b) \ - (__builtin_expect(!(e), 0) ? syslog(LOG_DEBUG, "Encountered bug: %d", b), false : true) - -#define launchd_assert(e) launchd_assumes(e) ? true : abort(); - -#define FIRSTBORN_LABEL "com.apple.launchd.firstborn" -#define READCONF_LABEL "com.apple.launchd.readconfig" +#define SHUTDOWN_LOG_DIR "/var/log/shutdown" struct kevent; struct conncb; -typedef void (*kq_callback)(void *, struct kevent *); - -extern kq_callback kqsimple_zombie_reaper; -extern sigset_t blocked_signals; -extern bool shutdown_in_progress; +extern bool debug_shutdown_hangs; extern bool network_up; -extern int batch_disabler_count; -extern mach_port_t launchd_internal_port; -extern mach_port_t ipc_port_set; bool init_check_pid(pid_t); -int kevent_mod(uintptr_t ident, short filter, u_short flags, u_int fflags, intptr_t data, void *udata); -void batch_job_enable(bool e, struct conncb *c); - launch_data_t launchd_setstdio(int d, launch_data_t o); void launchd_SessionCreate(void); void launchd_shutdown(void); void launchd_single_user(void); -pid_t launchd_fork(void); boolean_t launchd_mach_ipc_demux(mach_msg_header_t *Request, mach_msg_header_t *Reply); -kern_return_t launchd_set_bport(mach_port_t name); -kern_return_t launchd_get_bport(mach_port_t *name); -kern_return_t launchd_mport_notify_req(mach_port_t name, mach_msg_id_t which); -kern_return_t launchd_mport_notify_cancel(mach_port_t name, mach_msg_id_t which); -kern_return_t launchd_mport_request_callback(mach_port_t name, void *obj, bool readmsg); -kern_return_t launchd_mport_create_recv(mach_port_t *name); -kern_return_t launchd_mport_deallocate(mach_port_t name); -kern_return_t launchd_mport_make_send(mach_port_t name); -kern_return_t launchd_mport_close_recv(mach_port_t name); - -void init_boot(bool sflag); -void init_pre_kevent(void); - -void update_ttys(void); -void catatonia(void); - void mach_start_shutdown(void); -void mach_init_init(mach_port_t, mach_port_t, name_array_t, mach_port_array_t, mach_msg_type_number_t); -void mach_init_reap(void); int _fd(int fd); -void _log_launchd_bug(const char *rcs_rev, const char *path, unsigned int line, const char *test); - -bool progeny_check(pid_t p); - #endif diff --git a/launchd/src/launchd.plist.5 b/launchd/src/launchd.plist.5 index 7105f01..4fccc18 100644 --- a/launchd/src/launchd.plist.5 +++ b/launchd/src/launchd.plist.5 @@ -106,13 +106,17 @@ This configuration file only applies to hosts NOT listed with this key. This configuration file only applies to sessions of the type specified. This key is used in concert with the -S flag to .Nm launchctl . -.It Sy ProgramArguments -This required key maps to the second argument of -.Xr execvp 3 . .It Sy Program -This optional key maps to the first argument of +This key maps to the first argument of .Xr execvp 3 . If this key is missing, then the first element of the array of strings provided to the ProgramArguments will be used instead. +This key is required in the absence of the ProgramArguments key. +.It Sy ProgramArguments +This key maps to the second argument of +.Xr execvp 3 . +This key is required in the absence of the Program key. Please note! Many people are confused by this key. Please read +.Xr execvp 3 +very carefully! .It Sy EnableGlobbing This flag causes .Nm launchd @@ -151,6 +155,11 @@ Each key in this dictionary is a file-system path. If the value of the key is true, then the job will be kept alive as long as the path exists. If false, the job will be kept alive in the inverse condition. The intent of this feature is that two or more jobs may create semaphores in the file-system namespace. +.It Sy OtherJobEnabled +Each key in this dictionary is the label of another job. If the value of the key is +true, then this job is kept alive as long as that other job is enabled. Otherwise, +if the value is false, then this job is kept alive as long as the other job is disabled. +This feature should not be considered a substitute for the use of IPC. .El .It Sy RunAtLoad This optional key is used to control whether your job is launched once at the time the job is loaded. The default is false. @@ -169,18 +178,30 @@ This optional key specifies what value should be passed to .Xr umask 2 before running the job. Known bug: Property lists don't support octal, so please convert the value to decimal. .It Sy TimeOut -The recommended time out (in seconds) to pass to the job. If no value is specified, a default time out will be supplied by +The recommended idle time out (in seconds) to pass to the job. If no value is specified, a default time out will be supplied by .Nm launchd for use by the job at check in time. +.It Sy ExitTimeOut +The amount of time +.Nm launchd +waits before sending a SIGKILL signal. The default value is 20 seconds. The value zero is interpreted as infinity. +.It Sy ThrottleInterval +This key lets one override the default throttling policy imposed on jobs by +.Nm launchd . +The value is in seconds, and by default, jobs will not be spawned more than once every 10 seconds. +The principle behind this is that jobs should linger around just in case they are needed again in the near future. This not only +reduces the latency of responses, but it encourages developers to amortize the cost of program invocation. .It Sy InitGroups This optional key specifies whether the job should have .Xr initgroups 3 be called before running the job. -The default is false. +The default is true in 10.5 and false in 10.4. This key will be ignored if the UserName key is not set. .It Sy WatchPaths This optional key causes the job to be started if any one of the listed paths are modified. .It Sy QueueDirectories Much like the WatchPaths option, this key will watch the paths for modifications. The difference being that the job will only be started if the path is a directory and the directory is not empty. +.It Sy StartOnMount +This optional key causes the job to be started every time a filesystem is mounted. .It Sy StartInterval This optional key causes the job to be started every N seconds. If the system is asleep, the job will be started the next time the computer @@ -257,21 +278,49 @@ performed automatically by the system. This optional key specifies what .Xr nice 3 value should be applied to the daemon. +.It Sy AbandonProcessGroup +When a job dies, +.Nm launchd +kills any remaining processes with the same process group ID as the job. +Setting this key to true disables that behavior. +.It Sy HopefullyExitsFirst +This optional key causes programs to exit earlier during system shutdown. +This key exists because some jobs do more than flush buffers and exit like +they're supposed to. The use of this key should be considered a +temporary solution until the software can be changed to only flush dirty buffers +and then exit. +.It Sy HopefullyExitsLast +This optional key causes programs to exit later during system shutdown. This +key exists because some jobs don't reference count their clients, and therefore +do not know when it is safe to exit. The use of this key should be considered a +temporary solution until the software can be changed to properly reference +count clients. .It Sy LowPriorityIO This optional key specifies whether the kernel should consider this daemon to be low priority when doing file system I/O. -.It Sy MachServices +.It Sy LaunchOnlyOnce +This optional key specifies whether the job can only be run once and only once. +In other words, if the job cannot be safely respawned without a full machine +reboot, then set this key to be true. +.It Sy MachServices This optional key is used to specify Mach services to be registered with the Mach bootstrap sub-system. Each key in this dictionary should be the name of -service to be advertised. The value of the key must be a boolean. If the -boolean is true, the port is recycled, thus leaving clients to remain oblivious -to the demand nature of job. If the value is set to false, clients receive port +service to be advertised. The value of the key must be a boolean and set to true. +Alternatively, a dictionary can be used instead of a simple true value. +.Bl -ohang -offset indent +.It Sy ResetAtClose +If this boolean is false, the port is recycled, thus leaving clients to remain oblivious +to the demand nature of job. If the value is set to true, clients receive port death notifications when the job lets go of the receive right. The port will be recreated atomically with respect to bootstrap_look_up() calls, so that clients can trust that after receiving a port death notification, the new port will -have already been recreated. Setting the value to false should be done with -care. Not all clients may be able to handle this behavior. Finally, for the job -itself, the values will be replaced with Mach ports at the time of check-in -with +have already been recreated. Setting the value to true should be done with +care. Not all clients may be able to handle this behavior. The default value is false. +.It Sy HideUntilCheckIn +Reserve the name in the namespace, but cause bootstrap_look_up() to fail until the job has checked in with +.Nm launchd . +.El +.Pp +Finally, for the job itself, the values will be replaced with Mach ports at the time of check-in with .Nm launchd . .It Sy Sockets This optional key is used to specify launch on demand sockets that can be used to let @@ -284,7 +333,7 @@ At check in time, the value of each Sockets dictionary key will be an array of d consider all descriptors of a given key to be to be effectively equivalent, even though each file descriptor likely represents a different networking protocol which conforms to the criteria specified in the job configuration file. .Pp -The paramters below are used as inputs to call +The parameters below are used as inputs to call .Xr getaddrinfo 3 . .Bl -ohang -offset indent .It Sy SockType diff --git a/launchd/src/launchd_core_logic.c b/launchd/src/launchd_core_logic.c index 2c37ee9..726ab63 100644 --- a/launchd/src/launchd_core_logic.c +++ b/launchd/src/launchd_core_logic.c @@ -1,6 +1,4 @@ /* - * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. - * * @APPLE_APACHE_LICENSE_HEADER_START@ * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,10 +16,14 @@ * @APPLE_APACHE_LICENSE_HEADER_END@ */ -static const char *const __rcs_file_version__ = "$Revision: 1.77 $"; +static const char *const __rcs_file_version__ = "$Revision: 23433 $"; + +#include "config.h" +#include "launchd_core_logic.h" #include #include +#include #include #include #include @@ -31,14 +33,15 @@ static const char *const __rcs_file_version__ = "$Revision: 1.77 $"; #include #include #include +#include #include #include #include -#include #include #include #include #include +#include #include #include #include @@ -46,14 +49,15 @@ static const char *const __rcs_file_version__ = "$Revision: 1.77 $"; #include #include #include +#include #include #include #include #include +#include #include #include #include -#include #include #include #include @@ -68,37 +72,93 @@ static const char *const __rcs_file_version__ = "$Revision: 1.77 $"; #include #include #include +#include +#include + +#include "liblaunch_public.h" +#include "liblaunch_private.h" +#include "liblaunch_internal.h" +#include "libbootstrap_public.h" +#include "libbootstrap_private.h" +#include "libvproc_public.h" +#include "libvproc_internal.h" + +#include "reboot2.h" -#include "launch.h" -#include "launch_priv.h" #include "launchd.h" -#include "launchd_core_logic.h" +#include "launchd_runtime.h" #include "launchd_unix_ipc.h" -#include "bootstrap_private.h" -#include "bootstrap.h" -#include "bootstrapServer.h" -#include "mpm_reply.h" - -/* sys/queue.h is not up to date */ -#ifndef SLIST_FOREACH_SAFE -#define SLIST_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = SLIST_FIRST((head)); \ - (var) && ((tvar) = SLIST_NEXT((var), field), 1); \ - (var) = (tvar)) -#endif +#include "protocol_vproc.h" +#include "protocol_vprocServer.h" +#include "job_reply.h" + +#define LAUNCHD_MIN_JOB_RUN_TIME 10 +#define LAUNCHD_DEFAULT_EXIT_TIMEOUT 20 +#define LAUNCHD_SIGKILL_TIMER 5 + + +#define TAKE_SUBSET_NAME "TakeSubsetName" +#define TAKE_SUBSET_PID "TakeSubsetPID" +#define TAKE_SUBSET_PERPID "TakeSubsetPerPID" + +#define IS_POWER_OF_TWO(v) (!(v & (v - 1)) && v) + +extern char **environ; + +struct waiting_for_removal { + SLIST_ENTRY(waiting_for_removal) sle; + mach_port_t reply_port; +}; + +static bool waiting4removal_new(job_t j, mach_port_t rp); +static void waiting4removal_delete(job_t j, struct waiting_for_removal *w4r); + +struct mspolicy { + SLIST_ENTRY(mspolicy) sle; + unsigned int allow:1, per_pid:1; + const char name[0]; +}; + +static bool mspolicy_new(job_t j, const char *name, bool allow, bool pid_local, bool skip_check); +static bool mspolicy_copy(job_t j_to, job_t j_from); +static void mspolicy_setup(launch_data_t obj, const char *key, void *context); +static bool mspolicy_check(job_t j, const char *name, bool pid_local); +static void mspolicy_delete(job_t j, struct mspolicy *msp); struct machservice { SLIST_ENTRY(machservice) sle; - struct jobcb *job; + SLIST_ENTRY(machservice) special_port_sle; + LIST_ENTRY(machservice) name_hash_sle; + LIST_ENTRY(machservice) port_hash_sle; + job_t job; + uint64_t bad_perf_cnt; + unsigned int gen_num; mach_port_name_t port; - unsigned int isActive:1, reset:1, recv:1, hide:1, kUNCServer:1, __junk:27; - char name[0]; + unsigned int isActive:1, reset:1, recv:1, hide:1, kUNCServer:1, per_user_hack:1, debug_on_close:1, per_pid:1, special_port_num:10; + const char name[0]; }; +static SLIST_HEAD(, machservice) special_ports; /* hack, this should be per jobmgr_t */ + +#define PORT_HASH_SIZE 32 +#define HASH_PORT(x) (IS_POWER_OF_TWO(PORT_HASH_SIZE) ? (MACH_PORT_INDEX(x) & (PORT_HASH_SIZE - 1)) : (MACH_PORT_INDEX(x) % PORT_HASH_SIZE)) + +static LIST_HEAD(, machservice) port_hash[PORT_HASH_SIZE]; + static void machservice_setup(launch_data_t obj, const char *key, void *context); static void machservice_setup_options(launch_data_t obj, const char *key, void *context); -static void machservice_resetport(struct jobcb *j, struct machservice *ms); - +static void machservice_resetport(job_t j, struct machservice *ms); +static struct machservice *machservice_new(job_t j, const char *name, mach_port_t *serviceport, bool pid_local); +static void machservice_ignore(job_t j, struct machservice *ms); +static void machservice_watch(job_t j, struct machservice *ms); +static void machservice_delete(job_t j, struct machservice *, bool port_died); +static void machservice_request_notifications(struct machservice *); +static mach_port_t machservice_port(struct machservice *); +static job_t machservice_job(struct machservice *); +static bool machservice_hidden(struct machservice *); +static bool machservice_active(struct machservice *); +static const char *machservice_name(struct machservice *); +static bootstrap_status_t machservice_status(struct machservice *); struct socketgroup { SLIST_ENTRY(socketgroup) sle; @@ -107,36 +167,31 @@ struct socketgroup { char name[0]; }; -static bool socketgroup_new(struct jobcb *j, const char *name, int *fds, unsigned int fd_cnt, bool junkfds); -static void socketgroup_delete(struct jobcb *j, struct socketgroup *sg); -static void socketgroup_watch(struct jobcb *j, struct socketgroup *sg); -static void socketgroup_ignore(struct jobcb *j, struct socketgroup *sg); -static void socketgroup_callback(struct jobcb *j, struct kevent *kev); +static bool socketgroup_new(job_t j, const char *name, int *fds, unsigned int fd_cnt, bool junkfds); +static void socketgroup_delete(job_t j, struct socketgroup *sg); +static void socketgroup_watch(job_t j, struct socketgroup *sg); +static void socketgroup_ignore(job_t j, struct socketgroup *sg); +static void socketgroup_callback(job_t j); static void socketgroup_setup(launch_data_t obj, const char *key, void *context); - -struct watchpath { - SLIST_ENTRY(watchpath) sle; - int fd; - unsigned int is_qdir:1, __junk:31; - char name[0]; -}; - -static bool watchpath_new(struct jobcb *j, const char *name, bool qdir); -static void watchpath_delete(struct jobcb *j, struct watchpath *wp); -static void watchpath_watch(struct jobcb *j, struct watchpath *wp); -static void watchpath_ignore(struct jobcb *j, struct watchpath *wp); -static void watchpath_callback(struct jobcb *j, struct kevent *kev); +static void socketgroup_kevent_mod(job_t j, struct socketgroup *sg, bool do_add); struct calendarinterval { + LIST_ENTRY(calendarinterval) global_sle; SLIST_ENTRY(calendarinterval) sle; + job_t job; struct tm when; + time_t when_next; }; -static bool calendarinterval_new(struct jobcb *j, struct tm *w); -static bool calendarinterval_new_from_obj(struct jobcb *j, launch_data_t obj); -static void calendarinterval_delete(struct jobcb *j, struct calendarinterval *ci); -static void calendarinterval_setalarm(struct jobcb *j, struct calendarinterval *ci); -static void calendarinterval_callback(struct jobcb *j, struct kevent *kev); +static LIST_HEAD(, calendarinterval) sorted_calendar_events; + +static bool calendarinterval_new(job_t j, struct tm *w); +static bool calendarinterval_new_from_obj(job_t j, launch_data_t obj); +static void calendarinterval_new_from_obj_dict_walk(launch_data_t obj, const char *key, void *context); +static void calendarinterval_delete(job_t j, struct calendarinterval *ci); +static void calendarinterval_setalarm(job_t j, struct calendarinterval *ci); +static void calendarinterval_callback(void); +static void calendarinterval_sanity_check(void); struct envitem { SLIST_ENTRY(envitem) sle; @@ -144,8 +199,8 @@ struct envitem { char key[0]; }; -static bool envitem_new(struct jobcb *j, const char *k, const char *v, bool global); -static void envitem_delete(struct jobcb *j, struct envitem *ei, bool global); +static bool envitem_new(job_t j, const char *k, const char *v, bool global); +static void envitem_delete(job_t j, struct envitem *ei, bool global); static void envitem_setup(launch_data_t obj, const char *key, void *context); struct limititem { @@ -154,9 +209,10 @@ struct limititem { unsigned int setsoft:1, sethard:1, which:30; }; -static bool limititem_update(struct jobcb *j, int w, rlim_t r); -static void limititem_delete(struct jobcb *j, struct limititem *li); +static bool limititem_update(job_t j, int w, rlim_t r); +static void limititem_delete(job_t j, struct limititem *li); static void limititem_setup(launch_data_t obj, const char *key, void *context); +static void seatbelt_setup_flags(launch_data_t obj, const char *key, void *context); typedef enum { NETWORK_UP = 1, @@ -165,101 +221,218 @@ typedef enum { FAILED_EXIT, PATH_EXISTS, PATH_MISSING, + OTHER_JOB_ENABLED, + OTHER_JOB_DISABLED, + OTHER_JOB_ACTIVE, + OTHER_JOB_INACTIVE, + PATH_CHANGES, + DIR_NOT_EMPTY, // FILESYSTEMTYPE_IS_MOUNTED, /* for nfsiod, but maybe others */ } semaphore_reason_t; struct semaphoreitem { SLIST_ENTRY(semaphoreitem) sle; semaphore_reason_t why; + int fd; char what[0]; }; -static bool semaphoreitem_new(struct jobcb *j, semaphore_reason_t why, const char *what); -static void semaphoreitem_delete(struct jobcb *j, struct semaphoreitem *si); -static void semaphoreitem_setup(launch_data_t obj, const char *key, void *context); -static void semaphoreitem_setup_paths(launch_data_t obj, const char *key, void *context); +struct semaphoreitem_dict_iter_context { + job_t j; + semaphore_reason_t why_true; + semaphore_reason_t why_false; +}; +static bool semaphoreitem_new(job_t j, semaphore_reason_t why, const char *what); +static void semaphoreitem_delete(job_t j, struct semaphoreitem *si); +static void semaphoreitem_setup(launch_data_t obj, const char *key, void *context); +static void semaphoreitem_setup_dict_iter(launch_data_t obj, const char *key, void *context); +static void semaphoreitem_callback(job_t j, struct kevent *kev); +static void semaphoreitem_watch(job_t j, struct semaphoreitem *si); +static void semaphoreitem_ignore(job_t j, struct semaphoreitem *si); +static void semaphoreitem_runtime_mod_ref(struct semaphoreitem *si, bool add); + +#define ACTIVE_JOB_HASH_SIZE 32 +#define ACTIVE_JOB_HASH(x) (IS_POWER_OF_TWO(ACTIVE_JOB_HASH_SIZE) ? (x & (ACTIVE_JOB_HASH_SIZE - 1)) : (x % ACTIVE_JOB_HASH_SIZE)) +#define MACHSERVICE_HASH_SIZE 37 + +struct jobmgr_s { + kq_callback kqjobmgr_callback; + SLIST_ENTRY(jobmgr_s) sle; + SLIST_HEAD(, jobmgr_s) submgrs; + LIST_HEAD(, job_s) jobs; + LIST_HEAD(, job_s) active_jobs[ACTIVE_JOB_HASH_SIZE]; + LIST_HEAD(, machservice) ms_hash[MACHSERVICE_HASH_SIZE]; + mach_port_t jm_port; + mach_port_t req_port; + jobmgr_t parentmgr; + int reboot_flags; + unsigned int global_on_demand_cnt; + unsigned int hopefully_first_cnt; + unsigned int normal_active_cnt; + unsigned int sent_stop_to_normal_jobs:1, sent_stop_to_hopefully_last_jobs:1, shutting_down:1, session_initialized:1; + char name[0]; +}; -struct jobcb { +#define jobmgr_assumes(jm, e) \ + (__builtin_expect(!(e), 0) ? jobmgr_log_bug(jm, __rcs_file_version__, __FILE__, __LINE__, #e), false : true) + +static jobmgr_t jobmgr_new(jobmgr_t jm, mach_port_t requestorport, mach_port_t transfer_port, bool sflag, const char *name); +static job_t jobmgr_import2(jobmgr_t jm, launch_data_t pload); +static jobmgr_t jobmgr_parent(jobmgr_t jm); +static jobmgr_t jobmgr_do_garbage_collection(jobmgr_t jm); +static void jobmgr_reap_bulk(jobmgr_t jm, struct kevent *kev); +static void jobmgr_log_stray_children(jobmgr_t jm); +static void jobmgr_remove(jobmgr_t jm); +static void jobmgr_dispatch_all(jobmgr_t jm, bool newmounthack); +static job_t jobmgr_init_session(jobmgr_t jm, const char *session_type, bool sflag); +static job_t jobmgr_find_by_pid(jobmgr_t jm, pid_t p, bool create_anon); +static job_t job_mig_intran2(jobmgr_t jm, mach_port_t mport, pid_t upid); +static void job_export_all2(jobmgr_t jm, launch_data_t where); +static void jobmgr_callback(void *obj, struct kevent *kev); +static void jobmgr_setup_env_from_other_jobs(jobmgr_t jm); +static void jobmgr_export_env_from_other_jobs(jobmgr_t jm, launch_data_t dict); +static struct machservice *jobmgr_lookup_service(jobmgr_t jm, const char *name, bool check_parent, pid_t target_pid); +static void jobmgr_logv(jobmgr_t jm, int pri, int err, const char *msg, va_list ap) __attribute__((format(printf, 4, 0))); +static void jobmgr_log(jobmgr_t jm, int pri, const char *msg, ...) __attribute__((format(printf, 3, 4))); +/* static void jobmgr_log_error(jobmgr_t jm, int pri, const char *msg, ...) __attribute__((format(printf, 3, 4))); */ +static void jobmgr_log_bug(jobmgr_t jm, const char *rcs_rev, const char *path, unsigned int line, const char *test); + +#define DO_RUSAGE_SUMMATION 0 + +#define AUTO_PICK_LEGACY_LABEL (const char *)(~0) + +struct job_s { kq_callback kqjob_callback; - SLIST_ENTRY(jobcb) sle; + LIST_ENTRY(job_s) sle; + LIST_ENTRY(job_s) pid_hash_sle; + LIST_ENTRY(job_s) label_hash_sle; SLIST_HEAD(, socketgroup) sockets; - SLIST_HEAD(, watchpath) vnodes; SLIST_HEAD(, calendarinterval) cal_intervals; SLIST_HEAD(, envitem) global_env; SLIST_HEAD(, envitem) env; SLIST_HEAD(, limititem) limits; + SLIST_HEAD(, mspolicy) mspolicies; SLIST_HEAD(, machservice) machservices; SLIST_HEAD(, semaphoreitem) semaphores; - SLIST_HEAD(, jobcb) jobs; + SLIST_HEAD(, waiting_for_removal) removal_watchers; +#if DO_RUSAGE_SUMMATION struct rusage ru; - struct jobcb *parent; - mach_port_t bs_port; - mach_port_t req_port; +#endif + cpu_type_t *j_binpref; + size_t j_binpref_cnt; + mach_port_t j_port; mach_port_t wait_reply_port; uid_t mach_uid; + jobmgr_t mgr; char **argv; char *prog; char *rootdir; char *workingdir; char *username; char *groupname; - char *stdinpath; char *stdoutpath; char *stderrpath; + struct machservice *lastlookup; + unsigned int lastlookup_gennum; + char *seatbelt_profile; + uint64_t seatbelt_flags; + void *quarantine_data; + size_t quarantine_data_sz; pid_t p; int argc; int last_exit_status; - int execfd; + int forkfd; + int log_redirect_fd; int nice; - int timeout; - time_t start_time; - size_t failed_exits; - unsigned int start_interval; - unsigned int checkedin:1, firstborn:1, debug:1, throttle:1, inetcompat:1, inetcompat_wait:1, - ondemand:1, session_create:1, low_pri_io:1, init_groups:1, priv_port_has_senders:1, - importing_global_env:1, importing_hard_limits:1, setmask:1, legacy_mach_job:1, runatload:1; + unsigned int timeout; + unsigned int exit_timeout; + int stdout_err_fd; + uint64_t sent_sigterm_time; + uint64_t start_time; + uint32_t min_run_time; + uint32_t start_interval; + unsigned int checkedin:1, anonymous:1, debug:1, inetcompat:1, inetcompat_wait:1, + ondemand:1, session_create:1, low_pri_io:1, no_init_groups:1, priv_port_has_senders:1, + importing_global_env:1, importing_hard_limits:1, setmask:1, legacy_mach_job:1, start_pending:1; mode_t mask; - unsigned int globargv:1, wait4debugger:1, transfer_bstrap:1, unload_at_exit:1, force_ppc:1, stall_before_exec:1, __pad:26; - char label[0]; + unsigned int globargv:1, wait4debugger:1, unload_at_exit:1, stall_before_exec:1, only_once:1, + currently_ignored:1, forced_peers_to_demand_mode:1, setnice:1, hopefully_exits_last:1, removal_pending:1, + wait4pipe_eof:1, sent_sigkill:1, debug_before_kill:1, weird_bootstrap:1, start_on_mount:1, + per_user:1, hopefully_exits_first:1, deny_unknown_mslookups:1, unload_at_mig_return:1, abandon_pg:1, + poll_for_vfs_changes:1; + const char label[0]; }; -static struct jobcb *job_import2(launch_data_t pload); +#define LABEL_HASH_SIZE 53 + +static LIST_HEAD(, job_s) label_hash[LABEL_HASH_SIZE]; +static size_t hash_label(const char *label) __attribute__((pure)); +static size_t hash_ms(const char *msstr) __attribute__((pure)); + + +#define job_assumes(j, e) \ + (__builtin_expect(!(e), 0) ? job_log_bug(j, __rcs_file_version__, __FILE__, __LINE__, #e), false : true) + static void job_import_keys(launch_data_t obj, const char *key, void *context); -static void job_import_bool(struct jobcb *j, const char *key, bool value); -static void job_import_string(struct jobcb *j, const char *key, const char *value); -static void job_import_integer(struct jobcb *j, const char *key, long long value); -static void job_import_dictionary(struct jobcb *j, const char *key, launch_data_t value); -static void job_import_array(struct jobcb *j, const char *key, launch_data_t value); -static void job_watch(struct jobcb *j); -static void job_ignore(struct jobcb *j); -static void job_reap(struct jobcb *j); -static bool job_useless(struct jobcb *j); -static bool job_keepalive(struct jobcb *j); -static void job_start_child(struct jobcb *j, int execfd) __attribute__((noreturn)); -static void job_setup_attributes(struct jobcb *j); -static bool job_setup_machport(struct jobcb *j); +static void job_import_bool(job_t j, const char *key, bool value); +static void job_import_string(job_t j, const char *key, const char *value); +static void job_import_integer(job_t j, const char *key, long long value); +static void job_import_dictionary(job_t j, const char *key, launch_data_t value); +static void job_import_array(job_t j, const char *key, launch_data_t value); +static void job_import_opaque(job_t j, const char *key, launch_data_t value); +static bool job_set_global_on_demand(job_t j, bool val); +static const char *job_active(job_t j); +static void job_watch(job_t j); +static void job_ignore(job_t j); +static void job_reap(job_t j); +static bool job_useless(job_t j); +static bool job_keepalive(job_t j); +static void job_start(job_t j); +static void job_start_child(job_t j) __attribute__((noreturn)); +static void job_setup_attributes(job_t j); +static bool job_setup_machport(job_t j); +static void job_setup_fd(job_t j, int target_fd, const char *path, int flags); +static void job_postfork_become_user(job_t j); +static void job_find_and_blame_pids_with_weird_uids(job_t j); +static void job_force_sampletool(job_t j); +static void job_setup_exception_port(job_t j, task_t target_task); +static void job_reparent_hack(job_t j, const char *where); static void job_callback(void *obj, struct kevent *kev); -static pid_t job_fork(struct jobcb *j); -static size_t job_prep_log_preface(struct jobcb *j, char *buf); -static void job_setup_env_from_other_jobs(struct jobcb *j); -static void job_export_all2(struct jobcb *j, launch_data_t where); -static launch_data_t job_export2(struct jobcb *j, bool subjobs); +static void job_callback_proc(job_t j, int flags, int fflags); +static void job_callback_timer(job_t j, void *ident); +static void job_callback_read(job_t j, int ident); +static void job_log_stray_pg(job_t j); +static job_t job_new_anonymous(jobmgr_t jm, pid_t anonpid); +static job_t job_new(jobmgr_t jm, const char *label, const char *prog, const char *const *argv); +static job_t job_new_via_mach_init(job_t j, const char *cmd, uid_t uid, bool ond); +static const char *job_prog(job_t j); +static jobmgr_t job_get_bs(job_t j); +static void job_kill(job_t j); +static void job_uncork_fork(job_t j); +static void job_log_stdouterr(job_t j); +static void job_logv(job_t j, int pri, int err, const char *msg, va_list ap) __attribute__((format(printf, 4, 0))); +static void job_log_error(job_t j, int pri, const char *msg, ...) __attribute__((format(printf, 3, 4))); +static void job_log_bug(job_t j, const char *rcs_rev, const char *path, unsigned int line, const char *test); +static void job_log_stdouterr2(job_t j, const char *msg, ...); +static void job_set_exeception_port(job_t j, mach_port_t port); +static kern_return_t job_handle_mpm_wait(job_t j, mach_port_t srp, int *waitstatus); + static const struct { const char *key; int val; } launchd_keys2limits[] = { - { LAUNCH_JOBKEY_RESOURCELIMIT_CORE, RLIMIT_CORE }, - { LAUNCH_JOBKEY_RESOURCELIMIT_CPU, RLIMIT_CPU }, - { LAUNCH_JOBKEY_RESOURCELIMIT_DATA, RLIMIT_DATA }, - { LAUNCH_JOBKEY_RESOURCELIMIT_FSIZE, RLIMIT_FSIZE }, - { LAUNCH_JOBKEY_RESOURCELIMIT_MEMLOCK, RLIMIT_MEMLOCK }, - { LAUNCH_JOBKEY_RESOURCELIMIT_NOFILE, RLIMIT_NOFILE }, - { LAUNCH_JOBKEY_RESOURCELIMIT_NPROC, RLIMIT_NPROC }, - { LAUNCH_JOBKEY_RESOURCELIMIT_RSS, RLIMIT_RSS }, - { LAUNCH_JOBKEY_RESOURCELIMIT_STACK, RLIMIT_STACK }, + { LAUNCH_JOBKEY_RESOURCELIMIT_CORE, RLIMIT_CORE }, + { LAUNCH_JOBKEY_RESOURCELIMIT_CPU, RLIMIT_CPU }, + { LAUNCH_JOBKEY_RESOURCELIMIT_DATA, RLIMIT_DATA }, + { LAUNCH_JOBKEY_RESOURCELIMIT_FSIZE, RLIMIT_FSIZE }, + { LAUNCH_JOBKEY_RESOURCELIMIT_MEMLOCK, RLIMIT_MEMLOCK }, + { LAUNCH_JOBKEY_RESOURCELIMIT_NOFILE, RLIMIT_NOFILE }, + { LAUNCH_JOBKEY_RESOURCELIMIT_NPROC, RLIMIT_NPROC }, + { LAUNCH_JOBKEY_RESOURCELIMIT_RSS, RLIMIT_RSS }, + { LAUNCH_JOBKEY_RESOURCELIMIT_STACK, RLIMIT_STACK }, }; static time_t cronemu(int mon, int mday, int hour, int min); @@ -269,115 +442,165 @@ static bool cronemu_mday(struct tm *wtm, int mday, int hour, int min); static bool cronemu_hour(struct tm *wtm, int hour, int min); static bool cronemu_min(struct tm *wtm, int min); -static void simple_zombie_reaper(void *, struct kevent *); - -kq_callback kqsimple_zombie_reaper = simple_zombie_reaper; - -static int dir_has_files(const char *path); +/* miscellaneous file local functions */ +static void ensure_root_bkgd_setup(void); +static int dir_has_files(job_t j, const char *path); static char **mach_cmd2argv(const char *string); -struct jobcb *root_job = NULL; -struct jobcb *gc_this_job = NULL; -size_t total_children = 0; +static size_t our_strhash(const char *s) __attribute__((pure)); +static void extract_rcsid_substr(const char *i, char *o, size_t osz); +static void do_first_per_user_launchd_hack(void); +static void do_file_init(void) __attribute__((constructor)); + +/* file local globals */ +static size_t total_children; +static size_t total_anon_children; +static mach_port_t the_exception_server; +static bool did_first_per_user_launchd_BootCache_hack; +#define JOB_BOOTCACHE_HACK_CHECK(j) (j->per_user && !did_first_per_user_launchd_BootCache_hack && (j->mach_uid >= 500) && (j->mach_uid != (uid_t)-2)) +static jobmgr_t background_jobmgr; +static job_t workaround_5477111; +static mach_timebase_info_data_t tbi; + +/* process wide globals */ +mach_port_t inherited_bootstrap_port; +jobmgr_t root_jobmgr; -void -simple_zombie_reaper(void *obj __attribute__((unused)), struct kevent *kev) -{ - waitpid(kev->ident, NULL, 0); -} void -job_ignore(struct jobcb *j) +job_ignore(job_t j) { + struct semaphoreitem *si; struct socketgroup *sg; struct machservice *ms; - struct watchpath *wp; - SLIST_FOREACH(sg, &j->sockets, sle) + if (j->currently_ignored) { + return; + } + + job_log(j, LOG_DEBUG, "Ignoring..."); + + j->currently_ignored = true; + + if (j->poll_for_vfs_changes) { + j->poll_for_vfs_changes = false; + job_assumes(j, kevent_mod((uintptr_t)&j->semaphores, EVFILT_TIMER, EV_DELETE, 0, 0, j) != -1); + } + + SLIST_FOREACH(sg, &j->sockets, sle) { socketgroup_ignore(j, sg); + } - SLIST_FOREACH(wp, &j->vnodes, sle) - watchpath_ignore(j, wp); + SLIST_FOREACH(ms, &j->machservices, sle) { + machservice_ignore(j, ms); + } - SLIST_FOREACH(ms, &j->machservices, sle) - launchd_assumes(launchd_mport_request_callback(ms->port, NULL, false) == KERN_SUCCESS); + SLIST_FOREACH(si, &j->semaphores, sle) { + semaphoreitem_ignore(j, si); + } } void -job_watch(struct jobcb *j) +job_watch(job_t j) { + struct semaphoreitem *si; struct socketgroup *sg; struct machservice *ms; - struct watchpath *wp; - SLIST_FOREACH(sg, &j->sockets, sle) + if (!j->currently_ignored) { + return; + } + + job_log(j, LOG_DEBUG, "Watching..."); + + j->currently_ignored = false; + + SLIST_FOREACH(sg, &j->sockets, sle) { socketgroup_watch(j, sg); + } - SLIST_FOREACH(wp, &j->vnodes, sle) - watchpath_watch(j, wp); + SLIST_FOREACH(ms, &j->machservices, sle) { + machservice_watch(j, ms); + } - SLIST_FOREACH(ms, &j->machservices, sle) - launchd_assumes(launchd_mport_request_callback(ms->port, j, false) == KERN_SUCCESS); + SLIST_FOREACH(si, &j->semaphores, sle) { + semaphoreitem_watch(j, si); + } } void -job_stop(struct jobcb *j) +job_stop(job_t j) { - if (j->p) - kill(j->p, SIGTERM); -} + if (!j->p || j->anonymous) { + return; + } -launch_data_t -job_export(struct jobcb *j) -{ - return job_export2(j, true); + job_assumes(j, runtime_kill(j->p, SIGTERM) != -1); + j->sent_sigterm_time = mach_absolute_time(); + + if (j->exit_timeout) { + job_assumes(j, kevent_mod((uintptr_t)&j->exit_timeout, EVFILT_TIMER, + EV_ADD|EV_ONESHOT, NOTE_SECONDS, j->exit_timeout, j) != -1); + } + + job_log(j, LOG_DEBUG, "Sent SIGTERM signal"); } launch_data_t -job_export2(struct jobcb *j, bool subjobs) +job_export(job_t j) { launch_data_t tmp, tmp2, tmp3, r = launch_data_alloc(LAUNCH_DATA_DICTIONARY); - if (r == NULL) + if (r == NULL) { return NULL; + } - if ((tmp = launch_data_new_string(j->label))) + if ((tmp = launch_data_new_string(j->label))) { launch_data_dict_insert(r, tmp, LAUNCH_JOBKEY_LABEL); - - if ((tmp = launch_data_new_bool(j->ondemand))) + } + if ((tmp = launch_data_new_string(j->mgr->name))) { + launch_data_dict_insert(r, tmp, LAUNCH_JOBKEY_LIMITLOADTOSESSIONTYPE); + } + if ((tmp = launch_data_new_bool(j->ondemand))) { launch_data_dict_insert(r, tmp, LAUNCH_JOBKEY_ONDEMAND); - - if ((tmp = launch_data_new_integer(j->last_exit_status))) + } + if ((tmp = launch_data_new_integer(j->last_exit_status))) { launch_data_dict_insert(r, tmp, LAUNCH_JOBKEY_LASTEXITSTATUS); - - if (j->p && (tmp = launch_data_new_integer(j->p))) + } + if (j->p && (tmp = launch_data_new_integer(j->p))) { launch_data_dict_insert(r, tmp, LAUNCH_JOBKEY_PID); - - if ((tmp = launch_data_new_integer(j->timeout))) + } + if ((tmp = launch_data_new_integer(j->timeout))) { launch_data_dict_insert(r, tmp, LAUNCH_JOBKEY_TIMEOUT); - - if (j->prog && (tmp = launch_data_new_string(j->prog))) + } + if (j->prog && (tmp = launch_data_new_string(j->prog))) { launch_data_dict_insert(r, tmp, LAUNCH_JOBKEY_PROGRAM); - - if (j->stdoutpath && (tmp = launch_data_new_string(j->stdoutpath))) + } + if (j->stdoutpath && (tmp = launch_data_new_string(j->stdoutpath))) { launch_data_dict_insert(r, tmp, LAUNCH_JOBKEY_STANDARDOUTPATH); - - if (j->stderrpath && (tmp = launch_data_new_string(j->stderrpath))) + } + if (j->stderrpath && (tmp = launch_data_new_string(j->stderrpath))) { launch_data_dict_insert(r, tmp, LAUNCH_JOBKEY_STANDARDERRORPATH); - + } if (j->argv && (tmp = launch_data_alloc(LAUNCH_DATA_ARRAY))) { int i; for (i = 0; i < j->argc; i++) { - if ((tmp2 = launch_data_new_string(j->argv[i]))) + if ((tmp2 = launch_data_new_string(j->argv[i]))) { launch_data_array_set_index(tmp, tmp2, i); + } } launch_data_dict_insert(r, tmp, LAUNCH_JOBKEY_PROGRAMARGUMENTS); } + if (j->session_create && (tmp = launch_data_new_bool(true))) { + launch_data_dict_insert(r, tmp, LAUNCH_JOBKEY_SESSIONCREATE); + } + if (j->inetcompat && (tmp = launch_data_alloc(LAUNCH_DATA_DICTIONARY))) { - if ((tmp2 = launch_data_new_bool(j->inetcompat_wait))) + if ((tmp2 = launch_data_new_bool(j->inetcompat_wait))) { launch_data_dict_insert(tmp, tmp2, LAUNCH_JOBINETDCOMPATIBILITY_WAIT); + } launch_data_dict_insert(r, tmp, LAUNCH_JOBKEY_INETDCOMPATIBILITY); } @@ -386,10 +609,14 @@ job_export2(struct jobcb *j, bool subjobs) int i; SLIST_FOREACH(sg, &j->sockets, sle) { + if (sg->junkfds) { + continue; + } if ((tmp2 = launch_data_alloc(LAUNCH_DATA_ARRAY))) { for (i = 0; i < sg->fd_cnt; i++) { - if ((tmp3 = launch_data_new_fd(sg->fds[i]))) + if ((tmp3 = launch_data_new_fd(sg->fds[i]))) { launch_data_array_set_index(tmp2, tmp3, i); + } } launch_data_dict_insert(tmp, tmp2, sg->name); } @@ -400,150 +627,264 @@ job_export2(struct jobcb *j, bool subjobs) if (!SLIST_EMPTY(&j->machservices) && (tmp = launch_data_alloc(LAUNCH_DATA_DICTIONARY))) { struct machservice *ms; + + tmp3 = NULL; SLIST_FOREACH(ms, &j->machservices, sle) { - tmp2 = launch_data_new_machport(MACH_PORT_NULL); - launch_data_dict_insert(tmp, tmp2, ms->name); + if (ms->per_pid) { + if (tmp3 == NULL) { + tmp3 = launch_data_alloc(LAUNCH_DATA_DICTIONARY); + } + if (tmp3) { + tmp2 = launch_data_new_machport(MACH_PORT_NULL); + launch_data_dict_insert(tmp3, tmp2, ms->name); + } + } else { + tmp2 = launch_data_new_machport(MACH_PORT_NULL); + launch_data_dict_insert(tmp, tmp2, ms->name); + } } launch_data_dict_insert(r, tmp, LAUNCH_JOBKEY_MACHSERVICES); + + if (tmp3) { + launch_data_dict_insert(r, tmp3, LAUNCH_JOBKEY_PERJOBMACHSERVICES); + } + } + + return r; +} + +static void +jobmgr_log_active_jobs(jobmgr_t jm) +{ + const char *why_active; + jobmgr_t jmi; + job_t ji; + + SLIST_FOREACH(jmi, &jm->submgrs, sle) { + jobmgr_log_active_jobs(jmi); + } + + LIST_FOREACH(ji, &jm->jobs, sle) { + why_active = job_active(ji); + + job_log(ji, LOG_DEBUG, "%s", why_active ? why_active : "Inactive"); } - if (subjobs && !SLIST_EMPTY(&j->jobs) && (tmp = launch_data_alloc(LAUNCH_DATA_ARRAY))) { - struct jobcb *ji; - size_t i = 0; +} + +static void +still_alive_with_check(void) +{ + jobmgr_log(root_jobmgr, LOG_NOTICE, "Still alive with %lu/%lu children", total_children, total_anon_children); + + jobmgr_log_active_jobs(root_jobmgr); + + runtime_closelog(); /* hack to flush logs */ +} + +jobmgr_t +jobmgr_shutdown(jobmgr_t jm) +{ + jobmgr_t jmi, jmn; + job_t ji; + + jobmgr_log(jm, LOG_DEBUG, "Beginning job manager shutdown with flags: %s", reboot_flags_to_C_names(jm->reboot_flags)); + + jm->shutting_down = true; + + SLIST_FOREACH_SAFE(jmi, &jm->submgrs, sle, jmn) { + jobmgr_shutdown(jmi); + } - SLIST_FOREACH(ji, &j->jobs, sle) { - tmp2 = job_export2(ji, true); - launch_data_array_set_index(tmp, tmp2, i); - i++; + if (jm->hopefully_first_cnt) { + LIST_FOREACH(ji, &jm->jobs, sle) { + if (ji->p && ji->hopefully_exits_first) { + job_stop(ji); + } } + } - launch_data_dict_insert(r, tmp, LAUNCH_JOBKEY_SUBJOBS); + if (debug_shutdown_hangs && jm->parentmgr == NULL && getpid() == 1) { + runtime_set_timeout(still_alive_with_check, 5); } - return r; + return jobmgr_do_garbage_collection(jm); } void -job_remove_all_inactive(struct jobcb *j) +jobmgr_remove(jobmgr_t jm) { - struct jobcb *ji; + jobmgr_t jmi; + job_t ji; - SLIST_FOREACH(ji, &j->jobs, sle) - job_remove_all_inactive(ji); + jobmgr_log(jm, LOG_DEBUG, "Removed job manager"); - if (!job_active(j)) { - job_remove(j); - } else if (getpid() != 1) { - job_stop(j); + if (!jobmgr_assumes(jm, SLIST_EMPTY(&jm->submgrs))) { + while ((jmi = SLIST_FIRST(&jm->submgrs))) { + jobmgr_remove(jmi); + } + } + + while ((ji = LIST_FIRST(&jm->jobs))) { + /* We should only have anonymous jobs left */ + job_assumes(ji, ji->anonymous); + job_remove(ji); + } + + if (jm->req_port) { + jobmgr_assumes(jm, launchd_mport_deallocate(jm->req_port) == KERN_SUCCESS); + } + + if (jm->jm_port) { + jobmgr_assumes(jm, launchd_mport_close_recv(jm->jm_port) == KERN_SUCCESS); + } + + if (jm == background_jobmgr) { + background_jobmgr = NULL; } + + if (jm->parentmgr) { + runtime_del_ref(); + SLIST_REMOVE(&jm->parentmgr->submgrs, jm, jobmgr_s, sle); + } else if (getpid() == 1) { + jobmgr_log(jm, LOG_DEBUG, "About to call: reboot(%s)", reboot_flags_to_C_names(jm->reboot_flags)); + runtime_closelog(); + jobmgr_assumes(jm, reboot(jm->reboot_flags) != -1); + runtime_closelog(); + } else { + runtime_closelog(); + jobmgr_log(jm, LOG_DEBUG, "About to exit"); + exit(EXIT_SUCCESS); + } + + free(jm); } void -job_remove(struct jobcb *j) +job_remove(job_t j) { - struct jobcb *ji; + struct waiting_for_removal *w4r; struct calendarinterval *ci; + struct semaphoreitem *si; struct socketgroup *sg; - struct watchpath *wp; + struct machservice *ms; struct limititem *li; + struct mspolicy *msp; struct envitem *ei; - struct machservice *ms; - struct semaphoreitem *si; - job_log(j, LOG_DEBUG, "Removed"); + if (j->p && j->anonymous) { + job_reap(j); + } else if (j->p) { + job_log(j, LOG_DEBUG, "Removal pended until the job exits"); - if (j->p) { - if (kevent_mod(j->p, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, &kqsimple_zombie_reaper) == -1) { - job_reap(j); - } else { - /* we've attached the simple zombie reaper, we're going to delete the job before it is dead */ - total_children--; + if (!j->removal_pending) { + j->removal_pending = true; job_stop(j); } + + return; } - if (j->parent) - SLIST_REMOVE(&j->parent->jobs, j, jobcb, sle); + ipc_close_all_with_job(j); - if (j->execfd) - launchd_assumes(close(j->execfd) == 0); + if (j->forced_peers_to_demand_mode) { + job_set_global_on_demand(j, false); + } - if (j->bs_port) { - if (j->transfer_bstrap) { - launchd_assumes(launchd_mport_deallocate(j->bs_port) == KERN_SUCCESS); - } else { - launchd_assumes(launchd_mport_close_recv(j->bs_port) == KERN_SUCCESS); - } + if (!job_assumes(j, j->forkfd == 0)) { + job_assumes(j, runtime_close(j->forkfd) != -1); } - if (j->req_port) - launchd_assumes(launchd_mport_deallocate(j->req_port) == KERN_SUCCESS); + if (!job_assumes(j, j->log_redirect_fd == 0)) { + job_assumes(j, runtime_close(j->log_redirect_fd) != -1); + } -#if 0 - if (j->wait_reply_port) { + if (j->j_port) { + job_assumes(j, launchd_mport_close_recv(j->j_port) == KERN_SUCCESS); } -#endif - while ((ji = SLIST_FIRST(&j->jobs))) - job_remove(ji); + if (!job_assumes(j, j->wait_reply_port == MACH_PORT_NULL)) { + job_assumes(j, launchd_mport_deallocate(j->wait_reply_port) == KERN_SUCCESS); + } - while ((sg = SLIST_FIRST(&j->sockets))) + while ((msp = SLIST_FIRST(&j->mspolicies))) { + mspolicy_delete(j, msp); + } + while ((sg = SLIST_FIRST(&j->sockets))) { socketgroup_delete(j, sg); - - while ((wp = SLIST_FIRST(&j->vnodes))) - watchpath_delete(j, wp); - - while ((ci = SLIST_FIRST(&j->cal_intervals))) + } + while ((ci = SLIST_FIRST(&j->cal_intervals))) { calendarinterval_delete(j, ci); - - while ((ei = SLIST_FIRST(&j->env))) + } + while ((ei = SLIST_FIRST(&j->env))) { envitem_delete(j, ei, false); - - while ((ei = SLIST_FIRST(&j->global_env))) + } + while ((ei = SLIST_FIRST(&j->global_env))) { envitem_delete(j, ei, true); - - while ((li = SLIST_FIRST(&j->limits))) + } + while ((li = SLIST_FIRST(&j->limits))) { limititem_delete(j, li); - - while ((ms = SLIST_FIRST(&j->machservices))) - machservice_delete(ms); - - while ((si = SLIST_FIRST(&j->semaphores))) + } + while ((ms = SLIST_FIRST(&j->machservices))) { + machservice_delete(j, ms, false); + } + while ((si = SLIST_FIRST(&j->semaphores))) { semaphoreitem_delete(j, si); + } + while ((w4r = SLIST_FIRST(&j->removal_watchers))) { + waiting4removal_delete(j, w4r); + } - if (j->prog) + if (j->prog) { free(j->prog); - - if (j->argv) + } + if (j->argv) { free(j->argv); - - if (j->rootdir) + } + if (j->rootdir) { free(j->rootdir); - - if (j->workingdir) + } + if (j->workingdir) { free(j->workingdir); - - if (j->username) + } + if (j->username) { free(j->username); - - if (j->groupname) + } + if (j->groupname) { free(j->groupname); - - if (j->stdinpath) - free(j->stdinpath); - - if (j->stdoutpath) + } + if (j->stdoutpath) { free(j->stdoutpath); - - if (j->stderrpath) + } + if (j->stderrpath) { free(j->stderrpath); - - if (j->start_interval) - kevent_mod((uintptr_t)&j->start_interval, EVFILT_TIMER, EV_DELETE, 0, 0, NULL); + } + if (j->seatbelt_profile) { + free(j->seatbelt_profile); + } + if (j->quarantine_data) { + free(j->quarantine_data); + } + if (j->j_binpref) { + free(j->j_binpref); + } + if (j->start_interval) { + runtime_del_ref(); + job_assumes(j, kevent_mod((uintptr_t)&j->start_interval, EVFILT_TIMER, EV_DELETE, 0, 0, NULL) != -1); + } + if (j->poll_for_vfs_changes) { + job_assumes(j, kevent_mod((uintptr_t)&j->semaphores, EVFILT_TIMER, EV_DELETE, 0, 0, j) != -1); + } kevent_mod((uintptr_t)j, EVFILT_TIMER, EV_DELETE, 0, 0, NULL); + + LIST_REMOVE(j, sle); + LIST_REMOVE(j, label_hash_sle); + + job_log(j, LOG_DEBUG, "Removed"); + free(j); } @@ -551,20 +892,22 @@ void socketgroup_setup(launch_data_t obj, const char *key, void *context) { launch_data_t tmp_oai; - struct jobcb *j = context; + job_t j = context; unsigned int i, fd_cnt = 1; int *fds; - if (launch_data_get_type(obj) == LAUNCH_DATA_ARRAY) + if (launch_data_get_type(obj) == LAUNCH_DATA_ARRAY) { fd_cnt = launch_data_array_get_count(obj); + } fds = alloca(fd_cnt * sizeof(int)); for (i = 0; i < fd_cnt; i++) { - if (launch_data_get_type(obj) == LAUNCH_DATA_ARRAY) + if (launch_data_get_type(obj) == LAUNCH_DATA_ARRAY) { tmp_oai = launch_data_array_get_index(obj, i); - else + } else { tmp_oai = obj; + } fds[i] = launch_data_get_fd(tmp_oai); } @@ -575,68 +918,100 @@ socketgroup_setup(launch_data_t obj, const char *key, void *context) } bool -job_setup_machport(struct jobcb *j) +job_set_global_on_demand(job_t j, bool val) +{ + if (j->forced_peers_to_demand_mode && val) { + return false; + } else if (!j->forced_peers_to_demand_mode && !val) { + return false; + } + + if ((j->forced_peers_to_demand_mode = val)) { + j->mgr->global_on_demand_cnt++; + } else { + j->mgr->global_on_demand_cnt--; + } + + if (j->mgr->global_on_demand_cnt == 0) { + jobmgr_dispatch_all(j->mgr, false); + } + + return true; +} + +bool +job_setup_machport(job_t j) { - if (!launchd_assumes(launchd_mport_create_recv(&j->bs_port) == KERN_SUCCESS)) + mach_msg_size_t mxmsgsz; + + if (!job_assumes(j, launchd_mport_create_recv(&j->j_port) == KERN_SUCCESS)) { goto out_bad; + } + + /* Sigh... at the moment, MIG has maxsize == sizeof(reply union) */ + mxmsgsz = sizeof(union __RequestUnion__job_mig_protocol_vproc_subsystem); + if (job_mig_protocol_vproc_subsystem.maxsize > mxmsgsz) { + mxmsgsz = job_mig_protocol_vproc_subsystem.maxsize; + } - if (!launchd_assumes(launchd_mport_request_callback(j->bs_port, j, true) == KERN_SUCCESS)) + if (!job_assumes(j, runtime_add_mport(j->j_port, protocol_vproc_server, mxmsgsz) == KERN_SUCCESS)) { goto out_bad2; + } + + if (!job_assumes(j, launchd_mport_notify_req(j->j_port, MACH_NOTIFY_NO_SENDERS) == KERN_SUCCESS)) { + job_assumes(j, launchd_mport_close_recv(j->j_port) == KERN_SUCCESS); + goto out_bad; + } return true; out_bad2: - launchd_assumes(launchd_mport_close_recv(j->bs_port) == KERN_SUCCESS); + job_assumes(j, launchd_mport_close_recv(j->j_port) == KERN_SUCCESS); out_bad: return false; } -struct jobcb * -job_new_via_mach_init(struct jobcb *jbs, const char *cmd, uid_t uid, bool ond) +job_t +job_new_via_mach_init(job_t j, const char *cmd, uid_t uid, bool ond) { const char **argv = (const char **)mach_cmd2argv(cmd); - struct jobcb *j = NULL; - char buf[1000]; + job_t jr = NULL; - if (!launchd_assumes(argv != NULL)) + if (!job_assumes(j, argv != NULL)) { goto out_bad; + } - /* preflight the string so we know how big it is */ - sprintf(buf, "100000.%s", basename((char *)argv[0])); - - j = job_new(jbs, buf, NULL, argv, NULL, MACH_PORT_NULL); + jr = job_new(j->mgr, AUTO_PICK_LEGACY_LABEL, NULL, argv); free(argv); - if (!launchd_assumes(j != NULL)) + /* jobs can easily be denied creation during shutdown */ + if (!jr) { goto out_bad; + } - j->mach_uid = uid; - j->ondemand = ond; - j->legacy_mach_job = true; - j->priv_port_has_senders = true; /* the IPC that called us will make-send on this port */ - - if (!job_setup_machport(j)) - goto out_bad; + jr->mach_uid = uid; + jr->ondemand = ond; + jr->legacy_mach_job = true; + jr->abandon_pg = true; + jr->priv_port_has_senders = true; /* the IPC that called us will make-send on this port */ - if (!launchd_assumes(launchd_mport_notify_req(j->bs_port, MACH_NOTIFY_NO_SENDERS) == KERN_SUCCESS)) { - launchd_assumes(launchd_mport_close_recv(j->bs_port) == KERN_SUCCESS); + if (!job_setup_machport(jr)) { goto out_bad; } - sprintf(j->label, "%d.%s", MACH_PORT_INDEX(j->bs_port), basename(j->argv[0])); + job_log(jr, LOG_INFO, "Legacy%s server created", ond ? " on-demand" : ""); - job_log(j, LOG_INFO, "New%s server in bootstrap: %x", ond ? " on-demand" : "", jbs->bs_port); - - return j; + return jr; out_bad: - if (j) - job_remove(j); + if (jr) { + job_remove(jr); + } return NULL; } kern_return_t -job_handle_mpm_wait(struct jobcb *j, mach_port_t srp, int *waitstatus) +job_handle_mpm_wait(job_t j, mach_port_t srp, int *waitstatus) { if (j->p) { j->wait_reply_port = srp; @@ -648,108 +1023,171 @@ job_handle_mpm_wait(struct jobcb *j, mach_port_t srp, int *waitstatus) return 0; } -struct jobcb * -job_new_spawn(const char *label, const char *path, const char *workingdir, const char *const *argv, const char *const *env, mode_t *u_mask, bool w4d, bool fppc) +job_t +job_new_anonymous(jobmgr_t jm, pid_t anonpid) { - struct jobcb *jr; - - if ((jr = job_find(root_job, label)) != NULL) { - errno = EEXIST; + int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, anonpid }; + struct kinfo_proc kp; + size_t len = sizeof(kp); + const char *zombie = NULL; + bool shutdown_state; + job_t jp = NULL, jr = NULL; + + if (!jobmgr_assumes(jm, anonpid != 0)) { return NULL; } - - jr = job_new(root_job, label, path, argv, NULL, MACH_PORT_NULL); - - if (!jr) + + if (!jobmgr_assumes(jm, anonpid < 100000)) { + /* The kernel current defines PID_MAX to be 99999, but that define isn't exported */ return NULL; + } - jr->unload_at_exit = true; - jr->stall_before_exec = w4d; - jr->force_ppc = fppc; + if (!jobmgr_assumes(jm, sysctl(mib, 4, &kp, &len, NULL, 0) != -1)) { + return NULL; + } - if (!job_setup_machport(jr)) { - job_remove(jr); + if (len != sizeof(kp)) { + jobmgr_log(jm, LOG_DEBUG, "Tried to create an anonymous job for nonexistent PID: %u", anonpid); return NULL; } - if (workingdir) - jr->workingdir = strdup(workingdir); + if (!jobmgr_assumes(jm, kp.kp_proc.p_comm[0] != '\0')) { + return NULL; + } - if (u_mask) { - jr->mask = *u_mask; - jr->setmask = true; + if (kp.kp_proc.p_stat == SZOMB) { + jobmgr_log(jm, LOG_DEBUG, "Tried to create an anonymous job for zombie PID: %u", anonpid); + zombie = "zombie"; } - if (env) for (; *env; env++) { - char newkey[strlen(*env) + 1], *eqoff = strchr(*env, '='); - if (!eqoff) { - job_log(jr, LOG_WARNING, "Environmental variable missing '=' separator: %s", *env); - continue; + switch (kp.kp_eproc.e_ppid) { + case 0: + /* the kernel */ + break; + case 1: + if (getpid() != 1) { + /* we cannot possibly find a parent job_t that is useful in this function */ + break; + } + /* fall through */ + default: + jp = jobmgr_find_by_pid(jm, kp.kp_eproc.e_ppid, true); + jobmgr_assumes(jm, jp != NULL); + break; + } + + /* A total hack: Normally, job_new() returns an error during shutdown, but anonymous jobs are special. */ + if ((shutdown_state = jm->shutting_down)) { + jm->shutting_down = false; + } + + if (jobmgr_assumes(jm, (jr = job_new(jm, AUTO_PICK_LEGACY_LABEL, zombie ? zombie : kp.kp_proc.p_comm, NULL)) != NULL)) { + u_int proc_fflags = NOTE_EXEC|NOTE_EXIT /* |NOTE_REAP */; + + total_anon_children++; + jr->anonymous = true; + jr->p = anonpid; + + /* anonymous process reaping is messy */ + LIST_INSERT_HEAD(&jm->active_jobs[ACTIVE_JOB_HASH(jr->p)], jr, pid_hash_sle); + + if (kevent_mod(jr->p, EVFILT_PROC, EV_ADD, proc_fflags, 0, root_jobmgr) == -1 && job_assumes(jr, errno == ESRCH)) { + /* zombies are weird */ + job_log(jr, LOG_ERR, "Failed to add kevent for PID %u. Will unload at MIG return", jr->p); + jr->unload_at_mig_return = true; + } + + if (jp) { + job_assumes(jr, mspolicy_copy(jr, jp)); + } + + if (shutdown_state && jm->hopefully_first_cnt == 0) { + job_log(jr, LOG_APPLEONLY, "This process showed up to the party while all the guests were leaving. Odds are that it will have a miserable time"); } - strcpy(newkey, *env); - *eqoff = '\0'; - envitem_new(jr, newkey, eqoff + 1, false); + + job_log(jr, LOG_DEBUG, "Created PID %u anonymously by PPID %u%s%s", anonpid, kp.kp_eproc.e_ppid, jp ? ": " : "", jp ? jp->label : ""); } - job_start(jr); + if (shutdown_state) { + jm->shutting_down = true; + } return jr; } -struct jobcb * -job_new(struct jobcb *p, const char *label, const char *prog, const char *const *argv, const char *stdinpath, mach_port_t reqport) +job_t +job_new(jobmgr_t jm, const char *label, const char *prog, const char *const *argv) { const char *const *argv_tmp = argv; + char auto_label[1000]; + const char *bn = NULL; char *co; + size_t minlabel_len; int i, cc = 0; - struct jobcb *j; + job_t j; + + launchd_assert(offsetof(struct job_s, kqjob_callback) == 0); + + if (jm->shutting_down) { + errno = EINVAL; + return NULL; + } - if (reqport == MACH_PORT_NULL && prog == NULL && argv == NULL) { + if (prog == NULL && argv == NULL) { errno = EINVAL; return NULL; } - j = calloc(1, sizeof(struct jobcb) + strlen(label) + 1); + if (label == AUTO_PICK_LEGACY_LABEL) { + bn = prog ? prog : basename((char *)argv[0]); /* prog for auto labels is kp.kp_kproc.p_comm */ + snprintf(auto_label, sizeof(auto_label), "%s.%s", sizeof(void *) == 8 ? "0xdeadbeeffeedface" : "0xbabecafe", bn); + label = auto_label; + /* This is so we can do gross things later. See NOTE_EXEC for anonymous jobs */ + minlabel_len = strlen(label) + MAXCOMLEN; + } else { + minlabel_len = strlen(label); + } + + j = calloc(1, sizeof(struct job_s) + minlabel_len + 1); - if (!launchd_assumes(j != NULL)) - goto out_bad; + if (!jobmgr_assumes(jm, j != NULL)) { + return NULL; + } - strcpy(j->label, label); + if (label == auto_label) { + snprintf((char *)j->label, strlen(label) + 1, "%p.%s", j, bn); + } else { + strcpy((char *)j->label, label); + } j->kqjob_callback = job_callback; - j->parent = p ? job_get_bs(p) : NULL; + j->mgr = jm; + j->min_run_time = LAUNCHD_MIN_JOB_RUN_TIME; + j->timeout = RUNTIME_ADVISABLE_IDLE_TIMEOUT; + j->exit_timeout = LAUNCHD_DEFAULT_EXIT_TIMEOUT; + j->currently_ignored = true; j->ondemand = true; j->checkedin = true; - j->firstborn = (strcmp(label, FIRSTBORN_LABEL) == 0); - - if (reqport != MACH_PORT_NULL) { - j->req_port = reqport; - if (!launchd_assumes(launchd_mport_notify_req(reqport, MACH_NOTIFY_DEAD_NAME) == KERN_SUCCESS)) - goto out_bad; - } if (prog) { j->prog = strdup(prog); - if (!launchd_assumes(j->prog != NULL)) - goto out_bad; - } - - if (stdinpath) { - j->stdinpath = strdup(stdinpath); - if (!launchd_assumes(j->stdinpath != NULL)) + if (!job_assumes(j, j->prog != NULL)) { goto out_bad; + } } if (argv) { while (*argv_tmp++) j->argc++; - for (i = 0; i < j->argc; i++) + for (i = 0; i < j->argc; i++) { cc += strlen(argv[i]) + 1; + } j->argv = malloc((j->argc + 1) * sizeof(char *) + cc); - if (!launchd_assumes(j != NULL)) + if (!job_assumes(j, j->argv != NULL)) { goto out_bad; + } co = ((char *)j->argv) + ((j->argc + 1) * sizeof(char *)); @@ -761,156 +1199,241 @@ job_new(struct jobcb *p, const char *label, const char *prog, const char *const j->argv[i] = NULL; } - if (j->parent) { - SLIST_INSERT_HEAD(&j->parent->jobs, j, sle); - job_log(j->parent, LOG_DEBUG, "Conceived"); - } + LIST_INSERT_HEAD(&jm->jobs, j, sle); + LIST_INSERT_HEAD(&label_hash[hash_label(j->label)], j, label_hash_sle); + + job_log(j, LOG_DEBUG, "Conceived"); return j; out_bad: - if (j) { - if (j->prog) - free(j->prog); - if (j->stdinpath) - free(j->stdinpath); - free(j); + if (j->prog) { + free(j->prog); } + free(j); + return NULL; } -struct jobcb * +job_t job_import(launch_data_t pload) { - struct jobcb *j = job_import2(pload); + job_t j = jobmgr_import2(root_jobmgr, pload); - if (j == NULL) + if (j == NULL) { return NULL; + } - job_dispatch(j); - - return j; + return job_dispatch(j, false); } launch_data_t job_import_bulk(launch_data_t pload) { launch_data_t resp = launch_data_alloc(LAUNCH_DATA_ARRAY); - struct jobcb **ja; + job_t *ja; size_t i, c = launch_data_array_get_count(pload); - ja = alloca(c * sizeof(struct jobcb *)); + ja = alloca(c * sizeof(job_t )); for (i = 0; i < c; i++) { - if ((ja[i] = job_import2(launch_data_array_get_index(pload, i)))) + if ((ja[i] = jobmgr_import2(root_jobmgr, launch_data_array_get_index(pload, i)))) { errno = 0; + } launch_data_array_set_index(resp, launch_data_new_errno(errno), i); } for (i = 0; i < c; i++) { - if (ja[i] == NULL) + if (ja[i] == NULL) { continue; - job_dispatch(ja[i]); + } + job_dispatch(ja[i], false); } return resp; } void -job_import_bool(struct jobcb *j, const char *key, bool value) +job_import_bool(job_t j, const char *key, bool value) { + bool found_key = false; + switch (key[0]) { - case 'f': - case 'F': - if (strcasecmp(key, LAUNCH_JOBKEY_FORCEPOWERPC) == 0) - j->force_ppc = value; + case 'a': + case 'A': + if (strcasecmp(key, LAUNCH_JOBKEY_ABANDONPROCESSGROUP) == 0) { + j->abandon_pg = value; + found_key = true; + } break; case 'k': case 'K': - if (strcasecmp(key, LAUNCH_JOBKEY_KEEPALIVE) == 0) + if (strcasecmp(key, LAUNCH_JOBKEY_KEEPALIVE) == 0) { j->ondemand = !value; + found_key = true; + } break; case 'o': case 'O': - if (strcasecmp(key, LAUNCH_JOBKEY_ONDEMAND) == 0) + if (strcasecmp(key, LAUNCH_JOBKEY_ONDEMAND) == 0) { j->ondemand = value; + found_key = true; + } break; case 'd': case 'D': - if (strcasecmp(key, LAUNCH_JOBKEY_DEBUG) == 0) + if (strcasecmp(key, LAUNCH_JOBKEY_DEBUG) == 0) { j->debug = value; + found_key = true; + } else if (strcasecmp(key, LAUNCH_JOBKEY_DISABLED) == 0) { + job_assumes(j, !value); + found_key = true; + } + break; + case 'h': + case 'H': + if (strcasecmp(key, LAUNCH_JOBKEY_HOPEFULLYEXITSLAST) == 0) { + j->hopefully_exits_last = value; + found_key = true; + } else if (strcasecmp(key, LAUNCH_JOBKEY_HOPEFULLYEXITSFIRST) == 0) { + j->hopefully_exits_first = value; + found_key = true; + } break; case 's': case 'S': - if (strcasecmp(key, LAUNCH_JOBKEY_SESSIONCREATE) == 0) + if (strcasecmp(key, LAUNCH_JOBKEY_SESSIONCREATE) == 0) { j->session_create = value; + found_key = true; + } else if (strcasecmp(key, LAUNCH_JOBKEY_STARTONMOUNT) == 0) { + j->start_on_mount = value; + found_key = true; + } else if (strcasecmp(key, LAUNCH_JOBKEY_SERVICEIPC) == 0) { + /* this only does something on Mac OS X 10.4 "Tiger" */ + found_key = true; + } break; case 'l': case 'L': - if (strcasecmp(key, LAUNCH_JOBKEY_LOWPRIORITYIO) == 0) + if (strcasecmp(key, LAUNCH_JOBKEY_LOWPRIORITYIO) == 0) { j->low_pri_io = value; + found_key = true; + } else if (strcasecmp(key, LAUNCH_JOBKEY_LAUNCHONLYONCE) == 0) { + j->only_once = value; + found_key = true; + } break; case 'i': case 'I': - if (strcasecmp(key, LAUNCH_JOBKEY_INITGROUPS) == 0) - j->init_groups = value; + if (strcasecmp(key, LAUNCH_JOBKEY_INITGROUPS) == 0) { + if (getuid() != 0) { + job_log(j, LOG_WARNING, "Ignored this key: %s", key); + return; + } + j->no_init_groups = !value; + found_key = true; + } break; case 'r': case 'R': - if (strcasecmp(key, LAUNCH_JOBKEY_RUNATLOAD) == 0) - j->runatload = value; + if (strcasecmp(key, LAUNCH_JOBKEY_RUNATLOAD) == 0) { + if (value) { + /* We don't want value == false to change j->start_pending */ + j->start_pending = true; + } + found_key = true; + } break; case 'e': case 'E': - if (strcasecmp(key, LAUNCH_JOBKEY_ENABLEGLOBBING) == 0) + if (strcasecmp(key, LAUNCH_JOBKEY_ENABLEGLOBBING) == 0) { j->globargv = value; + found_key = true; + } else if (strcasecmp(key, LAUNCH_JOBKEY_ENTERKERNELDEBUGGERBEFOREKILL) == 0) { + j->debug_before_kill = value; + found_key = true; + } break; case 'w': case 'W': - if (strcasecmp(key, LAUNCH_JOBKEY_WAITFORDEBUGGER) == 0) + if (strcasecmp(key, LAUNCH_JOBKEY_WAITFORDEBUGGER) == 0) { j->wait4debugger = value; + found_key = true; + } break; default: break; } + + if (!found_key) { + job_log(j, LOG_WARNING, "Unknown key for boolean: %s", key); + } } void -job_import_string(struct jobcb *j, const char *key, const char *value) +job_import_string(job_t j, const char *key, const char *value) { char **where2put = NULL; - char **ignore = (char **)-1; switch (key[0]) { case 'p': case 'P': - if (strcasecmp(key, LAUNCH_JOBKEY_PROGRAM) == 0) - where2put = ignore; + if (strcasecmp(key, LAUNCH_JOBKEY_PROGRAM) == 0) { + return; + } break; case 'l': case 'L': - if (strcasecmp(key, LAUNCH_JOBKEY_LABEL) == 0) - where2put = ignore; + if (strcasecmp(key, LAUNCH_JOBKEY_LABEL) == 0) { + return; + } else if (strcasecmp(key, LAUNCH_JOBKEY_LIMITLOADTOHOSTS) == 0) { + return; + } else if (strcasecmp(key, LAUNCH_JOBKEY_LIMITLOADFROMHOSTS) == 0) { + return; + } else if (strcasecmp(key, LAUNCH_JOBKEY_LIMITLOADTOSESSIONTYPE) == 0) { + job_reparent_hack(j, value); + return; + } break; case 'r': case 'R': - if (strcasecmp(key, LAUNCH_JOBKEY_ROOTDIRECTORY) == 0) + if (strcasecmp(key, LAUNCH_JOBKEY_ROOTDIRECTORY) == 0) { + if (getuid() != 0) { + job_log(j, LOG_WARNING, "Ignored this key: %s", key); + return; + } where2put = &j->rootdir; + } break; case 'w': case 'W': - if (strcasecmp(key, LAUNCH_JOBKEY_WORKINGDIRECTORY) == 0) + if (strcasecmp(key, LAUNCH_JOBKEY_WORKINGDIRECTORY) == 0) { where2put = &j->workingdir; + } break; case 'u': case 'U': - if (strcasecmp(key, LAUNCH_JOBKEY_USERNAME) == 0) + if (strcasecmp(key, LAUNCH_JOBKEY_USERNAME) == 0) { + if (getuid() != 0) { + job_log(j, LOG_WARNING, "Ignored this key: %s", key); + return; + } else if (strcmp(value, "root") == 0) { + return; + } where2put = &j->username; + } break; case 'g': case 'G': - if (strcasecmp(key, LAUNCH_JOBKEY_GROUPNAME) == 0) + if (strcasecmp(key, LAUNCH_JOBKEY_GROUPNAME) == 0) { + if (getuid() != 0) { + job_log(j, LOG_WARNING, "Ignored this key: %s", key); + return; + } else if (strcmp(value, "wheel") == 0) { + return; + } where2put = &j->groupname; + } break; case 's': case 'S': @@ -918,38 +1441,63 @@ job_import_string(struct jobcb *j, const char *key, const char *value) where2put = &j->stdoutpath; } else if (strcasecmp(key, LAUNCH_JOBKEY_STANDARDERRORPATH) == 0) { where2put = &j->stderrpath; + } else if (strcasecmp(key, LAUNCH_JOBKEY_SANDBOXPROFILE) == 0) { + where2put = &j->seatbelt_profile; } break; default: + job_log(j, LOG_WARNING, "Unknown key for string: %s", key); break; } if (where2put) { - if (where2put == ignore) - return; - - launchd_assumes((*where2put = strdup(value)) != NULL); + job_assumes(j, (*where2put = strdup(value)) != NULL); } else { - job_log(j, LOG_WARNING, "Unknown value for key %s: %s", key, value); + job_log(j, LOG_WARNING, "Unknown key: %s", key); } } void -job_import_integer(struct jobcb *j, const char *key, long long value) +job_import_integer(job_t j, const char *key, long long value) { switch (key[0]) { + case 'e': + case 'E': + if (strcasecmp(key, LAUNCH_JOBKEY_EXITTIMEOUT) == 0) { + if (value < 0) { + job_log(j, LOG_WARNING, "%s less than zero. Ignoring.", LAUNCH_JOBKEY_EXITTIMEOUT); + } else if (value > UINT32_MAX) { + job_log(j, LOG_WARNING, "%s is too large. Ignoring.", LAUNCH_JOBKEY_EXITTIMEOUT); + } else { + j->exit_timeout = value; + } + } + break; case 'n': case 'N': - if (strcasecmp(key, LAUNCH_JOBKEY_NICE) == 0) + if (strcasecmp(key, LAUNCH_JOBKEY_NICE) == 0) { j->nice = value; + j->setnice = true; + } break; case 't': case 'T': if (strcasecmp(key, LAUNCH_JOBKEY_TIMEOUT) == 0) { - if (value <= 0) - job_log(j, LOG_WARNING, "Timeout less than or equal to zero. Ignoring."); - else + if (value < 0) { + job_log(j, LOG_WARNING, "%s less than zero. Ignoring.", LAUNCH_JOBKEY_TIMEOUT); + } else if (value > UINT32_MAX) { + job_log(j, LOG_WARNING, "%s is too large. Ignoring.", LAUNCH_JOBKEY_TIMEOUT); + } else { j->timeout = value; + } + } else if (strcasecmp(key, LAUNCH_JOBKEY_THROTTLEINTERVAL) == 0) { + if (value < 0) { + job_log(j, LOG_WARNING, "%s less than zero. Ignoring.", LAUNCH_JOBKEY_THROTTLEINTERVAL); + } else if (value > UINT32_MAX) { + job_log(j, LOG_WARNING, "%s is too large. Ignoring.", LAUNCH_JOBKEY_THROTTLEINTERVAL); + } else { + j->min_run_time = value; + } } break; case 'u': @@ -962,12 +1510,40 @@ job_import_integer(struct jobcb *j, const char *key, long long value) case 's': case 'S': if (strcasecmp(key, LAUNCH_JOBKEY_STARTINTERVAL) == 0) { - if (value <= 0) - job_log(j, LOG_WARNING, "StartInterval is not greater than zero, ignoring"); - else + if (value <= 0) { + job_log(j, LOG_WARNING, "%s is not greater than zero. Ignoring.", LAUNCH_JOBKEY_STARTINTERVAL); + } else if (value > UINT32_MAX) { + job_log(j, LOG_WARNING, "%s is too large. Ignoring.", LAUNCH_JOBKEY_STARTINTERVAL); + } else { + runtime_add_ref(); j->start_interval = value; - if (-1 == kevent_mod((uintptr_t)&j->start_interval, EVFILT_TIMER, EV_ADD, NOTE_SECONDS, value, j)) - job_log_error(j, LOG_ERR, "adding kevent timer"); + + job_assumes(j, kevent_mod((uintptr_t)&j->start_interval, EVFILT_TIMER, EV_ADD, NOTE_SECONDS, value, j) != -1); + } + } else if (strcasecmp(key, LAUNCH_JOBKEY_SANDBOXFLAGS) == 0) { + j->seatbelt_flags = value; + } + + break; + default: + job_log(j, LOG_WARNING, "Unknown key for integer: %s", key); + break; + } +} + +void +job_import_opaque(job_t j, const char *key, launch_data_t value) +{ + switch (key[0]) { + case 'q': + case 'Q': + if (strcasecmp(key, LAUNCH_JOBKEY_QUARANTINEDATA) == 0) { + size_t tmpsz = launch_data_get_opaque_size(value); + + if (job_assumes(j, j->quarantine_data = malloc(tmpsz))) { + memcpy(j->quarantine_data, launch_data_get_opaque(value), tmpsz); + j->quarantine_data_sz = tmpsz; + } } break; default: @@ -976,28 +1552,32 @@ job_import_integer(struct jobcb *j, const char *key, long long value) } void -job_import_dictionary(struct jobcb *j, const char *key, launch_data_t value) +job_import_dictionary(job_t j, const char *key, launch_data_t value) { launch_data_t tmp; switch (key[0]) { case 'k': case 'K': - if (strcasecmp(key, LAUNCH_JOBKEY_KEEPALIVE) == 0) + if (strcasecmp(key, LAUNCH_JOBKEY_KEEPALIVE) == 0) { launch_data_dict_iterate(value, semaphoreitem_setup, j); + } break; case 'i': case 'I': if (strcasecmp(key, LAUNCH_JOBKEY_INETDCOMPATIBILITY) == 0) { j->inetcompat = true; - if ((tmp = launch_data_dict_lookup(value, LAUNCH_JOBINETDCOMPATIBILITY_WAIT))) + j->abandon_pg = true; + if ((tmp = launch_data_dict_lookup(value, LAUNCH_JOBINETDCOMPATIBILITY_WAIT))) { j->inetcompat_wait = launch_data_get_bool(tmp); + } } break; case 'e': case 'E': - if (strcasecmp(key, LAUNCH_JOBKEY_ENVIRONMENTVARIABLES) == 0) + if (strcasecmp(key, LAUNCH_JOBKEY_ENVIRONMENTVARIABLES) == 0) { launch_data_dict_iterate(value, envitem_setup, j); + } break; case 'u': case 'U': @@ -1015,6 +1595,8 @@ job_import_dictionary(struct jobcb *j, const char *key, launch_data_t value) calendarinterval_new_from_obj(j, value); } else if (strcasecmp(key, LAUNCH_JOBKEY_SOFTRESOURCELIMITS) == 0) { launch_data_dict_iterate(value, limititem_setup, j); + } else if (strcasecmp(key, LAUNCH_JOBKEY_SANDBOXFLAGS) == 0) { + launch_data_dict_iterate(value, seatbelt_setup_flags, j); } break; case 'h': @@ -1029,69 +1611,99 @@ job_import_dictionary(struct jobcb *j, const char *key, launch_data_t value) case 'M': if (strcasecmp(key, LAUNCH_JOBKEY_MACHSERVICES) == 0) { launch_data_dict_iterate(value, machservice_setup, j); - if (!SLIST_EMPTY(&j->machservices)) - job_setup_machport(j); + } else if (strcasecmp(key, LAUNCH_JOBKEY_MACHSERVICELOOKUPPOLICIES) == 0) { + launch_data_dict_iterate(value, mspolicy_setup, j); } break; default: + job_log(j, LOG_WARNING, "Unknown key for dictionary: %s", key); break; } } void -job_import_array(struct jobcb *j, const char *key, launch_data_t value) +job_import_array(job_t j, const char *key, launch_data_t value) { - bool is_q_dir = false; - bool is_wp = false; + size_t i, value_cnt = launch_data_array_get_count(value); + const char *str; switch (key[0]) { + case 'p': + case 'P': + if (strcasecmp(key, LAUNCH_JOBKEY_PROGRAMARGUMENTS) == 0) { + return; + } + break; + case 'l': + case 'L': + if (strcasecmp(key, LAUNCH_JOBKEY_LIMITLOADTOHOSTS) == 0) { + return; + } else if (strcasecmp(key, LAUNCH_JOBKEY_LIMITLOADFROMHOSTS) == 0) { + return; + } else if (strcasecmp(key, LAUNCH_JOBKEY_LIMITLOADTOSESSIONTYPE) == 0) { + job_log(j, LOG_NOTICE, "launchctl should have transformed the \"%s\" array to a string", LAUNCH_JOBKEY_LIMITLOADTOSESSIONTYPE); + return; + } + break; case 'q': case 'Q': if (strcasecmp(key, LAUNCH_JOBKEY_QUEUEDIRECTORIES) == 0) { - is_q_dir = true; - is_wp = true; + for (i = 0; i < value_cnt; i++) { + str = launch_data_get_string(launch_data_array_get_index(value, i)); + if (job_assumes(j, str != NULL)) { + semaphoreitem_new(j, DIR_NOT_EMPTY, str); + } + } + } break; case 'w': case 'W': - if (strcasecmp(key, LAUNCH_JOBKEY_WATCHPATHS) == 0) - is_wp = true; + if (strcasecmp(key, LAUNCH_JOBKEY_WATCHPATHS) == 0) { + for (i = 0; i < value_cnt; i++) { + str = launch_data_get_string(launch_data_array_get_index(value, i)); + if (job_assumes(j, str != NULL)) { + semaphoreitem_new(j, PATH_CHANGES, str); + } + } + } break; case 'b': case 'B': - if (strcasecmp(key, LAUNCH_JOBKEY_BONJOURFDS) == 0) + if (strcasecmp(key, LAUNCH_JOBKEY_BONJOURFDS) == 0) { socketgroup_setup(value, LAUNCH_JOBKEY_BONJOURFDS, j); + } else if (strcasecmp(key, LAUNCH_JOBKEY_BINARYORDERPREFERENCE) == 0) { + if (job_assumes(j, j->j_binpref = malloc(value_cnt * sizeof(*j->j_binpref)))) { + j->j_binpref_cnt = value_cnt; + for (i = 0; i < value_cnt; i++) { + j->j_binpref[i] = launch_data_get_integer(launch_data_array_get_index(value, i)); + } + } + } break; case 's': case 'S': if (strcasecmp(key, LAUNCH_JOBKEY_STARTCALENDARINTERVAL) == 0) { - size_t i = 0, ci_cnt = launch_data_array_get_count(value); - for (i = 0; i < ci_cnt; i++) + for (i = 0; i < value_cnt; i++) { calendarinterval_new_from_obj(j, launch_data_array_get_index(value, i)); + } } break; default: + job_log(j, LOG_WARNING, "Unknown key for array: %s", key); break; } - - if (is_wp) { - size_t i, wp_cnt = launch_data_array_get_count(value); - const char *thepath; - for (i = 0; i < wp_cnt; i++) { - thepath = launch_data_get_string(launch_data_array_get_index(value, i)); - watchpath_new(j, thepath, is_q_dir); - } - } } void job_import_keys(launch_data_t obj, const char *key, void *context) { - struct jobcb *j = context; + job_t j = context; launch_data_type_t kind; - if (obj == NULL) + if (obj == NULL) { return; + } kind = launch_data_get_type(obj); @@ -1111,114 +1723,241 @@ job_import_keys(launch_data_t obj, const char *key, void *context) case LAUNCH_DATA_ARRAY: job_import_array(j, key, obj); break; + case LAUNCH_DATA_OPAQUE: + job_import_opaque(j, key, obj); + break; default: job_log(j, LOG_WARNING, "Unknown value type '%d' for key: %s", kind, key); break; } } -struct jobcb * -job_import2(launch_data_t pload) +job_t +jobmgr_import2(jobmgr_t jm, launch_data_t pload) { launch_data_t tmp, ldpa; const char *label = NULL, *prog = NULL; const char **argv = NULL; - struct jobcb *j; + job_t j; + + if (pload == NULL) { + errno = EINVAL; + return NULL; + } - if (pload == NULL) + if (launch_data_get_type(pload) != LAUNCH_DATA_DICTIONARY) { + errno = EINVAL; return NULL; + } - if (launch_data_get_type(pload) != LAUNCH_DATA_DICTIONARY) + if (!(tmp = launch_data_dict_lookup(pload, LAUNCH_JOBKEY_LABEL))) { + errno = EINVAL; return NULL; + } - if ((tmp = launch_data_dict_lookup(pload, LAUNCH_JOBKEY_LABEL)) && - (launch_data_get_type(tmp) == LAUNCH_DATA_STRING)) { - label = launch_data_get_string(tmp); + if (launch_data_get_type(tmp) != LAUNCH_DATA_STRING) { + errno = EINVAL; + return NULL; } + + if (!(label = launch_data_get_string(tmp))) { + errno = EINVAL; + return NULL; + } + if ((tmp = launch_data_dict_lookup(pload, LAUNCH_JOBKEY_PROGRAM)) && (launch_data_get_type(tmp) == LAUNCH_DATA_STRING)) { prog = launch_data_get_string(tmp); } - ldpa = launch_data_dict_lookup(pload, LAUNCH_JOBKEY_PROGRAMARGUMENTS); - if (label == NULL) { - errno = EINVAL; - return NULL; - } else if ((j = job_find(root_job, label)) != NULL) { + if ((ldpa = launch_data_dict_lookup(pload, LAUNCH_JOBKEY_PROGRAMARGUMENTS))) { + size_t i, c; + + if (launch_data_get_type(ldpa) != LAUNCH_DATA_ARRAY) { + errno = EINVAL; + return NULL; + } + + c = launch_data_array_get_count(ldpa); + + argv = alloca((c + 1) * sizeof(char *)); + + for (i = 0; i < c; i++) { + tmp = launch_data_array_get_index(ldpa, i); + + if (launch_data_get_type(tmp) != LAUNCH_DATA_STRING) { + errno = EINVAL; + return NULL; + } + + argv[i] = launch_data_get_string(tmp); + } + + argv[i] = NULL; + } + + if ((j = job_find(label)) != NULL) { errno = EEXIST; return NULL; } else if (label[0] == '\0' || (strncasecmp(label, "", strlen("com.apple.launchd")) == 0) || (strtol(label, NULL, 10) != 0)) { - syslog(LOG_ERR, "Somebody attempted to use a reserved prefix for a label: %s", label); + jobmgr_log(jm, LOG_ERR, "Somebody attempted to use a reserved prefix for a label: %s", label); /* the empty string, com.apple.launchd and number prefixes for labels are reserved */ errno = EINVAL; return NULL; } - if (ldpa) { - size_t i, c = launch_data_array_get_count(ldpa); + if ((j = job_new(jm, label, prog, argv))) { + launch_data_dict_iterate(pload, job_import_keys, j); + } - argv = alloca((c + 1) * sizeof(char *)); + return j; +} - for (i = 0; i < c; i++) - argv[i] = launch_data_get_string(launch_data_array_get_index(ldpa, i)); - argv[i] = NULL; +job_t +job_find(const char *label) +{ + job_t ji; + + LIST_FOREACH(ji, &label_hash[hash_label(label)], label_hash_sle) { + if (ji->removal_pending) { + continue; /* 5351245 */ + } else if (ji->mgr->shutting_down) { + continue; /* 5488633 */ + } + + if (strcmp(ji->label, label) == 0) { + return ji; + } } - if ((j = job_new(root_job, label, prog, argv, NULL, MACH_PORT_NULL))) - launch_data_dict_iterate(pload, job_import_keys, j); + errno = ESRCH; + return NULL; +} - return j; +job_t +jobmgr_find_by_pid(jobmgr_t jm, pid_t p, bool create_anon) +{ + job_t ji = NULL; + + LIST_FOREACH(ji, &jm->active_jobs[ACTIVE_JOB_HASH(p)], pid_hash_sle) { + if (ji->p == p) { + break; + } + } + + if (ji) { + return ji; + } else if (create_anon) { + return job_new_anonymous(jm, p); + } else { + return NULL; + } } -struct jobcb * -job_find(struct jobcb *j, const char *label) +job_t +job_mig_intran2(jobmgr_t jm, mach_port_t mport, pid_t upid) { - struct jobcb *jr, *ji; + jobmgr_t jmi; + job_t ji; - if (label[0] == '\0') - return root_job; + if (jm->jm_port == mport) { + jobmgr_assumes(jm, (ji = jobmgr_find_by_pid(jm, upid, true)) != NULL); + return ji; + } - if (strcmp(j->label, label) == 0) - return j; + SLIST_FOREACH(jmi, &jm->submgrs, sle) { + job_t jr; - SLIST_FOREACH(ji, &j->jobs, sle) { - if ((jr = job_find(ji, label))) + if ((jr = job_mig_intran2(jmi, mport, upid))) { return jr; + } + } + + LIST_FOREACH(ji, &jm->jobs, sle) { + if (ji->j_port == mport) { + return ji; + } } - errno = ESRCH; return NULL; } -struct jobcb * -job_find_by_pid(struct jobcb *j, pid_t p) +job_t +job_mig_intran(mach_port_t p) { - struct jobcb *jr, *ji; + struct ldcred ldc; + job_t jr; - if (j->p == p) - return j; + runtime_get_caller_creds(&ldc); - SLIST_FOREACH(ji, &j->jobs, sle) { - if ((jr = job_find_by_pid(ji, p))) - return jr; + jr = job_mig_intran2(root_jobmgr, p, ldc.pid); + + if (!jobmgr_assumes(root_jobmgr, jr != NULL)) { + int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, 0 }; + struct kinfo_proc kp; + size_t len = sizeof(kp); + + mib[3] = ldc.pid; + + if (jobmgr_assumes(root_jobmgr, sysctl(mib, 4, &kp, &len, NULL, 0) != -1) && jobmgr_assumes(root_jobmgr, len == sizeof(kp))) { + jobmgr_log(root_jobmgr, LOG_ERR, "%s() was confused by PID %u UID %u EUID %u Mach Port 0x%x: %s", __func__, ldc.pid, ldc.uid, ldc.euid, p, kp.kp_proc.p_comm); + } + } + + return jr; +} + +job_t +job_find_by_service_port(mach_port_t p) +{ + struct machservice *ms; + + LIST_FOREACH(ms, &port_hash[HASH_PORT(p)], port_hash_sle) { + if (ms->recv && (ms->port == p)) { + return ms->job; + } } - errno = ESRCH; return NULL; } void -job_export_all2(struct jobcb *j, launch_data_t where) +job_mig_destructor(job_t j) { - launch_data_t tmp; - struct jobcb *ji; + /* + * 5477111 + * + * 'j' can be invalid at this point. We should fix this up after Leopard ships. + */ + + if (j && j != workaround_5477111 && j->unload_at_mig_return) { + job_log(j, LOG_NOTICE, "Unloading PID %u at MIG return.", j->p); + job_remove(j); + } - if (launchd_assumes((tmp = job_export2(j, false)) != NULL)) - launch_data_dict_insert(where, tmp, j->label); + workaround_5477111 = NULL; - SLIST_FOREACH(ji, &j->jobs, sle) - job_export_all2(ji, where); + calendarinterval_sanity_check(); +} + +void +job_export_all2(jobmgr_t jm, launch_data_t where) +{ + jobmgr_t jmi; + job_t ji; + + SLIST_FOREACH(jmi, &jm->submgrs, sle) { + job_export_all2(jmi, where); + } + + LIST_FOREACH(ji, &jm->jobs, sle) { + launch_data_t tmp; + + if (jobmgr_assumes(jm, (tmp = job_export(ji)) != NULL)) { + launch_data_dict_insert(where, tmp, ji->label); + } + } } launch_data_t @@ -1226,36 +1965,140 @@ job_export_all(void) { launch_data_t resp = launch_data_alloc(LAUNCH_DATA_DICTIONARY); - job_export_all2(root_job, resp); + if (launchd_assumes(resp != NULL)) { + job_export_all2(root_jobmgr, resp); + } return resp; } void -job_reap(struct jobcb *j) +job_log_stray_pg(job_t j) { - struct rusage ru; - time_t td = time(NULL) - j->start_time; - bool bad_exit = false; - int status; - - job_log(j, LOG_DEBUG, "Reaping"); + int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PGRP, j->p }; + size_t i, kp_cnt, len = 10*1024*1024; + struct kinfo_proc *kp; - if (j->execfd) { - launchd_assumes(close(j->execfd) == 0); - j->execfd = 0; + if (!job_assumes(j, (kp = malloc(len)) != NULL)) { + return; + } + if (!job_assumes(j, sysctl(mib, 4, kp, &len, NULL, 0) != -1)) { + goto out; } - if (!launchd_assumes(wait4(j->p, &status, 0, &ru) != -1)) { - return; + kp_cnt = len / sizeof(struct kinfo_proc); + + for (i = 0; i < kp_cnt; i++) { + pid_t p_i = kp[i].kp_proc.p_pid; + pid_t pp_i = kp[i].kp_eproc.e_ppid; + const char *z = (kp[i].kp_proc.p_stat == SZOMB) ? "zombie " : ""; + const char *n = kp[i].kp_proc.p_comm; + + if (p_i == j->p) { + continue; + } else if (!job_assumes(j, p_i != 0 && p_i != 1)) { + continue; + } + + job_log(j, LOG_WARNING, "Stray %sprocess with PGID equal to this dead job: PID %u PPID %u %s", z, p_i, pp_i, n); + } + +out: + free(kp); +} + +void +job_reap(job_t j) +{ + struct rusage ru; + int status; + + job_log(j, LOG_DEBUG, "Reaping"); + + if (j->weird_bootstrap) { + mach_msg_size_t mxmsgsz = sizeof(union __RequestUnion__job_mig_protocol_vproc_subsystem); + + if (job_mig_protocol_vproc_subsystem.maxsize > mxmsgsz) { + mxmsgsz = job_mig_protocol_vproc_subsystem.maxsize; + } + + job_assumes(j, runtime_add_mport(j->mgr->jm_port, protocol_vproc_server, mxmsgsz) == KERN_SUCCESS); + j->weird_bootstrap = false; + } + + if (j->log_redirect_fd && !j->wait4pipe_eof) { + job_assumes(j, runtime_close(j->log_redirect_fd) != -1); + j->log_redirect_fd = 0; + } + + if (j->forkfd) { + job_assumes(j, runtime_close(j->forkfd) != -1); + j->forkfd = 0; + } + + if (j->anonymous) { + status = 0; + memset(&ru, 0, sizeof(ru)); + } else { + /* + * The job is dead. While the PID/PGID is still known to be + * valid, try to kill abandoned descendant processes. + */ + job_log_stray_pg(j); + if (!j->abandon_pg) { + job_assumes(j, runtime_killpg(j->p, SIGTERM) != -1 || errno == ESRCH); + } + + /* + * 5020256 + * + * The current implementation of ptrace() causes the traced process to + * be abducted away from the true parent and adopted by the tracer. + * + * Once the tracing process relinquishes control, the kernel then + * restores the true parent/child relationship. + * + * Unfortunately, the wait*() family of APIs is unaware of the temporarily + * data structures changes, and they return an error if reality hasn't + * been restored by the time they are called. + */ + if (!job_assumes(j, wait4(j->p, &status, 0, &ru) != -1)) { + job_log(j, LOG_NOTICE, "Working around 5020256. Assuming the job crashed."); + + status = W_EXITCODE(0, SIGSEGV); + memset(&ru, 0, sizeof(ru)); + } } + if (j->exit_timeout) { + kevent_mod((uintptr_t)&j->exit_timeout, EVFILT_TIMER, EV_DELETE, 0, 0, NULL); + } + + if (j->anonymous) { + total_anon_children--; + } else { + runtime_del_ref(); + total_children--; + } + LIST_REMOVE(j, pid_hash_sle); + if (j->wait_reply_port) { job_log(j, LOG_DEBUG, "MPM wait reply being sent"); - launchd_assumes(mpm_wait_reply(j->wait_reply_port, 0, status) == 0); + job_assumes(j, job_mig_wait_reply(j->wait_reply_port, 0, status) == 0); j->wait_reply_port = MACH_PORT_NULL; } + if (j->sent_sigterm_time) { + uint64_t td_sec, td_usec, td = (mach_absolute_time() - j->sent_sigterm_time) * tbi.numer / tbi.denom; + + td_sec = td / NSEC_PER_SEC; + td_usec = (td % NSEC_PER_SEC) / NSEC_PER_USEC; + + job_log(j, LOG_INFO, "Exited %lld.%06lld seconds after %s was sent", + td_sec, td_usec, signal_to_C_name(j->sent_sigkill ? SIGKILL : SIGTERM)); + } + +#if DO_RUSAGE_SUMMATION timeradd(&ru.ru_utime, &j->ru.ru_utime, &j->ru.ru_utime); timeradd(&ru.ru_stime, &j->ru.ru_stime, &j->ru.ru_stime); j->ru.ru_maxrss += ru.ru_maxrss; @@ -1272,10 +2115,10 @@ job_reap(struct jobcb *j) j->ru.ru_nsignals += ru.ru_nsignals; j->ru.ru_nvcsw += ru.ru_nvcsw; j->ru.ru_nivcsw += ru.ru_nivcsw; +#endif if (WIFEXITED(status) && WEXITSTATUS(status) != 0) { - job_log(j, LOG_WARNING, "exited with exit code: %d", WEXITSTATUS(status)); - bad_exit = true; + job_log(j, LOG_WARNING, "Exited with exit code: %d", WEXITSTATUS(status)); } if (WIFSIGNALED(status)) { @@ -1284,242 +2127,500 @@ job_reap(struct jobcb *j) job_log(j, LOG_NOTICE, "Exited: %s", strsignal(s)); } else { job_log(j, LOG_WARNING, "Exited abnormally: %s", strsignal(s)); - bad_exit = true; } } - if (!j->ondemand && !j->legacy_mach_job) { - if (td < LAUNCHD_MIN_JOB_RUN_TIME) { - job_log(j, LOG_WARNING, "respawning too quickly! throttling"); - bad_exit = true; - j->throttle = true; - } else if (td >= LAUNCHD_REWARD_JOB_RUN_TIME) { - job_log(j, LOG_INFO, "lived long enough, forgiving past exit failures"); - j->failed_exits = 0; - } + if (j->hopefully_exits_first) { + j->mgr->hopefully_first_cnt--; + } else if (!j->anonymous && !j->hopefully_exits_last) { + j->mgr->normal_active_cnt--; + } + j->last_exit_status = status; + j->sent_sigkill = false; + j->p = 0; + + /* + * We need to someday evaluate other jobs and find those who wish to track the + * active/inactive state of this job. The current job_dispatch() logic makes + * this messy, given that jobs can be deleted at dispatch. + */ +} + +void +jobmgr_dispatch_all(jobmgr_t jm, bool newmounthack) +{ + jobmgr_t jmi, jmn; + job_t ji, jn; + + if (jm->shutting_down) { + return; + } + + SLIST_FOREACH_SAFE(jmi, &jm->submgrs, sle, jmn) { + jobmgr_dispatch_all(jmi, newmounthack); } - if (!j->legacy_mach_job && bad_exit) - j->failed_exits++; + LIST_FOREACH_SAFE(ji, &jm->jobs, sle, jn) { + if (newmounthack && ji->start_on_mount) { + ji->start_pending = true; + } - if (j->failed_exits > 0) { - int failures_left = LAUNCHD_FAILED_EXITS_THRESHOLD - j->failed_exits; - if (failures_left) - job_log(j, LOG_WARNING, "%d more failure%s without living at least %d seconds will cause job removal", - failures_left, failures_left > 1 ? "s" : "", LAUNCHD_REWARD_JOB_RUN_TIME); + job_dispatch(ji, false); } +} - total_children--; - j->last_exit_status = status; - j->p = 0; +job_t +job_dispatch(job_t j, bool kickstart) +{ + /* + * The whole job removal logic needs to be consolidated. The fact that + * a job can be removed from just about anywhere makes it easy to have + * stale pointers left behind somewhere on the stack that might get + * used after the deallocation. In particular, during job iteration. + * + * This is a classic example. The act of dispatching a job may delete it. + */ + if (!job_active(j)) { + if (job_useless(j)) { + job_remove(j); + return NULL; + } else if (kickstart || job_keepalive(j)) { + job_start(j); + } else { + job_watch(j); + + /* + * 5455720 + * + * Path checking and monitoring is really racy right now. + * We should clean this up post Leopard. + */ + if (job_keepalive(j)) { + job_start(j); + } + } + } else { + job_log(j, LOG_DEBUG, "Tried to dispatch an already active job."); + } + + return j; } void -job_dispatch(struct jobcb *j) +job_log_stdouterr2(job_t j, const char *msg, ...) { - if (job_active(j)) { + struct runtime_syslog_attr attr = { j->label, j->label, j->mgr->name, LOG_NOTICE, getuid(), j->p, j->p }; + va_list ap; + + va_start(ap, msg); + runtime_vsyslog(&attr, msg, ap); + va_end(ap); +} + +void +job_log_stdouterr(job_t j) +{ + char *msg, *bufindex, *buf = malloc(BIG_PIPE_SIZE + 1); + bool close_log_redir = false; + ssize_t rsz; + + if (!job_assumes(j, buf != NULL)) { return; - } else if (job_useless(j)) { - job_remove(j); - } else if (job_keepalive(j)) { - job_start(j); + } + + bufindex = buf; + + rsz = read(j->log_redirect_fd, buf, BIG_PIPE_SIZE); + + if (rsz == 0) { + job_log(j, LOG_DEBUG, "Standard out/error pipe closed"); + close_log_redir = true; + } else if (!job_assumes(j, rsz != -1)) { + close_log_redir = true; } else { - job_watch(j); + buf[rsz] = '\0'; + + while ((msg = strsep(&bufindex, "\n\r"))) { + if (msg[0]) { + job_log_stdouterr2(j, "%s", msg); + } + } + } + + free(buf); + + if (close_log_redir) { + job_assumes(j, runtime_close(j->log_redirect_fd) != -1); + j->log_redirect_fd = 0; + job_dispatch(j, false); } } void -job_callback(void *obj, struct kevent *kev) +job_kill(job_t j) { - struct jobcb *j = obj; - bool d = j->debug; - int oldmask = 0; + if (!j->p || j->anonymous) { + return; + } - if (d) { - oldmask = setlogmask(LOG_UPTO(LOG_DEBUG)); + job_assumes(j, runtime_kill(j->p, SIGKILL) != -1); + + j->sent_sigkill = true; + + job_assumes(j, kevent_mod((uintptr_t)&j->exit_timeout, EVFILT_TIMER, + EV_ADD, NOTE_SECONDS, LAUNCHD_SIGKILL_TIMER, j) != -1); + + job_log(j, LOG_DEBUG, "Sent SIGKILL signal."); +} + +void +job_callback_proc(job_t j, int flags, int fflags) +{ + if ((fflags & NOTE_EXEC) && j->anonymous) { + int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, j->p }; + struct kinfo_proc kp; + size_t len = sizeof(kp); + + if (job_assumes(j, sysctl(mib, 4, &kp, &len, NULL, 0) != -1)) { + char newlabel[1000]; + + snprintf(newlabel, sizeof(newlabel), "%p.%s", j, kp.kp_proc.p_comm); + + job_log(j, LOG_DEBUG, "Program changed. Updating the label to: %s", newlabel); + + LIST_REMOVE(j, label_hash_sle); + strcpy((char *)j->label, newlabel); + LIST_INSERT_HEAD(&label_hash[hash_label(j->label)], j, label_hash_sle); + } } - switch (kev->filter) { - case EVFILT_PROC: + if (fflags & NOTE_FORK) { + job_log(j, LOG_DEBUG, "Called fork()"); + } + + if (fflags & NOTE_EXIT) { job_reap(j); - if (j->firstborn) { - job_log(j, LOG_DEBUG, "first born died, begin shutdown"); - launchd_shutdown(); + if (j->anonymous) { + job_remove(j); + j = NULL; } else { - job_dispatch(j); + j = job_dispatch(j, false); } - break; - case EVFILT_TIMER: - if ((uintptr_t)j == kev->ident) { - job_start(j); + } + + /* NOTE_REAP sanity checking is disabled for now while we try and diagnose 5289559 */ +#if 0 + if (j && (fflags & NOTE_REAP)) { + job_assumes(j, flags & EV_ONESHOT); + job_assumes(j, flags & EV_EOF); + + job_assumes(j, j->p == 0); + } +#endif +} + +void +job_callback_timer(job_t j, void *ident) +{ + if (j == ident) { + job_dispatch(j, true); + } else if (&j->semaphores == ident) { + job_dispatch(j, false); + } else if (&j->start_interval == ident) { + j->start_pending = true; + job_dispatch(j, false); + } else if (&j->exit_timeout == ident) { + if (j->sent_sigkill) { + uint64_t td = (mach_absolute_time() - j->sent_sigterm_time) * tbi.numer / tbi.denom; + + td /= NSEC_PER_SEC; + td -= j->exit_timeout; + + job_log(j, LOG_ERR, "Did not die after sending SIGKILL %llu seconds ago...", td); } else { - calendarinterval_callback(j, kev); + job_force_sampletool(j); + if (j->debug_before_kill) { + job_log(j, LOG_NOTICE, "Exit timeout elapsed. Entering the kernel debugger."); + job_assumes(j, host_reboot(mach_host_self(), HOST_REBOOT_DEBUGGER) == KERN_SUCCESS); + } + job_log(j, LOG_WARNING, "Exit timeout elapsed (%u seconds). Killing.", j->exit_timeout); + job_kill(j); } - break; - case EVFILT_VNODE: - watchpath_callback(j, kev); - break; - case EVFILT_READ: - if ((int)kev->ident != j->execfd) { - socketgroup_callback(j, kev); - break; + } else { + job_assumes(j, false); + } +} + +void +job_callback_read(job_t j, int ident) +{ + if (ident == j->log_redirect_fd) { + job_log_stdouterr(j); + } else { + socketgroup_callback(j); + } +} + +void +jobmgr_reap_bulk(jobmgr_t jm, struct kevent *kev) +{ + jobmgr_t jmi; + job_t j; + + SLIST_FOREACH(jmi, &jm->submgrs, sle) { + jobmgr_reap_bulk(jmi, kev); + } + + if ((j = jobmgr_find_by_pid(jm, kev->ident, false))) { + kev->udata = j; + job_callback(j, kev); + } +} + +void +jobmgr_callback(void *obj, struct kevent *kev) +{ + jobmgr_t jm = obj; + + switch (kev->filter) { + case EVFILT_PROC: + jobmgr_reap_bulk(jm, kev); + if (launchd_assumes(root_jobmgr != NULL)) { + root_jobmgr = jobmgr_do_garbage_collection(root_jobmgr); } - if (j->wait4debugger) { - /* Allow somebody else to attach */ - launchd_assumes(kill(j->p, SIGSTOP) != -1); - launchd_assumes(ptrace(PT_DETACH, j->p, NULL, 0) != -1); + break; + case EVFILT_SIGNAL: + switch (kev->ident) { + case SIGTERM: + return launchd_shutdown(); + case SIGUSR1: + return calendarinterval_callback(); + default: + return (void)jobmgr_assumes(jm, false); } - if (kev->data > 0) { - int e; - - read(j->execfd, &e, sizeof(e)); - errno = e; - job_log_error(j, LOG_ERR, "execve()"); - job_remove(j); - j = NULL; - } else { - launchd_assumes(close(j->execfd) == 0); - j->execfd = 0; + break; + case EVFILT_FS: + if (kev->fflags & VQ_MOUNT) { + jobmgr_dispatch_all(jm, true); } + jobmgr_dispatch_all_semaphores(jm); break; - case EVFILT_MACHPORT: - job_start(j); + case EVFILT_TIMER: + if (jobmgr_assumes(jm, kev->ident == (uintptr_t)&sorted_calendar_events)) { + calendarinterval_callback(); + } break; default: - launchd_assumes(false); - break; + return (void)jobmgr_assumes(jm, false); } +} - if (d) { - /* the job might have been removed, must not call job_log() */ - setlogmask(oldmask); +void +job_callback(void *obj, struct kevent *kev) +{ + job_t j = obj; + + job_log(j, LOG_DEBUG, "Dispatching kevent callback."); + + switch (kev->filter) { + case EVFILT_PROC: + return job_callback_proc(j, kev->flags, kev->fflags); + case EVFILT_TIMER: + return job_callback_timer(j, (void *)kev->ident); + case EVFILT_VNODE: + return semaphoreitem_callback(j, kev); + case EVFILT_READ: + return job_callback_read(j, kev->ident); + case EVFILT_MACHPORT: + return (void)job_dispatch(j, true); + default: + return (void)job_assumes(j, false); } } void -job_start(struct jobcb *j) +job_start(job_t j) { + uint64_t td, tnow = mach_absolute_time(); int spair[2]; int execspair[2]; + int oepair[2]; char nbuf[64]; pid_t c; bool sipc = false; + u_int proc_fflags = /* NOTE_EXEC|NOTE_FORK| */ NOTE_EXIT /* |NOTE_REAP */; - if (!launchd_assumes(j->req_port == MACH_PORT_NULL)) - return; - - if (!launchd_assumes(j->parent != NULL)) + if (!job_assumes(j, j->mgr != NULL)) { return; + } if (job_active(j)) { job_log(j, LOG_DEBUG, "Already started"); return; - } else if (!j->legacy_mach_job && j->throttle) { - j->throttle = false; - job_log(j, LOG_WARNING, "Throttling: Will restart in %d seconds", LAUNCHD_MIN_JOB_RUN_TIME); - launchd_assumes(kevent_mod((uintptr_t)j, EVFILT_TIMER, EV_ADD|EV_ONESHOT, - NOTE_SECONDS, LAUNCHD_MIN_JOB_RUN_TIME, j) != -1); + } + + job_assumes(j, tnow > j->start_time); + + /* + * Some users adjust the wall-clock and then expect software to not notice. + * Therefore, launchd must use an absolute clock instead of gettimeofday() + * or time() wherever possible. + */ + td = (tnow - j->start_time) * tbi.numer / tbi.denom; + td /= NSEC_PER_SEC; + + if (j->start_time && (td < j->min_run_time) && !j->legacy_mach_job && !j->inetcompat) { + time_t respawn_delta = j->min_run_time - (uint32_t)td; + + /* + * We technically should ref-count throttled jobs to prevent idle exit, + * but we're not directly tracking the 'throttled' state at the moment. + */ + + job_log(j, LOG_WARNING, "Throttling respawn: Will start in %ld seconds", respawn_delta); + job_assumes(j, kevent_mod((uintptr_t)j, EVFILT_TIMER, EV_ADD|EV_ONESHOT, NOTE_SECONDS, respawn_delta, j) != -1); + job_ignore(j); return; } - job_log(j, LOG_DEBUG, "Starting"); + j->sent_sigterm_time = 0; - if (!j->legacy_mach_job) + if (!j->legacy_mach_job) { sipc = (!SLIST_EMPTY(&j->sockets) || !SLIST_EMPTY(&j->machservices)); - - /* FIXME, using stdinpath is a hack for re-reading the conf file */ - if (j->stdinpath) - sipc = true; + } j->checkedin = false; - if (sipc) - socketpair(AF_UNIX, SOCK_STREAM, 0, spair); - - socketpair(AF_UNIX, SOCK_STREAM, 0, execspair); + if (sipc) { + job_assumes(j, socketpair(AF_UNIX, SOCK_STREAM, 0, spair) != -1); + } - time(&j->start_time); + job_assumes(j, socketpair(AF_UNIX, SOCK_STREAM, 0, execspair) != -1); - if (j->bs_port) { - launchd_assumes(launchd_mport_notify_req(j->bs_port, MACH_NOTIFY_NO_SENDERS) == KERN_SUCCESS); + if (!j->legacy_mach_job && job_assumes(j, pipe(oepair) != -1)) { + j->log_redirect_fd = _fd(oepair[0]); + job_assumes(j, fcntl(j->log_redirect_fd, F_SETFL, O_NONBLOCK) != -1); + job_assumes(j, kevent_mod(j->log_redirect_fd, EVFILT_READ, EV_ADD, 0, 0, j) != -1); } - switch (c = job_fork(j->bs_port ? j : j->parent)) { + j->start_time = tnow; + + switch (c = runtime_fork(j->weird_bootstrap ? j->j_port : j->mgr->jm_port)) { case -1: job_log_error(j, LOG_ERR, "fork() failed, will try again in one second"); - launchd_assumes(close(execspair[0]) == 0); - launchd_assumes(close(execspair[1]) == 0); + job_assumes(j, runtime_close(execspair[0]) == 0); + job_assumes(j, runtime_close(execspair[1]) == 0); if (sipc) { - launchd_assumes(close(spair[0]) == 0); - launchd_assumes(close(spair[1]) == 0); + job_assumes(j, runtime_close(spair[0]) == 0); + job_assumes(j, runtime_close(spair[1]) == 0); } break; case 0: - launchd_assumes(close(execspair[0]) == 0); + if (_vproc_post_fork_ping()) { + _exit(EXIT_FAILURE); + } + if (!j->legacy_mach_job) { + job_assumes(j, dup2(oepair[1], STDOUT_FILENO) != -1); + job_assumes(j, dup2(oepair[1], STDERR_FILENO) != -1); + job_assumes(j, runtime_close(oepair[1]) != -1); + } + job_assumes(j, runtime_close(execspair[0]) == 0); /* wait for our parent to say they've attached a kevent to us */ read(_fd(execspair[1]), &c, sizeof(c)); - if (j->firstborn) { - setpgid(getpid(), getpid()); - if (isatty(STDIN_FILENO)) { - if (tcsetpgrp(STDIN_FILENO, getpid()) == -1) - job_log_error(j, LOG_WARNING, "tcsetpgrp()"); - } - } if (sipc) { - launchd_assumes(close(spair[0]) == 0); - sprintf(nbuf, "%d", spair[1]); + job_assumes(j, runtime_close(spair[0]) == 0); + snprintf(nbuf, sizeof(nbuf), "%d", spair[1]); setenv(LAUNCHD_TRUSTED_FD_ENV, nbuf, 1); } - job_start_child(j, execspair[1]); + job_start_child(j); break; default: - if (!SLIST_EMPTY(&j->machservices)) - j->priv_port_has_senders = true; - j->p = c; + job_log(j, LOG_DEBUG, "Started as PID: %u", c); + + j->start_pending = false; + + runtime_add_ref(); total_children++; - launchd_assumes(close(execspair[1]) == 0); - j->execfd = _fd(execspair[0]); + LIST_INSERT_HEAD(&j->mgr->active_jobs[ACTIVE_JOB_HASH(c)], j, pid_hash_sle); + + if (JOB_BOOTCACHE_HACK_CHECK(j)) { + did_first_per_user_launchd_BootCache_hack = true; + } + + if (!j->legacy_mach_job) { + job_assumes(j, runtime_close(oepair[1]) != -1); + } + j->p = c; + if (j->hopefully_exits_first) { + j->mgr->hopefully_first_cnt++; + } else if (!j->hopefully_exits_last) { + j->mgr->normal_active_cnt++; + } + j->forkfd = _fd(execspair[0]); + job_assumes(j, runtime_close(execspair[1]) == 0); if (sipc) { - launchd_assumes(close(spair[1]) == 0); + job_assumes(j, runtime_close(spair[1]) == 0); ipc_open(_fd(spair[0]), j); } - if (kevent_mod(j->execfd, EVFILT_READ, EV_ADD, 0, 0, &j->kqjob_callback) == -1) - job_log_error(j, LOG_ERR, "kevent_mod(j->execfd): %m"); - if (kevent_mod(c, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, &j->kqjob_callback) == -1) { - job_log_error(j, LOG_ERR, "kevent()"); - job_reap(j); + if (job_assumes(j, kevent_mod(c, EVFILT_PROC, EV_ADD, proc_fflags, 0, root_jobmgr ? root_jobmgr : j->mgr) != -1)) { + job_ignore(j); } else { - if (j->ondemand) - job_ignore(j); + job_reap(j); } if (!j->stall_before_exec) { - /* this unblocks the child and avoids a race - * between the above fork() and the kevent_mod() */ - write(j->execfd, &c, sizeof(c)); + job_uncork_fork(j); } break; } } void -job_start_child(struct jobcb *j, int execfd) +do_first_per_user_launchd_hack(void) +{ + char *bcct_tool[] = { "/usr/sbin/BootCacheControl", "tag", NULL }; + int dummystatus; + pid_t bcp; + + if (launchd_assumes((bcp = vfork()) != -1)) { + if (bcp == 0) { + execve(bcct_tool[0], bcct_tool, environ); + _exit(EXIT_FAILURE); + } else { + launchd_assumes(waitpid(bcp, &dummystatus, 0) != -1); + } + } +} + +void +job_start_child(job_t j) { const char *file2exec = "/usr/libexec/launchproxy"; const char **argv; + posix_spawnattr_t spattr; int gflags = GLOB_NOSORT|GLOB_NOCHECK|GLOB_TILDE|GLOB_DOOFFS; + pid_t junk_pid; glob_t g; + short spflags = POSIX_SPAWN_SETEXEC; + size_t binpref_out_cnt = 0; int i; + if (JOB_BOOTCACHE_HACK_CHECK(j)) { + do_first_per_user_launchd_hack(); + } + + job_assumes(j, posix_spawnattr_init(&spattr) == 0); + job_setup_attributes(j); if (j->argv && j->globargv) { g.gl_offs = 1; for (i = 0; i < j->argc; i++) { - if (i > 0) + if (i > 0) { gflags |= GLOB_APPEND; + } if (glob(j->argv[i], gflags, NULL, &g) != 0) { job_log_error(j, LOG_ERR, "glob(\"%s\")", j->argv[i]); exit(EXIT_FAILURE); @@ -1530,8 +2631,9 @@ job_start_child(struct jobcb *j, int execfd) } else if (j->argv) { argv = alloca((j->argc + 2) * sizeof(char *)); argv[0] = file2exec; - for (i = 0; i < j->argc; i++) + for (i = 0; i < j->argc; i++) { argv[i + 1] = j->argv[i]; + } argv[i + 1] = NULL; } else { argv = alloca(3 * sizeof(char *)); @@ -1540,188 +2642,355 @@ job_start_child(struct jobcb *j, int execfd) argv[2] = NULL; } - if (!j->inetcompat) + if (!j->inetcompat) { argv++; + } + + if (j->wait4debugger) { + job_log(j, LOG_WARNING, "Spawned and waiting for the debugger to attach before continuing..."); + spflags |= POSIX_SPAWN_START_SUSPENDED; + } + + job_assumes(j, posix_spawnattr_setflags(&spattr, spflags) == 0); + + if (j->j_binpref_cnt) { + job_assumes(j, posix_spawnattr_setbinpref_np(&spattr, j->j_binpref_cnt, j->j_binpref, &binpref_out_cnt) == 0); + job_assumes(j, binpref_out_cnt == j->j_binpref_cnt); + } + + if (j->quarantine_data) { + qtn_proc_t qp; - if (j->wait4debugger && ptrace(PT_TRACE_ME, getpid(), NULL, 0) == -1) - job_log_error(j, LOG_ERR, "ptrace(PT_TRACE_ME, ...)"); + if (job_assumes(j, qp = qtn_proc_alloc())) { + if (job_assumes(j, qtn_proc_init_with_data(qp, j->quarantine_data, j->quarantine_data_sz) == 0)) { + job_assumes(j, qtn_proc_apply_to_self(qp) == 0); + } + } + } - if (j->force_ppc) { - int affinmib[] = { CTL_KERN, KERN_AFFINITY, 1, 1 }; - size_t mibsz = sizeof(affinmib) / sizeof(affinmib[0]); + if (j->seatbelt_profile) { + char *seatbelt_err_buf = NULL; - if (sysctl(affinmib, mibsz, NULL, NULL, NULL, 0) == -1) - job_log_error(j, LOG_WARNING, "Failed to force PowerPC execution"); + if (!job_assumes(j, sandbox_init(j->seatbelt_profile, j->seatbelt_flags, &seatbelt_err_buf) != -1)) { + if (seatbelt_err_buf) { + job_log(j, LOG_ERR, "Sandbox failed to init: %s", seatbelt_err_buf); + } + goto out_bad; + } } if (j->prog) { - execv(j->inetcompat ? file2exec : j->prog, (char *const*)argv); - job_log_error(j, LOG_ERR, "execv(\"%s\", ...)", j->prog); + errno = posix_spawn(&junk_pid, j->inetcompat ? file2exec : j->prog, NULL, &spattr, (char *const*)argv, environ); + job_log_error(j, LOG_ERR, "posix_spawn(\"%s\", ...)", j->prog); } else { - execvp(j->inetcompat ? file2exec : argv[0], (char *const*)argv); - job_log_error(j, LOG_ERR, "execvp(\"%s\", ...)", argv[0]); + errno = posix_spawnp(&junk_pid, j->inetcompat ? file2exec : argv[0], NULL, &spattr, (char *const*)argv, environ); + job_log_error(j, LOG_ERR, "posix_spawnp(\"%s\", ...)", argv[0]); } - write(execfd, &errno, sizeof(errno)); - exit(EXIT_FAILURE); +out_bad: + _exit(EXIT_FAILURE); } -void job_setup_env_from_other_jobs(struct jobcb *j) +void +jobmgr_export_env_from_other_jobs(jobmgr_t jm, launch_data_t dict) { + launch_data_t tmp; struct envitem *ei; - struct jobcb *ji; + job_t ji; - SLIST_FOREACH(ji, &j->jobs, sle) - job_setup_env_from_other_jobs(ji); + if (jm->parentmgr) { + jobmgr_export_env_from_other_jobs(jm->parentmgr, dict); + } else { + char **tmpenviron = environ; + for (; *tmpenviron; tmpenviron++) { + char envkey[1024]; + launch_data_t s = launch_data_alloc(LAUNCH_DATA_STRING); + launch_data_set_string(s, strchr(*tmpenviron, '=') + 1); + strncpy(envkey, *tmpenviron, sizeof(envkey)); + *(strchr(envkey, '=')) = '\0'; + launch_data_dict_insert(dict, s, envkey); + } + } - SLIST_FOREACH(ei, &j->global_env, sle) - setenv(ei->key, ei->value, 1); + LIST_FOREACH(ji, &jm->jobs, sle) { + SLIST_FOREACH(ei, &ji->global_env, sle) { + if ((tmp = launch_data_new_string(ei->value))) { + launch_data_dict_insert(dict, tmp, ei->key); + } + } + } } void -job_setup_attributes(struct jobcb *j) +jobmgr_setup_env_from_other_jobs(jobmgr_t jm) { - struct limititem *li; struct envitem *ei; - struct group *gre = NULL; - gid_t gre_g = 0; - - setpriority(PRIO_PROCESS, 0, j->nice); + job_t ji; - SLIST_FOREACH(li, &j->limits, sle) { - struct rlimit rl; + if (jm->parentmgr) { + jobmgr_setup_env_from_other_jobs(jm->parentmgr); + } - if (getrlimit(li->which, &rl) == -1) { - job_log_error(j, LOG_WARNING, "getrlimit()"); - continue; + LIST_FOREACH(ji, &jm->jobs, sle) { + SLIST_FOREACH(ei, &ji->global_env, sle) { + setenv(ei->key, ei->value, 1); } + } +} - if (li->sethard) - rl.rlim_max = li->lim.rlim_max; - if (li->setsoft) - rl.rlim_cur = li->lim.rlim_cur; +void +job_find_and_blame_pids_with_weird_uids(job_t j) +{ + int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL }; + size_t i, kp_cnt, len = 10*1024*1024; + struct kinfo_proc *kp = malloc(len); + uid_t u = j->mach_uid; - if (setrlimit(li->which, &rl) == -1) - job_log_error(j, LOG_WARNING, "setrlimit()"); + if (!job_assumes(j, kp != NULL)) { + return; + } + if (!job_assumes(j, sysctl(mib, 3, kp, &len, NULL, 0) != -1)) { + goto out; } - if (!j->inetcompat && j->session_create) - launchd_SessionCreate(); + kp_cnt = len / sizeof(struct kinfo_proc); - if (j->low_pri_io) { - int lowprimib[] = { CTL_KERN, KERN_PROC_LOW_PRI_IO }; - int val = 1; + for (i = 0; i < kp_cnt; i++) { + uid_t i_euid = kp[i].kp_eproc.e_ucred.cr_uid; + uid_t i_uid = kp[i].kp_eproc.e_pcred.p_ruid; + uid_t i_svuid = kp[i].kp_eproc.e_pcred.p_svuid; + pid_t i_pid = kp[i].kp_proc.p_pid; + + if (i_euid != u && i_uid != u && i_svuid != u) { + continue; + } - if (sysctl(lowprimib, sizeof(lowprimib) / sizeof(lowprimib[0]), NULL, NULL, &val, sizeof(val)) == -1) - job_log_error(j, LOG_WARNING, "sysctl(\"%s\")", "kern.proc_low_pri_io"); + job_log(j, LOG_ERR, "PID %u \"%s\" has no account to back it! Real/effective/saved UIDs: %u/%u/%u", + i_pid, kp[i].kp_proc.p_comm, i_uid, i_euid, i_svuid); + +/* Temporarily disabled due to 5423935 and 4946119. */ +#if 0 + /* Ask the accountless process to exit. */ + job_assumes(j, runtime_kill(i_pid, SIGTERM) != -1); +#endif } - if (j->rootdir) { - chroot(j->rootdir); - chdir("."); + +out: + free(kp); +} + +void +job_postfork_become_user(job_t j) +{ + char loginname[2000]; + char tmpdirpath[PATH_MAX]; + char shellpath[PATH_MAX]; + char homedir[PATH_MAX]; + struct passwd *pwe; + size_t r; + gid_t desired_gid = -1; + uid_t desired_uid = -1; + + if (getuid() != 0) { + return; + } + + /* + * I contend that having UID == 0 and GID != 0 is of dubious value. + * Nevertheless, this used to work in Tiger. See: 5425348 + */ + if (j->groupname && !j->username) { + j->username = "root"; + } + + if (j->username) { + if ((pwe = getpwnam(j->username)) == NULL) { + job_log(j, LOG_ERR, "getpwnam(\"%s\") failed", j->username); + _exit(EXIT_FAILURE); + } + } else if (j->mach_uid) { + if ((pwe = getpwuid(j->mach_uid)) == NULL) { + job_log(j, LOG_ERR, "getpwuid(\"%u\") failed", j->mach_uid); + job_find_and_blame_pids_with_weird_uids(j); + _exit(EXIT_FAILURE); + } + } else { + return; + } + + /* + * We must copy the results of getpw*(). + * + * Why? Because subsequent API calls may call getpw*() as a part of + * their implementation. Since getpw*() returns a [now thread scoped] + * global, we must therefore cache the results before continuing. + */ + + desired_uid = pwe->pw_uid; + desired_gid = pwe->pw_gid; + + strlcpy(shellpath, pwe->pw_shell, sizeof(shellpath)); + strlcpy(loginname, pwe->pw_name, sizeof(loginname)); + strlcpy(homedir, pwe->pw_dir, sizeof(homedir)); + + if (pwe->pw_expire && time(NULL) >= pwe->pw_expire) { + job_log(j, LOG_ERR, "Expired account"); + _exit(EXIT_FAILURE); + } + + + if (j->username && strcmp(j->username, loginname) != 0) { + job_log(j, LOG_WARNING, "Suspicious setup: User \"%s\" maps to user: %s", j->username, loginname); + } else if (j->mach_uid && (j->mach_uid != desired_uid)) { + job_log(j, LOG_WARNING, "Suspicious setup: UID %u maps to UID %u", j->mach_uid, desired_uid); } + if (j->groupname) { - gre = getgrnam(j->groupname); - if (gre) { - gre_g = gre->gr_gid; - if (-1 == setgid(gre_g)) { - job_log_error(j, LOG_ERR, "setgid(%d)", gre_g); - exit(EXIT_FAILURE); - } - } else { + struct group *gre; + + if ((gre = getgrnam(j->groupname)) == NULL) { job_log(j, LOG_ERR, "getgrnam(\"%s\") failed", j->groupname); - exit(EXIT_FAILURE); + _exit(EXIT_FAILURE); } + + desired_gid = gre->gr_gid; + } + + if (!job_assumes(j, setlogin(loginname) != -1)) { + _exit(EXIT_FAILURE); } - if (j->username || j->mach_uid) { - struct passwd *pwe; - if (j->username) - pwe = getpwnam(j->username); - else - pwe = getpwuid(j->mach_uid); + if (!job_assumes(j, setgid(desired_gid) != -1)) { + _exit(EXIT_FAILURE); + } - if (pwe) { - uid_t pwe_u = pwe->pw_uid; - uid_t pwe_g = pwe->pw_gid; + /* + * The kernel team and the DirectoryServices team want initgroups() + * called after setgid(). See 4616864 for more information. + */ - if (pwe->pw_expire && time(NULL) >= pwe->pw_expire) { - job_log(j, LOG_ERR, "expired account: %s", j->username); - exit(EXIT_FAILURE); - } - if (j->init_groups) { - if (-1 == initgroups(j->username, gre ? gre_g : pwe_g)) { - job_log_error(j, LOG_ERR, "initgroups()"); - exit(EXIT_FAILURE); - } - } - if (!gre) { - if (-1 == setgid(pwe_g)) { - job_log_error(j, LOG_ERR, "setgid(%d)", pwe_g); - exit(EXIT_FAILURE); - } - } - if (-1 == setuid(pwe_u)) { - job_log_error(j, LOG_ERR, "setuid(%d)", pwe_u); - exit(EXIT_FAILURE); - } - } else { - if (j->username) { - job_log(j, LOG_WARNING, "getpwnam(\"%s\") failed", j->username); - } else { - job_log(j, LOG_WARNING, "getpwuid(\"%d\") failed", j->mach_uid); - } - exit(EXIT_FAILURE); + if (!j->no_init_groups) { + if (!job_assumes(j, initgroups(loginname, desired_gid) != -1)) { + _exit(EXIT_FAILURE); } } - if (j->workingdir) - chdir(j->workingdir); - if (j->setmask) - umask(j->mask); - if (j->stdinpath) { - int sifd = open(j->stdinpath, O_RDONLY|O_NOCTTY); - if (sifd == -1) { - job_log_error(j, LOG_WARNING, "open(\"%s\", ...)", j->stdinpath); - } else { - launchd_assumes(dup2(sifd, STDIN_FILENO) != -1); - launchd_assumes(close(sifd) == 0); - } + + if (!job_assumes(j, setuid(desired_uid) != -1)) { + _exit(EXIT_FAILURE); } - if (j->stdoutpath) { - int sofd = open(j->stdoutpath, O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY, DEFFILEMODE); - if (sofd == -1) { - job_log_error(j, LOG_WARNING, "open(\"%s\", ...)", j->stdoutpath); - } else { - launchd_assumes(dup2(sofd, STDOUT_FILENO) != -1); - launchd_assumes(close(sofd) == 0); - } + + r = confstr(_CS_DARWIN_USER_TEMP_DIR, tmpdirpath, sizeof(tmpdirpath)); + + if (r > 0 && r < sizeof(tmpdirpath)) { + setenv("TMPDIR", tmpdirpath, 0); } - if (j->stderrpath) { - int sefd = open(j->stderrpath, O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY, DEFFILEMODE); - if (sefd == -1) { - job_log_error(j, LOG_WARNING, "open(\"%s\", ...)", j->stderrpath); - } else { - launchd_assumes(dup2(sefd, STDERR_FILENO) != -1); - launchd_assumes(close(sefd) == 0); + + setenv("SHELL", shellpath, 0); + setenv("HOME", homedir, 0); + setenv("USER", loginname, 0); + setenv("LOGNAME", loginname, 0); +} + +void +job_setup_attributes(job_t j) +{ + struct limititem *li; + struct envitem *ei; + + if (j->setnice) { + job_assumes(j, setpriority(PRIO_PROCESS, 0, j->nice) != -1); + } + + SLIST_FOREACH(li, &j->limits, sle) { + struct rlimit rl; + + if (!job_assumes(j, getrlimit(li->which, &rl) != -1)) { + continue; + } + + if (li->sethard) { + rl.rlim_max = li->lim.rlim_max; + } + if (li->setsoft) { + rl.rlim_cur = li->lim.rlim_cur; + } + + if (setrlimit(li->which, &rl) == -1) { + job_log_error(j, LOG_WARNING, "setrlimit()"); } } - job_setup_env_from_other_jobs(root_job); + if (!j->inetcompat && j->session_create) { + launchd_SessionCreate(); + } + + if (j->low_pri_io) { + job_assumes(j, setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_PROCESS, IOPOL_THROTTLE) != -1); + } + if (j->rootdir) { + job_assumes(j, chroot(j->rootdir) != -1); + job_assumes(j, chdir(".") != -1); + } + + job_postfork_become_user(j); + + if (j->workingdir) { + job_assumes(j, chdir(j->workingdir) != -1); + } + + if (j->setmask) { + umask(j->mask); + } + + job_setup_fd(j, STDOUT_FILENO, j->stdoutpath, O_WRONLY|O_APPEND|O_CREAT); + job_setup_fd(j, STDERR_FILENO, j->stderrpath, O_WRONLY|O_APPEND|O_CREAT); - SLIST_FOREACH(ei, &j->env, sle) + jobmgr_setup_env_from_other_jobs(j->mgr); + + SLIST_FOREACH(ei, &j->env, sle) { setenv(ei->key, ei->value, 1); + } + + /* + * We'd like to call setsid() unconditionally, but we have reason to + * believe that prevents launchd from being able to send signals to + * setuid children. We'll settle for process-groups. + */ + if (getppid() != 1) { + job_assumes(j, setpgid(0, 0) != -1); + } else { + job_assumes(j, setsid() != -1); + } +} + +void +job_setup_fd(job_t j, int target_fd, const char *path, int flags) +{ + int fd; + + if (!path) { + return; + } + + if ((fd = open(path, flags|O_NOCTTY, DEFFILEMODE)) == -1) { + job_log_error(j, LOG_WARNING, "open(\"%s\", ...)", path); + return; + } - setsid(); + job_assumes(j, dup2(fd, target_fd) != -1); + job_assumes(j, runtime_close(fd) == 0); } int -dir_has_files(const char *path) +dir_has_files(job_t j, const char *path) { DIR *dd = opendir(path); struct dirent *de; bool r = 0; - if (!dd) + if (!dd) { return -1; + } while ((de = readdir(dd))) { if (strcmp(de->d_name, ".") && strcmp(de->d_name, "..")) { @@ -1730,14 +2999,15 @@ dir_has_files(const char *path) } } - launchd_assumes(closedir(dd) == 0); + job_assumes(j, closedir(dd) == 0); return r; } void -calendarinterval_setalarm(struct jobcb *j, struct calendarinterval *ci) +calendarinterval_setalarm(job_t j, struct calendarinterval *ci) { - time_t later; + struct calendarinterval *ci_iter, *ci_prev = NULL; + time_t later, head_later; later = cronemu(ci->when.tm_mon, ci->when.tm_mday, ci->when.tm_hour, ci->when.tm_min); @@ -1751,256 +3021,486 @@ calendarinterval_setalarm(struct jobcb *j, struct calendarinterval *ci) } } - if (-1 == kevent_mod((uintptr_t)ci, EVFILT_TIMER, EV_ADD, NOTE_ABSOLUTE|NOTE_SECONDS, later, j)) { - job_log_error(j, LOG_ERR, "adding kevent alarm"); - } else { - job_log(j, LOG_INFO, "scheduled to run again at %s", ctime(&later)); + ci->when_next = later; + + LIST_FOREACH(ci_iter, &sorted_calendar_events, global_sle) { + if (ci->when_next < ci_iter->when_next) { + LIST_INSERT_BEFORE(ci_iter, ci, global_sle); + break; + } + + ci_prev = ci_iter; } -} -size_t -job_prep_log_preface(struct jobcb *j, char *buf) -{ - size_t lsz = strlen(j->label); - char newlabel[lsz * 2 + 1]; - size_t i, o, r = 0; + if (ci_iter == NULL) { + /* ci must want to fire after every other timer, or there are no timers */ - for (i = 0, o = 0; i < lsz; i++, o++) { - if (j->label[i] == '%') { - newlabel[o] = '%'; - o++; - newlabel[o] = '%'; + if (LIST_EMPTY(&sorted_calendar_events)) { + LIST_INSERT_HEAD(&sorted_calendar_events, ci, global_sle); } else { - newlabel[o] = j->label[i]; + LIST_INSERT_AFTER(ci_prev, ci, global_sle); } } - newlabel[o] = '\0'; - if (j->parent) - r = job_prep_log_preface(j->parent, buf); + head_later = LIST_FIRST(&sorted_calendar_events)->when_next; - return r + sprintf(buf + r, "%s%s", j->parent ? "/" : "", newlabel); -} + /* Workaround 5225889 */ + kevent_mod((uintptr_t)&sorted_calendar_events, EVFILT_TIMER, EV_DELETE, 0, 0, root_jobmgr); -void -job_log_error(struct jobcb *j, int pri, const char *msg, ...) -{ - char newmsg[10000]; - va_list ap; - size_t o; + if (job_assumes(j, kevent_mod((uintptr_t)&sorted_calendar_events, EVFILT_TIMER, EV_ADD, NOTE_ABSOLUTE|NOTE_SECONDS, head_later, root_jobmgr) != -1)) { + char time_string[100]; + size_t time_string_len; - o = job_prep_log_preface(j, newmsg); + ctime_r(&later, time_string); + time_string_len = strlen(time_string); - sprintf(newmsg + o, ": %s: %s", msg, strerror(errno)); + if (time_string_len && time_string[time_string_len - 1] == '\n') { + time_string[time_string_len - 1] = '\0'; + } - va_start(ap, msg); - vsyslog(pri, newmsg, ap); - va_end(ap); + job_log(j, LOG_INFO, "Scheduled to run again at %s", time_string); + } } void -job_log(struct jobcb *j, int pri, const char *msg, ...) +extract_rcsid_substr(const char *i, char *o, size_t osz) { - char newmsg[10000]; - va_list ap; - size_t o; + char *rcs_rev_tmp = strchr(i, ' '); - o = job_prep_log_preface(j, newmsg); - - sprintf(newmsg + o, ": %s", msg); - - va_start(ap, msg); - vsyslog(pri, newmsg, ap); - va_end(ap); + if (!rcs_rev_tmp) { + strlcpy(o, i, osz); + } else { + strlcpy(o, rcs_rev_tmp + 1, osz); + rcs_rev_tmp = strchr(o, ' '); + if (rcs_rev_tmp) { + *rcs_rev_tmp = '\0'; + } + } } -bool -watchpath_new(struct jobcb *j, const char *name, bool qdir) +void +jobmgr_log_bug(jobmgr_t jm, const char *rcs_rev, const char *path, unsigned int line, const char *test) { - struct watchpath *wp = calloc(1, sizeof(struct watchpath) + strlen(name) + 1); - - if (!launchd_assumes(wp != NULL)) - return false; - - wp->is_qdir = qdir; + int saved_errno = errno; + const char *file = strrchr(path, '/'); + char buf[100]; - wp->fd = -1; /* watchpath_watch() will open this */ + extract_rcsid_substr(rcs_rev, buf, sizeof(buf)); - strcpy(wp->name, name); - - SLIST_INSERT_HEAD(&j->vnodes, wp, sle); + if (!file) { + file = path; + } else { + file += 1; + } - return true; -} + jobmgr_log(jm, LOG_NOTICE, "Bug: %s:%u (%s):%u: %s", file, line, buf, saved_errno, test); +} void -watchpath_delete(struct jobcb *j, struct watchpath *wp) +job_log_bug(job_t j, const char *rcs_rev, const char *path, unsigned int line, const char *test) { - if (wp->fd != -1) - launchd_assumes(close(wp->fd) != -1); - - SLIST_REMOVE(&j->vnodes, wp, watchpath, sle); + int saved_errno = errno; + const char *file = strrchr(path, '/'); + char buf[100]; - free(wp); -} + extract_rcsid_substr(rcs_rev, buf, sizeof(buf)); -void -watchpath_ignore(struct jobcb *j, struct watchpath *wp) -{ - if (wp->fd != -1) { - job_log(j, LOG_DEBUG, "Ignoring Vnode: %d", wp->fd); - launchd_assumes(kevent_mod(wp->fd, EVFILT_VNODE, EV_DELETE, 0, 0, NULL) != -1); + if (!file) { + file = path; + } else { + file += 1; } + + job_log(j, LOG_NOTICE, "Bug: %s:%u (%s):%u: %s", file, line, buf, saved_errno, test); } void -watchpath_watch(struct jobcb *j, struct watchpath *wp) +job_logv(job_t j, int pri, int err, const char *msg, va_list ap) { - int fflags = NOTE_WRITE|NOTE_EXTEND|NOTE_ATTRIB|NOTE_LINK; - int qdir_file_cnt; + struct runtime_syslog_attr attr = { "com.apple.launchd", j->label, j->mgr->name, pri, getuid(), getpid(), j->p }; + char *newmsg; + int oldmask = 0; + size_t newmsgsz; - if (!wp->is_qdir) - fflags |= NOTE_DELETE|NOTE_RENAME|NOTE_REVOKE; + /* + * Hack: If bootstrap_port is set, we must be on the child side of a + * fork(), but before the exec*(). Let's route the log message back to + * launchd proper. + */ + if (bootstrap_port) { + return _vproc_logv(pri, err, msg, ap); + } - if (wp->fd == -1) - wp->fd = _fd(open(wp->name, O_EVTONLY|O_NOCTTY|O_NOFOLLOW)); + newmsgsz = strlen(msg) + 200; + newmsg = alloca(newmsgsz); - if (wp->fd == -1) - return job_log_error(j, LOG_ERR, "Watchpath monitoring failed on \"%s\"", wp->name); + if (err) { + snprintf(newmsg, newmsgsz, "%s: %s", msg, strerror(err)); + } else { + snprintf(newmsg, newmsgsz, "%s", msg); + } - job_log(j, LOG_DEBUG, "Watching Vnode: %d", wp->fd); - launchd_assumes(kevent_mod(wp->fd, EVFILT_VNODE, EV_ADD|EV_CLEAR, fflags, 0, j) != -1); + if (j->debug) { + oldmask = setlogmask(LOG_UPTO(LOG_DEBUG)); + } - if (!wp->is_qdir) - return; + runtime_vsyslog(&attr, newmsg, ap); - if (-1 == (qdir_file_cnt = dir_has_files(wp->name))) { - job_log_error(j, LOG_ERR, "dir_has_files(\"%s\", ...)", wp->name); - } else if (qdir_file_cnt > 0) { - job_start(j); + if (j->debug) { + setlogmask(oldmask); } } void -watchpath_callback(struct jobcb *j, struct kevent *kev) +job_log_error(job_t j, int pri, const char *msg, ...) { - struct watchpath *wp; - int dir_file_cnt; - - SLIST_FOREACH(wp, &j->vnodes, sle) { - if (wp->fd == (int)kev->ident) - break; - } - - launchd_assumes(wp != NULL); - - if ((NOTE_DELETE|NOTE_RENAME|NOTE_REVOKE) & kev->fflags) { - job_log(j, LOG_DEBUG, "Path invalidated: %s", wp->name); - launchd_assumes(close(wp->fd) == 0); - wp->fd = -1; /* this will get fixed in watchpath_watch() */ - } else if (!wp->is_qdir) { - job_log(j, LOG_DEBUG, "Watch path modified: %s", wp->name); - } else { - job_log(j, LOG_DEBUG, "Queue directory modified: %s", wp->name); - - if (-1 == (dir_file_cnt = dir_has_files(wp->name))) { - job_log_error(j, LOG_ERR, "dir_has_files(\"%s\", ...)", wp->name); - } else if (0 == dir_file_cnt) { - job_log(j, LOG_DEBUG, "Spurious wake up, directory is empty again: %s", wp->name); - return; - } - } + va_list ap; - job_start(j); + va_start(ap, msg); + job_logv(j, pri, errno, msg, ap); + va_end(ap); } -bool -calendarinterval_new_from_obj(struct jobcb *j, launch_data_t obj) +void +job_log(job_t j, int pri, const char *msg, ...) { - launch_data_t tmp_k; - struct tm tmptm; + va_list ap; - memset(&tmptm, 0, sizeof(0)); + va_start(ap, msg); + job_logv(j, pri, 0, msg, ap); + va_end(ap); +} - tmptm.tm_min = -1; - tmptm.tm_hour = -1; - tmptm.tm_mday = -1; - tmptm.tm_wday = -1; - tmptm.tm_mon = -1; +#if 0 +void +jobmgr_log_error(jobmgr_t jm, int pri, const char *msg, ...) +{ + va_list ap; - if (LAUNCH_DATA_DICTIONARY != launch_data_get_type(obj)) - return false; + va_start(ap, msg); + jobmgr_logv(jm, pri, errno, msg, ap); + va_end(ap); +} +#endif - if ((tmp_k = launch_data_dict_lookup(obj, LAUNCH_JOBKEY_CAL_MINUTE))) - tmptm.tm_min = launch_data_get_integer(tmp_k); - if ((tmp_k = launch_data_dict_lookup(obj, LAUNCH_JOBKEY_CAL_HOUR))) - tmptm.tm_hour = launch_data_get_integer(tmp_k); - if ((tmp_k = launch_data_dict_lookup(obj, LAUNCH_JOBKEY_CAL_DAY))) - tmptm.tm_mday = launch_data_get_integer(tmp_k); - if ((tmp_k = launch_data_dict_lookup(obj, LAUNCH_JOBKEY_CAL_WEEKDAY))) - tmptm.tm_wday = launch_data_get_integer(tmp_k); - if ((tmp_k = launch_data_dict_lookup(obj, LAUNCH_JOBKEY_CAL_MONTH))) - tmptm.tm_mon = launch_data_get_integer(tmp_k); +void +jobmgr_log(jobmgr_t jm, int pri, const char *msg, ...) +{ + va_list ap; - return calendarinterval_new(j, &tmptm); + va_start(ap, msg); + jobmgr_logv(jm, pri, 0, msg, ap); + va_end(ap); } -bool -calendarinterval_new(struct jobcb *j, struct tm *w) +void +jobmgr_logv(jobmgr_t jm, int pri, int err, const char *msg, va_list ap) { - struct calendarinterval *ci = calloc(1, sizeof(struct calendarinterval)); + char *newmsg; + char *newname; + size_t i, o, jmname_len = strlen(jm->name), newmsgsz; - if (!launchd_assumes(ci != NULL)) - return false; + newname = alloca((jmname_len + 1) * 2); + newmsgsz = (jmname_len + 1) * 2 + strlen(msg) + 100; + newmsg = alloca(newmsgsz); - ci->when = *w; + for (i = 0, o = 0; i < jmname_len; i++, o++) { + if (jm->name[i] == '%') { + newname[o] = '%'; + o++; + } + newname[o] = jm->name[i]; + } + newname[o] = '\0'; - SLIST_INSERT_HEAD(&j->cal_intervals, ci, sle); + if (err) { + snprintf(newmsg, newmsgsz, "%s: %s: %s", newname, msg, strerror(err)); + } else { + snprintf(newmsg, newmsgsz, "%s: %s", newname, msg); + } - calendarinterval_setalarm(j, ci); + if (jm->parentmgr) { + jobmgr_logv(jm->parentmgr, pri, 0, newmsg, ap); + } else { + struct runtime_syslog_attr attr = { "com.apple.launchd", "com.apple.launchd", jm->name, pri, getuid(), getpid(), getpid() }; - return true; + runtime_vsyslog(&attr, newmsg, ap); + } } void -calendarinterval_delete(struct jobcb *j, struct calendarinterval *ci) +semaphoreitem_ignore(job_t j, struct semaphoreitem *si) { - launchd_assumes(kevent_mod((uintptr_t)ci, EVFILT_TIMER, EV_DELETE, 0, 0, NULL) != -1); - - SLIST_REMOVE(&j->cal_intervals, ci, calendarinterval, sle); - - free(ci); + if (si->fd != -1) { + job_log(j, LOG_DEBUG, "Ignoring Vnode: %d", si->fd); + job_assumes(j, kevent_mod(si->fd, EVFILT_VNODE, EV_DELETE, 0, 0, NULL) != -1); + } } void -calendarinterval_callback(struct jobcb *j, struct kevent *kev) +semaphoreitem_watch(job_t j, struct semaphoreitem *si) { - struct calendarinterval *ci; + char parentdir_path[PATH_MAX], *which_path = si->what; + int saved_errno = 0; + int fflags = 0; + + strlcpy(parentdir_path, dirname(si->what), sizeof(parentdir_path)); - SLIST_FOREACH(ci, &j->cal_intervals, sle) { - if ((uintptr_t)ci == kev->ident) - break; + switch (si->why) { + case PATH_EXISTS: + fflags = NOTE_DELETE|NOTE_RENAME|NOTE_REVOKE|NOTE_EXTEND|NOTE_WRITE; + break; + case PATH_MISSING: + fflags = NOTE_DELETE|NOTE_RENAME; + break; + case DIR_NOT_EMPTY: + case PATH_CHANGES: + fflags = NOTE_DELETE|NOTE_RENAME|NOTE_REVOKE|NOTE_EXTEND|NOTE_WRITE|NOTE_ATTRIB|NOTE_LINK; + break; + default: + return; } - if (launchd_assumes(ci != NULL)) { - calendarinterval_setalarm(j, ci); - job_start(j); + /* See 5321044 for why we do the do-while loop and 5415523 for why ENOENT is checked */ + do { + if (si->fd == -1) { + if ((si->fd = _fd(open(which_path, O_EVTONLY|O_NOCTTY))) == -1) { + which_path = parentdir_path; + si->fd = _fd(open(which_path, O_EVTONLY|O_NOCTTY)); + } + } + + if (si->fd == -1) { + return job_log_error(j, LOG_ERR, "Path monitoring failed on \"%s\"", which_path); + } + + job_log(j, LOG_DEBUG, "Watching Vnode: %d", si->fd); + + if (kevent_mod(si->fd, EVFILT_VNODE, EV_ADD, fflags, 0, j) == -1) { + saved_errno = errno; + /* + * The FD can be revoked between the open() and kevent(). + * This is similar to the inability for kevents to be + * attached to short lived zombie processes after fork() + * but before kevent(). + */ + job_assumes(j, runtime_close(si->fd) == 0); + si->fd = -1; + } + } while ((si->fd == -1) && (saved_errno == ENOENT)); + + if (saved_errno == ENOTSUP) { + /* + * 3524219 NFS needs kqueue support + * 4124079 VFS needs generic kqueue support + * 5226811 EVFILT: Launchd EVFILT_VNODE doesn't work on /dev + */ + job_log(j, LOG_DEBUG, "Falling back to polling for path: %s", si->what); + + if (!j->poll_for_vfs_changes) { + j->poll_for_vfs_changes = true; + job_assumes(j, kevent_mod((uintptr_t)&j->semaphores, EVFILT_TIMER, EV_ADD, NOTE_SECONDS, 3, j) != -1); + } } } -bool -socketgroup_new(struct jobcb *j, const char *name, int *fds, unsigned int fd_cnt, bool junkfds) +void +semaphoreitem_callback(job_t j, struct kevent *kev) { - struct socketgroup *sg = calloc(1, sizeof(struct socketgroup) + strlen(name) + 1); - - if (!launchd_assumes(sg != NULL)) - return false; + char invalidation_reason[100] = ""; + struct semaphoreitem *si; + + SLIST_FOREACH(si, &j->semaphores, sle) { + switch (si->why) { + case PATH_CHANGES: + case PATH_EXISTS: + case PATH_MISSING: + case DIR_NOT_EMPTY: + break; + default: + continue; + } + + if (si->fd == (int)kev->ident) { + break; + } + } + + if (!job_assumes(j, si != NULL)) { + return; + } + + if (NOTE_DELETE & kev->fflags) { + strcat(invalidation_reason, "deleted"); + } + + if (NOTE_RENAME & kev->fflags) { + if (invalidation_reason[0]) { + strcat(invalidation_reason, "/renamed"); + } else { + strcat(invalidation_reason, "renamed"); + } + } + + if (NOTE_REVOKE & kev->fflags) { + if (invalidation_reason[0]) { + strcat(invalidation_reason, "/revoked"); + } else { + strcat(invalidation_reason, "revoked"); + } + } + + if (invalidation_reason[0]) { + job_log(j, LOG_DEBUG, "Path %s: %s", invalidation_reason, si->what); + job_assumes(j, runtime_close(si->fd) == 0); + si->fd = -1; /* this will get fixed in semaphoreitem_watch() */ + } + + job_log(j, LOG_DEBUG, "Watch path modified: %s", si->what); + + if (si->why == PATH_CHANGES) { + j->start_pending = true; + } + + job_dispatch(j, false); +} + +void +calendarinterval_new_from_obj_dict_walk(launch_data_t obj, const char *key, void *context) +{ + struct tm *tmptm = context; + int64_t val; + + if (LAUNCH_DATA_INTEGER != launch_data_get_type(obj)) { + /* hack to let caller know something went wrong */ + tmptm->tm_sec = -1; + return; + } + + val = launch_data_get_integer(obj); + + if (strcasecmp(key, LAUNCH_JOBKEY_CAL_MINUTE) == 0) { + tmptm->tm_min = val; + } else if (strcasecmp(key, LAUNCH_JOBKEY_CAL_HOUR) == 0) { + tmptm->tm_hour = val; + } else if (strcasecmp(key, LAUNCH_JOBKEY_CAL_DAY) == 0) { + tmptm->tm_mday = val; + } else if (strcasecmp(key, LAUNCH_JOBKEY_CAL_WEEKDAY) == 0) { + tmptm->tm_wday = val; + } else if (strcasecmp(key, LAUNCH_JOBKEY_CAL_MONTH) == 0) { + tmptm->tm_mon = val; + tmptm->tm_mon -= 1; /* 4798263 cron compatibility */ + } +} + +bool +calendarinterval_new_from_obj(job_t j, launch_data_t obj) +{ + struct tm tmptm; + + memset(&tmptm, 0, sizeof(0)); + + tmptm.tm_min = -1; + tmptm.tm_hour = -1; + tmptm.tm_mday = -1; + tmptm.tm_wday = -1; + tmptm.tm_mon = -1; + + if (!job_assumes(j, obj != NULL)) { + return false; + } + + if (LAUNCH_DATA_DICTIONARY != launch_data_get_type(obj)) { + return false; + } + + launch_data_dict_iterate(obj, calendarinterval_new_from_obj_dict_walk, &tmptm); + + if (tmptm.tm_sec == -1) { + return false; + } + + return calendarinterval_new(j, &tmptm); +} + +bool +calendarinterval_new(job_t j, struct tm *w) +{ + struct calendarinterval *ci = calloc(1, sizeof(struct calendarinterval)); + + if (!job_assumes(j, ci != NULL)) { + return false; + } + + ci->when = *w; + ci->job = j; + + SLIST_INSERT_HEAD(&j->cal_intervals, ci, sle); + + calendarinterval_setalarm(j, ci); + + runtime_add_ref(); + + return true; +} + +void +calendarinterval_delete(job_t j, struct calendarinterval *ci) +{ + SLIST_REMOVE(&j->cal_intervals, ci, calendarinterval, sle); + LIST_REMOVE(ci, global_sle); + + free(ci); + + runtime_del_ref(); +} + +void +calendarinterval_sanity_check(void) +{ + struct calendarinterval *ci = LIST_FIRST(&sorted_calendar_events); + time_t now = time(NULL); + + if (ci && (ci->when_next < now)) { + jobmgr_assumes(root_jobmgr, raise(SIGUSR1) != -1); + } +} + +void +calendarinterval_callback(void) +{ + struct calendarinterval *ci, *ci_next; + time_t now = time(NULL); + + LIST_FOREACH_SAFE(ci, &sorted_calendar_events, global_sle, ci_next) { + job_t j = ci->job; + + if (ci->when_next > now) { + break; + } + + LIST_REMOVE(ci, global_sle); + calendarinterval_setalarm(j, ci); + + j->start_pending = true; + job_dispatch(j, false); + } +} + +bool +socketgroup_new(job_t j, const char *name, int *fds, unsigned int fd_cnt, bool junkfds) +{ + struct socketgroup *sg = calloc(1, sizeof(struct socketgroup) + strlen(name) + 1); + + if (!job_assumes(j, sg != NULL)) { + return false; + } sg->fds = calloc(1, fd_cnt * sizeof(int)); sg->fd_cnt = fd_cnt; sg->junkfds = junkfds; - if (!launchd_assumes(sg->fds != NULL)) { + if (!job_assumes(j, sg->fds != NULL)) { free(sg); return false; } @@ -2010,72 +3510,93 @@ socketgroup_new(struct jobcb *j, const char *name, int *fds, unsigned int fd_cnt SLIST_INSERT_HEAD(&j->sockets, sg, sle); + runtime_add_ref(); + return true; } void -socketgroup_delete(struct jobcb *j, struct socketgroup *sg) +socketgroup_delete(job_t j, struct socketgroup *sg) { unsigned int i; - for (i = 0; i < sg->fd_cnt; i++) - launchd_assumes(close(sg->fds[i]) != -1); + for (i = 0; i < sg->fd_cnt; i++) { +#if 0 + struct sockaddr_storage ss; + struct sockaddr_un *sun = (struct sockaddr_un *)&ss; + socklen_t ss_len = sizeof(ss); + + /* 5480306 */ + if (job_assumes(j, getsockname(sg->fds[i], (struct sockaddr *)&ss, &ss_len) != -1) + && job_assumes(j, ss_len > 0) && (ss.ss_family == AF_UNIX)) { + job_assumes(j, unlink(sun->sun_path) != -1); + /* We might conditionally need to delete a directory here */ + } +#endif + job_assumes(j, runtime_close(sg->fds[i]) != -1); + } SLIST_REMOVE(&j->sockets, sg, socketgroup, sle); free(sg->fds); free(sg); + + runtime_del_ref(); } void -socketgroup_ignore(struct jobcb *j, struct socketgroup *sg) +socketgroup_kevent_mod(job_t j, struct socketgroup *sg, bool do_add) { + struct kevent kev[sg->fd_cnt]; char buf[10000]; unsigned int i, buf_off = 0; - if (sg->junkfds) + if (sg->junkfds) { return; + } + + for (i = 0; i < sg->fd_cnt; i++) { + EV_SET(&kev[i], sg->fds[i], EVFILT_READ, do_add ? EV_ADD : EV_DELETE, 0, 0, j); + buf_off += snprintf(buf + buf_off, sizeof(buf) - buf_off, " %d", sg->fds[i]); + } - for (i = 0; i < sg->fd_cnt; i++) - buf_off += sprintf(buf + buf_off, " %d", sg->fds[i]); + job_log(j, LOG_DEBUG, "%s Sockets:%s", do_add ? "Watching" : "Ignoring", buf); - job_log(j, LOG_DEBUG, "Ignoring Sockets:%s", buf); + job_assumes(j, kevent_bulk_mod(kev, sg->fd_cnt) != -1); - for (i = 0; i < sg->fd_cnt; i++) - launchd_assumes(kevent_mod(sg->fds[i], EVFILT_READ, EV_DELETE, 0, 0, NULL) != -1); + for (i = 0; i < sg->fd_cnt; i++) { + job_assumes(j, kev[i].flags & EV_ERROR); + errno = kev[i].data; + job_assumes(j, kev[i].data == 0); + } } void -socketgroup_watch(struct jobcb *j, struct socketgroup *sg) +socketgroup_ignore(job_t j, struct socketgroup *sg) { - char buf[10000]; - unsigned int i, buf_off = 0; - - if (sg->junkfds) - return; - - for (i = 0; i < sg->fd_cnt; i++) - buf_off += sprintf(buf + buf_off, " %d", sg->fds[i]); - - job_log(j, LOG_DEBUG, "Watching sockets:%s", buf); + socketgroup_kevent_mod(j, sg, false); +} - for (i = 0; i < sg->fd_cnt; i++) - launchd_assumes(kevent_mod(sg->fds[i], EVFILT_READ, EV_ADD, 0, 0, j) != -1); +void +socketgroup_watch(job_t j, struct socketgroup *sg) +{ + socketgroup_kevent_mod(j, sg, true); } void -socketgroup_callback(struct jobcb *j, struct kevent *kev) +socketgroup_callback(job_t j) { - job_start(j); + job_dispatch(j, true); } bool -envitem_new(struct jobcb *j, const char *k, const char *v, bool global) +envitem_new(job_t j, const char *k, const char *v, bool global) { struct envitem *ei = calloc(1, sizeof(struct envitem) + strlen(k) + 1 + strlen(v) + 1); - if (!launchd_assumes(ei != NULL)) + if (!job_assumes(j, ei != NULL)) { return false; + } strcpy(ei->key, k); ei->value = ei->key + strlen(k) + 1; @@ -2087,11 +3608,13 @@ envitem_new(struct jobcb *j, const char *k, const char *v, bool global) SLIST_INSERT_HEAD(&j->env, ei, sle); } + job_log(j, LOG_DEBUG, "Added environmental variable: %s=%s", k, v); + return true; } void -envitem_delete(struct jobcb *j, struct envitem *ei, bool global) +envitem_delete(job_t j, struct envitem *ei, bool global) { if (global) { SLIST_REMOVE(&j->global_env, ei, envitem, sle); @@ -2105,29 +3628,34 @@ envitem_delete(struct jobcb *j, struct envitem *ei, bool global) void envitem_setup(launch_data_t obj, const char *key, void *context) { - struct jobcb *j = context; + job_t j = context; - if (launch_data_get_type(obj) != LAUNCH_DATA_STRING) + if (launch_data_get_type(obj) != LAUNCH_DATA_STRING) { return; + } envitem_new(j, key, launch_data_get_string(obj), j->importing_global_env); } bool -limititem_update(struct jobcb *j, int w, rlim_t r) +limititem_update(job_t j, int w, rlim_t r) { struct limititem *li; SLIST_FOREACH(li, &j->limits, sle) { - if (li->which == w) + if (li->which == w) { break; + } } if (li == NULL) { li = calloc(1, sizeof(struct limititem)); - if (!launchd_assumes(li != NULL)) + if (!job_assumes(j, li != NULL)) { return false; + } + + SLIST_INSERT_HEAD(&j->limits, li, sle); li->which = w; } @@ -2144,61 +3672,90 @@ limititem_update(struct jobcb *j, int w, rlim_t r) } void -limititem_delete(struct jobcb *j, struct limititem *li) +limititem_delete(job_t j, struct limititem *li) { SLIST_REMOVE(&j->limits, li, limititem, sle); free(li); } +void +seatbelt_setup_flags(launch_data_t obj, const char *key, void *context) +{ + job_t j = context; + + if (launch_data_get_type(obj) != LAUNCH_DATA_BOOL) { + job_log(j, LOG_WARNING, "Sandbox flag value must be boolean: %s", key); + return; + } + + if (launch_data_get_bool(obj) == false) { + return; + } + + if (strcasecmp(key, LAUNCH_JOBKEY_SANDBOX_NAMED) == 0) { + j->seatbelt_flags |= SANDBOX_NAMED; + } +} + void limititem_setup(launch_data_t obj, const char *key, void *context) { - struct jobcb *j = context; + job_t j = context; int i, limits_cnt = (sizeof(launchd_keys2limits) / sizeof(launchd_keys2limits[0])); rlim_t rl; - if (launch_data_get_type(obj) != LAUNCH_DATA_INTEGER) + if (launch_data_get_type(obj) != LAUNCH_DATA_INTEGER) { return; + } rl = launch_data_get_integer(obj); for (i = 0; i < limits_cnt; i++) { - if (strcasecmp(launchd_keys2limits[i].key, key) == 0) + if (strcasecmp(launchd_keys2limits[i].key, key) == 0) { break; + } } - if (i == limits_cnt) + if (i == limits_cnt) { return; + } limititem_update(j, launchd_keys2limits[i].val, rl); } bool -job_useless(struct jobcb *j) +job_useless(job_t j) { - if (j->unload_at_exit) { + /* Yes, j->unload_at_exit and j->only_once seem the same, but they'll differ someday... */ + + if ((j->unload_at_exit || j->only_once) && j->start_time != 0) { + if (j->unload_at_exit && j->j_port) { + return false; + } job_log(j, LOG_INFO, "Exited. Was only configured to run once."); return true; - } else if (shutdown_in_progress) { - job_log(j, LOG_INFO, "Exited while shutdown in progress."); - return true; - } else if (j->failed_exits >= LAUNCHD_FAILED_EXITS_THRESHOLD) { - job_log(j, LOG_WARNING, "too many failures in succession"); + } else if (j->removal_pending) { + job_log(j, LOG_DEBUG, "Exited while removal was pending."); return true; - } else if (!j->checkedin && (!SLIST_EMPTY(&j->sockets) || !SLIST_EMPTY(&j->machservices))) { - job_log(j, LOG_WARNING, "Failed to check-in!"); - return true; - } else if (j->legacy_mach_job && SLIST_EMPTY(&j->machservices)) { - job_log(j, LOG_INFO, "Garbage collecting"); + } else if (j->mgr->shutting_down) { + job_log(j, LOG_DEBUG, "Exited while shutdown in progress. Processes remaining: %lu/%lu", total_children, total_anon_children); return true; + } else if (j->legacy_mach_job) { + if (SLIST_EMPTY(&j->machservices)) { + job_log(j, LOG_INFO, "Garbage collecting"); + return true; + } else if (!j->checkedin) { + job_log(j, LOG_WARNING, "Failed to check-in!"); + return true; + } } return false; } bool -job_keepalive(struct jobcb *j) +job_keepalive(job_t j) { mach_msg_type_number_t statusCnt; mach_port_status_t status; @@ -2206,10 +3763,19 @@ job_keepalive(struct jobcb *j) struct machservice *ms; struct stat sb; bool good_exit = (WIFEXITED(j->last_exit_status) && WEXITSTATUS(j->last_exit_status) == 0); - bool dispatch_others = false; - if (j->runatload && j->start_time == 0) { - job_log(j, LOG_DEBUG, "KeepAlive check: job needs to run at least once."); + /* + * 5066316 + * + * We definitely need to revisit this after Leopard ships. Please see + * launchctl.c for the other half of this hack. + */ + if (j->mgr->global_on_demand_cnt > 0 && strcmp(j->label, "com.apple.kextd") != 0) { + return false; + } + + if (j->start_pending) { + job_log(j, LOG_DEBUG, "KeepAlive check: Pent-up non-IPC launch criteria."); return true; } @@ -2221,8 +3787,9 @@ job_keepalive(struct jobcb *j) SLIST_FOREACH(ms, &j->machservices, sle) { statusCnt = MACH_PORT_RECEIVE_STATUS_COUNT; if (mach_port_get_attributes(mach_task_self(), ms->port, MACH_PORT_RECEIVE_STATUS, - (mach_port_info_t)&status, &statusCnt) != KERN_SUCCESS) + (mach_port_info_t)&status, &statusCnt) != KERN_SUCCESS) { continue; + } if (status.mps_msgcount) { job_log(j, LOG_DEBUG, "KeepAlive check: job restarted due to %d queued Mach messages on service: %s", status.mps_msgcount, ms->name); @@ -2233,13 +3800,15 @@ job_keepalive(struct jobcb *j) SLIST_FOREACH(si, &j->semaphores, sle) { bool wanted_state = false; + int qdir_file_cnt; + job_t other_j; + switch (si->why) { case NETWORK_UP: wanted_state = true; case NETWORK_DOWN: if (network_up == wanted_state) { - job_log(j, LOG_DEBUG, "KeepAlive check: job configured to run while the network is %s.", - wanted_state ? "up" : "down"); + job_log(j, LOG_DEBUG, "KeepAlive: The network is %s.", wanted_state ? "up" : "down"); return true; } break; @@ -2247,33 +3816,58 @@ job_keepalive(struct jobcb *j) wanted_state = true; case FAILED_EXIT: if (good_exit == wanted_state) { - job_log(j, LOG_DEBUG, "KeepAlive check: job configured to run while the exit state was %s.", - wanted_state ? "successful" : "failure"); + job_log(j, LOG_DEBUG, "KeepAlive: The exit state was %s.", wanted_state ? "successful" : "failure"); + return true; + } + break; + case OTHER_JOB_ENABLED: + wanted_state = true; + case OTHER_JOB_DISABLED: + if ((bool)job_find(si->what) == wanted_state) { + job_log(j, LOG_DEBUG, "KeepAlive: The following job is %s: %s", wanted_state ? "enabled" : "disabled", si->what); return true; } break; + case OTHER_JOB_ACTIVE: + wanted_state = true; + case OTHER_JOB_INACTIVE: + if ((other_j = job_find(si->what))) { + if ((bool)other_j->p == wanted_state) { + job_log(j, LOG_DEBUG, "KeepAlive: The following job is %s: %s", wanted_state ? "active" : "inactive", si->what); + return true; + } + } + break; case PATH_EXISTS: wanted_state = true; case PATH_MISSING: if ((bool)(stat(si->what, &sb) == 0) == wanted_state) { - job_log(j, LOG_DEBUG, "KeepAlive check: job configured to run while the following path %s: %s", - wanted_state ? "exists" : "is missing", si->what); + if (si->fd != -1) { + job_assumes(j, runtime_close(si->fd) == 0); + si->fd = -1; + } + job_log(j, LOG_DEBUG, "KeepAlive: The following path %s: %s", wanted_state ? "exists" : "is missing", si->what); + return true; + } + break; + case PATH_CHANGES: + break; + case DIR_NOT_EMPTY: + if (-1 == (qdir_file_cnt = dir_has_files(j, si->what))) { + job_log_error(j, LOG_ERR, "Failed to count the number of files in \"%s\"", si->what); + } else if (qdir_file_cnt > 0) { + job_log(j, LOG_DEBUG, "KeepAlive: Directory is not empty: %s", si->what); return true; } - dispatch_others = true; break; } } - /* Maybe another job has the inverse path based semaphore as this job */ - if (dispatch_others) - job_dispatch_all_other_semaphores(root_job, j); - return false; } const char * -job_prog(struct jobcb *j) +job_prog(job_t j) { if (j->prog) { return j->prog; @@ -2284,101 +3878,90 @@ job_prog(struct jobcb *j) } } -bool -job_active(struct jobcb *j) +const char * +job_active(job_t j) { struct machservice *ms; - if (j->req_port) - return true; + if (j->p) { + return "PID is still valid"; + } - if (j->p) - return true; + if (j->mgr->shutting_down && j->log_redirect_fd) { + job_assumes(j, runtime_close(j->log_redirect_fd) != -1); + j->log_redirect_fd = 0; + } - if (j->priv_port_has_senders) { - if (j->start_time && !j->checkedin) { - if (j->legacy_mach_job) { - job_log(j, LOG_NOTICE, "Daemonized. Extremely expensive no-op."); - } else if (!j->unload_at_exit) { - job_log(j, LOG_ERR, "Daemonization is not supported under launchd."); - return false; - } + if (j->log_redirect_fd) { + if (job_assumes(j, j->wait4pipe_eof)) { + return "Standard out/error is still valid"; + } else { + job_assumes(j, runtime_close(j->log_redirect_fd) != -1); + j->log_redirect_fd = 0; } - return true; + } + + if (j->priv_port_has_senders) { + return "Privileged Port still has outstanding senders"; } SLIST_FOREACH(ms, &j->machservices, sle) { - if (ms->isActive) - return true; + if (ms->recv && ms->isActive) { + return "Mach service is still active"; + } } - return false; + return NULL; } -pid_t -launchd_fork(void) +void +machservice_watch(job_t j, struct machservice *ms) { - return job_fork(root_job); + if (ms->recv) { + job_assumes(j, runtime_add_mport(ms->port, NULL, 0) == KERN_SUCCESS); + } } -pid_t -job_fork(struct jobcb *j) +void +machservice_ignore(job_t j, struct machservice *ms) { - mach_port_t p = j->bs_port; - pid_t r = -1; - - sigprocmask(SIG_BLOCK, &blocked_signals, NULL); - - launchd_assumes(launchd_mport_make_send(p) == KERN_SUCCESS); - launchd_assumes(launchd_set_bport(p) == KERN_SUCCESS); - launchd_assumes(launchd_mport_deallocate(p) == KERN_SUCCESS); - - r = fork(); - - if (r != 0) { - launchd_assumes(launchd_set_bport(MACH_PORT_NULL) == KERN_SUCCESS); - } else if (r == 0) { - size_t i; - - for (i = 0; i < NSIG; i++) { - if (sigismember(&blocked_signals, i)) - signal(i, SIG_DFL); - } - } - - sigprocmask(SIG_UNBLOCK, &blocked_signals, NULL); - - return r; + job_assumes(j, runtime_remove_mport(ms->port) == KERN_SUCCESS); } void -machservice_resetport(struct jobcb *j, struct machservice *ms) +machservice_resetport(job_t j, struct machservice *ms) { - launchd_assumes(launchd_mport_close_recv(ms->port) == KERN_SUCCESS); - launchd_assumes(launchd_mport_deallocate(ms->port) == KERN_SUCCESS); - launchd_assumes(launchd_mport_create_recv(&ms->port) == KERN_SUCCESS); - launchd_assumes(launchd_mport_make_send(ms->port) == KERN_SUCCESS); + LIST_REMOVE(ms, port_hash_sle); + job_assumes(j, launchd_mport_close_recv(ms->port) == KERN_SUCCESS); + job_assumes(j, launchd_mport_deallocate(ms->port) == KERN_SUCCESS); + ms->gen_num++; + job_assumes(j, launchd_mport_create_recv(&ms->port) == KERN_SUCCESS); + job_assumes(j, launchd_mport_make_send(ms->port) == KERN_SUCCESS); + LIST_INSERT_HEAD(&port_hash[HASH_PORT(ms->port)], ms, port_hash_sle); } struct machservice * -machservice_new(struct jobcb *j, const char *name, mach_port_t *serviceport) +machservice_new(job_t j, const char *name, mach_port_t *serviceport, bool pid_local) { struct machservice *ms; - if ((ms = calloc(1, sizeof(struct machservice) + strlen(name) + 1)) == NULL) + if ((ms = calloc(1, sizeof(struct machservice) + strlen(name) + 1)) == NULL) { return NULL; + } - strcpy(ms->name, name); + strcpy((char *)ms->name, name); ms->job = j; + ms->per_pid = pid_local; if (*serviceport == MACH_PORT_NULL) { - if (!launchd_assumes(launchd_mport_create_recv(&ms->port) == KERN_SUCCESS)) + if (!job_assumes(j, launchd_mport_create_recv(&ms->port) == KERN_SUCCESS)) { goto out_bad; + } - if (!launchd_assumes(launchd_mport_make_send(ms->port) == KERN_SUCCESS)) + if (!job_assumes(j, launchd_mport_make_send(ms->port) == KERN_SUCCESS)) { goto out_bad2; + } *serviceport = ms->port; - ms->isActive = false; ms->recv = true; } else { ms->port = *serviceport; @@ -2386,12 +3969,14 @@ machservice_new(struct jobcb *j, const char *name, mach_port_t *serviceport) } SLIST_INSERT_HEAD(&j->machservices, ms, sle); + LIST_INSERT_HEAD(&j->mgr->ms_hash[hash_ms(ms->name)], ms, name_hash_sle); + LIST_INSERT_HEAD(&port_hash[HASH_PORT(ms->port)], ms, port_hash_sle); job_log(j, LOG_INFO, "Mach service added: %s", name); return ms; out_bad2: - launchd_assumes(launchd_mport_close_recv(ms->port) == KERN_SUCCESS); + job_assumes(j, launchd_mport_close_recv(ms->port) == KERN_SUCCESS); out_bad: free(ms); return NULL; @@ -2410,14 +3995,13 @@ machservice_status(struct machservice *ms) } void -machservice_setup_options(launch_data_t obj, const char *key, void *context) +job_setup_exception_port(job_t j, task_t target_task) { - struct machservice *ms = context; - mach_port_t mhp = mach_host_self(); - mach_port_t mts = mach_task_self(); thread_state_flavor_t f = 0; - int which_port; - bool b; + + if (!the_exception_server) { + return; + } #if defined (__ppc__) f = PPC_THREAD_STATE64; @@ -2425,7 +4009,38 @@ machservice_setup_options(launch_data_t obj, const char *key, void *context) f = x86_THREAD_STATE; #endif - if (!launchd_assumes(mhp != MACH_PORT_NULL)) { + if (target_task) { + job_assumes(j, task_set_exception_ports(target_task, EXC_MASK_CRASH, the_exception_server, + EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES, f) == KERN_SUCCESS); + } else if (getpid() == 1) { + mach_port_t mhp = mach_host_self(); + job_assumes(j, host_set_exception_ports(mhp, EXC_MASK_CRASH, the_exception_server, + EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES, f) == KERN_SUCCESS); + job_assumes(j, launchd_mport_deallocate(mhp) == KERN_SUCCESS); + } + +} + +void +job_set_exeception_port(job_t j, mach_port_t port) +{ + if (!the_exception_server) { + the_exception_server = port; + job_setup_exception_port(j, 0); + } else { + job_log(j, LOG_WARNING, "The exception server is already claimed!"); + } +} + +void +machservice_setup_options(launch_data_t obj, const char *key, void *context) +{ + struct machservice *ms = context; + mach_port_t mhp = mach_host_self(); + int which_port; + bool b; + + if (!job_assumes(ms->job, mhp != MACH_PORT_NULL)) { return; } @@ -2433,44 +4048,65 @@ machservice_setup_options(launch_data_t obj, const char *key, void *context) case LAUNCH_DATA_INTEGER: which_port = launch_data_get_integer(obj); if (strcasecmp(key, LAUNCH_JOBKEY_MACH_TASKSPECIALPORT) == 0) { - launchd_assumes((errno = task_set_special_port(mts, which_port, ms->port)) == KERN_SUCCESS); + switch (which_port) { + case TASK_KERNEL_PORT: + case TASK_HOST_PORT: + case TASK_NAME_PORT: + case TASK_BOOTSTRAP_PORT: + /* I find it a little odd that zero isn't reserved in the header */ + case 0: + job_log(ms->job, LOG_WARNING, "Tried to set a reserved task special port: %d", which_port); + break; + default: + ms->special_port_num = which_port; + SLIST_INSERT_HEAD(&special_ports, ms, special_port_sle); + break; + } } else if (strcasecmp(key, LAUNCH_JOBKEY_MACH_HOSTSPECIALPORT) == 0 && getpid() == 1) { - launchd_assumes((errno = host_set_special_port(mhp, which_port, ms->port)) == KERN_SUCCESS); + if (which_port > HOST_MAX_SPECIAL_KERNEL_PORT) { + job_assumes(ms->job, (errno = host_set_special_port(mhp, which_port, ms->port)) == KERN_SUCCESS); + } else { + job_log(ms->job, LOG_WARNING, "Tried to set a reserved host special port: %d", which_port); + } } case LAUNCH_DATA_BOOL: b = launch_data_get_bool(obj); - if (strcasecmp(key, LAUNCH_JOBKEY_MACH_RESETATCLOSE) == 0) { + if (strcasecmp(key, LAUNCH_JOBKEY_MACH_ENTERKERNELDEBUGGERONCLOSE) == 0) { + ms->debug_on_close = b; + } else if (strcasecmp(key, LAUNCH_JOBKEY_MACH_RESETATCLOSE) == 0) { ms->reset = b; } else if (strcasecmp(key, LAUNCH_JOBKEY_MACH_HIDEUNTILCHECKIN) == 0) { ms->hide = b; } else if (strcasecmp(key, LAUNCH_JOBKEY_MACH_EXCEPTIONSERVER) == 0) { - launchd_assumes(task_set_exception_ports(mts, EXC_MASK_ALL, ms->port, - EXCEPTION_STATE_IDENTITY, f) == KERN_SUCCESS); + job_set_exeception_port(ms->job, ms->port); } else if (strcasecmp(key, LAUNCH_JOBKEY_MACH_KUNCSERVER) == 0) { ms->kUNCServer = b; - launchd_assumes(host_set_UNDServer(mhp, ms->port) == KERN_SUCCESS); + job_assumes(ms->job, host_set_UNDServer(mhp, ms->port) == KERN_SUCCESS); } break; + case LAUNCH_DATA_DICTIONARY: + job_set_exeception_port(ms->job, ms->port); + break; default: break; } - launchd_assumes(launchd_mport_deallocate(mhp) == KERN_SUCCESS); + job_assumes(ms->job, launchd_mport_deallocate(mhp) == KERN_SUCCESS); } void machservice_setup(launch_data_t obj, const char *key, void *context) { - struct jobcb *j = context; + job_t j = context; struct machservice *ms; mach_port_t p = MACH_PORT_NULL; - if ((ms = job_lookup_service(j->parent, key, false))) { + if ((ms = jobmgr_lookup_service(j->mgr, key, false, 0))) { job_log(j, LOG_WARNING, "Conflict with job: %s over Mach service: %s", ms->job->label, key); return; } - if ((ms = machservice_new(j, key, &p)) == NULL) { + if ((ms = machservice_new(j, key, &p, false)) == NULL) { job_log_error(j, LOG_WARNING, "Cannot add service: %s", key); return; } @@ -2482,96 +4118,294 @@ machservice_setup(launch_data_t obj, const char *key, void *context) } } -struct jobcb * -job_parent(struct jobcb *j) +jobmgr_t +jobmgr_do_garbage_collection(jobmgr_t jm) { - return j->parent; -} + jobmgr_t jmi, jmn; + job_t ji, jn; -void -job_uncork_fork(struct jobcb *j) -{ - pid_t c = j->p; + SLIST_FOREACH_SAFE(jmi, &jm->submgrs, sle, jmn) { + jobmgr_do_garbage_collection(jmi); + } - if (j->stall_before_exec) { - job_log(j, LOG_DEBUG, "Uncorking the fork()."); - /* this unblocks the child and avoids a race - * between the above fork() and the kevent_mod() */ - write(j->execfd, &c, sizeof(c)); - j->stall_before_exec = false; - } else { - job_log(j, LOG_WARNING, "Attempt to uncork a job that isn't in the middle of a fork()."); + if (!jm->shutting_down) { + return jm; + } + + jobmgr_log(jm, LOG_DEBUG, "Garbage collecting."); + + /* + * Normally, we wait for all resources of a job (Unix PIDs/FDs and Mach ports) + * to reset before we conider the job truly dead and ready to be spawned again. + * + * In order to work around 5487724 and 3456090, we're going to call reboot() + * when the last PID dies and not wait for the associated resources to reset. + */ + if (getpid() == 1 && jm->parentmgr == NULL && total_children == 0) { + jobmgr_log(jm, LOG_DEBUG, "About to force a call to: reboot(%s)", reboot_flags_to_C_names(jm->reboot_flags)); + runtime_closelog(); + jobmgr_assumes(jm, reboot(jm->reboot_flags) != -1); + } + + if (jm->hopefully_first_cnt) { + return jm; + } + + if (jm->parentmgr && jm->parentmgr->shutting_down && jm->parentmgr->hopefully_first_cnt) { + return jm; + } + + if (!jm->sent_stop_to_normal_jobs) { + jobmgr_log(jm, LOG_DEBUG, "Asking \"normal\" jobs to exit."); + + LIST_FOREACH_SAFE(ji, &jm->jobs, sle, jn) { + if (!job_active(ji)) { + job_remove(ji); + } else if (!ji->hopefully_exits_last) { + job_stop(ji); + } + } + + jm->sent_stop_to_normal_jobs = true; } + + if (jm->normal_active_cnt) { + return jm; + } + + if (!jm->sent_stop_to_hopefully_last_jobs) { + jobmgr_log(jm, LOG_DEBUG, "Asking \"hopefully last\" jobs to exit."); + + LIST_FOREACH(ji, &jm->jobs, sle) { + if (ji->p && ji->anonymous) { + continue; + } else if (ji->p && job_assumes(ji, ji->hopefully_exits_last)) { + job_stop(ji); + } + } + + jm->sent_stop_to_hopefully_last_jobs = true; + } + + if (!SLIST_EMPTY(&jm->submgrs)) { + return jm; + } + + LIST_FOREACH(ji, &jm->jobs, sle) { + if (!ji->anonymous) { + return jm; + } + } + + jobmgr_log_stray_children(jm); + jobmgr_remove(jm); + return NULL; } void -job_foreach_service(struct jobcb *j, void (*bs_iter)(struct machservice *, void *), void *context, bool include_subjobs) +jobmgr_log_stray_children(jobmgr_t jm) { - struct machservice *ms; - struct jobcb *ji; + int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL }; + size_t i, kp_cnt, len = 10*1024*1024; + struct kinfo_proc *kp; - j = job_get_bs(j); + if (jm->parentmgr || getpid() != 1) { + return; + } - if (include_subjobs) { - SLIST_FOREACH(ji, &j->jobs, sle) { - if (ji->req_port) - continue; + if (!jobmgr_assumes(jm, (kp = malloc(len)) != NULL)) { + return; + } + if (!jobmgr_assumes(jm, sysctl(mib, 3, kp, &len, NULL, 0) != -1)) { + goto out; + } + + kp_cnt = len / sizeof(struct kinfo_proc); - SLIST_FOREACH(ms, &ji->machservices, sle) - bs_iter(ms, context); + for (i = 0; i < kp_cnt; i++) { + pid_t p_i = kp[i].kp_proc.p_pid; + pid_t pp_i = kp[i].kp_eproc.e_ppid; + pid_t pg_i = kp[i].kp_eproc.e_pgid; + const char *z = (kp[i].kp_proc.p_stat == SZOMB) ? "zombie " : ""; + const char *n = kp[i].kp_proc.p_comm; + + if (p_i == 0 || p_i == 1) { + continue; } + + jobmgr_log(jm, LOG_WARNING, "Stray %sprocess at shutdown: PID %u PPID %u PGID %u %s", z, p_i, pp_i, pg_i, n); + + /* + * The kernel team requested that launchd not do this for Leopard. + * jobmgr_assumes(jm, runtime_kill(p_i, SIGKILL) != -1); + */ } - SLIST_FOREACH(ms, &j->machservices, sle) - bs_iter(ms, context); +out: + free(kp); } -struct jobcb * -job_new_bootstrap(struct jobcb *p, mach_port_t requestorport, mach_port_t checkin_port) +jobmgr_t +jobmgr_parent(jobmgr_t jm) { - char bslabel[1024] = "100000"; - struct jobcb *j; + return jm->parentmgr; +} - if (requestorport == MACH_PORT_NULL) { - if (p) { - job_log(p, LOG_ERR, "Mach sub-bootstrap create request requires a requester port"); - } +void +job_uncork_fork(job_t j) +{ + pid_t c = j->p; + + job_log(j, LOG_DEBUG, "Uncorking the fork()."); + /* this unblocks the child and avoids a race + * between the above fork() and the kevent_mod() */ + job_assumes(j, write(j->forkfd, &c, sizeof(c)) == sizeof(c)); + job_assumes(j, runtime_close(j->forkfd) != -1); + j->forkfd = 0; +} + +jobmgr_t +jobmgr_new(jobmgr_t jm, mach_port_t requestorport, mach_port_t transfer_port, bool sflag, const char *name) +{ + mach_msg_size_t mxmsgsz; + job_t bootstrapper = NULL; + jobmgr_t jmr; + + launchd_assert(offsetof(struct jobmgr_s, kqjobmgr_callback) == 0); + + if (jm && requestorport == MACH_PORT_NULL) { + jobmgr_log(jm, LOG_ERR, "Mach sub-bootstrap create request requires a requester port"); return NULL; } - j = job_new(p, bslabel, NULL, NULL, NULL, requestorport); + jmr = calloc(1, sizeof(struct jobmgr_s) + (name ? (strlen(name) + 1) : 128)); - if (j == NULL) + if (jmr == NULL) { return NULL; + } - if (checkin_port != MACH_PORT_NULL) { - j->bs_port = checkin_port; - } else if (!launchd_assumes(launchd_mport_create_recv(&j->bs_port) == KERN_SUCCESS)) { + jmr->kqjobmgr_callback = jobmgr_callback; + strcpy(jmr->name, name ? name : "Under construction"); + + jmr->req_port = requestorport; + + if ((jmr->parentmgr = jm)) { + SLIST_INSERT_HEAD(&jm->submgrs, jmr, sle); + } + + if (jm && !jobmgr_assumes(jmr, launchd_mport_notify_req(jmr->req_port, MACH_NOTIFY_DEAD_NAME) == KERN_SUCCESS)) { goto out_bad; } - sprintf(j->label, "%d", MACH_PORT_INDEX(j->bs_port)); + if (transfer_port != MACH_PORT_NULL) { + jobmgr_assumes(jmr, jm != NULL); + jmr->jm_port = transfer_port; + } else if (!jm && getpid() != 1) { + char *trusted_fd = getenv(LAUNCHD_TRUSTED_FD_ENV); + name_t service_buf; + + snprintf(service_buf, sizeof(service_buf), "com.apple.launchd.peruser.%u", getuid()); + + if (!jobmgr_assumes(jmr, bootstrap_check_in(bootstrap_port, service_buf, &jmr->jm_port) == 0)) { + goto out_bad; + } + + if (trusted_fd) { + int dfd, lfd = strtol(trusted_fd, NULL, 10); + + if ((dfd = dup(lfd)) >= 0) { + jobmgr_assumes(jmr, runtime_close(dfd) != -1); + jobmgr_assumes(jmr, runtime_close(lfd) != -1); + } + + unsetenv(LAUNCHD_TRUSTED_FD_ENV); + } + + /* cut off the Libc cache, we don't want to deadlock against ourself */ + inherited_bootstrap_port = bootstrap_port; + bootstrap_port = MACH_PORT_NULL; + launchd_assert(launchd_mport_notify_req(inherited_bootstrap_port, MACH_NOTIFY_DEAD_NAME) == KERN_SUCCESS); - if (!launchd_assumes(launchd_mport_request_callback(j->bs_port, j, true) == KERN_SUCCESS)) + /* We set this explicitly as we start each child */ + launchd_assert(launchd_set_bport(MACH_PORT_NULL) == KERN_SUCCESS); + } else if (!jobmgr_assumes(jmr, launchd_mport_create_recv(&jmr->jm_port) == KERN_SUCCESS)) { goto out_bad; + } - if (p) { - job_log(p, LOG_DEBUG, "Mach sub-bootstrap created: %s", j->label); + if (!name) { + sprintf(jmr->name, "%u", MACH_PORT_INDEX(jmr->jm_port)); } - return j; + /* Sigh... at the moment, MIG has maxsize == sizeof(reply union) */ + mxmsgsz = sizeof(union __RequestUnion__job_mig_protocol_vproc_subsystem); + if (job_mig_protocol_vproc_subsystem.maxsize > mxmsgsz) { + mxmsgsz = job_mig_protocol_vproc_subsystem.maxsize; + } + + if (!jm) { + jobmgr_assumes(jmr, kevent_mod(SIGTERM, EVFILT_SIGNAL, EV_ADD, 0, 0, jmr) != -1); + jobmgr_assumes(jmr, kevent_mod(SIGUSR1, EVFILT_SIGNAL, EV_ADD, 0, 0, jmr) != -1); + jobmgr_assumes(jmr, kevent_mod(0, EVFILT_FS, EV_ADD, VQ_MOUNT|VQ_UNMOUNT|VQ_UPDATE, 0, jmr) != -1); + } + + if (name) { + bootstrapper = jobmgr_init_session(jmr, name, sflag); + } + + if (!bootstrapper || !bootstrapper->weird_bootstrap) { + if (!jobmgr_assumes(jmr, runtime_add_mport(jmr->jm_port, protocol_vproc_server, mxmsgsz) == KERN_SUCCESS)) { + goto out_bad; + } + } + + jobmgr_log(jmr, LOG_DEBUG, "Created job manager%s%s", jm ? " with parent: " : ".", jm ? jm->name : ""); + + if (bootstrapper) { + jobmgr_assumes(jmr, job_dispatch(bootstrapper, true) != NULL); + } + + if (jmr->parentmgr) { + runtime_add_ref(); + } + + return jmr; out_bad: - if (j) - job_remove(j); + if (jmr) { + jobmgr_remove(jmr); + } return NULL; } -void -job_delete_anything_with_port(struct jobcb *j, mach_port_t port) +job_t +jobmgr_init_session(jobmgr_t jm, const char *session_type, bool sflag) +{ + const char *bootstrap_tool[] = { "/bin/launchctl", "bootstrap", "-S", session_type, sflag ? "-s" : NULL, NULL }; + char thelabel[1000]; + job_t bootstrapper; + + snprintf(thelabel, sizeof(thelabel), "com.apple.launchctl.%s", session_type); + bootstrapper = job_new(jm, thelabel, NULL, bootstrap_tool); + if (jobmgr_assumes(jm, bootstrapper != NULL) && (jm->parentmgr || getuid())) { + char buf[100]; + + /* launchd-201: can't ssh in with AFP OD account (hangs) */ + snprintf(buf, sizeof(buf), "0x%X:0:0", getuid()); + envitem_new(bootstrapper, "__CF_USER_TEXT_ENCODING", buf, false); + bootstrapper->weird_bootstrap = true; + jobmgr_assumes(jm, job_setup_machport(bootstrapper)); + } + + jm->session_initialized = true; + + return bootstrapper; +} + +jobmgr_t +jobmgr_delete_anything_with_port(jobmgr_t jm, mach_port_t port) { struct machservice *ms, *next_ms; - struct jobcb *ji, *jn; + jobmgr_t jmi, jmn; /* Mach ports, unlike Unix descriptors, are reference counted. In other * words, when some program hands us a second or subsequent send right @@ -2583,48 +4417,59 @@ job_delete_anything_with_port(struct jobcb *j, mach_port_t port) * to use. */ - if (j->req_port == port) - return job_remove(j); + if (jm == root_jobmgr) { + if (port == inherited_bootstrap_port) { + launchd_assumes(launchd_mport_deallocate(port) == KERN_SUCCESS); + inherited_bootstrap_port = MACH_PORT_NULL; - SLIST_FOREACH_SAFE(ji, &j->jobs, sle, jn) - job_delete_anything_with_port(ji, port); + return jobmgr_shutdown(jm); + } + + LIST_FOREACH_SAFE(ms, &port_hash[HASH_PORT(port)], port_hash_sle, next_ms) { + if (ms->port == port) { + machservice_delete(ms->job, ms, true); + } + } + } + + SLIST_FOREACH_SAFE(jmi, &jm->submgrs, sle, jmn) { + jobmgr_delete_anything_with_port(jmi, port); + } - SLIST_FOREACH_SAFE(ms, &j->machservices, sle, next_ms) { - if (ms->port == port) - machservice_delete(ms); + if (jm->req_port == port) { + jobmgr_log(jm, LOG_DEBUG, "Request port died: 0x%x", port); + return jobmgr_shutdown(jm); } + + return jm; } struct machservice * -job_lookup_service(struct jobcb *j, const char *name, bool check_parent) +jobmgr_lookup_service(jobmgr_t jm, const char *name, bool check_parent, pid_t target_pid) { struct machservice *ms; - struct jobcb *ji; - j = job_get_bs(j); - - SLIST_FOREACH(ji, &j->jobs, sle) { - if (ji->req_port) - continue; + if (target_pid) { + jobmgr_assumes(jm, !check_parent); + } - SLIST_FOREACH(ms, &ji->machservices, sle) { - if (strcmp(name, ms->name) == 0) + LIST_FOREACH(ms, &jm->ms_hash[hash_ms(name)], name_hash_sle) { + if ((target_pid && ms->per_pid && ms->job->p == target_pid) || (!target_pid && !ms->per_pid)) { + if (strcmp(name, ms->name) == 0) { return ms; + } } } - SLIST_FOREACH(ms, &j->machservices, sle) { - if (strcmp(name, ms->name) == 0) - return ms; - } - - if (j->parent == NULL) + if (jm->parentmgr == NULL) { return NULL; + } - if (!check_parent) + if (!check_parent) { return NULL; + } - return job_lookup_service(j->parent, name, true); + return jobmgr_lookup_service(jm->parentmgr, name, true, 0); } mach_port_t @@ -2633,7 +4478,7 @@ machservice_port(struct machservice *ms) return ms->port; } -struct jobcb * +job_t machservice_job(struct machservice *ms) { return ms->job; @@ -2658,42 +4503,53 @@ machservice_name(struct machservice *ms) } void -machservice_delete(struct machservice *ms) +machservice_delete(job_t j, struct machservice *ms, bool port_died) { - if (ms->recv) { - if (ms->isActive) { - /* FIXME we should cancel the notification */ - } else { - launchd_assumes(launchd_mport_close_recv(ms->port) == KERN_SUCCESS); - } + if (ms->debug_on_close) { + job_log(j, LOG_NOTICE, "About to enter kernel debugger because of Mach port: 0x%x", ms->port); + job_assumes(j, host_reboot(mach_host_self(), HOST_REBOOT_DEBUGGER) == KERN_SUCCESS); + } + + if (ms->recv && job_assumes(j, !ms->isActive)) { + job_assumes(j, launchd_mport_close_recv(ms->port) == KERN_SUCCESS); + } + + job_assumes(j, launchd_mport_deallocate(ms->port) == KERN_SUCCESS); + + if (ms->port == the_exception_server) { + the_exception_server = 0; } - launchd_assumes(launchd_mport_deallocate(ms->port) == KERN_SUCCESS); + job_log(j, LOG_INFO, "Mach service deleted%s: %s", port_died ? " (port died)" : "", ms->name); - job_log(ms->job, LOG_INFO, "Mach service deleted: %s", ms->name); + if (ms->special_port_num) { + SLIST_REMOVE(&special_ports, ms, machservice, special_port_sle); + } - SLIST_REMOVE(&ms->job->machservices, ms, machservice, sle); + SLIST_REMOVE(&j->machservices, ms, machservice, sle); + LIST_REMOVE(ms, name_hash_sle); + LIST_REMOVE(ms, port_hash_sle); free(ms); } void -machservice_watch(struct machservice *ms) +machservice_request_notifications(struct machservice *ms) { mach_msg_id_t which = MACH_NOTIFY_DEAD_NAME; ms->isActive = true; - if (ms->job->req_port == MACH_PORT_NULL) { + if (ms->recv) { which = MACH_NOTIFY_PORT_DESTROYED; job_checkin(ms->job); } - launchd_assumes(launchd_mport_notify_req(ms->port, which) == KERN_SUCCESS); + job_assumes(ms->job, launchd_mport_notify_req(ms->port, which) == KERN_SUCCESS); } -#define NELEM(x) (sizeof(x)/sizeof(x[0])) -#define END_OF(x) (&(x)[NELEM(x)]) +#define NELEM(x) (sizeof(x)/sizeof(x[0])) +#define END_OF(x) (&(x)[NELEM(x)]) char ** mach_cmd2argv(const char *string) @@ -2707,26 +4563,31 @@ mach_cmd2argv(const char *string) while (isspace(*cp)) cp++; term = (*cp == '"') ? *cp++ : '\0'; - if (nargs < NELEM(argv)) + if (nargs < NELEM(argv)) { argv[nargs++] = argp; + } while (*cp && (term ? *cp != term : !isspace(*cp)) && argp < END_OF(args)) { - if (*cp == '\\') + if (*cp == '\\') { cp++; + } *argp++ = *cp; - if (*cp) + if (*cp) { cp++; + } } *argp++ = '\0'; } argv[nargs] = NULL; - if (nargs == 0) + if (nargs == 0) { return NULL; + } argv_ret = malloc((nargs + 1) * sizeof(char *) + strlen(string) + 1); - if (!launchd_assumes(argv_ret != NULL)) + if (!launchd_assumes(argv_ret != NULL)) { return NULL; + } co = (char *)argv_ret + (nargs + 1) * sizeof(char *); @@ -2741,158 +4602,298 @@ mach_cmd2argv(const char *string) } void -job_checkin(struct jobcb *j) +job_checkin(job_t j) { j->checkedin = true; } bool -job_ack_port_destruction(struct jobcb *j, mach_port_t p) +job_ack_port_destruction(mach_port_t p) { - struct jobcb *ji; struct machservice *ms; - SLIST_FOREACH(ji, &j->jobs, sle) { - if (job_ack_port_destruction(ji, p)) - return true; - } - - SLIST_FOREACH(ms, &j->machservices, sle) { - if (ms->port == p) + LIST_FOREACH(ms, &port_hash[HASH_PORT(p)], port_hash_sle) { + if (ms->recv && (ms->port == p)) { break; + } } - if (ms == NULL) + if (!ms) { return false; + } ms->isActive = false; - if (ms->reset) - machservice_resetport(j, ms); + if (ms->reset) { + machservice_resetport(ms->job, ms); + } - job_log(j, LOG_DEBUG, "Receive right returned to us: %s", ms->name); + job_log(ms->job, LOG_DEBUG, "Receive right returned to us: %s", ms->name); + job_dispatch(ms->job, false); - job_dispatch(j); + root_jobmgr = jobmgr_do_garbage_collection(root_jobmgr); return true; } void -job_ack_no_senders(struct jobcb *j) +job_ack_no_senders(job_t j) { j->priv_port_has_senders = false; + job_assumes(j, launchd_mport_close_recv(j->j_port) == KERN_SUCCESS); + j->j_port = 0; + job_log(j, LOG_DEBUG, "No more senders on privileged Mach bootstrap port"); - job_dispatch(j); + job_dispatch(j, false); } -mach_port_t -job_get_reqport(struct jobcb *j) +jobmgr_t +job_get_bs(job_t j) { - j->transfer_bstrap = true; - gc_this_job = j; + if (job_assumes(j, j->mgr != NULL)) { + return j->mgr; + } - return j->req_port; + return NULL; } -mach_port_t -job_get_bsport(struct jobcb *j) +bool +job_is_anonymous(job_t j) { - return j->bs_port; + return j->anonymous; } -struct jobcb * -job_get_bs(struct jobcb *j) +void +job_force_sampletool(job_t j) { - if (j->req_port) - return j; + struct stat sb; + char logfile[PATH_MAX]; + char pidstr[100]; + char *sample_args[] = { "sample", pidstr, "1", "-mayDie", "-file", logfile, NULL }; + char *contents = NULL; + int logfile_fd = -1; + int console_fd = -1; + int wstatus; + pid_t sp; + + if (!debug_shutdown_hangs) { + return; + } + + snprintf(pidstr, sizeof(pidstr), "%u", j->p); + snprintf(logfile, sizeof(logfile), SHUTDOWN_LOG_DIR "/%s-%u.sample.txt", j->label, j->p); - if (launchd_assumes(j->parent != NULL)) - return j->parent; + if (!job_assumes(j, unlink(logfile) != -1 || errno == ENOENT)) { + goto out; + } - return NULL; -} + /* + * This will stall launchd for as long as the 'sample' tool runs. + * + * We didn't give the 'sample' tool a bootstrap port, so it therefore + * can't deadlock against launchd. + */ + if (!job_assumes(j, (errno = posix_spawnp(&sp, sample_args[0], NULL, NULL, sample_args, environ)) == 0)) { + goto out; + } -pid_t -job_get_pid(struct jobcb *j) -{ - return j->p; + job_log(j, LOG_DEBUG, "Waiting for 'sample' to finish."); + + if (!job_assumes(j, waitpid(sp, &wstatus, 0) != -1)) { + goto out; + } + + /* + * This won't work if the VFS or filesystems are sick: + * sync(); + */ + + if (!job_assumes(j, WIFEXITED(wstatus) && WEXITSTATUS(wstatus) == 0)) { + goto out; + } + + if (!job_assumes(j, (logfile_fd = open(logfile, O_RDONLY|O_NOCTTY)) != -1)) { + goto out; + } + + if (!job_assumes(j, (console_fd = open(_PATH_CONSOLE, O_WRONLY|O_APPEND|O_NOCTTY)) != -1)) { + goto out; + } + + if (!job_assumes(j, fstat(logfile_fd, &sb) != -1)) { + goto out; + } + + contents = malloc(sb.st_size); + + if (!job_assumes(j, contents != NULL)) { + goto out; + } + + if (!job_assumes(j, read(logfile_fd, contents, sb.st_size) == sb.st_size)) { + goto out; + } + + job_assumes(j, write(console_fd, contents, sb.st_size) == sb.st_size); + +out: + if (contents) { + free(contents); + } + + if (logfile_fd != -1) { + job_assumes(j, runtime_fsync(logfile_fd) != -1); + job_assumes(j, runtime_close(logfile_fd) != -1); + } + + if (console_fd != -1) { + job_assumes(j, runtime_close(console_fd) != -1); + } + + job_log(j, LOG_DEBUG, "Finished sampling."); } bool -semaphoreitem_new(struct jobcb *j, semaphore_reason_t why, const char *what) +semaphoreitem_new(job_t j, semaphore_reason_t why, const char *what) { struct semaphoreitem *si; size_t alloc_sz = sizeof(struct semaphoreitem); - if (what) + if (what) { alloc_sz += strlen(what) + 1; + } - if (!launchd_assumes(si = calloc(1, alloc_sz))) + if (!job_assumes(j, si = calloc(1, alloc_sz))) { return false; + } + si->fd = -1; si->why = why; - if (what) + if (what) { strcpy(si->what, what); + } SLIST_INSERT_HEAD(&j->semaphores, si, sle); + semaphoreitem_runtime_mod_ref(si, true); + return true; } void -semaphoreitem_delete(struct jobcb *j, struct semaphoreitem *ri) +semaphoreitem_runtime_mod_ref(struct semaphoreitem *si, bool add) +{ + /* + * External events need to be tracked. + * Internal events do NOT need to be tracked. + */ + + switch (si->why) { + case SUCCESSFUL_EXIT: + case FAILED_EXIT: + case OTHER_JOB_ENABLED: + case OTHER_JOB_DISABLED: + case OTHER_JOB_ACTIVE: + case OTHER_JOB_INACTIVE: + return; + default: + break; + } + + if (add) { + runtime_add_ref(); + } else { + runtime_del_ref(); + } +} + +void +semaphoreitem_delete(job_t j, struct semaphoreitem *si) { - SLIST_REMOVE(&j->semaphores, ri, semaphoreitem, sle); + semaphoreitem_runtime_mod_ref(si, false); + + SLIST_REMOVE(&j->semaphores, si, semaphoreitem, sle); - free(ri); + if (si->fd != -1) { + job_assumes(j, runtime_close(si->fd) != -1); + } + + free(si); } void -semaphoreitem_setup_paths(launch_data_t obj, const char *key, void *context) +semaphoreitem_setup_dict_iter(launch_data_t obj, const char *key, void *context) { - struct jobcb *j = context; + struct semaphoreitem_dict_iter_context *sdic = context; semaphore_reason_t why; - why = launch_data_get_bool(obj) ? PATH_EXISTS : PATH_MISSING; + why = launch_data_get_bool(obj) ? sdic->why_true : sdic->why_false; - semaphoreitem_new(j, why, key); + semaphoreitem_new(sdic->j, why, key); } void semaphoreitem_setup(launch_data_t obj, const char *key, void *context) { - struct jobcb *j = context; + struct semaphoreitem_dict_iter_context sdic = { context, 0, 0 }; + job_t j = context; semaphore_reason_t why; - if (strcasecmp(key, LAUNCH_JOBKEY_KEEPALIVE_NETWORKSTATE) == 0) { - why = launch_data_get_bool(obj) ? NETWORK_UP : NETWORK_DOWN; - semaphoreitem_new(j, why, NULL); - } else if (strcasecmp(key, LAUNCH_JOBKEY_KEEPALIVE_SUCCESSFULEXIT) == 0) { - why = launch_data_get_bool(obj) ? SUCCESSFUL_EXIT : FAILED_EXIT; - semaphoreitem_new(j, why, NULL); - j->runatload = true; - } else if (strcasecmp(key, LAUNCH_JOBKEY_KEEPALIVE_PATHSTATE) == 0 && - launch_data_get_type(obj) == LAUNCH_DATA_DICTIONARY) { - launch_data_dict_iterate(obj, semaphoreitem_setup_paths, j); + switch (launch_data_get_type(obj)) { + case LAUNCH_DATA_BOOL: + if (strcasecmp(key, LAUNCH_JOBKEY_KEEPALIVE_NETWORKSTATE) == 0) { + why = launch_data_get_bool(obj) ? NETWORK_UP : NETWORK_DOWN; + semaphoreitem_new(j, why, NULL); + } else if (strcasecmp(key, LAUNCH_JOBKEY_KEEPALIVE_SUCCESSFULEXIT) == 0) { + why = launch_data_get_bool(obj) ? SUCCESSFUL_EXIT : FAILED_EXIT; + semaphoreitem_new(j, why, NULL); + j->start_pending = true; + } else { + job_assumes(j, false); + } + break; + case LAUNCH_DATA_DICTIONARY: + if (strcasecmp(key, LAUNCH_JOBKEY_KEEPALIVE_PATHSTATE) == 0) { + sdic.why_true = PATH_EXISTS; + sdic.why_false = PATH_MISSING; + } else if (strcasecmp(key, LAUNCH_JOBKEY_KEEPALIVE_OTHERJOBACTIVE) == 0) { + sdic.why_true = OTHER_JOB_ACTIVE; + sdic.why_false = OTHER_JOB_INACTIVE; + } else if (strcasecmp(key, LAUNCH_JOBKEY_KEEPALIVE_OTHERJOBENABLED) == 0) { + sdic.why_true = OTHER_JOB_ENABLED; + sdic.why_false = OTHER_JOB_DISABLED; + } else { + job_assumes(j, false); + break; + } + + launch_data_dict_iterate(obj, semaphoreitem_setup_dict_iter, &sdic); + break; + default: + job_assumes(j, false); + break; } } void -job_dispatch_all_other_semaphores(struct jobcb *j, struct jobcb *nj) +jobmgr_dispatch_all_semaphores(jobmgr_t jm) { - struct jobcb *ji; + jobmgr_t jmi, jmn; + job_t ji, jn; - if (j == nj) - return; - if (!SLIST_EMPTY(&j->semaphores)) - job_dispatch(j); + SLIST_FOREACH_SAFE(jmi, &jm->submgrs, sle, jmn) { + jobmgr_dispatch_all_semaphores(jmi); + } - SLIST_FOREACH(ji, &j->jobs, sle) - job_dispatch_all_other_semaphores(ji, nj); + LIST_FOREACH_SAFE(ji, &jm->jobs, sle, jn) { + if (!SLIST_EMPTY(&ji->semaphores)) { + job_dispatch(ji, false); + } + } } time_t @@ -2933,8 +4934,9 @@ cronemu_wday(int wday, int hour, int min) workingtm.tm_sec = 0; workingtm.tm_min++; - if (wday == 7) + if (wday == 7) { wday = 0; + } while (!(workingtm.tm_wday == wday && cronemu_hour(&workingtm, hour, min))) { workingtm.tm_mday++; @@ -2960,17 +4962,19 @@ cronemu_mon(struct tm *wtm, int mon, int mday, int hour, int min) workingtm.tm_min = 0; carrytest = workingtm.tm_mon; mktime(&workingtm); - if (carrytest != workingtm.tm_mon) + if (carrytest != workingtm.tm_mon) { return false; + } } *wtm = workingtm; return true; } - if (mon < wtm->tm_mon) + if (mon < wtm->tm_mon) { return false; + } - if (mon > wtm->tm_mon) { + if (mon > wtm->tm_mon) { wtm->tm_mon = mon; wtm->tm_mday = 1; wtm->tm_hour = 0; @@ -2993,17 +4997,19 @@ cronemu_mday(struct tm *wtm, int mday, int hour, int min) workingtm.tm_min = 0; carrytest = workingtm.tm_mday; mktime(&workingtm); - if (carrytest != workingtm.tm_mday) + if (carrytest != workingtm.tm_mday) { return false; + } } *wtm = workingtm; return true; } - if (mday < wtm->tm_mday) + if (mday < wtm->tm_mday) { return false; + } - if (mday > wtm->tm_mday) { + if (mday > wtm->tm_mday) { wtm->tm_mday = mday; wtm->tm_hour = 0; wtm->tm_min = 0; @@ -3024,15 +5030,17 @@ cronemu_hour(struct tm *wtm, int hour, int min) workingtm.tm_min = 0; carrytest = workingtm.tm_hour; mktime(&workingtm); - if (carrytest != workingtm.tm_hour) + if (carrytest != workingtm.tm_hour) { return false; + } } *wtm = workingtm; return true; } - if (hour < wtm->tm_hour) + if (hour < wtm->tm_hour) { return false; + } if (hour > wtm->tm_hour) { wtm->tm_hour = hour; @@ -3045,11 +5053,13 @@ cronemu_hour(struct tm *wtm, int hour, int min) bool cronemu_min(struct tm *wtm, int min) { - if (min == -1) + if (min == -1) { return true; + } - if (min < wtm->tm_min) + if (min < wtm->tm_min) { return false; + } if (min > wtm->tm_min) { wtm->tm_min = min; @@ -3057,3 +5067,1546 @@ cronemu_min(struct tm *wtm, int min) return true; } + +kern_return_t +job_mig_create_server(job_t j, cmd_t server_cmd, uid_t server_uid, boolean_t on_demand, mach_port_t *server_portp) +{ + struct ldcred ldc; + job_t js; + + if (!launchd_assumes(j != NULL)) { + return BOOTSTRAP_NO_MEMORY; + } + + runtime_get_caller_creds(&ldc); + + job_log(j, LOG_DEBUG, "Server create attempt: %s", server_cmd); + +#define LET_MERE_MORTALS_ADD_SERVERS_TO_PID1 + /* XXX - This code should go away once the per session launchd is integrated with the rest of the system */ +#ifdef LET_MERE_MORTALS_ADD_SERVERS_TO_PID1 + if (getpid() == 1) { + if (ldc.euid && server_uid && (ldc.euid != server_uid)) { + job_log(j, LOG_WARNING, "Server create: \"%s\": Will run as UID %d, not UID %d as they told us to", + server_cmd, ldc.euid, server_uid); + server_uid = ldc.euid; + } + } else +#endif + if (getuid()) { + if (server_uid != getuid()) { + job_log(j, LOG_WARNING, "Server create: \"%s\": As UID %d, we will not be able to switch to UID %d", + server_cmd, getuid(), server_uid); + } + server_uid = 0; /* zero means "do nothing" */ + } + + js = job_new_via_mach_init(j, server_cmd, server_uid, on_demand); + + if (js == NULL) { + return BOOTSTRAP_NO_MEMORY; + } + + *server_portp = js->j_port; + return BOOTSTRAP_SUCCESS; +} + +kern_return_t +job_mig_send_signal(job_t j, mach_port_t srp, name_t targetlabel, int sig) +{ + struct ldcred ldc; + job_t otherj; + + if (!launchd_assumes(j != NULL)) { + return BOOTSTRAP_NO_MEMORY; + } + + runtime_get_caller_creds(&ldc); + + if (ldc.euid != 0 && ldc.euid != getuid()) { + return BOOTSTRAP_NOT_PRIVILEGED; + } + + if (!(otherj = job_find(targetlabel))) { + return BOOTSTRAP_UNKNOWN_SERVICE; + } + + if (sig == VPROC_MAGIC_UNLOAD_SIGNAL) { + bool do_block = otherj->p; + + if (otherj->anonymous) { + return BOOTSTRAP_NOT_PRIVILEGED; + } + + job_remove(otherj); + + if (do_block) { + job_log(j, LOG_DEBUG, "Blocking MIG return of job_remove(): %s", otherj->label); + /* this is messy. We shouldn't access 'otherj' after job_remove(), but we check otherj->p first... */ + job_assumes(otherj, waiting4removal_new(otherj, srp)); + return MIG_NO_REPLY; + } else { + return 0; + } + } else if (otherj->p) { + job_assumes(j, runtime_kill(otherj->p, sig) != -1); + } + + return 0; +} + +kern_return_t +job_mig_log_forward(job_t j, vm_offset_t inval, mach_msg_type_number_t invalCnt) +{ + struct ldcred ldc; + + if (!launchd_assumes(j != NULL)) { + return BOOTSTRAP_NO_MEMORY; + } + + if (!job_assumes(j, j->per_user)) { + return BOOTSTRAP_NOT_PRIVILEGED; + } + + runtime_get_caller_creds(&ldc); + + return runtime_log_forward(ldc.euid, ldc.egid, inval, invalCnt); +} + +kern_return_t +job_mig_log_drain(job_t j, mach_port_t srp, vm_offset_t *outval, mach_msg_type_number_t *outvalCnt) +{ + struct ldcred ldc; + + if (!launchd_assumes(j != NULL)) { + return BOOTSTRAP_NO_MEMORY; + } + + runtime_get_caller_creds(&ldc); + + if (ldc.euid) { + return BOOTSTRAP_NOT_PRIVILEGED; + } + + return runtime_log_drain(srp, outval, outvalCnt); +} + +kern_return_t +job_mig_swap_complex(job_t j, vproc_gsk_t inkey, vproc_gsk_t outkey, + vm_offset_t inval, mach_msg_type_number_t invalCnt, + vm_offset_t *outval, mach_msg_type_number_t *outvalCnt) +{ + const char *action; + launch_data_t input_obj, output_obj; + size_t data_offset = 0; + size_t packed_size; + struct ldcred ldc; + + runtime_get_caller_creds(&ldc); + + if (!launchd_assumes(j != NULL)) { + return BOOTSTRAP_NO_MEMORY; + } + + if (inkey && ldc.euid && ldc.euid != getuid()) { + return BOOTSTRAP_NOT_PRIVILEGED; + } + + if (inkey && outkey && !job_assumes(j, inkey == outkey)) { + return 1; + } + + if (inkey && outkey) { + action = "Swapping"; + } else if (inkey) { + action = "Setting"; + } else { + action = "Getting"; + } + + job_log(j, LOG_DEBUG, "%s key: %u", action, inkey ? inkey : outkey); + + *outvalCnt = 20 * 1024 * 1024; + mig_allocate(outval, *outvalCnt); + if (!job_assumes(j, *outval != 0)) { + return 1; + } + + if (invalCnt && !job_assumes(j, (input_obj = launch_data_unpack((void *)inval, invalCnt, NULL, 0, &data_offset, NULL)) != NULL)) { + goto out_bad; + } + + switch (outkey) { + case VPROC_GSK_ENVIRONMENT: + if (!job_assumes(j, (output_obj = launch_data_alloc(LAUNCH_DATA_DICTIONARY)))) { + goto out_bad; + } + jobmgr_export_env_from_other_jobs(j->mgr, output_obj); + if (!job_assumes(j, launch_data_pack(output_obj, (void *)*outval, *outvalCnt, NULL, NULL) != 0)) { + goto out_bad; + } + launch_data_free(output_obj); + break; + case VPROC_GSK_ALLJOBS: + if (!job_assumes(j, (output_obj = job_export_all()) != NULL)) { + goto out_bad; + } + ipc_revoke_fds(output_obj); + packed_size = launch_data_pack(output_obj, (void *)*outval, *outvalCnt, NULL, NULL); + if (!job_assumes(j, packed_size != 0)) { + goto out_bad; + } + launch_data_free(output_obj); + break; + case 0: + mig_deallocate(*outval, *outvalCnt); + *outval = 0; + *outvalCnt = 0; + break; + default: + goto out_bad; + } + + if (invalCnt) switch (inkey) { + case VPROC_GSK_ENVIRONMENT: + job_assumes(j, false); + break; + case 0: + break; + default: + goto out_bad; + } + + mig_deallocate(inval, invalCnt); + + return 0; + +out_bad: + if (*outval) { + mig_deallocate(*outval, *outvalCnt); + } + return 1; +} + +kern_return_t +job_mig_swap_integer(job_t j, vproc_gsk_t inkey, vproc_gsk_t outkey, int64_t inval, int64_t *outval) +{ + const char *action; + kern_return_t kr = 0; + struct ldcred ldc; + int oldmask; + + runtime_get_caller_creds(&ldc); + + if (!launchd_assumes(j != NULL)) { + return BOOTSTRAP_NO_MEMORY; + } + + if (inkey && ldc.euid && ldc.euid != getuid()) { + return BOOTSTRAP_NOT_PRIVILEGED; + } + + if (inkey && outkey && !job_assumes(j, inkey == outkey)) { + return 1; + } + + if (inkey && outkey) { + action = "Swapping"; + } else if (inkey) { + action = "Setting"; + } else { + action = "Getting"; + } + + job_log(j, LOG_DEBUG, "%s key: %u", action, inkey ? inkey : outkey); + + switch (outkey) { + case VPROC_GSK_LAST_EXIT_STATUS: + *outval = j->last_exit_status; + break; + case VPROC_GSK_MGR_UID: + *outval = getuid(); + break; + case VPROC_GSK_MGR_PID: + *outval = getpid(); + break; + case VPROC_GSK_IS_MANAGED: + *outval = j->anonymous ? 0 : 1; + break; + case VPROC_GSK_BASIC_KEEPALIVE: + *outval = !j->ondemand; + break; + case VPROC_GSK_START_INTERVAL: + *outval = j->start_interval; + break; + case VPROC_GSK_IDLE_TIMEOUT: + *outval = j->timeout; + break; + case VPROC_GSK_EXIT_TIMEOUT: + *outval = j->exit_timeout; + break; + case VPROC_GSK_GLOBAL_LOG_MASK: + oldmask = runtime_setlogmask(LOG_UPTO(LOG_DEBUG)); + *outval = oldmask; + runtime_setlogmask(oldmask); + break; + case VPROC_GSK_GLOBAL_UMASK: + oldmask = umask(0); + *outval = oldmask; + umask(oldmask); + break; + case 0: + *outval = 0; + break; + default: + kr = 1; + break; + } + + switch (inkey) { + case VPROC_GSK_GLOBAL_ON_DEMAND: + kr = job_set_global_on_demand(j, (bool)inval) ? 0 : 1; + break; + case VPROC_GSK_BASIC_KEEPALIVE: + j->ondemand = !inval; + break; + case VPROC_GSK_START_INTERVAL: + if ((uint64_t)inval > UINT32_MAX) { + kr = 1; + } else if (inval) { + if (j->start_interval == 0) { + runtime_add_ref(); + } else { + /* Workaround 5225889 */ + job_assumes(j, kevent_mod((uintptr_t)&j->start_interval, EVFILT_TIMER, EV_DELETE, 0, 0, j) != -1); + } + j->start_interval = inval; + job_assumes(j, kevent_mod((uintptr_t)&j->start_interval, EVFILT_TIMER, EV_ADD, NOTE_SECONDS, j->start_interval, j) != -1); + } else if (j->start_interval) { + job_assumes(j, kevent_mod((uintptr_t)&j->start_interval, EVFILT_TIMER, EV_DELETE, 0, 0, NULL) != -1); + if (j->start_interval != 0) { + runtime_del_ref(); + } + j->start_interval = 0; + } + break; + case VPROC_GSK_IDLE_TIMEOUT: + if ((unsigned int)inval > 0) { + j->timeout = inval; + } + break; + case VPROC_GSK_EXIT_TIMEOUT: + if ((unsigned int)inval > 0) { + j->exit_timeout = inval; + } + break; + case VPROC_GSK_GLOBAL_LOG_MASK: + runtime_setlogmask(inval); + break; + case VPROC_GSK_GLOBAL_UMASK: + umask(inval); + break; + case 0: + break; + default: + kr = 1; + break; + } + + return kr; +} + +kern_return_t +job_mig_post_fork_ping(job_t j, task_t child_task) +{ + struct machservice *ms; + + if (!launchd_assumes(j != NULL)) { + return BOOTSTRAP_NO_MEMORY; + } + + job_log(j, LOG_DEBUG, "Post fork ping."); + + job_setup_exception_port(j, child_task); + + SLIST_FOREACH(ms, &special_ports, special_port_sle) { + if (j->per_user && (ms->special_port_num != TASK_ACCESS_PORT)) { + /* The TASK_ACCESS_PORT funny business is to workaround 5325399. */ + continue; + } + + errno = task_set_special_port(child_task, ms->special_port_num, ms->port); + + if (errno) { + int desired_log_level = LOG_ERR; + + if (j->anonymous) { + /* 5338127 */ + + desired_log_level = LOG_WARNING; + + if (ms->special_port_num == TASK_SEATBELT_PORT) { + desired_log_level = LOG_DEBUG; + } + } + + job_log(j, desired_log_level, "Could not setup Mach task special port %u: %s", ms->special_port_num, mach_error_string(errno)); + } + } + + job_assumes(j, launchd_mport_deallocate(child_task) == KERN_SUCCESS); + + return 0; +} + +kern_return_t +job_mig_reboot2(job_t j, uint64_t flags) +{ + char who_started_the_reboot[2048] = ""; + struct kinfo_proc kp; + struct ldcred ldc; + pid_t pid_to_log; + + if (!launchd_assumes(j != NULL)) { + return BOOTSTRAP_NO_MEMORY; + } + + if (getpid() != 1) { + return BOOTSTRAP_NOT_PRIVILEGED; + } + + runtime_get_caller_creds(&ldc); + + if (ldc.euid) { + return BOOTSTRAP_NOT_PRIVILEGED; + } + + for (pid_to_log = ldc.pid; pid_to_log; pid_to_log = kp.kp_eproc.e_ppid) { + int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid_to_log }; + size_t who_offset, len = sizeof(kp); + + if (!job_assumes(j, sysctl(mib, 4, &kp, &len, NULL, 0) != -1)) { + return 1; + } + + who_offset = strlen(who_started_the_reboot); + snprintf(who_started_the_reboot + who_offset, sizeof(who_started_the_reboot) - who_offset, + " %s[%u]%s", kp.kp_proc.p_comm, pid_to_log, kp.kp_eproc.e_ppid ? " ->" : ""); + } + + root_jobmgr->reboot_flags = (int)flags; + + launchd_shutdown(); + + job_log(j, LOG_DEBUG, "reboot2() initiated by:%s", who_started_the_reboot); + + return 0; +} + +kern_return_t +job_mig_getsocket(job_t j, name_t spr) +{ + if (!launchd_assumes(j != NULL)) { + return BOOTSTRAP_NO_MEMORY; + } + + ipc_server_init(); + + if (!sockpath) { + return BOOTSTRAP_NO_MEMORY; + } + + strncpy(spr, sockpath, sizeof(name_t)); + + return BOOTSTRAP_SUCCESS; +} + +kern_return_t +job_mig_log(job_t j, int pri, int err, logmsg_t msg) +{ + if (!launchd_assumes(j != NULL)) { + return BOOTSTRAP_NO_MEMORY; + } + + if ((errno = err)) { + job_log_error(j, pri, "%s", msg); + } else { + job_log(j, pri, "%s", msg); + } + + return 0; +} + +void +ensure_root_bkgd_setup(void) +{ + if (background_jobmgr || getpid() != 1) { + return; + } + + if (!jobmgr_assumes(root_jobmgr, (background_jobmgr = jobmgr_new(root_jobmgr, mach_task_self(), MACH_PORT_NULL, false, VPROCMGR_SESSION_BACKGROUND)) != NULL)) { + return; + } + + background_jobmgr->req_port = 0; + jobmgr_assumes(root_jobmgr, launchd_mport_make_send(background_jobmgr->jm_port) == KERN_SUCCESS); +} + +kern_return_t +job_mig_lookup_per_user_context(job_t j, uid_t which_user, mach_port_t *up_cont) +{ + struct ldcred ldc; + job_t ji; + + if (!launchd_assumes(j != NULL)) { + return BOOTSTRAP_NO_MEMORY; + } + + job_log(j, LOG_DEBUG, "Looking up per user launchd for UID: %u", which_user); + + runtime_get_caller_creds(&ldc); + + if (getpid() != 1) { + job_log(j, LOG_ERR, "Only PID 1 supports per user launchd lookups."); + return BOOTSTRAP_NOT_PRIVILEGED; + } + + if (ldc.euid || ldc.uid) { + which_user = ldc.euid ? ldc.euid : ldc.uid; + } + + *up_cont = MACH_PORT_NULL; + + if (which_user == 0) { + ensure_root_bkgd_setup(); + + *up_cont = background_jobmgr->jm_port; + + return 0; + } + + LIST_FOREACH(ji, &root_jobmgr->jobs, sle) { + if (!ji->per_user) { + continue; + } + if (ji->mach_uid != which_user) { + continue; + } + if (SLIST_EMPTY(&ji->machservices)) { + continue; + } + if (!SLIST_FIRST(&ji->machservices)->per_user_hack) { + continue; + } + break; + } + + if (ji == NULL) { + struct machservice *ms; + char lbuf[1024]; + + job_log(j, LOG_DEBUG, "Creating per user launchd job for UID: %u", which_user); + + sprintf(lbuf, "com.apple.launchd.peruser.%u", which_user); + + ji = job_new(root_jobmgr, lbuf, "/sbin/launchd", NULL); + + if (ji == NULL) { + return BOOTSTRAP_NO_MEMORY; + } + + ji->mach_uid = which_user; + ji->per_user = true; + + if ((ms = machservice_new(ji, lbuf, up_cont, false)) == NULL) { + job_remove(ji); + return BOOTSTRAP_NO_MEMORY; + } + + ms->per_user_hack = true; + ms->hide = true; + + ji = job_dispatch(ji, false); + } else { + job_log(j, LOG_DEBUG, "Per user launchd job found for UID: %u", which_user); + } + + if (job_assumes(j, ji != NULL)) { + *up_cont = machservice_port(SLIST_FIRST(&ji->machservices)); + } + + return 0; +} + +kern_return_t +job_mig_check_in(job_t j, name_t servicename, mach_port_t *serviceportp) +{ + static pid_t last_warned_pid = 0; + struct machservice *ms; + struct ldcred ldc; + + if (!launchd_assumes(j != NULL)) { + return BOOTSTRAP_NO_MEMORY; + } + + runtime_get_caller_creds(&ldc); + + ms = jobmgr_lookup_service(j->mgr, servicename, true, 0); + + if (ms == NULL) { + job_log(j, LOG_DEBUG, "Check-in of Mach service failed. Unknown: %s", servicename); + return BOOTSTRAP_UNKNOWN_SERVICE; + } + if (machservice_job(ms) != j) { + if (last_warned_pid != ldc.pid) { + job_log(j, LOG_NOTICE, "Check-in of Mach service failed. PID %d is not privileged: %s", + ldc.pid, servicename); + last_warned_pid = ldc.pid; + } + return BOOTSTRAP_NOT_PRIVILEGED; + } + if (machservice_active(ms)) { + job_log(j, LOG_WARNING, "Check-in of Mach service failed. Already active: %s", servicename); + return BOOTSTRAP_SERVICE_ACTIVE; + } + + machservice_request_notifications(ms); + + job_log(j, LOG_INFO, "Check-in of service: %s", servicename); + + *serviceportp = machservice_port(ms); + return BOOTSTRAP_SUCCESS; +} + +kern_return_t +job_mig_register2(job_t j, name_t servicename, mach_port_t serviceport, uint64_t flags) +{ + struct machservice *ms; + struct ldcred ldc; + + if (!launchd_assumes(j != NULL)) { + return BOOTSTRAP_NO_MEMORY; + } + + runtime_get_caller_creds(&ldc); + +#if 0 + job_log(j, LOG_APPLEONLY, "bootstrap_register() is deprecated. Service: %s", servicename); +#endif + + job_log(j, LOG_DEBUG, "%sMach service registration attempt: %s", flags & BOOTSTRAP_PER_PID_SERVICE ? "Per PID " : "", servicename); + + /* + * From a per-user/session launchd's perspective, SecurityAgent (UID + * 92) is a rogue application (not our UID, not root and not a child of + * us). We'll have to reconcile this design friction at a later date. + */ + if (j->anonymous && job_get_bs(j)->parentmgr == NULL && ldc.uid != 0 && ldc.uid != getuid() && ldc.uid != 92) { + if (getpid() == 1) { + return VPROC_ERR_TRY_PER_USER; + } else { + return BOOTSTRAP_NOT_PRIVILEGED; + } + } + + ms = jobmgr_lookup_service(j->mgr, servicename, false, flags & BOOTSTRAP_PER_PID_SERVICE ? ldc.pid : 0); + + if (ms) { + if (machservice_job(ms) != j) { + return BOOTSTRAP_NOT_PRIVILEGED; + } + if (machservice_active(ms)) { + job_log(j, LOG_DEBUG, "Mach service registration failed. Already active: %s", servicename); + return BOOTSTRAP_SERVICE_ACTIVE; + } + job_checkin(j); + machservice_delete(j, ms, false); + } + + if (serviceport != MACH_PORT_NULL) { + if ((ms = machservice_new(j, servicename, &serviceport, flags & BOOTSTRAP_PER_PID_SERVICE ? true : false))) { + machservice_request_notifications(ms); + } else { + return BOOTSTRAP_NO_MEMORY; + } + } + + return BOOTSTRAP_SUCCESS; +} + +kern_return_t +job_mig_look_up2(job_t j, name_t servicename, mach_port_t *serviceportp, mach_msg_type_name_t *ptype, pid_t target_pid, uint64_t flags) +{ + struct machservice *ms; + struct ldcred ldc; + kern_return_t kr; + + if (!launchd_assumes(j != NULL)) { + return BOOTSTRAP_NO_MEMORY; + } + + runtime_get_caller_creds(&ldc); + + if (getpid() == 1 && j->anonymous && job_get_bs(j)->parentmgr == NULL && ldc.uid != 0 && ldc.euid != 0) { + return VPROC_ERR_TRY_PER_USER; + } + + if (!mspolicy_check(j, servicename, flags & BOOTSTRAP_PER_PID_SERVICE)) { + job_log(j, LOG_NOTICE, "Policy denied Mach service lookup: %s", servicename); + return BOOTSTRAP_NOT_PRIVILEGED; + } + + if (flags & BOOTSTRAP_PER_PID_SERVICE) { + ms = jobmgr_lookup_service(j->mgr, servicename, false, target_pid); + } else { + ms = jobmgr_lookup_service(j->mgr, servicename, true, 0); + } + + if (ms && machservice_hidden(ms) && !job_active(machservice_job(ms))) { + ms = NULL; + } else if (ms && ms->per_user_hack) { + ms = NULL; + } + + if (ms) { + launchd_assumes(machservice_port(ms) != MACH_PORT_NULL); + job_log(j, LOG_DEBUG, "%sMach service lookup: %s", flags & BOOTSTRAP_PER_PID_SERVICE ? "Per PID " : "", servicename); +#if 0 + /* After Leopard ships, we should enable this */ + if (j->lastlookup == ms && j->lastlookup_gennum == ms->gen_num && !j->per_user) { + ms->bad_perf_cnt++; + job_log(j, LOG_APPLEONLY, "Performance opportunity: Number of bootstrap_lookup(... \"%s\" ...) calls that should have been cached: %llu", + servicename, ms->bad_perf_cnt); + } + j->lastlookup = ms; + j->lastlookup_gennum = ms->gen_num; +#endif + *serviceportp = machservice_port(ms); + *ptype = MACH_MSG_TYPE_COPY_SEND; + kr = BOOTSTRAP_SUCCESS; + } else if (!(flags & BOOTSTRAP_PER_PID_SERVICE) && (inherited_bootstrap_port != MACH_PORT_NULL)) { + job_log(j, LOG_DEBUG, "Mach service lookup forwarded: %s", servicename); + *ptype = MACH_MSG_TYPE_MOVE_SEND; + kr = bootstrap_look_up(inherited_bootstrap_port, servicename, serviceportp); + } else if (getpid() == 1 && j->anonymous && ldc.euid >= 500 && strcasecmp(job_get_bs(j)->name, VPROCMGR_SESSION_LOGINWINDOW) == 0) { + /* + * 5240036 Should start background session when a lookup of CCacheServer occurs + * + * This is a total hack. We sniff out loginwindow session, and attempt to guess what it is up to. + * If we find a EUID that isn't root, we force it over to the per-user context. + */ + return VPROC_ERR_TRY_PER_USER; + } else { + job_log(j, LOG_DEBUG, "%sMach service lookup failed: %s", flags & BOOTSTRAP_PER_PID_SERVICE ? "Per PID " : "", servicename); + kr = BOOTSTRAP_UNKNOWN_SERVICE; + } + + return kr; +} + +kern_return_t +job_mig_parent(job_t j, mach_port_t *parentport, mach_msg_type_name_t *pptype) +{ + if (!launchd_assumes(j != NULL)) { + return BOOTSTRAP_NO_MEMORY; + } + + job_log(j, LOG_DEBUG, "Requested parent bootstrap port"); + jobmgr_t jm = j->mgr; + + *pptype = MACH_MSG_TYPE_MAKE_SEND; + + if (jobmgr_parent(jm)) { + *parentport = jobmgr_parent(jm)->jm_port; + } else if (MACH_PORT_NULL == inherited_bootstrap_port) { + *parentport = jm->jm_port; + } else { + *pptype = MACH_MSG_TYPE_COPY_SEND; + *parentport = inherited_bootstrap_port; + } + return BOOTSTRAP_SUCCESS; +} + +kern_return_t +job_mig_info(job_t j, name_array_t *servicenamesp, unsigned int *servicenames_cnt, + bootstrap_status_array_t *serviceactivesp, unsigned int *serviceactives_cnt) +{ + name_array_t service_names = NULL; + bootstrap_status_array_t service_actives = NULL; + unsigned int cnt = 0, cnt2 = 0; + struct machservice *ms; + jobmgr_t jm; + job_t ji; + + if (!launchd_assumes(j != NULL)) { + return BOOTSTRAP_NO_MEMORY; + } + + jm = j->mgr; + + LIST_FOREACH(ji, &jm->jobs, sle) { + SLIST_FOREACH(ms, &ji->machservices, sle) { + if (!ms->per_pid) { + cnt++; + } + } + } + + if (cnt == 0) { + goto out; + } + + mig_allocate((vm_address_t *)&service_names, cnt * sizeof(service_names[0])); + if (!launchd_assumes(service_names != NULL)) { + goto out_bad; + } + + mig_allocate((vm_address_t *)&service_actives, cnt * sizeof(service_actives[0])); + if (!launchd_assumes(service_actives != NULL)) { + goto out_bad; + } + + LIST_FOREACH(ji, &jm->jobs, sle) { + SLIST_FOREACH(ms, &ji->machservices, sle) { + if (!ms->per_pid) { + strlcpy(service_names[cnt2], machservice_name(ms), sizeof(service_names[0])); + service_actives[cnt2] = machservice_status(ms); + cnt2++; + } + } + } + + launchd_assumes(cnt == cnt2); + +out: + *servicenamesp = service_names; + *serviceactivesp = service_actives; + *servicenames_cnt = *serviceactives_cnt = cnt; + + return BOOTSTRAP_SUCCESS; + +out_bad: + if (service_names) { + mig_deallocate((vm_address_t)service_names, cnt * sizeof(service_names[0])); + } + if (service_actives) { + mig_deallocate((vm_address_t)service_actives, cnt * sizeof(service_actives[0])); + } + + return BOOTSTRAP_NO_MEMORY; +} + +void +job_reparent_hack(job_t j, const char *where) +{ + jobmgr_t jmi, jmi2; + + ensure_root_bkgd_setup(); + + /* NULL is only passed for our custom API for LaunchServices. If that is the case, we do magic. */ + if (where == NULL) { + if (strcasecmp(j->mgr->name, VPROCMGR_SESSION_LOGINWINDOW) == 0) { + where = VPROCMGR_SESSION_LOGINWINDOW; + } else { + where = VPROCMGR_SESSION_AQUA; + } + } + + if (strcasecmp(j->mgr->name, where) == 0) { + return; + } + + SLIST_FOREACH(jmi, &root_jobmgr->submgrs, sle) { + if (jmi->shutting_down) { + continue; + } else if (strcasecmp(jmi->name, where) == 0) { + goto jm_found; + } else if (strcasecmp(jmi->name, VPROCMGR_SESSION_BACKGROUND) == 0 && getpid() == 1) { + SLIST_FOREACH(jmi2, &jmi->submgrs, sle) { + if (strcasecmp(jmi2->name, where) == 0) { + jmi = jmi2; + goto jm_found; + } + } + } + } + +jm_found: + if (job_assumes(j, jmi != NULL)) { + struct machservice *msi; + + SLIST_FOREACH(msi, &j->machservices, sle) { + LIST_REMOVE(msi, name_hash_sle); + } + + LIST_REMOVE(j, sle); + LIST_INSERT_HEAD(&jmi->jobs, j, sle); + j->mgr = jmi; + + SLIST_FOREACH(msi, &j->machservices, sle) { + LIST_INSERT_HEAD(&j->mgr->ms_hash[hash_ms(msi->name)], msi, name_hash_sle); + } + } +} + +kern_return_t +job_mig_move_subset(job_t j, mach_port_t target_subset, name_t session_type) +{ + mach_msg_type_number_t l2l_i, l2l_port_cnt = 0; + mach_port_array_t l2l_ports = NULL; + mach_port_t reqport, rcvright; + kern_return_t kr = 1; + launch_data_t out_obj_array = NULL; + struct ldcred ldc; + jobmgr_t jmr = NULL; + + if (!launchd_assumes(j != NULL)) { + return BOOTSTRAP_NO_MEMORY; + } + + runtime_get_caller_creds(&ldc); + + if (target_subset == MACH_PORT_NULL) { + job_t j2; + + if (j->mgr->session_initialized) { + if (ldc.uid == 0 && getpid() == 1) { + if (strcmp(j->mgr->name, VPROCMGR_SESSION_LOGINWINDOW) == 0) { + job_t ji, jn; + + LIST_FOREACH_SAFE(ji, &j->mgr->jobs, sle, jn) { + if (!ji->anonymous) { + job_remove(ji); + } + } + + ensure_root_bkgd_setup(); + + SLIST_REMOVE(&j->mgr->parentmgr->submgrs, j->mgr, jobmgr_s, sle); + j->mgr->parentmgr = background_jobmgr; + SLIST_INSERT_HEAD(&j->mgr->parentmgr->submgrs, j->mgr, sle); + + /* + * We really should wait for all the jobs to die before proceeding. See 5351245 for more info. + * + * We have hacked around this in job_find() by ignoring jobs that are pending removal. + */ + + } else if (strcmp(j->mgr->name, VPROCMGR_SESSION_AQUA) == 0) { + job_log(j, LOG_DEBUG, "Tried to move the Aqua session."); + return 0; + } else if (strcmp(j->mgr->name, VPROCMGR_SESSION_BACKGROUND) == 0) { + job_log(j, LOG_DEBUG, "Tried to move the background session."); + return 0; + } else { + job_log(j, LOG_ERR, "Tried to initialize an already setup session!"); + kr = BOOTSTRAP_NOT_PRIVILEGED; + goto out; + } + } else { + job_log(j, LOG_ERR, "Tried to initialize an already setup session!"); + kr = BOOTSTRAP_NOT_PRIVILEGED; + goto out; + } + } else if (ldc.uid == 0 && getpid() == 1 && strcmp(session_type, VPROCMGR_SESSION_STANDARDIO) == 0) { + ensure_root_bkgd_setup(); + + SLIST_REMOVE(&j->mgr->parentmgr->submgrs, j->mgr, jobmgr_s, sle); + j->mgr->parentmgr = background_jobmgr; + SLIST_INSERT_HEAD(&j->mgr->parentmgr->submgrs, j->mgr, sle); + } else if (strcmp(session_type, VPROCMGR_SESSION_LOGINWINDOW) == 0) { + jobmgr_t jmi; + + /* + * 5330262 + * + * We're working around LoginWindow and the WindowServer. + * + * In practice, there is only one LoginWindow session. Unfortunately, for certain + * scenarios, the WindowServer spawns loginwindow, and in those cases, it frequently + * spawns a replacement loginwindow session before cleaning up the previous one. + * + * We're going to use the creation of a new LoginWindow context as a clue that the + * previous LoginWindow context is on the way out and therefore we should just + * kick-start the shutdown of it. + */ + + SLIST_FOREACH(jmi, &root_jobmgr->submgrs, sle) { + if (jmi->shutting_down) { + continue; + } else if (strcasecmp(jmi->name, session_type) == 0) { + jobmgr_shutdown(jmi); + break; + } + } + } + + jobmgr_log(j->mgr, LOG_DEBUG, "Renaming to: %s", session_type); + strcpy(j->mgr->name, session_type); + + if (job_assumes(j, (j2 = jobmgr_init_session(j->mgr, session_type, false)))) { + job_assumes(j, job_dispatch(j2, true)); + } + + kr = 0; + goto out; + } else if (job_mig_intran2(root_jobmgr, target_subset, ldc.pid)) { + job_log(j, LOG_ERR, "Moving a session to ourself is bogus."); + + kr = BOOTSTRAP_NOT_PRIVILEGED; + goto out; + } + + job_log(j, LOG_DEBUG, "Move subset attempt: 0x%x", target_subset); + + kr = _vproc_grab_subset(target_subset, &reqport, &rcvright, &out_obj_array, &l2l_ports, &l2l_port_cnt); + + if (!job_assumes(j, kr == 0)) { + goto out; + } + + launchd_assert(launch_data_array_get_count(out_obj_array) == l2l_port_cnt); + + if (!job_assumes(j, (jmr = jobmgr_new(j->mgr, reqport, rcvright, false, session_type)) != NULL)) { + kr = BOOTSTRAP_NO_MEMORY; + goto out; + } + + for (l2l_i = 0; l2l_i < l2l_port_cnt; l2l_i++) { + launch_data_t tmp, obj_at_idx; + struct machservice *ms; + job_t j_for_service; + const char *serv_name; + pid_t target_pid; + bool serv_perpid; + + job_assumes(j, obj_at_idx = launch_data_array_get_index(out_obj_array, l2l_i)); + job_assumes(j, tmp = launch_data_dict_lookup(obj_at_idx, TAKE_SUBSET_PID)); + target_pid = (pid_t)launch_data_get_integer(tmp); + job_assumes(j, tmp = launch_data_dict_lookup(obj_at_idx, TAKE_SUBSET_PERPID)); + serv_perpid = launch_data_get_bool(tmp); + job_assumes(j, tmp = launch_data_dict_lookup(obj_at_idx, TAKE_SUBSET_NAME)); + serv_name = launch_data_get_string(tmp); + + j_for_service = jobmgr_find_by_pid(jmr, target_pid, true); + + if (!j_for_service) { + /* The PID probably exited */ + job_assumes(j, launchd_mport_deallocate(l2l_ports[l2l_i]) == KERN_SUCCESS); + continue; + } + + if ((ms = machservice_new(j_for_service, serv_name, &l2l_ports[l2l_i], serv_perpid))) { + machservice_request_notifications(ms); + } + } + + kr = 0; + +out: + if (out_obj_array) { + launch_data_free(out_obj_array); + } + + if (l2l_ports) { + mig_deallocate((vm_address_t)l2l_ports, l2l_port_cnt * sizeof(l2l_ports[0])); + } + + if (kr == 0) { + if (target_subset) { + job_assumes(j, launchd_mport_deallocate(target_subset) == KERN_SUCCESS); + } + } else if (jmr) { + jobmgr_shutdown(jmr); + } + + return kr; +} + +kern_return_t +job_mig_take_subset(job_t j, mach_port_t *reqport, mach_port_t *rcvright, + vm_offset_t *outdata, mach_msg_type_number_t *outdataCnt, + mach_port_array_t *portsp, unsigned int *ports_cnt) +{ + launch_data_t tmp_obj, tmp_dict, outdata_obj_array = NULL; + mach_port_array_t ports = NULL; + unsigned int cnt = 0, cnt2 = 0; + size_t packed_size; + struct machservice *ms; + jobmgr_t jm; + job_t ji; + + if (!launchd_assumes(j != NULL)) { + return BOOTSTRAP_NO_MEMORY; + } + + jm = j->mgr; + + if (getpid() != 1) { + job_log(j, LOG_ERR, "Only the system launchd will transfer Mach sub-bootstraps."); + return BOOTSTRAP_NOT_PRIVILEGED; + } else if (jobmgr_parent(jm) == NULL) { + job_log(j, LOG_ERR, "Root Mach bootstrap cannot be transferred."); + return BOOTSTRAP_NOT_PRIVILEGED; + } else if (strcasecmp(jm->name, VPROCMGR_SESSION_AQUA) == 0) { + job_log(j, LOG_ERR, "Cannot transfer a setup GUI session."); + return BOOTSTRAP_NOT_PRIVILEGED; + } else if (!j->anonymous) { + job_log(j, LOG_ERR, "Only the anonymous job can transfer Mach sub-bootstraps."); + return BOOTSTRAP_NOT_PRIVILEGED; + } + + job_log(j, LOG_DEBUG, "Transferring sub-bootstrap to the per session launchd."); + + outdata_obj_array = launch_data_alloc(LAUNCH_DATA_ARRAY); + if (!job_assumes(j, outdata_obj_array)) { + goto out_bad; + } + + *outdataCnt = 20 * 1024 * 1024; + mig_allocate(outdata, *outdataCnt); + if (!job_assumes(j, *outdata != 0)) { + return 1; + } + + LIST_FOREACH(ji, &j->mgr->jobs, sle) { + if (!ji->anonymous) { + continue; + } + SLIST_FOREACH(ms, &ji->machservices, sle) { + cnt++; + } + } + + mig_allocate((vm_address_t *)&ports, cnt * sizeof(ports[0])); + if (!launchd_assumes(ports != NULL)) { + goto out_bad; + } + + LIST_FOREACH(ji, &j->mgr->jobs, sle) { + if (!ji->anonymous) { + continue; + } + + SLIST_FOREACH(ms, &ji->machservices, sle) { + if (job_assumes(j, (tmp_dict = launch_data_alloc(LAUNCH_DATA_DICTIONARY)))) { + job_assumes(j, launch_data_array_set_index(outdata_obj_array, tmp_dict, cnt2)); + } else { + goto out_bad; + } + + if (job_assumes(j, (tmp_obj = launch_data_new_string(machservice_name(ms))))) { + job_assumes(j, launch_data_dict_insert(tmp_dict, tmp_obj, TAKE_SUBSET_NAME)); + } else { + goto out_bad; + } + + if (job_assumes(j, (tmp_obj = launch_data_new_integer((ms->job->p))))) { + job_assumes(j, launch_data_dict_insert(tmp_dict, tmp_obj, TAKE_SUBSET_PID)); + } else { + goto out_bad; + } + + if (job_assumes(j, (tmp_obj = launch_data_new_bool((ms->per_pid))))) { + job_assumes(j, launch_data_dict_insert(tmp_dict, tmp_obj, TAKE_SUBSET_PERPID)); + } else { + goto out_bad; + } + + ports[cnt2] = machservice_port(ms); + + /* Increment the send right by one so we can shutdown the jobmgr cleanly */ + jobmgr_assumes(jm, (errno = mach_port_mod_refs(mach_task_self(), ports[cnt2], MACH_PORT_RIGHT_SEND, 1)) == 0); + cnt2++; + } + } + + launchd_assumes(cnt == cnt2); + + packed_size = launch_data_pack(outdata_obj_array, (void *)*outdata, *outdataCnt, NULL, NULL); + if (!job_assumes(j, packed_size != 0)) { + goto out_bad; + } + + launch_data_free(outdata_obj_array); + + *portsp = ports; + *ports_cnt = cnt; + + *reqport = jm->req_port; + *rcvright = jm->jm_port; + + jm->req_port = 0; + jm->jm_port = 0; + + workaround_5477111 = j; + + jobmgr_shutdown(jm); + + return BOOTSTRAP_SUCCESS; + +out_bad: + if (outdata_obj_array) { + launch_data_free(outdata_obj_array); + } + if (*outdata) { + mig_deallocate(*outdata, *outdataCnt); + } + if (ports) { + mig_deallocate((vm_address_t)ports, cnt * sizeof(ports[0])); + } + + return BOOTSTRAP_NO_MEMORY; +} + +kern_return_t +job_mig_subset(job_t j, mach_port_t requestorport, mach_port_t *subsetportp) +{ + int bsdepth = 0; + jobmgr_t jmr; + + if (!launchd_assumes(j != NULL)) { + return BOOTSTRAP_NO_MEMORY; + } + + jmr = j->mgr; + + while ((jmr = jobmgr_parent(jmr)) != NULL) { + bsdepth++; + } + + /* Since we use recursion, we need an artificial depth for subsets */ + if (bsdepth > 100) { + job_log(j, LOG_ERR, "Mach sub-bootstrap create request failed. Depth greater than: %d", bsdepth); + return BOOTSTRAP_NO_MEMORY; + } + + if ((jmr = jobmgr_new(j->mgr, requestorport, MACH_PORT_NULL, false, NULL)) == NULL) { + if (requestorport == MACH_PORT_NULL) { + return BOOTSTRAP_NOT_PRIVILEGED; + } + return BOOTSTRAP_NO_MEMORY; + } + + *subsetportp = jmr->jm_port; + return BOOTSTRAP_SUCCESS; +} + +kern_return_t +job_mig_create_service(job_t j, name_t servicename, mach_port_t *serviceportp) +{ + struct machservice *ms; + + if (!launchd_assumes(j != NULL)) { + return BOOTSTRAP_NO_MEMORY; + } + + if (job_prog(j)[0] == '\0') { + job_log(j, LOG_ERR, "Mach service creation requires a target server: %s", servicename); + return BOOTSTRAP_NOT_PRIVILEGED; + } + + if (!j->legacy_mach_job) { + job_log(j, LOG_ERR, "bootstrap_create_service() is only allowed against legacy Mach jobs: %s", servicename); + return BOOTSTRAP_NOT_PRIVILEGED; + } + + ms = jobmgr_lookup_service(j->mgr, servicename, false, 0); + if (ms) { + job_log(j, LOG_DEBUG, "Mach service creation attempt for failed. Already exists: %s", servicename); + return BOOTSTRAP_NAME_IN_USE; + } + + job_checkin(j); + + *serviceportp = MACH_PORT_NULL; + ms = machservice_new(j, servicename, serviceportp, false); + + if (!launchd_assumes(ms != NULL)) { + goto out_bad; + } + + return BOOTSTRAP_SUCCESS; + +out_bad: + launchd_assumes(launchd_mport_close_recv(*serviceportp) == KERN_SUCCESS); + return BOOTSTRAP_NO_MEMORY; +} + +kern_return_t +job_mig_wait(job_t j, mach_port_t srp, integer_t *waitstatus) +{ + if (!launchd_assumes(j != NULL)) { + return BOOTSTRAP_NO_MEMORY; + } +#if 0 + struct ldcred ldc; + runtime_get_caller_creds(&ldc); +#endif + return job_handle_mpm_wait(j, srp, waitstatus); +} + +kern_return_t +job_mig_uncork_fork(job_t j) +{ + if (!launchd_assumes(j != NULL)) { + return BOOTSTRAP_NO_MEMORY; + } + + if (!j->stall_before_exec) { + job_log(j, LOG_WARNING, "Attempt to uncork a job that isn't in the middle of a fork()."); + return 1; + } + + job_uncork_fork(j); + j->stall_before_exec = false; + return 0; +} + +kern_return_t +job_mig_set_service_policy(job_t j, pid_t target_pid, uint64_t flags, name_t target_service) +{ + job_t target_j; + + if (!launchd_assumes(j != NULL)) { + return BOOTSTRAP_NO_MEMORY; + } + + if (!job_assumes(j, (target_j = jobmgr_find_by_pid(j->mgr, target_pid, true)) != NULL)) { + return BOOTSTRAP_NO_MEMORY; + } + + if (SLIST_EMPTY(&j->mspolicies)) { + job_log(j, LOG_DEBUG, "Setting policy on job \"%s\" for Mach service: %s", target_j->label, target_service); + if (target_service[0]) { + job_assumes(j, mspolicy_new(target_j, target_service, flags & BOOTSTRAP_ALLOW_LOOKUP, flags & BOOTSTRAP_PER_PID_SERVICE, false)); + } else { + target_j->deny_unknown_mslookups = !(flags & BOOTSTRAP_ALLOW_LOOKUP); + } + } else { + job_log(j, LOG_WARNING, "Jobs that have policies assigned to them may not set policies."); + return BOOTSTRAP_NOT_PRIVILEGED; + } + + return 0; +} + +kern_return_t +job_mig_spawn(job_t j, vm_offset_t indata, mach_msg_type_number_t indataCnt, pid_t *child_pid, mach_port_t *obsvr_port) +{ + launch_data_t input_obj = NULL; + size_t data_offset = 0; + struct ldcred ldc; + job_t jr; + + runtime_get_caller_creds(&ldc); + + if (!launchd_assumes(j != NULL)) { + return BOOTSTRAP_NO_MEMORY; + } + + if (getpid() == 1 && ldc.euid && ldc.uid) { + job_log(j, LOG_DEBUG, "Punting spawn to per-user-context"); + return VPROC_ERR_TRY_PER_USER; + } + + if (!job_assumes(j, indataCnt != 0)) { + return 1; + } + + if (!job_assumes(j, (input_obj = launch_data_unpack((void *)indata, indataCnt, NULL, 0, &data_offset, NULL)) != NULL)) { + return 1; + } + + jr = jobmgr_import2(j->mgr, input_obj); + + if (!job_assumes(j, jr != NULL)) { + switch (errno) { + case EEXIST: + return BOOTSTRAP_NAME_IN_USE; + default: + return BOOTSTRAP_NO_MEMORY; + } + } + + job_reparent_hack(jr, NULL); + + if (getpid() == 1) { + jr->mach_uid = ldc.uid; + } + + jr->unload_at_exit = true; + jr->wait4pipe_eof = true; + jr->abandon_pg = true; + jr->stall_before_exec = jr->wait4debugger; + jr->wait4debugger = false; + + jr = job_dispatch(jr, true); + + if (!job_assumes(j, jr != NULL)) { + return BOOTSTRAP_NO_MEMORY; + } + + job_assumes(jr, jr->p); + + if (!job_setup_machport(jr)) { + job_remove(jr); + return BOOTSTRAP_NO_MEMORY; + } + + job_log(j, LOG_INFO, "Spawned"); + + *child_pid = jr->p; + *obsvr_port = jr->j_port; + + mig_deallocate(indata, indataCnt); + + return BOOTSTRAP_SUCCESS; +} + +void +jobmgr_init(bool sflag) +{ + const char *root_session_type = getpid() == 1 ? VPROCMGR_SESSION_SYSTEM : VPROCMGR_SESSION_BACKGROUND; + + launchd_assert((root_jobmgr = jobmgr_new(NULL, MACH_PORT_NULL, MACH_PORT_NULL, sflag, root_session_type)) != NULL); +} + +size_t +our_strhash(const char *s) +{ + size_t c, r = 5381; + + /* djb2 + * This algorithm was first reported by Dan Bernstein many years ago in comp.lang.c + */ + + while ((c = *s++)) { + r = ((r << 5) + r) + c; /* hash*33 + c */ + } + + return r; +} + +size_t +hash_label(const char *label) +{ + return our_strhash(label) % LABEL_HASH_SIZE; +} + +size_t +hash_ms(const char *msstr) +{ + return our_strhash(msstr) % MACHSERVICE_HASH_SIZE; +} + +bool +mspolicy_copy(job_t j_to, job_t j_from) +{ + struct mspolicy *msp; + + SLIST_FOREACH(msp, &j_from->mspolicies, sle) { + if (!mspolicy_new(j_to, msp->name, msp->allow, msp->per_pid, true)) { + return false; + } + } + + return true; +} + +bool +mspolicy_new(job_t j, const char *name, bool allow, bool pid_local, bool skip_check) +{ + struct mspolicy *msp; + + if (!skip_check) SLIST_FOREACH(msp, &j->mspolicies, sle) { + if (msp->per_pid != pid_local) { + continue; + } else if (strcmp(msp->name, name) == 0) { + return false; + } + } + + if ((msp = calloc(1, sizeof(struct mspolicy) + strlen(name) + 1)) == NULL) { + return false; + } + + strcpy((char *)msp->name, name); + msp->per_pid = pid_local; + msp->allow = allow; + + SLIST_INSERT_HEAD(&j->mspolicies, msp, sle); + + return true; +} + +void +mspolicy_setup(launch_data_t obj, const char *key, void *context) +{ + job_t j = context; + + if (launch_data_get_type(obj) != LAUNCH_DATA_BOOL) { + job_log(j, LOG_WARNING, "Invalid object type for Mach service policy key: %s", key); + return; + } + + job_assumes(j, mspolicy_new(j, key, launch_data_get_bool(obj), false, false)); +} + +bool +mspolicy_check(job_t j, const char *name, bool pid_local) +{ + struct mspolicy *mspi; + + SLIST_FOREACH(mspi, &j->mspolicies, sle) { + if (mspi->per_pid != pid_local) { + continue; + } else if (strcmp(mspi->name, name) != 0) { + continue; + } + return mspi->allow; + } + + return !j->deny_unknown_mslookups; +} + +void +mspolicy_delete(job_t j, struct mspolicy *msp) +{ + SLIST_REMOVE(&j->mspolicies, msp, mspolicy, sle); + + free(msp); +} + +bool +waiting4removal_new(job_t j, mach_port_t rp) +{ + struct waiting_for_removal *w4r; + + if (!job_assumes(j, (w4r = malloc(sizeof(struct waiting_for_removal))) != NULL)) { + return false; + } + + w4r->reply_port = rp; + + SLIST_INSERT_HEAD(&j->removal_watchers, w4r, sle); + + return true; +} + +void +waiting4removal_delete(job_t j, struct waiting_for_removal *w4r) +{ + job_assumes(j, job_mig_send_signal_reply(w4r->reply_port, 0) == 0); + + SLIST_REMOVE(&j->removal_watchers, w4r, waiting_for_removal, sle); + + free(w4r); +} + +void +do_file_init(void) +{ + launchd_assert(mach_timebase_info(&tbi) == 0); + +} diff --git a/launchd/src/launchd_core_logic.h b/launchd/src/launchd_core_logic.h index 1ef2011..ce0dc15 100644 --- a/launchd/src/launchd_core_logic.h +++ b/launchd/src/launchd_core_logic.h @@ -20,66 +20,36 @@ * @APPLE_APACHE_LICENSE_HEADER_END@ */ -#define LAUNCHD_MIN_JOB_RUN_TIME 10 -#define LAUNCHD_REWARD_JOB_RUN_TIME 60 -#define LAUNCHD_FAILED_EXITS_THRESHOLD 10 +#include "libbootstrap_public.h" +#include "liblaunch_public.h" -#include "bootstrap_public.h" +typedef struct job_s *job_t; +typedef struct jobmgr_s *jobmgr_t; -struct jobcb; -struct machservice; +extern jobmgr_t root_jobmgr; +extern mach_port_t inherited_bootstrap_port; +void jobmgr_init(bool); +jobmgr_t jobmgr_shutdown(jobmgr_t jm); +void jobmgr_dispatch_all_semaphores(jobmgr_t jm); +jobmgr_t jobmgr_delete_anything_with_port(jobmgr_t jm, mach_port_t port); -struct machservice *machservice_new(struct jobcb *j, const char *name, mach_port_t *serviceport); -void machservice_delete(struct machservice *); -void machservice_watch(struct machservice *); -mach_port_t machservice_port(struct machservice *); -struct jobcb *machservice_job(struct machservice *); -bool machservice_hidden(struct machservice *); -bool machservice_active(struct machservice *); -const char *machservice_name(struct machservice *); -bootstrap_status_t machservice_status(struct machservice *); - - -struct jobcb *job_find(struct jobcb *j, const char *label); -struct jobcb *job_find_by_pid(struct jobcb *j, pid_t p); -struct jobcb *job_find_by_port(mach_port_t mp); -struct jobcb *job_import(launch_data_t pload); -launch_data_t job_import_bulk(launch_data_t pload); -struct jobcb *job_new(struct jobcb *p, const char *label, const char *prog, const char *const *argv, const char *stdinpath, mach_port_t); -struct jobcb *job_new_spawn(const char *label, const char *path, const char *workingdir, const char *const *argv, const char *const *env, mode_t *u_mask, bool w4d, bool fppc); -struct jobcb *job_new_via_mach_init(struct jobcb *jbs, const char *cmd, uid_t uid, bool ond); -struct jobcb *job_new_bootstrap(struct jobcb *p, mach_port_t requestorport, mach_port_t checkin_port); -launch_data_t job_export(struct jobcb *j); launch_data_t job_export_all(void); -void job_dispatch(struct jobcb *j); -void job_dispatch_all_other_semaphores(struct jobcb *j, struct jobcb *nj); -void job_start(struct jobcb *j); -void job_stop(struct jobcb *j); -bool job_active(struct jobcb *j); -void job_checkin(struct jobcb *j); -const char *job_prog(struct jobcb *j); -void job_remove(struct jobcb *j); -void job_remove_all_inactive(struct jobcb *j); -bool job_ack_port_destruction(struct jobcb *j, mach_port_t p); -void job_ack_no_senders(struct jobcb *j); -pid_t job_get_pid(struct jobcb *j); -mach_port_t job_get_bsport(struct jobcb *j); -mach_port_t job_get_reqport(struct jobcb *j); -struct jobcb *job_get_bs(struct jobcb *j); -void job_delete_anything_with_port(struct jobcb *jbs, mach_port_t port); -struct jobcb *job_parent(struct jobcb *j); -void job_uncork_fork(struct jobcb *j); -struct machservice *job_lookup_service(struct jobcb *jbs, const char *name, bool check_parent); -void job_foreach_service(struct jobcb *jbs, void (*bs_iter)(struct machservice *, void *), void *context, bool include_subjobs); -void job_log(struct jobcb *j, int pri, const char *msg, ...) __attribute__((format(printf, 3, 4))); -void job_log_error(struct jobcb *j, int pri, const char *msg, ...) __attribute__((format(printf, 3, 4))); -kern_return_t job_handle_mpm_wait(struct jobcb *j, mach_port_t srp, int *waitstatus); -extern size_t total_children; - -extern struct jobcb *root_job; - -extern struct jobcb *gc_this_job; +job_t job_dispatch(job_t j, bool kickstart); /* returns j on success, NULL on job removal */ +job_t job_find(const char *label); +job_t job_find_by_service_port(mach_port_t p); +bool job_ack_port_destruction(mach_port_t p); +bool job_is_anonymous(job_t j); +launch_data_t job_export(job_t j); +void job_stop(job_t j); +void job_checkin(job_t j); +void job_remove(job_t j); +job_t job_import(launch_data_t pload); +launch_data_t job_import_bulk(launch_data_t pload); +job_t job_mig_intran(mach_port_t mp); +void job_mig_destructor(job_t j); +void job_ack_no_senders(job_t j); +void job_log(job_t j, int pri, const char *msg, ...) __attribute__((format(printf, 3, 4))); #endif diff --git a/launchd/src/launchd_mach_ipc.c b/launchd/src/launchd_mach_ipc.c deleted file mode 100644 index 91c571b..0000000 --- a/launchd/src/launchd_mach_ipc.c +++ /dev/null @@ -1,916 +0,0 @@ -/* - * Copyright (c) 1999-2004 Apple Computer, Inc. All rights reserved. - * - * @APPLE_APACHE_LICENSE_HEADER_START@ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * @APPLE_APACHE_LICENSE_HEADER_END@ - */ -/* - * bootstrap -- fundamental service initiator and port server - * Mike DeMoney, NeXT, Inc. - * Copyright, 1990. All rights reserved. - * - * bootstrap.c -- implementation of bootstrap main service loop - */ - -static const char *const __rcs_file_version__ = "$Revision: 1.52 $"; - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "bootstrap_public.h" -#include "bootstrap_private.h" -#include "bootstrap.h" -#include "bootstrapServer.h" -#include "notifyServer.h" -#include "launchd_internal.h" -#include "launchd_internalServer.h" -#include "launchd.h" -#include "launchd_core_logic.h" -#include "launch_priv.h" -#include "launchd_unix_ipc.h" - -struct ldcred { - uid_t euid; - uid_t uid; - gid_t egid; - gid_t gid; - pid_t pid; - au_asid_t asid; -}; - -static au_asid_t inherited_asid = 0; - -static bool canReceive(mach_port_t); -static void init_ports(void); -static void *mport_demand_loop(void *arg); -static void audit_token_to_launchd_cred(audit_token_t au_tok, struct ldcred *ldc); - -static mach_port_t inherited_bootstrap_port = MACH_PORT_NULL; -static mach_port_t demand_port_set = MACH_PORT_NULL; -static size_t port_to_obj_size = 0; -static void **port_to_obj = NULL; -static pthread_t demand_thread; - -static bool trusted_client_check(struct jobcb *j, struct ldcred *ldc); - -struct jobcb * -job_find_by_port(mach_port_t mp) -{ - return port_to_obj[MACH_PORT_INDEX(mp)]; -} - -kern_return_t -x_handle_mport(mach_port_t junk __attribute__((unused))) -{ - mach_port_name_array_t members; - mach_msg_type_number_t membersCnt; - mach_port_status_t status; - mach_msg_type_number_t statusCnt; - struct kevent kev; - unsigned int i; - - if (!launchd_assumes(mach_port_get_set_status(mach_task_self(), demand_port_set, &members, &membersCnt) == KERN_SUCCESS)) - return 1; - - for (i = 0; i < membersCnt; i++) { - statusCnt = MACH_PORT_RECEIVE_STATUS_COUNT; - if (mach_port_get_attributes(mach_task_self(), members[i], MACH_PORT_RECEIVE_STATUS, - (mach_port_info_t)&status, &statusCnt) != KERN_SUCCESS) - continue; - - if (status.mps_msgcount) { - EV_SET(&kev, members[i], EVFILT_MACHPORT, 0, 0, 0, job_find_by_port(members[i])); - (*((kq_callback *)kev.udata))(kev.udata, &kev); - /* the callback may have tainted our ability to continue this for loop */ - break; - } - } - - launchd_assumes(vm_deallocate(mach_task_self(), (vm_address_t)members, - (vm_size_t) membersCnt * sizeof(mach_port_name_t)) == KERN_SUCCESS); - - return 0; -} - -void -mach_init_init(mach_port_t req_port, mach_port_t checkin_port, - name_array_t l2l_names, mach_port_array_t l2l_ports, mach_msg_type_number_t l2l_cnt) -{ - mach_msg_type_number_t l2l_i; - auditinfo_t inherited_audit; - pthread_attr_t attr; - - getaudit(&inherited_audit); - inherited_asid = inherited_audit.ai_asid; - - init_ports(); - - launchd_assert((root_job = job_new_bootstrap(NULL, req_port ? req_port : mach_task_self(), checkin_port)) != NULL); - - launchd_assumes(launchd_get_bport(&inherited_bootstrap_port) == KERN_SUCCESS); - - if (getpid() != 1) - launchd_assumes(inherited_bootstrap_port != MACH_PORT_NULL); - - /* We set this explicitly as we start each child */ - launchd_assumes(launchd_set_bport(MACH_PORT_NULL) == KERN_SUCCESS); - - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); - pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN); - - launchd_assert(pthread_create(&demand_thread, &attr, mport_demand_loop, NULL) == 0); - - pthread_attr_destroy(&attr); - - /* cut off the Libc cache, we don't want to deadlock against ourself */ - bootstrap_port = MACH_PORT_NULL; - - if (l2l_names == NULL) - return; - - for (l2l_i = 0; l2l_i < l2l_cnt; l2l_i++) { - struct machservice *ms; - - if ((ms = machservice_new(root_job, l2l_names[l2l_i], l2l_ports + l2l_i))) - machservice_watch(ms); - } -} - -void mach_init_reap(void) -{ - void *status; - - launchd_assumes(mach_port_destroy(mach_task_self(), demand_port_set) == KERN_SUCCESS); - - launchd_assumes(pthread_join(demand_thread, &status) == 0); -} - -void -init_ports(void) -{ - launchd_assert((errno = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_PORT_SET, - &demand_port_set)) == KERN_SUCCESS); -} - -void * -mport_demand_loop(void *arg __attribute__((unused))) -{ - mach_msg_empty_rcv_t dummy; - kern_return_t kr; - - for (;;) { - kr = mach_msg(&dummy.header, MACH_RCV_MSG|MACH_RCV_LARGE, 0, 0, demand_port_set, 0, MACH_PORT_NULL); - if (kr == MACH_RCV_PORT_CHANGED) { - break; - } else if (!launchd_assumes(kr == MACH_RCV_TOO_LARGE)) { - continue; - } - launchd_assumes(handle_mport(launchd_internal_port) == 0); - } - - return NULL; -} - -boolean_t -launchd_mach_ipc_demux(mach_msg_header_t *Request, mach_msg_header_t *Reply) -{ - if (bootstrap_server_routine(Request)) - return bootstrap_server(Request, Reply); - - return notify_server(Request, Reply); -} - -bool -canReceive(mach_port_t port) -{ - mach_port_type_t p_type; - - if (!launchd_assumes(mach_port_type(mach_task_self(), port, &p_type) == KERN_SUCCESS)) - return false; - - return ((p_type & MACH_PORT_TYPE_RECEIVE) != 0); -} - -kern_return_t -launchd_set_bport(mach_port_t name) -{ - return errno = task_set_bootstrap_port(mach_task_self(), name); -} - -kern_return_t -launchd_get_bport(mach_port_t *name) -{ - return errno = task_get_bootstrap_port(mach_task_self(), name); -} - -kern_return_t -launchd_mport_notify_req(mach_port_t name, mach_msg_id_t which) -{ - mach_port_mscount_t msgc = (which == MACH_NOTIFY_NO_SENDERS) ? 1 : 0; - mach_port_t previous, where = (which == MACH_NOTIFY_NO_SENDERS) ? name : launchd_internal_port; - - if (which == MACH_NOTIFY_NO_SENDERS) { - /* Always make sure the send count is zero, in case a receive right is reused */ - errno = mach_port_set_mscount(mach_task_self(), name, 0); - if (errno != KERN_SUCCESS) - return errno; - } - - errno = mach_port_request_notification(mach_task_self(), name, which, msgc, where, - MACH_MSG_TYPE_MAKE_SEND_ONCE, &previous); - - if (errno == 0 && previous != MACH_PORT_NULL) - launchd_assumes(launchd_mport_deallocate(previous) == KERN_SUCCESS); - - return errno; -} - -kern_return_t -launchd_mport_request_callback(mach_port_t name, void *obj, bool readmsg) -{ - size_t needed_size; - - if (!obj) - return errno = mach_port_move_member(mach_task_self(), name, MACH_PORT_NULL); - - needed_size = (MACH_PORT_INDEX(name) + 1) * sizeof(void *); - - if (needed_size > port_to_obj_size) { - if (port_to_obj == NULL) { - launchd_assumes((port_to_obj = calloc(1, needed_size * 2)) != NULL); - } else { - launchd_assumes((port_to_obj = reallocf(port_to_obj, needed_size * 2)) != NULL); - memset((uint8_t *)port_to_obj + port_to_obj_size, 0, needed_size * 2 - port_to_obj_size); - } - port_to_obj_size = needed_size * 2; - } - - port_to_obj[MACH_PORT_INDEX(name)] = obj; - - return errno = mach_port_move_member(mach_task_self(), name, readmsg ? ipc_port_set : demand_port_set); -} - -kern_return_t -launchd_mport_make_send(mach_port_t name) -{ - return errno = mach_port_insert_right(mach_task_self(), name, name, MACH_MSG_TYPE_MAKE_SEND); -} - -kern_return_t -launchd_mport_close_recv(mach_port_t name) -{ - if (launchd_assumes(port_to_obj != NULL)) { - port_to_obj[MACH_PORT_INDEX(name)] = NULL; - return errno = mach_port_mod_refs(mach_task_self(), name, MACH_PORT_RIGHT_RECEIVE, -1); - } else { - return errno = KERN_FAILURE; - } -} - -kern_return_t -launchd_mport_create_recv(mach_port_t *name) -{ - return errno = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, name); -} - -kern_return_t -launchd_mport_deallocate(mach_port_t name) -{ - return errno = mach_port_deallocate(mach_task_self(), name); -} - -void -audit_token_to_launchd_cred(audit_token_t au_tok, struct ldcred *ldc) -{ - audit_token_to_au32(au_tok, /* audit UID */ NULL, - &ldc->euid, &ldc->egid, - &ldc->uid, &ldc->gid, &ldc->pid, - &ldc->asid, /* au_tid_t */ NULL); -} - -kern_return_t -x_bootstrap_create_server(mach_port_t bp, cmd_t server_cmd, uid_t server_uid, boolean_t on_demand, - audit_token_t au_tok, mach_port_t *server_portp) -{ - struct jobcb *js, *j = job_find_by_port(bp); - struct ldcred ldc; - - audit_token_to_launchd_cred(au_tok, &ldc); - - job_log(j, LOG_DEBUG, "Server create attempt: %s", server_cmd); - -#define LET_MERE_MORTALS_ADD_SERVERS_TO_PID1 - /* XXX - This code should go away once the per session launchd is integrated with the rest of the system */ - #ifdef LET_MERE_MORTALS_ADD_SERVERS_TO_PID1 - if (getpid() == 1) { - if (ldc.euid != 0 && ldc.euid != server_uid) { - job_log(j, LOG_WARNING, "Server create: \"%s\": Will run as UID %d, not UID %d as they told us to", - server_cmd, ldc.euid, server_uid); - server_uid = ldc.euid; - } - } else -#endif - if (!trusted_client_check(j, &ldc)) { - return BOOTSTRAP_NOT_PRIVILEGED; - } else if (server_uid != getuid()) { - job_log(j, LOG_WARNING, "Server create: \"%s\": As UID %d, we will not be able to switch to UID %d", - server_cmd, getuid(), server_uid); - server_uid = getuid(); - } - - js = job_new_via_mach_init(j, server_cmd, server_uid, on_demand); - - if (js == NULL) - return BOOTSTRAP_NO_MEMORY; - - *server_portp = job_get_bsport(js); - return BOOTSTRAP_SUCCESS; -} - -kern_return_t -x_bootstrap_getsocket(mach_port_t bp, name_t spr) -{ - if (!sockpath) { - return BOOTSTRAP_NO_MEMORY; - } else if (getpid() == 1) { - return BOOTSTRAP_NOT_PRIVILEGED; - } - - strncpy(spr, sockpath, sizeof(name_t)); - - return BOOTSTRAP_SUCCESS; -} - -kern_return_t -x_bootstrap_unprivileged(mach_port_t bp, mach_port_t *unprivportp) -{ - struct jobcb *j = job_find_by_port(bp); - - job_log(j, LOG_DEBUG, "Requested unprivileged bootstrap port"); - - j = job_get_bs(j); - - *unprivportp = job_get_bsport(j); - - return BOOTSTRAP_SUCCESS; -} - - -kern_return_t -x_bootstrap_check_in(mach_port_t bp, name_t servicename, audit_token_t au_tok, mach_port_t *serviceportp) -{ - static pid_t last_warned_pid = 0; - struct jobcb *j = job_find_by_port(bp); - struct machservice *ms; - struct ldcred ldc; - - audit_token_to_launchd_cred(au_tok, &ldc); - - trusted_client_check(j, &ldc); - - ms = job_lookup_service(j, servicename, true); - - if (ms == NULL) { - job_log(j, LOG_DEBUG, "Check-in of Mach service failed. Unknown: %s", servicename); - return BOOTSTRAP_UNKNOWN_SERVICE; - } - if (machservice_job(ms) != j) { - if (last_warned_pid != ldc.pid) { - job_log(j, LOG_NOTICE, "Check-in of Mach service failed. PID %d is not privileged: %s", - ldc.pid, servicename); - last_warned_pid = ldc.pid; - } - return BOOTSTRAP_NOT_PRIVILEGED; - } - if (!canReceive(machservice_port(ms))) { - launchd_assumes(machservice_active(ms)); - job_log(j, LOG_DEBUG, "Check-in of Mach service failed. Already active: %s", servicename); - return BOOTSTRAP_SERVICE_ACTIVE; - } - - machservice_watch(ms); - - job_log(j, LOG_INFO, "Check-in of service: %s", servicename); - - *serviceportp = machservice_port(ms); - return BOOTSTRAP_SUCCESS; -} - -kern_return_t -x_bootstrap_register(mach_port_t bp, audit_token_t au_tok, name_t servicename, mach_port_t serviceport) -{ - struct jobcb *j = job_find_by_port(bp); - struct machservice *ms; - struct ldcred ldc; - - audit_token_to_launchd_cred(au_tok, &ldc); - - trusted_client_check(j, &ldc); - - job_log(j, LOG_DEBUG, "Mach service registration attempt: %s", servicename); - - ms = job_lookup_service(j, servicename, false); - - if (ms) { - if (machservice_job(ms) != j) - return BOOTSTRAP_NOT_PRIVILEGED; - if (machservice_active(ms)) { - job_log(j, LOG_DEBUG, "Mach service registration failed. Already active: %s", servicename); - launchd_assumes(!canReceive(machservice_port(ms))); - return BOOTSTRAP_SERVICE_ACTIVE; - } - job_checkin(machservice_job(ms)); - machservice_delete(ms); - } - - if (serviceport != MACH_PORT_NULL) { - if ((ms = machservice_new(job_get_bs(j), servicename, &serviceport))) { - machservice_watch(ms); - } else { - return BOOTSTRAP_NO_MEMORY; - } - } - - return BOOTSTRAP_SUCCESS; -} - -kern_return_t -x_bootstrap_look_up(mach_port_t bp, audit_token_t au_tok, name_t servicename, mach_port_t *serviceportp, mach_msg_type_name_t *ptype) -{ - struct jobcb *j = job_find_by_port(bp); - struct machservice *ms; - struct ldcred ldc; - - audit_token_to_launchd_cred(au_tok, &ldc); - - trusted_client_check(j, &ldc); - - ms = job_lookup_service(j, servicename, true); - - if (ms && machservice_hidden(ms) && !job_active(machservice_job(ms))) { - ms = NULL; - } - - if (ms) { - launchd_assumes(machservice_port(ms) != MACH_PORT_NULL); - job_log(j, LOG_DEBUG, "Mach service lookup (by PID %d): %s", ldc.pid, servicename); - *serviceportp = machservice_port(ms); - *ptype = MACH_MSG_TYPE_COPY_SEND; - return BOOTSTRAP_SUCCESS; - } else if (inherited_bootstrap_port != MACH_PORT_NULL) { - job_log(j, LOG_DEBUG, "Mach service lookup (by PID %d) forwarded: %s", ldc.pid, servicename); - *ptype = MACH_MSG_TYPE_MOVE_SEND; - return bootstrap_look_up(inherited_bootstrap_port, servicename, serviceportp); - } else { - job_log(j, LOG_DEBUG, "Mach service lookup (by PID %d) failed: %s", ldc.pid, servicename); - return BOOTSTRAP_UNKNOWN_SERVICE; - } -} - -kern_return_t -x_bootstrap_parent(mach_port_t bp, mach_port_t *parentport, mach_msg_type_name_t *pptype) -{ - struct jobcb *j = job_find_by_port(bp); - - job_log(j, LOG_DEBUG, "Requested parent bootstrap port"); - - j = job_get_bs(j); - - *pptype = MACH_MSG_TYPE_MAKE_SEND; - - if (job_parent(j)) { - *parentport = job_get_bsport(job_parent(j)); - } else if (MACH_PORT_NULL == inherited_bootstrap_port) { - *parentport = job_get_bsport(j); - } else { - *pptype = MACH_MSG_TYPE_COPY_SEND; - *parentport = inherited_bootstrap_port; - } - return BOOTSTRAP_SUCCESS; -} - -static void -x_bootstrap_info_countservices(struct machservice *ms, void *context) -{ - unsigned int *cnt = context; - - (*cnt)++; -} - -struct x_bootstrap_info_copyservices_cb { - name_array_t service_names; - bootstrap_status_array_t service_actives; - mach_port_array_t ports; - unsigned int i; -}; - -static void -x_bootstrap_info_copyservices(struct machservice *ms, void *context) -{ - struct x_bootstrap_info_copyservices_cb *info_resp = context; - - strlcpy(info_resp->service_names[info_resp->i], machservice_name(ms), sizeof(info_resp->service_names[0])); - - launchd_assumes(info_resp->service_actives || info_resp->ports); - - if (info_resp->service_actives) { - info_resp->service_actives[info_resp->i] = machservice_status(ms); - } else { - info_resp->ports[info_resp->i] = machservice_port(ms); - } - info_resp->i++; -} - -kern_return_t -x_bootstrap_info(mach_port_t bp, name_array_t *servicenamesp, unsigned int *servicenames_cnt, - bootstrap_status_array_t *serviceactivesp, unsigned int *serviceactives_cnt) -{ - struct x_bootstrap_info_copyservices_cb info_resp = { NULL, NULL, NULL, 0 }; - struct jobcb *ji, *j = job_find_by_port(bp); - kern_return_t result; - unsigned int cnt = 0; - - for (ji = j; ji; ji = job_parent(ji)) - job_foreach_service(ji, x_bootstrap_info_countservices, &cnt, true); - - result = vm_allocate(mach_task_self(), (vm_address_t *)&info_resp.service_names, cnt * sizeof(info_resp.service_names[0]), true); - if (!launchd_assumes(result == KERN_SUCCESS)) - goto out_bad; - - result = vm_allocate(mach_task_self(), (vm_address_t *)&info_resp.service_actives, cnt * sizeof(info_resp.service_actives[0]), true); - if (!launchd_assumes(result == KERN_SUCCESS)) - goto out_bad; - - for (ji = j; ji; ji = job_parent(ji)) - job_foreach_service(ji, x_bootstrap_info_copyservices, &info_resp, true); - - launchd_assumes(info_resp.i == cnt); - - *servicenamesp = info_resp.service_names; - *serviceactivesp = info_resp.service_actives; - *servicenames_cnt = *serviceactives_cnt = cnt; - - return BOOTSTRAP_SUCCESS; - -out_bad: - if (info_resp.service_names) - vm_deallocate(mach_task_self(), (vm_address_t)info_resp.service_names, cnt * sizeof(info_resp.service_names[0])); - - return BOOTSTRAP_NO_MEMORY; -} - -kern_return_t -x_bootstrap_transfer_subset(mach_port_t bp, mach_port_t *reqport, mach_port_t *rcvright, - name_array_t *servicenamesp, unsigned int *servicenames_cnt, - mach_port_array_t *ports, unsigned int *ports_cnt) -{ - struct x_bootstrap_info_copyservices_cb info_resp = { NULL, NULL, NULL, 0 }; - struct jobcb *j = job_find_by_port(bp); - unsigned int cnt = 0; - kern_return_t result; - - if (getpid() != 1) { - job_log(j, LOG_ERR, "Only the system launchd will transfer Mach sub-bootstraps."); - return BOOTSTRAP_NOT_PRIVILEGED; - } else if (!job_parent(j)) { - job_log(j, LOG_ERR, "Root Mach bootstrap cannot be transferred."); - return BOOTSTRAP_NOT_PRIVILEGED; - } - - job_log(j, LOG_DEBUG, "Transferring sub-bootstrap to the per session launchd."); - - job_foreach_service(j, x_bootstrap_info_countservices, &cnt, false); - - result = vm_allocate(mach_task_self(), (vm_address_t *)&info_resp.service_names, cnt * sizeof(info_resp.service_names[0]), true); - if (!launchd_assumes(result == KERN_SUCCESS)) - goto out_bad; - - result = vm_allocate(mach_task_self(), (vm_address_t *)&info_resp.ports, cnt * sizeof(info_resp.ports[0]), true); - if (!launchd_assumes(result == KERN_SUCCESS)) - goto out_bad; - - job_foreach_service(j, x_bootstrap_info_copyservices, &info_resp, false); - - launchd_assumes(info_resp.i == cnt); - - *servicenamesp = info_resp.service_names; - *ports = info_resp.ports; - *servicenames_cnt = *ports_cnt = cnt; - - *reqport = job_get_reqport(j); - *rcvright = job_get_bsport(j); - - launchd_assumes(launchd_mport_request_callback(*rcvright, NULL, true) == KERN_SUCCESS); - - launchd_assumes(launchd_mport_make_send(*rcvright) == KERN_SUCCESS); - - return BOOTSTRAP_SUCCESS; - -out_bad: - if (info_resp.service_names) - vm_deallocate(mach_task_self(), (vm_address_t)info_resp.service_names, cnt * sizeof(info_resp.service_names[0])); - - return BOOTSTRAP_NO_MEMORY; -} - -kern_return_t -x_bootstrap_subset(mach_port_t bp, mach_port_t requestorport, mach_port_t *subsetportp) -{ - struct jobcb *js, *j = job_find_by_port(bp); - int bsdepth = 0; - - while ((j = job_parent(j)) != NULL) - bsdepth++; - - j = job_find_by_port(bp); - - /* Since we use recursion, we need an artificial depth for subsets */ - if (bsdepth > 100) { - job_log(j, LOG_ERR, "Mach sub-bootstrap create request failed. Depth greater than: %d", bsdepth); - return BOOTSTRAP_NO_MEMORY; - } - - if ((js = job_new_bootstrap(j, requestorport, MACH_PORT_NULL)) == NULL) { - if (requestorport == MACH_PORT_NULL) - return BOOTSTRAP_NOT_PRIVILEGED; - return BOOTSTRAP_NO_MEMORY; - } - - *subsetportp = job_get_bsport(js); - return BOOTSTRAP_SUCCESS; -} - -kern_return_t -x_bootstrap_create_service(mach_port_t bp, name_t servicename, mach_port_t *serviceportp) -{ - struct jobcb *j = job_find_by_port(bp); - struct machservice *ms; - - if (job_prog(j)[0] == '\0') { - job_log(j, LOG_ERR, "Mach service creation requires a target server: %s", servicename); - return BOOTSTRAP_NOT_PRIVILEGED; - } - - ms = job_lookup_service(j, servicename, false); - if (ms) { - job_log(j, LOG_DEBUG, "Mach service creation attempt for failed. Already exists: %s", servicename); - return BOOTSTRAP_NAME_IN_USE; - } - - job_checkin(j); - - *serviceportp = MACH_PORT_NULL; - ms = machservice_new(j, servicename, serviceportp); - - if (!launchd_assumes(ms != NULL)) - goto out_bad; - - return BOOTSTRAP_SUCCESS; - -out_bad: - launchd_assumes(launchd_mport_close_recv(*serviceportp) == KERN_SUCCESS); - return BOOTSTRAP_NO_MEMORY; -} - -kern_return_t -x_mpm_wait(mach_port_t bp, mach_port_t srp, audit_token_t au_tok, integer_t *waitstatus) -{ - struct jobcb *j = job_find_by_port(bp); -#if 0 - struct ldcred ldc; - audit_token_to_launchd_cred(au_tok, &ldc); -#endif - return job_handle_mpm_wait(j, srp, waitstatus); -} - -kern_return_t -x_mpm_uncork_fork(mach_port_t bp, audit_token_t au_tok) -{ - struct jobcb *j = job_find_by_port(bp); - - if (!j) - return BOOTSTRAP_NOT_PRIVILEGED; - - job_uncork_fork(j); - - return 0; -} - -kern_return_t -x_mpm_spawn(mach_port_t bp, audit_token_t au_tok, - _internal_string_t charbuf, mach_msg_type_number_t charbuf_cnt, - uint32_t argc, uint32_t envc, uint64_t flags, uint16_t mig_umask, - pid_t *child_pid, mach_port_t *obsvr_port) -{ - struct jobcb *jr, *j = job_find_by_port(bp); - struct ldcred ldc; - size_t offset = 0; - char *tmpp; - const char **argv = NULL, **env = NULL; - const char *label = NULL; - const char *path = NULL; - const char *workingdir = NULL; - size_t argv_i = 0, env_i = 0; - - audit_token_to_launchd_cred(au_tok, &ldc); - -#if 0 - if (ldc.asid != inherited_asid) { - job_log(j, LOG_ERR, "Security: PID %d (ASID %d) was denied a request to spawn a process in this session (ASID %d)", - ldc.pid, ldc.asid, inherited_asid); - return BOOTSTRAP_NOT_PRIVILEGED; - } -#endif - - argv = alloca((argc + 1) * sizeof(char *)); - memset(argv, 0, (argc + 1) * sizeof(char *)); - - if (envc > 0) { - env = alloca((envc + 1) * sizeof(char *)); - memset(env, 0, (envc + 1) * sizeof(char *)); - } - - while (offset < charbuf_cnt) { - tmpp = charbuf + offset; - offset += strlen(tmpp) + 1; - if (!label) { - label = tmpp; - } else if (argc > 0) { - argv[argv_i] = tmpp; - argv_i++; - argc--; - } else if (envc > 0) { - env[env_i] = tmpp; - env_i++; - envc--; - } else if (flags & SPAWN_HAS_PATH) { - path = tmpp; - flags &= ~SPAWN_HAS_PATH; - } else if (flags & SPAWN_HAS_WDIR) { - workingdir = tmpp; - flags &= ~SPAWN_HAS_WDIR; - } - } - - jr = job_new_spawn(label, path, workingdir, argv, env, flags & SPAWN_HAS_UMASK ? &mig_umask : NULL, - flags & SPAWN_WANTS_WAIT4DEBUGGER, flags & SPAWN_WANTS_FORCE_PPC); - - if (jr == NULL) switch (errno) { - case EEXIST: - return BOOTSTRAP_NAME_IN_USE; - default: - return BOOTSTRAP_NO_MEMORY; - } - - job_log(j, LOG_INFO, "Spawned with flags:%s%s", - flags & SPAWN_WANTS_FORCE_PPC ? " ppc": "", - flags & SPAWN_WANTS_WAIT4DEBUGGER ? " stopped": ""); - - *child_pid = job_get_pid(jr); - *obsvr_port = job_get_bsport(jr); - - return BOOTSTRAP_SUCCESS; -} - -kern_return_t -do_mach_notify_port_destroyed(mach_port_t notify, mach_port_t rights) -{ - /* This message is sent to us when a receive right is returned to us. */ - - if (!job_ack_port_destruction(root_job, rights)) { - launchd_assumes(launchd_mport_close_recv(rights) == KERN_SUCCESS); - } - - return KERN_SUCCESS; -} - -kern_return_t -do_mach_notify_port_deleted(mach_port_t notify, mach_port_name_t name) -{ - /* If we deallocate/destroy/mod_ref away a port with a pending notification, - * the original notification message is replaced with this message. - * - * To quote a Mach kernel expert, "the kernel has a send-once right that has - * to be used somehow." - */ - return KERN_SUCCESS; -} - -kern_return_t -do_mach_notify_no_senders(mach_port_t notify, mach_port_mscount_t mscount) -{ - struct jobcb *j = job_find_by_port(notify); - - /* This message is sent to us when the last customer of one of our objects - * goes away. - */ - - if (!launchd_assumes(j != NULL)) - return KERN_FAILURE; - - job_ack_no_senders(j); - - return KERN_SUCCESS; -} - -kern_return_t -do_mach_notify_send_once(mach_port_t notify) -{ - /* - * This message is sent to us every time we close a port that we have - * outstanding Mach notification requests on. We can safely ignore - * this message. - */ - return KERN_SUCCESS; -} - -kern_return_t -do_mach_notify_dead_name(mach_port_t notify, mach_port_name_t name) -{ - /* This message is sent to us when one of our send rights no longer has - * a receiver somewhere else on the system. - */ - - if (name == inherited_bootstrap_port) { - launchd_assumes(launchd_mport_deallocate(name) == KERN_SUCCESS); - inherited_bootstrap_port = MACH_PORT_NULL; - } - - job_delete_anything_with_port(root_job, name); - - /* A dead-name notification about a port appears to increment the - * rights on said port. Let's deallocate it so that we don't leak - * dead-name ports. - */ - launchd_assumes(launchd_mport_deallocate(name) == KERN_SUCCESS); - - return KERN_SUCCESS; -} - -bool -trusted_client_check(struct jobcb *j, struct ldcred *ldc) -{ - static pid_t last_warned_pid = 0; - - /* In the long run, we wish to enforce the progeny rule, but for now, - * we'll let root and the user be forgiven. Once we get CoreProcesses - * to switch to using launchd rather than the WindowServer for indirect - * process invocation, we can then seriously look at cranking up the - * warning level here. - */ - - if (inherited_asid == ldc->asid) - return true; - if (progeny_check(ldc->pid)) - return true; - if (ldc->euid == geteuid()) - return true; - if (ldc->euid == 0 && ldc->uid == 0) - return true; - if (last_warned_pid == ldc->pid) - return false; - - job_log(j, LOG_NOTICE, "Security: PID %d (ASID %d) was leaked into this session (ASID %d). This will be denied in the future.", ldc->pid, ldc->asid, inherited_asid); - - last_warned_pid = ldc->pid; - - return false; -} diff --git a/launchd/src/launchd_mig_types.defs b/launchd/src/launchd_mig_types.defs new file mode 100644 index 0000000..ad78611 --- /dev/null +++ b/launchd/src/launchd_mig_types.defs @@ -0,0 +1,42 @@ +/* + * Copyright (c) 1999-2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ +/* + * bootstrap -- fundamental service initiator and port server + * Mike DeMoney, NeXT, Inc. + * Copyright, 1990. All rights reserved. + */ + +type pid_t = integer_t; +type pid_array_t = ^array [] of pid_t; +type uid_t = integer_t; +type gid_t = integer_t; +type vproc_gsk_t = integer_t; +type logmsg_t = c_string[*:2048]; +type cmd_t = c_string[512]; +type name_t = c_string[128]; +type name_array_t = ^array [] of name_t; +type bootstrap_status_t = integer_t; +type bootstrap_status_array_t = ^array [] of bootstrap_status_t; + +type job_t = mach_port_t + intran: job_t job_mig_intran(mach_port_t) + outtran: mach_port_t job_mig_outtran(job_t) + destructor: job_mig_destructor(job_t) + cusertype: vproc_mig_t; diff --git a/launchd/src/launchd_runtime.c b/launchd/src/launchd_runtime.c new file mode 100644 index 0000000..7870ec1 --- /dev/null +++ b/launchd/src/launchd_runtime.c @@ -0,0 +1,1449 @@ +/* + * Copyright (c) 1999-2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ + +static const char *const __rcs_file_version__ = "$Revision: 23432 $"; + +#include "config.h" +#include "launchd_runtime.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "launchd_internalServer.h" +#include "launchd_internal.h" +#include "notifyServer.h" + +/* We shouldn't be including these */ +#include "launch.h" +#include "launchd.h" +#include "launchd_core_logic.h" +#include "libvproc_internal.h" +#include "job_reply.h" + +static mach_port_t ipc_port_set; +static mach_port_t demand_port_set; +static mach_port_t launchd_internal_port; +static int mainkq; + +#define BULK_KEV_MAX 100 +static struct kevent *bulk_kev; +static int bulk_kev_i; +static int bulk_kev_cnt; + +static pthread_t kqueue_demand_thread; +static pthread_t demand_thread; + +static void *mport_demand_loop(void *arg); +static void *kqueue_demand_loop(void *arg); +static void log_kevent_struct(int level, struct kevent *kev, int indx); + +static void record_caller_creds(mach_msg_header_t *mh); +static void launchd_runtime2(mach_msg_size_t msg_size, mig_reply_error_t *bufRequest, mig_reply_error_t *bufReply); +static mach_msg_size_t max_msg_size; +static mig_callback *mig_cb_table; +static size_t mig_cb_table_sz; +static timeout_callback runtime_idle_callback; +static mach_msg_timeout_t runtime_idle_timeout; +static audit_token_t *au_tok; +static size_t runtime_busy_cnt; + + +static STAILQ_HEAD(, logmsg_s) logmsg_queue = STAILQ_HEAD_INITIALIZER(logmsg_queue); +static size_t logmsg_queue_sz; +static size_t logmsg_queue_cnt; +static mach_port_t drain_reply_port; +static void runtime_log_uncork_pending_drain(void); +static kern_return_t runtime_log_pack(vm_offset_t *outval, mach_msg_type_number_t *outvalCnt); +static void runtime_log_push(void); + +static bool logmsg_add(struct runtime_syslog_attr *attr, int err_num, const char *msg); +static void logmsg_remove(struct logmsg_s *lm); + + +static const int sigigns[] = { SIGHUP, SIGINT, SIGPIPE, SIGALRM, SIGTERM, + SIGURG, SIGTSTP, SIGTSTP, SIGCONT, SIGTTIN, SIGTTOU, SIGIO, SIGXCPU, + SIGXFSZ, SIGVTALRM, SIGPROF, SIGWINCH, SIGINFO, SIGUSR1, SIGUSR2 +}; +static sigset_t sigign_set; + +void +launchd_runtime_init(void) +{ + mach_msg_size_t mxmsgsz; + pthread_attr_t attr; + + launchd_assert((mainkq = kqueue()) != -1); + + launchd_assert((errno = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_PORT_SET, &demand_port_set)) == KERN_SUCCESS); + launchd_assert((errno = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_PORT_SET, &ipc_port_set)) == KERN_SUCCESS); + + launchd_assert(launchd_mport_create_recv(&launchd_internal_port) == KERN_SUCCESS); + launchd_assert(launchd_mport_make_send(launchd_internal_port) == KERN_SUCCESS); + + /* Sigh... at the moment, MIG has maxsize == sizeof(reply union) */ + mxmsgsz = sizeof(union __RequestUnion__x_launchd_internal_subsystem); + if (x_launchd_internal_subsystem.maxsize > mxmsgsz) { + mxmsgsz = x_launchd_internal_subsystem.maxsize; + } + + launchd_assert(runtime_add_mport(launchd_internal_port, launchd_internal_demux, mxmsgsz) == KERN_SUCCESS); + + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN); + launchd_assert(pthread_create(&kqueue_demand_thread, &attr, kqueue_demand_loop, NULL) == 0); + pthread_attr_destroy(&attr); + + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN); + launchd_assert(pthread_create(&demand_thread, &attr, mport_demand_loop, NULL) == 0); + pthread_attr_destroy(&attr); +} + +void +launchd_runtime_init2(void) +{ + size_t i; + + for (i = 0; i < (sizeof(sigigns) / sizeof(int)); i++) { + sigaddset(&sigign_set, sigigns[i]); + launchd_assumes(signal(sigigns[i], SIG_IGN) != SIG_ERR); + } +} + +void * +mport_demand_loop(void *arg __attribute__((unused))) +{ + mach_msg_empty_rcv_t dummy; + kern_return_t kr; + + for (;;) { + kr = mach_msg(&dummy.header, MACH_RCV_MSG|MACH_RCV_LARGE, 0, 0, demand_port_set, 0, MACH_PORT_NULL); + if (kr == MACH_RCV_PORT_CHANGED) { + break; + } else if (!launchd_assumes(kr == MACH_RCV_TOO_LARGE)) { + continue; + } + launchd_assumes(handle_mport(launchd_internal_port) == 0); + } + + return NULL; +} + +const char * +proc_flags_to_C_names(unsigned int flags) +{ +#define MAX_PFLAG_STR "P_ADVLOCK|P_CONTROLT|P_LP64|P_NOCLDSTOP|P_PPWAIT|P_PROFIL|P_SELECT|P_CONTINUED|P_SUGID|P_SYSTEM|P_TIMEOUT|P_TRACED|P_RESV3|P_WEXIT|P_EXEC|P_OWEUPC|P_AFFINITY|P_TRANSLATED|P_RESV5|P_CHECKOPENEVT|P_DEPENDENCY_CAPABLE|P_REBOOT|P_TBE|P_RESV7|P_THCWD|P_RESV9|P_RESV10|P_RESV11|P_NOSHLIB|P_FORCEQUOTA|P_NOCLDWAIT|P_NOREMOTEHANG|0xdeadbeeffeedface" + + static char flags_buf[sizeof(MAX_PFLAG_STR)]; + char *flags_off = NULL; + + if (!flags) { + return ""; + } + + while (flags) { + if (flags_off) { + *flags_off = '|'; + flags_off++; + *flags_off = '\0'; + } else { + flags_off = flags_buf; + } + +#define FLAGIF(f) if (flags & f) { flags_off += sprintf(flags_off, #f); flags &= ~f; } + + FLAGIF(P_ADVLOCK) + else FLAGIF(P_CONTROLT) + else FLAGIF(P_LP64) + else FLAGIF(P_NOCLDSTOP) + else FLAGIF(P_PPWAIT) + else FLAGIF(P_PROFIL) + else FLAGIF(P_SELECT) + else FLAGIF(P_CONTINUED) + else FLAGIF(P_SUGID) + else FLAGIF(P_SYSTEM) + else FLAGIF(P_TIMEOUT) + else FLAGIF(P_TRACED) + else FLAGIF(P_RESV3) + else FLAGIF(P_WEXIT) + else FLAGIF(P_EXEC) + else FLAGIF(P_OWEUPC) + else FLAGIF(P_AFFINITY) + else FLAGIF(P_TRANSLATED) + else FLAGIF(P_RESV5) + else FLAGIF(P_CHECKOPENEVT) + else FLAGIF(P_DEPENDENCY_CAPABLE) + else FLAGIF(P_REBOOT) + else FLAGIF(P_TBE) + else FLAGIF(P_RESV7) + else FLAGIF(P_THCWD) + else FLAGIF(P_RESV9) + else FLAGIF(P_RESV10) + else FLAGIF(P_RESV11) + else FLAGIF(P_NOSHLIB) + else FLAGIF(P_FORCEQUOTA) + else FLAGIF(P_NOCLDWAIT) + else FLAGIF(P_NOREMOTEHANG) + else { + flags_off += sprintf(flags_off, "0x%x", flags); + flags = 0; + } + } + + return flags_buf; +} + +const char * +reboot_flags_to_C_names(unsigned int flags) +{ +#define MAX_RB_STR "RB_ASKNAME|RB_SINGLE|RB_NOSYNC|RB_KDB|RB_HALT|RB_INITNAME|RB_DFLTROOT|RB_ALTBOOT|RB_UNIPROC|RB_SAFEBOOT|RB_UPSDELAY|0xdeadbeeffeedface" + static char flags_buf[sizeof(MAX_RB_STR)]; + char *flags_off = NULL; + + if (flags) while (flags) { + if (flags_off) { + *flags_off = '|'; + flags_off++; + *flags_off = '\0'; + } else { + flags_off = flags_buf; + } + + FLAGIF(RB_ASKNAME) + else FLAGIF(RB_SINGLE) + else FLAGIF(RB_NOSYNC) + else FLAGIF(RB_KDB) + else FLAGIF(RB_HALT) + else FLAGIF(RB_INITNAME) + else FLAGIF(RB_DFLTROOT) + else FLAGIF(RB_ALTBOOT) + else FLAGIF(RB_UNIPROC) + else FLAGIF(RB_SAFEBOOT) + else FLAGIF(RB_UPSDELAY) + else { + flags_off += sprintf(flags_off, "0x%x", flags); + flags = 0; + } + return flags_buf; + } else { + return "RB_AUTOBOOT"; + } +} + +const char * +signal_to_C_name(unsigned int sig) +{ + static char unknown[25]; + +#define SIG2CASE(sg) case sg: return #sg + + switch (sig) { + SIG2CASE(SIGHUP); + SIG2CASE(SIGINT); + SIG2CASE(SIGQUIT); + SIG2CASE(SIGILL); + SIG2CASE(SIGTRAP); + SIG2CASE(SIGABRT); + SIG2CASE(SIGFPE); + SIG2CASE(SIGKILL); + SIG2CASE(SIGBUS); + SIG2CASE(SIGSEGV); + SIG2CASE(SIGSYS); + SIG2CASE(SIGPIPE); + SIG2CASE(SIGALRM); + SIG2CASE(SIGTERM); + SIG2CASE(SIGURG); + SIG2CASE(SIGSTOP); + SIG2CASE(SIGTSTP); + SIG2CASE(SIGCONT); + SIG2CASE(SIGCHLD); + SIG2CASE(SIGTTIN); + SIG2CASE(SIGTTOU); + SIG2CASE(SIGIO); + SIG2CASE(SIGXCPU); + SIG2CASE(SIGXFSZ); + SIG2CASE(SIGVTALRM); + SIG2CASE(SIGPROF); + SIG2CASE(SIGWINCH); + SIG2CASE(SIGINFO); + SIG2CASE(SIGUSR1); + SIG2CASE(SIGUSR2); + default: + snprintf(unknown, sizeof(unknown), "%u", sig); + return unknown; + } +} + +void +log_kevent_struct(int level, struct kevent *kev, int indx) +{ + const char *filter_str; + char ident_buf[100]; + char filter_buf[100]; + char fflags_buf[1000]; + char flags_buf[1000] = "0x0"; + char *flags_off = NULL; + char *fflags_off = NULL; + unsigned short flags = kev->flags; + unsigned int fflags = kev->fflags; + + if (flags) while (flags) { + if (flags_off) { + *flags_off = '|'; + flags_off++; + *flags_off = '\0'; + } else { + flags_off = flags_buf; + } + + FLAGIF(EV_ADD) + else FLAGIF(EV_RECEIPT) + else FLAGIF(EV_DELETE) + else FLAGIF(EV_ENABLE) + else FLAGIF(EV_DISABLE) + else FLAGIF(EV_CLEAR) + else FLAGIF(EV_EOF) + else FLAGIF(EV_ONESHOT) + else FLAGIF(EV_ERROR) + else { + flags_off += sprintf(flags_off, "0x%x", flags); + flags = 0; + } + } + + snprintf(ident_buf, sizeof(ident_buf), "%ld", kev->ident); + snprintf(fflags_buf, sizeof(fflags_buf), "0x%x", fflags); + + switch (kev->filter) { + case EVFILT_READ: + filter_str = "EVFILT_READ"; + break; + case EVFILT_WRITE: + filter_str = "EVFILT_WRITE"; + break; + case EVFILT_AIO: + filter_str = "EVFILT_AIO"; + break; + case EVFILT_VNODE: + filter_str = "EVFILT_VNODE"; + if (fflags) while (fflags) { + if (fflags_off) { + *fflags_off = '|'; + fflags_off++; + *fflags_off = '\0'; + } else { + fflags_off = fflags_buf; + } + +#define FFLAGIF(ff) if (fflags & ff) { fflags_off += sprintf(fflags_off, #ff); fflags &= ~ff; } + + FFLAGIF(NOTE_DELETE) + else FFLAGIF(NOTE_WRITE) + else FFLAGIF(NOTE_EXTEND) + else FFLAGIF(NOTE_ATTRIB) + else FFLAGIF(NOTE_LINK) + else FFLAGIF(NOTE_RENAME) + else FFLAGIF(NOTE_REVOKE) + else { + fflags_off += sprintf(fflags_off, "0x%x", fflags); + fflags = 0; + } + } + break; + case EVFILT_PROC: + filter_str = "EVFILT_PROC"; + if (fflags) while (fflags) { + if (fflags_off) { + *fflags_off = '|'; + fflags_off++; + *fflags_off = '\0'; + } else { + fflags_off = fflags_buf; + } + + FFLAGIF(NOTE_EXIT) + else FFLAGIF(NOTE_REAP) + else FFLAGIF(NOTE_FORK) + else FFLAGIF(NOTE_EXEC) + else FFLAGIF(NOTE_SIGNAL) + else FFLAGIF(NOTE_TRACK) + else FFLAGIF(NOTE_TRACKERR) + else FFLAGIF(NOTE_CHILD) + else { + fflags_off += sprintf(fflags_off, "0x%x", fflags); + fflags = 0; + } + } + break; + case EVFILT_SIGNAL: + filter_str = "EVFILT_SIGNAL"; + strcpy(ident_buf, signal_to_C_name(kev->ident)); + break; + case EVFILT_TIMER: + filter_str = "EVFILT_TIMER"; + snprintf(ident_buf, sizeof(ident_buf), "0x%lx", kev->ident); + if (fflags) while (fflags) { + if (fflags_off) { + *fflags_off = '|'; + fflags_off++; + *fflags_off = '\0'; + } else { + fflags_off = fflags_buf; + } + + FFLAGIF(NOTE_SECONDS) + else FFLAGIF(NOTE_USECONDS) + else FFLAGIF(NOTE_NSECONDS) + else FFLAGIF(NOTE_ABSOLUTE) + else { + fflags_off += sprintf(fflags_off, "0x%x", fflags); + fflags = 0; + } + } + break; + case EVFILT_MACHPORT: + filter_str = "EVFILT_MACHPORT"; + snprintf(ident_buf, sizeof(ident_buf), "0x%lx", kev->ident); + break; + case EVFILT_FS: + filter_str = "EVFILT_FS"; + snprintf(ident_buf, sizeof(ident_buf), "0x%lx", kev->ident); + if (fflags) while (fflags) { + if (fflags_off) { + *fflags_off = '|'; + fflags_off++; + *fflags_off = '\0'; + } else { + fflags_off = fflags_buf; + } + + FFLAGIF(VQ_NOTRESP) + else FFLAGIF(VQ_NEEDAUTH) + else FFLAGIF(VQ_LOWDISK) + else FFLAGIF(VQ_MOUNT) + else FFLAGIF(VQ_UNMOUNT) + else FFLAGIF(VQ_DEAD) + else FFLAGIF(VQ_ASSIST) + else FFLAGIF(VQ_NOTRESPLOCK) + else FFLAGIF(VQ_UPDATE) + else { + fflags_off += sprintf(fflags_off, "0x%x", fflags); + fflags = 0; + } + } + break; + default: + snprintf(filter_buf, sizeof(filter_buf), "%d", kev->filter); + filter_str = filter_buf; + break; + } + + runtime_syslog(level, "KEVENT[%d]: udata = %p data = 0x%lx ident = %s filter = %s flags = %s fflags = %s", + indx, kev->udata, kev->data, ident_buf, filter_str, flags_buf, fflags_buf); +} + +kern_return_t +x_handle_mport(mach_port_t junk __attribute__((unused))) +{ + mach_port_name_array_t members; + mach_msg_type_number_t membersCnt; + mach_port_status_t status; + mach_msg_type_number_t statusCnt; + struct kevent kev; + unsigned int i; + + if (!launchd_assumes((errno = mach_port_get_set_status(mach_task_self(), demand_port_set, &members, &membersCnt)) == KERN_SUCCESS)) { + return 1; + } + + for (i = 0; i < membersCnt; i++) { + statusCnt = MACH_PORT_RECEIVE_STATUS_COUNT; + if (mach_port_get_attributes(mach_task_self(), members[i], MACH_PORT_RECEIVE_STATUS, (mach_port_info_t)&status, + &statusCnt) != KERN_SUCCESS) { + continue; + } + if (status.mps_msgcount) { + EV_SET(&kev, members[i], EVFILT_MACHPORT, 0, 0, 0, job_find_by_service_port(members[i])); +#if 0 + if (launchd_assumes(kev.udata != NULL)) { +#endif + log_kevent_struct(LOG_DEBUG, &kev, 0); + (*((kq_callback *)kev.udata))(kev.udata, &kev); +#if 0 + } else { + log_kevent_struct(LOG_ERR, &kev); + } +#endif + /* the callback may have tainted our ability to continue this for loop */ + break; + } + } + + launchd_assumes(vm_deallocate(mach_task_self(), (vm_address_t)members, + (vm_size_t) membersCnt * sizeof(mach_port_name_t)) == KERN_SUCCESS); + + return 0; +} + +void * +kqueue_demand_loop(void *arg __attribute__((unused))) +{ + fd_set rfds; + + /* + * Yes, at first glance, calling select() on a kqueue seems silly. + * + * This avoids a race condition between the main thread and this helper + * thread by ensuring that we drain kqueue events on the same thread + * that manipulates the kqueue. + */ + + for (;;) { + FD_ZERO(&rfds); + FD_SET(mainkq, &rfds); + if (launchd_assumes(select(mainkq + 1, &rfds, NULL, NULL, NULL) == 1)) { + launchd_assumes(handle_kqueue(launchd_internal_port, mainkq) == 0); + } + } + + return NULL; +} + +kern_return_t +x_handle_kqueue(mach_port_t junk __attribute__((unused)), integer_t fd) +{ + struct timespec ts = { 0, 0 }; + struct kevent kev[BULK_KEV_MAX]; + int i; + + bulk_kev = kev; + + launchd_assumes((bulk_kev_cnt = kevent(fd, NULL, 0, kev, BULK_KEV_MAX, &ts)) != -1); + + if (bulk_kev_cnt > 0) { +#if 0 + Dl_info dli; + + if (launchd_assumes(malloc_size(kev.udata) || dladdr(kev.udata, &dli))) { +#endif + for (i = 0; i < bulk_kev_cnt; i++) { + log_kevent_struct(LOG_DEBUG, &kev[i], i); + } + for (i = 0; i < bulk_kev_cnt; i++) { + bulk_kev_i = i; + if (kev[i].filter) { + (*((kq_callback *)kev[i].udata))(kev[i].udata, &kev[i]); + } + } +#if 0 + } else { + log_kevent_struct(LOG_ERR, &kev); + } +#endif + } + + bulk_kev = NULL; + + return 0; +} + + + +void +launchd_runtime(void) +{ + mig_reply_error_t *req = NULL, *resp = NULL; + mach_msg_size_t mz = max_msg_size; + int flags = VM_MAKE_TAG(VM_MEMORY_MACH_MSG)|TRUE; + + for (;;) { + if (req) { + launchd_assumes(vm_deallocate(mach_task_self(), (vm_address_t)req, mz) == KERN_SUCCESS); + req = NULL; + } + if (resp) { + launchd_assumes(vm_deallocate(mach_task_self(), (vm_address_t)resp, mz) == KERN_SUCCESS); + resp = NULL; + } + + mz = max_msg_size; + + if (!launchd_assumes(vm_allocate(mach_task_self(), (vm_address_t *)&req, mz, flags) == KERN_SUCCESS)) { + continue; + } + if (!launchd_assumes(vm_allocate(mach_task_self(), (vm_address_t *)&resp, mz, flags) == KERN_SUCCESS)) { + continue; + } + + launchd_runtime2(mz, req, resp); + + /* If we get here, max_msg_size probably changed... */ + } +} + +kern_return_t +launchd_set_bport(mach_port_t name) +{ + return errno = task_set_bootstrap_port(mach_task_self(), name); +} + +kern_return_t +launchd_get_bport(mach_port_t *name) +{ + return errno = task_get_bootstrap_port(mach_task_self(), name); +} + +kern_return_t +launchd_mport_notify_req(mach_port_t name, mach_msg_id_t which) +{ + mach_port_mscount_t msgc = (which == MACH_NOTIFY_NO_SENDERS) ? 1 : 0; + mach_port_t previous, where = (which == MACH_NOTIFY_NO_SENDERS) ? name : launchd_internal_port; + + if (which == MACH_NOTIFY_NO_SENDERS) { + /* Always make sure the send count is zero, in case a receive right is reused */ + errno = mach_port_set_mscount(mach_task_self(), name, 0); + if (errno != KERN_SUCCESS) { + return errno; + } + } + + errno = mach_port_request_notification(mach_task_self(), name, which, msgc, where, + MACH_MSG_TYPE_MAKE_SEND_ONCE, &previous); + + if (errno == 0 && previous != MACH_PORT_NULL) { + launchd_assumes(launchd_mport_deallocate(previous) == KERN_SUCCESS); + } + + return errno; +} + +pid_t +runtime_fork(mach_port_t bsport) +{ + sigset_t emptyset, oset; + pid_t r = -1; + int saved_errno; + size_t i; + + sigemptyset(&emptyset); + + launchd_assumes(launchd_mport_make_send(bsport) == KERN_SUCCESS); + launchd_assumes(launchd_set_bport(bsport) == KERN_SUCCESS); + launchd_assumes(launchd_mport_deallocate(bsport) == KERN_SUCCESS); + + launchd_assumes(sigprocmask(SIG_BLOCK, &sigign_set, &oset) != -1); + for (i = 0; i < (sizeof(sigigns) / sizeof(int)); i++) { + launchd_assumes(signal(sigigns[i], SIG_DFL) != SIG_ERR); + } + + r = fork(); + saved_errno = errno; + + if (r != 0) { + for (i = 0; i < (sizeof(sigigns) / sizeof(int)); i++) { + launchd_assumes(signal(sigigns[i], SIG_IGN) != SIG_ERR); + } + launchd_assumes(sigprocmask(SIG_SETMASK, &oset, NULL) != -1); + launchd_assumes(launchd_set_bport(MACH_PORT_NULL) == KERN_SUCCESS); + } else { + launchd_assumes(sigprocmask(SIG_SETMASK, &emptyset, NULL) != -1); + } + + errno = saved_errno; + + return r; +} + + +void +runtime_set_timeout(timeout_callback to_cb, unsigned int sec) +{ + if (sec == 0 || to_cb == NULL) { + runtime_idle_callback = NULL; + runtime_idle_timeout = 0; + } + + runtime_idle_callback = to_cb; + runtime_idle_timeout = sec * 1000; +} + +kern_return_t +runtime_add_mport(mach_port_t name, mig_callback demux, mach_msg_size_t msg_size) +{ + size_t needed_table_sz = (MACH_PORT_INDEX(name) + 1) * sizeof(mig_callback); + mach_port_t target_set = demux ? ipc_port_set : demand_port_set; + + msg_size = round_page(msg_size + MAX_TRAILER_SIZE); + + if (needed_table_sz > mig_cb_table_sz) { + needed_table_sz *= 2; /* Let's try and avoid realloc'ing for a while */ + mig_callback *new_table = malloc(needed_table_sz); + + if (!launchd_assumes(new_table != NULL)) { + return KERN_RESOURCE_SHORTAGE; + } + + if (mig_cb_table) { + memcpy(new_table, mig_cb_table, mig_cb_table_sz); + free(mig_cb_table); + } + + mig_cb_table_sz = needed_table_sz; + mig_cb_table = new_table; + } + + mig_cb_table[MACH_PORT_INDEX(name)] = demux; + + if (msg_size > max_msg_size) { + max_msg_size = msg_size; + } + + return errno = mach_port_move_member(mach_task_self(), name, target_set); +} + +kern_return_t +runtime_remove_mport(mach_port_t name) +{ + mig_cb_table[MACH_PORT_INDEX(name)] = NULL; + + return errno = mach_port_move_member(mach_task_self(), name, MACH_PORT_NULL); +} + +kern_return_t +launchd_mport_make_send(mach_port_t name) +{ + return errno = mach_port_insert_right(mach_task_self(), name, name, MACH_MSG_TYPE_MAKE_SEND); +} + +kern_return_t +launchd_mport_close_recv(mach_port_t name) +{ + return errno = mach_port_mod_refs(mach_task_self(), name, MACH_PORT_RIGHT_RECEIVE, -1); +} + +kern_return_t +launchd_mport_create_recv(mach_port_t *name) +{ + return errno = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, name); +} + +kern_return_t +launchd_mport_deallocate(mach_port_t name) +{ + return errno = mach_port_deallocate(mach_task_self(), name); +} + +int +kevent_bulk_mod(struct kevent *kev, size_t kev_cnt) +{ + size_t i; + + for (i = 0; i < kev_cnt; i++) { + kev[i].flags |= EV_CLEAR|EV_RECEIPT; + } + + return kevent(mainkq, kev, kev_cnt, kev, kev_cnt, NULL); +} + +int +kevent_mod(uintptr_t ident, short filter, u_short flags, u_int fflags, intptr_t data, void *udata) +{ + struct kevent kev; + int r; + + switch (filter) { + case EVFILT_READ: + case EVFILT_WRITE: + break; + default: + flags |= EV_CLEAR; + break; + } + + flags |= EV_RECEIPT; + + if (flags & EV_ADD && !launchd_assumes(udata != NULL)) { + errno = EINVAL; + return -1; + } + + EV_SET(&kev, ident, filter, flags, fflags, data, udata); + + r = kevent(mainkq, &kev, 1, &kev, 1, NULL); + + if (!launchd_assumes(r == 1)) { + return -1; + } + + if (launchd_assumes(kev.flags & EV_ERROR)) { + if ((flags & EV_ADD) && kev.data) { + runtime_syslog(LOG_DEBUG, "%s(): See the next line...", __func__); + log_kevent_struct(LOG_DEBUG, &kev, 0); + errno = kev.data; + return -1; + } + } + + return r; +} + +boolean_t +launchd_internal_demux(mach_msg_header_t *Request, mach_msg_header_t *Reply) +{ + if (launchd_internal_server_routine(Request)) { + return launchd_internal_server(Request, Reply); + } + + return notify_server(Request, Reply); +} + +kern_return_t +do_mach_notify_port_destroyed(mach_port_t notify, mach_port_t rights) +{ + /* This message is sent to us when a receive right is returned to us. */ + + if (!launchd_assumes(job_ack_port_destruction(rights))) { + launchd_assumes(launchd_mport_close_recv(rights) == KERN_SUCCESS); + } + + return KERN_SUCCESS; +} + +kern_return_t +do_mach_notify_port_deleted(mach_port_t notify, mach_port_name_t name) +{ + /* If we deallocate/destroy/mod_ref away a port with a pending + * notification, the original notification message is replaced with + * this message. To quote a Mach kernel expert, "the kernel has a + * send-once right that has to be used somehow." + */ + return KERN_SUCCESS; +} + +kern_return_t +do_mach_notify_no_senders(mach_port_t notify, mach_port_mscount_t mscount) +{ + job_t j = job_mig_intran(notify); + + /* This message is sent to us when the last customer of one of our + * objects goes away. + */ + + if (!launchd_assumes(j != NULL)) { + return KERN_FAILURE; + } + + job_ack_no_senders(j); + + return KERN_SUCCESS; +} + +kern_return_t +do_mach_notify_send_once(mach_port_t notify) +{ + /* This message is sent to us every time we close a port that we have + * outstanding Mach notification requests on. We can safely ignore this + * message. + */ + + return KERN_SUCCESS; +} + +kern_return_t +do_mach_notify_dead_name(mach_port_t notify, mach_port_name_t name) +{ + /* This message is sent to us when one of our send rights no longer has + * a receiver somewhere else on the system. + */ + + if (name == drain_reply_port) { + launchd_assumes(launchd_mport_deallocate(name) == KERN_SUCCESS); + drain_reply_port = MACH_PORT_NULL; + } + + if (launchd_assumes(root_jobmgr != NULL)) { + root_jobmgr = jobmgr_delete_anything_with_port(root_jobmgr, name); + } + + /* A dead-name notification about a port appears to increment the + * rights on said port. Let's deallocate it so that we don't leak + * dead-name ports. + */ + launchd_assumes(launchd_mport_deallocate(name) == KERN_SUCCESS); + + return KERN_SUCCESS; +} + +void +record_caller_creds(mach_msg_header_t *mh) +{ + mach_msg_max_trailer_t *tp; + size_t trailer_size; + + tp = (mach_msg_max_trailer_t *)((vm_offset_t)mh + round_msg(mh->msgh_size)); + + trailer_size = tp->msgh_trailer_size - (mach_msg_size_t)(sizeof(mach_msg_trailer_type_t) - sizeof(mach_msg_trailer_size_t)); + + if (trailer_size < (mach_msg_size_t)sizeof(audit_token_t)) { + au_tok = NULL; + return; + } + + au_tok = &tp->msgh_audit; +} + +bool +runtime_get_caller_creds(struct ldcred *ldc) +{ + if (!au_tok) { + return false; + } + + audit_token_to_au32(*au_tok, /* audit UID */ NULL, &ldc->euid, + &ldc->egid, &ldc->uid, &ldc->gid, &ldc->pid, + &ldc->asid, /* au_tid_t */ NULL); + + return true; +} + +void +launchd_runtime2(mach_msg_size_t msg_size, mig_reply_error_t *bufRequest, mig_reply_error_t *bufReply) +{ + mach_msg_options_t options, tmp_options; + mig_reply_error_t *bufTemp; + mig_callback the_demux; + mach_msg_timeout_t to; + mach_msg_return_t mr; + + options = MACH_RCV_MSG|MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT) | + MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0); + + tmp_options = options; + + for (;;) { + to = MACH_MSG_TIMEOUT_NONE; + + if (msg_size != max_msg_size) { + /* The buffer isn't big enougth to receive messages anymore... */ + tmp_options &= ~MACH_RCV_MSG; + options &= ~MACH_RCV_MSG; + if (!(tmp_options & MACH_SEND_MSG)) { + return; + } + } + + if ((tmp_options & MACH_RCV_MSG) && (runtime_idle_callback || (runtime_busy_cnt == 0))) { + tmp_options |= MACH_RCV_TIMEOUT; + + if (!(tmp_options & MACH_SEND_TIMEOUT)) { + to = runtime_busy_cnt ? runtime_idle_timeout : (RUNTIME_ADVISABLE_IDLE_TIMEOUT * 1000); + } + } + + runtime_log_push(); + + mr = mach_msg(&bufReply->Head, tmp_options, bufReply->Head.msgh_size, + msg_size, ipc_port_set, to, MACH_PORT_NULL); + + tmp_options = options; + + if (mr == MACH_SEND_INVALID_DEST || mr == MACH_SEND_TIMED_OUT) { + /* We need to clean up and start over. */ + if (bufReply->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) { + mach_msg_destroy(&bufReply->Head); + } + continue; + } else if (mr == MACH_RCV_TIMED_OUT) { + if (to != MACH_MSG_TIMEOUT_NONE) { + if (runtime_busy_cnt == 0) { + launchd_shutdown(); + } else if (runtime_idle_callback) { + runtime_idle_callback(); + } + } + continue; + } else if (!launchd_assumes(mr == MACH_MSG_SUCCESS)) { + continue; + } + + bufTemp = bufRequest; + bufRequest = bufReply; + bufReply = bufTemp; + + if (!(tmp_options & MACH_RCV_MSG)) { + continue; + } + + /* we have another request message */ + + if (!launchd_assumes(mig_cb_table != NULL)) { + break; + } + + the_demux = mig_cb_table[MACH_PORT_INDEX(bufRequest->Head.msgh_local_port)]; + + if (!launchd_assumes(the_demux != NULL)) { + break; + } + + record_caller_creds(&bufRequest->Head); + + /* + * This is a total hack. We really need a bit in the kernel's proc + * struct to declare our intent. + */ + static int no_hang_fd = -1; + if (no_hang_fd == -1) { + no_hang_fd = _fd(open("/dev/autofs_nowait", 0)); + } + + if (the_demux(&bufRequest->Head, &bufReply->Head) == FALSE) { + /* XXX - also gross */ + if (bufRequest->Head.msgh_id == MACH_NOTIFY_NO_SENDERS) { + notify_server(&bufRequest->Head, &bufReply->Head); + } + } + + if (!(bufReply->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX)) { + if (bufReply->RetCode == MIG_NO_REPLY) { + bufReply->Head.msgh_remote_port = MACH_PORT_NULL; + } else if ((bufReply->RetCode != KERN_SUCCESS) && (bufRequest->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX)) { + /* destroy the request - but not the reply port */ + bufRequest->Head.msgh_remote_port = MACH_PORT_NULL; + mach_msg_destroy(&bufRequest->Head); + } + } + + if (bufReply->Head.msgh_remote_port != MACH_PORT_NULL) { + tmp_options |= MACH_SEND_MSG; + + if (MACH_MSGH_BITS_REMOTE(bufReply->Head.msgh_bits) != MACH_MSG_TYPE_MOVE_SEND_ONCE) { + tmp_options |= MACH_SEND_TIMEOUT; + } + } + } +} + +int +runtime_close(int fd) +{ + int i; + + if (bulk_kev) for (i = bulk_kev_i + 1; i < bulk_kev_cnt; i++) { + switch (bulk_kev[i].filter) { + case EVFILT_VNODE: + case EVFILT_WRITE: + case EVFILT_READ: + if ((int)bulk_kev[i].ident == fd) { + runtime_syslog(LOG_DEBUG, "Skipping kevent index: %d", i); + bulk_kev[i].filter = 0; + } + default: + break; + } + } + + return close(fd); +} + +static FILE *ourlogfile; + +void +runtime_closelog(void) +{ + if (ourlogfile) { + launchd_assumes(fflush(ourlogfile) == 0); + launchd_assumes(runtime_fsync(fileno(ourlogfile)) != -1); + } +} + +int +runtime_fsync(int fd) +{ + if (debug_shutdown_hangs) { + return fcntl(fd, F_FULLFSYNC, NULL); + } else { + return fsync(fd); + } +} + +static int internal_mask_pri = LOG_UPTO(LOG_NOTICE); +//static int internal_mask_pri = LOG_UPTO(LOG_DEBUG); + +int +runtime_setlogmask(int maskpri) +{ + internal_mask_pri = maskpri; + + return internal_mask_pri; +} + +void +runtime_syslog(int pri, const char *message, ...) +{ + struct runtime_syslog_attr attr = { + "com.apple.launchd", "com.apple.launchd", + getpid() == 1 ? "System" : "Background", + pri, getuid(), getpid(), getpid() + }; + va_list ap; + + va_start(ap, message); + + runtime_vsyslog(&attr, message, ap); + + va_end(ap); +} + +void +runtime_vsyslog(struct runtime_syslog_attr *attr, const char *message, va_list args) +{ + static pthread_mutex_t ourlock = PTHREAD_MUTEX_INITIALIZER; + static struct timeval shutdown_start; + static struct timeval prev_msg; + static int apple_internal_logging = 1; + struct timeval tvnow, tvd_total, tvd_msg_delta = { 0, 0 }; + struct stat sb; + int saved_errno = errno; + char newmsg[10000]; + size_t i, j; + + if (!(LOG_MASK(attr->priority) & internal_mask_pri)) { + goto out; + } + + if (apple_internal_logging == 1) { + apple_internal_logging = stat("/AppleInternal", &sb); + } + + + if (!(debug_shutdown_hangs && getpid() == 1)) { + if (attr->priority == LOG_APPLEONLY) { + if (apple_internal_logging == -1) { + goto out; + } + attr->priority = LOG_NOTICE; + } + vsnprintf(newmsg, sizeof(newmsg), message, args); + logmsg_add(attr, saved_errno, newmsg); + goto out; + } + + if (shutdown_start.tv_sec == 0) { + gettimeofday(&shutdown_start, NULL); + } + + if (gettimeofday(&tvnow, NULL) == -1) { + tvnow.tv_sec = 0; + tvnow.tv_usec = 0; + } + + pthread_mutex_lock(&ourlock); + + if (ourlogfile == NULL) { + rename("/var/log/launchd-shutdown.log", "/var/log/launchd-shutdown.log.1"); + ourlogfile = fopen("/var/log/launchd-shutdown.log", "a"); + } + + pthread_mutex_unlock(&ourlock); + + if (ourlogfile == NULL) { + goto out; + } + + if (message == NULL) { + goto out; + } + + timersub(&tvnow, &shutdown_start, &tvd_total); + + if (prev_msg.tv_sec != 0) { + timersub(&tvnow, &prev_msg, &tvd_msg_delta); + } + + prev_msg = tvnow; + + snprintf(newmsg, sizeof(newmsg), "%3ld.%06d%4ld.%06d%6u %-40s%6u %-40s ", + tvd_total.tv_sec, tvd_total.tv_usec, + tvd_msg_delta.tv_sec, tvd_msg_delta.tv_usec, + attr->from_pid, attr->from_name, + attr->about_pid, attr->about_name); + + for (i = 0, j = strlen(newmsg); message[i];) { + if (message[i] == '%' && message[i + 1] == 'm') { + char *errs = strerror(saved_errno); + strcpy(newmsg + j, errs ? errs : "unknown error"); + j += strlen(newmsg + j); + i += 2; + } else { + newmsg[j] = message[i]; + j++; + i++; + } + } + + strcpy(newmsg + j, "\n"); + + vfprintf(ourlogfile, newmsg, args); + +out: + runtime_log_uncork_pending_drain(); +} + +bool +logmsg_add(struct runtime_syslog_attr *attr, int err_num, const char *msg) +{ + size_t lm_sz = sizeof(struct logmsg_s) + strlen(msg) + strlen(attr->from_name) + strlen(attr->about_name) + strlen(attr->session_name) + 4; + char *data_off; + struct logmsg_s *lm; + +#define ROUND_TO_64BIT_WORD_SIZE(x) ((x + 7) & ~7) + + /* we do this to make the unpacking for the log_drain cause unalignment faults */ + lm_sz = ROUND_TO_64BIT_WORD_SIZE(lm_sz); + + if (!(lm = calloc(1, lm_sz))) { + return false; + } + + data_off = lm->data; + + launchd_assumes(gettimeofday(&lm->when, NULL) != -1); + lm->from_pid = attr->from_pid; + lm->about_pid = attr->about_pid; + lm->err_num = err_num; + lm->pri = attr->priority; + lm->obj_sz = lm_sz; + lm->msg = data_off; + data_off += sprintf(data_off, "%s", msg) + 1; + lm->from_name = data_off; + data_off += sprintf(data_off, "%s", attr->from_name) + 1; + lm->about_name = data_off; + data_off += sprintf(data_off, "%s", attr->about_name) + 1; + lm->session_name = data_off; + data_off += sprintf(data_off, "%s", attr->session_name) + 1; + + STAILQ_INSERT_TAIL(&logmsg_queue, lm, sqe); + logmsg_queue_sz += lm_sz; + logmsg_queue_cnt++; + + return true; +} + +void +logmsg_remove(struct logmsg_s *lm) +{ + STAILQ_REMOVE(&logmsg_queue, lm, logmsg_s, sqe); + logmsg_queue_sz -= lm->obj_sz; + logmsg_queue_cnt--; + + free(lm); +} + +kern_return_t +runtime_log_pack(vm_offset_t *outval, mach_msg_type_number_t *outvalCnt) +{ + struct logmsg_s *lm; + void *offset; + + *outvalCnt = logmsg_queue_sz; + + mig_allocate(outval, *outvalCnt); + + if (*outval == 0) { + return 1; + } + + offset = (void *)*outval; + + while ((lm = STAILQ_FIRST(&logmsg_queue))) { + lm->from_name -= (size_t)lm; + lm->about_name -= (size_t)lm; + lm->msg -= (size_t)lm; + lm->session_name -= (size_t)lm; + + memcpy(offset, lm, lm->obj_sz); + + offset += lm->obj_sz; + + logmsg_remove(lm); + } + + return 0; +} + +void +runtime_log_uncork_pending_drain(void) +{ + mach_msg_type_number_t outvalCnt; + mach_port_t tmp_port; + vm_offset_t outval; + + if (!drain_reply_port) { + return; + } + + if (logmsg_queue_cnt == 0) { + return; + } + + if (runtime_log_pack(&outval, &outvalCnt) != 0) { + return; + } + + tmp_port = drain_reply_port; + drain_reply_port = MACH_PORT_NULL; + + if ((errno = job_mig_log_drain_reply(tmp_port, 0, outval, outvalCnt))) { + launchd_assumes(errno == MACH_SEND_INVALID_DEST); + launchd_assumes(launchd_mport_deallocate(tmp_port) == KERN_SUCCESS); + } + + mig_deallocate(outval, outvalCnt); +} + +void +runtime_log_push(void) +{ + mach_msg_type_number_t outvalCnt; + vm_offset_t outval; + + if (logmsg_queue_cnt == 0) { + launchd_assumes(STAILQ_EMPTY(&logmsg_queue)); + return; + } else if (getpid() == 1) { + return; + } + + if (runtime_log_pack(&outval, &outvalCnt) != 0) { + return; + } + + launchd_assumes(_vprocmgr_log_forward(inherited_bootstrap_port, (void *)outval, outvalCnt) == NULL); + + mig_deallocate(outval, outvalCnt); +} + +kern_return_t +runtime_log_forward(uid_t forward_uid, gid_t forward_gid, vm_offset_t inval, mach_msg_type_number_t invalCnt) +{ + struct logmsg_s *lm, *lm_walk; + mach_msg_type_number_t data_left = invalCnt; + + if (inval == 0) { + return 0; + } + + for (lm_walk = (struct logmsg_s *)inval; (data_left > 0) && (lm_walk->obj_sz <= data_left); lm_walk = ((void *)lm_walk + lm_walk->obj_sz)) { + if (!launchd_assumes(lm = malloc(lm_walk->obj_sz))) { + continue; + } + + memcpy(lm, lm_walk, lm_walk->obj_sz); + lm->sender_uid = forward_uid; + lm->sender_gid = forward_gid; + + lm->from_name += (size_t)lm; + lm->about_name += (size_t)lm; + lm->msg += (size_t)lm; + lm->session_name += (size_t)lm; + + STAILQ_INSERT_TAIL(&logmsg_queue, lm, sqe); + logmsg_queue_sz += lm->obj_sz; + logmsg_queue_cnt++; + + data_left -= lm->obj_sz; + } + + mig_deallocate(inval, invalCnt); + + return 0; +} + +kern_return_t +runtime_log_drain(mach_port_t srp, vm_offset_t *outval, mach_msg_type_number_t *outvalCnt) +{ + if (logmsg_queue_cnt == 0) { + launchd_assumes(STAILQ_EMPTY(&logmsg_queue)); + launchd_assumes(drain_reply_port == 0); + + drain_reply_port = srp; + launchd_assumes(launchd_mport_notify_req(drain_reply_port, MACH_NOTIFY_DEAD_NAME) == KERN_SUCCESS); + + return MIG_NO_REPLY; + } + + return runtime_log_pack(outval, outvalCnt); +} + +/* + * We should break this into two reference counts. + * + * One for hard references that would prevent exiting. + * One for soft references that would only prevent idle exiting. + * + * In the long run, reference counting should completely automate when a + * process can and should exit. + */ +void +runtime_add_ref(void) +{ + runtime_busy_cnt++; +} + +void +runtime_del_ref(void) +{ + runtime_busy_cnt--; +} diff --git a/launchd/src/launchd_runtime.h b/launchd/src/launchd_runtime.h new file mode 100644 index 0000000..1f9fdf9 --- /dev/null +++ b/launchd/src/launchd_runtime.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. + * + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ +#ifndef __LAUNCHD_RUNTIME_H__ +#define __LAUNCHD_RUNTIME_H__ + +#include +#include +#include +#include +#include + +#include "launchd_runtime_kill.h" + +struct ldcred { + uid_t euid; + uid_t uid; + gid_t egid; + gid_t gid; + pid_t pid; + au_asid_t asid; +}; + +/* + * Use launchd_assumes() when we can recover, even if it means we leak or limp along. + * + * Use launchd_assert() for core initialization routines. + */ +#define launchd_assumes(e) \ + (__builtin_expect(!(e), 0) ? _log_launchd_bug(__rcs_file_version__, __FILE__, __LINE__, #e), false : true) + +#define launchd_blame(e, b) \ + (__builtin_expect(!(e), 0) ? syslog(LOG_DEBUG, "Encountered bug: %d", b), false : true) + +#define launchd_assert(e) if (__builtin_constant_p(e)) { char __compile_time_assert__[e ? 1 : -1] __attribute__((unused)); } else if (!launchd_assumes(e)) { abort(); } + +void _log_launchd_bug(const char *rcs_rev, const char *path, unsigned int line, const char *test); + +typedef void (*kq_callback)(void *, struct kevent *); +typedef boolean_t (*mig_callback)(mach_msg_header_t *, mach_msg_header_t *); +typedef void (*timeout_callback)(void); + +boolean_t launchd_internal_demux(mach_msg_header_t *Request, mach_msg_header_t *Reply); + +void runtime_add_ref(void); +void runtime_del_ref(void); + +void launchd_runtime_init(void); +void launchd_runtime_init2(void); +void launchd_runtime(void) __attribute__((noreturn)); + +int runtime_close(int fd); +int runtime_fsync(int fd); + +#define RUNTIME_ADVISABLE_IDLE_TIMEOUT 30 + +void runtime_set_timeout(timeout_callback to_cb, unsigned int sec); +kern_return_t runtime_add_mport(mach_port_t name, mig_callback demux, mach_msg_size_t msg_size); +kern_return_t runtime_remove_mport(mach_port_t name); +bool runtime_get_caller_creds(struct ldcred *ldc); + +const char *signal_to_C_name(unsigned int sig); +const char *reboot_flags_to_C_names(unsigned int flags); +const char *proc_flags_to_C_names(unsigned int flags); + + +int kevent_bulk_mod(struct kevent *kev, size_t kev_cnt); +int kevent_mod(uintptr_t ident, short filter, u_short flags, u_int fflags, intptr_t data, void *udata); + +pid_t runtime_fork(mach_port_t bsport); + +kern_return_t runtime_log_forward(uid_t forward_uid, gid_t forward_gid, vm_offset_t inval, mach_msg_type_number_t invalCnt); +kern_return_t runtime_log_drain(mach_port_t srp, vm_offset_t *outval, mach_msg_type_number_t *outvalCnt); + +#define LOG_APPLEONLY 0x4141504c /* AAPL in hex */ + +struct runtime_syslog_attr { + const char *from_name; + const char *about_name; + const char *session_name; + int priority; + uid_t from_uid; + pid_t from_pid; + pid_t about_pid; +}; + +int runtime_setlogmask(int maskpri); +void runtime_closelog(void); +void runtime_syslog(int pri, const char *message, ...) __attribute__((format(printf, 2, 3))); +void runtime_vsyslog(struct runtime_syslog_attr *attr, const char *message, va_list args) __attribute__((format(printf, 2, 0))); + + +kern_return_t launchd_set_bport(mach_port_t name); +kern_return_t launchd_get_bport(mach_port_t *name); +kern_return_t launchd_mport_notify_req(mach_port_t name, mach_msg_id_t which); +kern_return_t launchd_mport_notify_cancel(mach_port_t name, mach_msg_id_t which); +kern_return_t launchd_mport_create_recv(mach_port_t *name); +kern_return_t launchd_mport_deallocate(mach_port_t name); +kern_return_t launchd_mport_make_send(mach_port_t name); +kern_return_t launchd_mport_close_recv(mach_port_t name); + +#endif diff --git a/launchd/src/launchd_runtime_kill.c b/launchd/src/launchd_runtime_kill.c new file mode 100644 index 0000000..383c150 --- /dev/null +++ b/launchd/src/launchd_runtime_kill.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2007 Apple Inc. All rights reserved. + * + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ + +#define _NONSTD_SOURCE 1 +#include + +#include "launchd_runtime_kill.h" + +/* + * POSIX defines consistency over correctness, and consequently kill/killpg now + * returns EPERM instead of ESRCH. + * + * I've filed 5487498 to get a non-portable kill() variant, but for now, + * defining _NONSTD_SOURCE gets us the old behavior. + */ + +int +runtime_kill(pid_t pid, int sig) +{ + return kill(pid, sig); +} + +int +runtime_killpg(pid_t pgrp, int sig) +{ + return killpg(pgrp, sig); +} diff --git a/launchd/src/launchd_runtime_kill.h b/launchd/src/launchd_runtime_kill.h new file mode 100644 index 0000000..3b34086 --- /dev/null +++ b/launchd/src/launchd_runtime_kill.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2007 Apple Inc. All rights reserved. + * + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ +#ifndef __LAUNCHD_RUNTIME_KILL_H__ +#define __LAUNCHD_RUNTIME_KILL_H__ + +#include + +int runtime_kill(pid_t pid, int sig); +int runtime_killpg(pid_t pgrp, int sig); + +#endif diff --git a/launchd/src/launchd_unix_ipc.c b/launchd/src/launchd_unix_ipc.c index 712a124..c939c1f 100644 --- a/launchd/src/launchd_unix_ipc.c +++ b/launchd/src/launchd_unix_ipc.c @@ -18,7 +18,10 @@ * @APPLE_APACHE_LICENSE_HEADER_END@ */ -static const char *const __rcs_file_version__ = "$Revision: 1.11 $"; +static const char *const __rcs_file_version__ = "$Revision: 23274 $"; + +#include "config.h" +#include "launchd_unix_ipc.h" #include #include @@ -36,7 +39,6 @@ static const char *const __rcs_file_version__ = "$Revision: 1.11 $"; #include #include #include -#include #include #include #include @@ -45,15 +47,15 @@ static const char *const __rcs_file_version__ = "$Revision: 1.11 $"; #include #include -#include "launch.h" -#include "launch_priv.h" +#include "liblaunch_public.h" +#include "liblaunch_private.h" #include "launchd.h" +#include "launchd_runtime.h" #include "launchd_core_logic.h" -#include "launchd_unix_ipc.h" extern char **environ; -static SLIST_HEAD(, conncb) connections = { NULL }; +static LIST_HEAD(, conncb) connections; static launch_data_t adjust_rlimits(launch_data_t in); @@ -73,29 +75,28 @@ static bool ipc_inited = false; void ipc_clean_up(void) { - if (ipc_self != getpid()) + if (ipc_self != getpid()) { return; + } - if (-1 == unlink(sockpath)) - syslog(LOG_WARNING, "unlink(\"%s\"): %m", sockpath); - else if (-1 == rmdir(sockdir)) - syslog(LOG_WARNING, "rmdir(\"%s\"): %m", sockdir); + if (-1 == unlink(sockpath)) { + runtime_syslog(LOG_WARNING, "unlink(\"%s\"): %m", sockpath); + } else if (-1 == rmdir(sockdir)) { + runtime_syslog(LOG_WARNING, "rmdir(\"%s\"): %m", sockdir); + } } void -ipc_server_init(int *fds, size_t fd_cnt) +ipc_server_init(void) { struct sockaddr_un sun; mode_t oldmask; int r, fd = -1; char ourdir[1024]; - size_t i; - if (ipc_inited) + if (ipc_inited) { return; - - if (fds) - goto add_fds; + } memset(&sun, 0, sizeof(sun)); sun.sun_family = AF_UNIX; @@ -113,75 +114,69 @@ ipc_server_init(int *fds, size_t fd_cnt) stat(ourdir, &sb); if (!S_ISDIR(sb.st_mode)) { errno = EEXIST; - syslog(LOG_ERR, "mkdir(\"%s\"): %m", LAUNCHD_SOCK_PREFIX); + runtime_syslog(LOG_ERR, "mkdir(\"%s\"): %m", LAUNCHD_SOCK_PREFIX); goto out_bad; } } else { - syslog(LOG_ERR, "mkdir(\"%s\"): %m", ourdir); + runtime_syslog(LOG_ERR, "mkdir(\"%s\"): %m", ourdir); goto out_bad; } } } else { snprintf(ourdir, sizeof(ourdir), "/tmp/launchd-%u.XXXXXX", getpid()); - if (!launchd_assumes(mkdtemp(ourdir) != NULL)) + if (!launchd_assumes(mkdtemp(ourdir) != NULL)) { goto out_bad; + } snprintf(sun.sun_path, sizeof(sun.sun_path), "%s/sock", ourdir); - setenv(LAUNCHD_SOCKET_ENV, sun.sun_path, 1); } if (unlink(sun.sun_path) == -1 && errno != ENOENT) { - if (errno != EROFS) - syslog(LOG_ERR, "unlink(\"thesocket\"): %m"); + if (errno != EROFS) { + runtime_syslog(LOG_ERR, "unlink(\"thesocket\"): %m"); + } goto out_bad; } - if (!launchd_assumes((fd = _fd(socket(AF_UNIX, SOCK_STREAM, 0))) != -1)) + if (!launchd_assumes((fd = _fd(socket(AF_UNIX, SOCK_STREAM, 0))) != -1)) { goto out_bad; + } oldmask = umask(S_IRWXG|S_IRWXO); r = bind(fd, (struct sockaddr *)&sun, sizeof(sun)); umask(oldmask); if (r == -1) { - if (errno != EROFS) - syslog(LOG_ERR, "bind(\"thesocket\"): %m"); + if (errno != EROFS) { + runtime_syslog(LOG_ERR, "bind(\"thesocket\"): %m"); + } goto out_bad; } if (listen(fd, SOMAXCONN) == -1) { - syslog(LOG_ERR, "listen(\"thesocket\"): %m"); + runtime_syslog(LOG_ERR, "listen(\"thesocket\"): %m"); goto out_bad; } -add_fds: - if (fds) { - for (i = 0; i < fd_cnt; i++) { - if (kevent_mod(fds[i], EVFILT_READ, EV_ADD, 0, 0, &kqipc_listen_callback) == -1) { - syslog(LOG_ERR, "kevent_mod(%d, EVFILT_READ): %m", fds[i]); - goto out_bad; - } - } - } else if (kevent_mod(fd, EVFILT_READ, EV_ADD, 0, 0, &kqipc_listen_callback) == -1) { - syslog(LOG_ERR, "kevent_mod(\"thesocket\", EVFILT_READ): %m"); + if (kevent_mod(fd, EVFILT_READ, EV_ADD, 0, 0, &kqipc_listen_callback) == -1) { + runtime_syslog(LOG_ERR, "kevent_mod(\"thesocket\", EVFILT_READ): %m"); goto out_bad; } ipc_inited = true; - if (!fds) { - sockdir = strdup(ourdir); - sockpath = strdup(sun.sun_path); - ipc_self = getpid(); - atexit(ipc_clean_up); - } + sockdir = strdup(ourdir); + sockpath = strdup(sun.sun_path); + ipc_self = getpid(); + atexit(ipc_clean_up); out_bad: - if (!ipc_inited && fd != -1) - launchd_assumes(close(fd) == 0); + if (!ipc_inited && fd != -1) { + launchd_assumes(runtime_close(fd) == 0); + } } void -ipc_open(int fd, struct jobcb *j) +ipc_open(int fd, job_t j) { struct conncb *c = calloc(1, sizeof(struct conncb)); @@ -190,7 +185,7 @@ ipc_open(int fd, struct jobcb *j) c->kqconn_callback = ipc_callback; c->conn = launchd_fdopen(fd); c->j = j; - SLIST_INSERT_HEAD(&connections, c, sle); + LIST_INSERT_HEAD(&connections, c, sle); kevent_mod(fd, EVFILT_READ, EV_ADD, 0, 0, &c->kqconn_callback); } @@ -216,22 +211,23 @@ ipc_callback(void *obj, struct kevent *kev) if (kev->filter == EVFILT_READ) { if (launchd_msg_recv(c->conn, ipc_readmsg, c) == -1 && errno != EAGAIN) { - if (errno != ECONNRESET) - syslog(LOG_DEBUG, "%s(): recv: %m", __func__); + if (errno != ECONNRESET) { + runtime_syslog(LOG_DEBUG, "%s(): recv: %m", __func__); + } ipc_close(c); } } else if (kev->filter == EVFILT_WRITE) { r = launchd_msg_send(c->conn, NULL); if (r == -1) { if (errno != EAGAIN) { - syslog(LOG_DEBUG, "%s(): send: %m", __func__); + runtime_syslog(LOG_DEBUG, "%s(): send: %m", __func__); ipc_close(c); } } else if (r == 0) { kevent_mod(launchd_getfd(c->conn), EVFILT_WRITE, EV_DELETE, 0, 0, NULL); } } else { - syslog(LOG_DEBUG, "%s(): unknown filter type!", __func__); + runtime_syslog(LOG_DEBUG, "%s(): unknown filter type!", __func__); ipc_close(c); } } @@ -241,6 +237,18 @@ static void set_user_env(launch_data_t obj, const char *key, void *context __att setenv(key, launch_data_get_string(obj), 1); } +void +ipc_close_all_with_job(job_t j) +{ + struct conncb *ci, *cin; + + LIST_FOREACH_SAFE(ci, &connections, sle, cin) { + if (ci->j == j) { + ipc_close(ci); + } + } +} + void ipc_close_fds(launch_data_t o) { @@ -255,8 +263,9 @@ ipc_close_fds(launch_data_t o) ipc_close_fds(launch_data_array_get_index(o, i)); break; case LAUNCH_DATA_FD: - if (launch_data_get_fd(o) != -1) - launchd_assumes(close(launch_data_get_fd(o)) == 0); + if (launch_data_get_fd(o) != -1) { + launchd_assumes(runtime_close(launch_data_get_fd(o)) == 0); + } break; default: break; @@ -302,8 +311,9 @@ ipc_readmsg(launch_data_t msg, void *context) rmc.resp = launch_data_new_errno(EINVAL); } - if (NULL == rmc.resp) + if (NULL == rmc.resp) { rmc.resp = launch_data_new_errno(ENOSYS); + } ipc_close_fds(msg); @@ -311,7 +321,7 @@ ipc_readmsg(launch_data_t msg, void *context) if (errno == EAGAIN) { kevent_mod(launchd_getfd(rmc.c->conn), EVFILT_WRITE, EV_ADD, 0, 0, &rmc.c->kqconn_callback); } else { - syslog(LOG_DEBUG, "launchd_msg_send() == -1: %m"); + runtime_syslog(LOG_DEBUG, "launchd_msg_send() == -1: %m"); ipc_close(rmc.c); } } @@ -324,10 +334,13 @@ ipc_readmsg2(launch_data_t data, const char *cmd, void *context) { struct readmsg_context *rmc = context; launch_data_t resp = NULL; - struct jobcb *j; + job_t j; - if (rmc->resp) + if (rmc->resp) { return; + } + + //job_log(rmc->c->j, LOG_DEBUG, "Unix IPC request: %s", cmd); if (data == NULL) { if (!strcmp(cmd, LAUNCH_KEY_CHECKIN)) { @@ -337,9 +350,6 @@ ipc_readmsg2(launch_data_t data, const char *cmd, void *context) } else { resp = launch_data_new_errno(EACCES); } - } else if (!strcmp(cmd, LAUNCH_KEY_RELOADTTYS)) { - update_ttys(); - resp = launch_data_new_errno(0); } else if (!strcmp(cmd, LAUNCH_KEY_SHUTDOWN)) { launchd_shutdown(); resp = launch_data_new_errno(0); @@ -351,25 +361,6 @@ ipc_readmsg2(launch_data_t data, const char *cmd, void *context) ipc_revoke_fds(resp); } else if (!strcmp(cmd, LAUNCH_KEY_GETRESOURCELIMITS)) { resp = adjust_rlimits(NULL); - } else if (!strcmp(cmd, LAUNCH_KEY_GETUSERENVIRONMENT)) { - char **tmpenviron = environ; - resp = launch_data_alloc(LAUNCH_DATA_DICTIONARY); - for (; *tmpenviron; tmpenviron++) { - char envkey[1024]; - launch_data_t s = launch_data_alloc(LAUNCH_DATA_STRING); - launch_data_set_string(s, strchr(*tmpenviron, '=') + 1); - strncpy(envkey, *tmpenviron, sizeof(envkey)); - *(strchr(envkey, '=')) = '\0'; - launch_data_dict_insert(resp, s, envkey); - } - } else if (!strcmp(cmd, LAUNCH_KEY_GETLOGMASK)) { - int oldmask = setlogmask(LOG_UPTO(LOG_DEBUG)); - resp = launch_data_new_integer(oldmask); - setlogmask(oldmask); - } else if (!strcmp(cmd, LAUNCH_KEY_GETUMASK)) { - mode_t oldmask = umask(0); - resp = launch_data_new_integer(oldmask); - umask(oldmask); } else if (!strcmp(cmd, LAUNCH_KEY_GETRUSAGESELF)) { struct rusage rusage; getrusage(RUSAGE_SELF, &rusage); @@ -378,24 +369,21 @@ ipc_readmsg2(launch_data_t data, const char *cmd, void *context) struct rusage rusage; getrusage(RUSAGE_CHILDREN, &rusage); resp = launch_data_new_opaque(&rusage, sizeof(rusage)); - } else if (!strcmp(cmd, LAUNCH_KEY_BATCHQUERY)) { - resp = launch_data_alloc(LAUNCH_DATA_BOOL); - launch_data_set_bool(resp, batch_disabler_count == 0); } } else if (!strcmp(cmd, LAUNCH_KEY_STARTJOB)) { - if ((j = job_find(root_job, launch_data_get_string(data))) != NULL) { - job_start(j); + if ((j = job_find(launch_data_get_string(data))) != NULL) { + job_dispatch(j, true); errno = 0; } resp = launch_data_new_errno(errno); } else if (!strcmp(cmd, LAUNCH_KEY_STOPJOB)) { - if ((j = job_find(root_job, launch_data_get_string(data))) != NULL) { + if ((j = job_find(launch_data_get_string(data))) != NULL) { job_stop(j); errno = 0; } resp = launch_data_new_errno(errno); } else if (!strcmp(cmd, LAUNCH_KEY_REMOVEJOB)) { - if ((j = job_find(root_job, launch_data_get_string(data))) != NULL) { + if ((j = job_find(launch_data_get_string(data))) != NULL) { job_remove(j); errno = 0; } @@ -404,8 +392,9 @@ ipc_readmsg2(launch_data_t data, const char *cmd, void *context) if (launch_data_get_type(data) == LAUNCH_DATA_ARRAY) { resp = job_import_bulk(data); } else { - if (job_import(data)) + if (job_import(data)) { errno = 0; + } resp = launch_data_new_errno(errno); } } else if (!strcmp(cmd, LAUNCH_KEY_UNSETUSERENVIRONMENT)) { @@ -417,29 +406,12 @@ ipc_readmsg2(launch_data_t data, const char *cmd, void *context) } else if (!strcmp(cmd, LAUNCH_KEY_SETRESOURCELIMITS)) { resp = adjust_rlimits(data); } else if (!strcmp(cmd, LAUNCH_KEY_GETJOB)) { - if ((j = job_find(root_job, launch_data_get_string(data))) == NULL) { + if ((j = job_find(launch_data_get_string(data))) == NULL) { resp = launch_data_new_errno(errno); } else { resp = job_export(j); ipc_revoke_fds(resp); } - } else if (!strcmp(cmd, LAUNCH_KEY_GETJOBWITHHANDLES)) { - if ((j = job_find(root_job, launch_data_get_string(data))) == NULL) { - resp = launch_data_new_errno(errno); - } else { - resp = job_export(j); - } - } else if (!strcmp(cmd, LAUNCH_KEY_SETLOGMASK)) { - resp = launch_data_new_integer(setlogmask(launch_data_get_integer(data))); - } else if (!strcmp(cmd, LAUNCH_KEY_SETUMASK)) { - resp = launch_data_new_integer(umask(launch_data_get_integer(data))); - } else if (!strcmp(cmd, LAUNCH_KEY_SETSTDOUT)) { - resp = launchd_setstdio(STDOUT_FILENO, data); - } else if (!strcmp(cmd, LAUNCH_KEY_SETSTDERR)) { - resp = launchd_setstdio(STDERR_FILENO, data); - } else if (!strcmp(cmd, LAUNCH_KEY_BATCHCONTROL)) { - batch_job_enable(launch_data_get_bool(data), rmc->c); - resp = launch_data_new_errno(0); } rmc->resp = resp; @@ -448,10 +420,8 @@ ipc_readmsg2(launch_data_t data, const char *cmd, void *context) void ipc_close(struct conncb *c) { - batch_job_enable(true, c); - - SLIST_REMOVE(&connections, c, conncb, sle); - launchd_close(c->conn); + LIST_REMOVE(c, sle); + launchd_close(c->conn, runtime_close); free(c); } @@ -471,15 +441,16 @@ adjust_rlimits(launch_data_t in) ltmpsz = launch_data_get_opaque_size(in); if (ltmpsz > sizeof(l)) { - syslog(LOG_WARNING, "Too much rlimit data sent!"); + runtime_syslog(LOG_WARNING, "Too much rlimit data sent!"); ltmpsz = sizeof(l); } for (i = 0; i < (ltmpsz / sizeof(struct rlimit)); i++) { - if (ltmp[i].rlim_cur == l[i].rlim_cur && ltmp[i].rlim_max == l[i].rlim_max) + if (ltmp[i].rlim_cur == l[i].rlim_cur && ltmp[i].rlim_max == l[i].rlim_max) { continue; + } - if (/* XXX readcfg_pid && */ getpid() == 1) { + if (/* XXX readcfg_pid && */ getpid() == 1 && (i == RLIMIT_NOFILE || i == RLIMIT_NPROC)) { int gmib[] = { CTL_KERN, KERN_MAXPROC }; int pmib[] = { CTL_KERN, KERN_MAXPROCPERUID }; const char *gstr = "kern.maxproc"; @@ -495,8 +466,9 @@ adjust_rlimits(launch_data_t in) break; case RLIMIT_NPROC: /* kernel will not clamp to this value, we must */ - if (gval > (2048 + 20)) + if (gval > (2048 + 20)) { gval = 2048 + 20; + } break; default: break; @@ -505,12 +477,12 @@ adjust_rlimits(launch_data_t in) if (gval > 0) { launchd_assumes(sysctl(gmib, 2, NULL, NULL, &gval, sizeof(gval)) != -1); } else { - syslog(LOG_WARNING, "sysctl(\"%s\"): can't be zero", gstr); + runtime_syslog(LOG_WARNING, "sysctl(\"%s\"): can't be zero", gstr); } if (pval > 0) { launchd_assumes(sysctl(pmib, 2, NULL, NULL, &pval, sizeof(pval)) != -1); } else { - syslog(LOG_WARNING, "sysctl(\"%s\"): can't be zero", pstr); + runtime_syslog(LOG_WARNING, "sysctl(\"%s\"): can't be zero", pstr); } } launchd_assumes(setrlimit(i, ltmp + i) != -1); diff --git a/launchd/src/launchd_unix_ipc.h b/launchd/src/launchd_unix_ipc.h index 82440fd..a318ebb 100644 --- a/launchd/src/launchd_unix_ipc.h +++ b/launchd/src/launchd_unix_ipc.h @@ -20,23 +20,29 @@ * @APPLE_APACHE_LICENSE_HEADER_END@ */ +#include + +#include "launchd_runtime.h" +#include "launchd_core_logic.h" +#include "liblaunch_private.h" + struct conncb { kq_callback kqconn_callback; - SLIST_ENTRY(conncb) sle; + LIST_ENTRY(conncb) sle; launch_t conn; - struct jobcb *j; - int disabled_batch:1, futureflags:31; + job_t j; }; extern char *sockpath; -void ipc_open(int fd, struct jobcb *j); +void ipc_open(int fd, job_t j); +void ipc_close_all_with_job(job_t j); void ipc_close(struct conncb *c); void ipc_callback(void *, struct kevent *); void ipc_readmsg(launch_data_t msg, void *context); void ipc_revoke_fds(launch_data_t o); void ipc_close_fds(launch_data_t o); void ipc_clean_up(void); -void ipc_server_init(int *, size_t); +void ipc_server_init(void); #endif diff --git a/launchd/src/launchproxy.c b/launchd/src/launchproxy.c index 039c81a..4c62dcb 100644 --- a/launchd/src/launchproxy.c +++ b/launchd/src/launchproxy.c @@ -48,12 +48,12 @@ static int kq = 0; static void find_fds(launch_data_t o, const char *key __attribute__((unused)), void *context __attribute__((unused))) { - struct kevent kev; - size_t i; + struct kevent kev; + size_t i; int fd; - switch (launch_data_get_type(o)) { - case LAUNCH_DATA_FD: + switch (launch_data_get_type(o)) { + case LAUNCH_DATA_FD: fd = launch_data_get_fd(o); if (-1 == fd) break; @@ -61,17 +61,17 @@ static void find_fds(launch_data_t o, const char *key __attribute__((unused)), v EV_SET(&kev, fd, EVFILT_READ, EV_ADD, 0, 0, NULL); if (kevent(kq, &kev, 1, NULL, 0, NULL) == -1) syslog(LOG_DEBUG, "kevent(%d): %m", fd); - break; - case LAUNCH_DATA_ARRAY: - for (i = 0; i < launch_data_array_get_count(o); i++) - find_fds(launch_data_array_get_index(o, i), NULL, NULL); - break; - case LAUNCH_DATA_DICTIONARY: - launch_data_dict_iterate(o, find_fds, NULL); - break; - default: - break; - } + break; + case LAUNCH_DATA_ARRAY: + for (i = 0; i < launch_data_array_get_count(o); i++) + find_fds(launch_data_array_get_index(o, i), NULL, NULL); + break; + case LAUNCH_DATA_DICTIONARY: + launch_data_dict_iterate(o, find_fds, NULL); + break; + default: + break; + } } int main(int argc __attribute__((unused)), char *argv[]) @@ -108,7 +108,7 @@ int main(int argc __attribute__((unused)), char *argv[]) tmp = launch_data_dict_lookup(resp, LAUNCH_JOBKEY_TIMEOUT); if (tmp) - timeout.tv_sec = launch_data_get_integer(tmp); + timeout.tv_sec = (int)launch_data_get_integer(tmp); tmp = launch_data_dict_lookup(resp, LAUNCH_JOBKEY_PROGRAM); if (tmp) @@ -182,6 +182,8 @@ int main(int argc __attribute__((unused)), char *argv[]) continue; } + setpgid(0, 0); + if ((tmp = launch_data_dict_lookup(resp, LAUNCH_JOBKEY_SESSIONCREATE)) && launch_data_get_bool(tmp)) { if (SessionCreate) { OSStatus scr = SessionCreate(0, 0); diff --git a/launchd/src/libbootstrap.c b/launchd/src/libbootstrap.c new file mode 100644 index 0000000..dae92fa --- /dev/null +++ b/launchd/src/libbootstrap.c @@ -0,0 +1,207 @@ +/* + * Copyright (c) 1999-2005 Apple Computer, Inc. All rights reserved. + * + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ + +#include "config.h" +#include "libbootstrap_public.h" +#include "libbootstrap_private.h" + +#include "libvproc_public.h" +#include "libvproc_private.h" + +#include +#include +#include +#include +#include +#include + +#include "protocol_vproc.h" + +kern_return_t +bootstrap_create_server(mach_port_t bp, cmd_t server_cmd, uid_t server_uid, boolean_t on_demand, mach_port_t *server_port) +{ + return vproc_mig_create_server(bp, server_cmd, server_uid, on_demand, server_port); +} + +kern_return_t +bootstrap_subset(mach_port_t bp, mach_port_t requestor_port, mach_port_t *subset_port) +{ + return vproc_mig_subset(bp, requestor_port, subset_port); +} + +kern_return_t +bootstrap_unprivileged(mach_port_t bp, mach_port_t *unpriv_port) +{ + kern_return_t kr; + + *unpriv_port = MACH_PORT_NULL; + + kr = mach_port_mod_refs(mach_task_self(), bp, MACH_PORT_RIGHT_SEND, 1); + + if (kr == KERN_SUCCESS) { + *unpriv_port = bp; + } + + return kr; +} + +kern_return_t +bootstrap_parent(mach_port_t bp, mach_port_t *parent_port) +{ + return vproc_mig_parent(bp, parent_port); +} + +kern_return_t +bootstrap_set_policy(mach_port_t bp, pid_t target_pid, uint64_t flags, const char *target_service) +{ + return vproc_mig_set_service_policy(bp, target_pid, flags, target_service ? (char *)target_service : ""); +} + +kern_return_t +bootstrap_register(mach_port_t bp, name_t service_name, mach_port_t sp) +{ + return bootstrap_register2(bp, service_name, sp, 0); +} + +kern_return_t +bootstrap_register2(mach_port_t bp, name_t service_name, mach_port_t sp, uint64_t flags) +{ + kern_return_t kr = vproc_mig_register2(bp, service_name, sp, flags); + + if (kr == VPROC_ERR_TRY_PER_USER) { + mach_port_t puc; + + if (vproc_mig_lookup_per_user_context(bp, 0, &puc) == 0) { + kr = vproc_mig_register2(puc, service_name, sp, flags); + mach_port_deallocate(mach_task_self(), puc); + } + } + + return kr; +} + +kern_return_t +bootstrap_create_service(mach_port_t bp, name_t service_name, mach_port_t *sp) +{ + return vproc_mig_create_service(bp, service_name, sp); +} + +kern_return_t +bootstrap_check_in(mach_port_t bp, name_t service_name, mach_port_t *sp) +{ + return vproc_mig_check_in(bp, service_name, sp); +} + +kern_return_t +bootstrap_look_up_per_user(mach_port_t bp, name_t service_name, uid_t target_user, mach_port_t *sp) +{ + struct stat sb; + kern_return_t kr; + mach_port_t puc; + + if (pthread_main_np() && (stat("/AppleInternal", &sb) != -1)) { + _vproc_log(LOG_WARNING, "Please review the comments in 4890134."); + } + + if ((kr = vproc_mig_lookup_per_user_context(bp, target_user, &puc)) != 0) { + return kr; + } + + kr = vproc_mig_look_up2(puc, service_name, sp, 0, 0); + mach_port_deallocate(mach_task_self(), puc); + + return kr; +} + + +kern_return_t +bootstrap_look_up(mach_port_t bp, name_t service_name, mach_port_t *sp) +{ + return bootstrap_look_up2(bp, service_name, sp, 0, 0); +} + +kern_return_t +bootstrap_look_up2(mach_port_t bp, name_t service_name, mach_port_t *sp, pid_t target_pid, uint64_t flags) +{ + kern_return_t kr; + mach_port_t puc; + + if ((kr = vproc_mig_look_up2(bp, service_name, sp, target_pid, flags)) != VPROC_ERR_TRY_PER_USER) { + return kr; + } + + if ((kr = vproc_mig_lookup_per_user_context(bp, 0, &puc)) != 0) { + return kr; + } + + kr = vproc_mig_look_up2(puc, service_name, sp, target_pid, flags); + mach_port_deallocate(mach_task_self(), puc); + + return kr; +} + +kern_return_t +bootstrap_status(mach_port_t bp, name_t service_name, bootstrap_status_t *service_active) +{ + mach_port_t p; + + if (bootstrap_check_in(bp, service_name, &p) == BOOTSTRAP_SUCCESS) { + mach_port_mod_refs(mach_task_self(), p, MACH_PORT_RIGHT_RECEIVE, -1); + *service_active = BOOTSTRAP_STATUS_ON_DEMAND; + return BOOTSTRAP_SUCCESS; + } else if (bootstrap_look_up(bp, service_name, &p) == BOOTSTRAP_SUCCESS) { + mach_port_deallocate(mach_task_self(), p); + *service_active = BOOTSTRAP_STATUS_ACTIVE; + return BOOTSTRAP_SUCCESS; + } + + return BOOTSTRAP_UNKNOWN_SERVICE; +} + +kern_return_t +bootstrap_info(mach_port_t bp, + name_array_t *service_names, mach_msg_type_number_t *service_namesCnt, + bootstrap_status_array_t *service_active, mach_msg_type_number_t *service_activeCnt) +{ + return vproc_mig_info(bp, service_names, service_namesCnt, + service_active, service_activeCnt); +} + +const char * +bootstrap_strerror(kern_return_t r) +{ + switch (r) { + case BOOTSTRAP_SUCCESS: + return "Success"; + case BOOTSTRAP_NOT_PRIVILEGED: + return "Permission denied"; + case BOOTSTRAP_NAME_IN_USE: + case BOOTSTRAP_SERVICE_ACTIVE: + return "Service name already exists"; + case BOOTSTRAP_UNKNOWN_SERVICE: + return "Unknown service name"; + case BOOTSTRAP_BAD_COUNT: + return "Too many lookups were requested in one request"; + case BOOTSTRAP_NO_MEMORY: + return "Out of memory"; + default: + return mach_error_string(r); + } +} diff --git a/launchd/src/libbootstrap_private.h b/launchd/src/libbootstrap_private.h new file mode 100644 index 0000000..1bcfdaa --- /dev/null +++ b/launchd/src/libbootstrap_private.h @@ -0,0 +1,45 @@ +#ifndef _BOOTSTRAP_PRIVATE_H_ +#define _BOOTSTRAP_PRIVATE_H_ +/* + * Copyright (c) 2007 Apple Inc. All rights reserved. + * + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ + +#include +#include + +__BEGIN_DECLS + +#pragma GCC visibility push(default) + +#define BOOTSTRAP_PER_PID_SERVICE 0x1 +#define BOOTSTRAP_ALLOW_LOOKUP 0x2 + +kern_return_t bootstrap_register2(mach_port_t bp, name_t service_name, mach_port_t sp, uint64_t flags); + +kern_return_t bootstrap_look_up2(mach_port_t bp, name_t service_name, mach_port_t *sp, pid_t target_pid, uint64_t flags); + +kern_return_t bootstrap_look_up_per_user(mach_port_t bp, name_t service_name, uid_t target_user, mach_port_t *sp); + +kern_return_t bootstrap_set_policy(mach_port_t bp, pid_t target_pid, uint64_t flags, const char *target_service); + +#pragma GCC visibility pop + +__END_DECLS + +#endif diff --git a/launchd/src/bootstrap_public.h b/launchd/src/libbootstrap_public.h similarity index 92% rename from launchd/src/bootstrap_public.h rename to launchd/src/libbootstrap_public.h index bdd7485..b76c52a 100644 --- a/launchd/src/bootstrap_public.h +++ b/launchd/src/libbootstrap_public.h @@ -86,6 +86,8 @@ __BEGIN_DECLS +#pragma GCC visibility push(default) + #define BOOTSTRAP_MAX_NAME_LEN 128 #define BOOTSTRAP_MAX_CMD_LEN 512 @@ -196,7 +198,8 @@ kern_return_t bootstrap_subset( */ kern_return_t bootstrap_unprivileged( mach_port_t bp, - mach_port_t *unpriv_port); + mach_port_t *unpriv_port) + AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_5; /* * bootstrap_parent() @@ -228,6 +231,30 @@ kern_return_t bootstrap_parent( * do so. (Registering MACH_PORT_NULL is especially useful for shutting * down declared services). * + * This API is deprecated. Old scenarios and recommendations: + * + * 1) If the code was registering a well known name, please switch to launchd. + * + * 2) If the code was registering a dynamically generated string and passing + * the string to other applications, please rewrite the code to send a Mach + * send-right directly. + * + * 3) If the launchd job maintained an optional Mach service, please reserve + * the name with launchd and control the presense of the service through + * ownership of the Mach receive right like so. + * + * MachServices + * + * com.apple.windowserver + * + * com.apple.windowserver.active + * + * HideUntilCheckIn + * + * + * + * + * * Errors: Returns appropriate kernel errors on rpc failure. * Returns BOOTSTRAP_NOT_PRIVILEGED, if request directed to * bootstrap port without privilege. @@ -237,7 +264,8 @@ kern_return_t bootstrap_parent( kern_return_t bootstrap_register( mach_port_t bp, name_t service_name, - mach_port_t sp); + mach_port_t sp) + AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_5; /* * bootstrap_create_service() @@ -316,6 +344,8 @@ kern_return_t bootstrap_status( */ const char *bootstrap_strerror(kern_return_t r) __attribute__((__nothrow__, __pure__, __warn_unused_result__)); +#pragma GCC visibility pop + __END_DECLS #endif diff --git a/launchd/src/liblaunch.c b/launchd/src/liblaunch.c index ceebfef..cd36506 100644 --- a/launchd/src/liblaunch.c +++ b/launchd/src/liblaunch.c @@ -17,6 +17,12 @@ * * @APPLE_APACHE_LICENSE_HEADER_END@ */ + +#include "config.h" +#include "liblaunch_public.h" +#include "liblaunch_private.h" +#include "liblaunch_internal.h" + #include #include #include @@ -32,11 +38,12 @@ #include #include #include +#include -#include "launch.h" -#include "launch_priv.h" -#include "bootstrap_public.h" -#include "bootstrap_private.h" +#include "libbootstrap_public.h" +#include "libvproc_public.h" +#include "libvproc_private.h" +#include "libvproc_internal.h" /* __OSBogusByteSwap__() must not really exist in the symbol namespace * in order for the following to generate an error at build time. @@ -116,7 +123,7 @@ struct _launch_data { mach_port_t mp; int err; long long number; - bool boolean; + uint32_t boolean; /* We'd use 'bool' but this struct needs to be used under Rosetta, and sizeof(bool) is different between PowerPC and Intel */ double float_num; }; }; @@ -133,8 +140,6 @@ struct _launch { int fd; }; -static void make_msg_and_cmsg(launch_data_t, void **, size_t *, int **, size_t *); -static launch_data_t make_data(launch_t, size_t *, size_t *); static launch_data_t launch_data_array_pop_first(launch_data_t where); static int _fd(int fd); static void launch_client_init(void); @@ -157,6 +162,7 @@ launch_client_init(void) char *where = getenv(LAUNCHD_SOCKET_ENV); char *_launchd_fd = getenv(LAUNCHD_TRUSTED_FD_ENV); int dfd, lfd = -1; + name_t spath; _lc = calloc(1, sizeof(struct _launch_client)); @@ -181,10 +187,14 @@ launch_client_init(void) if (where && where[0] != '\0') { strncpy(sun.sun_path, where, sizeof(sun.sun_path)); - } else if (getuid() == 0) { - strncpy(sun.sun_path, LAUNCHD_SOCK_PREFIX "/sock", sizeof(sun.sun_path)); + } else if (!getenv("SUDO_COMMAND") && _vprocmgr_getsocket(spath) == 0) { + size_t min_len; + + min_len = sizeof(sun.sun_path) < sizeof(spath) ? sizeof(sun.sun_path) : sizeof(spath); + + strncpy(sun.sun_path, spath, min_len); } else { - goto out_bad; + strncpy(sun.sun_path, LAUNCHD_SOCK_PREFIX "/sock", sizeof(sun.sun_path)); } if ((lfd = _fd(socket(AF_UNIX, SOCK_STREAM, 0))) == -1) @@ -200,7 +210,7 @@ launch_client_init(void) return; out_bad: if (_lc->l) - launchd_close(_lc->l); + launchd_close(_lc->l, close); else if (lfd != -1) close(lfd); if (_lc) @@ -337,7 +347,7 @@ bool launch_data_array_set_index(launch_data_t where, launch_data_t what, size_t ind) { if ((ind + 1) >= where->_array_cnt) { - where->_array = realloc(where->_array, (ind + 1) * sizeof(launch_data_t)); + where->_array = reallocf(where->_array, (ind + 1) * sizeof(launch_data_t)); memset(where->_array + where->_array_cnt, 0, (ind + 1 - where->_array_cnt) * sizeof(launch_data_t)); where->_array_cnt = ind + 1; } @@ -362,7 +372,7 @@ launch_data_t launch_data_array_pop_first(launch_data_t where) { launch_data_t r = NULL; - + if (where->_array_cnt > 0) { r = where->_array[0]; memmove(where->_array, where->_array + 1, (where->_array_cnt - 1) * sizeof(launch_data_t)); @@ -515,23 +525,23 @@ launchd_getfd(launch_t l) launch_t launchd_fdopen(int fd) { - launch_t c; + launch_t c; - c = calloc(1, sizeof(struct _launch)); + c = calloc(1, sizeof(struct _launch)); if (!c) return NULL; - c->fd = fd; + c->fd = fd; fcntl(fd, F_SETFL, O_NONBLOCK); - if ((c->sendbuf = malloc(0)) == NULL) + if ((c->sendbuf = malloc(0)) == NULL) goto out_bad; - if ((c->sendfds = malloc(0)) == NULL) + if ((c->sendfds = malloc(0)) == NULL) goto out_bad; - if ((c->recvbuf = malloc(0)) == NULL) + if ((c->recvbuf = malloc(0)) == NULL) goto out_bad; - if ((c->recvfds = malloc(0)) == NULL) + if ((c->recvfds = malloc(0)) == NULL) goto out_bad; return c; @@ -550,7 +560,7 @@ out_bad: } void -launchd_close(launch_t lh) +launchd_close(launch_t lh, typeof(close) closefunc) { if (lh->sendbuf) free(lh->sendbuf); @@ -560,21 +570,23 @@ launchd_close(launch_t lh) free(lh->recvbuf); if (lh->recvfds) free(lh->recvfds); - close(lh->fd); + closefunc(lh->fd); free(lh); } -void -make_msg_and_cmsg(launch_data_t d, void **where, size_t *len, int **fd_where, size_t *fdcnt) +#define ROUND_TO_64BIT_WORD_SIZE(x) ((x + 7) & ~7) + +size_t +launch_data_pack(launch_data_t d, void *where, size_t len, int *fd_where, size_t *fd_cnt) { - launch_data_t o_in_w; - size_t i; + launch_data_t o_in_w = where; + size_t i, rsz, total_data_len = sizeof(struct _launch_data); - *where = realloc(*where, *len + sizeof(struct _launch_data)); + if (total_data_len > len) { + return 0; + } - o_in_w = *where + *len; - memset(o_in_w, 0, sizeof(struct _launch_data)); - *len += sizeof(struct _launch_data); + where += total_data_len; o_in_w->type = host2big(d->type); @@ -593,45 +605,60 @@ make_msg_and_cmsg(launch_data_t d, void **where, size_t *len, int **fd_where, si break; case LAUNCH_DATA_FD: o_in_w->fd = host2big(d->fd); - if (d->fd != -1) { - *fd_where = realloc(*fd_where, (*fdcnt + 1) * sizeof(int)); - (*fd_where)[*fdcnt] = d->fd; - (*fdcnt)++; + if (fd_where && d->fd != -1) { + fd_where[*fd_cnt] = d->fd; + (*fd_cnt)++; } break; case LAUNCH_DATA_STRING: o_in_w->string_len = host2big(d->string_len); - *where = realloc(*where, *len + strlen(d->string) + 1); - memcpy(*where + *len, d->string, strlen(d->string) + 1); - *len += strlen(d->string) + 1; + total_data_len += ROUND_TO_64BIT_WORD_SIZE(strlen(d->string) + 1); + if (total_data_len > len) { + return 0; + } + memcpy(where, d->string, strlen(d->string) + 1); break; case LAUNCH_DATA_OPAQUE: o_in_w->opaque_size = host2big(d->opaque_size); - *where = realloc(*where, *len + d->opaque_size); - memcpy(*where + *len, d->opaque, d->opaque_size); - *len += d->opaque_size; + total_data_len += ROUND_TO_64BIT_WORD_SIZE(d->opaque_size); + if (total_data_len > len) { + return 0; + } + memcpy(where, d->opaque, d->opaque_size); break; case LAUNCH_DATA_DICTIONARY: case LAUNCH_DATA_ARRAY: o_in_w->_array_cnt = host2big(d->_array_cnt); - *where = realloc(*where, *len + (d->_array_cnt * sizeof(launch_data_t))); - memcpy(*where + *len, d->_array, d->_array_cnt * sizeof(launch_data_t)); - *len += d->_array_cnt * sizeof(launch_data_t); + total_data_len += d->_array_cnt * sizeof(uint64_t); + if (total_data_len > len) { + return 0; + } - for (i = 0; i < d->_array_cnt; i++) - make_msg_and_cmsg(d->_array[i], where, len, fd_where, fdcnt); + where += d->_array_cnt * sizeof(uint64_t); + + for (i = 0; i < d->_array_cnt; i++) { + rsz = launch_data_pack(d->_array[i], where, len - total_data_len, fd_where, fd_cnt); + if (rsz == 0) { + return 0; + } + where += rsz; + total_data_len += rsz; + } break; default: break; } + + return total_data_len; } -static launch_data_t make_data(launch_t conn, size_t *data_offset, size_t *fdoffset) +launch_data_t +launch_data_unpack(void *data, size_t data_size, int *fds, size_t fd_cnt, size_t *data_offset, size_t *fdoffset) { - launch_data_t r = conn->recvbuf + *data_offset; + launch_data_t r = data + *data_offset; size_t i, tmpcnt; - if ((conn->recvlen - *data_offset) < sizeof(struct _launch_data)) + if ((data_size - *data_offset) < sizeof(struct _launch_data)) return NULL; *data_offset += sizeof(struct _launch_data); @@ -639,14 +666,14 @@ static launch_data_t make_data(launch_t conn, size_t *data_offset, size_t *fdoff case LAUNCH_DATA_DICTIONARY: case LAUNCH_DATA_ARRAY: tmpcnt = big2host(r->_array_cnt); - if ((conn->recvlen - *data_offset) < (tmpcnt * sizeof(launch_data_t))) { + if ((data_size - *data_offset) < (tmpcnt * sizeof(uint64_t))) { errno = EAGAIN; return NULL; } - r->_array = conn->recvbuf + *data_offset; - *data_offset += tmpcnt * sizeof(launch_data_t); + r->_array = data + *data_offset; + *data_offset += tmpcnt * sizeof(uint64_t); for (i = 0; i < tmpcnt; i++) { - r->_array[i] = make_data(conn, data_offset, fdoffset); + r->_array[i] = launch_data_unpack(data, data_size, fds, fd_cnt, data_offset, fdoffset); if (r->_array[i] == NULL) return NULL; } @@ -654,27 +681,27 @@ static launch_data_t make_data(launch_t conn, size_t *data_offset, size_t *fdoff break; case LAUNCH_DATA_STRING: tmpcnt = big2host(r->string_len); - if ((conn->recvlen - *data_offset) < (tmpcnt + 1)) { + if ((data_size - *data_offset) < (tmpcnt + 1)) { errno = EAGAIN; return NULL; } - r->string = conn->recvbuf + *data_offset; + r->string = data + *data_offset; r->string_len = tmpcnt; - *data_offset += tmpcnt + 1; + *data_offset += ROUND_TO_64BIT_WORD_SIZE(tmpcnt + 1); break; case LAUNCH_DATA_OPAQUE: tmpcnt = big2host(r->opaque_size); - if ((conn->recvlen - *data_offset) < tmpcnt) { + if ((data_size - *data_offset) < tmpcnt) { errno = EAGAIN; return NULL; } - r->opaque = conn->recvbuf + *data_offset; + r->opaque = data + *data_offset; r->opaque_size = tmpcnt; - *data_offset += tmpcnt; + *data_offset += ROUND_TO_64BIT_WORD_SIZE(tmpcnt); break; case LAUNCH_DATA_FD: - if (r->fd != -1) { - r->fd = _fd(conn->recvfds[*fdoffset]); + if (r->fd != -1 && fd_cnt > *fdoffset) { + r->fd = _fd(fds[*fdoffset]); *fdoffset += 1; } break; @@ -713,22 +740,40 @@ int launchd_msg_send(launch_t lh, launch_data_t d) memset(&mh, 0, sizeof(mh)); + /* confirm that the next hack works */ + assert((d && lh->sendlen == 0) || (!d && lh->sendlen)); + if (d) { - uint64_t msglen = lh->sendlen; + size_t fd_slots_used = 0; + size_t good_enough_size = 10 * 1024 * 1024; + uint64_t msglen; + + /* hack, see the above assert to verify "correctness" */ + free(lh->sendbuf); + lh->sendbuf = malloc(good_enough_size); + free(lh->sendfds); + lh->sendfds = malloc(4 * 1024); + + lh->sendlen = launch_data_pack(d, lh->sendbuf, good_enough_size, lh->sendfds, &fd_slots_used); + + if (lh->sendlen == 0) { + errno = ENOMEM; + return -1; + } - make_msg_and_cmsg(d, &lh->sendbuf, &lh->sendlen, &lh->sendfds, &lh->sendfdcnt); + lh->sendfdcnt = fd_slots_used; - msglen = (lh->sendlen - msglen) + sizeof(struct launch_msg_header); + msglen = lh->sendlen + sizeof(struct launch_msg_header); /* type promotion to make the host2big() macro work right */ lmh.len = host2big(msglen); lmh.magic = host2big(LAUNCH_MSG_HEADER_MAGIC); iov[0].iov_base = &lmh; iov[0].iov_len = sizeof(lmh); mh.msg_iov = iov; - mh.msg_iovlen = 2; + mh.msg_iovlen = 2; } else { mh.msg_iov = iov + 1; - mh.msg_iovlen = 1; + mh.msg_iovlen = 1; } iov[1].iov_base = lh->sendbuf; @@ -850,6 +895,12 @@ launch_msg_internal(launch_data_t d) { launch_data_t resp = NULL; + if (d && (launch_data_get_type(d) == LAUNCH_DATA_STRING) + && (strcmp(launch_data_get_string(d), LAUNCH_KEY_GETJOBS) == 0) + && vproc_swap_complex(NULL, VPROC_GSK_ALLJOBS, NULL, &resp) == NULL) { + return resp; + } + pthread_once(&_lc_once, launch_client_init); if (!_lc) { @@ -865,7 +916,7 @@ launch_msg_internal(launch_data_t d) goto out; } while (launchd_msg_send(_lc->l, NULL) == -1); } - + while (resp == NULL) { if (d == NULL && launch_data_array_get_count(_lc->async_resp) > 0) { resp = launch_data_array_pop_first(_lc->async_resp); @@ -899,15 +950,15 @@ int launchd_msg_recv(launch_t lh, void (*cb)(launch_data_t, void *), void *conte struct cmsghdr *cm = alloca(4096); launch_data_t rmsg = NULL; size_t data_offset, fd_offset; - struct msghdr mh; - struct iovec iov; + struct msghdr mh; + struct iovec iov; int r; - memset(&mh, 0, sizeof(mh)); - mh.msg_iov = &iov; - mh.msg_iovlen = 1; + memset(&mh, 0, sizeof(mh)); + mh.msg_iov = &iov; + mh.msg_iovlen = 1; - lh->recvbuf = realloc(lh->recvbuf, lh->recvlen + 8*1024); + lh->recvbuf = reallocf(lh->recvbuf, lh->recvlen + 8*1024); iov.iov_base = lh->recvbuf + lh->recvlen; iov.iov_len = 8*1024; @@ -926,7 +977,7 @@ int launchd_msg_recv(launch_t lh, void (*cb)(launch_data_t, void *), void *conte } lh->recvlen += r; if (mh.msg_controllen > 0) { - lh->recvfds = realloc(lh->recvfds, lh->recvfdcnt * sizeof(int) + mh.msg_controllen - sizeof(struct cmsghdr)); + lh->recvfds = reallocf(lh->recvfds, lh->recvfdcnt * sizeof(int) + mh.msg_controllen - sizeof(struct cmsghdr)); memcpy(lh->recvfds + lh->recvfdcnt, CMSG_DATA(cm), mh.msg_controllen - sizeof(struct cmsghdr)); lh->recvfdcnt += (mh.msg_controllen - sizeof(struct cmsghdr)) / sizeof(int); } @@ -953,7 +1004,7 @@ int launchd_msg_recv(launch_t lh, void (*cb)(launch_data_t, void *), void *conte goto need_more_data; } - if ((rmsg = make_data(lh, &data_offset, &fd_offset)) == NULL) { + if ((rmsg = launch_data_unpack(lh->recvbuf, lh->recvlen, lh->recvfds, lh->recvfdcnt, &data_offset, &fd_offset)) == NULL) { errno = EBADRPC; goto out_bad; } @@ -1016,41 +1067,24 @@ launch_data_t launch_data_copy(launch_data_t o) return r; } -void launchd_batch_enable(bool val) +void +launchd_batch_enable(bool b) { - launch_data_t resp, tmp, msg; - - tmp = launch_data_alloc(LAUNCH_DATA_BOOL); - launch_data_set_bool(tmp, val); - - msg = launch_data_alloc(LAUNCH_DATA_DICTIONARY); - launch_data_dict_insert(msg, tmp, LAUNCH_KEY_BATCHCONTROL); + int64_t val = b; - resp = launch_msg(msg); - - launch_data_free(msg); - - if (resp) - launch_data_free(resp); + vproc_swap_integer(NULL, VPROC_GSK_GLOBAL_ON_DEMAND, &val, NULL); } -bool launchd_batch_query(void) +bool +launchd_batch_query(void) { - launch_data_t resp, msg = launch_data_alloc(LAUNCH_DATA_STRING); - bool rval = true; - - launch_data_set_string(msg, LAUNCH_KEY_BATCHQUERY); + int64_t val; - resp = launch_msg(msg); - - launch_data_free(msg); - - if (resp) { - if (launch_data_get_type(resp) == LAUNCH_DATA_BOOL) - rval = launch_data_get_bool(resp); - launch_data_free(resp); + if (vproc_swap_integer(NULL, VPROC_GSK_GLOBAL_ON_DEMAND, NULL, &val) == NULL) { + return (bool)val; } - return rval; + + return false; } static int _fd(int fd) @@ -1065,7 +1099,7 @@ launch_data_t launch_data_new_errno(int e) launch_data_t r = launch_data_alloc(LAUNCH_DATA_ERRNO); if (r) - launch_data_set_errno(r, e); + launch_data_set_errno(r, e); return r; } @@ -1075,7 +1109,7 @@ launch_data_t launch_data_new_fd(int fd) launch_data_t r = launch_data_alloc(LAUNCH_DATA_FD); if (r) - launch_data_set_fd(r, fd); + launch_data_set_fd(r, fd); return r; } @@ -1085,7 +1119,7 @@ launch_data_t launch_data_new_machport(mach_port_t p) launch_data_t r = launch_data_alloc(LAUNCH_DATA_MACHPORT); if (r) - launch_data_set_machport(r, p); + launch_data_set_machport(r, p); return r; } @@ -1150,78 +1184,29 @@ launch_data_t launch_data_new_opaque(const void *o, size_t os) return r; } -static pid_t -fexecv_as_user(const char *login, uid_t u, gid_t g, char *const argv[]) +void +load_launchd_jobs_at_loginwindow_prompt(int flags __attribute__((unused)), ...) { - int i, dtsz; - pid_t p; - - if ((p = fork()) != 0) - return p; - - chdir("/"); - - seteuid(0); - setegid(0); - initgroups(login, g); - setgid(g); - setuid(u); - - dtsz = getdtablesize(); - - for (i = STDERR_FILENO + 1; i < dtsz; i++) - close(i); - - execv(argv[0], argv); - _exit(EXIT_FAILURE); + _vprocmgr_init("LoginWindow"); } pid_t -create_and_switch_to_per_session_launchd(const char *login, int flags, ...) +create_and_switch_to_per_session_launchd(const char *login __attribute__((unused)), int flags __attribute__((unused)), ...) { - static char *const ldargv[] = { "/sbin/launchd", "-S", "Aqua", NULL }; - char *largv[] = { "/bin/launchctl", "load", "-S", "Aqua", "-D", "all", "/etc/mach_init_per_user.d", NULL }; mach_port_t bezel_ui_server; - struct passwd *pwe; struct stat sb; - int wstatus; - name_t sp; - pid_t p, ldp; - uid_t u; - gid_t g; - - if ((pwe = getpwnam(login)) == NULL) - return -1; - - u = pwe->pw_uid; - g = pwe->pw_gid; - - if ((ldp = fexecv_as_user(login, u, g, ldargv)) == -1) - return -1; + uid_t target_user = geteuid() ? geteuid() : getuid(); - while (bootstrap_getsocket(bootstrap_port, sp) != BOOTSTRAP_SUCCESS) - usleep(20000); - - setenv(LAUNCHD_SOCKET_ENV, sp, 1); - - if (flags & LOAD_ONLY_SAFEMODE_LAUNCHAGENTS) - largv[5] = "system"; - - if ((p = fexecv_as_user(login, u, g, largv)) == -1) - return -1; - - if (waitpid(p, &wstatus, 0) != p) - return -1; - - if (!(WIFEXITED(wstatus) && WEXITSTATUS(wstatus) == 0)) + if (_vprocmgr_move_subset_to_user(target_user, "Aqua")) { return -1; + } #define BEZEL_UI_PATH "/System/Library/LoginPlugins/BezelServices.loginPlugin/Contents/Resources/BezelUI/BezelUIServer" #define BEZEL_UI_PLIST "/System/Library/LaunchAgents/com.apple.BezelUIServer.plist" #define BEZEL_UI_SERVICE "BezelUI" if (!(stat(BEZEL_UI_PLIST, &sb) == 0 && S_ISREG(sb.st_mode))) { - if (bootstrap_create_server(bootstrap_port, BEZEL_UI_PATH, u, true, &bezel_ui_server) == BOOTSTRAP_SUCCESS) { + if (bootstrap_create_server(bootstrap_port, BEZEL_UI_PATH, target_user, true, &bezel_ui_server) == BOOTSTRAP_SUCCESS) { mach_port_t srv; if (bootstrap_create_service(bezel_ui_server, BEZEL_UI_SERVICE, &srv) == BOOTSTRAP_SUCCESS) { @@ -1232,5 +1217,5 @@ create_and_switch_to_per_session_launchd(const char *login, int flags, ...) } } - return ldp; + return 1; } diff --git a/launchd/src/liblaunch_internal.h b/launchd/src/liblaunch_internal.h new file mode 100644 index 0000000..96154d2 --- /dev/null +++ b/launchd/src/liblaunch_internal.h @@ -0,0 +1,30 @@ +#ifndef _LAUNCH_INTERNAL_H_ +#define _LAUNCH_INTERNAL_H_ +/* + * Copyright (c) 2007 Apple Computer, Inc. All rights reserved. + * + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ + +#pragma GCC visibility push(default) + +size_t launch_data_pack(launch_data_t d, void *where, size_t len, int *fd_where, size_t *fdslotsleft); +launch_data_t launch_data_unpack(void *data, size_t data_size, int *fds, size_t fd_cnt, size_t *data_offset, size_t *fdoffset); + +#pragma GCC visibility pop + +#endif diff --git a/launchd/src/launch_priv.h b/launchd/src/liblaunch_private.h similarity index 69% rename from launchd/src/launch_priv.h rename to launchd/src/liblaunch_private.h index 3b016d3..bad934d 100644 --- a/launchd/src/launch_priv.h +++ b/launchd/src/liblaunch_private.h @@ -20,24 +20,22 @@ #ifndef _LAUNCH_PRIV_H_ #define _LAUNCH_PRIV_H_ +#include +#include #include +#include +#include + +#pragma GCC visibility push(default) __BEGIN_DECLS -#define LAUNCH_KEY_GETUSERENVIRONMENT "GetUserEnvironment" #define LAUNCH_KEY_SETUSERENVIRONMENT "SetUserEnvironment" #define LAUNCH_KEY_UNSETUSERENVIRONMENT "UnsetUserEnvironment" -#define LAUNCH_KEY_SETSTDOUT "SetStandardOut" -#define LAUNCH_KEY_SETSTDERR "SetStandardError" #define LAUNCH_KEY_SHUTDOWN "Shutdown" #define LAUNCH_KEY_SINGLEUSER "SingleUser" #define LAUNCH_KEY_GETRESOURCELIMITS "GetResourceLimits" #define LAUNCH_KEY_SETRESOURCELIMITS "SetResourceLimits" -#define LAUNCH_KEY_RELOADTTYS "ReloadTTYS" -#define LAUNCH_KEY_SETLOGMASK "SetLogMask" -#define LAUNCH_KEY_GETLOGMASK "GetLogMask" -#define LAUNCH_KEY_SETUMASK "SetUmask" -#define LAUNCH_KEY_GETUMASK "GetUmask" #define LAUNCH_KEY_GETRUSAGESELF "GetResourceUsageSelf" #define LAUNCH_KEY_GETRUSAGECHILDREN "GetResourceUsageChildren" @@ -48,16 +46,27 @@ __BEGIN_DECLS #define LAUNCH_KEY_BATCHCONTROL "BatchControl" #define LAUNCH_KEY_BATCHQUERY "BatchQuery" +#define LAUNCH_JOBKEY_QUARANTINEDATA "QuarantineData" +#define LAUNCH_JOBKEY_SANDBOXPROFILE "SandboxProfile" +#define LAUNCH_JOBKEY_SANDBOXFLAGS "SandboxFlags" +#define LAUNCH_JOBKEY_SANDBOX_NAMED "Named" + +#define LAUNCH_JOBKEY_ENTERKERNELDEBUGGERBEFOREKILL "EnterKernelDebuggerBeforeKill" +#define LAUNCH_JOBKEY_PERJOBMACHSERVICES "PerJobMachServices" +#define LAUNCH_JOBKEY_SERVICEIPC "ServiceIPC" +#define LAUNCH_JOBKEY_BINARYORDERPREFERENCE "BinaryOrderPreference" + #define LAUNCH_JOBKEY_MACH_KUNCSERVER "kUNCServer" #define LAUNCH_JOBKEY_MACH_EXCEPTIONSERVER "ExceptionServer" #define LAUNCH_JOBKEY_MACH_TASKSPECIALPORT "TaskSpecialPort" #define LAUNCH_JOBKEY_MACH_HOSTSPECIALPORT "HostSpecialPort" +#define LAUNCH_JOBKEY_MACH_ENTERKERNELDEBUGGERONCLOSE "EnterKernelDebuggerOnClose" typedef struct _launch *launch_t; launch_t launchd_fdopen(int); int launchd_getfd(launch_t); -void launchd_close(launch_t); +void launchd_close(launch_t, typeof(close) closefunc); launch_data_t launch_data_new_errno(int); bool launch_data_set_errno(launch_data_t, int); @@ -69,13 +78,17 @@ int launchd_msg_recv(launch_t, void (*)(launch_data_t, void *), void *); * * After this call, the task's bootstrap port is set to the per session launchd. * - * This returns the PID on of the per session launchd, and -1 on failure. - * - * If launchd terminates, loginwindow should exit. - * If loginwindow terminates, launchd will exit. + * This returns 1 on success (it used to return otherwise), and -1 on failure. */ #define LOAD_ONLY_SAFEMODE_LAUNCHAGENTS 1 -pid_t create_and_switch_to_per_session_launchd(const char *login, int flags, ...); +pid_t create_and_switch_to_per_session_launchd(const char * /* loginname */, int flags, ...); + +/* Also for LoginWindow. + * + * This is will load jobs at the LoginWindow prompt. + */ +void load_launchd_jobs_at_loginwindow_prompt(int flags, ...); + /* batch jobs will be implicity re-enabled when the last application who * disabled them exits. @@ -90,7 +103,6 @@ bool launchd_batch_query(void); */ #define SPAWN_VIA_LAUNCHD_STOPPED 0x0001 -#define SPAWN_VIA_LAUNCHD_FORCE_PPC 0x0002 struct spawn_via_launchd_attr { uint64_t spawn_flags; @@ -99,9 +111,14 @@ struct spawn_via_launchd_attr { const char *const * spawn_env; const mode_t * spawn_umask; mach_port_t * spawn_observer_port; + const cpu_type_t * spawn_binpref; + size_t spawn_binpref_cnt; + qtn_proc_t spawn_quarantine; + const char * spawn_seatbelt_profile; + const uint64_t * spawn_seatbelt_flags; }; -#define spawn_via_launchd(a, b, c) _spawn_via_launchd(a, b, c, 0) +#define spawn_via_launchd(a, b, c) _spawn_via_launchd(a, b, c, 2) pid_t _spawn_via_launchd( const char *label, const char *const *argv, @@ -115,4 +132,7 @@ kern_return_t mpm_uncork_fork(mach_port_t ajob); __END_DECLS +#pragma GCC visibility pop + + #endif diff --git a/launchd/src/launch.h b/launchd/src/liblaunch_public.h similarity index 91% rename from launchd/src/launch.h rename to launchd/src/liblaunch_public.h index 38b5d8d..ca12880 100644 --- a/launchd/src/launch.h +++ b/launchd/src/liblaunch_public.h @@ -25,6 +25,8 @@ #include #include +#pragma GCC visibility push(default) + __BEGIN_DECLS #ifdef __GNUC__ @@ -47,7 +49,6 @@ __BEGIN_DECLS #define LAUNCH_KEY_STARTJOB "StartJob" #define LAUNCH_KEY_STOPJOB "StopJob" #define LAUNCH_KEY_GETJOB "GetJob" -#define LAUNCH_KEY_GETJOBWITHHANDLES "GetJobWithHandles" #define LAUNCH_KEY_GETJOBS "GetJobs" #define LAUNCH_KEY_CHECKIN "CheckIn" @@ -56,9 +57,11 @@ __BEGIN_DECLS #define LAUNCH_JOBKEY_USERNAME "UserName" #define LAUNCH_JOBKEY_GROUPNAME "GroupName" #define LAUNCH_JOBKEY_TIMEOUT "TimeOut" +#define LAUNCH_JOBKEY_EXITTIMEOUT "ExitTimeOut" #define LAUNCH_JOBKEY_INITGROUPS "InitGroups" #define LAUNCH_JOBKEY_SOCKETS "Sockets" #define LAUNCH_JOBKEY_MACHSERVICES "MachServices" +#define LAUNCH_JOBKEY_MACHSERVICELOOKUPPOLICIES "MachServiceLookupPolicies" #define LAUNCH_JOBKEY_INETDCOMPATIBILITY "inetdCompatibility" #define LAUNCH_JOBKEY_ENABLEGLOBBING "EnableGlobbing" #define LAUNCH_JOBKEY_PROGRAMARGUMENTS "ProgramArguments" @@ -71,14 +74,15 @@ __BEGIN_DECLS #define LAUNCH_JOBKEY_RUNATLOAD "RunAtLoad" #define LAUNCH_JOBKEY_ROOTDIRECTORY "RootDirectory" #define LAUNCH_JOBKEY_WORKINGDIRECTORY "WorkingDirectory" -#define LAUNCH_JOBKEY_SERVICEDESCRIPTION "ServiceDescription" #define LAUNCH_JOBKEY_ENVIRONMENTVARIABLES "EnvironmentVariables" #define LAUNCH_JOBKEY_USERENVIRONMENTVARIABLES "UserEnvironmentVariables" -#define LAUNCH_JOBKEY_FORCEPOWERPC "ForcePowerPC" #define LAUNCH_JOBKEY_UMASK "Umask" #define LAUNCH_JOBKEY_NICE "Nice" +#define LAUNCH_JOBKEY_HOPEFULLYEXITSFIRST "HopefullyExitsFirst" +#define LAUNCH_JOBKEY_HOPEFULLYEXITSLAST "HopefullyExitsLast" #define LAUNCH_JOBKEY_LOWPRIORITYIO "LowPriorityIO" #define LAUNCH_JOBKEY_SESSIONCREATE "SessionCreate" +#define LAUNCH_JOBKEY_STARTONMOUNT "StartOnMount" #define LAUNCH_JOBKEY_SOFTRESOURCELIMITS "SoftResourceLimits" #define LAUNCH_JOBKEY_HARDRESOURCELIMITS "HardResourceLimits" #define LAUNCH_JOBKEY_STANDARDOUTPATH "StandardOutPath" @@ -92,7 +96,9 @@ __BEGIN_DECLS #define LAUNCH_JOBKEY_BONJOURFDS "BonjourFDs" #define LAUNCH_JOBKEY_LASTEXITSTATUS "LastExitStatus" #define LAUNCH_JOBKEY_PID "PID" -#define LAUNCH_JOBKEY_SUBJOBS "SubJobs" +#define LAUNCH_JOBKEY_THROTTLEINTERVAL "ThrottleInterval" +#define LAUNCH_JOBKEY_LAUNCHONLYONCE "LaunchOnlyOnce" +#define LAUNCH_JOBKEY_ABANDONPROCESSGROUP "AbandonProcessGroup" #define LAUNCH_JOBINETDCOMPATIBILITY_WAIT "Wait" @@ -102,6 +108,8 @@ __BEGIN_DECLS #define LAUNCH_JOBKEY_KEEPALIVE_SUCCESSFULEXIT "SuccessfulExit" #define LAUNCH_JOBKEY_KEEPALIVE_NETWORKSTATE "NetworkState" #define LAUNCH_JOBKEY_KEEPALIVE_PATHSTATE "PathState" +#define LAUNCH_JOBKEY_KEEPALIVE_OTHERJOBACTIVE "OtherJobActive" +#define LAUNCH_JOBKEY_KEEPALIVE_OTHERJOBENABLED "OtherJobEnabled" #define LAUNCH_JOBKEY_CAL_MINUTE "Minute" #define LAUNCH_JOBKEY_CAL_HOUR "Hour" @@ -119,6 +127,9 @@ __BEGIN_DECLS #define LAUNCH_JOBKEY_RESOURCELIMIT_RSS "ResidentSetSize" #define LAUNCH_JOBKEY_RESOURCELIMIT_STACK "Stack" +#define LAUNCH_JOBKEY_DISABLED_MACHINETYPE "MachineType" +#define LAUNCH_JOBKEY_DISABLED_MODELNAME "ModelName" + #define LAUNCH_JOBSOCKETKEY_TYPE "SockType" #define LAUNCH_JOBSOCKETKEY_PASSIVE "SockPassive" #define LAUNCH_JOBSOCKETKEY_BONJOUR "Bonjour" @@ -213,4 +224,6 @@ launch_data_t launch_msg(const launch_data_t) __ld_normal; __END_DECLS +#pragma GCC visibility pop + #endif diff --git a/launchd/src/libvproc.c b/launchd/src/libvproc.c new file mode 100644 index 0000000..c6b2199 --- /dev/null +++ b/launchd/src/libvproc.c @@ -0,0 +1,596 @@ +/* + * Copyright (c) 1999-2005 Apple Computer, Inc. All rights reserved. + * + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ + +#include "config.h" +#include "libvproc_public.h" +#include "libvproc_private.h" +#include "libvproc_internal.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "liblaunch_public.h" +#include "liblaunch_private.h" +#include "liblaunch_internal.h" + +#include "protocol_vproc.h" + +#include "reboot2.h" + +static mach_port_t get_root_bootstrap_port(void); + +static int64_t cached_pid = -1; + +kern_return_t +_vproc_grab_subset(mach_port_t bp, mach_port_t *reqport, mach_port_t *rcvright, launch_data_t *outval, + mach_port_array_t *ports, mach_msg_type_number_t *portCnt) +{ + mach_msg_type_number_t outdata_cnt; + vm_offset_t outdata = 0; + size_t data_offset = 0; + launch_data_t out_obj; + kern_return_t kr; + + if ((kr = vproc_mig_take_subset(bp, reqport, rcvright, &outdata, &outdata_cnt, ports, portCnt))) { + goto out; + } + + if ((out_obj = launch_data_unpack((void *)outdata, outdata_cnt, NULL, 0, &data_offset, NULL))) { + *outval = launch_data_copy(out_obj); + } else { + kr = 1; + } + +out: + if (outdata) { + mig_deallocate(outdata, outdata_cnt); + } + + return kr; +} + +vproc_err_t +_vproc_post_fork_ping(void) +{ + return vproc_mig_post_fork_ping(bootstrap_port, mach_task_self()) == 0 ? NULL : _vproc_post_fork_ping; +} + +static void +setup_env_hack(const launch_data_t obj, const char *key, void *context __attribute__((unused))) +{ + setenv(key, launch_data_get_string(obj), 1); +} + +vproc_err_t +_vprocmgr_init(const char *session_type) +{ + if (vproc_mig_move_subset(bootstrap_port, MACH_PORT_NULL, (char *)session_type) == 0) { + return NULL; + } + + return (vproc_err_t)_vprocmgr_init; +} + +vproc_err_t +_vprocmgr_move_subset_to_user(uid_t target_user, const char *session_type) +{ + launch_data_t output_obj; + kern_return_t kr = 0; + bool is_bkgd = (strcmp(session_type, VPROCMGR_SESSION_BACKGROUND) == 0); + int64_t ldpid, lduid; + + if (vproc_swap_integer(NULL, VPROC_GSK_MGR_PID, 0, &ldpid) != 0) { + return (vproc_err_t)_vprocmgr_move_subset_to_user; + } + + if (vproc_swap_integer(NULL, VPROC_GSK_MGR_UID, 0, &lduid) != 0) { + return (vproc_err_t)_vprocmgr_move_subset_to_user; + } + + if (!is_bkgd && ldpid != 1) { + if (lduid == getuid()) { + return NULL; + } + /* + * Not all sessions can be moved. + * We should clean up this mess someday. + */ + return (vproc_err_t)_vprocmgr_move_subset_to_user; + } + + if (is_bkgd || target_user) { + mach_port_t puc = 0, rootbs = get_root_bootstrap_port(); + + if (vproc_mig_lookup_per_user_context(rootbs, target_user, &puc) != 0) { + return (vproc_err_t)_vprocmgr_move_subset_to_user; + } + + if (is_bkgd) { + task_set_bootstrap_port(mach_task_self(), puc); + mach_port_deallocate(mach_task_self(), bootstrap_port); + bootstrap_port = puc; + } else { + kr = vproc_mig_move_subset(puc, bootstrap_port, (char *)session_type); + mach_port_deallocate(mach_task_self(), puc); + } + } else { + kr = _vprocmgr_init(session_type) ? 1 : 0; + } + + cached_pid = -1; + + if (kr) { + return (vproc_err_t)_vprocmgr_move_subset_to_user; + } + + /* XXX We need to give 'nohup' a better API after Leopard ships */ + if (getprogname() && strcmp(getprogname(), "nohup") != 0) { + if (vproc_swap_complex(NULL, VPROC_GSK_ENVIRONMENT, NULL, &output_obj) == NULL) { + if (launch_data_get_type(output_obj) == LAUNCH_DATA_DICTIONARY) { + launch_data_dict_iterate(output_obj, setup_env_hack, NULL); + launch_data_free(output_obj); + } + } + } + + return _vproc_post_fork_ping(); +} + + +pid_t +_spawn_via_launchd(const char *label, const char *const *argv, const struct spawn_via_launchd_attr *spawn_attrs, int struct_version) +{ + size_t i, good_enough_size = 10*1024*1024; + mach_msg_type_number_t indata_cnt = 0; + vm_offset_t indata = 0; + mach_port_t obsvr_port = MACH_PORT_NULL; + launch_data_t tmp, tmp_array, in_obj; + const char *const *tmpp; + kern_return_t kr = 1; + void *buf = NULL; + pid_t p = -1; + + if ((in_obj = launch_data_alloc(LAUNCH_DATA_DICTIONARY)) == NULL) { + goto out; + } + + if ((tmp = launch_data_new_string(label)) == NULL) { + goto out; + } + + launch_data_dict_insert(in_obj, tmp, LAUNCH_JOBKEY_LABEL); + + if ((tmp_array = launch_data_alloc(LAUNCH_DATA_ARRAY)) == NULL) { + goto out; + } + + for (i = 0; *argv; i++, argv++) { + tmp = launch_data_new_string(*argv); + if (tmp == NULL) { + goto out; + } + + launch_data_array_set_index(tmp_array, tmp, i); + } + + launch_data_dict_insert(in_obj, tmp_array, LAUNCH_JOBKEY_PROGRAMARGUMENTS); + + if (spawn_attrs) switch (struct_version) { + case 2: + if (spawn_attrs->spawn_quarantine) { + char qbuf[QTN_SERIALIZED_DATA_MAX]; + size_t qbuf_sz = QTN_SERIALIZED_DATA_MAX; + + if (qtn_proc_to_data(spawn_attrs->spawn_quarantine, qbuf, &qbuf_sz) == 0) { + tmp = launch_data_new_opaque(qbuf, qbuf_sz); + launch_data_dict_insert(in_obj, tmp, LAUNCH_JOBKEY_QUARANTINEDATA); + } + } + + if (spawn_attrs->spawn_seatbelt_profile) { + tmp = launch_data_new_string(spawn_attrs->spawn_seatbelt_profile); + launch_data_dict_insert(in_obj, tmp, LAUNCH_JOBKEY_SANDBOXPROFILE); + } + + if (spawn_attrs->spawn_seatbelt_flags) { + tmp = launch_data_new_integer(*spawn_attrs->spawn_seatbelt_flags); + launch_data_dict_insert(in_obj, tmp, LAUNCH_JOBKEY_SANDBOXFLAGS); + } + + /* fall through */ + case 1: + if (spawn_attrs->spawn_binpref) { + tmp_array = launch_data_alloc(LAUNCH_DATA_ARRAY); + for (i = 0; i < spawn_attrs->spawn_binpref_cnt; i++) { + tmp = launch_data_new_integer(spawn_attrs->spawn_binpref[i]); + launch_data_array_set_index(tmp_array, tmp, i); + } + launch_data_dict_insert(in_obj, tmp_array, LAUNCH_JOBKEY_BINARYORDERPREFERENCE); + } + /* fall through */ + case 0: + if (spawn_attrs->spawn_flags & SPAWN_VIA_LAUNCHD_STOPPED) { + tmp = launch_data_new_bool(true); + launch_data_dict_insert(in_obj, tmp, LAUNCH_JOBKEY_WAITFORDEBUGGER); + } + + if (spawn_attrs->spawn_env) { + launch_data_t tmp_dict = launch_data_alloc(LAUNCH_DATA_DICTIONARY); + + for (tmpp = spawn_attrs->spawn_env; *tmpp; tmpp++) { + char *eqoff, tmpstr[strlen(*tmpp) + 1]; + + strcpy(tmpstr, *tmpp); + + eqoff = strchr(tmpstr, '='); + + if (!eqoff) { + goto out; + } + + *eqoff = '\0'; + + launch_data_dict_insert(tmp_dict, launch_data_new_string(eqoff + 1), tmpstr); + } + + launch_data_dict_insert(in_obj, tmp_dict, LAUNCH_JOBKEY_ENVIRONMENTVARIABLES); + } + + if (spawn_attrs->spawn_path) { + tmp = launch_data_new_string(spawn_attrs->spawn_path); + launch_data_dict_insert(in_obj, tmp, LAUNCH_JOBKEY_PROGRAM); + } + + if (spawn_attrs->spawn_chdir) { + tmp = launch_data_new_string(spawn_attrs->spawn_chdir); + launch_data_dict_insert(in_obj, tmp, LAUNCH_JOBKEY_WORKINGDIRECTORY); + } + + if (spawn_attrs->spawn_umask) { + tmp = launch_data_new_integer(*spawn_attrs->spawn_umask); + launch_data_dict_insert(in_obj, tmp, LAUNCH_JOBKEY_UMASK); + } + + break; + default: + break; + } + + if (!(buf = malloc(good_enough_size))) { + goto out; + } + + if ((indata_cnt = launch_data_pack(in_obj, buf, good_enough_size, NULL, NULL)) == 0) { + goto out; + } + + indata = (vm_offset_t)buf; + + kr = vproc_mig_spawn(bootstrap_port, indata, indata_cnt, &p, &obsvr_port); + + if (kr == VPROC_ERR_TRY_PER_USER) { + mach_port_t puc; + + if (vproc_mig_lookup_per_user_context(bootstrap_port, 0, &puc) == 0) { + kr = vproc_mig_spawn(puc, indata, indata_cnt, &p, &obsvr_port); + mach_port_deallocate(mach_task_self(), puc); + } + } + +out: + if (in_obj) { + launch_data_free(in_obj); + } + + if (buf) { + free(buf); + } + + switch (kr) { + case BOOTSTRAP_SUCCESS: + if (spawn_attrs && spawn_attrs->spawn_observer_port) { + *spawn_attrs->spawn_observer_port = obsvr_port; + } else { + mach_port_deallocate(mach_task_self(), obsvr_port); + } + return p; + case BOOTSTRAP_NOT_PRIVILEGED: + errno = EPERM; break; + case BOOTSTRAP_NO_MEMORY: + errno = ENOMEM; break; + case BOOTSTRAP_NAME_IN_USE: + errno = EEXIST; break; + case 1: + errno = EIO; break; + default: + errno = EINVAL; break; + } + + return -1; +} + +kern_return_t +mpm_wait(mach_port_t ajob __attribute__((unused)), int *wstatus) +{ + return vproc_mig_wait(ajob, wstatus); +} + +kern_return_t +mpm_uncork_fork(mach_port_t ajob) +{ + return vproc_mig_uncork_fork(ajob); +} + +kern_return_t +_vprocmgr_getsocket(name_t sockpath) +{ + return vproc_mig_getsocket(bootstrap_port, sockpath); +} + +vproc_err_t +_vproc_get_last_exit_status(int *wstatus) +{ + int64_t val; + + if (vproc_swap_integer(NULL, VPROC_GSK_LAST_EXIT_STATUS, 0, &val) == 0) { + *wstatus = (int)val; + return NULL; + } + + return (vproc_err_t)_vproc_get_last_exit_status; +} + +vproc_err_t +_vproc_send_signal_by_label(const char *label, int sig) +{ + if (vproc_mig_send_signal(bootstrap_port, (char *)label, sig) == 0) { + return NULL; + } + + return _vproc_send_signal_by_label; +} + +vproc_err_t +_vprocmgr_log_forward(mach_port_t mp, void *data, size_t len) +{ + if (vproc_mig_log_forward(mp, (vm_offset_t)data, len) == 0) { + return NULL; + } + + return _vprocmgr_log_forward; +} + +vproc_err_t +_vprocmgr_log_drain(vproc_t vp __attribute__((unused)), pthread_mutex_t *mutex, _vprocmgr_log_drain_callback_t func) +{ + mach_msg_type_number_t outdata_cnt, tmp_cnt; + vm_offset_t outdata = 0; + struct logmsg_s *lm; + + if (!func) { + return _vprocmgr_log_drain; + } + + if (vproc_mig_log_drain(bootstrap_port, &outdata, &outdata_cnt) != 0) { + return _vprocmgr_log_drain; + } + + tmp_cnt = outdata_cnt; + + if (mutex) { + pthread_mutex_lock(mutex); + } + + for (lm = (struct logmsg_s *)outdata; tmp_cnt > 0; lm = ((void *)lm + lm->obj_sz)) { + lm->from_name += (size_t)lm; + lm->about_name += (size_t)lm; + lm->msg += (size_t)lm; + lm->session_name += (size_t)lm; + + func(&lm->when, lm->from_pid, lm->about_pid, lm->sender_uid, lm->sender_gid, lm->pri, + lm->from_name, lm->about_name, lm->session_name, lm->msg); + + tmp_cnt -= lm->obj_sz; + } + + if (mutex) { + pthread_mutex_unlock(mutex); + } + + if (outdata) { + mig_deallocate(outdata, outdata_cnt); + } + + return NULL; +} + +vproc_err_t +vproc_swap_integer(vproc_t vp __attribute__((unused)), vproc_gsk_t key, int64_t *inval, int64_t *outval) +{ + static int64_t cached_is_managed = -1; + int64_t dummyval = 0; + + switch (key) { + case VPROC_GSK_MGR_PID: + if (cached_pid != -1 && outval) { + *outval = cached_pid; + return NULL; + } + break; + case VPROC_GSK_IS_MANAGED: + if (cached_is_managed != -1 && outval) { + *outval = cached_is_managed; + return NULL; + } + break; + default: + break; + } + + if (vproc_mig_swap_integer(bootstrap_port, inval ? key : 0, outval ? key : 0, inval ? *inval : 0, outval ? outval : &dummyval) == 0) { + switch (key) { + case VPROC_GSK_MGR_PID: + cached_pid = outval ? *outval : dummyval; + break; + case VPROC_GSK_IS_MANAGED: + cached_is_managed = outval ? *outval : dummyval; + break; + default: + break; + } + return NULL; + } + + return (vproc_err_t)vproc_swap_integer; +} + +mach_port_t +get_root_bootstrap_port(void) +{ + mach_port_t parent_port = 0; + mach_port_t previous_port = 0; + + do { + if (previous_port) { + if (previous_port != bootstrap_port) { + mach_port_deallocate(mach_task_self(), previous_port); + } + previous_port = parent_port; + } else { + previous_port = bootstrap_port; + } + + if (bootstrap_parent(previous_port, &parent_port) != 0) { + return MACH_PORT_NULL; + } + + } while (parent_port != previous_port); + + return parent_port; +} + +vproc_err_t +vproc_swap_complex(vproc_t vp __attribute__((unused)), vproc_gsk_t key, launch_data_t inval, launch_data_t *outval) +{ + size_t data_offset = 0, good_enough_size = 10*1024*1024; + mach_msg_type_number_t indata_cnt = 0, outdata_cnt; + vm_offset_t indata = 0, outdata = 0; + launch_data_t out_obj; + void *rval = vproc_swap_complex; + void *buf = NULL; + + if (inval) { + if (!(buf = malloc(good_enough_size))) { + goto out; + } + + if ((indata_cnt = launch_data_pack(inval, buf, good_enough_size, NULL, NULL)) == 0) { + goto out; + } + + indata = (vm_offset_t)buf; + } + + if (vproc_mig_swap_complex(bootstrap_port, inval ? key : 0, outval ? key : 0, indata, indata_cnt, &outdata, &outdata_cnt) != 0) { + goto out; + } + + if (outval) { + if (!(out_obj = launch_data_unpack((void *)outdata, outdata_cnt, NULL, 0, &data_offset, NULL))) { + goto out; + } + + if (!(*outval = launch_data_copy(out_obj))) { + goto out; + } + } + + rval = NULL; +out: + if (buf) { + free(buf); + } + + if (outdata) { + mig_deallocate(outdata, outdata_cnt); + } + + return rval; +} + +void * +reboot2(uint64_t flags) +{ + if (vproc_mig_reboot2(get_root_bootstrap_port(), flags) == 0) { + return NULL; + } + + return reboot2; +} + +vproc_err_t +_vproc_set_global_on_demand(bool state) +{ + int64_t val = state ? ~0 : 0; + + if (vproc_swap_integer(NULL, VPROC_GSK_GLOBAL_ON_DEMAND, &val, NULL) == 0) { + return NULL; + } + + return (vproc_err_t)_vproc_set_global_on_demand; +} + +void +_vproc_logv(int pri, int err, const char *msg, va_list ap) +{ + char flat_msg[3000]; + + vsnprintf(flat_msg, sizeof(flat_msg), msg, ap); + + vproc_mig_log(bootstrap_port, pri, err, flat_msg); +} + +void +_vproc_log(int pri, const char *msg, ...) +{ + va_list ap; + + va_start(ap, msg); + _vproc_logv(pri, 0, msg, ap); + va_end(ap); +} + +void +_vproc_log_error(int pri, const char *msg, ...) +{ + int saved_errno = errno; + va_list ap; + + va_start(ap, msg); + _vproc_logv(pri, saved_errno, msg, ap); + va_end(ap); +} diff --git a/launchd/src/libvproc_internal.h b/launchd/src/libvproc_internal.h new file mode 100644 index 0000000..c3438b3 --- /dev/null +++ b/launchd/src/libvproc_internal.h @@ -0,0 +1,92 @@ +#ifndef _VPROC_INTERNAL_H_ +#define _VPROC_INTERNAL_H_ +/* + * Copyright (c) 2006-2007 Apple Inc. All rights reserved. + * + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ + +#include +#include +#include +#include +#include "liblaunch_public.h" +#include "libbootstrap_public.h" +#include "libvproc_public.h" + +typedef char * _internal_string_t; +typedef char * logmsg_t; +typedef pid_t * pid_array_t; +typedef mach_port_t vproc_mig_t; + +#ifdef protocol_vproc_MSG_COUNT +/* HACK */ +#include "launchd_core_logic.h" +#endif + +#define VPROC_ERR_TRY_PER_USER 1099 + +#pragma GCC visibility push(default) + +vproc_err_t _vprocmgr_init(const char *session_type); +vproc_err_t _vproc_post_fork_ping(void); + +#define SPAWN_HAS_PATH 0x0001 +#define SPAWN_HAS_WDIR 0x0002 +#define SPAWN_HAS_UMASK 0x0004 +#define SPAWN_WANTS_WAIT4DEBUGGER 0x0008 + +kern_return_t +_vproc_grab_subset(mach_port_t bp, mach_port_t *reqport, mach_port_t *rcvright, launch_data_t *outval, + mach_port_array_t *ports, mach_msg_type_number_t *portCnt); + +kern_return_t _vprocmgr_getsocket(name_t); + + +struct logmsg_s { + STAILQ_ENTRY(logmsg_s) sqe; + struct timeval when; + pid_t from_pid; + pid_t about_pid; + uid_t sender_uid; + gid_t sender_gid; + int err_num; + int pri; + const char *from_name; + const char *about_name; + const char *session_name; + const char *msg; + size_t obj_sz; + char data[0]; +}; + + +void _vproc_logv(int pri, int err, const char *msg, va_list ap); +vproc_err_t _vprocmgr_log_forward(mach_port_t mp, void *data, size_t len); + + +kern_return_t +bootstrap_info( + mach_port_t bp, + name_array_t *service_names, + mach_msg_type_number_t *service_namesCnt, + bootstrap_status_array_t *service_active, + mach_msg_type_number_t *service_activeCnt); + +#pragma GCC visibility pop + +#endif diff --git a/launchd/src/libvproc_private.h b/launchd/src/libvproc_private.h new file mode 100644 index 0000000..b303f5b --- /dev/null +++ b/launchd/src/libvproc_private.h @@ -0,0 +1,80 @@ +#ifndef _VPROC_PRIVATE_H_ +#define _VPROC_PRIVATE_H_ +/* + * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ + +#include +#include +#include +#include +#include +#include + +__BEGIN_DECLS + +#pragma GCC visibility push(default) + +/* DO NOT use this. This is a hack for launchctl */ +#define VPROC_MAGIC_UNLOAD_SIGNAL 0x4141504C + +typedef enum { + VPROC_GSK_LAST_EXIT_STATUS = 1, + VPROC_GSK_GLOBAL_ON_DEMAND, + VPROC_GSK_MGR_UID, + VPROC_GSK_MGR_PID, + VPROC_GSK_IS_MANAGED, + VPROC_GSK_BASIC_KEEPALIVE, + VPROC_GSK_START_INTERVAL, + VPROC_GSK_IDLE_TIMEOUT, + VPROC_GSK_EXIT_TIMEOUT, + VPROC_GSK_ENVIRONMENT, + VPROC_GSK_ALLJOBS, + VPROC_GSK_GLOBAL_LOG_MASK, + VPROC_GSK_GLOBAL_UMASK, +} vproc_gsk_t; + +vproc_err_t vproc_swap_integer(vproc_t vp, vproc_gsk_t key, int64_t *inval, int64_t *outval); +vproc_err_t vproc_swap_complex(vproc_t vp, vproc_gsk_t key, launch_data_t inval, launch_data_t *outval); + +vproc_err_t _vproc_get_last_exit_status(int *wstatus); +vproc_err_t _vproc_set_global_on_demand(bool val); + +typedef void (*_vprocmgr_log_drain_callback_t)(struct timeval *when, pid_t from_pid, pid_t about_pid, uid_t sender_uid, gid_t sender_gid, int priority, const char *from_name, const char *about_name, const char *session_name, const char *msg); + +vproc_err_t _vprocmgr_log_drain(vproc_t vp, pthread_mutex_t *optional_mutex_around_callback, _vprocmgr_log_drain_callback_t func); + +vproc_err_t _vproc_send_signal_by_label(const char *label, int sig); + +void _vproc_log(int pri, const char *msg, ...) __attribute__((format(printf, 2, 3))); +void _vproc_log_error(int pri, const char *msg, ...) __attribute__((format(printf, 2, 3))); + +#define VPROCMGR_SESSION_LOGINWINDOW "LoginWindow" +#define VPROCMGR_SESSION_BACKGROUND "Background" +#define VPROCMGR_SESSION_AQUA "Aqua" +#define VPROCMGR_SESSION_STANDARDIO "StandardIO" +#define VPROCMGR_SESSION_SYSTEM "System" + +vproc_err_t _vprocmgr_move_subset_to_user(uid_t target_user, const char *session_type); + +#pragma GCC visibility pop + +__END_DECLS + +#endif diff --git a/launchd/src/libvproc_public.h b/launchd/src/libvproc_public.h new file mode 100644 index 0000000..fcb348c --- /dev/null +++ b/launchd/src/libvproc_public.h @@ -0,0 +1,41 @@ +#ifndef _VPROC_H_ +#define _VPROC_H_ +/* + * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ + +#include +#include + +__BEGIN_DECLS + +#pragma GCC visibility push(default) + +typedef void * vproc_err_t; + +typedef void * vproc_t; +typedef void * vprocmgr_t; + +const char *vproc_strerror(vproc_err_t r); + +#pragma GCC visibility pop + +__END_DECLS + +#endif diff --git a/launchd/src/protocol_job.defs b/launchd/src/protocol_job.defs new file mode 100644 index 0000000..d709376 --- /dev/null +++ b/launchd/src/protocol_job.defs @@ -0,0 +1,168 @@ +/* + * Copyright (c) 1999-2004 Apple Computer, Inc. All rights reserved. + * + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ +/* + * bootstrap -- fundamental service initiator and port server + * Mike DeMoney, NeXT, Inc. + * Copyright, 1990. All rights reserved. + */ + +subsystem protocol_vproc 400; + +#include +#include +#include "launchd_mig_types.defs" +import "libvproc_public.h"; +import "libvproc_private.h"; +import "libvproc_internal.h"; + +type mach_port_move_send_array_t = array[] of mach_port_move_send_t + ctype: mach_port_array_t; + + +userprefix vproc_mig_; +serverprefix job_mig_; + +routine create_server( + __bs_port : job_t; + __server_cmd : cmd_t; + __server_uid : uid_t; + __on_demand : boolean_t; + out __server_port : mach_port_make_send_t); + +routine reboot2( + __bs_port : job_t; + __flags : uint64_t); + +routine check_in( + __bs_port : job_t; + __service_name : name_t; + out __service_port : mach_port_move_receive_t); + +routine register2( + __bs_port : job_t; + __service_name : name_t; + __service_port : mach_port_t; + __flags : uint64_t); + +routine look_up2( + __bs_port : job_t; + __service_name : name_t; + out __service_port : mach_port_send_t; + __target_pid : pid_t; + __flags : uint64_t); + +routine send_signal( + __bs_port : job_t; + sreplyport __rport : mach_port_make_send_once_t; + __label : name_t; + __signal : integer_t); + +routine parent( + __bs_port : job_t; + out __parent_port : mach_port_send_t); + +routine post_fork_ping( + __bs_port : job_t; + __task_port : task_t); + +routine info( + __bs_port : job_t; + out __service_names : name_array_t, dealloc; + out __service_active : bootstrap_status_array_t, dealloc); + +routine subset( + __bs_port : job_t; + __requestor_port: mach_port_t; + out __subset_port : mach_port_make_send_t); + +routine create_service( + __bs_port : job_t; + __service_name : name_t; + out __service_port : mach_port_t); + +routine take_subset( + __bs_port : job_t; + out __bs_reqport : mach_port_move_send_t; + out __bs_rcvright : mach_port_move_receive_t; + out __outdata : pointer_t, dealloc; + out __service_ports : mach_port_move_send_array_t, dealloc); + +routine getsocket( + __bs_port : job_t; + out __sockpath : name_t); + +routine spawn( + __bs_port : job_t; + __indata : pointer_t; + out __pid : pid_t; + out __obsvr_port : mach_port_make_send_t); + +routine wait( + __bs_port : job_t; + sreplyport __rport : mach_port_make_send_once_t; + out __waitval : integer_t); + +routine uncork_fork( + __bs_port : job_t); + +routine swap_integer( + __bs_port : job_t; + __inkey : vproc_gsk_t; + __outkey : vproc_gsk_t; + __inval : int64_t; + out __outval : int64_t); + +routine set_service_policy( + __bs_port : job_t; + __target_pid : pid_t; + __flags : uint64_t; + __service : name_t); + +routine log( + __bs_port : job_t; + __pri : integer_t; + __err : integer_t; + __msg : logmsg_t); + +routine lookup_per_user_context( + __bs_port : job_t; + __wu : uid_t; + out __u_cont : mach_port_t); + +routine move_subset( + __bs_port : job_t; + __target_port : mach_port_t; + __sessiontype : name_t); + +routine swap_complex( + __bs_port : job_t; + __inkey : vproc_gsk_t; + __outkey : vproc_gsk_t; + __inval : pointer_t; + out __outval : pointer_t, dealloc); + +routine log_drain( + __bs_port : job_t; + sreplyport __rport : mach_port_make_send_once_t; + out __outval : pointer_t, dealloc); + +routine log_forward( + __bs_port : job_t; + __inval : pointer_t); diff --git a/launchd/src/mpm_reply.defs b/launchd/src/protocol_job_reply.defs similarity index 63% rename from launchd/src/mpm_reply.defs rename to launchd/src/protocol_job_reply.defs index 3389098..58eda62 100644 --- a/launchd/src/mpm_reply.defs +++ b/launchd/src/protocol_job_reply.defs @@ -18,14 +18,14 @@ * @APPLE_APACHE_LICENSE_HEADER_END@ */ -subsystem mpm_reply 500; +subsystem job_reply 500; #include #include -import "bootstrap_public.h"; -import "bootstrap_private.h"; - -type pid_t = integer_t; +#include "launchd_mig_types.defs" +import "libbootstrap_public.h"; +import "libvproc_public.h"; +import "libvproc_internal.h"; skip; /* create_server */ @@ -37,11 +37,13 @@ skip; /* register */ skip; /* look_up */ -skip; +simpleroutine job_mig_send_signal_reply( + __r_port : mach_port_move_send_once_t; + __result : kern_return_t, RetCode); skip; /* parent */ -skip; +skip; /* post_fork_ping */ skip; /* info */ @@ -55,7 +57,26 @@ skip; /* getsocket */ skip; /* spawn */ -simpleroutine mpm_wait_reply( +simpleroutine job_mig_wait_reply( __r_port : mach_port_move_send_once_t; __result : kern_return_t, RetCode; __wait : integer_t); + +skip; /* uncork_fork */ + +skip; /* swap_integer */ + +skip; /* set_service_policy */ + +skip; /* log */ + +skip; /* lookup_per_user_context */ + +skip; /* move_subset */ + +skip; /* swap_complex */ + +simpleroutine job_mig_log_drain_reply( + __r_port : mach_port_move_send_once_t; + __result : kern_return_t, RetCode; + __outval : pointer_t); diff --git a/launchd/src/bootstrap.defs b/launchd/src/protocol_jobmgr.defs similarity index 68% rename from launchd/src/bootstrap.defs rename to launchd/src/protocol_jobmgr.defs index 9d0220f..3b05fa7 100644 --- a/launchd/src/bootstrap.defs +++ b/launchd/src/protocol_jobmgr.defs @@ -27,87 +27,78 @@ subsystem bootstrap 400; #include #include +#include "launchd_mig_types.defs" import "bootstrap_public.h"; import "bootstrap_private.h"; -type pid_t = integer_t; -type cmd_t = c_string[512]; -type cmd_array_t = ^array [] of cmd_t; -type name_t = c_string[128]; -type name_array_t = ^array [] of name_t; -type _internal_string_t = ^array [] of char; -type bootstrap_status_t = integer_t; -type bootstrap_status_array_t = ^array [] of bootstrap_status_t; +userprefix vproc_mig_; +serverprefix job_mig_; -userprefix raw_; -serverprefix x_; - -routine bootstrap_create_server( - __bs_port : mach_port_t; +routine create_server( + __bs_port : job_t; __server_cmd : cmd_t; __server_uid : natural_t; __on_demand : boolean_t; ServerAuditToken __token : audit_token_t; out __server_port : mach_port_make_send_t); -routine bootstrap_unprivileged( - __bs_port : mach_port_t; - out __unpriv_port : mach_port_make_send_t); +skip; /* Last used in 10.4. Was bootstrap_unprivileged() */ -routine bootstrap_check_in( - __bs_port : mach_port_t; +routine check_in( + __bs_port : job_t; __service_name : name_t; ServerAuditToken __token : audit_token_t; out __service_port : mach_port_move_receive_t); -routine bootstrap_register( - __bs_port : mach_port_t; +routine register( + __bs_port : job_t; ServerAuditToken __token : audit_token_t; __service_name : name_t; __service_port : mach_port_t); -routine bootstrap_look_up( - __bs_port : mach_port_t; +routine look_up( + __bs_port : job_t; ServerAuditToken __token : audit_token_t; __service_name : name_t; out __service_port : mach_port_send_t); skip; /* last used in 10.4 */ -routine bootstrap_parent( - __bs_port : mach_port_t; +routine parent( + __bs_port : job_t; out __parent_port : mach_port_send_t); skip; /* last used in 10.4 */ -routine bootstrap_info( - __bs_port : mach_port_t; +routine info( + __bs_port : job_t; out __service_names : name_array_t, dealloc; out __service_active : bootstrap_status_array_t, dealloc); -routine bootstrap_subset( - __bs_port : mach_port_t; +routine subset( + __bs_port : job_t; __requestor_port: mach_port_t; out __subset_port : mach_port_make_send_t); -routine bootstrap_create_service( - __bs_port : mach_port_t; +routine create_service( + __bs_port : job_t; __service_name : name_t; out __service_port : mach_port_t); -routine bootstrap_transfer_subset( - __bs_port : mach_port_t; +routine transfer_subset( + __bs_port : job_t; out __bs_reqport : mach_port_t; out __bs_rcvright : mach_port_move_receive_t; out __service_names : name_array_t, dealloc; + out __service_pids : pointer_t, dealloc; out __service_ports : mach_port_array_t, dealloc); -routine bootstrap_getsocket( - __bs_port : mach_port_t; +routine getsocket( + __bs_port : job_t; out __sockpath : name_t); -routine mpm_spawn( - __bs_port : mach_port_t; +routine spawn( + __bs_port : job_t; ServerAuditToken __token : audit_token_t; __chars : _internal_string_t; __argc : uint32_t; @@ -117,12 +108,18 @@ routine mpm_spawn( out __pid : pid_t; out __obsvr_port : mach_port_make_send_t); -routine mpm_wait( - __bs_port : mach_port_t; +routine wait( + __bs_port : job_t; sreplyport __rport : mach_port_make_send_once_t; ServerAuditToken __token : audit_token_t; out __waitval : integer_t); -routine mpm_uncork_fork( - __bs_port : mach_port_t; +routine uncork_fork( + __bs_port : job_t; ServerAuditToken __token : audit_token_t); + +/* Essentially the inverse of bootstrap_unprivileged() */ +routine get_self( + __bs_port : job_t; + ServerAuditToken __token : audit_token_t; + out __job_port : mach_port_make_send_t); diff --git a/launchd/src/rc.8 b/launchd/src/rc.8 index c577995..e252c04 100644 --- a/launchd/src/rc.8 +++ b/launchd/src/rc.8 @@ -1,6 +1,6 @@ .Dd May 31, 2006 .Dt RC 8 -.Os Darwin 9 +.Os Darwin .Sh NAME .Nm rc .Nd command script for boot diff --git a/launchd/src/rc.shutdown b/launchd/src/rc.shutdown deleted file mode 100644 index 0738e8d..0000000 --- a/launchd/src/rc.shutdown +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh -# Copyright 1997-2004 Apple Computer, Inc. - -. /etc/rc.common - -if [ -f /etc/rc.shutdown.local ]; then - sh /etc/rc.shutdown.local -fi - -SystemStarter stop - -kill -TERM 1 - -exit 0 diff --git a/launchd/src/reboot2.h b/launchd/src/reboot2.h new file mode 100644 index 0000000..635d723 --- /dev/null +++ b/launchd/src/reboot2.h @@ -0,0 +1,35 @@ +#ifndef _REBOOT2_H_ +#define _REBOOT2_H_ +/* + * Copyright (c) 2007 Apple Inc. All rights reserved. + * + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ + +#include +#include +#include + +__BEGIN_DECLS + +/* Returns NULL on success. Not NULL on failure */ + +__attribute__((visibility("default"))) void *reboot2(uint64_t flags); + +__END_DECLS + +#endif diff --git a/launchd/src/service b/launchd/src/service deleted file mode 100755 index 97cdf46..0000000 --- a/launchd/src/service +++ /dev/null @@ -1,167 +0,0 @@ -#!/bin/sh - -unset LAUNCHD_SOCKET - -set -e - -# don't let people kill us. We shouldn't be long, so this isn't a big deal. - -trap "" TSTP -trap "" HUP -trap "" INT -trap "" QUIT -trap "" TERM - -function restart_xinetd () -{ - lockfile -r-1 /var/run/.xinetd-restart.lock - kill -HUP $(cat /var/run/xinetd.pid 2>/dev/null) 2>/dev/null || /usr/sbin/xinetd -pidfile /var/run/xinetd.pid - rm -f /var/run/.xinetd-restart.lock -} - -function restart_xinetd_hard () -{ - lockfile -r-1 /var/run/.xinetd-restart.lock - kill -TERM $(cat /var/run/xinetd.pid 2>/dev/null) 2>/dev/null || echo >/dev/null - kill -0 $(cat /var/run/xinetd.pid 2>/dev/null) 2>/dev/null && sleep 1 - /usr/sbin/xinetd -pidfile /var/run/xinetd.pid - rm -f /var/run/.xinetd-restart.lock -} - -if [ $# -eq 0 ] -then - echo "Usage: $(basename $0) --list | " >&2 - exit 1 -fi - -if [ "$1" == "--list" ] -then - echo smtp - echo fax-receive - cd /etc/xinetd.d 2>/dev/null - ls -1 - cd /System/Library/LaunchDaemons 2>/dev/null - ls -1 | egrep '.plist$' | sed 's,.plist$,,g' - exit 0 -elif [ "$1" == "--test-if-configured-on" ] -then - if [ -f "/etc/xinetd.d/$2" ] - then - egrep "disable.*=.*no" /etc/xinetd.d/$2 >/dev/null 2>&1 - exit $? - fi - if [ -f /System/Library/LaunchDaemons/$2.plist ] - then - IS_OFF=$(defaults read /System/Library/LaunchDaemons/$2 Disabled 2>/dev/null || true) - if [ "$IS_OFF" = 1 ] - then - exit 1 - else - exit 0 - fi - fi - if [ "$2" = "smtp" ] - then - egrep '^MAILSERVER.*-YES-' /etc/hostconfig >/dev/null 2>&1 - exit $? - fi - if [ "$2" = "fax-receive" ] - then - egrep '^fax.*unknown.*on$' /etc/ttys >/dev/null 2>&1 - exit $? - fi - exit 1 -elif [ "$1" == "--test-if-available" ] -then - [ -f /System/Library/LaunchDaemons/$2.plist ] && exit 0 - [ "$2" = "smtp" ] && exit 0 - [ "$2" = "fax-receive" ] && exit 0 - [ ! -f "/etc/xinetd.d/$2" ] && exit 1 - SERVER_FILE=$(egrep 'server[ ]' "/etc/xinetd.d/$2" | sed 's,.*server[ ]*=[ ]*\(.*\),\1,g') - [ ! -f "$SERVER_FILE" ] && exit 1 - exit 0 -elif [ -f "/etc/xinetd.d/$1" ] -then - if [ $UID != 0 ] - then - echo "You must be root to run this option" >&2 - exit 1 - fi - # yes, /var/run is gross, but it is tmp directory cleaned up a boot, - # writable only by root (so i don't need to worry about the security - # implications of mktemp) - TMPFILE=$(mktemp /var/run/xinetd.tmp.$$.XXXXXX) - cp -f "/etc/xinetd.d/$1" $TMPFILE - if [ "$2" == start ] - then - sed 's/disable.*=.*/disable = no/g' < $TMPFILE > "/etc/xinetd.d/$1" - restart_xinetd - elif [ "$2" == stop ] - then - sed 's/disable.*=.*/disable = yes/g' < $TMPFILE > "/etc/xinetd.d/$1" - if [ "$1" == "nmbd" ] - then - restart_xinetd_hard - kill -TERM $(cat /var/run/nmbd.pid) || echo >/dev/null - else - restart_xinetd - fi - else - echo "No such service command" >&2 - fi - rm -f $TMPFILE -elif [ -f "/System/Library/LaunchDaemons/$1.plist" ] -then - [ "$2" == start ] && launchctl load -w /System/Library/LaunchDaemons/$1.plist - [ "$2" == stop ] && launchctl unload -w /System/Library/LaunchDaemons/$1.plist -elif [ "$1" = "smtp" ] -then - if [ $UID != 0 ] - then - echo "You must be root to run this option" >&2 - exit 1 - fi - TMPFILE=$(mktemp /var/run/xinetd.tmp.$$.XXXXXX) - cp -f /etc/hostconfig $TMPFILE - if [ "$2" == start ] - then - if grep -q MAILSERVER=-NO- /etc/hostconfig ; then - sed 's,^MAILSERVER=-NO-,MAILSERVER=-YES-,g' < $TMPFILE > /etc/hostconfig - fi - postfix start - postfix flush - elif [ "$2" == stop ] - then - if grep -q MAILSERVER=-YES- /etc/hostconfig ; then - sed 's,^MAILSERVER=-YES-,MAILSERVER=-NO-,g' < $TMPFILE > /etc/hostconfig - fi - postfix stop - else - echo "No such service command" >&2 - fi - rm -f $TMPFILE -elif [ "$1" = "fax-receive" ] -then - if [ $UID != 0 ] - then - echo "You must be root to run this option" >&2 - exit 1 - fi - TMPFILE=$(mktemp /var/run/xinetd.tmp.$$.XXXXXX) - cp -f /etc/ttys $TMPFILE - if [ "$2" == start ] - then - sed 's,^fax\(.*\)off$,fax\1on,g' < $TMPFILE > /etc/ttys - kill -HUP 1 - elif [ "$2" == stop ] - then - sed 's,^fax\(.*\)on$,fax\1off,g' < $TMPFILE > /etc/ttys - kill -HUP 1 - else - echo "No such service command" >&2 - fi - rm -f $TMPFILE -else - echo "No such service $1" >&2 - exit 1 -fi diff --git a/launchd/src/service.8 b/launchd/src/service.8 deleted file mode 100644 index adb0f83..0000000 --- a/launchd/src/service.8 +++ /dev/null @@ -1,29 +0,0 @@ -.Dd October 15, 2004 -.Dt SERVICE 8 -.Os Darwin -.Sh NAME -.Nm service -.Sh SYNOPSIS -.Nm -.Ar service Ar command -.Nm -.Fl -list -.Nm -.Fl -test-if-configured-on Ar service -.Nm -.Fl -test-if-available Ar service -.Sh DESCRIPTION -.Nm -is a simple script to abstract the management of services provided by the system. -It can be used to start and stop services, as well as to determine the status of services. -.Sh OPTIONS -.Bl -tag -width indent -.It Ar service Ar command -Attempt to execute a given command for a given service. Currently, the available commands are 'start' and 'stop'. -.It Fl -list -List all available services. -.It Fl -test-if-configured-on Ar service -Exit with status 0 if the service is currently enabled. Otherwise, exit with status 1. -.It Fl -test-if-available Ar service -Exit with status 0 if the service's daemon exists on your system. Otherwise, exit with status 1. -.El diff --git a/launchd/src/wait4path.c b/launchd/src/wait4path.c index 1f942e5..dd5f566 100644 --- a/launchd/src/wait4path.c +++ b/launchd/src/wait4path.c @@ -39,9 +39,6 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); } - if (stat(argv[1], &sb) == 0) - exit(EXIT_SUCCESS); - EV_SET(&kev, 0, EVFILT_FS, EV_ADD, 0, 0, 0); if (kevent(kq, &kev, 1, NULL, 0, NULL) == -1) { @@ -49,10 +46,15 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); } + if (stat(argv[1], &sb) == 0) { + exit(EXIT_SUCCESS); + } + for (;;) { kevent(kq, NULL, 0, &kev, 1, NULL); - if (stat(argv[1], &sb) == 0) + if (stat(argv[1], &sb) == 0) { break; + } } exit(EXIT_SUCCESS); diff --git "a/launchd/testing/Qu\304\261c\304\270s\304\261lv\316\265\312\200" "b/launchd/testing/Qu\304\261c\304\270s\304\261lv\316\265\312\200" deleted file mode 100755 index a54a10e..0000000 --- "a/launchd/testing/Qu\304\261c\304\270s\304\261lv\316\265\312\200" +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -echo "UTF-8 is fun!" diff --git a/launchd/testing/missed-EVFILT_TIMER.c b/launchd/testing/missed-EVFILT_TIMER.c new file mode 100644 index 0000000..117d49c --- /dev/null +++ b/launchd/testing/missed-EVFILT_TIMER.c @@ -0,0 +1,58 @@ +#include +#include +#include +#include +#include +#include + +void +test5225889(int first, int second) +{ + struct timeval tvs, tve, tvd; + struct timespec timeout = { 30, 0 }; + struct kevent kev; + int r, kq = kqueue(); + + fprintf(stdout, "First timer %i being updated to %i.\n", first, second); + + assert(kq != -1); + + EV_SET(&kev, 0, EVFILT_TIMER, EV_ADD|EV_ONESHOT, NOTE_SECONDS, first, NULL); + r = kevent(kq, &kev, 1, NULL, 0, NULL); + assert(r != -1); + + EV_SET(&kev, 0, EVFILT_TIMER, EV_ADD|EV_ONESHOT, NOTE_SECONDS, second, NULL); + r = kevent(kq, &kev, 1, NULL, 0, NULL); + assert(r != -1); + + gettimeofday(&tvs, NULL); + r = kevent(kq, NULL, 0, &kev, 1, &timeout); + gettimeofday(&tve, NULL); + + timersub(&tve, &tvs, &tvd); + + fprintf(stdout, "Waited %lu seconds for kevent() to return.\n", tvd.tv_sec); + + switch (r) { + case 1: + assert(kev.data == second); + assert(tvd.tv_sec >= second); + break; + case -1: + case 0: + default: + fprintf(stderr, "Bug 5225889 still exists!\n"); + exit(EXIT_FAILURE); + } +} + +int +main(void) +{ + test5225889(5, 10); + test5225889(10, 5); + + fprintf(stdout, "Finished.\n"); + + exit(EXIT_SUCCESS); +} diff --git a/launchd/testing/vproc_gsk_test.c b/launchd/testing/vproc_gsk_test.c new file mode 100644 index 0000000..5df62c0 --- /dev/null +++ b/launchd/testing/vproc_gsk_test.c @@ -0,0 +1,27 @@ +#include +#include +#include +#include + +int main(void) +{ + int64_t val; + bool is_native; + pid_t p; + uid_t u; + + /* we assign val to p or u due to 64 bit to 32 bit trucation */ + + assert(vproc_swap_integer(NULL, VPROC_GSK_MGR_PID, NULL, &val) == NULL); + p = val; + + assert(vproc_swap_integer(NULL, VPROC_GSK_MGR_UID, NULL, &val) == NULL); + u = val; + + assert(vproc_swap_integer(NULL, VPROC_GSK_IS_NATIVE, NULL, &val) == NULL); + is_native = val; + + fprintf(stdout, "UID = %u PID = %u Native = %u\n", u, p, is_native); + + return 0; +} diff --git a/launchd/testing/vproc_swap_complex.c b/launchd/testing/vproc_swap_complex.c new file mode 100644 index 0000000..6ff8d53 --- /dev/null +++ b/launchd/testing/vproc_swap_complex.c @@ -0,0 +1,28 @@ +#include +#include +#include +#include +#include +#include +#include + +static void my_callback(const launch_data_t obj, const char *key, void *context); + +int main(void) +{ + launch_data_t output_obj = NULL; + + assert(vproc_swap_complex(NULL, VPROC_GSK_ENVIRONMENT, NULL, &output_obj) == 0); + + assert(launch_data_get_type(output_obj) == LAUNCH_DATA_DICTIONARY); + + launch_data_dict_iterate(output_obj, my_callback, stdout); + + return 0; +} + +void +my_callback(const launch_data_t obj, const char *key, void *context) +{ + fprintf(context, "%s == %s\n", key, launch_data_get_string(obj)); +} -- 2.45.2