Из справочной страницы Linux bind(2)
:
It is normally necessary to assign a local address using bind() before a SOCK_STREAM socket may receive connections (see accept(2)).
The rules used in name binding vary between address families. Consult the manual entries in Section 7 for detailed information. For AF_INET, see ip(7); for AF_INET6, see ipv6(7); for AF_UNIX, see unix(7); for AF_APPLETALK, see ddp(7); for AF_PACKET, see packet(7); for AF_X25, see x25(7); and for AF_NETLINK, see netlink(7).
А для IPv4 на справочной странице ip(7)
говорится:
When a process wants to receive new incoming packets or connections, it should bind a socket to a local interface address using bind(2). In this case, only one IP socket may be bound to any given local (address, port) pair. When INADDR_ANY is specified in the bind call, the socket will be bound to all local interfaces. When listen(2) is called on an unbound socket, the socket is automatically bound to a random free port with the local address set to INADDR_ANY.
Таким образом, может показаться, что для сокетов IPv4 TCP или UDP IP-адрес для привязки должен быть либо INADDR_ANY
, либо одним из IP-адресов, назначенных любому из сетевых интерфейсов в локальной системе.
Но там же сказано:
There are several special addresses: INADDR_LOOPBACK (127.0.0.1) always refers to the local host via the loopback device; INADDR_ANY (0.0.0.0) means any address for binding; INADDR_BROADCAST (255.255.255.255) means any host and has the same effect on bind as INADDR_ANY for historical reasons.
Итак, привязка к 255.255.255.255 действительна и имеет тот же эффект, что и 0.0.0.0, но в современных реализациях предпочтительнее 0.0.0.0.
И если вы установите параметр сокета IP_FREEBIND
, вы можете привязаться к любому адресу, в предположении, что привязанный -к адресу может появиться на каком-то локальном интерфейсе позднее. Однако до тех пор, пока это действительно не произойдет, сокет, связанный таким образом, может быть не очень полезен.
Linux также имеет параметр сокета SO_BINDTODEVICE
, который можно использовать для привязки сокета к определенному сетевому интерфейсу без указания его IP-адреса.
Это ошибка в библиотеке libmagic, которую использует file
.
Простой обходной путь — «бесполезное использование кота»:
echo '#! /bin/sh' | file -
cat /path/to/fifo-or-special | file -
Ошибка впервые появилась вhttps://github.com/file/file/commit/fb6084e0f08:
commit fb6084e0f08aef8991afcb3eb74168a456601908
Author: Christos Zoulas <christos@zoulas.com>
Date: Tue May 28 21:24:31 2013 +0000
don't print a space if there was an error. (from Jan Kaluza)
Затем это было исправлено, но только для блочных и символьных устройств, НЕ для FIFO вhttps://github.com/file/file/commit/a9124dcb4e. неполное исправление для <(...)
в Linux было вhttps://github.com/file/file/commit/adbe541c32.
Исправление для устройств могло быть воспроизведено для FIFO. См. Патч в конце ответа (, применяемый вручную, потому что этот сайт искажает вкладки, и имейте в виду, что он противоречит ТОЛЬКО ЗЕРКАЛЬНОМУ репозиторию ).
Но и это еще остается:
mkfifo fifo; file -s fifo
fifo: writable, no read permission
Глупо и неправильно, потому что у FIFO есть разрешение на чтение.
Исправление этого будет означать либо переписывание половины libmagic, либо добавление еще пары спагетти ifdef и особых случаев в ужасный беспорядок.
diff --git a/src/fsmagic.c b/src/fsmagic.c
index 5204f20d..20b7f438 100644
--- a/src/fsmagic.c
+++ b/src/fsmagic.c
@@ -270,8 +270,10 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
/* TODO add code to handle V7 MUX and Blit MUX files */
#ifdef S_IFIFO
case S_IFIFO:
- if((ms->flags & MAGIC_DEVICES) != 0)
+ if((ms->flags & MAGIC_DEVICES) != 0) {
+ return 0;
break;
+ }
if (mime) {
if (handle_mime(ms, mime, "fifo") == -1)
return -1;