13 static void *find_map(int fd)
19 unsigned long long off, ino;
22 if (fstat(fd, &st) < 0) return 0;
23 if (!(f = fopen("/proc/self/maps", "rb"))) return 0;
25 while (fgets(buf, sizeof buf, f)) {
26 sscanf(buf, "%lx-%*lx %*s %llx %*x:%*x %llu /dev/shm%c",
27 (long *)&addr, &off, &ino, &c);
28 while (!strchr(buf, '\n') && fgets(buf, sizeof buf, f));
31 if (!off && st.st_ino == ino) {
40 sem_t *sem_open(const char *name, int flags, ...)
51 while (*name=='/') name++;
52 if (strchr(name, '/')) {
57 if (flags & O_CREAT) {
59 mode = va_arg(ap, mode_t) & 0666;
60 value = va_arg(ap, unsigned);
62 if (value > SEM_VALUE_MAX) {
66 sem_init(&newsem, 0, value);
67 clock_gettime(CLOCK_REALTIME, &ts);
68 snprintf(tmp, sizeof(tmp), "/dev/shm/%p-%p-%d-%d",
69 &name, name, (int)getpid(), (int)ts.tv_nsec);
70 tfd = open(tmp, O_CREAT|O_EXCL|O_RDWR, mode);
71 if (tfd<0) return SEM_FAILED;
72 dir = open("/dev/shm", O_DIRECTORY|O_RDONLY);
73 if (dir<0 || write(tfd,&newsem,sizeof newsem)!=sizeof newsem) {
74 if (dir >= 0) close(dir);
85 if (!(flags & O_EXCL)) {
86 fd = shm_open(name, flags&~O_CREAT, mode);
87 if (fd >= 0 || errno != ENOENT) {
88 if (flags & O_CREAT) {
93 if (fd < 0) return SEM_FAILED;
94 if ((map = find_map(fd)))
99 if (!linkat(AT_FDCWD, tmp, dir, name, 0)) {
105 if ((flags & O_EXCL) || errno != EEXIST) {
112 map = mmap(0, sizeof(sem_t), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
114 if (map == MAP_FAILED) return SEM_FAILED;