fprintf(stderr, "%s is not a symbolic link\n", link_path);
else
/* Произошла какая-то другая ошибка. */
perror("readlink");
return 1;
} else {
/* Завершаем путевое имя нулевым символом. */
target_path[len] = '\0';
/* Выводим результат. */
printf("%s\n", target_path);
return 0;
}
}
Ниже показано, как создать символическую ссылку и проверить ее с помощью программы print-symlink
:
% ln -s /usr/bin/wc my_link
% ./print-symlink my_link
/usr/bin/wc
8.12. Функция sendfile(): быстрая передача данных
Функция sendfile()
— это эффективный механизм копирования данных из одного файлового дескриптора в другой. Дескрипторам могут соответствовать дисковые файлы, сокеты или устройства.
Обычно цикл копирования реализуется следующим образом. Программа выделяет буфер фиксированного размера, перемещает в него данные из исходного дескриптора, затем записывает содержимое буфера во второй дескриптор и повторяет описанную процедуру до тех пор, пока не будут скопированы все данные. Такая схема неэффективна как с точки зрения времени, так и с точки зрения затрат памяти, поскольку выделяется дополнительный буфер и над его содержимым выполняются операции копирования.
Функция sendfile()
устраняет потребность в создании промежуточного буфера. Ей передаются дескриптор для записи, дескриптор для чтения, указатель на переменную смещения и число копируемых данных. Переменная смещения определяет позицию входного файла, с которой начинается копирование (0 — это начало файла). После окончания копирования переменная будет содержать смещение конца блока. Функция sendfile()
объявлена в файле .
Программа, показанная в листинге 8.10, представляет собой простую, но очень эффективную реализацию механизма файлового копирования. Она принимает в командной строке два имени файла и копирует содержимое первого файла во второй. Размер исходного файла определяется с помощью функции fstat()
.
Листинг 8.10. ( сору.с ) Копирование файла с помощью функции sendfile()
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char* argv[]) {
int read_fd;
int write_fd;
struct stat stat_buf;
off_t offset = 0;
/* Открытие входного файла. */
read_fd = open(argv[1], O_RDONLY);
/* Определение размера входного файла. */
fstat(read_fd, &stat_buf);
/* Открытие выходного файла для записи. */
write_fd =
open(argv[2], O_WRONLY | O_CREAT, stat_buf.st_mode);
/* Передача данных из одного файла в другой. */
sendfile(write_fd, read_fd, &offset, stat_buf.st_size);
/* Закрытие файлов. */
close(read_fd);
close(write_fd);
return 0;
}
Функция sendfile()
часто используется для повышения эффективности копирования. Она широко применяется Web-серверами и сетевыми демонами, предоставляющими файлы по сети клиентским программам. Запрос обычно поступает через сокет. Серверная программа открывает локальный дисковый файл, извлекает из него данные и записывает их в сокет. Благодаря функции sendfile()
эта операция существенно ускоряется.
8.13. Функция setitimer(): задание интервальных таймеров
Функция setitimer()
является обобщением системного вызова alarm()
. Она планирует доставку сигнала по истечении заданного промежутка времени.
С помощью функции setitimer()
можно создавать таймеры трех типов.
■ ITIMER_REAL
. По истечении указанного времени процессу посылается сигнал SIGALRM
.
■ ITIMER_VIRTUAL
. После того как процесс отработал требуемое время, ему посылается сигнал SIGVTALRM
. Время, когда процесс не выполнялся (работало ядро или другой процесс), не учитывается.
■ ITIMER_PROF
. По истечении указанного времени процессу посылается сигнал SIGPROF
. Учитывается время выполнения самого процесса, а также запускаемых в нем системных вызовов.
Код таймера задается в первом аргументе функции setitimer()
. Второй аргумент — это указатель на структуру типа itimerval
, содержащую параметры таймера. Третий аргумент либо равен NULL
, либо является указателем на другую структуру itimerval
, куда будут записаны прежние параметры таймера.
В структуре itimerval
два поля.
■ it_value
. Здесь находится структура типа timeval
, где записано время отправки сигнала. Если это поле равно нулю, таймер отменяется.
■ it_interval
. Это еще одна структура timeval
, определяющая, что произойдет после отправки первого сигнала. Если она равна нулю, таймер будет отменен. В противном случае здесь записан интервал генерирования сигналов.
Читать дальше