• 自己动手写shell命令之write


    Linux下write命令同意用户跟其它终端上的用户对话。用c语言实现shell命令write。代码例如以下:

    #include	<stdio.h>
    #include	<fcntl.h>
    #include	<unistd.h>
    #include	<utmp.h>
    #include	<pwd.h>
    #include	<sys/types.h>
    #include	<stdlib.h>
    #include	<sys/stat.h>
    #include	<time.h>
    
    char * get_terminal_name(char *);
    char * get_terminal_name_by_user_name(char *);
    void hello();
    
    int main(int argc, char * argv[]) {
    	int fd;
    	char buffer[1024];
    	char * terminal_name;
    	if (argc != 2) {
    		printf("write usage: write [ttyname|username]");
    		return 1;
    	}
    	terminal_name = get_terminal_name(argv[1]);
    	if(terminal_name == NULL)
    	{
    		printf("get terminal name error
    ");
    		return 1;
    	}
    	//printf("terminate_name:%s", terminal_name);
    
    	fd = open(terminal_name,O_WRONLY);
    	hello(fd);
    
    	while(fgets(buffer,1024,stdin) != EOF)
    	{
    		write(fd,buffer,strlen(buffer));
    	}
    	close(fd);
    	return 0;
    }
    
    void hello(int fd) {
    	char greeting[1024];
    	struct passwd * passwd_pointer;
    	time_t now;
    	char host[255];
    	gethostname(host, 255);
    	time(&now);
    	passwd_pointer = getpwuid(getuid());
    	sprintf(greeting, "Message from %s@%s on %s at %5.5s ...
    ",
    			passwd_pointer->pw_name, host, ttyname(0), ctime(&now) + 11);
    	write(fd,greeting,strlen(greeting));
    }
    
    char * get_terminal_name(char * user_input) {
    	char terminal_name[255];
    	struct stat stat_buffer;
    	if (lstat(user_input, &stat_buffer) != -1) {
    		if (S_ISCHR(stat_buffer.st_mode)) {
    			return user_input;
    		}
    	}
    	return get_terminal_name_by_user_name(user_input);
    }
    
    char * get_terminal_name_by_user_name(char * user_name) {
    	struct utmp * utmp_pointer;
    	setutent();
    	int number = 0;
    	char * result = (char *) malloc(sizeof(char) * 255);
    	char *mytty = ttyname(0); /* begins "/dev/" */
    	char *ttydev = mytty + strlen("/dev/");
    	printf("%s
    ", mytty);
    
    	while ((utmp_pointer = getutent()) != NULL) {
    		if (strcmp(user_name, utmp_pointer->ut_user) == 0
    				&& utmp_pointer->ut_type == USER_PROCESS
    				&& strcmp(utmp_pointer->ut_line, ttydev) != 0
    				&& utmp_pointer->ut_line[0] != ':') {
    			number++;
    			//printf("%s
    ", utmp_pointer->ut_line);
    			if (number == 1) {
    				strcpy(result, "/dev/");
    				strcat(result, utmp_pointer->ut_line);
    			}
    		}
    	}
    	endutent();
    	if (number > 1)
    		printf("warning:%s is logged in %d different terminals,using %s
    ",
    				user_name, number, result);
    	if(number == 0)
    		return NULL;
    	return result;
    }
    

  • 相关阅读:
    [转]WPF 4 媒体播放器(MediaElement)
    WPF简单的文件资源管理
    shell脚本自动化部署
    Linux知识
    单例模式及其四种实现方式
    支付宝对接步骤 (app)
    《异类》读书摘要(上)
    Linux初级指令
    项目构建基础统一结果,统一异常,统一日志
    git看这一篇就够用了
  • 原文地址:https://www.cnblogs.com/llguanli/p/6726530.html
Copyright © 2020-2023  润新知