int bee_flock(char *filename, int operation, int flags) { int res; int fd, fd2; struct stat statbuf_pre, statbuf_post; fd = open_and_stat(filename, O_RDONLY|O_CREAT|O_NOCTTY, 0666, &statbuf_pre); if (fd < 0) return -1; while (1) { res = bee_flock_fd(fd, operation, 0); if (res < 0) return -1; fd2 = open_and_stat(filename, O_RDONLY|O_CREAT|O_NOCTTY, 0666, &statbuf_post); if (fd2 < 0) { bee_flock_close(fd); return -1; } if (statbuf_pre.st_ino == statbuf_post.st_ino) { res = close(fd2); if (res < 0) { perror("bee_flock: close"); bee_flock_close(fd); return -1; } return fd; } res = bee_flock_close(fd); if (res < 0) { res = close(fd2); if (res < 0) perror("bee_flock: close"); return -1; } fd = fd2; statbuf_pre = statbuf_post; } return -1; }
int main(int argc, char *argv[]) { int ret; int fd; off_t length; pid_t pid; struct stat prev_stat; if (argc != 3) { printf("usage: %s path <length>\n", argv[0]); exit(EXIT_FAILURE); } fd = open_and_stat(argv[1], &prev_stat); if (fd == -1) exit(EXIT_FAILURE); length = atoi(argv[2]); pid = fork(); if (pid == -1) { perror("fork"); ret = -1; goto exit; } if (pid == 0) { /* child */ ret = testftruncate(fd, length); } else { /* parent */ ret = check_end_child_status(pid); if (ret) goto exit; ret = check_changes(fd, &prev_stat, length); if (ret) goto exit; } exit: close_and_exit(fd, ret); /* never reached */ return 0; }