diff options
Diffstat (limited to 'arch/um/kernel')
-rw-r--r-- | arch/um/kernel/Makefile | 6 | ||||
-rw-r--r-- | arch/um/kernel/irq_user.c | 48 | ||||
-rw-r--r-- | arch/um/kernel/process_kern.c | 4 | ||||
-rw-r--r-- | arch/um/kernel/sigio_user.c | 2 | ||||
-rw-r--r-- | arch/um/kernel/um_arch.c | 4 | ||||
-rw-r--r-- | arch/um/kernel/umid.c | 323 |
6 files changed, 29 insertions, 358 deletions
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile index 3de9d21e36bf..6f7700593a6f 100644 --- a/arch/um/kernel/Makefile +++ b/arch/um/kernel/Makefile | |||
@@ -10,8 +10,8 @@ obj-y = config.o exec_kern.o exitcode.o \ | |||
10 | init_task.o irq.o irq_user.o ksyms.o mem.o physmem.o \ | 10 | init_task.o irq.o irq_user.o ksyms.o mem.o physmem.o \ |
11 | process_kern.o ptrace.o reboot.o resource.o sigio_user.o sigio_kern.o \ | 11 | process_kern.o ptrace.o reboot.o resource.o sigio_user.o sigio_kern.o \ |
12 | signal_kern.o signal_user.o smp.o syscall_kern.o sysrq.o time.o \ | 12 | signal_kern.o signal_user.o smp.o syscall_kern.o sysrq.o time.o \ |
13 | time_kern.o tlb.o trap_kern.o trap_user.o uaccess.o um_arch.o \ | 13 | time_kern.o tlb.o trap_kern.o trap_user.o uaccess.o um_arch.o umid.o \ |
14 | umid.o user_util.o | 14 | user_util.o |
15 | 15 | ||
16 | obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o | 16 | obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o |
17 | obj-$(CONFIG_GPROF) += gprof_syms.o | 17 | obj-$(CONFIG_GPROF) += gprof_syms.o |
@@ -24,7 +24,7 @@ obj-$(CONFIG_MODE_SKAS) += skas/ | |||
24 | 24 | ||
25 | user-objs-$(CONFIG_TTY_LOG) += tty_log.o | 25 | user-objs-$(CONFIG_TTY_LOG) += tty_log.o |
26 | 26 | ||
27 | USER_OBJS := $(user-objs-y) config.o time.o tty_log.o umid.o user_util.o | 27 | USER_OBJS := $(user-objs-y) config.o time.o tty_log.o user_util.o |
28 | 28 | ||
29 | include arch/um/scripts/Makefile.rules | 29 | include arch/um/scripts/Makefile.rules |
30 | 30 | ||
diff --git a/arch/um/kernel/irq_user.c b/arch/um/kernel/irq_user.c index c3ccaf24f3e0..50a2aa35cda9 100644 --- a/arch/um/kernel/irq_user.c +++ b/arch/um/kernel/irq_user.c | |||
@@ -29,7 +29,6 @@ struct irq_fd { | |||
29 | int pid; | 29 | int pid; |
30 | int events; | 30 | int events; |
31 | int current_events; | 31 | int current_events; |
32 | int freed; | ||
33 | }; | 32 | }; |
34 | 33 | ||
35 | static struct irq_fd *active_fds = NULL; | 34 | static struct irq_fd *active_fds = NULL; |
@@ -41,9 +40,11 @@ static int pollfds_size = 0; | |||
41 | 40 | ||
42 | extern int io_count, intr_count; | 41 | extern int io_count, intr_count; |
43 | 42 | ||
43 | extern void free_irqs(void); | ||
44 | |||
44 | void sigio_handler(int sig, union uml_pt_regs *regs) | 45 | void sigio_handler(int sig, union uml_pt_regs *regs) |
45 | { | 46 | { |
46 | struct irq_fd *irq_fd, *next; | 47 | struct irq_fd *irq_fd; |
47 | int i, n; | 48 | int i, n; |
48 | 49 | ||
49 | if(smp_sigio_handler()) return; | 50 | if(smp_sigio_handler()) return; |
@@ -66,29 +67,15 @@ void sigio_handler(int sig, union uml_pt_regs *regs) | |||
66 | irq_fd = irq_fd->next; | 67 | irq_fd = irq_fd->next; |
67 | } | 68 | } |
68 | 69 | ||
69 | for(irq_fd = active_fds; irq_fd != NULL; irq_fd = next){ | 70 | for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){ |
70 | next = irq_fd->next; | ||
71 | if(irq_fd->current_events != 0){ | 71 | if(irq_fd->current_events != 0){ |
72 | irq_fd->current_events = 0; | 72 | irq_fd->current_events = 0; |
73 | do_IRQ(irq_fd->irq, regs); | 73 | do_IRQ(irq_fd->irq, regs); |
74 | |||
75 | /* This is here because the next irq may be | ||
76 | * freed in the handler. If a console goes | ||
77 | * away, both the read and write irqs will be | ||
78 | * freed. After do_IRQ, ->next will point to | ||
79 | * a good IRQ. | ||
80 | * Irqs can't be freed inside their handlers, | ||
81 | * so the next best thing is to have them | ||
82 | * marked as needing freeing, so that they | ||
83 | * can be freed here. | ||
84 | */ | ||
85 | next = irq_fd->next; | ||
86 | if(irq_fd->freed){ | ||
87 | free_irq(irq_fd->irq, irq_fd->id); | ||
88 | } | ||
89 | } | 74 | } |
90 | } | 75 | } |
91 | } | 76 | } |
77 | |||
78 | free_irqs(); | ||
92 | } | 79 | } |
93 | 80 | ||
94 | int activate_ipi(int fd, int pid) | 81 | int activate_ipi(int fd, int pid) |
@@ -136,8 +123,7 @@ int activate_fd(int irq, int fd, int type, void *dev_id) | |||
136 | .irq = irq, | 123 | .irq = irq, |
137 | .pid = pid, | 124 | .pid = pid, |
138 | .events = events, | 125 | .events = events, |
139 | .current_events = 0, | 126 | .current_events = 0 } ); |
140 | .freed = 0 } ); | ||
141 | 127 | ||
142 | /* Critical section - locked by a spinlock because this stuff can | 128 | /* Critical section - locked by a spinlock because this stuff can |
143 | * be changed from interrupt handlers. The stuff above is done | 129 | * be changed from interrupt handlers. The stuff above is done |
@@ -313,26 +299,6 @@ static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out) | |||
313 | return(irq); | 299 | return(irq); |
314 | } | 300 | } |
315 | 301 | ||
316 | void free_irq_later(int irq, void *dev_id) | ||
317 | { | ||
318 | struct irq_fd *irq_fd; | ||
319 | unsigned long flags; | ||
320 | |||
321 | flags = irq_lock(); | ||
322 | for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){ | ||
323 | if((irq_fd->irq == irq) && (irq_fd->id == dev_id)) | ||
324 | break; | ||
325 | } | ||
326 | if(irq_fd == NULL){ | ||
327 | printk("free_irq_later found no irq, irq = %d, " | ||
328 | "dev_id = 0x%p\n", irq, dev_id); | ||
329 | goto out; | ||
330 | } | ||
331 | irq_fd->freed = 1; | ||
332 | out: | ||
333 | irq_unlock(flags); | ||
334 | } | ||
335 | |||
336 | void reactivate_fd(int fd, int irqnum) | 302 | void reactivate_fd(int fd, int irqnum) |
337 | { | 303 | { |
338 | struct irq_fd *irq; | 304 | struct irq_fd *irq; |
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c index 34b54a3e2132..651abf255bc5 100644 --- a/arch/um/kernel/process_kern.c +++ b/arch/um/kernel/process_kern.c | |||
@@ -324,10 +324,6 @@ int user_context(unsigned long sp) | |||
324 | return(stack != (unsigned long) current_thread); | 324 | return(stack != (unsigned long) current_thread); |
325 | } | 325 | } |
326 | 326 | ||
327 | extern void remove_umid_dir(void); | ||
328 | |||
329 | __uml_exitcall(remove_umid_dir); | ||
330 | |||
331 | extern exitcall_t __uml_exitcall_begin, __uml_exitcall_end; | 327 | extern exitcall_t __uml_exitcall_begin, __uml_exitcall_end; |
332 | 328 | ||
333 | void do_uml_exitcalls(void) | 329 | void do_uml_exitcalls(void) |
diff --git a/arch/um/kernel/sigio_user.c b/arch/um/kernel/sigio_user.c index 48b1f644b9a6..62e5cfdf2188 100644 --- a/arch/um/kernel/sigio_user.c +++ b/arch/um/kernel/sigio_user.c | |||
@@ -216,6 +216,8 @@ static int write_sigio_thread(void *unused) | |||
216 | "err = %d\n", -n); | 216 | "err = %d\n", -n); |
217 | } | 217 | } |
218 | } | 218 | } |
219 | |||
220 | return 0; | ||
219 | } | 221 | } |
220 | 222 | ||
221 | static int need_poll(int n) | 223 | static int need_poll(int n) |
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 142a9493912b..26626b2b9172 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c | |||
@@ -146,8 +146,8 @@ void set_cmdline(char *cmd) | |||
146 | 146 | ||
147 | if(CHOOSE_MODE(honeypot, 0)) return; | 147 | if(CHOOSE_MODE(honeypot, 0)) return; |
148 | 148 | ||
149 | umid = get_umid(1); | 149 | umid = get_umid(); |
150 | if(umid != NULL){ | 150 | if(*umid != '\0'){ |
151 | snprintf(argv1_begin, | 151 | snprintf(argv1_begin, |
152 | (argv1_end - argv1_begin) * sizeof(*ptr), | 152 | (argv1_end - argv1_begin) * sizeof(*ptr), |
153 | "(%s) ", umid); | 153 | "(%s) ", umid); |
diff --git a/arch/um/kernel/umid.c b/arch/um/kernel/umid.c index 0b21d59ba0cd..4eaee823bfd2 100644 --- a/arch/um/kernel/umid.c +++ b/arch/um/kernel/umid.c | |||
@@ -3,61 +3,30 @@ | |||
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <stdio.h> | 6 | #include "asm/errno.h" |
7 | #include <unistd.h> | ||
8 | #include <errno.h> | ||
9 | #include <string.h> | ||
10 | #include <stdlib.h> | ||
11 | #include <dirent.h> | ||
12 | #include <signal.h> | ||
13 | #include <sys/stat.h> | ||
14 | #include <sys/param.h> | ||
15 | #include "user.h" | ||
16 | #include "umid.h" | ||
17 | #include "init.h" | 7 | #include "init.h" |
18 | #include "os.h" | 8 | #include "os.h" |
19 | #include "user_util.h" | 9 | #include "kern.h" |
20 | #include "choose-mode.h" | 10 | #include "linux/kernel.h" |
21 | 11 | ||
22 | #define UMID_LEN 64 | 12 | /* Changed by set_umid_arg */ |
23 | #define UML_DIR "~/.uml/" | ||
24 | |||
25 | /* Changed by set_umid and make_umid, which are run early in boot */ | ||
26 | static char umid[UMID_LEN] = { 0 }; | ||
27 | |||
28 | /* Changed by set_uml_dir and make_uml_dir, which are run early in boot */ | ||
29 | static char *uml_dir = UML_DIR; | ||
30 | |||
31 | /* Changed by set_umid */ | ||
32 | static int umid_is_random = 1; | ||
33 | static int umid_inited = 0; | 13 | static int umid_inited = 0; |
34 | /* Have we created the files? Should we remove them? */ | ||
35 | static int umid_owned = 0; | ||
36 | 14 | ||
37 | static int make_umid(int (*printer)(const char *fmt, ...)); | 15 | static int __init set_umid_arg(char *name, int *add) |
38 | |||
39 | static int __init set_umid(char *name, int is_random, | ||
40 | int (*printer)(const char *fmt, ...)) | ||
41 | { | 16 | { |
42 | if(umid_inited){ | 17 | int err; |
43 | (*printer)("Unique machine name can't be set twice\n"); | ||
44 | return(-1); | ||
45 | } | ||
46 | 18 | ||
47 | if(strlen(name) > UMID_LEN - 1) | 19 | if(umid_inited) |
48 | (*printer)("Unique machine name is being truncated to %d " | 20 | return 0; |
49 | "characters\n", UMID_LEN); | ||
50 | strlcpy(umid, name, sizeof(umid)); | ||
51 | 21 | ||
52 | umid_is_random = is_random; | ||
53 | umid_inited = 1; | ||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | static int __init set_umid_arg(char *name, int *add) | ||
58 | { | ||
59 | *add = 0; | 22 | *add = 0; |
60 | return(set_umid(name, 0, printf)); | 23 | err = set_umid(name); |
24 | if(err == -EEXIST) | ||
25 | printf("umid '%s' already in use\n", name); | ||
26 | else if(!err) | ||
27 | umid_inited = 1; | ||
28 | |||
29 | return 0; | ||
61 | } | 30 | } |
62 | 31 | ||
63 | __uml_setup("umid=", set_umid_arg, | 32 | __uml_setup("umid=", set_umid_arg, |
@@ -66,265 +35,3 @@ __uml_setup("umid=", set_umid_arg, | |||
66 | " is used for naming the pid file and management console socket.\n\n" | 35 | " is used for naming the pid file and management console socket.\n\n" |
67 | ); | 36 | ); |
68 | 37 | ||
69 | int __init umid_file_name(char *name, char *buf, int len) | ||
70 | { | ||
71 | int n; | ||
72 | |||
73 | if(!umid_inited && make_umid(printk)) return(-1); | ||
74 | |||
75 | n = strlen(uml_dir) + strlen(umid) + strlen(name) + 1; | ||
76 | if(n > len){ | ||
77 | printk("umid_file_name : buffer too short\n"); | ||
78 | return(-1); | ||
79 | } | ||
80 | |||
81 | sprintf(buf, "%s%s/%s", uml_dir, umid, name); | ||
82 | return(0); | ||
83 | } | ||
84 | |||
85 | extern int tracing_pid; | ||
86 | |||
87 | static void __init create_pid_file(void) | ||
88 | { | ||
89 | char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")]; | ||
90 | char pid[sizeof("nnnnn\0")]; | ||
91 | int fd, n; | ||
92 | |||
93 | if(umid_file_name("pid", file, sizeof(file))) | ||
94 | return; | ||
95 | |||
96 | fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))), | ||
97 | 0644); | ||
98 | if(fd < 0){ | ||
99 | printf("Open of machine pid file \"%s\" failed: %s\n", | ||
100 | file, strerror(-fd)); | ||
101 | return; | ||
102 | } | ||
103 | |||
104 | sprintf(pid, "%d\n", os_getpid()); | ||
105 | n = os_write_file(fd, pid, strlen(pid)); | ||
106 | if(n != strlen(pid)) | ||
107 | printf("Write of pid file failed - err = %d\n", -n); | ||
108 | os_close_file(fd); | ||
109 | } | ||
110 | |||
111 | static int actually_do_remove(char *dir) | ||
112 | { | ||
113 | DIR *directory; | ||
114 | struct dirent *ent; | ||
115 | int len; | ||
116 | char file[256]; | ||
117 | |||
118 | directory = opendir(dir); | ||
119 | if(directory == NULL){ | ||
120 | printk("actually_do_remove : couldn't open directory '%s', " | ||
121 | "errno = %d\n", dir, errno); | ||
122 | return(1); | ||
123 | } | ||
124 | while((ent = readdir(directory)) != NULL){ | ||
125 | if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) | ||
126 | continue; | ||
127 | len = strlen(dir) + sizeof("/") + strlen(ent->d_name) + 1; | ||
128 | if(len > sizeof(file)){ | ||
129 | printk("Not deleting '%s' from '%s' - name too long\n", | ||
130 | ent->d_name, dir); | ||
131 | continue; | ||
132 | } | ||
133 | sprintf(file, "%s/%s", dir, ent->d_name); | ||
134 | if(unlink(file) < 0){ | ||
135 | printk("actually_do_remove : couldn't remove '%s' " | ||
136 | "from '%s', errno = %d\n", ent->d_name, dir, | ||
137 | errno); | ||
138 | return(1); | ||
139 | } | ||
140 | } | ||
141 | if(rmdir(dir) < 0){ | ||
142 | printk("actually_do_remove : couldn't rmdir '%s', " | ||
143 | "errno = %d\n", dir, errno); | ||
144 | return(1); | ||
145 | } | ||
146 | return(0); | ||
147 | } | ||
148 | |||
149 | void remove_umid_dir(void) | ||
150 | { | ||
151 | char dir[strlen(uml_dir) + UMID_LEN + 1]; | ||
152 | if (!umid_owned) | ||
153 | return; | ||
154 | |||
155 | sprintf(dir, "%s%s", uml_dir, umid); | ||
156 | actually_do_remove(dir); | ||
157 | } | ||
158 | |||
159 | char *get_umid(int only_if_set) | ||
160 | { | ||
161 | if(only_if_set && umid_is_random) | ||
162 | return NULL; | ||
163 | return umid; | ||
164 | } | ||
165 | |||
166 | static int not_dead_yet(char *dir) | ||
167 | { | ||
168 | char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")]; | ||
169 | char pid[sizeof("nnnnn\0")], *end; | ||
170 | int dead, fd, p, n; | ||
171 | |||
172 | sprintf(file, "%s/pid", dir); | ||
173 | dead = 0; | ||
174 | fd = os_open_file(file, of_read(OPENFLAGS()), 0); | ||
175 | if(fd < 0){ | ||
176 | if(fd != -ENOENT){ | ||
177 | printk("not_dead_yet : couldn't open pid file '%s', " | ||
178 | "err = %d\n", file, -fd); | ||
179 | return(1); | ||
180 | } | ||
181 | dead = 1; | ||
182 | } | ||
183 | if(fd > 0){ | ||
184 | n = os_read_file(fd, pid, sizeof(pid)); | ||
185 | if(n < 0){ | ||
186 | printk("not_dead_yet : couldn't read pid file '%s', " | ||
187 | "err = %d\n", file, -n); | ||
188 | return(1); | ||
189 | } | ||
190 | p = strtoul(pid, &end, 0); | ||
191 | if(end == pid){ | ||
192 | printk("not_dead_yet : couldn't parse pid file '%s', " | ||
193 | "errno = %d\n", file, errno); | ||
194 | dead = 1; | ||
195 | } | ||
196 | if(((kill(p, 0) < 0) && (errno == ESRCH)) || | ||
197 | (p == CHOOSE_MODE(tracing_pid, os_getpid()))) | ||
198 | dead = 1; | ||
199 | } | ||
200 | if(!dead) | ||
201 | return(1); | ||
202 | return(actually_do_remove(dir)); | ||
203 | } | ||
204 | |||
205 | static int __init set_uml_dir(char *name, int *add) | ||
206 | { | ||
207 | if((strlen(name) > 0) && (name[strlen(name) - 1] != '/')){ | ||
208 | uml_dir = malloc(strlen(name) + 2); | ||
209 | if(uml_dir == NULL){ | ||
210 | printf("Failed to malloc uml_dir - error = %d\n", | ||
211 | errno); | ||
212 | uml_dir = name; | ||
213 | /* Return 0 here because do_initcalls doesn't look at | ||
214 | * the return value. | ||
215 | */ | ||
216 | return(0); | ||
217 | } | ||
218 | sprintf(uml_dir, "%s/", name); | ||
219 | } | ||
220 | else uml_dir = name; | ||
221 | return(0); | ||
222 | } | ||
223 | |||
224 | static int __init make_uml_dir(void) | ||
225 | { | ||
226 | char dir[MAXPATHLEN + 1] = { '\0' }; | ||
227 | int len; | ||
228 | |||
229 | if(*uml_dir == '~'){ | ||
230 | char *home = getenv("HOME"); | ||
231 | |||
232 | if(home == NULL){ | ||
233 | printf("make_uml_dir : no value in environment for " | ||
234 | "$HOME\n"); | ||
235 | exit(1); | ||
236 | } | ||
237 | strlcpy(dir, home, sizeof(dir)); | ||
238 | uml_dir++; | ||
239 | } | ||
240 | strlcat(dir, uml_dir, sizeof(dir)); | ||
241 | len = strlen(dir); | ||
242 | if (len > 0 && dir[len - 1] != '/') | ||
243 | strlcat(dir, "/", sizeof(dir)); | ||
244 | |||
245 | uml_dir = malloc(strlen(dir) + 1); | ||
246 | if (uml_dir == NULL) { | ||
247 | printf("make_uml_dir : malloc failed, errno = %d\n", errno); | ||
248 | exit(1); | ||
249 | } | ||
250 | strcpy(uml_dir, dir); | ||
251 | |||
252 | if((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)){ | ||
253 | printf("Failed to mkdir %s: %s\n", uml_dir, strerror(errno)); | ||
254 | return(-1); | ||
255 | } | ||
256 | return 0; | ||
257 | } | ||
258 | |||
259 | static int __init make_umid(int (*printer)(const char *fmt, ...)) | ||
260 | { | ||
261 | int fd, err; | ||
262 | char tmp[strlen(uml_dir) + UMID_LEN + 1]; | ||
263 | |||
264 | strlcpy(tmp, uml_dir, sizeof(tmp)); | ||
265 | |||
266 | if(!umid_inited){ | ||
267 | strcat(tmp, "XXXXXX"); | ||
268 | fd = mkstemp(tmp); | ||
269 | if(fd < 0){ | ||
270 | (*printer)("make_umid - mkstemp(%s) failed: %s\n", | ||
271 | tmp,strerror(errno)); | ||
272 | return(1); | ||
273 | } | ||
274 | |||
275 | os_close_file(fd); | ||
276 | /* There's a nice tiny little race between this unlink and | ||
277 | * the mkdir below. It'd be nice if there were a mkstemp | ||
278 | * for directories. | ||
279 | */ | ||
280 | unlink(tmp); | ||
281 | set_umid(&tmp[strlen(uml_dir)], 1, printer); | ||
282 | } | ||
283 | |||
284 | sprintf(tmp, "%s%s", uml_dir, umid); | ||
285 | |||
286 | err = mkdir(tmp, 0777); | ||
287 | if(err < 0){ | ||
288 | if(errno == EEXIST){ | ||
289 | if(not_dead_yet(tmp)){ | ||
290 | (*printer)("umid '%s' is in use\n", umid); | ||
291 | umid_owned = 0; | ||
292 | return(-1); | ||
293 | } | ||
294 | err = mkdir(tmp, 0777); | ||
295 | } | ||
296 | } | ||
297 | if(err < 0){ | ||
298 | (*printer)("Failed to create %s - errno = %d\n", umid, errno); | ||
299 | return(-1); | ||
300 | } | ||
301 | |||
302 | umid_owned = 1; | ||
303 | return 0; | ||
304 | } | ||
305 | |||
306 | __uml_setup("uml_dir=", set_uml_dir, | ||
307 | "uml_dir=<directory>\n" | ||
308 | " The location to place the pid and umid files.\n\n" | ||
309 | ); | ||
310 | |||
311 | static int __init make_umid_setup(void) | ||
312 | { | ||
313 | /* one function with the ordering we need ... */ | ||
314 | make_uml_dir(); | ||
315 | make_umid(printf); | ||
316 | create_pid_file(); | ||
317 | return 0; | ||
318 | } | ||
319 | __uml_postsetup(make_umid_setup); | ||
320 | |||
321 | /* | ||
322 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
323 | * Emacs will notice this stuff at the end of the file and automatically | ||
324 | * adjust the settings for this buffer only. This must remain at the end | ||
325 | * of the file. | ||
326 | * --------------------------------------------------------------------------- | ||
327 | * Local variables: | ||
328 | * c-file-style: "linux" | ||
329 | * End: | ||
330 | */ | ||