diff options
| author | Joseph Hunkeler <jhunkeler@gmail.com> | 2024-05-20 10:07:16 -0400 | 
|---|---|---|
| committer | Joseph Hunkeler <jhunkeler@gmail.com> | 2024-05-20 10:11:29 -0400 | 
| commit | 67975a5944706e382fe1e7b00d226715c6242358 (patch) | |
| tree | e93dd37df57f49d4327567479521014f380206e5 /src | |
| parent | 30c9945e0da19305ebad88a2835653ff4f409313 (diff) | |
| download | ohmycal-67975a5944706e382fe1e7b00d226715c6242358.tar.gz | |
Mass attempt at windows portability
Diffstat (limited to 'src')
| -rw-r--r-- | src/copy.c | 17 | ||||
| -rw-r--r-- | src/deliverable.c | 148 | ||||
| -rw-r--r-- | src/docker.c | 16 | ||||
| -rw-r--r-- | src/main.c | 0 | ||||
| -rw-r--r-- | src/omc_main.c | 2 | ||||
| -rw-r--r-- | src/str.c | 13 | ||||
| -rw-r--r-- | src/system.c | 80 | ||||
| -rw-r--r-- | src/utils.c | 67 | 
8 files changed, 284 insertions, 59 deletions
@@ -26,6 +26,7 @@ int copy2(const char *src, const char *dest, unsigned int op) {      }      stat(dname, &dnamest); +#if ! defined(OMC_OS_WINDOWS)      if (S_ISLNK(src_stat.st_mode)) {          char lpath[1024] = {0};          if (readlink(src, lpath, sizeof(lpath)) < 0) { @@ -46,7 +47,9 @@ int copy2(const char *src, const char *dest, unsigned int op) {              perror(src);              return -1;          } -    } else if (S_ISREG(src_stat.st_mode)) { +    } else +#endif +    if (S_ISREG(src_stat.st_mode)) {          fp1 = fopen(src, "rb");          if (!fp1) {              perror(src); @@ -67,13 +70,15 @@ int copy2(const char *src, const char *dest, unsigned int op) {          fclose(fp2);          if (bytes_written != (size_t) src_stat.st_size) { -            fprintf(stderr, "%s: SHORT WRITE (expected %zu bytes, but wrote %zu bytes)\n", dest, src_stat.st_size, bytes_written); +            fprintf(stderr, "%s: SHORT WRITE (expected %li bytes, but wrote %zu bytes)\n", dest, src_stat.st_size, bytes_written);              return -1;          } +#if !defined(OMC_OS_WINDOWS)          if (op & CT_OWNER && chown(dest, src_stat.st_uid, src_stat.st_gid) < 0) {              perror(dest);          } +#endif          if (op & CT_PERM && chmod(dest, src_stat.st_mode) < 0) {              perror(dest); @@ -173,7 +178,13 @@ int copytree(const char *srcdir, const char *destdir, unsigned int op) {              return -1;          } -        if (d->d_type == DT_DIR) { +        int is_dir = 0; +#if defined (OMC_OS_WINDOWS) +        is_dir = S_ISDIR(st.st_mode); +#else +        is_dir = DT_DIR == rec->d_type; +#endif +        if (is_dir) {              if (strncmp(src, dest, strlen(src)) == 0) {                  closedir(dir);                  return -1; diff --git a/src/deliverable.c b/src/deliverable.c index f72f535..88c42a5 100644 --- a/src/deliverable.c +++ b/src/deliverable.c @@ -1,9 +1,14 @@  #define _GNU_SOURCE -#include <fnmatch.h>  #include "omc.h" - -extern struct OMC_GLOBAL globals; +#if !defined(OMC_OS_WINDOWS) +#include <fnmatch.h> +#include <sys/statvfs.h> +#endif +#include "deliverable.h" +#include "str.h" +#include "strlist.h" +#include "copy.h"  static void ini_has_key_required(struct INIFILE *ini, const char *section_name, char *key) {      int status = ini_has_key(ini, section_name, key); @@ -98,6 +103,7 @@ int delivery_init_tmpdir(struct Delivery *ctx) {          goto l_delivery_init_tmpdir_fatal;      } +#if !defined(OMC_OS_WINDOWS)      struct statvfs st;      if (statvfs(tmpdir, &st) < 0) {          goto l_delivery_init_tmpdir_fatal; @@ -114,6 +120,7 @@ int delivery_init_tmpdir(struct Delivery *ctx) {          msg(OMC_MSG_ERROR | OMC_MSG_L1, "%s is mounted read-only\n", tmpdir);          goto l_delivery_init_tmpdir_fatal;      } +#endif      if (!globals.tmpdir) {          globals.tmpdir = strdup(tmpdir); @@ -140,7 +147,7 @@ void delivery_free(struct Delivery *ctx) {      guard_free(ctx->meta.mission);      guard_free(ctx->meta.python_compact);      guard_free(ctx->meta.based_on); -    guard_runtime_free(ctx->runtime.environ); +    guard_runtime_free(ctx->runtime.env);      guard_free(ctx->storage.root);      guard_free(ctx->storage.tmpdir);      guard_free(ctx->storage.delivery_dir); @@ -189,7 +196,7 @@ void delivery_free(struct Delivery *ctx) {          guard_free(ctx->tests[i].script);          guard_free(ctx->tests[i].build_recipe);          // test-specific runtime variables -        guard_runtime_free(ctx->tests[i].runtime.environ); +        guard_runtime_free(ctx->tests[i].runtime.env);      }      guard_free(ctx->rules.release_fmt); @@ -304,11 +311,6 @@ void delivery_init_dirs_stage1(struct Delivery *ctx) {  int delivery_init_platform(struct Delivery *ctx) {      msg(OMC_MSG_L2, "Setting architecture\n");      char archsuffix[20]; -    struct utsname uts; -    if (uname(&uts)) { -        msg(OMC_MSG_ERROR | OMC_MSG_L2, "uname() failed: %s\n", strerror(errno)); -        return -1; -    }      ctx->system.platform = calloc(DELIVERY_PLATFORM_MAX + 1, sizeof(*ctx->system.platform));      if (!ctx->system.platform) { @@ -319,6 +321,35 @@ int delivery_init_platform(struct Delivery *ctx) {          ctx->system.platform[i] = calloc(DELIVERY_PLATFORM_MAXLEN, sizeof(*ctx->system.platform[0]));      } +#if !defined(OMC_OS_WINDOWS) +    struct utsname uts; +    if (uname(&uts)) { +        msg(OMC_MSG_ERROR | OMC_MSG_L2, "uname() failed: %s\n", strerror(errno)); +        return -1; +    } +#else +#include <sysinfoapi.h> +    struct utsname { +        char machine[65]; +        char sysname[MAX_COMPUTERNAME_LENGTH + 1]; +    } uts; +    SYSTEM_INFO si; +    GetSystemInfo(&si); +    switch (si.wProcessorArchitecture) { +        case PROCESSOR_ARCHITECTURE_AMD64: +            strcpy(uts.machine, "x86_64"); +            break; +        case PROCESSOR_ARCHITECTURE_ARM64: +            strcpy(uts.machine, "arm64"); +            break; +        default: +            strcpy(uts.machine, "unknown"); +            break; +    } +    unsigned long maxlen = MAX_COMPUTERNAME_LENGTH; +    GetComputerNameA(uts.sysname, &maxlen); +#endif +      ctx->system.arch = strdup(uts.machine);      if (!ctx->system.arch) {          // memory error @@ -469,7 +500,7 @@ static int populate_delivery_ini(struct Delivery *ctx) {          runtime_set(rt, rtdata->key, rtdata->value);      }      runtime_apply(rt); -    ctx->runtime.environ = rt; +    ctx->runtime.env = rt;      ini_getval_required(ini, "meta", "mission", INIVAL_TYPE_STR, &val);      conv_str(&ctx->meta.mission, val); @@ -604,7 +635,7 @@ static int populate_delivery_ini(struct Delivery *ctx) {              conv_str(&ctx->tests[z].build_recipe, val);              ini_getval(ini, ini->section[i]->key, "runtime", INIVAL_TO_LIST, &val); -            conv_strlist(&ctx->tests[z].runtime.environ, LINE_SEP, val); +            conv_strlist(&ctx->tests[z].runtime.env, LINE_SEP, val);              z++;          }      } @@ -963,7 +994,7 @@ void delivery_tests_show(struct Delivery *ctx) {  void delivery_runtime_show(struct Delivery *ctx) {      printf("\n====RUNTIME====\n");      struct StrList *rt = NULL; -    rt = strlist_copy(ctx->runtime.environ); +    rt = strlist_copy(ctx->runtime.env);      if (!rt) {          // no data          return; @@ -1063,7 +1094,8 @@ static int filter_repo_tags(char *repo, struct StrList *patterns) {              char *tag = strlist_item(tags, i);              for (size_t p = 0; p < strlist_count(patterns); p++) {                  char *pattern = strlist_item(patterns, p); -                int match = fnmatch(pattern, tag, 0); +                //int match = fnmatch(pattern, tag, 0); +                int match = 0; // TODO fnmatch                  if (!match) {                      char cmd[PATH_MAX] = {0};                      sprintf(cmd, "git tag -d %s", tag); @@ -1159,7 +1191,7 @@ int delivery_install_packages(struct Delivery *ctx, char *conda_install_dir, cha              // Activate the requested environment              printf("Activating: %s\n", env_name);              conda_activate(conda_install_dir, env_name); -            runtime_replace(&ctx->runtime.environ, __environ); +            runtime_replace(&ctx->runtime.env, __environ);          }      } @@ -1318,50 +1350,60 @@ int delivery_index_wheel_artifacts(struct Delivery *ctx) {      }      while ((rec = readdir(dp)) != NULL) { -        // skip directories -        if (DT_REG == rec->d_type || !strcmp(rec->d_name, "..") || !strcmp(rec->d_name, ".")) { +        unsigned is_dir = 0; +#if defined(OMC_OS_WINDOWS) +        struct stat st; +        if (stat(rec->d_name, &st)) { +            perror(rec->d_name);              continue;          } +        is_dir = S_ISDIR(st.st_mode); +#else +        is_dir = DT_DIR == rec->d_type; +#endif +        // skip directories +        if (is_dir || !endswith(rec->d_name, ".whl")) { + +            FILE *bottom_fp; +            char bottom_index[PATH_MAX * 2]; +            memset(bottom_index, 0, sizeof(bottom_index)); +            sprintf(bottom_index, "%s/%s/index.html", ctx->storage.wheel_artifact_dir, rec->d_name); +            bottom_fp = fopen(bottom_index, "w+"); +            if (!bottom_fp) { +                return -3; +            } -        FILE *bottom_fp; -        char bottom_index[PATH_MAX * 2]; -        memset(bottom_index, 0, sizeof(bottom_index)); -        sprintf(bottom_index, "%s/%s/index.html", ctx->storage.wheel_artifact_dir, rec->d_name); -        bottom_fp = fopen(bottom_index, "w+"); -        if (!bottom_fp) { -            return -3; -        } - -        if (globals.verbose) { -            printf("+ %s\n", rec->d_name); -        } -        // Add record to top level index -        fprintf(top_fp, "<a href=\"%s/\">%s</a><br/>\n", rec->d_name, rec->d_name); +            if (globals.verbose) { +                printf("+ %s\n", rec->d_name); +            } +            // Add record to top level index +            fprintf(top_fp, "<a href=\"%s/\">%s</a><br/>\n", rec->d_name, rec->d_name); + +            char dpath[PATH_MAX * 2]; +            memset(dpath, 0, sizeof(dpath)); +            sprintf(dpath, "%s/%s", ctx->storage.wheel_artifact_dir, rec->d_name); +            struct StrList *packages = listdir(dpath); +            if (!packages) { +                fclose(top_fp); +                fclose(bottom_fp); +                return -4; +            } -        char dpath[PATH_MAX * 2]; -        memset(dpath, 0, sizeof(dpath)); -        sprintf(dpath, "%s/%s", ctx->storage.wheel_artifact_dir, rec->d_name); -        struct StrList *packages = listdir(dpath); -        if (!packages) { -            fclose(top_fp); +            for (size_t i = 0; i < strlist_count(packages); i++) { +                char *package = strlist_item(packages, i); +                if (!endswith(package, ".whl")) { +                    continue; +                } +                if (globals.verbose) { +                    printf("`- %s\n", package); +                } +                // Write record to bottom level index +                fprintf(bottom_fp, "<a href=\"%s\">%s</a><br/>\n", package, package); +            }              fclose(bottom_fp); -            return -4; -        } -        for (size_t i = 0; i < strlist_count(packages); i++) { -            char *package = strlist_item(packages, i); -            if (!endswith(package, ".whl")) { -                continue; -            } -            if (globals.verbose) { -                printf("`- %s\n", package); -            } -            // Write record to bottom level index -            fprintf(bottom_fp, "<a href=\"%s\">%s</a><br/>\n", package, package); +            guard_strlist_free(&packages);          } -        fclose(bottom_fp); - -        guard_strlist_free(&packages);      }      closedir(dp);      fclose(top_fp); @@ -1409,7 +1451,7 @@ void delivery_conda_enable(struct Delivery *ctx, char *conda_install_dir) {      char rcpath[PATH_MAX];      sprintf(rcpath, "%s/%s", conda_install_dir, ".condarc");      setenv("CONDARC", rcpath, 1); -    if (runtime_replace(&ctx->runtime.environ, __environ)) { +    if (runtime_replace(&ctx->runtime.env, __environ)) {          perror("unable to replace runtime environment after activating conda");          exit(1);      } diff --git a/src/docker.c b/src/docker.c index f8c9c11..872e06a 100644 --- a/src/docker.c +++ b/src/docker.c @@ -36,7 +36,20 @@ int docker_script(const char *image, char *data, unsigned flags) {          return -1;      } +#if defined(OMC_OS_WINDOWS) +    char tempfile[PATH_MAX]; +    strcpy(tempfile, "OMC.docker.XXXXXX"); +    if (mkstemp(tempfile)) { +        // creating temp file failed +        return -1; +    } +    infile = fopen(tempfile, "w"); +    for (size_t i = 0; i < strlen(data); i++) { +        fputc(data[i], infile); +    } +#else      infile = fmemopen(data, strlen(data), "r"); +#endif      if (!infile) {          // opening memory file for reading failed          return -1; @@ -49,6 +62,9 @@ int docker_script(const char *image, char *data, unsigned flags) {      } while (!feof(infile));      fclose(infile); +#if defined(OMC_OS_WINDOWS) +    remove(tempfile); +#endif      return pclose(outfile);  } diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/main.c diff --git a/src/omc_main.c b/src/omc_main.c index 90460ee..e229453 100644 --- a/src/omc_main.c +++ b/src/omc_main.c @@ -331,7 +331,7 @@ int main(int argc, char *argv[]) {          exit(1);      } -    runtime_apply(ctx.runtime.environ); +    runtime_apply(ctx.runtime.env);      strcpy(env_name, ctx.info.release_name);      strcpy(env_name_testing, env_name);      strcat(env_name_testing, "-test"); @@ -2,7 +2,18 @@   * @file strings.c   */  #include <unistd.h> -#include "str.h" +#include "omc.h" + +#if defined(OMC_OS_WINDOWS) +char *strsep(char **str, const char *delim) { +    static char *last; +    return strtok_r(*str, delim, &last); +} + +char *strndup(const char *str, size_t nelem) { +    return calloc(nelem, sizeof(*str)); +} +#endif  int num_chars(const char *sptr, int ch) {      int result = 0; diff --git a/src/system.c b/src/system.c index ca2da97..895ed8a 100644 --- a/src/system.c +++ b/src/system.c @@ -5,6 +5,85 @@  #include "system.h"  #include "omc.h" +#if defined(OMC_OS_WINDOWS) +int shell(struct Process *proc, char *args) { +    char cmd[OMC_BUFSIZ]; +    memset(cmd, 0, sizeof(cmd)); +    strcat(cmd, args); +    return system(cmd); +} +#else +int shell(struct Process *proc, char *args[]) { +    FILE *fp_out, *fp_err; +    pid_t pid; +    pid_t status; +    status = 0; +    errno = 0; + +    pid = fork(); +    if (pid == -1) { +        fprintf(stderr, "fork failed\n"); +        exit(1); +    } else if (pid == 0) { +        int retval; +        if (proc != NULL) { +            if (strlen(proc->standard_output)) { +                fp_out = freopen(proc->standard_output, "w+", stdout); +            } + +            if (strlen(proc->standard_error)) { +                fp_err = freopen(proc->standard_error, "w+", stderr); +            } + +            if (proc->redirect_stderr) { +                if (fp_err) { +                    fclose(fp_err); +                    fclose(stderr); +                } +                dup2(fileno(stdout), fileno(stderr)); +            } +        } + +        retval = execv(args[0], args); +        fprintf(stderr, "# executing: "); +        for (size_t x = 0; args[x] != NULL; x++) { +            fprintf(stderr, "%s ", args[x]); +        } + +        if (proc != NULL && strlen(proc->standard_output)) { +            fflush(fp_out); +            fclose(fp_out); +            fflush(stdout); +            fclose(stdout); +        } +        if (proc != NULL && strlen(proc->standard_error)) { +            fflush(fp_err); +            fclose(fp_err); +            fflush(stderr); +            fclose(stderr); +        } +        exit(retval); +    } else { +        if (waitpid(pid, &status, WUNTRACED) > 0) { +            if (WIFEXITED(status) && WEXITSTATUS(status)) { +                if (WEXITSTATUS(status) == 127) { +                    fprintf(stderr, "execv failed\n"); +                } +            } else if (WIFSIGNALED(status))  { +                fprintf(stderr, "signal received: %d\n", WIFSIGNALED(status)); +            } +        } else { +            fprintf(stderr, "waitpid() failed\n"); +        } +    } + + +    if (proc != NULL) { +        proc->returncode = status; +    } +    return WEXITSTATUS(status); +} +  int shell(struct Process *proc, char *args) {      FILE *fp_out = NULL;      FILE *fp_err = NULL; @@ -96,6 +175,7 @@ int shell(struct Process *proc, char *args) {      guard_free(t_name);      return WEXITSTATUS(status);  } +#endif  int shell_safe(struct Process *proc, char *args) {      FILE *fp; diff --git a/src/utils.c b/src/utils.c index ea79f10..c62af08 100644 --- a/src/utils.c +++ b/src/utils.c @@ -52,8 +52,16 @@ int rmtree(char *_path) {              continue;          } +        int is_dir = 0; +#if defined(OMC_OS_WINDOWS) +        struct stat st; +        stat(d_entity->d_name, &st); +        is_dir = S_ISDIR(st.st_mode); +#else +        is_dir = DT_DIR == rec->d_type; +#endif          // Push directories on to the stack first -        if (d_entity->d_type == DT_DIR) { +        if (is_dir) {              rmtree(abspath);          } else {              remove(abspath); @@ -385,12 +393,21 @@ char *git_rev_parse(const char *path, char *args) {      return version;  } +#if defined(OMC_OS_WINDOWS) +#define OMC_COLOR_RED "" +#define OMC_COLOR_GREEN "" +#define OMC_COLOR_YELLOW "" +#define OMC_COLOR_BLUE "" +#define OMC_COLOR_WHITE "" +#define OMC_COLOR_RESET "" +#else  #define OMC_COLOR_RED "\e[1;91m"  #define OMC_COLOR_GREEN "\e[1;92m"  #define OMC_COLOR_YELLOW "\e[1;93m"  #define OMC_COLOR_BLUE "\e[1;94m"  #define OMC_COLOR_WHITE "\e[1;97m"  #define OMC_COLOR_RESET "\e[0;37m\e[0m" +#endif  void msg(unsigned type, char *fmt, ...) {      FILE *stream = NULL; @@ -763,3 +780,51 @@ struct StrList *listdir(const char *path) {      return node;  } +#if defined(OMC_OS_WINDOWS) +char *realpath(const char *path, char **dest) { +    char cwd_start[PATH_MAX] = {0}; +    char cwd[PATH_MAX] = {0}; +    char where[PATH_MAX] = {0}; +    char bname[PATH_MAX] = {0}; +    char *w = where; +    getcwd(cwd_start, sizeof(cwd) - 1); +    strcpy(w, path); +    w = path_dirname(w); +    if (chdir(w)) { +        getcwd(cwd, sizeof(cwd) - 1); +        path_basename(bname); +        strcat(cwd, bname); +        chdir(cwd_start); +    } + +    char *result; +    result = strdup(cwd); +    if (!result) { +        return NULL; +    } + +    if (dest) { +        *dest = result; +    } + +    return result; +} + +int setenv(const char *key, const char *value, int overwrite) { +    size_t len = 0; +    char *data = NULL; +    len = strlen(key) + strlen(value) + 2; +    data = calloc(len, sizeof(*data)); +    if (!data) { +        return -1; +    } +    sprintf(data, "%s=%s", key, value); +    if (_putenv(data)) { +        free(data); +        return 1; +    } + +    free(data); +    return 0; +} +#endif  | 
