_flock_stub.c revision 303975
1321369Sdim/*
2234285Sdim * Copyright (c) 1998 John Birrell <jb@cimlogic.com.au>.
3353358Sdim * All rights reserved.
4353358Sdim *
5353358Sdim * Redistribution and use in source and binary forms, with or without
6234285Sdim * modification, are permitted provided that the following conditions
7234285Sdim * are met:
8234285Sdim * 1. Redistributions of source code must retain the above copyright
9261991Sdim *    notice, this list of conditions and the following disclaimer.
10261991Sdim * 2. Redistributions in binary form must reproduce the above copyright
11261991Sdim *    notice, this list of conditions and the following disclaimer in the
12261991Sdim *    documentation and/or other materials provided with the distribution.
13261991Sdim * 3. Neither the name of the author nor the names of any co-contributors
14261991Sdim *    may be used to endorse or promote products derived from this software
15261991Sdim *    without specific prior written permission.
16261991Sdim *
17261991Sdim * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
18261991Sdim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19261991Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20261991Sdim * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21261991Sdim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22261991Sdim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23261991Sdim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24261991Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25276479Sdim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26261991Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27261991Sdim * SUCH DAMAGE.
28327952Sdim */
29261991Sdim
30261991Sdim/*
31261991Sdim * POSIX stdio FILE locking functions. These assume that the locking
32261991Sdim * is only required at FILE structure level, not at file descriptor
33261991Sdim * level too.
34321369Sdim *
35261991Sdim */
36261991Sdim
37261991Sdim#include <sys/cdefs.h>
38261991Sdim__FBSDID("$FreeBSD: releng/11.0/lib/libc/stdio/_flock_stub.c 288031 2015-09-20 20:26:46Z rodrigc $");
39261991Sdim
40261991Sdim#include "namespace.h"
41261991Sdim#include <stdio.h>
42261991Sdim#include <stdlib.h>
43261991Sdim#include <string.h>
44314564Sdim#include <pthread.h>
45314564Sdim#include "un-namespace.h"
46261991Sdim
47261991Sdim#include "local.h"
48261991Sdim
49261991Sdim
50261991Sdim/*
51234285Sdim * Weak symbols for externally visible functions in this file:
52234285Sdim */
53234285Sdim__weak_reference(_flockfile, flockfile);
54234285Sdim__weak_reference(_flockfile_debug_stub, _flockfile_debug);
55234285Sdim__weak_reference(_ftrylockfile, ftrylockfile);
56234285Sdim__weak_reference(_funlockfile, funlockfile);
57234285Sdim
58234285Sdimvoid _flockfile_debug_stub(FILE *, char *, int);
59234285Sdimint _ftrylockfile(FILE *);
60234285Sdim
61261991Sdimvoid
62261991Sdim_flockfile(FILE *fp)
63261991Sdim{
64261991Sdim	pthread_t curthread = _pthread_self();
65261991Sdim
66261991Sdim	if (fp->_fl_owner == curthread)
67261991Sdim		fp->_fl_count++;
68261991Sdim	else {
69261991Sdim		/*
70261991Sdim		 * Make sure this mutex is treated as a private
71261991Sdim		 * internal mutex:
72234285Sdim		 */
73234285Sdim		_pthread_mutex_lock(&fp->_fl_mutex);
74249423Sdim		fp->_fl_owner = curthread;
75249423Sdim		fp->_fl_count = 1;
76234285Sdim	}
77314564Sdim}
78314564Sdim
79314564Sdim/*
80314564Sdim * This can be overriden by the threads library if it is linked in.
81314564Sdim */
82314564Sdimvoid
83296417Sdim_flockfile_debug_stub(FILE *fp, char *fname, int lineno)
84314564Sdim{
85234285Sdim	_flockfile(fp);
86243830Sdim}
87314564Sdim
88243830Sdimint
89309124Sdim_ftrylockfile(FILE *fp)
90314564Sdim{
91314564Sdim	pthread_t curthread = _pthread_self();
92314564Sdim	int	ret = 0;
93314564Sdim
94314564Sdim	if (fp->_fl_owner == curthread)
95276479Sdim		fp->_fl_count++;
96314564Sdim	/*
97314564Sdim	 * Make sure this mutex is treated as a private
98276479Sdim	 * internal mutex:
99234285Sdim	 */
100234285Sdim	else if (_pthread_mutex_trylock(&fp->_fl_mutex) == 0) {
101243830Sdim		fp->_fl_owner = curthread;
102243830Sdim		fp->_fl_count = 1;
103360784Sdim	}
104243830Sdim	else
105234285Sdim		ret = -1;
106234285Sdim	return (ret);
107321369Sdim}
108321369Sdim
109234285Sdimvoid
110239462Sdim_funlockfile(FILE *fp)
111249423Sdim{
112276479Sdim	pthread_t	curthread = _pthread_self();
113321369Sdim
114321369Sdim	/*
115321369Sdim	 * Check if this file is owned by the current thread:
116234285Sdim	 */
117234285Sdim	if (fp->_fl_owner == curthread) {
118234285Sdim		/*
119234285Sdim		 * Check if this thread has locked the FILE
120321369Sdim		 * more than once:
121321369Sdim		 */
122321369Sdim		if (fp->_fl_count > 1)
123321369Sdim			/*
124321369Sdim			 * Decrement the count of the number of
125321369Sdim			 * times the running thread has locked this
126234285Sdim			 * file:
127239462Sdim			 */
128239462Sdim			fp->_fl_count--;
129239462Sdim		else {
130239462Sdim			/*
131234285Sdim			 * The running thread will release the
132234285Sdim			 * lock now:
133234285Sdim			 */
134234285Sdim			fp->_fl_count = 0;
135344779Sdim			fp->_fl_owner = NULL;
136344779Sdim			_pthread_mutex_unlock(&fp->_fl_mutex);
137344779Sdim		}
138234285Sdim	}
139321369Sdim}
140234285Sdim