Path: utzoo!mnetor!uunet!husc6!bbn!uwmcsd1!ig!jade!ucbvax!cascade.carleton.CDN!holtz From: holtz@cascade.carleton.CDN (Neal Holtz) Newsgroups: comp.sys.apollo Subject: Re: Suspending processes Message-ID: <694*holtz@cascade.carleton.cdn> Date: 18 Dec 87 14:18:00 GMT Sender: daemon@ucbvax.BERKELEY.EDU Organization: The ARPA Internet Lines: 153 > Sender: Danny Wilson > > i.e. How do you suspend a print server running in background > given its process name or UID?? By using (even more) undocumented system calls. Following is a short C program that does the trick for us: -------------------------- cut here ------------------------------- /* * will suspend a process, given its UID or name * * Usage: suspend { proc_name | uid } * * If argument begins with a decimal digit, it is assumed to be a UID, * otherwise it is assumed to be a process name. */ #include #include "/sys/ins/base.ins.c" #include "/sys/ins/streams.ins.c" #include "/sys/ins/proc2.ins.c" #include "/sys/ins/error.ins.c" #define PROC_DIR "`node_data/proc_dir" typedef union { struct { time_$clockh_t toc; /* time of creation */ short xxx; /* what is this? */ short node; } p1; struct { unsigned int high32; unsigned int low32; } p2; } UID_T; UID_T puid; char procname[64]; std_$call void proc2_$suspend(); main( argc, argv ) int argc; char *argv[]; { int n; status_$t st; error_$init_std_format( stream_$errout, "?", *argv[0], (short)strlen(argv[0]) ); if( (argc<2) || (argc>3) ) complain(argv[0]); puid.high32 = 0; puid.low32 = 0; if( *argv[1] >= '0' && *argv[1] <= '9' ) { /* its a UID */ n = sscanf( argv[1], "%x.%x", &puid.high32, &puid.low32 ); if( n==0 ) complain(argv[0]); if( n==1 ) { if( argc==3 ) if( sscanf( argv[2], "%x", &puid.low32 ) != 1 ) complain(argv[0]); } sprintf( procname, "%08lx.%08lx", puid.high32, puid.low32 ); } else { /* its a process name */ getprocuid( PROC_DIR, argv[1], &puid ); sprintf( procname, "%s", argv[1] ); } proc2_$suspend( puid, st ); if( st.all == status_$ok ) printf("\n******************** Please remember to resume process \"%s\" ********************\n\n", procname ); else error_$std_format( st, "Unable to suspend process \"%la\"%$", procname, (short)strlen(procname) ); } complain( s ) char *s; { fprintf( stderr, "?(%s) Usage: %s { proc_name | uid_high.uid_low | uid_high uid_low}\n", s, s ); exit( 1 ); } /* * translate a process name to its UID by searching the node proc_dir directory * Apollo directories contain the UID associated with each name (undocumented) */ getprocuid( dirname, procname, puid ) char *dirname; char *procname; UID_T *puid; { stream_$id_t sid; stream_$sk_t sk; status_$t st; linteger len; stream_$dir_entry_t dirent, *d; char pname[256], ename[256], *s, *t; /* prepare to read the directory */ stream_$open( *dirname, (short)strlen(dirname), stream_$read, stream_$unregulated, sid, st ); if( st.all != status_$ok ) { error_$std_format( st, "Unable to open directory \"%la\"%$", *dirname, (short)strlen(dirname) ); exit( 1 ); } /* translate process name to lower case */ for( t=pname, s=procname; *s != '\0'; s++, t++ ) if( *s >= 'A' && *s <= 'Z' ) *t = *s + 32; else *t = *s; *t = '\0'; /* search proc_dir for process name */ do { stream_$get_rec( sid, &dirent, sizeof(dirent), d, len, sk, st ); if( st.code == stream_$end_of_file ) { error_$std_format( status_$ok, "Process \"%la\" not found%$", *procname, (short)strlen(procname) ); exit( 1 ); } if( st.all != status_$ok ) { error_$std_format( st, "Error reading directory \"%la\"%$", *dirname, (short)strlen(dirname) ); exit( 1 ); } if( d->entlen <= 0 || d->entlen > sizeof(d->entname) ) { error_$std_format( status_$ok, "Invalid directory entry in \"%la\"%$" , *dirname, (short)strlen(dirname) ); exit( 1 ); } strncpy( ename, d->entname, d->entlen ); ename[d->entlen] = '\0'; if( strcmp(pname,ename) == 0 ) { puid->high32 = d->unused1; /* this isn't documented, but */ puid->low32 = d->unused2; /* we know what it is. Heh. Heh. */ return; } } while( 1 ); } -------------------------- end cut --------------------------------