[BACK]Return to file_lock.c CVS log [TXT][DIR] Up to [Development] / projects / ltp / lib

File: [Development] / projects / ltp / lib / file_lock.c (download)

Revision 1.2, Thu Jul 27 17:13:18 2000 UTC (17 years, 2 months ago) by alaffin
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +1 -0 lines

New additions:
 - tst_ library code.
 - new quickhit tests
 - more general code cleanup

/*
 * 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 version 2 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.
 * 
 * Further, this software is distributed without any warranty that it is
 * free of the rightful claim of any third person regarding infringement
 * or the like.  Any license provided herein, whether implied or
 * otherwise, applies only to this software file.  Patent licenses, if
 * any, provided herein do not apply to combinations of this program with
 * other software, or any other product whatsoever.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write the Free Software Foundation, Inc., 59
 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
 * 
 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
 * Mountain View, CA  94043, or:
 * 
 * http://www.sgi.com 
 * 
 * For further information regarding this notice, see: 
 * 
 * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
 */
#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"

extern int errno;

#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 */