home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD2.bin / bbs / util / vim-3.0.lha / Vim / src / unix.c < prev    next >
C/C++ Source or Header  |  1994-08-13  |  30KB  |  1,488 lines

  1. /* vi:ts=4:sw=4
  2.  *
  3.  * VIM - Vi IMproved        by Bram Moolenaar
  4.  *
  5.  * Read the file "credits.txt" for a list of people who contributed.
  6.  * Read the file "uganda.txt" for copying and usage conditions.
  7.  */
  8.  
  9. /*
  10.  * unix.c -- BSD and SYSV code
  11.  *
  12.  * A lot of this file was written by Juergen Weigert.
  13.  */
  14.  
  15. #include "vim.h"
  16. #include "globals.h"
  17. #include "param.h"
  18. #include "proto.h"
  19.  
  20. #include <fcntl.h>
  21. #if !defined(pyr) && !defined(NOT_BOTH_TIME)
  22. # include <time.h>            /* on some systems time.h should not be
  23.                                included together with sys/time.h */
  24. #endif
  25. #include <sys/ioctl.h>
  26. #ifndef M_XENIX
  27. # include <sys/types.h>
  28. #endif
  29. #include <signal.h>
  30.  
  31. #ifndef USE_SYSTEM        /* use fork/exec to start the shell */
  32. # include <sys/wait.h>
  33. # if !defined(SCO) && !defined(SOLARIS) && !defined(hpux) && !defined(__NetBSD__) && !defined(__FreeBSD__) && !defined(_SEQUENT_) && !defined(UNISYS)    /* SCO returns pid_t */
  34. extern int fork();
  35. # endif
  36. # if !defined(linux) && !defined(SOLARIS) && !defined(USL) && !defined(sun) && !(defined(hpux) && defined(__STDC__)) && !defined(__NetBSD__) && !defined(__FreeBSD__) && !defined(USL) && !defined(UNISYS)
  37. extern int execvp __ARGS((const char *, const char **));
  38. # endif
  39. #endif
  40.  
  41. #if defined(SYSV_UNIX) || defined(USL)
  42. # if defined(__sgi) || defined(UTS2) || defined(UTS4) || defined(MIPS) || defined (MIPSEB) || defined(__osf__)
  43. #  include <sys/time.h>
  44. # endif
  45. # if defined(M_XENIX) || defined(SCO)
  46. #  include <stropts.h>
  47. # endif
  48. # if defined(M_XENIX) || defined(SCO) || defined(UNICOS)
  49. #  include <sys/select.h>
  50. #  define bzero(a, b)    memset((a), 0, (b))
  51. # endif
  52. # if !defined(M_XENIX) && !defined(UNICOS)
  53. #  include <poll.h>
  54. # endif
  55. # if defined(SCO) || defined(ISC)
  56. #  include <sys/stream.h>
  57. #  include <sys/ptem.h>
  58. # endif
  59. # if defined(M_UNIX) && !defined(SCO)
  60. #  include <sys/time.h>
  61. # endif       /* M_UNIX */
  62. # ifdef ISC
  63. #  include <termios.h>
  64. # endif
  65. # include <termio.h>
  66. #else    /* SYSV_UNIX */
  67. # include <sys/time.h>
  68. # if defined(hpux) || defined(linux)
  69. #  include <termio.h>
  70. #  if defined(hpux) && !defined(SIGWINCH)    /* hpux 9.01 has it */
  71. #   define SIGWINCH SIGWINDOW
  72. #  endif
  73. # else
  74. #  include <sgtty.h>
  75. # endif    /* hpux */
  76. #endif    /* !SYSV_UNIX */
  77.  
  78. #if (defined(pyr) || defined(NO_FD_ZERO)) && defined(SYSV_UNIX) && defined(FD_ZERO)
  79. # undef FD_ZERO
  80. #endif
  81.  
  82. #if defined(ESIX) || defined(M_UNIX) && !defined(SCO)
  83. # ifdef SIGWINCH
  84. #  undef SIGWINCH
  85. # endif
  86. # ifdef TIOCGWINSZ
  87. #  undef TIOCGWINSZ
  88. # endif
  89. #endif
  90.  
  91. #ifdef USE_X11
  92.  
  93. # include <X11/Xlib.h>
  94. # include <X11/Xutil.h>
  95.  
  96. Window        x11_window = 0;
  97. Display        *x11_display = NULL;
  98.  
  99. static int    get_x11_windis __ARGS((void));
  100. #ifdef BUGGY
  101. static void set_x11_title __ARGS((char_u *));
  102. static void set_x11_icon __ARGS((char_u *));
  103. #endif
  104. #endif
  105.  
  106. static void get_x11_title __ARGS((void));
  107. static void get_x11_icon __ARGS((void));
  108.  
  109. static int    Read __ARGS((char_u *, long));
  110. static int    WaitForChar __ARGS((int));
  111. static int    RealWaitForChar __ARGS((int));
  112. static void fill_inbuf __ARGS((void));
  113. #ifdef USL
  114. static void sig_winch __ARGS((int));
  115. #else
  116. # if defined(SIGWINCH) && !defined(linux) && !defined(__alpha) && !defined(mips) && !defined(_SEQUENT_) && !defined(SCO) && !defined(SOLARIS) && !defined(ISC)
  117. static void sig_winch __ARGS((int, int, struct sigcontext *));
  118. # endif
  119. #endif
  120.  
  121. static int do_resize = FALSE;
  122. static char_u *oldtitle = NULL;
  123. static char_u *oldicon = NULL;
  124. static char_u *extra_shell_arg = NULL;
  125. static int show_shell_mess = TRUE;
  126.  
  127. /*
  128.  * At this point TRUE and FALSE are defined as 1L and 0L, but we want 1 and 0.
  129.  */
  130. #undef TRUE
  131. #define TRUE 1
  132. #undef FALSE
  133. #define FALSE 0
  134.  
  135.     void
  136. mch_write(s, len)
  137.     char_u    *s;
  138.     int        len;
  139. {
  140.     write(1, (char *)s, len);
  141. }
  142.  
  143. /*
  144.  * GetChars(): low level input funcion.
  145.  * Get a characters from the keyboard.
  146.  * If wtime == 0 do not wait for characters.
  147.  * If wtime == n wait a short time for characters.
  148.  * If wtime == -1 wait forever for characters.
  149.  */
  150.     int
  151. GetChars(buf, maxlen, wtime)
  152.     char_u    *buf;
  153.     int        maxlen;
  154.     int        wtime;            /* don't use "time", MIPS cannot handle it */
  155. {
  156.     int        len;
  157.  
  158.     if (wtime >= 0)
  159.     {
  160.         while (WaitForChar(wtime) == 0)        /* no character available */
  161.         {
  162.             if (!do_resize)            /* return if not interrupted by resize */
  163.                 return 0;
  164.             set_winsize(0, 0, FALSE);
  165.             do_resize = FALSE;
  166.         }
  167.     }
  168.     else        /* wtime == -1 */
  169.     {
  170.     /*
  171.      * If there is no character available within 'updatetime' seconds
  172.      * flush all the swap files to disk
  173.      * Also done when interrupted by SIGWINCH.
  174.      */
  175.         if (WaitForChar((int)p_ut) == 0)
  176.             updatescript(0);
  177.     }
  178.  
  179.     for (;;)    /* repeat until we got a character */
  180.     {
  181.         if (do_resize)        /* window changed size */
  182.         {
  183.             set_winsize(0, 0, FALSE);
  184.             do_resize = FALSE;
  185.         }
  186.         /* 
  187.          * we want to be interrupted by the winch signal
  188.          */
  189.         WaitForChar(-1);
  190.         if (do_resize)        /* interrupted by SIGWINCHsignal */
  191.             continue;
  192.         len = Read(buf, (long)maxlen);
  193.         if (len > 0)
  194.             return len;
  195.     }
  196. }
  197.  
  198. /*
  199.  * return non-zero if a character is available
  200.  */
  201.     int
  202. mch_char_avail()
  203. {
  204.     return WaitForChar(0);
  205. }
  206.  
  207.     long
  208. mch_avail_mem(special)
  209.     int special;
  210. {
  211.     return 0x7fffffff;        /* virual memory eh */
  212. }
  213.  
  214. #ifndef FD_ZERO
  215.     void
  216. vim_delay()
  217. {
  218.     poll(0, 0, 500);
  219. }
  220. #else
  221. # if (defined(__STDC__) && !defined(hpux)) || defined(ultrix)
  222. extern int select __ARGS((int, fd_set *, fd_set *, fd_set *, struct timeval *));
  223. # endif
  224.  
  225.     void
  226. vim_delay()
  227. {
  228.     struct timeval tv;
  229.  
  230.     tv.tv_sec = 25 / 50;
  231.     tv.tv_usec = (25 % 50) * (1000000/50);
  232.     select(0, 0, 0, 0, &tv);
  233. }
  234. #endif
  235.  
  236.     static void
  237. #if defined(__alpha) || (defined(mips) && !defined(USL))
  238. sig_winch()
  239. #else
  240. # if defined(_SEQUENT_) || defined(SCO) || defined(ISC)
  241. sig_winch(sig, code)
  242.     int        sig;
  243.     int        code;
  244. # else
  245. #  if defined(USL)
  246. sig_winch(sig)
  247.     int        sig;
  248. #  else
  249. sig_winch(sig, code, scp)
  250.     int        sig;
  251.     int        code;
  252.     struct sigcontext *scp;
  253. #  endif
  254. # endif
  255. #endif
  256. {
  257. #if defined(SIGWINCH)
  258.         /* this is not required on all systems, but it doesn't hurt anybody */
  259.     signal(SIGWINCH, (void (*)())sig_winch);
  260. #endif
  261.     do_resize = TRUE;
  262. }
  263.  
  264. /*
  265.  * If the machine has job control, use it to suspend the program,
  266.  * otherwise fake it by starting a new shell.
  267.  */
  268.     void
  269. mch_suspend()
  270. {
  271. #ifdef SIGTSTP
  272.     settmode(0);
  273.     kill(0, SIGTSTP);        /* send ourselves a STOP signal */
  274.     settmode(1);
  275. #else
  276.     OUTSTR("new shell started\n");
  277.     (void)call_shell(NULL, 0, TRUE);
  278. #endif
  279. }
  280.  
  281.     void
  282. mch_windinit()
  283. {
  284.     Columns = 80;
  285.     Rows = 24;
  286.  
  287.     flushbuf();
  288.  
  289.     (void)mch_get_winsize();
  290. #if defined(SIGWINCH)
  291.     signal(SIGWINCH, (void (*)())sig_winch);
  292. #endif
  293. }
  294.  
  295. /*
  296.  * Check_win checks whether we have an interactive window.
  297.  * If not, a new window is opened with the newcli command.
  298.  * If we would open a window ourselves, the :sh and :! commands would not
  299.  * work properly (Why? probably because we are then running in a background CLI).
  300.  * This also is the best way to assure proper working in a next Workbench release.
  301.  *
  302.  * For the -e option (quickfix mode) we open our own window and disable :sh.
  303.  * Otherwise we would never know when editing is finished.
  304.  */
  305. #define BUF2SIZE 320        /* lenght of buffer for argument with complete path */
  306.  
  307.     void
  308. check_win(argc, argv)
  309.     int        argc;
  310.     char    **argv;
  311. {
  312.     if (!isatty(0) || !isatty(1))
  313.     {
  314.         fprintf(stderr, "VIM: no controlling terminal\n");
  315.         exit(2);
  316.     }
  317. }
  318.  
  319. /*
  320.  * fname_case(): Set the case of the filename, if it already exists.
  321.  *                 This will cause the filename to remain exactly the same.
  322.  */
  323.     void
  324. fname_case(name)
  325.     char_u *name;
  326. {
  327. }
  328.  
  329. #ifdef USE_X11
  330. /*
  331.  * try to get x11 window and display
  332.  *
  333.  * return FAIL for failure, OK otherwise
  334.  */
  335.     static int
  336. get_x11_windis()
  337. {
  338.     char        *winid;
  339.  
  340.     /*
  341.      * If WINDOWID not set, should try another method to find out
  342.      * what the current window number is. The only code I know for
  343.      * this is very complicated.
  344.      * We assume that zero is invalid for WINDOWID.
  345.      */
  346.     if (x11_window == 0 && (winid = getenv("WINDOWID")) != NULL) 
  347.         x11_window = (Window)atol(winid);
  348.     if (x11_window != 0 && x11_display == NULL)
  349.         x11_display = XOpenDisplay(NULL);
  350.     if (x11_window == 0 || x11_display == NULL)
  351.         return FAIL;
  352.     return OK;
  353. }
  354.  
  355. /*
  356.  * Determine original x11 Window Title
  357.  */
  358.     static void
  359. get_x11_title()
  360. {
  361.     XTextProperty    text_prop;
  362.  
  363.     if (get_x11_windis() == OK)
  364.     {
  365.             /* Get window name if any */
  366.         if (XGetWMName(x11_display, x11_window, &text_prop))
  367.         {
  368.             if (text