Системный вызов 
close. Раньше я думал, что для прикладной программы файл закрывается мгновенно, а далее система потихоньку освобождает системный буфер файлов, но выяснилось, что это не так. Минимальный пример. В качестве аргумента указать имя файла для копирования, он будет скопирован под именем "
test". Файл у меня 374 кб.
//   gcc test.c -o test.cgi -Wall -Werror -O3
//   ./test.cgi
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
//------------------- gettime_dt_msek ----------------------
// разность двух временных меток в миллисекундах
int gettime_dt_msek(struct timeval *tv1, struct timeval *tv2)
{
    return((tv2->tv_sec - tv1->tv_sec)*1000 +
           (tv2->tv_usec - tv1->tv_usec + 500)/1000);
}
//--------- time_metka --------
// печатает метку времени. tv0 -начало отсчета времени.
void time_metka(struct timeval *tv0, const char *metka)
{
    int t;
    struct timeval tv1;
    gettimeofday(&tv1, NULL);
    t = gettime_dt_msek(tv0, &tv1);
    printf("%s=%d.%03d sec\n", metka, t/1000, t%1000);
    return;
}
//------------ main --------------
int main(int argc, char **argv)
{
    struct timeval tv0[1];
    int fd1, fd2, k, n;
    char buf[8192];
    if(argc<2){ printf("Err-arg\n"); exit(0);}
    gettimeofday(tv0, NULL); // начало отсчета времени
    fd1=open(argv[1], O_RDONLY);
    if(fd1<0){ printf("fd1=open(%s)<0\n", argv[1]); exit(0);};
    //unlink("test");
    time_metka(tv0, "t1");
    fd2=open("test", O_CREAT|O_TRUNC|O_WRONLY, 00644);
    if(fd2<0){ printf("fd2=open()<0\n"); exit(0);};
    time_metka(tv0, "t2");
    while(1){
        k=read(fd1, buf, sizeof(buf));
        if(k<0){ printf("Error read\n"); exit(0);}
        if(k==0) break;
        n=write(fd2, buf, k);
        if(n != k){ printf("Error write\n"); exit(0);}
    }
    time_metka(tv0, "t3");
    close(fd1);
    time_metka(tv0, "t4");
    close(fd2);
    time_metka(tv0, "t5");
    exit(0);
}
/*
Тестовый файл для копирования 374 кб
Распечатка с закомментированным unlink.
Первый запуск, когда ещё нет выходного файла.
t1=0.000 sec
t2=0.000 sec
t3=1.182 sec
t4=1.182 sec
t5=1.182 sec
Следующие запуски.
t1=0.000 sec
t2=0.196 sec
t3=1.308 sec
t4=1.308 sec
t5=9.448 sec
Распечатка с раскомментированным unlink.
Первый запуск, когда ещё нет выходного файла.
t1=0.000 sec
t2=0.000 sec
t3=1.221 sec
t4=1.221 sec
t5=1.221 sec
Следующие запуски.
t1=0.208 sec
t2=0.209 sec
t3=1.395 sec
t4=1.395 sec
t5=1.395 sec
*/
 
  В программе есть закомментированная строка 
unlink, она существенно влияет. Имею пять меток времени. При распечатке отсчет от нулевой метки (
tv0).
Вопрос 1. Есть ли какое-нибудь объяснение этому явлению, почему так надолго подвисает 
close, если файл уже существует и открыт с флагом 
O_TRUNC, т. е. с опустошением? И зачем система его подвешивает?
Вопрос 2. Вызов 
close может быть прерван сигналом с ошибкой 
EINTR. Что при этом происходит? Немедленный возврат? А что с файлом, закрыт он или открыт? Или открыт наполовину? Не может же система так на половине всё бросить. Казалось бы, она должна тогда дозакрыть файл в фоновом режиме. Или же прикладная программа при получении 
EINTR может дальше пользоваться этим файлом как открытым, включая повторный вызов 
close?
Прошу ответить. Если можно, в общих чертах словами. Ссылки на английские тексты мне не прочитать.