This patch will add the following functions to eppic:
1) Allow main() as the entry for any eppic program. Previously only func()
which companied by func_help() & func_usage() is regarded as the main
entry of the eppic program. This constraint only makes sense for creating
a crash-like cmd. If users only want to create a oneshot run program for
fast testing, then the constraint is misleading. So this patch will add
main() as entry for eppic programs.
2) Add new option "-r" for eppic cmd "edit". Previously eppic expect
programs
to run as the form of crash-like cmd, and it is not convenient for the
oneshot run programs. Luckly the programs can be executed automatically
after "edit -f". So I create a "edit -r" cmd to run the eppic
program
without invoke the editor, in order to reuse the code. So eppic programs
can be now executed by "edit -r myfile.c", and "edit -r" will be
alias as
"eppic" in later patches, so a eppic program can be run simply by
"eppic myfile.c".
3) Add a template for any new eppic program files. If "edit -f" a new file, a
template with an example will be written into the new file. So users can
refer to it when writting any eppic programs.
Signed-off-by: Tao Liu <ltao(a)redhat.com>
---
extensions/eppic.mk | 13 ++-
extensions/eppic.patch | 195 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 207 insertions(+), 1 deletion(-)
create mode 100644 extensions/eppic.patch
diff --git a/extensions/eppic.mk b/extensions/eppic.mk
index 9435793..b175df5 100644
--- a/extensions/eppic.mk
+++ b/extensions/eppic.mk
@@ -53,7 +53,18 @@ all:
fi; \
if [ -f $(APPFILE) ]; \
then \
- make -f eppic.mk eppic.so; \
+ pushd eppic >/dev/null; \
+ if patch --dry-run -N -p0 < ../eppic.patch >/dev/null ; then \
+ patch -N -p0 < ../eppic.patch; \
+ popd >/dev/null; \
+ make -f eppic.mk eppic.so; \
+ elif patch --dry-run -N -p0 -R < ../eppic.patch >/dev/null ; then \
+ popd >/dev/null; \
+ make -f eppic.mk eppic.so; \
+ else \
+ popd >/dev/null; \
+ echo "eppic.so: apply eppic.patch error"; \
+ fi; \
else \
echo "eppic.so: failed to pull eppic code from git repo"; \
fi; \
diff --git a/extensions/eppic.patch b/extensions/eppic.patch
new file mode 100644
index 0000000..f38eac0
--- /dev/null
+++ b/extensions/eppic.patch
@@ -0,0 +1,195 @@
+--- applications/crash/eppic.c
++++ applications/crash/eppic.c
+@@ -642,12 +642,12 @@ FILE *ofp = NULL;
+ eppic_setofile(ofp);
+ }
+
+-
++void *eppic_findfile(char *, int);
+ void
+ edit_cmd(void)
+ {
+-int c, file=0;
+- while ((c = getopt(argcnt, args, "lf")) != EOF) {
++int c, file=0, run=0;
++ while ((c = getopt(argcnt, args, "lfr")) != EOF) {
+ switch(c)
+ {
+ case 'l':
+@@ -657,6 +657,9 @@ int c, file=0;
+ case 'f':
+ file++;
+ break;
++ case 'r':
++ run++;
++ break;
+ default:
+ argerrs++;
+ break;
+@@ -666,10 +669,17 @@ int c, file=0;
+ if (argerrs)
+ cmd_usage(crash_global_cmd(), SYNOPSIS);
+
+- else if(args[optind]) {
++ else if(args[optind] && file && !run) {
+ while(args[optind]) {
+ eppic_vi(args[optind++], file);
+ }
++ } else if(args[optind] && !file && run) {
++ while(args[optind]) {
++ eppic_load(args[optind]);
++ if (eppic_findfile(args[optind], 0))
++ eppic_unload(args[optind]);
++ optind++;
++ }
+ }
+ else cmd_usage(crash_global_cmd(), SYNOPSIS);
+ }
+@@ -677,7 +687,7 @@ int c, file=0;
+ char *edit_help[]={
+ "edit",
+ "Start a $EDITOR session of a eppic function or file",
+- "<-f fileName>|<function name>",
++ "<-f fileName>|<function name>|<-r
fileName>",
+ "This command can be use during a tight development cycle",
+ "where frequent editing->run->editing sequences are
executed.",
+ "To edit a known eppic macro file use the -f option. To edit the
file",
+@@ -689,6 +699,10 @@ char *edit_help[]={
+ " %s> edit ps",
+ " %s> edit ps_opt",
+ " %s> edit -l",
++ "Oneshot run from main():",
++ " %s> edit -r myfile.c",
++ "Or:",
++ " %s> eppic myfile.c",
+ NULL
+ };
+
+@@ -885,6 +899,13 @@ char **help=malloc(sizeof *help * 5);
+ }
+ }
+ free(help);
++
++ if (load && !strcmp(name, "main")) {
++ int optind_save = optind;
++ eppic_cmd(name, NULL, 0);
++ optind = optind_save;
++ }
++
+ return;
+ }
+
+--- libeppic/eppic_func.c
++++ libeppic/eppic_func.c
+@@ -22,6 +22,8 @@
+ #include <sys/types.h>
+ #include <time.h>
+ #include <sys/stat.h>
++#include <fcntl.h>
++#include <unistd.h>
+ #include "eppic.h"
+
+ /*
+@@ -793,6 +795,37 @@ char *ed=getenv("EDITOR");
+ if(!system(buf)) eppic_load(fname);
+ }
+
++static const char *example[] = {
++"/* ",
++" * Example: Output all PIDs by eppic program. ",
++" * ",
++" * // Global variables and kernel data structures can be used directly. ",
++" * // If any are within kernel modules, should preload the .ko first via ",
++" * // \"mod -S/-s\" cmd in crash before invoke your eppic
program. ",
++" * ",
++" * int main(void) ",
++" * { ",
++" * struct task_struct *p; ",
++" * unsigned long offset; ",
++" * ",
++" * p = (struct task_struct *)&init_task; ",
++" * offset = (unsigned long)&(p->tasks) - (unsigned long)p; ",
++" * ",
++" * do { ",
++" * printf(\"PID: %d\\n\", (int)(p->pid)); ",
++" * p = (struct task_struct *)((unsigned long)(p->tasks.next) -
offset);",
++" * } while(p != &init_task); ",
++" * ",
++" * return 0; ",
++" * } ",
++" * ",
++" * crash> eppic file_name.c ",
++" * or ",
++" * crash> edit -r file_name.c ",
++" */ ",
++};
++
++char *eppic_get_func_file(char *);
+ /*
+ This funciton is called to start a vi session on a function
+ (file=0) or a file (file=1);
+@@ -800,24 +833,31 @@ char *ed=getenv("EDITOR");
+ void
+ eppic_vi(char *fname, int file)
+ {
+-int line, freeit=0;
++int line=1, freeit=0, fd;
+ char *filename;
++char newline = '\n';
+
+ if(file) {
+
+ filename=eppic_filempath(fname);
+
+ if(!filename) {
+-
+- eppic_msg("File not found : %s\n", fname);
+- return;
+-
+- }
+-
+- line=1;
+- freeit=1;
+-
+-
++ fd = creat(fname, 0644);
++ if (fd < 0) {
++ eppic_msg("File not found : %s\n", fname);
++ return;
++ } else {
++ for (int i = 0; i < sizeof(example)/sizeof(char *); i++) {
++ write(fd, example[i], strlen(example[i]));
++ write(fd, &newline, sizeof(newline));
++ }
++ close(fd);
++ filename = fname;
++ freeit=0;
++ }
++ } else {
++ freeit=1;
++ }
+ } else {
+
+ func *f=eppic_getfbyname(fname, 0);
+@@ -837,6 +877,10 @@ char *filename;
+
+ eppic_exevi(filename, line);
+
++ char *fi_name = eppic_get_func_file("main");
++ if (fi_name)
++ eppic_deletefile(fi_name);
++
+ if(freeit) eppic_free(filename);
+
+ }
+@@ -1184,3 +1228,10 @@ eppic_runcmd(char *fname, var_t*args)
+ return 0;
+ }
+
++char *eppic_get_func_file(char *funcname)
++{
++ func *fn = eppic_getfbyname(funcname, 0);
++ if (!fn)
++ return NULL;
++ return fn->file->fname;
++}
--
2.47.0