Changeset fbcfc4da in mainline for uspace


Ignore:
Timestamp:
2009-12-03T19:25:17Z (16 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
9510be2
Parents:
cb3d641a (diff), 22e6802 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes.

Location:
uspace
Files:
1 added
28 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/bdsh/input.c

    rcb3d641a rfbcfc4da  
    3838#include <vfs/vfs.h>
    3939#include <errno.h>
     40#include <assert.h>
    4041#include <bool.h>
    4142
     
    4748#include "exec.h"
    4849
    49 static void read_line(char *, int);
     50#define HISTORY_LEN 10
     51
     52typedef struct {
     53        wchar_t buffer[INPUT_MAX];
     54        int col0, row0;
     55        int con_cols, con_rows;
     56        int nc;
     57        int pos;
     58
     59        char *history[1 + HISTORY_LEN];
     60        int hnum;
     61        int hpos;
     62} tinput_t;
     63
     64typedef enum {
     65        seek_backward = -1,
     66        seek_forward = 1
     67} seek_dir_t;
     68
     69static tinput_t tinput;
     70
     71static char *tinput_read(tinput_t *ti);
    5072
    5173/* Tokenizes input from console, sees if the first word is a built-in, if so
     
    99121}
    100122
    101 static void read_line(char *buffer, int n)
     123static void tinput_display_tail(tinput_t *ti, int start, int pad)
     124{
     125        int i;
     126
     127        console_goto(fphone(stdout), (ti->col0 + start) % ti->con_cols,
     128            ti->row0 + (ti->col0 + start) / ti->con_cols);
     129        printf("%ls", ti->buffer + start);
     130        for (i = 0; i < pad; ++i)
     131                putchar(' ');
     132        fflush(stdout);
     133}
     134
     135static char *tinput_get_str(tinput_t *ti)
     136{
     137        return wstr_to_astr(ti->buffer);
     138}
     139
     140static void tinput_position_caret(tinput_t *ti)
     141{
     142        console_goto(fphone(stdout), (ti->col0 + ti->pos) % ti->con_cols,
     143            ti->row0 + (ti->col0 + ti->pos) / ti->con_cols);
     144}
     145
     146/** Update row0 in case the screen could have scrolled. */
     147static void tinput_update_origin(tinput_t *ti)
     148{
     149        int width, rows;
     150
     151        width = ti->col0 + ti->nc;
     152        rows = (width / ti->con_cols) + 1;
     153 
     154        /* Update row0 if the screen scrolled. */
     155        if (ti->row0 + rows > ti->con_rows)
     156                ti->row0 = ti->con_rows - rows;
     157}
     158
     159static void tinput_insert_char(tinput_t *ti, wchar_t c)
     160{
     161        int i;
     162        int new_width, new_height;
     163
     164        if (ti->nc == INPUT_MAX)
     165                return;
     166
     167        new_width = ti->col0 + ti->nc + 1;
     168        if (new_width % ti->con_cols == 0) {
     169                /* Advancing to new line. */
     170                new_height = (new_width / ti->con_cols) + 1;
     171                if (new_height >= ti->con_rows)
     172                        return; /* Disallow text longer than 1 page for now. */
     173        }
     174
     175        for (i = ti->nc; i > ti->pos; --i)
     176                ti->buffer[i] = ti->buffer[i - 1];
     177
     178        ti->buffer[ti->pos] = c;
     179        ti->pos += 1;
     180        ti->nc += 1;
     181        ti->buffer[ti->nc] = '\0';
     182
     183        tinput_display_tail(ti, ti->pos - 1, 0);
     184        tinput_update_origin(ti);
     185        tinput_position_caret(ti);
     186}
     187
     188static void tinput_backspace(tinput_t *ti)
     189{
     190        int i;
     191
     192        if (ti->pos == 0)
     193                return;
     194
     195        for (i = ti->pos; i < ti->nc; ++i)
     196                ti->buffer[i - 1] = ti->buffer[i];
     197        ti->pos -= 1;
     198        ti->nc -= 1;
     199        ti->buffer[ti->nc] = '\0';
     200
     201        tinput_display_tail(ti, ti->pos, 1);
     202        tinput_position_caret(ti);
     203}
     204
     205static void tinput_delete(tinput_t *ti)
     206{
     207        if (ti->pos == ti->nc)
     208                return;
     209
     210        ti->pos += 1;
     211        tinput_backspace(ti);
     212}
     213
     214static void tinput_seek_cell(tinput_t *ti, seek_dir_t dir)
     215{
     216        if (dir == seek_forward) {
     217                if (ti->pos < ti->nc)
     218                        ti->pos += 1;
     219        } else {
     220                if (ti->pos > 0)
     221                        ti->pos -= 1;
     222        }
     223
     224        tinput_position_caret(ti);
     225}
     226
     227static void tinput_seek_word(tinput_t *ti, seek_dir_t dir)
     228{
     229        if (dir == seek_forward) {
     230                if (ti->pos == ti->nc)
     231                        return;
     232
     233                while (1) {
     234                        ti->pos += 1;
     235
     236                        if (ti->pos == ti->nc)
     237                                break;
     238
     239                        if (ti->buffer[ti->pos - 1] == ' ' &&
     240                            ti->buffer[ti->pos] != ' ')
     241                                break;
     242                }
     243        } else {
     244                if (ti->pos == 0)
     245                        return;
     246
     247                while (1) {
     248                        ti->pos -= 1;
     249
     250                        if (ti->pos == 0)
     251                                break;
     252
     253                        if (ti->buffer[ti->pos - 1] == ' ' &&
     254                            ti->buffer[ti->pos] != ' ')
     255                                break;
     256                }
     257
     258        }
     259
     260        tinput_position_caret(ti);
     261}
     262
     263static void tinput_seek_vertical(tinput_t *ti, seek_dir_t dir)
     264{
     265        if (dir == seek_forward) {
     266                if (ti->pos + ti->con_cols <= ti->nc)
     267                        ti->pos = ti->pos + ti->con_cols;
     268        } else {
     269                if (ti->pos - ti->con_cols >= 0)
     270                        ti->pos = ti->pos - ti->con_cols;
     271        }
     272
     273        tinput_position_caret(ti);
     274}
     275
     276static void tinput_seek_max(tinput_t *ti, seek_dir_t dir)
     277{
     278        if (dir == seek_backward)
     279                ti->pos = 0;
     280        else
     281                ti->pos = ti->nc;
     282
     283        tinput_position_caret(ti);
     284}
     285
     286static void tinput_history_insert(tinput_t *ti, char *str)
     287{
     288        int i;
     289
     290        if (ti->hnum < HISTORY_LEN) {
     291                ti->hnum += 1;
     292        } else {
     293                if (ti->history[HISTORY_LEN] != NULL)
     294                        free(ti->history[HISTORY_LEN]);
     295        }
     296
     297        for (i = ti->hnum; i > 1; --i)
     298                ti->history[i] = ti->history[i - 1];
     299
     300        ti->history[1] = str_dup(str);
     301
     302        if (ti->history[0] != NULL) {
     303                free(ti->history[0]);
     304                ti->history[0] = NULL;
     305        }
     306}
     307
     308static void tinput_set_str(tinput_t *ti, char *str)
     309{
     310        str_to_wstr(ti->buffer, INPUT_MAX, str);
     311        ti->nc = wstr_length(ti->buffer);
     312        ti->pos = ti->nc;
     313}
     314
     315static void tinput_history_seek(tinput_t *ti, int offs)
     316{
     317        int pad;
     318
     319        if (ti->hpos + offs < 0 || ti->hpos + offs > ti->hnum)
     320                return;
     321
     322        if (ti->history[ti->hpos] != NULL) {
     323                free(ti->history[ti->hpos]);
     324                ti->history[ti->hpos] = NULL;
     325        }
     326
     327        ti->history[ti->hpos] = tinput_get_str(ti);
     328        ti->hpos += offs;
     329
     330        pad = ti->nc - str_length(ti->history[ti->hpos]);
     331        if (pad < 0) pad = 0;
     332
     333        tinput_set_str(ti, ti->history[ti->hpos]);
     334        tinput_display_tail(ti, 0, pad);
     335        tinput_update_origin(ti);
     336        tinput_position_caret(ti);
     337}
     338
     339static void tinput_init(tinput_t *ti)
     340{
     341        ti->hnum = 0;
     342        ti->hpos = 0;
     343        ti->history[0] = NULL;
     344}
     345
     346static char *tinput_read(tinput_t *ti)
    102347{
    103348        console_event_t ev;
    104         size_t offs, otmp;
    105         wchar_t dec;
    106 
    107         offs = 0;
     349        char *str;
     350
     351        fflush(stdout);
     352
     353        if (console_get_size(fphone(stdin), &ti->con_cols, &ti->con_rows) != EOK)
     354                return NULL;
     355        if (console_get_pos(fphone(stdin), &ti->col0, &ti->row0) != EOK)
     356                return NULL;
     357
     358        ti->pos = 0;
     359        ti->nc = 0;
     360        ti->buffer[0] = '\0';
     361
    108362        while (true) {
    109363                fflush(stdout);
    110364                if (!console_get_event(fphone(stdin), &ev))
    111                         return;
     365                        return NULL;
    112366               
    113367                if (ev.type != KEY_PRESS)
    114368                        continue;
    115                
    116                 if (ev.key == KC_ENTER || ev.key == KC_NENTER)
    117                         break;
    118                 if (ev.key == KC_BACKSPACE) {
    119                         if (offs > 0) {
    120                                 /*
    121                                  * Back up until we reach valid start of
    122                                  * character.
    123                                  */
    124                                 while (offs > 0) {
    125                                         --offs; otmp = offs;
    126                                         dec = str_decode(buffer, &otmp, n);
    127                                         if (dec != U_SPECIAL)
    128                                                 break;
    129                                 }
    130                                 putchar('\b');
     369
     370                if ((ev.mods & KM_CTRL) != 0 &&
     371                    (ev.mods & (KM_ALT | KM_SHIFT)) == 0) {
     372                        switch (ev.key) {
     373                        case KC_LEFT:
     374                                tinput_seek_word(ti, seek_backward);
     375                                break;
     376                        case KC_RIGHT:
     377                                tinput_seek_word(ti, seek_forward);
     378                                break;
     379                        case KC_UP:
     380                                tinput_seek_vertical(ti, seek_backward);
     381                                break;
     382                        case KC_DOWN:
     383                                tinput_seek_vertical(ti, seek_forward);
     384                                break;
    131385                        }
    132                         continue;
    133386                }
     387
     388                if ((ev.mods & (KM_CTRL | KM_ALT | KM_SHIFT)) == 0) {
     389                        switch (ev.key) {
     390                        case KC_ENTER:
     391                        case KC_NENTER:
     392                                goto done;
     393                        case KC_BACKSPACE:
     394                                tinput_backspace(ti);
     395                                break;
     396                        case KC_DELETE:
     397                                tinput_delete(ti);
     398                                break;
     399                        case KC_LEFT:
     400                                tinput_seek_cell(ti, seek_backward);
     401                                break;
     402                        case KC_RIGHT:
     403                                tinput_seek_cell(ti, seek_forward);
     404                                break;
     405                        case KC_HOME:
     406                                tinput_seek_max(ti, seek_backward);
     407                                break;
     408                        case KC_END:
     409                                tinput_seek_max(ti, seek_forward);
     410                                break;
     411                        case KC_UP:
     412                                tinput_history_seek(ti, +1);
     413                                break;
     414                        case KC_DOWN:
     415                                tinput_history_seek(ti, -1);
     416                                break;
     417                        }
     418                }
     419
    134420                if (ev.c >= ' ') {
    135                         if (chr_encode(ev.c, buffer, &offs, n - 1) == EOK)
    136                                 putchar(ev.c);
     421                        tinput_insert_char(ti, ev.c);
    137422                }
    138423        }
     424
     425done:
     426        ti->pos = ti->nc;
     427        tinput_position_caret(ti);
    139428        putchar('\n');
    140         buffer[offs] = '\0';
    141 }
    142 
    143 /* TODO:
    144  * Implement something like editline() / readline(), if even
    145  * just for command history and making arrows work. */
     429
     430        str = tinput_get_str(ti);
     431        if (str_cmp(str, "") != 0)
     432                tinput_history_insert(ti, str);
     433
     434        ti->hpos = 0;
     435
     436        return str;
     437}
     438
    146439void get_input(cliuser_t *usr)
    147440{
    148         char line[INPUT_MAX];
     441        char *str;
    149442
    150443        fflush(stdout);
     
    154447        console_set_style(fphone(stdout), STYLE_NORMAL);
    155448
    156         read_line(line, INPUT_MAX);
    157         /* Make sure we don't have rubbish or a C/R happy user */
    158         if (str_cmp(line, "") == 0 || str_cmp(line, "\n") == 0)
     449        str = tinput_read(&tinput);
     450
     451        /* Check for empty input. */
     452        if (str_cmp(str, "") == 0) {
     453                free(str);
    159454                return;
    160         usr->line = str_dup(line);
    161 
     455        }
     456
     457        usr->line = str;
    162458        return;
    163459}
    164460
     461void input_init(void)
     462{
     463        tinput_init(&tinput);
     464}
  • uspace/app/bdsh/input.h

    rcb3d641a rfbcfc4da  
    88extern void get_input(cliuser_t *);
    99extern int tok_input(cliuser_t *);
     10extern void input_init(void);
    1011
    1112#endif
  • uspace/app/bdsh/scli.c

    rcb3d641a rfbcfc4da  
    6464        usr->prompt = (char *) NULL;
    6565        usr->lasterr = 0;
     66
     67        input_init();
     68
    6669        return (int) cli_set_prompt(usr);
    6770}
  • uspace/app/edit/edit.c

    rcb3d641a rfbcfc4da  
    3636
    3737#include <stdio.h>
     38#include <stdlib.h>
    3839#include <sys/types.h>
    3940#include <vfs/vfs.h>
     
    101102#define ED_INFTY 65536
    102103
     104/** Maximum filename length that can be entered. */
     105#define INFNAME_MAX_LEN 128
     106
    103107static void key_handle_unmod(console_event_t const *ev);
    104108static void key_handle_ctrl(console_event_t const *ev);
    105109static int file_save(char const *fname);
     110static void file_save_as(void);
    106111static int file_insert(char *fname);
    107112static int file_save_range(char const *fname, spt_t const *spos,
    108113    spt_t const *epos);
     114static char *filename_prompt(char const *prompt, char const *init_value);
    109115static void pane_text_display(void);
    110116static void pane_row_display(void);
     
    150156
    151157        if (argc == 2) {
    152                 doc.file_name = argv[1];
     158                doc.file_name = str_dup(argv[1]);
    153159        } else if (argc > 1) {
    154160                printf("Invalid arguments.\n");
    155161                return -2;
    156162        } else {
    157                 doc.file_name = "/edit.txt";
     163                doc.file_name = NULL;
    158164        }
    159165
    160166        new_file = false;
    161167
    162         if (file_insert(doc.file_name) != EOK)
     168        if (doc.file_name == NULL || file_insert(doc.file_name) != EOK)
    163169                new_file = true;
    164170
     
    170176        pane_text_display();
    171177        pane_status_display();
    172         if (new_file)
    173                 status_display("File not found. Created empty file.");
     178        if (new_file && doc.file_name != NULL)
     179                status_display("File not found. Starting empty file.");
    174180        pane_caret_display();
    175181
     
    266272                break;
    267273        case KC_S:
    268                 (void) file_save(doc.file_name);
     274                if (doc.file_name != NULL)
     275                        file_save(doc.file_name);
     276                else
     277                        file_save_as();
     278                break;
     279        case KC_E:
     280                file_save_as();
    269281                break;
    270282        default:
     
    272284        }
    273285}
    274 
    275286
    276287/** Save the document. */
     
    285296
    286297        rc = file_save_range(fname, &sp, &ep);
    287         status_display("File saved.");
     298
     299        switch (rc) {
     300        case EINVAL:
     301                status_display("Error opening file!");
     302                break;
     303        case EIO:
     304                status_display("Error writing data!");
     305                break;
     306        default:
     307                status_display("File saved.");
     308                break;
     309        }
    288310
    289311        return rc;
     312}
     313
     314/** Change document name and save. */
     315static void file_save_as(void)
     316{
     317        char *old_fname, *fname;
     318        int rc;
     319
     320        old_fname = (doc.file_name != NULL) ? doc.file_name : "";
     321        fname = filename_prompt("Save As", old_fname);
     322        if (fname == NULL) {
     323                status_display("Save cancelled.");
     324                return;
     325        }
     326
     327        rc = file_save(fname);
     328        if (rc != EOK)
     329                return;
     330
     331        if (doc.file_name != NULL)
     332                free(doc.file_name);
     333        doc.file_name = fname;
     334}
     335
     336/** Ask for a file name. */
     337static char *filename_prompt(char const *prompt, char const *init_value)
     338{
     339        console_event_t ev;
     340        char *str;
     341        wchar_t buffer[INFNAME_MAX_LEN + 1];
     342        int max_len;
     343        int nc;
     344        bool done;
     345
     346        asprintf(&str, "%s: %s", prompt, init_value);
     347        status_display(str);
     348        console_goto(con, 1 + str_length(str), scr_rows - 1);
     349        free(str);
     350
     351        console_set_color(con, COLOR_WHITE, COLOR_BLACK, 0);
     352
     353        max_len = min(INFNAME_MAX_LEN, scr_columns - 4 - str_length(prompt));
     354        str_to_wstr(buffer, max_len + 1, init_value);
     355        nc = wstr_length(buffer);
     356        done = false;
     357
     358        while (!done) {
     359                console_get_event(con, &ev);
     360
     361                if (ev.type == KEY_PRESS) {
     362                        /* Handle key press. */
     363                        if (((ev.mods & KM_ALT) == 0) &&
     364                             (ev.mods & KM_CTRL) != 0) {
     365                                ;
     366                        } else if ((ev.mods & (KM_CTRL | KM_ALT)) == 0) {
     367                                switch (ev.key) {
     368                                case KC_ESCAPE:
     369                                        return NULL;
     370                                case KC_BACKSPACE:
     371                                        if (nc > 0) {
     372                                                putchar('\b');
     373                                                fflush(stdout);
     374                                                --nc;
     375                                        }
     376                                        break;
     377                                case KC_ENTER:
     378                                        done = true;
     379                                        break;
     380                                default:
     381                                        if (ev.c >= 32 && nc < max_len) {
     382                                                putchar(ev.c);
     383                                                fflush(stdout);
     384                                                buffer[nc++] = ev.c;
     385                                        }
     386                                        break;
     387                                }
     388                        }
     389                }
     390        }
     391
     392        buffer[nc] = '\0';
     393        str = wstr_to_astr(buffer);
     394
     395        console_set_color(con, COLOR_BLACK, COLOR_WHITE, 0);
     396
     397        return str;
    290398}
    291399
     
    359467        } while (!spt_equal(&bep, epos));
    360468
    361         fclose(f);
     469        if (fclose(f) != EOK)
     470                return EIO;
    362471
    363472        return EOK;
     
    473582        spt_t caret_pt;
    474583        coord_t coord;
     584        char *fname;
    475585        int n;
    476586
     
    478588        spt_get_coord(&caret_pt, &coord);
    479589
     590        fname = (doc.file_name != NULL) ? doc.file_name : "<unnamed>";
     591
    480592        console_goto(con, 0, scr_rows - 1);
    481593        console_set_color(con, COLOR_WHITE, COLOR_BLACK, 0);
    482         n = printf(" %d, %d: File '%s'. Ctrl-S Save  Ctrl-Q Quit",
    483             coord.row, coord.column, doc.file_name);
     594        n = printf(" %d, %d: File '%s'. Ctrl-Q Quit  Ctrl-S Save  "
     595            "Ctrl-E Save As", coord.row, coord.column, fname);
    484596        printf("%*s", scr_columns - 1 - n, "");
    485597        fflush(stdout);
  • uspace/lib/libc/arch/amd64/include/atomic.h

    rcb3d641a rfbcfc4da  
    3737#ifndef LIBC_amd64_ATOMIC_H_
    3838#define LIBC_amd64_ATOMIC_H_
     39
     40#define LIBC_ARCH_ATOMIC_H_
     41
     42#include <atomicdflt.h>
    3943
    4044static inline void atomic_inc(atomic_t *val) {
  • uspace/lib/libc/arch/arm32/include/atomic.h

    rcb3d641a rfbcfc4da  
    3737#define LIBC_arm32_ATOMIC_H_
    3838
     39#include <bool.h>
     40
     41typedef struct atomic {
     42        volatile long count;
     43} atomic_t;
     44
     45static inline void atomic_set(atomic_t *val, long i)
     46{
     47        val->count = i;
     48}
     49
     50static inline long atomic_get(atomic_t *val)
     51{
     52        return val->count;
     53}
     54
     55static inline bool cas(atomic_t *val, long ov, long nv)
     56{
     57        /* FIXME: is not atomic */
     58        if (val->count == ov) {
     59                val->count = nv;
     60                return true;
     61        }
     62        return false;
     63}
     64
    3965/** Atomic addition.
    4066 *
     
    4975        volatile long * mem = &(val->count);
    5076
     77        /* FIXME: is not atomic, is broken */
    5178        asm volatile (
    5279        "1:\n"
  • uspace/lib/libc/arch/ia32/Makefile.inc

    rcb3d641a rfbcfc4da  
    3939        arch/$(UARCH)/src/setjmp.S
    4040
     41GCC_CFLAGS += -march=pentium
    4142LFLAGS += -N
    4243
  • uspace/lib/libc/arch/ia32/include/atomic.h

    rcb3d641a rfbcfc4da  
    3535#ifndef LIBC_ia32_ATOMIC_H_
    3636#define LIBC_ia32_ATOMIC_H_
     37
     38#define LIBC_ARCH_ATOMIC_H_
     39
     40#include <atomicdflt.h>
    3741
    3842static inline void atomic_inc(atomic_t *val) {
  • uspace/lib/libc/arch/ia64/include/atomic.h

    rcb3d641a rfbcfc4da  
    3535#ifndef LIBC_ia64_ATOMIC_H_
    3636#define LIBC_ia64_ATOMIC_H_
     37
     38#define LIBC_ARCH_ATOMIC_H_
     39
     40#include <atomicdflt.h>
    3741
    3842static inline void atomic_inc(atomic_t *val)
  • uspace/lib/libc/arch/mips32/include/atomic.h

    rcb3d641a rfbcfc4da  
    3636#ifndef LIBC_mips32_ATOMIC_H_
    3737#define LIBC_mips32_ATOMIC_H_
     38
     39#define LIBC_ARCH_ATOMIC_H_
     40
     41#include <atomicdflt.h>
    3842
    3943#define atomic_inc(x)   ((void) atomic_add(x, 1))
  • uspace/lib/libc/arch/ppc32/include/atomic.h

    rcb3d641a rfbcfc4da  
    3535#ifndef LIBC_ppc32_ATOMIC_H_
    3636#define LIBC_ppc32_ATOMIC_H_
     37
     38#define LIBC_ARCH_ATOMIC_H_
     39
     40#include <atomicdflt.h>
    3741
    3842static inline void atomic_inc(atomic_t *val)
  • uspace/lib/libc/arch/sparc64/include/atomic.h

    rcb3d641a rfbcfc4da  
    3636#define LIBC_sparc64_ATOMIC_H_
    3737
     38#define LIBC_ARCH_ATOMIC_H_
     39
     40#include <atomicdflt.h>
    3841#include <sys/types.h>
    3942
  • uspace/lib/libc/generic/async.c

    rcb3d641a rfbcfc4da  
    392392        /* If nothing in queue, wait until something arrives */
    393393        while (list_empty(&conn->msg_queue)) {
     394                if (conn->close_callid) {
     395                        /*
     396                         * Handle the case when the connection was already
     397                         * closed by the client but the server did not notice
     398                         * the first IPC_M_PHONE_HUNGUP call and continues to
     399                         * call async_get_call_timeout(). Repeat
     400                         * IPC_M_PHONE_HUNGUP until the caller notices.
     401                         */
     402                        memset(call, 0, sizeof(ipc_call_t));
     403                        IPC_SET_METHOD(*call, IPC_M_PHONE_HUNGUP);
     404                        futex_up(&async_futex);
     405                        return conn->close_callid;
     406                }
     407
    394408                if (usecs)
    395409                        async_insert_timeout(&conn->wdata);
     
    528542        list_initialize(&conn->msg_queue);
    529543        conn->callid = callid;
    530         conn->close_callid = false;
     544        conn->close_callid = 0;
    531545       
    532546        if (call)
  • uspace/lib/libc/generic/futex.c

    rcb3d641a rfbcfc4da  
    3636#include <atomic.h>
    3737#include <libc.h>
    38 #include <stdio.h>
    3938#include <sys/types.h>
    40 #include <kernel/synch/synch.h>
    41 
    42 /*
    43  * Note about race conditions.
    44  * Because of non-atomic nature of operations performed sequentially on the
    45  * futex counter and the futex wait queue, there is a race condition:
    46  *
    47  * (wq->missed_wakeups == 1) && (futex->count = 1)
    48  *
    49  * Scenario 1 (wait queue timeout vs. futex_up()):
    50  * 1. assume wq->missed_wakeups == 0 && futex->count == -1
    51  *    (ie. thread A sleeping, thread B in the critical section)
    52  * 2. A receives timeout and gets removed from the wait queue
    53  * 3. B wants to leave the critical section and calls futex_up()
    54  * 4. B thus changes futex->count from -1 to 0
    55  * 5. B has to call SYS_FUTEX_WAKEUP syscall to wake up the sleeping thread
    56  * 6. B finds the wait queue empty and changes wq->missed_wakeups from 0 to 1
    57  * 7. A fixes futex->count (i.e. the number of waiting threads) by changing it
    58  *    from 0 to 1
    59  *
    60  * Scenario 2 (conditional down operation vs. futex_up)
    61  * 1. assume wq->missed_wakeups == 0 && futex->count == 0
    62  *    (i.e. thread A is in the critical section)
    63  * 2. thread B performs futex_trydown() operation and changes futex->count from
    64  *    0 to -1
    65  *    B is now obliged to call SYS_FUTEX_SLEEP syscall
    66  * 3. A wants to leave the critical section and does futex_up()
    67  * 4. A thus changes futex->count from -1 to 0 and must call SYS_FUTEX_WAKEUP
    68  *    syscall
    69  * 5. B finds the wait queue empty and immediatelly aborts the conditional sleep
    70  * 6. No thread is queueing in the wait queue so wq->missed_wakeups changes from
    71  *    0 to 1
    72  * 6. B fixes futex->count (i.e. the number of waiting threads) by changing it
    73  *    from 0 to 1
    74  *
    75  * Both scenarios allow two threads to be in the critical section
    76  * simultaneously. One without kernel intervention and the other through
    77  * wq->missed_wakeups being 1.
    78  *
    79  * To mitigate this problem, futex_down_timeout() detects that the syscall
    80  * didn't sleep in the wait queue, fixes the futex counter and RETRIES the
    81  * whole operation again.
    82  */
    8339
    8440/** Initialize futex counter.
     
    9248}
    9349
    94 int futex_down(futex_t *futex)
    95 {
    96         return futex_down_timeout(futex, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE);
    97 }
    98 
    99 int futex_trydown(futex_t *futex)
    100 {
    101         return futex_down_timeout(futex, SYNCH_NO_TIMEOUT,
    102             SYNCH_FLAGS_NON_BLOCKING);
    103 }
    104 
    10550/** Try to down the futex.
    10651 *
    10752 * @param futex         Futex.
    108  * @param usec          Microseconds to wait. Zero value means sleep without
    109  *                      timeout.
    110  * @param flags         Select mode of operation. See comment for
    111  *                      waitq_sleep_timeout().
     53 * @return              Non-zero if the futex was acquired.
     54 * @return              Zero if the futex was not acquired.
     55 */
     56int futex_trydown(futex_t *futex)
     57{
     58        return cas(futex, 1, 0);
     59}
     60
     61/** Down the futex.
    11262 *
    113  * @return              ENOENT if there is no such virtual address. One of
    114  *                      ESYNCH_OK_ATOMIC and ESYNCH_OK_BLOCKED on success or
    115  *                      ESYNCH_TIMEOUT if the lock was not acquired because of
    116  *                      a timeout or ESYNCH_WOULD_BLOCK if the operation could
    117  *                      not be carried out atomically (if requested so).
     63 * @param futex         Futex.
     64 * @return              ENOENT if there is no such virtual address.
     65 * @return              Zero in the uncontended case.
     66 * @return              Otherwise one of ESYNCH_OK_ATOMIC or ESYNCH_OK_BLOCKED.
    11867 */
    119 int futex_down_timeout(futex_t *futex, uint32_t usec, int flags)
     68int futex_down(futex_t *futex)
    12069{
    121         int rc;
    122        
    123         while (atomic_predec(futex) < 0) {
    124                 rc = __SYSCALL3(SYS_FUTEX_SLEEP, (sysarg_t) &futex->count,
    125                     (sysarg_t) usec, (sysarg_t) flags);
    126                
    127                 switch (rc) {
    128                 case ESYNCH_OK_ATOMIC:
    129                         /*
    130                          * Because of a race condition between timeout and
    131                          * futex_up() and between conditional
    132                          * futex_down_timeout() and futex_up(), we have to give
    133                          * up and try again in this special case.
    134                          */
    135                         atomic_inc(futex);
    136                         break;
     70        if (atomic_predec(futex) < 0)
     71                return __SYSCALL1(SYS_FUTEX_SLEEP, (sysarg_t) &futex->count);
    13772
    138                 case ESYNCH_TIMEOUT:
    139                         atomic_inc(futex);
    140                         return ESYNCH_TIMEOUT;
    141                         break;
    142 
    143                 case ESYNCH_WOULD_BLOCK:
    144                         /*
    145                          * The conditional down operation should be implemented
    146                          * this way. The userspace-only variant tends to
    147                          * accumulate missed wakeups in the kernel futex wait
    148                          * queue.
    149                          */
    150                         atomic_inc(futex);
    151                         return ESYNCH_WOULD_BLOCK;
    152                         break;
    153 
    154                 case ESYNCH_OK_BLOCKED:
    155                         /*
    156                          * Enter the critical section.
    157                          * The futex counter has already been incremented for
    158                          * us.
    159                          */
    160                         return ESYNCH_OK_BLOCKED;
    161                         break;
    162                 default:
    163                         return rc;
    164                 }
    165         }
    166 
    167         /*
    168          * Enter the critical section.
    169          */
    170         return ESYNCH_OK_ATOMIC;
     73        return 0;
    17174}
    17275
     
    17477 *
    17578 * @param futex         Futex.
    176  *
    177  * @return              ENOENT if there is no such virtual address. Otherwise
    178  *                      zero.
     79 * @return              ENOENT if there is no such virtual address.
     80 * @return              Zero in the uncontended case.
    17981 */
    18082int futex_up(futex_t *futex)
    18183{
    182         long val;
    183        
    184         val = atomic_postinc(futex);
    185         if (val < 0)
     84        if (atomic_postinc(futex) < 0)
    18685                return __SYSCALL1(SYS_FUTEX_WAKEUP, (sysarg_t) &futex->count);
    18786               
  • uspace/lib/libc/generic/io/console.c

    rcb3d641a rfbcfc4da  
    9494}
    9595
     96int console_get_pos(int phone, int *col, int *row)
     97{
     98        ipcarg_t col_v;
     99        ipcarg_t row_v;
     100        int rc;
     101
     102        rc = async_req_0_2(phone, CONSOLE_GET_POS, &col_v, &row_v);
     103
     104        *col = (int) col_v;
     105        *row = (int) row_v;
     106        return rc;
     107}
     108
    96109void console_goto(int phone, int col, int row)
    97110{
  • uspace/lib/libc/generic/io/klog.c

    rcb3d641a rfbcfc4da  
    4242size_t klog_write(const void *buf, size_t size)
    4343{
    44         return (size_t) __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, size);
     44        ssize_t ret = (ssize_t) __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, size);
     45       
     46        if (ret >= 0)
     47                return (size_t) ret;
     48       
     49        return 0;
    4550}
    4651
  • uspace/lib/libc/generic/string.c

    rcb3d641a rfbcfc4da  
    471471 * null-terminated and containing only complete characters.
    472472 *
    473  * @param dst   Destination buffer.
     473 * @param dest   Destination buffer.
    474474 * @param count Size of the destination buffer (must be > 0).
    475475 * @param src   Source string.
     
    505505 * have to be null-terminated.
    506506 *
    507  * @param dst   Destination buffer.
     507 * @param dest   Destination buffer.
    508508 * @param count Size of the destination buffer (must be > 0).
    509509 * @param src   Source string.
     
    537537 * null-terminated and containing only complete characters.
    538538 *
    539  * @param dst   Destination buffer.
     539 * @param dest   Destination buffer.
    540540 * @param count Size of the destination buffer.
    541541 * @param src   Source string.
     
    549549}
    550550
    551 /** Copy NULL-terminated wide string to string
    552  *
    553  * Copy source wide string @a src to destination buffer @a dst.
    554  * No more than @a size bytes are written. NULL-terminator is always
    555  * written after the last succesfully copied character (i.e. if the
    556  * destination buffer is has at least 1 byte, it will be always
    557  * NULL-terminated).
    558  *
    559  * @param src   Source wide string.
    560  * @param dst   Destination buffer.
    561  * @param count Size of the destination buffer.
    562  *
    563  */
    564 void wstr_nstr(char *dst, const wchar_t *src, size_t size)
    565 {
    566         /* No space for the NULL-terminator in the buffer */
    567         if (size == 0)
    568                 return;
    569        
     551/** Convert wide string to string.
     552 *
     553 * Convert wide string @a src to string. The output is written to the buffer
     554 * specified by @a dest and @a size. @a size must be non-zero and the string
     555 * written will always be well-formed.
     556 *
     557 * @param dest  Destination buffer.
     558 * @param size  Size of the destination buffer.
     559 * @param src   Source wide string.
     560 */
     561void wstr_to_str(char *dest, size_t size, const wchar_t *src)
     562{
    570563        wchar_t ch;
    571         size_t src_idx = 0;
    572         size_t dst_off = 0;
    573        
     564        size_t src_idx;
     565        size_t dest_off;
     566
     567        /* There must be space for a null terminator in the buffer. */
     568        assert(size > 0);
     569       
     570        src_idx = 0;
     571        dest_off = 0;
     572
    574573        while ((ch = src[src_idx++]) != 0) {
    575                 if (chr_encode(ch, dst, &dst_off, size) != EOK)
     574                if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
    576575                        break;
    577576        }
    578        
    579         if (dst_off >= size)
    580                 dst[size - 1] = 0;
    581         else
    582                 dst[dst_off] = 0;
     577
     578        dest[dest_off] = '\0';
     579}
     580
     581/** Convert wide string to new string.
     582 *
     583 * Convert wide string @a src to string. Space for the new string is allocated
     584 * on the heap.
     585 *
     586 * @param src   Source wide string.
     587 * @return      New string.
     588 */
     589char *wstr_to_astr(const wchar_t *src)
     590{
     591        char dbuf[STR_BOUNDS(1)];
     592        char *str;
     593        wchar_t ch;
     594
     595        size_t src_idx;
     596        size_t dest_off;
     597        size_t dest_size;
     598
     599        /* Compute size of encoded string. */
     600
     601        src_idx = 0;
     602        dest_size = 0;
     603
     604        while ((ch = src[src_idx++]) != 0) {
     605                dest_off = 0;
     606                if (chr_encode(ch, dbuf, &dest_off, STR_BOUNDS(1)) != EOK)
     607                        break;
     608                dest_size += dest_off;
     609        }
     610
     611        str = malloc(dest_size + 1);
     612        if (str == NULL)
     613                return NULL;
     614
     615        /* Encode string. */
     616
     617        src_idx = 0;
     618        dest_off = 0;
     619
     620        while ((ch = src[src_idx++]) != 0) {
     621                if (chr_encode(ch, str, &dest_off, dest_size) != EOK)
     622                        break;
     623        }
     624
     625        str[dest_size] = '\0';
     626        return str;
     627}
     628
     629
     630/** Convert string to wide string.
     631 *
     632 * Convert string @a src to wide string. The output is written to the
     633 * buffer specified by @a dest and @a dlen. @a dlen must be non-zero
     634 * and the wide string written will always be null-terminated.
     635 *
     636 * @param dest  Destination buffer.
     637 * @param dlen  Length of destination buffer (number of wchars).
     638 * @param src   Source string.
     639 */
     640void str_to_wstr(wchar_t *dest, size_t dlen, const char *src)
     641{
     642        size_t offset;
     643        size_t di;
     644        wchar_t c;
     645
     646        assert(dlen > 0);
     647
     648        offset = 0;
     649        di = 0;
     650
     651        do {
     652                if (di >= dlen - 1)
     653                        break;
     654
     655                c = str_decode(src, &offset, STR_NO_LIMIT);
     656                dest[di++] = c;
     657        } while (c != '\0');
     658
     659        dest[dlen - 1] = '\0';
    583660}
    584661
  • uspace/lib/libc/generic/time.c

    rcb3d641a rfbcfc4da  
    3131 */
    3232/** @file
    33  */ 
     33 */
    3434
    3535#include <sys/time.h>
     
    4040#include <unistd.h>
    4141#include <atomic.h>
    42 #include <futex.h>
    4342#include <sysinfo.h>
    4443#include <ipc/services.h>
     44#include <libc.h>
    4545
    4646#include <sysinfo.h>
     
    189189
    190190/** Wait unconditionally for specified number of microseconds */
    191 int usleep(unsigned long usec)
    192 {
    193         atomic_t futex = FUTEX_INITIALIZER;
    194 
    195         futex_initialize(&futex, 0);
    196         futex_down_timeout(&futex, usec, 0);
     191int usleep(useconds_t usec)
     192{
     193        (void) __SYSCALL1(SYS_THREAD_USLEEP, usec);
    197194        return 0;
    198195}
    199196
    200197/** Wait unconditionally for specified number of seconds */
    201 unsigned int sleep(unsigned int seconds)
    202 {
    203         atomic_t futex = FUTEX_INITIALIZER;
    204 
    205         futex_initialize(&futex, 0);
    206        
     198unsigned int sleep(unsigned int sec)
     199{
    207200        /* Sleep in 1000 second steps to support
    208201           full argument range */
    209         while (seconds > 0) {
    210                 unsigned int period = (seconds > 1000) ? 1000 : seconds;
     202        while (sec > 0) {
     203                unsigned int period = (sec > 1000) ? 1000 : sec;
    211204       
    212                 futex_down_timeout(&futex, period * 1000000, 0);
    213                 seconds -= period;
     205                usleep(period * 1000000);
     206                sec -= period;
    214207        }
    215208        return 0;
  • uspace/lib/libc/generic/vfs/canonify.c

    rcb3d641a rfbcfc4da  
    142142        t->start[-1] = '\0';
    143143}
    144 /** Eat the extra '/'..
     144/** Eat the extra '/'.
    145145 *
    146146 * @param t             The current TK_SLASH token.
     
    288288 *
    289289 * A file system path is canonical, if the following holds:
    290  * 1) the path is absolute (i.e. a/b/c is not canonical)
    291  * 2) there is no trailing slash in the path (i.e. /a/b/c is not canonical)
    292  * 3) there is no extra slash in the path (i.e. /a//b/c is not canonical)
    293  * 4) there is no '.' component in the path (i.e. /a/./b/c is not canonical)
    294  * 5) there is no '..' component in the path (i.e. /a/b/../c is not canonical)
     290 *
     291 * 1) the path is absolute
     292 *    (i.e. a/b/c is not canonical)
     293 * 2) there is no trailing slash in the path if it has components
     294 *    (i.e. /a/b/c/ is not canonical)
     295 * 3) there is no extra slash in the path
     296 *    (i.e. /a//b/c is not canonical)
     297 * 4) there is no '.' component in the path
     298 *    (i.e. /a/./b/c is not canonical)
     299 * 5) there is no '..' component in the path
     300 *    (i.e. /a/b/../c is not canonical)
    295301 *
    296302 * This function makes a potentially non-canonical file system path canonical.
  • uspace/lib/libc/include/atomic.h

    rcb3d641a rfbcfc4da  
    11/*
    2  * Copyright (c) 2006 Jakub Jermar
     2 * Copyright (c) 2009 Jakub Jermar
    33 * All rights reserved.
    44 *
     
    3636#define LIBC_ATOMIC_H_
    3737
    38 typedef struct atomic {
    39         volatile long count;
    40 } atomic_t;
    41 
    4238#include <libarch/atomic.h>
    43 
    44 static inline void atomic_set(atomic_t *val, long i)
    45 {
    46         val->count = i;
    47 }
    48 
    49 static inline long atomic_get(atomic_t *val)
    50 {
    51         return val->count;
    52 }
    5339
    5440#endif
  • uspace/lib/libc/include/futex.h

    rcb3d641a rfbcfc4da  
    4646extern int futex_down(futex_t *futex);
    4747extern int futex_trydown(futex_t *futex);
    48 extern int futex_down_timeout(futex_t *futex, uint32_t usec, int flags);
    4948extern int futex_up(futex_t *futex);
    5049
  • uspace/lib/libc/include/io/console.h

    rcb3d641a rfbcfc4da  
    6969
    7070extern int console_get_size(int phone, int *cols, int *rows);
     71extern int console_get_pos(int phone, int *col, int *row);
    7172extern void console_goto(int phone, int col, int row);
    7273
  • uspace/lib/libc/include/ipc/console.h

    rcb3d641a rfbcfc4da  
    4343        CONSOLE_GET_COLOR_CAP,
    4444        CONSOLE_GET_EVENT,
     45        CONSOLE_GET_POS,
    4546        CONSOLE_GOTO,
    4647        CONSOLE_CLEAR,
  • uspace/lib/libc/include/string.h

    rcb3d641a rfbcfc4da  
    7373extern void str_append(char *dest, size_t size, const char *src);
    7474
    75 extern void wstr_nstr(char *dst, const wchar_t *src, size_t size);
     75extern void wstr_to_str(char *dest, size_t size, const wchar_t *src);
     76extern char *wstr_to_astr(const wchar_t *src);
     77extern void str_to_wstr(wchar_t *dest, size_t dlen, const char *src);
    7678
    7779extern char *str_chr(const char *str, wchar_t ch);
  • uspace/lib/libc/include/unistd.h

    rcb3d641a rfbcfc4da  
    5151#endif
    5252
     53typedef uint32_t useconds_t;
     54
    5355extern int dup2(int oldfd, int newfd);
    5456
     
    6870
    6971extern void _exit(int status) __attribute__ ((noreturn));
    70 extern int usleep(unsigned long usec);
    71 extern unsigned int sleep(unsigned int seconds);
     72extern int usleep(useconds_t uses);
     73extern unsigned int sleep(unsigned int se);
    7274
    7375#endif
  • uspace/srv/console/console.c

    rcb3d641a rfbcfc4da  
    601601                                    IPC_GET_ARG2(call));
    602602                        break;
     603                case CONSOLE_GET_POS:
     604                        arg1 = cons->scr.position_x;
     605                        arg2 = cons->scr.position_y;
     606                        break;
    603607                case CONSOLE_GET_SIZE:
    604608                        arg1 = fb_info.cols;
  • uspace/srv/fs/fat/fat_ops.c

    rcb3d641a rfbcfc4da  
    363363                                }
    364364                                rc = fat_node_get_core(&nodep, idx);
    365                                 assert(rc == EOK);
    366365                                fibril_mutex_unlock(&idx->lock);
    367                                 (void) block_put(b);
     366                                if (rc != EOK) {
     367                                        (void) block_put(b);
     368                                        return rc;
     369                                }
    368370                                *rfn = FS_NODE(nodep);
    369                                 return EOK;
     371                                rc = block_put(b);
     372                                if (rc != EOK)
     373                                        (void) fat_node_put(*rfn);
     374                                return rc;
    370375                        }
    371376                }
     
    10721077                        rc = fat_block_get(&b, bs, nodep, pos / bps,
    10731078                            BLOCK_FLAGS_NONE);
    1074                         assert(rc == EOK);
     1079                        if (rc != EOK) {
     1080                                fat_node_put(fn);
     1081                                ipc_answer_0(callid, rc);
     1082                                ipc_answer_0(rid, rc);
     1083                                return;
     1084                        }
    10751085                        (void) async_data_read_finalize(callid, b->data + pos % bps,
    10761086                            bytes);
    10771087                        rc = block_put(b);
    1078                         assert(rc == EOK);
     1088                        if (rc != EOK) {
     1089                                fat_node_put(fn);
     1090                                ipc_answer_0(rid, rc);
     1091                                return;
     1092                        }
    10791093                }
    10801094        } else {
     
    11001114                        rc = fat_block_get(&b, bs, nodep, bnum,
    11011115                            BLOCK_FLAGS_NONE);
    1102                         assert(rc == EOK);
     1116                        if (rc != EOK)
     1117                                goto err;
    11031118                        for (o = pos % (bps / sizeof(fat_dentry_t));
    11041119                            o < bps / sizeof(fat_dentry_t);
     
    11111126                                case FAT_DENTRY_LAST:
    11121127                                        rc = block_put(b);
    1113                                         assert(rc == EOK);
     1128                                        if (rc != EOK)
     1129                                                goto err;
    11141130                                        goto miss;
    11151131                                default:
     
    11171133                                        fat_dentry_name_get(d, name);
    11181134                                        rc = block_put(b);
    1119                                         assert(rc == EOK);
     1135                                        if (rc != EOK)
     1136                                                goto err;
    11201137                                        goto hit;
    11211138                                }
    11221139                        }
    11231140                        rc = block_put(b);
    1124                         assert(rc == EOK);
     1141                        if (rc != EOK)
     1142                                goto err;
    11251143                        bnum++;
    11261144                }
    11271145miss:
    1128                 fat_node_put(fn);
    1129                 ipc_answer_0(callid, ENOENT);
    1130                 ipc_answer_1(rid, ENOENT, 0);
    1131                 return;
     1146                rc = fat_node_put(fn);
     1147                ipc_answer_0(callid, rc != EOK ? rc : ENOENT);
     1148                ipc_answer_1(rid, rc != EOK ? rc : ENOENT, 0);
     1149                return;
     1150
     1151err:
     1152                (void) fat_node_put(fn);
     1153                ipc_answer_0(callid, rc);
     1154                ipc_answer_0(rid, rc);
     1155                return;
     1156
    11321157hit:
    11331158                (void) async_data_read_finalize(callid, name, str_size(name) + 1);
     
    11351160        }
    11361161
    1137         fat_node_put(fn);
    1138         ipc_answer_1(rid, EOK, (ipcarg_t)bytes);
     1162        rc = fat_node_put(fn);
     1163        ipc_answer_1(rid, rc, (ipcarg_t)bytes);
    11391164}
    11401165
     
    11471172        fat_node_t *nodep;
    11481173        fat_bs_t *bs;
    1149         size_t bytes;
     1174        size_t bytes, size;
    11501175        block_t *b;
    11511176        uint16_t bps;
     
    11701195        size_t len;
    11711196        if (!async_data_write_receive(&callid, &len)) {
    1172                 fat_node_put(fn);
     1197                (void) fat_node_put(fn);
    11731198                ipc_answer_0(callid, EINVAL);
    11741199                ipc_answer_0(rid, EINVAL);
     
    12011226                 */
    12021227                rc = fat_fill_gap(bs, nodep, FAT_CLST_RES0, pos);
    1203                 assert(rc == EOK);
     1228                if (rc != EOK) {
     1229                        (void) fat_node_put(fn);
     1230                        ipc_answer_0(callid, rc);
     1231                        ipc_answer_0(rid, rc);
     1232                        return;
     1233                }
    12041234                rc = fat_block_get(&b, bs, nodep, pos / bps, flags);
    1205                 assert(rc == EOK);
     1235                if (rc != EOK) {
     1236                        (void) fat_node_put(fn);
     1237                        ipc_answer_0(callid, rc);
     1238                        ipc_answer_0(rid, rc);
     1239                        return;
     1240                }
    12061241                (void) async_data_write_finalize(callid, b->data + pos % bps,
    12071242                    bytes);
    12081243                b->dirty = true;                /* need to sync block */
    12091244                rc = block_put(b);
    1210                 assert(rc == EOK);
     1245                if (rc != EOK) {
     1246                        (void) fat_node_put(fn);
     1247                        ipc_answer_0(rid, rc);
     1248                        return;
     1249                }
    12111250                if (pos + bytes > nodep->size) {
    12121251                        nodep->size = pos + bytes;
    12131252                        nodep->dirty = true;    /* need to sync node */
    12141253                }
    1215                 ipc_answer_2(rid, EOK, bytes, nodep->size);     
    1216                 fat_node_put(fn);
     1254                size = nodep->size;
     1255                rc = fat_node_put(fn);
     1256                ipc_answer_2(rid, rc, bytes, nodep->size);
    12171257                return;
    12181258        } else {
     
    12211261                 * clusters for the node and zero them out.
    12221262                 */
    1223                 int status;
    12241263                unsigned nclsts;
    12251264                fat_cluster_t mcl, lcl;
     
    12271266                nclsts = (ROUND_UP(pos + bytes, bpc) - boundary) / bpc;
    12281267                /* create an independent chain of nclsts clusters in all FATs */
    1229                 status = fat_alloc_clusters(bs, dev_handle, nclsts, &mcl, &lcl);
    1230                 if (status != EOK) {
     1268                rc = fat_alloc_clusters(bs, dev_handle, nclsts, &mcl, &lcl);
     1269                if (rc != EOK) {
    12311270                        /* could not allocate a chain of nclsts clusters */
    1232                         fat_node_put(fn);
    1233                         ipc_answer_0(callid, status);
    1234                         ipc_answer_0(rid, status);
     1271                        (void) fat_node_put(fn);
     1272                        ipc_answer_0(callid, rc);
     1273                        ipc_answer_0(rid, rc);
    12351274                        return;
    12361275                }
    12371276                /* zero fill any gaps */
    12381277                rc = fat_fill_gap(bs, nodep, mcl, pos);
    1239                 assert(rc == EOK);
     1278                if (rc != EOK) {
     1279                        (void) fat_free_clusters(bs, dev_handle, mcl);
     1280                        (void) fat_node_put(fn);
     1281                        ipc_answer_0(callid, rc);
     1282                        ipc_answer_0(rid, rc);
     1283                        return;
     1284                }
    12401285                rc = _fat_block_get(&b, bs, dev_handle, lcl, (pos / bps) % spc,
    12411286                    flags);
    1242                 assert(rc == EOK);
     1287                if (rc != EOK) {
     1288                        (void) fat_free_clusters(bs, dev_handle, mcl);
     1289                        (void) fat_node_put(fn);
     1290                        ipc_answer_0(callid, rc);
     1291                        ipc_answer_0(rid, rc);
     1292                        return;
     1293                }
    12431294                (void) async_data_write_finalize(callid, b->data + pos % bps,
    12441295                    bytes);
    12451296                b->dirty = true;                /* need to sync block */
    12461297                rc = block_put(b);
    1247                 assert(rc == EOK);
     1298                if (rc != EOK) {
     1299                        (void) fat_free_clusters(bs, dev_handle, mcl);
     1300                        (void) fat_node_put(fn);
     1301                        ipc_answer_0(rid, rc);
     1302                        return;
     1303                }
    12481304                /*
    12491305                 * Append the cluster chain starting in mcl to the end of the
     
    12511307                 */
    12521308                rc = fat_append_clusters(bs, nodep, mcl);
    1253                 assert(rc == EOK);
    1254                 nodep->size = pos + bytes;
     1309                if (rc != EOK) {
     1310                        (void) fat_free_clusters(bs, dev_handle, mcl);
     1311                        (void) fat_node_put(fn);
     1312                        ipc_answer_0(rid, rc);
     1313                        return;
     1314                }
     1315                nodep->size = size = pos + bytes;
    12551316                nodep->dirty = true;            /* need to sync node */
    1256                 ipc_answer_2(rid, EOK, bytes, nodep->size);
    1257                 fat_node_put(fn);
     1317                rc = fat_node_put(fn);
     1318                ipc_answer_2(rid, rc, bytes, size);
    12581319                return;
    12591320        }
  • uspace/srv/vfs/vfs_file.c

    rcb3d641a rfbcfc4da  
    8989        unsigned int i;
    9090        if (desc)
    91                 i = MAX_OPEN_FILES;
     91                i = MAX_OPEN_FILES - 1;
    9292        else
    9393                i = 0;
     
    111111                        i--;
    112112                } else {
    113                         if (i == MAX_OPEN_FILES)
     113                        if (i == MAX_OPEN_FILES - 1)
    114114                                break;
    115115                       
Note: See TracChangeset for help on using the changeset viewer.