int main(int argc, char *argv[]) { DIR *dirp; struct dirent *dp; Status *status; Status *previous = NULL; dirp = opendir("/proc/"); while ((dp = readdir(dirp)) != NULL) { if (isNumericString(dp->d_name)) { status = getProcessStatus(atoi(dp->d_name)); if (status != NULL) { insertProcess(previous, status); previous = status; } } } draw(status); freeAll(previous); closedir(dirp); exit(EXIT_SUCCESS); }
static bool hasChildren(int proc_fd, int pid) { bool ret = false; // Open "/proc" int fd = dup(proc_fd); lseek(fd, SEEK_SET, 0); DIR *dir = fd >= 0 ? fdopendir(fd) : NULL; struct dirent de, *res; while (dir && !readdir_r(dir, &de, &res) && res) { // Find numerical entries. Those are processes. if (res->d_name[0] <= '0' || res->d_name[0] > '9') { continue; } // For each process, check the parent's pid int ppid = getProcessStatus(proc_fd, res->d_name, "PPid"); if (ppid == pid) { // We found a child process. We can stop searching, now ret = true; break; } } closedir(dir); return ret; }
int commandClearFlash(uint8_t *buffer) { uint8_t state = getProcessStatus(); if( (state == 1) || (state == 3) ) *buffer = 0x0E; else { EventBits_t flags = xEventGroupGetBits(xEventGroup); if( flags & FLAG_FLASH_CLEARING ) { *buffer++ = 0x0d; //устройство занято *buffer = 0x04; //устройство зянято стиранием памяти return 7; } else { memset((void*)flashMap, 0xff, sizeof(flashMap)); memset((void*)headerList, 0xff, sizeof(headerList)); countProc = 0; spiChipErase(); xEventGroupSetBits(xEventGroup, FLAG_FLASH_CLEARING); //стартуем таймер на 22 сек, после которого state сменим с 4 на 2. xTimerStart(timerClearFlash, 500); } } return 6; }
int main(int argc, char *argv[]) { DIR *proc_dp; DIR *fd_dp; Status *status; struct dirent *pid_dir; struct dirent *fd_dir; char pathname[PATH_MAX] = {0}; char fd_pathname[PATH_MAX] = {0}; char content[CONTENT_MAX] = {0}; if (argc != 2) { usageErr("./program filename\n"); } proc_dp = opendir("/proc/"); while ((pid_dir = readdir(proc_dp)) != NULL) { if (isNumericString(pid_dir->d_name)) { snprintf(pathname, PATH_MAX, "/proc/%s/fd/", pid_dir->d_name); fd_dp = opendir(pathname); if (!fd_dp) { cleanup(NULL, pathname, NULL); continue; } while ((fd_dir = readdir(fd_dp)) != NULL) { snprintf(fd_pathname, PATH_MAX, "/proc/%s/fd/%s", pid_dir->d_name, fd_dir->d_name ); if (readlink(fd_pathname, content, CONTENT_MAX - 1) == -1) { cleanup(NULL, NULL, fd_pathname); continue; } status = getProcessStatus(atoi(pid_dir->d_name)); if (status == NULL) { continue; } if (endswith(content, argv[1])) { printf("%s (%ld)\n", status->comm, (long)status->pid); } free(status); cleanup(content, NULL, fd_pathname); } cleanup(NULL, pathname, NULL); } } closedir(proc_dp); closedir(fd_dp); exit(EXIT_SUCCESS); }
void SystemInitProcess(int init_fd, int child_pid, int proc_fd, int null_fd) { int ret = 0; // CLONE_NEWPID doesn't adjust the contents of the "/proc" file system. // This is very confusing. And it is even possible the kernel developers // will consider this a bug and fix it at some point in the future. // So, to be on the safe side, we explicitly retrieve our process id // from the "/proc" file system. This should continue to work, even if // the kernel eventually gets fixed so that "/proc" shows the view from // inside of the new pid namespace. pid_t init_pid = getProcessStatus(proc_fd, "self", "Pid"); if (init_pid <= 0) { fprintf(stderr, "Failed to determine real process id of new \"init\" process\n"); _exit(1); } // Redirect stdio to /dev/null if (null_fd < 0 || dup2(null_fd, 0) != 0 || dup2(null_fd, 1) != 1 || dup2(null_fd, 2) != 2) { fprintf(stderr, "Failed to point stdio to a safe place\n"); _exit(1); } close(null_fd); // Close all file handles int fds_fd = openat(proc_fd, "self/fd", O_RDONLY | O_DIRECTORY); DIR *dir = fds_fd >= 0 ? fdopendir(fds_fd) : NULL; if (dir == NULL) { // If we don't know the list of our open file handles, just try closing // all valid ones. for (int fd = sysconf(_SC_OPEN_MAX); --fd > 2; ) { if (fd != init_fd && fd != proc_fd) { close(fd); } } } else { // If available, it is much more efficient to just close the file // handles that show up in "/proc/self/fd/" struct dirent de, *res; while (!readdir_r(dir, &de, &res) && res) { if (res->d_name[0] < '0') continue; int fd = atoi(res->d_name); if (fd > 2 && fd != init_fd && fd != proc_fd && fd != dirfd(dir)) { close(fd); } } closedir(dir); } // Set up signal handler to catch SIGCHLD, but mask the signal for now sigset_t mask; sigemptyset(&mask); sigaddset(&mask, SIGCHLD); sigprocmask(SIG_BLOCK, &mask, NULL); // Notify other processes that we are done initializing if (write(init_fd, " ", 1)) { } close(init_fd); // Handle dying processes that have been re-parented to the "init" process for (;;) { bool retry = false; do { for (;;) { // Reap all exit codes of our child processes. This includes both // processes that originally were our immediate children, and processes // that have since been re-parented to be our children. int status; pid_t pid = waitpid(0, &status, __WALL | WNOHANG); if (pid <= 0) { break; } else { // We found some newly deceased child processes. Better schedule // another very thorough inspection of our state. retry = false; } if (pid == child_pid) { // If our first immediate child died, remember its exit code. That's // the exit code that we should be reporting to our parent process if (WIFEXITED(status)) { ret = WEXITSTATUS(status); } else if (WIFSIGNALED(status)) { ret = -WTERMSIG(status); } } } if (hasChildren(proc_fd, init_pid)) { // As long as we still have child processes, continue waiting for // their ultimate demise. retry = false; } else { if (retry) { // No more child processes. We can exit now. if (ret < 0) { // Try to exit with the same signal that our child terminated with signal(-ret, SIG_DFL); kill(1, -ret); ret = 1; } // Exit with the same exit code that our child exited with _exit(ret); } else { // There is a little bit of a race condition between getting // notifications and scanning the "/proc" file system. This is // particularly true, because scanning "/proc" cannot possibly be // an atomic operation. // If we find that we no longer appear to have any children, we check // one more time whether there are any children we can now reap. // They might have died while we were scanning "/proc" and if so, // they should now show up. retry = true; } } } while (retry); // Wait until we receive a SIGCHLD signal. Our signal handler doesn't // actually need to do anything, though sigwaitinfo(&mask, NULL); } }