我有一个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
应该是什么时候
-rw------- 1 xyz users 0 2011-09-24 16:45 test.txt
如果我从另一个C程序调用此函数,它可以正常工作。有人可以指出出了什么问题吗?
规格: 64位linux GNU Fortran(SUSE Linux)4.5.0,GCC(SUSE Linux)4.5.0
谢谢, Kshitij
答案 0 :(得分:5)
您的常量是错误的,因为权限通常以八进制指定。试试这个程序:
#include <stdio.h>
#include <fcntl.h>
int main(void)
{
printf("oflag=%d mode=%d\n", O_CREAT|O_RDWR, S_IRUSR|S_IWUSR);
}
我明白了:
oflag = 66 mode = 384
600八进制equals 384十进制。
答案 1 :(得分:2)
open
希望你给它一个八进制模式的值,而不是十进制(这就是为什么你在C代码中处理模式时基本上总是看到一个额外的前导零,因为在C中你写了一个八进制带有前导零的文字。
600十进制是八进制的1130。 1130对应于---x-wx--T
,你可能有一个022的umask,只剩下---x--x--T
。
我相信你可以像这样在Fortran中指定一个八进制值:o'600'
(这是字母o,然后是单引号内的八进制值)。或者,正如David Schwartz在他的回答中建议的那样,你可以使用你想要的模式的十进制等值。但是,当你稍后回顾它时,这可能会令人困惑。
编辑:MSB指出,虽然GNU Fortran可能是more permissive,但要符合标准,您必须在data
中声明八进制常量声明或(自Fortran 2003起)为int(o'600')
。
答案 2 :(得分:2)
以下是使用Fortran ISO C绑定标准版的示例。 Fortran和C部分之间的便携式接口。在我的计算机上,我发现O_CREAT | O_RDWR具有不同的值,即514,因此将标志设置为特定值是不可移植的。
PROGRAM TEST
use iso_c_binding
implicit none
interface test2_interface
subroutine test2 ( filename, flag, mode ) bind (C, name="test2")
import
character (kind=c_char, len=1), dimension (100), intent (in) :: filename
integer (c_int), intent (in), VALUE :: flag, mode
end subroutine test2
end interface test2_interface
integer (c_int) :: oflag, mode
character (kind=c_char, len=100) :: filename
!Set oflag to O_CREAT|O_RDWR
oflag = 66 ! incorrect value ... not used
mode = int ( o'600', c_int)
filename = "test.txt" // C_NULL_CHAR
call test2 (filename, oflag, mode)
END PROGRAM
和
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <fcntl.h>
void test2(char* filename, int flag, int mode)
{
int fd;
printf ( "filename = '%s'\n", filename );
flag = O_CREAT | O_RDWR;
printf ( "flag = %d\n", flag );
printf ( "mode = octal %o\n", mode );
if(-1 == (fd = open(filename, flag, mode)))
puts("Returned -1");
}