#include #include #include static int isme(char *uid) { int n; char *p; n = strtol(uid, &p, 10); if(*p == 0 && p > uid) return n == getuid(); return strcmp(getuser(), uid) == 0; } /* * Absent other hints, it works reasonably well to use * the X11 display name as the name space identifier. * This is how sam's B has worked since the early days. * Since most programs using name spaces are also using X, * this still seems reasonable. Terminal-only sessions * can set $NAMESPACE. */ static char* nsfromdisplay(void) { int fd; Dir *d; char *disp, *p; if((disp = getenv("DISPLAY")) == nil){ #ifdef __APPLE__ // Might be running native GUI on OS X. disp = strdup(":0.0"); if(disp == nil) return nil; #else werrstr("$DISPLAY not set"); return nil; #endif } /* canonicalize: xxx:0.0 => xxx:0 */ p = strrchr(disp, ':'); if(p){ p++; while(isdigit((uchar)*p)) p++; if(strcmp(p, ".0") == 0) *p = 0; } /* turn /tmp/launch/:0 into _tmp_launch_:0 (OS X 10.5) */ for(p=disp; *p; p++) if(*p == '/') *p = '_'; p = smprint("/tmp/ns.%s.%s", getuser(), disp); free(disp); if(p == nil){ werrstr("out of memory"); return p; } if((fd=create(p, OREAD, DMDIR|0700)) >= 0){ close(fd); return p; } if((d = dirstat(p)) == nil){ free(d); werrstr("stat %s: %r", p); free(p); return nil; } if((d->mode&0777) != 0700 || !isme(d->uid)){ werrstr("bad name space dir %s", p); free(p); free(d); return nil; } free(d); return p; } char* getns(void) { char *ns; ns = getenv("NAMESPACE"); if(ns == nil) ns = nsfromdisplay(); if(ns == nil){ werrstr("$NAMESPACE not set, %r"); return nil; } return ns; }