summaryrefslogtreecommitdiff
path: root/sys/src/ape/lib/ap/posix
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /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-xsys/src/ape/lib/ap/posix/getgrent.c62
-rwxr-xr-xsys/src/ape/lib/ap/posix/getpwent.c69
-rwxr-xr-xsys/src/ape/lib/ap/posix/locale.c62
-rwxr-xr-xsys/src/ape/lib/ap/posix/mkfifo.c12
-rwxr-xr-xsys/src/ape/lib/ap/posix/mkfile16
-rwxr-xr-xsys/src/ape/lib/ap/posix/pathconf.c55
-rwxr-xr-xsys/src/ape/lib/ap/posix/sigset.c67
-rwxr-xr-xsys/src/ape/lib/ap/posix/sysconf.c42
-rwxr-xr-xsys/src/ape/lib/ap/posix/tzset.c141
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?
+ */
+}