2010-04-20 56 views
13

Tôi có giao diện Qt 4 nơi tôi cần có tùy chọn trong trình đơn thả xuống cho phép người dùng chọn khởi động lại máy tính. Tôi nhận ra rằng điều này có vẻ như redunant với khả năng khởi động lại máy tính theo những cách khác, nhưng sự lựa chọn cần phải ở lại đó. Tôi đã thử sử dụng hệ thống() để gọi như sau:Làm thế nào để khởi động lại Linux từ bên trong một chương trình C++?

  1. một suid root shell script
  2. một kịch bản shell phi suid
  3. một suid gốc chương trình nhị phân

và tất cả chúng chỉ gây ra

reboot: must be superuser
để in. Sử dụng hệ thống() để gọi khởi động lại trực tiếp làm điều tương tự. Tôi không đặc biệt gắn liền với việc sử dụng hệ thống() để làm điều này, nhưng nó có vẻ giống như sự lựa chọn trực tiếp nhất.

Làm cách nào để khởi động lại hệ thống từ GUI?

+13

printf ("Vui lòng nhấn nút đặt lại ngay bây giờ"); –

+2

Bạn đã thử chạy nó như một superuser? – fingerprint211b

+7

Có rất nhiều cách để thực hiện việc này trong Windows, nhưng hầu hết không phải là cố ý – RickNotFred

Trả lời

5

Bạn đã thử chạy tập lệnh shell, sử dụng gksudo chưa? Một cái gì đó giống như

gksudo shutdown -r 

Với bất kỳ may mắn nào, việc này sẽ tạo ra một cuộc đối thoại để nhận thông tin xác thực người dùng.

+0

Vâng, bạn không thực sự cần chạy nó như là một kịch bản lệnh shell, chỉ cần 'execv' nó, hoặc nếu bạn thực sự muốn hàm PATH đi kèm với các kịch bản lệnh shell, 'execvp'. – Cascabel

0

Trong nhị phân cố gắng để gọi

setuid (0); 

trước khi hệ thống) gọi (.

+0

Cảm ơn bạn đã đề xuất, nhưng điều này không hoạt động khi chương trình được gọi từ một chương trình khác. Nó hoạt động nếu một chương trình được gọi trực tiếp từ dòng lệnh. –

0

cách bạn khởi động lại hệ thống từ dòng lệnh trên hệ thống của bạn?

về cơ bản làm

system(<however you wouuld do it from the command line>); 
+1

Cảm ơn bạn đã đề xuất, nhưng đó là những gì chúng tôi đã thử và nó không hoạt động. –

1

kịch bản shell suid-ing chỉ là nguy hiểm như đã đề cập (đó là lý do mà không làm việc).

Tôi nghi ngờ việc tạo nhị phân không hoạt động vì hệ thống sinh ra tiến trình con với uid thực tế của người dùng và không phải là suid, một lần nữa vì lý do bảo mật (nó sẽ cho phép bạn thay thế bất kỳ nhị phân nào chạy nó dưới dạng root).

Bạn có thể đặt bản sao khởi động lại ở một vị trí được bảo vệ sao cho chỉ những người dùng bạn muốn có quyền mới có thể thực thi nó và sau đó suid-root THAT.

Cách khác cung cấp cho họ sudoer đặc quyền để thực hiện JUST lệnh mà bạn quan tâm và hệ thống ra cái gì đó như "ksh -c 'sudo reboot'"

7

Trong Linux:

#define LINUX_REBOOT_CMD_POWER_OFF 0x4321fedc 

sync(); 
reboot(LINUX_REBOOT_CMD_POWER_OFF); 
+4

Nếu bạn đang sử dụng phiên bản glibc, #include nên được bao gồm trong mã ở trên ... nếu có, chỉ cần sử dụng #define RB_POWER_OFF trong tệp tiêu đề đó ... – AceFunk

+0

Điều này phù hợp với Minix 3 là tốt. –

8

Chức năng reboot được mô tả trong Linux Programmer's Manual. Dưới glibc, bạn có thể vượt qua hằng số macro RB_AUTOBOOT để thực hiện khởi động lại.

Lưu ý rằng nếu reboot không có trước cuộc gọi đến sync, dữ liệu có thể bị mất.

Sử dụng glibc trong Linux:

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

sync(); 
reboot(RB_AUTOBOOT); 
0

này nên làm điều đó trên hầu hết các hệ thống Linux.

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

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

Sau đó, chỉ biên dịch với gcc reboot.c -o reboot và làm chmod a+s reboot trên nhị phân. Sau đó gọi khởi động lại như bất kỳ người dùng nào và hệ thống sẽ khởi động lại suôn sẻ. Cách bạn làm điều này thông qua GUI của bạn khác nhau, như trong môi trường Desktop của bạn là KDE, ví dụ, nó hoàn toàn khác với việc làm tương tự trong Fluxbox.

Các vấn đề liên quan