|
I do not know whether the C RTL muddles the picture but in
RMS native terms a variable length record with embedded new-
lines will remain a single record. So if you can not get to
a solution using C IO you can always just call $PUT directly
and that'll do the job. You may want to consider using STREAM_LF
files after all. In that case something 'cute' will happen.
During the put, all the data will be entered into the file as
a single record with embedded LFs. Upon reading the data, the LFs
in the record will turn into terminators and will break up that
chunk of data into multiple lines. Perhaps exactly what you want?
The writers can not be interupted, the readers will see 'normal'
single lines.
Sharing RMS files is straightforward, C mussdles again a little.
Numerous other topics here discuss this. Also check the C conference.
You may need FFLUSH and/or FSYNC calls to make fresh data visible.
If all fails, just use sprintf and then call SYS$PUT directly!
Hein.
|
|
You've got enough OpenVMS-isms on that fopen, that you might as well
just call RMS directly. It'll likely be easier, and you won't have
C contributing confusions due to the (necessary and expected) UNIX
emulation provided by the CRTL. (The UNIX record locking and file
sharing support is quite different from that of OpenVMS.)
Alternatively, consider using a single "logging" application, or use
per-application-instantiation (seperate) log files.
|
| For what it's worth, I've been able to acheive the desired results with code based upon the following
sample program. Many thanks to the previous replies to get me pointed in the right direction. -rm
/*
** file:
** rmsfun.c
** description:
** This sample program demonstrates how one might have an application
** program written in C "log" messages to a text file. The program
** will open a log file and will periodically append text to that file.
** The text will include several "newlines". There may be multiple
** instances of this program running concurrently. The multi-line
** message from program instance "A" cannot be intermixed with the
** multi-line message from program instance "B". Both type/continuous
** and type/tail of this shared log file work as expected.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <rms.h>
#include <stsdef.h>
#include <starlet.h>
#ifndef TRUE
#define TRUE (1)
#endif
#ifndef FALSE
#define FALSE (0)
#endif
#define LOG_FILE_NAME "rmsfun.log"
#define LOG_LOCK_TIMEOUT (10)
#define LOG_LOOP_MAX (20)
#define VMS_SUCCESS(lRetVal) \
((lRetVal & STS$M_SUCCESS) ? TRUE : FALSE)
int
main(void)
{
struct FAB aFab;
struct RAB aRab;
unsigned long lRet;
int iPID, iCnt;
char cFileName[] = LOG_FILE_NAME;
char cMsgBuf[1024] = "";
iPID = getpid(); /* to uniquely identify the writer ... */
aFab = cc$rms_fab; /* set default file access block values ... */
aFab.fab$b_fac = FAB$M_PUT;
aFab.fab$l_fna = cFileName;
aFab.fab$b_fns = (unsigned char)strlen(cFileName);
aFab.fab$l_fop = FAB$M_DFW | FAB$M_CIF;
aFab.fab$b_org = FAB$C_SEQ;
aFab.fab$b_rat = FAB$M_CR;
aFab.fab$b_rfm = FAB$C_STMLF;
aFab.fab$b_shr = FAB$M_SHRPUT | FAB$M_SHRGET | FAB$M_SHRUPD;
lRet = sys$create(&aFab, 0, 0); /* open/create file ... */
if (! VMS_SUCCESS(lRet))
{
printf("Could not create/open file >%s<, status: >%u<\n", cFileName, lRet);
exit(lRet);
}
aRab = cc$rms_rab; /* set default record access block args ... */
aRab.rab$l_fab = &aFab;
aRab.rab$b_rac = RAB$C_SEQ;
aRab.rab$l_rbf = cMsgBuf;
aRab.rab$l_rop = RAB$M_EOF | RAB$M_NLK | RAB$M_RLK | RAB$M_TMO | RAB$M_WAT;
aRab.rab$w_rsz = (unsigned short)strlen(cMsgBuf);
aRab.rab$b_tmo = (unsigned char)LOG_LOCK_TIMEOUT;
for(iCnt = 0; iCnt < LOG_LOOP_MAX; iCnt++) /* now do some test msgs ... */
{
lRet = sys$connect(&aRab, 0, 0); /* connect RAB to FAB ... */
if (! VMS_SUCCESS(lRet))
{
printf("Could not connect to file >%s<, status: >%u<\n", cFileName, lRet);
exit(lRet);
}
sprintf(cMsgBuf,
"%x: Line number 1, pass >%d<\n%x: Line number 2, pass >%d<\n%x: Line number 3, pass >%d<\n\n",
iPID, iCnt, iPID, iCnt, iPID, iCnt);
aRab.rab$w_rsz = (unsigned short)strlen(cMsgBuf);
lRet = sys$put(&aRab, 0, 0); /* then put ... */
if (! VMS_SUCCESS(lRet))
{
printf("Could not put to file >%s<, pass: >%d<, status: >%u<\n",
cFileName, lRet);
exit(lRet);
}
lRet = sys$disconnect(&aRab, 0, 0); /* then disconnect ... */
if (! VMS_SUCCESS(lRet))
{
printf("Could not disconnect from file >%s<, status: >%u<\n",
cFileName, lRet);
exit(lRet);
}
}
lRet = sys$close(&aFab, 0, 0); /* now close ... */
if (! VMS_SUCCESS(lRet))
{
printf("Could not close file >%s<, status: >%u<\n", cFileName, lRet);
exit(lRet);
}
return(0);
}
|