Index: server/slimservice.pl =================================================================== --- server/slimservice.pl (revision 33753) +++ server/slimservice.pl (working copy) @@ -652,6 +652,11 @@ # # Clean up resources and exit. # +sub restartServer { + + stopServer(); +} + sub stopServer { logger('')->info("Logitech Media Server shutting down."); Index: server/Slim/Control/Commands.pm =================================================================== --- server/Slim/Control/Commands.pm (revision 33753) +++ server/Slim/Control/Commands.pm (working copy) @@ -2845,7 +2845,7 @@ # pass true value if we want to restart the server if ($request->isCommand([['restartserver']])) { - Slim::Utils::OSDetect->getOS()->restartServer(); + main::restartServer(); } else { main::stopServer(); Index: server/Slim/Utils/OS/OSX.pm =================================================================== --- server/Slim/Utils/OS/OSX.pm (revision 33753) +++ server/Slim/Utils/OS/OSX.pm (working copy) @@ -436,11 +436,15 @@ sub installerExtension { 'dmg' }; sub installerOS { 'osx' } +sub canRestartServer { 1 } + sub restartServer { my $class = shift; my $helper = Slim::Utils::Misc::findbin('restart-server.sh'); - system("'$helper' &") if $helper; + return system("'$helper' &") if $helper; + + return 0; } Index: server/Slim/Utils/OS/Win32.pm =================================================================== --- server/Slim/Utils/OS/Win32.pm (revision 33753) +++ server/Slim/Utils/OS/Win32.pm (working copy) @@ -858,12 +858,6 @@ my $log = Slim::Utils::Log::logger('server.update'); - - if (!$class->canRestartServer()) { - $log->warn("Logitech Media Server can't be restarted automatically on Windows if run from the perl source."); - return; - } - if ($PerlSvc::VERSION && PerlSvc::RunningAsService()) { my $svcHelper = Win32::GetShortPathName( catdir( $class->installPath, 'server', 'squeezesvc.exe' ) ); @@ -871,15 +865,17 @@ Slim::bootstrap::tryModuleLoad('Win32::Process'); - if ($@ || !Win32::Process::Create( + return 1 + unless ($@ || !Win32::Process::Create( $processObj, $svcHelper, "$svcHelper --restart", 0, Win32::Process::DETACHED_PROCESS() | Win32::Process::CREATE_NO_WINDOW() | Win32::Process::NORMAL_PRIORITY_CLASS(), ".") - ) { - $log->error("Couldn't restart Logitech Media Server service (squeezesvc)"); + ); + + $log->error("Couldn't restart Logitech Media Server service (squeezesvc)"); } } @@ -889,14 +885,17 @@ if (open(RESTART, ">$restartFlag")) { close RESTART; main::stopServer(); + return 1; } else { $log->error("Can't write restart flag ($restartFlag) - don't shut down"); } } -}; + return 0; +} + sub canRestartServer { return $PerlSvc::VERSION ? 1 : 0; } 1; Index: server/Slim/Utils/OS/Unix.pm =================================================================== --- server/Slim/Utils/OS/Unix.pm (revision 33753) +++ server/Slim/Utils/OS/Unix.pm (working copy) @@ -128,4 +128,23 @@ # leave log rotation to the system sub logRotate {} -1; \ No newline at end of file +sub canRestartServer { 1 } + +sub restartServer { + + my $class = shift; + my ($progFile, $progArgs) = @_; + + # Prefer to execute the script directly if possible, otherwise + # invoke the interpreter to start the script. + # + # The difference between the two approaches is visible on + # some systems in the process title. See the process name + # in /proc/$$/stat on Linux as an example. + + my $execProg = (-x $progFile) ? $progFile : $^X; + + return exec($execProg, $progFile, @$progArgs); +} + +1; Index: server/Slim/Utils/OS.pm =================================================================== --- server/Slim/Utils/OS.pm (revision 33753) +++ server/Slim/Utils/OS.pm (working copy) @@ -422,19 +422,20 @@ sub directFirmwareDownload { 0 }; -=head2 restartServer( ) +=head2 restartServer( ) and canRestartServer -The server can initiate a restart on some systems. -This should call main::cleanup() or stopServer() to cleanly shut down before restarting +Squeezebox Server can initiate a restart on some systems. +These methods must only be called from main::restartServer and +main::canRestartServer which supervise other cleanup operations. +The implementations of the methods are redefined in each of the +OS implementations that can support the restart feature. + =cut -sub restartServer { - my $class = shift; - main::stopServer(1) if $class->canRestartServer(); -} +sub restartServer { 0 } -sub canRestartServer { 1 } +sub canRestartServer { 0 } sub progressJSON { } Index: server/Slim/Web/Settings/Server/Plugins.pm =================================================================== --- server/Slim/Web/Settings/Server/Plugins.pm (revision 33753) +++ server/Slim/Web/Settings/Server/Plugins.pm (working copy) @@ -15,8 +15,6 @@ use Slim::Utils::PluginManager; use Slim::Utils::OSDetect; -my $os = Slim::Utils::OSDetect->getOS(); - sub name { return Slim::Web::HTTP::CSRF->protectName('SETUP_PLUGINS'); } @@ -84,7 +82,7 @@ my ($class, $paramRef, $noRestartMsg) = @_; # show a link/button to restart SC if this is supported by this platform - if ($os->canRestartServer()) { + if (main::canRestartServer()) { $paramRef->{'restartUrl'} = $paramRef->{webroot} . $paramRef->{path} . '?restart=1'; $paramRef->{'restartUrl'} .= '&rand=' . $paramRef->{'rand'} if $paramRef->{'rand'}; @@ -109,7 +107,7 @@ sub restartServer { my ($class, $paramRef, $needsRestart) = @_; - if ($needsRestart && $paramRef->{restart} && $os->canRestartServer()) { + if ($needsRestart && $paramRef->{restart} && main::canRestartServer()) { $paramRef->{'warning'} = '' . Slim::Utils::Strings::string('RESTARTING_PLEASE_WAIT') @@ -130,7 +128,7 @@ } else { - $os->restartServer(); + main::restartServer(); } } Index: server/slimserver.pl =================================================================== --- server/slimserver.pl (revision 33753) +++ server/slimserver.pl (working copy) @@ -924,11 +924,13 @@ } open STDOUT, '>>/dev/null'; - + + # Do not attempt to daemonize again. + @argv = grep { $_ ne '--daemon' } @argv; + # On Leopard, GD will crash because you can't run CoreServices code in a forked child, # so we have to exec as well. if ( $^O =~ /darwin/ ) { - @argv = grep { $_ ne '--daemon' } @argv; exec $^X . ' "' . $0 . '" ' . join( ' ', @argv ); exit; } @@ -1083,22 +1085,34 @@ # # Clean up resources and exit. # +# All server code must direct stop and restart requests here and should +# not attempt to manipulate or interrogate the OS specific code directly. +# +sub canRestartServer { + return ! $::norestart && + Slim::Utils::OSDetect->getOS()->canRestartServer() ; +} + +sub restartServer { + + stopServer() unless ( canRestartServer() ); + + cleanup(); + + logger('')->info( 'Logitech Media Server restarting...' ); + + logger('')->error("Unable to restart Logitech Media Server") unless + Slim::Utils::OSDetect->getOS()->restartServer($0, \@argv); + + exit(); +} + sub stopServer { - my $restart = shift; - logger('')->info( 'Logitech Media Server ' . ($restart && !$::norestart ? 'restarting...' : 'shutting down.') ); - - $::stop = 1; - cleanup(); + + logger('')->info( 'Logitech Media Server shutting down.' ); - if ($restart && !$::norestart - && Slim::Utils::OSDetect->getOS()->canRestartServer() - && !main::ISWINDOWS) - { - exec($^X, $0, @argv); - } - exit(); }