[successivo] [precedente] [inizio] [fine] [indice generale] [violazione GPL] [translators] [docinfo] [indice analitico] [volume] [parte]


Capitolo 65.   Eseguibili, interpretabili e automazione dell'interpretazione

Quando si utilizza un sistema operativo complesso come GNU/Linux, dove il kernel ha un ruolo così importante, è difficile stabilire una distinzione netta tra un programma eseguibile binario e un programma interpretato. A livello astratto si intende che il programma interpretato richiede un programma interprete che è di fatto il suo esecutore, ma anche l'interprete potrebbe a sua volta essere interpretato da un altro programma di livello inferiore. È un po' come quando per tradurre un testo dal cinese all'italiano, si preferisce partire dal lavoro di qualcun altro che l'ha già tradotto in inglese.

Evidentemente si pone il problema di stabilire il livello di astrazione a cui si vuole fare riferimento. Si potrebbe dire che un programma binario «normale» sia quello che viene eseguito direttamente dal kernel senza bisogno di altri sostegni da parte di programmi interpreti aggiuntivi. In questo senso, potrebbe accadere anche di avere un programma che nel sistema «A» è un binario normale, mentre nel sistema «B» potrebbe essere eseguito per opera di un interprete intermedio, diventando lì un programma interpretato.

65.1   Script

Il classico tipo di programma interpretato è lo script che normalmente viene individuato dalla stessa shell attraverso cui viene avviato. Per questo è stata stabilita la convenzione per cui questi programmi sono contenuti in file di testo, in cui la prima riga indichi il percorso dell'interprete necessario.

#/bin/bash

Tale convenzione impone che, in questo tipo di script, il simbolo # rappresenti l'inizio di un commento e che comunque si tratti di un file di testo normale. Inoltre, è stabilito implicitamente, che il programma interprete indicato riceva il nome dello script da interpretare come primo argomento.

Attualmente, non è solo la shell che può accorgersi del fatto che si tratti di uno script; anche il kernel è coinvolto in questa forma di riconoscimento, tanto da poter creare dei sistemi specifici che, all'avvio, invece di mettere in funzione l'eseguibile init, avviano direttamente uno script attraverso l'interprete relativo.

65.2   Programmi da interpretare che non sono script

Quando il file da interpretare non è così semplice come uno script, per esempio perché non si tratta di un file di testo, si pone il problema di stabilire un metodo per il suo riconoscimento, altrimenti si è costretti a usare sempre un comando che richiami esplicitamente il suo interprete. L'esempio più comune di questa situazione è il programma scritto per un'altra piattaforma che si vuole utilizzare attraverso un interprete (o un emulatore) adatto. Generalmente, questi programmi estranei sono riconoscibili in base a una stringa binaria tipica che si può trovare all'inizio del file che li contiene; in pratica, in base al magic number del file. In altre situazioni, si può essere costretti a definire un'estensione particolare per i nomi di questi file, come avviene nel Dos.

65.3   Gestione del kernel dei binari eterogenei

A partire dall'introduzione dell'interprete Java anche per GNU/Linux, si è sentito maggiormente il problema di organizzare in modo coerente la gestione dei programmi che per un motivo o per l'altro devono essere interpretati attraverso un programma esterno al kernel stesso. Il meccanismo attuale permette una configurazione molto semplice del sistema, attraverso la quale si può automatizzare l'interpretazione di ciò che si vuole (sezione 29.2.4).

Per verificare che il kernel sia in grado di gestire questa funzione, basta controllare che all'interno della directory /proc/sys/fs/binfmt_misc/ appaiano i file register e status; il secondo in particolare, dovrebbe contenere la parola enabled.

Questa funzionalità può essere attivata, se necessario, con il comando seguente:

echo 1 > /proc/sys/fs/binfmt_misc/status

Per disattivarla, basta utilizzare il valore zero.

echo 0 > /proc/sys/fs/binfmt_misc/status

Quando la gestione è disattivata, la lettura del file /proc/sys/fs/binfmt_misc/status restituisce la stringa disabled.

65.3.1   Configurazione

Trattandosi di un'attività che riguarda il kernel, non c'è un file di configurazione vero e proprio. Per informare il kernel della presenza di programmi da interpretare attraverso eseguibili esterni, occorre sovrascrivere un file virtuale del file system /proc/. In generale, questo si ottiene utilizzando un comando echo, il cui standard output viene ridiretto nel file /proc/sys/fs/binfmt_misc/register. Per definire il supporto a un tipo di programma interpretato, si utilizza una riga secondo la sintassi seguente:

:nome:tipo:[scostamento]:riconoscimento:[maschera]:programma_interprete:

