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

📄 target.c

📁 是一个手机功能的模拟程序
💻 C
📖 第 1 页 / 共 3 页
字号:
        req->path = pathname;
        req->value16 = action;
        req->size = param;
        req->request_id = request_id_get();
        req->fb = fb;
        req->cp = cp;
        req->cmd = FCONTROL;
        MSG_SEND(req);
        return req->request_id;
    }
}

effs_t task_fcontrol(struct ffs_req_s *p)
{
    iref_t i;

#define pathname p->path
#define action p->value16
#define param p->size

    if (fs.initerror)
        return fs.initerror;

    if (pathname == NULL)
        return EFFS_BADNAME;

    if ((i = ffs_strcmp(pathname, "/dev/ffs")) != 0)
    {
        if ((i = object_lookup_once(pathname, 0, 0)) < 0)
            return i;

        if ((i = is_readonly(i, pathname)) < 0)
            return i;
    }

    if ((i = object_control(i, action, param)) < 0)
        return i;

    tw(tr_bstat());

    return EFFS_OK;

#undef pathname
#undef action
#undef param

}


effs_t ffs_fcontrol(const char *pathname, int8 action, int param)
{
    FFS_BLOCKING_CALL_BEGIN();

    result = ffs_fcontrol_b(pathname, action, param, 0, &fb);

    FFS_BLOCKING_CALL_END();

    return result;
}


req_id_t ffs_fcontrol_nb(const char *pathname, int8 action, int param,
                       T_RV_RETURN *cp)
{
    return ffs_fcontrol_b(pathname, action, param, cp, 0);
}


req_id_t ffs_rename_b(const char *pathname, const char *newname,
                     T_RV_RETURN *cp, struct ffs_blocking_s *fb)
{
    iref_t i, oldi, dir;
    char *name;
    struct inode_s *ip;

    tw(tr(TR_FUNC, TrApi, "ffs_rename('%s', '%s') ?\n", pathname, newname));
	ttw(ttr(TTrApi, "ffs_rename('%s', '%s') ?" NL, pathname, newname)); 

    {
        struct ffs_req_s *req;
        MSG_ALLOC(req);
        req->path = pathname;
        req->src = (char *) newname;
        req->request_id = request_id_get();
        req->fb = fb;
        req->cp = cp;
        req->cmd = RENAME;
        MSG_SEND(req);
        return req->request_id;
    }

}

effs_t task_rename(struct ffs_req_s *p)
{
    iref_t i, oldi, dir;
    char *name;
    struct inode_s *ip;

#define pathname p->path
#define newname p->src

    if (fs.initerror)
        return fs.initerror;

    // pathname MUST exist, not be open and MUST be writable
    if ((oldi = object_lookup_once(pathname, 0, 0)) < 0)
        return oldi;
    if ((oldi = is_readonly(oldi, pathname)) < 0)
        return oldi;
    if (get_fdi(oldi) >= 0)
        return EFFS_LOCKED;

    journal_begin(oldi);

    if ((i = object_lookup_once(newname, &name, &dir)) < 0) {
        if (i != EFFS_NOTFOUND)
            return i;
    }
    else {                               // newname obj exist   
        ip = inode_addr(oldi);
        if (is_object(ip, OT_FILE)) {    // is old obj a file?
            if ((i = is_readonly(i, newname)) < 0)
                return i;

            ip = inode_addr(i);
            if (!is_object(ip, OT_FILE)) // newname MUST be a file 
                return EFFS_NOTAFILE;

            fs.journal.repli = i;        
        }
        else
            return EFFS_EXISTS;         
    }
    
    if ((i = object_rename(oldi, name, -dir)) < 0)
        return i;

    journal_end(0);

    tw(tr_bstat());    

    return EFFS_OK;

#undef pathname
#undef newname

}


