Browse Source

Fix for UI/API intensity changes

The API and UI functions to change intensity would update the gpu
settings directly without updating the config option strings. This
resulted in the intensity updates not saving in config files. This
update should resolve that problem.

Also added API functions to change xintensity and rawintensity.
djm34
ystarnaud 10 years ago committed by troky
parent
commit
8a6168fa4b
  1. 67
      api.c
  2. 5
      api.h
  3. 231
      config_parser.c
  4. 15
      config_parser.h
  5. 16
      driver-opencl.c
  6. 36
      logging.c
  7. 3
      logging.h
  8. 28
      miner.h
  9. 18
      sgminer.c

67
api.c

@ -143,6 +143,10 @@ struct CODES codes[] = { @@ -143,6 +143,10 @@ struct CODES codes[] = {
{ SEVERITY_ERR, MSG_NOGPUADL,PARAM_GPU, "GPU %d does not have ADL" },
{ SEVERITY_ERR, MSG_INVINT, PARAM_STR, "Invalid intensity (%s) - must be '" _DYNAMIC "' or range " MIN_INTENSITY_STR " - " MAX_INTENSITY_STR },
{ SEVERITY_INFO, MSG_GPUINT, PARAM_BOTH, "GPU %d set new intensity to %s" },
{ SEVERITY_ERR, MSG_INVXINT, PARAM_STR, "Invalid xintensity (%s) - must be range " MIN_XINTENSITY_STR " - " MAX_XINTENSITY_STR },
{ SEVERITY_INFO, MSG_GPUXINT, PARAM_BOTH, "GPU %d set new xintensity to %s" },
{ SEVERITY_ERR, MSG_INVRAWINT, PARAM_STR, "Invalid rawintensity (%s) - must be range " MIN_RAWINTENSITY_STR " - " MAX_RAWINTENSITY_STR },
{ SEVERITY_INFO, MSG_GPURAWINT, PARAM_BOTH, "GPU %d set new rawintensity to %s" },
{ SEVERITY_SUCC, MSG_MINECONFIG,PARAM_NONE, "sgminer config" },
{ SEVERITY_ERR, MSG_GPUMERR, PARAM_BOTH, "Setting GPU %d memoryclock to (%s) reported failure" },
{ SEVERITY_SUCC, MSG_GPUMEM, PARAM_BOTH, "Setting GPU %d memoryclock to (%s) reported success" },
@ -2329,12 +2333,73 @@ static void gpuintensity(struct io_data *io_data, __maybe_unused SOCKETTYPE c, c @@ -2329,12 +2333,73 @@ static void gpuintensity(struct io_data *io_data, __maybe_unused SOCKETTYPE c, c
gpus[id].dynamic = false;
gpus[id].intensity = intensity;
gpus[id].xintensity = 0;
gpus[id].rawintensity = 0;
sprintf(intensitystr, "%d", intensity);
}
// fix config with new settings so that we can save them
update_config_intensity(get_gpu_profile(id));
message(io_data, MSG_GPUINT, id, intensitystr, isjson);
}
static void gpuxintensity(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group)
{
int id;
char *value;
int intensity;
char intensitystr[7];
if (!splitgpuvalue(io_data, param, &id, &value, isjson))
return;
intensity = atoi(value);
if (intensity < MIN_XINTENSITY || intensity > MAX_XINTENSITY) {
message(io_data, MSG_INVXINT, 0, value, isjson);
return;
}
gpus[id].dynamic = false;
gpus[id].intensity = 0;
gpus[id].xintensity = intensity;
gpus[id].rawintensity = 0;
sprintf(intensitystr, "%d", intensity);
// fix config with new settings so that we can save them
update_config_xintensity(get_gpu_profile(id));
message(io_data, MSG_GPUXINT, id, intensitystr, isjson);
}
static void gpurawintensity(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group)
{
int id;
char *value;
int intensity;
char intensitystr[16];
if (!splitgpuvalue(io_data, param, &id, &value, isjson))
return;
intensity = atoi(value);
if (intensity < MIN_RAWINTENSITY || intensity > MAX_RAWINTENSITY) {
message(io_data, MSG_INVRAWINT, 0, value, isjson);
return;
}
gpus[id].dynamic = false;
gpus[id].intensity = 0;
gpus[id].xintensity = 0;
gpus[id].rawintensity = intensity;
sprintf(intensitystr, "%d", intensity);
// fix config with new settings so that we can save them
update_config_rawintensity(get_gpu_profile(id));
message(io_data, MSG_GPURAWINT, id, intensitystr, isjson);
}
static void gpumem(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
{
#ifdef HAVE_ADL
@ -2929,6 +2994,8 @@ struct CMDS { @@ -2929,6 +2994,8 @@ struct CMDS {
{ "addprofile", api_profile_add, true, false },
{ "removeprofile", api_profile_remove, true, false },
{ "gpuintensity", gpuintensity, true, false },
{ "gpuxintensity", gpuxintensity, true, false },
{ "gpurawintensity", gpurawintensity, true, false },
{ "gpumem", gpumem, true, false },
{ "gpuengine", gpuengine, true, false },
{ "gpufan", gpufan, true, false },

5
api.h

@ -181,6 +181,11 @@ @@ -181,6 +181,11 @@
#define MSG_CHPOOLPR 139
#define MSG_INVXINT 140
#define MSG_GPUXINT 141
#define MSG_INVRAWINT 142
#define MSG_GPURAWINT 143
enum code_severity {
SEVERITY_ERR,
SEVERITY_WARN,

231
config_parser.c

@ -89,6 +89,12 @@ static struct profile *add_profile() @@ -89,6 +89,12 @@ static struct profile *add_profile()
profile->name = strdup(buf);
profile->algorithm.name[0] = '\0';
// intensity set to blank by default
buf[0] = 0;
profile->intensity = strdup(buf);
profile->xintensity = strdup(buf);
profile->rawintensity = strdup(buf);
profiles = (struct profile **)realloc(profiles, sizeof(struct profile *) * (total_profiles + 2));
profiles[total_profiles++] = profile;
@ -141,15 +147,33 @@ static struct profile *get_profile(char *name) @@ -141,15 +147,33 @@ static struct profile *get_profile(char *name)
{
int i;
for(i=total_profiles;i--;)
{
if(!strcasecmp(profiles[i]->name, name))
if (empty_string(name)) {
return NULL;
}
for (i=0;i<total_profiles;++i) {
if (!safe_cmp(profiles[i]->name, name)) {
return profiles[i];
}
}
return NULL;
}
struct profile *get_gpu_profile(int gpuid)
{
struct profile *profile;
struct pool *pool = pools[gpus[gpuid].thr[0]->pool_no];
if (!(profile = get_profile(pool->profile))) {
if (!(profile = get_profile(default_profile.name))) {
profile = &default_profile;
}
}
return profile;
}
/******* Default profile functions used during config parsing *****/
char *set_default_algorithm(const char *arg)
{
@ -189,19 +213,19 @@ char *set_default_lookup_gap(const char *arg) @@ -189,19 +213,19 @@ char *set_default_lookup_gap(const char *arg)
char *set_default_intensity(const char *arg)
{
default_profile.intensity = arg;
opt_set_charp(arg, &default_profile.intensity);
return NULL;
}
char *set_default_xintensity(const char *arg)
{
default_profile.xintensity = arg;
opt_set_charp(arg, &default_profile.xintensity);
return NULL;
}
char *set_default_rawintensity(const char *arg)
{
default_profile.rawintensity = arg;
opt_set_charp(arg, &default_profile.rawintensity);
return NULL;
}
@ -317,21 +341,21 @@ char *set_profile_lookup_gap(const char *arg) @@ -317,21 +341,21 @@ char *set_profile_lookup_gap(const char *arg)
char *set_profile_intensity(const char *arg)
{
struct profile *profile = get_current_profile();
profile->intensity = arg;
opt_set_charp(arg, &profile->intensity);
return NULL;
}
char *set_profile_xintensity(const char *arg)
{
struct profile *profile = get_current_profile();
profile->xintensity = arg;
opt_set_charp(arg, &profile->xintensity);
return NULL;
}
char *set_profile_rawintensity(const char *arg)
{
struct profile *profile = get_current_profile();
profile->rawintensity = arg;
opt_set_charp(arg, &profile->rawintensity);
return NULL;
}
@ -795,6 +819,20 @@ void load_default_config(void) @@ -795,6 +819,20 @@ void load_default_config(void)
* Startup functions
* *****************************************/
void init_default_profile()
{
char buf[32];
buf[0] = 0;
default_profile.name = strdup(buf);
default_profile.algorithm.name[0] = 0;
default_profile.algorithm.kernelfile = strdup(buf);
default_profile.intensity = strdup(buf);
default_profile.xintensity = strdup(buf);
default_profile.rawintensity = strdup(buf);
}
// assign default settings from default profile if set
void load_default_profile()
{
@ -1275,17 +1313,23 @@ static json_t *build_pool_json() @@ -1275,17 +1313,23 @@ static json_t *build_pool_json()
return NULL;
// rawintensity
if (!empty_string(pool->rawintensity))
if (!build_pool_json_add(obj, "rawintensity", pool->rawintensity, profile->rawintensity, default_profile.rawintensity, pool->pool_no))
if (!empty_string(pool->rawintensity)) {
if (!build_pool_json_add(obj, "rawintensity", pool->rawintensity, profile->rawintensity, default_profile.rawintensity, pool->pool_no)) {
return NULL;
}
}
// xintensity
else if (!empty_string(pool->xintensity))
if (!build_pool_json_add(obj, "xintensity", pool->xintensity, profile->xintensity, default_profile.xintensity, pool->pool_no))
else if (!empty_string(pool->xintensity)) {
if (!build_pool_json_add(obj, "xintensity", pool->xintensity, profile->xintensity, default_profile.xintensity, pool->pool_no)) {
return NULL;
}
}
// intensity
else
if (!build_pool_json_add(obj, "intensity", pool->intensity, profile->intensity, default_profile.intensity, pool->pool_no))
else if (!empty_string(pool->intensity)) {
if (!build_pool_json_add(obj, "intensity", pool->intensity, profile->intensity, default_profile.intensity, pool->pool_no)) {
return NULL;
}
}
// shaders
if (!build_pool_json_add(obj, "shaders", pool->shaders, profile->shaders, default_profile.shaders, pool->pool_no))
@ -1344,12 +1388,14 @@ static json_t *build_profile_json_add(json_t *object, const char *key, const cha @@ -1344,12 +1388,14 @@ static json_t *build_profile_json_add(json_t *object, const char *key, const cha
val = str_compare;
// no value, return...
if(empty_string(val))
if (empty_string(val)) {
return object;
}
//if the value is the same as default profile and, the current profile is not default profile, return...
if((safe_cmp(str_compare, val) == 0) && isdefault == false)
if ((safe_cmp(str_compare, val) == 0) && isdefault == false) {
return object;
}
json_profile_add(object, key, json_string(val), parentkey, id);
@ -1383,17 +1429,23 @@ static json_t *build_profile_settings_json(json_t *object, struct profile *profi @@ -1383,17 +1429,23 @@ static json_t *build_profile_settings_json(json_t *object, struct profile *profi
return NULL;
// rawintensity
if (!empty_string(profile->rawintensity))
if(!build_profile_json_add(object, "rawintensity", profile->rawintensity, default_profile.rawintensity, isdefault, parentkey, profile->profile_no))
if (!empty_string(profile->rawintensity) || (isdefault && !empty_string(default_profile.rawintensity))) {
if(!build_profile_json_add(object, "rawintensity", profile->rawintensity, default_profile.rawintensity, isdefault, parentkey, profile->profile_no)) {
return NULL;
}
}
// xintensity
else if (!empty_string(profile->xintensity))
if(!build_profile_json_add(object, "xintensity", profile->xintensity, default_profile.xintensity, isdefault, parentkey, profile->profile_no))
else if (!empty_string(profile->xintensity) || (isdefault && !empty_string(default_profile.xintensity))) {
if(!build_profile_json_add(object, "xintensity", profile->xintensity, default_profile.xintensity, isdefault, parentkey, profile->profile_no)) {
return NULL;
}
}
// intensity
else if (!empty_string(profile->intensity))
if(!build_profile_json_add(object, "intensity", profile->intensity, default_profile.intensity, isdefault, parentkey, profile->profile_no))
else if (!empty_string(profile->intensity) || (isdefault && !empty_string(default_profile.intensity))) {
if(!build_profile_json_add(object, "intensity", profile->intensity, default_profile.intensity, isdefault, parentkey, profile->profile_no)) {
return NULL;
}
}
//shaders
if (!build_profile_json_add(object, "shaders", profile->shaders, default_profile.shaders, isdefault, parentkey, profile->profile_no))
@ -2062,3 +2114,136 @@ void api_pool_profile(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char @@ -2062,3 +2114,136 @@ void api_pool_profile(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char
message(io_data, MSG_CHPOOLPR, pool->pool_no, profile->name, isjson);
}
void update_config_intensity(struct profile *profile)
{
int i;
char buf[255];
memset(buf, 0, 255);
for (i = 0; i<nDevs; ++i) {
if (gpus[i].dynamic) {
sprintf(buf, "%s%sd", buf, ((i > 0)?",":""));
}
else {
sprintf(buf, "%s%s%d", buf, ((i > 0)?",":""), gpus[i].intensity);
}
}
if (profile->intensity) {
free(profile->intensity);
}
profile->intensity = strdup((const char *)buf);
if (profile->xintensity) {
profile->xintensity[0] = 0;
}
if (profile->rawintensity) {
profile->rawintensity[0] = 0;
}
// if this profile is also default profile, make sure to set the default_profile structure value
if (!safe_cmp(profile->name, default_profile.name)) {
if (default_profile.intensity) {
free(default_profile.intensity);
}
default_profile.intensity = strdup((const char *)buf);
if (default_profile.xintensity) {
default_profile.xintensity[0] = 0;
}
if (default_profile.rawintensity) {
default_profile.rawintensity[0] = 0;
}
}
}
void update_config_xintensity(struct profile *profile)
{
int i;
char buf[255];
memset(buf, 0, 255);
for (i = 0; i<nDevs; ++i) {
sprintf(buf, "%s%s%d", buf, ((i > 0)?",":""), gpus[i].xintensity);
}
if (profile->intensity) {
profile->intensity[0] = 0;
}
if (profile->xintensity) {
free(profile->xintensity);
}
profile->xintensity = strdup((const char *)buf);
if (profile->rawintensity) {
profile->rawintensity[0] = 0;
}
// if this profile is also default profile, make sure to set the default_profile structure value
if (!safe_cmp(profile->name, default_profile.name)) {
if (default_profile.intensity) {
default_profile.intensity[0] = 0;
}
if (default_profile.xintensity) {
free(default_profile.xintensity);
}
default_profile.xintensity = strdup((const char *)buf);
if (default_profile.rawintensity) {
default_profile.rawintensity[0] = 0;
}
}
}
void update_config_rawintensity(struct profile *profile)
{
int i;
char buf[255];
memset(buf, 0, 255);
for (i = 0; i<nDevs; ++i) {
sprintf(buf, "%s%s%d", buf, ((i > 0)?",":""), gpus[i].rawintensity);
}
if (profile->intensity) {
profile->intensity[0] = 0;
}
if (profile->xintensity) {
profile->xintensity[0] = 0;
}
if (profile->rawintensity) {
free(profile->rawintensity);
}
profile->rawintensity = strdup((const char *)buf);
// if this profile is also default profile, make sure to set the default_profile structure value
if (!safe_cmp(profile->name, default_profile.name)) {
if (default_profile.intensity) {
default_profile.intensity[0] = 0;
}
if (default_profile.xintensity) {
default_profile.xintensity[0] = 0;
}
if (default_profile.rawintensity) {
free(default_profile.rawintensity);
}
default_profile.rawintensity = strdup((const char *)buf);
}
}

15
config_parser.h

@ -15,9 +15,9 @@ struct profile { @@ -15,9 +15,9 @@ struct profile {
algorithm_t algorithm;
const char *devices;
const char *intensity;
const char *xintensity;
const char *rawintensity;
char *intensity;
char *xintensity;
char *rawintensity;
const char *lookup_gap;
const char *gpu_engine;
const char *gpu_memclock;
@ -43,6 +43,9 @@ extern struct profile default_profile; @@ -43,6 +43,9 @@ extern struct profile default_profile;
extern struct profile **profiles;
extern int total_profiles;
/* profile helper functions */
extern struct profile *get_gpu_profile(int gpuid);
/* option parser functions */
extern char *set_default_algorithm(const char *arg);
extern char *set_default_nfactor(const char *arg);
@ -93,6 +96,7 @@ extern char *set_default_config(const char *arg); @@ -93,6 +96,7 @@ extern char *set_default_config(const char *arg);
extern void load_default_config(void);
/* startup functions */
extern void init_default_profile();
extern void load_default_profile();
extern void apply_defaults();
extern void apply_pool_profiles();
@ -107,4 +111,9 @@ extern void api_profile_add(struct io_data *io_data, __maybe_unused SOCKETTYPE c @@ -107,4 +111,9 @@ extern void api_profile_add(struct io_data *io_data, __maybe_unused SOCKETTYPE c
extern void api_profile_remove(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group);
extern void api_pool_profile(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group);
/* API/UI config update functions */
extern void update_config_intensity(struct profile *profile);
extern void update_config_xintensity(struct profile *profile);
extern void update_config_rawintensity(struct profile *profile);
#endif // CONFIG_PARSER_H

16
driver-opencl.c

@ -890,6 +890,10 @@ retry: // TODO: refactor @@ -890,6 +890,10 @@ retry: // TODO: refactor
if (!strncasecmp(intvar, "d", 1)) {
wlogprint("Dynamic mode enabled on gpu %d\n", selected);
gpus[selected].dynamic = true;
// fix config with new settings so that we can save them
update_config_intensity(get_gpu_profile(selected));
pause_dynamic_threads(selected);
free(intvar);
goto retry;
@ -905,6 +909,10 @@ retry: // TODO: refactor @@ -905,6 +909,10 @@ retry: // TODO: refactor
gpus[selected].xintensity = 0; // Disable xintensity when enabling intensity
gpus[selected].rawintensity = 0; // Disable raw intensity when enabling intensity
wlogprint("Intensity on gpu %d set to %d\n", selected, intensity);
// fix config with new settings so that we can save them
update_config_intensity(get_gpu_profile(selected));
pause_dynamic_threads(selected);
goto retry;
} else if (!strncasecmp(&input, "x", 1)) {
@ -934,6 +942,10 @@ retry: // TODO: refactor @@ -934,6 +942,10 @@ retry: // TODO: refactor
gpus[selected].rawintensity = 0; // Disable raw intensity when enabling xintensity
gpus[selected].xintensity = xintensity;
wlogprint("Experimental intensity on gpu %d set to %d\n", selected, xintensity);
// fix config with new settings so that we can save them
update_config_xintensity(get_gpu_profile(selected));
pause_dynamic_threads(selected);
goto retry;
} else if (!strncasecmp(&input, "a", 1)) {
@ -963,6 +975,10 @@ retry: // TODO: refactor @@ -963,6 +975,10 @@ retry: // TODO: refactor
gpus[selected].xintensity = 0; // Disable xintensity when enabling raw intensity
gpus[selected].rawintensity = rawintensity;
wlogprint("Raw intensity on gpu %d set to %d\n", selected, rawintensity);
// fix config with new settings so that we can save them
update_config_rawintensity(get_gpu_profile(selected));
pause_dynamic_threads(selected);
goto retry;
} else if (!strncasecmp(&input, "r", 1)) {

36
logging.c

@ -143,3 +143,39 @@ void _applog(int prio, const char *str, bool force) @@ -143,3 +143,39 @@ void _applog(int prio, const char *str, bool force)
}
}
}
void __debug(const char *filename, const char *fmt, ...)
{
FILE *f;
va_list args;
if (!(f = fopen(((!empty_string(filename))?filename:"debug.log"), "a+"))) {
return;
}
//prepend timestamp
struct timeval tv = {0, 0};
struct tm *tm;
cgtime(&tv);
const time_t tmp_time = tv.tv_sec;
tm = localtime(&tmp_time);
fprintf(f, "[%d-%02d-%02d %02d:%02d:%02d] ",
tm->tm_year + 1900,
tm->tm_mon + 1,
tm->tm_mday,
tm->tm_hour,
tm->tm_min,
tm->tm_sec);
va_start(args, fmt);
vfprintf(f, fmt, args);
va_end(args);
//add \n
fprintf(f, "\n");
fclose(f);
}

3
logging.h

@ -92,4 +92,7 @@ extern void _applog(int prio, const char *str, bool force); @@ -92,4 +92,7 @@ extern void _applog(int prio, const char *str, bool force);
#endif
extern void __debug(const char *filename, const char *fmt, ...);
#endif /* LOGGING_H */

28
miner.h

@ -1297,20 +1297,20 @@ struct pool { @@ -1297,20 +1297,20 @@ struct pool {
char *profile;
algorithm_t algorithm;
const char *devices;
const char *intensity;
const char *xintensity;
const char *rawintensity;
const char *lookup_gap;
const char *gpu_engine;
const char *gpu_memclock;
const char *gpu_threads;
const char *gpu_fan;
const char *gpu_powertune;
const char *gpu_vddc;
const char *shaders;
const char *thread_concurrency;
const char *worksize;
const char *devices;
char *intensity;
char *xintensity;
char *rawintensity;
const char *lookup_gap;
const char *gpu_engine;
const char *gpu_memclock;
const char *gpu_threads;
const char *gpu_fan;
const char *gpu_powertune;
const char *gpu_vddc;
const char *shaders;
const char *thread_concurrency;
const char *worksize;
pthread_mutex_t pool_lock;
cglock_t data_lock;

18
sgminer.c

@ -532,6 +532,11 @@ struct pool *add_pool(void) @@ -532,6 +532,11 @@ struct pool *add_pool(void)
pool->profile = strdup(buf); //profile blank by default
pool->algorithm.name[0] = '\0'; //blank algorithm name
/* intensities default to blank */
pool->intensity = strdup(buf);
pool->xintensity = strdup(buf);
pool->rawintensity = strdup(buf);
pools = (struct pool **)realloc(pools, sizeof(struct pool *) * (total_pools + 2));
pools[total_pools++] = pool;
mutex_init(&pool->pool_lock);
@ -817,21 +822,21 @@ static char *set_pool_lookup_gap(const char *arg) @@ -817,21 +822,21 @@ static char *set_pool_lookup_gap(const char *arg)
static char *set_pool_intensity(const char *arg)
{
struct pool *pool = get_current_pool();
pool->intensity = arg;
opt_set_charp(arg, &pool->intensity);
return NULL;
}
static char *set_pool_xintensity(const char *arg)
{
struct pool *pool = get_current_pool();
pool->xintensity = arg;
opt_set_charp(arg, &pool->xintensity);
return NULL;
}
static char *set_pool_rawintensity(const char *arg)
{
struct pool *pool = get_current_pool();
pool->rawintensity = arg;
opt_set_charp(arg, &pool->rawintensity);
return NULL;
}
@ -1457,10 +1462,6 @@ struct opt_table opt_config_table[] = { @@ -1457,10 +1462,6 @@ struct opt_table opt_config_table[] = {
set_default_xintensity, NULL, NULL,
"Shader based intensity of GPU scanning (" MIN_XINTENSITY_STR " to "
MAX_XINTENSITY_STR "), overridden --xintensity|-X and --rawintensity."),
OPT_WITH_ARG("--xintensity|-X",
set_default_xintensity, NULL, NULL,
"Shader based intensity of GPU scanning (" MIN_XINTENSITY_STR " to "
MAX_XINTENSITY_STR "), overrides --intensity|-I, overridden by --rawintensity."),
OPT_WITH_ARG("--rawintensity",
set_default_rawintensity, NULL, NULL,
"Raw intensity of GPU scanning (" MIN_RAWINTENSITY_STR " to "
@ -8367,6 +8368,9 @@ int main(int argc, char *argv[]) @@ -8367,6 +8368,9 @@ int main(int argc, char *argv[])
quithere(1, "Failed to pthread_mutex_init lockstat_lock errno=%d", errno);
#endif
// initialize default profile (globals) before reading config options
init_default_profile();
initial_args = (const char **)malloc(sizeof(char *)* (argc + 1));
for (i = 0; i < argc; i++)
initial_args[i] = (const char *)strdup(argv[i]);

Loading…
Cancel
Save