Allo stato attuale, dal momento che i due punti verticali separano i vari campi di questo record, tale simbolo non può apparire all'interno di questi.

  1. nome

    Il primo campo serve a dare un nome a questo tipo di programma da interpretare. Ciò si tradurrà nella creazione di un file virtuale con lo stesso nome, /proc/sys/fs/binfmt_misc/nome, che poi permette di controllarne le funzionalità.

  2. tipo

    Il secondo campo definisce il tipo di riconoscimento che si vuole utilizzare. La lettera M indica l'utilizzo di un magic number, ovvero una stringa nella parte iniziale del file, oppure la lettera E specifica che viene presa in considerazione l'estensione nel nome. Ciò serve a definire in che modo interpretare il quarto campo di questo record.

  3. scostamento

    Nel caso in cui si utilizzi un riconoscimento basato su una stringa iniziale, questa deve essere contenuta nei primi 128 byte, anche se non è detto che inizi dal primo. L'inizio della stringa di riconoscimento può essere indicato espressamente con un numero intero posto all'interno di questo campo: zero rappresenta il primo byte.

  4. riconoscimento

    Il quarto campo consente di inserire la stringa di riconoscimento o l'estensione del file. La stringa, ovvero il magic number, può essere specificata utilizzando delle sequenze di escape che consentono l'indicazione di valori esadecimali. Per questo si usa il prefisso \x, seguito da due cifre esadecimali che rappresentano un byte alla volta. A questo proposito, è bene ricordare che se il record viene definito in una riga di comando di una shell, è molto probabile che la barra obliqua inversa debba essere raddoppiata.

    La stringa di riconoscimento può essere applicata a ciò che resta dopo il filtro con la maschera indicata nel campo successivo.

    Nel caso si specifichi l'uso dell'estensione per riconoscere il tipo di file, questa non deve contenere il punto iniziale, che così è sottinteso.

  5. maschera

    Il quinto campo serve a indicare una maschera da utilizzare per filtrare i bit che compongono la parte di file che deve essere utilizzata per il riconoscimento attraverso il magic number. In pratica, di solito non si utilizza e si ottiene l'applicazione della maschera predefinita corrisponde a \ff. La maschera viene applicata attraverso un AND con i byte corrispondenti del file; quello che ne deriva viene usato per il paragone con il modello specificato nel quarto campo.

    La maschera predefinita, evidentemente, non provoca alcuna modifica.

  6. programma_interprete

    L'ultimo campo serve a indicare il percorso assoluto dell'interprete da utilizzare per mettere in esecuzione il programma identificato attraverso questo record. Evidentemente, si presume che questo programma possa essere avviato indicando il file da interpretare come primo argomento. Se necessario, l'interprete può essere uno script predisposto opportunamente per avviare il vero interprete nel modo richiesto.

Attualmente, si pongono delle limitazioni a cui è già stato accennato in parte:

Esempi

echo ':Java:M::\xca\xfe\xba\xbe::/usr/bin/java:' <-'
`->> /proc/sys/fs/binfmt_misc/register

Definisce il binario Java, riconoscibile dalla sequenza esadecimale CAFEBABE16, a partire dall'inizio del file. Per la sua interpretazione viene specificato il programma /usr/bin/java, il quale potrebbe essere uno script che si occupa di avviare correttamente l'interprete giusto.

echo ':Java:E::class::/usr/bin/java:' <-'
`->> /proc/sys/fs/binfmt_misc/register

Come nell'esempio precedente, con la differenza che l'eseguibile Java viene identificato solo per la presenza dell'estensione .class.

65.3.2   Realizzazione pratica

Non si può pensare che ogni volta che si vuole utilizzare un binario estraneo da interpretare, si debba dare il comando apposito, come negli esempi mostrati nella sezione precedente. Evidentemente, si tratta di inserire queste dichiarazioni in uno script della procedura di inizializzazione del sistema; in mancanza d'altro nel solito rc.local contenuto nella directory /etc/rc.d/, oppure in altra simile.

Una volta definito un tipo di eseguibile da interpretare, nella directory /proc/sys/fs/binfmt_misc/ viene creato un file virtuale con il nome corrispondente a quanto indicato nel primo campo del record di definizione. Se questo file viene sovrascritto con il valore -1, si ottiene l'eliminazione del tipo corrispondente. Se si fa la stessa cosa con il file status, si elimina la gestione di tutti i binari specificati precedentemente.

Esempi

echo -1 > /proc/sys/fs/binfmt_misc/Java

Elimina la gestione del tipo di binario Java.

echo -1 > /proc/sys/fs/binfmt_misc/status

Elimina la gestione di tutti i tipi di binari da interpretare.

65.4   Riferimenti

Appunti di informatica libera 2003.01.01 --- Copyright © 2000-2003 Daniele Giacomini -- daniele @ swlibero.org

Dovrebbe essere possibile fare riferimento a questa pagina anche con il nome eseguibili_interpretabili_e_automazione_dell_interpretazione.html

[successivo] [precedente] [inizio] [fine] [indice generale] [violazione GPL] [translators] [docinfo] [indice analitico]