/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- initarea
- refreshscreen
- handler
- main
/* This example uses curses library. In Linux use:
cc -o sharedit sharedit.c -lncurses
in other Unix'es use:
cc -o sharedit shared.c -lcurses
usage:
sharedit filename
*/
#include<stdio.h>
#include<signal.h>
#include<fcntl.h>
#include<sys/mman.h>
#include<curses.h>
#include<errno.h>
#define ROWS 23
#define COLS 80
#define REFRESH 1
char *area;
int row=0,col=0;
void initarea()
/* Change all 0 bytes to space character if a new file*/
{
int i;
for (i=0;i<ROWS*COLS;i++)
if (area[i]==0)
area[i]=' ';
}
void refreshscreen()
/* Move all data in the file into window using curses function and refresh */
{
int i;
for (i=0;i<ROWS;i++)
mvwaddnstr(stdscr,i,0,area+i*COLS,COLS);
move(row,col); /* recover curses position */
refresh(); /* redraw the window */
}
void handler(int s)
/* SIGALRM handler in order to refresh the screen
in order to reflect changes (possibly by another process */
{
refreshscreen();
alarm(REFRESH);
/* some systems alarm handler is cleared, reset it */
signal(SIGALRM,handler);
}
int main(int argc, char *argv[])
{
int fd;
int key;
if (argc != 2) {
fprintf(stderr,"Usage: sharedit filename\n");
return -1;
}
fd=open(argv[1],O_RDWR|O_CREAT,0600);
/* open the first argument as a file, create with rw------ if
file does not exist */
lseek(fd,ROWS*COLS,SEEK_SET); /* Guarantee that file size */
read(fd,&key,1); /* is large enough */
lseek(fd,-1,SEEK_CUR);
write(fd,&key,1);
if (fd<0) {
perror(argv[0]);
return -2;
}
area=mmap(0,ROWS*COLS, PROT_READ|PROT_WRITE, MAP_SHARED,fd,0);
if (area==NULL) {
perror("mmap:");
return -3;
}
initarea();
/* Curses routines to initialize the interactive window */
initscr(); cbreak(); noecho();
keypad(stdscr,TRUE);
clear();
/* adjust alarm */
signal(SIGALRM,handler);
alarm(REFRESH);
refreshscreen();
/* infinite loop until F10 key is pressed */
while ((key=getch())!=KEY_F(10)) {
switch (key) {
case KEY_LEFT: if (col>0)
col--;
break;
case KEY_RIGHT: if (col<COLS-1)
col++;
break;
case KEY_UP: if (row>0)
row--;
break;
case KEY_DOWN: if (row<ROWS-1)
row++;
break;
default: if (isprint(key)) {
area[row*COLS+col]=key;
addch(key);
if (col<COLS-1) col++;
}
}
/* Cursor position report in the status (bottom) line */
mvprintw(ROWS,0,"%2d,%2d",col,row);
move(row,col);
}
}