Changeset dda2602 in mainline


Ignore:
Timestamp:
2019-08-03T09:41:07Z (5 years ago)
Author:
Matthieu Riolo <matthieu.riolo@…>
Children:
dd5c623
Parents:
c0e4fc50
git-author:
Michal Koutný <xm.koutny+hos@…> (2015-05-08 11:10:06)
git-committer:
Matthieu Riolo <matthieu.riolo@…> (2019-08-03 09:41:07)
Message:

sysman: Create units to start up to compositor

  • add necessary units to support basic GUI (barber, vterm)
  • lacking autostart is compensated with explicit dependencies
  • IPC_FLAG_AUTOSTART in compositor and locsrv fix
  • paths to v* binaries
  • refactored job closure creation

Conflicts:

boot/Makefile.common
uspace/app/vlaunch/vlaunch.c
uspace/srv/hid/compositor/compositor.c
uspace/srv/locsrv/locsrv.c

Location:
uspace
Files:
9 added
17 edited

Legend:

Unmodified
Added
Removed
  • uspace/cfg/sysman/logger.svc

    rc0e4fc50 rdda2602  
    11[Service]
    2 ExecStart = /srv/logger
     2ExecStart = /srv/logger warn
    33
  • uspace/cfg/sysman/rootfs.tgt

    rc0e4fc50 rdda2602  
    11[Unit]
     2; should there be this dependency?
     3; then the target could be used instead of mount in other dependencies
    24After = rootfs.mnt
     5After = rootfs.cfg
  • uspace/srv/hid/compositor/compositor.c

    rc0e4fc50 rdda2602  
    21832183        async_sess_t *sess;
    21842184        service_id_t dsid;
    2185 
    2186         errno_t rc = loc_service_get_id(svc, &dsid, 0);
     2185        unsigned int flags = IPC_FLAG_AUTOSTART;
     2186
     2187        errno_t rc = loc_service_get_id(svc, &dsid, flags);
    21872188        if (rc != EOK) {
    21882189                printf("%s: Input service %s not found\n", NAME, svc);
     
    21902191        }
    21912192
    2192         sess = loc_service_connect(dsid, INTERFACE_INPUT, 0);
     2193        sess = loc_service_connect(dsid, INTERFACE_INPUT, flags);
    21932194        if (sess == NULL) {
    21942195                printf("%s: Unable to connect to input service %s\n", NAME,
  • uspace/srv/locsrv/locsrv.c

    rc0e4fc50 rdda2602  
    359359        }
    360360
    361         printf("%s(%s) before\n", __func__, unit_name);
     361        //printf("%s(%s) before\n", __func__, unit_name);//DEBUG
    362362        int rc = sysman_unit_start(unit_name, IPC_FLAG_BLOCKING);
    363         printf("%s(%s) after %i\n", __func__, unit_name, rc);
     363        //printf("%s(%s) after %i\n", __func__, unit_name, rc);//DEBUG
    364364        free(unit_name);
    365365        free(service_name);
     
    566566        list_append(&service->server_services, &service->server->services);
    567567       
    568         printf("%s: broadcast new service '%s/%s'\n", NAME, namespace->name,
    569             service->name);
    570 
    571568        fibril_mutex_unlock(&service->server->services_mutex);
    572569        fibril_condvar_broadcast(&services_list_cv);
     
    801798        const loc_service_t *svc;
    802799        int flags = ipc_get_arg1(*icall);
     800        bool start_requested = false;
    803801       
    804802recheck:
     
    813811         */
    814812        if (svc == NULL) {
    815                 printf("%s: service '%s/%s' not found\n", NAME, ns_name, name);
     813                //printf("%s: service '%s/%s' not found\n", NAME, ns_name, name);//DEBUG
    816814                if (flags & (IPC_FLAG_AUTOSTART | IPC_FLAG_BLOCKING)) {
    817815                        /* TODO:
     
    821819                         * for ID might be someone else than those connecting)
    822820                         */
    823                         if (flags & IPC_FLAG_AUTOSTART) {
     821                        if (!start_requested && (flags & IPC_FLAG_AUTOSTART)) {
    824822                                rc = loc_service_request_start(ns_name, name);
    825823                                if (rc != EOK) {
    826824                                        goto finish;
    827825                                }
     826                                start_requested = true;
    828827                        }
    829828
     
    834833                rc = ENOENT;
    835834        } else {
    836                 printf("%s: service '%s/%s' FOUND\n", NAME, ns_name, name);
     835                //printf("%s: service '%s/%s' FOUND\n", NAME, ns_name, name);//DEBUG
    837836                rc = EOK;
    838837        }
  • uspace/srv/sysman/configuration.c

    rc0e4fc50 rdda2602  
    3838#include "log.h"
    3939
    40 static hash_table_t units;
     40LIST_INITIALIZE(units);
     41
     42static hash_table_t units_by_name;
    4143
    4244/* Hash table functions */
    43 static size_t units_ht_hash(const ht_link_t *item)
     45static size_t units_by_name_ht_hash(const ht_link_t *item)
    4446{
    4547        unit_t *unit =
    46             hash_table_get_inst(item, unit_t, units);
     48            hash_table_get_inst(item, unit_t, units_by_name);
    4749        return hash_string(unit->name);
    4850}
    4951
    50 static size_t units_ht_key_hash(void *key)
     52static size_t units_by_name_ht_key_hash(void *key)
    5153{
    5254        return hash_string((const char *)key);
    5355}
    5456
    55 static bool units_ht_equal(const ht_link_t *item1, const ht_link_t *item2)
     57static bool units_by_name_ht_equal(const ht_link_t *item1, const ht_link_t *item2)
    5658{
    5759        return str_cmp(
    58             hash_table_get_inst(item1, unit_t, units)->name,
    59             hash_table_get_inst(item2, unit_t, units)->name) == 0;
    60 }
    61 
    62 static bool units_ht_key_equal(void *key, const ht_link_t *item)
     60            hash_table_get_inst(item1, unit_t, units_by_name)->name,
     61            hash_table_get_inst(item2, unit_t, units_by_name)->name) == 0;
     62}
     63
     64static bool units_by_name_ht_key_equal(void *key, const ht_link_t *item)
    6365{
    6466        return str_cmp((const char *)key,
    65             hash_table_get_inst(item, unit_t, units)->name) == 0;
    66 }
    67 
    68 
    69 static hash_table_ops_t units_ht_ops = {
    70         .hash            = &units_ht_hash,
    71         .key_hash        = &units_ht_key_hash,
    72         .equal           = &units_ht_equal,
    73         .key_equal       = &units_ht_key_equal,
     67            hash_table_get_inst(item, unit_t, units_by_name)->name) == 0;
     68}
     69
     70
     71static hash_table_ops_t units_by_name_ht_ops = {
     72        .hash            = &units_by_name_ht_hash,
     73        .key_hash        = &units_by_name_ht_key_hash,
     74        .equal           = &units_by_name_ht_equal,
     75        .key_equal       = &units_by_name_ht_key_equal,
    7476        .remove_callback = NULL // TODO realy unneeded?
    7577};
     
    7981void configuration_init(void)
    8082{
    81         hash_table_create(&units, 0, 0, &units_ht_ops);
     83        hash_table_create(&units_by_name, 0, 0, &units_by_name_ht_ops);
    8284}
    8385
     
    8991        sysman_log(LVL_DEBUG2, "%s('%s')", __func__, unit_name(unit));
    9092
    91         if (hash_table_insert_unique(&units, &unit->units)) {
     93        if (hash_table_insert_unique(&units_by_name, &unit->units_by_name)) {
     94                list_append(&unit->units, &units);
    9295                return EOK;
    9396        } else {
     
    102105static bool configuration_commit_unit(ht_link_t *ht_link, void *arg)
    103106{
    104         unit_t *unit = hash_table_get_inst(ht_link, unit_t, units);
     107        unit_t *unit = hash_table_get_inst(ht_link, unit_t, units_by_name);
    105108        // TODO state locking?
    106109        if (unit->state == STATE_EMBRYO) {
     
    116119}
    117120
    118 /** Marks newly added units as usable (via state change) */
     121/** Marks newly added units_by_name as usable (via state change) */
    119122void configuration_commit(void)
    120123{
     
    122125
    123126        /*
    124          * Apply commit to all units, each commited unit commits its outgoing
     127         * Apply commit to all units_by_name, each commited unit commits its outgoing
    125128         * deps, thus eventually commiting all embryo deps as well.
    126129         */
    127         hash_table_apply(&units, &configuration_commit_unit, NULL);
     130        hash_table_apply(&units_by_name, &configuration_commit_unit, NULL);
    128131}
    129132
    130133static bool configuration_rollback_unit(ht_link_t *ht_link, void *arg)
    131134{
    132         unit_t *unit = hash_table_get_inst(ht_link, unit_t, units);
     135        unit_t *unit = hash_table_get_inst(ht_link, unit_t, units_by_name);
    133136
    134137        list_foreach_safe(unit->dependencies, cur_link, next_link) {
     
    141144
    142145        if (unit->state == STATE_EMBRYO) {
    143                 hash_table_remove_item(&units, ht_link);
     146                hash_table_remove_item(&units_by_name, ht_link);
     147                list_remove(&unit->units);
    144148                unit_destroy(&unit);
    145149        }
     
    148152}
    149153
    150 /** Remove all uncommited units and edges from configuratio
     154/** Remove all uncommited units_by_name and edges from configuratio
    151155 *
    152156 * Memory used by removed object is released.
     
    156160        sysman_log(LVL_DEBUG2, "%s", __func__);
    157161
    158         hash_table_apply(&units, &configuration_rollback_unit, NULL);
     162        hash_table_apply(&units_by_name, &configuration_rollback_unit, NULL);
    159163}
    160164
     
    162166{
    163167        bool *has_error_ptr = arg;
    164         unit_t *unit = hash_table_get_inst(ht_link, unit_t, units);
     168        unit_t *unit = hash_table_get_inst(ht_link, unit_t, units_by_name);
    165169
    166170        list_foreach(unit->dependencies, dependencies, unit_dependency_t, dep) {
     
    187191}
    188192
    189 /** Resolve unresolved dependencies between any pair of units
     193/** Resolve unresolved dependencies between any pair of units_by_name
    190194 *
    191195 * @return EOK      on success
     
    197201
    198202        bool has_error = false;
    199         hash_table_apply(&units, &configuration_resolve_unit, &has_error);
     203        hash_table_apply(&units_by_name, &configuration_resolve_unit, &has_error);
    200204
    201205        return has_error ? ENOENT : EOK;
     
    204208unit_t *configuration_find_unit_by_name(const char *name)
    205209{
    206         ht_link_t *ht_link = hash_table_find(&units, (void *)name);
     210        ht_link_t *ht_link = hash_table_find(&units_by_name, (void *)name);
    207211        if (ht_link != NULL) {
    208                 return hash_table_get_inst(ht_link, unit_t, units);
     212                return hash_table_get_inst(ht_link, unit_t, units_by_name);
    209213        } else {
    210214                return NULL;
  • uspace/srv/sysman/configuration.h

    rc0e4fc50 rdda2602  
    3030#define SYSMAN_CONFIGURATION_H
    3131
     32#include <adt/list.h>
     33
    3234#include "unit.h"
     35
     36extern list_t units;
    3337
    3438extern void configuration_init(void);
  • uspace/srv/sysman/connection_ctl.c

    rc0e4fc50 rdda2602  
    7878        unit_t *unit = configuration_find_unit_by_name(unit_name);
    7979        if (unit == NULL) {
     80                sysman_log(LVL_NOTE, "Unit '%s' not found.", unit_name);
    8081                retval = ENOENT;
    8182                goto answer;
  • uspace/srv/sysman/job.c

    rc0e4fc50 rdda2602  
    2727 */
    2828
    29 #include <adt/fifo.h>
     29#include <adt/list.h>
    3030#include <assert.h>
    3131#include <errno.h>
    32 
     32#include <stdlib.h>
     33
     34#include "configuration.h"
    3335#include "dep.h"
    3436#include "job.h"
     
    4244 */
    4345
    44 static int job_add_blocked_job(job_t *job, job_t *blocked_job)
    45 {
    46         int rc = dyn_array_append(&job->blocked_jobs, job_ptr_t, blocked_job);
     46static int job_add_blocked_job(job_t *blocking_job, job_t *blocked_job)
     47{
     48        int rc = dyn_array_append(&blocking_job->blocked_jobs, job_ptr_t,
     49            blocked_job);
    4750        if (rc != EOK) {
    4851                return ENOMEM;
     
    7376        assert(job);
    7477        assert(u);
     78        assert(u->job == NULL);
    7579        memset(job, 0, sizeof(*job));
    7680
     
    8286        job->unit = u;
    8387
    84         dyn_array_initialize(&job->blocked_jobs, job_ptr_t, 0);
     88        u->job = job;
     89        job_add_ref(job);
     90
     91        (void)dyn_array_initialize(&job->blocked_jobs, job_ptr_t, 0);
    8592        job->blocking_jobs = 0;
    8693        job->blocking_job_failed = false;
     
    225232int job_create_closure(job_t *main_job, dyn_array_t *job_closure)
    226233{
    227         // TODO replace hard-coded FIFO size with resizable FIFO
    228         FIFO_INITIALIZE_DYNAMIC(jobs_fifo, job_ptr_t, 10);
    229         void *fifo_data = fifo_create(jobs_fifo);
    230234        int rc;
    231         if (fifo_data == NULL) {
    232                 rc = ENOMEM;
    233                 goto finish;
    234         }
    235 
    236         /*
    237          * Traverse dependency graph in BFS fashion and create jobs for every
    238          * necessary unit.
    239          * Closure keeps reference to each job. We've to add reference to the
    240          * main job, other newly created jobs are pased to the closure.
    241          */
    242         fifo_push(jobs_fifo, main_job);
    243         job_add_ref(main_job);
    244         while (jobs_fifo.head != jobs_fifo.tail) {
    245                 job_t *job = fifo_pop(jobs_fifo);
     235        list_t units_fifo;
     236        list_initialize(&units_fifo);
     237
     238        /* Zero BFS tags before use */
     239        list_foreach(units, units, unit_t, u) {
     240                u->bfs_tag = false;
     241        }
    246242               
     243        unit_t *unit = main_job->unit;
     244        list_append(&unit->bfs_link, &units_fifo);
     245        unit->bfs_tag = true;
     246       
     247        while (!list_empty(&units_fifo)) {
     248                unit = list_get_instance(list_first(&units_fifo), unit_t,
     249                    bfs_link);
     250                assert(unit->job);
     251                list_remove(&unit->bfs_link);
     252                job_t *job = unit->job;
     253
     254
    247255                // TODO more sophisticated check? (unit that is in transitional
    248256                //      state cannot have currently multiple jobs queued)
    249                 if (job->target_state == job->unit->state) {
     257                if (job->target_state == unit->state) {
    250258                        /*
    251259                         * Job would do nothing, finish it on spot.
     
    254262                        job->retval = JOB_OK;
    255263                        job_finish(job);
    256                         job_del_ref(&job);
    257264                        continue;
    258                 } else {
    259                         /* No refcount increase, pass it to the closure */
    260                         dyn_array_append(job_closure, job_ptr_t, job);
    261265                }
    262266
    263                 /* Traverse dependencies edges */
    264                 unit_t *u = job->unit;
    265                 list_foreach(u->dependencies, dependencies, unit_dependency_t, dep) {
    266                         // TODO prepare for reverse edge direction and
    267                         //      non-identity state mapping
    268                         job_t *new_job =
    269                             job_create(dep->dependency, job->target_state);
    270                         if (new_job == NULL) {
    271                                 rc = ENOMEM;
    272                                 goto finish;
     267                job_add_ref(job);
     268                dyn_array_append(job_closure, job_ptr_t, job);
     269
     270                /*
     271                 * Traverse dependencies edges
     272                 * Depending on dependency type and edge direction create
     273                 * appropriate jobs.
     274                 */
     275                list_foreach(unit->dependencies, dependencies, unit_dependency_t, dep) {
     276                        unit_t *u = dep->dependency;
     277                        job_t *blocking_job;
     278                        if (u->bfs_tag) {
     279                                assert(u->job);
     280                                blocking_job = u->job;
     281                        } else {
     282                                u->bfs_tag = true;
     283                                blocking_job = job_create(u, job->target_state);
     284                                if (blocking_job == NULL) {
     285                                        rc = ENOMEM;
     286                                        goto finish;
     287                                }
     288                                /* Reference to job is kept in unit */
     289                                job_del_ref(&blocking_job);
     290                                list_append(&u->bfs_link, &units_fifo);
    273291                        }
    274                         job_add_blocked_job(new_job, job);
    275                         fifo_push(jobs_fifo, new_job);
     292                       
     293                        job_add_blocked_job(blocking_job, job);
    276294                }
    277295        }
     296        sysman_log(LVL_DEBUG2, "%s(%s):", __func__, unit_name(main_job->unit));
     297        dyn_array_foreach(*job_closure, job_ptr_t, job_it) {
     298                sysman_log(LVL_DEBUG2, "%s\t%s", __func__, unit_name((*job_it)->unit));
     299        }
    278300        rc = EOK;
    279301
    280302finish:
    281         free(fifo_data);
    282         /*
    283          * Newly created jobs are already passed to the closure, thus not
    284          * deleting reference to them here.
    285          */
     303        /* Any unprocessed jobs may be referenced by units */
     304        list_foreach(units_fifo, bfs_link, unit_t, u) {
     305                job_del_ref(&u->job);
     306        }
    286307        return rc;
    287308}
    288309
     310/** Create job assigned to the unit
     311 *
     312 * @param[in]  unit          unit to be modified, its job must be empty
     313 * @param[in]  target_state
     314 *
     315 * @return NULL or newly created job
     316 *         There are two references to the job, one set in the unit and second
     317 *         is the return value.
     318 */
    289319job_t *job_create(unit_t *u, unit_state_t target_state)
    290320{
     
    293323                job_init(job, u, target_state);
    294324
    295                 /* Start with one reference for the creator */
     325                /* Add one reference for the creator */
    296326                job_add_ref(job);
    297327        }
     
    354384        }
    355385        if (rc != EOK) {
     386                sysman_log(LVL_DEBUG, "%s(%p), %s -> %i, error: %i",
     387                    __func__, job, unit_name(u), job->target_state, rc);
    356388                goto fail;
    357389        }
     
    378410        assert(job->state != JOB_FINISHED);
    379411        assert(job->retval != JOB_UNDEFINED_);
     412        assert(job->unit->job == job);
    380413
    381414        sysman_log(LVL_DEBUG2, "%s(%p) %s -> %i",
     
    390423        dyn_array_clear(&job->blocked_jobs);
    391424
    392         /* Add reference for the event */
    393         job_add_ref(job);
     425        /*
     426         * Remove job from unit and pass the reference from the unit to the
     427         * event.
     428         */
     429        job->unit->job = NULL;
    394430        sysman_raise_event(&sysman_event_job_finished, job);
    395431}
  • uspace/srv/sysman/job.h

    rc0e4fc50 rdda2602  
    5454} job_retval_t;
    5555
    56 typedef struct {
     56struct job {
    5757        link_t job_queue;
    5858        atomic_t refcnt;
     
    7272        /** See job_retval_t */
    7373        job_retval_t retval;
    74 } job_t;
     74};
    7575
     76typedef struct job job_t;
    7677typedef job_t *job_ptr_t;
    7778
  • uspace/srv/sysman/sysman.c

    rc0e4fc50 rdda2602  
    151151
    152152                /* Process event */
    153                 sysman_log(LVL_DEBUG2, "process_event(%p, %p)",
    154                     event->handler, event->data);
     153                //sysman_log(LVL_DEBUG2, "process_event(%p, %p)",
     154                //    event->handler, event->data);
    155155                event->handler(event->data);
    156156                free(event);
     
    182182void sysman_raise_event(event_handler_t handler, void *data)
    183183{
    184         sysman_log(LVL_DEBUG2, "%s(%p, %p)", __func__, handler, data);
     184        //sysman_log(LVL_DEBUG2, "%s(%p, %p)", __func__, handler, data);
    185185        event_t *event = malloc(sizeof(event_t));
    186186        if (event == NULL) {
  • uspace/srv/sysman/unit.c

    rc0e4fc50 rdda2602  
    7070        unit->state = STATE_EMBRYO;
    7171
     72        link_initialize(&unit->units);
     73        link_initialize(&unit->bfs_link);
    7274        list_initialize(&unit->dependants);
    7375        list_initialize(&unit->dependencies);
     
    181183}
    182184
    183 bool unit_parse_unit_list(const char *value, void *dst, text_parse_t *parse,
     185bool unit_parse_unit_list(const char *string, void *dst, text_parse_t *parse,
    184186    size_t lineno)
    185187{
    186188        unit_t *unit = dst;
    187189        bool result;
    188         char *my_value = str_dup(value);
    189 
    190         if (!my_value) {
     190        char *my_string = str_dup(string);
     191
     192        if (!my_string) {
    191193                result = false;
    192194                goto finish;
    193195        }
    194196
    195         char *to_split = my_value;
     197        char *to_split = my_string;
    196198        char *cur_tok;
    197199
     
    206208
    207209finish:
    208         free(my_value);
     210        free(my_string);
    209211        return result;
    210212}
  • uspace/srv/sysman/unit.h

    rc0e4fc50 rdda2602  
    4242typedef enum {
    4343        UNIT_TYPE_INVALID = -1,
    44         UNIT_TARGET = 0,
     44        UNIT_CONFIGURATION = 0,
    4545        UNIT_MOUNT,
    46         UNIT_CONFIGURATION,
    47         UNIT_SERVICE
     46        UNIT_SERVICE,
     47        UNIT_TARGET
    4848} unit_type_t;
    4949
     
    5656} unit_state_t;
    5757
     58/* Forward declarations */
     59typedef struct unit_vmt unit_vmt_t;
     60struct unit_vmt;
     61
     62typedef struct job job_t;
     63struct job;
     64
    5865typedef struct {
    59         ht_link_t units;
     66        /** Link to name-to-unit hash table */
     67        ht_link_t units_by_name;
     68
     69        /** Link to list of all units */
     70        link_t units;
     71
     72        /** Link to queue, when BFS traversing units */
     73        link_t bfs_link;
     74
     75        /** Seen tag for BFS traverse, must be reset before each BFS */
     76        bool bfs_tag;
     77
     78        job_t *job;
    6079
    6180        unit_type_t type;
     
    6786        list_t dependants;
    6887} unit_t;
    69 
    70 typedef struct unit_vmt unit_vmt_t;
    71 struct unit_vmt;
    7288
    7389#include "unit_cfg.h"
  • uspace/srv/sysman/units/unit_cfg.c

    rc0e4fc50 rdda2602  
    101101        assert(u->type == unit_type);
    102102
    103         fn = compose_path(dirname, filename);
     103        fn = util_compose_path(dirname, filename);
    104104        if (fn == NULL) {
    105105                rc = ENOMEM;
  • uspace/srv/sysman/units/unit_svc.c

    rc0e4fc50 rdda2602  
    3939
    4040static config_item_t unit_configuration[] = {
    41         {"ExecStart", &config_parse_string, offsetof(unit_svc_t, exec_start), NULL},
     41        {"ExecStart", &util_parse_command, offsetof(unit_svc_t, exec_start), NULL},
    4242        CONFIGURATION_ITEM_SENTINEL
    4343};
     
    4747        unit_svc_t *u_svc = CAST_SVC(unit);
    4848        assert(u_svc);
     49        util_command_init(&u_svc->exec_start);
    4950}
    5051
     
    5455        unit_svc_t *u_svc = CAST_SVC(unit);
    5556
    56         free(u_svc->exec_start);
     57        util_command_deinit(&u_svc->exec_start);
    5758}
    5859
     
    8485        assert(unit->state == STATE_STOPPED);
    8586
    86         // TODO extend the simple implementation
    87         const char *args[] = {"warn", NULL};
    88         int rc = task_spawnv(NULL, NULL, u_svc->exec_start, args);
     87        int rc = task_spawnv(NULL, NULL, u_svc->exec_start.path,
     88            u_svc->exec_start.argv);
     89        sysman_log(LVL_DEBUG2, "task_spawn(%s, %s)", u_svc->exec_start.path, u_svc->exec_start.argv[0]);
    8990        if (rc != EOK) {
    9091                unit->state = STATE_FAILED;
     
    101102        unit->state = STATE_STARTED;
    102103
     104        /*
     105         * Workaround to see log output even after devman starts (and overrides
     106         * kernel's frame buffer. It's here since devman is started as a
     107         * service (however not all services are devman...).
     108         */
    103109        if (console_kcon()) {
    104110                sysman_log(LVL_DEBUG2, "%s: Kconsole grabbed.", __func__);
  • uspace/srv/sysman/units/unit_svc.h

    rc0e4fc50 rdda2602  
    3131
    3232#include "unit.h"
     33#include "util.h"
    3334
    3435typedef struct {
    3536        unit_t unit;
    3637
    37         char *exec_start;
    38 
     38        command_t exec_start;
    3939} unit_svc_t;
    4040
  • uspace/srv/sysman/util.c

    rc0e4fc50 rdda2602  
    3838 * @return      NULL on error
    3939 */
    40 char *compose_path(const char *dirname, const char *filename)
     40char *util_compose_path(const char *dirname, const char *filename)
    4141{
    4242        size_t size = str_size(dirname) + str_size(filename) + 2;
     
    5151        return result;
    5252}
     53
     54/** Parse command line
     55 *
     56 * @param[out]  dst      pointer to command_t
     57 *                       path and zeroth argument are the equal
     58 *
     59 * @return  true   on success
     60 * @return  false  on (low memory) error
     61 */
     62bool util_parse_command(const char *string, void *dst, text_parse_t *parse,
     63    size_t lineno)
     64{
     65        command_t *command = dst;
     66        util_command_deinit(command);
     67
     68        command->buffer = str_dup(string);
     69        if (!command->buffer) {
     70                return false;
     71        }
     72
     73        command->argc = 0;
     74        char *to_split = command->buffer;
     75        char *cur_tok;
     76        bool has_path = false;
     77
     78        while ((cur_tok = str_tok(to_split, " ", &to_split)) &&
     79            command->argc < MAX_COMMAND_ARGS) {
     80                if (!has_path) {
     81                        command->path = cur_tok;
     82                        has_path = true;
     83                }
     84                command->argv[command->argc++] = cur_tok;
     85        }
     86        command->argv[command->argc] = NULL;
     87
     88
     89        if (command->argc > MAX_COMMAND_ARGS) {
     90                text_parse_raise_error(parse, lineno,
     91                    CONFIGURATION_ELIMIT);
     92                return false;
     93        } else {
     94                return true;
     95        }
     96}
     97
     98
     99void util_command_init(command_t *command)
     100{
     101        memset(command, 0, sizeof(*command));
     102}
     103
     104void util_command_deinit(command_t *command)
     105{
     106        free(command->buffer);
     107        memset(command, 0, sizeof(*command));
     108}
  • uspace/srv/sysman/util.h

    rc0e4fc50 rdda2602  
    3030#define SYSMAN_UTIL_H
    3131
    32 extern char *compose_path(const char *, const char *);
     32#include <conf/configuration.h>
     33
     34#define MAX_COMMAND_ARGS 256
     35
     36/** Represent stuctured execute command */
     37typedef struct {
     38        /** Path to executable */
     39        const char *path;
     40        /** No. of command line arguments */
     41        size_t argc;
     42        /** NULL-terminated vector of command line arguments */
     43        const char *argv[MAX_COMMAND_ARGS + 1];
     44        /** (internal) Buffer holding raw string data */
     45        char *buffer;
     46} command_t;
     47
     48extern char *util_compose_path(const char *, const char *);
     49
     50extern bool util_parse_command(const char *, void *, text_parse_t *, size_t);
     51
     52extern void util_command_init(command_t *);
     53extern void util_command_deinit(command_t *);
    3354
    3455#endif
Note: See TracChangeset for help on using the changeset viewer.