comparison lib/lib.c @ 643:7bdebd2af1d6

Add signal handler to clean up tempfile.
author Rob Landley <rob@landley.net>
date Mon, 30 Jul 2012 01:01:33 -0500
parents 85fc06bd63c4
children 2b957eaa00c7
comparison
equal deleted inserted replaced
642:812afb883392 643:7bdebd2af1d6
706 perror_msg("%s", *argv); 706 perror_msg("%s", *argv);
707 toys.exitval = 1; 707 toys.exitval = 1;
708 continue; 708 continue;
709 } 709 }
710 function(fd, *argv); 710 function(fd, *argv);
711 if (!flags) close(fd); 711 if (flags == O_RDONLY) close(fd);
712 } while (*++argv); 712 } while (*++argv);
713 } 713 }
714 714
715 // Call loopfiles_rw with O_RDONLY and !failok (common case). 715 // Call loopfiles_rw with O_RDONLY and !failok (common case).
716 void loopfiles(char **argv, void (*function)(int fd, char *name)) 716 void loopfiles(char **argv, void (*function)(int fd, char *name))
770 toys.exitval=1; 770 toys.exitval=1;
771 } 771 }
772 return rc; 772 return rc;
773 } 773 }
774 774
775 static char *tempfile2zap;
776 static void tempfile_handler(int i)
777 {
778 if (1 < (long)tempfile2zap) unlink(tempfile2zap);
779 _exit(1);
780 }
781
775 // Open a temporary file to copy an existing file into. 782 // Open a temporary file to copy an existing file into.
776 int copy_tempfile(int fdin, char *name, char **tempname) 783 int copy_tempfile(int fdin, char *name, char **tempname)
777 { 784 {
778 struct stat statbuf; 785 struct stat statbuf;
779 int fd; 786 int fd;
780 787
781 *tempname = xstrndup(name, strlen(name)+6); 788 *tempname = xstrndup(name, strlen(name)+6);
782 strcat(*tempname,"XXXXXX"); 789 strcat(*tempname,"XXXXXX");
783 if(-1 == (fd = mkstemp(*tempname))) error_exit("no temp file"); 790 if(-1 == (fd = mkstemp(*tempname))) error_exit("no temp file");
791 if (!tempfile2zap) sigatexit(tempfile_handler);
792 tempfile2zap = *tempname;
784 793
785 // Set permissions of output file 794 // Set permissions of output file
786 795
787 fstat(fdin, &statbuf); 796 fstat(fdin, &statbuf);
788 fchmod(fd, statbuf.st_mode); 797 fchmod(fd, statbuf.st_mode);
794 void delete_tempfile(int fdin, int fdout, char **tempname) 803 void delete_tempfile(int fdin, int fdout, char **tempname)
795 { 804 {
796 close(fdin); 805 close(fdin);
797 close(fdout); 806 close(fdout);
798 unlink(*tempname); 807 unlink(*tempname);
808 tempfile2zap = (char *)1;
799 free(*tempname); 809 free(*tempname);
800 *tempname = NULL; 810 *tempname = NULL;
801 } 811 }
802 812
803 // Copy the rest of the data and replace the original with the copy. 813 // Copy the rest of the data and replace the original with the copy.
810 xsendfile(fdin, fdout); 820 xsendfile(fdin, fdout);
811 xclose(fdin); 821 xclose(fdin);
812 } 822 }
813 xclose(fdout); 823 xclose(fdout);
814 rename(*tempname, temp); 824 rename(*tempname, temp);
825 tempfile2zap = (char *)1;
815 free(*tempname); 826 free(*tempname);
816 free(temp); 827 free(temp);
817 *tempname = NULL; 828 *tempname = NULL;
818 } 829 }
819 830
925 // http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html 936 // http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html
926 937
927 #define SIGNIFY(x) {SIG##x, #x} 938 #define SIGNIFY(x) {SIG##x, #x}
928 939
929 static struct signame signames[] = { 940 static struct signame signames[] = {
930 SIGNIFY(ABRT), SIGNIFY(ALRM), SIGNIFY(BUS), SIGNIFY(CHLD), SIGNIFY(CONT), 941 SIGNIFY(ABRT), SIGNIFY(ALRM), SIGNIFY(BUS),
931 SIGNIFY(FPE), SIGNIFY(HUP), SIGNIFY(ILL), SIGNIFY(INT), SIGNIFY(KILL), 942 SIGNIFY(FPE), SIGNIFY(HUP), SIGNIFY(ILL), SIGNIFY(INT), SIGNIFY(KILL),
932 SIGNIFY(PIPE), SIGNIFY(QUIT), SIGNIFY(SEGV), SIGNIFY(STOP), SIGNIFY(TERM), 943 SIGNIFY(PIPE), SIGNIFY(QUIT), SIGNIFY(SEGV), SIGNIFY(TERM),
933 SIGNIFY(TSTP), SIGNIFY(TTIN), SIGNIFY(TTOU), SIGNIFY(USR1), SIGNIFY(USR2), 944 SIGNIFY(USR1), SIGNIFY(USR2), SIGNIFY(SYS), SIGNIFY(TRAP),
934 SIGNIFY(SYS), SIGNIFY(TRAP), SIGNIFY(URG), SIGNIFY(VTALRM), SIGNIFY(XCPU), 945 SIGNIFY(VTALRM), SIGNIFY(XCPU), SIGNIFY(XFSZ),
935 SIGNIFY(XFSZ) 946
947 // Start of non-terminal signals
948
949 SIGNIFY(CHLD), SIGNIFY(CONT), SIGNIFY(STOP), SIGNIFY(TSTP),
950 SIGNIFY(TTIN), SIGNIFY(TTOU), SIGNIFY(URG)
936 }; 951 };
937 952
938 // not in posix: SIGNIFY(STKFLT), SIGNIFY(WINCH), SIGNIFY(IO), SIGNIFY(PWR) 953 // not in posix: SIGNIFY(STKFLT), SIGNIFY(WINCH), SIGNIFY(IO), SIGNIFY(PWR)
939 // obsolete: SIGNIFY(PROF) SIGNIFY(POLL) 954 // obsolete: SIGNIFY(PROF) SIGNIFY(POLL)
940 955
956 // Install the same handler on every signal that defaults to killing the process
957 void sigatexit(void *handler)
958 {
959 int i;
960 for (i=0; signames[i].num != SIGCHLD; i++)
961 signal(signames[i].num, handler);
962 }
941 // Convert name to signal number. If name == NULL print names. 963 // Convert name to signal number. If name == NULL print names.
942 int sig_to_num(char *pidstr) 964 int sig_to_num(char *pidstr)
943 { 965 {
944 int i; 966 int i;
945 967
965 for (i=0; i<sizeof(signames)/sizeof(struct signame); i++) 987 for (i=0; i<sizeof(signames)/sizeof(struct signame); i++)
966 if (signames[i].num == sig) return signames[i].name; 988 if (signames[i].num == sig) return signames[i].name;
967 return NULL; 989 return NULL;
968 } 990 }
969 991
970 992 // premute mode bits based on posix mode strings.
971 mode_t string_to_mode(char *modestr, mode_t mode) 993 mode_t string_to_mode(char *modestr, mode_t mode)
972 { 994 {
973 char *whos = "ogua", *hows = "=+-", *whats = "xwrstX", *whys = "ogu"; 995 char *whos = "ogua", *hows = "=+-", *whats = "xwrstX", *whys = "ogu";
974 char *s, *str = modestr; 996 char *s, *str = modestr;
975 997