#include #include #include #include #include #include #include #include #include #include #include #include void set_bit(uint8_t *bits, unsigned long index) { bits[index / 8] |= (1 << (7 - index % 8)); } void clear_bit(uint8_t *bits, unsigned long index) { bits[index / 8] &= ~(1 << (7 - index % 8)); } int has_bit(const uint8_t *bits, unsigned long index) { return bits[index / 8] & (1 << (7 - index % 8)); } int set_nonblocking(int fd) { int oflags; if ((oflags = fcntl(fd, F_GETFL, 0)) == -1) return errno; if (fcntl(fd, F_SETFL, oflags | O_NONBLOCK) == -1) return errno; return 0; } int set_blocking(int fd) { int oflags; if ((oflags = fcntl(fd, F_GETFL, 0)) == -1) return errno; if (fcntl(fd, F_SETFL, oflags & ~O_NONBLOCK) == -1) return errno; return 0; } int mkdirs(char *path) { int err = 0; char *spos = strchr(path + 1, '/'); // Must ignore the root while (spos != NULL) { *spos = '\0'; err = mkdir(path, 0777); *spos = '/'; if (err != 0 && errno != EEXIST) { err = errno; break; } spos = strchr(spos + 1, '/'); } return err; } int vopen(int *res, int flags, const char *fmt, ...) { int fd, didmkdirs; char path[PATH_MAX + 1]; va_list ap; va_start(ap, fmt); if (vsnprintf(path, PATH_MAX, fmt, ap) >= PATH_MAX) { va_end(ap); return ENAMETOOLONG; } va_end(ap); didmkdirs = 0; again: fd = open(path, flags, 0666); if (fd < 0 && errno == ENOENT && (flags & O_CREAT) != 0 && !didmkdirs) { if (mkdirs(path) == 0) { didmkdirs = 1; goto again; } else return errno; } if (fd >= 0) { *res = fd; return 0; } else return errno; } int canon_path(const char *path, char **res) { char rp[PATH_MAX]; if (realpath(path, rp) == NULL) return errno; #if 0 // This could be necessary on solaris. if (rp[0] != '/') { char wd[MAXPATHLEN]; if (getcwd(wd, MAXPATHLEN) == NULL) return errno; if (strlcat(wd, "/", MAXPATHLEN) >= MAXPATHLEN) return ENAMETOOLONG; if (strlcat(wd, rp, MAXPATHLEN) >= MAXPATHLEN) return ENAMETOOLONG; strcpy(rp, wd); } #endif if ((*res = strdup(rp)) == NULL) return ENOMEM; return 0; } long rand_between(long min, long max) { return min + (long)rint((double)random() * (max - min) / RAND_MAX); }