static int rtems_rfs_rtems_mknod (const rtems_filesystem_location_info_t *parentloc, const char *name, size_t namelen, mode_t mode, dev_t dev) { rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (parentloc); rtems_rfs_ino parent = rtems_rfs_rtems_get_pathloc_ino (parentloc); rtems_rfs_ino ino; rtems_rfs_inode_handle inode; uid_t uid; gid_t gid; int rc; uid = geteuid (); gid = getegid (); rc = rtems_rfs_inode_create (fs, parent, name, namelen, rtems_rfs_rtems_imode (mode), 1, uid, gid, &ino); if (rc > 0) { return rtems_rfs_rtems_error ("mknod: inode create", rc); } rc = rtems_rfs_inode_open (fs, ino, &inode, true); if (rc > 0) { return rtems_rfs_rtems_error ("mknod: inode open", rc); } if (S_ISDIR(mode) || S_ISREG(mode)) { } else if (S_ISCHR (mode) || S_ISBLK (mode)) { int major; int minor; rtems_filesystem_split_dev_t (dev, major, minor); rtems_rfs_inode_set_block (&inode, 0, major); rtems_rfs_inode_set_block (&inode, 1, minor); } else { rtems_rfs_inode_close (fs, &inode); return rtems_rfs_rtems_error ("mknod: bad mode", EINVAL); } rc = rtems_rfs_inode_close (fs, &inode); if (rc > 0) { return rtems_rfs_rtems_error ("mknod: closing inode", rc); } return 0; }
int rtems_rfs_symlink (rtems_rfs_file_system* fs, const char* name, int length, const char* link, int link_length, uid_t uid, gid_t gid, rtems_rfs_ino parent) { rtems_rfs_inode_handle inode; rtems_rfs_ino ino; int rc; if (rtems_rfs_trace (RTEMS_RFS_TRACE_SYMLINK)) { int c; printf ("rtems-rfs: symlink: parent:%" PRIu32 " name:", parent); for (c = 0; c < length; c++) printf ("%c", name[c]); printf (" link:"); for (c = 0; c < link_length; c++) printf ("%c", link[c]); } if (link_length >= rtems_rfs_fs_block_size (fs)) return ENAMETOOLONG; rc = rtems_rfs_inode_create (fs, parent, name, strlen (name), RTEMS_RFS_S_SYMLINK, 1, uid, gid, &ino); if (rc > 0) return rc; rc = rtems_rfs_inode_open (fs, ino, &inode, true); if (rc > 0) return rc; /* * If the link length is less than the length of data union in the inode * place the link into the data area else allocate a block and write the link * to that. */ if (link_length < RTEMS_RFS_INODE_DATA_NAME_SIZE) { memset (inode.node->data.name, 0, RTEMS_RFS_INODE_DATA_NAME_SIZE); memcpy (inode.node->data.name, link, link_length); rtems_rfs_inode_set_block_count (&inode, 0); } else { rtems_rfs_block_map map; rtems_rfs_block_no block; rtems_rfs_buffer_handle buffer; uint8_t* data; rc = rtems_rfs_block_map_open (fs, &inode, &map); if (rc > 0) { rtems_rfs_inode_close (fs, &inode); return rc; } rc = rtems_rfs_block_map_grow (fs, &map, 1, &block); if (rc > 0) { rtems_rfs_block_map_close (fs, &map); rtems_rfs_inode_close (fs, &inode); return rc; } rc = rtems_rfs_buffer_handle_open (fs, &buffer); if (rc > 0) { rtems_rfs_block_map_close (fs, &map); rtems_rfs_inode_close (fs, &inode); return rc; } rc = rtems_rfs_buffer_handle_request (fs, &buffer, block, false); if (rc > 0) { rtems_rfs_block_map_close (fs, &map); rtems_rfs_inode_close (fs, &inode); return rc; } data = rtems_rfs_buffer_data (&buffer); memset (data, 0xff, rtems_rfs_fs_block_size (fs)); memcpy (data, link, link_length); rc = rtems_rfs_buffer_handle_close (fs, &buffer); if (rc > 0) { rtems_rfs_block_map_close (fs, &map); rtems_rfs_inode_close (fs, &inode); return rc; } rc = rtems_rfs_block_map_close (fs, &map); if (rc > 0) { rtems_rfs_inode_close (fs, &inode); return rc; } } rtems_rfs_inode_set_block_offset (&inode, link_length); rc = rtems_rfs_inode_close (fs, &inode); return rc; }