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]#
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
znalazłem to wyjaśnienie w dodatku c do książki. Mybe powinienem to zobaczyć zanim zadaję to pytanie ... – user3693690
jeśli to jest sposób, w jaki kernel linuxa stosował SIGXFSZ, niech to będzie. Ale myślę, że to naprawdę dziwne. – user3693690