Is SIGXFSZ sent by the kernel if something doesn't print to stdout?

I am studying Advanced Unix Programming and have a problem with exercise 11 in chapter 10 .

In my program, I set RLIMIT_FSIZE to 1024 .

Therefore, the kernel should send SIGXFSZ to my program when writing, trying to exceed this limit.

But I found that SIGXFSZ not sent unless something is printed on stdout .

Here is my code:

 #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; } 

If I comment on the next line in the code, the kernel will not pass SIGXFSZ .

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

Why is this happening? Thanks in advance.

 [ root@luaDevelopment ex11]# ./myCopy < /root/workspace/AdvanceProgrammingInTheUnixEnvironment.20140627.tar.bz2 >aa.tar.bz2 byteWrite=24, n=100 [ root@luaDevelopment ex11]# make gcc -o myCopy myCopy.c -std=gnu99 -I../../lib/ -L../../lib/ -lch10 [ root@luaDevelopment ex11]# ./myCopy < /root/workspace/AdvanceProgrammingInTheUnixEnvironment.20140627.tar.bz2 >aa.tar.bz2 byteWrite=24, n=100 25, File size limit exceeded [ root@luaDevelopment ex11]# 
+6
source share
1 answer

user3693690 found the answer in Appendix C of the book:

10.11 On Linux 3.2.0, Mac OS X 10.6.8, and Solaris 10, the signal handler for SIGXFSZ is never called [because the loop exits the program with a short write], but the record returns a count of 24 as soon as the file size reaches 1024 bytes. When the file size reaches 1000 bytes in FreeBSD 8.0, the signal handler is called on the next attempt to write 100 bytes, and the write call returns -1, and errno returns in EFBIG ("The file is too large"). On all four platforms, if we try to perform additional recording at the current file offset (end of file), we will get SIGXFSZ, and the recording will fail, return -1 with the error set to EFBIG.

If that's the way the Linux kernel is used to work with SIGXFSZ, so be it, but I think it's really weird.

+1
source

Source: https://habr.com/ru/post/971696/


All Articles