+static int time_and_pid_from_socket_name(char *sock_name, unsigned long *time,
+ pid_t *pid)
+{
+ char *saveptr, *pid_m_time_str;
+ char *sock_basename = strdup(basename(sock_name));
+
+ if (!sock_basename) {
+ return -1;
+ }
+
+ /* This is the pid */
+ pid_m_time_str = strtok_r(sock_basename, ".", &saveptr);
+ if (!pid_m_time_str) {
+ goto out_err;
+ }
+
+ errno = 0;
+ *pid = (pid_t)strtoul(pid_m_time_str, NULL, 10);
+ if (errno) {
+ goto out_err;
+ }
+
+ /* This should be the time-stamp */
+ pid_m_time_str = strtok_r(NULL, ".", &saveptr);
+ if (!pid_m_time_str) {
+ goto out_err;
+ }
+
+ errno = 0;
+ *time = strtoul(pid_m_time_str, NULL, 10);
+ if (errno) {
+ goto out_err;
+ }
+
+ return 0;
+
+out_err:
+ free(sock_basename);
+ return -1;
+}
+
+time_t ustcomm_pid_st_mtime(pid_t pid)
+{
+ struct stat proc_stat;
+ char proc_name[PATH_MAX];
+
+ if (snprintf(proc_name, PATH_MAX - 1, "/proc/%ld", (long) pid) < 0) {
+ return 0;
+ }
+
+ if (stat(proc_name, &proc_stat)) {
+ return 0;
+ }
+
+ return proc_stat.st_mtime;
+}
+
+int ustcomm_is_socket_live(char *sock_name, pid_t *read_pid)
+{
+ time_t time_from_pid;
+ unsigned long time_from_sock;
+ pid_t pid;
+
+ if (time_and_pid_from_socket_name(sock_name, &time_from_sock, &pid)) {
+ return 0;
+ }
+
+ if (read_pid) {
+ *read_pid = pid;
+ }
+
+ time_from_pid = ustcomm_pid_st_mtime(pid);
+ if (!time_from_pid) {
+ return 0;
+ }
+
+ if ((unsigned long) time_from_pid == time_from_sock) {
+ return 1;
+ }
+
+ return 0;
+}
+
+#define MAX_SOCK_PATH_BASE_LEN 100
+
+static int ustcomm_get_sock_name(char *dir_name, pid_t pid, char *sock_name)
+{
+ struct dirent *dirent;
+ char sock_path_base[MAX_SOCK_PATH_BASE_LEN];
+ int len;
+ DIR *dir = opendir(dir_name);
+
+ snprintf(sock_path_base, MAX_SOCK_PATH_BASE_LEN - 1,
+ "%ld.", (long) pid);
+ len = strlen(sock_path_base);
+
+ while ((dirent = readdir(dir))) {
+ if (!strcmp(dirent->d_name, ".") ||
+ !strcmp(dirent->d_name, "..") ||
+ !strcmp(dirent->d_name, "ust-consumer") ||
+ dirent->d_type == DT_DIR ||
+ strncmp(dirent->d_name, sock_path_base, len)) {
+ continue;
+ }
+
+ if (ustcomm_is_socket_live(dirent->d_name, NULL)) {
+ if (snprintf(sock_name, PATH_MAX - 1, "%s/%s",
+ dir_name, dirent->d_name) < 0) {
+ PERROR("path longer than PATH_MAX?");
+ goto out_err;
+ }
+ closedir(dir);
+ return 0;
+ }
+ }
+
+out_err:
+ closedir(dir);
+ return -1;
+}
+