diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/ape/lib/ap/posix |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/ape/lib/ap/posix')
-rwxr-xr-x | sys/src/ape/lib/ap/posix/getgrent.c | 62 | ||||
-rwxr-xr-x | sys/src/ape/lib/ap/posix/getpwent.c | 69 | ||||
-rwxr-xr-x | sys/src/ape/lib/ap/posix/locale.c | 62 | ||||
-rwxr-xr-x | sys/src/ape/lib/ap/posix/mkfifo.c | 12 | ||||
-rwxr-xr-x | sys/src/ape/lib/ap/posix/mkfile | 16 | ||||
-rwxr-xr-x | sys/src/ape/lib/ap/posix/pathconf.c | 55 | ||||
-rwxr-xr-x | sys/src/ape/lib/ap/posix/sigset.c | 67 | ||||
-rwxr-xr-x | sys/src/ape/lib/ap/posix/sysconf.c | 42 | ||||
-rwxr-xr-x | sys/src/ape/lib/ap/posix/tzset.c | 141 |
9 files changed, 526 insertions, 0 deletions
diff --git a/sys/src/ape/lib/ap/posix/getgrent.c b/sys/src/ape/lib/ap/posix/getgrent.c new file mode 100755 index 000000000..345ec2ed5 --- /dev/null +++ b/sys/src/ape/lib/ap/posix/getgrent.c @@ -0,0 +1,62 @@ +#include <stdio.h> +#include <grp.h> +#include <stdlib.h> + +#define CL ':' +#define CM ',' +#define NL '\n' +#define MAXGRP 100 + +static char GROUP[] = "/etc/group"; +static FILE *grf = NULL; +static char line[BUFSIZ+1]; +static struct group group; +static char *gr_mem[MAXGRP]; + +setgrent() +{ + if( !grf ) + grf = fopen( GROUP, "r" ); + else + rewind( grf ); +} + +endgrent() +{ + if( grf ){ + fclose( grf ); + grf = NULL; + } +} + +static char * +grskip(register char *p, register c) +{ + while( *p && *p != c ) ++p; + if( *p ) *p++ = 0; + return( p ); +} + +struct group * +getgrent() +{ + register char *p, **q; + + if( !grf && !(grf = fopen( GROUP, "r" )) ) + return(NULL); + if( !(p = fgets( line, BUFSIZ, grf )) ) + return(NULL); + group.gr_name = p; + p = grskip(p,CL); /* passwd */ + group.gr_gid = atoi(p = grskip(p,CL)); + group.gr_mem = gr_mem; + p = grskip(p,CL); + grskip(p,NL); + q = gr_mem; + while( *p ){ + *q++ = p; + p = grskip(p,CM); + } + *q = NULL; + return( &group ); +} diff --git a/sys/src/ape/lib/ap/posix/getpwent.c b/sys/src/ape/lib/ap/posix/getpwent.c new file mode 100755 index 000000000..779ae3a54 --- /dev/null +++ b/sys/src/ape/lib/ap/posix/getpwent.c @@ -0,0 +1,69 @@ +#include <stdio.h> +#include <pwd.h> +#include <stdlib.h> + +static char PASSWD[] = "/etc/passwd"; +static FILE *pwf = NULL; +static char line[BUFSIZ+2]; +static struct passwd passwd; + +void +setpwent(void) +{ + if( pwf == NULL ) + pwf = fopen( PASSWD, "r" ); + else + rewind( pwf ); +} + +void +endpwent(void) +{ + if( pwf != NULL ){ + fclose( pwf ); + pwf = NULL; + } +} + +static char * +pwskip(char *p) +{ + while( *p && *p != ':' && *p != '\n' ) + ++p; + if( *p ) *p++ = 0; + else p[1] = 0; + return(p); +} + +struct passwd * +pwdecode(char *p) +{ + passwd.pw_name = p; + p = pwskip(p); + p = pwskip(p); /* passwd */ + passwd.pw_uid = atoi(p); + p = pwskip(p); + passwd.pw_gid = atoi(p); + p = pwskip(p); /* comment */ + p = pwskip(p); /* gecos */ + passwd.pw_dir = p; + p = pwskip(p); + passwd.pw_shell = p; + p = pwskip(p); + return(&passwd); +} + +struct passwd * +getpwent(void) +{ + register char *p; + + if (pwf == NULL) { + if( (pwf = fopen( PASSWD, "r" )) == NULL ) + return(0); + } + p = fgets(line, BUFSIZ, pwf); + if (p==NULL) + return(0); + return pwdecode (p); +} diff --git a/sys/src/ape/lib/ap/posix/locale.c b/sys/src/ape/lib/ap/posix/locale.c new file mode 100755 index 000000000..2468a3510 --- /dev/null +++ b/sys/src/ape/lib/ap/posix/locale.c @@ -0,0 +1,62 @@ +#include <locale.h> +#include <limits.h> +#include <string.h> + +static struct lconv Clocale = { + ".", /* decimal_point */ + "", /* thousands_sep */ + "", /* grouping */ + "", /* int_curr_symbol */ + "", /* currency_symbol */ + "", /* mon_decimal_point */ + "", /* mon_thousands_sep */ + "", /* mon_grouping */ + "", /* positive_sign */ + "", /* negative_sign */ + CHAR_MAX, /* int_frac_digits */ + CHAR_MAX, /* frac_digits */ + CHAR_MAX, /* p_cs_precedes */ + CHAR_MAX, /* p_sep_by_space */ + CHAR_MAX, /* n_cs_precedes */ + CHAR_MAX, /* n_sep_by_space */ + CHAR_MAX, /* p_sign_posn */ + CHAR_MAX, /* n_sign_posn */ +}; + +static char *localename[2] = {"C", ""}; +static short catlocale[6] = {0, 0, 0, 0, 0, 0}; + /* indices into localename for categories LC_ALL, LC_COLLATE, etc. */ + +#define ASIZE(a) (sizeof(a)/sizeof(a[0])) + +char * +setlocale(int category, const char *locale) +{ + int c, i; + + if(category < 0 || category >= ASIZE(catlocale)) + return 0; + if(!locale) + return localename[catlocale[category]]; + for(c=0; c<ASIZE(localename); c++) + if(strcmp(locale, localename[c]) == 0) + break; + if(c >= ASIZE(localename)) + return 0; + catlocale[category] = c; + if(category == LC_ALL) + for(i=0; i<ASIZE(catlocale); i++) + catlocale[i] = c; + return localename[c]; +} + +struct lconv * +localeconv(void) +{ + /* BUG: posix says look at environment variables + * to set locale "", but we just make it the same + * as C, always. + */ + return &Clocale; +} + diff --git a/sys/src/ape/lib/ap/posix/mkfifo.c b/sys/src/ape/lib/ap/posix/mkfifo.c new file mode 100755 index 000000000..7dbc8f5b6 --- /dev/null +++ b/sys/src/ape/lib/ap/posix/mkfifo.c @@ -0,0 +1,12 @@ +#include <sys/types.h> +#include <sys/stat.h> +#include <errno.h> + +int +mkfifo(char *path, mode_t mode) +{ +#pragma ref path +#pragma ref mode + errno = 0; + return -1; +} diff --git a/sys/src/ape/lib/ap/posix/mkfile b/sys/src/ape/lib/ap/posix/mkfile new file mode 100755 index 000000000..268a991d0 --- /dev/null +++ b/sys/src/ape/lib/ap/posix/mkfile @@ -0,0 +1,16 @@ +APE=/sys/src/ape +<$APE/config +LIB=/$objtype/lib/ape/libap.a +OFILES=\ + getgrent.$O\ + getpwent.$O\ + locale.$O\ + mkfifo.$O\ + pathconf.$O\ + sigset.$O\ + sysconf.$O\ + tzset.$O\ + +</sys/src/cmd/mksyslib + +CFLAGS=-c -D_POSIX_SOURCE diff --git a/sys/src/ape/lib/ap/posix/pathconf.c b/sys/src/ape/lib/ap/posix/pathconf.c new file mode 100755 index 000000000..9fdf47684 --- /dev/null +++ b/sys/src/ape/lib/ap/posix/pathconf.c @@ -0,0 +1,55 @@ +#include <unistd.h> +#include <limits.h> +#include <errno.h> +#include <sys/limits.h> + +long +pathconf(const char *path, int name) +{ +#pragma ref path + + switch(name) + { + case _PC_LINK_MAX: + return LINK_MAX; + case _PC_MAX_CANON: + return MAX_CANON; + case _PC_MAX_INPUT: + return MAX_INPUT; + case _PC_NAME_MAX: + return NAME_MAX; + case _PC_PATH_MAX: + return PATH_MAX; + case _PC_PIPE_BUF: + return PIPE_BUF; + case _PC_CHOWN_RESTRICTED: +#ifdef _POSIX_CHOWN_RESTRICTED + return _POSIX_CHOWN_RESTRICTED; +#else + return -1; +#endif + case _PC_NO_TRUNC: +#ifdef _POSIX_NO_TRUNC + return _POSIX_NO_TRUNC; +#else + return -1; +#endif + case _PC_VDISABLE: +#ifdef _POSIX_VDISABLE + return _POSIX_VDISABLE; +#else + return -1; +#endif + } + errno = EINVAL; + return -1; +} + +long +fpathconf(int fd, int name) +{ +#pragma ref fd + + return pathconf(0, name); +} + diff --git a/sys/src/ape/lib/ap/posix/sigset.c b/sys/src/ape/lib/ap/posix/sigset.c new file mode 100755 index 000000000..1a9ef12aa --- /dev/null +++ b/sys/src/ape/lib/ap/posix/sigset.c @@ -0,0 +1,67 @@ +#include <signal.h> +#include <errno.h> + +/* + * sigsets are 32-bit longs. if the 2<<(i-1) bit is on, + * the signal #define'd as i in signal.h is inluded. + */ + +static sigset_t stdsigs = SIGHUP|SIGINT|SIGQUIT|SIGILL|SIGABRT|SIGFPE|SIGKILL| + SIGSEGV|SIGPIPE|SIGALRM|SIGTERM|SIGUSR1|SIGUSR2; + +#define BITSIG(s) (2<<(s)) + +int +sigemptyset(sigset_t *set) +{ + *set = 0; + return 0; +} + +int +sigfillset(sigset_t *set) +{ + *set = stdsigs; + return 0; +} + +int +sigaddset(sigset_t *set, int signo) +{ + int b; + + b = BITSIG(signo); + if(!(b&stdsigs)){ + errno = EINVAL; + return -1; + } + *set |= b; + return 0; +} + +int +sigdelset(sigset_t *set, int signo) +{ + int b; + + b = BITSIG(signo); + if(!(b&stdsigs)){ + errno = EINVAL; + return -1; + } + *set &= ~b; + return 0; +} + +int +sigismember(sigset_t *set, int signo) +{ + int b; + + b = BITSIG(signo); + if(!(b&stdsigs)){ + errno = EINVAL; + return -1; + } + return (b&*set)? 1 : 0; +} diff --git a/sys/src/ape/lib/ap/posix/sysconf.c b/sys/src/ape/lib/ap/posix/sysconf.c new file mode 100755 index 000000000..cd7adaaab --- /dev/null +++ b/sys/src/ape/lib/ap/posix/sysconf.c @@ -0,0 +1,42 @@ +#include <stdio.h> +#include <unistd.h> +#include <limits.h> +#include <time.h> +#include <errno.h> +#include <sys/limits.h> + +long +sysconf(int name) +{ + switch(name) + { + case _SC_ARG_MAX: + return ARG_MAX; + case _SC_CHILD_MAX: + return CHILD_MAX; + case _SC_CLK_TCK: + return CLOCKS_PER_SEC; + case _SC_NGROUPS_MAX: + return NGROUPS_MAX; + case _SC_OPEN_MAX: + return OPEN_MAX; + case _SC_JOB_CONTROL: +#ifdef _POSIX_JOB_CONTROL + return _POSIX_JOB_CONTROL; +#else + return -1; +#endif + case _SC_SAVED_IDS: +#ifdef _POSIX_SAVED_IDS + return _POSIX_SAVED_IDS; +#else + return -1; +#endif + case _SC_VERSION: + return _POSIX_VERSION; + case _SC_LOGIN_NAME_MAX: + return L_cuserid; + } + errno = EINVAL; + return -1; +} diff --git a/sys/src/ape/lib/ap/posix/tzset.c b/sys/src/ape/lib/ap/posix/tzset.c new file mode 100755 index 000000000..8502c6d66 --- /dev/null +++ b/sys/src/ape/lib/ap/posix/tzset.c @@ -0,0 +1,141 @@ +#include <stdlib.h> +#include <sys/types.h> +#include <fcntl.h> +#include <time.h> +#include <ctype.h> +#include <string.h> +#include <unistd.h> + +#define TZFILE "/etc/TZ" + +static char TZ[128]; +static char std[32] = "GMT0"; +static char dst[32]; +char *tzname[2] = { + std, dst +}; +time_t tzoffset, tzdstoffset; +int tzdst = 0; + +static int +offset(char *env, time_t *off) +{ + int n, sign; + size_t len, retlen; + + retlen = 0; + sign = 1; + /* + * strictly, no sign is allowed in the 'time' part of the + * dst start/stop rules, but who cares? + */ + if (*env == '-' || *env == '+') { + if (*env++ == '-') + sign = -1; + retlen++; + } + if ((len = strspn(env, ":0123456789")) == 0) + return 0; + retlen += len; + for (*off = 0; len && isdigit(*env); len--) /* hours */ + *off = *off*10 + (*env++ - '0')*60*60; + if (len) { + if (*env++ != ':') + return 0; + len--; + } + for (n = 0; len && isdigit(*env); len--) /* minutes */ + n = n*10 + (*env++ - '0')*60; + *off += n; + if (len) { + if (*env++ != ':') + return 0; + len--; + } + for (n = 0; len && isdigit(*env); len--) /* seconds */ + n = n*10 + (*env++ - '0'); + *off = (*off + n)*sign; + return retlen; +} + +/* + * TZ=stdoffset[dst[offset][,start[/time],end[/time]]] + */ +void +tzset(void) +{ + char *env, *p, envbuf[128]; + int fd, i; + size_t len, retlen; + time_t off; + + /* + * get the TZ environment variable and check for validity. + * the implementation-defined manner for dealing with the + * leading ':' format is to reject it. + * if it's ok, stash a copy away for quick comparison next time. + */ + if ((env = getenv("TZ")) == 0) { + if ((fd = open(TZFILE, O_RDONLY)) == -1) + return; + if (read(fd, envbuf, sizeof(envbuf)-1) == -1) { + close(fd); + return; + } + close(fd); + for (i = 0; i < sizeof(envbuf); i++) { + if (envbuf[i] != '\n') + continue; + envbuf[i] = '\0'; + break; + } + env = envbuf; + } + if (strcmp(env, TZ) == 0) + return; + if (*env == 0 || *env == ':') + return; + strncpy(TZ, env, sizeof(TZ)-1); + TZ[sizeof(TZ)-1] = 0; + /* + * get the 'std' string. + * before committing, check there is a valid offset. + */ + if ((len = strcspn(env, ":0123456789,-+")) == 0) + return; + if ((retlen = offset(env+len, &off)) == 0) + return; + for (p = std, i = len+retlen; i; i--) + *p++ = *env++; + *p = 0; + tzoffset = -off; + /* + * get the 'dst' string (if any). + */ + if (*env == 0 || (len = strcspn(env, ":0123456789,-+")) == 0) + return; + for (p = dst; len; len--) + *p++ = *env++; + *p = 0; + /* + * optional dst offset. + * default is one hour. + */ + tzdst = 1; + if (retlen = offset(env+len, &off)) { + tzdstoffset = -off; + env += retlen; + } + else + tzdstoffset = tzoffset + 60*60; + /* + * optional rule(s) for start/end of dst. + */ + if (*env == 0 || *env != ',' || *(env+1) == 0) + return; + env++; + /* + * we could go on... + * but why bother? + */ +} |