1 #pragma ident "%Z%%M% %I% %E% SMI" 2 /* 3 * lib/krb5/os/lock_file.c 4 * 5 * Copyright 1990, 1998 by the Massachusetts Institute of Technology. 6 * All Rights Reserved. 7 * 8 * Export of this software from the United States of America may 9 * require a specific license from the United States Government. 10 * It is the responsibility of any person or organization contemplating 11 * export to obtain such a license before exporting. 12 * 13 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 14 * distribute this software and its documentation for any purpose and 15 * without fee is hereby granted, provided that the above copyright 16 * notice appear in all copies and that both that copyright notice and 17 * this permission notice appear in supporting documentation, and that 18 * the name of M.I.T. not be used in advertising or publicity pertaining 19 * to distribution of the software without specific, written prior 20 * permission. Furthermore if you modify this software you must label 21 * your software as modified software and not distribute it in such a 22 * fashion that it might be confused with the original M.I.T. software. 23 * M.I.T. makes no representations about the suitability of 24 * this software for any purpose. It is provided "as is" without express 25 * or implied warranty. 26 * 27 * 28 * libos: krb5_lock_file routine 29 */ 30 31 #include <k5-int.h> 32 #include <stdio.h> 33 34 #if !defined(_WIN32) 35 36 /* Unix version... */ 37 38 #if HAVE_UNISTD_H 39 #include <unistd.h> 40 #endif 41 42 #include <errno.h> 43 44 #ifdef HAVE_FCNTL_H 45 #include <fcntl.h> 46 #endif 47 48 #if defined(HAVE_FCNTL_H) && defined(F_SETLKW) && defined(F_RDLCK) 49 #define POSIX_FILE_LOCKS 50 #endif 51 52 #ifdef HAVE_FLOCK 53 #ifndef sysvimp 54 #include <sys/file.h> 55 #endif 56 #else 57 #ifndef LOCK_SH 58 #define LOCK_SH 0 59 #define LOCK_EX 0 60 #define LOCK_UN 0 61 #endif 62 #endif 63 64 /*ARGSUSED*/ 65 krb5_error_code 66 krb5_lock_file(krb5_context context, int fd, int mode) 67 { 68 int lock_flag = -1; 69 krb5_error_code retval = 0; 70 #ifdef POSIX_FILE_LOCKS 71 int lock_cmd = F_SETLKW; 72 static struct flock flock_zero; 73 struct flock lock_arg = { 0 }; 74 75 lock_arg = flock_zero; 76 #endif 77 78 switch (mode & ~KRB5_LOCKMODE_DONTBLOCK) { 79 case KRB5_LOCKMODE_SHARED: 80 #ifdef POSIX_FILE_LOCKS 81 lock_arg.l_type = F_RDLCK; 82 #endif 83 lock_flag = LOCK_SH; 84 break; 85 case KRB5_LOCKMODE_EXCLUSIVE: 86 #ifdef POSIX_FILE_LOCKS 87 lock_arg.l_type = F_WRLCK; 88 #endif 89 lock_flag = LOCK_EX; 90 break; 91 case KRB5_LOCKMODE_UNLOCK: 92 #ifdef POSIX_FILE_LOCKS 93 lock_arg.l_type = F_UNLCK; 94 #endif 95 lock_flag = LOCK_UN; 96 break; 97 } 98 99 if (lock_flag == -1) 100 return(KRB5_LIBOS_BADLOCKFLAG); 101 102 if (mode & KRB5_LOCKMODE_DONTBLOCK) { 103 #ifdef POSIX_FILE_LOCKS 104 lock_cmd = F_SETLK; 105 #endif 106 #ifdef HAVE_FLOCK 107 lock_flag |= LOCK_NB; 108 #endif 109 } 110 111 #ifdef POSIX_FILE_LOCKS 112 lock_arg.l_whence = 0; 113 lock_arg.l_start = 0; 114 lock_arg.l_len = 0; 115 if (fcntl(fd, lock_cmd, &lock_arg) == -1) { 116 if (errno == EACCES || errno == EAGAIN) /* see POSIX/IEEE 1003.1-1988, 117 6.5.2.4 */ 118 return(EAGAIN); 119 if (errno != EINVAL) /* Fall back to flock if we get EINVAL */ 120 return(errno); 121 retval = errno; 122 } else 123 return 0; /* We succeeded. Yay. */ 124 #endif 125 126 #ifdef HAVE_FLOCK 127 if (flock(fd, lock_flag) == -1) 128 retval = errno; 129 #endif 130 131 return retval; 132 } 133 #else /* Windows or Macintosh */ 134 135 krb5_error_code 136 krb5_lock_file(context, fd, mode) 137 krb5_context context; 138 int fd; 139 int mode; 140 { 141 return 0; 142 } 143 #endif 144