Merge from trunk
[bpt/emacs.git] / src / dosfns.c
index 240f19c..fea7038 100644 (file)
@@ -1,7 +1,7 @@
 /* MS-DOS specific Lisp utilities.  Coded by Manabu Higashida, 1991.
    Major changes May-July 1993 Morten Welinder (only 10% original code left)
    Copyright (C) 1991, 1993, 1996, 1997, 1998, 2001, 2002, 2003, 2004,
-                 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+                 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -24,8 +24,8 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 /* The entire file is within this conditional */
 
 #include <stdio.h>
-#include <string.h>
 #include <dos.h>
+#include <setjmp.h>
 #include "lisp.h"
 #include "buffer.h"
 #include "termchar.h"
@@ -38,29 +38,27 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "dispextern.h"
 #include "character.h"
 #include "coding.h"
+#include "process.h"
 #include <dpmi.h>
 #include <go32.h>
 #include <dirent.h>
 #include <sys/vfs.h>
-
-#ifndef __DJGPP_MINOR__
-# define __tb _go32_info_block.linear_address_of_transfer_buffer;
-#endif
+#include <unistd.h>
+#include <grp.h>
+#include <crt0.h>
 
 DEFUN ("int86", Fint86, Sint86, 2, 2, 0,
-       doc: /* Call specific MSDOS interrupt number INTERRUPT with REGISTERS.
+       doc: /* Call specific MS-DOS interrupt number INTERRUPT with REGISTERS.
 Return the updated REGISTER vector.
 
 INTERRUPT should be an integer in the range 0 to 255.
 REGISTERS should be a vector produced by `make-register' and
 `set-register-value'.  */)
-     (interrupt, registers)
-     Lisp_Object interrupt, registers;
+  (Lisp_Object interrupt, Lisp_Object registers)
 {
   register int i;
   int no;
   union REGS inregs, outregs;
-  Lisp_Object val;
 
   CHECK_NUMBER (interrupt);
   no = (unsigned long) XINT (interrupt);
@@ -96,13 +94,11 @@ REGISTERS should be a vector produced by `make-register' and
 DEFUN ("msdos-memget", Fdos_memget, Sdos_memget, 2, 2, 0,
        doc: /* Read DOS memory at offset ADDRESS into VECTOR.
 Return the updated VECTOR.  */)
-     (address, vector)
-     Lisp_Object address, vector;
+  (Lisp_Object address, Lisp_Object vector)
 {
   register int i;
   int offs, len;
   char *buf;
-  Lisp_Object val;
 
   CHECK_NUMBER (address);
   offs = (unsigned long) XINT (address);
@@ -121,13 +117,11 @@ Return the updated VECTOR.  */)
 
 DEFUN ("msdos-memput", Fdos_memput, Sdos_memput, 2, 2, 0,
        doc: /* Write DOS memory at offset ADDRESS from VECTOR.  */)
-     (address, vector)
-     Lisp_Object address, vector;
+  (Lisp_Object address, Lisp_Object vector)
 {
   register int i;
   int offs, len;
   char *buf;
-  Lisp_Object val;
 
   CHECK_NUMBER (address);
   offs = (unsigned long) XINT (address);
@@ -152,8 +146,7 @@ DEFUN ("msdos-set-keyboard", Fmsdos_set_keyboard, Smsdos_set_keyboard, 1, 2, 0,
 If the optional argument ALLKEYS is non-nil, the keyboard is mapped for
 all keys; otherwise it is only used when the ALT key is pressed.
 The current keyboard layout is available in dos-keyboard-code.  */)
-     (country_code, allkeys)
-     Lisp_Object country_code, allkeys;
+  (Lisp_Object country_code, Lisp_Object allkeys)
 {
   CHECK_NUMBER (country_code);
   if (!dos_set_keyboard (XINT (country_code), !NILP (allkeys)))
@@ -167,7 +160,7 @@ The current keyboard layout is available in dos-keyboard-code.  */)
 
 DEFUN ("msdos-mouse-p", Fmsdos_mouse_p, Smsdos_mouse_p, 0, 0, 0,
        doc: /* Report whether a mouse is present.  */)
-     ()
+  (void)
 {
   if (have_mouse)
     return Qt;
@@ -178,7 +171,7 @@ DEFUN ("msdos-mouse-p", Fmsdos_mouse_p, Smsdos_mouse_p, 0, 0, 0,
 
 DEFUN ("msdos-mouse-init", Fmsdos_mouse_init, Smsdos_mouse_init, 0, 0, "",
        doc: /* Initialize and enable mouse if available.  */)
-     ()
+  (void)
 {
   if (have_mouse)
     {
@@ -191,7 +184,7 @@ DEFUN ("msdos-mouse-init", Fmsdos_mouse_init, Smsdos_mouse_init, 0, 0, "",
 
 DEFUN ("msdos-mouse-enable", Fmsdos_mouse_enable, Smsdos_mouse_enable, 0, 0, "",
        doc: /* Enable mouse if available.  */)
-     ()
+  (void)
 {
   if (have_mouse)
     {
@@ -203,7 +196,7 @@ DEFUN ("msdos-mouse-enable", Fmsdos_mouse_enable, Smsdos_mouse_enable, 0, 0, "",
 
 DEFUN ("msdos-mouse-disable", Fmsdos_mouse_disable, Smsdos_mouse_disable, 0, 0, "",
        doc: /* Disable mouse if available.  */)
-     ()
+  (void)
 {
   mouse_off ();
   if (have_mouse) have_mouse = -1;
@@ -213,7 +206,7 @@ DEFUN ("msdos-mouse-disable", Fmsdos_mouse_disable, Smsdos_mouse_disable, 0, 0,
 DEFUN ("insert-startup-screen", Finsert_startup_screen, Sinsert_startup_screen, 0, 0, "",
        doc: /* Insert copy of screen contents prior to starting Emacs.
 Return nil if startup screen is not available.  */)
-     ()
+  (void)
 {
   char *s;
   int rows, cols, i, j;
@@ -282,13 +275,15 @@ restore_parent_vm_title (void)
 #endif /* !HAVE_X_WINDOWS */
 
 void
-init_dosfns ()
+init_dosfns (void)
 {
   union REGS regs;
   _go32_dpmi_registers dpmiregs;
   unsigned long xbuf = _go32_info_block.linear_address_of_transfer_buffer;
 
 #ifndef SYSTEM_MALLOC
+  extern void get_lim_data (void);
+
   get_lim_data (); /* why the hell isn't this called elsewhere? */
 #endif
 
@@ -380,8 +375,6 @@ init_dosfns ()
     }
 #endif /* !HAVE_X_WINDOWS */
 
-#if __DJGPP__ >= 2
-
   /* Without this, we never see hidden files.
      Don't OR it with the previous value, so the value recorded at dump
      time, possibly with `preserve-case' flags set, won't get through.  */
@@ -393,7 +386,6 @@ init_dosfns ()
   if (!NILP (Fmsdos_long_file_names ()))
     __opendir_flags |= __OPENDIR_PRESERVE_CASE;
 #endif /* __DJGPP_MINOR__ == 0 */
-#endif /* __DJGPP__ >= 2 */
 }
 \f
 #ifndef HAVE_X_WINDOWS
