/*
This program creates and locks ./example.lock, waiting for the user
before unlocking the file again.
Compilation: g++ ./code.cpp -o programname
By running this program in many terminals simultanously, file
locking can be demonstrated.
1 $ ./programname read
2 $ ./programname write first
3 $ ./programname write second
4 $ ./programname read
References:
http://linux.die.net/man/2/flock
http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=144
http://www.site.uottawa.ca/~lucia/courses/2131-05/labs/Lab3/CommandLineArguments.html
http://www.oracle.com/technology/documentation/berkeley-db/xml/api_reference/CXX/frame_main.html
(The Db::fd() method provides access to a file descriptor representative of the underlying database.
A file descriptor referring to the same file will be returned to all processes that call Db::open()
with the same file parameter.
This file descriptor may be safely used as a parameter to the fcntl(2) and flock(2) locking functions.
*/
#include <iostream> // for std::cin, std::cout std::cerr
#include <string> // standard C++ string
#include <fstream> // file I/O, ex: ifstream, ofstream
using namespace std; // to write XYZ instead of std:XYZ, ex: cout
#include <sys/file.h> // for flock(2)
#define FILENAME "example.lock"
int main(int argc,char **argv)
{
for(int i = 0; i<argc && 1==0; i++)
{
if (i==0) cout << "argc = " << argc << endl;
cout << "argv[" << i << "] = " << argv[i] << endl;
}
string programname=string(argv[0]);
if (argc<2)
{
cerr<<"Purpose -- demonstrate file locking"<<endl;
cerr<<"./"<<programname << " read"<<endl;
cerr<<"./"<<programname << " write something"<<endl;
exit(1);
}
string locktype=string(argv[1]);
string label="";
if ( locktype=="read")
{
label="not used";
}
else if (locktype=="write")
{
if (argc<3)
{
cerr<<"./"<<programname << " write something"<<endl;
exit(1);
}
label=string(argv[2]);
}
else
{
cerr<<"error: unsupported locktype: "<<locktype<<endl;
exit(1);
}
string lockfile=FILENAME; // name of lockfile
int fd; // associated file descriptor
fd=open(lockfile.c_str(),O_RDWR|O_CREAT, 0644);
if (fd==-1)
{
cerr<<"error: could not open file: "<< lockfile<<endl;
exit(1);
}
// lock the file
if (locktype=="write")
{
cerr<<"./"<< lockfile << " ("<<fd<<"): ";
cerr<<"waiting for an exclusive write lock ... ";
if (flock(fd,LOCK_EX) != 0)
{
cerr<<endl<<"error: flock(fd,LOCK_EX):"<<endl;
exit(1);
}
cerr<<" got it!"<<endl;
// append the text label to the lock file
ofstream outfile;
outfile.open(lockfile.c_str(), ios::app);
if (!outfile)
{
cerr<<"error: <ofstream>: unable to open file: ./"<<lockfile<<endl;
exit(1);
}
outfile<<label<<endl;
outfile.close();
}
else if (locktype=="read")
{
cerr<<"./"<< lockfile <<" ("<<fd<<"): ";
cerr<<"waiting for a shared read lock ... ";
if (flock(fd,LOCK_SH) != 0)
{
cerr<<endl<<"error: flock(fd,LOCK_SH): "<<endl;
exit(1);
}
cerr<<" got it!"<<endl;
// read the content of the lock file using C++ ifstream
ifstream infile;
infile.open(lockfile.c_str());
if (!infile)
{
cerr<<"error: <ifstream>: unable to open file: ./"<< lockfile<<endl;
exit(1);
}
string line;
int i=0;
while (getline(infile,line))
{
cout<<"./"<<lockfile<<", "<<++i<<": " << line<<endl;
}
infile.close();
}
string a;
cerr<<"To cancel the lock, press any character followed by enter: ";
cin>>a;
// close the lockfile
if (close(fd)==-1)
{
cerr<<"error: something went wrong when closing the lock file"<<endl;
}
exit(0);
}
Returner til Utvikling i Linux
Registrerte brukere: Google [Bot]