Mercurial > hg > xemacs-beta
comparison src/process-nt.c @ 563:183866b06e0b
[xemacs-hg @ 2001-05-24 07:50:48 by ben]
Makefile.in.in, abbrev.c, alloc.c, buffer.c, bytecode.c, callint.c, callproc.c, casetab.c, chartab.c, cmdloop.c, cmds.c, console-msw.c, console-msw.h, console-stream.c, console-tty.c, console-x.c, console.c, data.c, database.c, debug.c, device-gtk.c, device-msw.c, device-tty.c, device-x.c, device.c, dialog-gtk.c, dialog-msw.c, dialog-x.c, dialog.c, dired-msw.c, dired.c, doc.c, doprnt.c, dragdrop.c, editfns.c, eldap.c, eldap.h, elhash.c, emacs-widget-accessors.c, emacs.c, emodules.c, esd.c, eval.c, event-Xt.c, event-gtk.c, event-msw.c, event-stream.c, events.c, extents.c, faces.c, file-coding.c, fileio.c, filelock.c, floatfns.c, fns.c, font-lock.c, frame-gtk.c, frame-x.c, frame.c, general-slots.h, glade.c, glyphs-gtk.c, glyphs-msw.c, glyphs-widget.c, glyphs-x.c, glyphs.c, glyphs.h, gpmevent.c, gui-gtk.c, gui-x.c, gui.c, gutter.c, hpplay.c, indent.c, input-method-xlib.c, insdel.c, intl.c, keymap.c, libsst.c, libsst.h, linuxplay.c, lisp.h, lread.c, lstream.c, lstream.h, macros.c, marker.c, md5.c, menubar-gtk.c, menubar-msw.c, menubar-x.c, menubar.c, minibuf.c, miscplay.c, miscplay.h, mule-ccl.c, mule-charset.c, mule-wnnfns.c, mule.c, nas.c, ntplay.c, ntproc.c, objects-gtk.c, objects-msw.c, objects-x.c, objects.c, postgresql.c, print.c, process-nt.c, process-unix.c, process.c, ralloc.c, rangetab.c, redisplay.c, scrollbar.c, search.c, select-gtk.c, select-x.c, select.c, sgiplay.c, sheap.c, sound.c, specifier.c, sunplay.c, symbols.c, symeval.h, symsinit.h, syntax.c, sysdep.c, toolbar-msw.c, toolbar.c, tooltalk.c, ui-byhand.c, ui-gtk.c, undo.c, unexaix.c, unexapollo.c, unexconvex.c, unexec.c, widget.c, win32.c, window.c:
-- defsymbol -> DEFSYMBOL.
-- add an error type to all errors.
-- eliminate the error functions in eval.c that let you just
use Qerror as the type.
-- redo the error API to be more consistent, sensibly named,
and easier to use.
-- redo the error hierarchy somewhat. create new errors:
structure-formation-error, gui-error, invalid-constant,
stack-overflow, out-of-memory, process-error, network-error,
sound-error, printing-unreadable-object, base64-conversion-
error; coding-system-error renamed to text-conversion error;
some others.
-- fix Mule problems in error strings in emodules.c, tooltalk.c.
-- fix error handling in mswin open-network-stream.
-- Mule-ize all sound files and clean up the headers.
-- nativesound.h -> sound.h and used for all sound files.
-- move some shared stuff into glyphs-shared.c: first attempt
at eliminating some of the massive GTK code duplication.
xemacs.mak: add glyphs-shared.c.
xemacs-faq.texi: document how to debug X errors
subr.el: fix doc string to reflect reality
author | ben |
---|---|
date | Thu, 24 May 2001 07:51:33 +0000 |
parents | ed498ef2108b |
children | 373ced43e288 |
comparison
equal
deleted
inserted
replaced
562:c775bd016b32 | 563:183866b06e0b |
---|---|
1 /* Asynchronous subprocess implementation for Win32 | 1 /* Asynchronous subprocess implementation for Win32 |
2 Copyright (C) 1985, 1986, 1987, 1988, 1992, 1993, 1994, 1995 | 2 Copyright (C) 1985, 1986, 1987, 1988, 1992, 1993, 1994, 1995 |
3 Free Software Foundation, Inc. | 3 Free Software Foundation, Inc. |
4 Copyright (C) 1995 Sun Microsystems, Inc. | 4 Copyright (C) 1995 Sun Microsystems, Inc. |
5 Copyright (C) 1995, 1996, 2000 Ben Wing. | 5 Copyright (C) 1995, 1996, 2000, 2001 Ben Wing. |
6 | 6 |
7 This file is part of XEmacs. | 7 This file is part of XEmacs. |
8 | 8 |
9 XEmacs is free software; you can redistribute it and/or modify it | 9 XEmacs is free software; you can redistribute it and/or modify it |
10 under the terms of the GNU General Public License as published by the | 10 under the terms of the GNU General Public License as published by the |
616 validate_signal_number (int signo) | 616 validate_signal_number (int signo) |
617 { | 617 { |
618 if (signo != SIGKILL && signo != SIGTERM | 618 if (signo != SIGKILL && signo != SIGTERM |
619 && signo != SIGQUIT && signo != SIGINT | 619 && signo != SIGQUIT && signo != SIGINT |
620 && signo != SIGHUP) | 620 && signo != SIGHUP) |
621 invalid_argument ("Signal number not supported", make_int (signo)); | 621 invalid_constant ("Signal number not supported", make_int (signo)); |
622 } | 622 } |
623 | 623 |
624 /*-----------------------------------------------------------------------*/ | 624 /*-----------------------------------------------------------------------*/ |
625 /* Process methods */ | 625 /* Process methods */ |
626 /*-----------------------------------------------------------------------*/ | 626 /*-----------------------------------------------------------------------*/ |
651 { | 651 { |
652 /* Initialize winsock */ | 652 /* Initialize winsock */ |
653 WSADATA wsa_data; | 653 WSADATA wsa_data; |
654 /* Request Winsock v1.1 Note the order: (minor=1, major=1) */ | 654 /* Request Winsock v1.1 Note the order: (minor=1, major=1) */ |
655 WSAStartup (MAKEWORD (1,1), &wsa_data); | 655 WSAStartup (MAKEWORD (1,1), &wsa_data); |
656 } | |
657 | |
658 DOESNT_RETURN | |
659 mswindows_report_process_error (const char *string, Lisp_Object data, | |
660 int errnum) | |
661 { | |
662 report_file_type_error (Qprocess_error, mswindows_lisp_error (errnum), | |
663 string, data); | |
664 } | |
665 | |
666 static DOESNT_RETURN | |
667 mswindows_report_winsock_error (const char *string, Lisp_Object data, | |
668 int errnum) | |
669 { | |
670 report_file_type_error (Qnetwork_error, mswindows_lisp_error (errnum), | |
671 string, data); | |
672 } | |
673 | |
674 static void | |
675 ensure_console_window_exists (void) | |
676 { | |
677 if (mswindows_windows9x_p ()) | |
678 mswindows_hide_console (); | |
679 } | |
680 | |
681 int | |
682 compare_env (const void *strp1, const void *strp2) | |
683 { | |
684 const char *str1 = *(const char**)strp1, *str2 = *(const char**)strp2; | |
685 | |
686 while (*str1 && *str2 && *str1 != '=' && *str2 != '=') | |
687 { | |
688 if ((*str1) > (*str2)) | |
689 return 1; | |
690 else if ((*str1) < (*str2)) | |
691 return -1; | |
692 str1++, str2++; | |
693 } | |
694 | |
695 if (*str1 == '=' && *str2 == '=') | |
696 return 0; | |
697 else if (*str1 == '=') | |
698 return -1; | |
699 else | |
700 return 1; | |
656 } | 701 } |
657 | 702 |
658 /* | 703 /* |
659 * Fork off a subprocess. P is a pointer to newly created subprocess | 704 * Fork off a subprocess. P is a pointer to newly created subprocess |
660 * object. If this function signals, the caller is responsible for | 705 * object. If this function signals, the caller is responsible for |
662 * | 707 * |
663 * The method must return PID of the new process, a (positive??? ####) number | 708 * The method must return PID of the new process, a (positive??? ####) number |
664 * which fits into Lisp_Int. No return value indicates an error, the method | 709 * which fits into Lisp_Int. No return value indicates an error, the method |
665 * must signal an error instead. | 710 * must signal an error instead. |
666 */ | 711 */ |
667 | |
668 static void | |
669 signal_cannot_launch (Lisp_Object image_file, DWORD err) | |
670 { | |
671 mswindows_set_errno (err); | |
672 report_file_error ("Error starting", image_file); | |
673 } | |
674 | |
675 static void | |
676 ensure_console_window_exists (void) | |
677 { | |
678 if (mswindows_windows9x_p ()) | |
679 mswindows_hide_console (); | |
680 } | |
681 | |
682 int | |
683 compare_env (const void *strp1, const void *strp2) | |
684 { | |
685 const char *str1 = *(const char**)strp1, *str2 = *(const char**)strp2; | |
686 | |
687 while (*str1 && *str2 && *str1 != '=' && *str2 != '=') | |
688 { | |
689 if ((*str1) > (*str2)) | |
690 return 1; | |
691 else if ((*str1) < (*str2)) | |
692 return -1; | |
693 str1++, str2++; | |
694 } | |
695 | |
696 if (*str1 == '=' && *str2 == '=') | |
697 return 0; | |
698 else if (*str1 == '=') | |
699 return -1; | |
700 else | |
701 return 1; | |
702 } | |
703 | 712 |
704 static int | 713 static int |
705 nt_create_process (Lisp_Process *p, | 714 nt_create_process (Lisp_Process *p, |
706 Lisp_Object *argv, int nargv, | 715 Lisp_Object *argv, int nargv, |
707 Lisp_Object program, Lisp_Object cur_dir) | 716 Lisp_Object program, Lisp_Object cur_dir) |
737 char progname[PATH_MAX]; | 746 char progname[PATH_MAX]; |
738 sprintf (progname, "%s.exe", (char *)XSTRING_DATA (program)); | 747 sprintf (progname, "%s.exe", (char *)XSTRING_DATA (program)); |
739 image_type = xSHGetFileInfoA (progname, 0, NULL, 0, SHGFI_EXETYPE); | 748 image_type = xSHGetFileInfoA (progname, 0, NULL, 0, SHGFI_EXETYPE); |
740 } | 749 } |
741 if (image_type == 0) | 750 if (image_type == 0) |
742 signal_cannot_launch (program, (GetLastError () == ERROR_FILE_NOT_FOUND | 751 mswindows_report_process_error |
743 ? ERROR_BAD_FORMAT : GetLastError ())); | 752 ("Error starting", |
753 program, | |
754 GetLastError () == ERROR_FILE_NOT_FOUND | |
755 ? ERROR_BAD_FORMAT : GetLastError ()); | |
744 windowed = HIWORD (image_type) != 0; | 756 windowed = HIWORD (image_type) != 0; |
745 } | 757 } |
746 else /* NT 3.5; we have no idea so just guess. */ | 758 else /* NT 3.5; we have no idea so just guess. */ |
747 windowed = 0; | 759 windowed = 0; |
748 | 760 |
961 if (do_io) | 973 if (do_io) |
962 { | 974 { |
963 CloseHandle (hmyshove); | 975 CloseHandle (hmyshove); |
964 CloseHandle (hmyslurp); | 976 CloseHandle (hmyslurp); |
965 } | 977 } |
966 signal_cannot_launch (program, GetLastError ()); | 978 mswindows_report_process_error |
979 ("Error starting", | |
980 program, GetLastError ()); | |
967 } | 981 } |
968 | 982 |
969 /* The process started successfully */ | 983 /* The process started successfully */ |
970 if (do_io) | 984 if (do_io) |
971 { | 985 { |
1138 /* #### Hey MS, how long Winsock 2 for '95 will be in beta? */ | 1152 /* #### Hey MS, how long Winsock 2 for '95 will be in beta? */ |
1139 | 1153 |
1140 #define SOCK_TIMER_ID 666 | 1154 #define SOCK_TIMER_ID 666 |
1141 #define XM_SOCKREPLY (WM_USER + 666) | 1155 #define XM_SOCKREPLY (WM_USER + 666) |
1142 | 1156 |
1157 /* Return 0 for success, or error code */ | |
1158 | |
1143 static int | 1159 static int |
1144 get_internet_address (Lisp_Object host, struct sockaddr_in *address, | 1160 get_internet_address (Lisp_Object host, struct sockaddr_in *address) |
1145 Error_behavior errb) | |
1146 { | 1161 { |
1147 char buf [MAXGETHOSTSTRUCT]; | 1162 char buf [MAXGETHOSTSTRUCT]; |
1148 HWND hwnd; | 1163 HWND hwnd; |
1149 HANDLE hasync; | 1164 HANDLE hasync; |
1150 int success = 0; | 1165 int errcode = 0; |
1151 | 1166 |
1152 address->sin_family = AF_INET; | 1167 address->sin_family = AF_INET; |
1153 | 1168 |
1154 /* First check if HOST is already a numeric address */ | 1169 /* First check if HOST is already a numeric address */ |
1155 { | 1170 { |
1156 unsigned long inaddr = inet_addr (XSTRING_DATA (host)); | 1171 unsigned long inaddr = inet_addr (XSTRING_DATA (host)); |
1157 if (inaddr != INADDR_NONE) | 1172 if (inaddr != INADDR_NONE) |
1158 { | 1173 { |
1159 address->sin_addr.s_addr = inaddr; | 1174 address->sin_addr.s_addr = inaddr; |
1160 return 1; | 1175 return 0; |
1161 } | 1176 } |
1162 } | 1177 } |
1163 | 1178 |
1164 /* Create a window which will receive completion messages */ | 1179 /* Create a window which will receive completion messages */ |
1165 hwnd = CreateWindow ("STATIC", NULL, WS_OVERLAPPED, 0, 0, 1, 1, | 1180 hwnd = CreateWindow ("STATIC", NULL, WS_OVERLAPPED, 0, 0, 1, 1, |
1168 | 1183 |
1169 /* Post name resolution request */ | 1184 /* Post name resolution request */ |
1170 hasync = WSAAsyncGetHostByName (hwnd, XM_SOCKREPLY, XSTRING_DATA (host), | 1185 hasync = WSAAsyncGetHostByName (hwnd, XM_SOCKREPLY, XSTRING_DATA (host), |
1171 buf, sizeof (buf)); | 1186 buf, sizeof (buf)); |
1172 if (hasync == NULL) | 1187 if (hasync == NULL) |
1173 goto done; | 1188 { |
1189 errcode = WSAGetLastError (); | |
1190 goto done; | |
1191 } | |
1174 | 1192 |
1175 /* Set a timer to poll for quit every 250 ms */ | 1193 /* Set a timer to poll for quit every 250 ms */ |
1176 SetTimer (hwnd, SOCK_TIMER_ID, 250, NULL); | 1194 SetTimer (hwnd, SOCK_TIMER_ID, 250, NULL); |
1177 | 1195 |
1178 while (1) | 1196 while (1) |
1180 MSG msg; | 1198 MSG msg; |
1181 GetMessage (&msg, hwnd, 0, 0); | 1199 GetMessage (&msg, hwnd, 0, 0); |
1182 if (msg.message == XM_SOCKREPLY) | 1200 if (msg.message == XM_SOCKREPLY) |
1183 { | 1201 { |
1184 /* Ok, got an answer */ | 1202 /* Ok, got an answer */ |
1185 if (WSAGETASYNCERROR(msg.lParam) == NO_ERROR) | 1203 errcode = WSAGETASYNCERROR (msg.lParam); |
1186 success = 1; | |
1187 else | |
1188 { | |
1189 warn_when_safe(Qstream, Qwarning, | |
1190 "cannot get IP address for host \"%s\"", | |
1191 XSTRING_DATA (host)); | |
1192 } | |
1193 goto done; | 1204 goto done; |
1194 } | 1205 } |
1195 else if (msg.message == WM_TIMER && msg.wParam == SOCK_TIMER_ID) | 1206 else if (msg.message == WM_TIMER && msg.wParam == SOCK_TIMER_ID) |
1196 { | 1207 { |
1197 if (QUITP) | 1208 if (QUITP) |
1206 } | 1217 } |
1207 | 1218 |
1208 done: | 1219 done: |
1209 KillTimer (hwnd, SOCK_TIMER_ID); | 1220 KillTimer (hwnd, SOCK_TIMER_ID); |
1210 DestroyWindow (hwnd); | 1221 DestroyWindow (hwnd); |
1211 if (success) | 1222 if (!errcode) |
1212 { | 1223 { |
1213 /* BUF starts with struct hostent */ | 1224 /* BUF starts with struct hostent */ |
1214 struct hostent* he = (struct hostent*) buf; | 1225 struct hostent* he = (struct hostent*) buf; |
1215 address->sin_addr.s_addr = *(unsigned long*)he->h_addr_list[0]; | 1226 address->sin_addr.s_addr = *(unsigned long*)he->h_addr_list[0]; |
1216 } | 1227 } |
1217 return success; | 1228 return errcode; |
1218 } | 1229 } |
1219 | 1230 |
1220 static Lisp_Object | 1231 static Lisp_Object |
1221 nt_canonicalize_host_name (Lisp_Object host) | 1232 nt_canonicalize_host_name (Lisp_Object host) |
1222 { | 1233 { |
1223 struct sockaddr_in address; | 1234 struct sockaddr_in address; |
1224 | 1235 |
1225 if (!get_internet_address (host, &address, ERROR_ME_NOT)) | 1236 if (get_internet_address (host, &address)) /* error */ |
1226 return host; | 1237 return host; |
1227 | 1238 |
1228 if (address.sin_family == AF_INET) | 1239 if (address.sin_family == AF_INET) |
1229 return build_string (inet_ntoa (address.sin_addr)); | 1240 return build_string (inet_ntoa (address.sin_addr)); |
1230 else | 1241 else |
1245 /* !!#### not Mule-ized */ | 1256 /* !!#### not Mule-ized */ |
1246 struct sockaddr_in address; | 1257 struct sockaddr_in address; |
1247 SOCKET s; | 1258 SOCKET s; |
1248 int port; | 1259 int port; |
1249 int retval; | 1260 int retval; |
1261 int errnum; | |
1250 | 1262 |
1251 CHECK_STRING (host); | 1263 CHECK_STRING (host); |
1252 | 1264 |
1253 if (!EQ (protocol, Qtcp)) | 1265 if (!EQ (protocol, Qtcp)) |
1254 invalid_argument ("Unsupported protocol", protocol); | 1266 invalid_constant ("Unsupported protocol", protocol); |
1255 | 1267 |
1256 if (INTP (service)) | 1268 if (INTP (service)) |
1257 port = htons ((unsigned short) XINT (service)); | 1269 port = htons ((unsigned short) XINT (service)); |
1258 else | 1270 else |
1259 { | 1271 { |
1263 if (svc_info == 0) | 1275 if (svc_info == 0) |
1264 invalid_argument ("Unknown service", service); | 1276 invalid_argument ("Unknown service", service); |
1265 port = svc_info->s_port; | 1277 port = svc_info->s_port; |
1266 } | 1278 } |
1267 | 1279 |
1268 get_internet_address (host, &address, ERROR_ME); | 1280 retval = get_internet_address (host, &address); |
1281 if (retval) | |
1282 mswindows_report_winsock_error ("Getting IP address", host, | |
1283 retval); | |
1269 address.sin_port = port; | 1284 address.sin_port = port; |
1270 | 1285 |
1271 s = socket (address.sin_family, SOCK_STREAM, 0); | 1286 s = socket (address.sin_family, SOCK_STREAM, 0); |
1272 if (s < 0) | 1287 if (s < 0) |
1273 report_file_error ("error creating socket", list1 (name)); | 1288 mswindows_report_winsock_error ("Creating socket", name, |
1289 WSAGetLastError ()); | |
1274 | 1290 |
1275 /* We don't want to be blocked on connect */ | 1291 /* We don't want to be blocked on connect */ |
1276 { | 1292 { |
1277 unsigned long nonblock = 1; | 1293 unsigned long nonblock = 1; |
1278 ioctlsocket (s, FIONBIO, &nonblock); | 1294 ioctlsocket (s, FIONBIO, &nonblock); |
1279 } | 1295 } |
1280 | 1296 |
1281 retval = connect (s, (struct sockaddr *) &address, sizeof (address)); | 1297 retval = connect (s, (struct sockaddr *) &address, sizeof (address)); |
1282 if (retval != NO_ERROR && WSAGetLastError() != WSAEWOULDBLOCK) | 1298 if (retval != NO_ERROR && WSAGetLastError() != WSAEWOULDBLOCK) |
1283 goto connect_failed; | 1299 { |
1300 errnum = WSAGetLastError (); | |
1301 goto connect_failed; | |
1302 } | |
1303 | |
1304 #if 0 /* PUTA! I thought getsockopt() was failing, so I created the | |
1305 following based on the code in get_internet_address(), but | |
1306 it was my own fault down below. Both versions should work. */ | |
1284 /* Wait while connection is established */ | 1307 /* Wait while connection is established */ |
1308 { | |
1309 HWND hwnd; | |
1310 | |
1311 /* Create a window which will receive completion messages */ | |
1312 hwnd = CreateWindow ("STATIC", NULL, WS_OVERLAPPED, 0, 0, 1, 1, | |
1313 NULL, NULL, NULL, NULL); | |
1314 assert (hwnd); | |
1315 | |
1316 /* Post request */ | |
1317 if (WSAAsyncSelect (s, hwnd, XM_SOCKREPLY, FD_CONNECT)) | |
1318 { | |
1319 errnum = WSAGetLastError (); | |
1320 goto done; | |
1321 } | |
1322 | |
1323 /* Set a timer to poll for quit every 250 ms */ | |
1324 SetTimer (hwnd, SOCK_TIMER_ID, 250, NULL); | |
1325 | |
1326 while (1) | |
1327 { | |
1328 MSG msg; | |
1329 GetMessage (&msg, hwnd, 0, 0); | |
1330 if (msg.message == XM_SOCKREPLY) | |
1331 { | |
1332 /* Ok, got an answer */ | |
1333 errnum = WSAGETASYNCERROR (msg.lParam); | |
1334 goto done; | |
1335 } | |
1336 | |
1337 else if (msg.message == WM_TIMER && msg.wParam == SOCK_TIMER_ID) | |
1338 { | |
1339 if (QUITP) | |
1340 { | |
1341 WSAAsyncSelect (s, hwnd, XM_SOCKREPLY, 0); | |
1342 KillTimer (hwnd, SOCK_TIMER_ID); | |
1343 DestroyWindow (hwnd); | |
1344 REALLY_QUIT; | |
1345 } | |
1346 } | |
1347 DispatchMessage (&msg); | |
1348 } | |
1349 | |
1350 done: | |
1351 WSAAsyncSelect (s, hwnd, XM_SOCKREPLY, 0); | |
1352 KillTimer (hwnd, SOCK_TIMER_ID); | |
1353 DestroyWindow (hwnd); | |
1354 if (errnum) | |
1355 goto connect_failed; | |
1356 } | |
1357 | |
1358 #else | |
1285 while (1) | 1359 while (1) |
1286 { | 1360 { |
1287 fd_set fdset; | 1361 fd_set fdwriteset, fdexceptset; |
1288 struct timeval tv; | 1362 struct timeval tv; |
1289 int nsel; | 1363 int nsel; |
1290 | 1364 |
1291 if (QUITP) | 1365 if (QUITP) |
1292 { | 1366 { |
1296 | 1370 |
1297 /* Poll for quit every 250 ms */ | 1371 /* Poll for quit every 250 ms */ |
1298 tv.tv_sec = 0; | 1372 tv.tv_sec = 0; |
1299 tv.tv_usec = 250 * 1000; | 1373 tv.tv_usec = 250 * 1000; |
1300 | 1374 |
1301 FD_ZERO (&fdset); | 1375 FD_ZERO (&fdwriteset); |
1302 FD_SET (s, &fdset); | 1376 FD_SET (s, &fdwriteset); |
1303 nsel = select (0, NULL, &fdset, &fdset, &tv); | 1377 FD_ZERO (&fdexceptset); |
1378 FD_SET (s, &fdexceptset); | |
1379 nsel = select (0, NULL, &fdwriteset, &fdexceptset, &tv); | |
1380 | |
1381 if (nsel == SOCKET_ERROR) | |
1382 { | |
1383 errnum = WSAGetLastError (); | |
1384 goto connect_failed; | |
1385 } | |
1304 | 1386 |
1305 if (nsel > 0) | 1387 if (nsel > 0) |
1306 { | 1388 { |
1307 /* Check: was connection successful or not? */ | 1389 /* Check: was connection successful or not? */ |
1308 tv.tv_usec = 0; | 1390 if (FD_ISSET (s, &fdwriteset)) |
1309 nsel = select (0, NULL, NULL, &fdset, &tv); | 1391 break; |
1310 if (nsel > 0) | 1392 else if (FD_ISSET (s, &fdexceptset)) |
1311 goto connect_failed; | 1393 { |
1394 int store_me_harder = sizeof (errnum); | |
1395 /* OK, we finally can get the REAL error code. Any paths | |
1396 in this code that lead to a call of WSAGetLastError() | |
1397 indicate probable logic failure. */ | |
1398 if (getsockopt (s, SOL_SOCKET, SO_ERROR, (char *) &errnum, | |
1399 &store_me_harder)) | |
1400 errnum = WSAGetLastError (); | |
1401 goto connect_failed; | |
1402 } | |
1312 else | 1403 else |
1313 break; | 1404 { |
1405 signal_error (Qinternal_error, | |
1406 "Porra, esse caralho de um sistema de operacao", | |
1407 Qunbound); | |
1408 break; | |
1409 } | |
1314 } | 1410 } |
1315 } | 1411 } |
1412 #endif | |
1316 | 1413 |
1317 /* We are connected at this point */ | 1414 /* We are connected at this point */ |
1318 *vinfd = (void*)s; | 1415 *vinfd = (void*)s; |
1319 DuplicateHandle (GetCurrentProcess(), (HANDLE)s, | 1416 DuplicateHandle (GetCurrentProcess(), (HANDLE)s, |
1320 GetCurrentProcess(), (LPHANDLE)voutfd, | 1417 GetCurrentProcess(), (LPHANDLE)voutfd, |
1321 0, FALSE, DUPLICATE_SAME_ACCESS); | 1418 0, FALSE, DUPLICATE_SAME_ACCESS); |
1322 return; | 1419 return; |
1323 | 1420 |
1324 connect_failed: | 1421 connect_failed: |
1325 closesocket (s); | 1422 { |
1326 if (INTP (service)) | 1423 closesocket (s); |
1327 { | 1424 mswindows_report_winsock_error ("Connection failed", |
1328 warn_when_safe (Qstream, Qwarning, | 1425 list3 (Qunbound, host, service), |
1329 "failure to open network stream to host \"%s\" for service \"%d\"", | 1426 errnum); |
1330 XSTRING_DATA (host), | 1427 } |
1331 (unsigned short) XINT (service)); | |
1332 } | |
1333 else | |
1334 { | |
1335 warn_when_safe (Qstream, Qwarning, | |
1336 "failure to open network stream to host \"%s\" for service \"%s\"", | |
1337 XSTRING_DATA (host), | |
1338 XSTRING_DATA (service)); | |
1339 } | |
1340 report_file_error ("connection failed", list2 (host, name)); | |
1341 } | 1428 } |
1342 | 1429 |
1343 #endif | 1430 #endif |
1344 | 1431 |
1345 /*-----------------------------------------------------------------------*/ | 1432 /*-----------------------------------------------------------------------*/ |