Thứ Hai, 28 tháng 1, 2013

Bệnh SĨ

Bệnh SĨ

Kim cổ chữ DANH bán vạn đồng
Được rồi mua giúp chữ SĨ không
Hai tay dâng lấy DANH hư hão
SĨ DIỆN thôi rồi cũng thất công

Ti tiện thói đời bày trước mắt
Thôi thì tích cóp để phòng cơ
Góp sự ý hay chừng tưởng bở
Lời rằng mọi chuyển thế mới may

Chấp nhặt làm chi lòng bứt rứt
Của họ cớ gì lại tòng hong
Bớt lời có dễ sao chẳng tập
Hỏi hỏi hông hông để chạnh lòng.

Tokyo, Jan.28.2013
VO Huu-Phuc.

Suy gẫm

Suy gẫm

Cuộc đời xoay tít như con tạo
Thanh bình liệu có dễ dễ không
Dòng đời hối hả tuôn tuôn chảy
Cuốn mất tuổi xuân một thoáng trời

Thế sự nhiễu nhương như canh hẹ
Ta ung dung đứng, trong hay ngoài ?
Kẻ ở bên trong thì hối hả
Bên ngoài người đứng cũng trầm ưu

Học sĩ đương thời lim dim mắt
Nhắm mở thôi thì chuyện cũng xong
Cơm no ấm cật tàm tạm đủ
Ươm mầm nhân thế tự nhiên thôi

Mộng mị à ơi ru ru mãi
Khi nào gà gáy rạng rạng ngời
Ngẫm nghĩ bâng quơ vài dòng viết
Không rảnh nhưng đành nhại thơ thôi.

Tokyo, Jan.28.2013
VO Huu-Phuc.

Victory loves Preparation

Victory loves Preparation 

Chủ Nhật, 27 tháng 1, 2013

Chiều tà

Chiều tà

Một ánh hào quang tắt tắt dần
Nửa hồn cô quạnh dạ bâng khuâng
Chim kêu não ruột vờn trong gió
Tắt ánh tà dương nhạc khúc sầu

Tiết đông se lạnh đêm tĩnh mịch
Quạnh quẽ cô phòng nhớ cố hương
Nhật nguyệt thay phiên mà ấm lạnh
Tinh tú soi đường có vấn vương

Không gian chìm lắng rì rào gió
Cố chấp một lời thoảng thoảng đưa
Từ bi đâu dễ, tìm có thấy ?
Từ tâm thực tập có được xuôi ?

Chấp niệm chi bằng tuân hỉ xả
An lành ắt hiện chẳng xa xôi
Bể khổ vô luân chìm chìm đắm
Trần tục vô thường lại vấn vương

Chiến ý năm xưa giờ đâu mất
Tư lự não nề lại nhiễu nhương
Đánh thắng vạn quân là hiển hách
Nhân tâm tự phục liệt liệt oanh.

Tokyo, Jan.27.2013
VO Huu-Phuc.

Cõi Thiền

Cõi Thiền

Chập chờn mộng mị vô thường
Ồn ào tơ tưởng vấn vương cõi lòng
Thanh bình xa tận mây hồng
An lành đâu đó một vòng vân vu
Chuyện đời bọt nước bê dâu
Vô thanh vô sắc như sương trên cành
Dẫu rằng giữa bể luân trầm
Thinh không tĩnh lặng giữ tâm yên bình
Đời người như cuộc bể dâu
Lời hay tiếng ấy biết đâu mà lường
Nghĩ suy cho đến tỏ tường
Vô thường rồi lại vô thường mà hồi luân
Chiêm bao một giấc bình thường
Êm đềm mộng điệp vấn vương làm gì
Ngày ngày vẫn cứ nghĩ suy
Đêm về thao trức trầm mê luân hồi
Hào quang chói lọi bốn bề
Lời kinh tiếng kệ u mê tan dần

Tokyo, Jan.27.2013
-- VO Huu-Phuc --

Thứ Sáu, 25 tháng 1, 2013

Under a violet moon


Under a Violet Moon

Dancing to the feel of the drum

