Home | History | Annotate | Download | only in sys
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 
     22 /*
     23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 /*	Copyright (c) 1988 AT&T	*/
     28 /*	  All Rights Reserved  	*/
     29 
     30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     31 
     32 #include <sys/feature_tests.h>
     33 
     34 #if !defined(_LP64) && _FILE_OFFSET_BITS == 64
     35 #define	__lockf		__lockf64
     36 #endif
     37 
     38 #include "lint.h"
     39 #include <sys/types.h>
     40 #include <unistd.h>
     41 #include <errno.h>
     42 #include <fcntl.h>
     43 
     44 int
     45 __lockf(int fildes, int function, off_t size)
     46 {
     47 	struct flock l;
     48 	int rv;
     49 
     50 	l.l_whence = 1;
     51 	if (size < 0) {
     52 		l.l_start = size;
     53 		l.l_len = -size;
     54 	} else {
     55 		l.l_start = (off_t)0;
     56 		l.l_len = size;
     57 	}
     58 	switch (function) {
     59 	case F_ULOCK:
     60 		l.l_type = F_UNLCK;
     61 		rv = fcntl(fildes, F_SETLK, &l);
     62 		break;
     63 	case F_LOCK:
     64 		l.l_type = F_WRLCK;
     65 		rv = fcntl(fildes, F_SETLKW, &l);
     66 		break;
     67 	case F_TLOCK:
     68 		l.l_type = F_WRLCK;
     69 		rv = fcntl(fildes, F_SETLK, &l);
     70 		break;
     71 	case F_TEST:
     72 		l.l_type = F_WRLCK;
     73 		rv = fcntl(fildes, F_GETLK, &l);
     74 		if (rv != -1) {
     75 			if (l.l_type == F_UNLCK)
     76 				return (0);
     77 			else {
     78 				errno = EAGAIN;
     79 				return (-1);
     80 			}
     81 		}
     82 		break;
     83 	default:
     84 		errno = EINVAL;
     85 		return (-1);
     86 	}
     87 	if (rv < 0) {
     88 		switch (errno) {
     89 		case EMFILE:
     90 		case ENOSPC:
     91 		case ENOLCK:
     92 			/*
     93 			 * A deadlock error is given if we run out of resources,
     94 			 * in compliance with /usr/group standards.
     95 			 */
     96 			errno = EDEADLK;
     97 			break;
     98 		default:
     99 			break;
    100 		}
    101 	}
    102 	return (rv);
    103 }
    104