@EDIT Looks like fread function reads more characters than record_size parameter ;x
I've got 2 functions which sort file(bubble sort) by records(key is first character). The first one is using system functions(read, write, etc.) and secong is using library functions(fread, fwrite, etc.). For small record_size parameter both works well but e.g for record_size = 5000 only sys_sort works properly. File sorted by lib_sort has less lines and different lengths. Why? I don't know what is the problem.
void lib_sort(const char *filename, long long int record_size, long long int num_of_lines) {
    record_size++;  // '\n' char at the end of line
    FILE *file;
    if (!(file = fopen(filename, "r+"))) {
        printf("Cannot open %s file.\n", filename);
        fclose(file);
        exit(EXIT_FAILURE);
    }
    char *buffer1 = malloc(sizeof(char) * record_size);
    char *buffer2 = malloc(sizeof(char) * record_size);
    bool flag = true;
    while (flag) {
        flag = false;
        if(fseek(file, 0, SEEK_SET) != 0) {
            printf("fseek failed.\n");
        }
        if((fread(buffer1, sizeof(char), (size_t) record_size, file)) != record_size) {
            printf("fread failed.\n");
        }
        for (int i = 1; i < num_of_lines; ++i) {
            if((fread(buffer2, sizeof(char), (size_t) record_size, file)) != record_size) {
                printf("fread failed.\n");
            }
            if (buffer1[0] > buffer2[0]) {
                if(fseek(file, record_size * (-2), SEEK_CUR) != 0) {
                    printf("fseek failed.\n");
                }
                if((fwrite(buffer2, sizeof(char), (size_t) record_size, file)) != record_size) {
                    printf("fwrite failed.\n");
                }
                if((fwrite(buffer1, sizeof(char), (size_t) record_size, file)) != record_size) {
                    printf("write failed.\n");
                }
                flag = true;
            } else {
                char *tmp = buffer2;
                buffer2 = buffer1;
                buffer1 = tmp;
            }
        }
        num_of_lines--;
    }
    fclose(file);
    free(buffer1);
    free(buffer2);
}
And this is the correct one:
void sys_sort(const char *filename, long long int record_size, long long int num_of_records) {
    record_size++;  // '\n' char at the end of line
    int file;
    if ((file = open(filename, O_RDWR)) < 0) {
        printf("Cannot open %s file.\n", filename);
        close(file);
        exit(EXIT_FAILURE);
    }
    char *buffer1 = malloc(sizeof(char) * record_size);
    char *buffer2 = malloc(sizeof(char) * record_size);
    bool flag = true;
    while (flag) {
        flag = false;
        lseek(file, 0, SEEK_SET);
        read(file, buffer1, (size_t) record_size);
        for (int i = 1; i < num_of_records; ++i) {
            read(file, buffer2, (size_t) record_size);
            if (buffer1[0] > buffer2[0]) {
                lseek(file, record_size * (-2), SEEK_CUR);
                write(file, buffer2, (size_t) record_size);
                write(file, buffer1, (size_t) record_size);
                flag = true;
            } else {
                char *tmp = buffer2;
                buffer2 = buffer1;
                buffer1 = tmp;
            }
        }
        num_of_records--;
    }
    close(file);
    free(buffer1);
    free(buffer2);
}
I use ubuntu 16.04 and standard C99
 
     
    