diff --git a/src/apps/installer/InstallerApp.cpp b/src/apps/installer/InstallerApp.cpp index 51ec1d284e..b71580579d 100644 --- a/src/apps/installer/InstallerApp.cpp +++ b/src/apps/installer/InstallerApp.cpp @@ -1,4 +1,5 @@ /* + * Copyright 2015, Axel Dörfler * Copyright 2009, Stephan Aßmus * Copyright 2005, Jérôme DUVAL. * All rights reserved. Distributed under the terms of the MIT License. @@ -6,10 +7,16 @@ #include "InstallerApp.h" +#include + #include +#include #include +#include + #include "tracker_private.h" +#include "Utility.h" static const uint32 kMsgAgree = 'agre'; @@ -108,3 +115,25 @@ InstallerApp::ReadyToRun() new InstallerWindow(); #endif } + + +void +InstallerApp::Quit() +{ + BApplication::Quit(); + + if (!be_roster->IsRunning(kDeskbarSignature)) { + // Synchronize disks, and reboot the system + sync(); + + if (Utility::IsReadOnlyVolume("/boot")) { + // Unblock CD tray, and eject the CD + Utility::BlockMedia("/boot", false); + Utility::EjectMedia("/boot"); + } + + // Quickly shutdown without possibly touching anything on disk + // (which we might just have ejected) + _kern_shutdown(false); + } +} diff --git a/src/apps/installer/InstallerApp.h b/src/apps/installer/InstallerApp.h index 49aa72a5e9..4fb43aa81b 100644 --- a/src/apps/installer/InstallerApp.h +++ b/src/apps/installer/InstallerApp.h @@ -18,8 +18,10 @@ public: InstallerApp(); virtual void MessageReceived(BMessage* message); + virtual void AboutRequested(); virtual void ReadyToRun(); + virtual void Quit(); private: EULAWindow* fEULAWindow; diff --git a/src/apps/installer/Jamfile b/src/apps/installer/Jamfile index e3146bc35f..71e02303fe 100644 --- a/src/apps/installer/Jamfile +++ b/src/apps/installer/Jamfile @@ -1,7 +1,10 @@ SubDir HAIKU_TOP src apps installer ; UsePrivateHeaders shared storage tracker ; +UsePrivateSystemHeaders ; + SubDirHdrs [ FDirName $(HAIKU_TOP) src kits tracker ] ; +SubDirHdrs [ FDirName $(HAIKU_TOP) src servers launch ] ; Application Installer : CopyEngine.cpp @@ -14,11 +17,18 @@ Application Installer : ProgressReporter.cpp UnzipEngine.cpp WorkerThread.cpp - : be tracker translation libshared.a [ TargetLibstdc++ ] + + # From launch_daemon + Utility.cpp + + : be tracker translation libshared.a [ TargetLibstdc++ ] localestub : Installer.rdef ; +SEARCH on Utility.cpp = [ + FDirName $(HAIKU_TOP) src servers launch ] ; + DoCatalogs Installer : x-vnd.Haiku-Installer : diff --git a/src/servers/launch/Utility.cpp b/src/servers/launch/Utility.cpp index 7d1c727b71..17f139f76c 100644 --- a/src/servers/launch/Utility.cpp +++ b/src/servers/launch/Utility.cpp @@ -17,6 +17,38 @@ #include +namespace { + + +status_t +IssueDeviceCommand(const char* path, int opcode, void* buffer, + size_t bufferSize) +{ + fs_info info; + if (fs_stat_dev(dev_for_path(path), &info) == B_OK) { + if (strcmp(info.fsh_name, "devfs") != 0) + path = info.device_name; + } + + int device = open(path, O_RDONLY); + if (device < 0) + return device; + + status_t status = B_OK; + + if (ioctl(device, opcode, buffer, bufferSize) != 0) { + fprintf(stderr, "Failed to process %d on %s: %s\n", opcode, path, + strerror(errno)); + status = errno; + } + close(device); + return status; +} + + +} // private namespace + + namespace Utility { @@ -55,25 +87,15 @@ IsReadOnlyVolume(const char* path) status_t BlockMedia(const char* path, bool block) { - fs_info info; - if (fs_stat_dev(dev_for_path(path), &info) == B_OK) { - if (strcmp(info.fsh_name, "devfs") != 0) - path = info.device_name; - } + return IssueDeviceCommand(path, B_SCSI_PREVENT_ALLOW, &block, + sizeof(block)); +} - int device = open(path, O_RDONLY); - if (device < 0) - return device; - status_t status = B_OK; - - if (ioctl(device, B_SCSI_PREVENT_ALLOW, &block, sizeof(block)) != 0) { - fprintf(stderr, "Failed to block media on %s: %s\n", path, - strerror(errno)); - status = errno; - } - close(device); - return status; +status_t +EjectMedia(const char* path) +{ + return IssueDeviceCommand(path, B_EJECT_DEVICE, NULL, 0); } diff --git a/src/servers/launch/Utility.h b/src/servers/launch/Utility.h index 183b21502c..b5daf6d017 100644 --- a/src/servers/launch/Utility.h +++ b/src/servers/launch/Utility.h @@ -14,6 +14,7 @@ namespace Utility { bool IsReadOnlyVolume(const char* path); status_t BlockMedia(const char* path, bool block); + status_t EjectMedia(const char* path); }