How to Lock In HP-UX

Hi ,

How should i implemet a lock function Hp-ux .

I want to a lock a file through fcntl in Hp-ux .

But is not locking properly .

Thanks
Narendra

hpux does not have mandatory locking - that means every process that opens the file has to play by the rules. So, if you lock your file, then run another program that does not play by those rules, the lock will not work. It's like obeying a traffic light. Some people break the rules and do not stop on red. There is no physical barrier to stop them - a physical barrier at a traffic light is like manadtory locking. They cannot run the red light/They can't play with the file no matter what

Please show your code.

As HP-UX does not provide mandactory locking, so is there way to lock a file?
If yes can you please provide me more details in to the same?

can I use IPC to lock file ?

Thanks,
Manju

When you drive a car and come to a traffic light - and the light is green - you go thru the intersection. If the light is red, you stop. The traffic light works because everyone agrees to stop on red, well most of the time.

A system without mandatory locking works just like the traffic light. Every program accessing the file has to agree to check the lock and abide by it.

A not-very-good option:

  1. mv the file to a directory you own while your program accesses it.
  2. mv the file back to where it belongs when you are done.

What problem are you trying to solve?

I just tested manditory locking in HP-UX and it works as well as it works for any other version of unix.

$ chmod 666 datafile
$ cp datafile1 datafile
$ ./locktest &
[1]     1302
$ cp datafile2 datafile
$ datafile2 line 1
datafile2 line 2
$
[1] +  Done                    ./locktest &
$
$
$ cp datafile1 datafile
$ chmod 2666 datafile
$ ./locktest &
[1]     1330
$ cp datafile2 datafile
cp: cannot create datafile: Resource temporarily unavailable
$ datafile1 line 1
datafile1 line 2
$
[1] +  Done                    ./locktest &
$
$ uname -srv
HP-UX B.11.00 A
$ cat locktest.c
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>

main(void)
{
        char buff[250];
        FILE *F;
        struct flock mylock;
        int fd, iret;
        fd = open("datafile", O_RDWR);

        mylock.l_type = F_WRLCK;
        mylock.l_whence = SEEK_SET;
        mylock.l_start = 0;
        mylock.l_len = 0;
        iret = fcntl(fd,F_SETLK, &mylock);
        if (iret == -1) {
                 if ((errno == EACCES) || (errno == EAGAIN)) {
                        printf("locked \n");
                        exit(1);
                } else {
                        printf("fcntl failed\n");
                        exit(1);
                }
        }
        sleep(30);
        F = fdopen(fd, "r");
        while (fgets(buff,250,F)) {
                fputs(buff,stdout);
        }
        exit(0);
}

I guess I wasn't clear. HPUX (11.0) follows the POSIX.1 standard for fcntl.

http://www.opengroup.org/onlinepubs/009695399/functions/fcntl.html
Please note the last paragraph that states why mandatory locking is not part of
the standard.

mandatory locking: locks enforced by the kernel on the open, read, write etc. system calls. Not based on fcntl. As long as the process calls fcntl first to get a lock, it's obeying the traffic cop rules. Mandaory locking does not allow circumventing the rules.

This is my take on it anyway, YMMV

I checked the fcntl locking with two programs, as Jim mentioned in his reply the mandatory locking didn't worked for me in HP-UX.
I have cut pasted both programs for reference.

The scenario I followed to test the locking.

  1. first I ran ./locktest executable in background

  2. I ran ./locktest1 executable, This program will check the lock and after seeing it locked it tries to write into that file. According to my understanding as the file is locked by "locktest" process
    It should not allow "locktest1" process to write into it, but in this case the "locktest1" process is able to write into that file.

Please let me know if I'm missing anything.

Jim:
>> What problem are you trying to solve?
I'm trying to lock file using fcntl or lockf function on HP-UX, In my case I have 2 programs which are trying to update single file. In order to synchronize this I thought locking is better option.

Now also I can do it, I can modify my program to work based on the return value of fcntl() function.

I was just curious and wanted to know why the mandatory locking is not working in HP-UX. Is there any other way so that I can lock (mandatory) file in HP-UX? I,e using IPC's.

Thanks Jim and Perderbo for your answers.

$ cat locktest.c

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>

main(void)
{
char buff[250];
FILE *F;
struct flock mylock;
int fd, iret,i;
fd = open("datafile", O_APPEND | O_RDWR);

    mylock.l_type = F_WRLCK;
    mylock.l_whence = SEEK_SET;
    mylock.l_start = 0;
    mylock.l_len = 0;
    iret = fcntl\(fd,F_SETLK, &mylock\);
    if \(iret == -1\) \{
             if \(\(errno == EACCES\) || \(errno == EAGAIN\)\) \{
                    printf\("locked \\n"\);
                    exit\(1\);
            \} else \{
                    printf\("fcntl failed\\n"\);
                    exit\(1\);
            \}
    \}
    for\(i=0;i&lt;20;i\+\+\)
    \{
            sleep\(2\);
            write\(fd,"A",1\);
    \}
    F = fdopen\(fd, "r"\);
    while \(fgets\(buff,250,F\)\) \{
            fputs\(buff,stdout\);
    \}
    close\(fd\);
    exit\(0\);

}

$cat locktest1.c
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>

main(void)
{
char buff[250];
FILE *F;
struct flock mylock;
int fd, iret,i;
fd = open("datafile", O_APPEND | O_RDWR);

    mylock.l_type = F_WRLCK;
    mylock.l_whence = SEEK_SET;
    mylock.l_start = 0;
    mylock.l_len = 0;
    iret = fcntl\(fd,F_SETLK, &mylock\);
    if \(iret == -1\) \{
             if \(\(errno == EACCES\) || \(errno == EAGAIN\)\) \{
                    printf\("locked \\n"\);
                    for\(i=0;i&lt;20;i\+\+\)
                    \{
                            write\(fd,"B",1\);
                    \}
                    exit\(1\);
            \} else \{
                    printf\("fcntl failed\\n"\);
                    exit\(1\);
            \}
    \}
    F = fdopen\(fd, "r"\);
    while \(fgets\(buff,250,F\)\) \{
            fputs\(buff,stdout\);
    \}
    close\(fd\);
    exit\(0\);

}

I put a lengthy sleep in my code so the lock stayed around for a while. While a manditory lock is in effect no process can write to the file. So when I tried a simple cp to the file I got:
$ cp datafile2 datafile
cp: cannot create datafile: Resource temporarily unavailable

But I did that quickly, while the locking process was still asleep.