#include #include #include #include #include #include #include #include #include void usage(char *progname) { fprintf(stderr, "usage: %s [-s] [filename]\n", progname); exit(EXIT_FAILURE); } typedef enum { false, true, FALSE = 0, TRUE = 1 } bool; int main(int argc, char *argv[]) { int fd; char *filename = "shared.txt"; bool done; short lmode = F_WRLCK; struct stat st; char line[128]; int fsize; int offset; int length; struct flock fl; // get filename and locking options if ( argc == 2 ) { if ( strcmp("-s", argv[1]) == 0 ) { lmode = F_RDLCK; } else { filename = argv[1]; } } else if ( argc == 3 ) { if ( strcmp("-s", argv[1]) == 0 ) { lmode = F_RDLCK; filename = argv[2]; } else if ( strcmp("-s", argv[2]) == 0 ) { lmode = F_RDLCK; filename = argv[1]; } else { usage(argv[0]); } } else if ( argc > 3 ) { usage(argv[0]); } // open file fd = open(filename, O_RDWR); if ( fd < 0 ) { fprintf(stderr, "Could not open file %s\n", filename); exit(EXIT_FAILURE); } // get stats fstat(fd, &st); fsize = (int) st.st_size; // ask user where to start the range locking done = false; while ( ! done ) { fprintf(stdout, "Enter start offset for range locking: "); fflush(stdout); fgets(line, sizeof(line), stdin); offset = atoi(line); if ( offset < 0 ) { fprintf(stdout, "Enter a valid integer larger than or equal to 0.\n"); fflush(stdout); } else { done = TRUE; } } done = false; while ( ! done ) { fprintf(stdout, "Enter start length: "); fflush(stdout); fgets(line, sizeof(line), stdin); length = atoi(line); if ( length < 1 ) { fprintf(stdout, "Enter a valid integer larger than 0.\n"); fflush(stdout); } else { done = true; } } fl.l_type = lmode; fl.l_start = offset; fl.l_whence = SEEK_SET; fl.l_len = length; errno = 0; fprintf(stdout, "trying to lock %s (%s)\n", filename, lmode == F_WRLCK ? "write" : "read"); fcntl(fd, F_SETLKW, &fl); fprintf(stdout, "successfully locked %s (%d, %d)\n", filename, offset, offset+length); while ( 1 ) { sleep(1); } }