]> code.delx.au - gnu-emacs/blobdiff - src/msdos.c
Minor typo fixes in vc-src.el.
[gnu-emacs] / src / msdos.c
index 2b636977f61805b1c90498180eedf4385b3ed55b..14c2624114d06704ce83be9d186ddac9588f3269 100644 (file)
@@ -50,6 +50,8 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <unistd.h>     /* for chdir, dup, dup2, etc. */
 #include <dir.h>        /* for getdisk */
 #pragma pack(0)                 /* dir.h does a pack(4), which isn't GCC's default */
+#undef opendir
+#include <dirent.h>     /* for opendir */
 #include <fcntl.h>
 #include <io.h>                 /* for setmode */
 #include <dpmi.h>       /* for __dpmi_xxx stuff */
@@ -69,6 +71,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "coding.h"
 #include "disptab.h"
 #include "window.h"
+#include "menu.h"
 #include "buffer.h"
 #include "commands.h"
 #include "blockinput.h"
@@ -564,7 +567,7 @@ dos_set_window_size (int *rows, int *cols)
       };
       int i = 0;
 
-      while (i < EARRAYSIZE (std_dimension))
+      while (i < ARRAYELTS (std_dimension))
        {
         if (std_dimension[i].need_vga <= have_vga
             && std_dimension[i].rows >= *rows)
@@ -1789,7 +1792,7 @@ internal_terminal_init (void)
        }
 
       Vinitial_window_system = Qpc;
-      Vwindow_system_version = make_number (24); /* RE Emacs version */
+      Vwindow_system_version = make_number (25); /* RE Emacs version */
       tty->terminal->type = output_msdos_raw;
 
       /* If Emacs was dumped on DOS/V machine, forget the stale VRAM
@@ -1861,6 +1864,7 @@ initialize_msdos_display (struct terminal *term)
   term->update_end_hook = IT_update_end;
   term->frame_up_to_date_hook = IT_frame_up_to_date;
   term->mouse_position_hook = 0; /* set later by dos_ttraw */
+  term->menu_show_hook = x_menu_show;
   term->frame_rehighlight_hook = 0;
   term->frame_raise_lower_hook = 0;
   term->set_vertical_scroll_bar_hook = 0;
@@ -1883,18 +1887,6 @@ dos_get_saved_screen (char **screen, int *rows, int *cols)
 #endif
 }
 
-#ifndef HAVE_X_WINDOWS
-
-/* We are not X, but we can emulate it well enough for our needs... */
-void
-check_window_system (void)
-{
-  if (! FRAME_MSDOS_P (SELECTED_FRAME ()))
-    error ("Not running under a window system");
-}
-
-#endif
-
 \f
 /* ----------------------- Keyboard control ----------------------
  *
@@ -3465,7 +3457,7 @@ init_environment (int argc, char **argv, int skip_args)
   static const char * const tempdirs[] = {
     "$TMPDIR", "$TEMP", "$TMP", "c:/"
   };
-  const int imax = EARRAYSIZE (tempdirs);
+  const int imax = ARRAYELTS (tempdirs);
 
   /* Make sure they have a usable $TMPDIR.  Many Emacs functions use
      temporary files and assume "/tmp" if $TMPDIR is unset, which
@@ -3875,6 +3867,9 @@ int setpgid (int pid, int pgid) { return 0; }
 int setpriority (int x, int y, int z) { return 0; }
 pid_t setsid (void) { return 0; }
 
+\f
+/* Gnulib support and emulation.  */
+
 #if __DJGPP__ == 2 && __DJGPP_MINOR__ < 4
 ssize_t
 readlink (const char *name, char *dummy1, size_t dummy2)
@@ -3886,6 +3881,38 @@ readlink (const char *name, char *dummy1, size_t dummy2)
 }
 #endif
 
