Я начинаю с нуля, пытаясь использовать dup()
, я написал программу для проверки этой функции, результат немного отличается от того, что я ожидал.dup() и cache flush
Код:
// unistd.h, dup() test
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
extern void dup_test();
int main() {
dup_test();
}
// dup()test
void dup_test() {
// open a file
FILE *f = fopen("/tmp/a.txt", "w+");
int fd = fileno(f);
printf("original file descriptor:\t%d\n",fd);
// duplicate file descriptor of an opened file,
int fd_dup = dup(fd);
printf("duplicated file descriptor:\t%d\n",fd_dup);
FILE *f_dup = fdopen(fd_dup, "w+");
// write to file, use the duplicated file descriptor,
fputs("hello\n", f_dup);
fflush(f_dup);
// close duplicated file descriptor,
fclose(f_dup);
close(fd_dup);
// allocate memory
int maxSize = 1024; // 1 kb
char *buf = malloc(maxSize);
// move to beginning of file,
rewind(f);
// read from file, use the original file descriptor,
fgets(buf, maxSize, f);
printf("%s", buf);
// close original file descriptor,
fclose(f);
// free memory
free(buf);
}
Программа попробуйте написать с помощью дублированного дескриптора, затем закройте дублированный ФО, а затем попытаться прочитать с помощью оригинального дескриптора.
Я ожидал, что когда я закрою дублированный fd, кеш-ке будет автоматически очищен, но это не так, если я удалю функцию fflush()
в коде, исходный fd не сможет прочитать содержимое, написанное дублированный fd, который уже закрыт.
Мой вопрос:
ли это означает, что, когда близко дублируется FD, он не будет делать вровень автоматически?
@Edit:
Я извиняюсь, моя ошибка, я нашел причину, в моей первоначальной программе есть:
close(fd_dup);
, но не имеют:
fclose(f_dup);
после использования fclose(f_dup);
на замену close(f_dup);
оно работает.
Таким образом, дублируется FD делать автоматически вровень, если близко надлежащим образом, write()
& close()
пара, fwrite()
& fclose()
пара, не следует смешивать их.
На самом деле, в коде я мог бы использовать дублированный fd_dup непосредственно write()
& close()
, и нет необходимости создавать новый FILE
вообще.
Таким образом, код может быть просто:
// unistd.h, dup() test
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#define BUF_SIZE 1024 // 1 kb
extern void dup_test();
int main() {
dup_test();
}
// dup()test
void dup_test() {
// open a file
FILE *f = fopen("/tmp/a.txt", "w+");
int fd = fileno(f);
printf("original file descriptor:\t%d\n",fd);
// duplicate file descriptor of an opened file,
int fd_dup = dup(fd);
printf("duplicated file descriptor:\t%d\n",fd_dup);
// write to file, use the duplicated file descriptor,
write(fd_dup, "hello\n", BUF_SIZE);
// close duplicated file descriptor,
close(fd_dup);
// allocate memory
char *buf = malloc(BUF_SIZE);
// move to beginning of file,
rewind(f);
// read from file, use the original file descriptor,
fgets(buf, BUF_SIZE, f);
printf("%s", buf);
// close original file descriptor,
fclose(f);
// free memory
free(buf);
}
Возможно, вы захотите «отцепить» свою программу, чтобы проверить, какие именно системные вызовы она на самом деле делает. В моей системе ваша программа всегда печатает «привет». Я думаю, что может произойти, что 'f_dup' очищается, но' f' делает вид вашего файла до этого (на 'fopen'). – zch
, так как у вас есть 'fdopen' ваш' fd', объект, в котором вы должны работать, это 'FILE *'. они по сути то же самое, не закрывайте одно и то же дважды. и вы немного сбиты с толку о 'FILE *' и 'int', который должен быть' fd'. 'FILE *' является файловым потоком, это стандартное представление, поэтому оно является кросс-платформенным. 'fd' - фактически' int', индексный номер таблицы дескриптора файла, это функция * nix-системы. – HuStmpHrrr
@zch Thx, strace - отличный инструмент! –