📄 18.htm
字号:
<p>} </p>
<p>return(0); </p>
<p>} </p>
<p>_______________________________________________________________________</p>
<p>_______ </p>
<p>程序18.4 cli_args函数 </p>
<p>_______________________________________________________________________</p>
<p>_______ </p>
<p>#include "calld.h" </p>
<p>static void </p>
<p>client_alloc(void) /* alloc more entries in the client[]</p>
<p>array */ </p>
<p>{ </p>
<p>int i; </p>
<p>if (client == NULL) </p>
<p>client = malloc(NALLOC * sizeof(Client)); </p>
<p>else </p>
<p>client = realloc(client, (client_size + NALLOC) *</p>
<p>sizeof(Client) </p>
<p>; </p>
<p>if (client == NULL) </p>
<p>err_sys("can't alloc for client array"); </p>
<p>/* have to initialize the new entries */ </p>
<p>for (i = client_size; i < client_size + NALLOC; i++) </p>
<p>client[i].fd = -1; /* fd of -1 means entry available */ </p>
<p>client_size += NALLOC; </p>
<p>} </p>
<p>/* Called by loop() when connection request from a new</p>
<p>client arrives * </p>
<p>/ </p>
<p>int </p>
<p>client_add(int fd, uid_t uid) </p>
<p>{ </p>
<p>int i; </p>
<p>if (client == NULL) /* first time we're called */ </p>
<p>client_alloc(); </p>
<p>again: </p>
<p>for (i = 0; i < client_size; i++) { </p>
<p>if (client[i].fd == -1) { /* find an available entry */ </p>
<p>client[i].fd = fd; </p>
<p>client[i].uid = uid; </p>
<p>return(i); /* return index in client[] array */ </p>
<p>} </p>
<p>} </p>
<p>/* client array full, time to realloc for more */ </p>
<p>client_alloc(); </p>
<p>goto again; /* and search again (will work this time) */ </p>
<p>} </p>
<p>/* Called by loop() when we're done with a client */ </p>
<p>void </p>
<p>client_del(int fd) </p>
<p>{ </p>
<p>int i; </p>
<p>for (i = 0; i < client_size; i++) { </p>
<p>if (client[i].fd == fd) { </p>
<p>client[i].fd = -1; </p>
<p>return; </p>
<p>} </p>
<p>} </p>
<p>log_quit("can't find client entry for fd %d", fd); </p>
<p>} </p>
<p>/* Find the client entry corresponding to a process ID. </p>
<p>* This function is called by the sig_chld() signal </p>
<p>* handler only after a child has terminated. */ </p>
<p>void </p>
<p>client_sigchld(pid_t pid, int stat) </p>
<p>{ </p>
<p>int i; </p>
<p>for (i = 0; i < client_size; i++) { </p>
<p>if (client[i].pid == pid) { </p>
<p>client[i].childdone = stat; /* child's exit() status </p>
<p>+1 */ </p>
<p>return; </p>
<p>} </p>
<p>} </p>
<p>log_quit("can't find client entry for pid %d", pid); </p>
<p>} </p>
<p>_______________________________________________________________________</p>
<p>_______ </p>
<p>程序18.5 client.c程序 </p>
<p>_______________________________________________________________________</p>
<p>_______ </p>
<p>#include "calld.h" </p>
<p>typedef struct { </p>
<p>char *line; /* points to malloc()ed area */ </p>
<p>/* we lock by line (device name) */ </p>
<p>pid_t pid; /* but unlock by process ID */ </p>
<p>/* pid of 0 means available */ </p>
<p>} Lock; </p>
<p>static Lock *lock = NULL; /* the malloc'ed/realloc'ed array</p>
<p>*/ </p>
<p>static int lock_size; /* #entries in lock[] */ </p>
<p>static int nlocks; /* #entries currently used in lock[] */ </p>
<p>/* Find the entry in lock[] for the specified device (line).</p>
<p>* If we don't find it, create a new entry at the end of the </p>
<p>* lock[] array for the new device. This is how all the</p>
<p>possible </p>
<p>* devices get added to the lock[] array over time. */ </p>
<p>static Lock * </p>
<p>find_line(char *line) </p>
<p>{ </p>
<p>int i; </p>
<p>Lock *lptr; </p>
<p>for (i = 0; i < nlocks; i++) { </p>
<p>if (strcmp(line, lock[i].line) == 0) </p>
<p>return(&lock[i]); /* found entry for device */ </p>
<p>} </p>
<p>/* Entry not found. This device has never been locked</p>
<p>before. </p>
<p>Add a new entry to lock[] array. */ </p>
<p>if (nlocks >= lock_size) { /* lock[] array is full */ </p>
<p>if (lock == NULL) /* first time through */ </p>
<p>lock = malloc(NALLOC * sizeof(Lock)); </p>
<p>else </p>
<p>lock = realloc(lock, (lock_size + NALLOC) * sizeof(Lock) </p>
<p>; </p>
<p>if (lock == NULL) </p>
<p>err_sys("can't alloc for lock array"); </p>
<p>lock_size += NALLOC; </p>
<p>} </p>
<p>lptr = &lock[nlocks++]; </p>
<p>if ( (lptr->line = malloc(strlen(line) + 1)) == NULL) </p>
<p>log_sys("calloc error"); </p>
<p>strcpy(lptr->line, line); /* copy caller's line name */ </p>
<p>lptr->pid = 0; </p>
<p>return(lptr); </p>
<p>} </p>
<p>void </p>
<p>lock_set(char *line, pid_t pid) </p>
<p>{ </p>
<p>Lock *lptr; </p>
<p>log_msg("locking %s for pid %d", line, pid); </p>
<p>lptr = find_line(line); </p>
<p>lptr->pid = pid; </p>
<p>} </p>
<p>void </p>
<p>lock_rel(pid_t pid) </p>
<p>{ </p>
<p>Lock *lptr; </p>
<p>for (lptr = &lock[0]; lptr < &lock[nlocks]; lptr++) { </p>
<p>if (lptr->pid == pid) { </p>
<p>log_msg("unlocking %s for pid %d", lptr->line, pid); </p>
<p>lptr->pid = 0; </p>
<p>return; </p>
<p>} </p>
<p>} </p>
<p>log_msg("can't find lock for pid = %d", pid); </p>
<p>} </p>
<p>pid_t </p>
<p>is_locked(char *line) </p>
<p>{ </p>
<p>return( find_line(line)->pid ); /* nonzero pid means locked</p>
<p>*/ </p>
<p>} </p>
<p>_______________________________________________________________________</p>
<p>_______ </p>
<p>程序18.6 管理设备锁的函数组 </p>
<p>在lock数组中的每一项都与一个line(Devices文件的第二个域)相关联。</p>
<p>因 </p>
<p>为这些加锁函数不知道在该数据文件中的所有的line值,所以每当一个新</p>
<p>line被第 </p>
<p>一次加锁时,就在lock数组中增加一项。函数find_line处理加锁。 </p>
<p>下面的三个源程序文件处理三个数据文件:Systems, Devices和Dialers。</p>
<p>每 </p>
<p>个文件有个XXX_next函数,它读取文件中的下一行,调用ANSI C函数</p>
<p>strtok把这一 </p>
<p>行分成各个标记。程序18.7处理Systems文件。 </p>
<p>_______________________________________________________________________</p>
<p>_______ </p>
<p>#include "calld.h" </p>
<p>static FILE *fpsys = NULL; </p>
<p>static int syslineno; /* for error messages */ </p>
<p>static char sysline[MAXLINE]; </p>
<p>/* can't be automatic; sys_next() returns pointers into here</p>
<p>*/ </p>
<p>/* Read and break apart a line in the Systems file. */ </p>
<p>long /* return >0 if OK, -1 on EOF */ </p>
<p>sys_next(Systems *sysptr) /* structure is filled in with</p>
<p>pointers */ </p>
<p>{ </p>
<p>if (fpsys == NULL) { </p>
<p>if ( (fpsys = fopen(SYSTEMS, "r")) == NULL) </p>
<p>log_sys("can't open %s", SYSTEMS); </p>
<p>syslineno = 0; </p>
<p>} </p>
<p>again: </p>
<p>if (fgets(sysline, MAXLINE, fpsys) == NULL) </p>
<p>return(-1); /* EOF */ </p>
<p>syslineno++; </p>
<p>if ( (sysptr->name = strtok(sysline, WHITE)) == NULL) { </p>
<p>if (sysline[0] == '\n') </p>
<p>goto again; /* ignore empty line */ </p>
<p>log_quit("missing `name' in Systems file, line %d",</p>
<p>syslineno); </p>
<p>} </p>
<p>if (sysptr->name[0] == '#') </p>
<p>goto again; /* ignore comment line */ </p>
<p>if ( (sysptr->time = strtok(NULL, WHITE)) == NULL) </p>
<p>log_quit("missing `time' in Systems file, line %d",</p>
<p>syslineno); </p>
<p>if ( (sysptr->type = strtok(NULL, WHITE)) == NULL) </p>
<p>log_quit("missing `type' in Systems file, line %d",</p>
<p>syslineno); </p>
<p>if ( (sysptr->class = strtok(NULL, WHITE)) == NULL) </p>
<p>log_quit("missing `class' in Systems file, line %d",</p>
<p>syslineno); </p>
<p>if ( (sysptr->phone = strtok(NULL, WHITE)) == NULL) </p>
<p>log_quit("missing `phone' in Systems file, line %d",</p>
<p>syslineno); </p>
<p>if ( (sysptr->login = strtok(NULL, "\n")) == NULL) </p>
<p>log_quit("missing `login' in Systems file, line %d",</p>
<p>syslineno); </p>
<p>return(ftell(fpsys)); /* return the position in Systems file</p>
<p>*/ </p>
<p>} </p>
<p>void </p>
<p>sys_rew(void) </p>
<p>{ </p>
<p>if (fpsys != NULL) </p>
<p>rewind(fpsys); </p>
<p>syslineno = 0; </p>
<p>} </p>
<p>void </p>
<p>sys_posn(long posn) /* position Systems file */ </p>
<p>{ </p>
<p>if (posn == 0) </p>
<p>sys_rew(); </p>
<p>else if (fseek(fpsys, posn, SEEK_SET) != 0) </p>
<p>log_sys("fseek error"); </p>
<p>} </p>
<p>_______________________________________________________________________</p>
<p>_______ </p>
<p>程序18.7 读取Systems文件的函数 </p>
<p>函数sys_netx由request(程序18.10)调用,其功能是读取Systems文件</p>
<p>的下 </p>
<p>一项。 </p>
<p>对于每一个客户端我们必须记住我们的当前位置(Client结构的sysftell成</p>
<p>员变量 </p>
<p>)。这样如果一个子进程拨号远程系统没有成功,我们可以知道是在Systems</p>
<p>文件 </p>
<p>中的那一项失败的,然后尝试其他项。这个位置可通过调用标准的I/O函数</p>
<p>ftell得 </p>
<p>到,可以用fseek函数复位。 </p>
<p>程序18.8 包含了读取Devices文件的函数。 </p>
<p>_______________________________________________________________________</p>
<p>_______ </p>
<p>#include "calld.h" </p>
<p>static FILE *fpdev = NULL; </p>
<p>static int devlineno; /* for error messages */ </p>
<p>static char devline[MAXLINE]; </p>
<p>/* can't be automatic; dev_next() returns pointers into here</p>
<p>*/ </p>
<p>/* Read and break apart a line in the Devices file. */ </p>
<p>int </p>
<p>dev_next(Devices *devptr) /* pointers in structure are</p>
<p>filled in */ </p>
<p>{ </p>
<p>if (fpdev == NULL) { </p>
<p>if ( (fpdev = fopen(DEVICES, "r")) == NULL) </p>
<p>log_sys("can't open %s", DEVICES); </p>
<p>devlineno = 0; </p>
<p>} </p>
<p>again: </p>
<p>if (fgets(devline, MAXLINE, fpdev) == NULL) </p>
<p>return(-1); /* EOF */ </p>
<p>devlineno++; </p>
<p>if ( (devptr->type = strtok(devline, WHITE)) == NULL) { </p>
<p>if (devline[0] == '\n') </p>
<p>goto again; /* ignore empty line */ </p>
<p>log_quit("missing `type' in Devices file, line %d",</p>
<p>devlineno); </p>
<p>} </p>
<p>if (devptr->type[0] == '#') </p>
<p>goto again; /* ignore comment line */ </p>
<p>if ( (devptr->line = strtok(NULL, WHITE)) == NULL) </p>
<p>log_quit("missing `line' in Devices file, line %d",</p>
<p>devlineno); </p>
<p>if ( (devptr->line2 = strtok(NULL, WHITE)) == NULL) </p>
<p>log_quit("missing `line2' in Devices file, line %d",</p>
<p>devlineno); </p>
<p>if ( (devptr->class = strtok(NULL, WHITE)) == NULL) </p>
<p>log_quit("missing `class' in Devices file, line %d",</p>
<p>devlineno); </p>
<p>if ( (devptr->dialer = strtok(NULL, WHITE)) == NULL) </p>
<p>log_quit("missing `dialer' in Devices file, line %d",</p>
<p>devlineno); </p>
<p>return(0); </p>
<p>} </p>
<p>void </p>
<p>dev_rew(void) </p>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -