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