diff options
author | ng0 <ng0@n0.is> | 2019-09-10 16:59:32 +0000 |
---|---|---|
committer | ng0 <ng0@n0.is> | 2019-09-10 16:59:32 +0000 |
commit | 04b6df21cd281e8cd540139f8d9ae85defc1961c (patch) | |
tree | 6357199445df8d5c0c631bc8f10aef838b1f9f1e /src/util/os_priority.c | |
parent | 483b0139a218a5f8a8311bda3eb23bcd88f57688 (diff) | |
download | gnunet-04b6df21cd281e8cd540139f8d9ae85defc1961c.tar.gz gnunet-04b6df21cd281e8cd540139f8d9ae85defc1961c.zip |
remove CYGWIN codeblocks, drop vendored Windows openvpn, drop win32 specific files.
configures and builds okay.
testsuite wasn't checked, will be checked.
diff including the plibc removal is now around 14370 lines of code less.
Diffstat (limited to 'src/util/os_priority.c')
-rw-r--r-- | src/util/os_priority.c | 615 |
1 files changed, 1 insertions, 614 deletions
diff --git a/src/util/os_priority.c b/src/util/os_priority.c index ebe469b3b..e25623af5 100644 --- a/src/util/os_priority.c +++ b/src/util/os_priority.c | |||
@@ -350,7 +350,6 @@ start_process(int pipe_control, | |||
350 | const char *filename, | 350 | const char *filename, |
351 | char *const argv[]) | 351 | char *const argv[]) |
352 | { | 352 | { |
353 | #ifndef MINGW | ||
354 | pid_t ret; | 353 | pid_t ret; |
355 | char fds[16]; | 354 | char fds[16]; |
356 | struct GNUNET_OS_Process *gnunet_proc; | 355 | struct GNUNET_OS_Process *gnunet_proc; |
@@ -464,7 +463,7 @@ start_process(int pipe_control, | |||
464 | GNUNET_array_append(lscp, ls, -1); | 463 | GNUNET_array_append(lscp, ls, -1); |
465 | } | 464 | } |
466 | #if DARWIN | 465 | #if DARWIN |
467 | /* see https://gnunet.org/vfork */ | 466 | /* see https://web.archive.org/web/20150924082249/gnunet.org/vfork */ |
468 | ret = vfork(); | 467 | ret = vfork(); |
469 | #else | 468 | #else |
470 | ret = fork(); | 469 | ret = fork(); |
@@ -589,547 +588,6 @@ start_process(int pipe_control, | |||
589 | execvp(filename, argv); | 588 | execvp(filename, argv); |
590 | LOG_STRERROR_FILE(GNUNET_ERROR_TYPE_ERROR, "execvp", filename); | 589 | LOG_STRERROR_FILE(GNUNET_ERROR_TYPE_ERROR, "execvp", filename); |
591 | _exit(1); | 590 | _exit(1); |
592 | #else | ||
593 | struct GNUNET_DISK_FileHandle *childpipe_read; | ||
594 | struct GNUNET_DISK_FileHandle *childpipe_write; | ||
595 | HANDLE childpipe_read_handle; | ||
596 | char **arg; | ||
597 | char **non_const_argv; | ||
598 | unsigned int cmdlen; | ||
599 | char *cmd; | ||
600 | char *idx; | ||
601 | STARTUPINFOW start; | ||
602 | PROCESS_INFORMATION proc; | ||
603 | int argcount = 0; | ||
604 | struct GNUNET_OS_Process *gnunet_proc; | ||
605 | char path[MAX_PATH + 1]; | ||
606 | char *our_env[7] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; | ||
607 | char *env_block = NULL; | ||
608 | char *pathbuf; | ||
609 | DWORD pathbuf_len; | ||
610 | DWORD alloc_len; | ||
611 | char *self_prefix; | ||
612 | char *bindir; | ||
613 | char *libdir; | ||
614 | char *ptr; | ||
615 | char *non_const_filename; | ||
616 | char win_path[MAX_PATH + 1]; | ||
617 | struct GNUNET_DISK_PipeHandle *lsocks_pipe; | ||
618 | const struct GNUNET_DISK_FileHandle *lsocks_write_fd; | ||
619 | HANDLE lsocks_read; | ||
620 | HANDLE lsocks_write; | ||
621 | wchar_t *wpath; | ||
622 | wchar_t *wcmd; | ||
623 | size_t wpath_len; | ||
624 | size_t wcmd_len; | ||
625 | int env_off; | ||
626 | int fail; | ||
627 | long lRet; | ||
628 | HANDLE stdin_handle; | ||
629 | HANDLE stdout_handle; | ||
630 | HANDLE stdih, stdoh, stdeh; | ||
631 | DWORD stdif, stdof, stdef; | ||
632 | BOOL bresult; | ||
633 | DWORD error_code; | ||
634 | DWORD create_no_window; | ||
635 | |||
636 | if (GNUNET_SYSERR == | ||
637 | GNUNET_OS_check_helper_binary(filename, GNUNET_NO, NULL)) | ||
638 | return NULL; /* not executable */ | ||
639 | |||
640 | /* Search in prefix dir (hopefully - the directory from which | ||
641 | * the current module was loaded), bindir and libdir, then in PATH | ||
642 | */ | ||
643 | self_prefix = GNUNET_OS_installation_get_path(GNUNET_OS_IPK_SELF_PREFIX); | ||
644 | bindir = GNUNET_OS_installation_get_path(GNUNET_OS_IPK_BINDIR); | ||
645 | libdir = GNUNET_OS_installation_get_path(GNUNET_OS_IPK_LIBDIR); | ||
646 | |||
647 | pathbuf_len = GetEnvironmentVariableA("PATH", (char *)&pathbuf, 0); | ||
648 | |||
649 | alloc_len = pathbuf_len + 1 + strlen(self_prefix) + 1 + strlen(bindir) + 1 + | ||
650 | strlen(libdir); | ||
651 | |||
652 | pathbuf = GNUNET_malloc(alloc_len * sizeof(char)); | ||
653 | |||
654 | ptr = pathbuf; | ||
655 | ptr += sprintf(pathbuf, "%s;%s;%s;", self_prefix, bindir, libdir); | ||
656 | GNUNET_free(self_prefix); | ||
657 | GNUNET_free(bindir); | ||
658 | GNUNET_free(libdir); | ||
659 | |||
660 | alloc_len = GetEnvironmentVariableA("PATH", ptr, pathbuf_len); | ||
661 | if (alloc_len != pathbuf_len - 1) | ||
662 | { | ||
663 | GNUNET_free(pathbuf); | ||
664 | errno = ENOSYS; /* PATH changed on the fly. What kind of error is that? */ | ||
665 | return NULL; | ||
666 | } | ||
667 | |||
668 | cmdlen = strlen(filename); | ||
669 | if ((cmdlen < 5) || (0 != strcmp(&filename[cmdlen - 4], ".exe"))) | ||
670 | GNUNET_asprintf(&non_const_filename, "%s.exe", filename); | ||
671 | else | ||
672 | GNUNET_asprintf(&non_const_filename, "%s", filename); | ||
673 | |||
674 | /* It could be in POSIX form, convert it to a DOS path early on */ | ||
675 | if (ERROR_SUCCESS != | ||
676 | (lRet = plibc_conv_to_win_path(non_const_filename, win_path))) | ||
677 | { | ||
678 | SetErrnoFromWinError(lRet); | ||
679 | LOG_STRERROR_FILE(GNUNET_ERROR_TYPE_ERROR, | ||
680 | "plibc_conv_to_win_path", | ||
681 | non_const_filename); | ||
682 | GNUNET_free(non_const_filename); | ||
683 | GNUNET_free(pathbuf); | ||
684 | return NULL; | ||
685 | } | ||
686 | GNUNET_free(non_const_filename); | ||
687 | non_const_filename = GNUNET_strdup(win_path); | ||
688 | /* Check that this is the full path. If it isn't, search. */ | ||
689 | /* FIXME: convert it to wchar_t and use SearchPathW? | ||
690 | * Remember: arguments to _start_process() are technically in UTF-8... | ||
691 | */ | ||
692 | if (non_const_filename[1] == ':') | ||
693 | { | ||
694 | snprintf(path, sizeof(path) / sizeof(char), "%s", non_const_filename); | ||
695 | LOG(GNUNET_ERROR_TYPE_DEBUG, | ||
696 | "Using path `%s' as-is. PATH is %s\n", | ||
697 | path, | ||
698 | ptr); | ||
699 | } | ||
700 | else if (!SearchPathA(pathbuf, | ||
701 | non_const_filename, | ||
702 | NULL, | ||
703 | sizeof(path) / sizeof(char), | ||
704 | path, | ||
705 | NULL)) | ||
706 | { | ||
707 | SetErrnoFromWinError(GetLastError()); | ||
708 | LOG_STRERROR_FILE(GNUNET_ERROR_TYPE_ERROR, | ||
709 | "SearchPath", | ||
710 | non_const_filename); | ||
711 | GNUNET_free(non_const_filename); | ||
712 | GNUNET_free(pathbuf); | ||
713 | return NULL; | ||
714 | } | ||
715 | else | ||
716 | LOG(GNUNET_ERROR_TYPE_DEBUG, "Found `%s' in PATH `%s'\n", path, pathbuf); | ||
717 | GNUNET_free(pathbuf); | ||
718 | GNUNET_free(non_const_filename); | ||
719 | |||
720 | /* Count the number of arguments */ | ||
721 | arg = (char **)argv; | ||
722 | while (*arg) | ||
723 | { | ||
724 | arg++; | ||
725 | argcount++; | ||
726 | } | ||
727 | |||
728 | /* Allocate a copy argv */ | ||
729 | non_const_argv = GNUNET_malloc(sizeof(char *) * (argcount + 1)); | ||
730 | |||
731 | /* Copy all argv strings */ | ||
732 | argcount = 0; | ||
733 | arg = (char **)argv; | ||
734 | while (*arg) | ||
735 | { | ||
736 | if (arg == argv) | ||
737 | non_const_argv[argcount] = GNUNET_strdup(path); | ||
738 | else | ||
739 | non_const_argv[argcount] = GNUNET_strdup(*arg); | ||
740 | arg++; | ||
741 | argcount++; | ||
742 | } | ||
743 | non_const_argv[argcount] = NULL; | ||
744 | |||
745 | /* Count cmd len */ | ||
746 | cmdlen = 1; | ||
747 | arg = non_const_argv; | ||
748 | while (*arg) | ||
749 | { | ||
750 | cmdlen = cmdlen + strlen(*arg) + 4; | ||
751 | arg++; | ||
752 | } | ||
753 | |||
754 | /* Allocate and create cmd */ | ||
755 | cmd = idx = GNUNET_malloc(sizeof(char) * cmdlen); | ||
756 | arg = non_const_argv; | ||
757 | while (*arg) | ||
758 | { | ||
759 | char arg_last_char = (*arg)[strlen(*arg) - 1]; | ||
760 | idx += sprintf(idx, | ||
761 | "\"%s%s\"%s", | ||
762 | *arg, | ||
763 | arg_last_char == '\\' ? "\\" : "", | ||
764 | *(arg + 1) ? " " : ""); | ||
765 | arg++; | ||
766 | } | ||
767 | |||
768 | while (argcount > 0) | ||
769 | GNUNET_free(non_const_argv[--argcount]); | ||
770 | GNUNET_free(non_const_argv); | ||
771 | |||
772 | memset(&start, 0, sizeof(start)); | ||
773 | start.cb = sizeof(start); | ||
774 | if ((pipe_stdin != NULL) || (pipe_stdout != NULL) || (std_inheritance != 0)) | ||
775 | start.dwFlags |= STARTF_USESTDHANDLES; | ||
776 | |||
777 | stdih = GetStdHandle(STD_INPUT_HANDLE); | ||
778 | GetHandleInformation(stdih, &stdif); | ||
779 | if (pipe_stdin != NULL) | ||
780 | { | ||
781 | GNUNET_DISK_internal_file_handle_( | ||
782 | GNUNET_DISK_pipe_handle(pipe_stdin, GNUNET_DISK_PIPE_END_READ), | ||
783 | &stdin_handle, | ||
784 | sizeof(HANDLE)); | ||
785 | start.hStdInput = stdin_handle; | ||
786 | } | ||
787 | else if (stdih) | ||
788 | { | ||
789 | if (std_inheritance & GNUNET_OS_INHERIT_STD_IN) | ||
790 | { | ||
791 | SetHandleInformation(stdih, HANDLE_FLAG_INHERIT, 1); | ||
792 | if (pipe_stdin == NULL) | ||
793 | start.hStdInput = stdih; | ||
794 | } | ||
795 | else | ||
796 | SetHandleInformation(stdih, HANDLE_FLAG_INHERIT, 0); | ||
797 | } | ||
798 | |||
799 | |||
800 | stdoh = GetStdHandle(STD_OUTPUT_HANDLE); | ||
801 | GetHandleInformation(stdoh, &stdof); | ||
802 | if (NULL != pipe_stdout) | ||
803 | { | ||
804 | GNUNET_DISK_internal_file_handle_( | ||
805 | GNUNET_DISK_pipe_handle(pipe_stdout, GNUNET_DISK_PIPE_END_WRITE), | ||
806 | &stdout_handle, | ||
807 | sizeof(HANDLE)); | ||
808 | start.hStdOutput = stdout_handle; | ||
809 | } | ||
810 | else if (stdoh) | ||
811 | { | ||
812 | if (std_inheritance & GNUNET_OS_INHERIT_STD_OUT) | ||
813 | { | ||
814 | SetHandleInformation(stdoh, HANDLE_FLAG_INHERIT, 1); | ||
815 | if (pipe_stdout == NULL) | ||
816 | start.hStdOutput = stdoh; | ||
817 | } | ||
818 | else | ||
819 | SetHandleInformation(stdoh, HANDLE_FLAG_INHERIT, 0); | ||
820 | } | ||
821 | |||
822 | stdeh = GetStdHandle(STD_ERROR_HANDLE); | ||
823 | GetHandleInformation(stdeh, &stdef); | ||
824 | if (stdeh) | ||
825 | { | ||
826 | if (std_inheritance & GNUNET_OS_INHERIT_STD_ERR) | ||
827 | { | ||
828 | SetHandleInformation(stdeh, HANDLE_FLAG_INHERIT, 1); | ||
829 | start.hStdError = stdeh; | ||
830 | } | ||
831 | else | ||
832 | SetHandleInformation(stdeh, HANDLE_FLAG_INHERIT, 0); | ||
833 | } | ||
834 | |||
835 | if (GNUNET_YES == pipe_control) | ||
836 | { | ||
837 | struct GNUNET_DISK_PipeHandle *childpipe; | ||
838 | childpipe = GNUNET_DISK_pipe(GNUNET_NO, GNUNET_NO, GNUNET_YES, GNUNET_NO); | ||
839 | if (NULL == childpipe) | ||
840 | return NULL; | ||
841 | childpipe_read = | ||
842 | GNUNET_DISK_pipe_detach_end(childpipe, GNUNET_DISK_PIPE_END_READ); | ||
843 | childpipe_write = | ||
844 | GNUNET_DISK_pipe_detach_end(childpipe, GNUNET_DISK_PIPE_END_WRITE); | ||
845 | GNUNET_DISK_pipe_close(childpipe); | ||
846 | if ((NULL == childpipe_read) || (NULL == childpipe_write) || | ||
847 | (GNUNET_OK != GNUNET_DISK_internal_file_handle_(childpipe_read, | ||
848 | &childpipe_read_handle, | ||
849 | sizeof(HANDLE)))) | ||
850 | { | ||
851 | if (childpipe_read) | ||
852 | GNUNET_DISK_file_close(childpipe_read); | ||
853 | if (childpipe_write) | ||
854 | GNUNET_DISK_file_close(childpipe_write); | ||
855 | GNUNET_free(cmd); | ||
856 | return NULL; | ||
857 | } | ||
858 | /* Unlike *nix variant, we don't dup the handle, so can't close | ||
859 | * filehandle right now. | ||
860 | */ | ||
861 | SetHandleInformation(childpipe_read_handle, HANDLE_FLAG_INHERIT, 1); | ||
862 | } | ||
863 | else | ||
864 | { | ||
865 | childpipe_read = NULL; | ||
866 | childpipe_write = NULL; | ||
867 | } | ||
868 | |||
869 | if (lsocks != NULL && lsocks[0] != INVALID_SOCKET) | ||
870 | { | ||
871 | lsocks_pipe = | ||
872 | GNUNET_DISK_pipe(GNUNET_YES, GNUNET_YES, GNUNET_YES, GNUNET_NO); | ||
873 | |||
874 | if (lsocks_pipe == NULL) | ||
875 | { | ||
876 | GNUNET_free(cmd); | ||
877 | GNUNET_DISK_pipe_close(lsocks_pipe); | ||
878 | if (GNUNET_YES == pipe_control) | ||
879 | { | ||
880 | GNUNET_DISK_file_close(childpipe_write); | ||
881 | GNUNET_DISK_file_close(childpipe_read); | ||
882 | } | ||
883 | return NULL; | ||
884 | } | ||
885 | lsocks_write_fd = | ||
886 | GNUNET_DISK_pipe_handle(lsocks_pipe, GNUNET_DISK_PIPE_END_WRITE); | ||
887 | GNUNET_DISK_internal_file_handle_(lsocks_write_fd, | ||
888 | &lsocks_write, | ||
889 | sizeof(HANDLE)); | ||
890 | GNUNET_DISK_internal_file_handle_( | ||
891 | GNUNET_DISK_pipe_handle(lsocks_pipe, GNUNET_DISK_PIPE_END_READ), | ||
892 | &lsocks_read, | ||
893 | sizeof(HANDLE)); | ||
894 | } | ||
895 | else | ||
896 | { | ||
897 | lsocks_pipe = NULL; | ||
898 | lsocks_write_fd = NULL; | ||
899 | } | ||
900 | |||
901 | env_off = 0; | ||
902 | if (GNUNET_YES == pipe_control) | ||
903 | { | ||
904 | GNUNET_asprintf(&our_env[env_off++], "%s=", GNUNET_OS_CONTROL_PIPE); | ||
905 | GNUNET_asprintf(&our_env[env_off++], "%p", childpipe_read_handle); | ||
906 | } | ||
907 | if ((lsocks != NULL) && (lsocks[0] != INVALID_SOCKET)) | ||
908 | { | ||
909 | /*This will tell the child that we're going to send lsocks over the pipe*/ | ||
910 | GNUNET_asprintf(&our_env[env_off++], "%s=", "GNUNET_OS_READ_LSOCKS"); | ||
911 | GNUNET_asprintf(&our_env[env_off++], "%lu", lsocks_read); | ||
912 | } | ||
913 | our_env[env_off++] = NULL; | ||
914 | env_block = CreateCustomEnvTable(our_env); | ||
915 | while (0 > env_off) | ||
916 | GNUNET_free_non_null(our_env[--env_off]); | ||
917 | |||
918 | wpath_len = 0; | ||
919 | if (NULL == | ||
920 | (wpath = | ||
921 | u8_to_u16((uint8_t *)path, 1 + strlen(path), NULL, &wpath_len))) | ||
922 | { | ||
923 | LOG(GNUNET_ERROR_TYPE_DEBUG, | ||
924 | "Failed to convert `%s' from UTF-8 to UTF-16: %d\n", | ||
925 | path, | ||
926 | errno); | ||
927 | GNUNET_free(env_block); | ||
928 | GNUNET_free(cmd); | ||
929 | if (lsocks_pipe) | ||
930 | GNUNET_DISK_pipe_close(lsocks_pipe); | ||
931 | if (GNUNET_YES == pipe_control) | ||
932 | { | ||
933 | GNUNET_DISK_file_close(childpipe_write); | ||
934 | GNUNET_DISK_file_close(childpipe_read); | ||
935 | } | ||
936 | return NULL; | ||
937 | } | ||
938 | |||
939 | wcmd_len = 0; | ||
940 | if (NULL == | ||
941 | (wcmd = u8_to_u16((uint8_t *)cmd, 1 + strlen(cmd), NULL, &wcmd_len))) | ||
942 | { | ||
943 | LOG(GNUNET_ERROR_TYPE_DEBUG, | ||
944 | "Failed to convert `%s' from UTF-8 to UTF-16: %d\n", | ||
945 | cmd, | ||
946 | errno); | ||
947 | GNUNET_free(env_block); | ||
948 | GNUNET_free(cmd); | ||
949 | free(wpath); | ||
950 | if (lsocks_pipe) | ||
951 | GNUNET_DISK_pipe_close(lsocks_pipe); | ||
952 | if (GNUNET_YES == pipe_control) | ||
953 | { | ||
954 | GNUNET_DISK_file_close(childpipe_write); | ||
955 | GNUNET_DISK_file_close(childpipe_read); | ||
956 | } | ||
957 | return NULL; | ||
958 | } | ||
959 | |||
960 | create_no_window = 0; | ||
961 | { | ||
962 | HANDLE console_input = CreateFile("CONIN$", | ||
963 | GENERIC_READ, | ||
964 | FILE_SHARE_READ | FILE_SHARE_WRITE, | ||
965 | NULL, | ||
966 | OPEN_EXISTING, | ||
967 | 0, | ||
968 | NULL); | ||
969 | if (INVALID_HANDLE_VALUE == console_input) | ||
970 | create_no_window = CREATE_NO_WINDOW; | ||
971 | else | ||
972 | CloseHandle(console_input); | ||
973 | } | ||
974 | |||
975 | bresult = CreateProcessW(wpath, | ||
976 | wcmd, | ||
977 | NULL, | ||
978 | NULL, | ||
979 | GNUNET_YES, | ||
980 | create_no_window | CREATE_SUSPENDED, | ||
981 | env_block, | ||
982 | NULL, | ||
983 | &start, | ||
984 | &proc); | ||
985 | error_code = GetLastError(); | ||
986 | |||
987 | if ((NULL == pipe_stdin) && (stdih)) | ||
988 | SetHandleInformation(stdih, HANDLE_FLAG_INHERIT, stdif); | ||
989 | |||
990 | |||
991 | if ((NULL == pipe_stdout) && (stdoh)) | ||
992 | SetHandleInformation(stdoh, HANDLE_FLAG_INHERIT, stdof); | ||
993 | |||
994 | if (stdeh) | ||
995 | SetHandleInformation(stdeh, HANDLE_FLAG_INHERIT, stdef); | ||
996 | |||
997 | if (!bresult) | ||
998 | LOG(GNUNET_ERROR_TYPE_ERROR, | ||
999 | "CreateProcess(%s, %s) failed: %lu\n", | ||
1000 | path, | ||
1001 | cmd, | ||
1002 | error_code); | ||
1003 | |||
1004 | GNUNET_free(env_block); | ||
1005 | GNUNET_free(cmd); | ||
1006 | free(wpath); | ||
1007 | free(wcmd); | ||
1008 | if (GNUNET_YES == pipe_control) | ||
1009 | { | ||
1010 | GNUNET_DISK_file_close(childpipe_read); | ||
1011 | } | ||
1012 | |||
1013 | if (!bresult) | ||
1014 | { | ||
1015 | if (GNUNET_YES == pipe_control) | ||
1016 | { | ||
1017 | GNUNET_DISK_file_close(childpipe_write); | ||
1018 | } | ||
1019 | if (NULL != lsocks) | ||
1020 | GNUNET_DISK_pipe_close(lsocks_pipe); | ||
1021 | SetErrnoFromWinError(error_code); | ||
1022 | return NULL; | ||
1023 | } | ||
1024 | |||
1025 | gnunet_proc = GNUNET_new(struct GNUNET_OS_Process); | ||
1026 | gnunet_proc->pid = proc.dwProcessId; | ||
1027 | gnunet_proc->handle = proc.hProcess; | ||
1028 | gnunet_proc->control_pipe = childpipe_write; | ||
1029 | |||
1030 | CreateThread(NULL, 64000, &child_wait_thread, (void *)gnunet_proc, 0, NULL); | ||
1031 | |||
1032 | ResumeThread(proc.hThread); | ||
1033 | CloseHandle(proc.hThread); | ||
1034 | |||
1035 | if ((NULL == lsocks) || (INVALID_SOCKET == lsocks[0])) | ||
1036 | return gnunet_proc; | ||
1037 | |||
1038 | GNUNET_DISK_pipe_close_end(lsocks_pipe, GNUNET_DISK_PIPE_END_READ); | ||
1039 | |||
1040 | /* This is a replacement for "goto error" that doesn't use goto */ | ||
1041 | fail = 1; | ||
1042 | do | ||
1043 | { | ||
1044 | ssize_t wrote; | ||
1045 | uint64_t size; | ||
1046 | uint64_t count; | ||
1047 | unsigned int i; | ||
1048 | |||
1049 | /* Tell the number of sockets */ | ||
1050 | for (count = 0; lsocks && lsocks[count] != INVALID_SOCKET; count++) | ||
1051 | ; | ||
1052 | |||
1053 | wrote = GNUNET_DISK_file_write(lsocks_write_fd, &count, sizeof(count)); | ||
1054 | if (sizeof(count) != wrote) | ||
1055 | { | ||
1056 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
1057 | "Failed to write %u count bytes to the child: %lu\n", | ||
1058 | sizeof(count), | ||
1059 | GetLastError()); | ||
1060 | break; | ||
1061 | } | ||
1062 | for (i = 0; lsocks && lsocks[i] != INVALID_SOCKET; i++) | ||
1063 | { | ||
1064 | WSAPROTOCOL_INFOA pi; | ||
1065 | /* Get a socket duplication info */ | ||
1066 | if (SOCKET_ERROR == | ||
1067 | WSADuplicateSocketA(lsocks[i], gnunet_proc->pid, &pi)) | ||
1068 | { | ||
1069 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
1070 | "Failed to duplicate an socket[%u]: %lu\n", | ||
1071 | i, | ||
1072 | GetLastError()); | ||
1073 | break; | ||
1074 | } | ||
1075 | /* Synchronous I/O is not nice, but we can't schedule this: | ||
1076 | * lsocks will be closed/freed by the caller soon, and until | ||
1077 | * the child creates a duplicate, closing a socket here will | ||
1078 | * close it for good. | ||
1079 | */ | ||
1080 | /* Send the size of the structure | ||
1081 | * (the child might be built with different headers...) | ||
1082 | */ | ||
1083 | size = sizeof(pi); | ||
1084 | wrote = GNUNET_DISK_file_write(lsocks_write_fd, &size, sizeof(size)); | ||
1085 | if (sizeof(size) != wrote) | ||
1086 | { | ||
1087 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
1088 | "Failed to write %u size[%u] bytes to the child: %lu\n", | ||
1089 | sizeof(size), | ||
1090 | i, | ||
1091 | GetLastError()); | ||
1092 | break; | ||
1093 | } | ||
1094 | /* Finally! Send the data */ | ||
1095 | wrote = GNUNET_DISK_file_write(lsocks_write_fd, &pi, sizeof(pi)); | ||
1096 | if (sizeof(pi) != wrote) | ||
1097 | { | ||
1098 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
1099 | "Failed to write %u socket[%u] bytes to the child: %lu\n", | ||
1100 | sizeof(pi), | ||
1101 | i, | ||
1102 | GetLastError()); | ||
1103 | break; | ||
1104 | } | ||
1105 | } | ||
1106 | /* This will block us until the child makes a final read or closes | ||
1107 | * the pipe (hence no 'wrote' check), since we have to wait for it | ||
1108 | * to duplicate the last socket, before we return and start closing | ||
1109 | * our own copies) | ||
1110 | */ | ||
1111 | wrote = GNUNET_DISK_file_write(lsocks_write_fd, &count, sizeof(count)); | ||
1112 | fail = 0; | ||
1113 | } | ||
1114 | while (fail); | ||
1115 | |||
1116 | GNUNET_DISK_file_sync(lsocks_write_fd); | ||
1117 | GNUNET_DISK_pipe_close(lsocks_pipe); | ||
1118 | |||
1119 | if (fail) | ||
1120 | { | ||
1121 | /* If we can't pass on the socket(s), the child will block forever, | ||
1122 | * better put it out of its misery. | ||
1123 | */ | ||
1124 | SafeTerminateProcess(gnunet_proc->handle, 0, 0); | ||
1125 | CloseHandle(gnunet_proc->handle); | ||
1126 | if (NULL != gnunet_proc->control_pipe) | ||
1127 | GNUNET_DISK_file_close(gnunet_proc->control_pipe); | ||
1128 | GNUNET_free(gnunet_proc); | ||
1129 | return NULL; | ||
1130 | } | ||
1131 | return gnunet_proc; | ||
1132 | #endif | ||
1133 | } | 591 | } |
1134 | 592 | ||
1135 | 593 | ||
@@ -1439,7 +897,6 @@ process_status(struct GNUNET_OS_Process *proc, | |||
1439 | unsigned long *code, | 897 | unsigned long *code, |
1440 | int options) | 898 | int options) |
1441 | { | 899 | { |
1442 | #ifndef MINGW | ||
1443 | int status; | 900 | int status; |
1444 | int ret; | 901 | int ret; |
1445 | 902 | ||
@@ -1488,53 +945,6 @@ process_status(struct GNUNET_OS_Process *proc, | |||
1488 | *type = GNUNET_OS_PROCESS_UNKNOWN; | 945 | *type = GNUNET_OS_PROCESS_UNKNOWN; |
1489 | *code = 0; | 946 | *code = 0; |
1490 | } | 947 | } |
1491 | #else | ||
1492 | #ifndef WNOHANG | ||
1493 | #define WNOHANG 42 /* just a flag for W32, purely internal at this point */ | ||
1494 | #endif | ||
1495 | |||
1496 | HANDLE h; | ||
1497 | DWORD c, error_code, ret; | ||
1498 | |||
1499 | h = proc->handle; | ||
1500 | ret = proc->pid; | ||
1501 | if (h == NULL || ret == 0) | ||
1502 | { | ||
1503 | LOG(GNUNET_ERROR_TYPE_WARNING, | ||
1504 | "Invalid process information {%d, %08X}\n", | ||
1505 | ret, | ||
1506 | h); | ||
1507 | return GNUNET_SYSERR; | ||
1508 | } | ||
1509 | if (h == NULL) | ||
1510 | h = GetCurrentProcess(); | ||
1511 | |||
1512 | if (WNOHANG != options) | ||
1513 | { | ||
1514 | if (WAIT_OBJECT_0 != WaitForSingleObject(h, INFINITE)) | ||
1515 | { | ||
1516 | SetErrnoFromWinError(GetLastError()); | ||
1517 | return GNUNET_SYSERR; | ||
1518 | } | ||
1519 | } | ||
1520 | SetLastError(0); | ||
1521 | ret = GetExitCodeProcess(h, &c); | ||
1522 | error_code = GetLastError(); | ||
1523 | if (ret == 0 || error_code != NO_ERROR) | ||
1524 | { | ||
1525 | SetErrnoFromWinError(error_code); | ||
1526 | LOG_STRERROR(GNUNET_ERROR_TYPE_WARNING, "GetExitCodeProcess"); | ||
1527 | return GNUNET_SYSERR; | ||
1528 | } | ||
1529 | if (STILL_ACTIVE == c) | ||
1530 | { | ||
1531 | *type = GNUNET_OS_PROCESS_RUNNING; | ||
1532 | *code = 0; | ||
1533 | return GNUNET_NO; | ||
1534 | } | ||
1535 | *type = GNUNET_OS_PROCESS_EXITED; | ||
1536 | *code = c; | ||
1537 | #endif | ||
1538 | 948 | ||
1539 | return GNUNET_OK; | 949 | return GNUNET_OK; |
1540 | } | 950 | } |
@@ -1589,7 +999,6 @@ GNUNET_OS_process_wait_status(struct GNUNET_OS_Process *proc, | |||
1589 | int | 999 | int |
1590 | GNUNET_OS_process_wait(struct GNUNET_OS_Process *proc) | 1000 | GNUNET_OS_process_wait(struct GNUNET_OS_Process *proc) |
1591 | { | 1001 | { |
1592 | #ifndef MINGW | ||
1593 | pid_t pid = proc->pid; | 1002 | pid_t pid = proc->pid; |
1594 | pid_t ret; | 1003 | pid_t ret; |
1595 | 1004 | ||
@@ -1601,28 +1010,6 @@ GNUNET_OS_process_wait(struct GNUNET_OS_Process *proc) | |||
1601 | return GNUNET_SYSERR; | 1010 | return GNUNET_SYSERR; |
1602 | } | 1011 | } |
1603 | return GNUNET_OK; | 1012 | return GNUNET_OK; |
1604 | #else | ||
1605 | HANDLE h; | ||
1606 | |||
1607 | h = proc->handle; | ||
1608 | if (NULL == h) | ||
1609 | { | ||
1610 | LOG(GNUNET_ERROR_TYPE_WARNING, | ||
1611 | "Invalid process information {%d, %08X}\n", | ||
1612 | proc->pid, | ||
1613 | h); | ||
1614 | return GNUNET_SYSERR; | ||
1615 | } | ||
1616 | if (NULL == h) | ||
1617 | h = GetCurrentProcess(); | ||
1618 | |||
1619 | if (WAIT_OBJECT_0 != WaitForSingleObject(h, INFINITE)) | ||
1620 | { | ||
1621 | SetErrnoFromWinError(GetLastError()); | ||
1622 | return GNUNET_SYSERR; | ||
1623 | } | ||
1624 | return GNUNET_OK; | ||
1625 | #endif | ||
1626 | } | 1013 | } |
1627 | 1014 | ||
1628 | 1015 | ||