#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/stat.h>#include "portability.h"#include "utility.h"
Go to the source code of this file.
Defines | |
| #define | BUFSZ 400 |
Functions | |
| int | gs_versions_incompatible (const char *ver1, const char *ver2) |
| char * | gs_get_line (FILE *in) |
| char * | gs_read_line (FILE *f, int *linecount) |
| int | gs_parse_config_file (char *filename, gs_info_t **tmp) |
| int | gs_open_locked_file (char *filename, short lock_type, int flags) |
| int | gs_unlock_file (int fd) |
| static void | gs_alarm_catch (int sig) |
| int | gs_open_locked_file_timeout (char *lockfile, short lock_type, int flags, int timeout) |
| long | gs_seconds_since_modified (char *filename) |
| int | gs_get_contents_of_file (char *name, char **contents) |
| static float | gs_popen_loadavg (char *cmd) |
| static float | gs_fopen_loadavg (char *filename) |
| int | gs_get_workload () |
| Get workload on machine. | |
This file contains various utility routines used by GridSolve.
Definition in file utility.c.
| #define BUFSZ 400 |
| static void gs_alarm_catch | ( | int | sig | ) | [static] |
Empty signal handler for SIGALRM used in gs_open_locked_file_timeout().
| sig | -- signal number (unused) |
Definition at line 299 of file utility.c.
{
return;
}
| static float gs_fopen_loadavg | ( | char * | filename | ) | [static] |
Definition at line 457 of file utility.c.
{
FILE *loadavg_file;
float tmpf;
int n;
if((loadavg_file = fopen(filename, "r")) == NULL)
return -1;
n = fscanf(loadavg_file, "%f", &tmpf);
fclose(loadavg_file);
if(n != 1)
return -1;
return tmpf;
}


| int gs_get_contents_of_file | ( | char * | name, | |
| char ** | contents | |||
| ) |
Definition at line 390 of file utility.c.
{
struct stat stbuf;
int cfd, nread;
char *buf;
if(stat(name, &stbuf) < 0)
return -1;
buf = malloc((int)stbuf.st_size+1);
if(!buf) {
ERRPRINTF("malloc failed\n");
return -1;
}
cfd = open(name, O_RDONLY, 0600);
if(cfd < 0) {
ERRPRINTF("Warning: failed to open file '%s'\n", name);
free(buf);
return -1;
}
nread = read(cfd, buf, (int) stbuf.st_size + 1);
buf[nread] = '\0';
close(cfd);
if(nread <= 0) {
free(buf);
return -1;
}
*contents = buf;
return nread;
}

| char* gs_get_line | ( | FILE * | in | ) |
Keeps reading chunks from the specified file until a newline is found. Appends all the chunks to one string and returns that. This code was lifted from f2j.
| in | -- the file to read from |
Definition at line 66 of file utility.c.
{
#define BUFSZ 400
char buf[BUFSZ];
char *rv, *line, *ltmp;
int idx = 0, cur_size = BUFSZ;
if(!in) return NULL;
line = (char *)malloc(BUFSZ);
*line = '\0';
if(!line) return NULL;
do {
rv = fgets(buf, BUFSZ, in);
if(!rv) {
free(line);
return NULL;
}
memcpy(line+idx, buf, BUFSZ);
idx += strlen(buf);
cur_size += BUFSZ;
ltmp = realloc(line, cur_size);
if(!ltmp) return NULL;
line = ltmp;
} while(buf[strlen(buf)-1] != '\n');
return line;
}

| int gs_get_workload | ( | ) |
Get workload on machine.
Call the uptime command to get the system load, and return it as a percentage.
Definition at line 485 of file utility.c.
{
char *commands[] = {"uptime", "w", NULL};
char *files[] = {"/proc/loadavg", NULL};
float workload;
int i, scale;
scale = 100;
for(i=0;files[i];i++)
if((workload = gs_fopen_loadavg(files[i])) >= 0)
return (int) (scale * workload);
for(i=0;commands[i];i++)
if((workload = gs_popen_loadavg(commands[i])) >= 0)
return (int) (scale * workload);
return -1;
}


