Beispiel #1
0
// Write 'n' bytes from 'buf' to 'fd' at the current seek position.
static ssize_t
file_write(struct Fd *fd, const void *buf, size_t n, off_t offset)
{
	int r;
	size_t tot;

	// don't write past the maximum file size
	tot = offset + n;
	if (tot > MAXFILESIZE)
		return -E_NO_DISK;

	// increase the file's size if necessary
	if (tot > fd->fd_file.file.f_size) {
		if ((r = file_trunc(fd, tot)) < 0)
			return r;
	}

	// write the data
	memcpy(fd2data(fd) + offset, buf, n);
	return n;
}
Beispiel #2
0
static void* file_open(void* obj, char* path, s64 flag, s64 mode)
{
	assert(IS_PTR(obj));

    fatfile_t* file = (fatfile_t*)obj;

    down(&file->sem);

    if(*path == NULL) // last name in path
    {
        file->ref ++;
        if((!file->attr.directory) && (flag & O_TRUNC))
            file_trunc(file);

		up_one(&file->sem);
        return file;
    }

    if(!file->attr.directory) // 路径中的名称必须是目录
    {
    	up_one(&file->sem);
    	return (void*)-1;
    }

    char filename[32];
    char* end = strchr(path, '/');
    strncpy(filename, path, end -path);
    UpperStr(filename);

    if(*end == '/') // skip '/'
        end ++;

    // find in child list
    fatfile_t* child = findChild(file, filename);
    if(child == NULL)
    {
        child = (fatfile_t*)kmalloc(sizeof(fatfile_t));
        memset(child, 0, sizeof(fatfile_t));
        child->ops = &file_ops;
        sem_init(&child->sem, 1, "file sem");
        child->fatfs = file->fatfs;
        child->name = strdup(filename);

        struct FAT_ENTRY entry;
        int index = findEntryByName(file, filename, &entry);
        if(index >= 0)
        {
            child->index = index;
            child->cluster = (entry.start_clusterHI << 16) | entry.start_clusterLO;
            child->size = entry.file_size;
            child->attr = entry.attribute;

            getEntryCreateDate(child, &entry);
            getEntryWriteDate(child, &entry);
        }
        else
        {
            if((flag &O_CREAT) && (*end == NULL))
            {
                rtcdate rtc;
                cmostime(&rtc);
                child->cdatetime = rtc;
                child->wdatetime = rtc;

                child->dirty = TRUE; // update entry
            }
            else
            {
                kmfree(child->name);
                kmfree(child);

                up_one(&file->sem);
                return (void*)-2;
            }
        }

        insertChild(file, child);
    }

    up_one(&file->sem);
    return file_open(child, end, flag, mode);
}