We are developing Fortran-based applications on Linux OSes. I would like to write a message to /var/log/messages, etc. (according to settings such as /etc/syslog.conf). In other words, I would like to send a message to syslogd. Could you please answer any of the following (1)(2)(3)?
(1) Are there any subroutines that have considerable functionality with the libc syslog or vsyslog that can be invoked from Fortran?
(2) Is it possible to call the libc syslog or vsyslog from Fotran?If possible, use variable arguments.However, the message format can be "%d\n" in C style.
(3) Is there any other way to achieve this?
As a precondition, the operating system is RedHat-based Linux and does not consider remote (over the network). If necessary, it is possible to mix the codes of C, but the purpose is to output an error or the like of the Fotran code. I want a certain amount of speed performance (therefore, call system("...") is not allowed). The latest version of the Intel Fortran Compiler is available for Fortran processing.
That's all.
linux fortran
Intel Fortran Compiler (ifort) can call libc functions directly.
There are two points that call the C function from ifort:
(1) Specify a rule or argument type for stacking C function arguments into the stack in the interface statement.
(2) An argument is passed according to the designation of (1) when calling a C function.(Use %val()
to pass the value.)
Below is a sample program that calls puts()
and isdigit()
.
module libc_api
useiso_c_binding
implicit none
interface
integer(c_int) function puts(s) bind(c, name='puts')
use,intrinsic::iso_c_binding
character(c_char), dimension(*), int(in)::s
end function puts
integer(c_int) function isdigit(c) bind(c, name='isdigit')
use,intrinsic::iso_c_binding
integer(c_int), int(in)::c
end function isdigit
end interface
end module libc_api
program main
use libc_api
implicit none
character(64,c_char)str
integer(c_int)ret
integer(c_int)cint
! call c-apiputs()
str="hello world."c
ret = puts(str)
print'("puts()ret:", i0)',ret
! call c-api isdigit()-1
cint=ichar('7')
ret = isdigit(%val(cint))
print'("isdigit('',a1,')ret:',i0')',cint,ret
! call c-api isdigit()-2
cint=ichar('f')
ret = isdigit(%val(cint))
print'("isdigit('',a1,')ret:',i0')',cint,ret
end program main
compiling:
$ifort highge.f90
Results:
$./a.out
Hello world.
puts()ret:13
isdigit('7') ret:2048
isdigit('f') ret:0
The syslog()
call is a variable argument, so specify ATTRIBUTES VARYING
in the interface statement.
(If you specify this, you will not be able to check the type of arguments during compilation.)
module libc_api
useiso_c_binding
implicit none
interface
subroutine syslog(pri,fmt) bind(c,name='syslog')
!dir$attributes varying::syslog
end subroutine syslog
end interface
end module libc_api
program main
use libc_api
implicit none
integer(c_int)cint
! call c-apisyslog()
cint=12345
call syslog(%val(3), "write from fortran.cint:%d\n"c, %val(cint))
call syslog(%val(3), "%s%s, %d\n"c, "hello"c, "world"c, %val(cint))
end program main
After building and executing the above code, we verified that /var/log/messages
has the following message:
Jan 10 17:01:47 system7 a.out:write from fortran.cint:12345
Jan 10 17:01:47 system7 a.out: hello world, 12345
Keep C compatibility
Keep C compatibility
in the code
Search the Intel® Fortran Compiler 15.0 User Reference Guide to find relevant information.
Verification Environment:
OS: fedora 19 (64bit), GNU libc 2.17
Fortran Compiler Environment: Intel® Parallel Studio XE Professional Edition for Fortran (Assessment) for Linux
$ifort --version
ifort (IFORT) 12.1.3 20120212
Others: I did yum install syslog-ng
because syslogd was not working in fedora 19.
You can link *.o to FORTRAN and call it, so why don't you use it? As you may know, when exchanging strings between FORTRAN and C, the format is different, so please be careful.
I wrote a sample below.
https://github.com/magicdrive/FORTRAN_SYSLOG_SAMPLE
© 2024 OneMinuteCode. All rights reserved.