Created
October 20, 2019 00:50
-
-
Save NotKyon/9de31a53321aecd531ea6b21e26c863c to your computer and use it in GitHub Desktop.
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
/* read a string from a program's output */ | |
char *mk_com_readprogf(const char *format, ...) { | |
static char cmd[32768]; | |
static char buf[4096]; | |
static char *out = NULL; | |
size_t n = 0, m = 0; | |
FILE *fp = (FILE *)0; | |
va_list args; | |
va_start(args, format); | |
#if MK_SECLIB | |
vsprintf_s(cmd, sizeof(cmd)/2, format, args); | |
#else | |
vsnprintf(cmd, sizeof(cmd)/2, format, args); | |
cmd[sizeof(cmd)/2 - 1] = 0; | |
#endif | |
va_end(args); | |
if( cmd[0] != '/' ) { | |
static char path[sizeof(cmd)/2 - 1]; | |
size_t repindex; | |
char repchar = '\0'; | |
char *pathvar = NULL; | |
for( repindex = 0; repindex < sizeof(cmd)-1 && cmd[repindex] != '\0'; ++repindex ) { | |
if( cmd[repindex] == ' ' ) { | |
if( repindex > 0 && cmd[repindex-1] == '\\' ) { | |
continue; | |
} | |
repchar = cmd[repindex]; // should just be ' ', but we might adjust this | |
cmd[repindex] = '\0'; | |
break; | |
} | |
} | |
if( ( pathvar = getenv("PATH") ) != NULL ) { | |
static const char pathenvsep = | |
#if defined(_WIN32) | |
';' | |
#else | |
':' | |
#endif | |
; | |
const char *s, *e; | |
size_t pathlen; | |
s = pathvar; | |
do { | |
e = strchr( s, pathenvsep ); | |
if( e != NULL ) { | |
pathlen = (size_t)(ptrdiff_t)( e - s ); | |
mk_com_strncpy( &path[0], sizeof(path)-1, s, pathlen ); | |
s = e + 1; | |
} else { | |
mk_com_strcpy( &path[0], sizeof(path)-1, s ); | |
pathlen = strlen(s); | |
} | |
if( pathlen > 0 && path[pathlen-1] != '/' && path[pathlen-1] != '\\' ) { | |
path[pathlen++] = '/'; | |
path[pathlen] = '\0'; | |
++pathlen; | |
} | |
mk_com_strcpy( &path[pathlen], sizeof(path) - pathlen, cmd ); | |
if( mk_fs_isFile( path ) ) { | |
path[pathlen] = '\0'; | |
if( repchar != '\0' && repindex < sizeof(cmd) ) { | |
cmd[repindex ] = repchar; | |
repchar = '\0'; | |
repindex = ~(size_t)0; | |
} | |
memmove( &cmd[pathlen], &cmd[0], strlen(cmd) + 1 ); | |
memcpy( &cmd[0], &path[0], pathlen ); | |
break; | |
} | |
} while( e != NULL ); | |
} | |
if( repchar != '\0' && repindex < sizeof(cmd) ) { | |
cmd[repindex] = repchar; | |
repchar = '\0'; | |
repindex = ~(size_t)0; | |
} | |
} | |
#ifdef _WIN32 | |
# undef popen | |
# undef pclose | |
# define popen _popen | |
# define pclose _pclose | |
#endif | |
fp = popen( cmd, "r" ); | |
if( !fp ) { | |
return NULL; | |
} | |
m = 1024; | |
out = (char*)malloc( m ); | |
if( !out ) { | |
abort(); | |
} | |
*out = '\0'; | |
n = 0; | |
while( fgets( buf, sizeof(buf) - 1, fp ) != NULL ) { | |
size_t bufn; | |
bufn = strlen(buf); | |
if( n + bufn + 1 > m ) { | |
char *q; | |
m += bufn + 1024; | |
m += m/2; | |
q = realloc( out, m ); | |
if( !q ) { | |
abort(); | |
} | |
out = q; | |
} | |
memcpy( &out[n], &buf[0], bufn ); | |
n += bufn; | |
out[n] = '\0'; | |
} | |
pclose( fp ); | |
return out; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment