Changeset b2712e3 in rtems
- Timestamp:
- May 24, 2001, 9:58:39 PM (20 years ago)
- Branches:
- 4.10, 4.11, 4.8, 4.9, 5, master
- Children:
- 87fb080d
- Parents:
- e565720a
- Files:
-
- 5 added
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
c/src/libmisc/ChangeLog
re565720a rb2712e3 1 2000-05-24 Fernando Ruiz Casas <fernando.ruiz@ctv.es> 2 3 * monitor/mon-prmisc.c: Correct print line. 4 * shell/Makefile.am: Added new file telnetd.c. 5 * shell/telnetd.c, shell/telnetd.h, shell/pty.c: New files. 6 * shell/shell.c, shell/cmds.c, shell/shell.h: Numerous improvments: 7 - The shell_init has a new parameter 'forever' because in 8 /dev/console you need that this process runs forever but in 9 tcp/ip not. (respawn?) 10 - A new task for every session opened trought tcp/ip telnet client. 11 (the chargen,daytime and more are possible of implementation but 12 I ask me if they are necesary) 13 - Exit from the session delete the task and when the client fails too. 14 - More cmds have been implemented. (very reduced version of these) 15 umask, chmod, id, whoami, rm, cat, ... 16 - A reduced line edit has been implemented. 17 Ctrl-C abort the input, 18 Ctrl-d in the first position gives EOF (logout). 19 '\b' and DEL makes the rubout operation. 20 I think that readline() for every session spents a lot of resources. 21 1 22 2001-04-28 Ralf Corsepius <corsepiu@faw.uni-ulm.de> 2 23 -
c/src/libmisc/monitor/mon-prmisc.c
re565720a rb2712e3 109 109 length += rtems_monitor_dump_char(u.c[i]); 110 110 #else 111 for (i= sizeof(u.c)-1; i ; i--)112 length += rtems_monitor_dump_char(u.c[ i]);111 for (i=0; i<sizeof(u.c); i++) 112 length += rtems_monitor_dump_char(u.c[sizeof(u.c)-1-i]); 113 113 #endif 114 114 return length; -
c/src/libmisc/shell/Makefile.am
re565720a rb2712e3 10 10 LIB = $(ARCH)/$(LIBNAME).a 11 11 12 C_FILES = cmds.c shell.c 12 C_FILES = cmds.c shell.c pty.c telnetd.c 13 13 C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o) 14 14 15 include_rtems_HEADERS = shell.h 15 include_rtems_HEADERS = shell.h telnetd.h 16 16 17 17 OBJS = $(C_O_FILES) … … 40 40 .PRECIOUS: $(LIB) 41 41 42 EXTRA_DIST = README shell.c cmds.c shell.h42 EXTRA_DIST = README shell.c cmds.c pty.c telnetd.c shell.h telnetd.h 43 43 44 44 include $(top_srcdir)/../../../automake/local.am -
c/src/libmisc/shell/README
re565720a rb2712e3 20 20 and enjoy it. 21 21 22 22 3. If you have tcp/ip inited you can start telnetd daemon. 23 You need register pseudo-terminals driver into device drivers table. 24 16 ptyX termios device terminales are created into /dev/. 25 Calling rtems_initialize_telnetd() starts the daemon. 26 Enjoy it. 23 27 24 28 FUTURE: 25 29 26 30 1. Adding new commands in cmds.c to give file manegement to shell. 27 28 2. Create a telnetd daemon. (pseudo-terminal needed) -
c/src/libmisc/shell/cmds.c
re565720a rb2712e3 14 14 * 15 15 * TODO: A lot of improvements of course. 16 * c at, cp, rm, mv, ...16 * cp, mv, ... 17 17 * hexdump, 18 18 * … … 35 35 #include <fcntl.h> 36 36 #include <unistd.h> 37 #include <pwd.h> 38 #include <grp.h> 37 39 #include <errno.h> 38 40 #include <sys/types.h> … … 258 260 struct dirent *dp; 259 261 struct stat stat_buf; 262 struct passwd * pwd; 263 struct group * grp; 264 char * user; 265 char * group; 260 266 char sbuf[256]; 261 267 char nbuf[1024]; … … 280 286 { /* AWFUL buts works...*/ 281 287 strftime(sbuf,sizeof(sbuf)-1,"%b %d %H:%M",gmtime(&stat_buf.st_atime)); 282 printf("%c%c%c%c%c%c%c%c%c%c %3d rtems rtems %11d %s %s%c\n", 288 pwd=getpwuid(stat_buf.st_uid); 289 user=pwd?pwd->pw_name:"nouser"; 290 grp=getgrgid(stat_buf.st_gid); 291 group=grp?grp->gr_name:"nogrp"; 292 printf("%c%c%c%c%c%c%c%c%c%c %3d %6.6s %6.6s %11d %s %s%c\n", 283 293 (S_ISLNK(stat_buf.st_mode)?('l'): 284 294 (S_ISDIR(stat_buf.st_mode)?('d'):('-'))), … … 293 303 (stat_buf.st_mode & S_IXOTH)?('x'):('-'), 294 304 (int)stat_buf.st_nlink, 305 user,group, 295 306 (int)stat_buf.st_size, 296 307 sbuf, … … 351 362 }; 352 363 return 0; 364 } 365 /*-----------------------------------------------------------*/ 366 int main_cat (int argc, char *argv[]) 367 { 368 int n; 369 n=1; 370 while (n<argc) cat_file(stdout,argv[n++]); 371 return 0; 372 } 373 /*-----------------------------------------------------------*/ 374 int main_rm (int argc, char *argv[]) 375 { 376 int n; 377 n=1; 378 while (n<argc) { 379 if (unlink(argv[n])) { 380 printf("error %s:rm %s\n",strerror(errno),argv[n]); 381 return -1; 382 }; 383 n++; 384 }; 385 return 0; 353 386 } 354 387 /*-----------------------------------------------------------*/ … … 425 458 return 0; 426 459 } 460 /*-----------------------------------------------------------*/ 461 int main_logoff(int argc,char *argv[]) 462 { 463 printf("logoff from the system..."); 464 current_shell_env->exit_shell=TRUE; 465 return 0; 466 } 467 /*-----------------------------------------------------------*/ 468 int main_tty (int argc,char *argv[]) 469 { 470 printf("%s\n",ttyname(fileno(stdin))); 471 return 0; 472 } 473 /*-----------------------------------------------------------*/ 474 int main_whoami(int argc,char *argv[]) 475 { 476 struct passwd * pwd; 477 pwd=getpwuid(getuid()); 478 printf("%s\n",pwd?pwd->pw_name:"nobody"); 479 return 0; 480 } 481 /*-----------------------------------------------------------*/ 482 int main_id (int argc,char *argv[]) 483 { 484 struct passwd * pwd; 485 struct group * grp; 486 pwd=getpwuid(getuid()); 487 grp=getgrgid(getgid()); 488 printf("uid=%d(%s),gid=%d(%s),", 489 getuid(),pwd?pwd->pw_name:"", 490 getgid(),grp?grp->gr_name:""); 491 pwd=getpwuid(geteuid()); 492 grp=getgrgid(getegid()); 493 printf("euid=%d(%s),egid=%d(%s)\n", 494 geteuid(),pwd?pwd->pw_name:"", 495 getegid(),grp?grp->gr_name:""); 496 return 0; 497 } 498 /*-----------------------------------------------------------*/ 499 int main_umask(int argc,char *argv[]) 500 { 501 mode_t msk=umask(0); 502 if (argc == 2) msk=str2int(argv[1]); 503 umask(msk); 504 msk=umask(0); 505 printf("0%o\n",msk); 506 umask(msk); 507 return 0; 508 } 509 /*-----------------------------------------------------------*/ 510 int main_chmod(int argc,char *argv[]) 511 { 512 int n; 513 mode_t mode; 514 if (argc > 2){ 515 mode=str2int(argv[1])&0777; 516 n=2; 517 while (n<argc) chmod(argv[n++],mode); 518 }; 519 return 0; 520 } 427 521 /*-----------------------------------------------------------* 428 522 * with this you can call at all the rtems monitor commands. … … 443 537 rtems_monitor_command_entry_t *command; 444 538 extern rtems_monitor_command_entry_t rtems_monitor_commands[]; 539 /* monitor topic */ 540 command=rtems_monitor_commands; 541 while (command) { 542 if (strcmp("exit",command->command)) /*Exclude EXIT (alias quit)*/ 543 shell_add_cmd(command->command,"monitor", 544 command->usage ,main_monitor); 545 command=command->next; 546 }; 445 547 /* dir[ectories] topic */ 446 548 shell_add_cmd ("ls" ,"dir","ls [dir] # list files in the directory" ,main_ls ); … … 450 552 shell_add_cmd ("pwd" ,"dir","pwd # print work directory" ,main_pwd ); 451 553 shell_add_cmd ("chroot","dir","chroot [dir] # change the root directory" ,main_chroot); 554 shell_add_cmd ("cat" ,"dir","cat n1 [n2 [n3...]]# show the ascii contents",main_cat ); 555 shell_add_cmd ("rm" ,"dir","rm n1 [n2 [n3...]]# remove files" ,main_rm ); 556 shell_add_cmd ("chmod" ,"dir","chmod 0777 n1 n2... #change filemode" ,main_chmod); 452 557 453 558 shell_alias_cmd("ls" ,"dir"); … … 455 560 456 561 /* misc. topic */ 562 shell_add_cmd ("logoff","misc","logoff from the system" ,main_logoff); 563 shell_alias_cmd("logoff","exit"); 457 564 shell_add_cmd ("date" ,"misc","date [[MMDDYY]hhmm[ss]]" ,main_date); 458 565 shell_add_cmd ("reset","misc","reset the BSP" ,main_reset); 459 566 shell_add_cmd ("alias","misc","alias old new" ,main_alias); 567 shell_add_cmd ("tty" ,"misc","show ttyname" ,main_tty ); 568 shell_add_cmd ("whoami","misc","show current user" ,main_whoami); 569 shell_add_cmd ("id" ,"misc","show uid,gid,euid,egid" ,main_id ); 570 shell_add_cmd ("umask" ,"misc","umask [new_umask]" ,main_umask ); 571 460 572 461 573 /* memory topic */ … … 468 580 shell_add_cmd ("malloc","mem","mem show memory malloc'ed" ,main_mem); 469 581 #endif 470 /* monitor topic */ 471 command=rtems_monitor_commands; 472 while (command) { 473 shell_add_cmd(command->command,"monitor", 474 command->usage ,main_monitor); 475 command=command->next; 476 }; 477 } 478 /*-----------------------------------------------------------*/ 582 } 583 /*-----------------------------------------------------------*/ -
c/src/libmisc/shell/shell.c
re565720a rb2712e3 13 13 * $Id$ 14 14 */ 15 #ifdef HAVE_CONFIG_H 16 #include "config.h" 17 #endif 15 18 16 19 #include <stdio.h> … … 20 23 #include <rtems/libio.h> 21 24 #include <rtems/libio_.h> 25 #include <rtems/system.h> 26 #include <rtems/shell.h> 22 27 23 28 #include <termios.h> … … 27 32 #include <unistd.h> 28 33 #include <errno.h> 29 30 #include <rtems/shell.h> 34 #include <pwd.h> 35 31 36 /* ----------------------------------------------- * 32 37 * This is a stupidity but is cute. … … 276 281 int c,col; 277 282 col=0; 283 tcdrain(fileno(out)); 278 284 for (;;) { 279 285 line[col]=0; 280 286 c=fgetc(in); 281 287 switch (c) { 288 case 0x04:/*Control-d*/ 289 if (col) break; 282 290 case EOF :return 0; 291 case '\n':break; 292 case '\f':if (out) fputc('\f',out); 293 case 0x03:/*Control-C*/ 294 line[0]=0; 283 295 case '\r':if (out) fputc('\n',out); 284 296 return 1; 297 case 127: 285 298 case '\b':if (col) { 286 299 if (out) { … … 302 315 }; 303 316 } else { 304 if (out) fputc('\a',out); 317 if (out) 318 if (c=='\a') fputc('\a',out); 305 319 }; 306 320 break; … … 318 332 extern char **environ; 319 333 334 void cat_file(FILE * out,char * name) { 335 FILE * fd; 336 int c; 337 if (out) { 338 fd=fopen(name,"r"); 339 if (fd) { 340 while ((c=fgetc(fd))!=EOF) fputc(c,out); 341 fclose(fd); 342 }; 343 }; 344 } 345 346 int shell_login(FILE * in,FILE * out) { 347 FILE * fd; 348 int c; 349 time_t t; 350 int times; 351 char name[128]; 352 char pass[128]; 353 struct passwd * passwd; 354 setuid(0); 355 setgid(0); 356 rtems_current_user_env->euid= 357 rtems_current_user_env->egid=0; 358 if (out) { 359 if((current_shell_env->devname[5]!='p')|| 360 (current_shell_env->devname[6]!='t')|| 361 (current_shell_env->devname[7]!='y')) { 362 cat_file(out,"/etc/issue"); 363 } else { 364 fd=fopen("/etc/issue.net","r"); 365 if (fd) { 366 while ((c=fgetc(fd))!=EOF) { 367 if (c=='%') { 368 switch(c=fgetc(fd)) { 369 case 't':fprintf(out,"%s",current_shell_env->devname); 370 break; 371 case 'h':fprintf(out,"0"); 372 break; 373 case 'D':fprintf(out," "); 374 break; 375 case 'd':time(&t); 376 fprintf(out,"%s",ctime(&t)); 377 break; 378 case 's':fprintf(out,"RTEMS"); 379 break; 380 case 'm':fprintf(out,"(" CPU_NAME "/" CPU_MODEL_NAME ")"); 381 break; 382 case 'r':fprintf(out,_RTEMS_version); 383 break; 384 case 'v':fprintf(out,"%s\n%s",_RTEMS_version,_Copyright_Notice); 385 break; 386 case '%':fprintf(out,"%%"); 387 break; 388 default :fprintf(out,"%%%c",c); 389 break; 390 }; 391 } else { 392 fputc(c,out); 393 }; 394 }; 395 fclose(fd); 396 } 397 }; 398 }; 399 times=0; 400 for (;;) { 401 times++; 402 if (times>3) break; 403 if (out) fprintf(out,"\nlogin: "); 404 if (!shell_scanline(name,sizeof(name),in,out )) break; 405 if (out) fprintf(out,"Password: "); 406 if (!shell_scanline(pass,sizeof(pass),in,NULL)) break; 407 if (out) fprintf(out,"\n"); 408 if ((passwd=getpwnam(name))) { 409 setuid(passwd->pw_uid); 410 setgid(passwd->pw_gid); 411 rtems_current_user_env->euid= 412 rtems_current_user_env->egid=0; 413 chown(current_shell_env->devname,passwd->pw_uid,0); 414 rtems_current_user_env->euid=passwd->pw_uid; 415 rtems_current_user_env->egid=passwd->pw_gid; 416 if (!strcmp(passwd->pw_passwd,"*")) { 417 /* /etc/shadow */ 418 return 0; 419 } else { 420 /* crypt() */ 421 return 0; 422 }; 423 }; 424 if (out) fprintf(out,"Login incorrect\n"); 425 }; 426 return -1; 427 } 428 320 429 rtems_task shell_shell(rtems_task_argument task_argument) { 321 430 … … 327 436 struct termios term; 328 437 char * devname; 329 char * curdir; 330 438 439 char curdir[256]; 331 440 char cmd[256]; 332 441 char last_cmd[256]; /* to repeat 'r' */ … … 334 443 char * argv[128]; 335 444 445 sc=rtems_task_variable_add(RTEMS_SELF,(void*)¤t_shell_env,free); 446 if (sc!=RTEMS_SUCCESSFUL) { 447 rtems_error(sc,"rtems_task_variable_add(current_shell_env):"); 448 rtems_task_delete(RTEMS_SELF); 449 }; 450 451 current_shell_env=shell_env; 452 336 453 sc=rtems_libio_set_private_env(); 337 454 if (sc!=RTEMS_SUCCESSFUL) { 338 455 rtems_error(sc,"rtems_libio_set_private_env():"); 339 printk("rtems_libio_set_private_env():%d",sc);340 456 rtems_task_delete(RTEMS_SELF); 341 457 }; 342 458 343 sc=rtems_task_variable_add(RTEMS_SELF,(void*)¤t_shell_env,free);344 if (sc!=RTEMS_SUCCESSFUL) {345 rtems_error(sc,"rtems_task_variable_add():");346 printk("rtems_task_variable_add():%d",sc);347 rtems_task_delete(RTEMS_SELF);348 };349 350 current_shell_env=shell_env; /* Set the task var */351 459 352 460 devname=shell_env->devname; 461 setuid(0); 462 setgid(0); 463 rtems_current_user_env->euid= 464 rtems_current_user_env->egid=0; 353 465 354 466 stdin =fopen(devname,"r+"); … … 356 468 if (!stdin) { 357 469 fprintf(stderr,"shell:unable to open stdin.%s:%s\n",devname,strerror(errno)); 358 printk("shell:unable to open stdin.(%s)",strerror(errno));359 470 rtems_task_delete(RTEMS_SELF); 360 471 }; … … 364 475 term.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); 365 476 term.c_oflag &= ~OPOST; 366 term.c_oflag |= (OPOST|ONLCR); 477 term.c_oflag |= (OPOST|ONLCR); /* But with cr+nl on output */ 367 478 term.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); 368 479 term.c_cflag = CLOCAL | CREAD |(shell_env->tcflag); … … 386 497 }; 387 498 shell_add_cmd(NULL,NULL,NULL,NULL); /* init the chain list*/ 388 strcpy(cmd,""); 389 printf("\n" 390 "RTEMS-SHELL:%s. "__DATE__". 'help' to list commands.\n",devname); 391 curdir=malloc(1024); 392 chdir("/"); 393 for (;;) { 394 /* Prompt section */ 395 /* XXX: show_prompt user adjustable */ 396 getcwd(curdir,1024); 397 printf("%s [%s] # ",devname,curdir); 398 /* getcmd section */ 399 if (!shell_scanline(cmd,sizeof(cmd),stdin,stdout)) { 400 printf("shell:unable scanline(%s)\n",devname); 401 break; 402 }; 403 /* evaluate cmd section */ 404 if (!strcmp(cmd,"r")) { /* repeat last command, forced, not automatic */ 405 strcpy(cmd,last_cmd); 406 } else 407 if (strcmp(cmd,"")) { /* only for get a new prompt */ 408 strcpy(last_cmd,cmd); 409 }; 410 /* exec cmd section */ 411 /* TODO: 412 * To avoid user crash catch the signals. 413 * Open a new stdio files with posibility of redirection * 414 * Run in a new shell task background. (unix &) 415 * Resuming. A little bash. 416 */ 417 if (shell_make_args(cmd,&argc,argv)) { 418 if ((shell_cmd=shell_lookup_cmd(argv[0]))!=NULL) { 419 current_shell_env->errorlevel=shell_cmd->command(argc,argv); 420 } else { 421 printf("shell:%s command not found\n",argv[0]); 422 current_shell_env->errorlevel=-1; 499 do { 500 if (!shell_login(stdin,stdout)) { 501 cat_file(stdout,"/etc/motd"); 502 strcpy(last_cmd,""); 503 strcpy(cmd,""); 504 printf("\n" 505 "RTEMS SHELL (Version 1.0-FRC):%s. "__DATE__". 'help' to list commands.\n",devname); 506 chdir("/"); 507 shell_env->exit_shell=FALSE; 508 for (;;) { 509 /* Prompt section */ 510 /* XXX: show_prompt user adjustable */ 511 getcwd(curdir,sizeof(curdir)); 512 printf("%s [%s] %c ",shell_env->taskname,curdir,geteuid()?'$':'#'); 513 /* getcmd section */ 514 if (!shell_scanline(cmd,sizeof(cmd),stdin,stdout)) break; /*EOF*/ 515 /* evaluate cmd section */ 516 if (!strcmp(cmd,"r")) { /* repeat last command, forced, not automatic */ 517 strcpy(cmd,last_cmd); 518 } else 519 if (strcmp(cmd,"")) { /* only for get a new prompt */ 520 strcpy(last_cmd,cmd); 521 }; 522 /* exec cmd section */ 523 /* TODO: 524 * To avoid user crash catch the signals. 525 * Open a new stdio files with posibility of redirection * 526 * Run in a new shell task background. (unix &) 527 * Resuming. A little bash. 528 */ 529 if (shell_make_args(cmd,&argc,argv)) { 530 if ((shell_cmd=shell_lookup_cmd(argv[0]))!=NULL) { 531 shell_env->errorlevel=shell_cmd->command(argc,argv); 532 } else { 533 printf("shell:%s command not found\n",argv[0]); 534 shell_env->errorlevel=-1; 535 }; 423 536 }; 424 }; 425 /* end exec cmd section */ 426 }; 427 free(curdir); 537 /* end exec cmd section */ 538 if (shell_env->exit_shell) break; 539 }; 540 printf("\nGoodbye from RTEMS SHELL :-(\n"); 541 }; 542 } while (shell_env->forever); 543 fclose(stdin ); 544 fclose(stdout); 545 fclose(stderr); 428 546 rtems_task_delete(RTEMS_SELF); 429 547 } … … 433 551 rtems_task_priority task_priority, 434 552 char * devname, 435 tcflag_t tcflag) { 553 tcflag_t tcflag, 554 int forever) { 436 555 rtems_id task_id; 437 556 rtems_status_code sc; … … 440 559 task_priority, 441 560 task_stacksize?task_stacksize:RTEMS_MINIMUM_STACK_SIZE, 442 (RTEMS_DEFAULT_MODES&~RTEMS_ASR_MASK)|RTEMS_ASR,561 RTEMS_DEFAULT_MODES, 443 562 RTEMS_DEFAULT_ATTRIBUTES, 444 563 &task_id); … … 455 574 }; 456 575 if (global_shell_env.magic!=new_rtems_name("SENV")) { 457 global_shell_env.magic =new_rtems_name("SENV"); 458 global_shell_env.devname ="/dev/console"; 459 global_shell_env.taskname="GLOBAL"; 460 global_shell_env.tcflag =0; 576 global_shell_env.magic =new_rtems_name("SENV"); 577 global_shell_env.devname ="/dev/console"; 578 global_shell_env.taskname ="GLOBAL"; 579 global_shell_env.tcflag =0; 580 global_shell_env.exit_shell=0; 581 global_shell_env.forever =TRUE; 461 582 }; 462 shell_env->magic =global_shell_env.magic; 463 shell_env->devname =devname; 464 shell_env->taskname=task_name; 465 shell_env->tcflag =tcflag; 583 shell_env->magic =global_shell_env.magic; 584 shell_env->devname =devname; 585 shell_env->taskname =task_name; 586 shell_env->tcflag =tcflag; 587 shell_env->exit_shell=FALSE; 588 shell_env->forever =forever; 466 589 return rtems_task_start(task_id,shell_shell,(rtems_task_argument) shell_env); 467 590 } 468 591 /* ----------------------------------------------- */ 469 -
c/src/libmisc/shell/shell.h
re565720a rb2712e3 46 46 tcflag_t tcflag; 47 47 /* user extensions */ 48 int exit_shell; /* logout */ 49 int forever ; /* repeat login */ 48 50 int errorlevel; 49 51 int mdump_adr; … … 51 53 52 54 int shell_scanline(char * line,int size,FILE * in,FILE * out) ; 55 void cat_file(FILE * out,char *name); 53 56 54 57 rtems_status_code shell_init(char * task_name , … … 56 59 rtems_task_priority task_priority , 57 60 char * devname , 58 tcflag_t tcflag ); 61 tcflag_t tcflag , 62 int forever ); 59 63 60 64 extern shell_env_t global_shell_env, 61 65 * current_shell_env; 66 /*--------*/ 67 /* pty.c */ 68 /*--------*/ 69 70 char * get_pty(int socket); 71 72 73 rtems_device_driver pty_initialize( 74 rtems_device_major_number major, 75 rtems_device_minor_number minor, 76 void *arg); 77 rtems_device_driver pty_open( 78 rtems_device_major_number major, 79 rtems_device_minor_number minor, 80 void * arg); 81 rtems_device_driver pty_close( 82 rtems_device_major_number major, 83 rtems_device_minor_number minor, 84 void * arg); 85 rtems_device_driver pty_read( 86 rtems_device_major_number major, 87 rtems_device_minor_number minor, 88 void * arg); 89 rtems_device_driver pty_write( 90 rtems_device_major_number major, 91 rtems_device_minor_number minor, 92 void * arg); 93 rtems_device_driver pty_control( 94 rtems_device_major_number major, 95 rtems_device_minor_number minor, 96 void * arg); 97 98 99 #define PTY_DRIVER_TABLE_ENTRY \ 100 { pty_initialize , pty_open , pty_close , \ 101 pty_read , pty_write , pty_control } 62 102 /*--------*/ 63 103 /* cmds.c */ -
cpukit/libmisc/ChangeLog
re565720a rb2712e3 1 2000-05-24 Fernando Ruiz Casas <fernando.ruiz@ctv.es> 2 3 * monitor/mon-prmisc.c: Correct print line. 4 * shell/Makefile.am: Added new file telnetd.c. 5 * shell/telnetd.c, shell/telnetd.h, shell/pty.c: New files. 6 * shell/shell.c, shell/cmds.c, shell/shell.h: Numerous improvments: 7 - The shell_init has a new parameter 'forever' because in 8 /dev/console you need that this process runs forever but in 9 tcp/ip not. (respawn?) 10 - A new task for every session opened trought tcp/ip telnet client. 11 (the chargen,daytime and more are possible of implementation but 12 I ask me if they are necesary) 13 - Exit from the session delete the task and when the client fails too. 14 - More cmds have been implemented. (very reduced version of these) 15 umask, chmod, id, whoami, rm, cat, ... 16 - A reduced line edit has been implemented. 17 Ctrl-C abort the input, 18 Ctrl-d in the first position gives EOF (logout). 19 '\b' and DEL makes the rubout operation. 20 I think that readline() for every session spents a lot of resources. 21 1 22 2001-04-28 Ralf Corsepius <corsepiu@faw.uni-ulm.de> 2 23 -
cpukit/libmisc/monitor/mon-prmisc.c
re565720a rb2712e3 109 109 length += rtems_monitor_dump_char(u.c[i]); 110 110 #else 111 for (i= sizeof(u.c)-1; i ; i--)112 length += rtems_monitor_dump_char(u.c[ i]);111 for (i=0; i<sizeof(u.c); i++) 112 length += rtems_monitor_dump_char(u.c[sizeof(u.c)-1-i]); 113 113 #endif 114 114 return length; -
cpukit/libmisc/shell/Makefile.am
re565720a rb2712e3 10 10 LIB = $(ARCH)/$(LIBNAME).a 11 11 12 C_FILES = cmds.c shell.c 12 C_FILES = cmds.c shell.c pty.c telnetd.c 13 13 C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o) 14 14 15 include_rtems_HEADERS = shell.h 15 include_rtems_HEADERS = shell.h telnetd.h 16 16 17 17 OBJS = $(C_O_FILES) … … 40 40 .PRECIOUS: $(LIB) 41 41 42 EXTRA_DIST = README shell.c cmds.c shell.h42 EXTRA_DIST = README shell.c cmds.c pty.c telnetd.c shell.h telnetd.h 43 43 44 44 include $(top_srcdir)/../../../automake/local.am -
cpukit/libmisc/shell/README
re565720a rb2712e3 20 20 and enjoy it. 21 21 22 22 3. If you have tcp/ip inited you can start telnetd daemon. 23 You need register pseudo-terminals driver into device drivers table. 24 16 ptyX termios device terminales are created into /dev/. 25 Calling rtems_initialize_telnetd() starts the daemon. 26 Enjoy it. 23 27 24 28 FUTURE: 25 29 26 30 1. Adding new commands in cmds.c to give file manegement to shell. 27 28 2. Create a telnetd daemon. (pseudo-terminal needed) -
cpukit/libmisc/shell/cmds.c
re565720a rb2712e3 14 14 * 15 15 * TODO: A lot of improvements of course. 16 * c at, cp, rm, mv, ...16 * cp, mv, ... 17 17 * hexdump, 18 18 * … … 35 35 #include <fcntl.h> 36 36 #include <unistd.h> 37 #include <pwd.h> 38 #include <grp.h> 37 39 #include <errno.h> 38 40 #include <sys/types.h> … … 258 260 struct dirent *dp; 259 261 struct stat stat_buf; 262 struct passwd * pwd; 263 struct group * grp; 264 char * user; 265 char * group; 260 266 char sbuf[256]; 261 267 char nbuf[1024]; … … 280 286 { /* AWFUL buts works...*/ 281 287 strftime(sbuf,sizeof(sbuf)-1,"%b %d %H:%M",gmtime(&stat_buf.st_atime)); 282 printf("%c%c%c%c%c%c%c%c%c%c %3d rtems rtems %11d %s %s%c\n", 288 pwd=getpwuid(stat_buf.st_uid); 289 user=pwd?pwd->pw_name:"nouser"; 290 grp=getgrgid(stat_buf.st_gid); 291 group=grp?grp->gr_name:"nogrp"; 292 printf("%c%c%c%c%c%c%c%c%c%c %3d %6.6s %6.6s %11d %s %s%c\n", 283 293 (S_ISLNK(stat_buf.st_mode)?('l'): 284 294 (S_ISDIR(stat_buf.st_mode)?('d'):('-'))), … … 293 303 (stat_buf.st_mode & S_IXOTH)?('x'):('-'), 294 304 (int)stat_buf.st_nlink, 305 user,group, 295 306 (int)stat_buf.st_size, 296 307 sbuf, … … 351 362 }; 352 363 return 0; 364 } 365 /*-----------------------------------------------------------*/ 366 int main_cat (int argc, char *argv[]) 367 { 368 int n; 369 n=1; 370 while (n<argc) cat_file(stdout,argv[n++]); 371 return 0; 372 } 373 /*-----------------------------------------------------------*/ 374 int main_rm (int argc, char *argv[]) 375 { 376 int n; 377 n=1; 378 while (n<argc) { 379 if (unlink(argv[n])) { 380 printf("error %s:rm %s\n",strerror(errno),argv[n]); 381 return -1; 382 }; 383 n++; 384 }; 385 return 0; 353 386 } 354 387 /*-----------------------------------------------------------*/ … … 425 458 return 0; 426 459 } 460 /*-----------------------------------------------------------*/ 461 int main_logoff(int argc,char *argv[]) 462 { 463 printf("logoff from the system..."); 464 current_shell_env->exit_shell=TRUE; 465 return 0; 466 } 467 /*-----------------------------------------------------------*/ 468 int main_tty (int argc,char *argv[]) 469 { 470 printf("%s\n",ttyname(fileno(stdin))); 471 return 0; 472 } 473 /*-----------------------------------------------------------*/ 474 int main_whoami(int argc,char *argv[]) 475 { 476 struct passwd * pwd; 477 pwd=getpwuid(getuid()); 478 printf("%s\n",pwd?pwd->pw_name:"nobody"); 479 return 0; 480 } 481 /*-----------------------------------------------------------*/ 482 int main_id (int argc,char *argv[]) 483 { 484 struct passwd * pwd; 485 struct group * grp; 486 pwd=getpwuid(getuid()); 487 grp=getgrgid(getgid()); 488 printf("uid=%d(%s),gid=%d(%s),", 489 getuid(),pwd?pwd->pw_name:"", 490 getgid(),grp?grp->gr_name:""); 491 pwd=getpwuid(geteuid()); 492 grp=getgrgid(getegid()); 493 printf("euid=%d(%s),egid=%d(%s)\n", 494 geteuid(),pwd?pwd->pw_name:"", 495 getegid(),grp?grp->gr_name:""); 496 return 0; 497 } 498 /*-----------------------------------------------------------*/ 499 int main_umask(int argc,char *argv[]) 500 { 501 mode_t msk=umask(0); 502 if (argc == 2) msk=str2int(argv[1]); 503 umask(msk); 504 msk=umask(0); 505 printf("0%o\n",msk); 506 umask(msk); 507 return 0; 508 } 509 /*-----------------------------------------------------------*/ 510 int main_chmod(int argc,char *argv[]) 511 { 512 int n; 513 mode_t mode; 514 if (argc > 2){ 515 mode=str2int(argv[1])&0777; 516 n=2; 517 while (n<argc) chmod(argv[n++],mode); 518 }; 519 return 0; 520 } 427 521 /*-----------------------------------------------------------* 428 522 * with this you can call at all the rtems monitor commands. … … 443 537 rtems_monitor_command_entry_t *command; 444 538 extern rtems_monitor_command_entry_t rtems_monitor_commands[]; 539 /* monitor topic */ 540 command=rtems_monitor_commands; 541 while (command) { 542 if (strcmp("exit",command->command)) /*Exclude EXIT (alias quit)*/ 543 shell_add_cmd(command->command,"monitor", 544 command->usage ,main_monitor); 545 command=command->next; 546 }; 445 547 /* dir[ectories] topic */ 446 548 shell_add_cmd ("ls" ,"dir","ls [dir] # list files in the directory" ,main_ls ); … … 450 552 shell_add_cmd ("pwd" ,"dir","pwd # print work directory" ,main_pwd ); 451 553 shell_add_cmd ("chroot","dir","chroot [dir] # change the root directory" ,main_chroot); 554 shell_add_cmd ("cat" ,"dir","cat n1 [n2 [n3...]]# show the ascii contents",main_cat ); 555 shell_add_cmd ("rm" ,"dir","rm n1 [n2 [n3...]]# remove files" ,main_rm ); 556 shell_add_cmd ("chmod" ,"dir","chmod 0777 n1 n2... #change filemode" ,main_chmod); 452 557 453 558 shell_alias_cmd("ls" ,"dir"); … … 455 560 456 561 /* misc. topic */ 562 shell_add_cmd ("logoff","misc","logoff from the system" ,main_logoff); 563 shell_alias_cmd("logoff","exit"); 457 564 shell_add_cmd ("date" ,"misc","date [[MMDDYY]hhmm[ss]]" ,main_date); 458 565 shell_add_cmd ("reset","misc","reset the BSP" ,main_reset); 459 566 shell_add_cmd ("alias","misc","alias old new" ,main_alias); 567 shell_add_cmd ("tty" ,"misc","show ttyname" ,main_tty ); 568 shell_add_cmd ("whoami","misc","show current user" ,main_whoami); 569 shell_add_cmd ("id" ,"misc","show uid,gid,euid,egid" ,main_id ); 570 shell_add_cmd ("umask" ,"misc","umask [new_umask]" ,main_umask ); 571 460 572 461 573 /* memory topic */ … … 468 580 shell_add_cmd ("malloc","mem","mem show memory malloc'ed" ,main_mem); 469 581 #endif 470 /* monitor topic */ 471 command=rtems_monitor_commands; 472 while (command) { 473 shell_add_cmd(command->command,"monitor", 474 command->usage ,main_monitor); 475 command=command->next; 476 }; 477 } 478 /*-----------------------------------------------------------*/ 582 } 583 /*-----------------------------------------------------------*/ -
cpukit/libmisc/shell/shell.c
re565720a rb2712e3 13 13 * $Id$ 14 14 */ 15 #ifdef HAVE_CONFIG_H 16 #include "config.h" 17 #endif 15 18 16 19 #include <stdio.h> … … 20 23 #include <rtems/libio.h> 21 24 #include <rtems/libio_.h> 25 #include <rtems/system.h> 26 #include <rtems/shell.h> 22 27 23 28 #include <termios.h> … … 27 32 #include <unistd.h> 28 33 #include <errno.h> 29 30 #include <rtems/shell.h> 34 #include <pwd.h> 35 31 36 /* ----------------------------------------------- * 32 37 * This is a stupidity but is cute. … … 276 281 int c,col; 277 282 col=0; 283 tcdrain(fileno(out)); 278 284 for (;;) { 279 285 line[col]=0; 280 286 c=fgetc(in); 281 287 switch (c) { 288 case 0x04:/*Control-d*/ 289 if (col) break; 282 290 case EOF :return 0; 291 case '\n':break; 292 case '\f':if (out) fputc('\f',out); 293 case 0x03:/*Control-C*/ 294 line[0]=0; 283 295 case '\r':if (out) fputc('\n',out); 284 296 return 1; 297 case 127: 285 298 case '\b':if (col) { 286 299 if (out) { … … 302 315 }; 303 316 } else { 304 if (out) fputc('\a',out); 317 if (out) 318 if (c=='\a') fputc('\a',out); 305 319 }; 306 320 break; … … 318 332 extern char **environ; 319 333 334 void cat_file(FILE * out,char * name) { 335 FILE * fd; 336 int c; 337 if (out) { 338 fd=fopen(name,"r"); 339 if (fd) { 340 while ((c=fgetc(fd))!=EOF) fputc(c,out); 341 fclose(fd); 342 }; 343 }; 344 } 345 346 int shell_login(FILE * in,FILE * out) { 347 FILE * fd; 348 int c; 349 time_t t; 350 int times; 351 char name[128]; 352 char pass[128]; 353 struct passwd * passwd; 354 setuid(0); 355 setgid(0); 356 rtems_current_user_env->euid= 357 rtems_current_user_env->egid=0; 358 if (out) { 359 if((current_shell_env->devname[5]!='p')|| 360 (current_shell_env->devname[6]!='t')|| 361 (current_shell_env->devname[7]!='y')) { 362 cat_file(out,"/etc/issue"); 363 } else { 364 fd=fopen("/etc/issue.net","r"); 365 if (fd) { 366 while ((c=fgetc(fd))!=EOF) { 367 if (c=='%') { 368 switch(c=fgetc(fd)) { 369 case 't':fprintf(out,"%s",current_shell_env->devname); 370 break; 371 case 'h':fprintf(out,"0"); 372 break; 373 case 'D':fprintf(out," "); 374 break; 375 case 'd':time(&t); 376 fprintf(out,"%s",ctime(&t)); 377 break; 378 case 's':fprintf(out,"RTEMS"); 379 break; 380 case 'm':fprintf(out,"(" CPU_NAME "/" CPU_MODEL_NAME ")"); 381 break; 382 case 'r':fprintf(out,_RTEMS_version); 383 break; 384 case 'v':fprintf(out,"%s\n%s",_RTEMS_version,_Copyright_Notice); 385 break; 386 case '%':fprintf(out,"%%"); 387 break; 388 default :fprintf(out,"%%%c",c); 389 break; 390 }; 391 } else { 392 fputc(c,out); 393 }; 394 }; 395 fclose(fd); 396 } 397 }; 398 }; 399 times=0; 400 for (;;) { 401 times++; 402 if (times>3) break; 403 if (out) fprintf(out,"\nlogin: "); 404 if (!shell_scanline(name,sizeof(name),in,out )) break; 405 if (out) fprintf(out,"Password: "); 406 if (!shell_scanline(pass,sizeof(pass),in,NULL)) break; 407 if (out) fprintf(out,"\n"); 408 if ((passwd=getpwnam(name))) { 409 setuid(passwd->pw_uid); 410 setgid(passwd->pw_gid); 411 rtems_current_user_env->euid= 412 rtems_current_user_env->egid=0; 413 chown(current_shell_env->devname,passwd->pw_uid,0); 414 rtems_current_user_env->euid=passwd->pw_uid; 415 rtems_current_user_env->egid=passwd->pw_gid; 416 if (!strcmp(passwd->pw_passwd,"*")) { 417 /* /etc/shadow */ 418 return 0; 419 } else { 420 /* crypt() */ 421 return 0; 422 }; 423 }; 424 if (out) fprintf(out,"Login incorrect\n"); 425 }; 426 return -1; 427 } 428 320 429 rtems_task shell_shell(rtems_task_argument task_argument) { 321 430 … … 327 436 struct termios term; 328 437 char * devname; 329 char * curdir; 330 438 439 char curdir[256]; 331 440 char cmd[256]; 332 441 char last_cmd[256]; /* to repeat 'r' */ … … 334 443 char * argv[128]; 335 444 445 sc=rtems_task_variable_add(RTEMS_SELF,(void*)¤t_shell_env,free); 446 if (sc!=RTEMS_SUCCESSFUL) { 447 rtems_error(sc,"rtems_task_variable_add(current_shell_env):"); 448 rtems_task_delete(RTEMS_SELF); 449 }; 450 451 current_shell_env=shell_env; 452 336 453 sc=rtems_libio_set_private_env(); 337 454 if (sc!=RTEMS_SUCCESSFUL) { 338 455 rtems_error(sc,"rtems_libio_set_private_env():"); 339 printk("rtems_libio_set_private_env():%d",sc);340 456 rtems_task_delete(RTEMS_SELF); 341 457 }; 342 458 343 sc=rtems_task_variable_add(RTEMS_SELF,(void*)¤t_shell_env,free);344 if (sc!=RTEMS_SUCCESSFUL) {345 rtems_error(sc,"rtems_task_variable_add():");346 printk("rtems_task_variable_add():%d",sc);347 rtems_task_delete(RTEMS_SELF);348 };349 350 current_shell_env=shell_env; /* Set the task var */351 459 352 460 devname=shell_env->devname; 461 setuid(0); 462 setgid(0); 463 rtems_current_user_env->euid= 464 rtems_current_user_env->egid=0; 353 465 354 466 stdin =fopen(devname,"r+"); … … 356 468 if (!stdin) { 357 469 fprintf(stderr,"shell:unable to open stdin.%s:%s\n",devname,strerror(errno)); 358 printk("shell:unable to open stdin.(%s)",strerror(errno));359 470 rtems_task_delete(RTEMS_SELF); 360 471 }; … … 364 475 term.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); 365 476 term.c_oflag &= ~OPOST; 366 term.c_oflag |= (OPOST|ONLCR); 477 term.c_oflag |= (OPOST|ONLCR); /* But with cr+nl on output */ 367 478 term.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); 368 479 term.c_cflag = CLOCAL | CREAD |(shell_env->tcflag); … … 386 497 }; 387 498 shell_add_cmd(NULL,NULL,NULL,NULL); /* init the chain list*/ 388 strcpy(cmd,""); 389 printf("\n" 390 "RTEMS-SHELL:%s. "__DATE__". 'help' to list commands.\n",devname); 391 curdir=malloc(1024); 392 chdir("/"); 393 for (;;) { 394 /* Prompt section */ 395 /* XXX: show_prompt user adjustable */ 396 getcwd(curdir,1024); 397 printf("%s [%s] # ",devname,curdir); 398 /* getcmd section */ 399 if (!shell_scanline(cmd,sizeof(cmd),stdin,stdout)) { 400 printf("shell:unable scanline(%s)\n",devname); 401 break; 402 }; 403 /* evaluate cmd section */ 404 if (!strcmp(cmd,"r")) { /* repeat last command, forced, not automatic */ 405 strcpy(cmd,last_cmd); 406 } else 407 if (strcmp(cmd,"")) { /* only for get a new prompt */ 408 strcpy(last_cmd,cmd); 409 }; 410 /* exec cmd section */ 411 /* TODO: 412 * To avoid user crash catch the signals. 413 * Open a new stdio files with posibility of redirection * 414 * Run in a new shell task background. (unix &) 415 * Resuming. A little bash. 416 */ 417 if (shell_make_args(cmd,&argc,argv)) { 418 if ((shell_cmd=shell_lookup_cmd(argv[0]))!=NULL) { 419 current_shell_env->errorlevel=shell_cmd->command(argc,argv); 420 } else { 421 printf("shell:%s command not found\n",argv[0]); 422 current_shell_env->errorlevel=-1; 499 do { 500 if (!shell_login(stdin,stdout)) { 501 cat_file(stdout,"/etc/motd"); 502 strcpy(last_cmd,""); 503 strcpy(cmd,""); 504 printf("\n" 505 "RTEMS SHELL (Version 1.0-FRC):%s. "__DATE__". 'help' to list commands.\n",devname); 506 chdir("/"); 507 shell_env->exit_shell=FALSE; 508 for (;;) { 509 /* Prompt section */ 510 /* XXX: show_prompt user adjustable */ 511 getcwd(curdir,sizeof(curdir)); 512 printf("%s [%s] %c ",shell_env->taskname,curdir,geteuid()?'$':'#'); 513 /* getcmd section */ 514 if (!shell_scanline(cmd,sizeof(cmd),stdin,stdout)) break; /*EOF*/ 515 /* evaluate cmd section */ 516 if (!strcmp(cmd,"r")) { /* repeat last command, forced, not automatic */ 517 strcpy(cmd,last_cmd); 518 } else 519 if (strcmp(cmd,"")) { /* only for get a new prompt */ 520 strcpy(last_cmd,cmd); 521 }; 522 /* exec cmd section */ 523 /* TODO: 524 * To avoid user crash catch the signals. 525 * Open a new stdio files with posibility of redirection * 526 * Run in a new shell task background. (unix &) 527 * Resuming. A little bash. 528 */ 529 if (shell_make_args(cmd,&argc,argv)) { 530 if ((shell_cmd=shell_lookup_cmd(argv[0]))!=NULL) { 531 shell_env->errorlevel=shell_cmd->command(argc,argv); 532 } else { 533 printf("shell:%s command not found\n",argv[0]); 534 shell_env->errorlevel=-1; 535 }; 423 536 }; 424 }; 425 /* end exec cmd section */ 426 }; 427 free(curdir); 537 /* end exec cmd section */ 538 if (shell_env->exit_shell) break; 539 }; 540 printf("\nGoodbye from RTEMS SHELL :-(\n"); 541 }; 542 } while (shell_env->forever); 543 fclose(stdin ); 544 fclose(stdout); 545 fclose(stderr); 428 546 rtems_task_delete(RTEMS_SELF); 429 547 } … … 433 551 rtems_task_priority task_priority, 434 552 char * devname, 435 tcflag_t tcflag) { 553 tcflag_t tcflag, 554 int forever) { 436 555 rtems_id task_id; 437 556 rtems_status_code sc; … … 440 559 task_priority, 441 560 task_stacksize?task_stacksize:RTEMS_MINIMUM_STACK_SIZE, 442 (RTEMS_DEFAULT_MODES&~RTEMS_ASR_MASK)|RTEMS_ASR,561 RTEMS_DEFAULT_MODES, 443 562 RTEMS_DEFAULT_ATTRIBUTES, 444 563 &task_id); … … 455 574 }; 456 575 if (global_shell_env.magic!=new_rtems_name("SENV")) { 457 global_shell_env.magic =new_rtems_name("SENV"); 458 global_shell_env.devname ="/dev/console"; 459 global_shell_env.taskname="GLOBAL"; 460 global_shell_env.tcflag =0; 576 global_shell_env.magic =new_rtems_name("SENV"); 577 global_shell_env.devname ="/dev/console"; 578 global_shell_env.taskname ="GLOBAL"; 579 global_shell_env.tcflag =0; 580 global_shell_env.exit_shell=0; 581 global_shell_env.forever =TRUE; 461 582 }; 462 shell_env->magic =global_shell_env.magic; 463 shell_env->devname =devname; 464 shell_env->taskname=task_name; 465 shell_env->tcflag =tcflag; 583 shell_env->magic =global_shell_env.magic; 584 shell_env->devname =devname; 585 shell_env->taskname =task_name; 586 shell_env->tcflag =tcflag; 587 shell_env->exit_shell=FALSE; 588 shell_env->forever =forever; 466 589 return rtems_task_start(task_id,shell_shell,(rtems_task_argument) shell_env); 467 590 } 468 591 /* ----------------------------------------------- */ 469 -
cpukit/libmisc/shell/shell.h
re565720a rb2712e3 46 46 tcflag_t tcflag; 47 47 /* user extensions */ 48 int exit_shell; /* logout */ 49 int forever ; /* repeat login */ 48 50 int errorlevel; 49 51 int mdump_adr; … … 51 53 52 54 int shell_scanline(char * line,int size,FILE * in,FILE * out) ; 55 void cat_file(FILE * out,char *name); 53 56 54 57 rtems_status_code shell_init(char * task_name , … … 56 59 rtems_task_priority task_priority , 57 60 char * devname , 58 tcflag_t tcflag ); 61 tcflag_t tcflag , 62 int forever ); 59 63 60 64 extern shell_env_t global_shell_env, 61 65 * current_shell_env; 66 /*--------*/ 67 /* pty.c */ 68 /*--------*/ 69 70 char * get_pty(int socket); 71 72 73 rtems_device_driver pty_initialize( 74 rtems_device_major_number major, 75 rtems_device_minor_number minor, 76 void *arg); 77 rtems_device_driver pty_open( 78 rtems_device_major_number major, 79 rtems_device_minor_number minor, 80 void * arg); 81 rtems_device_driver pty_close( 82 rtems_device_major_number major, 83 rtems_device_minor_number minor, 84 void * arg); 85 rtems_device_driver pty_read( 86 rtems_device_major_number major, 87 rtems_device_minor_number minor, 88 void * arg); 89 rtems_device_driver pty_write( 90 rtems_device_major_number major, 91 rtems_device_minor_number minor, 92 void * arg); 93 rtems_device_driver pty_control( 94 rtems_device_major_number major, 95 rtems_device_minor_number minor, 96 void * arg); 97 98 99 #define PTY_DRIVER_TABLE_ENTRY \ 100 { pty_initialize , pty_open , pty_close , \ 101 pty_read , pty_write , pty_control } 62 102 /*--------*/ 63 103 /* cmds.c */
Note: See TracChangeset
for help on using the changeset viewer.