He estado leyendo sobre cómo se implementan las canalizaciones en el kernel de Linux y quería validar mi comprensión. Si soy incorrecto, se seleccionará la respuesta con la explicación correcta.
- Linux tiene un VFS llamado pipefs que está montado en el kernel (no en el espacio del usuario)
- pipefs tiene un súper bloque único y está montado en su propia raíz (
pipe:), junto a/ - pipefs no se puede ver directamente a diferencia de la mayoría de los sistemas de archivos
- La entrada a pipefs es a través de
pipe(2)syscall - La
pipe(2)llamada al sistema utilizada por los shells para canalizar con el|operador (o manualmente desde cualquier otro proceso) crea un nuevo archivo en pipefs que se comporta más o menos como un archivo normal - El archivo en el lado izquierdo del operador de tubería se
stdoutredirige al archivo temporal creado en pipefs - El archivo en el lado derecho del operador de tubería tiene su
stdinconjunto en el archivo en pipefs - pipefs se almacena en la memoria y, a través de la magia del kernel, no se debe paginar
¿Es esta explicación de cómo funcionan las tuberías (p ls -la | less. Ej. ) Bastante correcta?
Una cosa que no entiendo es cómo algo como bash establecería un proceso ' stdino stdoutal descriptor de archivo devuelto por pipe(2). Todavía no he podido encontrar nada al respecto.

pipe()llamada del kernel junto con la maquinaria que lo soporta (pipefs, etc.) es de un nivel mucho más bajo que el|operador ofrecido en su shell. Este último generalmente se implementa utilizando el primero, pero no tiene que ser así.|operador solo está llamandopipe(2)como un proceso como lo hace bash.Respuestas:
Su análisis hasta ahora es generalmente correcto. La forma en que un shell puede establecer el stdin de un proceso en un descriptor de tubería podría ser (pseudocódigo):
fuente
dup2se necesita la llamada y no puede asignar directamente el descriptor de tubería a stdin?pipe(). Ladup2()llamada permite a la persona que llama copiar el descriptor de archivo a un valor numérico específico (necesario porque 0, 1, 2 son stdin, stdout, stderr). Ese es el equivalente del núcleo de "asignar directamente a stdin". Tenga en cuenta que la variable global de la biblioteca de tiempo de ejecución Cstdines aFILE *, que no está relacionada con el núcleo (aunque se inicializa para conectarse al descriptor 0).dup2llamada no cambiap[1]. En su lugar, hace los dos identificadoresp[1]y0apuntan al mismo objeto del núcleo (la tubería). Dado que el proceso secundario no necesita dos identificadores estándar (y dep[1]todos modos no sabría cuál es el identificador numerado ),p[1]se cierra antesexec.