]> code.delx.au - gnu-emacs/blobdiff - src/w32.c
Revision: emacs@sv.gnu.org/emacs--unicode--0--patch-34
[gnu-emacs] / src / w32.c
index cdc41a8c7723cacc93b95e239d9801c03fc17b2e..71799befdbb42c98a015fee55e1b8244f94782e1 100644 (file)
--- a/src/w32.c
+++ b/src/w32.c
@@ -1,5 +1,6 @@
 /* Utility and Unix shadow routines for GNU Emacs on the Microsoft W32 API.
-   Copyright (C) 1994, 1995, 2000, 2001 Free Software Foundation, Inc.
+   Copyright (C) 1994, 1995, 2000, 2001, 2002, 2003, 2004,
+                 2005, 2006 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -15,13 +16,11 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU Emacs; see the file COPYING.  If not, write to
-the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.
 
    Geoff Voelker (voelker@cs.washington.edu)                         7-29-94
 */
-
-
 #include <stddef.h> /* for offsetof */
 #include <stdlib.h>
 #include <stdio.h>
@@ -73,6 +72,7 @@ Boston, MA 02111-1307, USA.
 #define _ANONYMOUS_STRUCT
 #endif
 #include <windows.h>
+#include <shlobj.h>
 
 #ifdef HAVE_SOCKETS    /* TCP connection support, if kernel can do it */
 #include <sys/socket.h>
@@ -100,6 +100,9 @@ Boston, MA 02111-1307, USA.
 #include "w32heap.h"
 #include "systime.h"
 
+typedef HRESULT (WINAPI * ShGetFolderPath_fn)
+  (IN HWND, IN int, IN HANDLE, IN DWORD, OUT char *);
+
 void globals_of_w32 ();
 
 extern Lisp_Object Vw32_downcase_file_names;
@@ -903,7 +906,9 @@ init_environment (char ** argv)
   static const char * const tempdirs[] = {
     "$TMPDIR", "$TEMP", "$TMP", "c:/"
   };
+
   int i;
