D
DiAvOl
Hello everyone,
I've recently implemented a function which I use in order to check if
a binary file exists in the PATH environment variable and returns the
full path. I'm not sure however how efficient and fast my
implementation is or if it contains bugs (although it works fine at
the moment) and I am looking forward for a better one.
First I am pasting the code that contains non-portable non-ANSI C code
(please ignore those portions - stat etc -) and the second one is the
same function ( check_variable() ) without the *nix functions which
just prints the contents of the path variable after parsing it (in
short just the code that I am interested in making faster/better)
The full implementation:
-----------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifndef PATH_MAX
#define PATH_MAX 4096
#endif
#define UNUSED(x) ((void) x)
char *check_variable(const char *var, const char *program) {
char *lvar = NULL;
char *p;
char *t;
const char *pname;
static char path[PATH_MAX] = {0};
struct stat sb;
if (var == NULL)
return NULL;
lvar = strdup(var);
p = t = lvar;
if ( (pname = strchr(program, '/')) != NULL)
pname++;
else
pname = program;
for (; {
if ( (*p == '\0') && (*t == '\0')) {
free(lvar);
break;
}
while(*p && *p != ':')
p++;
if (*p)
*p++ = '\0';
strcat(path, t);
strcat(path, "/");
strcat(path, pname);
if (stat(path, &sb) == 0) {
free(lvar);
return path;
}
path[0] = '\0';
t = p;
}
return NULL;
}
int main(int argc, char *argv[]) {
char *path;
UNUSED(argc); /* Ignore argument checks, testing purposes */
if ( (path = check_variable(getenv("PATH"), argv[1])) == NULL) {
fprintf(stderr, "Could not find the executable in the path\n");
exit(EXIT_FAILURE);
} else {
fprintf(stdout, "Found path: %s\n", path);
}
return 0;
}
The check_variable function without *nix functions
------------------------------------------------------------------------
void check_variable_demo(const char *var) {
char *lvar = NULL;
char *p;
char *t;
static char path[PATH_MAX] = {0};
if (var == NULL)
return;
lvar = strdup(var);
p = t = lvar;
for (; {
if ( (*p == '\0') && (*t == '\0')) {
free(lvar);
break;
}
while(*p && *p != ':')
p++;
if (*p)
*p++ = '\0';
strcat(path, t);
strcat(path, "/");
printf("Path: %s\n", path);
path[0] = '\0';
t = p;
}
}
Thanks for your time and sorry for my bad english
I've recently implemented a function which I use in order to check if
a binary file exists in the PATH environment variable and returns the
full path. I'm not sure however how efficient and fast my
implementation is or if it contains bugs (although it works fine at
the moment) and I am looking forward for a better one.
First I am pasting the code that contains non-portable non-ANSI C code
(please ignore those portions - stat etc -) and the second one is the
same function ( check_variable() ) without the *nix functions which
just prints the contents of the path variable after parsing it (in
short just the code that I am interested in making faster/better)
The full implementation:
-----------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifndef PATH_MAX
#define PATH_MAX 4096
#endif
#define UNUSED(x) ((void) x)
char *check_variable(const char *var, const char *program) {
char *lvar = NULL;
char *p;
char *t;
const char *pname;
static char path[PATH_MAX] = {0};
struct stat sb;
if (var == NULL)
return NULL;
lvar = strdup(var);
p = t = lvar;
if ( (pname = strchr(program, '/')) != NULL)
pname++;
else
pname = program;
for (; {
if ( (*p == '\0') && (*t == '\0')) {
free(lvar);
break;
}
while(*p && *p != ':')
p++;
if (*p)
*p++ = '\0';
strcat(path, t);
strcat(path, "/");
strcat(path, pname);
if (stat(path, &sb) == 0) {
free(lvar);
return path;
}
path[0] = '\0';
t = p;
}
return NULL;
}
int main(int argc, char *argv[]) {
char *path;
UNUSED(argc); /* Ignore argument checks, testing purposes */
if ( (path = check_variable(getenv("PATH"), argv[1])) == NULL) {
fprintf(stderr, "Could not find the executable in the path\n");
exit(EXIT_FAILURE);
} else {
fprintf(stdout, "Found path: %s\n", path);
}
return 0;
}
The check_variable function without *nix functions
------------------------------------------------------------------------
void check_variable_demo(const char *var) {
char *lvar = NULL;
char *p;
char *t;
static char path[PATH_MAX] = {0};
if (var == NULL)
return;
lvar = strdup(var);
p = t = lvar;
for (; {
if ( (*p == '\0') && (*t == '\0')) {
free(lvar);
break;
}
while(*p && *p != ':')
p++;
if (*p)
*p++ = '\0';
strcat(path, t);
strcat(path, "/");
printf("Path: %s\n", path);
path[0] = '\0';
t = p;
}
}
Thanks for your time and sorry for my bad english