+static void
+fs_sanitize_cmdline(char *args)
+{
+ char *nl;
+
+ nl = strrchr(args, '\n');
+ if (nl)
+ nl[0] = '\0';
+}
+
+static int
+fs_execute_cmd(struct sub_device *sdev, char *cmdline)
+{
+ FILE *fp;
+ /* store possible newline as well */
+ char output[DEVARGS_MAXLEN + 1];
+ size_t len;
+ int ret;
+
+ RTE_ASSERT(cmdline != NULL || sdev->cmdline != NULL);
+ if (sdev->cmdline == NULL) {
+ size_t i;
+
+ len = strlen(cmdline) + 1;
+ sdev->cmdline = calloc(1, len);
+ if (sdev->cmdline == NULL) {
+ ERROR("Command line allocation failed");
+ return -ENOMEM;
+ }
+ strlcpy(sdev->cmdline, cmdline, len);
+ /* Replace all commas in the command line by spaces */
+ for (i = 0; i < len; i++)
+ if (sdev->cmdline[i] == ',')
+ sdev->cmdline[i] = ' ';
+ }
+ DEBUG("'%s'", sdev->cmdline);
+ fp = popen(sdev->cmdline, "r");
+ if (fp == NULL) {
+ ret = -errno;
+ ERROR("popen: %s", strerror(errno));
+ return ret;
+ }
+ /* We only read one line */
+ if (fgets(output, sizeof(output) - 1, fp) == NULL) {
+ DEBUG("Could not read command output");
+ ret = -ENODEV;
+ goto ret_pclose;
+ }
+ fs_sanitize_cmdline(output);
+ if (output[0] == '\0') {
+ ret = -ENODEV;
+ goto ret_pclose;
+ }
+ ret = fs_parse_device(sdev, output);
+ if (ret)
+ ERROR("Parsing device '%s' failed", output);
+ret_pclose:
+ if (pclose(fp) == -1)
+ ERROR("pclose: %s", strerror(errno));
+ return ret;
+}
+
+static int
+fs_read_fd(struct sub_device *sdev, char *fd_str)
+{
+ FILE *fp = NULL;
+ int fd = -1;
+ /* store possible newline as well */
+ char output[DEVARGS_MAXLEN + 1];
+ int err = -ENODEV;
+ int oflags;
+ int lcount;
+
+ RTE_ASSERT(fd_str != NULL || sdev->fd_str != NULL);
+ if (sdev->fd_str == NULL) {
+ sdev->fd_str = strdup(fd_str);
+ if (sdev->fd_str == NULL) {
+ ERROR("Command line allocation failed");
+ return -ENOMEM;
+ }
+ }
+ errno = 0;
+ fd = strtol(fd_str, &fd_str, 0);
+ if (errno || *fd_str || fd < 0) {
+ ERROR("Parsing FD number failed");
+ goto error;
+ }
+ /* Fiddle with copy of file descriptor */
+ fd = dup(fd);
+ if (fd == -1)
+ goto error;
+ oflags = fcntl(fd, F_GETFL);
+ if (oflags == -1)
+ goto error;
+ if (fcntl(fd, F_SETFL, oflags | O_NONBLOCK) == -1)
+ goto error;
+ fp = fdopen(fd, "r");
+ if (fp == NULL)
+ goto error;
+ fd = -1;
+ /* Only take the last line into account */
+ lcount = 0;
+ while (fgets(output, sizeof(output), fp))
+ ++lcount;
+ if (lcount == 0)
+ goto error;
+ else if (ferror(fp) && errno != EAGAIN)
+ goto error;
+ /* Line must end with a newline character */
+ fs_sanitize_cmdline(output);
+ if (output[0] == '\0')
+ goto error;
+ err = fs_parse_device(sdev, output);
+ if (err)
+ ERROR("Parsing device '%s' failed", output);
+error:
+ if (fp)
+ fclose(fp);
+ if (fd != -1)
+ close(fd);
+ return err;
+}
+