ИМЯ
link, linkat -
    создаёт
    новое имя
    файла
ОБЗОР
#include <unistd.h>
int link(const char *oldpath, const char *newpath);
#include <fcntl.h>           /* определения констант of AT_* */
#include <unistd.h>
int linkat(int olddirfd, const char *oldpath,
           int newdirfd, const char *newpath, int flags);
  
  Требования
    макроса
    тестирования
    свойств
    для glibc (см.
    feature_test_macros(7)):
  
linkat():
  - Начиная с glibc
    2.10:
- _POSIX_C_SOURCE >= 200809L
- До glibc 2.10:
- _ATFILE_SOURCE
 
ОПИСАНИЕ
link()
    создаёт
    новую
    ссылку
    (также
    называемую
    жёсткую
    ссылку) на
    существующий
    файл.
Если newpath
    существует,
    то он не
    будет
    перезаписан.
Это новое
    имя может
    использоваться
    как и
    старое для
    любых
    операций;
    оба имени
    ссылаются
    на один
    файл (и
    имеют
    одинаковые
    права и
    владельцев)
    и
    невозможно
    сказать
    какое имя
    считать
    "изначальным".
Системный
    вызов linkat()
    работает
    также как
    системный
    вызов link(), за
    исключением
    случаев,
    описанных
    здесь.
Если в oldpath
    задан
    относительный
    путь, то он
    считается
    относительно
    каталога,
    на который
    ссылается
    файловый
    дескриптор
    olddirfd (а не
    относительно
    текущего
    рабочего
    каталога
    вызывающего
    процесса,
    как это
    делается в
    link()).
Если в oldpath
    задан
    относительный
    путь и olddirfd
    равно
    специальному
    значению
    AT_FDCWD, то oldpath
    рассматривается
    относительно
    текущего
    рабочего
    каталога
    вызывающего
    процесса
    (как link()).
Если в oldpath
    задан
    абсолютный
    путь, то olddirfd
    игнорируется.
Значение
    newpath
    интерпретируется
    как oldpath, за
    исключением
    того, что
    относительный
    путь
    интерпретируется
    относительно
    каталога,
    на который
    ссылается
    файловый
    дескриптор
    newdirfd.
Следующие
    значения
    можно
    побитово (OR)
    объединять
    в flags:
  - AT_EMPTY_PATH
    (начиная с Linux
    2.6.39)
- Если
      значение
      oldpath равно
      пустой
      строке, то
      создаётся
      ссылка на
      файл, на
      который
      указывает
      olddirfd (который
      может быть
      получен с
      помощью open(2)
      с флагом O_PATH).
      В этом
      случае olddirfd
      может
      указывать
      на файл
      любого
      типа кроме
      каталога.
      Это,
      обычно, не
      работает,
      если файл
      имеет
      счётчик
      ссылок
      равный
      нулю
      (исключение
      — файлы,
      созданные
      с флагом O_TMPFILE
      и без O_EXCL).
      Вызывающий
      должен
      иметь
      мандат
      CAP_DAC_READ_SEARCH, чтобы
      использовать
      этот флаг.
      Данный
      флаг есть
      только в Linux;
      для
      получения
      его
      определения
      определите
      _GNU_SOURCE.
- AT_SYMLINK_FOLLOW
    (начиная с Linux
    2.6.18)
- По
      умолчанию,
      linkat() не
      разыменовывает
      oldpath, если это
      символьная
      ссылка
      (подобно link()).
      В flags можно
      указать
      флаг AT_SYMLINK_FOLLOW, и
      тогда
      значение
      oldpath будет
      разыменовано,
      если это
      символьная
      ссылка.
      Если
      смонтирована
      procfs, то это
      может быть
      использовано
      как
      альтернатива
      AT_EMPTY_PATH,
      например:
  
  - 
    
    linkat(AT_FDCWD, "/proc/self/fd/<fd>", newdirfd,
       newname, AT_SYMLINK_FOLLOW);
До версии
    ядра 2.6.18
    аргумент
    flags не
    использовался
    и должен
    был быть
    равен 0.
Смотрите
    в openat(2)
    объяснение
    необходимости
    linkat().
ВОЗВРАЩАЕМОЕ
  ЗНАЧЕНИЕ
При
    успешном
    выполнении
    возвращается
    0. В случае
    ошибки
    возвращается
    -1, а errno
    устанавливается
    в
    соответствующее
    значение.
ОШИБКИ
  - EACCES
- Нет прав на
      запись в
      каталог,
      содержащий
      newpath, или в
      одном из
      каталогов
      пути до oldpath
      или newpath не
      разрешён
      поиск (см.
      также path_resolution(7)).
- EDQUOT
- Исчерпана
      пользовательская
      квота на
      дисковые
      блоки
      файловой
      системы.
- EEXIST
- newpath уже
      существует.
- EFAULT
- Значения
      oldpath и newpath
      указывают
      за пределы
      доступного
      адресного
      пространства.
- EIO
- Произошла
      ошибка
      ввода-вывода.
- ELOOP
- Во время
      определения
      oldpath или newpath
      встретилось
      слишком
      много
      символьных
      ссылок.
- EMLINK
- На файл, на
      который
      указывает
      oldpath, уже
      создано
      максимальное
      количество
      ссылок.
      Например,
      для
      файловой
      системы ext4(5),
      в которой
      не
      используется
      свойство
      dir_index,
      ограничение
      по
      количеству
      жёстких
      ссылок на
      файл равно
      65000; в btrfs(5) — 65535
      ссылок.
