fixes makefile_cc breaks tranche ..
authorThomas Walker Lynch <thomas.lynch@reasoningtechnology.com>
Mon, 1 Apr 2019 12:58:30 +0000 (14:58 +0200)
committerThomas Walker Lynch <thomas.lynch@reasoningtechnology.com>
Mon, 1 Apr 2019 12:58:30 +0000 (14:58 +0200)
module/da/makefile
module/dispatch/dispatch.lib.c [new file with mode: 0644]
module/dispatch/dispatch.lib.h [new file with mode: 0644]
module/share/lib/libda.a
module/tranche/src/tranche-target.cli.c
module/tranche/src/tranche.lib.c
module/tranche/src/tranche.lib.h
tool/lib/makefile-cc

index 49d84f9..e3947d9 100644 (file)
@@ -8,7 +8,7 @@ MAKE=/usr/bin/make --no-print-directory -f $(PROJECT_SUBU)/tool/lib/makefile-cc
 -include makefile-flags
 
 .PHONY: all
-all: version dep lib exec
+all: version
 
 .PHONY: lib
 lib:
diff --git a/module/dispatch/dispatch.lib.c b/module/dispatch/dispatch.lib.c
new file mode 100644 (file)
index 0000000..c8303d4
--- /dev/null
@@ -0,0 +1,123 @@
+
+
+#include "dispatch.h"
+
+// we need the declaration for uid_t etc.
+// without this #define execvpe is undefined
+#define _GNU_SOURCE   
+
+#include <wait.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+
+void dispatch_f_mess(char *fname, int err, char *dispatchee){
+  if(err == 0) return;
+  fprintf(stderr, "%s: ", fname); // if fprintf gets an error, errno will be overwritten
+  if(err > ERR_DISPATCH){
+    fprintf(stderr, "dispatchee \"%s\" returned the error %d\n", dispatchee, err);
+    return;
+  }
+  switch(err){
+  case ERR_DISPATCH_NEGATIVE_RETURN_STATUS:
+    fprintf(stderr, " dispatchee \"%s\" returned a negative status.", dispatchee);
+    break;
+  case ERR_DISPATCH_F_FORK:
+  case ERR_DISPATCH_F_SETEUID:
+  case ERR_DISPATCH_F_SETEGID:
+    fputc(' ', stderr);
+    perror(dispatchee);
+    break;
+  case ERR_DISPATCH_NULL_EXECUTABLE:
+    fprintf(stderr, " executable was not specified");
+    break;
+  case ERR_DISPATCH_EXEC:
+    // exec is running in another process when it fails, so we can't see the errno value it set
+    fprintf(stderr, " exec of \"%s\" failed", dispatchee);
+    break;
+  default:
+    fprintf(stderr, " returned undefined status when dispatching \"%s\"", dispatchee);
+  }
+  fputc('\n', stderr);
+}
+
+//--------------------------------------------------------------------------------
+// interface call point, dispatch a function
+int dispatch_f(char *fname, int (*f)(void *arg), void *f_arg){
+  #ifdef DEBUG
+  dbprintf("%s %s\n", "dispatch_f", fname);
+  #endif
+  pid_t pid = fork();
+  if( pid == -1 ) return ERR_DISPATCH_F_FORK; // something went wrong and we are still in the parent process
+  if( pid == 0 ){ // we are the child
+    int status = (*f)(f_arg); // we require that f return a zero or positive value
+    if( status < ERR_DISPATCH ) status = ERR_DISPATCH_NEGATIVE_RETURN_STATUS;
+    exit(status);
+  }else{ // we are the parent
+    int err;
+    waitpid(pid, &err, 0);
+    return err;
+  }
+}
+
+//--------------------------------------------------------------------------------
+// interface call point, dispatch a function with a given euid/egid
+// of course this will only work if our euid is root in the first place
+int dispatch_f_euid_egid(char *fname, int (*f)(void *arg), void *f_arg, uid_t euid, gid_t egid){
+  #ifdef DEBUG
+  dbprintf("%s %s as euid:%u egid:%u\n", "dispatch_f_euid_egid", fname, euid, egid);
+  #endif
+  pid_t pid = fork();
+  if( pid == -1 ) return ERR_DISPATCH_F_FORK;
+  if( pid == 0 ){ // we are the child
+    int status;
+    if( seteuid(euid) == -1 )
+      status = ERR_DISPATCH_F_SETEUID;
+    else if( setegid(egid) == -1 )
+      status = ERR_DISPATCH_F_SETEGID;
+    else{
+      status = (*f)(f_arg);
+      if( status <= ERR_DISPATCH ) status = ERR_DISPATCH_NEGATIVE_RETURN_STATUS;
+      exit(status);
+    }
+  }else{ // we are the parent
+    uint err;
+    waitpid(pid, &err, 0);
+    return err;
+  }
+}
+
+//--------------------------------------------------------------------------------
+// interface call point, dispatch a executable
+int dispatch_exec(char **argv, char **envp){
+  char *command;
+  {
+    if( !argv || !argv[0] ) return ERR_DISPATCH_NULL_EXECUTABLE;
+    #ifdef DEBUG
+      dbprintf("dispatch_exec:");
+      char **apt = argv;
+      while( *apt ){
+        dbprintf(" %s",*apt);
+        apt++;
+      }
+      dbprintf("\n");
+    #endif
+    command = argv[0];
+  }
+  pid_t pid = fork();
+  if( pid == -1 ) return ERR_DISPATCH_F_FORK; // something went wrong and we are still in the parent process
+  if( pid == 0 ){ // we are the child
+    execvpe(command, argv, envp); // exec will only return if it has an error
+    #ifdef DEBUG
+    dbprintf("dispatch_exec: exec returned, perror message:");
+    perror("dispatch_exec"); // our only chance to print this message, as this is the child process
+    #endif
+    fflush(stdout);
+    exit(ERR_DISPATCH_EXEC); 
+  }else{ // we are the parent
+    int err;
+    waitpid(pid, &err, 0);
+    return err;
+  }
+}
+
diff --git a/module/dispatch/dispatch.lib.h b/module/dispatch/dispatch.lib.h
new file mode 100644 (file)
index 0000000..5e0994f
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+  Runs a command or function as its own process.
+
+  The return status integer from command or function must be greater than ERR_DISPATCH.
+  In the case of dispatch_exec, we only have a promise from the user to not dispatch
+  non compliant commands.
+
+*/
+#ifndef DISPATCH_LIB_H
+#define DISPATCH_LIB_H
+#include <sys/types.h>
+#include <unistd.h>
+
+#define ERR_DISPATCH -1024
+#define ERR_DISPATCH_NEGATIVE_RETURN_STATUS -1024
+#define ERR_DISPATCH_F_FORK -1025
+#define ERR_DISPATCH_F_SETEUID -1026
+#define ERR_DISPATCH_F_SETEGID -1027
+#define ERR_DISPATCH_NULL_EXECUTABLE -1028
+#define ERR_DISPATCH_EXEC -1029
+
+// currently both dispatcher and dispatchee strings are statically allocated
+struct dispatch_ctx{
+  char *dispatcher; // name of the dispatch function ("dispatch_f", "dispatch_f_euid_egid", etc.)
+  char *dispatchee; // name of the function being dispatched
+  int err; // error code as listed below, or status returned from dispatchee
+};
+void dispatch_f_mess(char *fname, int err, char *dispatchee);
+int dispatch_f(char *fname, int (*f)(void *arg), void *f_arg);
+int dispatch_f_euid_egid(char *fname, int (*f)(void *arg), void *f_arg, uid_t euid, gid_t egid);
+int dispatch_exec(char **argv, char **envp);
index a3da46e..7e790c4 100644 (file)
Binary files a/module/share/lib/libda.a and b/module/share/lib/libda.a differ
index c216534..52277b9 100644 (file)
@@ -21,6 +21,7 @@ int main(int argc, char **argv, char **envp){
 
   int err = 0;
   char *sep = 0;
+  char *tdir = 0;
   Da args; // we will queue the non option args here
   Da *argsp = &args; // collection of the non-option non-option-value args
   da_alloc(argsp, sizeof(char *));
@@ -55,6 +56,11 @@ int main(int argc, char **argv, char **envp){
           sep = value;
           goto endif;
         }
+        if( !strcmp(option, "tdir") ){
+          tdir = value;
+          path_trim_slashes(tdir);
+          goto endif;
+        }
         fprintf(stderr, "Unrecognized option %s.", option);
         err |= TRANCHE_ERR_ARG_PARSE;
         goto endif;
@@ -87,7 +93,7 @@ int main(int argc, char **argv, char **envp){
   char *src_file_path;
   FILE *src_file;
   if(da_emptyq(src_arrp))
-    tranche_target(stdin, target_arrp);
+    tranche_target(stdin, target_arrp, tdir);
   else{
     char *pt = src_arrp->base;
     while( pt < src_arrp->end ){
@@ -97,7 +103,7 @@ int main(int argc, char **argv, char **envp){
         fprintf(stderr,"Could not open source file %s.\n", src_file_path);
         err |= TRANCHE_ERR_SRC_OPEN;
       }else{
-        tranche_target(src_file, target_arrp);
+        tranche_target(src_file, target_arrp, tdir);
         if( fclose(src_file) == -1 ){perror(NULL); err |= TRANCHE_ERR_FCLOSE;}
       }
     pt += src_arrp->element_size;
index 412e950..71f2e33 100644 (file)
 //--------------------------------------------------------------------------------
 // parsing
 
+char sp = ' ';
+char colon = ':';
+char slash = '/';
 char newline = '\n';
+char tab = '\t';
 char terminator = 0;
 
+
 char tranche_begin_tag[] = "#tranche";
 size_t tranche_begin_tag_len = 8;
 
@@ -36,17 +41,23 @@ static char *is_tranche_end(char *pt){
   return pt + tranche_end_tag_len;
 }
 
-static bool parse_file_list(Da *file_names, char *pt0){
-  char *pt1;
+static void parse_file_list(Da *file_names, char *pt0, char *tdir){
+  Da filename_arr;
+  Da *fn_arrp = &filename_arr;
+  da_alloc(fn_arrp,sizeof(char));
+
   while( *pt0 && isspace(*pt0) ) pt0++;
-  pt1 = pt0;
-  while( *pt0 ){
-    while( *pt1 && !isspace(*pt1) ) pt1++;
-    char *file_name = strndup(pt0, pt1 - pt0);
-    da_push(file_names, &file_name);
-    while( *pt1 && isspace(*pt1) ) pt1++;
-    pt0 = pt1;
+  if(tdir){
+    da_string_push(fn_arrp, tdir);
+    da_push(fn_arrp, &slash);
   }
+  while( *pt0 && !isspace(*pt0) ){
+    da_push(fn_arrp, *pt0);
+  }
+  da_push(fn_arrp, &terminator);
+
+  char *file_name = strdup(*(char **)fn_arrp->base);
+  da_push(file_names, &file_name);
 }
 
 //--------------------------------------------------------------------------------
@@ -99,7 +110,7 @@ int tranche_send(FILE *src, Da *arg_fdap){
     if( is_tranche_end(line.base) ) break;
     pt = is_tranche_begin(line.base);
     if(pt){ // then this line is the start of a nested tranche block
-      parse_file_list(&file_name_arr, pt);
+      parse_file_list(&file_name_arr, pt, NULL);
       tranche_open_fds(&file_name_arr, &fda);
       da_free_elements(&file_name_arr);
       tranche_send(src, &fda);
@@ -123,7 +134,7 @@ int tranche_send(FILE *src, Da *arg_fdap){
 // returns a list of unique target file names from a tranche source
 
 // make a list of the unique tranche target files found in src
-int tranche_target(FILE *src, Da *target_arrp){
+int tranche_target(FILE *src, Da *target_arrp, char *tdir){
   char *pt;
   Da line; // buffer holding the characters from a line
   Da file_name_arr;// an array of file name parameters parsed from a #tranche line
@@ -134,7 +145,7 @@ int tranche_target(FILE *src, Da *target_arrp){
     if( is_tranche_end(line.base) ) break;
     pt = is_tranche_begin(line.base);
     if(pt){ // then this line is the start of a nested tranche block
-      parse_file_list(&file_name_arr, pt);
+      parse_file_list(&file_name_arr, pt, tdir);
       da_strings_set_union(target_arrp, &file_name_arr, free);
       da_rewind(&file_name_arr);
       tranche_target(src, target_arrp);
@@ -170,13 +181,6 @@ void tranche_make(FILE *src_file, char *src_name, int mfile_fd, char *tdir){
   da_alloc(tap, sizeof(char *));
   tranche_target(src_file, tap);
 
-  char sp = ' ';
-  char colon = ':';
-  char slash = '/';
-  char newline = '\n';
-  char tab = '\t';
-  char terminator = 0;
-
   // construct then output the dependency line ----------------------------------------
   Da dla;
   Da *dlap=&dla; // dependency line array pointer
index d40c074..7ec3720 100644 (file)
@@ -10,7 +10,7 @@
 
 void path_trim_slashes(char *path);
 int tranche_send(FILE *src, Da *arg_fds);
-int tranche_target(FILE *src, Da *targets);
+int tranche_target(FILE *src, Da *targets, char *tdir);
 void tranche_make(FILE *src_file, char *src_name, int mfile_fd, char *tdir);
 
 #endif
index 1265908..581b444 100755 (executable)
@@ -70,9 +70,11 @@ INCFILE=$(INCDIR)/$(MODULE).h
 # when local customizations set a TRCDIR, then these are the actual sources
 
 ifneq ($TRCDIR,)
-  TRCFILES= $(wildcard $(TRCDIR)/*.trc.c) $(wildcard $(TRCDIR)/*.trc.cc)
+  TRCSOURCES=$(wildcard $(TRCDIR)/*.trc.c)$(wildcard $(TRCDIR)/*.trc.cc)
+  TRCTARGETS=
 else
-  TRCFILES=
+  TRCSOURCES=
+  TRCTARGETS=
 endif
 
 
@@ -108,7 +110,7 @@ info:
        @echo "DEPFILE: " $(DEPFILE)
        @echo "LIBFILE: " $(LIBFILE)
        @echo "INCFILE: " $(INCFILE)
-       @echo "TRCFILES: " $(TRCFILES)
+       @echo "TRCSOURCES: " $(TRCSOURCES)
        @echo "C_SOURCE_LIB: " $(C_SOURCE_LIB)
        @echo "C_SOURCE_LIB: " $(C_SOURCE_LIB)
        @echo "C_SOURCE_CLI: " $(C_SOURCE_CLI)
@@ -140,9 +142,9 @@ setup:
 # gee this script could be better, particlarly in gathering the targets
 # it would be simplified if the tranche commands took multiple source arguments
 # if [ -e $(DEPFILE) ]; then rm $(DEPFILE); fi
-# if [ ! -z "$(TRCFILES)" ]; then\
+# if [ ! -z "$(TRCSOURCES)" ]; then\
 #   targets="";\
-#   for i in $(TRCFILES); do\
+#   for i in $(TRCSOURCES); do\
 #     tranche-make $$i -tdir $(SRCDIR) -mfile $(DEPFILE);\
 #     targets+=$$(tranche-target $$i);\
 #     targets+=" ";\
@@ -154,13 +156,20 @@ setup:
 .PHONY: dep
 dep:
        if [ -e $(DEPFILE) ]; then rm $(DEPFILE); fi
-       if [ ! -z "$(TRCFILES)" ]; then\
-         tranche-make $(TRCFILES) -mfile $(DEPFILE);\
-         $(MAKE) $(shell tranche-targets $(TRCFILES) -sep " ");\
-       fi       
-       if [ -z "$(CC)" ]; then\
+ifneq ($(TRCDIR),)
+       $(ECHO) TRC deps
+       @trcsources=$(wildcard $(TRCDIR)/*.trc.c)$(wildcard $(TRCDIR)/*.trc.cc);\
+       $(ECHO) $$trcsources;\
+       if [ ! -z "$$trcsources" ]; then\
+         trctargets=$$(tranche-target $$trcsources -sep " ");\
+         echo $$trctargets;\
+         tranche-make $$trcsources -tdir $(SRCDIR) -mfile $(DEPFILE);\
+         $(MAKE) $$trctargets;\
+       fi
+endif
+       @if [ -z "$(CC)" ]; then\
          if [ -z "$C()" ]; then\
-           echo "No compiler specified";\
+           $(ECHO) "No compiler specified";\
            exit 1;\
          else\
            echo "C compiler only deps" ;\