int main(int argc, char *argv[]) { bus_t bus; int i; if (argc < 2) return fprintf(stderr, "USAGE: %s daemon...", *argv), 2; t(bus_open(&bus, getenv("BUS_INIT"), BUS_WRONLY)); for (i = 1; i < argc; i++) { sprintf(arg, "grep '^%s$' < \"${XDG_RUNTIME_DIR}/started-daemons\" >/dev/null", argv[i]); if (WEXITSTATUS(system(arg))) { sprintf(arg, "%ji require %s", (intmax_t)getppid(), argv[i]); t(bus_write(&bus, arg, 0)); } } bus_close(&bus); return 0; fail: perror("require"); bus_close(&bus); return 1; }
/** * Change the permissions for a bus * * `stat(2)` can be used of the bus's associated file to get the bus's permissions * * @param file The pathname of the bus * @param mode The permissions of the bus, any permission for a user implies * full permissions for that user, except only the owner may * edit the bus's associated file * @return 0 on success, -1 on error */ int bus_chmod(const char *file, mode_t mode) { bus_t bus; mode_t fmode; struct semid_ds sem_stat; struct shmid_ds shm_stat; int shm_id; mode = (mode & S_IRWXU) ? (mode | S_IRWXU) : (mode & ~S_IRWXU); mode = (mode & S_IRWXG) ? (mode | S_IRWXG) : (mode & ~S_IRWXG); mode = (mode & S_IRWXO) ? (mode | S_IRWXO) : (mode & ~S_IRWXO); mode &= (S_IWUSR | S_IWGRP | S_IWOTH | S_IRUSR | S_IRGRP | S_IROTH); fmode = mode & ~(S_IWGRP | S_IWOTH); t(bus_open(&bus, file, -1)); t(chmod(file, fmode)); /* chmod sem */ t(open_semaphores(&bus)); t(semctl(bus.sem_id, 0, IPC_STAT, &sem_stat)); sem_stat.sem_perm.mode = mode; t(semctl(bus.sem_id, 0, IPC_SET, &sem_stat)); /* chmod shm */ t(shm_id = shmget(bus.key_shm, (size_t)BUS_MEMORY_SIZE, 0)); t(shmctl(shm_id, IPC_STAT, &shm_stat)); shm_stat.shm_perm.mode = mode; t(shmctl(shm_id, IPC_SET, &shm_stat)); return 0; fail: return -1; }
/** * Change the ownership of a bus * * `stat(2)` can be used of the bus's associated file to get the bus's ownership * * @param file The pathname of the bus * @param owner The user ID of the bus's new owner * @param group The group ID of the bus's new group * @return 0 on success, -1 on error */ int bus_chown(const char *file, uid_t owner, gid_t group) { bus_t bus; struct semid_ds sem_stat; struct shmid_ds shm_stat; int shm_id; t(bus_open(&bus, file, -1)); t(chown(file, owner, group)); /* chown sem */ t(open_semaphores(&bus)); t(semctl(bus.sem_id, 0, IPC_STAT, &sem_stat)); sem_stat.sem_perm.uid = owner; sem_stat.sem_perm.gid = group; t(semctl(bus.sem_id, 0, IPC_SET, &sem_stat)); /* chown shm */ t(shm_id = shmget(bus.key_shm, (size_t)BUS_MEMORY_SIZE, 0)); t(shmctl(shm_id, IPC_STAT, &shm_stat)); shm_stat.shm_perm.uid = owner; shm_stat.shm_perm.gid = group; t(shmctl(shm_id, IPC_SET, &shm_stat)); return 0; fail: return -1; }
int main(int argc, char *argv[]) { bus_t bus; if (argc < 3) return fprintf(stderr, "USAGE: %s state daemon", *argv), 2; t(bus_open(&bus, getenv("BUS_INIT"), BUS_WRONLY)); sprintf(arg, "%ji %s %s", (intmax_t)getppid(), argv[1], argv[2]); t(bus_write(&bus, arg)); t(bus_close(&bus)); return 0; fail: perror("announce"); return 1; }
static void announce_wait(pid_t pid) { bus_t bus; int i; t(bus_open(&bus, getenv("BUS_INIT"), BUS_WRONLY)); for (i = 1; i < argc; i++) { if (!started[i]) { sprintf(arg, "%ji awaiting-started %s", (intmax_t)pid, argv[i]); t(bus_write(&bus, arg, 0)); } } t(bus_close(&bus)); return; fail: perror("await-started"); }
int main() { bus_t bus; struct timespec timeout; t(bus_open(&bus, "/tmp/example-bus", BUS_RDONLY)); t(clock_gettime(CLOCK_MONOTONIC, &timeout)); timeout.tv_sec += 10; t(bus_read_timed(&bus, callback, NULL, &timeout, CLOCK_MONOTONIC)); bus_close(&bus); return 0; fail: perror("poll"); bus_poll_stop(&bus); bus_close(&bus); return 1; }
int main(int argc_, char *argv_[]) { bus_t bus; int i; argc = argc_; argv = argv_; if (argc < 2) return fprintf(stderr, "USAGE: %s daemon...", *argv), 2; t(bus_open(&bus, getenv("BUS_INIT"), BUS_RDONLY)); started = calloc(argc, sizeof(char)); t(started == NULL); started[0] = 1; for (i = 1; i < argc; i++) { sprintf(arg, "grep '^%s$' < \"${XDG_RUNTIME_DIR}/started-daemons\" >/dev/null", argv[i]); if (!WEXITSTATUS(system(arg))) { started[i] = 1; } else { sprintf(arg, "grep '^%s$' < \"${XDG_RUNTIME_DIR}/ready-daemons\" >/dev/null", argv[i]); if (!WEXITSTATUS(system(arg))) started[i] = 1; else remaining++; } } if (remaining) bus_read(&bus, callback, NULL); bus_close(&bus); free(started); return 0; fail: perror("await-started"); bus_close(&bus); free(started); return 1; }
/** * Remove a bus * * @param file The pathname of the bus * @return 0 on success, -1 on error */ int bus_unlink(const char *file) { int r = 0, saved_errno = 0; bus_t bus; t(bus_open(&bus, file, -1)); r |= remove_semaphores(&bus); if (r && !saved_errno) saved_errno = errno; r |= remove_shared_memory(&bus); if (r && !saved_errno) saved_errno = errno; r |= unlink(file); if (r && !saved_errno) saved_errno = errno; errno = saved_errno; return r; fail: return -1; }