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