diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/um/os-Linux/file.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'arch/um/os-Linux/file.c')
-rw-r--r-- | arch/um/os-Linux/file.c | 680 |
1 files changed, 680 insertions, 0 deletions
diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c new file mode 100644 index 000000000000..77d4066d1af8 --- /dev/null +++ b/arch/um/os-Linux/file.c | |||
@@ -0,0 +1,680 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) | ||
3 | * Licensed under the GPL | ||
4 | */ | ||
5 | |||
6 | #include <stdio.h> | ||
7 | #include <unistd.h> | ||
8 | #include <errno.h> | ||
9 | #include <fcntl.h> | ||
10 | #include <signal.h> | ||
11 | #include <sys/types.h> | ||
12 | #include <sys/stat.h> | ||
13 | #include <sys/socket.h> | ||
14 | #include <sys/un.h> | ||
15 | #include <sys/ioctl.h> | ||
16 | #include <sys/mount.h> | ||
17 | #include <sys/uio.h> | ||
18 | #include "os.h" | ||
19 | #include "user.h" | ||
20 | #include "kern_util.h" | ||
21 | |||
22 | static void copy_stat(struct uml_stat *dst, struct stat64 *src) | ||
23 | { | ||
24 | *dst = ((struct uml_stat) { | ||
25 | .ust_dev = src->st_dev, /* device */ | ||
26 | .ust_ino = src->st_ino, /* inode */ | ||
27 | .ust_mode = src->st_mode, /* protection */ | ||
28 | .ust_nlink = src->st_nlink, /* number of hard links */ | ||
29 | .ust_uid = src->st_uid, /* user ID of owner */ | ||
30 | .ust_gid = src->st_gid, /* group ID of owner */ | ||
31 | .ust_size = src->st_size, /* total size, in bytes */ | ||
32 | .ust_blksize = src->st_blksize, /* blocksize for filesys I/O */ | ||
33 | .ust_blocks = src->st_blocks, /* number of blocks allocated */ | ||
34 | .ust_atime = src->st_atime, /* time of last access */ | ||
35 | .ust_mtime = src->st_mtime, /* time of last modification */ | ||
36 | .ust_ctime = src->st_ctime, /* time of last change */ | ||
37 | }); | ||
38 | } | ||
39 | |||
40 | int os_stat_fd(const int fd, struct uml_stat *ubuf) | ||
41 | { | ||
42 | struct stat64 sbuf; | ||
43 | int err; | ||
44 | |||
45 | do { | ||
46 | err = fstat64(fd, &sbuf); | ||
47 | } while((err < 0) && (errno == EINTR)) ; | ||
48 | |||
49 | if(err < 0) | ||
50 | return(-errno); | ||
51 | |||
52 | if(ubuf != NULL) | ||
53 | copy_stat(ubuf, &sbuf); | ||
54 | return(err); | ||
55 | } | ||
56 | |||
57 | int os_stat_file(const char *file_name, struct uml_stat *ubuf) | ||
58 | { | ||
59 | struct stat64 sbuf; | ||
60 | int err; | ||
61 | |||
62 | do { | ||
63 | err = stat64(file_name, &sbuf); | ||
64 | } while((err < 0) && (errno == EINTR)) ; | ||
65 | |||
66 | if(err < 0) | ||
67 | return(-errno); | ||
68 | |||
69 | if(ubuf != NULL) | ||
70 | copy_stat(ubuf, &sbuf); | ||
71 | return(err); | ||
72 | } | ||
73 | |||
74 | int os_access(const char* file, int mode) | ||
75 | { | ||
76 | int amode, err; | ||
77 | |||
78 | amode=(mode&OS_ACC_R_OK ? R_OK : 0) | (mode&OS_ACC_W_OK ? W_OK : 0) | | ||
79 | (mode&OS_ACC_X_OK ? X_OK : 0) | (mode&OS_ACC_F_OK ? F_OK : 0) ; | ||
80 | |||
81 | err = access(file, amode); | ||
82 | if(err < 0) | ||
83 | return(-errno); | ||
84 | |||
85 | return(0); | ||
86 | } | ||
87 | |||
88 | void os_print_error(int error, const char* str) | ||
89 | { | ||
90 | errno = error < 0 ? -error : error; | ||
91 | |||
92 | perror(str); | ||
93 | } | ||
94 | |||
95 | /* FIXME? required only by hostaudio (because it passes ioctls verbatim) */ | ||
96 | int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg) | ||
97 | { | ||
98 | int err; | ||
99 | |||
100 | err = ioctl(fd, cmd, arg); | ||
101 | if(err < 0) | ||
102 | return(-errno); | ||
103 | |||
104 | return(err); | ||
105 | } | ||
106 | |||
107 | int os_window_size(int fd, int *rows, int *cols) | ||
108 | { | ||
109 | struct winsize size; | ||
110 | |||
111 | if(ioctl(fd, TIOCGWINSZ, &size) < 0) | ||
112 | return(-errno); | ||
113 | |||
114 | *rows = size.ws_row; | ||
115 | *cols = size.ws_col; | ||
116 | |||
117 | return(0); | ||
118 | } | ||
119 | |||
120 | int os_new_tty_pgrp(int fd, int pid) | ||
121 | { | ||
122 | if(ioctl(fd, TIOCSCTTY, 0) < 0){ | ||
123 | printk("TIOCSCTTY failed, errno = %d\n", errno); | ||
124 | return(-errno); | ||
125 | } | ||
126 | |||
127 | if(tcsetpgrp(fd, pid) < 0){ | ||
128 | printk("tcsetpgrp failed, errno = %d\n", errno); | ||
129 | return(-errno); | ||
130 | } | ||
131 | |||
132 | return(0); | ||
133 | } | ||
134 | |||
135 | /* FIXME: ensure namebuf in os_get_if_name is big enough */ | ||
136 | int os_get_ifname(int fd, char* namebuf) | ||
137 | { | ||
138 | if(ioctl(fd, SIOCGIFNAME, namebuf) < 0) | ||
139 | return(-errno); | ||
140 | |||
141 | return(0); | ||
142 | } | ||
143 | |||
144 | int os_set_slip(int fd) | ||
145 | { | ||
146 | int disc, sencap; | ||
147 | |||
148 | disc = N_SLIP; | ||
149 | if(ioctl(fd, TIOCSETD, &disc) < 0){ | ||
150 | printk("Failed to set slip line discipline - " | ||
151 | "errno = %d\n", errno); | ||
152 | return(-errno); | ||
153 | } | ||
154 | |||
155 | sencap = 0; | ||
156 | if(ioctl(fd, SIOCSIFENCAP, &sencap) < 0){ | ||
157 | printk("Failed to set slip encapsulation - " | ||
158 | "errno = %d\n", errno); | ||
159 | return(-errno); | ||
160 | } | ||
161 | |||
162 | return(0); | ||
163 | } | ||
164 | |||
165 | int os_set_owner(int fd, int pid) | ||
166 | { | ||
167 | if(fcntl(fd, F_SETOWN, pid) < 0){ | ||
168 | int save_errno = errno; | ||
169 | |||
170 | if(fcntl(fd, F_GETOWN, 0) != pid) | ||
171 | return(-save_errno); | ||
172 | } | ||
173 | |||
174 | return(0); | ||
175 | } | ||
176 | |||
177 | /* FIXME? moved wholesale from sigio_user.c to get fcntls out of that file */ | ||
178 | int os_sigio_async(int master, int slave) | ||
179 | { | ||
180 | int flags; | ||
181 | |||
182 | flags = fcntl(master, F_GETFL); | ||
183 | if(flags < 0) { | ||
184 | printk("fcntl F_GETFL failed, errno = %d\n", errno); | ||
185 | return(-errno); | ||
186 | } | ||
187 | |||
188 | if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) || | ||
189 | (fcntl(master, F_SETOWN, os_getpid()) < 0)){ | ||
190 | printk("fcntl F_SETFL or F_SETOWN failed, errno = %d\n", | ||
191 | errno); | ||
192 | return(-errno); | ||
193 | } | ||
194 | |||
195 | if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0)){ | ||
196 | printk("fcntl F_SETFL failed, errno = %d\n", errno); | ||
197 | return(-errno); | ||
198 | } | ||
199 | |||
200 | return(0); | ||
201 | } | ||
202 | |||
203 | int os_mode_fd(int fd, int mode) | ||
204 | { | ||
205 | int err; | ||
206 | |||
207 | do { | ||
208 | err = fchmod(fd, mode); | ||
209 | } while((err < 0) && (errno==EINTR)) ; | ||
210 | |||
211 | if(err < 0) | ||
212 | return(-errno); | ||
213 | |||
214 | return(0); | ||
215 | } | ||
216 | |||
217 | int os_file_type(char *file) | ||
218 | { | ||
219 | struct uml_stat buf; | ||
220 | int err; | ||
221 | |||
222 | err = os_stat_file(file, &buf); | ||
223 | if(err < 0) | ||
224 | return(err); | ||
225 | |||
226 | if(S_ISDIR(buf.ust_mode)) return(OS_TYPE_DIR); | ||
227 | else if(S_ISLNK(buf.ust_mode)) return(OS_TYPE_SYMLINK); | ||
228 | else if(S_ISCHR(buf.ust_mode)) return(OS_TYPE_CHARDEV); | ||
229 | else if(S_ISBLK(buf.ust_mode)) return(OS_TYPE_BLOCKDEV); | ||
230 | else if(S_ISFIFO(buf.ust_mode)) return(OS_TYPE_FIFO); | ||
231 | else if(S_ISSOCK(buf.ust_mode)) return(OS_TYPE_SOCK); | ||
232 | else return(OS_TYPE_FILE); | ||
233 | } | ||
234 | |||
235 | int os_file_mode(char *file, struct openflags *mode_out) | ||
236 | { | ||
237 | int err; | ||
238 | |||
239 | *mode_out = OPENFLAGS(); | ||
240 | |||
241 | err = os_access(file, OS_ACC_W_OK); | ||
242 | if((err < 0) && (err != -EACCES)) | ||
243 | return(err); | ||
244 | |||
245 | *mode_out = of_write(*mode_out); | ||
246 | |||
247 | err = os_access(file, OS_ACC_R_OK); | ||
248 | if((err < 0) && (err != -EACCES)) | ||
249 | return(err); | ||
250 | |||
251 | *mode_out = of_read(*mode_out); | ||
252 | |||
253 | return(0); | ||
254 | } | ||
255 | |||
256 | int os_open_file(char *file, struct openflags flags, int mode) | ||
257 | { | ||
258 | int fd, f = 0; | ||
259 | |||
260 | if(flags.r && flags.w) f = O_RDWR; | ||
261 | else if(flags.r) f = O_RDONLY; | ||
262 | else if(flags.w) f = O_WRONLY; | ||
263 | else f = 0; | ||
264 | |||
265 | if(flags.s) f |= O_SYNC; | ||
266 | if(flags.c) f |= O_CREAT; | ||
267 | if(flags.t) f |= O_TRUNC; | ||
268 | if(flags.e) f |= O_EXCL; | ||
269 | |||
270 | fd = open64(file, f, mode); | ||
271 | if(fd < 0) | ||
272 | return(-errno); | ||
273 | |||
274 | if(flags.cl && fcntl(fd, F_SETFD, 1)){ | ||
275 | os_close_file(fd); | ||
276 | return(-errno); | ||
277 | } | ||
278 | |||
279 | return(fd); | ||
280 | } | ||
281 | |||
282 | int os_connect_socket(char *name) | ||
283 | { | ||
284 | struct sockaddr_un sock; | ||
285 | int fd, err; | ||
286 | |||
287 | sock.sun_family = AF_UNIX; | ||
288 | snprintf(sock.sun_path, sizeof(sock.sun_path), "%s", name); | ||
289 | |||
290 | fd = socket(AF_UNIX, SOCK_STREAM, 0); | ||
291 | if(fd < 0) | ||
292 | return(fd); | ||
293 | |||
294 | err = connect(fd, (struct sockaddr *) &sock, sizeof(sock)); | ||
295 | if(err) | ||
296 | return(-errno); | ||
297 | |||
298 | return(fd); | ||
299 | } | ||
300 | |||
301 | void os_close_file(int fd) | ||
302 | { | ||
303 | close(fd); | ||
304 | } | ||
305 | |||
306 | int os_seek_file(int fd, __u64 offset) | ||
307 | { | ||
308 | __u64 actual; | ||
309 | |||
310 | actual = lseek64(fd, offset, SEEK_SET); | ||
311 | if(actual != offset) | ||
312 | return(-errno); | ||
313 | return(0); | ||
314 | } | ||
315 | |||
316 | static int fault_buffer(void *start, int len, | ||
317 | int (*copy_proc)(void *addr, void *buf, int len)) | ||
318 | { | ||
319 | int page = getpagesize(), i; | ||
320 | char c; | ||
321 | |||
322 | for(i = 0; i < len; i += page){ | ||
323 | if((*copy_proc)(start + i, &c, sizeof(c))) | ||
324 | return(-EFAULT); | ||
325 | } | ||
326 | if((len % page) != 0){ | ||
327 | if((*copy_proc)(start + len - 1, &c, sizeof(c))) | ||
328 | return(-EFAULT); | ||
329 | } | ||
330 | return(0); | ||
331 | } | ||
332 | |||
333 | static int file_io(int fd, void *buf, int len, | ||
334 | int (*io_proc)(int fd, void *buf, int len), | ||
335 | int (*copy_user_proc)(void *addr, void *buf, int len)) | ||
336 | { | ||
337 | int n, err; | ||
338 | |||
339 | do { | ||
340 | n = (*io_proc)(fd, buf, len); | ||
341 | if((n < 0) && (errno == EFAULT)){ | ||
342 | err = fault_buffer(buf, len, copy_user_proc); | ||
343 | if(err) | ||
344 | return(err); | ||
345 | n = (*io_proc)(fd, buf, len); | ||
346 | } | ||
347 | } while((n < 0) && (errno == EINTR)); | ||
348 | |||
349 | if(n < 0) | ||
350 | return(-errno); | ||
351 | return(n); | ||
352 | } | ||
353 | |||
354 | int os_read_file(int fd, void *buf, int len) | ||
355 | { | ||
356 | return(file_io(fd, buf, len, (int (*)(int, void *, int)) read, | ||
357 | copy_from_user_proc)); | ||
358 | } | ||
359 | |||
360 | int os_write_file(int fd, const void *buf, int len) | ||
361 | { | ||
362 | return(file_io(fd, (void *) buf, len, | ||
363 | (int (*)(int, void *, int)) write, copy_to_user_proc)); | ||
364 | } | ||
365 | |||
366 | int os_file_size(char *file, long long *size_out) | ||
367 | { | ||
368 | struct uml_stat buf; | ||
369 | int err; | ||
370 | |||
371 | err = os_stat_file(file, &buf); | ||
372 | if(err < 0){ | ||
373 | printk("Couldn't stat \"%s\" : err = %d\n", file, -err); | ||
374 | return(err); | ||
375 | } | ||
376 | |||
377 | if(S_ISBLK(buf.ust_mode)){ | ||
378 | int fd, blocks; | ||
379 | |||
380 | fd = os_open_file(file, of_read(OPENFLAGS()), 0); | ||
381 | if(fd < 0){ | ||
382 | printk("Couldn't open \"%s\", errno = %d\n", file, -fd); | ||
383 | return(fd); | ||
384 | } | ||
385 | if(ioctl(fd, BLKGETSIZE, &blocks) < 0){ | ||
386 | printk("Couldn't get the block size of \"%s\", " | ||
387 | "errno = %d\n", file, errno); | ||
388 | err = -errno; | ||
389 | os_close_file(fd); | ||
390 | return(err); | ||
391 | } | ||
392 | *size_out = ((long long) blocks) * 512; | ||
393 | os_close_file(fd); | ||
394 | return(0); | ||
395 | } | ||
396 | *size_out = buf.ust_size; | ||
397 | return(0); | ||
398 | } | ||
399 | |||
400 | int os_file_modtime(char *file, unsigned long *modtime) | ||
401 | { | ||
402 | struct uml_stat buf; | ||
403 | int err; | ||
404 | |||
405 | err = os_stat_file(file, &buf); | ||
406 | if(err < 0){ | ||
407 | printk("Couldn't stat \"%s\" : err = %d\n", file, -err); | ||
408 | return(err); | ||
409 | } | ||
410 | |||
411 | *modtime = buf.ust_mtime; | ||
412 | return(0); | ||
413 | } | ||
414 | |||
415 | int os_get_exec_close(int fd, int* close_on_exec) | ||
416 | { | ||
417 | int ret; | ||
418 | |||
419 | do { | ||
420 | ret = fcntl(fd, F_GETFD); | ||
421 | } while((ret < 0) && (errno == EINTR)) ; | ||
422 | |||
423 | if(ret < 0) | ||
424 | return(-errno); | ||
425 | |||
426 | *close_on_exec = (ret&FD_CLOEXEC) ? 1 : 0; | ||
427 | return(ret); | ||
428 | } | ||
429 | |||
430 | int os_set_exec_close(int fd, int close_on_exec) | ||
431 | { | ||
432 | int flag, err; | ||
433 | |||
434 | if(close_on_exec) flag = FD_CLOEXEC; | ||
435 | else flag = 0; | ||
436 | |||
437 | do { | ||
438 | err = fcntl(fd, F_SETFD, flag); | ||
439 | } while((err < 0) && (errno == EINTR)) ; | ||
440 | |||
441 | if(err < 0) | ||
442 | return(-errno); | ||
443 | return(err); | ||
444 | } | ||
445 | |||
446 | int os_pipe(int *fds, int stream, int close_on_exec) | ||
447 | { | ||
448 | int err, type = stream ? SOCK_STREAM : SOCK_DGRAM; | ||
449 | |||
450 | err = socketpair(AF_UNIX, type, 0, fds); | ||
451 | if(err < 0) | ||
452 | return(-errno); | ||
453 | |||
454 | if(!close_on_exec) | ||
455 | return(0); | ||
456 | |||
457 | err = os_set_exec_close(fds[0], 1); | ||
458 | if(err < 0) | ||
459 | goto error; | ||
460 | |||
461 | err = os_set_exec_close(fds[1], 1); | ||
462 | if(err < 0) | ||
463 | goto error; | ||
464 | |||
465 | return(0); | ||
466 | |||
467 | error: | ||
468 | printk("os_pipe : Setting FD_CLOEXEC failed, err = %d\n", -err); | ||
469 | os_close_file(fds[1]); | ||
470 | os_close_file(fds[0]); | ||
471 | return(err); | ||
472 | } | ||
473 | |||
474 | int os_set_fd_async(int fd, int owner) | ||
475 | { | ||
476 | /* XXX This should do F_GETFL first */ | ||
477 | if(fcntl(fd, F_SETFL, O_ASYNC | O_NONBLOCK) < 0){ | ||
478 | printk("os_set_fd_async : failed to set O_ASYNC and " | ||
479 | "O_NONBLOCK on fd # %d, errno = %d\n", fd, errno); | ||
480 | return(-errno); | ||
481 | } | ||
482 | #ifdef notdef | ||
483 | if(fcntl(fd, F_SETFD, 1) < 0){ | ||
484 | printk("os_set_fd_async : Setting FD_CLOEXEC failed, " | ||
485 | "errno = %d\n", errno); | ||
486 | } | ||
487 | #endif | ||
488 | |||
489 | if((fcntl(fd, F_SETSIG, SIGIO) < 0) || | ||
490 | (fcntl(fd, F_SETOWN, owner) < 0)){ | ||
491 | printk("os_set_fd_async : Failed to fcntl F_SETOWN " | ||
492 | "(or F_SETSIG) fd %d to pid %d, errno = %d\n", fd, | ||
493 | owner, errno); | ||
494 | return(-errno); | ||
495 | } | ||
496 | |||
497 | return(0); | ||
498 | } | ||
499 | |||
500 | int os_clear_fd_async(int fd) | ||
501 | { | ||
502 | int flags = fcntl(fd, F_GETFL); | ||
503 | |||
504 | flags &= ~(O_ASYNC | O_NONBLOCK); | ||
505 | if(fcntl(fd, F_SETFL, flags) < 0) | ||
506 | return(-errno); | ||
507 | return(0); | ||
508 | } | ||
509 | |||
510 | int os_set_fd_block(int fd, int blocking) | ||
511 | { | ||
512 | int flags; | ||
513 | |||
514 | flags = fcntl(fd, F_GETFL); | ||
515 | |||
516 | if(blocking) flags &= ~O_NONBLOCK; | ||
517 | else flags |= O_NONBLOCK; | ||
518 | |||
519 | if(fcntl(fd, F_SETFL, flags) < 0){ | ||
520 | printk("Failed to change blocking on fd # %d, errno = %d\n", | ||
521 | fd, errno); | ||
522 | return(-errno); | ||
523 | } | ||
524 | return(0); | ||
525 | } | ||
526 | |||
527 | int os_accept_connection(int fd) | ||
528 | { | ||
529 | int new; | ||
530 | |||
531 | new = accept(fd, NULL, 0); | ||
532 | if(new < 0) | ||
533 | return(-errno); | ||
534 | return(new); | ||
535 | } | ||
536 | |||
537 | #ifndef SHUT_RD | ||
538 | #define SHUT_RD 0 | ||
539 | #endif | ||
540 | |||
541 | #ifndef SHUT_WR | ||
542 | #define SHUT_WR 1 | ||
543 | #endif | ||
544 | |||
545 | #ifndef SHUT_RDWR | ||
546 | #define SHUT_RDWR 2 | ||
547 | #endif | ||
548 | |||
549 | int os_shutdown_socket(int fd, int r, int w) | ||
550 | { | ||
551 | int what, err; | ||
552 | |||
553 | if(r && w) what = SHUT_RDWR; | ||
554 | else if(r) what = SHUT_RD; | ||
555 | else if(w) what = SHUT_WR; | ||
556 | else { | ||
557 | printk("os_shutdown_socket : neither r or w was set\n"); | ||
558 | return(-EINVAL); | ||
559 | } | ||
560 | err = shutdown(fd, what); | ||
561 | if(err < 0) | ||
562 | return(-errno); | ||
563 | return(0); | ||
564 | } | ||
565 | |||
566 | int os_rcv_fd(int fd, int *helper_pid_out) | ||
567 | { | ||
568 | int new, n; | ||
569 | char buf[CMSG_SPACE(sizeof(new))]; | ||
570 | struct msghdr msg; | ||
571 | struct cmsghdr *cmsg; | ||
572 | struct iovec iov; | ||
573 | |||
574 | msg.msg_name = NULL; | ||
575 | msg.msg_namelen = 0; | ||
576 | iov = ((struct iovec) { .iov_base = helper_pid_out, | ||
577 | .iov_len = sizeof(*helper_pid_out) }); | ||
578 | msg.msg_iov = &iov; | ||
579 | msg.msg_iovlen = 1; | ||
580 | msg.msg_control = buf; | ||
581 | msg.msg_controllen = sizeof(buf); | ||
582 | msg.msg_flags = 0; | ||
583 | |||
584 | n = recvmsg(fd, &msg, 0); | ||
585 | if(n < 0) | ||
586 | return(-errno); | ||
587 | |||
588 | else if(n != sizeof(iov.iov_len)) | ||
589 | *helper_pid_out = -1; | ||
590 | |||
591 | cmsg = CMSG_FIRSTHDR(&msg); | ||
592 | if(cmsg == NULL){ | ||
593 | printk("rcv_fd didn't receive anything, error = %d\n", errno); | ||
594 | return(-1); | ||
595 | } | ||
596 | if((cmsg->cmsg_level != SOL_SOCKET) || | ||
597 | (cmsg->cmsg_type != SCM_RIGHTS)){ | ||
598 | printk("rcv_fd didn't receive a descriptor\n"); | ||
599 | return(-1); | ||
600 | } | ||
601 | |||
602 | new = ((int *) CMSG_DATA(cmsg))[0]; | ||
603 | return(new); | ||
604 | } | ||
605 | |||
606 | int os_create_unix_socket(char *file, int len, int close_on_exec) | ||
607 | { | ||
608 | struct sockaddr_un addr; | ||
609 | int sock, err; | ||
610 | |||
611 | sock = socket(PF_UNIX, SOCK_DGRAM, 0); | ||
612 | if (sock < 0){ | ||
613 | printk("create_unix_socket - socket failed, errno = %d\n", | ||
614 | errno); | ||
615 | return(-errno); | ||
616 | } | ||
617 | |||
618 | if(close_on_exec) { | ||
619 | err = os_set_exec_close(sock, 1); | ||
620 | if(err < 0) | ||
621 | printk("create_unix_socket : close_on_exec failed, " | ||
622 | "err = %d", -err); | ||
623 | } | ||
624 | |||
625 | addr.sun_family = AF_UNIX; | ||
626 | |||
627 | /* XXX Be more careful about overflow */ | ||
628 | snprintf(addr.sun_path, len, "%s", file); | ||
629 | |||
630 | err = bind(sock, (struct sockaddr *) &addr, sizeof(addr)); | ||
631 | if (err < 0){ | ||
632 | printk("create_listening_socket at '%s' - bind failed, " | ||
633 | "errno = %d\n", file, errno); | ||
634 | return(-errno); | ||
635 | } | ||
636 | |||
637 | return(sock); | ||
638 | } | ||
639 | |||
640 | void os_flush_stdout(void) | ||
641 | { | ||
642 | fflush(stdout); | ||
643 | } | ||
644 | |||
645 | int os_lock_file(int fd, int excl) | ||
646 | { | ||
647 | int type = excl ? F_WRLCK : F_RDLCK; | ||
648 | struct flock lock = ((struct flock) { .l_type = type, | ||
649 | .l_whence = SEEK_SET, | ||
650 | .l_start = 0, | ||
651 | .l_len = 0 } ); | ||
652 | int err, save; | ||
653 | |||
654 | err = fcntl(fd, F_SETLK, &lock); | ||
655 | if(!err) | ||
656 | goto out; | ||
657 | |||
658 | save = -errno; | ||
659 | err = fcntl(fd, F_GETLK, &lock); | ||
660 | if(err){ | ||
661 | err = -errno; | ||
662 | goto out; | ||
663 | } | ||
664 | |||
665 | printk("F_SETLK failed, file already locked by pid %d\n", lock.l_pid); | ||
666 | err = save; | ||
667 | out: | ||
668 | return(err); | ||
669 | } | ||
670 | |||
671 | /* | ||
672 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
673 | * Emacs will notice this stuff at the end of the file and automatically | ||
674 | * adjust the settings for this buffer only. This must remain at the end | ||
675 | * of the file. | ||
676 | * --------------------------------------------------------------------------- | ||
677 | * Local variables: | ||
678 | * c-file-style: "linux" | ||
679 | * End: | ||
680 | */ | ||