effs_t ffs_rename(const char *pathname, const char *newname)
{
    FFS_BLOCKING_CALL_BEGIN();

    result = ffs_rename_b(pathname, newname, 0, &fb);


    FFS_BLOCKING_CALL_END();

    return result;
}



req_id_t ffs_rename_nb(const char *pathname, const char *newname,
                     T_RV_RETURN *cp)
{
    return ffs_rename_b(pathname, newname, cp, 0);
}


/******************************************************************************
 * Directory Operations
 ******************************************************************************/

// All directory operations are more or less similar to unix
// semantics.
req_id_t ffs_mkdir_b(const char *pathname, T_RV_RETURN *cp, 
           struct ffs_blocking_s *fb)
{
    iref_t i, dir;
    char *name;

    tw(tr(TR_FUNC, TrApi, "ffs_mkdir('%s')\n", pathname));
	ttw(ttr(TTrApi, "ffs_mkdir('%s') ?" NL, pathname)); 
	
    {
        struct ffs_req_s *req;
        MSG_ALLOC(req);
        req->path = pathname;
        req->request_id = request_id_get();
        req->fb = fb;
        req->cp = cp;
        req->cmd = MKDIR;
        MSG_SEND(req);
        return req->request_id;
    }
}

effs_t task_mkdir(struct ffs_req_s *p)
{
    iref_t i, dir;
    char *name;

#define pathname p->path

    if (fs.initerror)
        return fs.initerror;

    i = object_lookup(pathname, &name, &dir);
    if (i > 0)
        return EFFS_EXISTS;
    if (i != EFFS_NOTFOUND)
        return i;

    journal_begin(0);

    if ((i = object_create(name, 0, 0, -dir)) < 0)
        return i;

    journal_end(OT_DIR);

    tw(tr_bstat());

    return EFFS_OK;

#undef pathname

}


effs_t ffs_mkdir(const char *pathname)
{
    FFS_BLOCKING_CALL_BEGIN();

    result = ffs_mkdir_b(pathname, 0, &fb);

    FFS_BLOCKING_CALL_END();

    return result;
}


req_id_t ffs_mkdir_nb(const char *pathname, T_RV_RETURN *cp)
{
    return ffs_mkdir_b(pathname, cp, 0);
}


int ffs_opendir(const char *name, struct dir_s *dir)
{
    int i;

    tw(tr(TR_FUNC, TrApi, "ffs_opendir('%s', ?)\n", name));
	ttw(ttr(TTrApi, "ffs_opendir('%s', ?) ?" NL, name)); 

    if (dir == NULL)
        return EFFS_INVALID;

    if ((i = ffs_begin()) == EFFS_OK)
    {
        if ((i = dir_open(name)) >= 0)
        {
            dir->this = i;
            dir->index = i;

            // Now count the number of entries in the directory
            dir_traverse(-i, (iref_t *) &i);
        }
    }
    return ffs_end(i);
}


int ffs_readdir(struct dir_s *dir, char *name, int size)
{
    iref_t i;

    tw(tr(TR_BEGIN, TrApi, "ffs_readdir(?, ?, ?) {\n"));
	ttw(ttr(TTrApi, "ffs_readdir(?, ?, ?) ?" NL)); 

    if (dir == NULL || name == NULL || size < 0) {
        tw(tr(TR_END, TrApi, "} %d\n", EFFS_INVALID));
        return EFFS_INVALID;
    }

    if ((i = ffs_begin()) == EFFS_OK)
    {
        if ((i = dir_next(dir->this, dir->index, name, size)))
            dir->index = i;
    }
    tw(tr(TR_END, TrApi, "} ('%s') %d\n", name, i));

    return ffs_end(i);
}



/******************************************************************************
 * Preformat and Format
 ******************************************************************************/

// Note that we do NOT call ffs_begin() because it will just return
// EFFS_NOFORMAT!
req_id_t ffs_format_b(const char *name, uint16 magic, T_RV_RETURN *cp,
            struct ffs_blocking_s *fb)
{
    effs_t i;
	
