⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 file.c

📁 编译后直接运行的MP3播放器全部C语言源代码 一个包含FAT文件系统、系统引导 Boot、FLASH Driver等内容的
💻 C
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************** *             __________               __   ___. *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  / *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  < *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \ *                     \/            \/     \/    \/            \/ * $Id: file.c,v 1.53 2004/03/10 19:47:59 linusnielsen Exp $ * * Copyright (C) 2002 by Bj鰎n Stenberg * * All files in this archive are subject to the GNU General Public License. * See the file COPYING in the source tree root for full license agreement. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/#include <string.h>#include <errno.h>#include <stdbool.h>#include "file.h"#include "fat.h"#include "dir.h"#include "debug.h"/*  These functions provide a roughly POSIX-compatible file IO API.  Since the fat32 driver only manages sectors, we maintain a one-sector  cache for each open file. This way we can provide byte access without  having to re-read the sector each time.   The penalty is the RAM used for the cache and slightly more complex code.*/#define MAX_OPEN_FILES 8struct filedesc {    unsigned char cache[SECTOR_SIZE];    int cacheoffset;    int fileoffset;    int size;    int attr;    struct fat_file fatfile;    bool busy;    bool write;    bool dirty;    bool trunc;};static struct filedesc openfiles[MAX_OPEN_FILES];static int flush_cache(int fd);int creat(const char *pathname, mode_t mode){    (void)mode;    return open(pathname, O_WRONLY|O_CREAT|O_TRUNC);}int open(const char* pathname, int flags){    DIR* dir;    struct dirent* entry;    int fd;    char* name;    struct filedesc* file = NULL;    int rc;    LDEBUGF("open(\"%s\",%d)\n",pathname,flags);    if ( pathname[0] != '/' ) {        DEBUGF("'%s' is not an absolute path.\n",pathname);        DEBUGF("Only absolute pathnames supported at the moment\n");        errno = EINVAL;        return -1;    }    /* find a free file descriptor */    for ( fd=0; fd<MAX_OPEN_FILES; fd++ )        if ( !openfiles[fd].busy )            break;    if ( fd == MAX_OPEN_FILES ) {        DEBUGF("Too many files open\n");        errno = EMFILE;        return -2;    }    file = &openfiles[fd];    memset(file, 0, sizeof(struct filedesc));    if (flags & (O_RDWR | O_WRONLY)) {        file->write = true;                if (flags & O_TRUNC)            file->trunc = true;    }    file->busy = true;    /* locate filename */    name=strrchr(pathname+1,'/');    if ( name ) {        *name = 0;        dir = opendir((char*)pathname);        *name = '/';        name++;    }    else {        dir = opendir("/");        name = (char*)pathname+1;    }    if (!dir) {        DEBUGF("Failed opening dir\n");        errno = EIO;        file->busy = false;        return -4;    }    if(name[0] == 0) {        DEBUGF("Empty file name\n");        errno = EINVAL;        file->busy = false;        closedir(dir);        return -5;    }        /* scan dir for name */    while ((entry = readdir(dir))) {        if ( !strcasecmp(name, entry->d_name) ) {            fat_open(entry->startcluster,                     &(file->fatfile),                     &(dir->fatdir));            file->size = entry->size;            file->attr = entry->attribute;            break;        }    }    if ( !entry ) {        LDEBUGF("Didn't find file %s\n",name);        if ( file->write && (flags & O_CREAT) ) {            rc = fat_create_file(name,                                 &(file->fatfile),                                 &(dir->fatdir));            if (rc < 0) {                DEBUGF("Couldn't create %s in %s\n",name,pathname);                errno = EIO;                file->busy = false;                closedir(dir);                return rc * 10 - 6;            }            file->size = 0;            file->attr = 0;        }        else {            DEBUGF("Couldn't find %s in %s\n",name,pathname);            errno = ENOENT;            file->busy = false;            closedir(dir);            return -7;        }    } else {        if(file->write && (file->attr & FAT_ATTR_DIRECTORY)) {            errno = EISDIR;            file->busy = false;            closedir(dir);            return -8;        }    }    closedir(dir);    file->cacheoffset = -1;    file->fileoffset = 0;    if (file->write && (flags & O_APPEND)) {        rc = lseek(fd,0,SEEK_END);        if (rc < 0 )            return rc * 10 - 9;    }    return fd;}int close(int fd){    struct filedesc* file = &openfiles[fd];    int rc = 0;    LDEBUGF("close(%d)\n", fd);    if (fd < 0 || fd > MAX_OPEN_FILES-1) {        errno = EINVAL;        return -1;    }    if (!file->busy) {        errno = EBADF;        return -2;    }    if (file->write) {        rc = fsync(fd);        if (rc < 0)            return rc * 10 - 3;    }    file->busy = false;    return 0;}int fsync(int fd){    struct filedesc* file = &openfiles[fd];    int rc = 0;    LDEBUGF("fsync(%d)\n", fd);    if (fd < 0 || fd > MAX_OPEN_FILES-1) {        errno = EINVAL;        return -1;    }    if (!file->busy) {        errno = EBADF;        return -2;    }    if (file->write) {        /* flush sector cache */        if ( file->dirty ) {            rc = flush_cache(fd);            if (rc < 0)                return rc * 10 - 3;        }        /* truncate? */        if (file->trunc) {            rc = ftruncate(fd, file->fileoffset);            if (rc < 0)                return rc * 10 - 4;        }        /* tie up all loose ends */        rc = fat_closewrite(&(file->fatfile), file->size, file->attr);        if (rc < 0)            return rc * 10 - 5;    }    return 0;}int remove(const char* name){    int rc;    struct filedesc* file;    int fd = open(name, O_WRONLY);    if ( fd < 0 )        return fd * 10 - 1;    file = &openfiles[fd];    rc = fat_truncate(&(file->fatfile));    if ( rc < 0 ) {        DEBUGF("Failed truncating file: %d\n", rc);        errno = EIO;        return rc * 10 - 2;    }    rc = fat_remove(&(file->fatfile));    if ( rc < 0 ) {        DEBUGF("Failed removing file: %d\n", rc);        errno = EIO;        return rc * 10 - 3;    }    file->size = 0;    rc = close(fd);    if (rc<0)        return rc * 10 - 4;    return 0;}int rename(const char* path, const char* newpath){    int rc, fd;    char* nameptr;    struct filedesc* file;    /* verify new path does not already exist */    fd = open(newpath, O_RDONLY);    if ( fd >= 0 ) {        close(fd);        errno = EBUSY;        return -1;    }    close(fd);    fd = open(path, O_RDONLY);    if ( fd < 0 ) {        errno = EIO;        return fd * 10 - 2;    }    /* strip path */    nameptr = strrchr(newpath,'/');    if (nameptr)        nameptr++;    else        nameptr = (char*)newpath;    file = &openfiles[fd];    rc = fat_rename(&file->fatfile, nameptr, file->size, file->attr);    if ( rc < 0 ) {        DEBUGF("Failed renaming file: %d\n", rc);        errno = EIO;        return rc * 10 - 3;    }    rc = close(fd);    if (rc<0) {        errno = EIO;        return rc * 10 - 4;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -