| 240 | } |
| 241 | |
| 242 | FTS* yfts_open(char* const* argv, int options, int (*compar)(const FTSENT**, const FTSENT**)) |
| 243 | { |
| 244 | FTS* sp; |
| 245 | FTSENT *p, *root; |
| 246 | int nitems; |
| 247 | FTSENT *parent, *tmp; |
| 248 | int len; |
| 249 | |
| 250 | errno = 0; |
| 251 | |
| 252 | Y_ASSERT(argv); |
| 253 | if (!*argv) { |
| 254 | errno = ENOENT; |
| 255 | return nullptr; |
| 256 | } |
| 257 | |
| 258 | /* Options check. */ |
| 259 | if (options & ~FTS_OPTIONMASK) { |
| 260 | errno = EINVAL; |
| 261 | return nullptr; |
| 262 | } |
| 263 | |
| 264 | /* Allocate/initialize the stream */ |
| 265 | if ((sp = (FTS*)malloc(sizeof(FTS))) == nullptr) { |
| 266 | return nullptr; |
| 267 | } |
| 268 | memset(sp, 0, sizeof(FTS)); |
| 269 | sp->fts_compar = compar; |
| 270 | sp->fts_options = options; |
| 271 | |
| 272 | /* Shush, GCC. */ |
| 273 | tmp = nullptr; |
| 274 | |
| 275 | /* Logical walks turn on NOCHDIR; symbolic links are too hard. */ |
| 276 | if (ISSET(FTS_LOGICAL)) { |
| 277 | SET(FTS_NOCHDIR); |
| 278 | } |
| 279 | |
| 280 | /* |
| 281 | * Start out with 1K of path space, and enough, in any case, |
| 282 | * to hold the user's paths. |
| 283 | */ |
| 284 | if (fts_palloc(sp, MAX(fts_maxarglen(argv), MAXPATHLEN))) { |
| 285 | goto mem1; |
| 286 | } |
| 287 | |
| 288 | /* Allocate/initialize root's parent. */ |
| 289 | if ((parent = fts_alloc(sp, "", 0)) == nullptr) { |
| 290 | goto mem2; |
| 291 | } |
| 292 | parent->fts_level = FTS_ROOTPARENTLEVEL; |
| 293 | |
| 294 | /* Allocate/initialize root(s). */ |
| 295 | for (root = nullptr, nitems = 0; *argv; ++argv, ++nitems) { |
| 296 | /* Don't allow zero-length paths. */ |
| 297 | |
| 298 | len = strlen(*argv); |
| 299 |
no test coverage detected