    tw(tr(TR_BEGIN, TrApi, "ffs_format('%s', 0x%x) {\n", name, magic));
	ttw(ttr(TTrApi, "ffs_format('%s', 0x%x) ?" NL, name, magic)); 

    {
        struct ffs_req_s *req;
        MSG_ALLOC(req);
        req->path = name;
        req->size = magic;
        req->request_id = request_id_get();
        req->fb = fb;
        req->cp = cp;
        req->cmd = FORMAT;
        MSG_SEND(req);
        return req->request_id;
    }
}

effs_t task_format(struct ffs_req_s *p)
{
    iref_t i;

#define name p->path
#define magic p->size
	
    if (magic != 0x2BAD) {
        tw(tr(TR_END, TrApi, "} %d\n", EFFS_INVALID));
        return EFFS_INVALID;
    }

	if (name == NULL) {
// The following line is automatically expanded by the revision control
// system to make a default drive label. 

//$Format: "name = \"/ffs-$ProjectMajorVersion$.$ProjectMinorVersion$\";"$	
name = "/ffs-5.53";
	}

    if (*name != '/') {
        tw(tr(TR_END, TrApi, "} %d\n", EFFS_BADNAME));
        return EFFS_BADNAME;
    }

    if ((i = is_formattable(1)) < 0) {
        tw(tr(TR_END, TrApi, "} %d\n", i));
        return i;
    }

    if ((i = fs_format(name)) < 0)
        return i;

    tw(tr(TR_END, TrApi, "} %d\n", i));

    tw(tr_bstat());

    return EFFS_OK;

#undef name
#undef magic

}

 
effs_t ffs_format(const char *name, uint16 magic)
{
    FFS_BLOCKING_CALL_BEGIN();
    
    result = ffs_format_b(name, magic, 0, &fb);
    
    FFS_BLOCKING_CALL_END();

    return result;
}


req_id_t ffs_format_nb(const char *name, uint16 magic, T_RV_RETURN *cp)
{
   return ffs_format_b(name, magic, cp, 0);
}


req_id_t ffs_preformat_b(uint16 magic, T_RV_RETURN *cp, 
               struct ffs_blocking_s *fb)
{
    effs_t i;

    tw(tr(TR_BEGIN, TrApi, "ffs_preformat(0x%x) {\n", magic));
	ttw(ttr(TTrApi, "ffs_preformat(0x%x) ?" NL, magic)); 

    {
        struct ffs_req_s *req;
        MSG_ALLOC(req);
        req->path = "/";
        req->size = magic;
        req->request_id = request_id_get();
        req->fb = fb;
        req->cp = cp;
        req->cmd = PREFORMAT;
        MSG_SEND(req);
        return req->request_id;
    }
}

effs_t task_preformat(struct ffs_req_s *p)
{
    effs_t i;

#define magic p->size

    if (magic != 0xDEAD) {
        tw(tr(TR_END, TrApi, "} %d\n", EFFS_INVALID));
        return EFFS_INVALID;
    }

    if (!ffs_is_modifiable("")) {
        tw(tr(TR_END, TrApi, "} %d\n", EFFS_ACCESS));
        return EFFS_ACCESS;
    }

    if ((i = is_formattable(0)) < 0) {
        tw(tr(TR_END, TrApi, "} %d\n", i));
        return i;
    }

    if ((i = fs_preformat()) < 0)
        return i;

    tw(tr(TR_END, TrApi, "} %d\n", i));

    tw(tr_bstat());

    return EFFS_OK;

#undef magic

}


effs_t ffs_preformat(uint16 magic)
{
    FFS_BLOCKING_CALL_BEGIN();

    result = ffs_preformat_b(magic, 0, &fb);
    
    FFS_BLOCKING_CALL_END();

    return result;
}


req_id_t ffs_preformat_nb(uint16 magic, T_RV_RETURN *cp)
{
  return ffs_preformat_b(magic, cp, 0);
}


