| 136 | } |
| 137 | |
| 138 | static int |
| 139 | fs_read_fd(struct sub_device *sdev, char *fd_str) |
| 140 | { |
| 141 | FILE *fp = NULL; |
| 142 | int fd = -1; |
| 143 | /* store possible newline as well */ |
| 144 | char output[DEVARGS_MAXLEN + 1]; |
| 145 | int err = -ENODEV; |
| 146 | int oflags; |
| 147 | int lcount; |
| 148 | |
| 149 | RTE_ASSERT(fd_str != NULL || sdev->fd_str != NULL); |
| 150 | if (sdev->fd_str == NULL) { |
| 151 | sdev->fd_str = strdup(fd_str); |
| 152 | if (sdev->fd_str == NULL) { |
| 153 | ERROR("Command line allocation failed"); |
| 154 | return -ENOMEM; |
| 155 | } |
| 156 | } |
| 157 | errno = 0; |
| 158 | fd = strtol(fd_str, &fd_str, 0); |
| 159 | if (errno || *fd_str || fd < 0) { |
| 160 | ERROR("Parsing FD number failed"); |
| 161 | goto error; |
| 162 | } |
| 163 | /* Fiddle with copy of file descriptor */ |
| 164 | fd = dup(fd); |
| 165 | if (fd == -1) |
| 166 | goto error; |
| 167 | oflags = fcntl(fd, F_GETFL); |
| 168 | if (oflags == -1) |
| 169 | goto error; |
| 170 | if (fcntl(fd, F_SETFL, oflags | O_NONBLOCK) == -1) |
| 171 | goto error; |
| 172 | fp = fdopen(fd, "r"); |
| 173 | if (fp == NULL) |
| 174 | goto error; |
| 175 | fd = -1; |
| 176 | /* Only take the last line into account */ |
| 177 | lcount = 0; |
| 178 | while (fgets(output, sizeof(output), fp)) |
| 179 | ++lcount; |
| 180 | if (lcount == 0) |
| 181 | goto error; |
| 182 | else if (ferror(fp) && errno != EAGAIN) |
| 183 | goto error; |
| 184 | /* Line must end with a newline character */ |
| 185 | fs_sanitize_cmdline(output); |
| 186 | if (output[0] == '\0') |
| 187 | goto error; |
| 188 | err = fs_parse_device(sdev, output); |
| 189 | if (err) |
| 190 | ERROR("Parsing device '%s' failed", output); |
| 191 | error: |
| 192 | if (fp) |
| 193 | fclose(fp); |
| 194 | if (fd != -1) |
| 195 | close(fd); |
no test coverage detected