Leave this world behind
We'll have a drink and toast to ourselves
Under a Violet Moon
Tudor Rose with her hair in curls
Will make you turn and stare
Try to steal a kiss at the bridge
Under a Violet Moon
Raise your hats and your glasses too
We will dance the whole night through
We're going back to a time we knew
Under a Violet Moon
Cheers to the Knights and days of old
the beggars and the thieves
living in an enchanted wood
Under a Violet Moon
Fortuneteller what do you see
Future in a card
Share your secrets, tell them to me
Under a Violet Moon
Close your eyes and lose yourself
In a medieval mood
Taste the treasures and sing the tunes
Under a Violet Moon
Tis my delight on a shiny night
The season of the year
To keep the lanterns burning bright
Under a Violet Moon





Thứ Năm, 24 tháng 1, 2013

Vô vi

Vô vi

Ngẩn ngơ cây cỏ giữa trời
Tưởng như vô nghĩa cho đời vô vi
Bao mùa lại đến rồi đi
Vờn trong ngọn gió thầm thì với mây
Cỏ cây vươn vấn tháng ngày
Ngỡ đâu vô sự lại chừng thương đau
Lá buồn héo rũ âu sầu
Cành buồn hiu hắt dẫu còn xuân xanh
Bướm vờn ong lượn quẩn quanh
Hoa tàn lá úa nghe ươm mộng lành.

Basic unix commands

http://mally.stanford.edu/~sr/computing/basic-unix.html


Basic UNIX commands

Note: not all of these are actually part of UNIX itself, and you may not find them on all UNIX machines. But they can all be used on turing in essentially the same way, by typing the command and hitting return. Note that some of these commands are different on non-Solaris machines - see SunOS differences.
If you've made a typo, the easiest thing to do is hit CTRL-u to cancel the whole line. But you can also edit the command line (see the guide toMore UNIX).
UNIX is case-sensitive.

