OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [uClibc/] [libc/] [pwd_grp/] [lckpwdf.c] - Blame information for rev 1325

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1325 phoenix
/* vi: set sw=4 ts=4: */
2
/* Handle locking of password file.
3
   Copyright (C) 1996, 1998 Free Software Foundation, Inc.
4
   This file is part of the GNU C Library.
5
   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
6
 
7
   The GNU C Library is free software; you can redistribute it and/or
8
   modify it under the terms of the GNU Library General Public License as
9
   published by the Free Software Foundation; either version 2 of the
10
   License, or (at your option) any later version.
11
 
12
   The GNU C Library is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
   Library General Public License for more details.
16
 
17
   You should have received a copy of the GNU Library General Public
18
   License along with the GNU C Library; see the file COPYING.LIB.  If not,
19
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20
   Boston, MA 02111-1307, USA.  */
21
 
22
#include <features.h>
23
#include <fcntl.h>
24
#include <signal.h>
25
#include <string.h>
26
#include <unistd.h>
27
#include <sys/file.h>
28
#include <paths.h>
29
 
30
#ifdef __UCLIBC_HAS_THREADS__
31
#include <pthread.h>
32
static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
33
# define LOCK   __pthread_mutex_lock(&mylock)
34
# define UNLOCK __pthread_mutex_unlock(&mylock);
35
#else       
36
# define LOCK
37
# define UNLOCK
38
#endif      
39
 
40
/* How long to wait for getting the lock before returning with an
41
   error.  */
42
#define TIMEOUT 15 /* sec */
43
 
44
/* File descriptor for lock file.  */
45
static int lock_fd = -1;
46
 
47
/* Prototypes for local functions.  */
48
static void noop_handler __P ((int __sig));
49
 
50
 
51
int lckpwdf (void)
52
{
53
        int flags;
54
        sigset_t saved_set;         /* Saved set of caught signals.  */
55
        struct sigaction saved_act; /* Saved signal action.  */
56
        sigset_t new_set;           /* New set of caught signals.  */
57
        struct sigaction new_act;   /* New signal action.  */
58
        struct flock fl;            /* Information struct for locking.  */
59
        int result;
60
 
61
        if (lock_fd != -1)
62
                /* Still locked by own process.  */
63
                return -1;
64
 
65
        LOCK;
66
 
67
        lock_fd = open (_PATH_PASSWD, O_WRONLY);
68
        if (lock_fd == -1) {
69
                /* Cannot create lock file.  */
70
                UNLOCK;
71
                return -1;
72
        }
73
 
74
        /* Make sure file gets correctly closed when process finished.  */
75
        flags = fcntl (lock_fd, F_GETFD, 0);
76
        if (flags == -1) {
77
                /* Cannot get file flags.  */
78
                close(lock_fd);
79
                lock_fd = -1;
80
                UNLOCK;
81
                return -1;
82
        }
83
        flags |= FD_CLOEXEC;            /* Close on exit.  */
84
        if (fcntl (lock_fd, F_SETFD, flags) < 0) {
85
                /* Cannot set new flags.  */
86
                close(lock_fd);
87
                lock_fd = -1;
88
                UNLOCK;
89
                return -1;
90
        }
91
 
92
        /* Now we have to get exclusive write access.  Since multiple
93
           process could try this we won't stop when it first fails.
94
           Instead we set a timeout for the system call.  Once the timer
95
           expires it is likely that there are some problems which cannot be
96
           resolved by waiting.
97
 
98
           It is important that we don't change the signal state.  We must
99
           restore the old signal behaviour.  */
100
        memset (&new_act, '\0', sizeof (struct sigaction));
101
        new_act.sa_handler = noop_handler;
102
        sigfillset (&new_act.sa_mask);
103
        new_act.sa_flags = 0ul;
104
 
105
        /* Install new action handler for alarm and save old.  */
106
        if (sigaction (SIGALRM, &new_act, &saved_act) < 0) {
107
                /* Cannot install signal handler.  */
108
                close(lock_fd);
109
                lock_fd = -1;
110
                UNLOCK;
111
                return -1;
112
        }
113
 
114
        /* Now make sure the alarm signal is not blocked.  */
115
        sigemptyset (&new_set);
116
        sigaddset (&new_set, SIGALRM);
117
        if (sigprocmask (SIG_UNBLOCK, &new_set, &saved_set) < 0) {
118
                sigaction (SIGALRM, &saved_act, NULL);
119
                close(lock_fd);
120
                lock_fd = -1;
121
                UNLOCK;
122
                return -1;
123
        }
124
 
125
        /* Start timer.  If we cannot get the lock in the specified time we
126
           get a signal.  */
127
        alarm (TIMEOUT);
128
 
129
        /* Try to get the lock.  */
130
        memset (&fl, '\0', sizeof (struct flock));
131
        fl.l_type = F_WRLCK;
132
        fl.l_whence = SEEK_SET;
133
        result = fcntl (lock_fd, F_SETLKW, &fl);
134
 
135
        /* Clear alarm.  */
136
        alarm (0);
137
 
138
        /* Restore old set of handled signals.  We don't need to know
139
           about the current one.*/
140
        sigprocmask (SIG_SETMASK, &saved_set, NULL);
141
 
142
        /* Restore old action handler for alarm.  We don't need to know
143
           about the current one.  */
144
        sigaction (SIGALRM, &saved_act, NULL);
145
 
146
        if (result < 0) {
147
                close(lock_fd);
148
                lock_fd = -1;
149
                UNLOCK;
150
                return -1;
151
        }
152
 
153
        UNLOCK;
154
        return 0;
155
}
156
 
157
 
158
int ulckpwdf (void)
159
{
160
        int result;
161
 
162
        if (lock_fd == -1) {
163
                /* There is no lock set.  */
164
                result = -1;
165
        }
166
        else {
167
                LOCK;
168
                result = close (lock_fd);
169
                /* Mark descriptor as unused.  */
170
                lock_fd = -1;
171
                UNLOCK;
172
        }
173
 
174
        return result;
175
}
176
 
177
 
178
static void noop_handler (int sig)
179
{
180
        /* We simply return which makes the `fcntl' call return with an error.  */
181
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.