diff --git a/ChangeLog.txt b/ChangeLog.txt index 8b43d785b..26ae31b63 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1461,3 +1461,7 @@ leading or trailing whitespace (2015-11-23). * apps/nshlib: The mount commands now accepts mount options (currently needed only for the hostfs file system). From Ken Petit (2015-11-25). + * apps/nshlib: NSH no longer calls losetup() and loteardown directly. + Now it opens /dev/loop and accomplishes these things using ioctl() + calls (2015-11-25). + diff --git a/nshlib/nsh.h b/nshlib/nsh.h index fc685e118..1b705f506 100644 --- a/nshlib/nsh.h +++ b/nshlib/nsh.h @@ -594,7 +594,7 @@ * entries the provide the necessary interfaces. * - Other interfaces are more standard and for these there probably should * be new system calls to support the OS interface. Such interfaces - * include things like losetup, loteardown, and mkrd. + * include things like ps, mkfatfs, and mkrd. * - Other interfaces simply need to be moved out of the OS and into the C * library where they will become accessible to application code. Such * interfaces include mkfatfs. @@ -605,8 +605,6 @@ # define CONFIG_NSH_DISABLE_PS 1 # undef CONFIG_NSH_DISABLE_DF /* 'df' depends on foreach_mountpoint */ # define CONFIG_NSH_DISABLE_DF 1 -# undef CONFIG_NSH_DISABLE_LOSETUP /* 'losetup' depends on losetup/loteardown */ -# define CONFIG_NSH_DISABLE_LOSETUP 1 # undef CONFIG_NSH_DISABLE_MKFATFS /* 'mkfatfs' depends on mkfatfs interface */ # define CONFIG_NSH_DISABLE_MKFATFS 1 # undef CONFIG_NSH_DISABLE_MKRD /* 'mkrd' depends on ramdisk_register */ @@ -908,7 +906,7 @@ void nsh_usbtrace(void); # endif /* CONFIG_NFILE_STREAMS && NSH_HAVE_DIROPTS */ # ifndef CONFIG_DISABLE_MOUNTPOINT -# ifndef CONFIG_NSH_DISABLE_LOSETUP +# if defined(CONFIG_DEV_LOOP) && !defined(CONFIG_NSH_DISABLE_LOSETUP) int cmd_losetup(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); # endif # ifndef CONFIG_NSH_DISABLE_MKFIFO diff --git a/nshlib/nsh_command.c b/nshlib/nsh_command.c index abaa4b10a..7668763a6 100644 --- a/nshlib/nsh_command.c +++ b/nshlib/nsh_command.c @@ -243,7 +243,7 @@ static const struct cmdmap_s g_cmdmap[] = #endif #if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_MOUNTPOINT) -# ifndef CONFIG_NSH_DISABLE_LOSETUP +# if defined(CONFIG_DEV_LOOP) && !defined(CONFIG_NSH_DISABLE_LOSETUP) { "losetup", cmd_losetup, 3, 6, "[-d ] | [[-o ] [-r] ]" }, # endif #endif diff --git a/nshlib/nsh_fscmds.c b/nshlib/nsh_fscmds.c index 681c81274..68f63dcd4 100644 --- a/nshlib/nsh_fscmds.c +++ b/nshlib/nsh_fscmds.c @@ -51,6 +51,10 @@ # include # include # endif +# ifdef CONFIG_DEV_LOOP +# include +# include +# endif # ifdef CONFIG_FS_FAT # include # endif @@ -838,17 +842,19 @@ errout: ****************************************************************************/ #if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_MOUNTPOINT) -#ifndef CONFIG_NSH_DISABLE_LOSETUP +# if defined(CONFIG_DEV_LOOP) && !defined(CONFIG_NSH_DISABLE_LOSETUP) int cmd_losetup(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) { - char *loopdev = NULL; - char *filepath = NULL; - bool teardown = false; - bool readonly = false; - off_t offset = 0; - bool badarg = false; - int ret = ERROR; - int option; + FAR char *loopdev = NULL; + FAR char *filepath = NULL; + struct losetup_s setup; + bool teardown = false; + bool readonly = false; + off_t offset = 0; + bool badarg = false; + int ret = ERROR; + int option; + int fd; /* Get the losetup options: Two forms are supported: * @@ -917,10 +923,19 @@ int cmd_losetup(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) /* There should be nothing else on the command line */ if (optind < argc) - { - nsh_output(vtbl, g_fmttoomanyargs, argv[0]); - goto errout_with_paths; - } + { + nsh_output(vtbl, g_fmttoomanyargs, argv[0]); + goto errout_with_paths; + } + + /* Open the loop device */ + + fd = open("/dev/loop", O_RDONLY); + if (fd < 0) + { + nsh_output(vtbl, g_fmtcmdfailed, argv[0], "open", NSH_ERRNO); + goto errout_with_paths; + } /* Perform the teardown operation */ @@ -928,26 +943,37 @@ int cmd_losetup(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) { /* Tear down the loop device. */ - ret = loteardown(loopdev); + ret = ioctl(fd, LOOPIOC_TEARDOWN, (unsigned long)((uintptr_t)loopdev)); if (ret < 0) { - nsh_output(vtbl, g_fmtcmdfailed, argv[0], "loteardown", NSH_ERRNO_OF(-ret)); - goto errout_with_paths; + nsh_output(vtbl, g_fmtcmdfailed, argv[0], "ioctl", NSH_ERRNO); + goto errout_with_fd; } } else { /* Set up the loop device */ - ret = losetup(loopdev, filepath, 512, offset, readonly); + setup.devname = loopdev; /* The loop block device to be created */ + setup.filename = filepath; /* The file or character device to use */ + setup.sectsize = 512; /* The sector size to use with the block device */ + setup.offset = offset; /* An offset that may be applied to the device */ + setup.readonly = readonly; /* True: Read access will be supported only */ + + ret = ioctl(fd, LOOPIOC_SETUP, (unsigned long)((uintptr_t)&setup)); if (ret < 0) { - nsh_output(vtbl, g_fmtcmdfailed, argv[0], "losetup", NSH_ERRNO_OF(-ret)); - goto errout_with_paths; + nsh_output(vtbl, g_fmtcmdfailed, argv[0], "ioctl", NSH_ERRNO); + goto errout_with_fd; } } - /* Free memory */ + ret = OK; + + /* Free resources */ + +errout_with_fd: + (void)close(fd); errout_with_paths: if (loopdev)