AuLock.c revision 313a12fd
127702724Smrg/* 227702724Smrg 327702724SmrgCopyright 1988, 1998 The Open Group 427702724Smrg 527702724SmrgPermission to use, copy, modify, distribute, and sell this software and its 627702724Smrgdocumentation for any purpose is hereby granted without fee, provided that 727702724Smrgthe above copyright notice appear in all copies and that both that 827702724Smrgcopyright notice and this permission notice appear in supporting 927702724Smrgdocumentation. 1027702724Smrg 1127702724SmrgThe above copyright notice and this permission notice shall be included in 1227702724Smrgall copies or substantial portions of the Software. 1327702724Smrg 1427702724SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1527702724SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1627702724SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1727702724SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 1827702724SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 1927702724SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2027702724Smrg 2127702724SmrgExcept as contained in this notice, the name of The Open Group shall not be 2227702724Smrgused in advertising or otherwise to promote the sale, use or other dealings 2327702724Smrgin this Software without prior written authorization from The Open Group. 2427702724Smrg 2527702724Smrg*/ 2627702724Smrg 2727702724Smrg#ifdef HAVE_CONFIG_H 2827702724Smrg#include <config.h> 2927702724Smrg#endif 3027702724Smrg#include <X11/Xauth.h> 3127702724Smrg#include <X11/Xos.h> 3227702724Smrg#include <sys/stat.h> 3327702724Smrg#include <errno.h> 3427702724Smrg#include <time.h> 3527702724Smrg#define Time_t time_t 36313a12fdSmrg#ifdef HAVE_UNISTD_H 37313a12fdSmrg# include <unistd.h> 3827702724Smrg#endif 39313a12fdSmrg#ifdef WIN32 40313a12fdSmrg# include <X11/Xwindows.h> 41313a12fdSmrg# define link rename 4227702724Smrg#endif 4327702724Smrg 4427702724Smrgint 4527702724SmrgXauLockAuth ( 4627702724Smrg_Xconst char *file_name, 4727702724Smrgint retries, 4827702724Smrgint timeout, 4927702724Smrglong dead) 5027702724Smrg{ 5127702724Smrg char creat_name[1025], link_name[1025]; 5227702724Smrg struct stat statb; 5327702724Smrg Time_t now; 5427702724Smrg int creat_fd = -1; 5527702724Smrg 5627702724Smrg if (strlen (file_name) > 1022) 5727702724Smrg return LOCK_ERROR; 58313a12fdSmrg snprintf (creat_name, sizeof(creat_name), "%s-c", file_name); 59313a12fdSmrg snprintf (link_name, sizeof(link_name), "%s-l", file_name); 6027702724Smrg if (stat (creat_name, &statb) != -1) { 6127702724Smrg now = time ((Time_t *) 0); 6227702724Smrg /* 6327702724Smrg * NFS may cause ctime to be before now, special 6427702724Smrg * case a 0 deadtime to force lock removal 6527702724Smrg */ 6627702724Smrg if (dead == 0 || now - statb.st_ctime > dead) { 67313a12fdSmrg (void) remove (creat_name); 68313a12fdSmrg (void) remove (link_name); 6927702724Smrg } 7027702724Smrg } 71313a12fdSmrg 7227702724Smrg while (retries > 0) { 7327702724Smrg if (creat_fd == -1) { 7427702724Smrg creat_fd = open (creat_name, O_WRONLY | O_CREAT | O_EXCL, 0600); 7527702724Smrg if (creat_fd == -1) { 76313a12fdSmrg if (errno != EACCES && errno != EEXIST) 7727702724Smrg return LOCK_ERROR; 7827702724Smrg } else 7927702724Smrg (void) close (creat_fd); 8027702724Smrg } 8127702724Smrg if (creat_fd != -1) { 82313a12fdSmrg#ifdef HAVE_PATHCONF 83e19dfac4Smrg /* The file system may not support hard links, and pathconf should tell us that. */ 84e19dfac4Smrg if (1 == pathconf(creat_name, _PC_LINK_MAX)) { 85e19dfac4Smrg if (-1 == rename(creat_name, link_name)) { 86e19dfac4Smrg /* Is this good enough? Perhaps we should retry. TEST */ 87e19dfac4Smrg return LOCK_ERROR; 88e19dfac4Smrg } else { 89e19dfac4Smrg return LOCK_SUCCESS; 90e19dfac4Smrg } 91313a12fdSmrg } else 92e19dfac4Smrg#endif 93313a12fdSmrg { 94e19dfac4Smrg if (link (creat_name, link_name) != -1) 95e19dfac4Smrg return LOCK_SUCCESS; 96e19dfac4Smrg if (errno == ENOENT) { 97e19dfac4Smrg creat_fd = -1; /* force re-creat next time around */ 98e19dfac4Smrg continue; 99e19dfac4Smrg } 100e19dfac4Smrg if (errno != EEXIST) 101e19dfac4Smrg return LOCK_ERROR; 102e19dfac4Smrg } 10327702724Smrg } 10427702724Smrg (void) sleep ((unsigned) timeout); 10527702724Smrg --retries; 10627702724Smrg } 10727702724Smrg return LOCK_TIMEOUT; 10827702724Smrg} 109