Created
January 1, 2019 13:47
-
-
Save sebgod/3654d7867ca5a0a6acccf45faee6ed05 to your computer and use it in GitHub Desktop.
A wrapper executable to wrap Linux executable files on WSL to be callable from Windows.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define __STDC_WANT_LIB_EXT1__ 1 | |
#include <stdio.h> | |
#include <stdlib.h> | |
#define _GNU_SOURCE | |
#include <string.h> | |
#if _WIN32 || _WIN64 | |
# define CDECL __cdecl | |
# define WIN32_LEAN_AND_MEAN | |
# include <windows.h> | |
# define GET_CMD_LINE() GetCommandLine() | |
# define EXEC_CMD(cmd) \ | |
do { \ | |
STARTUPINFO si = { 0 }; \ | |
PROCESS_INFORMATION pi = { 0 }; \ | |
if ( !CreateProcess( \ | |
NULL, /* No module name (use command line) */ \ | |
(cmd), /* Command line */ \ | |
NULL, /* Process handle not inheritable */ \ | |
NULL, /* Thread handle not inheritable */ \ | |
TRUE, /* Set handle inheritance to TRUE */ \ | |
0, /* No creation flags */ \ | |
NULL, /* Use parent's environment block */ \ | |
NULL, /* Use parent's starting directory */ \ | |
&si, /* Pointer to STARTUPINFO structure */ \ | |
&pi ) /* Pointer to PROCESS_INFORMATION structure */ \ | |
) \ | |
{ \ | |
fprintf(stderr, "CreateProcess failed (%d).\n", GetLastError() ); \ | |
return EXIT_FAILURE; \ | |
} \ | |
/* Wait until child process exits. */ \ | |
WaitForSingleObject( pi.hProcess, INFINITE ); \ | |
CloseHandle( pi.hProcess ); /* Close process and thread handles. */ \ | |
CloseHandle( pi.hThread ); \ | |
} while (0) | |
#else | |
# include <unistd.h> | |
# include <libgen.h> | |
# define CDECL | |
#endif | |
#ifdef _MSC_VER | |
# define __STDC_LIB_EXT1__ 1 | |
#endif | |
#ifndef _countof | |
# define _countof(array) (sizeof(array) / sizeof(array[0])) | |
#endif | |
#ifndef _MAX_ARG | |
# define _MAX_ARG 0x8000 | |
#endif | |
#ifndef _MAX_FNAME | |
# define _MAX_FNAME 256 | |
#endif | |
#if __STDC_LIB_EXT1__ | |
# define STRCAT(p, s) strcat_s((p), _countof((p)), (s)) | |
# define FILENAME(p, f) _splitpath_s((p), NULL, 0, NULL, 0, (f), _countof((f)), NULL, 0) | |
#else | |
# define STRCAT(p, s) strcat(p, s) | |
# define FILENAME(p, f) _splitpath((p), NULL, NULL, (f), NULL) | |
#endif | |
int | |
CDECL main(int argc, char *argv[]) | |
{ | |
#ifdef GET_CMD_LINE | |
char wslArgs[_MAX_ARG] = { 0 }; | |
char fname[_MAX_FNAME] = { 0 }; | |
char *cmdLine; | |
char *spaceOrQuote; | |
int spaceOrQuoteIdx; | |
cmdLine = GET_CMD_LINE(); | |
if (strchr(argv[0], ' ')) | |
{ | |
if (spaceOrQuote = strchr(strchr(cmdLine, ' '), '"')) | |
{ | |
spaceOrQuoteIdx = (spaceOrQuote - cmdLine) + 1; | |
} | |
else | |
{ | |
fprintf(stderr, "%s is not properly escaped!\n", argv[0]); | |
return EXIT_FAILURE; | |
} | |
} | |
else | |
{ | |
spaceOrQuoteIdx = strlen(argv[0]); | |
} | |
FILENAME(argv[0], fname); | |
STRCAT(wslArgs, "wsl.exe \""); | |
STRCAT(wslArgs, fname); | |
STRCAT(wslArgs, "\" "); | |
STRCAT(wslArgs, cmdLine + spaceOrQuoteIdx); | |
EXEC_CMD(wslArgs); | |
#else | |
char *cargv[argc + 1]; | |
cargv[0] = basename(argv[0]); | |
for (int i = 1; i < argc; i++) | |
{ | |
cargv[i] = argv[i]; | |
} | |
cargv[argc] = NULL; | |
/* basically just pass through all arguments and use the executable | |
in the path. So `./cp' will turn into `cp' and thus `/bin/cp' */ | |
execvp(cargv[0], cargv); | |
#endif | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment