void extstart(void) { #ifndef NOFIFO char *disp; char *user; int fd; int flags; user = getuser(); disp = getenv("DISPLAY"); if (disp) { exname = (char *)alloc(4 + 6 + strlen(user) + 1 + strlen(disp) + 1); sprint(exname, "/tmp/.sam.%s.%s", user, disp); } else { exname = (char *)alloc(4 + 6 + strlen(user) + 1); sprint(exname, "/tmp/.sam.%s", user); } /* Make the named pipe. Multiple sams with the same user/display share the same pipe */ if (mkfifo(exname, 0600) == -1) { struct stat statb; extern int errno; if (errno != EEXIST || stat(exname, &statb) == -1) return; if (!S_ISFIFO(statb.st_mode)) { removeextern(); if (mkfifo(exname, 0600) == -1) return; } } fd = open(exname, O_RDONLY | O_NONBLOCK); if (fd == -1) { removeextern(); return; } /* * Turn off no-delay and provide ourselves as a lingering * writer so as not to get end of file on read. */ flags = fcntl(fd, F_GETFL, 0); if (flags == -1 || fcntl(fd, F_SETFL, flags & ~O_NONBLOCK) == -1 || open(exname, O_WRONLY) == -1) { (void)close(fd); removeextern(); return; } estart(Eextern, fd, 8192); atexit(removeextern); #endif }
void extstart(void) { char *user, *disp; int fd, flags; static void *arg[2]; user = getenv("USER"); if(user == nil) return; disp = getenv("DISPLAY"); if(disp) exname = smprint("/tmp/.sam.%s.%s", user, disp); else exname = smprint("/tmp/.sam.%s", user); if(exname == nil){ fprint(2, "not posting for B: out of memory\n"); return; } if(mkfifo(exname, 0600) < 0){ struct stat st; if(errno != EEXIST || stat(exname, &st) < 0) return; if(!S_ISFIFO(st.st_mode)){ removeextern(); if(mkfifo(exname, 0600) < 0) return; } } fd = open(exname, OREAD|ONONBLOCK); if(fd == -1){ removeextern(); return; } /* * Turn off no-delay and provide ourselves as a lingering * writer so as not to get end of file on read. */ flags = fcntl(fd, F_GETFL, 0); if(flags<0 || fcntl(fd, F_SETFL, flags&~O_NONBLOCK)<0 ||open(exname, OWRITE) < 0){ close(fd); removeextern(); return; } plumbc = chancreate(sizeof(int), 0); chansetname(plumbc, "plumbc"); arg[0] = plumbc; arg[1] = (void*)(uintptr)fd; proccreate(extproc, arg, STACK); atexit(removeextern); }