ref: 285f335215033ccc0178a34c09a22f951ef4fee4
dir: /util.c/
#include <u.h>
#include <libc.h>
#include <thread.h>
#include <ctype.h>
#include <json.h>
#include "nvi.h"
enum {
Us,
Them,
};
typedef struct Exec Exec;
struct Exec {
char *file;
char **argv;
int p[2];
Channel *pid;
};
static void
pexec(void *args)
{
Exec *e = args;
if(e->p[0] >= 0){
dup(e->p[Them], 0);
dup(e->p[Them], 1);
close(e->p[0]);
close(e->p[1]);
}else{
close(0);
close(1);
}
if(debug < 1)
close(2);
procexec(e->pid, e->file, e->argv);
}
int
pipeexec(int *fd, char *file, char **argv)
{
int pid;
Exec e;
threadwaitchan();
e.file = file;
e.argv = argv;
e.pid = chancreate(sizeof(int), 0);
e.p[0] = fd[0];
e.p[1] = fd[1];
procrfork(pexec, &e, 4096, RFFDG);
recv(e.pid, &pid);
chanfree(e.pid);
close(e.p[Them]);
if(pid < 0){
close(e.p[Us]);
return -1;
}
return e.p[Us];
}
void
procwait(void)
{
free(recvp(threadwaitchan()));
}
char *
readall(int f)
{
int bufsz, sz, n;
char *s;
bufsz = 1023;
s = nil;
for(sz = 0;; sz += n){
if(bufsz-sz < 1024){
bufsz *= 2;
s = realloc(s, bufsz);
}
if((n = readn(f, s+sz, bufsz-sz-1)) < 1)
break;
}
if(n < 0 || sz < 1){
free(s);
return nil;
}
s[sz] = 0;
return s;
}
int
hget(char *url, int out)
{
char *argv[] = {"hget", url, nil};
int p[2];
if(out >= 0){
p[0] = open("/dev/null", OREAD);
p[1] = out;
}else{
pipe(p);
}
return pipeexec(p, "/bin/hget", argv);
}
char *
estrdup(char *s)
{
if((s = strdup(s == nil ? "" : s)) == nil)
sysfatal("memory");
return s;
}
int
alldigit(char *s)
{
if(*s == 0)
return 0;
for(; *s; s++)
if(!isdigit(*s))
return 0;
return 1;
}
int
Zfmt(Fmt *f)
{
vlong z;
z = va_arg(f->args, vlong);
if(z > 1024*1024*1024)
return fmtprint(f, "%.1fGb", (double)z / (1024.0*1024.0*1024.0));
if(z > 1024*1024)
return fmtprint(f, "%.1fMb", (double)z / (1024.0*1024.0));
if(z > 1024)
return fmtprint(f, "%lldKb", z / 1024);
if(z == 0)
return fmtprint(f, "----");
return fmtprint(f, "%lld", z);
}
int
Pfmt(Fmt *f)
{
char *s, tmp[16];
u64int sec;
s = tmp;
sec = va_arg(f->args, uvlong);
if(sec >= 3600){
s = seprint(s, tmp+sizeof(tmp), "%02lld:", sec/3600);
sec %= 3600;
}
s = seprint(s, tmp+sizeof(tmp), "%02lld:", sec/60);
sec %= 60;
seprint(s, tmp+sizeof(tmp), "%02lld", sec);
return fmtstrcpy(f, tmp);
}
JSON *
jfield(JSON *j, int type, ...)
{
va_list a;
char *s;
va_start(a, type);
while((s = va_arg(a, char*)) != nil){
if((j = jsonbyname(j, s)) == nil)
break;
}
va_end(a);
return (j == nil || (type >= 0 && j->t != type)) ? nil : j;
}
char *
jstrdup(JSON *j, char *name)
{
return estrdup(jsonstr(jsonbyname(j, name)));
}
vlong
jint(JSON *j, char *name)
{
if((j = jfield(j, -1, name, nil)) != nil){
if(j->t == JSONNumber)
return j->n;
if(j->t == JSONString)
return atoll(jsonstr(j));
}
return 0;
}