| 1816 | |
| 1817 | |
| 1818 | #if defined(OSDarwin) |
| 1819 | #include <sys/sysctl.h> |
| 1820 | int |
| 1821 | pid_is_user(pid_t pid, uid_t uid) |
| 1822 | { |
| 1823 | int mib[4]; |
| 1824 | size_t size; |
| 1825 | struct kinfo_proc ki; |
| 1826 | |
| 1827 | size = sizeof(ki); |
| 1828 | mib[0] = CTL_KERN; |
| 1829 | mib[1] = KERN_PROC; |
| 1830 | mib[2] = KERN_PROC_PID; |
| 1831 | mib[3] = pid; |
| 1832 | if (sysctl(mib, 4, &ki, &size, NULL, 0) < 0) |
| 1833 | errx(1, "%s", "Failure calling sysctl"); |
| 1834 | return (uid == ki.kp_eproc.e_pcred.p_ruid); |
| 1835 | } |
| 1836 | |
| 1837 | static int |
| 1838 | pid_is_cmd(pid_t pid, const char *name) |
| 1839 | { |
| 1840 | int mib[4]; |
| 1841 | size_t size; |
| 1842 | struct kinfo_proc ki; |
| 1843 | |
| 1844 | size = sizeof(ki); |
| 1845 | mib[0] = CTL_KERN; |
| 1846 | mib[1] = KERN_PROC; |
| 1847 | mib[2] = KERN_PROC_PID; |
| 1848 | mib[3] = pid; |
| 1849 | if (sysctl(mib, 4, &ki, &size, NULL, 0) < 0) |
| 1850 | errx(1, "%s", "Failure calling sysctl"); |
| 1851 | return (!strncmp(name, ki.kp_proc.p_comm, MAXCOMLEN)); |
| 1852 | } |
| 1853 | |
| 1854 | static void |
| 1855 | do_procinit(void) |
| 1856 | { |
| 1857 | int mib[3]; |
| 1858 | size_t size; |
| 1859 | int nprocs, ret, i; |
| 1860 | struct kinfo_proc *procs = NULL, *newprocs; |
| 1861 | |
| 1862 | mib[0] = CTL_KERN; |
| 1863 | mib[1] = KERN_PROC; |
| 1864 | mib[2] = KERN_PROC_ALL; |
| 1865 | ret = sysctl(mib, 3, NULL, &size, NULL, 0); |
| 1866 | /* Allocate enough memory for entire process table */ |
| 1867 | do { |
| 1868 | size += size / 10; |
| 1869 | newprocs = realloc(procs, size); |
| 1870 | if (newprocs == NULL) { |
| 1871 | if (procs) |
| 1872 | free(procs); |
| 1873 | errx(1, "%s", "Could not reallocate memory"); |
| 1874 | } |
| 1875 | procs = newprocs; |
| 1876 | ret = sysctl(mib, 3, procs, &size, NULL, 0); |
| 1877 | } while (ret >= 0 && errno == ENOMEM); |
| 1878 | |
| 1879 | if (ret < 0) |
| 1880 | errx(1, "%s", "Failure calling sysctl"); |
| 1881 | |
| 1882 | /* Verify size of proc structure */ |
| 1883 | if (size % sizeof(struct kinfo_proc) != 0) |
| 1884 | errx(1, "%s", "proc size mismatch, userland out of sync with kernel"); |
| 1885 | nprocs = size / sizeof(struct kinfo_proc); |
| 1886 | for (i = 0; i < nprocs; i++) { |
| 1887 | check(procs[i].kp_proc.p_pid); |
| 1888 | } |
| 1889 | } |
| 1890 | #endif /* OSDarwin */ |