Дело в том, что компилятор требует, чтобы при указании флага O_CREAT был задан и аргумент mode.
А проблема, конечно, не в правах как таковых. Более подробное описание этой ошибки в errno-base.h.
[quote="Peter"]Дело в том, что компилятор требует, чтобы при указании флага O_CREAT был задан и аргумент mode.
что за бред? Что за компилятор?
"Peter" написал:
0644
говорю же, 0666, а 0644 оно будет после &~UMASK, если UMASK=022.[/quote]
Вчера в Ubuntu-14.04 я запустил вариант автора и компилятор gcc сказал,
что при задании O_CREAT необходим и 3-й аргумент.
Сегодня попробовал в другой системе, фактически это Debian stable,
там 3-й аргумент не требовался, но без него программа не работает с O_TRUNC,
если файл уже существует.
Я не выяснял, какой там umask, но с mode=0644 права у файла тоже 644.
Нет, насколько сейчас помню, все эти три файла были включены.
Код ошибки не помню, а сообщение при запуске программы при уже
существующем файле - Bad file descriptor, но это, кажется,
при вызове write().
Мне нравится писать плотно, чтобы на экране или на листе бумаги
был виден сразу большой кусок. Я и для перфокарт для программ на PL/1
заполнял бланк полностью, а когда стал работать в дисплейном зале,
то написал программу, которая из текста на PL/1 удаляла лишние пробелы
и получался ласкающий глаз прямоугольник. Я там видел ещё одного
человека с такими же распечатками. И вообще компилятору всё равно.
А сейчас, если надо, можно воспользоваться программой indent.
Я составил команду её вызова с дополнительными опциями.
Что такое umask и mode, я конечно, читал. Иногда я явно использую umask.
Вот эта команда для вызова indent, параметр - имя файла в форме name.ext.
[quote="Peter"]Дело в том, что компилятор требует, чтобы при указании флага O_CREAT был задан и аргумент mode.
что за бред? Что за компилятор?
[/quote]
Вот его сообщения при попытке использовать флаг O_CREAT без mode:
[console]
In file included from /usr/include/fcntl.h:279:0,
from ch_wr.c:5:
In function ‘open’,
inlined from ‘main’ at ch_wr.c:10:4:
/usr/include/x86_64-linux-gnu/bits/fcntl2.h:50:24: error: call to ‘__open_missing_mode’ declared with attribute error: open with O_CREAT in second argument needs 3 arguments
__open_missing_mode ();
[/console]
/* use open(2) */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
/* use fprintf(3) */
#include <stdio.h>
/* use close(2) */
#include <unistd.h>
int main()
{
int fd = open("./test", O_CREAT);
if(fd<0)
{
fprintf(stderr, "Can't open file\n");
return 1;
}
close(fd);
return 0;
}
нормально всё собирается в
[console]$ gcc --version
gcc (GCC) 4.8.3
Copyright (C) 2013 Free Software Foundation, Inc.
Это свободно распространяемое программное обеспечение. Условия копирования
приведены в исходных текстах. Без гарантии каких-либо качеств, включая
коммерческую ценность и применимость для каких-либо целей.
[/console]
да, новый файл вот такой получается:
[console]$ ls -l test
---------- 1 drb users 0 сен 24 03:46 test
[/console]
т.ч. ладно, уломали, mode тут нужно. Раз вы файл создаёте, то оно принимается равным 0000, о чём вас бубунтовская версия компилятора и предупреждает.
/* Open FILE and return a new file descriptor for it, or -1 on error.
OFLAG determines the type of access used. If O_CREAT is on OFLAG,
the third argument is taken as a `mode_t', the mode of the created file.
This function is a cancellation point and therefore not marked with
__THROW. */
#ifndef __USE_FILE_OFFSET64
extern int open (const char *__file, int __oflag, ...) __nonnull ((1));
#else
# ifdef __REDIRECT
extern int __REDIRECT (open, (const char *__file, int __oflag, ...), open64)
__nonnull ((1));
# else
# define open open64
# endif
#endif
#ifdef __USE_LARGEFILE64
extern int open64 (const char *__file, int __oflag, ...) __nonnull ((1));
#endif
#ifdef __USE_ATFILE
+-- 9 строк: Similar to `open' but a relative path name is interpreted relative to------------------------------
# ifndef __USE_FILE_OFFSET64
extern int openat (int __fd, const char *__file, int __oflag, ...)
__nonnull ((2));
# else
# ifdef __REDIRECT
extern int __REDIRECT (openat, (int __fd, const char *__file, int __oflag,
· · · · ...), openat64) __nonnull ((2));
# else
# define openat openat64
# endif
# endif
мораль: на добыло юзать fopen(3), как я с самого начала и предлагал.
да, новый файл вот такой получается:
[console]$ ls -l test
---------- 1 drb users 0 сен 24 03:46 test
[/console]
т.ч. ладно, уломали, mode тут нужно. Раз вы файл создаёте, то оно принимается равным 0000, о чём вас бубунтовская версия компилятора и предупреждает.
Сейчас ещё раз запустил там, где компилируется без mode, у файла оказались права 0250.
Я не стал обрабатывать свой текст программой indent, т.к. она короткая и чтобы было легче
скопировать. И всё равно она тестовая.
Если вывод делается неформатированный, то лучше open и write,
т.к. и проще и всё равно в конечном счёте работает через них.
Сейчас ещё раз запустил там, где компилируется без mode, у файла оказались права 0250.
похоже у вас всё равно три параметра, но там многоточие из ansi C, и вместо mode у вас попадает мусор. А у меня именно два параметра. Подозреваю, что это связано с тем, что я пробовал на нетбуке, а тут у меня 32х битная ОС. Проверять на 64х битном компе лениво.
В любом случае, O_CREAT это просто целая константа, от неё ничего не зависит (без O_CREAT open(2) игнорирует третий параметр).
"Peter" написал:
Если вывод делается неформатированный, то лучше open и write,
т.к. и проще и всё равно в конечном счёте работает через них.
ЩИТО? Что значит "вывод неформатированный"?
И да, в конечном счёте всё делается ATA командами, что вы их не юзаете? Оно жеж "проще", не?
А вот я рекомендую юзать самый высокоуровневый интерфейс, в C98 это fopen(3), а open(2) нужно для чего-то такого низкоурвнего, которое совершенно непереносимо и его сложно поддерживать. Вы сами видите, что поведение open(2) разное в разных системах, вам так нужна лишняя головная боль? Юзали-бы стандартную (прописанную в стандарте) fopen(3), и проблемы-бы не было.
PS:
"Peter" написал:
Я не стал обрабатывать свой текст программой indent, т.к. она короткая и чтобы было легче
скопировать. И всё равно она тестовая.
программа без отступов, это как неграмотный русский текст. Мне плевать на _вашу_ грамотность, это не имеет значения. Читать тяжело! И остаётся вопрос: зачем вы это запостили? Ведь для ТСа это будет ещё сложнее, разве нет? У него тоже проблемы со стилем, но он-то начинающий, ему можно. Т.ч. не обижайтесь пожалуйста, я не говорю, что "у вас плохой стиль", не потому что он плохой, а потому, что меня это не волнует. Плохо то, что ваш код сложно читать, особенно на форуме, а не в уютном редакторе (который к тому-же может исправить ваш любимый стиль на мой любимый стиль, что-бы всем было хорошо).
Ещё раз: я не собираюсь начинать полемику "какой стиль лучше и сколько пробелов должно быть в инденте!!!!", это не имеет для меня значения. Просто не волнует. Кого волнует, может идти на ЛОР, там полно тем про это. Но раз тут подсветки нет, то хоть отступы делайте, что-бы было понятнее.
Для сравнения:
Код с отступами:Показать
text
#!/bin/sed -rf
# сохранение строки
h
:begin_loop
# p
# удаление обычного начала
s/^[^'"#\]+(.*)/\1/
t begin_loop
# удаление экранированных символов
s/^\\.//
t begin_loop
# удаление закавыченного блока
s/^'[^']*'//
t begin_loop
s/^'.*//
T lq
# незакрытый блок кавычек, необходима подгрузка
${
x
b end
}
n
H
s/^/'/
t begin_loop
:lq
# удаление экранированной кавычки внутри закавыченного блока
s/^"[^"]*\\"/"/
t begin_loop
# удаление закавыченного блока
s/^"[^"]*"//
t begin_loop
s/^".*//
T lq2
${
x
b end
}
n
H
s/^/"/
t begin_loop
:lq2
/^\#/{
# теперь строка начинается с #
H
x
s/^(.*)(\#[^\n]*)\n\2$/\1/
b end
}
# а коммента и нету
x
:end
# s/.*/\x1b[32m'&'\x1b[0m/
А вот как пишет ТС:
Показать
text
#!/bin/sed -rf
h
:b
s/^[^'"#\]+(.*)/\1/
tb
s/^\\.//
tb
s/^'[^']*'//
tb
s/^'.*//
Tl
${
x
be
}
n
H
s/^/'/
tb
:l
s/^"[^"]*\\"/"/
tb
s/^"[^"]*"//
tb
s/^".*//
T lq2
${
x
be
}
n
H
s/^/"/
tb
:l2
/^\#/{
H
x
s/^(.*)(\#[^\n]*)\n\2$/\1/
be
}
x
:e
"Неформатированный вывод" - вывод некоего количества байтов, как в функции write(),
а форматированный я имел в виду который делает fprintf().
fwrite() я никогда не пользуюсь, сейчас посмотрел, что это и подумал, что open()/write()
гораздо удобнее. Если в точности соблюдать синтаксис, то и работать будет
везде одинаково.
Я как раз для ТС и поместил это, у него же не работало. А разбить на строки такую
короткую программу ему бы труда не составило. Тем более, что там часть можно
просто выбросить, т.к. она только для наглядности. Главное, что надо было
использовать 3-й аргумент в open().