Add David Benbennick's changes to open_pipe() and move it to nano.c, and add his nperror function

git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1159 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
This commit is contained in:
Chris Allegretta 2002-03-29 16:31:29 +00:00
parent 9b4055c4da
commit 77777d4c0d
5 changed files with 129 additions and 52 deletions

View File

@ -3,9 +3,10 @@ CVS code -
- Type misalignments and mem leaks in renumber_all, do_justify
and do_spell (Rocco & Steven Kneizys).
- New "External Command" code, originally by Dwayne Rightler,
Chris & Rocco. New function files.c:open_pipe(), changes to
do_insertfile(), new list extcmd_list, cmd is ^X after ^R by
default.
various fixes and changes by Chris, Rocco and David Benbennick.
New function nano.c:open_pipe() and signal handler cancel_fork(),
changes to do_insertfile(), new list extcmd_list, cmd is
^X after ^R.
- Added separate regex variable (color_regex and colormatches)
so that color syntax and regex search/replace can coexist.
- files.c:
@ -50,6 +51,8 @@ CVS code -
- utils.c:
stristr()
- Defined regardless of NANO_SMALL (noticed by Jordi).
nperror()
- New wrapper for perror (David Benbennick).
- winio.c:
do_credits()
- Add Thomas Dickey.

51
files.c
View File

@ -110,12 +110,8 @@ int read_byte(int fd, char *filename, char *input)
index = 0;
size = read(fd, buf, BUFSIZ);
if (size == -1) {
clear();
refresh();
resetty();
endwin();
perror(filename);
total_refresh();
size = index; /* note index==0 */
nperror(filename);
return -1;
}
if (!size)
@ -292,49 +288,6 @@ int read_file(int fd, char *filename, int quiet)
return 1;
}
#ifndef NANO_SMALL
int open_pipe(char *command)
{
int fd[2], pid;
int fork_status;
/* Make our pipes. */
if (pipe(fd) == -1) {
statusbar(_("Could not pipe"));
return 1;
}
/* Fork a child */
if ((pid = fork()) == 0) {
close(fd[0]);
dup2(fd[1], fileno(stdout));
dup2(fd[1], fileno(stderr));
/* If execl() returns at all, there was an error. */
execl("/bin/sh","sh","-c",command,0);
exit(0);
}
/* Else continue as parent */
close(fd[1]);
if (pid == -1) {
close(fd[0]);
statusbar(_("Could not fork"));
return 1;
}
read_file(fd[0],"stdin",0);
set_modified();
wait(&fork_status);
return 0;
}
#endif /* NANO_SMALL */
/* Open the file (and decide if it exists) */
int open_file(char *filename, int insert, int quiet)

105
nano.c
View File

@ -1733,6 +1733,111 @@ int do_spell(void)
#endif
}
#ifndef NANO_SMALL
static int pid; /* this is the PID of the newly forked process below.
* It must be global since the signal handler needs it.
*/
RETSIGTYPE cancel_fork(int signal) {
if (kill(pid, SIGKILL)==-1) nperror("kill");
}
int open_pipe(char *command)
{
int fd[2];
struct sigaction oldaction, newaction;
/* original and temporary handlers for SIGINT */
#ifdef _POSIX_VDISABLE
struct termios term, newterm;
#endif /* _POSIX_VDISABLE */
int cancel_sigs = 0;
/* cancel_sigs==1 means that sigaction failed without changing the
* signal handlers. cancel_sigs==2 means the signal handler was
* changed, but the tcsetattr didn't succeed.
* I use this variable since it is important to put things back when
* we finish, even if we get errors.
*/
/* Make our pipes. */
if (pipe(fd) == -1) {
statusbar(_("Could not pipe"));
return 1;
}
/* Fork a child */
if ((pid = fork()) == 0) {
close(fd[0]);
dup2(fd[1], fileno(stdout));
dup2(fd[1], fileno(stderr));
/* If execl() returns at all, there was an error. */
execl("/bin/sh","sh","-c",command,0);
exit(0);
}
/* Else continue as parent */
close(fd[1]);
if (pid == -1) {
close(fd[0]);
statusbar(_("Could not fork"));
return 1;
}
/* before we start reading the forked command's output, we set
* things up so that ^C will cancel the new process.
*/
if (sigaction(SIGINT, NULL, &newaction)==-1) {
cancel_sigs = 1;
nperror("sigaction");
} else {
newaction.sa_handler = cancel_fork;
if (sigaction(SIGINT, &newaction, &oldaction)==-1) {
cancel_sigs = 1;
nperror("sigaction");
}
}
/* note that now oldaction is the previous SIGINT signal handler, to
be restored later */
/* if the platform supports disabling individual control characters */
#ifdef _POSIX_VDISABLE
if (!cancel_sigs && tcgetattr(0, &term) == -1) {
cancel_sigs = 2;
nperror("tcgetattr");
}
if (!cancel_sigs) {
newterm = term;
/* Grab oldterm's VINTR key :-) */
newterm.c_cc[VINTR] = oldterm.c_cc[VINTR];
if (tcsetattr(0, TCSANOW, &newterm) == -1) {
cancel_sigs = 2;
nperror("tcsetattr");
}
}
#endif /* _POSIX_VDISABLE */
read_file(fd[0],"stdin",0);
set_modified();
if (wait(NULL) == -1)
nperror("wait");
#ifdef _POSIX_VDISABLE
if (!cancel_sigs && tcsetattr(0, TCSANOW, &term) == -1)
nperror("tcsetattr");
#endif /* _POSIX_VDISABLE */
if (cancel_sigs!=1 && sigaction(SIGINT, &oldaction, NULL) == -1)
nperror("sigaction");
return 0;
}
#endif /* NANO_SMALL */
int do_exit(void)
{
int i;

View File

@ -116,6 +116,8 @@ int open_file(char *filename, int insert, int quiet);
int do_insertfile(int loading_file);
int length_of_list(shortcut *s);
int num_of_digits(int n);
int open_pipe(char *command);
int read_file(int fd, char *filename, int quiet);
#ifdef ENABLE_MULTIBUFFER
int add_open_file(int update);
@ -171,6 +173,7 @@ void center_cursor(void);
void bottombars(shortcut *s);
void blank_statusbar_refresh(void);
void *nmalloc (size_t howmuch);
void nperror(const char *s);
void *mallocstrcpy(char *dest, char *src);
void wrap_reset(void);
void display_main_list(void);

13
utils.c
View File

@ -21,6 +21,7 @@
#include "config.h"
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
@ -160,6 +161,18 @@ char *strstrwrapper(char *haystack, char *needle, char *rev_start)
#endif
}
/* This is a wrapper for the perror function. The wrapper takes care of
* ncurses, calls perror (which writes to STDERR), then refreshes the
* screen. Note that nperror causes the window to flicker once.
*/
void nperror(const char *s) {
/* leave ncurses mode, go to the terminal */
if (endwin() != ERR) {
perror(s); /* print the error */
total_refresh(); /* return to ncurses and repaint */
}
}
/* Thanks BG, many ppl have been asking for this... */
void *nmalloc(size_t howmuch)
{