]> git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/lxclock.c
make lxc_af_unix_open() safely return error on long pathnames
[mirror_lxc.git] / src / lxc / lxclock.c
1 /* liblxcapi
2 *
3 * Copyright © 2012 Serge Hallyn <serge.hallyn@ubuntu.com>.
4 * Copyright © 2012 Canonical Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include "lxclock.h"
21 #include <malloc.h>
22 #include <stdio.h>
23
24 #define OFLAG (O_CREAT | O_RDWR)
25 #define SEMMODE 0660
26 #define SEMVALUE 1
27 #define SEMVALUE_LOCKED 0
28 #define LXCLOCK_PREFIX "/lxcapi."
29
30
31 static char *lxclock_name(const char *container)
32 {
33 int ret;
34 int len = strlen(container) + strlen(LXCLOCK_PREFIX) + 1;
35 char *dest = malloc(len);
36 if (!dest)
37 return NULL;
38 ret = snprintf(dest, len, "%s%s", LXCLOCK_PREFIX, container);
39 if (ret < 0 || ret >= len) {
40 free(dest);
41 return NULL;
42 }
43 return dest;
44 }
45
46 static void lxcfree_name(char *name)
47 {
48 if (name)
49 free(name);
50 }
51
52 static sem_t *lxc_new_unnamed_sem(void)
53 {
54 sem_t *s;
55 int ret;
56
57 s = malloc(sizeof(*s));
58 if (!s)
59 return NULL;
60 ret = sem_init(s, 0, 1);
61 if (ret) {
62 free(s);
63 return NULL;
64 }
65 return s;
66 }
67
68 sem_t *lxc_newlock(const char *name)
69 {
70 char *lname;
71 sem_t *lock;
72
73 if (!name)
74 return lxc_new_unnamed_sem();
75
76 lname = lxclock_name(name);
77 if (!lname)
78 return NULL;
79 lock = sem_open(lname, OFLAG, SEMMODE, SEMVALUE);
80 lxcfree_name(lname);
81 if (lock == SEM_FAILED)
82 return NULL;
83 return lock;
84 }
85
86 int lxclock(sem_t *sem, int timeout)
87 {
88 int ret;
89
90 if (!timeout) {
91 ret = sem_wait(sem);
92 } else {
93 struct timespec ts;
94 if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
95 return -2;
96 ts.tv_sec += timeout;
97 ret = sem_timedwait(sem, &ts);
98 }
99
100 return ret;
101 }
102
103 int lxcunlock(sem_t *sem)
104 {
105 if (!sem)
106 return -2;
107 return sem_post(sem);
108 }