コード例 #1
0
ファイル: file.c プロジェクト: fxstein/sky
// Recursively copies a directory.
//
// src  - The path of the file or directory to copy.
// dest - The path where the copy should be placed.
//
// Returns 0 if successful, otherwise returns -1.
int sky_file_cp_r(bstring src, bstring dest)
{
    int rc;
    bstring ent_src = NULL;
    bstring ent_dest = NULL;
    check(src != NULL, "Source path required");
    check(dest != NULL, "Destination path required");
    check(sky_file_exists(src), "Source file does not exist");

    // If this is a directory then create a new dest directory and copy the
    // contents.
    if(sky_file_is_dir(src)) {
        // Create destination directory if it doesn't exist.
        if(!sky_file_exists(dest)) {
            struct stat st;
            rc = stat(bdatae(src, ""), &st);
            check(rc == 0, "Unable to stat source directory: %s", bdatae(src, ""));
            rc = mkdir(bdatae(dest, ""), st.st_mode);
            check(rc == 0, "Unable to create directory: %s", bdatae(dest, ""));
        }
        
        // Open directory.
        DIR *dir = opendir(bdatae(src, ""));
        check(dir != NULL, "Unable to open directory: %s", bdatae(src, ""));
        
        // Copy over contents of directory.
        struct dirent *ent;
        while((ent = readdir(dir))) {
            if(strcmp(ent->d_name, ".") != 0 && strcmp(ent->d_name, "..") != 0) {
                ent_src  = bformat("%s/%s", bdatae(src, ""), ent->d_name); check_mem(ent_src);
                ent_dest = bformat("%s/%s", bdatae(dest, ""), ent->d_name); check_mem(ent_dest);

                rc = sky_file_cp_r(ent_src, ent_dest);
                check(rc == 0, "Unable to copy: %s", bdatae(ent_src, ""));

                bdestroy(ent_src);
                bdestroy(ent_dest);
            }
        }
        
        // Close directory.
        closedir(dir);
    }
    // If this is a file then copy its contents.
    else {
        rc = sky_file_cp(src, dest);
        check(rc == 0, "Unable to copy file: %s", bdatae(src, ""));
    }
    
    return 0;

error:
    bdestroy(ent_src);
    bdestroy(ent_dest);
    return -1;
}
コード例 #2
0
ファイル: file.c プロジェクト: fxstein/sky
// Retrieves the size of a file, in bytes.
//
// path - The path of the file.
//
// Returns the size of the file at the given path in bytes.
off_t sky_file_get_size(bstring path)
{
    struct stat buffer;
    if(stat(bdatae(path, ""), &buffer) == 0) {
        return buffer.st_size;
    }
    else {
        return 0;
    }
}
コード例 #3
0
ファイル: procer.c プロジェクト: 304471720/mongrel2
int Action_exec(Action *action, Profile *prof)
{
    int rc = 0;
    char *procer_run_log = NULL;

    bstring pidfile_env = bformat("PROCER_PIDFILE=%s", bdata(prof->pid_file)); 
    putenv(bdata(pidfile_env));

    bstring action_env = bformat("PROCER_ACTION=%s", bdata(action->name)); 
    putenv(bdata(action_env));

    debug("ACTION: command=%s, pid_file=%s, restart=%d, depends=%s",
            bdata(prof->command), bdata(prof->pid_file), prof->restart,
            bdata(action->depends));

    pid_t pid = fork();
    check(pid >= 0, "Fork failed, WTF.  How can fork fail?");

    if(pid == 0) {
        rc = Unixy_drop_priv(action->profile_dir);

        if(rc != 0) {
            log_err("Not fatal, but we couldn't drop priv for %s",
                    bdata(action->name));
        }

        if( (procer_run_log = getenv("PROCER_RUN_LOG")) == NULL)
            procer_run_log = "run.log";
        redirect_output(procer_run_log);

        rc = execle(bdatae(prof->command, ""), bdatae(prof->command, ""), NULL, environ);
        check(rc != -1, "Failed to exec command: %s", bdata(prof->command));
    } else {
        int status = 0;
        debug("WAITING FOR CHILD.");
        pid = waitpid(pid, &status, 0);
    }

    debug("Command ran and exited successfully, now looking for the PID file.");
    return 0;
error:
    return -1;
}
コード例 #4
0
ファイル: file.c プロジェクト: fxstein/sky
// Checks if a file is a directory.
//
// path - The path of the file.
//
// Returns true if the file at the given path is a directory. Otherwise
// returns false.
bool sky_file_is_dir(bstring path)
{
    struct stat buffer;
    int rc = stat(bdatae(path, ""), &buffer);
    if(rc == 0) {
        return S_ISDIR(buffer.st_mode);
    }
    else {
        return false;
    }
}
コード例 #5
0
ファイル: procer.c プロジェクト: 304471720/mongrel2
void Action_task(void *v)
{
    Action *action = (Action *)v;
    int rc = 0;
    pid_t child = 0;
    Profile *prof = Profile_load(action->profile_dir);

    taskname(bdata(action->name));

    taskstate("depends");
    rc = Rampart_wait(action->before);
    check(rc != -1, "A dependency failed to start, we can't start.");

    Rampart_running(&action->after);

    taskstate("ready");
    debug("STARTED %s", bdata(action->name));

    while(RUNNING) {
        taskstate("starting");

        if(Unixy_still_running(prof->pid_file, &child)) {
            debug("Looks like %s is already running, we'll just leave it alone.", bdata(action->name));
        } else {
            Unixy_remove_dead_pidfile(prof->pid_file);
            Action_exec(action, prof);
        }

        if(access(bdatae(prof->pid_file, ""), R_OK) != 0) {
            log_warn("%s didn't make pidfile %s. Waiting then trying again.", 
                bdata(action->name), bdata(prof->pid_file));
            Action_sleep(2);
        }

        taskstate("waiting");
        while(Unixy_still_running(prof->pid_file, &child) && RUNNING) {
            Action_sleep(1);
        }

        if(!prof->restart) {
            break;
        }

        taskstate("restarting");
        Action_sleep(1);
    }

    debug("ACTION %s exited.", bdata(action->name));

error:
    Rampart_failed(&action->after);
    return;
}
コード例 #6
0
ファイル: file.c プロジェクト: fxstein/sky
// Copies a single file from the source path to the destination path.
//
// src  - The path of the file to copy.
// dest - The path where the copy should be placed.
//
// Returns 0 if successful, otherwise returns -1.
int sky_file_cp(bstring src, bstring dest)
{
    int rc;
    check(src != NULL, "Source path required");
    check(dest != NULL, "Destination path required");
    check(sky_file_exists(src), "Source file does not exist");
    check(!sky_file_is_dir(src), "Source file cannot be a directory");

    // Open source files.
    FILE *src_file = fopen(bdatae(src, ""), "r");
    check(src_file != NULL, "Unable to open source file for reading");

    // Open destination file.
    FILE *dest_file = fopen(bdatae(dest, ""), "w");
    check(dest_file != NULL, "Unable to open destination file for writing");
    
    // Read from source and write to destination until done.
    while(!feof(src_file)) {
        int buffer_size = 1024;
        char *buffer[buffer_size];
        
        size_t sz = fread(buffer, sizeof(char), buffer_size, src_file);
        fwrite(buffer, sizeof(char), sz, dest_file);
    }
    
    // Close files.
    fclose(src_file);
    fclose(dest_file);
    
    // Copy permissions to destination file.
    struct stat st;
    stat(bdatae(src, ""), &st);
    rc = chmod(bdatae(dest, ""), st.st_mode);
    check(rc == 0, "Unable to copy permissions");
    
    return 0;

error:
    return -1;
}
コード例 #7
0
ファイル: file.c プロジェクト: fxstein/sky
// Deletes a single file.
//
// path - The path of the file to delete.
//
// Returns 0 if successful, otherwise returns -1.
int sky_file_rm(bstring path)
{
    int rc;
    check(path != NULL, "Path required");
    check(!sky_file_is_dir(path), "File cannot be a directory");

    if(sky_file_exists(path)) {
        rc = remove(bdatae(path, ""));
        check(rc == 0, "Unable to delete file");
    }

    return 0;

error:
    return -1;
}
コード例 #8
0
ファイル: lua_aggregate_message.c プロジェクト: fxstein/sky
// Writes the results to an output stream.
//
// worker - The worker.
// output - The output stream.
//
// Returns 0 if successful, otherwise returns -1.
int sky_lua_aggregate_message_worker_write(sky_worker *worker, FILE *output)
{
    size_t sz;
    assert(worker != NULL);
    assert(output != NULL);
    
    // Ease-of-use references.
    sky_lua_aggregate_message *message = (sky_lua_aggregate_message*)worker->data;

    // Return.
    //   {status:"ok", data:{<action_id>:{count:0}, ...}}
    check(minipack_fwrite_map(output, 2, &sz) == 0, "Unable to write root map");
    check(sky_minipack_fwrite_bstring(output, &SKY_LUA_AGGREGATE_STATUS_STR) == 0, "Unable to write status key");
    check(sky_minipack_fwrite_bstring(output, &SKY_LUA_AGGREGATE_OK_STR) == 0, "Unable to write status value");
    check(sky_minipack_fwrite_bstring(output, &SKY_LUA_AGGREGATE_DATA_STR) == 0, "Unable to write data key");
    check(fwrite(bdatae(message->results, ""), blength(message->results), 1, output) == 1, "Unable to write data value");
    
    return 0;

error:
    return -1;
}
コード例 #9
0
ファイル: file.c プロジェクト: fxstein/sky
// Recursively deletes a file or directory.
//
// path  - The path of the file or directory to delete.
//
// Returns 0 if successful, otherwise returns -1.
int sky_file_rm_r(bstring path)
{
    int rc;
    bstring ent_path = NULL;
    check(path != NULL, "Path required");
    
    // If path doesn't exist then just ignore it.
    if(sky_file_exists(path)) {
        // If the file is a directory then delete its contents first and then
        // delete it.
        if(sky_file_is_dir(path)) {
            // Open directory.
            DIR *dir = opendir(bdatae(path, ""));
            check(dir != NULL, "Unable to open directory: %s", bdatae(path, ""));

            // Remove each file inside directory.
            struct dirent *ent;
            while((ent = readdir(dir))) {
                if(strcmp(ent->d_name, ".") != 0 && strcmp(ent->d_name, "..") != 0) {
                    ent_path  = bformat("%s/%s", bdatae(path, ""), ent->d_name); check_mem(ent_path);
                    rc = sky_file_rm_r(ent_path);
                    check(rc == 0, "Unable to delete: %s", bdatae(ent_path, ""));
                    bdestroy(ent_path);
                }
            }

            // Close directory.
            closedir(dir);

            // Remove directory.
            remove(bdatae(path, ""));
        }
        // If this is a file then delete it.
        else {
            rc = sky_file_rm(path);
            check(rc == 0, "Unable to delete file: %s", bdatae(path, ""));
        }
    }
    
    return 0;

error:
    bdestroy(ent_path);
    return -1;
}
コード例 #10
0
ファイル: block.c プロジェクト: dasfaha/sky
// Creates the LLVM block for this AST but does not generate the statements.
//
// node    - The node to generate an LLVM value for.
// module  - The compilation unit this node is a part of.
// block   - A pointer to where the LLVM basic block should be returned.
//
// Returns 0 if successful, otherwise returns -1.
int qip_ast_block_codegen_block(qip_ast_node *node, qip_module *module, 
                                LLVMBasicBlockRef *block)
{
    int rc;
    check(node != NULL, "Node required");
    check(node->type == QIP_AST_TYPE_BLOCK, "Node type expected to be 'block'");
    check(node->parent != NULL, "Node parent required");
    check(module != NULL, "Module required");
    
    // Retrieve current function scope.
    qip_scope *scope = NULL;
    rc = qip_module_get_current_function_scope(module, &scope);
    check(rc == 0 && scope != NULL, "Unable to retrieve current function scope");

    // Create LLVM block.
    *block = LLVMAppendBasicBlock(scope->llvm_function, bdatae(node->block.name, ""));
    
    return 0;
    
error:
    *block = NULL;
    return -1;
}
コード例 #11
0
ファイル: block.c プロジェクト: dasfaha/sky
// Append the contents of the AST node to the string.
// 
// node - The node to dump.
// ret  - A pointer to the bstring to concatenate to.
//
// Return 0 if successful, otherwise returns -1.s
int qip_ast_block_dump(qip_ast_node *node, bstring ret)
{
    int rc;
    check(node != NULL, "Node required");
    check(ret != NULL, "String required");

    // Append dump.
    bstring str = bformat("<block name='%s'>\n", bdatae(node->block.name, ""));
    check_mem(str);
    check(bconcat(ret, str) == BSTR_OK, "Unable to append dump");

    // Recursively dump children
    unsigned int i;
    for(i=0; i<node->block.expr_count; i++) {
        rc = qip_ast_node_dump(node->block.exprs[i], ret);
        check(rc == 0, "Unable to dump block expression");
    }

    return 0;

error:
    if(str != NULL) bdestroy(str);
    return -1;
}
コード例 #12
0
ファイル: file.c プロジェクト: fxstein/sky
// Checks if a file exists.
//
// path - The path of the file.
//
// Returns true if the file at the given path exists. Otherwise returns false.
bool sky_file_exists(bstring path)
{
    struct stat buffer;
    int rc = stat(bdatae(path, ""), &buffer);
    return (rc == 0);
}