| int gs_open_locked_file | ( | char * | filename, | |
| short | lock_type, | |||
| int | flags | |||
| ) |
Opens and locks the specified file.
| filename | -- name of the file to lock | |
| lock_type | -- type of lock (F_RDLCK, F_WRLCK) | |
| flags | -- mode to open the file (O_RDONLY, O_RDWR, etc) |
Definition at line 245 of file utility.c.
{
int fd;
if(!filename) {
ERRPRINTF("Invalid arg: null filename\n");
return -1;
}
if((fd = open(filename, flags, 0600)) == -1) {
ERRPRINTF("open failed\n");
perror("open");
return -1;
}
/* lock file */
if (gs_lock_fd(fd, lock_type) == -1) {
perror("lock");
close(fd);
return -1;
}
return fd;
}


| int gs_open_locked_file_timeout | ( | char * | lockfile, | |
| short | lock_type, | |||
| int | flags, | |||
| int | timeout | |||
| ) |
Opens and locks the specified file. If the lock cannot be obtained within 'timeout' seconds, then -1 is returned.
| filename | -- name of the file to lock | |
| lock_type | -- type of lock (F_RDLCK, F_WRLCK) | |
| flags | -- mode to open the file (O_RDONLY, O_RDWR, etc) | |
| timeout | -- number of seconds to wait for lock |
Definition at line 317 of file utility.c.
{
struct itimerval tv = {{timeout, 0}, {timeout, 0}};
struct itimerval cv = {{0, 0}, {0, 0}};
struct sigaction act, oldact;
sigset_t set, oldset;
int fd;
memset(&act, 0, sizeof(act));
act.sa_handler = gs_alarm_catch;
act.sa_flags = 0; /* no SA_RESTART */
sigfillset(&act.sa_mask);
if(sigaction(SIGALRM, &act, &oldact) == -1) {
ERRPRINTF("error setting up SIGALRM\n");
return -1;
}
sigemptyset(&set);
sigaddset(&set, SIGALRM);
if(sigprocmask(SIG_UNBLOCK, &set, &oldset) == -1) {
ERRPRINTF("sigprocmask failed\n");
sigaction(SIGALRM, &oldact, NULL);
return -1;
}
setitimer(ITIMER_REAL, &tv, 0);
fd = gs_open_locked_file(lockfile, lock_type, flags);
if(fd < 0) {
setitimer(ITIMER_REAL, &cv, 0);
sigprocmask(SIG_SETMASK, &oldset, NULL);
return -1;
}
setitimer(ITIMER_REAL, &cv, 0);
sigprocmask(SIG_SETMASK, &oldset, NULL);
sigaction(SIGALRM, &oldact, NULL);
return fd;
}


| int gs_parse_config_file | ( | char * | filename, | |
| gs_info_t ** | tmp | |||
| ) |
Parse server config file and build linked list of attributes
| filename | -- the name of the config file to be parsed | |
| tmp | -- upon return, contains a list of gs_info_t representing all the attributes parsed from the file |
Definition at line 139 of file utility.c.
{
gs_info_t *sa_headNode; /* server attribute list */
int i = 0, linecount = 0;
char *p, *line;
FILE *sc_file;
/* Open server configuration file */
sc_file = fopen(filename, "r");
if(!sc_file) {
ERRPRINTF("Could not open %s file\n", filename);
return -1;
}
/*
* parse each line with strtok "="
* store into the linked list
* also putenv each attribute
*/
sa_headNode = (gs_info_t *)malloc(sizeof(gs_info_t));
if(!sa_headNode) {
fclose(sc_file);
ERRPRINTF("Could not allocate memory for server attributes\n");
return -1;
}
*tmp = sa_headNode;
while((line = gs_read_line(sc_file, &linecount))) {
(*tmp)->next = (gs_info_t *)malloc(sizeof(gs_info_t));
if(!(*tmp)->next){
free(line);
free(sa_headNode);
fclose(sc_file);
ERRPRINTF("Could not allocate memory for server attributes\n");
return -1;
}
(*tmp) = (*tmp)->next;
(*tmp)->value = strdup(strpbrk(line,"=")+1);
if(!(*tmp)->value){
free(line);
free(sa_headNode);
fclose(sc_file);
ERRPRINTF("Could not strdup for (*tmp)->value\n");
return -1;
}
(*tmp)->type = strdup(strtok(line,"="));
if(!(*tmp)->type){
free(line);
free(sa_headNode);
fclose(sc_file);
ERRPRINTF("Could not strdup for (*tmp)->type\n");
return -1;
}
(*tmp)->next= NULL;
while(((*tmp)->value[strlen((*tmp)->value)-1] == ' ') ||
((*tmp)->value[strlen((*tmp)->value)-1] == '\n'))
(*tmp)->value[strlen((*tmp)->value)-1] = '\0';
i = strspn((*tmp)->value, " ");
if(i >0){
for (p = (*tmp)->value; ; p++){
*p = *(p+i);
if(*p == '\0') break;
}
}
while((*tmp)->type[strlen((*tmp)->type)-1] == ' ')
(*tmp)->type[strlen((*tmp)->type)-1] = '\0';
sprintf(line,"%s=%s",(*tmp)->type,(*tmp)->value);
if (putenv(strdup(line)) != 0){
free(line);
free(sa_headNode);
fclose(sc_file);
ERRPRINTF("Could not putenv \n");
return -1;
}
free(line);
}
*tmp = sa_headNode->next;
free(sa_headNode);
fclose(sc_file);
return 0;
}


