ssize_t fs_load_file(const char *path, void *ptr, size_t maxlen) { filehandle *handle; /* open the file */ status_t err = fs_open_file(path, &handle); if (err < 0) return err; /* stat it for size, see how much we need to read */ struct file_stat stat; fs_stat_file(handle, &stat); ssize_t read_bytes = fs_read_file(handle, ptr, 0, MIN(maxlen, stat.size)); fs_close_file(handle); return read_bytes; }
/* * ディレクトリを削除する。 * */ W sfs_i_rmdir (struct inode *parent, char *fname, struct access_info *acc) { int nentry; int i; int inodeindex; struct inode *ip; W rsize, errno; errno = fs_lookup (parent, fname, O_RDWR, 0, acc, &ip); if (errno) { printk("[PM] sfs_i_rmdir: can't remove directory %s(%d)\n", fname, errno); return (errno); } if ((ip->i_mode & SFS_FMT_DIR) == 0) { fs_close_file(ip); return (EP_NOTDIR); } if (ip->i_refcount >= 2) { fs_close_file(ip); return (EP_BUSY); } nentry = sfs_read_dir (ip, 0, NULL); if (nentry >= 3) { fs_close_file(ip); return (EP_NOTEMPTY); } nentry = sfs_read_dir (parent, 0, NULL); if (nentry <= 0) { fs_close_file(ip); return (EP_NOENT); } { struct sfs_dir buf[nentry]; /* GCC の拡張機能を使っている */ if (sfs_read_dir (parent, nentry, buf) != 0) { fs_close_file(ip); return (EP_IO); } for (i = 0; i < nentry; i++) { /* 表示文字長を SFS_MAXNAMELEN にするため.後に pad があるので大丈夫 */ if (strncmp (fname, buf[i].sfs_d_name, SFS_MAXNAMELEN+1) == 0) { inodeindex = buf[i].sfs_d_index; break; } } if (i >= nentry) { fs_close_file(ip); return (EP_NOENT); } while (i < nentry) { buf[i].sfs_d_index = buf[i + 1].sfs_d_index; /* 表示文字長を SFS_MAXNAMELEN にするため.後に pad があるので大丈夫 */ strncpy (buf[i].sfs_d_name, buf[i + 1].sfs_d_name, SFS_MAXNAMELEN+1); i++; } i = parent->i_size - sizeof (struct sfs_dir); sfs_i_write(parent, 0, (B *)buf, i, &rsize); sfs_i_truncate (parent, i); ip->i_link--; ip->i_dirty = 1; if (ip->i_link <= 1) { sfs_i_truncate (ip, 0); sfs_free_inode(ip->i_fs, inodeindex); } parent->i_link -= 1; parent->i_dirty = 1; } fs_close_file(ip); return (EP_OK); }