| 43 | #define STAT_PARENT_PID_READ_N 64 |
| 44 | |
| 45 | static int parse_proc_stat(struct strbuf *sb, struct strbuf *name, |
| 46 | int *statppid) |
| 47 | { |
| 48 | const char *comm_lhs = strchr(sb->buf, '('); |
| 49 | const char *comm_rhs = strrchr(sb->buf, ')'); |
| 50 | const char *ppid_lhs, *ppid_rhs; |
| 51 | char *p; |
| 52 | pid_t ppid; |
| 53 | |
| 54 | if (!comm_lhs || !comm_rhs) |
| 55 | goto bad_kernel; |
| 56 | |
| 57 | /* |
| 58 | * We're at the ")", that's followed by " X ", where X is a |
| 59 | * single "state" character. So advance by 4 bytes. |
| 60 | */ |
| 61 | ppid_lhs = comm_rhs + 4; |
| 62 | |
| 63 | /* |
| 64 | * Read until the space between the "ppid" and "pgrp" fields |
| 65 | * to make sure we're anchored after the untruncated "ppid" |
| 66 | * field.. |
| 67 | */ |
| 68 | ppid_rhs = strchr(ppid_lhs, ' '); |
| 69 | if (!ppid_rhs) |
| 70 | goto bad_kernel; |
| 71 | |
| 72 | ppid = strtol(ppid_lhs, &p, 10); |
| 73 | if (ppid_rhs == p) { |
| 74 | const char *comm = comm_lhs + 1; |
| 75 | size_t commlen = comm_rhs - comm; |
| 76 | |
| 77 | strbuf_add(name, comm, commlen); |
| 78 | *statppid = ppid; |
| 79 | |
| 80 | return 0; |
| 81 | } |
| 82 | |
| 83 | bad_kernel: |
| 84 | /* |
| 85 | * We were able to read our STAT_PARENT_PID_READ_N bytes from |
| 86 | * /proc/%d/stat, but the content is bad. Broken kernel? |
| 87 | * Should not happen, but handle it gracefully. |
| 88 | */ |
| 89 | return -1; |
| 90 | } |
| 91 | |
| 92 | static int stat_parent_pid(pid_t pid, struct strbuf *name, int *statppid) |
| 93 | { |
no test coverage detected