diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/w32.c | 171 |
1 files changed, 119 insertions, 52 deletions
| @@ -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 */ |