Solved

file open - read -write problem

Posted on 2000-02-16
19
166 Views
Last Modified: 2010-03-05
I'd like to open file, read file , modify file, rewrite file and then close file.
It is done like this:

if(open(FILE_USERS,"<FILE_USERS"))
{@fileUsers=<FILE_USERS>;
 modifyFile(@fileUsers);
 if(open(FILE_USERS,">FILE_USERS"))
  {print FILE_USERS "$NewFileContent";}
 close(FILE_USERS);
}

This works fine, but when 2 users connect almost simultaneously the problem arise in that way:

1) User 1 reads file
2) User 2 reads file (not supposed until User 2 finish with the file)
3) User 1 modify file
4) User 2 modify file
5) User 1 rerecords and close file
6) User 2 rerecords and close file

So actually User 2 doesn't see modification made to file by user 1 becouse he reads file before it recorded by user 1. And all modification made by user 1 is lost.

Is there any way prevent user 2 read and modify file until User 1 (who opened file first) finished?
0
Comment
Question by:serg111
  • 8
  • 5
  • 4
  • +2
19 Comments
 
LVL 3

Expert Comment

by:RobWMartin
Comment Utility
If you are on an O/S that supports flock, you can use it, as follows:

if(open(FILE_USERS,"<FILE_USERS"))
{
 flock(FILE_USERS,LOCK_EX);
 @fileUsers=<FILE_USERS>;
 modifyFile(@fileUsers);
 if(open(FILE_USERS,">FILE_USERS"))
  {print FILE_USERS "$NewFileContent";}
 close(FILE_USERS);
 flock(FILE_USERS,LOCK_UN);
}

This works as long as both users are accessing the file through the same script.  I.e. both have to attempt the flock.

Rob

0
 
LVL 3

Expert Comment

by:guadalupe
Comment Utility
Use the perl flock() command:

flock(FILEHANDLE, 1) #To lock

flock(FILEHANDLE, 0) #To unlock
0
 
LVL 3

Expert Comment

by:RobWMartin
Comment Utility
BTW: you can read the details in perlfunc, i.e.:

perldoc -f flock

The second argument specifies the type of lock, or action.  Thus, LOCK_EX says lock the filehandle exclusively (i.e. no one else can access it, will it is locked); the LOCK_UN says unlock the filehandle.  This is a blocking lock, so if the flock never gets a lock for whatever reason it will continue waiting indefinitely.

0
 
LVL 2

Author Comment

by:serg111
Comment Utility
It looks like flock() doesn't work:
I tested following code

open(FILE_USERS1,"<$filePath");
$iRet=flock(FILE_CLIENTS1, 2);
open(FILE_USERS2,">>$filePath");
$iRet=flock(FILE_CLIENTS1, 8);

Both flock returns 1
and both open() successfully opened file.

Regards
0
 
LVL 2

Author Comment

by:serg111
Comment Utility
Sorry there is misspelling in code it should look like h

open(FILE_USERS1,"<$filePath");
$iRet=flock(FILE_USERS1, 2);
open(FILE_USERS2,">>$filePath");
$iRet=flock(FILE_USERS1, 8);

0
 
LVL 84

Expert Comment

by:ozo
Comment Utility
Did you open FILE_CLIENTS1?
0
 
LVL 2

Author Comment

by:serg111
Comment Utility
in both cases open() return 1

Thanks
0
 
LVL 3

Expert Comment

by:RobWMartin
Comment Utility
You misunderstand the purpose of flock.  It will block indefinitely if called the second time with LOCK_EX (i.e. 2), waiting for someone to unlock the file.  It is an advisory lock, not a real file-system lock.  So, before you try to open a file that might have multiple processes access it, you try to lock it first with flock.  If some other, cooperating, process has a valid flock on the file, your flock will sit and wait.  When it returns, then you are safe to go on and open the file.  Thus, if you try the following, your script will hang:

$iRet=flock(FILE_CLIENTS1, 2);               #  2 (LOCK_EX) here
open(FILE_USERS1,"<$filePath");


$iRet=flock(FILE_CLIENTS1, 2);               #  2 (LOCK_EX) here, also.
open(FILE_USERS2,">>$filePath");

The second will block forever.  It is protecting the file like it should.

Hope this clarifies it for you.

Rob
0
 
