1 /* safe.c - error-free I/O routines (panic on error)
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 "hackerlab/os/stdarg.h"
13 #include "hackerlab/os/errno.h"
14 #include "hackerlab/os/errno-to-string.h"
15 #include "hackerlab/bugs/panic.h"
16 #include "hackerlab/vu/vu-utils.h"
17 #include "hackerlab/vu/safe.h"
18 
19 
20 /************************************************************************
21  *(h0 "An Errorless Front-end to the VU File-system Interface")
22  *
23  * These functions perform I/O but never return errors.  If an error
24  * occurs, they print a message and abort the program.
25  *
26  */
27 
28 
29 
30 
31 /*(c safe_access)
32  * int safe_access (const char * path, int mode);
33  *
34  * See xref:"vu_access".
35  *
36  * If mode is F_OK and the file does not exist, return -1.
37  */
38 int
safe_access(const char * path,int mode)39 safe_access (const char * path, int mode)
40 {
41   int errn;
42   int answer;
43   answer = vu_access (&errn, path, mode);
44   if (answer < 0)
45     {
46       if ((errn == ENOENT) && (mode == F_OK))
47         return -1;
48       printfmt (&errn, 2, "Error during call to `vu_access' for %s (%s)\n", path, errno_to_string (errn));
49       panic ("I/O error");
50     }
51   return answer;
52 }
53 
54 
55 /*(c safe_chdir)
56  * int safe_chdir (const char * path);
57  *
58  * See xref:"vu_chdir".
59  */
60 int
safe_chdir(const char * path)61 safe_chdir (const char * path)
62 {
63   int errn;
64   int answer;
65   answer = vu_chdir (&errn, path);
66   if (answer < 0)
67     {
68       printfmt (&errn, 2, "Error during call to `vu_chdir' for %s (%s)\n", path, errno_to_string (errn));
69       panic ("I/O error");
70     }
71   return answer;
72 }
73 
74 
75 /*(c safe_chmod)
76  * int safe_chmod (const char * path, int mode);
77  *
78  * See xref:"vu_chmod".
79  */
80 int
safe_chmod(const char * path,int mode)81 safe_chmod (const char * path, int mode)
82 {
83   int errn;
84   int answer;
85   answer = vu_chmod (&errn, path, mode);
86   if (answer < 0)
87     {
88       printfmt (&errn, 2, "Error during call to `vu_chmod' for %s (%s)\n", path, errno_to_string (errn));
89       panic ("I/O error");
90     }
91   return answer;
92 }
93 
94 
95 /*(c safe_chown)
96  * int safe_chown (const char * path, int owner, int group);
97  *
98  * See xref:"vu_chown".
99  */
100 int
safe_chown(const char * path,int owner,int group)101 safe_chown (const char * path, int owner, int group)
102 {
103   int errn;
104   int answer;
105   answer = vu_chown (&errn, path, owner, group);
106   if (answer < 0)
107     {
108       printfmt (&errn, 2, "Error during call to `vu_chown' for %s (%s)\n", path, errno_to_string (errn));
109       panic ("I/O error");
110     }
111   return answer;
112 }
113 
114 
115 /*(c safe_chroot)
116  * int safe_chroot (const char * path);
117  *
118  * See xref:"vu_chroot".
119  */
120 int
safe_chroot(const char * path)121 safe_chroot (const char * path)
122 {
123   int errn;
124   int answer;
125   answer = vu_chroot (&errn, path);
126   if (answer < 0)
127     {
128       printfmt (&errn, 2, "Error during call to `vu_chroot' for %s (%s)\n", path, errno_to_string (errn));
129       panic ("I/O error");
130     }
131   return answer;
132 }
133 
134 
135 /*(c safe_close)
136  * int safe_close (int fd);
137  *
138  * See xref:"vu_close".
139  */
140 int
safe_close(int fd)141 safe_close (int fd)
142 {
143   int errn;
144   int answer;
145 
146   answer = vu_close (&errn, fd);
147   if (0 > answer)
148     {
149       printfmt (&errn, 2, "Error while closing descriptor %d (%s)\n", fd, errno_to_string (errn));
150       panic ("I/O error");
151     }
152   return answer;
153 }
154 
155 
156 /*(c safe_closedir)
157  * int safe_closedir (DIR * dir);
158  *
159  * See xref:"vu_closedir".
160  */
161 int
safe_closedir(DIR * dir)162 safe_closedir (DIR * dir)
163 {
164   int errn;
165   int answer;
166 
167   answer = vu_closedir (&errn, dir);
168   if (0 > answer)
169     {
170       printfmt (&errn, 2, "Error while closing directory (%s)\n", errno_to_string (errn));
171       panic ("I/O error");
172     }
173   return answer;
174 }
175 
176 
177 /*(c safe_fchdir)
178  * int safe_fchdir (int fd);
179  *
180  * See xref:"vu_fchdir".
181  */
182 int
safe_fchdir(int fd)183 safe_fchdir (int fd)
184 {
185   int errn;
186   int answer;
187 
188   answer = vu_fchdir (&errn, fd);
189   if (0 > answer)
190     {
191       printfmt (&errn, 2, "Error calling `vu_fchdir' for descriptor %d (%s)\n", fd, errno_to_string (errn));
192       panic ("I/O error");
193     }
194   return answer;
195 }
196 
197 
198 /*(c safe_fchmod)
199  * int safe_fchmod (int fd, int mode);
200  *
201  * See xref:"vu_fchmod".
202  */
203 int
safe_fchmod(int fd,int mode)204 safe_fchmod (int fd, int mode)
205 {
206   int errn;
207   int answer;
208 
209   answer = vu_fchmod (&errn, fd, mode);
210   if (0 > answer)
211     {
212       printfmt (&errn, 2, "Error calling `vu_fchmod' for descriptor %d (%s)\n", fd, errno_to_string (errn));
213       panic ("I/O error");
214     }
215   return answer;
216 }
217 
218 
219 /*(c safe_fchown)
220  * int safe_fchown (int fd, int owner, int group);
221  *
222  * See xref:"vu_fchown".
223  */
224 int
safe_fchown(int fd,int owner,int group)225 safe_fchown (int fd, int owner, int group)
226 {
227   int errn;
228   int answer;
229 
230   answer = vu_fchown (&errn, fd, owner, group);
231   if (0 > answer)
232     {
233       printfmt (&errn, 2, "Error calling `vu_fchgrp' for descriptor %d (%s)\n", fd, errno_to_string (errn));
234       panic ("I/O error");
235     }
236   return answer;
237 }
238 
239 
240 /*(c safe_fstat)
241  * int safe_fstat (int fd, struct stat * buf);
242  *
243  * See xref:"vu_fstat".
244  */
245 int
safe_fstat(int fd,struct stat * buf)246 safe_fstat (int fd, struct stat * buf)
247 {
248   int errn;
249   int answer;
250 
251   answer = vu_fstat (&errn, fd, buf);
252   if (0 > answer)
253     {
254       printfmt (&errn, 2, "Error calling `vu_fstat' for descriptor %d (%s)\n", fd, errno_to_string (errn));
255       panic ("I/O error");
256     }
257   return answer;
258 }
259 
260 
261 /*(c safe_fsync)
262  * int safe_fsync (int fd);
263  *
264  * See xref:"vu_fsync".
265  */
266 int
safe_fsync(int fd)267 safe_fsync (int fd)
268 {
269   int errn;
270   int answer;
271 
272   answer = vu_fsync (&errn, fd);
273   if (0 > answer)
274     {
275       printfmt (&errn, 2, "Error calling `vu_fsync' for descriptor %d (%s)\n", fd, errno_to_string (errn));
276       panic ("I/O error");
277     }
278   return answer;
279 }
280 
281 
282 /*(c safe_ftruncate)
283  * int safe_ftruncate (int fd, long where);
284  *
285  * See xref:"vu_ftruncate".
286  */
287 int
safe_ftruncate(int fd,long where)288 safe_ftruncate (int fd, long where)
289 {
290   int errn;
291   int answer;
292 
293   answer = vu_ftruncate (&errn, fd, where);
294   if (0 > answer)
295     {
296       printfmt (&errn, 2, "Error calling `vu_ftruncate' for descriptor %d (%s)\n", fd, errno_to_string (errn));
297       panic ("I/O error");
298     }
299   return answer;
300 }
301 
302 
303 /*(c safe_link)
304  * int safe_link (const char * from, const char * to);
305  *
306  * See xref:"vu_link".
307  */
308 int
safe_link(const char * from,const char * to)309 safe_link (const char * from, const char * to)
310 {
311   int errn;
312   int answer;
313 
314   answer = vu_link (&errn, from, to);
315   if (0 > answer)
316     {
317       printfmt (&errn, 2, "Error calling `vu_link' to link \"%s\" to \"%s\" (%s)\n", to, from, errno_to_string (errn));
318       panic ("I/O error");
319     }
320   return answer;
321 }
322 
323 
324 /*(c safe_lseek)
325  * long safe_lseek (int fd, long offset, int whence);
326  *
327  * See xref:"vu_lseek".
328  */
329 long
safe_lseek(int fd,long offset,int whence)330 safe_lseek (int fd, long offset, int whence)
331 {
332   int errn;
333   long answer;
334 
335   answer = vu_lseek (&errn, fd, offset, whence);
336   if (0 > answer)
337     {
338       printfmt (&errn, 2, "Error calling `vu_lseek' for descriptor %d, offset %ld, whence=%d (%s)\n", fd, offset, whence, errno_to_string (errn));
339       panic ("I/O error");
340     }
341   return answer;
342 }
343 
344 
345 /*(c safe_lstat)
346  * int safe_lstat (const char * path, struct stat * buf);
347  *
348  * See xref:"vu_lstat".
349  */
350 int
safe_lstat(const char * path,struct stat * buf)351 safe_lstat (const char * path, struct stat * buf)
352 {
353   int errn;
354   int answer;
355 
356   answer = vu_lstat (&errn, path, buf);
357   if (0 > answer)
358     {
359       printfmt (&errn, 2, "Error calling `vu_lstat' for \"%s\" (%s)\n", path, errno_to_string (errn));
360       panic ("I/O error");
361     }
362   return answer;
363 }
364 
365 
366 /*(c safe_mkdir)
367  * int safe_mkdir (const char * path, int mode);
368  *
369  * See xref:"vu_mkdir".
370  */
371 int
safe_mkdir(const char * path,int mode)372 safe_mkdir (const char * path, int mode)
373 {
374   int errn;
375   int answer;
376 
377   answer = vu_mkdir (&errn, path, mode);
378   if (0 > answer)
379     {
380       printfmt (&errn, 2, "unable to create directory \"%s\" (%s)\n", path, errno_to_string (errn));
381       panic ("I/O error");
382     }
383   return answer;
384 }
385 
386 /*(c safe_open)
387  * int safe_open (const char * path, int flags, int mode);
388  *
389  * See xref:"vu_open".
390  */
391 int
safe_open(const char * path,int flags,int mode)392 safe_open (const char * path, int flags, int mode)
393 {
394   int errn;
395   int fd;
396 
397   fd = vu_open (&errn, path, flags, mode);
398   if (0 > fd)
399     {
400       printfmt (&errn, 2, "unable to open file \"%s\" (%s)\n", path, errno_to_string (errn));
401       panic ("I/O error");
402     }
403   return fd;
404 }
405 
406 /*(c safe_opendir)
407  * int safe_opendir (DIR ** retv, const char * path);
408  *
409  * See xref:"vu_opendir".
410  */
411 int
safe_opendir(DIR ** retv,const char * path)412 safe_opendir (DIR ** retv, const char * path)
413 {
414   int errn;
415   int answer;
416 
417   answer = vu_opendir (&errn, retv, path);
418   if (0 > answer)
419     {
420       printfmt (&errn, 2, "unable to open directory \"%s\" (%s)\n", path, errno_to_string (errn));
421       panic ("I/O error");
422     }
423   return answer;
424 }
425 
426 
427 /*(c safe_read)
428  * long safe_read (int fd, char * buf, long count);
429  *
430  * See xref:"vu_read".
431  */
432 long
safe_read(int fd,char * buf,long count)433 safe_read (int fd, char * buf, long count)
434 {
435   int errn;
436   long answer;
437 
438   answer = vu_read (&errn, fd, buf, count);
439   if (0 > answer)
440     {
441       printfmt (&errn, 2, "Error calling `vu_read' for descriptor %d (%s)\n", fd, errno_to_string (errn));
442       panic ("I/O error");
443     }
444   return answer;
445 }
446 
447 
448 /*(c safe_read_retry)
449  * long safe_read_retry (int fd, char * buf, long count);
450  *
451  * See xref:"vu_read_retry".
452  */
453 long
safe_read_retry(int fd,char * buf,long count)454 safe_read_retry (int fd, char * buf, long count)
455 {
456   int errn;
457   long answer;
458 
459   answer = vu_read_retry (&errn, fd, buf, count);
460   if (0 > answer)
461     {
462       printfmt (&errn, 2, "Error calling `vu_read_retry' for descriptor %d (%s)\n", fd, errno_to_string (errn));
463       panic ("I/O error");
464     }
465   return answer;
466 }
467 
468 
469 /*(c safe_readdir)
470  * int safe_readdir (char ** file_ret, DIR * dir);
471  *
472  * See xref:"vu_readdir".
473  */
474 int
safe_readdir(char ** file_ret,DIR * dir)475 safe_readdir (char ** file_ret, DIR * dir)
476 {
477   int errn;
478   int answer;
479 
480   answer = vu_readdir (&errn, 0, file_ret, dir);
481   if (0 > answer)
482     {
483       if (!errn)
484         *file_ret = 0;
485       else
486         {
487           printfmt (&errn, 2, "unable to read directory (%s)\n", errno_to_string (errn));
488           panic ("I/O error");
489         }
490     }
491   return answer;
492 }
493 
494 
495 /*(c safe_readlink)
496  * int safe_readlink (const char * path, char * buf, int bufsize);
497  *
498  * See xref:"vu_readlink".
499  */
500 int
safe_readlink(const char * path,char * buf,int bufsize)501 safe_readlink (const char * path, char * buf, int bufsize)
502 {
503   int errn;
504   int answer;
505 
506   answer = vu_readlink (&errn, path, buf, bufsize);
507   if (0 > answer)
508     {
509       printfmt (&errn, 2, "unable to read link \"%s\" (%s)\n", path, errno_to_string (errn));
510       panic ("I/O error");
511     }
512   return answer;
513 }
514 
515 
516 /*(c safe_rename)
517  * int safe_rename (const char * from, const char * to);
518  *
519  * See xref:"vu_rename".
520  */
521 int
safe_rename(const char * from,const char * to)522 safe_rename (const char * from, const char * to)
523 {
524   int errn;
525   int answer;
526 
527   answer = vu_rename (&errn, from, to);
528   if (0 > answer)
529     {
530       printfmt (&errn, 2, "unable to rename \"%s\" to \"%s\" (%s)\n", from, to, errno_to_string (errn));
531       panic ("I/O error");
532     }
533   return answer;
534 }
535 
536 
537 /*(c safe_rmdir)
538  * int safe_rmdir (const char * path);
539  *
540  * See xref:"vu_rmdir".
541  */
542 int
safe_rmdir(const char * path)543 safe_rmdir (const char * path)
544 {
545   int errn;
546   int answer;
547 
548   answer = vu_rmdir (&errn, path);
549   if (0 > answer)
550     {
551       printfmt (&errn, 2, "unable to rmdir \"%s\" (%s)\n", path, errno_to_string (errn));
552       panic ("I/O error");
553     }
554   return answer;
555 }
556 
557 
558 
559 /*(c safe_stat)
560  * int safe_stat (const char * path, struct stat * buf);
561  *
562  * See xref:"vu_stat".
563  */
564 int
safe_stat(const char * path,struct stat * buf)565 safe_stat (const char * path, struct stat * buf)
566 {
567   int errn;
568   int answer;
569 
570   answer = vu_stat (&errn, path, buf);
571   if (0 > answer)
572     {
573       printfmt (&errn, 2, "Error calling `vu_stat' for \"%s\" (%s)\n", path, errno_to_string (errn));
574       panic ("I/O error");
575     }
576   return answer;
577 }
578 
579 
580 /*(c safe_symlink)
581  * int safe_symlink (const char * from, const char * to);
582  *
583  * See xref:"vu_symlink".
584  */
585 int
safe_symlink(const char * from,const char * to)586 safe_symlink (const char * from, const char * to)
587 {
588   int errn;
589   int answer;
590 
591   answer = vu_symlink (&errn, from, to);
592   if (0 > answer)
593     {
594       printfmt (&errn, 2, "Error calling `vu_symlink' to link \"%s\" to \"%s\" (%s)\n", to, from, errno_to_string (errn));
595       panic ("I/O error");
596     }
597   return answer;
598 }
599 
600 
601 
602 /*(c safe_truncate)
603  * int safe_truncate (const char * path, long where);
604  *
605  * See xref:"vu_truncate".
606  */
607 int
safe_truncate(const char * path,long where)608 safe_truncate (const char * path, long where)
609 {
610   int errn;
611   int answer;
612 
613   answer = vu_truncate (&errn, path, where);
614   if (0 > answer)
615     {
616       printfmt (&errn, 2, "Error calling `vu_truncate' to truncate \"%s\" at %ld (%s)\n", path, where, errno_to_string (errn));
617       panic ("I/O error");
618     }
619   return answer;
620 }
621 
622 
623 /*(c safe_unlink)
624  * int safe_unlink (const char * path);
625  *
626  * See xref:"vu_unlink".
627  */
628 int
safe_unlink(const char * path)629 safe_unlink (const char * path)
630 {
631   int errn;
632   int answer;
633 
634   answer = vu_unlink (&errn, path);
635   if (0 > answer)
636     {
637       printfmt (&errn, 2, "Error calling `vu_unlink' to remove \"%s\" (%s)\n", path, errno_to_string (errn));
638       panic ("I/O error");
639     }
640   return answer;
641 }
642 
643 
644 /*(c safe_utime)
645  * int safe_utime (const char * path, struct utimbuf * times);
646  *
647  * See xref:"vu_utime".
648  */
649 int
safe_utime(const char * path,struct utimbuf * times)650 safe_utime (const char * path, struct utimbuf * times)
651 {
652   int errn;
653   int answer;
654 
655   answer = vu_utime (&errn, path, times);
656   if (0 > answer)
657     {
658       printfmt (&errn, 2, "Error calling `vu_utime' to change timestamps of \"%s\" (%s)\n", path, errno_to_string (errn));
659       panic ("I/O error");
660     }
661   return answer;
662 }
663 
664 
665 /*(c safe_write)
666  * long safe_write (int fd, const char * buf, long count);
667  *
668  * See xref:"vu_write".
669  */
670 long
safe_write(int fd,const char * buf,long count)671 safe_write (int fd, const char * buf, long count)
672 {
673   int errn;
674   long answer;
675 
676   answer = vu_write (&errn, fd, buf, count);
677   if (0 > answer)
678     {
679       printfmt (&errn, 2, "Error calling `vu_write' for descriptor %d (%s)\n", fd, errno_to_string (errn));
680       panic ("I/O error");
681     }
682   return answer;
683 }
684 
685 
686 /*(c safe_write_retry)
687  * long safe_write_retry (int fd, const t_uchar * buf, int amt);
688  *
689  * See xref:"vu_write_retry".
690  */
691 long
safe_write_retry(int fd,const t_uchar * buf,int amt)692 safe_write_retry (int fd, const t_uchar * buf, int amt)
693 {
694   int errn;
695   long answer;
696 
697   answer = vu_write_retry (&errn, fd, buf, amt);
698   if (0 > answer)
699     {
700       printfmt (&errn, 2, "Error calling `vu_write_retry' for descriptor %d (%s)\n", fd, errno_to_string (errn));
701       panic ("I/O error");
702     }
703   return answer;
704 }
705 
706 
707 /*(c safe_fcntl)
708  * int safe_fcntl (int fd, int cmd, long arg);
709  *
710  * See xref:"vu_fcntl".
711  */
712 int
safe_fcntl(int fd,int cmd,long arg)713 safe_fcntl (int fd, int cmd, long arg)
714 {
715   int errn;
716   int answer;
717 
718   answer = vu_fcntl (&errn, fd, cmd, arg);
719   if (0 > answer)
720     {
721       printfmt (&errn, 2, "Error calling `vu_fcntl' for descriptor %d (%s)\n", fd, errno_to_string (errn));
722       panic ("I/O error");
723     }
724   return answer;
725 }
726 
727 
728 /*(c safe_dup)
729  * int safe_dup (int fd);
730  *
731  * See xref:"vu_dup".
732  */
733 int
safe_dup(int fd)734 safe_dup (int fd)
735 {
736   int errn;
737   int answer;
738 
739   answer = vu_dup (&errn, fd);
740   if (0 > answer)
741     {
742       printfmt (&errn, 2, "Error calling `vu_dup' for descriptor %d (%s)\n", fd, errno_to_string (errn));
743       panic ("I/O error");
744     }
745   return answer;
746 }
747 
748 
749 /*(c safe_dup2)
750  * int safe_dup2 (int fd, int newfd);
751  *
752  * See xref:"vu_dup2".
753  */
754 int
safe_dup2(int fd,int newfd)755 safe_dup2 (int fd, int newfd)
756 {
757   int errn;
758   int answer;
759 
760   answer = vu_dup2 (&errn, fd, newfd);
761   if (0 > answer)
762     {
763       printfmt (&errn, 2, "Error calling `vu_dup2' to duplicate %d to %d (%s)\n", fd, newfd, errno_to_string (errn));
764       panic ("I/O error");
765     }
766   return answer;
767 }
768 
769 
770 
771 /*(c safe_move_state)
772  * int safe_move_state (int fd, int newfd);
773  *
774  * See xref:"vu_move_state".
775  */
776 int
safe_move_state(int fd,int newfd)777 safe_move_state (int fd, int newfd)
778 {
779   int errn;
780   int answer;
781 
782   answer = vu_move_state (&errn, fd, newfd);
783   if (0 > answer)
784     {
785       printfmt (&errn, 2, "Error calling `vu_move_state' to copy VU state for descriptor %d to descriptor %d (%s)\n", fd, newfd, errno_to_string (errn));
786       panic ("I/O error");
787     }
788   return answer;
789 }
790 
791 
792