679 lines
18 KiB
C
Executable File
679 lines
18 KiB
C
Executable File
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <errno.h>
|
|
#include <ctype.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/resource.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
|
|
#include "outlog.h"
|
|
#include "fileops.h"
|
|
#include "mjson.h"
|
|
|
|
#define BASE_JSON_PATH "/global/info/outlog/markdown/outdir"
|
|
#define DEFAULT_SAVEDIR "/mnt/UDISK/md"
|
|
#define DEFAULT_RESULT "/mnt/UDISK/md/result-list"
|
|
#define DEFAULT_REPORT_NAME "report.md"
|
|
#define PREFIX_LOG "log"
|
|
#define PREFIX_ATTR "attr"
|
|
#define SUFFIX_MD ".md"
|
|
|
|
#define TITLE_OVERVIEW "overview"
|
|
#define TITLE_ATTRIBUTE "attribute"
|
|
#define TITLE_INPUT "input"
|
|
#define TITLE_RESOURCE "resource"
|
|
#define TITLE_LOG "log"
|
|
|
|
#define RESULT_PASS "<font color=green>Pass</font>"
|
|
#define RESULT_FAILED "**<font color=red>Failed</font>**"
|
|
|
|
static char *outdir;
|
|
|
|
// get base dir
|
|
static char *md_get_outdir(void)
|
|
{
|
|
char *outdir = NULL;
|
|
if ((outdir = mjson_fetch_string(BASE_JSON_PATH)) == NULL)
|
|
outdir = DEFAULT_SAVEDIR;
|
|
|
|
if (outdir[strlen(outdir) - 1] == '/')
|
|
outdir[strlen(outdir) - 1] = '\0';
|
|
|
|
return outdir;
|
|
}
|
|
|
|
// get outlog and outattr
|
|
static int md_get_outname(char *keypath, char *outlog, int loglen, char *outattr, int attrlen)
|
|
{
|
|
int ret = -1;
|
|
if (keypath == NULL) {
|
|
ERROR("keypath is NULL\n");
|
|
goto out;
|
|
}
|
|
|
|
char *p = NULL;
|
|
|
|
// outlog
|
|
snprintf(outlog, loglen, PREFIX_LOG);
|
|
p = outlog + strlen(PREFIX_LOG);
|
|
strncpy(p, keypath, loglen - strlen(PREFIX_LOG));
|
|
while ((p = strchr(p, (int)'/')) != NULL)
|
|
*p = (char)'-';
|
|
p = outlog + strlen(outlog);
|
|
strncpy(p, SUFFIX_MD, strlen(SUFFIX_MD));
|
|
|
|
// outattr
|
|
snprintf(outattr, attrlen, PREFIX_ATTR);
|
|
p = outattr + strlen(PREFIX_ATTR);
|
|
strncpy(p, keypath, attrlen - strlen(PREFIX_ATTR));
|
|
while ((p = strchr(p, (int)'/')) != NULL)
|
|
*p = (char)'-';
|
|
p = outattr + strlen(outattr);
|
|
strncpy(p, SUFFIX_MD, strlen(SUFFIX_MD));
|
|
|
|
ret = 0;
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static inline char *strtoupper(char *str)
|
|
{
|
|
int len = strlen(str);
|
|
for (int num = 0; num < len; num++)
|
|
str[num] = toupper(str[num]);
|
|
|
|
return str;
|
|
}
|
|
|
|
static int md_get_result(const char *keypath)
|
|
{
|
|
int ret = -1;
|
|
if (is_existed(DEFAULT_RESULT) == false) {
|
|
ERROR("%s is non-existent\n", DEFAULT_RESULT);
|
|
goto err;
|
|
}
|
|
|
|
FILE *fp = fopen(DEFAULT_RESULT, "r");
|
|
if (fp == NULL) {
|
|
ERROR("open %s failed\n", DEFAULT_RESULT);
|
|
goto err;
|
|
}
|
|
|
|
char *line = NULL, *p = NULL;
|
|
size_t len = 0;
|
|
while (getline(&line, &len, fp) != -1) {
|
|
p = strchr(line, ' ');
|
|
*p = '\0';
|
|
if (strcmp(keypath, line) == 0) {
|
|
p++;
|
|
ret = atoi(p);
|
|
break;
|
|
}
|
|
}
|
|
|
|
free(line);
|
|
fclose(fp);
|
|
err:
|
|
return ret;
|
|
}
|
|
|
|
static int md_save_result(const char *keypath, int result)
|
|
{
|
|
int ret = -1;
|
|
FILE *fp = fopen(DEFAULT_RESULT, "a");
|
|
if (fp == NULL) {
|
|
ERROR("open %s failed\n", DEFAULT_RESULT);
|
|
goto err;
|
|
}
|
|
fprintf(fp, "%s %d\n", keypath, result);
|
|
fclose(fp);
|
|
|
|
ret = 0;
|
|
err:
|
|
return ret;
|
|
}
|
|
|
|
static int md_out_log(struct task *task, char *path)
|
|
{
|
|
int ret = -1;
|
|
FILE *fpout = NULL;
|
|
|
|
/* out path */
|
|
fpout = fopen(path, "w");
|
|
if (fpout == NULL) {
|
|
ERROR("open %s failed - %s\n", path, strerror(errno));
|
|
goto err;
|
|
}
|
|
|
|
/* log title */
|
|
{
|
|
char *buf = malloc(sizeof(TITLE_LOG) + 3);
|
|
if (buf == NULL) {
|
|
ERROR("malloc failed - %s\n", strerror(errno));
|
|
goto err;
|
|
}
|
|
memcpy(buf, TITLE_LOG, sizeof(TITLE_LOG));
|
|
fprintf(fpout, "### %s\n\n", strtoupper(buf));
|
|
free(buf);
|
|
}
|
|
|
|
if (NULL == task->logpath) {
|
|
fprintf(fpout, " real_time_log was set, None! \n");
|
|
} else {
|
|
char *line = NULL;
|
|
size_t len = 0, bytes = 0;
|
|
FILE *fpin = fopen(task->logpath, "r");
|
|
if (fpin == NULL) {
|
|
ERROR("open %s failed - %s\n", task->logpath, strerror(errno));
|
|
goto err;
|
|
}
|
|
|
|
while ((bytes = getline(&line, &len, fpin)) != -1) {
|
|
line[bytes - 1] = '\0';
|
|
fprintf(fpout, " %s \n", line);
|
|
}
|
|
free(line);
|
|
fclose(fpin);
|
|
}
|
|
|
|
ret = 0;
|
|
err:
|
|
fclose(fpout);
|
|
return ret;
|
|
}
|
|
|
|
static inline void md_out_attr_attribute(struct task *task, FILE *fp)
|
|
{
|
|
char *buf = malloc(sizeof(TITLE_ATTRIBUTE) + 3);
|
|
if (buf == NULL) {
|
|
ERROR("malloc failed - %s\n", strerror(errno));
|
|
return;
|
|
}
|
|
memcpy(buf, TITLE_ATTRIBUTE, sizeof(TITLE_ATTRIBUTE));
|
|
|
|
// title
|
|
fprintf(fp, "### %s\n\n", strtoupper(buf));
|
|
free(buf);
|
|
|
|
fprintf(fp, "| class | key | value |\n");
|
|
fprintf(fp, "| --- | --- | --- |\n");
|
|
fprintf(fp, "| task | command | %s |\n", task->command);
|
|
if (task->env.info.date == true) {
|
|
struct tm *tm = gmtime(&task->begin_date);
|
|
fprintf(fp, "| task | begin date | %d-%d-%d %d:%d:%d |\n",
|
|
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
|
|
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
|
tm = gmtime(&task->end_date);
|
|
fprintf(fp, "| task | end date | %d-%d-%d %d:%d:%d |\n",
|
|
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
|
|
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
|
}
|
|
switch (task->input_t) {
|
|
case TASK_NO_INPUT: {
|
|
fprintf(fp, "| task | input | none |\n");
|
|
break;
|
|
}
|
|
case TASK_STDIN: {
|
|
fprintf(fp, "| task | input | stdin |\n");
|
|
break;
|
|
}
|
|
case TASK_FSTDIN: {
|
|
fprintf(fp, "| task | input | file-stdin |\n");
|
|
break;
|
|
}
|
|
}
|
|
if (task->env.limit.may_reboot == true) {
|
|
fprintf(fp, "| task | reboot times (real/max) | %d/%d |\n",
|
|
task->rebooted_times, task->env.limit.run_times);
|
|
}
|
|
fprintf(fp, "| info | date | %s |\n",
|
|
task->env.info.date == true ? "true" : "false" );
|
|
fprintf(fp, "| info | resource | %s |\n",
|
|
task->env.info.resource == true ? "true" : "false" );
|
|
fprintf(fp, "| info | real_time_log | %s |\n",
|
|
task->env.info.real_time_log == true ? "true" : "false" );
|
|
fprintf(fp, "| limit | run_times (real/max) | %d/%d |\n",
|
|
task->run_times, task->env.limit.run_times);
|
|
fprintf(fp, "| limit | run_alone | %s |\n",
|
|
task->env.limit.run_alone == true ? "true" : "false" );
|
|
fprintf(fp, "| limit | run_parallel | %s |\n",
|
|
task->env.limit.run_parallel == true ? "true" : "false" );
|
|
fprintf(fp, "| limit | may_reboot | %s |\n",
|
|
task->env.limit.may_reboot == true ? "true" : "false" );
|
|
fprintf(fp, "| limit | testcase_run_once_time | %d |\n",
|
|
task->env.limit.testcase_run_once_time_sec);
|
|
fprintf(fp, "\n");
|
|
}
|
|
|
|
static void md_out_attr_overview(struct task *task, FILE *fp)
|
|
{
|
|
int result = 0;
|
|
struct tm *time;
|
|
char *buf = malloc(sizeof(TITLE_OVERVIEW) + 3);
|
|
if (buf == NULL) {
|
|
ERROR("malloc failed - %s\n", strerror(errno));
|
|
return;
|
|
}
|
|
memcpy(buf, TITLE_OVERVIEW, sizeof(TITLE_OVERVIEW));
|
|
|
|
// title
|
|
fprintf(fp, "### %s\n\n", strtoupper(buf));
|
|
free(buf);
|
|
|
|
fprintf(fp, "| num | pid | pgid | return | begin | end | killed by signal |\n");
|
|
fprintf(fp, "| :---: | :---: | :---: | :---: | :---: | :---: | :---: |\n");
|
|
for (int num = 0; num < task->run_times; num++) {
|
|
fprintf(fp, "| %d | %d | %d | %d |", num, -task->pid[num],
|
|
abs(task->shmem->pgid), task->result[num]);
|
|
|
|
time = gmtime(&task->begin_time[num]);
|
|
fprintf(fp, " %2.2d:%2.2d:%2.2d |", time->tm_hour, time->tm_min, time->tm_sec);
|
|
|
|
time = gmtime(&task->end_time[num]);
|
|
fprintf(fp, " %2.2d:%2.2d:%2.2d |", time->tm_hour, time->tm_min, time->tm_sec);
|
|
|
|
if (task->killed[num])
|
|
fprintf(fp, " %s(%d) |\n",
|
|
strsignal(task->killed[num]), task->killed[num]);
|
|
else
|
|
fprintf(fp, " none |\n");
|
|
|
|
// get result
|
|
if (task->result[num] != 0)
|
|
result = task->result[num];
|
|
}
|
|
fprintf(fp, "\n");
|
|
|
|
md_save_result(task->keypath, result);
|
|
}
|
|
|
|
static void md_out_attr_resource(struct task *task, FILE *fp)
|
|
{
|
|
char *buf = malloc(sizeof(TITLE_RESOURCE) + 3);
|
|
if (buf == NULL) {
|
|
ERROR("malloc failed - %s\n", strerror(errno));
|
|
return;
|
|
}
|
|
memcpy(buf, TITLE_RESOURCE, sizeof(TITLE_RESOURCE));
|
|
|
|
// title
|
|
fprintf(fp, "### %s\n\n", strtoupper(buf));
|
|
free(buf);
|
|
|
|
fprintf(fp, "| item | value |\n");
|
|
fprintf(fp, "| ---- | ---- |\n");
|
|
fprintf(fp, "| user cpu time | %ld.%ld |\n",
|
|
task->res->ru_utime.tv_sec, task->res->ru_utime.tv_usec/1000);
|
|
fprintf(fp, "| system cpu time | %ld.%ld |\n",
|
|
task->res->ru_stime.tv_sec, task->res->ru_stime.tv_usec/1000);
|
|
fprintf(fp, "| maximum resident size | %ldkB |\n",
|
|
task->res->ru_maxrss);
|
|
fprintf(fp, "| page faults break times (without I/O) | %ld |\n",
|
|
task->res->ru_minflt);
|
|
fprintf(fp, "| page faults break times (with I/O) | %ld |\n",
|
|
task->res->ru_majflt);
|
|
fprintf(fp, "| input times | %ld |\n", task->res->ru_inblock);
|
|
fprintf(fp, "| output times | %ld |\n", task->res->ru_oublock);
|
|
fprintf(fp, "| wait resource actively times | %ld |\n", task->res->ru_nvcsw);
|
|
fprintf(fp, "| wait resource passively times | %ld |\n", task->res->ru_nivcsw);
|
|
fprintf(fp, "\n");
|
|
}
|
|
|
|
static void md_out_attr_input(struct task *task, FILE *fp)
|
|
{
|
|
char *buf = malloc(sizeof(TITLE_INPUT) + 3);
|
|
if (buf == NULL) {
|
|
ERROR("malloc failed - %s\n", strerror(errno));
|
|
return;
|
|
}
|
|
memcpy(buf, TITLE_INPUT, sizeof(TITLE_INPUT));
|
|
|
|
// title
|
|
fprintf(fp, "### %s\n\n", strtoupper(buf));
|
|
free(buf);
|
|
|
|
switch (task->input_t) {
|
|
case TASK_NO_INPUT: {
|
|
break;
|
|
}
|
|
case TASK_STDIN: {
|
|
char **p = (char **)task->input;
|
|
int cnt = atoi(p[0]);
|
|
for (int num = 1; num <= cnt; num++)
|
|
fprintf(fp, " %s \n", p[num]);
|
|
break;
|
|
}
|
|
case TASK_FSTDIN: {
|
|
char *line = NULL;
|
|
size_t len = 0, bytes = 0;
|
|
FILE *fin = fopen((char *)task->input, "r");
|
|
if (fin != NULL) {
|
|
while ((bytes = getline(&line, &len, fin)) != -1) {
|
|
line[bytes - 1] = '\0';
|
|
fprintf(fp, " %s \n", line);
|
|
}
|
|
} else {
|
|
fprintf(fp, "ERROR");
|
|
ERROR("open %s failed - %s\n", (char *)task->input, strerror(errno));
|
|
}
|
|
free(line);
|
|
fclose(fin);
|
|
break;
|
|
}
|
|
}
|
|
fprintf(fp, "\n");
|
|
}
|
|
|
|
static int md_out_attr(struct task *task, char *path)
|
|
{
|
|
int ret = -1;
|
|
FILE *fp = NULL;
|
|
fp = fopen(path, "w");
|
|
if (fp == NULL) {
|
|
ERROR("open %s failed - %s\n", path, strerror(errno));
|
|
goto err;
|
|
}
|
|
|
|
// title
|
|
fprintf(fp, "## %s\n", task->keypath);
|
|
|
|
// result
|
|
md_out_attr_overview(task, fp);
|
|
// attr
|
|
md_out_attr_attribute(task, fp);
|
|
// resource
|
|
if (task->env.info.resource == true
|
|
&& task->res != NULL) {
|
|
md_out_attr_resource(task, fp);
|
|
}
|
|
// input
|
|
if (task->input_t != TASK_NO_INPUT) {
|
|
md_out_attr_input(task, fp);
|
|
}
|
|
|
|
ret = 0;
|
|
err:
|
|
fclose(fp);
|
|
return ret;
|
|
}
|
|
|
|
static inline void md_del_char(char *s, int c)
|
|
{
|
|
int j,k;
|
|
for(j=k=0; s[j]!='\0'; j++)
|
|
if(s[j]!=(char )c)
|
|
s[k++]=s[j];
|
|
s[k]= '\0';
|
|
}
|
|
|
|
static int md_report_detail(struct list_head *TASK_LIST, FILE *fp)
|
|
{
|
|
int ret = -1;
|
|
char *outlog = NULL, *outattr = NULL, *path = NULL;
|
|
int outlen = 1000;
|
|
int len = strlen(outdir) + outlen;
|
|
int from = -1, to = fileno(fp);
|
|
|
|
outlog = calloc(1, outlen);
|
|
outattr = calloc(1, outlen);
|
|
path = calloc(1, len);
|
|
if (outlog == NULL || outattr == NULL || path == NULL) {
|
|
ERROR("malloc failed - %s\n", strerror(errno));
|
|
goto err;
|
|
}
|
|
|
|
fprintf(fp, "# DETAIL\n");
|
|
struct task *task = NULL;
|
|
list_for_each_entry(task, TASK_LIST, lnode) {
|
|
if (md_get_outname(task->keypath, outlog, outlen, outattr, outlen) < 0)
|
|
continue;
|
|
|
|
// outattr
|
|
snprintf(path, len, "%s/%s", outdir, outattr);
|
|
if (is_existed(path) == false) {
|
|
ERROR("not found %s\n", path);
|
|
goto err;
|
|
}
|
|
from = open(path, O_RDONLY);
|
|
if (from < 0) {
|
|
ERROR("open %s failed - %s\n", path, strerror(errno));
|
|
goto err;
|
|
}
|
|
|
|
fprintf(fp, "\n");
|
|
fflush(fp);
|
|
cp_fd(from, to);
|
|
close(from);
|
|
|
|
// outlog
|
|
snprintf(path, len, "%s/%s", outdir, outlog);
|
|
if (is_existed(path) == false) {
|
|
ERROR("not found %s\n", path);
|
|
goto err;
|
|
}
|
|
from = open(path, O_RDONLY);
|
|
if (from < 0) {
|
|
ERROR("open %s failed - %s\n", path, strerror(errno));
|
|
goto err;
|
|
}
|
|
|
|
fprintf(fp, "\n");
|
|
fflush(fp);
|
|
cp_fd(from, to);
|
|
close(from);
|
|
|
|
from = -1;
|
|
}
|
|
|
|
ret = 0;
|
|
err:
|
|
free(path);
|
|
free(outlog);
|
|
free(outattr);
|
|
close(from);
|
|
return ret;
|
|
}
|
|
|
|
static int md_report_summary(struct list_head *TASK_LIST, FILE *fp)
|
|
{
|
|
int result = 0;
|
|
int cnt = 0;
|
|
int ret = -1;
|
|
int len = 1000;
|
|
char *suffix = NULL, *link = NULL;
|
|
|
|
suffix = malloc(len);
|
|
link = malloc(len);
|
|
if (suffix == NULL || link == NULL) {
|
|
ERROR("malloc failed - %s\n", strerror(errno));
|
|
goto err;
|
|
}
|
|
|
|
fprintf(fp, "# REPORT\n\n");
|
|
fprintf(fp, "| testcase | result | overview | attribute | resource | input | log |\n");
|
|
fprintf(fp, "| :--- | :---: | :---: | :---: | :---: | :---: | :---: |\n");
|
|
|
|
struct task *task = NULL;
|
|
list_for_each_entry(task, TASK_LIST, lnode) {
|
|
// get result
|
|
// we can't use task->result because it was reset after rebooting
|
|
result = md_get_result(task->keypath);
|
|
DEBUG(DATA, "%s: result is %d\n", task->keypath, result);
|
|
|
|
// init suffix
|
|
if (cnt == 0)
|
|
*suffix = '\0';
|
|
else
|
|
snprintf(suffix, len, "-%d", cnt);
|
|
|
|
// init link
|
|
snprintf(link, len, "%s", task->keypath);
|
|
md_del_char(link, '/');
|
|
|
|
// testcase && result && overview && attribute
|
|
fprintf(fp, "| [%s](#%s) | %s | [view](#%s%s) | [attr](#%s%s) |",
|
|
task->keypath, link, result == 0 ? RESULT_PASS : RESULT_FAILED,
|
|
TITLE_OVERVIEW, suffix,
|
|
TITLE_ATTRIBUTE, suffix);
|
|
|
|
// resource
|
|
if (task->env.info.resource == true
|
|
&& task->res != NULL)
|
|
fprintf(fp, " [res](#%s%s) |", TITLE_RESOURCE, suffix);
|
|
else
|
|
fprintf(fp, " none |");
|
|
|
|
// input
|
|
if (task->input_t != TASK_NO_INPUT)
|
|
fprintf(fp, " [input](#%s%s) |", TITLE_INPUT, suffix);
|
|
else
|
|
fprintf(fp, " none |");
|
|
|
|
// log
|
|
fprintf(fp, " [log](#%s%s) |", TITLE_LOG, suffix);
|
|
|
|
fprintf(fp, "\n");
|
|
cnt++;
|
|
}
|
|
|
|
fprintf(fp, "\n");
|
|
ret = 0;
|
|
err:
|
|
free(link);
|
|
free(suffix);
|
|
return ret;
|
|
}
|
|
|
|
static int md_report(struct list_head *TASK_LIST, char *path)
|
|
{
|
|
int ret = -1;
|
|
FILE *fp = NULL;
|
|
fp = fopen(path, "w");
|
|
if (fp == NULL) {
|
|
ERROR("open %s failed - %s\n", path, strerror(errno));
|
|
goto err;
|
|
}
|
|
|
|
// summary
|
|
if (md_report_summary(TASK_LIST, fp) < 0)
|
|
ERROR("markdown: report summary failed\n");
|
|
// detail
|
|
if (md_report_detail(TASK_LIST, fp) < 0)
|
|
ERROR("markdown: report detail failed\n");
|
|
|
|
ret = 0;
|
|
err:
|
|
fclose(fp);
|
|
return ret;
|
|
}
|
|
|
|
|
|
int md_after_one(struct task *task)
|
|
{
|
|
int ret = -1;
|
|
char *path = NULL;
|
|
char *outlog = NULL, *outattr = NULL;
|
|
if (task == NULL) {
|
|
ERROR("no task infomations\n");
|
|
goto err;
|
|
}
|
|
int outlen = strlen(task->keypath) + 30;
|
|
outlog = calloc(1, outlen);
|
|
outattr = calloc(1, outlen);
|
|
if (outlog == NULL || outattr == NULL) {
|
|
ERROR("malloc failed - %s\n", strerror(errno));
|
|
goto err;
|
|
}
|
|
|
|
DEBUG(BASE, "markdown: after one : %s\n", task->keypath);
|
|
// init outlog outattr
|
|
if (md_get_outname(task->keypath, outlog, outlen, outattr, outlen) < 0)
|
|
goto err;
|
|
DEBUG(DATA, "%s: outlog set to %s/%s\n", task->keypath, outdir, outlog);
|
|
DEBUG(DATA, "%s: outattr set to %s/%s\n", task->keypath, outdir, outattr);
|
|
|
|
int len = strlen(outdir) + 10 + strlen(task->keypath) +
|
|
(sizeof(PREFIX_LOG) > sizeof(PREFIX_ATTR) ? sizeof(PREFIX_LOG) : sizeof(PREFIX_ATTR));
|
|
path = malloc(len);
|
|
if (path == NULL) {
|
|
ERROR("%s: malloc failed - %s\n", task->keypath, strerror(errno));
|
|
goto err;
|
|
}
|
|
|
|
// get outattr
|
|
snprintf(path, len, "%s/%s", outdir, outattr);
|
|
DEBUG(BASE, "%s: print attrtbutes to %s\n", task->keypath, path);
|
|
if (md_out_attr(task, path) < 0) {
|
|
ERROR("%s: print attrtbutes failed\n", task->keypath);
|
|
goto err;
|
|
}
|
|
|
|
// get outlog
|
|
snprintf(path, len, "%s/%s", outdir, outlog);
|
|
DEBUG(BASE, "%s: print log to %s\n", task->keypath, path);
|
|
if (md_out_log(task, path) < 0) {
|
|
ERROR("%s: print log failed\n", task->keypath);
|
|
goto err;
|
|
}
|
|
|
|
DEBUG(BASE, "markdown: after one : %s exit\n", task->keypath);
|
|
|
|
ret = 0;
|
|
err:
|
|
free(path);
|
|
free(outlog);
|
|
free(outattr);
|
|
return ret;
|
|
}
|
|
|
|
int md_after_all(struct list_head *TASK_LIST)
|
|
{
|
|
int ret = -1;
|
|
char *path = NULL;
|
|
if (TASK_LIST == NULL) {
|
|
ERROR("TASK_LIST NULL\n");
|
|
goto err;
|
|
}
|
|
|
|
DEBUG(BASE, "markdown: after all\n");
|
|
int len = strlen(outdir) + sizeof(DEFAULT_REPORT_NAME) + 5;
|
|
path = malloc(len);
|
|
if (path == NULL) {
|
|
ERROR("malloc failed - %s\n", strerror(errno));
|
|
goto err;
|
|
}
|
|
snprintf(path, len, "%s/%s", outdir, DEFAULT_REPORT_NAME);
|
|
|
|
if (md_report(TASK_LIST, path) < 0) {
|
|
ERROR("print report failed\n");
|
|
goto err;
|
|
}
|
|
DEBUG(BASE, "markdown: after all exit\n");
|
|
|
|
ret = 0;
|
|
err:
|
|
remove(DEFAULT_RESULT);
|
|
free(path);
|
|
return ret;
|
|
}
|
|
|
|
void module_init(void) {
|
|
outdir = md_get_outdir();
|
|
DEBUG(DATA, "outlog_markdown: outdir is %s\n", outdir);
|
|
if (mkdir_p(outdir) < 0) {
|
|
ERROR("mkdir %s failed \n", outdir);
|
|
ERROR("init outlog module markdown failed\n");
|
|
return;
|
|
}
|
|
|
|
outlog_register(
|
|
NULL,
|
|
NULL,
|
|
md_after_one,
|
|
md_after_all);
|
|
}
|