+
   const int imax = sizeof (tempdirs) / sizeof (tempdirs[0]);
 
   /* Make sure they have a usable $TMPDIR.  Many Emacs functions use
@@ -942,6 +947,8 @@ init_environment (char ** argv)
     LPBYTE lpval;
     DWORD dwType;
     char locale_name[32];
+    struct stat ignored;
+    char default_home[MAX_PATH];
 
     static struct env_entry
     {
@@ -964,6 +971,35 @@ init_environment (char ** argv)
       {"LANG", NULL},
     };
 
+    /* For backwards compatibility, check if a .emacs file exists in C:/
+       If not, then we can try to default to the appdata directory under the
+       user's profile, which is more likely to be writable.   */
+    if (stat ("C:/.emacs", &ignored) < 0)
+    {
+      HRESULT profile_result;
+      /* Dynamically load ShGetFolderPath, as it won't exist on versions
+        of Windows 95 and NT4 that have not been updated to include
+        MSIE 5.  Also we don't link with shell32.dll by default.  */
+      HMODULE shell32_dll;
+      ShGetFolderPath_fn get_folder_path;
+      shell32_dll = GetModuleHandle ("shell32.dll");
+      get_folder_path = (ShGetFolderPath_fn)
+       GetProcAddress (shell32_dll, "SHGetFolderPathA");
+
+      if (get_folder_path != NULL)
+       {
+         profile_result = get_folder_path (NULL, CSIDL_APPDATA, NULL,
+                                           0, default_home);
+
+         /* If we can't get the appdata dir, revert to old behaviour.  */
+         if (profile_result == S_OK)
+           env_vars[0].def_value = default_home;
+       }
+
+      /* Unload shell32.dll, it is not needed anymore.  */
+      FreeLibrary (shell32_dll);
+    }
+
   /* Get default locale info and use it for LANG.  */
   if (GetLocaleInfo (LOCALE_USER_DEFAULT,
                      LOCALE_SABBREVLANGNAME | LOCALE_USE_CP_ACP,
@@ -1273,7 +1309,7 @@ get_emacs_configuration_options (void)
 void
 gettimeofday (struct timeval *tv, struct timezone *tz)
 {
-  struct timeb tb;
+  struct _timeb tb;
   _ftime (&tb);
 
   tv->tv_sec = tb.time;
@@ -1777,7 +1813,7 @@ open_unc_volume (const char *path)
   nr.dwDisplayType = RESOURCEDISPLAYTYPE_SERVER;
   nr.dwUsage = RESOURCEUSAGE_CONTAINER;
   nr.lpLocalName = NULL;
-  nr.lpRemoteName = map_w32_filename (path, NULL);
+  nr.lpRemoteName = (LPSTR)map_w32_filename (path, NULL);
   nr.lpComment = NULL;
   nr.lpProvider = NULL;
 
@@ -1897,6 +1933,14 @@ sys_chmod (const char * path, int mode)
   return _chmod (map_w32_filename (path, NULL), mode);
 }
 
+int
+sys_chown (const char *path, uid_t owner, gid_t group)
+{
+  if (sys_chmod (path, _S_IREAD) == -1) /* check if file exists */
+    return -1;
+  return 0;
+}
+
 int
 sys_creat (const char * path, int mode)
 {
@@ -3207,7 +3251,7 @@ sys_shutdown (int s, int how)
 }
 
 int
-sys_setsockopt (int s, int level, int optname, const char * optval, int optlen)
+sys_setsockopt (int s, int level, int optname, const void * optval, int optlen)
 {
   if (winsock_lib == NULL)
     {
@@ -3219,7 +3263,7 @@ sys_setsockopt (int s, int level, int optname, const char * optval, int optlen)
   if (fd_info[s].flags & FILE_SOCKET)
     {
       int rc = pfn_setsockopt (SOCK_HANDLE (s), level, optname,
-                              optval, optlen);
+                              (const char *)optval, optlen);
       if (rc == SOCKET_ERROR)
        set_errno ();
       return rc;
@@ -3382,13 +3426,13 @@ sys_close (int fd)
 {
   int rc;
 
-  if (fd < 0 || fd >= MAXDESC)
+  if (fd < 0)
     {
       errno = EBADF;
       return -1;
     }
 
-  if (fd_info[fd].cp)
+  if (fd < MAXDESC && fd_info[fd].cp)
     {
       child_process * cp = fd_info[fd].cp;
 
@@ -3430,7 +3474,7 @@ sys_close (int fd)
      because socket handles are fully fledged kernel handles. */
   rc = _close (fd);
 
-  if (rc == 0)
+  if (rc == 0 && fd < MAXDESC)
     fd_info[fd].flags = 0;
 
   return rc;
@@ -3442,7 +3486,7 @@ sys_dup (int fd)
   int new_fd;
 
   new_fd = _dup (fd);
-  if (new_fd >= 0)
+  if (new_fd >= 0 && new_fd < MAXDESC)
     {
       /* duplicate our internal info as well */
       fd_info[new_fd] = fd_info[fd];
@@ -3597,13 +3641,13 @@ sys_read (int fd, char * buffer, unsigned int count)
   DWORD waiting;
   char * orig_buffer = buffer;
 
-  if (fd < 0 || fd >= MAXDESC)
+  if (fd < 0)
     {
       errno = EBADF;
       return -1;
     }
 
-  if (fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET))
+  if (fd < MAXDESC && fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET))
     {
       child_process *cp = fd_info[fd].cp;
 
@@ -3741,13 +3785,13 @@ sys_write (int fd, const void * buffer, unsigned int count)
 {
   int nchars;
 
-  if (fd < 0 || fd >= MAXDESC)
+  if (fd < 0)
     {
       errno = EBADF;
       return -1;
     }
 
-  if (fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET))
+  if (fd < MAXDESC && fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET))
     {
       if ((fd_info[fd].flags & FILE_WRITE) == 0)
        {
@@ -3789,7 +3833,7 @@ sys_write (int fd, const void * buffer, unsigned int count)
     }
 
 #ifdef HAVE_SOCKETS
-  if (fd_info[fd].flags & FILE_SOCKET)
+  if (fd < MAXDESC && fd_info[fd].flags & FILE_SOCKET)
     {
       unsigned long nblock = 0;
       if (winsock_lib == NULL) abort ();
@@ -3844,13 +3888,15 @@ check_windows_init_file ()
       objs[1] = decode_env_path (0, (getenv ("EMACSLOADPATH")));
       full_load_path = Fappend (2, objs);
       init_file = build_string ("term/w32-win");
-      fd = openp (full_load_path, init_file, Vload_suffixes, NULL, Qnil);
+      fd = openp (full_load_path, init_file, Fget_load_suffixes (), NULL, Qnil);
       if (fd < 0)
        {
          Lisp_Object load_path_print = Fprin1_to_string (full_load_path, Qnil);
          char *init_file_name = SDATA (init_file);
          char *load_path = SDATA (load_path_print);
-         char *buffer = alloca (1024);
+         char *buffer = alloca (1024
+                                + strlen (init_file_name)
+                                + strlen (load_path));
 
          sprintf (buffer,
                   "The Emacs Windows initialization file \"%s.el\" "