- ENAMETOOLONG
- Слишком
      длинное
      значение
      аргумента
      oldpath или newpath.
- ENOENT
- Компонент
      каталога в
      oldpath или newpath не
      существует
      или
      является
      повисшей
      ссылкой.
- ENOMEM
- Недостаточное
      количество
      памяти
      ядра.
- ENOSPC
- На
      устройстве,
      содержащем
      файл, нет
      места для
      создания
      нового
      элемента
      каталога.
- ENOTDIR
- Компонент,
      используемый
      как
      каталог в
      oldpath или newpath, на
      самом деле
      не
      является
      каталогом.
- EPERM
- oldpath
      является
      каталогом.
- EPERM
- Файловая
      система,
      содержащая
      oldpath и newpath, не
      поддерживает
      создание
      жёстких
      ссылок.
- EPERM
    (начиная с Linux
    3.6)
- Вызывающий
      не имеет
      прав для
      создания
      жёстких
      ссылок на
      этот файл
      (смотрите
      описание
      /proc/sys/fs/protected_hardlinks в proc(5)).
- EPERM
- Файл oldpath
      помечен
      как
      неизменяемый
      (immutable) или
      только для
      добавления
      (смотрите
      ioctl_iflags(2)).
- EROFS
- Файл
      расположен
      в файловой
      системе,
      доступной
      только для
      чтения.
- EXDEV
- oldpath и newpath
      находятся
      не в одной
      смонтированной
      файловой
      системе (Linux
      позволяет
      монтировать
      файловую
      систему в
      несколько
      точек, но link()
      не
      работает с
      отличающими
      точками
      монтирования,
      даже если в
      них
      смонтирована
      идентичная
      файловая
      система).
В linkat()
    дополнительно
    могут
    возникнуть
    следующие
    ошибки:
  - EBADF
- В olddirfd или newdirfd
      указаны
      неправильные
      файловые
      дескрипторы.
- EINVAL
- В flags
      указано
      неверное
      значение
      флага.
- ENOENT
- Флаг AT_EMPTY_PATH
      указан в flags,
      но
      вызывающий
      не имеет
      мандата
      CAP_DAC_READ_SEARCH.
- ENOENT
- Предпринята
      попытка
      сделать
      ссылку на
      файл /proc/self/fd/NN,
      который
      соответствует
      файловому
      дескриптору,
      созданному
      с помощью
  
  - 
    
     open(path, O_TMPFILE | O_EXCL, mode);
- Смотрите
      open(2).
  - ENOENT
- Значение
      oldpath
      является
      относительным
      путём и olddirfd
      ссылается
      на каталог,
      который
      был удалён,
      или newpath
      является
      относительным
      путём и newdirfd
      ссылается
      на каталог,
      который
      был
    удалён.
- ENOTDIR
- Значение
      oldpath
      содержит
      относительный
      путь и olddirfd
      содержит
      файловый
      дескриптор,
      указывающий
      на файл, а
      не на
      каталог;
      или
      произошло
      тоже самое
      с newpath и newdirfd.
- EPERM
- Значение
      AT_EMPTY_PATH было
      указано в
      flags,
      значение
      oldpath равно
      пустой
      строке и olddirfd
      указывает
      на
    каталог.
ВЕРСИИ
Вызов linkat()
    был
    добавлен в
    ядро Linux
    версии 2.6.16;
    поддержка
    в glibc
    доступна с
    версии 2.4.
СООТВЕТСТВИЕ
  СТАНДАРТАМ
link(): SVr4, 4.3BSD, POSIX.1-2001 (но
    смотрите
    ЗАМЕЧАНИЯ),
    POSIX.1-2008.
linkat(): POSIX.1-2008.
ЗАМЕЧАНИЯ
Жёсткие
    ссылки,
    создаваемые
    link(), не могут
    располагаться
    в разных
    файловых
    системах.
    Если это
    необходимо,
    используйте
    symlink(2).
В POSIX.1-001
    сказано,
    что link()
    должен
    разыменовывать
    oldpath, если он
    является
    символьной
    ссылкой.
    Однако,
    начиная с
    ядра
    версии 2.0, Linux
    также не
    поступает:
    если oldpath
    является
    символьной
    ссылкой, то
    newpath
    создаётся
    как
    (жёсткая)
    ссылка на
    файл этой
    символьной
    ссылки (т.е.,
    newpath
    становится
    символьной
    ссылкой на
    файл,
    содержащий
    ссылку на
    oldpath).
    Некоторые
    другие
    реализации
    поступают
    также как Linux.
    В POSIX.1-2008
    изменено
    описание
    link(), теперь
    разыменование
    символьной
    ссылки oldpath
    зависит от
    реализации.
    Для
    точного
    управления
    по
    обработке
    символьных
    ссылок при
    создании
    используйте
    linkat().
Замечания
  по glibc
В старых
    ядрах, где
    linkat()
    отсутствует
    (и если не
    указан
    флаг AT_SYMLINK_NOFOLLOW),
    обёрточная
    функция glibc
    использует
    link(). Если oldpath и
    newpath
    являются
    относительными
    путями, то glibc
    собирает
    пути
    относительно
    символической
    ссылки в
    /proc/self/fd,
    которая
    соответствует
    аргументам
    olddirfd и newdirfd.
ДЕФЕКТЫ
В
    файловых
    системах NFS
    возвращаемый
    код может
    быть
    неправильным,
    если
    сервер NFS
    выполнит
    создание
    ссылки и
    завершит
    работу до
    возврата
    результата
    операции.
    Используйте
    stat(2), чтобы
    выяснить
    была ли
    создана
    ссылка.