| static float gs_popen_loadavg | ( | char * | cmd | ) | [static] |
Definition at line 429 of file utility.c.
{
float tmpf = -1;
#ifndef WIN32
char buf[200], *tmp, tmp2[20];
FILE *pstream;
if((pstream = popen(cmd, "r")) == NULL)
return -1;
tmp = fgets(buf, 200, pstream);
pclose(pstream);
if(!tmp)
return -1;
tmp = strstr(buf, "average:");
if(!tmp)
return -1;
if(sscanf(tmp, "%s %f", tmp2, &tmpf) != 2)
return -1;
#endif
return tmpf;
}

| char* gs_read_line | ( | FILE * | f, | |
| int * | linecount | |||
| ) |
Reads a line from a file. Skips lines starting with a '#' or a '
'. Increments an integer for line counting.
| f | -- the file to read from | |
| linecount | -- set upon return to the current line number |
Definition at line 113 of file utility.c.
{
char *tmp = NULL;
do
{
if(tmp)
free(tmp);
tmp = gs_get_line(f);
if(!tmp)
break;
(*linecount)++;
} while((tmp[0] == '\n')||(tmp[0] == '#'));
return tmp;
}


| long gs_seconds_since_modified | ( | char * | filename | ) |
Returns the number of seconds since the specified file was modified.
| filename | -- the file to check |
Definition at line 370 of file utility.c.
{
gs_struct_stat stbuf;
struct timeval tv;
long age;
if(!filename)
return -1;
if(gs_stat(filename, &stbuf) < 0)
return -1;
gettimeofday(&tv, NULL);
age = tv.tv_sec - stbuf.st_mtime;
return age;
}

| int gs_unlock_file | ( | int | fd | ) |
Unlock the previously locked memory-mapped file.
| fd | -- the file to unlock |
Definition at line 281 of file utility.c.
{
if(gs_unlock_fd(fd) == -1) {
ERRPRINTF("Warning: could not unlock file\n");
perror("unlock");
return -1;
}
return 0;
}


| int gs_versions_incompatible | ( | const char * | ver1, | |
| const char * | ver2 | |||
| ) |
Check whether the two versions are not compatible with each other. Currently the numbering is: major.minor.revision and the revision number is not considered significant in terms of compatibility, so 0.18.0 would be compatible with 0.18.3, but not with 0.19.0.
| ver1 | -- one version number to check | |
| ver2 | -- another version number to check |
Definition at line 33 of file utility.c.
{
int maj1, min1, rev1, maj2, min2, rev2, n1, n2;
if(!ver1 || !ver2) {
ERRPRINTF("Warning: bad args\n");
return 1;
}
maj1 = min1 = rev1 = maj2 = min2 = rev2 = 0;
n1 = sscanf(ver1, "%d.%d.%d", &maj1, &min1, &rev1);
n2 = sscanf(ver2, "%d.%d.%d", &maj2, &min2, &rev2);
if((n1 < 1) || (n2 < 1)) {
ERRPRINTF("Warning: malformed version number\n");
return 1;
}
return (maj1 != maj2) || (min1 != min2);
}

1.6.3-20100507