卸载挂载点失败时获取字符串的问题

到目前为止,我使用了四种方式卸载挂载点。第一种是使用system函数,但是没法获取umount失败时的字符串,比如说device is busy。第二种方式是使用系统函数umount,虽然可以得到设备忙的错误码,但是不能清楚系统文件/etc/mtab的记录。第三种方式是使用popen函数(参数1是“umount /mnt/wzhwho”,参数2是“r”),但是卸载挂载点失败时还是不能获取到字符串。第四种是使用pipe函数,fork函数和execlp函数,实现了我期望的效果。但是我不明白第三种方式为什么不行?

第三种和第四种的源程序如下:

/******************************************************************************* * * 卸载挂载点失败时获取字符串(pipe, vfork, execlp) * *******************************************************************************/ #include <sys/types.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <sys/wait.h> #define BUFFER_LEN 1023 #define MOUNT_POINT "/mnt/wzhwho" # ifndef errno extern int errno; # endif int main(void) { int32_t ret = 0; uint32_t retval = 0; int32_t fd[2];// 创建管道返回的文件描述符 int32_t status_child = 0; int32_t childpid = 0; // 子进程pid int length = 1; unsigned int chars_read = 0; char *buf = NULL; char *tmp = NULL; char read_buf[BUFFER_LEN + 1] = {0}; // 调用pipe建立管道 ret = pipe(fd); if (0 != ret) { // 打印创建管道失败 retval = errno; printf("Failed to pipe: %s/n", strerrno(errno)); return retval; } // 调用vfork创建新进程,并获取pid childpid = vfork(); if (0 == childpid) { /*========= 进入子进程处理流程 ========*/ // 关闭管道读取端 if ( 0> (ret = close(fd[0]))) { printf("Failed to close file: %s/n",strerrno(errno)); } // 将标准输出定向到管道写入端 if (0 > (ret = dup2(fd[1],STDOUT_FILENO))) { printf("Failed to dup2: %s/n",strerrno(errno)); } // 将标准错误输出定向到管道写入端 if (0 > (ret = dup2(fd[1],STDERR_FILENO))) { printf("Failed to dup2: %s/n",strerrno(errno)); } //执行命令 ret = execlp("umount","umount", MOUNT_POINT, (char *)0); if (-1 == ret) { printf("Failed to execvp: %s/n",strerrno(errno)); } // 退出子进程 exit(EXIT_FAILURE) ; // 成功执行后不返回 } else if(-1 == childpid) { retval = build_retval(errno); /* 打印fork子进程出错 */ if ( 0> (ret = close(fd[1]))) { printf("Failed to close file: %s/n",strerrno(errno)); } if ( 0> (ret = close(fd[0]))) { printf("Failed to close file: %s/n",strerrno(errno)); } return retval; } // 关闭管道写入端 if ( 0> (ret = close(fd[1]))) { printf("Failed to close file: %s/n",strerrno(errno)); } /*==========父进程处理流程 ============*/ // 读取子进程信息 memset(read_buf,0, sizeof(read_buf)); chars_read = read(fd[0],read_buf, sizeof(read_buf) -1); // 循环的读通道信息,直到读完 while(chars_read > 0) { tmp = realloc(buf,(unsigned int)(length + (int)chars_read)); // 分配空间失败 if(NULL == tmp) { printf("Fail to realloc: %s/n",strerrno(errno)); if(buf != NULL) { free(buf); } return -1; } buf = tmp; strncpy(buf+length-1,read_buf,chars_read); length = length+(int)chars_read; buf[length-1] = 0; chars_read = read(fd[0],read_buf, sizeof(read_buf) -1); } // 关闭管道读端 if ( 0> (ret = close(fd[0]))) { printf("Failed to close file: %s/n",strerrno(errno)); } // 调用waitpid等待子进程返回 */ waitpid(childpid,&status_child,0); // 调用WIFEXITED判断子进程的返回状态字是可以访问的 if (!WIFEXITED(status_child)) { // 状态字不可访问信息 if ( 0> (ret = close(fd[0]))) { printf("Failed to close file: %s/n",strerrno(errno)); } return -1; } // 取得进程结束返回值 if (WEXITSTATUS(status_child)) { //判断管道中的数据是否带有busy if(buf != NULL) { tmp = NULL; printf("buf = %s/n", buf); if((tmp = strstr(buf, "busy")) != NULL) { printf("Fail to umount %s : device is busy/n", MOUNT_POINT); } free(buf); } // 子进程退出异常 printf("Fail to umount %s/n", MOUNT_POINT); return -1; } exit(EXIT_SUCCESS); } /******************************************************************************* * * 卸载挂载点失败时获取字符串(popen) * *******************************************************************************/ int main() { FILE *fp; int length = 1; unsigned int chars_read = 0; char *buf = NULL; char *tmp = NULL; char read_buf[BUFFER_LEN + 1] = {0}; char cmd[BUFFER_LEN + 1] = {0}; uint32_t ret = 0; snprintf(cmd,sizeof(cmd),"umount %s",MOUNT_POINT); fp = popen(cmd, "r"); if(NULL == fp) { printf("Fail to popen: %s/n", strerrno(errno)); return -1; } else { memset(read_buf, 0, sizeof(read_buf)); chars_read = fread(read_buf, sizeof(char), BUFFER_LEN, fp); // 读信息失败 if(chars_read == 0) { printf("Failed to read message./n"); pclose(fp); return -1; } // 循环的读通道信息,直到读完 */ while(chars_read > 0) { tmp = realloc(buf,(unsigned int)(length + (int)chars_read)); // 分配空间失败 if(NULL == tmp) { printf("Fail to realloc./n"); if(buf != NULL) { free(buf); } return -1; } buf = tmp; strncpy(buf+length-1,read_buf,chars_read); length = length+(int)chars_read; buf[length-1] = 0; chars_read = fread(read_buf, sizeof(char), BUFFER_LEN, fp); } pclose(fp); } //判断管道中的数据是否带有busy if(buf != NULL) { tmp = NULL; printf("buf = %s/n", buf); if((tmp = strstr(buf, "busy")) != NULL) { printf("Fail to umount %s : device is busy/n", MOUNT_POINT); } free(buf); return -1; } exit(EXIT_SUCCESS); }

 

 

 

你可能感兴趣的:(File,cmd,null,System,buffer,FP)