How to restart Linux from inside a C++ program?
Asked Answered
G

7

21

I have a Qt 4 GUI where I need to have a option in a drop-down menu that allows the user to choose to restart the computer. I realize this might seem redunant with the ability to restart the computer in other ways, but the choice needs to stay there. I've tried using system() to call the following:

  1. a suid-root shell script
  2. a non-suid shell script
  3. a suid-root binary program

and all of them just cause

reboot: must be superuser
to be printed. Using system() to call reboot directly does the same thing. I'm not especially attached to using system() to do this, but it seemed like the most direct choice.

How can I reboot the system from the GUI?

Gizmo answered 20/4, 2010 at 21:25 Comment(6)
printf("Please push the reset button now");Scheldt
Have you tried running it as a superuser?Escaut
There are lots of ways to do this in Windows, but most are not intentionalLevan
blogs.msdn.com/oldnewthing/archive/2010/03/24/9983984.aspxGlandulous
This can be done within KDE apps. For instance, both KGet and KTorrent can told to turn off your computer when they've finished downloading. But I don't know if what they use to do that is KDE-specific or whether you can do it Qt without the KDE stuff.Rodrigues
FYI, Linux ignores the suid bit on scripts, since there is a serious security problem with allowing suid scripts. See section 5.5.3 here: docstore.mik.ua/orelly/networking/puis/ch05_05.htmGuyette
R
20

The reboot function is described in the Linux Programmer's Manual. Under glibc, you can pass the RB_AUTOBOOT macro constant to perform the reboot.

Note that if reboot is not preceded by a call to sync, data may be lost.

Using glibc in Linux:

#include <unistd.h>
#include <sys/reboot.h>

sync();
reboot(RB_AUTOBOOT);
Rickets answered 12/9, 2013 at 14:15 Comment(0)
D
9

In Linux:

#define LINUX_REBOOT_CMD_POWER_OFF 0x4321fedc   

sync();
reboot(LINUX_REBOOT_CMD_POWER_OFF);
Dyeline answered 30/1, 2011 at 11:31 Comment(1)
If you're using the glibc version, #include <sys/reboot.h> should be included in the above code... if so, just use the #define RB_POWER_OFF in that header file...Pinprick
S
4

Have you tried running a shell script, using gksudo? Something like

gksudo shutdown -r

With any luck, that should pull up a modal dialogue to get user credentials.

Shul answered 20/4, 2010 at 21:35 Comment(1)
Well, you don't really need to run it as a shell script, just execv it, or if you really want the PATH functionality that comes along with shell scripts, execvp.Petromilli
K
3

This should do it on almost any linux system.

#include <unistd.h>
#include <sys/reboot.h>

int main () {
  sync();
  setuid(0);
  reboot(RB_AUTOBOOT);
  return(0);
}

Then just compile with gcc reboot.c -o reboot and do chmod a+s reboot on the binary. Then call reboot as any user and the system should reboot smoothly. The way you do this through your GUI varies, as in if your Desktop Environment was KDE for example, it's quite different than doing the same thing under Fluxbox.

Kelda answered 8/10, 2017 at 4:21 Comment(0)
S
1

suid-ing shell scripts is just dangerous as already mentioned (which is why that didn't work).

I suspect that suid-ing the binary doesn't work because system spawns its subprocess with the user's actual uid and not the suid one, again for security reasons (it would let you substitute any binary for the one being called and run it as root).

You could put a copy of reboot in a location protected such that only users you want have permission to can execute it, and then suid-root THAT.

Alternately give them sudoer privilege to execute JUST the command you care about and system out to something like "ksh -c 'sudo reboot'"

Stephie answered 21/4, 2010 at 15:56 Comment(0)
M
0

In binary try to call

setuid (0);

before system() call.

Meghannmegiddo answered 20/4, 2010 at 21:41 Comment(1)
Thanks for the suggestion, but this didn't work when the program was called from another program. It does work if a program is called directly from the command line though.Gizmo
C
0

how would you reboot the system from the command line on your system?

basically do

system( <however you wouuld do it from the command line> );
Chemosynthesis answered 21/4, 2010 at 15:25 Comment(1)
Thanks for the suggestion, but that's what we've tried, and it doesn't work.Gizmo

© 2022 - 2024 — McMap. All rights reserved.