|
- #include <sys/types.h>
- #include <sys/stat.h>
-
- #include <errno.h>
- #include <fcntl.h>
- #include <inttypes.h>
- #include <limits.h>
- #include <stdarg.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
-
- 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(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;
- }
-
- size_t
- round_to_page(size_t size)
- {
- size_t psize = getpagesize();
- size_t rem = size % psize;
- if (rem != 0)
- size += psize - rem;
- return size;
- }
|