AuLock.c revision e19dfac4
1/* $Xorg: AuLock.c,v 1.4 2001/02/09 02:03:42 xorgcvs Exp $ */
2
3/*
4
5Copyright 1988, 1998  The Open Group
6
7Permission to use, copy, modify, distribute, and sell this software and its
8documentation for any purpose is hereby granted without fee, provided that
9the above copyright notice appear in all copies and that both that
10copyright notice and this permission notice appear in supporting
11documentation.
12
13The above copyright notice and this permission notice shall be included in
14all copies or substantial portions of the Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
19OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
23Except as contained in this notice, the name of The Open Group shall not be
24used in advertising or otherwise to promote the sale, use or other dealings
25in this Software without prior written authorization from The Open Group.
26
27*/
28/* $XFree86: xc/lib/Xau/AuLock.c,v 3.6 2002/05/31 18:45:43 dawes Exp $ */
29
30#ifdef HAVE_CONFIG_H
31#include <config.h>
32#endif
33#include <X11/Xauth.h>
34#include <X11/Xos.h>
35#include <sys/stat.h>
36#include <errno.h>
37#include <time.h>
38#define Time_t time_t
39#ifndef X_NOT_POSIX
40#include <unistd.h>
41#else
42#ifndef WIN32
43extern unsigned	sleep ();
44#else
45#include <X11/Xwindows.h>
46#define link rename
47#endif
48#endif
49#ifdef __UNIXOS2__
50#define link rename
51#endif
52
53int
54XauLockAuth (
55_Xconst char *file_name,
56int	retries,
57int	timeout,
58long	dead)
59{
60    char	creat_name[1025], link_name[1025];
61    struct stat	statb;
62    Time_t	now;
63    int		creat_fd = -1;
64
65    if (strlen (file_name) > 1022)
66	return LOCK_ERROR;
67    (void) strcpy (creat_name, file_name);
68    (void) strcat (creat_name, "-c");
69    (void) strcpy (link_name, file_name);
70    (void) strcat (link_name, "-l");
71    if (stat (creat_name, &statb) != -1) {
72	now = time ((Time_t *) 0);
73	/*
74	 * NFS may cause ctime to be before now, special
75	 * case a 0 deadtime to force lock removal
76	 */
77	if (dead == 0 || now - statb.st_ctime > dead) {
78	    (void) unlink (creat_name);
79	    (void) unlink (link_name);
80	}
81    }
82
83    while (retries > 0) {
84	if (creat_fd == -1) {
85	    creat_fd = open (creat_name, O_WRONLY | O_CREAT | O_EXCL, 0600);
86	    if (creat_fd == -1) {
87		if (errno != EACCES)
88		    return LOCK_ERROR;
89	    } else
90		(void) close (creat_fd);
91	}
92	if (creat_fd != -1) {
93#ifndef X_NOT_POSIX
94	    /* The file system may not support hard links, and pathconf should tell us that. */
95	    if (1 == pathconf(creat_name, _PC_LINK_MAX)) {
96		if (-1 == rename(creat_name, link_name)) {
97		    /* Is this good enough?  Perhaps we should retry.  TEST */
98		    return LOCK_ERROR;
99		} else {
100		    return LOCK_SUCCESS;
101		}
102	    } else {
103#endif
104	    	if (link (creat_name, link_name) != -1)
105		    return LOCK_SUCCESS;
106		if (errno == ENOENT) {
107		    creat_fd = -1;	/* force re-creat next time around */
108		    continue;
109	    	}
110	    	if (errno != EEXIST)
111		    return LOCK_ERROR;
112#ifndef X_NOT_POSIX
113	   }
114#endif
115	}
116	(void) sleep ((unsigned) timeout);
117	--retries;
118    }
119    return LOCK_TIMEOUT;
120}
121