从 fortran 调用 C 的 open() 函数时文件权限不正确
我有一个 Fortran 程序,它调用 C 函数并使用 open()
main.f90 打开一个文件:
PROGRAM TEST
integer :: oflag, mode
!Set oflag to O_CREAT|O_RDWR
oflag = 66
mode = 600
call test2("test.txt", oflag, mode)
END PROGRAM
test.c:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#pragma weak test2_ = test2
#pragma weak test2__ = test2
#pragma weak TEST2 = test2
void test2(char* filename, int* flag, int* mode)
{
int fd;
if(-1 == (fd = open(filename, *flag, *mode)))
puts("Returned -1");
}
编译为:
gcc -c test.c
gfortran main.f90 test.o
当我运行该程序时,它会创建文件 test.txt,但权限不正确:
---x--x--T 1 xyz users 0 2011-09-24 16:40 test.txt
我 如果我从另一个 C 程序调用这个函数,它应该可以
-rw------- 1 xyz users 0 2011-09-24 16:45 test.txt
正常工作。有人可以指出出了什么问题吗?
规格: 64位Linux GNU Fortran (SUSE Linux) 4.5.0、GCC (SUSE Linux) 4.5.0
谢谢, 克什蒂吉
I have a fortran program which calls a C function and opens a file using open()
main.f90:
PROGRAM TEST
integer :: oflag, mode
!Set oflag to O_CREAT|O_RDWR
oflag = 66
mode = 600
call test2("test.txt", oflag, mode)
END PROGRAM
test.c:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#pragma weak test2_ = test2
#pragma weak test2__ = test2
#pragma weak TEST2 = test2
void test2(char* filename, int* flag, int* mode)
{
int fd;
if(-1 == (fd = open(filename, *flag, *mode)))
puts("Returned -1");
}
I compile as:
gcc -c test.c
gfortran main.f90 test.o
When I run the program, it creates the file test.txt, but with incorrect permissions:
---x--x--T 1 xyz users 0 2011-09-24 16:40 test.txt
when it should have been
-rw------- 1 xyz users 0 2011-09-24 16:45 test.txt
If I call this function from another C program, it works fine. Can someone point out what is going wrong?
Specs:
64 bit linux
GNU Fortran (SUSE Linux) 4.5.0, GCC (SUSE Linux) 4.5.0
Thanks,
Kshitij
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的常量是错误的,因为权限通常以八进制指定。试试这个程序:
我得到:
600 八进制等于 384 十进制。
Your constants are wrong because permissions are typically specified in octal. Try this program:
I get:
600 octal eqals 384 decimal.
open
期望您为它提供八进制模式的值,而不是十进制(这就是为什么在处理 C 代码中的模式时您基本上总是看到一个额外的前导零,因为在 C 中您编写了一个八进制带前导零的文字)。十进制的 600 八进制的 1130。 1130 对应于
---x-wx--T
,并且您的 umask 可能为 022,留下---x--x--T
。我相信您可以在 Fortran 中指定一个八进制值,如下所示:
o'600'
(即字母 o,然后是单引号内的八进制值)。或者,正如 David Schwartz 在他的回答中建议的那样,您可以只使用所需模式的十进制等效值。不过,当您稍后回顾时,这可能会令人困惑。编辑:MSB指出,虽然GNU Fortran可能是更宽松,为了符合标准,您必须在
data
语句中声明一个八进制常量,或者(自 Fortran 2003 起)如下int(o'600')
。open
expects you to give it a value for the mode in octal, not decimal (this is why you basically always see an extra leading zero when dealing with modes in C code, since in C you write an octal literal with a leading zero).600 in decimal is 1130 in octal. 1130 would correspond to
---x-wx--T
, and you likely have a umask of 022, leaving you with---x--x--T
.I believe you can specify an octal value in Fortran like this:
o'600'
(that's the letter o and then the octal value inside single quotes). Or, as David Schwartz suggested in his answer, you can just use the decimal equivalent of the mode you want. That's likely to be confusing when you look back at it later, though.Edit: M. S. B. has pointed out that, while GNU Fortran may be more permissive, to comply with the standard you'd have to declare an octal constant in a
data
statement or (since Fortran 2003) asint(o'600')
.下面是一个使用 Fortran ISO C 绑定作为标准和标准的示例。 Fortran 和 C 部分之间的可移植接口。在我的计算机上,我发现 O_CREAT|O_RDWR 有不同的值,即 514,因此将标志设置为特定值是不可移植的。
和
Here is an example using the Fortran ISO C Binding for a standard & portable interface between the Fortran and C portions. On my computer I found O_CREAT|O_RDWR to have a different value, i.e., 514, so setting flag to a specific value is not portable.
and