[BACK]Return to file_lock.c CVS log [TXT][DIR] Up to [Development] / xfs-cmds / xfstests / lib

File: [Development] / xfs-cmds / xfstests / lib / file_lock.c (download)

Revision 1.2, Wed Nov 9 02:50:19 2005 UTC (11 years, 11 months ago) by nathans.longdrop.melbourne.sgi.com
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +14 -28 lines

Update copyright annotations and license boilerplates to correspond with SGI Legals preferences.
Merge of master-melb:xfs-cmds:24329a by kenmcd.

/*
 * Copyright (c) 2000 Silicon Graphics, Inc.
 * All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it would be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write the Free Software Foundation,
 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/param.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <sys/sysmacros.h>
#include <string.h> /* memset, strerror */
#include "file_lock.h"


#ifndef EFSEXCLWR
#define EFSEXCLWR	503
#endif

/*
 * String containing the last system call.
 *
 */
char Fl_syscall_str[128];

static char errmsg[256];

/***********************************************************************
 *
 * Test interface to the fcntl system call.
 * It will loop if the LOCK_NB flags is NOT set.
 ***********************************************************************/
int
file_lock(fd, flags, errormsg)
int fd;
int flags;
char **errormsg;
{
        register int cmd, ret;
        struct flock flocks;

        memset(&flocks, 0, sizeof(struct flock));

        if (flags&LOCK_NB)
                cmd = F_SETLK;
        else
                cmd = F_SETLKW;

        flocks.l_whence = 0;
        flocks.l_start = 0;
        flocks.l_len = 0;

        if (flags&LOCK_UN)
                flocks.l_type = F_UNLCK;
        else if (flags&LOCK_EX)
                flocks.l_type = F_WRLCK;
        else if (flags&LOCK_SH)
                flocks.l_type = F_RDLCK;
        else {
                errno = EINVAL;
	    if ( errormsg != NULL ) {
		sprintf(errmsg,
		    "Programmer error, called file_lock with in valid flags\n");
		*errormsg = errmsg;
            }
            return -1;
        }

	sprintf(Fl_syscall_str,
	    "fcntl(%d, %d, &flocks): type:%d whence:%d, start:%lld len:%lld\n",
                fd, cmd, flocks.l_type, flocks.l_whence,
		(long long)flocks.l_start, (long long)flocks.l_len);

	while (1) {
            ret = fcntl(fd, cmd, &flocks);

	    if ( ret < 0 ) {
	        if ( cmd == F_SETLK )
	            switch (errno) {
		       /* these errors are okay */
		        case EACCES:	/* Permission denied */
		        case EINTR:		/* interrupted system call */
#ifdef EFILESH
		        case EFILESH:	/* file shared */
#endif
		        case EFSEXCLWR:	/* File is write protected */
			    continue;	/* retry getting lock */
	        }
	        if ( errormsg != NULL ) {
	            sprintf(errmsg, "fcntl(%d, %d, &flocks): errno:%d %s\n",
		        fd, cmd, errno, strerror(errno));
		    *errormsg = errmsg;
	        }
	        return -1;
	    }
	    break;
	}

        return ret;

}	/* end of file_lock */

/***********************************************************************
 *
 * Test interface to the fcntl system call.
 * It will loop if the LOCK_NB flags is NOT set.
 ***********************************************************************/
int
record_lock(fd, flags, start, len, errormsg)
int fd;
int flags;
int start;
int len;
char **errormsg;
{
        register int cmd, ret;
        struct flock flocks;

        memset(&flocks, 0, sizeof(struct flock));

        if (flags&LOCK_NB)
                cmd = F_SETLK;
        else
                cmd = F_SETLKW;

        flocks.l_whence = 0;
        flocks.l_start = start;
        flocks.l_len = len;

        if (flags&LOCK_UN)
                flocks.l_type = F_UNLCK;
        else if (flags&LOCK_EX)
                flocks.l_type = F_WRLCK;
        else if (flags&LOCK_SH)
                flocks.l_type = F_RDLCK;
        else {
                errno = EINVAL;
	    if ( errormsg != NULL ) {
		sprintf(errmsg,
		    "Programmer error, called record_lock with in valid flags\n");
		*errormsg = errmsg;
            }
            return -1;
        }

	sprintf(Fl_syscall_str,
	    "fcntl(%d, %d, &flocks): type:%d whence:%d, start:%lld len:%lld\n",
                fd, cmd, flocks.l_type, flocks.l_whence,
		(long long)flocks.l_start, (long long)flocks.l_len);

	while (1) {
            ret = fcntl(fd, cmd, &flocks);

	    if ( ret < 0 ) {
	        if ( cmd == F_SETLK )
	            switch (errno) {
		       /* these errors are okay */
		        case EACCES:	/* Permission denied */
		        case EINTR:		/* interrupted system call */
#ifdef EFILESH
		        case EFILESH:	/* file shared */
#endif
		        case EFSEXCLWR:	/* File is write protected */
			    continue;	/* retry getting lock */
	        }
	        if ( errormsg != NULL ) {
	            sprintf(errmsg, "fcntl(%d, %d, &flocks): errno:%d %s\n",
		        fd, cmd, errno, strerror(errno));
		    *errormsg = errmsg;
	        }
	        return -1;
	    }
	    break;
	}

        return ret;

}	/* end of record_lock */