wxArrayString ArrayVariableProperty::get_dataset_vars() const { wxArrayString ret = read_cache(); if (!ret.empty()) return ret; wxBusyCursor wait_cursor; wxString msg; msg = "Please wait, building variable list from dataset..."; wxBusyInfo wait_info(msg); const wxString pathname = get_var_pathname(); std::fstream fs(pathname.c_str(), std::fstream::in); if (fs.fail()) return ret; // file not found std::string line; getline(fs, line); // skip header size_t col = GetLabel() == "Episodes" ? 0 : 3; // episode-id or variable std::set<wxString> vars; while (getline(fs, line)) { if (iscntrl(line.back())) line.pop_back(); // remove Microsoft return boost::char_separator<char> sep(","); // only commas boost::tokenizer<boost::char_separator<char>> tokens(line, sep); boost::tokenizer<boost::char_separator<char>>::const_iterator it; for (it = tokens.begin(); it != tokens.end(); it++) if (std::distance(tokens.begin(), it) == col) vars.emplace(*it); } fs.close(); for (const wxString& var : vars) ret.Add(var); write_cache(ret); return ret; }
static int trace_cont(int pid) { struct ptrace_lwpinfo lwpinfo; int status; if (ptrace(PT_CONTINUE, pid, (caddr_t)1, 0) < 0) { perror("PT_CONTINUE"); ptrace(PT_KILL, pid, NULL, 0); return (-1); } if (waitpid(pid, &status, 0) == -1) { perror("waitpid"); return (-1); } if (WIFEXITED(status) || WIFSIGNALED(status)) { wait_info(pid, status, NULL); return (-1); } assert(WIFSTOPPED(status)); assert(WSTOPSIG(status) == SIGTRAP); if (ptrace(PT_LWPINFO, pid, (caddr_t)&lwpinfo, sizeof(lwpinfo)) < 0) { perror("PT_LWPINFO"); ptrace(PT_KILL, pid, NULL, 0); return (-1); } wait_info(pid, status, &lwpinfo); if ((lwpinfo.pl_flags & (PL_FLAG_EXEC | PL_FLAG_SCX)) == (PL_FLAG_EXEC | PL_FLAG_SCX)) get_pathname(pid); if ((lwpinfo.pl_flags & (PL_FLAG_FORKED | PL_FLAG_SCX)) == (PL_FLAG_FORKED | PL_FLAG_SCX)) { printf(TRACE "forked child %d\n", lwpinfo.pl_child_pid); return (lwpinfo.pl_child_pid); } return (0); }
int main(int argc, char *argv[]) { struct ptrace_lwpinfo lwpinfo; int c, status, use_vfork; pid_t pid, pid1; trace_syscalls = 1; use_vfork = 0; while ((c = getopt(argc, argv, "csv")) != -1) { switch (c) { case 'c': trace_syscalls = 0; break; case 's': trace_syscalls = 1; break; case 'v': use_vfork = 1; break; default: case '?': fprintf(stderr, "Usage: %s [-c] [-s] [-v]\n", argv[0]); return (2); } } if ((pid = fork()) < 0) { perror("fork"); return 1; } else if (pid == 0) { if (ptrace(PT_TRACE_ME, 0, NULL, 0) < 0) { perror("PT_TRACE_ME"); _exit(1); } kill(getpid(), SIGSTOP); getpid(); if ((pid1 = use_vfork ? vfork() : fork()) < 0) { perror("fork1"); return (1); } else if (pid1 == 0) { printf("Hi from child %d\n", getpid()); execl("/bin/ls", "ls", "/", (char *)NULL); } } else { /* parent */ if (waitpid(pid, &status, 0) == -1) { perror("waitpid"); return (-1); } assert(WIFSTOPPED(status)); assert(WSTOPSIG(status) == SIGSTOP); if (ptrace(PT_LWPINFO, pid, (caddr_t)&lwpinfo, sizeof(lwpinfo)) < 0) { perror("PT_LWPINFO"); ptrace(PT_KILL, pid, NULL, 0); return (-1); } wait_info(pid, status, &lwpinfo); if (ptrace(PT_FOLLOW_FORK, pid, 0, 1) < 0) { perror("PT_FOLLOW_FORK"); ptrace(PT_KILL, pid, NULL, 0); return (2); } while ((pid1 = trace(pid)) >= 0) { if (pid1 != 0) { printf(TRACE "attached to pid %d\n", pid1); #if 0 kill(pid1, SIGCONT); #endif if (waitpid(pid1, &status, 0) == -1) { perror("waitpid"); return (-1); } printf(TRACE "nested loop, pid %d status %s\n", pid1, decode_wait_status(status)); assert(WIFSTOPPED(status)); assert(WSTOPSIG(status) == SIGSTOP); if (ptrace(PT_LWPINFO, pid1, (caddr_t)&lwpinfo, sizeof(lwpinfo)) < 0) { perror("PT_LWPINFO"); ptrace(PT_KILL, pid1, NULL, 0); return (-1); } wait_info(pid1, status, &lwpinfo); while (trace(pid1) >= 0) ; } } ptrace(PT_CONTINUE, pid, (caddr_t)1, 0); } return (0); }