2014-07-03 11 views
6

uczę "Zaawansowane programowanie w środowisku Unix", i mają problem z wykonywaniem No.11 w rozdziale 10.SIGXFSZ jest wysyłany przez jądro, chyba że coś zostanie wydrukowane na standardowe wyjście?

W moim programie ustawiłem RLIMIT_FSIZE na 1024.

Tak więc jądro powinno wysłać SIGXFSZ do mojego programu, gdy zapis próbuje przekroczyć ten limit.

Ale znalazłem, że SIGXFSZ nie jest wysyłane, chyba że coś zostanie wydrukowane na stdout.

Oto mój kod:

#include <unistd.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sys/time.h> 
#include <sys/resource.h> 
#include <signal.h> 

#define BUFFSIZE 100 

void xfsz_handler(int signo) 
{ 
    fprintf(stderr, "%d, %s\n", signo, strsignal(signo)); 
} 

int main(int argc, char* argv[]) 
{ 
    int n; 
    char buf[BUFFSIZE]; 
    struct rlimit fsizeLimit; 

    fsizeLimit.rlim_cur=1024; 
    fsizeLimit.rlim_max=1024; 
    if(setrlimit(RLIMIT_FSIZE, &fsizeLimit) < 0) 
    { 
     perror("setrlimit error"); 
     exit(-1); 
    } 

    if(signal(SIGXFSZ, xfsz_handler)==SIG_ERR) 
    { 
     fprintf(stderr, "set signal handler error for %d\n", SIGXFSZ); 
     exit(-1); 
    } 

    printf("what ever\n"); /* we need this to get SIGXFSZ sent */ 


    while ((n=read(STDIN_FILENO, buf, BUFFSIZE)) > 0) 
    { 
     int byteWrite = 0; 
     if ((byteWrite = write(STDOUT_FILENO, buf, n)) < 0) 
     { 
      perror("write error"); 
      exit(-1); 
     } 

     if(byteWrite!=n) 
     { 
      fprintf(stderr, "byteWrite=%d, n=%d\n", byteWrite, n); 
      exit(-1); 
     } 
    } 

    if (n<0) 
    { 
     perror("read error"); 
     exit(-1); 
    } 
    return 0; 
} 

jeśli I ustosunkowania się następującą linię w kodzie jądra nie będzie transmitować SIGXFSZ.

printf("What ever . . . \n"); 

Dlaczego tak się dzieje? Z góry dziękuję.

[[email protected] ex11]# ./myCopy </root/workspace/AdvanceProgrammingInTheUnixEnvironment.20140627.tar.bz2>aa.tar.bz2 
byteWrite=24, n=100 
[[email protected] ex11]# make 
gcc -o myCopy myCopy.c -std=gnu99 -I../../lib/ -L../../lib/ -lch10 
[[email protected] ex11]# ./myCopy </root/workspace/AdvanceProgrammingInTheUnixEnvironment.20140627.tar.bz2>aa.tar.bz2 
byteWrite=24, n=100 
25, File size limit exceeded 
[[email protected] ex11]# 
+0

10.11 W systemach Linux 3.2.0, Mac OS X 10.6.8 i Solaris 10 obsługa sygnału dla SIGXFSZ nigdy nie jest wywoływana. Ale zapis zwraca liczbę 24, jak tylko rozmiar pliku osiągnie 1024 bajty. Gdy rozmiar pliku osiągnął 1000 bajtów w FreeBSD 8.0, procedura obsługi sygnału jest wywoływana przy kolejnej próbie zapisu 100 bajtów, a wywołanie zapisu zwraca -1, przy ustawieniu errno na EFBIG ("Plik za duży"). Na wszystkich czterech platformach, jeśli spróbujemy dodatkowego zapisu przy aktualnym przesunięciu pliku (koniec pliku), otrzymamy SIGXFSZ i zapis nie powiedzie się, powracając-1 z errno ustawionym na EFBIG. – user3693690

+0

znalazłem to wyjaśnienie w dodatku c do książki. Mybe powinienem to zobaczyć zanim zadaję to pytanie ... – user3693690

+0

jeśli to jest sposób, w jaki kernel linuxa stosował SIGXFSZ, niech to będzie. Ale myślę, że to naprawdę dziwne. – user3693690

Odpowiedz

1

user3693690 znaleźć odpowiedź w dodatku C książki:

10,11 Pod Linuksem 3.2.0, Mac OS X 10.6.8 i Solaris 10, procedura obsługi sygnału dla SIGXFSZ nigdy nie nazwie [ponieważ pętla kończy program po krótkim wpisie], ale zapis zwraca liczbę 24, gdy tylko rozmiar pliku osiągnie 1024 bajty. Kiedy rozmiar pliku osiągnie 1000 bajtów w FreeBSD 8.0, obsługa sygnału jest wywoływana przy kolejnej próbie zapisu 100 bajtów, a wywołanie zapisu zwraca -1, przy ustawieniu errno na EFBIG ("Plik za duży"). Na wszystkich czterech platformach, jeśli spróbujemy dodatkowego zapisu przy bieżącym przesunięciu pliku (koniec pliku), otrzymamy SIGXFSZ i zapis nie powiedzie się, powracając-1 z errno ustawionym na EFBIG.

Jeśli jest to sposób, w jaki jądro Linuksa miało do czynienia z SIGXFSZ, niech tak będzie, ale myślę, że to naprawdę dziwne.

Powiązane problemy