about summary refs log tree commit diff
path: root/Src/Modules/system.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Modules/system.c')
-rw-r--r--Src/Modules/system.c97
1 files changed, 88 insertions, 9 deletions
diff --git a/Src/Modules/system.c b/Src/Modules/system.c
index dfdf094b9..1eaa2fabd 100644
--- a/Src/Modules/system.c
+++ b/Src/Modules/system.c
@@ -340,6 +340,12 @@ bin_syserror(char *nam, char **args, Options ops, UNUSED(int func))
     return 0;
 }
 
+static struct builtin bintab[] = {
+    BUILTIN("syserror", 0, bin_syserror, 0, 1, 0, "e:p:", NULL),
+    BUILTIN("sysread", 0, bin_sysread, 0, 1, 0, "c:i:o:s:t:", NULL),
+    BUILTIN("syswrite", 0, bin_syswrite, 1, 1, 0, "c:o:", NULL),
+};
+
 
 /* Functions for the errnos special parameter. */
 
@@ -351,16 +357,54 @@ errnosgetfn(UNUSED(Param pm))
     return arrdup((char **)sys_errnames);
 }
 
-
-static struct builtin bintab[] = {
-    BUILTIN("syserror", 0, bin_syserror, 0, 1, 0, "e:p:", NULL),
-    BUILTIN("sysread", 0, bin_sysread, 0, 1, 0, "c:i:o:s:t:", NULL),
-    BUILTIN("syswrite", 0, bin_syswrite, 1, 1, 0, "c:o:", NULL),
-};
-
 static const struct gsu_array errnos_gsu =
 { errnosgetfn, arrsetfn, stdunsetfn };
 
+
+/* Functions for the sysparams special parameter. */
+
+/**/
+static char *
+sysparamgetfn(Param pm)
+{
+    char buf[DIGBUFSIZE];
+    int num;
+
+    if (!strcmp(pm->node.nam, "pid")) {
+	num = (int)getpid();
+    } else if (!strcmp(pm->node.nam, "ppid")) {
+	num = (int)getppid();
+    }
+    else {
+#ifdef DEBUG
+	dputs("Bad sysparam parameter");
+#endif
+	return "";
+    }
+
+    sprintf(buf, "%d", num);
+    return dupstring(buf);
+}
+
+static const struct gsu_scalar sysparam_gsu =
+{ sysparamgetfn, strsetfn, stdunsetfn };
+
+static void
+fixsysparams(HashNode hn, int flags)
+{
+    Param pm = (Param)hn;
+
+    if (flags) {
+	/* prepare to free */
+	pm->node.flags &= ~PM_READONLY;
+    } else {
+	/* assign */
+	pm->gsu.s = &sysparam_gsu;
+	pm->node.flags |= PM_READONLY;
+    }
+}
+
+
 /* The load/unload routines required by the zsh library interface */
 
 /**/
@@ -385,7 +429,12 @@ tidyparam(Param pm)
 int
 boot_(Module m)
 {
-    Param pm_nos;
+    Param pm_nos, pm_params;
+    HashTable ht;
+    const char *sysparams_args[] = {
+	"pid", 	"ppid", NULL
+    }, **srcptr;
+    char **arglist, **dstptr;
 
     /* this takes care of an autoload on errnos */
     unsetparam("errnos");
@@ -394,8 +443,31 @@ boot_(Module m)
 	return 1;
     pm_nos->gsu.a = &errnos_gsu;
 
+    if (!(pm_params = createparam("sysparams", PM_HASHED|PM_SPECIAL|
+				  PM_HIDE|PM_HIDEVAL|PM_REMOVABLE))) {
+	tidyparam(pm_nos);
+	return 1;
+    }
+    pm_params->level = pm_params->old ? locallevel : 0;
+    pm_params->gsu.h = &stdhash_gsu;
+    pm_params->u.hash = ht = newparamtable(0, "sysparams");
+
+    arglist = (char **)zshcalloc((2*arrlen((char **)sysparams_args) + 1) *
+			       sizeof(char *));
+    for (srcptr = sysparams_args, dstptr = arglist; *srcptr; ) {
+	*dstptr++ = ztrdup(*srcptr++);
+	*dstptr++ = ztrdup("");
+    }
+    *dstptr = NULL;
+    /* make sure we don't overwrite the hash table: use the "augment" arg */
+    arrhashsetfn(pm_params, arglist, 1);
+    scanhashtable(ht, 0, 0, 0, fixsysparams, 0);
+
+    pm_params->node.flags |= PM_READONLY;
+
     if (!addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab))) {
 	tidyparam(pm_nos);
+	tidyparam(pm_params);
 	return 1;
     }
     return 0;
@@ -406,7 +478,14 @@ boot_(Module m)
 int
 cleanup_(Module m)
 {
-    tidyparam((Param)paramtab->getnode(paramtab, "errnos"));
+    Param pm;
+    if ((pm = (Param)paramtab->getnode(paramtab, "errnos")))
+	tidyparam(pm);
+    if ((pm = (Param)paramtab->getnode(paramtab, "sysparams")))
+    {
+	scanhashtable(pm->u.hash, 0, 0, 0, fixsysparams, 1);
+	tidyparam(pm);
+    }
 
     deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
     return 0;