Task: Read a specific line from a file

C: #include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <err.h>


int read_file_line(const char *path, int line_no)
{
	struct stat s;
	char *buf;
	off_t start = -1, end = -1;
	size_t i;
	int ln, fd, ret = 1;

	if (line_no == 1) start = 0;
	else if (line_no < 1){
		warn("line_no too small");
		return 0; 
	}

	line_no--; 

	fd = open(path, O_RDONLY);
	fstat(fd, &s);

	
	buf = mmap(0, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0);

	
	madvise(buf, s.st_size, MADV_SEQUENTIAL);

	for (i = ln = 0; i < s.st_size && ln <= line_no; i++) {
		if (buf[i] != '\n') continue;

		if (++ln == line_no) start = i + 1;
		else if (ln == line_no + 1) end = i + 1;
	}

	if (start >= s.st_size || start < 0) {
		warn("file does not have line %d", line_no + 1);
		ret = 0;
	} else {
		
	}

	munmap(buf, s.st_size);
	close(fd);

	return ret;
}










Fortran:       MODULE SAMPLER    
       CONTAINS                                                         SAM00200
        CHARACTER*20 FUNCTION GETREC(N,F,IS)    
Careful. Some compilers get confused over the function name's usage.    SAM00400
         INTEGER N              
         INTEGER F              
         CHARACTER*(*) IS       
         INTEGER I,L            
          IS = ""               
          IF (N.LE.0) THEN      
            WRITE (GETREC,1) "
    1       FORMAT (A,1X,I0)                    
          ELSE IF (F.LE.0) THEN                 
            WRITE (GETREC,1) "
          ELSE IF (LEN(IS).LE.0) THEN           
            WRITE (GETREC,1) "
          ELSE                  
            REWIND (F)          
            DO I = 1,N - 1      
              READ (F,2,END=3)  
            END DO              
            READ (F,2,END = 3) L,IS(1:MIN(L,LEN(IS)))    
    2       FORMAT (Q,A)        
            IF (L.LT.LEN(IS)) IS(L + 1:) = ""   
            IF (L.GT.LEN(IS)) THEN              
              WRITE (GETREC,1) "+Length",L      
            ELSE IF (L.LE.0) THEN               
              WRITE (GETREC,1) "+Null"          
            ELSE IF (IS.EQ."") THEN             
              WRITE (GETREC,1) "+Blank",L       
            ELSE                                
              WRITE (GETREC,1) " Length",L      
            END IF              
          END IF                
          RETURN                
    3     WRITE (GETREC,1) "
        END FUNCTION GETREC     
      END MODULE SAMPLER        
                                                                        SAM03900
      PROGRAM POKE                                                      POK00100
      USE SAMPLER                                                       POK00200
      INTEGER ENUFF     
      PARAMETER (ENUFF = 666)   
      CHARACTER*(ENUFF) STUFF   
      CHARACTER*20 RESULT                                               POK00600
      INTEGER MSG,F     
      MSG = 6           
      F = 10            
      WRITE (MSG,*) "      To select record 7 from a disc file."        POK01000
                                                                        POK01100
      WRITE (MSG,*) "As a FORMATTED file."                              POK01200
      OPEN (F,FILE="FileSlurpN.for",STATUS="OLD",ACTION="READ")         POK01300
      RESULT = GETREC(7,F,STUFF)                                        POK01400
      WRITE (MSG,1) "Result",RESULT                                     POK01500
      WRITE (MSG,1) "Record",STUFF                                      POK01600
    1 FORMAT (A,":",A)                                                  POK01700
                                                                        POK01800
      CLOSE (F)                                                         POK01900
      WRITE (MSG,*) "As a random-access unformatted file."              POK02000
      OPEN (F,FILE="FileSlurpN.for",STATUS="OLD",ACTION="READ",         POK02100
     1 ACCESS="DIRECT",FORM="UNFORMATTED",RECL=82)      
      STUFF = "Cleared."                                                POK02300
      READ (F,REC = 7,ERR = 666) STUFF(1:80)                            POK02400
      WRITE (MSG,1) "Record",STUFF(1:80)                                POK02500
      STOP                                                              POK02600
  666 WRITE (MSG,*) "Can't get the record
      END