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 /*-----------------------------------------------------------------------*/