Mercurial > hg > toybox
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 |