- Community Home
- >
- Servers and Operating Systems
- >
- Operating Systems
- >
- Operating System - OpenVMS
- >
- Re: C RTL: fwrite following fsync fails; what's go...
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
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
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
01-24-2013 07:59 PM
01-24-2013 07:59 PM
I am running the following C code on an OpenVMS v8.4 I64 machine:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #ifdef __VMS #define myfopen(fname, amode, ...) fopen(fname,amode,__VA_ARGS__) #else #define myfopen(fname, amode, ...) fopen(fname,amode) #endif void peep(FILE *otherStream) { char buf[1024]; fsync(fileno(otherStream)); /*FILE *peeper = myfopen("hello.txt", "r", "shr=get,put,upd"); fread( buf, 1, 8, peeper ); fclose(peeper); printf("peeped: '%s'\n", buf); */ } int main( int argc, char *argv[] ) { const char *text = "I am definitely not angry right now. No, not me. Why would I be angry? Pish posh."; FILE *this_is_a_file = fopen("hello.txt","w"); fclose(this_is_a_file); this_is_a_file = myfopen("hello.txt","r+", "shr=get,put,upd"); peep(this_is_a_file); fwrite( text, 1, sizeof(text), this_is_a_file ); if ( ferror(this_is_a_file) ) { printf("Generic exclamation of surprise with subdued jest.\n"); perror(NULL); exit(1); } peep(this_is_a_file); fclose( this_is_a_file ); }
The output looks like this:
Generic exclamation of surprise with subdued jest. non-translatable vms error code: 0x1827A %rms-e-eof, end of file detected
This works fine on Linux. What am I doing wrong?
Background:
I'm trying to write unittests (and other code) that should be easily portable between VMS and Linux, so using direct RMS calls is highly undesirable. I'd like to get it working using the standard C file I/O routines.
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-24-2013 10:49 PM
01-24-2013 10:49 PM
Re: C RTL: fwrite following fsync fails; what's going on?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-25-2013 06:46 AM
01-25-2013 06:46 AM
Re: C RTL: fwrite following fsync fails; what's going on?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-25-2013 09:41 AM
01-25-2013 09:41 AM
Re: C RTL: fwrite following fsync fails; what's going on?
Yeah, checking the return value of fwrite allows me to do what I want. Thanks!
I realized that I did my test case reduction poorly and removed a bunch of checks that were otherwise already in the original code. fwrite was an exception, but the original code did check the return value of fsync. In the original code I expected any failure in fsync to halt the program and prevent fwrite from being called at all.
I've found some interesting behavior because of this:
fsync will complete and return a success code (returns 0), yet set ferror to 1 (the end of file reached error).
This behavior is inconsistant with Linux, and I can't find any documentation that details how fsync is supposed to interact with ferror on either system. It just isn't mentioned. I believe this omission in the documents lead me to believe that checking fsync's return value was sufficient to ensure that no error flags would be set.
Docs checked:
http://h71000.www7.hp.com/commercial/c/docs/5763p029.html
http://linux.die.net/man/2/fsync
So fsync seems to be working: the new data appears in the file. However, it is also setting ferror. Does this have any implications on the integrity of the sync'd file handle?
Here's a new test case:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #ifdef __VMS #define myfopen(fname, amode, ...) fopen(fname,amode,__VA_ARGS__) #else #define myfopen(fname, amode, ...) fopen(fname,amode) #endif void peep(FILE *otherStream) { char buf[1024]; printf("ferror before fsync == %d\n",ferror(otherStream)); int errval = fsync(fileno(otherStream)); printf("ferror after fsync == %d\n",ferror(otherStream)); if ( errval != 0 || ferror(otherStream) ) { printf("fsync failed.\n"); perror(NULL); exit(1); } /*FILE *peeper = myfopen("hello.txt", "r", "shr=get,put,upd"); fread( buf, 1, 8, peeper ); fclose(peeper); printf("peeped: '%s'\n", buf); */ } int main( int argc, char *argv[] ) { const char *text = "I am definitely not angry right now. No, not me. Why would I be angry? Pish posh."; FILE *this_is_a_file = fopen("hello.txt","w"); fclose(this_is_a_file); this_is_a_file = myfopen("hello.txt","r+", "shr=get,put,upd"); peep(this_is_a_file); size_t nbytes = fwrite( text, 1, strlen(text), this_is_a_file ); printf("strlen == %ld\n", strlen(text)); printf("nbytes == %ld\n", nbytes); if ( ferror(this_is_a_file) ) { printf("Generic exclamation of surprise with subdued jest.\n"); perror(NULL); exit(1); } peep(this_is_a_file); fclose( this_is_a_file ); }
Results:
ferror before fsync == 0 ferror after fsync == 1 fsync failed. non-translatable vms error code: 0x1827A %rms-e-eof, end of file detected
As for the stream vs record format thing, I think I will use "ctx=stm" in my fopen options for now and hope for the best. I'll keep that in mind for fwrite should I need to worry about the distinction. Thanks for mentioning that. Is there a way to determine at runtime which mode a FILE* handle is operating in?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-25-2013 12:55 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-25-2013 01:26 PM
01-25-2013 01:26 PM
Re: C RTL: fwrite following fsync fails; what's going on?
Understood. Thank you for the info!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-25-2013 03:22 PM
01-25-2013 03:22 PM
Re: C RTL: fwrite following fsync fails; what's going on?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-26-2013 07:14 PM
01-26-2013 07:14 PM
Re: C RTL: fwrite following fsync fails; what's going on?
>> fwrite(text, 1, sizeof(text), this_is_a_file );
>A pointer to char is almost the same as an array of char, but not quite
Right. You can also fix it by changing the declaration to an array (also saves the wasted pointer):
static const char text[] = "I am definitely not angry right now. No, not me. Why would I be angry? Pish posh.";
You would also have to change the fwrite length:
items = fwrite(text, sizeof(text)-1, 1, this_is_a_file );