фкнтл не работает

I have a small program that tires to change the files access mode after it has been opened.


int main(int argc, char* argv[])
{
    int fd;
    char *filename = argv[1];
    char data[1];
    int curval;                         //current flag value
    int newval;                         //new flag value

fd = open(filename, O_RDONLY);

while(read(fd, data, 1)>0)
{
    write(STDOUT_FILENO, data, 1);
}

lseek(fd, 0, SEEK_SET);

if((curval = fcntl(fd, F_GETFL, 0))<0)              
{
    perror("file flag get failed");
}

printf("%d\n", curval); newval = curval | O_WRONLY | O_APPEND; printf("%d\n", newval);

    if(fcntl(fd, F_SETFL, newval)<0)
{
    perror("file flag set failed");
}

if(write(fd, argv[2], strlen(argv[2]))<0)   //appending more data to the file
{
    perror("write failed");
    }

lseek(fd, 0, SEEK_SET);

while(read(fd, data, 1)>0)
{
    write(STDOUT_FILENO, data, 1);
}
close (fd);
return 0;

}

Вот вывод, когда я запускаю эту программу с текстовым файлом в качестве входных данных.

$ cat input
this is the inital data
$ ./a.out input newdata
this is the inital data
0
1025
write failed: Bad file descriptor
this is the inital data

Почему запись в программе не работает? Также я не могу найти, где определены константы флага состояния файла. Я проверил в usr/include/


person John    schedule 23.02.2011    source источник


Ответы (2)


Поведение, которое вы пытаетесь выполнить, недопустимо. На справочной странице fcntl(2):

   F_SETFL (long)
         Set  the  file status flags to the value specified by arg.  File
         access mode (O_RDONLY, O_WRONLY, O_RDWR) and file creation flags
         (i.e.,  O_CREAT,  O_EXCL, O_NOCTTY, O_TRUNC) in arg are ignored.
         On Linux this command can only  change  the  O_APPEND,  O_ASYNC,
         O_DIRECT, O_NOATIME, and O_NONBLOCK flags.
person Conrad Meyer    schedule 23.02.2011
comment
Итак, остальные флаги используются только для получения статуса файла? - person John; 23.02.2011

Если вы читаете справочную страницу Linux, вы увидите, что fcntl не может изменять режимы доступа к файлам (например, с чтения только на чтение-запись).

person zvrba    schedule 23.02.2011
comment
Ой. Есть ли способ сделать это? - person John; 23.02.2011
comment
Закройте файл и откройте его с новыми флагами. (На самом деле вам даже не нужно закрывать его, просто откройте его снова и используйте другой файловый дескриптор). - person zvrba; 23.02.2011
comment
да я это сделал. И это работает. Но последний цикл while, который снова выводит файл на стандартный вывод, не работает. - person John; 25.02.2011
comment
@John: zvrba означает, что у вас должно быть два файловых дескриптора, readfd и writefd (или fd1 и fd2 или что-то еще). Ваш последний цикл while должен использовать readfd, а не fd, который вы получили от второго вызова open. - person Mikel; 01.03.2011
comment
кривая = fcntl(fd, F_GETFL, 0); новыйвал = криволинейный | O_WRONLY | О_ПРИЛОЖЕНИЕEND; - person John; 01.03.2011
comment
это все, что я делаю. И после первого чтения я закрываю fd, а затем снова открываю новый fd в том же файле с newval. Тем не менее, он не печатает цикл отправки. - person John; 01.03.2011