| 768 | |
| 769 | |
| 770 | Try<vector<string>> get(const string& hierarchy, const string& cgroup) |
| 771 | { |
| 772 | Result<string> hierarchyAbsPath = os::realpath(hierarchy); |
| 773 | if (!hierarchyAbsPath.isSome()) { |
| 774 | return Error( |
| 775 | "Failed to determine canonical path of '" + hierarchy + "': " + |
| 776 | (hierarchyAbsPath.isError() |
| 777 | ? hierarchyAbsPath.error() |
| 778 | : "No such file or directory")); |
| 779 | } |
| 780 | |
| 781 | Result<string> destAbsPath = os::realpath(path::join(hierarchy, cgroup)); |
| 782 | if (!destAbsPath.isSome()) { |
| 783 | return Error( |
| 784 | "Failed to determine canonical path of '" + |
| 785 | path::join(hierarchy, cgroup) + "': " + |
| 786 | (destAbsPath.isError() |
| 787 | ? destAbsPath.error() |
| 788 | : "No such file or directory")); |
| 789 | } |
| 790 | |
| 791 | char* paths[] = {const_cast<char*>(destAbsPath->c_str()), nullptr}; |
| 792 | |
| 793 | FTS* tree = fts_open(paths, FTS_NOCHDIR, nullptr); |
| 794 | if (tree == nullptr) { |
| 795 | return ErrnoError("Failed to start traversing file system"); |
| 796 | } |
| 797 | |
| 798 | vector<string> cgroups; |
| 799 | |
| 800 | FTSENT* node; |
| 801 | while ((node = fts_read(tree)) != nullptr) { |
| 802 | // Use post-order walk here. fts_level is the depth of the traversal, |
| 803 | // numbered from -1 to N, where the file/dir was found. The traversal root |
| 804 | // itself is numbered 0. fts_info includes flags for the current node. |
| 805 | // FTS_DP indicates a directory being visited in postorder. |
| 806 | if (node->fts_level > 0 && node->fts_info & FTS_DP) { |
| 807 | string path = |
| 808 | strings::trim(node->fts_path + hierarchyAbsPath->length(), "/"); |
| 809 | cgroups.push_back(path); |
| 810 | } |
| 811 | } |
| 812 | |
| 813 | if (errno != 0) { |
| 814 | Error error = |
| 815 | ErrnoError("Failed to read a node while traversing file system"); |
| 816 | fts_close(tree); |
| 817 | return error; |
| 818 | } |
| 819 | |
| 820 | if (fts_close(tree) != 0) { |
| 821 | return ErrnoError("Failed to stop traversing file system"); |
| 822 | } |
| 823 | |
| 824 | return cgroups; |
| 825 | } |
| 826 | |
| 827 | |