Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

AST on directory file? (no poll)

8 views
Skip to first unread message

jdt...@decus.org.au

unread,
Mar 11, 1996, 3:00:00 AM3/11/96
to
In article <1996Mar7.1...@inland.com>, del...@inland.com writes:
> I believe this is an internals question (I don't know where else to
> ask).
>
> I am running VMS V6.1 on a VAX. I will either be programming in Fortran
> or GNU C (unless this has to be done in MACRO).
>
> I would like to post an AST on a directory file so that when the
> directory file was written to, the AST would spring to life. I could
> just poll the directory to see if there were any changes, but I think
> the former method would be less resource-intensive (if it could be
> done).
>
> Has someone done this already? Could someone point me in the right
> direction? Please send E-mail. Please do not post. Our newsfeed is 6
> days behind.
>
> Thanks in advance.
>
> -Jeff

Hi Jeff,

find following my sig a bit of VAX C that does exactly what you require.
It requires CMKRNL privilege, so the usual diclaimers apply (Use at your own
risk; don't blame me if this crashes your system; etc, etc)

This code was originally written to be run as part of a DCL command procedure
but would be easily converted to be called as part of a program.

Hope this points you in the right direction.

Regards,
Jim.
--
Jim Duff JDT Computer Systems Pty LTD JDT...@DECUS.ORG.AU
P.O. Box R1561 Royal Exchange NSW Australia 2000 Ph: +61 419 802 714
<Insert witty quote here>


---------------------------Cut Here---------------------------------------
/*
**++
**
** MODULE DESCRIPTION:
**
** Did you ever write a program that would periodically poll a directory
** to see if there are files to process and wonder if there was a better
** way? Well, this is it! This program demonstrates how to take out
** what is known as the "Serialization lock" for a file. This lock is
** described in the "VMS File System Interals" manual. This lock is taken
** out before the file system attempts to write to the directory file,
** and, as this program has already taken it out in exclusive mode,
** a blocking ast fires which drops the lock (allowing the file system
** to get it) and awakens the main module.
**
** AUTHORS:
**
** James F. Duff
** JDT Computer Systems Pty Limited
** P.O. Box R1561 Royal Exchange NSW 2000 Australia
** JDT...@DECUS.ORG.AU
** Phone: +61 (0) 419 802 714
**
** CREATION DATE:
**
** 05-Sep-1994
**
**
** ENVIRONMENT:
**
** User and Kernel modes. SYSLCK and CMKRNL privileges required.
**
**
** MODIFICATION HISTORY:
**
** X01-00 Jim Duff 05-Sep-1994
** Original version of module
**
**--
*/

#include <stdio.h>
#include <stsdef.h>
#include <ssdef.h>
#include <lckdef.h>
#include <descrip.h>
#include <dvidef.h>
#include <lib$routines.h>
#include <starlet.h>
#include <rms.h>

#define EFN 20

/*
** Declare a global structure to hold vaiables that the kernel mode
** routines use.
*/
static struct {
struct {
short int status;
short int unused;
long int lock_id;
} plock_sb;
struct {
short int status;
short int unused;
long int lock_id;
} clock_sb;
char logname[12];
short int fid[3];
} kmp;

/******************************************************************************/
void drop_lock (void) {
/*
** This routine is called as an AST in kernel mode.
*/

static long int r0_status;

/*
** Drop the serialization lock
*/
r0_status = sys$deq (kmp.clock_sb.lock_id, 0, 0, 0);
if (!($VMS_STATUS_SUCCESS (r0_status))) {
lib$signal (r0_status);
}
/*
** Drop the volume lock
*/
r0_status = sys$deq (kmp.plock_sb.lock_id, 0, 0, 0);
if (!($VMS_STATUS_SUCCESS (r0_status))) {
lib$signal (r0_status);
}
/*
** Set the event flag the main routine is waiting on.
*/
r0_status = sys$setef (EFN);
if (!($VMS_STATUS_SUCCESS (r0_status))) {
lib$signal (r0_status);
}
}

/******************************************************************************/
void get_lock (void) {
/*
** This routine is executed in kernel mode
*/

static long int r0_status;

static struct {
char prefix[6];
char logname[12];
} parent_resource = { "F11B$v" };

static struct {
char prefix[6];
short int fid;
char unused;
char rvn;
} child_resource = { "F11B$s" };

static struct dsc$descriptor parent_resource_d =
{ sizeof (parent_resource),
DSC$K_DTYPE_T,
DSC$K_CLASS_S,
&parent_resource };

static struct dsc$descriptor child_resource_d =
{ sizeof (child_resource),
DSC$K_DTYPE_T,
DSC$K_CLASS_S,
&child_resource };


/*
** Construct the parent and child resources.
*/
memcpy (parent_resource.logname, kmp.logname, 12);
child_resource.fid = kmp.fid[0];
child_resource.rvn = kmp.fid[2];

/*
** Obtain a null mode lock on the volume resource.
*/
r0_status = sys$enqw (0,
LCK$K_NLMODE,
&kmp.plock_sb,
LCK$M_SYSTEM,
&parent_resource_d,
0,
0,
0,
0,
0,
0);
if (!($VMS_STATUS_SUCCESS (r0_status))) {
lib$signal (r0_status);
}

/*
** Obtain the serialization lock for the file in exclusive mode. Note we
** specify the blocking ast parameter as our drop_lock routine.
*/
r0_status = sys$enqw (0,
LCK$K_EXMODE,
&kmp.clock_sb,
LCK$M_SYSTEM,
&child_resource_d,
kmp.plock_sb.lock_id,
0,
0,
&drop_lock,
0,
0);
if (!($VMS_STATUS_SUCCESS (r0_status))) {
lib$signal (r0_status);
}
}

/******************************************************************************/
main (void) {
/*
** Main routine. Obtain the name of the directory the user wants to watch.
** Find the label of the device the file is on, and the FID of the file. These
** pieces of info are required to format the resource names for the locks.
** Get to kernel to obtain the locks and then wait for the AST to fire to
** tell us to go ahead.
*/

static struct FAB fab;
static struct NAM nam;

static long int r0_status;
static long int i;

static char file[255];
static char es[255];
static char rs[255];
static char lockname[13];

static struct {
short int length;
short int code;
void *bufadr;
void *retlen;
long int end_list;
} dviitms = { 12, DVI$_VOLNAM, kmp.logname, NULL, 0 };

static struct {
long int status;
long int unused;
} iosb;

static struct dsc$descriptor file_d = { sizeof (file),
DSC$K_DTYPE_T,
DSC$K_CLASS_S,
file };

static $DESCRIPTOR (prompt_d, "Directory to watch: ");


/*
** Get the name of the directory the user wants to watch
*/
r0_status = lib$get_input (&file_d, &prompt_d, &file_d);
if (!($VMS_STATUS_SUCCESS (r0_status))) {
lib$signal (r0_status);
}

/*
** Set up a RMS file access block specifying the file name. Attach a
** Name attributes block.
*/
fab = cc$rms_fab;
fab.fab$l_nam = &nam;
fab.fab$l_fop = FAB$M_NAM;
fab.fab$l_fna = file;
fab.fab$b_fns = file_d.dsc$w_length;

/*
** Set up a name attributes block
*/
nam = cc$rms_nam;
nam.nam$l_esa = es;
nam.nam$b_ess = sizeof(es);
nam.nam$l_rsa = rs;
nam.nam$b_rss = sizeof(rs);

/*
** Use RMS to parse the file to pick up any fields in the filename
** the user failed to specify.
*/
r0_status = sys$parse (&fab);
if (!($VMS_STATUS_SUCCESS(r0_status))) {
lib$signal (r0_status);
}

/*
** Use RMS to search for the file. This fills in the NAM block, including
** the file id.
*/
r0_status = sys$search (&fab);
if (!($VMS_STATUS_SUCCESS(r0_status))) {
lib$signal (r0_status);
}

/*
** Reuse our filename string descriptor
*/
strcpy (file, rs);
file_d.dsc$w_length = strlen (file);

/*
** Call SYS$GETDVI to obtain the 12 character volume label. This is used
** to construct the resource for the volume lock, which is the parent
** of all serialization locks.
*/
r0_status = sys$getdviw (0,
0,
&file_d,
&dviitms,
&iosb,
0,
0,
0);
if (!($VMS_STATUS_SUCCESS (r0_status))) {
lib$signal (r0_status);
}
if (!($VMS_STATUS_SUCCESS (iosb.status))) {
lib$signal (iosb.status);
}

/*
** SYS$GETJPI returns a null filled string in the last call, but we need
** space filled, so loop through the string replacing nulls with spaces.
*/
for (i = 11; i >= 0; i--) {
if (kmp.logname[i] != '\0') {
break;
} else {
kmp.logname[i] = ' ';
}
}

/*
** Store the file id in the global structure.
*/
kmp.fid[0] = nam.nam$w_fid[0];
kmp.fid[1] = nam.nam$w_fid[1];
kmp.fid[2] = nam.nam$w_fid[2];

/*
** Get to kernel and lock the resources.
*/
r0_status = sys$cmkrnl (&get_lock, 0);
if (!($VMS_STATUS_SUCCESS (r0_status))) {
lib$signal (r0_status);
}

/*
** Wait on an event flag. The blocking AST which drops the locks will
** set this flag so the program exits.
*/
r0_status = sys$clref (EFN);
if (!($VMS_STATUS_SUCCESS (r0_status))) {
lib$signal (r0_status);
}
r0_status = sys$waitfr (EFN);
if (!($VMS_STATUS_SUCCESS (r0_status))) {
lib$signal (r0_status);
}
}

JefferBSI

unread,
Mar 14, 1996, 3:00:00 AM3/14/96
to
In article <4hp27v$7...@gap.cco.caltech.edu>, ca...@SOL1.GPS.CALTECH.EDU
(Carl J Lydick) writes:

>= I believe this is an internals question (I don't know where else to
>= ask).
>=
>= I am running VMS V6.1 on a VAX. I will either be programming in
Fortran
>= or GNU C (unless this has to be done in MACRO).
>=
>= I would like to post an AST on a directory file so that when the
>= directory file was written to, the AST would spring to life. I could
>= just poll the directory to see if there were any changes, but I
think
>= the former method would be less resource-intensive (if it could be
>= done).
>=
>= Has someone done this already? Could someone point me in the right
>= direction? Please send E-mail. Please do not post. Our newsfeed is 6
>= days behind.
>
>I *THINK* what you want to do is to put an appropriate Security ACL on
the
>directory, set up your process to be able to receive audit alarms (this
may,
>if
>the process isn't interactive, require that you create a pseudo-terminal
and
>enable it for audit alarms), and then deal with those.
>

Another way would be to take out an EX mode lock on the resource name that
VMS will use to open the directory for write access (read the internals
book to find out how to build this resource string), and specify a
blocking AST. Then hibernate The blocking AST should then lower your
lock to NL (so that VMS's writing process can get to it) then re-convert
back to EX with the same blocking AST. Also, wake your main process to
look at the directory for the change then loop back to the hibernate.

I'd do this ONLY if the security alarm thing won't fit your needs because
the resource string may change at any release, and you're in danger of
interupting VMS's processing of the directory update.


Jeff...@AOL.COM
Jefferson Corbett, Business Systems, Inc
PO Box 26868, Greenville SC 29616

heinvand...@gmail.com

unread,
May 20, 2013, 2:46:17 PM5/20/13
to
On Monday, March 11, 1996 4:00:00 AM UTC-4, jdt...@decus.org.au wrote:
> In article <1996Mar7.121904.9...@inland.com>, deli...@inland.com writes:
:
> > I would like to post an AST on a directory file so that when the
> > directory file was written to, the AST would spring to life. I could
> > just poll the directory to see if there were any changes, but I think
> > the former method would be less resource-intensive (if it could be
> > done).
:
> Hi Jeff,
>
> find following my sig a bit of VAX C that does exactly what you require.
> It requires CMKRNL privilege, so the usual diclaimers apply (Use at your own
> risk; don't blame me if this crashes your system; etc, etc)
:
> ** X01-00 Jim Duff 05-Sep-1994

Hi folks,

I just stumbled into this many years (decades!) later.
Firstly, Thank you Jim for the reply, and the subsequent sharing on his website in.
http://www.eight-cubed.com/downloads.html#watchdir
Today, he have revision X01-05 out there.
Folks, please don't used the code here, nor in X01-05.

When I had a close look at this, I noticed 2 issues…
1) it returns for any directory access, also for 'just looking'. It should really watch the DATASEQ field in the Lock Value Block to recognize changes.
2) While it works safely in normal conditions, it is in fact a system crasher when abused:
watch a directory; control-y; do something else (I used edit/edt…); touch the directory; poof.

I have informed Jim and provided fixed code. I hope he will update eventually update his website. If someone need this tool here and now, feel free to try to contact me using all 16 characters of my name at gmail or hotmail.

Cheers,
Hein van den Heuvel

VAXman-

unread,
May 20, 2013, 4:19:04 PM5/20/13
to
In article <22ca3569-2f41-430b...@googlegroups.com>, heinvand...@gmail.com writes:
>On Monday, March 11, 1996 4:00:00 AM UTC-4, jdt...@decus.org.au wrote:
>> In article <1996Mar7.121904.9...@inland.com>, deli...@inland.com writes:
>:
>> > I would like to post an AST on a directory file so that when the
>> > directory file was written to, the AST would spring to life. I coul=
>d
>> > just poll the directory to see if there were any changes, but I thi=
>nk
>> > the former method would be less resource-intensive (if it could be
>> > done).=20
>:
>> Hi Jeff,
>>=20
>> find following my sig a bit of VAX C that does exactly what you require.
>> It requires CMKRNL privilege, so the usual diclaimers apply (Use at your =
>own
>> risk; don't blame me if this crashes your system; etc, etc)
>:
>> ** X01-00 Jim Duff 05-Sep-1994
>
>Hi folks,
>
>I just stumbled into this many years (decades!) later.
>Firstly, Thank you Jim for the reply, and the subsequent sharing on his web=
>site in.
>http://www.eight-cubed.com/downloads.html#watchdir
>Today, he have revision X01-05 out there.
>Folks, please don't used the code here, nor in X01-05.
>
>When I had a close look at this, I noticed 2 issues=85=20
>1) it returns for any directory access, also for 'just looking'. It should =
>really watch the DATASEQ field in the Lock Value Block to recognize changes=
>..
>2) While it works safely in normal conditions, it is in fact a system crash=
>er when abused:
>watch a directory; control-y; do something else (I used edit/edt=85); touch=
> the directory; poof.
>
>I have informed Jim and provided fixed code. I hope he will update eventual=
>ly update his website. If someone need this tool here and now, feel free to=
> try to contact me using all 16 characters of my name at gmail or hotmail.
>
>Cheers,
>Hein van den Heuvel

... and I thought that vmsnet.internals was extinct!

--
VAXman- A Bored Certified VMS Kernel Mode Hacker VAXman(at)TMESIS(dot)ORG

Well I speak to machines with the voice of humanity.
0 new messages