- Community Home
- >
- Servers and Operating Systems
- >
- Operating Systems
- >
- Operating System - OpenVMS
- >
- fseek and ftell on stdout (i.e. SYS$OUTPUT)
Categories
Company
Local Language
Forums
Discussions
Forums
- Data Protection and Retention
- Entry Storage Systems
- Legacy
- Midrange and Enterprise Storage
- Storage Networking
- HPE Nimble Storage
Discussions
Forums
Discussions
Discussions
Discussions
Forums
Discussions
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
- BladeSystem Infrastructure and Application Solutions
- Appliance Servers
- Alpha Servers
- BackOffice Products
- Internet Products
- HPE 9000 and HPE e3000 Servers
- Networking
- Netservers
- Secure OS Software for Linux
- Server Management (Insight Manager 7)
- Windows Server 2003
- Operating System - Tru64 Unix
- ProLiant Deployment and Provisioning
- Linux-Based Community / Regional
- Microsoft System Center Integration
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Community
Resources
Forums
Blogs
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-07-2010 03:54 PM
02-07-2010 03:54 PM
Attempts to use C's ftell() on stdout - i.e. SYS$OUTPUT, the log file for the detached process - fail with status EOF when accessing the log file that was defined in the call to SYS$CREPRC but after I use 'freopen(logfile_name, "w+", stdout, "rop=wbh", "shr=get" , "fop=dfw")' to create a new log file the functions ftell() and fseek() work fine on that new file.
Is it possible to do what we want to do with just the original log file or must we use two log files (original plus the one with certain attributes)?
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-07-2010 07:26 PM
02-07-2010 07:26 PM
Re: fseek and ftell on stdout (i.e. SYS$OUTPUT)
Figuring out exactly what "work fine" means in this context can be complex! You don't necessarily know when/if you're seeing the latest data in your file, as it can be in several buffers upstream from the disk.
It all depends on the sharing options you specify on the file for both reader and writer, how the file is flushed, and how the EOF is updated. For some combinations, the EOF is NEVER updated until the file is closed by the writer. Bottom line is, if the default SYS$OUTPUT doesn't give you the right sharing options to do what you want, you'll need to open it yourself.
I do something that sounds much like what you're doing. A detached process which tracks the log files of several other detached processes. I scan the contents for interesting looking strings, and, for some files, send every record to a remote system - kind of file/record level "shadowing". We can do monitoring, analysis and display on the remote system without interfering with production processing.
From the READER, I open the files with:
LogFAB: $FAB FAC=GET SHR=
Note the "SHR=
Since I don't have source for any of my writer processes, I'm not entirely sure how the files are opened. Since you have control of the source of the writer, you're in better shape.
A few things to test... Does TYPE display the contents of the file? What does this do:
$ OPEN/APPEND/SHARE=WRITE LOG your-log-file
$ CLOSE LOG
$ TYPE your-log-file
(the request to append the file forces RMS to update the EOF).
FWIW, here are some stats from one process, monitoring 130 files, scan interval is 0.25 seconds, with a maximum block of 200 records from a single scan. That means the downstream side will see worst case lag of about 30 seconds for an update in a log file.
ELAPSED: 1 13:53:56.26 CPU: 0:06:10.86 BUFIO: 8346195 DIRIO: 761163 FAULTS: 228
RMS stats: $PARSE:32364, $SEARCH:32364, $OPEN:706328, $CONNECT:706328, $FIND:697914, $GET:11128952
So, don't be scared off by the cost of the OPEN. 4 seconds CPU per day is a tiny price to pay (and that includes a whole lot of pattern matching and message dispatches)
Of course, this would be significantly reduced if RMS had a (supported and documented) mechanism to tell me when a particular file has been updated, so I don't have to poll!
Since you have control of your writers... you could take a whole different approach to the general problem. Instead of writing your log files to disk, send SYS$OUTPUT to a "logfile daemon" process, possibly through a mailbox. Have your logging routine on the writer side add an ID (& timestamp?) to each message. What you do with it once the daemon has it is up to you.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-07-2010 08:24 PM
02-07-2010 08:24 PM
Re: fseek and ftell on stdout (i.e. SYS$OUTPUT)
Just one thing at the moment because it might be relevant to those comments ... we have the line "fsync(fileno(stdout));" just before the freopen() call, so I believe that all data is flushed to disk before we attempt to access it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-07-2010 08:48 PM
02-07-2010 08:48 PM
Re: fseek and ftell on stdout (i.e. SYS$OUTPUT)
"$ TYPE logfile" works fine.
"$ OPEN/APPEND/SHARE=WRITE LOG logfile" fails with message "RMS-E-FLK, file currently locked by another user" (as does any attempt to edit the file, even /READONLY)
When trying to open a new channel to the file with "r" (read) and "shr=get,put", the open works okay, but then the ftell on stdout fails.
I'm tempted to try opening the file "a+" to test if ftell will work on the new channel, but I'll wait for further responses in case they say "Won't work".
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-07-2010 09:04 PM
02-07-2010 09:04 PM
Re: fseek and ftell on stdout (i.e. SYS$OUTPUT)
>"$ TYPE logfile" works fine.
Aha! I think that's your clue. Don't be too concerned about the writer.
I'm fairly sure your reader process won't ever see an EOF beyond the point it was at when the file was opened, regardless of what you do in the writer. The only way to see an updated EOF is for the reader to close and reopen the file.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-08-2010 01:32 PM
02-08-2010 01:32 PM
Re: fseek and ftell on stdout (i.e. SYS$OUTPUT)
As I understand it, the ftell() function should return the byte offset from the start of the file. The value EOF (which I think is -1) is returned when any error occurs and is not an indication that the file is at EOF. Presumably if the file was positioned at the start the returned value would be zero, so any error flags do need to be negative.
Unfortunately it seems typical of C RTL function that different types of errors are not separately flagged, so I'll just have to experiment with various alternatives.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-09-2010 02:47 PM
02-09-2010 02:47 PM
Re: fseek and ftell on stdout (i.e. SYS$OUTPUT)
The C RTL functions differentiate the errors using errno.
-Boris
x.c
---
#include
int main() {
if ( ftell(stdout) == -1 )
perror("ftell");
}
$ run x
ftell: illegal seek
$
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-09-2010 03:12 PM
02-09-2010 03:12 PM
Re: fseek and ftell on stdout (i.e. SYS$OUTPUT)
I'd like something like
- SS$_NORMAL (or equivalent)
- Warning - position is past EOF
- Warning - position reset to start of current record
- Error - attempt to access before start of file
- Error - operation not permitted on this file type
etc.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-09-2010 03:55 PM
02-09-2010 03:55 PM
Re: fseek and ftell on stdout (i.e. SYS$OUTPUT)
I've managed to extract the log file records by the following method.
(a) Set-up
1 - Open new channel (for Read) on log file, positioning at EOF
2 - use ftell() and save offset for EOF
3 - close channel
(b) to extract
4 - Open new channel (for Read) on Log file
5 - use fseek() to set position saved in step 2
6 - Read forward to EOF (i.e. get extract)
I'd rather open the second channel just once, but it seems the EOF is recorded when I open the file for reading and later I can't read any new records written past that old EOF point.
John G, does RMS give me the freedom to control (or worki around) this? I'd prefer to use RFA's to position the file pointer anyway, but then how do I get the RFA of the initial EOF point?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-09-2010 05:25 PM
02-09-2010 05:25 PM
SolutionAs much as we would like to reduce the number of opens, I don't think it's possible.
I remember going into this for a customer case some years ago. Ultimately the answer was, "you need to reopen the file to get the new EOF". I couldn't find anything, even undocumented/unsupported, to get around that. See source code for TYPE/TAIL/CONTINUOUS as an example.
From my stats, opens aren't the performance bogeyman that one might expect, at least for this type of application.
To find the RFA of the last record before EOF you either need to scan the file with $FIND, or open the file with ROP=EOF and try to work your way backwards (see source of TYPE/TAIL for some heuristics in locating records backwards... it ain't pretty!).
Given the position of the EOF, I believe you could fabricate an RFA for a record written after that position. A few experiments should reveal the secrets. Obviously not supported, but also not something engineering would dare change!
(My log file tracker always reads from the beginning of the file. Even when recovering, I just read to EOF and keep track of the RFA. Even though I'm following numerous files, some of which are quite large, timing is fast enough that I didn't think it worth the effort to try to do anything more heroic)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-10-2010 03:33 AM
02-10-2010 03:33 AM
Re: fseek and ftell on stdout (i.e. SYS$OUTPUT)
I'd like something like
- SS$_NORMAL (or equivalent)
...
<<<
Boris pointed out that there is additional information in errno.
You probably know that ftell() is not a VMS system service or a VMS RTL function. The behavior is defined by the ISO C standards. There it is said that errno can hold (extracted from errno.h):
#define EBADF 9 /* Bad file number */
#define ESPIPE 29 /* Illegal seek */
#define EOVERFLOW 88 /* Value to large for datatype */
What Boris showed with perror() was a ESPIPE.
There may be extensions and depending on the function and the value in errno you may find VMS specific information in vaxc$errno. The CRTL documentation should have the details. But there is no way to have this function behave like a VMS system service.
From what I read (and understand), you just want to position in a log file: one writer and one or more readers. Except for sys$output and if I correctly recollect, this seems doable in C, on VMS. What's the usual discloser, here?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-10-2010 01:25 PM
02-10-2010 01:25 PM
Re: fseek and ftell on stdout (i.e. SYS$OUTPUT)
As I mentioned above, we have a workable solution. It's something that we'll use to extract diagnostic information on an ad hoc basis. Good performance would be nice but isn't critical; medium performance is fine because it will have little impact on other processes.
That said,... I mentioned how the fopen() seems to retrieve an EOF marker (Max allocated block?) that prevented me reading beyond that point even when more data had been written there.
(Reminder: we're accessing SYS$OUTPUT which is being written by other functions in, or called by, the same image. This extracting is an occasional thing and requires a start point and a later read of SYS$OUTPUT from that start point)
Is there any way to remove or reset this EOF marker so that we can read forward from our initial point? This would mean just one OPEN and one later CLOSE of the "extract" channel into the file SYS$OUTPUT.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-10-2010 01:31 PM
02-10-2010 01:31 PM
Re: fseek and ftell on stdout (i.e. SYS$OUTPUT)
I'd probably punt on using the C RTL for this stuff - I usually punt on the C RTL whenever I'm trying to do more than what is the norm on a Unix box - and would go directly to RMS.
Yes, using RMS directly for the first time is daunting; the API is massive and complex. But then I have available a set of wrappers for calling RMS from C at the HoffmanLabs web site. The stuff deals with sequential and indexed formats, sharing and other such. Full source code. BSD-style license. Search for NEWUSER over there.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-10-2010 02:08 PM
02-10-2010 02:08 PM
Re: fseek and ftell on stdout (i.e. SYS$OUTPUT)
I had to read your email twice. "Take a punt" over here means "to bet on" and is an expression of endorsement of an action but I think where you are it means "give it the boot" (i.e. reject it).
As I said we have a workable solution but it would be better if what appears to be an EOF limit (is it max allocated block?) that seems to be recorded during the fopen() (or RMS SYS$OPEN) can be reset. Do you know if this is possible and if so what value means "unknown"?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-10-2010 02:39 PM
02-10-2010 02:39 PM
Re: fseek and ftell on stdout (i.e. SYS$OUTPUT)
http://www.opengroup.org/onlinepubs/000095399/functions/fseek.html
I haven't tried to prove that the CRTL follows the standard, but you may want to before giving up -- something like fseek(fp, 0, SEEK_CUR) before calling ftell(fp).
Also, it appears from the discussion that this log file may be record-oriented, so be sure to read the CRTL docs on caveats associated with positioning on a record boundary rather than a byte offset when using ftell().
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-10-2010 02:40 PM
02-10-2010 02:40 PM
Re: fseek and ftell on stdout (i.e. SYS$OUTPUT)
I'd walk forward on the records until I hit the EOF using RMS, and would then wait and retry the reads at intervals. IIRC, some of the older OpenVMS stuff required you to close and reopen the file when you hit EOF, but I think that may have gotten fixed. (And if it didn't, then the RFA will get you back to the location quickly.)
Or I'd punt^H^H^H^Herr, is "scrap it" OK? entirely, and use something like syslog or analogous, or some locally-built analog, and send the activity data over to a remote server for evaluation and processing.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-10-2010 03:19 PM
02-10-2010 03:19 PM
Re: fseek and ftell on stdout (i.e. SYS$OUTPUT)
I started out trying to use ftell and fseek because from the returned values I could get the total number of bytes that had been written to the file and use that to malloc() before an fread() of all the data. Now I've moved to fread()s into blocks of 8192 bytes and realloc() (and modify the ptr to the input buffer) if I need to read more.
However, if a fseek() clears the EOF marker and I can open and close the "extract channel" once rather than twice it would be nice.
Hoff - what you describe sounds similar to what John Gillings is using. I'm running out of time on what I'm doing and my use is from within what's writing the logfile, which makes the sequencing easier. I'll put your idea aside for a future generic "file record extractor".
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-10-2010 08:03 PM
02-10-2010 08:03 PM
Re: fseek and ftell on stdout (i.e. SYS$OUTPUT)
I tested the sequence open - fseek, then later read - close, but it failed to extract any records from the log file, which probably meant that the channel hit EOF immediately.
This suggests that fseek (fp,0,SEEK_END) and the fsee(fp,0,SEEK_CUR) I tried in a previous image did not clear the EOF flag.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-16-2010 01:28 PM
02-16-2010 01:28 PM
Re: fseek and ftell on stdout (i.e. SYS$OUTPUT)
At least I've moved away from the old solution, which was the C function freopen using a new filename, which of course that meant overheads for the processing of the directory immediately and, because of the extra files, ongoing issues.