[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference hydra::axp-developer

Title:Alpha Developer Support
Notice:[email protected], 800-332-4786
Moderator:HYDRA::SYSTEM
Created:Mon Jun 06 1994
Last Modified:Fri Jun 06 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:3722
Total number of notes:11359

3446.0. "Nectar - Point 25037" by KZIN::ASAP () Mon Apr 07 1997 09:13

    Company Name :  Nectar - Point 25037
    Contact Name :  Mats Nilsson
    Phone        :  +46 (0)451 893 00
    Fax          :  +46 (0)451 817 30
    Email        :  [email protected]
    Date/Time in :   7-APR-1997 13:12:43
    Entered by   :  Nick Hudson
    SPE center   :  REO

    Category     :  vms
    OS Version   :  
    System H/W   :  


    Brief Description of Problem:
    -----------------------------

From:	VBORMC::"[email protected]" "Declan Lennon"  7-APR-1997 11:01:06.81
To:	"'[email protected]'" <IMCEAX400-c=US+3Ba=+20+3Bp=DIGITAL+3Bo=SBUEURMFG+3Bdda+3ASMTP=asap+40rdgeng+2Eenet+2Edec+2Ecom+3B@MAIL.DEC.COM>
CC:	
Subj:	POINT 25037, Nectar


Hello - 

POINT Log Number	 25037

Company Name 	Nectar

Engineers name	Mats Nilsson

Telephone Number 		+46 (0)451 893 00

Fax Number		+46 (0)451 817 30

E-mail Address	[email protected]           

Operating System, Version	OpenVMS, ??
 
Platform			Alpha (??)

Problem Statement		


Hello

I wonder how vfork works ?

Are the open tables from the father also open in the child process ?

In Unix we do as follows

cc=fork();
if(cc == 0) {  /* child process */
	for(i=3,i<_NFILE;i++) {
		close(i);
	}
.
.
.

When we do this in OpenVMS all tables in the father are also closed.

Best regards

Mats
+----------------------------------------------+
!                                              !
!    oooooo     ooooo  Nectar Systems AB       !
!    ooooooo    ooooo  Mats Nilsson            !
!      oooooo   ooo    Development Manager     !
!      ooooooo  ooo    [email protected]           !
!      ooo oooo ooo    Box 124                 !
!      ooo  ooooooo    S-281 22 Hassleholm     !
!    ooooo   oooooooo  Tel. +46 (0)451 893 00  !
!    ooooo    ooooooo  Fax. +46 (0)451 817 30  !
!                                              !
! -For excellence in 4GL-                      !
!                                              !
+----------------------- http://www.nectar.se -+


% ====== Internet headers and postmarks (see DECWRL::GATEWAY.DOC) ======
% Received: from reoexc1.reo.dec.com (reoexc1.reo.dec.com [16.196.160.207]) by vbormc.vbo.dec.com (8.7.3/8.7) with SMTP id LAA14121 for <[email protected]>; Mon, 7 Apr 1997 11:54:21 +0200
% Received: by reoexc1.reo.dec.com with SMTP (Microsoft Exchange Server Internet Mail Connector Version 4.0.994.63) id <[email protected]>; Mon, 7 Apr 1997 11:03:44 +010
% Message-ID: <c=US%a=_%p=Digital%[email protected]>
% From: Declan Lennon <[email protected]>
% To: "'[email protected]'" <IMCEAX400-c=US+3Ba=+20+3Bp=DIGITAL+3Bo=SBUEURMFG+3Bdda+3ASMTP=asap+40rdgeng+2Eenet+2Edec+2Ecom+3B@MAIL.DEC.COM>
% Subject: POINT 25037, Nectar
% Date: Mon, 7 Apr 1997 12:04:57 +0100
% X-Mailer:  Microsoft Exchange Server Internet Mail Connector Version 4.0.994.63
% Encoding: 59 TEXT
T.RTitleUserPersonal
Name
DateLines
3446.1KZIN::HUDSONThat&#039;s what I thinkTue Apr 08 1997 11:2240
From:	DEC:.REO.REOVTX::HUDSON       "[email protected] - UK Software
Partner Engineering 830-4121"  8-APR-1997 15:19:46.87
To:	nm%vbormc::"[email protected]"
CC:	HUDSON
Subj:	POINT 25037, Nectar -vfork closing tables

>I wonder how vfork works ?
>
>Are the open tables from the father also open in the child process ?
>
>In Unix we do as follows
>
>cc=fork();
>if(cc == 0) {  /* child process */
>	for(i=3,i<_NFILE;i++) {
>		close(i);
>	}
>.
>.
>.
>
>When we do this in OpenVMS all tables in the father are also closed.
>

The "vfork" function on VMS C does not behave in the same way as "fork" on
Unix.  The C RTL manual discusses these differences.  One major difference is
that no child process is created when you call vfork - that doesn't happen
until you call a corresponding "exec" function.

I am not clear from the code extract above what you are doing.  For example,
since a call to vfork() will return zero, if you substitute "vfork" for "fork"
in the above snippet of code, then "cc" will be zero, and you will execute the
code that is commented "child process", even though you're still in the parent.

Could you send me a program example which shows what your problem is?


Regards
Nick Hudson
Digital Software Partner Engineering
3446.2example code from customer (NOT)KZIN::HUDSONThat&#039;s what I thinkWed Apr 09 1997 05:4172
From:	VBORMC::"[email protected]" "Mats Nilsson"  9-APR-1997 08:19:29.08
To:	"[email protected] - UK Software Partner Engineering 830-4121
08-Apr-1997 1519 +0100" <[email protected]>
CC:	
Subj:	POINT 25037, Nectar -vfork closing tables

Reply to the message of Tuesday April 8, 1997 17:15 +0100
-----------------------------------------------------------------
>>I wonder how vfork works ?

>>Are the open tables from the father also open in the child process ?



>I am not clear from the code extract above what you are doing.  For
>example, since a call to vfork() will return zero, if you substitute
>"vfork" for "fork" in the above snippet of code, then "cc" will be
>zero, and you will execute the code that is commented "child process",
>even though you're still in the parent.

>Could you send me a program example which shows what your problem is?

My question is does the subprocess inherit the open files from the father=
?
Because we want to close them for the subprocess.
This is a bit of the same problem that I asked about in 23091.

In the example when we fork, for the subprocess we close all open files
with fildes greater than STDERR.

Regards

Mats
+----------------------------------------------+
!                                              !
!    oooooo     ooooo  Nectar Systems AB       !
!    ooooooo    ooooo  Mats Nilsson            !
!      oooooo   ooo    Development Manager     !
!      ooooooo  ooo    [email protected]           !
!      ooo oooo ooo    Box 124                 !
!      ooo  ooooooo    S-281 22 H=E4ssleholm     !
!    ooooo   oooooooo  Tel. +46 (0)451 893 00  !
!    ooooo    ooooooo  Fax. +46 (0)451 817 30  !
!                                              !
! -For excellence in 4GL-                      !
!                                              !
+----------------------- http://www.nectar.se -+

% ====== Internet headers and postmarks (see DECWRL::GATEWAY.DOC) ======
% Received: from mail.vbo.dec.com ([16.36.208.34]) by vbormc.vbo.dec.com
(8.7.3/8.7) with ESMTP id JAA19662 for <[email protected]>; Wed, 9 Apr
1997 09:12:30 +0200
% Received: from server21.digital.fr (server21.digital.fr [193.56.15.21]) by
mail.vbo.dec.com (8.7.3/8.7) with ESMTP id JAA17283 for
<[email protected]>; Wed, 9 Apr 1997 09:18:49 +0200 (MET DST)
% Received: from nectar (nectar.nectar.se [193.14.116.1]) by server21.digital.fr
(8.7.5/8.7) with SMTP id JAA25032 for <[email protected]>; Wed, 9 Apr
1997 09:23:50 +0200 (MET DST)
% Received: (from gmail@localhost) by nectar (8.6.12/8.6.12) id JAA16150 for
[email protected]; Wed, 9 Apr 1997 09:15:51 +0200
% Received: by gmail.nectar.se with Gmail (ginets/4.0.1) id 334b421e; Wed, 9 Apr
97 09:15:51 +010
% Date: Wed, 9 Apr 97 09:12:06 +0100
% Message-Id: <[email protected]>
% In-Reply-To: <[email protected]>
% From: Mats Nilsson <[email protected]>
% To: "[email protected] - UK Software Partner Engineering 830-4121
08-Apr-1997 1519 +0100" <[email protected]>
% Subject: POINT 25037, Nectar -vfork closing tables
% Mime-Version: 1.0
% Content-Type: text/plain; charset=ISO-8859-1
% Content-Transfer-Encoding: quoted-printable
3446.3KZIN::HUDSONThat&#039;s what I thinkWed Apr 09 1997 11:23241
From:	DEC:.REO.REOVTX::HUDSON       "[email protected] - UK Software
Partner Engineering 830-4121"  9-APR-1997 15:17:59.11
To:	nm%VBORMC::"[email protected]"
CC:	HUDSON
Subj:	RE:  No.23091, and 25037, files and child processes 

Hello Mats

I have done some investigation and hope I can now answer your questions.

There are a couple of things that are causing problems.  Partly this is because
"vfork" doesn't work the same way on VMS as Unix, and partly this is because of
the bug in the C RTL which we've already mentioned.

To start with, following your question on whether a "close" in a child will
close the parent's files, you need to understand that vfork on VMS is different
from Unix.  Section 5.2 in the DEC C RTL manual discusses this, but
essentially:

When you call "vfork", this does NOT create a child process.  After vfork, you
are expected to call "execl" (or "execv", etc.), and it is the "execl" call
that creates the subprocess.  So if you have:

	status = vfork();
	if (status == 0) {
		/* I must be the child */
		close(x);
	}
	if (status != 0) {
		/* I must be the parent */
		write(x,...)
	}

Then the "close" you do is actually happening in the parent.   The "status"
returned from the vfork() call should be used only to decide whether you call
execl() or not.

When the execl is called and the child program starts, then all the open file
descriptors from the parent are given to the child, and it should be able to
use them.  But because of the C RTL problem, it can't use them in the case
where you are trying to do shared writes.

I have below a parent and child program which show what I mean.  Also is an
annotated run from the program which I hope explains what's happening.

As I said, this is discussed in the C RTL manual.  If there are things you
don't understand in the book or from what I include here please let me know and
I'll try to explain better.

Regards

Nick

/*
    Program:        Parent_fork.c

    Description:
        Program to test "UNIX" like system service routines for subprocesses
    on VMS. Program uses VFORK, EXECL & WAIT:

    EXECL passes the name of an image to be activated in a child process.
    VFORK creates a duplicate process of the current process. It returns
          the process ID of the child process to the parent; & returns 0 to
          the child process, indicating successful creation of process
          context.
*/


#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <perror.h>
#include <processes.h>
#include <climsgdef>        /* for CLI status values */


main()
{
    int status, cstatus;
    int logfile,textfile;

    textfile = open("textfile.dat",O_RDONLY);
    logfile = open("logfile.dat",(O_APPEND | O_RDWR | O_TRUNC | O_CREAT),
		"shr=put,get","ctx=rec");
	printf("fileno of logfile is %d\n",logfile);
	printf("fileno of textfile is %d\n",textfile);

    /* create independent child process */
    status = vfork();
    printf( "parent_fork: status from vfork = %d\n", status );

    if (status == 0) {
	write(logfile,"status from vfork was zero : child\n",36);
    } else {
        write(logfile,"status from vfork nonzero : parent\n",36);
    }
    /* check for failure (-1) */
    if (status < 0)
    {
        printf( "parent_fork: Child process failed: status %d\n", status );
        exit( status );
    }


    if (status > 0)
    {
	/* this piece of code is executed by parent process only */
        printf( "parent_fork: waiting for Child (status = %d [0x%x])\n",
                    status, status );
        /* call WAIT function to suspend parent process until child */
        /* process exits: WAIT returns status from child process */
        if ((status = wait( &cstatus )) == -1)
            perror( "parent_fork: Wait failed" );
        else
            if (cstatus == CLI$_IMAGEFNF)
                printf( "parent_fork: Child does not exist\n" );
            else
                printf( "parent_fork: Child final status: %d\n", cstatus );


        exit(0);
    }


    /* ..else status from vfork must be 0 */
    /* - so this is the new process */
    
    /* we can close the logfile for the child now */
    printf( "parent_fork: This is new forked process\n" );
    /* call EXECL which passes name of image to be activated by child */
    /*( rem: second parameter can be an argument list - set to NULL here */
    if ((status = execl( "child_fork", 0 )) == -1)
    {
        perror( "parent_fork: (New Forked process) Execl failed\n" ), exit(0);
    }

}

/* child_fork.c */
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>

main()
{
	int	stat;
	int	textfile,logfile;
	char	buff[100] = "******************************************";
	printf("Hello, this is child_fork, give me logfile number ?");
	scanf("%d",&logfile);
	printf("Give me textfile number ?");
	scanf("%d",&textfile);

	stat = read(textfile,buff,100);
	printf("read from textfile returns %d\n",stat);
	buff[stat] = 0;
	printf("buffer is now -->%s<--\n",buff);
	printf("write to logfile returns %d\n",write(logfile,"hello",6));
	exit(1);
}





This session shows the programs being run.  The steps numbered show:

1. To start with, there is no "logfile.dat" file

2. There is a "textfile.dat", containing three lines of text

When I run "parent_fork":
3. The call to "vfork" returns zero, which indicates that this is running a
   child process.  In fact though, this is still the parent process running.
   So at this stage, all variables, files and so on that I touch will change
   in the "parent" thread.  For example, if I "close()" a file here, I'm
   actually closing the parent's file descriptor.

4. The call to "vfork" returns a child-id.  This indicates that the child has
   been successfully created, by the call to "execl"

5. This is the actual child process now, running the "child_fork" program.
   At this stage, the file descriptors for files that were opened by the 
   parent will have been set up in the child, so I should be able to access
   those same files (as long as I know the file descriptor numbers).  You
   can see that I am able to read the textfile...

6. But I can't write to the logfile.  This is because of the C RTL bug

7. When the child terminates, the parent realises and also finishes

8. Looking in the logfile, you can see output which was written by both 
   paths from the "vfork".  But these are both written by the parent, since
   the child doesn't really appear until after the "execl"







	$ cc parent_fork/pref=all
	$ link parent_fork
	$ cc child_fork/pref=all
	$ link child_fork
	$!done
1.	$ ty logfile.dat
	%TYPE-W-SEARCHFAIL, error searching for
SYS$SYSDEVICE:[HUDSON.ASAP.VFORK]LOGFILE.DAT;
	-RMS-E-FNF, file not found
2.	$ ty textfile.dat
	this is textfile.dat
	line 2
	line 3
	$ r parent_fork
	fileno of logfile is 4
	fileno of textfile is 3
3.	parent_fork: status from vfork = 0
	parent_fork: This is new forked process
4.	parent_fork: status from vfork = 692
	parent_fork: waiting for Child (status = 692 [0x2b4])
5.	Hello, this is child_fork, give me logfile number ? 4
	Give me textfile number ? 3
	read from textfile returns 21
	buffer is now -->this is textfile.dat
	<--
6.	write to logfile returns -1
7.	parent_fork: Child final status: 1
8.	$ type logfile.dat
	status from vfork was zero : child
	
	status from vfork nonzero : parent
	
	$ 




3446.4KZIN::HUDSONThat&#039;s what I thinkThu Apr 10 1997 06:1982
From:	VBORMC::"[email protected]" "Mats Nilsson" 10-APR-1997 07:19:54.84
To:	"[email protected] - UK Software Partner Engineering 830-4121
09-Apr-1997 1517 +0100" <[email protected]>
CC:	
Subj:	RE:  No.23091, and 25037, files and child processes

Reply to the message of Wednesday April 9, 1997 17:13 +0100
-----------------------------------------------------------------
Hello Nick

Thank you for your answer.

I understand how vfork works and the C rtl problem, but I have some more
questions.

1. If I add keyword "ctx=3Drec" to my open statement now afterwards, when
the files are already created, without this keyword, I get and errorcode
from open.

Questions:

-What does "ctx=3Drec" really mean ?
-Shall I use this keyword to open, to solv the the problem to share files
beetween processes, as I described eariler ?
-Will it be another type of file if I use this keyword to open, and is
that why I get an error from open, or why do I get this error from open
when I add this keyword ?
-Do I have to recreate the files with this keyword to avoid the error ?


As I showed in my earier example, when we closing all files in the
childprocess, and we can not do this in VMS, and all open files are
inherited by the childprocess and new files opened by th child.

Question:

What does this this affect the resources of VMS, if each user starts a
chain of up to six seven processes as every new processes in the chain
gets more and more files opened ?

Thanks

Mats
+----------------------------------------------+
!                                              !
!    oooooo     ooooo  Nectar Systems AB       !
!    ooooooo    ooooo  Mats Nilsson            !
!      oooooo   ooo    Development Manager     !
!      ooooooo  ooo    [email protected]           !
!      ooo oooo ooo    Box 124                 !
!      ooo  ooooooo    S-281 22 H=E4ssleholm     !
!    ooooo   oooooooo  Tel. +46 (0)451 893 00  !
!    ooooo    ooooooo  Fax. +46 (0)451 817 30  !
!                                              !
! -For excellence in 4GL-                      !
!                                              !
+----------------------- http://www.nectar.se -+

% ====== Internet headers and postmarks (see DECWRL::GATEWAY.DOC) ======
% Received: from mail.vbo.dec.com (mail.vbo.dec.com [16.36.208.34]) by
vbormc.vbo.dec.com (8.7.3/8.7) with ESMTP id HAA12707 for
<[email protected]>; Thu, 10 Apr 1997 07:47:46 +0200
% Received: from server21.digital.fr (server21.digital.fr [193.56.15.21]) by
mail.vbo.dec.com (8.7.3/8.7) with ESMTP id HAA06355 for
<[email protected]>; Thu, 10 Apr 1997 07:54:31 +0200 (MET DST)
% Received: from nectar (nectar.nectar.se [193.14.116.1]) by server21.digital.fr
(8.7.5/8.7) with SMTP id HAA16507 for <[email protected]>; Thu, 10 Apr
1997 07:59:34 +0200 (MET DST)
% Received: (from gmail@localhost) by nectar (8.6.12/8.6.12) id HAA20930 for
[email protected]; Thu, 10 Apr 1997 07:51:39 +0200
% Received: by gmail.nectar.se with Gmail (ginets/4.0.1) id 334c7fdf; Thu, 10
Apr 97 07:51:39 +010
% Date: Thu, 10 Apr 97 07:47:46 +0100
% Message-Id: <[email protected]>
% In-Reply-To: <[email protected]>
% From: Mats Nilsson <[email protected]>
% To: "[email protected] - UK Software Partner Engineering 830-4121
09-Apr-1997 1517 +0100" <[email protected]>
% Subject: RE:  No.23091, and 25037, files and child processes
% Mime-Version: 1.0
% Content-Type: text/plain; charset=ISO-8859-1
% Content-Transfer-Encoding: quoted-printable
3446.5KZIN::HUDSONThat&#039;s what I thinkThu Apr 10 1997 07:11132
From:	DEC:.REO.REOVTX::HUDSON       "[email protected] - UK Software
Partner Engineering 830-4121" 10-APR-1997 11:10:16.21
To:	nm%VBORMC::"[email protected]"
CC:	HUDSON
Subj:	RE:  No.23091, and 25037, files and child processes

Hello Mats

Here is some more info.  I think the whole thing may just boil down to the fact
that VMS is fundamentally different in several ways to Unix, and so while DEC C
and the C RTL do their best to give you an environment similar to the Unix one,
there are inevitably compromises and situations where you can't get identical
behaviour.

If you really need full control over file-sharing, then the best way is to use
pure RMS calls, but obviously this is VMS specific and will make your code
non-portable to Unix.



>1. If I add keyword "ctx=rec" to my open statement now afterwards, when
>the files are already created, without this keyword, I get and errorcode
>from open.

You don't say what the error is.  Maybe "errno" would give you more info.

>Questions:
>
>-What does "ctx=rec" really mean ?
>
This is a big question to answer.  Basically, the RMS file system that is used
by VMS is a RECORD management system, which doesn't fit very well to the model
used by Unix, where a file is a stream of bytes, not a series of records.

On VMS, the C RTL tries to give an approximation to Unix I/O by using a form
of RMS file called "Stream files".  If you create a file from a C program and
then do a "DIR/FULL" of it, you should see that the file format is some type
of "STREAM" format.

A limitation of stream format files is that certain RMS file sharing options
don't work.  RMS allows multiple users to share files by using locks, and
locks are done on a record-by-record basis.  Since stream files don't really
have records, then locking can't be done like that by RMS, and so it won't let
you have many people writing to the same file at once - the first person to
open a stream file for writing will get exclusive access.

In order to be able to share files in this case, you therefore need to stop
the C RTL from using "stream" format.  This is what "ctx=rec" is for.  If you
look in the C RTL manual under the description of "creat()", which talks about
all the RMS options, it says:

	Notes

	- While these options provide much flexibility and
	  functionality, many of them can also cause severe
	  problems if not used correctly.

	- You cannot share the default DEC C for
	  OpenVMS stream file I/O.  If you wish to share
	  files, you must specify "ctx=rec" to force record
	  access mode.  You must also specify the appropriate
	  "shr" options depending on the type of access you
	  want.

So "ctx=rec" is a special flag to the C RTL to say "don't use stream, use
record format".  If you create a file with this flag and do a DIR/FULL, I'd
expect you won't see "file format:stream", you'll see "variable length, max xx
bytes" or something like that.

Because you have told the C RTL to use record format, then the "shr" options
you use will take effect.


>-Shall I use this keyword to open, to solv the the problem to share files
>beetween processes, as I described eariler ?
>-Will it be another type of file if I use this keyword to open, and is
>that why I get an error from open, or why do I get this error from open
>when I add this keyword ?
>-Do I have to recreate the files with this keyword to avoid the error ?

Don't know the answer to this, it depends what the error is.  Basically if you
want to share write access, then you won't be able to do it unless you have
"ctx=rec" and "shr=....".  But if you do that then there are still limitations
on what RMS will let you do.

>As I showed in my earier example, when we closing all files in the
>childprocess, and we can not do this in VMS, and all open files are
>inherited by the childprocess and new files opened by th child.
>
>Question:
>
>What does this this affect the resources of VMS, if each user starts a
>chain of up to six seven processes as every new processes in the chain
>gets more and more files opened ?

If your parent has several open files, then does vfork/exec to create a
subprocess which runs a different program, then as we have seen, that
subprocess should have the same filenumbers open that were in the parent.

At this stage, the subprocess could do a "for (i=3;i<NFILE;i++) {close(i)};"
type thing I suppose.

As far as resources go, then every time you have a file open, you use up 1 of
your "FILLM" limit ("Open File Quota" in SHOW PROC/QUOTA), and at least 96 of
your "BYTLM" ("Buffered I/O byte count quota").  This info comes from the
OpenVMS System Manager's manual.

Both "FILLM" and "BYTLM" are "pooled" quotas.  That means that the quota
applies to all the processes and subprocesses in a tree.  So if you have a
FILLM of 100, and you open 50 files then create a subprocess, the subprocess
won't be able to open more than 50 more files (and if it did, then the parent
wouldn't be able to open any more new ones).

So if you have a parent which has files open, and then creates a child which
creates a child,... then you could quickly use up FILLM I suppose.  

FILLM and BYTLM are quotas which you can set as high as you like, like a disk
quota.  Having a high quota doesn't take up resources, but it means that a
user has the potential to use up resources.

As well as FILLM and BYTLM, which are quotas set in the AUTHORIZE utility, any
one process can't open more files than is specified by the SYSGEN parameter
CHANNELCNT.

Normally FILLM will be around 100, and CHANNELCNT is 127, so it is very
unusual to hit CHANNELCNT.

Does this help?

Regards
nick