1 /* vu-sys.c - direct VU functions
2 *
3 ****************************************************************
4 * Copyright (C) 1999, 2000 Thomas Lord
5 *
6 * See the file "COPYING" for further information about
7 * the copyright and warranty status of this work.
8 */
9
10
11
12 #include <stdio.h>
13 #include "hackerlab/os/errno.h"
14 #include "hackerlab/os/unistd.h"
15 #include "hackerlab/mem/mem.h"
16 #include "hackerlab/vu/vu-sys.h"
17 #include "hackerlab/char/str.h"
18
19
20 /************************************************************************
21 *(h0 "VU Native File System Access")
22 *
23 *
24 * These functions define a trivial file-system implementation in
25 * which all functions call their system-call equivalents.
26 */
27
28 struct vu_fs_discipline _vu_system_fs_vtable
29 = { VU_FS_DISCIPLINE_INITIALIZERS (vu_sys_) };
30
31 /*(c vu_sys_make_closure)
32 * void * vu_sys_make_closure (void * closure);
33 *
34 * Return `closure'.
35 */
36 void *
vu_sys_make_closure(void * closure)37 vu_sys_make_closure (void * closure)
38 {
39 return closure;
40 }
41
42
43 /*(c vu_sys_free_closure)
44 * void vu_sys_free_closure (void * closure);
45 *
46 * A noop.
47 */
48 void
vu_sys_free_closure(void * closure)49 vu_sys_free_closure (void * closure)
50 {}
51
52
53 /*(c vu_sys_access)
54 * int vu_sys_access (int * errn, const char * path, int mode, void * closure);
55 *
56 * Call `access'.
57 */
58 int
vu_sys_access(int * errn,const char * path,int mode,void * closure)59 vu_sys_access (int * errn, const char * path, int mode, void * closure)
60 {
61 int rv;
62 rv = access (path, mode);
63 if (rv)
64 if (errn) *errn = errno;
65 return rv;
66 }
67
68
69 /*(c vu_sys_chdir)
70 * int vu_sys_chdir (int * errn, const char * path, void * closure);
71 *
72 * Call `chdir'.
73 */
74 int
vu_sys_chdir(int * errn,const char * path,void * closure)75 vu_sys_chdir (int * errn, const char * path, void * closure)
76 {
77 int rv;
78 rv = chdir (path);
79 if (rv)
80 if (errn) *errn = errno;
81 return rv;
82 }
83
84
85 /*(c vu_sys_chmod)
86 * int vu_sys_chmod (int * errn, const char * path, int mode, void * closure);
87 *
88 * Call `chmod'.
89 */
90 int
vu_sys_chmod(int * errn,const char * path,int mode,void * closure)91 vu_sys_chmod (int * errn, const char * path, int mode, void * closure)
92 {
93 int rv;
94 rv = chmod (path, mode);
95 if (rv)
96 if (errn) *errn = errno;
97 return rv;
98 }
99
100
101 /*(c vu_sys_chown)
102 * int vu_sys_chown (int * errn,
103 * const char * path,
104 * int owner,
105 * int group,
106 * void * closure);
107 *
108 * Call `chown'.
109 */
110 int
vu_sys_chown(int * errn,const char * path,int owner,int group,void * closure)111 vu_sys_chown (int * errn,
112 const char * path,
113 int owner,
114 int group,
115 void * closure)
116 {
117 int rv;
118 rv = chown (path, owner, group);
119 if (rv)
120 if (errn) *errn = errno;
121 return rv;
122 }
123
124
125 /*(c vu_sys_chroot)
126 * int vu_sys_chroot (int * errn, const char * path, void * closure);
127 *
128 * Call `chroot'.
129 */
130 int
vu_sys_chroot(int * errn,const char * path,void * closure)131 vu_sys_chroot (int * errn, const char * path, void * closure)
132 {
133 int rv;
134 rv = chroot (path);
135 if (rv)
136 if (errn) *errn = errno;
137 return rv;
138 }
139
140
141 /*(c vu_sys_closedir)
142 * int vu_sys_closedir (int * errn, DIR * dir, void * closure);
143 *
144 * Call `closedir'.
145 */
146 int
vu_sys_closedir(int * errn,DIR * dir,void * closure)147 vu_sys_closedir (int * errn, DIR * dir, void * closure)
148 {
149 int rv;
150 rv = closedir (dir);
151 if (rv)
152 if (errn) *errn = errno;
153 return rv;
154 }
155
156
157 /*(c vu_sys_close)
158 * int vu_sys_close (int * errn, int fd, void * closure);
159 *
160 * Call `close'.
161 */
162 int
vu_sys_close(int * errn,int fd,void * closure)163 vu_sys_close (int * errn, int fd, void * closure)
164 {
165 int rv;
166 rv = close (fd);
167 if (rv)
168 if (errn) *errn = errno;
169 return rv;
170 }
171
172
173 /*(c vu_sys_fchdir)
174 * int vu_sys_fchdir (int * errn, int fd, void * closure);
175 *
176 * Call `fchdir'.
177 */
178 int
vu_sys_fchdir(int * errn,int fd,void * closure)179 vu_sys_fchdir (int * errn, int fd, void * closure)
180 {
181 int rv;
182 rv = fchdir (fd);
183 if (rv)
184 if (errn) *errn = errno;
185 return rv;
186 }
187
188
189 /*(c vu_sys_fchmod)
190 * int vu_sys_fchmod (int * errn, int fd, int mode, void * closure);
191 *
192 * Call `fchmod'.
193 */
194 int
vu_sys_fchmod(int * errn,int fd,int mode,void * closure)195 vu_sys_fchmod (int * errn, int fd, int mode, void * closure)
196 {
197 int rv;
198 rv = fchmod (fd, mode);
199 if (rv)
200 if (errn) *errn = errno;
201 return rv;
202 }
203
204
205 /*(c vu_sys_fchown)
206 * int vu_sys_fchown (int * errn,
207 * int fd,
208 * int owner,
209 * int group,
210 * void * closure);
211 *
212 * Call `fchown'.
213 */
214 int
vu_sys_fchown(int * errn,int fd,int owner,int group,void * closure)215 vu_sys_fchown (int * errn,
216 int fd,
217 int owner,
218 int group,
219 void * closure)
220 {
221 int rv;
222 rv = fchown (fd, owner, group);
223 if (rv)
224 if (errn) *errn = errno;
225 return rv;
226 }
227
228
229 /*(c vu_sys_fstat)
230 * int vu_sys_fstat (int * errn,
231 * int fd,
232 * struct stat * buf,
233 * void * closure);
234 *
235 * Call `fstat'.
236 */
237 int
vu_sys_fstat(int * errn,int fd,struct stat * buf,void * closure)238 vu_sys_fstat (int * errn,
239 int fd,
240 struct stat * buf,
241 void * closure)
242 {
243 int rv;
244 rv = fstat (fd, buf);
245 if (rv)
246 if (errn) *errn = errno;
247 return rv;
248 }
249
250 /*(c vu_sys_fsync)
251 * int vu_sys_fsync (int * errn, int fd, void * closure);
252 *
253 * Call `fsync'.
254 */
255 int
vu_sys_fsync(int * errn,int fd,void * closure)256 vu_sys_fsync (int * errn, int fd, void * closure)
257 {
258 int rv;
259 rv = fsync (fd);
260 if (rv)
261 if (errn) *errn = errno;
262 return rv;
263 }
264
265 /*(c vu_sys_ftruncate)
266 * int vu_sys_ftruncate (int * errn, int fd, off_t where, void * closure);
267 *
268 * Call `ftruncate'.
269 */
270 int
vu_sys_ftruncate(int * errn,int fd,off_t where,void * closure)271 vu_sys_ftruncate (int * errn, int fd, off_t where, void * closure)
272 {
273 int rv;
274 rv = ftruncate (fd, where);
275 if (rv)
276 if (errn) *errn = errno;
277 return rv;
278 }
279
280
281 /*(c vu_sys_link)
282 * int vu_sys_link (int * errn, const char * from, const char * to, void * closure);
283 *
284 * Call `link'.
285 */
286 int
vu_sys_link(int * errn,const char * from,const char * to,void * closure)287 vu_sys_link (int * errn, const char * from, const char * to, void * closure)
288 {
289 int rv;
290 rv = link (from, to);
291 if (rv)
292 if (errn) *errn = errno;
293 return rv;
294 }
295
296
297 /*(c vu_sys_lseek)
298 * off_t vu_sys_lseek (int * errn,
299 * int fd,
300 * off_t offset,
301 * int whence,
302 * void * closure);
303 *
304 * Call `lseek'.
305 */
306 off_t
vu_sys_lseek(int * errn,int fd,off_t offset,int whence,void * closure)307 vu_sys_lseek (int * errn,
308 int fd,
309 off_t offset,
310 int whence,
311 void * closure)
312 {
313 off_t rv;
314 rv = lseek (fd, offset, whence);
315 if (rv)
316 if (errn) *errn = errno;
317 return rv;
318 }
319
320
321 /*(c vu_sys_lstat)
322 * int vu_sys_lstat (int * errn,
323 * const char * path,
324 * struct stat * buf,
325 * void * closure);
326 *
327 * Call `lstat'.
328 */
329 int
vu_sys_lstat(int * errn,const char * path,struct stat * buf,void * closure)330 vu_sys_lstat (int * errn,
331 const char * path,
332 struct stat * buf,
333 void * closure)
334 {
335 int rv;
336 rv = lstat (path, buf);
337 if (rv)
338 if (errn) *errn = errno;
339 return rv;
340 }
341
342
343 /*(c vu_sys_mkdir)
344 * int vu_sys_mkdir (int * errn, const char * path, int mode, void * closure);
345 *
346 * Call `mkdir'.
347 */
348 int
vu_sys_mkdir(int * errn,const char * path,int mode,void * closure)349 vu_sys_mkdir (int * errn, const char * path, int mode, void * closure)
350 {
351 int rv;
352 rv = mkdir (path, mode);
353 if (rv)
354 if (errn) *errn = errno;
355 return rv;
356 }
357
358
359 /*(c vu_sys_open)
360 * int vu_sys_open (int * errn,
361 * const char * path,
362 * int flags,
363 * int mode,
364 * void * closure);
365 *
366 * Call `open'.
367 */
368 int
vu_sys_open(int * errn,const char * path,int flags,int mode,void * closure)369 vu_sys_open (int * errn,
370 const char * path,
371 int flags,
372 int mode,
373 void * closure)
374 {
375 int rv;
376 rv = open (path, flags, mode);
377 if (rv)
378 if (errn) *errn = errno;
379 return rv;
380 }
381
382
383 /*(c vu_sys_opendir)
384 * int vu_sys_opendir (int * errn,
385 * DIR ** retv,
386 * const char * path,
387 * void * closure);
388 *
389 * Call `opendir'.
390 */
391 int
vu_sys_opendir(int * errn,DIR ** retv,const char * path,void * closure)392 vu_sys_opendir (int * errn,
393 DIR ** retv,
394 const char * path,
395 void * closure)
396 {
397 *retv = opendir (path);
398 if (!*retv)
399 if (errn) *errn = errno;
400 return (*retv == 0 ? -1 : 0);
401 }
402
403 /*(c vu_sys_read)
404 * ssize_t vu_sys_read (int * errn,
405 * int fd,
406 * char * buf,
407 * size_t count,
408 * void * closure);
409 *
410 *
411 * Call `read'.
412 */
413 ssize_t
vu_sys_read(int * errn,int fd,char * buf,size_t count,void * closure)414 vu_sys_read (int * errn,
415 int fd,
416 char * buf,
417 size_t count,
418 void * closure)
419 {
420 ssize_t rv;
421 rv = read (fd, buf, count);
422 if (rv == -1)
423 if (errn) *errn = errno;
424 return rv;
425 }
426
427
428 /*(c vu_sys_readdir)
429 * int vu_sys_readdir (int * errn,
430 * struct alloc_limits * limits,
431 * char ** file_ret,
432 * DIR * dir,
433 * void * closure);
434 *
435 * Call `readdir'.
436 */
437 int
vu_sys_readdir(int * errn,struct alloc_limits * limits,char ** file_ret,DIR * dir,void * closure)438 vu_sys_readdir (int * errn,
439 struct alloc_limits * limits,
440 char ** file_ret,
441 DIR * dir,
442 void * closure)
443 {
444 struct dirent * de;
445 errno = 0;
446 de = readdir (dir);
447 if (!de)
448 {
449 if (errn) *errn = errno;
450 return -1;
451 }
452
453 if (file_ret)
454 {
455 *file_ret = str_save (limits, de->d_name);
456 if (!*file_ret)
457 {
458 if (errn) *errn = ENOMEM;
459 return -1;
460 }
461 }
462
463 return 0;
464 }
465
466 /*(c vu_sys_readlink)
467 * int vu_sys_readlink (int * errn,
468 * const char * path,
469 * char * buf,
470 * int bufsize,
471 * void * closure);
472 *
473 * Call `readlink'.
474 */
475 int
vu_sys_readlink(int * errn,const char * path,char * buf,int bufsize,void * closure)476 vu_sys_readlink (int * errn,
477 const char * path,
478 char * buf,
479 int bufsize,
480 void * closure)
481 {
482 int rv;
483 rv = readlink (path, buf, bufsize);
484 if (rv)
485 if (errn) *errn = errno;
486 return rv;
487 }
488
489 /*(c vu_sys_rename)
490 * int vu_sys_rename (int * errn, const char * from, const char * to, void * closure);
491 *
492 * Call `rename'.
493 */
494 int
vu_sys_rename(int * errn,const char * from,const char * to,void * closure)495 vu_sys_rename (int * errn, const char * from, const char * to, void * closure)
496 {
497 int rv;
498 rv = rename (from, to);
499 if (rv)
500 if (errn) *errn = errno;
501 return rv;
502 }
503
504 /*(c vu_sys_rmdir)
505 * int vu_sys_rmdir (int * errn, const char * path, void * closure);
506 *
507 * Call `rmdir'.
508 */
509 int
vu_sys_rmdir(int * errn,const char * path,void * closure)510 vu_sys_rmdir (int * errn, const char * path, void * closure)
511 {
512 int rv;
513 rv = rmdir (path);
514 if (rv)
515 if (errn) *errn = errno;
516 return rv;
517 }
518
519
520 /*(c vu_sys_stat)
521 * int vu_sys_stat (int * errn,
522 * const char * path,
523 * struct stat * buf,
524 * void * closure);
525 *
526 * Call `stat'.
527 */
528 int
vu_sys_stat(int * errn,const char * path,struct stat * buf,void * closure)529 vu_sys_stat (int * errn,
530 const char * path,
531 struct stat * buf,
532 void * closure)
533 {
534 int rv;
535 rv = stat (path, buf);
536 if (rv)
537 if (errn) *errn = errno;
538 return rv;
539 }
540
541
542 /*(c vu_sys_symlink)
543 * int vu_sys_symlink (int * errn, const char * from, const char * to, void * closure);
544 *
545 * Call `symlink'.
546 */
547 int
vu_sys_symlink(int * errn,const char * from,const char * to,void * closure)548 vu_sys_symlink (int * errn, const char * from, const char * to, void * closure)
549 {
550 int rv;
551 rv = symlink (from, to);
552 if (rv)
553 if (errn) *errn = errno;
554 return rv;
555 }
556
557
558 /*(c vu_sys_truncate)
559 * int vu_sys_truncate (int * errn,
560 * const char * path,
561 * off_t where,
562 * void * closure);
563 *
564 * Call `truncate'.
565 */
566 int
vu_sys_truncate(int * errn,const char * path,off_t where,void * closure)567 vu_sys_truncate (int * errn,
568 const char * path,
569 off_t where,
570 void * closure)
571 {
572 int rv;
573 rv = truncate (path, where);
574 if (rv)
575 if (errn) *errn = errno;
576 return rv;
577 }
578
579
580 /*(c vu_sys_unlink)
581 * int vu_sys_unlink (int * errn, const char * path, void * closure);
582 *
583 * Call `unlink'.
584 */
585 int
vu_sys_unlink(int * errn,const char * path,void * closure)586 vu_sys_unlink (int * errn, const char * path, void * closure)
587 {
588 int rv;
589 rv = unlink (path);
590 if (rv)
591 if (errn) *errn = errno;
592 return rv;
593 }
594
595
596 /*(c vu_sys_utime)
597 * int vu_sys_utime (int * errn,
598 * const char * path,
599 * struct utimbuf * times,
600 * void * closure);
601 *
602 * Call `utime'.
603 */
604 int
vu_sys_utime(int * errn,const char * path,struct utimbuf * times,void * closure)605 vu_sys_utime (int * errn,
606 const char * path,
607 struct utimbuf * times,
608 void * closure)
609 {
610 int rv;
611 rv = utime (path, times);
612 if (rv)
613 if (errn) *errn = errno;
614 return rv;
615 }
616
617
618 /*(c vu_sys_write)
619 * ssize_t vu_sys_write (int * errn,
620 * int fd,
621 * const char * buf,
622 * size_t count,
623 * void * closure);
624 *
625 * Call `write'.
626 */
627 ssize_t
vu_sys_write(int * errn,int fd,const char * buf,size_t count,void * closure)628 vu_sys_write (int * errn,
629 int fd,
630 const char * buf,
631 size_t count,
632 void * closure)
633 {
634 ssize_t rv;
635
636 if (count == 0)
637 {
638 /* Posix leaves unspecified the behavior of `write' if
639 * `count' is 0 and `fd' is not a regular file.
640 *
641 * I beg to differ.
642 */
643 return 0;
644 }
645
646 rv = write (fd, buf, count);
647 if (rv == -1)
648 if (errn) *errn = errno;
649 return rv;
650 }
651
652
653 /*(c vu_sys_fcntl)
654 * int vu_sys_fcntl (int * errn,
655 * int fd,
656 * int cmd,
657 * long arg,
658 * void * closure);
659 *
660 * Call `fcntl'.
661 */
662 int
vu_sys_fcntl(int * errn,int fd,int cmd,long arg,void * closure)663 vu_sys_fcntl (int * errn,
664 int fd,
665 int cmd,
666 long arg,
667 void * closure)
668 {
669 int rv;
670 rv = fcntl (fd, cmd, arg);
671 if (rv)
672 if (errn) *errn = errno;
673 return rv;
674 }
675
676
677 /*(c vu_sys_dup)
678 * int vu_sys_dup (int * errn, int fd, void * closure);
679 *
680 * Call `dup'.
681 */
682 int
vu_sys_dup(int * errn,int fd,void * closure)683 vu_sys_dup (int * errn, int fd, void * closure)
684 {
685 int rv;
686 rv = dup (fd);
687 if (rv == -1)
688 if (errn) *errn = errno;
689 return rv;
690 }
691
692
693 /*(c vu_sys_dup2)
694 * int vu_sys_dup2 (int * errn, int fd, int newfd, void * closure);
695 *
696 * Call `dup2'.
697 */
698 int
vu_sys_dup2(int * errn,int fd,int newfd,void * closure)699 vu_sys_dup2 (int * errn, int fd, int newfd, void * closure)
700 {
701 int rv;
702 rv = dup2 (fd, newfd);
703 if (rv == -1)
704 if (errn) *errn = errno;
705 return rv;
706 }
707
708
709
710 /*(c vu_sys_move_state)
711 * int vu_sys_move_state (int * errn, int fd, int newfd, void * closure);
712 *
713 * A noop (return 0).
714 */
715 int
vu_sys_move_state(int * errn,int fd,int newfd,void * closure)716 vu_sys_move_state (int * errn, int fd, int newfd, void * closure)
717 {
718 return 0;
719 }
720
721