/******************************************************************************
 * Open, Read, Write, Close
 ******************************************************************************/
req_id_t ffs_open_b(const char *pathname, ffs_options_t option,
        T_RV_RETURN *cp, struct ffs_blocking_s *fb)
{
    iref_t i, dir, dummy;            
    char *name;
    fd_t other_fdi, fdi = 0;
    int error; 
    struct inode_s *ip;
    
    tw(tr(TR_FUNC, TrApi, "ffs_open('%s', 0x%x) ?\n", pathname, option));
	ttw(ttr(TTrApi, "ffs_open('%s', 0x%x) ?" NL, pathname, option)); 

    {
        struct ffs_req_s *req;
        MSG_ALLOC(req);
        req->path = pathname;
        req->value16 = option;
        req->request_id = request_id_get();
        req->fb = fb;
        req->cp = cp;
        req->cmd = OPEN;
        MSG_SEND(req);
        return req->request_id;
    }
}

fd_t task_open(struct ffs_req_s *p)
{
    iref_t i, dir, dummy;
    char *name;
    fd_t other_fdi, fdi = 0;
    int error;
    struct inode_s *ip;

#define pathname p->path
#define option p->value16

    if (fs.initerror)
        return fs.initerror;
    
    // Minimum one of the flags RD or WR must be specifyed
    if (!is_open_option(option, FFS_O_RDONLY) && 
        !is_open_option(option, FFS_O_WRONLY))
        return EFFS_INVALID;
    
    // RDONLY must not be combined with any other options if not together
    // with WR!
    if (is_open_option(option, FFS_O_RDONLY) && 
        !is_open_option(option, FFS_O_WRONLY))     
        if (!(option == FFS_O_RDONLY))
            return EFFS_INVALID;
    
    for (fdi = 0; fdi < fs.fd_max; fdi++) {  // Find free fd
        if (fs.fd[fdi].options == 0) {
            break;
        }
    }

    if (fdi >= fs.fd_max)
        return EFFS_NUMFD;  // Too many open files in system

    i = object_lookup(pathname, &name, &dir);
    if (i < 0 && i != EFFS_NOTFOUND)
        return i;

    // Open one file several times in RD is okay but only one time in WR
    if (i != EFFS_NOTFOUND && (other_fdi = get_fdi(i)) >= 0) {
        if (is_open_option(fs.fd[other_fdi].options, FFS_O_WRONLY) || 
			is_open_option(option, FFS_O_WRONLY))
            return EFFS_LOCKED;
    }

    // Init default values
    fs.fd[fdi].fp = fs.fd[fdi].size = fs.fd[fdi].wfp = fs.fd[fdi].dirty = 0;
         
    if (i == EFFS_NOTFOUND) {
        if (is_open_option(option, (FFS_O_CREATE | FFS_O_WRONLY))) {
            if ((error = is_filename(name)) < 0)
                return error;

            // Create segmenthead
            journal_begin(0);

            if ((i = object_create(name, 0, 0, -dir)) < 0)
                return i;

            journal_end(OT_FILE);  
            tw(tr_bstat());
            fs.fd[fdi].seghead = i;
        }
        else 
            return EFFS_NOTFOUND;    
    }
    else {
        if (is_open_option(option, FFS_O_WRONLY)) {
            if (is_open_option(option, (FFS_O_CREATE | FFS_O_EXCL)))
                return EFFS_EXISTS;   
            if ((i = is_readonly(i, pathname)) < 0)
                return i;
        }
        ip = inode_addr(i);
        
        if (is_object(ip, OT_DIR))
            return EFFS_NOTAFILE;

        if (is_open_option(option, FFS_O_TRUNC)) { 
            // Save the segment (if any) in the global variable because this
            // global variable will be updated if the inode is relocated by
            // an inode_reclaim() triggeret by object_create()
            fs.i_backup = segment_next(i);

⌨️ 快捷键说明

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