@@ -483,9 +475,7 @@ w95_set_virtual_machine_title (const char *title_string)
    sets the name in the frame struct, but has no other effects.  */
 
 void
-x_set_title (f, name)
-     struct frame *f;
-     Lisp_Object name;
+x_set_title (struct frame *f, Lisp_Object name)
 {
   /* Don't change the title if it's already NAME.  */
   if (EQ (name, f->title))
@@ -513,8 +503,7 @@ Value is a list of floats (TOTAL FREE AVAIL), where TOTAL is the total
 storage of the file system, FREE is the free storage, and AVAIL is the
 storage available to a non-superuser.  All 3 numbers are in bytes.
 If the underlying system call fails, value is nil.  */)
-     (filename)
-     Lisp_Object filename;
+  (Lisp_Object filename)
 {
   struct statfs stfs;
   Lisp_Object encoded, value;
@@ -533,6 +522,135 @@ If the underlying system call fails, value is nil.  */)
   return value;
 }
 \f
+/* System depended enumeration of and access to system processes a-la
+   ps(1).  Here, we only return info about the running Emacs process.
+   (There are no other processes on DOS, right?)  */
+
+Lisp_Object
+list_system_processes (void)
+{
+  Lisp_Object proclist = Qnil;
+
+  proclist = Fcons (make_fixnum_or_float (getpid ()), proclist);
+
+  return proclist;
+}
+
+Lisp_Object
+system_process_attributes (Lisp_Object pid)
+{
+  int proc_id;
+  Lisp_Object attrs = Qnil;
+
+  CHECK_NUMBER_OR_FLOAT (pid);
+  proc_id = FLOATP (pid) ? XFLOAT_DATA (pid) : XINT (pid);
+
+  if (proc_id == getpid ())
+    {
+      EMACS_INT uid, gid;
+      char *usr;
+      struct group *gr;
+      char cmd[FILENAME_MAX];
+      char *cmdline = NULL, *p, *q;
+      size_t cmdline_size = 0;
+      int i;
+      Lisp_Object cmd_str, decoded_cmd, tem;
+      double pmem;
+      EXFUN (Fget_internal_run_time, 0);
+#ifndef SYSTEM_MALLOC
+      extern unsigned long ret_lim_data ();
+#endif
+
+      uid = getuid ();
+      attrs = Fcons (Fcons (Qeuid, make_fixnum_or_float (uid)), attrs);
+      usr = getlogin ();
+      if (usr)
+       attrs = Fcons (Fcons (Quser, build_string (usr)), attrs);
+      gid = getgid ();
+      attrs = Fcons (Fcons (Qegid, make_fixnum_or_float (gid)), attrs);
+      gr = getgrgid (gid);
+      if (gr)
+       attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
+      strcpy (cmd, basename (__crt0_argv[0]));
+      /* Command name is encoded in locale-coding-system; decode it.  */
+      cmd_str = make_unibyte_string (cmd, strlen (cmd));
+      decoded_cmd = code_convert_string_norecord (cmd_str,
+                                                 Vlocale_coding_system, 0);
+      attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs);
+      /* Pretend we have 0 as PPID.  */
+      attrs = Fcons (Fcons (Qppid, make_number (0)), attrs);
+      attrs = Fcons (Fcons (Qpgrp, pid), attrs);
+      attrs = Fcons (Fcons (Qttname, build_string ("/dev/tty")), attrs);
+      /* We are never idle!  */
+      tem = Fget_internal_run_time ();
+      attrs = Fcons (Fcons (Qtime, tem), attrs);
+      attrs = Fcons (Fcons (Qthcount, make_number (1)), attrs);
+      attrs = Fcons (Fcons (Qstart,
+                           Fsymbol_value (intern ("before-init-time"))),
+                    attrs);
+      attrs = Fcons (Fcons (Qvsize,
+                           make_fixnum_or_float ((unsigned long)sbrk(0)/1024)),
+                    attrs);
+      attrs = Fcons (Fcons (Qetime, tem), attrs);
+#ifndef SYSTEM_MALLOC
+      /* ret_lim_data is on vm-limit.c, which is not compiled in under
+        SYSTEM_MALLOC.  */
+      pmem = (double)((unsigned long) sbrk (0)) / ret_lim_data () * 100.0;
+      if (pmem > 100)
+#endif
+       pmem = 100;
+      attrs = Fcons (Fcons (Qpmem, make_float (pmem)), attrs);
+      /* Pass 1: Count how much storage we need.  */
+      for (i = 0; i < __crt0_argc; i++)
+       {
+         cmdline_size += strlen (__crt0_argv[i]) + 1; /* +1 for blank delim */
+         if (strpbrk (__crt0_argv[i], " \t\n\r\v\f"))
+           {
+             cmdline_size += 2;
+             for (p = __crt0_argv[i]; *p; p++)
+               {
+                 if (*p == '"')
+                   cmdline_size++;
+               }
+           }
+       }
+      /* Pass 2: Allocate storage and concatenate argv[].  */
+      cmdline = xmalloc (cmdline_size + 1);
+      for (i = 0, q = cmdline; i < __crt0_argc; i++)
+       {
+         if (strpbrk (__crt0_argv[i], " \t\n\r\v\f"))
+           {
+             *q++ = '"';
+             for (p = __crt0_argv[i]; *p; p++)
+               {
+                 if (*p == '\"')
+                   *q++ = '\\';
+                 *q++ = *p;
+               }
+             *q++ = '"';
+           }
+         else
+           {
+             strcpy (q, __crt0_argv[i]);
+             q += strlen (__crt0_argv[i]);
+           }
+         *q++ = ' ';
+       }
+      /* Remove the trailing blank.  */
+      if (q > cmdline)
+       q[-1] = '\0';
+
+      /* Command line is encoded in locale-coding-system; decode it.  */
+      cmd_str = make_unibyte_string (cmdline, strlen (cmdline));
+      decoded_cmd = code_convert_string_norecord (cmd_str,
+                                                 Vlocale_coding_system, 0);
+      xfree (cmdline);
+      attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs);
+    }
+
+  return attrs;
+}
+\f
 void
 dos_cleanup (void)
 {
@@ -563,7 +681,8 @@ dos_cleanup (void)
 /*
  *     Define everything
  */
-syms_of_dosfns ()
+void
+syms_of_dosfns (void)
 {
   defsubr (&Sint86);
   defsubr (&Sdos_memget);