aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2025-04-27 06:31:04 +0300
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2025-04-27 06:35:36 +0300
commit05569802996888f857ead155631fd3bd9c680876 (patch)
tree7d6f19a57a3e013eb48495db58146c09a1ea4765
parentb5325e00c402ec18034da4b4a4aaaefa87bb1fef (diff)
downloadvideoteco-fork-05569802996888f857ead155631fd3bd9c680876.tar.gz
implemented EC for non-UNIX almost pure standard C compilers
In particular, this will work on MS-DOS, albeit inefficiently. You also cannot generically redirect stderr on COMMAND.COM.
-rw-r--r--Makefile.wcc3
-rw-r--r--teccmd.c126
-rw-r--r--teco.h16
3 files changed, 128 insertions, 17 deletions
diff --git a/Makefile.wcc b/Makefile.wcc
index 57684f2..13ab749 100644
--- a/Makefile.wcc
+++ b/Makefile.wcc
@@ -37,7 +37,8 @@ LDFLAGS += format dos option eliminate option map option stack=16k &
set WCC_DEFS=-dSTDC_HEADERS=1 -dHAVE_STDIO_H -dHAVE_CTYPE_H -dHAVE_ERRNO_H &
-dHAVE_STRING_H -dHAVE_STRINGS_H -dHAVE_FCNTL_H -dHAVE_IO_H &
-dHAVE_SYS_STAT_H -dHAVE_SIGNAL_H -dHAVE_STDLIB_H -dHAVE_UNISTD_H &
- -dHAVE_STDINT_H -dHAVE_DIRECT_H -dHAVE_I86_H &
+ -dHAVE_STDINT_H -dHAVE_DIRECT_H -dHAVE_I86_H -dHAVE_PROCESS_H -dHAVE_CONIO_H &
+ -dHAVE_MALLOC_H &
-dHAVE_SBRK -dHAVE_STRCHR -dTERMCAP -d__WATCOM_LFN__
all : teco.exe .SYMBOLIC
diff --git a/teccmd.c b/teccmd.c
index 53a5a31..22c1219 100644
--- a/teccmd.c
+++ b/teccmd.c
@@ -1716,7 +1716,6 @@ register int length;
-#ifdef UNIX
/**
* \brief Issue a command to the operating system
*
@@ -1743,6 +1742,8 @@ register int length;
* \retval SUCCESS Command succeeded
* \retval FAIL Command failed. Error message has been displayed.
*/
+#ifdef UNIX
+
int
cmd_oscmd(struct cmd_token *uct, int arg_count, unsigned long arg1, unsigned long arg2, char *cp)
{
@@ -1953,27 +1954,128 @@ failreap:
#else /* UNIX */
-/**
- * \brief Issue a command to the operating system
+/*
+ * This version will work on any/most systems with a standard C library
+ * as it relies on temporary files.
*
- * This routine is called in response to the EC command which allows the
- * user to execute operating system commands from within the editor.
+ * FIXME: We cannot redirect stderr in MS-DOS.
*/
int
cmd_oscmd(struct cmd_token *uct, int arg_count, unsigned long arg1, unsigned long arg2, char *cp)
{
+char tmpbuf[LINE_BUFFER_SIZE];
+char pipebuff[IO_BUFFER_SIZE];
+struct undo_token *ut;
+int bidir_flag = arg_count > 0;
+int status,w;
+char cmdline[TECO_FILENAME_TOTAL_LENGTH];
+int input_fd = -1, output_fd = -1;
+char input_filename[L_tmpnam] = "", output_filename[L_tmpnam] = "";
+int rc = FAIL;
+
PREAMBLE();
- /*
- * FIXME: We could at least implement a subset with system(),
- * that would work on DOS as well.
- */
- error_message("?OS Does not currently support EC");
- return(FAIL);
+ snprintf(cmdline,sizeof(cmdline),"%s >%s <",
+ cp,tmpnam(output_filename));
-}/* End Routine */
+ if(bidir_flag){
+ strcat(cmdline,tmpnam(input_filename));
+ input_fd = open(input_filename,O_WRONLY|O_CREAT|O_TRUNC);
+ if(input_fd < 0){
+ sprintf(tmpbuf,"?Error opening input temporary file %s: %s",
+ input_filename,error_text(errno));
+ error_message(tmpbuf);
+ goto cleanup;
+ }/* End IF */
+
+/*
+ * In bidirectional mode, write buffer range to input_pipe, delete buffer range
+ * and care about the Undo structures
+ */
+ status = buff_write(curbuf,input_fd,arg1,arg2);
+ if(status == FAIL) goto cleanup;
+
+ ut = allocate_undo_token(uct);
+ if(ut == NULL) goto cleanup;
+ ut->opcode = UNDO_C_CHANGEDOT;
+ ut->iarg1 = curbuf->dot;
+
+ status = buff_delete_with_undo(uct,curbuf,arg1,arg2-arg1);
+ if(status == FAIL) goto cleanup;
+
+ close(input_fd);
+ input_fd = -1;
+ }/* End IF */
+#ifdef MSDOS
+ else{
+ strcat(cmdline,"NUL");
+ }/*End IF*/
+ _heapshrink();
#endif
+ errno = 0;
+ status = system(cmdline);
+ if(errno){
+ sprintf(tmpbuf,"?Error spawning external process: %s",
+ error_text(errno));
+ error_message(tmpbuf);
+ goto cleanup;
+ }/* End If */
+ if(status){
+ sprintf(tmpbuf,"?External process failed: %d",status);
+ error_message(tmpbuf);
+ goto cleanup;
+ }/* End If */
+
+ output_fd = open(output_filename,O_RDONLY);
+ if(output_fd < 0){
+ sprintf(tmpbuf,"?Error opening output temporary file %s: %s",
+ output_filename,error_text(errno));
+ error_message(tmpbuf);
+ goto cleanup;
+ }/* End IF */
+
+/*
+ * Loop reading stuff coming back from the pipe until we get an
+ * EOF which means the process has finished. Update the screen
+ * on newlines so the user can see what is going on.
+ *
+ * In unidirectional mode, process output is written to DOT, otherwise to
+ * the selected buffer range (it effectively gets replaced by the process output).
+ */
+ ut = allocate_undo_token(uct);
+ if(ut == NULL) goto cleanup;
+ ut->opcode = UNDO_C_DELETE;
+ ut->carg1 = (char *)curbuf;
+ ut->iarg1 = bidir_flag ? arg1 : curbuf->dot;
+ ut->iarg2 = 0;
+
+ while((w = read(output_fd,pipebuff,sizeof(pipebuff))) > 0){
+ status = buff_insert(curbuf,ut->iarg1 + ut->iarg2,pipebuff,w);
+ if(status == FAIL) goto cleanup;
+
+ ut->iarg2 += w;
+ }/* End While */
+ if(w < 0){
+ sprintf(tmpbuf,"?Error reading from output file %s: %s",
+ output_filename,error_text(errno));
+ error_message(tmpbuf);
+ goto cleanup;
+ }/* End If */
+
+ rc = SUCCESS;
+
+cleanup:
+ if(input_fd < 0) close(input_fd);
+ if(*input_filename) unlink(input_filename);
+ if(output_fd < 0) close(output_fd);
+ if(*output_filename) unlink(output_filename);
+ return(rc);
+}/* End Routine */
+
+#endif /* !UNIX */
+
+/* END OF UNIX CONDITIONAL CODE */
diff --git a/teco.h b/teco.h
index 42d04ce..746ed63 100644
--- a/teco.h
+++ b/teco.h
@@ -76,6 +76,10 @@
#include <sys/ioctl.h>
#endif
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+
/*
* sys/filio.h has the FIONREAD definition
*/
@@ -173,6 +177,14 @@
#include <i86.h>
#endif
+#if HAVE_PROCESS_H
+#include <process.h>
+#endif
+
+#ifdef HAVE_CONIO_H
+#include <conio.h>
+#endif
+
#if HAVE_SYS_WAIT_H
# include <sys/wait.h>
#endif
@@ -287,10 +299,6 @@
}
#endif
-#ifdef MSDOS
-#include <conio.h>
-#endif
-
#define TECO_FILENAME_TOTAL_LENGTH FILENAME_MAX
#define TECO_FILENAME_COMPONENT_LENGTH 256
#define TECO_READONLY_NAME "visit"