From: Thomas Walker Lynch Date: Mon, 1 Apr 2019 12:58:30 +0000 (+0200) Subject: fixes makefile_cc breaks tranche .. X-Git-Url: https://git.reasoningtechnology.com/style/static/gitweb.css?a=commitdiff_plain;h=b52d081653b3b2f078115f74c6d2e9c66a51677a;p=subu fixes makefile_cc breaks tranche .. --- diff --git a/module/da/makefile b/module/da/makefile index 49d84f9..e3947d9 100644 --- a/module/da/makefile +++ b/module/da/makefile @@ -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 index 0000000..c8303d4 --- /dev/null +++ b/module/dispatch/dispatch.lib.c @@ -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 +#include +#include +#include + +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 index 0000000..5e0994f --- /dev/null +++ b/module/dispatch/dispatch.lib.h @@ -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 +#include + +#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); diff --git a/module/share/lib/libda.a b/module/share/lib/libda.a index a3da46e..7e790c4 100644 Binary files a/module/share/lib/libda.a and b/module/share/lib/libda.a differ diff --git a/module/tranche/src/tranche-target.cli.c b/module/tranche/src/tranche-target.cli.c index c216534..52277b9 100644 --- a/module/tranche/src/tranche-target.cli.c +++ b/module/tranche/src/tranche-target.cli.c @@ -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; diff --git a/module/tranche/src/tranche.lib.c b/module/tranche/src/tranche.lib.c index 412e950..71f2e33 100644 --- a/module/tranche/src/tranche.lib.c +++ b/module/tranche/src/tranche.lib.c @@ -11,9 +11,14 @@ //-------------------------------------------------------------------------------- // 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 diff --git a/module/tranche/src/tranche.lib.h b/module/tranche/src/tranche.lib.h index d40c074..7ec3720 100644 --- a/module/tranche/src/tranche.lib.h +++ b/module/tranche/src/tranche.lib.h @@ -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 diff --git a/tool/lib/makefile-cc b/tool/lib/makefile-cc index 1265908..581b444 100755 --- a/tool/lib/makefile-cc +++ b/tool/lib/makefile-cc @@ -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" ;\