Changes in / [051e6ac:b7ee0369] in mainline


Ignore:
Location:
uspace
Files:
5 added
17 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/posix/assert.h

    r051e6ac rb7ee0369  
    4040
    4141#ifndef NDEBUG
    42         #define assert(expr) \
    43                 do { \
    44                         if (!(expr)) { \
    45                                 assert_abort(#expr, __FILE__, __LINE__); \
    46                         } \
    47                 } while (0)
     42        #define assert(expr) ((expr) ? (void) 0 : assert_abort(#expr, __FILE__, __LINE__))
    4843#else
    4944        #define assert(expr) ((void) 0)
  • uspace/lib/posix/ctype.c

    r051e6ac rb7ee0369  
    9494int posix_isprint(int c)
    9595{
    96         return !posix_iscntrl(c);
     96        return posix_isascii(c) && !posix_iscntrl(c);
    9797}
    9898
  • uspace/lib/posix/fnmatch.c

    r051e6ac rb7ee0369  
    525525static char *_casefold(const char *s)
    526526{
     527        assert(s != NULL);
    527528        char *result = strdup(s);
    528529        for (char *i = result; *i != '\0'; ++i) {
     
    542543int posix_fnmatch(const char *pattern, const char *string, int flags)
    543544{
     545        assert(pattern != NULL);
     546        assert(string != NULL);
     547
    544548        // TODO: don't fold everything in advance, but only when needed
    545549
  • uspace/lib/posix/internal/common.h

    r051e6ac rb7ee0369  
    4343    __func__, __FILE__, __LINE__), abort())
    4444
     45/* A little helper macro to avoid typing this over and over. */
     46#define errnify(func, ...) ({ \
     47        int rc = func(__VA_ARGS__); \
     48        if (rc < 0) { \
     49                errno = -rc; \
     50                rc = -1; \
     51        } \
     52        rc; \
     53})
     54
    4555#endif /* LIBPOSIX_COMMON_H_ */
    4656
  • uspace/lib/posix/pwd.c

    r051e6ac rb7ee0369  
    3939#include "errno.h"
    4040
    41 // TODO: documentation
    42 
    4341static bool entry_read = false;
    4442
     
    4644static const struct posix_passwd dummy_pwd = {
    4745        .pw_name = (char *) "user",
    48         .pw_uid = 1,
    49         .pw_gid = 1,
     46        .pw_uid = 0,
     47        .pw_gid = 0,
    5048        .pw_dir = (char *) "/",
    5149        .pw_shell = (char *) "/app/bdsh"
     
    115113{
    116114        assert(name != NULL);
     115        assert(pwd != NULL);
     116        assert(buffer != NULL);
     117        assert(result != NULL);
    117118       
    118119        if (posix_strcmp(name, "user") != 0) {
     
    121122        }
    122123       
    123         return posix_getpwuid_r(1, pwd, buffer, bufsize, result);
     124        return posix_getpwuid_r(0, pwd, buffer, bufsize, result);
    124125}
    125126
     
    132133struct posix_passwd *posix_getpwuid(posix_uid_t uid)
    133134{
    134         if (uid != 1) {
     135        if (uid != 0) {
    135136                return NULL;
    136137        }
     
    159160            '/', '\0', 'b', 'd', 's', 'h', '\0' };
    160161       
    161         if (uid != 1) {
     162        if (uid != 0) {
    162163                *result = NULL;
    163164                return 0;
     
    171172
    172173        pwd->pw_name = (char *) bf;
    173         pwd->pw_uid = 1;
    174         pwd->pw_gid = 1;
     174        pwd->pw_uid = 0;
     175        pwd->pw_gid = 0;
    175176        pwd->pw_dir = (char *) bf + 5;
    176177        pwd->pw_shell = (char *) bf + 7;
  • uspace/lib/posix/pwd.h

    r051e6ac rb7ee0369  
    3535#ifndef POSIX_PWD_H_
    3636#define POSIX_PWD_H_
    37 
    38 // TODO: documentation
    3937
    4038#include "sys/types.h"
  • uspace/lib/posix/signal.c

    r051e6ac rb7ee0369  
    6666
    6767/**
    68  *
    69  * @param signo
     68 * Default signal handler. Executes the default action for each signal,
     69 * as reasonable within HelenOS.
     70 *
     71 * @param signo Signal number.
    7072 */
    7173void __posix_default_signal_handler(int signo)
     
    7577                abort();
    7678        case SIGQUIT:
    77                 fprintf(stderr, "Quit signal raised. Exiting.");
     79                fprintf(stderr, "Quit signal raised. Exiting.\n");
    7880                exit(EXIT_FAILURE);
    7981        case SIGINT:
    80                 fprintf(stderr, "Interrupt signal caught. Exiting.");
     82                fprintf(stderr, "Interrupt signal caught. Exiting.\n");
    8183                exit(EXIT_FAILURE);
    8284        case SIGTERM:
    83                 fprintf(stderr, "Termination signal caught. Exiting.");
     85                fprintf(stderr, "Termination signal caught. Exiting.\n");
    8486                exit(EXIT_FAILURE);
    8587        case SIGSTOP:
    86                 fprintf(stderr, "Stop signal caught, but unsupported. Ignoring.");
     88                fprintf(stderr, "Stop signal caught, but unsupported. Ignoring.\n");
    8789                break;
    8890        case SIGKILL:
     
    250252                    " or fully unsupported signal. This handler may only be"
    251253                    " invoked by the raise() function, which may not be what"
    252                     " the application developer intended.\nSignal name");
     254                    " the application developer intended");
    253255        }
    254256
     
    358360        }
    359361
     362        if (signo > _TOP_SIGNAL) {
     363                errno = EINVAL;
     364                return -1;
     365        }
     366
    360367        if (pid == (posix_pid_t) task_get_id()) {
    361368                return posix_raise(signo);
    362         }
    363 
    364         if (pid > _TOP_SIGNAL) {
    365                 errno = EINVAL;
    366                 return -1;
    367369        }
    368370
  • uspace/lib/posix/stdio.c

    r051e6ac rb7ee0369  
    4444#include "assert.h"
    4545#include "errno.h"
     46#include "stdlib.h"
    4647#include "string.h"
    4748#include "sys/types.h"
     49#include "unistd.h"
    4850
    4951#include "libc/io/printf_core.h"
    5052#include "libc/str.h"
    5153#include "libc/malloc.h"
     54#include "libc/adt/list.h"
     55#include "libc/sys/stat.h"
    5256
    5357
     
    252256        assert(mode != NULL);
    253257        assert(stream != NULL);
    254 
     258       
     259        /* Retieve the node. */
     260        struct stat st;
     261        int rc;
     262       
    255263        if (filename == NULL) {
    256                 // TODO
    257                
    258                 /* print error to stderr as well, to avoid hard to find problems
    259                  * with buggy apps that expect this to work
    260                  */
    261                 fprintf(stderr,
    262                     "ERROR: Application wants to use freopen() to change mode of opened stream.\n"
    263                     "       libposix does not support that yet, the application may function improperly.\n");
    264                 errno = ENOTSUP;
     264                rc = fstat(stream->fd, &st);
     265        } else {
     266                rc = stat(filename, &st);
     267        }
     268       
     269        if (rc != EOK) {
     270                fclose(stream);
     271                errno = -rc;
    265272                return NULL;
    266273        }
    267 
    268         FILE* copy = malloc(sizeof(FILE));
    269         if (copy == NULL) {
    270                 errno = ENOMEM;
     274       
     275        fdi_node_t node = {
     276                .fs_handle = st.fs_handle,
     277                .devmap_handle = st.devmap_handle,
     278                .index = st.index
     279        };
     280       
     281        /* Open a new stream. */
     282        FILE* new = fopen_node(&node, mode);
     283        if (new == NULL) {
     284                fclose(stream);
     285                /* fopen_node() sets errno. */
    271286                return NULL;
    272287        }
    273         memcpy(copy, stream, sizeof(FILE));
    274         fclose(copy); /* copy is now freed */
    275        
    276         copy = fopen(filename, mode); /* open new stream */
    277         if (copy == NULL) {
    278                 /* fopen() sets errno */
    279                 return NULL;
    280         }
    281        
    282         /* move the new stream to the original location */
    283         memcpy(stream, copy, sizeof (FILE));
    284         free(copy);
    285        
    286         /* update references in the file list */
     288       
     289        /* Close the original stream without freeing it (ignoring errors). */
     290        if (stream->buf != NULL) {
     291                fflush(stream);
     292        }
     293        if (stream->sess != NULL) {
     294                async_hangup(stream->sess);
     295        }
     296        if (stream->fd >= 0) {
     297                close(stream->fd);
     298        }
     299        list_remove(&stream->link);
     300       
     301        /* Move the new stream to the original location. */
     302        memcpy(stream, new, sizeof (FILE));
     303        free(new);
     304       
     305        /* Update references in the file list. */
    287306        stream->link.next->prev = &stream->link;
    288307        stream->link.prev->next = &stream->link;
     
    676695
    677696/**
    678  * Remove a file.
     697 * Remove a file or directory.
    679698 *
    680699 * @param path Pathname of the file that shall be removed.
    681  * @return Zero on success, -1 otherwise.
     700 * @return Zero on success, -1 (with errno set) otherwise.
    682701 */
    683702int posix_remove(const char *path)
    684703{
    685         // FIXME: unlink() and rmdir() seem to be equivalent at the moment,
    686         //        but that does not have to be true forever
    687         return unlink(path);
    688 }
    689 
    690 /**
    691  *
    692  * @param s
    693  * @return
     704        struct stat st;
     705        int rc = stat(path, &st);
     706       
     707        if (rc != EOK) {
     708                errno = -rc;
     709                return -1;
     710        }
     711       
     712        if (st.is_directory) {
     713                rc = rmdir(path);
     714        } else {
     715                rc = unlink(path);
     716        }
     717       
     718        if (rc != EOK) {
     719                errno = -rc;
     720                return -1;
     721        }
     722        return 0;
     723}
     724
     725/**
     726 * Rename a file or directory.
     727 *
     728 * @param old Old pathname.
     729 * @param new New pathname.
     730 * @return Zero on success, -1 (with errno set) otherwise.
     731 */
     732int posix_rename(const char *old, const char *new)
     733{
     734        return errnify(rename, old, new);
     735}
     736
     737/**
     738 * Get a unique temporary file name (obsolete).
     739 *
     740 * @param s Buffer for the file name. Must be at least L_tmpnam bytes long.
     741 * @return The value of s on success, NULL on failure.
    694742 */
    695743char *posix_tmpnam(char *s)
    696744{
    697         // TODO: low priority, just a compile-time dependency of binutils
    698         not_implemented();
     745        assert(L_tmpnam >= posix_strlen("/tmp/tnXXXXXX"));
     746       
     747        static char buffer[L_tmpnam + 1];
     748        if (s == NULL) {
     749                s = buffer;
     750        }
     751       
     752        posix_strcpy(s, "/tmp/tnXXXXXX");
     753        posix_mktemp(s);
     754       
     755        if (*s == '\0') {
     756                /* Errno set by mktemp(). */
     757                return NULL;
     758        }
     759       
     760        return s;
     761}
     762
     763/**
     764 * Get an unique temporary file name with additional constraints (obsolete).
     765 *
     766 * @param dir Path to directory, where the file should be created.
     767 * @param pfx Optional prefix up to 5 characters long.
     768 * @return Newly allocated unique path for temporary file. NULL on failure.
     769 */
     770char *posix_tempnam(const char *dir, const char *pfx)
     771{
     772        /* Sequence number of the filename. */
     773        static int seq = 0;
     774       
     775        size_t dir_len = posix_strlen(dir);
     776        if (dir[dir_len - 1] == '/') {
     777                dir_len--;
     778        }
     779       
     780        size_t pfx_len = posix_strlen(pfx);
     781        if (pfx_len > 5) {
     782                pfx_len = 5;
     783        }
     784       
     785        char *result = malloc(dir_len + /* slash*/ 1 +
     786            pfx_len + /* three-digit seq */ 3 + /* .tmp */ 4 + /* nul */ 1);
     787       
     788        if (result == NULL) {
     789                errno = ENOMEM;
     790                return NULL;
     791        }
     792       
     793        char *res_ptr = result;
     794        posix_strncpy(res_ptr, dir, dir_len);
     795        res_ptr += dir_len;
     796        posix_strncpy(res_ptr, pfx, pfx_len);
     797        res_ptr += pfx_len;
     798       
     799        for (; seq < 1000; ++seq) {
     800                snprintf(res_ptr, 8, "%03d.tmp", seq);
     801               
     802                int orig_errno = errno;
     803                errno = 0;
     804                /* Check if the file exists. */
     805                if (posix_access(result, F_OK) == -1) {
     806                        if (errno == ENOENT) {
     807                                errno = orig_errno;
     808                                break;
     809                        } else {
     810                                /* errno set by access() */
     811                                return NULL;
     812                        }
     813                }
     814        }
     815       
     816        if (seq == 1000) {
     817                free(result);
     818                errno = EINVAL;
     819                return NULL;
     820        }
     821       
     822        return result;
     823}
     824
     825/**
     826 * Create and open an unique temporary file.
     827 * The file is automatically removed when the stream is closed.
     828 *
     829 * @param dir Path to directory, where the file should be created.
     830 * @param pfx Optional prefix up to 5 characters long.
     831 * @return Newly allocated unique path for temporary file. NULL on failure.
     832 */
     833FILE *posix_tmpfile(void)
     834{
     835        char filename[] = "/tmp/tfXXXXXX";
     836        int fd = posix_mkstemp(filename);
     837        if (fd == -1) {
     838                /* errno set by mkstemp(). */
     839                return NULL;
     840        }
     841       
     842        /* Unlink the created file, so that it's removed on close(). */
     843        posix_unlink(filename);
     844        return fdopen(fd, "w+");
    699845}
    700846
  • uspace/lib/posix/stdio.h

    r051e6ac rb7ee0369  
    116116extern int posix_remove(const char *path);
    117117
     118/* Renaming Files */
     119extern int posix_rename(const char *old, const char *new);
     120
    118121/* Temporary Files */
    119122#undef L_tmpnam
    120123#define L_tmpnam PATH_MAX
    121124extern char *posix_tmpnam(char *s);
     125extern char *posix_tempnam(const char *dir, const char *pfx);
     126extern FILE *posix_tmpfile(void);
    122127
    123128#ifndef LIBPOSIX_INTERNAL
     
    170175        #define remove posix_remove
    171176
     177        #define rename posix_rename
     178
    172179        #define tmpnam posix_tmpnam
     180        #define tempnam posix_tempnam
     181        #define tmpfile posix_tmpfile
    173182#endif
    174183
  • uspace/lib/posix/stdlib.c

    r051e6ac rb7ee0369  
    4040
    4141#include "errno.h"
     42#include "fcntl.h"
    4243#include "limits.h"
     44#include "string.h"
     45#include "sys/stat.h"
     46#include "unistd.h"
    4347
    4448#include "libc/sort.h"
     
    385389
    386390/**
    387  *
    388  * @param tmpl
    389  * @return
     391 * Creates and opens an unique temporary file from template.
     392 *
     393 * @param tmpl Template. Last six characters must be XXXXXX.
     394 * @return The opened file descriptor or -1 on error.
     395 */
     396int posix_mkstemp(char *tmpl)
     397{
     398        int fd = -1;
     399       
     400        char *tptr = tmpl + posix_strlen(tmpl) - 6;
     401       
     402        while (fd < 0) {
     403                if (*posix_mktemp(tmpl) == '\0') {
     404                        /* Errno set by mktemp(). */
     405                        return -1;
     406                }
     407               
     408                fd = open(tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
     409               
     410                if (fd == -1) {
     411                        /* Restore template to it's original state. */
     412                        snprintf(tptr, 7, "XXXXXX");
     413                }
     414        }
     415       
     416        return fd;
     417}
     418
     419/**
     420 * Creates an unique temporary file name from template.
     421 *
     422 * @param tmpl Template. Last six characters must be XXXXXX.
     423 * @return The value of tmpl. The template is modified in place.
     424 *    If no temporary file name can be created, template is
     425 *    reduced to an empty string.
    390426 */
    391427char *posix_mktemp(char *tmpl)
    392428{
    393         // TODO: low priority, just a compile-time dependency of binutils
    394         not_implemented();
     429        int tmpl_len = posix_strlen(tmpl);
     430        if (tmpl_len < 6) {
     431                errno = EINVAL;
     432                *tmpl = '\0';
     433                return tmpl;
     434        }
     435       
     436        char *tptr = tmpl + tmpl_len - 6;
     437        if (posix_strcmp(tptr, "XXXXXX") != 0) {
     438                errno = EINVAL;
     439                *tmpl = '\0';
     440                return tmpl;
     441        }
     442       
     443        static int seq = 0;
     444       
     445        for (; seq < 1000000; ++seq) {
     446                snprintf(tptr, 7, "%06d", seq);
     447               
     448                int orig_errno = errno;
     449                errno = 0;
     450                /* Check if the file exists. */
     451                if (posix_access(tmpl, F_OK) == -1) {
     452                        if (errno == ENOENT) {
     453                                errno = orig_errno;
     454                                break;
     455                        } else {
     456                                /* errno set by access() */
     457                                *tmpl = '\0';
     458                                return tmpl;
     459                        }
     460                }
     461        }
     462       
     463        if (seq == 10000000) {
     464                errno = EEXIST;
     465                *tmpl = '\0';
     466                return tmpl;
     467        }
     468       
     469        return tmpl;
    395470}
    396471
  • uspace/lib/posix/stdlib.h

    r051e6ac rb7ee0369  
    113113extern void posix_free(void *ptr);
    114114
     115/* Temporary Files */
     116extern int posix_mkstemp(char *tmpl);
     117
    115118/* Legacy Declarations */
    116119extern char *posix_mktemp(char *tmpl);
     
    158161        #define free posix_free
    159162
     163        #define mkstemp posix_mkstemp
     164
    160165        #define mktemp posix_mktemp
    161166        #define getloadavg bsd_getloadavg
  • uspace/lib/posix/sys/wait.c

    r051e6ac rb7ee0369  
    3939#include "wait.h"
    4040
     41#include "../libc/task.h"
     42#include "../assert.h"
     43#include "../errno.h"
     44#include "../limits.h"
     45#include "../signal.h"
     46
     47int __posix_wifexited(int status) {
     48        return status != INT_MIN;
     49}
     50
     51int __posix_wexitstatus(int status) {
     52        assert(__posix_wifexited(status));
     53        return status;
     54}
     55
     56int __posix_wifsignaled(int status) {
     57        return status == INT_MIN;
     58}
     59
     60int __posix_wtermsig(int status) {
     61        assert(__posix_wifsignaled(status));
     62        /* There is no way to distinguish reason
     63         * for unexpected termination at the moment.
     64         */
     65        return SIGABRT;
     66}
     67
    4168/**
     69 * Wait for any child process to stop or terminate.
    4270 *
    43  * @param stat_ptr
    44  * @return
     71 * @param stat_ptr Location of the final status code of the child process.
     72 * @return ID of the child process for which status is reported,
     73 *     -1 on signal interrupt, (pid_t)-1 otherwise.
    4574 */
    4675posix_pid_t posix_wait(int *stat_ptr)
    4776{
    48         // TODO: low priority, just a compile-time dependency of binutils
    49         not_implemented();
     77        /* HelenOS does not support this. */
     78        errno = ENOSYS;
     79        return (posix_pid_t) -1;
    5080}
    5181
    5282/**
     83 * Wait for a child process to stop or terminate.
    5384 *
    54  * @param pid
    55  * @param stat_ptr
    56  * @param options
    57  * @return
     85 * @param pid What child process shall the caller wait for. See POSIX manual
     86 *     for details.
     87 * @param stat_ptr Location of the final status code of the child process.
     88 * @param options Constraints of the waiting. See POSIX manual for details.
     89 * @return ID of the child process for which status is reported,
     90 *     -1 on signal interrupt, 0 if non-blocking wait is requested but there is
     91 *     no child process whose status can be reported, (pid_t)-1 otherwise.
    5892 */
    5993posix_pid_t posix_waitpid(posix_pid_t pid, int *stat_ptr, int options)
    6094{
    61         // TODO: low priority, just a compile-time dependency of binutils
    62         not_implemented();
     95        assert(stat_ptr != NULL);
     96        assert(options == 0 /* None of the options are supported. */);
     97       
     98        task_exit_t texit;
     99        int retval;
     100       
     101        int rc = task_wait((task_id_t) pid, &texit, &retval);
     102       
     103        if (rc < 0) {
     104                /* Unable to retrieve status. */
     105                errno = -rc;
     106                return (posix_pid_t) -1;
     107        }
     108       
     109        if (texit == TASK_EXIT_NORMAL) {
     110                // FIXME: relies on application not returning this value
     111                assert(retval != INT_MIN);
     112                *stat_ptr = retval;
     113        } else {
     114                /* Reserve the lowest value for unexpected termination. */
     115                *stat_ptr = INT_MIN;
     116        }
     117       
     118        return pid;
    63119}
    64120
  • uspace/lib/posix/sys/wait.h

    r051e6ac rb7ee0369  
    3838#include "types.h"
    3939
     40#undef WIFEXITED
     41#undef WEXITSTATUS
     42#undef WIFSIGNALED
     43#undef WTERMSIG
     44#define WIFEXITED(status) __posix_wifexited(status)
     45#define WEXITSTATUS(status) __posix_wexitstatus(status)
     46#define WIFSIGNALED(status) __posix_wifsignaled(status)
     47#define WTERMSIG(status) __posix_wtermsig(status)
     48
     49extern int __posix_wifexited(int status);
     50extern int __posix_wexitstatus(int status);
     51extern int __posix_wifsignaled(int status);
     52extern int __posix_wtermsig(int status);
     53
    4054extern posix_pid_t posix_wait(int *stat_ptr);
    4155extern posix_pid_t posix_waitpid(posix_pid_t pid, int *stat_ptr, int options);
     
    4357#ifndef LIBPOSIX_INTERNAL
    4458        #define wait posix_wait
    45         #define waitpid posix_waitpid
     59        #define waitpid posix_waitpid
    4660#endif
    4761
  • uspace/lib/posix/unistd.c

    r051e6ac rb7ee0369  
    110110                return NULL;
    111111        }
     112       
     113        /* Save the original value to comply with the "no modification on
     114         * success" semantics.
     115         */
     116        int orig_errno = errno;
     117        errno = EOK;
     118       
    112119        char *ret = getcwd(buf, size);
    113         if (ret == NULL && errno == EOK) {
    114                 errno = ERANGE;
    115         }
     120        if (ret == NULL) {
     121                /* Check errno to avoid shadowing other possible errors. */
     122                if (errno == EOK) {
     123                        errno = ERANGE;
     124                }
     125        } else {
     126                /* Success, restore previous errno value. */
     127                errno = orig_errno;
     128        }
     129       
    116130        return ret;
     131}
     132
     133/**
     134 * Change the current working directory.
     135 *
     136 * @param path New working directory.
     137 */
     138int posix_chdir(const char *path)
     139{
     140        return errnify(chdir, path);
    117141}
    118142
     
    157181        /* There is currently no support for user accounts in HelenOS. */
    158182        return 0;
     183}
     184
     185/**
     186 * Close a file.
     187 *
     188 * @param fildes File descriptor of the opened file.
     189 * @return 0 on success, -1 on error.
     190 */
     191int posix_close(int fildes)
     192{
     193        return errnify(close, fildes);
    159194}
    160195
     
    169204ssize_t posix_read(int fildes, void *buf, size_t nbyte)
    170205{
    171         int rc = read(fildes, buf, nbyte);
    172         if (rc < 0) {
    173                 errno = -rc;
    174                 return -1;
    175         } else {
    176                 return rc;
    177         }
     206        return errnify(read, fildes, buf, nbyte);
     207}
     208
     209/**
     210 * Write to a file.
     211 *
     212 * @param fildes File descriptor of the opened file.
     213 * @param buf Buffer to write.
     214 * @param nbyte Size of the buffer.
     215 * @return Number of written bytes on success, -1 otherwise.
     216 */
     217ssize_t posix_write(int fildes, const void *buf, size_t nbyte)
     218{
     219        return errnify(write, fildes, buf, nbyte);
     220}
     221
     222/**
     223 * Requests outstanding data to be written to the underlying storage device.
     224 *
     225 * @param fildes File descriptor of the opened file.
     226 * @return Zero on success, -1 otherwise.
     227 */
     228int posix_fsync(int fildes)
     229{
     230        return errnify(fsync, fildes);
     231}
     232
     233/**
     234 * Truncate a file to a specified length.
     235 *
     236 * @param fildes File descriptor of the opened file.
     237 * @param length New length of the file.
     238 * @return Zero on success, -1 otherwise.
     239 */
     240int posix_ftruncate(int fildes, posix_off_t length)
     241{
     242        return errnify(ftruncate, fildes, (aoff64_t) length);
     243}
     244
     245/**
     246 * Remove a directory.
     247 *
     248 * @param path Directory pathname.
     249 * @return Zero on success, -1 otherwise.
     250 */
     251int posix_rmdir(const char *path)
     252{
     253        return errnify(rmdir, path);
    178254}
    179255
     
    186262int posix_unlink(const char *path)
    187263{
    188         int rc = unlink(path);
    189         if (rc < 0) {
    190                 errno = -rc;
    191                 return -1;
    192         } else {
    193                 return rc;
    194         }
     264        return errnify(unlink, path);
     265}
     266
     267/**
     268 * Duplicate an open file descriptor.
     269 *
     270 * @param fildes File descriptor to be duplicated.
     271 * @return On success, new file descriptor for the same file, otherwise -1.
     272 */
     273int posix_dup(int fildes)
     274{
     275        return posix_fcntl(fildes, F_DUPFD, 0);
     276}
     277
     278/**
     279 * Duplicate an open file descriptor.
     280 *
     281 * @param fildes File descriptor to be duplicated.
     282 * @param fildes2 File descriptor to be paired with the same file description
     283 *     as is paired fildes.
     284 * @return fildes2 on success, -1 otherwise.
     285 */
     286int posix_dup2(int fildes, int fildes2)
     287{
     288        return errnify(dup2, fildes, fildes2);
    195289}
    196290
     
    204298int posix_access(const char *path, int amode)
    205299{
    206         if (amode == F_OK) {
    207                 /* Check file existence by attempt to open it. */
     300        if (amode == F_OK || (amode & (X_OK | W_OK | R_OK))) {
     301                /* HelenOS doesn't support permissions, permission checks
     302                 * are equal to existence check.
     303                 *
     304                 * Check file existence by attempting to open it.
     305                 */
    208306                int fd = open(path, O_RDONLY);
    209                 if (fd != -1) {
    210                         close(fd);
     307                if (fd < 0) {
     308                        errno = -fd;
     309                        return -1;
    211310                }
    212                 return fd;
    213         } else if (amode & (X_OK | W_OK | R_OK)) {
    214                 /* HelenOS doesn't support permissions, return success. */
     311                close(fd);
    215312                return 0;
    216313        } else {
  • uspace/lib/posix/unistd.h

    r051e6ac rb7ee0369  
    6060/* Working Directory */
    6161extern char *posix_getcwd(char *buf, size_t size);
     62extern int posix_chdir(const char *path);
    6263
    6364/* Query Memory Parameters */
     
    6970extern posix_gid_t posix_getgid(void);
    7071
    71 /* File Input/Output */
     72/* File Manipulation */
     73extern int posix_close(int fildes);
    7274extern ssize_t posix_read(int fildes, void *buf, size_t nbyte);
    73 
    74 /* Deleting Files */
     75extern ssize_t posix_write(int fildes, const void *buf, size_t nbyte);
     76extern int posix_fsync(int fildes);
     77extern int posix_ftruncate(int fildes, posix_off_t length);
     78extern int posix_rmdir(const char *path);
    7579extern int posix_unlink(const char *path);
     80extern int posix_dup(int fildes);
     81extern int posix_dup2(int fildes, int fildes2);
    7682
    7783/* Standard Streams */
     
    144150
    145151        #define getcwd posix_getcwd
     152        #define chdir posix_chdir
    146153
    147154        #define isatty posix_isatty
     
    154161        #define getgid posix_getgid
    155162
     163        #define close posix_close
    156164        #define read posix_read
    157 
     165        #define write posix_write
     166        #define fsync posix_fsync
     167        #define ftruncate posix_ftruncate
     168        #define rmdir posix_rmdir
    158169        #define unlink posix_unlink
     170        #define dup posix_dup
     171        #define dup2 posix_dup2
    159172
    160173        #define access posix_access
  • uspace/lib/softint/Makefile

    r051e6ac rb7ee0369  
    3535
    3636SOURCES = \
     37        generic/comparison.c \
    3738        generic/division.c \
    38         generic/multiplication.c
     39        generic/multiplication.c \
     40        generic/shift.c
    3941
    4042include $(USPACE_PREFIX)/Makefile.common
  • uspace/srv/hw/irc/apic/apic.c

    r051e6ac rb7ee0369  
    4242#include <as.h>
    4343#include <ddi.h>
    44 #include <libarch/ddi.h>
    45 #include <align.h>
    4644#include <bool.h>
    4745#include <errno.h>
    4846#include <async.h>
    49 #include <align.h>
    50 #include <async.h>
    51 #include <stdio.h>
    52 #include <ipc/devmap.h>
    5347
    5448#define NAME  "apic"
    5549
     50#define APIC_MAX_IRQ    15
     51
     52#define IOREGSEL  (0x00U / sizeof(uint32_t))
     53#define IOWIN     (0x10U / sizeof(uint32_t))
     54
     55#define IOREDTBL   0x10U
     56
     57/** I/O Register Select Register. */
     58typedef union {
     59        uint32_t value;
     60        struct {
     61                uint8_t reg_addr;       /**< APIC Register Address. */
     62                unsigned int : 24;      /**< Reserved. */
     63        } __attribute__ ((packed));
     64} io_regsel_t;
     65
     66/** I/O Redirection Register. */
     67typedef struct io_redirection_reg {
     68        union {
     69                uint32_t lo;
     70                struct {
     71                        uint8_t intvec;                 /**< Interrupt Vector. */
     72                        unsigned int delmod : 3;        /**< Delivery Mode. */
     73                        unsigned int destmod : 1;       /**< Destination mode. */
     74                        unsigned int delivs : 1;        /**< Delivery status (RO). */
     75                        unsigned int intpol : 1;        /**< Interrupt Input Pin Polarity. */
     76                        unsigned int irr : 1;           /**< Remote IRR (RO). */
     77                        unsigned int trigger_mode : 1;  /**< Trigger Mode. */
     78                        unsigned int masked : 1;        /**< Interrupt Mask. */
     79                        unsigned int : 15;              /**< Reserved. */
     80                } __attribute__ ((packed));
     81        };
     82        union {
     83                uint32_t hi;
     84                struct {
     85                        unsigned int : 24;      /**< Reserved. */
     86                        uint8_t dest : 8;       /**< Destination Field. */
     87                } __attribute__ ((packed));
     88        };
     89} __attribute__ ((packed)) io_redirection_reg_t;
     90
     91// FIXME: get the address from the kernel
     92#define IO_APIC_BASE    0xfec00000UL
     93#define IO_APIC_SIZE    20
     94
     95ioport32_t *io_apic = NULL;
     96
     97/** Read from IO APIC register.
     98 *
     99 * @param address IO APIC register address.
     100 *
     101 * @return Content of the addressed IO APIC register.
     102 *
     103 */
     104static uint32_t io_apic_read(uint8_t address)
     105{
     106        io_regsel_t regsel;
     107
     108        regsel.value = io_apic[IOREGSEL];
     109        regsel.reg_addr = address;
     110        io_apic[IOREGSEL] = regsel.value;
     111        return io_apic[IOWIN];
     112}
     113
     114/** Write to IO APIC register.
     115 *
     116 * @param address IO APIC register address.
     117 * @param val     Content to be written to the addressed IO APIC register.
     118 *
     119 */
     120static void io_apic_write(uint8_t address, uint32_t val)
     121{
     122        io_regsel_t regsel;
     123
     124        regsel.value = io_apic[IOREGSEL];
     125        regsel.reg_addr = address;
     126        io_apic[IOREGSEL] = regsel.value;
     127        io_apic[IOWIN] = val;
     128}
     129
     130static int irq_to_pin(int irq)
     131{
     132        // FIXME: get the map from the kernel, even though this may work
     133        //        for simple cases
     134        return irq;
     135}
     136
    56137static int apic_enable_irq(sysarg_t irq)
    57138{
    58         // FIXME: TODO
    59         return ENOTSUP;
     139        io_redirection_reg_t reg;
     140
     141        if (irq > APIC_MAX_IRQ)
     142                return ELIMIT;
     143
     144        int pin = irq_to_pin(irq);
     145        if (pin == -1)
     146                return ENOENT;
     147
     148        reg.lo = io_apic_read((uint8_t) (IOREDTBL + pin * 2));
     149        reg.masked = false;
     150        io_apic_write((uint8_t) (IOREDTBL + pin * 2), reg.lo);
     151
     152        return EOK;
    60153}
    61154
     
    111204                return false;
    112205        }
     206
     207        if (pio_enable((void *) IO_APIC_BASE, IO_APIC_SIZE,
     208            (void **) &io_apic) != EOK)
     209                return false;   
    113210       
    114211        async_set_client_connection(apic_connection);
Note: See TracChangeset for help on using the changeset viewer.