- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi everyone,
I have a program written in Fortran 90/95; after invocation it always reads a certain data file. For the users' convenience I'd like them to just have to place this file in the same directory as the executable itself, without making them set some environment variable or forcing them to use a certain directory for that purpose. The program should 'simply' look for the file in the directory in which it itself is stored, NOT in the directory from which it is run. So far, however, I have failed to find a solution to this problem. I tried using
If you have any suggestions, also concerning workarounds, please don't hesitate to reply. Thanks a lot in advance!
I have a program written in Fortran 90/95; after invocation it always reads a certain data file. For the users' convenience I'd like them to just have to place this file in the same directory as the executable itself, without making them set some environment variable or forcing them to use a certain directory for that purpose. The program should 'simply' look for the file in the directory in which it itself is stored, NOT in the directory from which it is run. So far, however, I have failed to find a solution to this problem. I tried using
[fortran]getarg(0,path)[/fortran]but that only gave me whatever string I had used to invoke the program, not its absolute path.
If you have any suggestions, also concerning workarounds, please don't hesitate to reply. Thanks a lot in advance!
1 Solution
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In UNIX and UNIX-like, there's usually a /proc//exe link pointing to the executable's real location. With the aid of POSIX's readlink, you can get the path you want, e.g.:
[fortran]program test_cmdpath use ISO_C_BINDING use IFPORT implicit none interface function readlink(path, buf, bufsize) bind(C, NAME = 'readlink') import integer(C_SIZE_T) :: readlink character(KIND = C_CHAR), intent(IN) :: path(*) character(KIND = C_CHAR) :: buf(*) integer(C_SIZE_T), value :: bufsize end function end interface integer :: pid, i, idx integer(C_SIZE_T) :: szret character(256) :: path character(KIND = C_CHAR) :: cbuf(256) pid = GETPID() write (path, '(i0)') pid path = '/proc/'//TRIM(path)//'/exe' szret = readlink(TRIM(path)//C_NULL_CHAR, cbuf, SIZE(cbuf, KIND = C_SIZE_T)) if (szret == -1) stop 'Error reading link' path = '' do i = 1, SIZE(cbuf) if (cbuf(i) == C_NULL_CHAR) exit path(i:i) = cbuf(i) enddo print '("Command full path: ", A)', TRIM(path) idx = INDEX(path, '/', BACK = .TRUE.) print '("Command directory: ", A)', TRIM(path(:idx - 1)) end program test_cmdpath[/fortran]
Link Copied
4 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If your user was able to run the program from a directory other than the
one containing the executable by typing only its name, rather than the
full path, then the directory containing the executable was ascertained
by examining the value of $PATH.
To retrieve the path, your program could take the output of which and use the prefix from the result. This could be done by calling system in your program, or by using a shell script which obtains the path and invokes your program with the path as an extra argument.
To retrieve the path, your program could take the output of which
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear mecej4
Thank you for your reply! The trouble with this approach is that it would restrict the users to only using directories in their path for program storage; alternatively they'd have to extend $PATH. We would like to keep things as simple and unrestricted as possible, i.e. we'd like the users to be able to place the program in whatever directory they choose and be able to use it right away, without having to set anything up. At least as long as this is possible... (admittedly, extending the path isn't a big deal, but many of our users are likely not to be familiar with such things and may be scared off by what they might perceive to be some technical obstacles, but maybe I simply ought to have stronger faith in our users!?)
Thank you for your reply! The trouble with this approach is that it would restrict the users to only using directories in their path for program storage; alternatively they'd have to extend $PATH. We would like to keep things as simple and unrestricted as possible, i.e. we'd like the users to be able to place the program in whatever directory they choose and be able to use it right away, without having to set anything up. At least as long as this is possible... (admittedly, extending the path isn't a big deal, but many of our users are likely not to be familiar with such things and may be scared off by what they might perceive to be some technical obstacles, but maybe I simply ought to have stronger faith in our users!?)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In UNIX and UNIX-like, there's usually a /proc//exe link pointing to the executable's real location. With the aid of POSIX's readlink, you can get the path you want, e.g.:
[fortran]program test_cmdpath use ISO_C_BINDING use IFPORT implicit none interface function readlink(path, buf, bufsize) bind(C, NAME = 'readlink') import integer(C_SIZE_T) :: readlink character(KIND = C_CHAR), intent(IN) :: path(*) character(KIND = C_CHAR) :: buf(*) integer(C_SIZE_T), value :: bufsize end function end interface integer :: pid, i, idx integer(C_SIZE_T) :: szret character(256) :: path character(KIND = C_CHAR) :: cbuf(256) pid = GETPID() write (path, '(i0)') pid path = '/proc/'//TRIM(path)//'/exe' szret = readlink(TRIM(path)//C_NULL_CHAR, cbuf, SIZE(cbuf, KIND = C_SIZE_T)) if (szret == -1) stop 'Error reading link' path = '' do i = 1, SIZE(cbuf) if (cbuf(i) == C_NULL_CHAR) exit path(i:i) = cbuf(i) enddo print '("Command full path: ", A)', TRIM(path) idx = INDEX(path, '/', BACK = .TRUE.) print '("Command directory: ", A)', TRIM(path(:idx - 1)) end program test_cmdpath[/fortran]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear John
Thanks a lot for this reply, the code seems to do just what I've been looking for! I've compiled and run your program, and it all works very nicely. Now I'll try to incorporate it in my code, let's hope everything will go smoothly. Thanks a lot once more.
Thanks a lot for this reply, the code seems to do just what I've been looking for! I've compiled and run your program, and it all works very nicely. Now I'll try to incorporate it in my code, let's hope everything will go smoothly. Thanks a lot once more.
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page