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