Logo Search packages:      
Sourcecode: qfits version File versions  Download package

char* qfits_memory_falloc ( char *  name,
size_t  offs,
size_t *  size,
const char *  srcname,
int  srclin 
)

Map a file's contents to memory as a char pointer.

Parameters:
name Name of the file to map
offs Offset to the first mapped byte in file.
size Returned size of the mapped file in bytes.
srcname Name of the source file making the call.
srclin Line # where the call was made.
Returns:
A pointer to char, to be freed using qfits_memory_free().
This function takes in input the name of a file. It tries to map the file into memory and if it succeeds, returns the file's contents as a char pointer. It also modifies the input size variable to be the size of the mapped file in bytes. This function is normally never directly called but through the falloc() macro.

The offset indicates the starting point for the mapping, i.e. if you are not interested in mapping the whole file but only from a given place.

The returned pointer ptr must be deallocated with qfits_memory_fdealloc(ptr)

Definition at line 465 of file qfits_memory.c.

{
    unsigned        mm_hash ;
    char        *   ptr ;
    struct stat     sta ;
    int             fd ;
    int             nptrs ;
    int             i ;

    /* If QFITS_MEMORY_MODE is 0 or 1, do not use the qfits_memory model  */
    if ((QFITS_MEMORY_MODE == 0) || (QFITS_MEMORY_MODE == 1)) {

        if (size!=NULL) *size = 0 ;

        /* Check file's existence and compute its size */
        if (stat(name, &sta)==-1) {
            qfits_mem_debug(
                fprintf(stderr, "qfits_mem: cannot stat file %s - %s (%d)\n",
                        name, srcname, srclin);
            );
            if (QFITS_MEMORY_MODE == 0) return NULL ;
            else exit(1) ;
        }
        /* Check offset request does not go past end of file */
        if (offs>=(size_t)sta.st_size) {
            qfits_mem_debug(
                fprintf(stderr,
                    "qfits_mem: falloc offsets larger than file size");
            );
            if (QFITS_MEMORY_MODE == 0) return NULL ;
            else exit(1) ;
        }

        /* Open file */
        if ((fd=open(name, O_RDONLY))==-1) {
            qfits_mem_debug(
                fprintf(stderr, "qfits_mem: cannot open file %s - %s (%d)\n",
                        name, srcname, srclin);
            );
            if (QFITS_MEMORY_MODE == 0) return NULL ;
            else exit(1) ;
        }

        /* Memory-map input file */
        ptr = (char*)mmap(0, sta.st_size, 
                PROT_READ | PROT_WRITE, MAP_PRIVATE,fd,0);
        
        /* Close file */
        close(fd);
        if (ptr == (char*)-1 || ptr==NULL) {
            qfits_mem_debug(
                perror("mmap");
                fprintf(stderr, "qfits_mem: falloc cannot mmap file %s", name);
            );
            if (QFITS_MEMORY_MODE == 0) return NULL ;
            else exit(1) ;
        }

        qfits_mem_debug(
            fprintf(stderr,
                    "qfits_mem: falloc mmap succeeded for [%s] - %s (%d)\n",
                    name, srcname, srclin);
        );

        if (size!=NULL) (*size) = sta.st_size ;
        
        return ptr + offs ;
    }

    /* Protect the call */
    if (size!=NULL) *size = 0 ;

    /* Initialize table if needed */
    if (qfits_memory_initialized==0) {
        qfits_memory_init() ;
        qfits_memory_initialized++ ;
    }

    if (qfits_memory_table.ncells>0) {
        /* Check if file has already been mapped */
        /* Compute hash for this name */
        mm_hash = qfits_memory_hash(name);
        /* Loop over all memory cells */
        nptrs=0 ;
        for (i=0 ; i<QFITS_MEMORY_MAXPTRS ; i++) {
            if (qfits_memory_p_val[i]!=NULL)
                nptrs++ ;
            if ((qfits_memory_p_val[i]!=NULL) &&
                (qfits_memory_p_mm_filename[i] != NULL) &&
                (qfits_memory_p_mm_hash[i] == mm_hash)) {
                if (!strncmp(qfits_memory_p_mm_filename[i], name,
                             MAPFILENAMESZ)) {
                    /* File already mapped */
                    /* Check offset consistency wrt file size */
                    if (offs >= qfits_memory_p_size[i]) {
                        qfits_mem_debug(
                            fprintf(stderr,
                                "qfits_mem: falloc offset larger than file sz");
                        );
                        return NULL ;
                    }
                    /* Increase reference counter */
                    qfits_memory_p_mm_refcount[i] ++ ;
                    qfits_mem_debug(
                        fprintf(stderr,
                                "qfits_mem: incref on %s (%d mappings)\n",
                                name,
                                qfits_memory_p_mm_refcount[i]);
                    );
                    /* Increase number of mappings */
                    qfits_memory_table.n_mm_mappings ++ ;
                    /* Build up return pointer */
                    ptr = (char*)qfits_memory_p_val[i] + offs ;
                    /* Available size is filesize minus offset */
                    if (size!=NULL) {
                        *size = qfits_memory_p_size[i] - offs ;
                    }
                    /* Return constructed pointer as void * */
                    return (void*)ptr ;
                }
            }
            if (nptrs>=qfits_memory_table.ncells) break ;
        }
    }

    /* First mapping attempt for this file */
    /* Check file's existence and compute its size */
    if (stat(name, &sta)==-1) {
        qfits_mem_debug(
            fprintf(stderr, "qfits_mem: cannot stat file %s - %s (%d)\n",
                    name, srcname, srclin);
        );
        return NULL ;
    }
    /* Check offset request does not go past end of file */
    if (offs>=(size_t)sta.st_size) {
        qfits_mem_debug(
            fprintf(stderr,
                "qfits_mem: falloc offsets larger than file size");
        );
        return NULL ;
    }

    /* Open file */
    if ((fd=open(name, O_RDONLY))==-1) {
        qfits_mem_debug(
            fprintf(stderr, "qfits_mem: cannot open file %s - %s (%d)\n",
                    name, srcname, srclin);
        );
        return NULL ;
    }

    /* Memory-map input file */
    ptr = (char*)mmap(0, sta.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE,fd,0);
    
    /* Close file */
    close(fd);
    if (ptr == (char*)-1 || ptr==NULL) {
        qfits_mem_debug(
            perror("mmap");
            fprintf(stderr, "qfits_mem: falloc cannot mmap file %s", name);
        );
        return NULL ;
    }

    qfits_memory_table.n_mm_files ++ ;
    qfits_memory_table.n_mm_mappings ++ ;
    qfits_mem_debug(
        fprintf(stderr,
                "qfits_mem: falloc mmap succeeded for [%s] - %s (%d)\n",
                name, srcname, srclin);
    );

    /* Add cell into general table */
    (void) qfits_memory_addcell((void*)ptr, sta.st_size, srcname, srclin, 
                           MEMTYPE_MMAP, -1, -1, name) ;

    if (size!=NULL) (*size) = sta.st_size ;
    
    return ptr + offs ;
}


Generated by  Doxygen 1.6.0   Back to index