LVL 3

Expert Comment

by:RobWMartin
Comment Utility
Well, if I could get it in the right order, it would help:

open(FILE_USERS1,"<$filePath");
$iRet=flock(FILE_CLIENTS1, 2);               #  2 (LOCK_EX) here


open(FILE_USERS2,">>$filePath");
$iRet=flock(FILE_CLIENTS2, 2);               #  2 (LOCK_EX) here, also.
 

In other words, you may open successfully, but don't mess with it until you get a successful lock.

Rob
0
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 
LVL 2

Author Comment

by:serg111
Comment Utility
OK.
I have tested this code

open(FILE_USERS1,"<$filePath");
$iRet=flock(FILE_CLIENTS1, 2);
open(FILE_USERS2,"<<$filePath");
$iRet=flock(FILE_CLIENTS2, 2);  

For first time it worked fine (first flock() return 1 and second doesn't return.
But when I call script now first flock() doesn't return. So it looks like it is locked forever. When I added $iRet=flock(FILE_CLIENTS2, 8) it does not help. Is there any way to remove the lock?

0
 

Expert Comment

by:Whitty
Comment Utility
You should use flock() as follows:

open(FILE_USERS1,"<$filePath");
$retVal=flock(FILE_CLIENTS1, 2);               #  Performs and exclusive lock
# Process file as needed
$retVal=flock(FILE_CLIENTS1, 8);               #  Removes the lock
close(FILE_CLIENTS1);

Although the file is automatically "unlocked" when closed, it is a good idea to manually perform the unlock just to be safe.

Now if the same application is called again, for say the second user, the flock() for the second user will wait until any existing locks are released.

For info, see the Perl Cookbook, pg. 245.

Hope this helps...

Whitty

                       
0
 
LVL 3

Expert Comment

by:RobWMartin
Comment Utility
Just realized I cut and pasted the wrong code.  The FILEHANDLES don't match up.  

open(FILE_USERS1,"<$filePath");
$iRet=flock(FILE_USERS1, 2);               #  2 (LOCK_EX) here


open(FILE_USERS2,">>$filePath");
$iRet=flock(FILE_USERS2, 2);               #  2 (LOCK_EX) here, also.


 

0
 
LVL 2

Author Comment

by:serg111
Comment Utility
More:

This code works fine with other files. I'm quite happy with it, but I still have prblem with one file "clients/M" where this code is not working.
I tested this file first and probably it remains locked.

Any ideas please
0
 
LVL 3

Accepted Solution

by:
RobWMartin earned 40 total points
Comment Utility
Odd that it is stuck like that.  However, to break the lock, you just need to unlink the file.  As root,

cp thefile{,.bak}
rm thefile
cp thefile{.bak,}

Rob
0
 

Expert Comment

by:Whitty
Comment Utility
Are you implementing an unlock call?

flock(FILE_CLIENTS1, 8);               #  Removes the lock

Whitty
0
 
LVL 3

Expert Comment

by:RobWMartin
Comment Utility
Don't think that works if some other (rampaging) process has it locked.  If I understand serg111's (current) problem, it's that one of his initial tests with locking still has the file locked somehow(?????)  Requires intervention outside the flock function.

Rob
0
 

Expert Comment

by:Whitty
Comment Utility
If that is the case, killing the rampaging process would terminate the lock.  Perl's built-in cleanup would handle this by closing any open file handles.  When a file is closed, the lock is automatically terminated (it's just good practice to do it manually prior to the close).

Whitty
0
 
LVL 3

Expert Comment

by:RobWMartin
Comment Utility
Agreed, but the file removal method above doesn't require serg111 to look for the rampaging process.  I'm still not certain how the file can still be locked.  Unless, serg111 is in bash and did ^Z vs ^C.

????

Rob
0
 

Expert Comment

by:Whitty
Comment Utility
Good point.  Since serg111 hasn't responded to any of our comments for a while, I assume everything is working now?!?

Whitty
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

On Microsoft Windows, if  when you click or type the name of a .pl file, you get an error "is not recognized as an internal or external command, operable program or batch file", then this means you do not have the .pl file extension associated with …
There are many situations when we need to display the data in sorted order. For example: Student details by name or by rank or by total marks etc. If you are working on data driven based projects then you will use sorting techniques very frequently.…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now