aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/w32.c171
1 files changed, 119 insertions, 52 deletions
diff --git a/src/w32.c b/src/w32.c
index a7fd59366d6..243948c0a03 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -289,9 +289,9 @@ init_user_info ()
289 289
290 /* Ensure HOME and SHELL are defined. */ 290 /* Ensure HOME and SHELL are defined. */
291 if (getenv ("HOME") == NULL) 291 if (getenv ("HOME") == NULL)
292 putenv ("HOME=c:/"); 292 abort ();
293 if (getenv ("SHELL") == NULL) 293 if (getenv ("SHELL") == NULL)
294 putenv (os_subtype == OS_WIN95 ? "SHELL=command" : "SHELL=cmd"); 294 abort ();
295 295
296 /* Set dir and shell from environment variables. */ 296 /* Set dir and shell from environment variables. */
297 strcpy (the_passwd.pw_dir, getenv ("HOME")); 297 strcpy (the_passwd.pw_dir, getenv ("HOME"));
@@ -692,52 +692,96 @@ init_environment (char ** argv)
692 Qnil)), 692 Qnil)),
693 "While setting TMPDIR: "); 693 "While setting TMPDIR: ");
694 694
695 /* Check for environment variables and use registry if they don't exist */ 695 /* Check for environment variables and use registry settings if they
696 don't exist. Fallback on default values where applicable. */
696 { 697 {
697 int i; 698 int i;
698 LPBYTE lpval; 699 LPBYTE lpval;
699 DWORD dwType; 700 DWORD dwType;
700 701
701 static char * env_vars[] = 702 static struct env_entry
702 { 703 {
703 "HOME", 704 char * name;
704 "PRELOAD_WINSOCK", 705 char * def_value;
705 "emacs_dir", 706 } env_vars[] =
706 "EMACSLOADPATH", 707 {
707 "SHELL", 708 {"HOME", "C:/"},
708 "CMDPROXY", 709 {"PRELOAD_WINSOCK", NULL},
709 "EMACSDATA", 710 {"emacs_dir", "C:/emacs"},
710 "EMACSPATH", 711 {"EMACSLOADPATH", "%emacs_dir%/site-lisp;%emacs_dir%/lisp;%emacs_dir%/leim"},
711 "EMACSLOCKDIR", 712 {"SHELL", "%emacs_dir%/bin/cmdproxy.exe"},
713 {"EMACSDATA", "%emacs_dir%/etc"},
714 {"EMACSPATH", "%emacs_dir%/bin"},
715 {"EMACSLOCKDIR", "%emacs_dir%/lock"},
712 /* We no longer set INFOPATH because Info-default-directory-list 716 /* We no longer set INFOPATH because Info-default-directory-list
713 is then ignored. We use a hook in winnt.el instead. */ 717 is then ignored. */
714 /* "INFOPATH", */ 718 /* {"INFOPATH", "%emacs_dir%/info"}, */
715 "EMACSDOC", 719 {"EMACSDOC", "%emacs_dir%/etc"},
716 "TERM", 720 {"TERM", "cmd"}
717 }; 721 };
718 722
723#define SET_ENV_BUF_SIZE (4 * MAX_PATH) /* to cover EMACSLOADPATH */
724
725 /* Treat emacs_dir specially: set it unconditionally based on our
726 location, if it appears that we are running from the bin subdir
727 of a standard installation. */
728 {
729 char *p;
730 char modname[MAX_PATH];
731
732 if (!GetModuleFileName (NULL, modname, MAX_PATH))
733 abort ();
734 if ((p = strrchr (modname, '\\')) == NULL)
735 abort ();
736 *p = 0;
737
738 if ((p = strrchr (modname, '\\')) && stricmp (p, "\\bin") == 0)
739 {
740 char buf[SET_ENV_BUF_SIZE];
741
742 *p = 0;
743 for (p = modname; *p; p++)
744 if (*p == '\\') *p = '/';
745
746 _snprintf (buf, sizeof(buf)-1, "emacs_dir=%s", modname);
747 putenv (strdup (buf));
748 }
749 }
750
719 for (i = 0; i < (sizeof (env_vars) / sizeof (env_vars[0])); i++) 751 for (i = 0; i < (sizeof (env_vars) / sizeof (env_vars[0])); i++)
720 { 752 {
721 if (!getenv (env_vars[i]) 753 if (!getenv (env_vars[i].name))
722 && (lpval = w32_get_resource (env_vars[i], &dwType)) != NULL)
723 { 754 {
724 if (dwType == REG_EXPAND_SZ) 755 int dont_free = 0;
725 {
726 char buf1[500], buf2[500];
727 756
728 ExpandEnvironmentStrings ((LPSTR) lpval, buf1, 500); 757 if ((lpval = w32_get_resource (env_vars[i].name, &dwType)) == NULL)
729 _snprintf (buf2, 499, "%s=%s", env_vars[i], buf1); 758 {
730 putenv (strdup (buf2)); 759 lpval = env_vars[i].def_value;
760 dwType = REG_EXPAND_SZ;
761 dont_free = 1;
731 } 762 }
732 else if (dwType == REG_SZ) 763
764 if (lpval)
733 { 765 {
734 char buf[500]; 766 if (dwType == REG_EXPAND_SZ)
767 {
768 char buf1[SET_ENV_BUF_SIZE], buf2[SET_ENV_BUF_SIZE];
769
770 ExpandEnvironmentStrings ((LPSTR) lpval, buf1, sizeof(buf1));
771 _snprintf (buf2, sizeof(buf2)-1, "%s=%s", env_vars[i].name, buf1);
772 putenv (strdup (buf2));
773 }
774 else if (dwType == REG_SZ)
775 {
776 char buf[SET_ENV_BUF_SIZE];
735 777
736 _snprintf (buf, 499, "%s=%s", env_vars[i], lpval); 778 _snprintf (buf, sizeof(buf)-1, "%s=%s", env_vars[i].name, lpval);
737 putenv (strdup (buf)); 779 putenv (strdup (buf));
738 } 780 }
739 781
740 xfree (lpval); 782 if (!dont_free)
783 xfree (lpval);
784 }
741 } 785 }
742 } 786 }
743 } 787 }
@@ -1149,6 +1193,13 @@ map_w32_filename (const char * name, const char ** pPath)
1149 char * path; 1193 char * path;
1150 const char * save_name = name; 1194 const char * save_name = name;
1151 1195
1196 if (strlen (name) >= MAX_PATH)
1197 {
1198 /* Return a filename which will cause callers to fail. */
1199 strcpy (shortname, "?");
1200 return shortname;
1201 }
1202
1152 if (is_fat_volume (name, &path)) /* truncate to 8.3 */ 1203 if (is_fat_volume (name, &path)) /* truncate to 8.3 */
1153 { 1204 {
1154 register int left = 8; /* maximum number of chars in part */ 1205 register int left = 8; /* maximum number of chars in part */
@@ -2548,35 +2599,51 @@ sys_socket(int af, int type, int protocol)
2548 _set_osfhnd (fd, s); 2599 _set_osfhnd (fd, s);
2549 /* setmode (fd, _O_BINARY); */ 2600 /* setmode (fd, _O_BINARY); */
2550#else 2601#else
2551 /* Make a non-inheritable copy of the socket handle. */ 2602 /* Make a non-inheritable copy of the socket handle. Note
2603 that it is possible that sockets aren't actually kernel
2604 handles, which appears to be the case on Windows 9x when
2605 the MS Proxy winsock client is installed. */
2552 { 2606 {
2553 HANDLE parent;
2554 HANDLE new_s = INVALID_HANDLE_VALUE;
2555
2556 parent = GetCurrentProcess ();
2557
2558 /* Apparently there is a bug in NT 3.51 with some service 2607 /* Apparently there is a bug in NT 3.51 with some service
2559 packs, which prevents using DuplicateHandle to make a 2608 packs, which prevents using DuplicateHandle to make a
2560 socket handle non-inheritable (causes WSACleanup to 2609 socket handle non-inheritable (causes WSACleanup to
2561 hang). The work-around is to use SetHandleInformation 2610 hang). The work-around is to use SetHandleInformation
2562 instead if it is available and implemented. */ 2611 instead if it is available and implemented. */
2563 if (!pfn_SetHandleInformation 2612 if (pfn_SetHandleInformation)
2564 || !pfn_SetHandleInformation ((HANDLE) s, 2613 {
2565 HANDLE_FLAG_INHERIT, 2614 pfn_SetHandleInformation ((HANDLE) s, HANDLE_FLAG_INHERIT, 0);
2566 0)) 2615 }
2616 else
2567 { 2617 {
2568 DuplicateHandle (parent, 2618 HANDLE parent = GetCurrentProcess ();
2569 (HANDLE) s, 2619 HANDLE new_s = INVALID_HANDLE_VALUE;
2570 parent, 2620
2571 &new_s, 2621 if (DuplicateHandle (parent,
2572 0, 2622 (HANDLE) s,
2573 FALSE, 2623 parent,
2574 DUPLICATE_SAME_ACCESS); 2624 &new_s,
2575 pfn_closesocket (s); 2625 0,
2576 s = (SOCKET) new_s; 2626 FALSE,
2627 DUPLICATE_SAME_ACCESS))
2628 {
2629 /* It is possible that DuplicateHandle succeeds even
2630 though the socket wasn't really a kernel handle,
2631 because a real handle has the same value. So
2632 test whether the new handle really is a socket. */
2633 long nonblocking = 0;
2634 if (pfn_ioctlsocket ((SOCKET) new_s, FIONBIO, &nonblocking) == 0)
2635 {
2636 pfn_closesocket (s);
2637 s = (SOCKET) new_s;
2638 }
2639 else
2640 {
2641 CloseHandle (new_s);
2642 }
2643 }
2577 } 2644 }
2578 fd_info[fd].hnd = (HANDLE) s;
2579 } 2645 }
2646 fd_info[fd].hnd = (HANDLE) s;
2580#endif 2647#endif
2581 2648
2582 /* set our own internal flags */ 2649 /* set our own internal flags */