Il existe des fichiers spéciaux sous Linux qui ne sont pas vraiment des fichiers.
Les exemples les plus remarquables et les plus clairs de ceux-ci sont dans le dev
dossier, "fichiers" comme:
/dev/null
- Ignore tout ce que vous écrivez dans le fichier/dev/random
- Affiche des données aléatoires à la place du contenu d'un fichier/dev/tcp
- Envoie toutes les données que vous écrivez dans ce fichier sur le réseau
Tout d’abord, quel est le nom de ces types de "fichiers" qui sont vraiment une sorte de script ou de binaire déguisé?
Deuxièmement, comment sont-ils créés? Ces fichiers sont-ils intégrés au système au niveau du noyau ou existe-t-il un moyen de créer un "fichier magique" vous-même (qu'en est-il de a /dev/rickroll
)?
man 2 mknod
open()
,read()
,close()
, etc. Après cela, il est au logicielRéponses:
/dev/zero
est un exemple de "fichier spécial", en particulier de "nœud de périphérique". Normalement , ceux - ci sont créées par le processus d'installation de distribution, mais vous pouvez tout à fait les créer vous - même si vous voulez.Si vous posez des questions
ls
sur/dev/zero
:Le "c" au début vous indique qu'il s'agit d'un "périphérique de caractère"; l'autre type est "périphérique de bloc" (imprimé par
ls
"b"). En gros, les périphériques à accès aléatoire tels que les disques durs ont tendance à être des périphériques bloqués, tandis que les éléments séquentiels tels que les lecteurs de bande ou votre carte son ont tendance à être des périphériques à caractères.La partie "1, 5" est le "numéro de périphérique majeur" et le "numéro de périphérique mineur".
Avec ces informations, nous pouvons utiliser la
mknod
commande pour créer notre propre nœud de périphérique:Cela crée un nouveau fichier nommé
foobar
, dans le dossier actuel, qui fait exactement la même chose que/dev/zero
. (Vous pouvez bien sûr définir des autorisations différentes si vous le souhaitez.) Tout ce "fichier" contient en réalité les trois éléments ci-dessus - type de périphérique, numéro majeur, nombre mineur. Vous pouvez égalementls
rechercher les codes d’autres périphériques et les recréer. Lorsque vous vous ennuyez, utilisez simplementrm
pour supprimer les nœuds de périphérique que vous venez de créer.Fondamentalement, le numéro majeur indique au noyau Linux avec quel pilote de périphérique parler, et le numéro mineur indique au pilote de périphérique le périphérique dont vous parlez. (Par exemple, vous avez probablement un contrôleur SATA, mais peut-être plusieurs disques durs branchés dessus.)
Si vous voulez inventer de nouveaux périphériques qui font quelque chose de nouveau ... eh bien, vous devrez éditer le code source du noyau Linux et compiler votre propre noyau personnalisé. Alors ne faisons pas ça! :-) Mais vous pouvez ajouter des fichiers de périphérique qui dupliquent ceux que vous avez déjà très bien. Un système automatisé comme udev surveille simplement les événements de périphérique et appelle
mknod
/rm
pour vous automatiquement. Rien de plus magique que ça.Il existe encore d' autres types de fichiers spéciaux:
Linux considère un répertoire comme un type spécial de fichier. (Habituellement, vous ne pouvez pas ouvrir directement un répertoire, mais si vous le pouviez, vous découvririez qu'il s'agit d'un fichier normal contenant des données dans un format spécial et indiquant au noyau où trouver tous les fichiers de ce répertoire.)
Un lien symbolique est un fichier spécial. (Mais un lien dur ne l'est pas.) Vous pouvez créer des liens symboliques à l'aide de la
ln -s
commande. (Recherchez la page de manuel.)Il existe également un élément appelé "tube nommé" ou "FIFO" (file d'attente premier entré, premier sorti). Vous pouvez en créer un avec
mkfifo
. Une FIFO est un fichier magique qui peut être ouvert par deux programmes à la fois - une lecture, une écriture. Lorsque cela se produit, cela fonctionne comme un tuyau shell normal. Mais vous pouvez démarrer chaque programme séparément ...Un fichier qui n'est en aucun cas "spécial" s'appelle un "fichier normal". Vous verrez parfois cette mention dans la documentation Unix. C'est ce que ça signifie; un fichier qui n'est pas un nœud de périphérique ou un lien symbolique ou autre. Juste un fichier de tous les jours sans propriétés magiques.
la source
mknod
, lancezcat /proc/devices
pour voir les numéros majeurs pour tous les pilotes. Ce qui nous amène à un autre type de fichier spécial, le/proc
système de fichiers ( cette réponse en parle).La plupart des
/dev
entrées sont des inodes de périphérique en mode bloc ou des inodes de périphérique en caractères. Wikipedia a beaucoup de détails à ce sujet, que je ne vais pas répéter.Mais
/dev/tcp
ce qui est mentionné dans votre question n’est expliqué par aucune des réponses existantes./dev/tcp
et/dev/udp
sont différents de la plupart des autres/dev
entrées. Les périphériques de bloc et de caractère sont mises en œuvre par le noyau, mais/dev/tcp
et/dev/udp
sont mises en œuvre en mode utilisateur.Le shell bash est un programme qui a une implémentation de
/dev/tcp
et/dev/udp
(copié à partir deksh93
). Lorsque vous essayez d'ouvrir un chemin sous ceux avec des opérateurs de redirection bash, il ne réalisera pas unopen
appel système ordinaire . Au lieu de cela, bash créera un socket TCP et le connectera au port spécifié.Cela est implémenté en mode utilisateur et seulement dans certains programmes, comme le montre l'exemple suivant, qui montre la différence entre laisser
bash
etcat
essayer d'ouvrir/dev/tcp/::1/22
Une différence
ksh93
est quebash
seules les connexions TCP avec des opérateurs de redirection seront effectuées, pas dans les autres endroits où il peut ouvrir des fichiers tels que lesource
ou.
.la source
gawk
des cas similaires/inet{,4,6}/{tcp,udp}/$port/$remote/$rport
, depuis environ 2010 (je ne me souviens pas exactement et je ne trouve pas de notes de publication)./dev/tcp
est que ce n'est pas un fichier. Il n'y a jamais un fichier appelé ceci. La syntaxe utilisée par Bash pour ouvrir des sockets utilise la chaîne/dev/tcp/address
comme un nom de fichier, mais l'appeler un "fichier implémenté dans l'espace utilisateur" sonne simplement bizarre. Intéressant quiksh
accroche ces noms de fichiers pour tout, pas seulement pour les redirections. C'est plus proche de "implémenter un fichier".bash
copiez seulement ce comportement, mais il provient ailleurs.Outre les nœuds de périphérique expliqués dans d'autres réponses (créés avec mknod (2) ou fournis par certains devfs ), Linux possède d'autres fichiers "magiques" fournis par des systèmes de fichiers virtuels spéciaux , en particulier dans
/proc/
(voir proc (5) , en savoir plus sur procfs ) et in/sys/
(lisez à propos de sysfs ).Ces pseudo-fichiers (qui apparaissent, par exemple, dans stat (2) , sous forme de fichiers ordinaires et non de périphériques) constituent une vue virtuelle fournie par le noyau; en particulier, la lecture de
/proc/
(par exemple aveccat /proc/$$/maps
, ou ouvert (2) -ment/proc/self/status
dans votre programme) n'impliquent généralement pas d' E / S physiques à partir du disque ou d'un réseau, est donc assez rapide.Pour créer une pseudo-fichier supplémentaire ,
/proc/
vous devez généralement écrire votre propre module de noyau et le charger (voir par exemple ce ).la source
Ils sont appelés nœuds de périphériques et sont créés manuellement
mknod
ou automatiquement parudev
. Ce sont généralement des interfaces de type fichier vers des périphériques de type caractères ou blocs avec des pilotes dans le noyau - par exemple, les disques sont des périphériques de type bloc, les ports série et les ports série, etc. sont des périphériques de type caractère.Il existe également d'autres types de fichiers "spéciaux", notamment les canaux nommés, les fifos et les sockets.
la source
Comme d'autres utilisateurs l'ont déjà expliqué en détail, les fichiers spéciaux nécessitent un code pour les sauvegarder. Cependant, personne ne semble avoir mentionné que Linux fournit plusieurs façons d'écrire ce code dans l'espace utilisateur:
A. FUSE (système de fichiers dans USErspace) vous permet d’écrire quelque chose comme
/proc
sans risque de planter le noyau et de le faire dans une langue / exécution de votre choix, telle que Go , Node.js , Perl , PHP , Python , Ruby , Rust , etc. etc .Il présente également l’avantage que les systèmes de fichiers FUSE peuvent être montés sans,
sudo
car ils sont exécutés en tant qu’utilisateur effectuant le montage.Voici quelques exemples d'éléments écrits par les utilisateurs de FUSE:
B. Si vous souhaitez créer un périphérique d’entrée virtuel, comme un clavier, une souris, une manette de jeu, etc. (par exemple, écrire un pilote d’espace utilisateur pour un périphérique USB avec lequel vous parlez
libusb
), vous pouvez entrer .Les liaisons pour cela sont plus difficiles à trouver, mais je sais qu’elles existent pour Go (clavier uniquement), Python et Ruby (2) .
Voici des exemples d'utilisation réelle dans le monde réel:
C. Pour les périphériques à caractères génériques, il existe CUSE (périphériques à caractères dans USErspace). C'est beaucoup moins populaire cependant.
Le seul utilisateur de l'API Cuse que je suis personnellement au courant est le même programme qui a incité sa création: osspd , qui met en œuvre
/dev/dsp
,/dev/adsp
et/dev/mixer
(l'API audio OSS) dans l' espace utilisateur afin qu'ils puissent être acheminés par PulseAudio ou dmix.La seule liaison CUSE que j'ai pu trouver est Cusepy , qui n'a pas été mise à jour depuis 2010.
D. Vous n’avez peut-être pas besoin d’un nouveau fichier spécial.
Par exemple, vous pouvez ouvrir une communication brute avec n’importe quel périphérique USB à l’aide de libusb (liste des liaisons sur la page), puis communiquer avec d’autres programmes via un autre mécanisme (sockets TCP / UDP, lecture / écriture de fichiers stdin / stdout ou normaux sur disque). , etc.).
la source
poll
, mais étant donné que cusepy utilise ctypes et les liaisons sont générées automatiquement basées sur les fichiers d' en- tête C, la fixation des fonctions manquantes est juste une question d'ajouter le nom de la fonction désirée à la liste des fonctions exportées dans lesetup.py
.Le livre Linux Device Drivers (hautement recommandé) explique cela en détail et vous a même demandé de créer un module de noyau à titre d'exemple. Cependant, en résumé, chaque pilote de périphérique possède des fonctions spécifiques qui sont appelées lors de l'ouverture, de la fermeture d'un fichier. , lu, écrit, etc. Les fichiers "spéciaux" font simplement quelque chose de spécial dans ces fonctions, au lieu d’accéder au matériel de stockage sur un disque.
Par exemple, la fonction write
/dev/null
ne fait rien, ignorant les octets. La fonction de lecture pour/dev/random
renvoie un nombre aléatoire.la source
mount -t devtmpfs
Il est également intéressant de constater que, dans les systèmes modernes, il
/dev
s’agit généralement d’un système de fichiers pouvant être monté où vous le souhaitez. Ubuntu 16.04:Ceci est activé par
CONFIG_DEVTMPFS=y
et permet au noyau lui-même de créer et de détruire les fichiers de périphérique selon les besoins.CONFIG_DEVTMPFS_MOUNT=y
Cette option rend devtmpfs sur le noyau pour le montage automatique
/dev
.drivers/base/Kconfig
documents:file_operations
Enfin, vous devez créer votre propre module de noyau de périphérique de caractères pour voir exactement ce qui se passe.
Voici un exemple minimal d’exécution: Comprendre les fichiers de périphériques de caractères (ou de caractères spéciaux)
L’étape la plus importante est la configuration de la
file_operations
structure, par exemple:qui contient les pointeurs de fonction appelés pour chaque appel système lié à un fichier.
Il devient alors évident que vous substituez ces appels système liés aux fichiers pour faire ce que vous voulez, et voici comment le noyau implémente des périphériques tels que
/dev/zero
.Créer des
/dev
entrées à automatiquement sansmknod
Le mystère final concerne la manière dont le noyau crée automatiquement des
/dev
entrées.Le mécanisme peut être observé en créant un module de noyau qui le fait vous-même, comme indiqué à l' adresse : https://stackoverflow.com/questions/5970595/how-to-create-a-device-node-from-the-init-module- code-of-a-linux-kernel-module / 45531867 # 45531867 et se réduit à un
device_create
appel.la source