source: trunk/user/ksh/ksh.c @ 450

Last change on this file since 450 was 446, checked in by alain, 7 years ago

miscelaneous...

File size: 21.2 KB
RevLine 
[407]1///////////////////////////////////////////////////////////////////////////////
2// File   :  ksh.c
3// Date   :  October 2017
4// Author :  Alain Greiner
5///////////////////////////////////////////////////////////////////////////////
[446]6// This applications implement a minimal shell for ALMOS-MKH.
7// This user process contains two POSIX threads:
8// - the "main" thread contains the infinite loop implementing
9//   the children processes termination monitoring (children processes
10//   are created by the <load> command and attached to the KSH TXT terminal).
11// - the "interactive" thread contains the infinite loop implementing
12//   the command interpreter attached to the TXT terminal.
[407]13///////////////////////////////////////////////////////////////////////////////
[230]14
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
[444]18#include <sys/wait.h>
19#include <signal.h>
20#include <unistd.h>
[445]21#include <almosmkh.h>
[230]22
[407]23#define CMD_MAX_SIZE   (256)    // max number of characters in one command
[436]24#define LOG_DEPTH      (32)     // max number of registered commands
[407]25#define MAX_ARGS           (32)     // max number of arguments in a command
26#define FIFO_SIZE      (1024)   // FIFO depth for recursive ls
[230]27
[407]28////////////////////////////////////////////////////////////////////////////////
29//         Structures
30////////////////////////////////////////////////////////////////////////////////
[230]31
[407]32// one entry in the registered commands array
33typedef struct log_entry_s
34{
35        char          buf[CMD_MAX_SIZE];
36        unsigned int  count;
37}
38log_entry_t;
[230]39
[407]40// one entry in the supported command types array
41typedef struct ksh_cmd_s
42{
43        char * name;
44        char * desc;
45        void   (*fn)( int , char ** );
46}
47ksh_cmd_t;
48
49
[230]50////////////////////////////////////////////////////////////////////////////////
51//         Global Variables
52////////////////////////////////////////////////////////////////////////////////
53
[407]54ksh_cmd_t       cmd[];                    // array of supported commands
[230]55
[407]56log_entry_t     log_entries[LOG_DEPTH];   // array of registered commands
[230]57
[407]58unsigned int    ptw;                      // write pointer in log_entries[]
59unsigned int    ptr;                      // read pointer in log_entries[]
[230]60
[446]61pthread_attr_t  attr;                     // monitor thread attributes
62
[230]63////////////////////////////////////////////////////////////////////////////////
64//         Shell  Commands
65////////////////////////////////////////////////////////////////////////////////
66
[407]67/////////////////////////////////////////////
68static void cmd_cat( int argc , char **argv )
[230]69{
[407]70        char         * path;
[230]71
[407]72        if (argc != 2) 
73    {
[409]74                printf("  usage: cat pathname\n");
[230]75                return;
76        }
[407]77
[230]78        path = argv[1];
79
[409]80    printf("  error: not implemented yet\n");
[407]81
82/*
83        // open the file
84        fd = open( path , O_RDONLY , 0 );
85        if (fd < 0)
86    {
[409]87                printf("  error: cannot open %s\n", path);
[230]88                goto exit;
89        }
90
[407]91        // get file size
92        if (stat(path, &st) == -1)
93    {
[409]94                printf("  error: cannot stat %s\n", path);
[230]95                goto exit;
96        }
97        if (S_ISDIR(st.st_mode)) {
[409]98                printf("  error: %s is a directory\n", path);
[230]99                goto exit;
100        }
101        size = st.st_size;
102
[407]103        // mmap the file
[230]104        buf = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
105        if (buf == NULL || buf == (char *)-1) {
[409]106                printf("  error: cannot map %s\n", path);
[230]107                goto exit;
108        }
109
[446]110        // set terminating '0'
[230]111        buf[size-1] = 0;
112
[407]113        // display the file content
[230]114        printf("%s", buf);
115
116exit:
[407]117        if (buf != NULL) munmap(buf, size);
118        if (fd >= 0) close(fd);
119*/
[230]120
[407]121}   // end cmd_cat()
122
123////////////////////////////////////////////
124static void cmd_cd( int argc , char **argv )
125{
126        char * path;
127
128        if (argc != 2)
129    {
[409]130                printf("  usage: cd pathname\n");
[407]131                return;
132        }
133
134        path = argv[1];
135
[409]136    printf("  error: not implemented yet\n");
[407]137/*
138        path = argv[1];
139
140        if (chdir(path) == -1)
141    {
[409]142                printf("  error: cannot cd to %s\n", path);
[407]143        }
144*/
145
146}   // end cmd_cd()
147
148/////////////////////////////////////////
[230]149static void cmd_cp(int argc, char **argv)
150{
[407]151//      int src_fd = -1, dst_fd = -1;
152//      char *srcpath, *dstpath;
153//      struct stat st;
154//      size_t size, i;
155//      char buf[1024];
[230]156
[407]157        if (argc != 3) 
158    {
[409]159                printf("  usage: cp src_pathname dst_pathname\n");
[230]160                return;
161        }
162
[409]163    printf("  error: not implemented yet\n");
[407]164
165/*
[230]166        srcpath = argv[1];
167        dstpath = argv[2];
168
[407]169        // open the src file
[230]170        src_fd = open(srcpath, O_RDONLY, 0);
171        if (src_fd < 0) {
[409]172                printf("  error: cannot open %s / err = %d\n", srcpath, errno);
[230]173                goto exit;
174        }
175
[407]176        // get file size
[230]177        if (stat(srcpath, &st) == -1) {
[409]178                printf("  error: cannot stat %s\n", srcpath);
[230]179                goto exit;
180        }
181        if (S_ISDIR(st.st_mode)) {
[409]182                printf("  error: %s is a directory\n", srcpath);
[230]183                goto exit;
184        }
185        size = st.st_size;
186
[407]187        // open the dst file
[230]188        dst_fd = open(dstpath, O_CREAT|O_TRUNC|O_RDWR, 0);
189        if (dst_fd < 0) {
[409]190                printf("  error: cannot open %s / err = %d\n", dstpath, errno);
[230]191                goto exit;
192        }
193        if (stat(dstpath, &st) == -1) {
[409]194                printf("  error: cannot stat %s\n", dstpath);
[230]195                goto exit;
196        }
197        if (S_ISDIR(st.st_mode)) {
[409]198                printf("  error: %s is a directory\n", dstpath);
[230]199                goto exit;
200        }
201
202        i = 0;
203        while (i < size)
204        {
205                size_t rlen = (size - i < 1024 ? size - i : 1024);
206                size_t wlen;
207                ssize_t ret;
208
[407]209                // read the source
[230]210                ret = read(src_fd, buf, rlen);
211                if (ret == -1) {
[409]212                        printf("  error: cannot read from file %s\n", srcpath);
[230]213                        goto exit;
214                }
215                rlen = (size_t)ret;
216
[407]217                // write to the destination
[230]218                ret = write(dst_fd, buf, rlen);
219                if (ret == -1) {
[409]220                        printf("  error: cannot write to file %s\n", dstpath);
[230]221                        goto exit;
222                }
223                wlen = (size_t)ret;
224
[407]225                // check
[230]226                if (wlen != rlen) {
[409]227                        printf("  error: cannot write on device\n");
[230]228                        goto exit;
229                }
230
231                i += rlen;
232        }
233
234exit:
[407]235        if (src_fd >= 0) close(src_fd);
236        if (dst_fd >= 0) close(dst_fd);
237*/
[230]238
[407]239}   // end cmd_cp()
240
[436]241/////////////////////////////////////////////////
242static void cmd_display( int argc , char **argv )
243{
244    unsigned int  cxy;
245    unsigned int  lid;
246    unsigned int  pid;
247    unsigned int  txt_id;
248
249    if( strcmp( argv[1] , "vmm" ) == 0 )
250    {
[442]251        if( argc != 4 )
[436]252        {
[442]253                    printf("  usage: display vmm cxy pid\n");
[436]254                    return;
255            }
256
[442]257            cxy = atoi(argv[2]);
258            pid = atoi(argv[3]);
[436]259
[442]260        if( display_vmm( cxy , pid ) )
[436]261        {
[442]262            printf("  error: no process %x in cluster %x\n", pid , cxy );
[436]263        }
264    }
265    else if( strcmp( argv[1] , "sched" ) == 0 )
266    {
267        if( argc != 4 )
268        {
269                    printf("  usage: display sched cxy lid\n");
270                    return;
271            }
272
273            cxy = atoi(argv[2]);
274            lid = atoi(argv[3]);
275
276        if( display_sched( cxy , lid ) )
277        {
278            printf("  error: illegal arguments cxy = %x / lid = %d\n", cxy, lid );
279        }
280    }
281    else if( strcmp( argv[1] , "process" ) == 0 )
282    {
283        if( argc != 3 )
284        {
285                    printf("  usage: display process cxy\n");
286                    return;
287            }
288
289            cxy = atoi(argv[2]);
290
291        if( display_cluster_processes( cxy ) )
292        {
293            printf("  error: illegal argument cxy = %x\n", cxy );
294        }
295    }
296    else if( strcmp( argv[1] , "txt" ) == 0 )
297    {
298        if( argc != 3 )
299        {
300                    printf("  usage: display txt txt_id\n");
301                    return;
302            }
303
304            txt_id = atoi(argv[2]);
305
306        if( display_txt_processes( txt_id ) )
307        {
308            printf("  error: illegal argument txt_id = %x\n", txt_id );
309        }
310    }
311    else if( strcmp( argv[1] , "vfs" ) == 0 )
312    {
313        if( argc != 2 )
314        {
315                    printf("  usage: display vfs\n");
316                    return;
317            }
318
319        display_vfs();
320    }
321    else if( strcmp( argv[1] , "chdev" ) == 0 )
322    {
323        if( argc != 2 )
324        {
325                    printf("  usage: display chdev\n");
326                    return;
327            }
328
329        display_chdev();
330    }
[445]331    else if( strcmp( argv[1] , "dqdt" ) == 0 )
332    {
333        if( argc != 2 )
334        {
335                    printf("  usage: display dqdt\n");
336                    return;
337            }
338
339        display_dqdt();
340    }
[436]341    else
342    {
343        printf("  usage: display (vmm/sched/process/vfs/chdev/txt) [arg2] [arg3]\n");
344    }
345} // end cmd_display()
346
[427]347/////////////////////////////////////////
348static void cmd_fg(int argc, char **argv)
349{
350        unsigned int pid;
351
352        if (argc != 2) 
353    {
354                printf("  usage: %s pid\n", argv[0]);
355                return;
356        }
357
358    pid = atoi( argv[1] );   
359
360    if( pid == 0 )
361    {
[442]362                printf("  error: PID cannot be 0\n" );
[427]363        }
364
365    if( fg( pid ) )
366    {
367                printf("  error: cannot find process %x\n", pid );
368        }
[436]369}  // end cmd_fg()
[427]370
[407]371//////////////////////////////////////////////
372static void cmd_help( int argc , char **argv )
[230]373{
[407]374        unsigned int i;
[230]375
[407]376        if (argc != 1) 
377    {
[409]378                printf("  usage: %s\n", argv[0]);
[230]379                return;
380        }
381
382        printf("available commands:\n");
[407]383        for (i = 0 ; cmd[i].name ; i++) 
384    {
[230]385                printf("\t%s\t : %s\n", cmd[i].name , cmd[i].desc);
386        }
[407]387}   // end cmd_help()
[230]388
[407]389//////////////////////////////////////////////
390static void cmd_kill( int argc , char **argv )
[230]391{
[407]392        unsigned int pid;
[230]393
[407]394        if (argc != 2) 
395    {
[409]396                printf("  usage: %s pid\n", argv[0]);
[230]397                return;
398        }
399
[427]400        pid = atoi( argv[1] );
[230]401
[427]402    if( pid == 0 )
403    {
[440]404                printf("  error: kernel process 0 cannot be killed\n" );
[427]405        }
406
[416]407        if( kill( pid , SIGKILL ) )
[407]408    {
[440]409                printf("  error: process %x cannot be killed\n", pid );
[230]410        }
[407]411}   // end cmd_kill()
[230]412
[407]413//////////////////////////////////////////////
414static void cmd_load( int argc , char **argv )
[230]415{
[436]416        int                  ret_fork;           // return value from fork
417        int                  ret_exec;           // return value from exec
418    unsigned int         ksh_pid;            // KSH process PID
419        char               * pathname;           // path to .elf file
420    unsigned int         background;         // background execution if non zero
421    int                  status;             // new process exit status
[407]422
[427]423        if( (argc < 2) || (argc > 3) ) 
[407]424    {
[434]425                printf("  usage: %s pathname [&]\n", argv[0] );
[407]426                return;
427        }
428
429        pathname = argv[1];
430
[427]431    if( argc == 3 ) background = (argv[2][0] == '&');
[434]432    else            background = 0;
[427]433
[434]434    // get KSH process PID
435    ksh_pid = getpid();
[407]436
[434]437    // KSH process fork CHILD process
[436]438        ret_fork = fork();
[434]439
[436]440    if ( ret_fork < 0 )          // it is a failure reported to KSH
[407]441    {
[434]442        printf("  error: ksh process unable to fork\n");
[440]443        return;
[434]444    }
[436]445    else if (ret_fork == 0)      // it is the CHILD process
[434]446    {
447        // CHILD process exec NEW process
[444]448        ret_exec = execve( pathname , NULL , NULL );
[434]449
[441]450        // this is only executed in case of exec failure
[436]451        if( ret_exec )
[409]452        {
[441]453            printf("  error: child process unable to exec <%s>\n", pathname );
454            exit( 0 );
[436]455        }   
456        } 
457    else                        // it is the parent KSH : ret_fork is the new process PID
458    {
[446]459        // give back terminal ownership to KSH
460        // when new process created in background
[441]461        if( background )   fg( ksh_pid );
[436]462
[441]463        // return to command interpreter
464        return;
[436]465    }
[407]466}   // end cmd_load
467
468/////////////////////////////////////////////
469static void cmd_log( int argc , char **argv )
470{
471        unsigned int i;
472
[230]473        printf("--- registered commands ---\n");
[407]474        for (i = 0; i < LOG_DEPTH; i++) 
475    {
[436]476                printf(" - %d\t: %s\n", i, &log_entries[i].buf);
[230]477        }
478}
479
[407]480////////////////////////////////////////////
481static void cmd_ls( int argc , char **argv )
[230]482{
[407]483        char  * path;
[230]484
[407]485//  struct dirent * file;
486//  DIR *dir;
487
488        if (argc == 1)
489    {
[230]490                path = ".";
[407]491        }
492    else if (argc == 2) 
493    {
[230]494                path = argv[1];
[407]495        } 
496    else 
497    {
[409]498                printf("  usage: ls [path]\n");
[230]499                return;
500        }
501
[409]502    printf("  error: not implemented yet\n");
[407]503/*
504        dir = opendir( path );
[230]505        while ((file = readdir(dir)) != NULL)
506        {
507                printf(" %s\n", file->d_name);
508        }
509        closedir(dir);
[407]510*/
[230]511}
512
[407]513///////////////////////////////////////////////
514static void cmd_mkdir( int argc , char **argv )
[230]515{
[407]516        char * pathname;
[230]517
[407]518        if (argc != 2)
519    {
[409]520                printf("  usage: mkdir pathname\n");
[230]521                return;
522        }
523
[407]524    pathname = argv[1];
[230]525
[409]526    printf("  error: not implemented yet\n");
[407]527/*
528        if ( mkdir( path, 0x700) == -1 )
529    {
[409]530                printf("  error: cannot create directory %s\n", path);
[230]531        }
[407]532*/
[230]533}
534
[407]535////////////////////////////////////////////
536static void cmd_mv( int argc , char **argv )
[230]537{
[407]538
[230]539        if (argc < 3)
540        {
541                printf("  usage : %s src_pathname dst_pathname\n", argv[0]);
542                return;
543        }
544
[409]545    printf("  error: not implemented yet\n");
[407]546   
547/*
[230]548        int ret = giet_fat_rename(argv[1], argv[2]);
549        if (ret < 0)
550        {
[409]551                printf("  error : cannot move %s to %s / err = %d\n", argv[1], argv[2], ret );
[230]552        }
[407]553*/
554
[230]555}
556
[407]557/////////////////////////////////////////////
558static void cmd_pwd( int argc , char **argv )
[230]559{
[407]560        char buf[1024];
[230]561
[407]562        if (argc != 1)
563    {
[409]564                printf("  usage: pwd\n");
[407]565                return;
566        }
567
568        if ( getcwd( buf , 1024 ) ) 
569    {
[409]570                printf("  error: unable to get current directory\n");
[407]571        }
572    else 
573    {
574                printf("%s\n", buf);
575        }
576}
577
578////////////////////////////////////////////
579static void cmd_rm( int argc , char **argv )
580{
581        char * pathname;
582
583        if (argc != 2)
584    {
[409]585                printf("  usage: rm pathname\n");
[230]586                return;
587        }
588
[407]589        pathname = argv[1];
[230]590
[409]591    printf("  error: not implemented yet\n");
[407]592/*
593        if (remove(path) == -1)
594    {
[409]595                printf("  error: cannot remove %s\n", path);
[230]596        }
[407]597*/
598
[230]599}
600
[407]601///////////////////////////////////////////////
602static void cmd_rmdir( int argc , char **argv )
[230]603{
604        cmd_rm(argc, argv);
605}
606
[442]607///////////////////////////////////////////////
608static void cmd_trace( int argc , char **argv )
609{
610    unsigned int cxy;
611    unsigned int lid;
612
613        if (argc != 3)
614    {
615                printf("  usage: trace cxy lid \n");
616                return;
617        }
618
619    cxy = atoi(argv[1]);
620    lid = atoi(argv[2]);
621
622    if( trace( 1 , cxy , lid ) )
623    {
624        printf("  error: core[%x,%d] not found\n", cxy, lid );
625    }
626}
627
628///////////////////////////////////////////////
629static void cmd_untrace( int argc , char **argv )
630{
631    unsigned int cxy;
632    unsigned int lid;
633
634        if (argc != 3)
635    {
636                printf("  usage: untrace cxy lid \n");
637                return;
638        }
639
640    cxy = atoi(argv[1]);
641    lid = atoi(argv[2]);
642
643    if( trace( 0 , cxy , lid ) )
644    {
645        printf("  error: core[%x,%d] not found\n", cxy, lid );
646    }
647}
648
[407]649//////////////////////////////////////////////////////////////////
650// Array of commands
651//////////////////////////////////////////////////////////////////
[230]652
[407]653ksh_cmd_t cmd[] =
[230]654{
[435]655        { "cat",     "display file content",                            cmd_cat     },
656        { "cd",      "change current directory",                        cmd_cd      },
657        { "cp",      "replicate a file in file system",                 cmd_cp      },
658    { "fg",      "put a process in foreground",                     cmd_fg      },
659    { "display", "display vmm/sched/process/vfs/chdev/txt",         cmd_display },
660        { "load",    "load an user application",                        cmd_load    },
661        { "help",    "list available commands",                         cmd_help    },
662        { "kill",    "kill an application (all threads)",               cmd_kill    },
663        { "log",     "list registered commands",                        cmd_log     },
664        { "ls",      "list directory entries",                          cmd_ls      },
665        { "mkdir",   "create a new directory",                          cmd_mkdir   },
666        { "mv",      "move a file in file system",                      cmd_mv      },
667        { "pwd",     "print current working directory",                 cmd_pwd     },
668        { "rm",      "remove a file from file system",                  cmd_rm      },
669        { "rmdir",   "remove a directory from file system",             cmd_rmdir   },
[442]670        { "trace",   "activate trace for a given core",                 cmd_trace   },
671        { "untrace", "desactivate trace for a given core",              cmd_untrace },
[435]672        { NULL,      NULL,                                                                              NULL        }
[230]673};
674
[407]675////////////////////////////////////////////////////////////////////////////////////
676// This function analyses one command (with arguments), execute it, and return.
677////////////////////////////////////////////////////////////////////////////////////
[230]678static void parse(char *buf)
679{
680        int argc = 0;
681        char *argv[MAX_ARGS];
682        int i;
683        int len = strlen(buf);
684
685        // build argc/argv
[407]686        for (i = 0; i < len; i++) 
687    {
688                if (buf[i] == ' ') 
689        {
[230]690                        buf[i] = '\0';
[407]691                }
692        else if (i == 0 || buf[i - 1] == '\0') 
693        {
694                        if (argc < MAX_ARGS) 
695            {
[230]696                                argv[argc] = &buf[i];
697                                argc++;
698                        }
699                }
700        }
701
[407]702        if (argc > 0)
703    {
[230]704                int found = 0;
705
706                argv[argc] = NULL;
707
[407]708                // try to match typed command
709                for (i = 0; cmd[i].name; i++)
710        {
711                        if (strcmp(argv[0], cmd[i].name) == 0)
712            {
[230]713                                cmd[i].fn(argc, argv);
714                                found = 1;
715                                break;
716                        }
717                }
718
[407]719                if (!found)
720        {
[434]721                        printf("  undefined command <%s>\n", argv[0]);
[230]722                }
723        }
[446]724}  // end parse()
[230]725
[446]726/////////////////////////
727static void interactive()
[230]728{
[407]729        char         c;                                           // read character
730        char         buf[CMD_MAX_SIZE];           // buffer for one command
[446]731        unsigned int count;                               // pointer in buf
[407]732        unsigned int i;                                           // index for loops
[230]733
[407]734        enum fsm_states
735    {
[230]736                NORMAL,
737                ESCAPE,
738                BRAKET,
739        };
740
[446]741        // initialize command buffer
[407]742        memset( buf, 0x20 , sizeof(buf) );
[230]743        count = 0;
744
745        // display first prompt
746        printf("# ");
747
748        // This lexical analyser writes one command line in the buf buffer.
749        // It is implemented as a 3 states FSM to handle the following sequences:
750        // - ESC [ A : up arrow
751        // - ESC [ B : down arrow
752        // - ESC [ C : right arrow
753        // - ESC [ D : left arrow
[407]754        // The three states have the following semantic:
[230]755        // - NORMAL : no (ESC) character has been found
756        // - ESCAPE : the character (ESC) has been found
757        // - BRAKET : the wo characters (ESC,[) have been found
[436]758
[230]759        unsigned int state = NORMAL;
760
[407]761// @@@
[446]762parse("load /bin/user/idbg.elf");
[407]763// @@@
[408]764
[230]765        while (1)
766        {
[407]767                c = (char)getchar();
[230]768
[407]769        if( c == 0 ) continue;
770
[230]771                switch (state)
772                {
773                        case NORMAL:
774                        {
775                                if ((c == '\b') || (c == 0x7F))  // backspace => remove one character
776                                {
777                                        if (count > 0) {
778                                                printf("\b \b");
779                                                count--;
780                                        }
781                                }
782                                else if (c == '\n')      // new line => call parser to execute command
783                                {
784                                        if (count > 0)
785                                        {
786                                                // complete command
787                                                buf[count] = '\0';
788
789                                                // register command in log arrays
790                                                strcpy(log_entries[ptw].buf, buf);
791                                                log_entries[ptw].count = count;
792                                                ptw = (ptw + 1) % LOG_DEPTH;
793                                                ptr = ptw;
794
795                                                // execute command
796                                                printf("\n");
797                                                parse((char *)&buf);
798
799                                                // reinitialise buffer and display prompt
800                                                for ( i = 0 ; i < sizeof(buf) ; i++ ) buf[i] = 0x20;
801                                                count = 0;
802                                                printf("# ");
803                                        }
[441]804                    else
805                    {
806                        printf("\n# ");
807                    }
[230]808                                }
809                                else if (c == '\t')     // tabulation => do nothing
810                                {
811                                }
[436]812                                else if (c == (char)0x1B)       // ESC => start an escape sequence
[230]813                                {
814                                        state = ESCAPE;
815                                }
816                                else                                     // register character in command buffer
817                                {
818                                        if (count < sizeof(buf) - 1)
819                                        {
[418]820                                                putchar( c );
[230]821                                                buf[count] = c;
822                                                count++;
823                                        }
824                                }
825                                break;
826                        }
827                        case ESCAPE:
828                        {
829                                if (c == '[')           //  valid sequence => continue
830                                {
831                                        state = BRAKET;
832                                }
833                                else                               // invalid sequence => do nothing
834                                {
835                                        state = NORMAL;
836                                }
837                                break;
838                        }
839                        case BRAKET:
840                        {
841                                if (c == 'D')   // valid  LEFT sequence => move buf pointer left
842                                {
843                                        if (count > 0)
844                                        {
845                                                printf("\b");
846                                                count--;
847                                        }
848
849                                        // get next user char
850                                        state = NORMAL;
851                                }
852                                else if (c == 'C')   // valid  RIGHT sequence => move buf pointer right
853                                {
854                                        if (count < sizeof(buf) - 1)
855                                        {
856                                                printf("%c", buf[count]);
857                                                count++;
858                                        }
859
860                                        // get next user char
861                                        state = NORMAL;
862                                }
863                                else if (c == 'A')   // valid  UP sequence => move log pointer backward
864                                {
865                                        // cancel current command
866                                        for (i = 0; i < count; i++) printf("\b \b");
867                                        count = 0;
868
869                                        // copy log command into buf
870                                        ptr = (ptr - 1) % LOG_DEPTH;
871                                        strcpy(buf, log_entries[ptr].buf);
872                                        count = log_entries[ptr].count;
873
874                                        // display log command
875                                        printf("%s", buf);
876
877                                        // get next user char
878                                        state = NORMAL;
879                                }
880                                else if (c == 'B')   // valid  DOWN sequence => move log pointer forward
881                                {
882                                        // cancel current command
883                                        for (i = 0 ; i < count; i++) printf("\b \b");
884                                        count = 0;
885
886                                        // copy log command into buf
887                                        ptr = (ptr + 1) % LOG_DEPTH;
888                                        strcpy(buf, log_entries[ptr].buf);
889                                        count = log_entries[ptr].count;
890
891                                        // display log command
892                                        printf("%s", buf);
893
894                                        // get next user char
895                                        state = NORMAL;
896                                }
897                                else                               // other character => do nothing
898                                {
899                                        // get next user char
900                                        state = NORMAL;
901                                }
902                                break;
903                        }
904                }
905        }
[446]906}  // end interactive()
907
908///////////////////////////////////
909int main( int argc , char *argv[] )
910{
911    unsigned int cxy;             // owner cluster identifier for this KSH process
912    unsigned int lid;             // core identifier for this KSH main thread
913    int          status;          // child process termination status
914    int          pid;             // chils process identifier
915    pthread_t    trdid;           // kernel allocated index for interactive thread
916
917    // initialize log buffer
918        memset( &log_entries , 0, sizeof(log_entries));
919        ptw   = 0;
920        ptr   = 0;
921
922    get_core( &cxy , & lid );
923        printf( "\n\n~~~ KSH on core[%x,%d] ~~~\n\n", cxy , lid );
924
925    // initialize interactive thread attributes
926    attr.attributes = PT_ATTR_DETACH | PT_ATTR_CLUSTER_DEFINED;
927    attr.cxy        = cxy;
928
929    // lauch the interactive thread
930    pthread_create( &trdid,
931                    &attr,
932                    &interactive,   // entry function
933                    NULL ); 
934   
935    // enter infinite loop monitoring children processes termination
936    while( 1 )
937    {
938        pid = wait( &status );
939
940#if 0
941        if     ( WIFEXITED  (status) ) printf("\n[KSH] process %x exited\n" , pid );
942        else if( WIFSIGNALED(status) ) printf("\n[KSH] process %x killed\n" , pid );
943        else if( WIFSTOPPED (status) ) printf("\n[KSH] process %x stopped\n", pid );
944        else                           printf("\n[KSH] process %x strange\n", pid ); 
945#endif
946
947    }
[436]948}  // end main()
[230]949
[446]950
Note: See TracBrowser for help on using the repository browser.