2010-08-04 31 views
8

Tôi đang cố gắng làm điều gì đó hơi lạ ở đây. Tôi cần phải bắt đầu một quá trình, logcat, từ một deamon sẽ chạy ở chế độ nền và in tới thiết bị đầu cuối mà không cần kiểm soát stdin. Nó là dành cho việc ghi nhật ký lý tưởng vì vậy logcat sẽ in các thông điệp tường trình trong khi vẫn cho phép người dùng nhập các lệnh chuẩn và khởi tạo các chương trình từ trình bao. Đây là mã cho daemon tôi có cho đến nay. Chương trình, logcat, bắt đầu và hiển thị các thông điệp tường trình nhưng tôi không thể nhập bất kỳ lệnh nào vào stdin vì nó xuất hiện chương trình đã kiểm soát stdin.Bắt đầu một quá trình trong nền trong Linux với C

int main (int argc, char** argv, char** env) 
{ 
    int fd; 
    if ((fd = open("/dev/console", O_RDWR)) < 0) { 
     fd = open("/dev/null", O_RDWR); 
    } 
    printf("THIS IS A TEST\n"); 
    dup2(1, fd); 
    dup2(2, fd); 

    pid_t childpid = fork(); 

    if(childpid == -1) { 
     perror("Failed to fork, logcat not starting"); 
     return 1; 
    } 

    if(childpid == 0) { 
     //this is the child, exec logcat 
     setsid(); 
     int execReturn = execl("/system/bin/logcat", "logcat", (char *) 0); 
    } else { 
     //this is the parent do nothing 
     close(fd); 
     return 0; 
    } 
    close(fd); 
    return 0; 
} 

Cảm ơn

Trả lời

4

Lệnh 'logcat' có vẻ là để phát triển Android - đó có thể giải thích vị trí lẻ của lệnh.

Các hoạt động quan trọng mà bạn phải sửa chữa là để đảm bảo rằng bạn đóng đầu vào của bạn hiện tại tiêu chuẩn (nhà ga) và mở /dev/null/ cho thiết bị đầu vào:

close(0); 
if ((fd = open("/dev/null", O_RDONLY)) != 0) 
    ...error - failed to open /dev/null! 

này có nghĩa là quá trình con daemonized của bạn sẽ không đọc bất cứ thứ gì từ nhà ga.


Những gì tôi nghĩ rằng bạn muốn làm là:

  1. Chạy chương trình phóng từ một dòng lệnh, trong đó sẽ có đầu vào tiêu chuẩn, đầu ra tiêu chuẩn và sai số chuẩn kết nối với 'nhà ga'.
  2. Bên trong chương trình của bạn, bạn muốn thay thế đầu vào chuẩn sao cho nó xuất phát từ /dev/null.
  3. Bạn muốn để riêng đầu ra tiêu chuẩn - bạn muốn logcat để ghi vào đầu ra tiêu chuẩn hiện tại.
  4. Có thể bạn cũng muốn để lỗi chuẩn.

Tại một số điểm trong quá trình tố tụng, bạn làm bạn daemonization đúng cách (vay liên kết từ câu trả lời @ bstpierre của), đảm bảo rằng các thiết bị đầu cuối bạn được kết nối với không phải là thiết bị đầu cuối kiểm soát của bạn, do đó ngắt và hangups gửi đến thiết bị đầu cuối không ảnh hưởng đến daemon của bạn. Hệ thống ống nước đơn giản hơn những gì bạn đã thiết lập - bạn nên xử lý đầu vào tiêu chuẩn và để lại đầu ra tiêu chuẩn và lỗi chuẩn không thay đổi (thay vì thay đổi đầu ra và để nguyên đầu vào không thay đổi).

Bây giờ, bạn có thể muốn đầu ra đi tới /dev/console; nếu có, thì hãy sửa lại mã để mở /dev/console. Tuy nhiên, không hợp lý để quay lại /dev/null nếu bạn không thể mở /dev/console; chương trình của bạn nên báo cáo lỗi và không thành công (vì không có điểm nào trong việc ghi logcat vào /dev/null!). Hãy chắc chắn rằng bạn mở giao diện điều khiển với cờ O_NOCTTY để nó không trở thành thiết bị đầu cuối điều khiển cho daemon.

Các bình luận cuối cùng tôi muốn làm là:

  • Bạn có chắc chắn bạn muốn văn bản ngẫu nhiên xuất hiện trên thiết bị đầu cuối hoặc giao diện điều khiển của bạn khi nó được sử dụng cho những thứ khác?

Tôi không thích điều đó khi điều đó xảy ra.


Xem thêm: SO 958249

+0

Cảm ơn bạn rất nhiều vì câu trả lời chuyên sâu của bạn. Vấn đề là stdin như bạn đã đề cập. Tôi đã phải chuyển hướng từ logcat sang stdin, cùng với một số công cụ khác như daemonizing quá trình. Điều này đã giúp tôi tiết kiệm rất nhiều căng thẳng và lo lắng. Cảm ơn một lần nữa tôi thực sự đánh giá cao nó. – Mike

4
+0

này đã giúp một tấn. Cảm ơn bạn. – Mike

+0

@Mike - có rất nhiều thứ bạn có thể nhận được sai ... Tôi đã để lại bit trước và bài viết đó là một điểm khởi đầu tốt để ghi nhớ tất cả các phần. – bstpierre

+2

Liên kết dường như đã chết. – Bharat

0

Có chức năng có mục tiêu đặc biệt cho điều này trong glibc:

#include <unistd.h> 

... 
/* We are in the parent, yet */ 
daemon(0,0); 
/* Now we are in the child */ 
... 

Xem thêm chi tiết tại đây http://linux.die.net/man/3/daemon

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