2009-09-17 11 views

risposta

37

L'utilità di coda fa parte del coreutils su linux.

Ho sempre trovato FreeBSD per avere il codice sorgente molto più chiaro rispetto alle utility GNU. Quindi, ecco tail.c nel progetto FreeBSD:

+0

+1 per la diversità, anche se la domanda originale riguardava l'utilità linux. –

+1

Mi piace come la versione di Linux sia molte volte più lunga della versione BSD. –

+5

La versione BSD è più breve perché le funzioni che fanno tutto il lavoro non sono in quel file. vale a dire seguire(). –

1

Poke intorno al sito uclinux. Dal momento che hanno distribuito il software, sono tenuti a rendere la fonte disponibile in un modo o nell'altro.

Oppure, è possibile leggere man fseek e indovinare come potrebbe essere fatto.

NB - Vedere i commenti di William qui sotto, ci sono casi in cui non è possibile utilizzare la ricerca.

+0

coda non utilizza fseek. Se lo facesse, non funzionerebbe su uno stream (ad es. 'Grep pat file | tail') –

+0

Hmm, non ci avevo mai pensato. Grazie. Devo pensare che sarebbe ancora più veloce quando si lavora con input ricercabili. – dmckee

+1

Questo non è esattamente vero. 'tail' non * sempre * usa seek ;-) –

0

si potrebbe trovare un esercizio interessante per scrivere il proprio. La stragrande maggioranza degli strumenti da riga di comando di Unix è una pagina di codice C abbastanza semplice.

Per osservare il codice, le fonti GNU CoreUtils si trovano facilmente su gnu.org o sul sito mirror di Linux preferito.

+1

Ho scritto un set abbastanza completo di strumenti per MS-DOS quando Linux era nella sua infanzia. E mentre molti sono certamente diretti, esiterei a dire "una pagina" e non direi una "grande maggioranza". ** trovare ** e ** ls **, ad esempio, erano considerevolmente più complessi. – NVRAM

+0

Il nucleo la maggior parte degli strumenti generalmente * è * breve, ma l'elaborazione degli argomenti e la gestione dei casi angolari può essere un problema – dmckee

+0

Sì, probabilmente avrei dovuto dire che "molti" strumenti sono brevi e semplici. La coda GNU ha molte opzioni, quindi probabilmente non si adatta alla categoria "semplice": la versione di coda che la maggior parte delle persone userebbe (cioè il file tail -xxx, o tail -f file) sarebbe piuttosto semplice. –

-2
/`*This example implements the option n of tail command.*/` 

    #define _FILE_OFFSET_BITS 64 
    #include <stdio.h> 
    #include <stdlib.h> 
    #include <fcntl.h> 
    #include <errno.h> 
    #include <unistd.h> 
    #include <getopt.h> 

    #define BUFF_SIZE 4096 

    FILE *openFile(const char *filePath) 
    { 
     FILE *file; 
     file= fopen(filePath, "r"); 
     if(file == NULL) 
     { 
     fprintf(stderr,"Error opening file: %s\n",filePath); 
     exit(errno); 
     } 
     return(file); 
    } 

    void printLine(FILE *file, off_t startline) 
    { 
     int fd; 
     fd= fileno(file); 
     int nread; 
     char buffer[BUFF_SIZE]; 
     lseek(fd,(startline + 1),SEEK_SET); 
     while((nread= read(fd,buffer,BUFF_SIZE)) > 0) 
     { 
     write(STDOUT_FILENO, buffer, nread); 
     } 
    } 

    void walkFile(FILE *file, long nlines) 
    { 
     off_t fposition; 
     fseek(file,0,SEEK_END); 
     fposition= ftell(file); 
     off_t index= fposition; 
     off_t end= fposition; 
     long countlines= 0; 
     char cbyte; 

     for(index; index >= 0; index --) 
     { 
     cbyte= fgetc(file); 
     if (cbyte == '\n' && (end - index) > 1) 
     { 
      countlines ++; 
      if(countlines == nlines) 
      { 
     break; 
      } 
     } 
     fposition--; 
     fseek(file,fposition,SEEK_SET); 
     } 
     printLine(file, fposition); 
     fclose(file); 
    } 

    int main(int argc, char *argv[]) 
    { 
     FILE *file; 
     file= openFile(argv[2]); 
     walkFile(file, atol(argv[1])); 
     return 0; 
    } 

    /*Note: take in mind that i not wrote code to parse input options and arguments, neither code to check if the lines number argument is really a number.*/ 
Problemi correlati