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 >
Wrap
C/C++ Source or Header
|
1994-08-13
|
30KB
|
1,488 lines
/* vi:ts=4:sw=4
*
* VIM - Vi IMproved by Bram Moolenaar
*
* Read the file "credits.txt" for a list of people who contributed.
* Read the file "uganda.txt" for copying and usage conditions.
*/
/*
* unix.c -- BSD and SYSV code
*
* A lot of this file was written by Juergen Weigert.
*/
#include "vim.h"
#include "globals.h"
#include "param.h"
#include "proto.h"
#include <fcntl.h>
#if !defined(pyr) && !defined(NOT_BOTH_TIME)
# include <time.h> /* on some systems time.h should not be
included together with sys/time.h */
#endif
#include <sys/ioctl.h>
#ifndef M_XENIX
# include <sys/types.h>
#endif
#include <signal.h>
#ifndef USE_SYSTEM /* use fork/exec to start the shell */
# include <sys/wait.h>
# if !defined(SCO) && !defined(SOLARIS) && !defined(hpux) && !defined(__NetBSD__) && !defined(__FreeBSD__) && !defined(_SEQUENT_) && !defined(UNISYS) /* SCO returns pid_t */
extern int fork();
# endif
# if !defined(linux) && !defined(SOLARIS) && !defined(USL) && !defined(sun) && !(defined(hpux) && defined(__STDC__)) && !defined(__NetBSD__) && !defined(__FreeBSD__) && !defined(USL) && !defined(UNISYS)
extern int execvp __ARGS((const char *, const char **));
# endif
#endif
#if defined(SYSV_UNIX) || defined(USL)
# if defined(__sgi) || defined(UTS2) || defined(UTS4) || defined(MIPS) || defined (MIPSEB) || defined(__osf__)
# include <sys/time.h>
# endif
# if defined(M_XENIX) || defined(SCO)
# include <stropts.h>
# endif
# if defined(M_XENIX) || defined(SCO) || defined(UNICOS)
# include <sys/select.h>
# define bzero(a, b) memset((a), 0, (b))
# endif
# if !defined(M_XENIX) && !defined(UNICOS)
# include <poll.h>
# endif
# if defined(SCO) || defined(ISC)
# include <sys/stream.h>
# include <sys/ptem.h>
# endif
# if defined(M_UNIX) && !defined(SCO)
# include <sys/time.h>
# endif /* M_UNIX */
# ifdef ISC
# include <termios.h>
# endif
# include <termio.h>
#else /* SYSV_UNIX */
# include <sys/time.h>
# if defined(hpux) || defined(linux)
# include <termio.h>
# if defined(hpux) && !defined(SIGWINCH) /* hpux 9.01 has it */
# define SIGWINCH SIGWINDOW
# endif
# else
# include <sgtty.h>
# endif /* hpux */
#endif /* !SYSV_UNIX */
#if (defined(pyr) || defined(NO_FD_ZERO)) && defined(SYSV_UNIX) && defined(FD_ZERO)
# undef FD_ZERO
#endif
#if defined(ESIX) || defined(M_UNIX) && !defined(SCO)
# ifdef SIGWINCH
# undef SIGWINCH
# endif
# ifdef TIOCGWINSZ
# undef TIOCGWINSZ
# endif
#endif
#ifdef USE_X11
# include <X11/Xlib.h>
# include <X11/Xutil.h>
Window x11_window = 0;
Display *x11_display = NULL;
static int get_x11_windis __ARGS((void));
#ifdef BUGGY
static void set_x11_title __ARGS((char_u *));
static void set_x11_icon __ARGS((char_u *));
#endif
#endif
static void get_x11_title __ARGS((void));
static void get_x11_icon __ARGS((void));
static int Read __ARGS((char_u *, long));
static int WaitForChar __ARGS((int));
static int RealWaitForChar __ARGS((int));
static void fill_inbuf __ARGS((void));
#ifdef USL
static void sig_winch __ARGS((int));
#else
# if defined(SIGWINCH) && !defined(linux) && !defined(__alpha) && !defined(mips) && !defined(_SEQUENT_) && !defined(SCO) && !defined(SOLARIS) && !defined(ISC)
static void sig_winch __ARGS((int, int, struct sigcontext *));
# endif
#endif
static int do_resize = FALSE;
static char_u *oldtitle = NULL;
static char_u *oldicon = NULL;
static char_u *extra_shell_arg = NULL;
static int show_shell_mess = TRUE;
/*
* At this point TRUE and FALSE are defined as 1L and 0L, but we want 1 and 0.
*/
#undef TRUE
#define TRUE 1
#undef FALSE
#define FALSE 0
void
mch_write(s, len)
char_u *s;
int len;
{
write(1, (char *)s, len);
}
/*
* GetChars(): low level input funcion.
* Get a characters from the keyboard.
* If wtime == 0 do not wait for characters.
* If wtime == n wait a short time for characters.
* If wtime == -1 wait forever for characters.
*/
int
GetChars(buf, maxlen, wtime)
char_u *buf;
int maxlen;
int wtime; /* don't use "time", MIPS cannot handle it */
{
int len;
if (wtime >= 0)
{
while (WaitForChar(wtime) == 0) /* no character available */
{
if (!do_resize) /* return if not interrupted by resize */
return 0;
set_winsize(0, 0, FALSE);
do_resize = FALSE;
}
}
else /* wtime == -1 */
{
/*
* If there is no character available within 'updatetime' seconds
* flush all the swap files to disk
* Also done when interrupted by SIGWINCH.
*/
if (WaitForChar((int)p_ut) == 0)
updatescript(0);
}
for (;;) /* repeat until we got a character */
{
if (do_resize) /* window changed size */
{
set_winsize(0, 0, FALSE);
do_resize = FALSE;
}
/*
* we want to be interrupted by the winch signal
*/
WaitForChar(-1);
if (do_resize) /* interrupted by SIGWINCHsignal */
continue;
len = Read(buf, (long)maxlen);
if (len > 0)
return len;
}
}
/*
* return non-zero if a character is available
*/
int
mch_char_avail()
{
return WaitForChar(0);
}
long
mch_avail_mem(special)
int special;
{
return 0x7fffffff; /* virual memory eh */
}
#ifndef FD_ZERO
void
vim_delay()
{
poll(0, 0, 500);
}
#else
# if (defined(__STDC__) && !defined(hpux)) || defined(ultrix)
extern int select __ARGS((int, fd_set *, fd_set *, fd_set *, struct timeval *));
# endif
void
vim_delay()
{
struct timeval tv;
tv.tv_sec = 25 / 50;
tv.tv_usec = (25 % 50) * (1000000/50);
select(0, 0, 0, 0, &tv);
}
#endif
static void
#if defined(__alpha) || (defined(mips) && !defined(USL))
sig_winch()
#else
# if defined(_SEQUENT_) || defined(SCO) || defined(ISC)
sig_winch(sig, code)
int sig;
int code;
# else
# if defined(USL)
sig_winch(sig)
int sig;
# else
sig_winch(sig, code, scp)
int sig;
int code;
struct sigcontext *scp;
# endif
# endif
#endif
{
#if defined(SIGWINCH)
/* this is not required on all systems, but it doesn't hurt anybody */
signal(SIGWINCH, (void (*)())sig_winch);
#endif
do_resize = TRUE;
}
/*
* If the machine has job control, use it to suspend the program,
* otherwise fake it by starting a new shell.
*/
void
mch_suspend()
{
#ifdef SIGTSTP
settmode(0);
kill(0, SIGTSTP); /* send ourselves a STOP signal */
settmode(1);
#else
OUTSTR("new shell started\n");
(void)call_shell(NULL, 0, TRUE);
#endif
}
void
mch_windinit()
{
Columns = 80;
Rows = 24;
flushbuf();
(void)mch_get_winsize();
#if defined(SIGWINCH)
signal(SIGWINCH, (void (*)())sig_winch);
#endif
}
/*
* Check_win checks whether we have an interactive window.
* If not, a new window is opened with the newcli command.
* If we would open a window ourselves, the :sh and :! commands would not
* work properly (Why? probably because we are then running in a background CLI).
* This also is the best way to assure proper working in a next Workbench release.
*
* For the -e option (quickfix mode) we open our own window and disable :sh.
* Otherwise we would never know when editing is finished.
*/
#define BUF2SIZE 320 /* lenght of buffer for argument with complete path */
void
check_win(argc, argv)
int argc;
char **argv;
{
if (!isatty(0) || !isatty(1))
{
fprintf(stderr, "VIM: no controlling terminal\n");
exit(2);
}
}
/*
* fname_case(): Set the case of the filename, if it already exists.
* This will cause the filename to remain exactly the same.
*/
void
fname_case(name)
char_u *name;
{
}
#ifdef USE_X11
/*
* try to get x11 window and display
*
* return FAIL for failure, OK otherwise
*/
static int
get_x11_windis()
{
char *winid;
/*
* If WINDOWID not set, should try another method to find out
* what the current window number is. The only code I know for
* this is very complicated.
* We assume that zero is invalid for WINDOWID.
*/
if (x11_window == 0 && (winid = getenv("WINDOWID")) != NULL)
x11_window = (Window)atol(winid);
if (x11_window != 0 && x11_display == NULL)
x11_display = XOpenDisplay(NULL);
if (x11_window == 0 || x11_display == NULL)
return FAIL;
return OK;
}
/*
* Determine original x11 Window Title
*/
static void
get_x11_title()
{
XTextProperty text_prop;
if (get_x11_windis() == OK)
{
/* Get window name if any */
if (XGetWMName(x11_display, x11_window, &text_prop))
{
if (text