diff options
| author | Eli Zaretskii | 2013-11-02 17:15:37 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2013-11-02 17:15:37 +0200 |
| commit | b1846422dd1ed7ff1cf497e22e9612264f0ba69b (patch) | |
| tree | 34a581bc011c9f717587de086ea2484daba9e644 /src | |
| parent | 1fd201bb1d720d0c5ab727a3972363778eef834f (diff) | |
| download | emacs-b1846422dd1ed7ff1cf497e22e9612264f0ba69b.tar.gz emacs-b1846422dd1ed7ff1cf497e22e9612264f0ba69b.zip | |
Done with init_environment and emacs_root_dir.
Diffstat (limited to 'src')
| -rw-r--r-- | src/w32.c | 261 |
1 files changed, 71 insertions, 190 deletions
| @@ -248,7 +248,7 @@ static int enable_privilege (LPCTSTR, BOOL, TOKEN_PRIVILEGES *); | |||
| 248 | static int restore_privilege (TOKEN_PRIVILEGES *); | 248 | static int restore_privilege (TOKEN_PRIVILEGES *); |
| 249 | static BOOL WINAPI revert_to_self (void); | 249 | static BOOL WINAPI revert_to_self (void); |
| 250 | 250 | ||
| 251 | extern int sys_access (const char *, int); | 251 | static int sys_access (const char *, int); |
| 252 | extern void *e_malloc (size_t); | 252 | extern void *e_malloc (size_t); |
| 253 | extern int sys_select (int, SELECT_TYPE *, SELECT_TYPE *, SELECT_TYPE *, | 253 | extern int sys_select (int, SELECT_TYPE *, SELECT_TYPE *, SELECT_TYPE *, |
| 254 | struct timespec *, void *); | 254 | struct timespec *, void *); |
| @@ -2037,7 +2037,7 @@ is_unc_volume (const char *filename) | |||
| 2037 | if (!IS_DIRECTORY_SEP (ptr[0]) || !IS_DIRECTORY_SEP (ptr[1]) || !ptr[2]) | 2037 | if (!IS_DIRECTORY_SEP (ptr[0]) || !IS_DIRECTORY_SEP (ptr[1]) || !ptr[2]) |
| 2038 | return 0; | 2038 | return 0; |
| 2039 | 2039 | ||
| 2040 | if (_mbspbrk (ptr + 2, "*?|<>\"\\/")) | 2040 | if (strpbrk (ptr + 2, "*?|<>\"\\/")) |
| 2041 | return 0; | 2041 | return 0; |
| 2042 | 2042 | ||
| 2043 | return 1; | 2043 | return 1; |
| @@ -2137,8 +2137,6 @@ w32_get_resource (char *key, LPDWORD lpdwtype) | |||
| 2137 | return (NULL); | 2137 | return (NULL); |
| 2138 | } | 2138 | } |
| 2139 | 2139 | ||
| 2140 | char *get_emacs_configuration (void); | ||
| 2141 | |||
| 2142 | void | 2140 | void |
| 2143 | init_environment (char ** argv) | 2141 | init_environment (char ** argv) |
| 2144 | { | 2142 | { |
| @@ -2150,6 +2148,13 @@ init_environment (char ** argv) | |||
| 2150 | 2148 | ||
| 2151 | const int imax = sizeof (tempdirs) / sizeof (tempdirs[0]); | 2149 | const int imax = sizeof (tempdirs) / sizeof (tempdirs[0]); |
| 2152 | 2150 | ||
| 2151 | /* Implementation note: This function explicitly works with ANSI | ||
| 2152 | file names, not with UTF-8 encoded file names. This is because | ||
| 2153 | this function pushes variables into the Emacs's environment, and | ||
| 2154 | the environment variables are always assumed to be in the | ||
| 2155 | locale-specific encoding. Do NOT call any functions that accept | ||
| 2156 | UTF-8 file names from this function! */ | ||
| 2157 | |||
| 2153 | /* Make sure they have a usable $TMPDIR. Many Emacs functions use | 2158 | /* Make sure they have a usable $TMPDIR. Many Emacs functions use |
| 2154 | temporary files and assume "/tmp" if $TMPDIR is unset, which | 2159 | temporary files and assume "/tmp" if $TMPDIR is unset, which |
| 2155 | will break on DOS/Windows. Refuse to work if we cannot find | 2160 | will break on DOS/Windows. Refuse to work if we cannot find |
| @@ -2165,8 +2170,8 @@ init_environment (char ** argv) | |||
| 2165 | The only way to be really sure is to actually create a file and | 2170 | The only way to be really sure is to actually create a file and |
| 2166 | see if it succeeds. But I think that's too much to ask. */ | 2171 | see if it succeeds. But I think that's too much to ask. */ |
| 2167 | 2172 | ||
| 2168 | /* MSVCRT's _access crashes with D_OK. */ | 2173 | /* MSVCRT's _access crashes with D_OK, so we use our replacement. */ |
| 2169 | if (tmp && faccessat (AT_FDCWD, tmp, D_OK, AT_EACCESS) == 0) | 2174 | if (tmp && sys_access (tmp, D_OK) == 0) |
| 2170 | { | 2175 | { |
| 2171 | char * var = alloca (strlen (tmp) + 8); | 2176 | char * var = alloca (strlen (tmp) + 8); |
| 2172 | sprintf (var, "TMPDIR=%s", tmp); | 2177 | sprintf (var, "TMPDIR=%s", tmp); |
| @@ -2228,7 +2233,7 @@ init_environment (char ** argv) | |||
| 2228 | /* For backwards compatibility, check if a .emacs file exists in C:/ | 2233 | /* For backwards compatibility, check if a .emacs file exists in C:/ |
| 2229 | If not, then we can try to default to the appdata directory under the | 2234 | If not, then we can try to default to the appdata directory under the |
| 2230 | user's profile, which is more likely to be writable. */ | 2235 | user's profile, which is more likely to be writable. */ |
| 2231 | if (faccessat (AT_FDCWD, "C:/.emacs", F_OK, AT_EACCESS) != 0) | 2236 | if (sys_access ("C:/.emacs", F_OK) != 0) |
| 2232 | { | 2237 | { |
| 2233 | HRESULT profile_result; | 2238 | HRESULT profile_result; |
| 2234 | /* Dynamically load ShGetFolderPath, as it won't exist on versions | 2239 | /* Dynamically load ShGetFolderPath, as it won't exist on versions |
| @@ -2304,33 +2309,6 @@ init_environment (char ** argv) | |||
| 2304 | _putenv (strdup (buf)); | 2309 | _putenv (strdup (buf)); |
| 2305 | } | 2310 | } |
| 2306 | } | 2311 | } |
| 2307 | /* Handle running emacs from the build directory: src/oo-spd/i386/ */ | ||
| 2308 | |||
| 2309 | /* FIXME: should use substring of get_emacs_configuration (). | ||
| 2310 | But I don't think the Windows build supports alpha, mips etc | ||
| 2311 | anymore, so have taken the easy option for now. */ | ||
| 2312 | else if (p && (xstrcasecmp (p, "\\i386") == 0 | ||
| 2313 | || xstrcasecmp (p, "\\AMD64") == 0)) | ||
| 2314 | { | ||
| 2315 | *p = 0; | ||
| 2316 | p = _mbsrchr (modname, '\\'); | ||
| 2317 | if (p != NULL) | ||
| 2318 | { | ||
| 2319 | *p = 0; | ||
| 2320 | p = _mbsrchr (modname, '\\'); | ||
| 2321 | if (p && xstrcasecmp (p, "\\src") == 0) | ||
| 2322 | { | ||
| 2323 | char buf[SET_ENV_BUF_SIZE]; | ||
| 2324 | |||
| 2325 | *p = 0; | ||
| 2326 | for (p = modname; *p; p = CharNext (p)) | ||
| 2327 | if (*p == '\\') *p = '/'; | ||
| 2328 | |||
| 2329 | _snprintf (buf, sizeof (buf)-1, "emacs_dir=%s", modname); | ||
| 2330 | _putenv (strdup (buf)); | ||
| 2331 | } | ||
| 2332 | } | ||
| 2333 | } | ||
| 2334 | } | 2312 | } |
| 2335 | 2313 | ||
| 2336 | for (i = 0; i < N_ENV_VARS; i++) | 2314 | for (i = 0; i < N_ENV_VARS; i++) |
| @@ -2366,8 +2344,7 @@ init_environment (char ** argv) | |||
| 2366 | strcpy (&fname[pend - pstart + 1], "cmdproxy.exe"); | 2344 | strcpy (&fname[pend - pstart + 1], "cmdproxy.exe"); |
| 2367 | ExpandEnvironmentStrings ((LPSTR) fname, bufc, | 2345 | ExpandEnvironmentStrings ((LPSTR) fname, bufc, |
| 2368 | sizeof (bufc)); | 2346 | sizeof (bufc)); |
| 2369 | if (faccessat (AT_FDCWD, bufc, F_OK, AT_EACCESS) | 2347 | if (sys_access (bufc, F_OK) == 0) |
| 2370 | == 0) | ||
| 2371 | { | 2348 | { |
| 2372 | lpval = bufc; | 2349 | lpval = bufc; |
| 2373 | dwType = REG_SZ; | 2350 | dwType = REG_SZ; |
| @@ -2485,170 +2462,18 @@ init_environment (char ** argv) | |||
| 2485 | char * | 2462 | char * |
| 2486 | emacs_root_dir (void) | 2463 | emacs_root_dir (void) |
| 2487 | { | 2464 | { |
| 2488 | static char root_dir[FILENAME_MAX]; | 2465 | static char root_dir[MAX_UTF8_PATH]; |
| 2489 | const char *p; | 2466 | const char *p; |
| 2490 | 2467 | ||
| 2491 | p = getenv ("emacs_dir"); | 2468 | p = getenv ("emacs_dir"); |
| 2492 | if (p == NULL) | 2469 | if (p == NULL) |
| 2493 | emacs_abort (); | 2470 | emacs_abort (); |
| 2494 | strcpy (root_dir, p); | 2471 | filename_from_ansi (p, root_dir); |
| 2495 | root_dir[parse_root (root_dir, NULL)] = '\0'; | 2472 | root_dir[parse_root (root_dir, NULL)] = '\0'; |
| 2496 | dostounix_filename (root_dir); | 2473 | dostounix_filename (root_dir); |
| 2497 | return root_dir; | 2474 | return root_dir; |
| 2498 | } | 2475 | } |
| 2499 | 2476 | ||
| 2500 | /* We don't have scripts to automatically determine the system configuration | ||
| 2501 | for Emacs before it's compiled, and we don't want to have to make the | ||
| 2502 | user enter it, so we define EMACS_CONFIGURATION to invoke this runtime | ||
| 2503 | routine. */ | ||
| 2504 | |||
| 2505 | char * | ||
| 2506 | get_emacs_configuration (void) | ||
| 2507 | { | ||
| 2508 | char *arch, *oem, *os; | ||
| 2509 | int build_num; | ||
| 2510 | static char configuration_buffer[32]; | ||
| 2511 | |||
| 2512 | /* Determine the processor type. */ | ||
| 2513 | switch (get_processor_type ()) | ||
| 2514 | { | ||
| 2515 | |||
| 2516 | #ifdef PROCESSOR_INTEL_386 | ||
| 2517 | case PROCESSOR_INTEL_386: | ||
| 2518 | case PROCESSOR_INTEL_486: | ||
| 2519 | case PROCESSOR_INTEL_PENTIUM: | ||
| 2520 | #ifdef _WIN64 | ||
| 2521 | arch = "amd64"; | ||
| 2522 | #else | ||
| 2523 | arch = "i386"; | ||
| 2524 | #endif | ||
| 2525 | break; | ||
| 2526 | #endif | ||
| 2527 | #ifdef PROCESSOR_AMD_X8664 | ||
| 2528 | case PROCESSOR_AMD_X8664: | ||
| 2529 | arch = "amd64"; | ||
| 2530 | break; | ||
| 2531 | #endif | ||
| 2532 | |||
| 2533 | #ifdef PROCESSOR_MIPS_R2000 | ||
| 2534 | case PROCESSOR_MIPS_R2000: | ||
| 2535 | case PROCESSOR_MIPS_R3000: | ||
| 2536 | case PROCESSOR_MIPS_R4000: | ||
| 2537 | arch = "mips"; | ||
| 2538 | break; | ||
| 2539 | #endif | ||
| 2540 | |||
| 2541 | #ifdef PROCESSOR_ALPHA_21064 | ||
| 2542 | case PROCESSOR_ALPHA_21064: | ||
| 2543 | arch = "alpha"; | ||
| 2544 | break; | ||
| 2545 | #endif | ||
| 2546 | |||
| 2547 | default: | ||
| 2548 | arch = "unknown"; | ||
| 2549 | break; | ||
| 2550 | } | ||
| 2551 | |||
| 2552 | /* Use the OEM field to reflect the compiler/library combination. */ | ||
| 2553 | #ifdef _MSC_VER | ||
| 2554 | #define COMPILER_NAME "msvc" | ||
| 2555 | #else | ||
| 2556 | #ifdef __GNUC__ | ||
| 2557 | #define COMPILER_NAME "mingw" | ||
| 2558 | #else | ||
| 2559 | #define COMPILER_NAME "unknown" | ||
| 2560 | #endif | ||
| 2561 | #endif | ||
| 2562 | oem = COMPILER_NAME; | ||
| 2563 | |||
| 2564 | switch (osinfo_cache.dwPlatformId) { | ||
| 2565 | case VER_PLATFORM_WIN32_NT: | ||
| 2566 | os = "nt"; | ||
| 2567 | build_num = osinfo_cache.dwBuildNumber; | ||
| 2568 | break; | ||
| 2569 | case VER_PLATFORM_WIN32_WINDOWS: | ||
| 2570 | if (osinfo_cache.dwMinorVersion == 0) { | ||
| 2571 | os = "windows95"; | ||
| 2572 | } else { | ||
| 2573 | os = "windows98"; | ||
| 2574 | } | ||
| 2575 | build_num = LOWORD (osinfo_cache.dwBuildNumber); | ||
| 2576 | break; | ||
| 2577 | case VER_PLATFORM_WIN32s: | ||
| 2578 | /* Not supported, should not happen. */ | ||
| 2579 | os = "windows32s"; | ||
| 2580 | build_num = LOWORD (osinfo_cache.dwBuildNumber); | ||
| 2581 | break; | ||
| 2582 | default: | ||
| 2583 | os = "unknown"; | ||
| 2584 | build_num = 0; | ||
| 2585 | break; | ||
| 2586 | } | ||
| 2587 | |||
| 2588 | if (osinfo_cache.dwPlatformId == VER_PLATFORM_WIN32_NT) { | ||
| 2589 | sprintf (configuration_buffer, "%s-%s-%s%d.%d.%d", arch, oem, os, | ||
| 2590 | get_w32_major_version (), get_w32_minor_version (), build_num); | ||
| 2591 | } else { | ||
| 2592 | sprintf (configuration_buffer, "%s-%s-%s.%d", arch, oem, os, build_num); | ||
| 2593 | } | ||
| 2594 | |||
| 2595 | return configuration_buffer; | ||
| 2596 | } | ||
| 2597 | |||
| 2598 | char * | ||
| 2599 | get_emacs_configuration_options (void) | ||
| 2600 | { | ||
| 2601 | static char *options_buffer; | ||
| 2602 | char cv[32]; /* Enough for COMPILER_VERSION. */ | ||
| 2603 | char *options[] = { | ||
| 2604 | cv, /* To be filled later. */ | ||
| 2605 | #ifdef EMACSDEBUG | ||
| 2606 | " --no-opt", | ||
| 2607 | #endif | ||
| 2608 | #ifdef ENABLE_CHECKING | ||
| 2609 | " --enable-checking", | ||
| 2610 | #endif | ||
| 2611 | /* configure.bat already sets USER_CFLAGS and USER_LDFLAGS | ||
| 2612 | with a starting space to save work here. */ | ||
| 2613 | #ifdef USER_CFLAGS | ||
| 2614 | " --cflags", USER_CFLAGS, | ||
| 2615 | #endif | ||
| 2616 | #ifdef USER_LDFLAGS | ||
| 2617 | " --ldflags", USER_LDFLAGS, | ||
| 2618 | #endif | ||
| 2619 | NULL | ||
| 2620 | }; | ||
| 2621 | size_t size = 0; | ||
| 2622 | int i; | ||
| 2623 | |||
| 2624 | /* Work out the effective configure options for this build. */ | ||
| 2625 | #ifdef _MSC_VER | ||
| 2626 | #define COMPILER_VERSION "--with-msvc (%d.%02d)", _MSC_VER / 100, _MSC_VER % 100 | ||
| 2627 | #else | ||
| 2628 | #ifdef __GNUC__ | ||
| 2629 | #define COMPILER_VERSION "--with-gcc (%d.%d)", __GNUC__, __GNUC_MINOR__ | ||
| 2630 | #else | ||
| 2631 | #define COMPILER_VERSION "" | ||
| 2632 | #endif | ||
| 2633 | #endif | ||
| 2634 | |||
| 2635 | if (_snprintf (cv, sizeof (cv) - 1, COMPILER_VERSION) < 0) | ||
| 2636 | return "Error: not enough space for compiler version"; | ||
| 2637 | cv[sizeof (cv) - 1] = '\0'; | ||
| 2638 | |||
| 2639 | for (i = 0; options[i]; i++) | ||
| 2640 | size += strlen (options[i]); | ||
| 2641 | |||
| 2642 | options_buffer = xmalloc (size + 1); | ||
| 2643 | options_buffer[0] = '\0'; | ||
| 2644 | |||
| 2645 | for (i = 0; options[i]; i++) | ||
| 2646 | strcat (options_buffer, options[i]); | ||
| 2647 | |||
| 2648 | return options_buffer; | ||
| 2649 | } | ||
| 2650 | |||
| 2651 | |||
| 2652 | #include <sys/timeb.h> | 2477 | #include <sys/timeb.h> |
| 2653 | 2478 | ||
| 2654 | /* Emulate gettimeofday (Ulrich Leodolter, 1/11/95). */ | 2479 | /* Emulate gettimeofday (Ulrich Leodolter, 1/11/95). */ |
| @@ -3480,6 +3305,62 @@ faccessat (int dirfd, const char * path, int mode, int flags) | |||
| 3480 | return 0; | 3305 | return 0; |
| 3481 | } | 3306 | } |
| 3482 | 3307 | ||
| 3308 | /* A version of 'access' to be used locally with file names in | ||
| 3309 | locale-specific encoding. Does not resolve symlinks and does not | ||
| 3310 | support file names on FAT12 and FAT16 volumes, but that's OK, since | ||
| 3311 | we only invoke this function for files inside the Emacs source or | ||
| 3312 | installation tree, on directories (so any symlinks should have the | ||
| 3313 | directory bit set), and on short file names such as "C:/.emacs". */ | ||
| 3314 | static int | ||
| 3315 | sys_access (const char *fname, int mode) | ||
| 3316 | { | ||
| 3317 | char fname_copy[MAX_PATH], *p; | ||
| 3318 | DWORD attributes; | ||
| 3319 | |||
| 3320 | strcpy (fname_copy, fname); | ||
| 3321 | /* Do the equivalent of unixtodos_filename. */ | ||
| 3322 | for (p = fname_copy; *p; p = CharNext (p)) | ||
| 3323 | if (*p == '/') | ||
| 3324 | *p = '\\'; | ||
| 3325 | |||
| 3326 | if ((attributes = GetFileAttributesA (fname_copy)) == -1) | ||
| 3327 | { | ||
| 3328 | DWORD w32err = GetLastError (); | ||
| 3329 | |||
| 3330 | switch (w32err) | ||
| 3331 | { | ||
| 3332 | case ERROR_INVALID_NAME: | ||
| 3333 | case ERROR_BAD_PATHNAME: | ||
| 3334 | case ERROR_FILE_NOT_FOUND: | ||
| 3335 | case ERROR_BAD_NETPATH: | ||
| 3336 | errno = ENOENT; | ||
| 3337 | break; | ||
| 3338 | default: | ||
| 3339 | errno = EACCES; | ||
| 3340 | break; | ||
| 3341 | } | ||
| 3342 | return -1; | ||
| 3343 | } | ||
| 3344 | if ((mode & X_OK) != 0 | ||
| 3345 | && !(is_exec (fname_copy) | ||
| 3346 | || (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0)) | ||
| 3347 | { | ||
| 3348 | errno = EACCES; | ||
| 3349 | return -1; | ||
| 3350 | } | ||
| 3351 | if ((mode & W_OK) != 0 && (attributes & FILE_ATTRIBUTE_READONLY) != 0) | ||
| 3352 | { | ||
| 3353 | errno = EACCES; | ||
| 3354 | return -1; | ||
| 3355 | } | ||
| 3356 | if ((mode & D_OK) != 0 && (attributes & FILE_ATTRIBUTE_DIRECTORY) == 0) | ||
| 3357 | { | ||
| 3358 | errno = EACCES; | ||
| 3359 | return -1; | ||
| 3360 | } | ||
| 3361 | return 0; | ||
| 3362 | } | ||
| 3363 | |||
| 3483 | /* Shadow some MSVC runtime functions to map requests for long filenames | 3364 | /* Shadow some MSVC runtime functions to map requests for long filenames |
| 3484 | to reasonable short names if necessary. This was originally added to | 3365 | to reasonable short names if necessary. This was originally added to |
| 3485 | permit running Emacs on NT 3.1 on a FAT partition, which doesn't support | 3366 | permit running Emacs on NT 3.1 on a FAT partition, which doesn't support |