+/* dir_pathname is set by sys_opendir and used in readlinkat and in
+   fstatat, when they get a special FD of zero, which means use the
+   last directory opened by opendir.  */
+static char dir_pathname[MAXPATHLEN];
+DIR *
+sys_opendir (const char *dirname)
+{
+  _fixpath (dirname, dir_pathname);
+  return opendir (dirname);
+}
+
+ssize_t
+readlinkat (int fd, char const *name, char *buffer, size_t buffer_size)
+{
+  /* Rely on a hack: an open directory is modeled as file descriptor 0,
+     as in fstatat.  FIXME: Add proper support for readlinkat.  */
+  char fullname[MAXPATHLEN];
+
+  if (fd != AT_FDCWD)
+    {
+      if (strlen (dir_pathname) + strlen (name) + 1 >= MAXPATHLEN)
+       {
+         errno = ENAMETOOLONG;
+         return -1;
+       }
+      sprintf (fullname, "%s/%s", dir_pathname, name);
+      name = fullname;
+    }
+
+  return readlink (name, buffer, buffer_size);
+}
+
 char *
 careadlinkat (int fd, char const *filename,
               char *buffer, size_t buffer_size,
@@ -3913,104 +3940,83 @@ careadlinkat (int fd, char const *filename,
   return buffer;
 }
 
-\f
-#if __DJGPP__ == 2 && __DJGPP_MINOR__ < 2
-
-/* Augment DJGPP library POSIX signal functions.  This is needed
-   as of DJGPP v2.01, but might be in the library in later releases. */
-
-#include <libc/bss.h>
-
-/* A counter to know when to re-initialize the static sets.  */
-static int sigprocmask_count = -1;
-
-/* Which signals are currently blocked (initially none).  */
-static sigset_t current_mask;
-
-/* Which signals are pending (initially none).  */
-static sigset_t msdos_pending_signals;
+/* Emulate faccessat(2).  */
+int
+faccessat (int dirfd, const char * path, int mode, int flags)
+{
+  /* We silently ignore FLAGS.  */
+  flags = flags;
 
-/* Previous handlers to restore when the blocked signals are unblocked.  */
-typedef void (*sighandler_t)(int);
-static sighandler_t prev_handlers[320];
+  if (dirfd != AT_FDCWD
+      && !(IS_DIRECTORY_SEP (path[0])
+          || IS_DEVICE_SEP (path[1])))
+    {
+      errno = EBADF;
+      return -1;
+    }
 
-/* A signal handler which just records that a signal occurred
-   (it will be raised later, if and when the signal is unblocked).  */
-static void
-sig_suspender (int signo)
-{
-  sigaddset (&msdos_pending_signals, signo);
+  return access (path, mode);
 }
 
+/* Emulate fstatat.  */
 int
-sigprocmask (int how, const sigset_t *new_set, sigset_t *old_set)
+fstatat (int fd, char const *name, struct stat *st, int flags)
 {
-  int signo;
-  sigset_t new_mask;
+  /* Rely on a hack: an open directory is modeled as file descriptor 0.
+     This is good enough for the current usage in Emacs, but is fragile.
 
-  /* If called for the first time, initialize.  */
-  if (sigprocmask_count != __bss_count)
+     FIXME: Add proper support for fdopendir, fstatat, readlinkat.
+     Gnulib does this and can serve as a model.  */
+  char fullname[MAXPATHLEN];
+
+  flags = flags;
+
+  if (fd != AT_FDCWD)
     {
-      sigprocmask_count = __bss_count;
-      sigemptyset (&msdos_pending_signals);
-      sigemptyset (&current_mask);
-      for (signo = 0; signo < 320; signo++)
-       prev_handlers[signo] = SIG_ERR;
+      char lastc = dir_pathname[strlen (dir_pathname) - 1];
+
+      if (strlen (dir_pathname) + strlen (name) + IS_DIRECTORY_SEP (lastc)
+         >= MAXPATHLEN)
+       {
+         errno = ENAMETOOLONG;
+         return -1;
+       }
+
+      sprintf (fullname, "%s%s%s",
+              dir_pathname, IS_DIRECTORY_SEP (lastc) ? "" : "/", name);
+      name = fullname;
     }
 
-  if (old_set)
-    *old_set = current_mask;
+#if __DJGPP__ > 2 || __DJGPP_MINOR__ > 3
+  return (flags & AT_SYMLINK_NOFOLLOW) ? lstat (name, st) : stat (name, st);
+#else
+  return stat (name, st);
+#endif
+}
 
-  if (new_set == 0)
-    return 0;
+#if __DJGPP__ == 2 && __DJGPP_MINOR__ < 4
+/* Emulate the Posix unsetenv.  DJGPP v2.04 has this in the library.  */
+int
+unsetenv (const char *name)
+{
+  char *var;
+  size_t name_len;
+  int retval;
 
-  if (how != SIG_BLOCK && how != SIG_UNBLOCK && how != SIG_SETMASK)
+  if (name == NULL || *name == '\0' || strchr (name, '=') != NULL)
     {
       errno = EINVAL;
       return -1;
     }
 
-  sigemptyset (&new_mask);
-
-  /* DJGPP supports upto 320 signals.  */
-  for (signo = 0; signo < 320; signo++)
-    {
-      if (sigismember (&current_mask, signo))
-       sigaddset (&new_mask, signo);
-      else if (sigismember (new_set, signo) && how != SIG_UNBLOCK)
-       {
-         sigaddset (&new_mask, signo);
+  /* DJGPP's 'putenv' deletes the entry if it doesn't include '='.  */
+  putenv (name);
 
-         /* SIGKILL is silently ignored, as on other platforms.  */
-         if (signo != SIGKILL && prev_handlers[signo] == SIG_ERR)
-           prev_handlers[signo] = signal (signo, sig_suspender);
-       }
-      if ((   how == SIG_UNBLOCK
-             && sigismember (&new_mask, signo)
-             && sigismember (new_set, signo))
-         || (how == SIG_SETMASK
-             && sigismember (&new_mask, signo)
-             && !sigismember (new_set, signo)))
-       {
-         sigdelset (&new_mask, signo);
-         if (prev_handlers[signo] != SIG_ERR)
-           {
-             signal (signo, prev_handlers[signo]);
-             prev_handlers[signo] = SIG_ERR;
-           }
-         if (sigismember (&msdos_pending_signals, signo))
-           {
-             sigdelset (&msdos_pending_signals, signo);
-             raise (signo);
-           }
-       }
-    }
-  current_mask = new_mask;
   return 0;
 }
+#endif
 
-#endif /* not __DJGPP_MINOR__ < 2 */
-
+\f
 #ifndef HAVE_SELECT
 #include "sysselect.h"
 
@@ -4038,7 +4044,7 @@ dos_yield_time_slice (void)
 /* We don't have to call timer_check here
    because wait_reading_process_output takes care of that.  */
 int
-sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
+sys_select (int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds,
            struct timespec *timeout, void *ignored)
 {
   int check_input;
@@ -4157,15 +4163,7 @@ msdos_abort (void)
   dos_ttcooked ();
   ScreenSetCursor (10, 0);
   cputs ("\r\n\nEmacs aborted!\r\n");
-#if __DJGPP__ == 2 && __DJGPP_MINOR__ < 2
-  if (screen_virtual_segment)
-    dosv_refresh_virtual_screen (2 * 10 * screen_size_X, 4 * screen_size_X);
-  /* Generate traceback, so we could tell whodunit.  */
-  signal (SIGINT, SIG_DFL);
-  __asm__ __volatile__ ("movb $0x1b,%al;call ___djgpp_hw_exception");
-#else  /* __DJGPP_MINOR__ >= 2 */
   raise (SIGABRT);
-#endif /* __DJGPP_MINOR__ >= 2 */
   exit (2);
 }