#define _GNU_SOURCE // for ucred #include #include #include #include void print_exe_path(pid_t pid) { char link_path[512]; snprintf(link_path, sizeof(link_path), "/proc/%d/exe", pid); char exe_path[512]; ssize_t exe_path_len = readlink(link_path, exe_path, sizeof(exe_path) - 1); if (exe_path_len < 0) { perror("readlink"); return; } exe_path[exe_path_len] = '\0'; printf("%d: path=%s\n", pid, exe_path); } int main(int argc, char *argv[]) { int sfd = socket(AF_UNIX, SOCK_STREAM, 0); if (sfd < 0) { perror("socket"); return 1; } struct sockaddr_un addr = { .sun_family = AF_UNIX, .sun_path = "socket", }; if (bind(sfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("bind"); return 1; } if (listen(sfd, 32) < 0) { perror("listen"); return 1; } while (1) { int cfd = accept(sfd, NULL, NULL); if (cfd < 0) { perror("accept"); return 1; } printf("client connected\n"); struct ucred peer_ucred; socklen_t ucred_size = sizeof(struct ucred); if (getsockopt(cfd, SOL_SOCKET, SO_PEERCRED, &peer_ucred, &ucred_size) < 0) { perror("getsockopt(SO_PEERCRED)"); goto next; } printf("SO_PEERCRED: pid=%d\n", peer_ucred.pid); int data; ssize_t n = read(cfd, &data, sizeof(data)); if (n < 0) { perror("read"); goto next; } else if (n == 0) { fprintf(stderr, "read returned 0\n"); goto next; } print_exe_path(peer_ucred.pid); next: close(cfd); } return 0; }