Files

  • ls --- lists your files
    ls -l --- lists your files in 'long format', which contains lots of useful information, e.g. the exact size of the file, who owns the file and who has the right to look at it, and when it was last modified.
    ls -a --- lists all files, including the ones whose filenames begin in a dot, which you do not always want to see.
    There are many more options, for example to list files by size, by date, recursively etc.
  • more filename --- shows the first part of a file, just as much as will fit on one screen. Just hit the space bar to see more or q to quit. You can use /pattern to search for a pattern.
  • emacs filename --- is an editor that lets you create and edit a file. See the emacs page.
  • mv filename1 filename2 --- moves a file (i.e. gives it a different name, or moves it into a different directory (see below)
  • cp filename1 filename2 --- copies a file
  • rm filename --- removes a file. It is wise to use the option rm -i, which will ask you for confirmation before actually deleting anything. You can make this your default by making an alias in your .cshrc file.
  • diff filename1 filename2 --- compares files, and shows where they differ
  • wc filename --- tells you how many lines, words, and characters there are in a file
  • chmod options filename --- lets you change the read, write, and execute permissions on your files. The default is that only you can look at them and change them, but you may sometimes want to change these permissions. For example, chmod o+r filename will make the file readable for everyone, and chmod o-r filename will make it unreadable for others again. Note that for someone to be able to actually look at the file the directories it is in need to be at least executable. See help protection for more details.
  • File Compression
    • gzip filename --- compresses files, so that they take up much less space. Usually text files compress to about half their original size, but it depends very much on the size of the file and the nature of the contents. There are other tools for this purpose, too (e.g.compress), but gzip usually gives the highest compression rate. Gzip produces files with the ending '.gz' appended to the original filename.
    • gunzip filename --- uncompresses files compressed by gzip.
    • gzcat filename --- lets you look at a gzipped file without actually having to gunzip it (same as gunzip -c). You can even print it directly, using gzcat filename | lpr
  • printing
    • lpr filename --- print. Use the -P option to specify the printer name if you want to use a printer other than your default printer. For example, if you want to print double-sided, use 'lpr -Pvalkyr-d', or if you're at CSLI, you may want to use 'lpr -Pcord115-d'. See 'help printers' for more information about printers and their locations.
    • lpq --- check out the printer queue, e.g. to get the number needed for removal, or to see how many other files will be printed before yours will come out
    • lprm jobnumber --- remove something from the printer queue. You can find the job number by using lpq. Theoretically you also have to specify a printer name, but this isn't necessary as long as you use your default printer in the department.
    • genscript --- converts plain text files into postscript for printing, and gives you some options for formatting. Consider making an alias like alias ecop 'genscript -2 -r \!* | lpr -h -Pvalkyr' to print two pages on one piece of paper.
    • dvips filename --- print .dvi files (i.e. files produced by LaTeX). You can use dviselect to print only selected pages. See the LaTeX page for more information about how to save paper when printing drafts.

Directories

Directories, like folders on a Macintosh, are used to group files together in a hierarchical structure.
  • mkdir dirname --- make a new directory
  • cd dirname --- change directory. You basically 'go' to another directory, and you will see the files in that directory when you do 'ls'. You always start out in your 'home directory', and you can get back there by typing 'cd' without arguments. 'cd ..' will get you one level up from your current position. You don't have to walk along step by step - you can make big leaps or avoid walking around by specifyingpathnames.
  • pwd --- tells you where you currently are.

Finding things

  • ff --- find files anywhere on the system. This can be extremely useful if you've forgotten in which directory you put a file, but do remember the name. In fact, if you use ff -p you don't even need the full name, just the beginning. This can also be useful for finding other things on the system, e.g. documentation.
  • grep string filename(s) --- looks for the string in the files. This can be useful a lot of purposes, e.g. finding the right file among many, figuring out which is the right version of something, and even doing serious corpus work. grep comes in several varieties (grepegrep, andfgrep) and has a lot of very flexible options. Check out the man pages if this sounds good to you.

About other people

  • w --- tells you who's logged in, and what they're doing. Especially useful: the 'idle' part. This allows you to see whether they're actually sitting there typing away at their keyboards right at the moment.
  • who --- tells you who's logged on, and where they're coming from. Useful if you're looking for someone who's actually physically in the same building as you, or in some other particular location.
  • finger username --- gives you lots of information about that user, e.g. when they last read their mail and whether they're logged in. Often people put other practical information, such as phone numbers and addresses, in a file called .plan. This information is also displayed by 'finger'.
  • last -1 username --- tells you when the user last logged on and off and from where. Without any options, last will give you a list of everyone's logins.
  • talk username --- lets you have a (typed) conversation with another user
  • write username --- lets you exchange one-line messages with another user
  • elm --- lets you send e-mail messages to people around the world (and, of course, read them). It's not the only mailer you can use, but the one we recommend. See the elm page, and find out about the departmental mailing lists (which you can also find in /user/linguistics/helpfile).

About your (electronic) self

  • whoami --- returns your username. Sounds useless, but isn't. You may need to find out who it is who forgot to log out somewhere, and make sure *you* have logged out.
  • finger & .plan files
    of course you can finger yourself, too. That can be useful e.g. as a quick check whether you got new mail. Try to create a useful .plan file soon. Look at other people's .plan files for ideas. The file needs to be readable for everyone in order to be visible through 'finger'. Do 'chmod a+r .plan' if necessary. You should realize that this information is accessible from anywhere in the world, not just to other people on turing.
  • passwd --- lets you change your password, which you should do regularly (at least once a year). See the LRB guide and/or look at help password.
  • ps -u yourusername --- lists your processes. Contains lots of information about them, including the process ID, which you need if you have to kill a process. Normally, when you have been kicked out of a dialin session or have otherwise managed to get yourself disconnected abruptly, this list will contain the processes you need to kill. Those may include the shell (tcsh or whatever you're using), and anything you were running, for example emacs or elm. Be careful not to kill your current shell - the one with the number closer to the one of the ps command you're currently running. But if it happens, don't panic. Just try again :) If you're using an X-display you may have to kill some X processes before you can start them again. These will show only when you use ps -efl, because they're root processes.
  • kill PID --- kills (ends) the processes with the ID you gave. This works only for your own processes, of course. Get the ID by using ps. If the process doesn't 'die' properly, use the option -9. But attempt without that option first, because it doesn't give the process a chance to finish possibly important business before dying. You may need to kill processes for example if your modem connection was interrupted and you didn't get logged out properly, which sometimes happens.
  • quota -v --- show what your disk quota is (i.e. how much space you have to store files), how much you're actually using, and in case you've exceeded your quota (which you'll be given an automatic warning about by the system) how much time you have left to sort them out (by deleting or gzipping some, or moving them to your own computer).
  • du filename --- shows the disk usage of the files and directories in filename (without argument the current directory is used). du -s gives only a total.
  • last yourusername --- lists your last logins. Can be a useful memory aid for when you were where, how long you've been working for, and keeping track of your phonebill if you're making a non-local phonecall for dialling in.

Connecting to the outside world

  • nn --- allows you to read news. It will first let you read the news local to turing, and then the remote news. If you want to read only the local or remote news, you can use nnl or nnr, respectively. To learn more about nn type nn, then \tty{:man}, then \tty{=.*}, then \tty{Z}, then hit the space bar to step through the manual. Or look at the man page. Or check out the hypertext nn FAQ - probably the easiest and most fun way to go.
  • rlogin hostname --- lets you connect to a remote host
  • telnet hostname --- also lets you connect to a remote host. Use rlogin whenever possible.
  • ftp hostname --- lets you download files from a remote host which is set up as an ftp-server. This is a common method for exchanging academic papers and drafts. If you need to make a paper of yours available in this way, you can (temporarily) put a copy in /user/ftp/pub/TMP. For more permanent solutions, ask Emma. The most important commands within ftp are get for getting files from the remote machine, and put for putting them there (mget and mput let you specify more than one file at once). Sounds straightforward, but be sure not to confuse the two, especially when your physical location doesn't correspond to the direction of the ftp connection you're making. ftp just overwrites files with the same filename. If you're transferring anything other than ASCII text, use binary mode.
  • lynx --- lets you browse the web from an ordinary terminal. Of course you can see only the text, not the pictures. You can type any URL as an argument to the G command. When you're doing this from any Stanford host you can leave out the .stanford.edu part of the URL when connecting to Stanford URLs. Type H at any time to learn more about lynx, and Q to exit.

Miscellaneous tools

  • webster word --- looks up the word in an electronic version of Webster's dictionary and returns the definition(s)
  • date --- shows the current date and time.
  • cal --- shows a calendar of the current month. Use e.g., 'cal 10 1995' to get that for October 95, or 'cal 1995' to get the whole year.
You can find out more about these commands by looking up their manpages:
man commandname --- shows you the manual page for the commandFor further ways of obtaining help, look at the pages with electronic sources of information and non-electronic sources.
More UNIX commands

Back up to the Main Computing Page

Thứ Bảy, 19 tháng 1, 2013

SIGPLAN - Advice on how to write submissions


If you would like some advice on how to write submissions, here are some suggestions by
Link: http://www.sigplan.org/authorInformation.htm

VO Huu-Phuc (Tokyo)

Thứ Năm, 17 tháng 1, 2013

Das Rad des Schicksals - The wheel of fortune.

Das Rad des Schicksals - The wheel of fortune.





Ocaml - minishell

Previous Up Next

 3  Processes

A process is a program executing on the operating system. It consists of a program (machine code) and a state of the program (current control point, variable values, call stack, open file descriptors, etc.).
This section presents the Unix system calls to create new processes and make them run other programs.

3.1  Creation of processes

The system call fork creates a process.
val fork : unit -> int
The new child process is a nearly perfect clone of the parent process which calledfork. Both processes execute the same code, are initially at the same control point (the return from fork), attribute the same values to all variables, have identical call stacks, and hold open the same file descriptors to the same files. The only thing which distinguishes the two processes is the return value from fork: zero in the child process, and a non-zero integer in the parent. By checking the return value from fork, a program can thus determine if it is in the parent process or the child and behave accordingly:
match fork () with | 0 -> (* code run only in the child *) | pid -> (* code run only in the parent *)
The non-zero integer returned by fork in the parent process is the process id of the child. The process id is used by the kernel to uniquely identify each process. A process can obtain its process id by calling getpid.
The child process is initially in the same state as the parent process (same variable values, same open file descriptors). This state is not shared between the parent and the child, but merely duplicated at the moment of the fork. For example, if one variable is bound to a reference before the fork, a copy of that reference and its current contents is made at the moment of the fork; after thefork, each process independently modifies its “own” reference without affecting the other process.
Similarly, the open file descriptors are copied at the moment of the fork: one may be closed and the other kept open. On the other hand, the two descriptors designate the same entry in the file table (residing in system memory) and share their current position: if one reads and then the other, each will read a different part of the file; likewise, changes in the read/write position by one process withlseek are immediately visible to the other.

3.2  Complete Example: the command leave

The command leave hhmm exits immediately, but forks a background process which, at the time hhmm, reports that it is time to leave.
1 open Unix;; 2 3 let leave () = 4 let hh = int_of_string (String.sub Sys.argv.(1) 0 2) 5 and mm = int_of_string (String.sub Sys.argv.(1) 2 2) in 6 let now = localtime(time ()) in 7 let delay = (hh - now.tm_hour) * 3600 + (mm - now.tm_min) * 60 in 8 9 if delay <= 0 then begin 10 print_endline "Hey! That time has already passed!"; 11 exit 0 12 end; 13 if fork () <> 0 then exit 0; 14 sleep delay; 15 print_endline "\007\007\007Time to leave!"; 16 exit 0;; 17 18 handle_unix_error leave ();;
The program begins with a rudimentary parsing of the command line, in order to extract the time provided. It then calculates the delay in seconds (line 8). Thetime call returns the current date, in seconds from the epoch (January 1st 1970, midnight). The function localtime splits this duration into years, months, days, hours, minutes and seconds. It then creates a new process using fork. The parent process (whose return value from fork is a non-zero integer) terminates immediately. The shell which launched leave thereby returns control to the user. The child process (whose return value from fork is zero) continues executing. It does nothing during the indicated time (the call to sleep), then displays its message and terminates.

3.3  Awaiting the termination of a process

The system call wait waits for one of the child processes created by fork to terminate and returns information about how it did. It provides a parent-child synchronization mechanism and a very rudimentary form of communication from the child to the parent.
val wait : unit -> int * process_status val waitpid : wait_flag list -> int -> int * process_status
The primitive system call is waitpid and the function wait () is merely a shortcut for the expression waitpid [] (-1). The behavior ofwaitpid [] p depends on the value of p:
  • If p > 0, it awaits the termination of the child with id equal to p.
  • If p = 0, it awaits any child with the same group id as the calling process.
  • If p = −1, it awaits any process.
  • If p <−1, it awaits a child process with group id equal to -p.
The first component of the result is the process id of the child caught by wait. The second component of the result is a value of type process_status:
WEXITED rThe child process terminated normally via exit or by reaching the end of the program; r is the return code (the argument passed to exit).
WSIGNALED sThe child process was killed by a signal (ctrl-C, kill, etc., see chapter 4 for more information about signals); s identifies the signal.
WSTOPPED sThe child process was halted by the signal s; this occurs only in very special cases where a process (typically a debugger) is currently monitoring the execution of another (by callingptrace).
If one of the child processes has already terminated by the time the parent callswait, the call returns immediately. Otherwise, the parent process blocks until some child process terminates (a behavior called “rendezvous”). To wait for nchild processes, one must call wait n times.
The command waitpid accepts two optional flags for its first argument: the flagWNOHANG indicates not to wait if there is a child that responds to the request but has not yet terminated. In that case, the first result is 0 and the second undefined. The flag WUNTRACED returns the child processes that have been halted by the signal sigstop. The command raises the exception ECHILD if no child processes match p (in particular, if p is -1 and the current process has no more children).
Example
 The function fork_search below performs a linear search in an array with two processes. It relies on the function simple_search to perform the linear search.
1 open Unix;; 2 exception Found;; 3 4 let simple_search cond v = 5 try 6 for i = 0 to Array.length v - 1 do 7 if cond v.(i) then raise Found 8 done; 9 false 10 with Found -> true;; 11 12 let fork_search cond v = 13 let n = Array.length v in 14 match fork () with 15 | 0 -> 16 let found = simple_search cond (Array.sub v (n/2) (n-n/2)) in 17 exit (if found then 0 else 1) 18 | _ -> 19 let found = simple_search cond (Array.sub v 0 (n/2)) in 20 match wait () with 21 | (pid, WEXITED retcode) -> found || (retcode = 0) 22 | (pid, _) -> failwith "fork_search";;
After the fork, the child process traverses the upper half of the table, and exits with the return code 1 if it found an element satisfying the predicate cond, or 0 otherwise (lines 16 and 17). The parent process traverses the lower half of the table, then calls wait to sync with the child process (lines 21 and 22). If the child terminated normally, it combines its return code with the boolean result of the search in the lower half of the table. Otherwise, something horrible happened, and the function fork_search fails.
* * *
In addition to the synchronization between processes, the wait call also ensures recovery of all resources used by the child processes. When a process terminates, it moves into a “zombie” state, where most, but not all, of its resources (memory, etc.) have been freed. It continues to occupy a slot in the process table to transmit its return value to the parent via the wait call. Once the parent calls wait, the zombie process is removed from the process table. Since this table is of fixed size, it is important to call wait on each forked process to avoid leaks.
If the parent process terminates before the child, the child is given the process number 1 (usually init) as parent. This process contains an infinite loop ofwait calls, and will therefore make the child process disappear once it finishes. This leads to the useful “double fork” technique if you cannot easily call wait on each process you create (because you cannot afford to block on termination of the child process, for example).
match fork () with | 0 -> if fork () <> 0 then exit 0; (* do whatever the child should do *) | _ -> wait (); (* do whatever the parent should do *)
The child terminates via exit just after the second fork. The grandson becomes an orphan, and is adopted by init. In this way, it leaves no zombie processes. The parent immediately calls wait to reap the child. This wait will not block for long since the child terminates very quickly.

3.4  Launching a program

The system calls execveexecv, and execvp launch a program within the current process. Except in case of error, these calls never return: they halt the progress of the current program and switch to the new program.
val execve : string -> string array -> string array -> unit val execv : string -> string array -> unit val execvp : string -> string array -> unit
The first argument is the name of the file containing the program to execute. In the case of execvp, this name is looked for in the directories of the search path (specified in the environment variable PATH).
The second argument is the array of command line arguments with which to execute the program; this array will be the Sys.argv array of the executed program.
In the case of execve, the third argument is the environment given to the executed program; execv and execvp give the current environment unchanged.
The calls execveexecv, and execvp never return a result: either everything works without errors and the process starts the requested program or an error occurs (file not found, etc.), and the call raises the exception Unix_error in the calling program.
Example
 The following three forms are equivalent:
execve "/bin/ls" [|"ls"; "-l"; "/tmp"|] (environment ()) execv "/bin/ls" [|"ls"; "-l"; "/tmp"|] execvp "ls" [|"ls"; "-l"; "/tmp"|]
* * *
Example
 Here is a “wrapper” around the command grep which adds the option -i (to ignore case) to the list of arguments:
open Sys;; open Unix;; let grep () = execvp "grep" (Array.concat [ [|"grep"; "-i"|]; (Array.sub Sys.argv 1 (Array.length Sys.argv - 1)) ]) ;; handle_unix_error grep ();;
* * *
Example
 Here’s a “wrapper” around the command emacs which changes the terminal type:
open Sys;; open Unix;; let emacs () = execve "/usr/bin/emacs" Sys.argv (Array.concat [ [|"TERM=hacked-xterm"|]; (environment ()) ]);; handle_unix_error emacs ();;
* * *
The process which calls exec is the same one that executes the new program. As a result, the new program inherits some features of the execution environment of the program which called exec:
  • the same process id and parent process
  • same standard input, standard output and standard error
  • same ignored signals (see chapter 4)

3.5  Complete example: a mini-shell

The following program is a simplified command interpreter: it reads lines from standard input, breaks them into words, launches the corresponding command, and repeats until the end of file on the standard input. We begin with the function which splits a string into a list of words. Please, no comments on this horror.
open Unix;; open Printf;; let split_words s = let rec skip_blanks i = if i < String.length s & s.[i] = ' ' then skip_blanks (i+1) else i in let rec split start i = if i >= String.length s then [String.sub s start (i-start)] else if s.[i] = ' ' then let j = skip_blanks i in String.sub s start (i-start) :: split j j else split start (i+1) in Array.of_list (split 0 0);;
We now move on to the main loop of the interpreter.
let exec_command cmd = try execvp cmd.(0) cmd with Unix_error(err, _, _) -> printf "Cannot execute %s : %s\n%!" cmd.(0) (error_message err); exit 255 let print_status program status = match status with | WEXITED 255 -> () | WEXITED status -> printf "%s exited with code %d\n%!" program status; | WSIGNALED signal -> printf "%s killed by signal %d\n%!" program signal; | WSTOPPED signal -> printf "%s stopped (???)\n%!" program;;
The function exec_command executes a command and handles errors. The return code 255 indicates that the command could not be executed. (This is not a standard convention; we just hope that few commands terminate with a return code of 255.) The function print_status decodes and prints the status information returned by a process, ignoring the return code of 255.
let minishell () = try while true do let cmd = input_line Pervasives.stdin in let words = split_words cmd in match fork () with | 0 -> exec_command words | pid_son -> let pid, status = wait () in print_status "Program" status done with End_of_file -> () ;; handle_unix_error minishell ();;
Each time through the loop, we read a line from stdin with the functioninput_line. This function raises the End_of_file exception when the end of file is reached, causing the loop to exit. We split the line into words, and then callfork. The child process uses exec_command to execute the command. The parent process calls wait to wait for the command to finish and prints the status information returned by wait.
Exercise 10
 Add the ability to execute commands in the background if they are followed by &Answer.
* * *

Previous Up Next