static char* get_default_emulator(char* progname) { char sbuf[MAXPATHLEN]; char* s; if (strlen(progname) >= sizeof(sbuf)) return ERL_NAME; strcpy(sbuf, progname); for (s = sbuf+strlen(sbuf); s >= sbuf; s--) { if (IS_DIRSEP(*s)) { strcpy(s+1, ERL_NAME); #ifdef __WIN32__ if (_access(sbuf, 0) != -1) { return strsave(sbuf); } #else if (access(sbuf, 1) != -1) { return strsave(sbuf); } #endif break; } } return ERL_NAME; }
/* extract the basename of a file */ PUB_FUNC char *tcc_basename(const char *name) { char *p = strchr (name, 0); while (p && p > name && !IS_DIRSEP (p[-1])) --p; return p; }
static char* get_default_emulator(char* progname) { char sbuf[MAXPATHLEN]; char* s; if (strlen(progname) >= sizeof(sbuf)) return ERL_NAME; strcpy(sbuf, progname); for (s = sbuf+strlen(sbuf); s >= sbuf; s--) { if (IS_DIRSEP(*s)) { strcpy(s+1, ERL_NAME); if(file_exists(sbuf)) return strsave(sbuf); break; } } return ERL_NAME; }
int list_dir_internal(stralloc* dir, char type) { size_t l; struct dir_s d; stralloc pre; int dtype; int is_dir, is_symlink; size_t len; #if !WINDOWS_NATIVE struct stat st; static dev_t root_dev; #endif char *name, *s; (void)type; while(dir->len > 1 && IS_DIRSEP(dir->s[dir->len - 1])) dir->len--; stralloc_nul(dir); #if !WINDOWS_NATIVE if(root_dev == 0) { if(stat(dir->s, &st) != -1) { root_dev = st.st_dev; } } #endif if(dir_open(&d, dir->s) != 0) { buffer_puts(buffer_2, "ERROR: Opening directory "); buffer_putsa(buffer_2, dir); buffer_puts(buffer_2, " failed!\n"); buffer_flush(buffer_2); goto end; } if(dir->s[dir->len - 1] != DIRSEP_C) stralloc_cats(dir, DIRSEP_S); l = dir->len; while((name = dir_read(&d))) { unsigned int mode = 0, nlink = 0, uid = 0, gid = 0; uint64 size = 0, mtime = 0; dtype = dir_type(&d); dir->len = l; if(str_equal(name, "") || str_equal(name, ".") || str_equal(name, "..")) { continue; } stralloc_readyplus(dir, str_len(name) + 1); str_copy(dir->s + dir->len, name); dir->len += str_len(name); is_symlink = !!(dtype & D_SYMLINK); #if !WINDOWS_NATIVE if(!opt_deref && lstat(dir->s, &st) != -1) { if(root_dev && st.st_dev) { if(st.st_dev != root_dev) { continue; } } } #endif #if !WINDOWS_NATIVE if(S_ISLNK(st.st_mode)) { stat(dir->s, &st); } mode = st.st_mode; #endif if(dtype) { is_dir = !!(dtype & D_DIRECTORY); } else { #if WINDOWS_NATIVE is_dir = 0; #else is_dir = !!S_ISDIR(mode); #endif } if(dtype & D_SYMLINK) is_symlink = 1; #if !WINDOWS_NATIVE nlink = st.st_nlink; uid = st.st_uid; gid = st.st_gid; size = st.st_size; mtime = st.st_mtime; #else mode = (is_dir ? 0040000 : 0100000) | (is_symlink ? 0120000 : 0); #if USE_READDIR if(!is_dir) { size = dir_size(&d); /* dir_INTERNAL(&d)->dir_entry->d_name); */ mtime = dir_time(&d); } else { mtime = 0; size = 0; } #else size = dir_size(&d); mtime = dir_time(&d, D_TIME_MODIFICATION); #endif #endif if(opt_list && size >= opt_minsize) { stralloc_init(&pre); /* Mode string */ mode_str(&pre, mode); stralloc_catb(&pre, " ", 1); /* num links */ make_num(&pre, nlink, 3); stralloc_catb(&pre, " ", 1); /* uid */ make_num(&pre, uid, 0); stralloc_catb(&pre, " ", 1); /* gid */ make_num(&pre, gid, 0); stralloc_catb(&pre, " ", 1); /* size */ make_num(&pre, size, 6); stralloc_catb(&pre, " ", 1); /* time */ make_num(&pre, mtime, 0); /* make_time(&pre, mtime, 10); */ stralloc_catb(&pre, " ", 1); } /* fprintf(stderr, "%d %08x\n", is_dir, dir_ATTRS(&d)); */ if(is_dir) stralloc_catc(dir, opt_separator); if(dir->len > MAX_PATH) { buffer_puts(buffer_2, "ERROR: Directory "); buffer_putsa(buffer_2, dir); buffer_puts(buffer_2, " longer than MAX_PATH (" STRINGIFY(MAX_PATH) ")!\n"); /*buffer_putulong(buffer_2, MAX_PATH); buffer_puts(buffer_2, ")!\n");*/ buffer_flush(buffer_2); goto end; } s = dir->s; len = dir->len; if(len >= 2 && s[0] == '.' && IS_DIRSEP(s[1])) { len -= 2; s += 2; } if(opt_list && size >= opt_minsize) buffer_putsa(buffer_1, &pre); if(opt_relative_to) { size_t sz = str_len(opt_relative_to); if(str_diffn(s, opt_relative_to, sz) == 0) { s += sz; len -= sz; while(*s == '\\' || *s == '/') { s++; len--; } } } if(size >= opt_minsize) { buffer_put(buffer_1, s, len); buffer_put(buffer_1, "\n", 1); buffer_flush(buffer_1); } if(is_dir && (opt_deref || !is_symlink)) { dir->len--; list_dir_internal(dir, 0); } } end: dir_close(&d); return 0; }
int main(int argc, char** argv) { int eargv_size; int eargc_base; /* How many arguments in the base of eargv. */ char* emulator; char* env; char* basename; char* absname; char scriptname[PMAX]; char** last_opt; char** first_opt; emulator = env = get_env("ESCRIPT_EMULATOR"); if (emulator == NULL) { emulator = get_default_emulator(argv[0]); } if (strlen(emulator) >= PMAX) error("Value of environment variable ESCRIPT_EMULATOR is too large"); /* * Allocate the argv vector to be used for arguments to Erlang. * Arrange for starting to pushing information in the middle of * the array, to allow easy addition of commands in the beginning. */ eargv_size = argc*4+1000+LINEBUFSZ/2; eargv_base = (char **) emalloc(eargv_size*sizeof(char*)); eargv = eargv_base; eargc = 0; push_words(emulator); eargc_base = eargc; eargv = eargv + eargv_size/2; eargc = 0; free_env_val(env); /* * Push initial arguments. */ PUSH("+B"); PUSH2("-boot", "start_clean"); PUSH("-noshell"); /* Determine basename of the executable */ for (basename = argv[0]+strlen(argv[0]); basename > argv[0] && !(IS_DIRSEP(basename[-1])); --basename) ; first_opt = argv; last_opt = argv; #ifdef __WIN32__ if ( (_stricmp(basename, "escript.exe") == 0) ||(_stricmp(basename, "escript") == 0)) { #else if (strcmp(basename, "escript") == 0) { #endif /* * Locate all options before the script name. */ while (argc > 1 && argv[1][0] == '-') { argc--; argv++; last_opt = argv; } if (argc <= 1) { error("Missing filename\n"); } strncpy(scriptname, argv[1], sizeof(scriptname)); scriptname[sizeof(scriptname)-1] = '\0'; argc--; argv++; } else { #ifdef __WIN32__ int len; #endif absname = find_prog(argv[0]); #ifdef __WIN32__ len = strlen(absname); if (len >= 4 && _stricmp(absname+len-4, ".exe") == 0) { absname[len-4] = '\0'; } #endif erts_snprintf(scriptname, sizeof(scriptname), "%s.escript", absname); efree(absname); } /* * Read options from the %%! row in the script and add them as args */ append_shebang_args(scriptname); /* * Push the script name and everything following it as extra arguments. */ PUSH3("-run", "escript", "start"); /* * Push all options before the script name. But omit the leading hyphens. */ while (first_opt != last_opt) { PUSH(first_opt[1]+1); first_opt++; } PUSH("-extra"); PUSH(scriptname); while (argc > 1) { PUSH(argv[1]); argc--, argv++; } /* * Move up the commands for invoking the emulator and adjust eargv * accordingly. */ while (--eargc_base >= 0) { UNSHIFT(eargv_base[eargc_base]); } /* * Invoke Erlang with the collected options. */ PUSH(NULL); return run_erlang(eargv[0], eargv); } static void push_words(char* src) { char sbuf[PMAX]; char* dst; dst = sbuf; while ((*dst++ = *src++) != '\0') { if (isspace((int)*src)) { *dst = '\0'; PUSH(strsave(sbuf)); dst = sbuf; do { src++; } while (isspace((int)*src)); } } if (sbuf[0]) PUSH(strsave(sbuf)); }
int wmain(int argc, wchar_t **wcargv) { char** argv; #else int main(int argc, char** argv) { #endif int eargv_size; int eargc_base; /* How many arguments in the base of eargv. */ char* emulator; char* basename; char* def_emu_lookup_path; char scriptname[PMAX]; char** last_opt; char** first_opt; #ifdef __WIN32__ int i; int len; /* Convert argv to utf8 */ argv = emalloc((argc+1) * sizeof(char*)); for (i=0; i<argc; i++) { len = WideCharToMultiByte(CP_UTF8, 0, wcargv[i], -1, NULL, 0, NULL, NULL); argv[i] = emalloc(len*sizeof(char)); WideCharToMultiByte(CP_UTF8, 0, wcargv[i], -1, argv[i], len, NULL, NULL); } argv[argc] = NULL; #endif /* * Allocate the argv vector to be used for arguments to Erlang. * Arrange for starting to pushing information in the middle of * the array, to allow easy addition of commands in the beginning. */ eargv_size = argc*4+1000+LINEBUFSZ/2; eargv_base = (char **) emalloc(eargv_size*sizeof(char*)); eargv = eargv_base; eargc = 0; eargc_base = eargc; eargv = eargv + eargv_size/2; eargc = 0; /* Determine basename of the executable */ for (basename = argv[0]+strlen(argv[0]); basename > argv[0] && !(IS_DIRSEP(basename[-1])); --basename) ; first_opt = argv; last_opt = argv; #ifdef __WIN32__ if ( (_stricmp(basename, "escript.exe") == 0) ||(_stricmp(basename, "escript") == 0)) { #else if (strcmp(basename, "escript") == 0) { #endif def_emu_lookup_path = argv[0]; /* * Locate all options before the script name. */ while (argc > 1 && argv[1][0] == '-') { argc--; argv++; last_opt = argv; } if (argc <= 1) { error("Missing filename\n"); } strncpy(scriptname, argv[1], sizeof(scriptname)); scriptname[sizeof(scriptname)-1] = '\0'; argc--; argv++; } else { char *absname = find_prog(argv[0]); #ifdef __WIN32__ int len = strlen(absname); if (len >= 4 && _stricmp(absname+len-4, ".exe") == 0) { absname[len-4] = '\0'; } #endif erts_snprintf(scriptname, sizeof(scriptname), "%s.escript", absname); efree(absname); def_emu_lookup_path = scriptname; } /* Determine path to emulator */ emulator = get_env("ESCRIPT_EMULATOR"); if (emulator == NULL) { emulator = get_default_emulator(def_emu_lookup_path); } if (strlen(emulator) >= PMAX) error("Value of environment variable ESCRIPT_EMULATOR is too large"); /* * Push initial arguments. */ PUSH(emulator); PUSH("+B"); PUSH2("-boot", "no_dot_erlang"); PUSH("-noshell"); /* * Read options from the %%! row in the script and add them as args */ append_shebang_args(scriptname); /* * Push the script name and everything following it as extra arguments. */ PUSH3("-run", "escript", "start"); /* * Push all options before the script name. But omit the leading hyphens. */ while (first_opt != last_opt) { PUSH(first_opt[1]+1); first_opt++; } PUSH("-extra"); PUSH(scriptname); while (argc > 1) { PUSH(argv[1]); argc--, argv++; } /* * Move up the commands for invoking the emulator and adjust eargv * accordingly. */ while (--eargc_base >= 0) { UNSHIFT(eargv_base[eargc_base]); } /* * Add scriptname to env */ set_env("ESCRIPT_NAME", scriptname); /* * Invoke Erlang with the collected options. */ PUSH(NULL); return run_erlang(eargv[0], eargv); } #ifdef __WIN32__ wchar_t *make_commandline(char **argv) { static wchar_t *buff = NULL; static int siz = 0; int num = 0, len; char **arg; wchar_t *p; if (*argv == NULL) { return L""; } for (arg = argv; *arg != NULL; ++arg) { num += strlen(*arg)+1; } if (!siz) { siz = num; buff = (wchar_t *) emalloc(siz*sizeof(wchar_t)); } else if (siz < num) { siz = num; buff = (wchar_t *) erealloc(buff,siz*sizeof(wchar_t)); } p = buff; num=0; for (arg = argv; *arg != NULL; ++arg) { len = MultiByteToWideChar(CP_UTF8, 0, *arg, -1, p, siz); p+=(len-1); *p++=L' '; } *(--p) = L'\0'; if (debug) { printf("Processed command line:%S\n",buff); } return buff; } int my_spawnvp(char **argv) { STARTUPINFOW siStartInfo; PROCESS_INFORMATION piProcInfo; DWORD ec; memset(&siStartInfo,0,sizeof(STARTUPINFOW)); siStartInfo.cb = sizeof(STARTUPINFOW); siStartInfo.dwFlags = STARTF_USESTDHANDLES; siStartInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE); siStartInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); siStartInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE); if (!CreateProcessW(NULL, make_commandline(argv), NULL, NULL, TRUE, 0, NULL, NULL, &siStartInfo, &piProcInfo)) { return -1; } CloseHandle(piProcInfo.hThread); WaitForSingleObject(piProcInfo.hProcess,INFINITE); if (!GetExitCodeProcess(piProcInfo.hProcess,&ec)) { return 0; } return (int) ec; }