Revision: 23070 http://trac.macosforge.org/projects/launchd/changeset/23070 Author: zarzycki@apple.com Date: 2007-02-15 10:26:22 -0800 (Thu, 15 Feb 2007) Log Message: ----------- <rdar://problem/5001306> poweroff() API to wrap reboot() Modified Paths: -------------- trunk/launchd/src/Makefile.am trunk/launchd/src/Makefile.in trunk/launchd/src/launchd_core_logic.c trunk/launchd/src/libvproc.c trunk/launchd/src/protocol_job.defs Added Paths: ----------- trunk/launchd/src/poweroff.h Modified: trunk/launchd/src/Makefile.am =================================================================== --- trunk/launchd/src/Makefile.am 2007-02-15 16:12:48 UTC (rev 23069) +++ trunk/launchd/src/Makefile.am 2007-02-15 18:26:22 UTC (rev 23070) @@ -89,6 +89,7 @@ mkdir -p $(DESTDIR)/usr/local/include 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)/poweroff.h $(DESTDIR)/usr/local/include/poweroff.h mkdir -p $(DESTDIR)/$(sysconfdir)/mach_init.d mkdir -p $(DESTDIR)/$(sysconfdir)/mach_init_per_user.d mkdir -p $(DESTDIR)/Library/LaunchDaemons Modified: trunk/launchd/src/Makefile.in =================================================================== --- trunk/launchd/src/Makefile.in 2007-02-15 16:12:48 UTC (rev 23069) +++ trunk/launchd/src/Makefile.in 2007-02-15 18:26:22 UTC (rev 23070) @@ -1103,6 +1103,7 @@ @LIBS_ONLY_FALSE@ mkdir -p $(DESTDIR)/usr/local/include @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)/poweroff.h $(DESTDIR)/usr/local/include/poweroff.h @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)/Library/LaunchDaemons Modified: trunk/launchd/src/launchd_core_logic.c =================================================================== --- trunk/launchd/src/launchd_core_logic.c 2007-02-15 16:12:48 UTC (rev 23069) +++ trunk/launchd/src/launchd_core_logic.c 2007-02-15 18:26:22 UTC (rev 23070) @@ -80,6 +80,8 @@ #include "libvproc_public.h" #include "libvproc_internal.h" +#include "poweroff.h" + #include "launchd.h" #include "launchd_runtime.h" #include "launchd_unix_ipc.h" @@ -201,7 +203,7 @@ char *jm_stdout; char *jm_stderr; unsigned int global_on_demand_cnt; - unsigned int transfer_bstrap:1, sent_stop_to_hopeful_jobs:1, shutting_down:1; + unsigned int transfer_bstrap:1, sent_stop_to_hopeful_jobs:1, shutting_down:1, power_cycle:1; char name[0]; }; @@ -586,7 +588,7 @@ SLIST_REMOVE(&jm->parentmgr->submgrs, jm, jobmgr_s, sle); jobmgr_tickle(jm->parentmgr); } else if (getpid() == 1) { - jobmgr_assumes(jm, reboot(RB_HALT) != -1); + jobmgr_assumes(jm, reboot(jm->power_cycle ? RB_AUTOBOOT : RB_HALT) != -1); } else { exit(EXIT_SUCCESS); } @@ -4111,6 +4113,30 @@ } kern_return_t +job_mig_poweroff(job_t j, uint64_t flags) +{ + struct ldcred ldc; + + if (getpid() != 1) { + return BOOTSTRAP_NOT_PRIVILEGED; + } + + runtime_get_caller_creds(&ldc); + + if (ldc.euid) { + return BOOTSTRAP_NOT_PRIVILEGED; + } + + if (flags & POWEROFF_RESET) { + root_jobmgr->power_cycle = true; + } + + launchd_shutdown(); + + return 0; +} + +kern_return_t job_mig_set_integer(job_t j, get_set_int_key_t key, int64_t val) { kern_return_t kr = 0; Modified: trunk/launchd/src/libvproc.c =================================================================== --- trunk/launchd/src/libvproc.c 2007-02-15 16:12:48 UTC (rev 23069) +++ trunk/launchd/src/libvproc.c 2007-02-15 18:26:22 UTC (rev 23070) @@ -36,6 +36,8 @@ #include "protocol_vproc.h" +#include "poweroff.h" + kern_return_t _vproc_grab_subset(mach_port_t bp, mach_port_t *reqport, mach_port_t *rcvright, name_array_t *service_names, mach_msg_type_number_t *service_namesCnt, @@ -217,6 +219,34 @@ return (vproc_err_t)__vproc_tag_loginwindow_context; } +void * +poweroff(uint64_t flags) +{ + mach_port_t parent_port = 0; + mach_port_t previous_port = 0; + + do { + if (previous_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) { + goto out_bad; + } + + } while (parent_port != previous_port); + + if (vproc_mig_poweroff(parent_port, flags) == 0) { + return NULL; + } + +out_bad: + return poweroff; +} + vproc_err_t _vproc_set_global_on_demand(bool state) { Added: trunk/launchd/src/poweroff.h =================================================================== --- trunk/launchd/src/poweroff.h (rev 0) +++ trunk/launchd/src/poweroff.h 2007-02-15 18:26:22 UTC (rev 23070) @@ -0,0 +1,36 @@ +#ifndef _POWEROFF_H_ +#define _POWEROFF_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 <sys/cdefs.h> +#include <stdint.h> + +__BEGIN_DECLS + +#define POWEROFF_RESET 1 + +/* Returns NULL on success. Not NULL on failure */ + +__attribute__((visibility("default"))) void *poweroff(uint64_t flags); + +__END_DECLS + +#endif Modified: trunk/launchd/src/protocol_job.defs =================================================================== --- trunk/launchd/src/protocol_job.defs 2007-02-15 16:12:48 UTC (rev 23069) +++ trunk/launchd/src/protocol_job.defs 2007-02-15 18:26:22 UTC (rev 23070) @@ -41,7 +41,9 @@ __on_demand : boolean_t; out __server_port : mach_port_make_send_t); -skip; /* Last used in 10.4. Was bootstrap_unprivileged() */ +routine poweroff( + __bs_port : job_t; + __flags : uint64_t); routine check_in( __bs_port : job_t;