AuLock.c revision e19dfac4
127702724Smrg/* $Xorg: AuLock.c,v 1.4 2001/02/09 02:03:42 xorgcvs Exp $ */
227702724Smrg
327702724Smrg/*
427702724Smrg
527702724SmrgCopyright 1988, 1998  The Open Group
627702724Smrg
727702724SmrgPermission to use, copy, modify, distribute, and sell this software and its
827702724Smrgdocumentation for any purpose is hereby granted without fee, provided that
927702724Smrgthe above copyright notice appear in all copies and that both that
1027702724Smrgcopyright notice and this permission notice appear in supporting
1127702724Smrgdocumentation.
1227702724Smrg
1327702724SmrgThe above copyright notice and this permission notice shall be included in
1427702724Smrgall copies or substantial portions of the Software.
1527702724Smrg
1627702724SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1727702724SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1827702724SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
1927702724SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
2027702724SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
2127702724SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2227702724Smrg
2327702724SmrgExcept as contained in this notice, the name of The Open Group shall not be
2427702724Smrgused in advertising or otherwise to promote the sale, use or other dealings
2527702724Smrgin this Software without prior written authorization from The Open Group.
2627702724Smrg
2727702724Smrg*/
2827702724Smrg/* $XFree86: xc/lib/Xau/AuLock.c,v 3.6 2002/05/31 18:45:43 dawes Exp $ */
2927702724Smrg
3027702724Smrg#ifdef HAVE_CONFIG_H
3127702724Smrg#include <config.h>
3227702724Smrg#endif
3327702724Smrg#include <X11/Xauth.h>
3427702724Smrg#include <X11/Xos.h>
3527702724Smrg#include <sys/stat.h>
3627702724Smrg#include <errno.h>
3727702724Smrg#include <time.h>
3827702724Smrg#define Time_t time_t
3927702724Smrg#ifndef X_NOT_POSIX
4027702724Smrg#include <unistd.h>
4127702724Smrg#else
4227702724Smrg#ifndef WIN32
4327702724Smrgextern unsigned	sleep ();
4427702724Smrg#else
4527702724Smrg#include <X11/Xwindows.h>
4627702724Smrg#define link rename
4727702724Smrg#endif
4827702724Smrg#endif
4927702724Smrg#ifdef __UNIXOS2__
5027702724Smrg#define link rename
5127702724Smrg#endif
5227702724Smrg
5327702724Smrgint
5427702724SmrgXauLockAuth (
5527702724Smrg_Xconst char *file_name,
5627702724Smrgint	retries,
5727702724Smrgint	timeout,
5827702724Smrglong	dead)
5927702724Smrg{
6027702724Smrg    char	creat_name[1025], link_name[1025];
6127702724Smrg    struct stat	statb;
6227702724Smrg    Time_t	now;
6327702724Smrg    int		creat_fd = -1;
6427702724Smrg
6527702724Smrg    if (strlen (file_name) > 1022)
6627702724Smrg	return LOCK_ERROR;
6727702724Smrg    (void) strcpy (creat_name, file_name);
6827702724Smrg    (void) strcat (creat_name, "-c");
6927702724Smrg    (void) strcpy (link_name, file_name);
7027702724Smrg    (void) strcat (link_name, "-l");
7127702724Smrg    if (stat (creat_name, &statb) != -1) {
7227702724Smrg	now = time ((Time_t *) 0);
7327702724Smrg	/*
7427702724Smrg	 * NFS may cause ctime to be before now, special
7527702724Smrg	 * case a 0 deadtime to force lock removal
7627702724Smrg	 */
7727702724Smrg	if (dead == 0 || now - statb.st_ctime > dead) {
7827702724Smrg	    (void) unlink (creat_name);
7927702724Smrg	    (void) unlink (link_name);
8027702724Smrg	}
8127702724Smrg    }
8227702724Smrg
8327702724Smrg    while (retries > 0) {
8427702724Smrg	if (creat_fd == -1) {
8527702724Smrg	    creat_fd = open (creat_name, O_WRONLY | O_CREAT | O_EXCL, 0600);
8627702724Smrg	    if (creat_fd == -1) {
8727702724Smrg		if (errno != EACCES)
8827702724Smrg		    return LOCK_ERROR;
8927702724Smrg	    } else
9027702724Smrg		(void) close (creat_fd);
9127702724Smrg	}
9227702724Smrg	if (creat_fd != -1) {
93e19dfac4Smrg#ifndef X_NOT_POSIX
94e19dfac4Smrg	    /* The file system may not support hard links, and pathconf should tell us that. */
95e19dfac4Smrg	    if (1 == pathconf(creat_name, _PC_LINK_MAX)) {
96e19dfac4Smrg		if (-1 == rename(creat_name, link_name)) {
97e19dfac4Smrg		    /* Is this good enough?  Perhaps we should retry.  TEST */
98e19dfac4Smrg		    return LOCK_ERROR;
99e19dfac4Smrg		} else {
100e19dfac4Smrg		    return LOCK_SUCCESS;
101e19dfac4Smrg		}
102e19dfac4Smrg	    } else {
103e19dfac4Smrg#endif
104e19dfac4Smrg	    	if (link (creat_name, link_name) != -1)
105e19dfac4Smrg		    return LOCK_SUCCESS;
106e19dfac4Smrg		if (errno == ENOENT) {
107e19dfac4Smrg		    creat_fd = -1;	/* force re-creat next time around */
108e19dfac4Smrg		    continue;
109e19dfac4Smrg	    	}
110e19dfac4Smrg	    	if (errno != EEXIST)
111e19dfac4Smrg		    return LOCK_ERROR;
112e19dfac4Smrg#ifndef X_NOT_POSIX
113e19dfac4Smrg	   }
114e19dfac4Smrg#endif
11527702724Smrg	}
11627702724Smrg	(void) sleep ((unsigned) timeout);
11727702724Smrg	--retries;
11827702724Smrg    }
11927702724Smrg    return LOCK_TIMEOUT;
12027702724Smrg}
121