aboutsummaryrefslogtreecommitdiff
path: root/src/util/os_priority.c
diff options
context:
space:
mode:
authorng0 <ng0@n0.is>2019-09-10 16:59:32 +0000
committerng0 <ng0@n0.is>2019-09-10 16:59:32 +0000
commit04b6df21cd281e8cd540139f8d9ae85defc1961c (patch)
tree6357199445df8d5c0c631bc8f10aef838b1f9f1e /src/util/os_priority.c
parent483b0139a218a5f8a8311bda3eb23bcd88f57688 (diff)
downloadgnunet-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.c615
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,
1589int 999int
1590GNUNET_OS_process_wait(struct GNUNET_OS_Process *proc) 1000GNUNET_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