Archive for the ‘HPUX’ Category

Example find command usage

The Unix/Linux find searches the directory tree rooted at each give file name by evaluating the given expression from left to right, according to the rules of precedence, until the output is known, at which point find moves to the next file name. The following is some example usage of find command:

  • find /home -user kevin
    • Find every file under the directory /home owned by kevin
  • find /home -name *kevin
    • find every file under the directory /home ending in kevin
  • find /home -mtime +60
    • find every file under the directory /home that was modified more than 60 days ago
  • find /home -name core -type f -print | xargs /bin/rm -f
    • find file named core in or below the directory /home and delete them. Note that this will not work if there are any file names containing newline, single or double quotes, or spaces
  • find /tmp -name core -type f -print0 | xargs -0 /bin/rm -f
    • Find files named core in or below the directory /tmp and delete them, processing filenames in such a way that file or directory names containing single or double quotes, spaces or newlines are correctly handled. The -name test comes before the -type test in order to avoid having to call stat(2) on every file.
  • find . -type f -exec file ‘{}’ \;
    • Runs `file’ on every file in or below the current directory. Notice that the braces are enclosed in single quote marks to protect them from interpretation as shell script punctuation. The semicolon is similarly protected by the use of a backslash, though ‘;’ could have been used in that case also.

Read Full Post »

PAM Framework

The core component of the PAM framework are the authentication library API (the front end) and the authentication mechanism-specific modules (the back end), connected through the Service Provider Interface. Applications write to the PAM API, while the authentication-system providers write to PAM API and supply the back end module that are independent of the applications.

When an application makes a call to the PAM API, it loads the appropriate authentication module as determined by the configuration file, `pam.conf’.  The request is forwarded to the underlying authentication module (for example, UNIX password, Kerberos, smart cards) to perform the specified operation.  The PAM layer then returns the response from the authentication module to the application.

Not all applications or services may need all of the above components, and not each authentication module may need to provide support for all of the interfaces.

PAM API usually include four areas of functionality:

  • Authentication :::::: This set includes the `pam_authenticate()’ function to authenticate the user, and the `pam_setcred()’ interface to set, refresh or destroy the user
  • account :::::: This set includes the `pam_acct_mgmt()’ function to check whether the authenticated user should be given access to his/her account.  This function can implement account expiration and access hour restrictions.
  • session :::::: This set includes the `pam_open_session()’ and `pam_close_session()’ functions for session management and accounting.  For example, the system may want to store the total time for the session
  • password :::::: This set includes a function, `pam_chauthtok()’, to change the password.

Read Full Post »

daemon, orphan, zombie process

  • Daemon: On Unix or other computer multitasking operating program, a daemon is a computer program that runs in the background. In Unix environment, the parent process of Daemon is often init process(PID=1). Process usually become daemon by forking a child and exit the parents immediately, thus cause init to adopt the child process.
  • Orphan: An orphan process is a computer process whose parent process has finished or terminated, though itself remains running. In a Unix-like operating system, any orphaned process will be immediately adopted by the init process.  A process may be intentionally orphaned so that it becomes detached from the user’s session and left running in the background. Usually to allow a long-running job to complete without further user attention, or to start an indefinitely running service(This kind of orphaned process usually called Daemon)
  • Zombie: On Unix and Unix-like computer OS, a zombie process is a process that completed execution but still has an entry in the process table. This entry is still needed to allow the process that started the process to read its exit status. Unlike normal process, the kill() call has no effect on a zombie process. When a process ends, all the memory and resources are deallocated so they can be used by other process. However, the process’s entry in the process table remains. The parent can read the child’s exit status by wait() system calls, at which stage the zombie are removed.

A zombie process is not the same as an orphan process. An orphan process is a process that is still executing, but whose parent has died. They do not become zombie     processes; instead, they are adopted by init(PID 1), which wait() on its children.

Read Full Post »

Blocking vs Non-Blocking Sockets

One of the first issues that you’ll encounter when developing your Windows Sockets applications is the difference between blocking and non-blocking sockets. Whenever you perform some operation on a socket, it may not be able to complete immediately and return control back to your program. For example, a read on a socket cannot complete until some data has been sent by the remote host. If there is no data waiting to be read, one of two things can happen: the function can wait until some data has been written on the socket, or it can return immediately with an error that indicates that there is no data to be read.

The first case is called a blocking socket. In other words, the program is “blocked” until the request for data has been satisfied. When the remote system does write some data on the socket, the read operation will complete and execution of the program will resume. The second case is called a non-blocking socket, and requires that the application recognize the error condition and handle the situation appropriately. Programs that use non-blocking sockets typically use one of two methods when sending and receiving data. The first method, called polling, is when the program periodically attempts to read or write data from the socket (typically using a timer). The second, and preferred method, is to use what is called asynchronous notification. This means that the program is notified whenever a socket event takes place, and in turn can respond to that event. For example, if the remote program writes some data to the socket, a “read event” is generated so that program knows it can read the data from the socket at that point.

For historical reasons, the default behavior is for socket functions to “block” and not return until the operation has completed. However, blocking sockets in Windows can introduce some special problems. For 16-bit applications, the blocking function will enter what is called a “message loop” where it continues to process messages sent to it by Windows and other applications. Since messages are being processed, this means that the program can be re-entered at a different point with the blocked operation parked on the program’s stack. For example, consider a program that attempts to read some data from the socket when a button is pressed. Because no data has been written yet, it blocks and the program goes into a message loop. The user then presses a different button, which causes code to be executed, which in turn attempts to read data from the socket, and so on.

Blocking socket functions can introduce a different type of problem in 32-bit applications because blocking functions will prevent the calling thread from processing any messages sent to it. Since many applications are single-threaded, this can result in the application being unresponsive to user actions. To resolve the general problems with blocking sockets, the Windows Sockets standard states that there may only be one outstanding blocked call per thread of execution. This means that 16-bit applications that are re-entered (as in the example above) will encounter errors whenever they try to take some action while a blocking function is already in progress. With 32-bit programs, the creation of worker threads to perform blocking socket operations is a common approach, although it introduces additional complexity into the application.

In summary, there are three general approaches that can be taken when building an application with the control in regard to blocking or non-blocking sockets:

  • Use a blocking (synchronous) socket. In this mode, the program will not resume execution until the socket operation has completed. Blocking sockets in 16-bit application will allow it to be re-entered at a different point, and 32-bit applications will stop responding to user actions. This can lead to complex interactions (and difficult debugging) if there are multiple active controls in use by the application.
  • Use a non-blocking (asynchronous) socket, which allows your application to respond to events. For example, when the remote system writes data to the socket, a Read event is generated for the control. Your application can respond by reading the data from the socket, and perhaps send some data back, depending on the context of the data received.
  • Use a combination of blocking and non-blocking socket operations. The ability to switch between blocking and non-blocking modes “on the fly” provides a powerful and convenient way to perform socket operations. Note that the warning regarding blocking sockets also applies here

If you decide to use non-blocking sockets in your application, it’s important to keep in mind that you must check the return value from every read and write operation, since it is possible that you may not be able to send or receive all of the specified data. Frequently, developers encounter problems when they write a program that assumes a given number of bytes can always be written to, or read from, the socket. In many cases, the program works as expected when developed and tested on a local area network, but fails unpredictably when the program is released to a user that has a slower network connection (such as a serial dial-up connection to the Internet). By always checking the return values of these operations, you insure that your program will work correctly, regardless of the speed or configuration of the network.

Read Full Post »



A daemon is a background process designed to run autonomously with little or no user intervention.


  1. Fork off the parent process
  2. Change file create mode using umask()
  3. Open log for writing
  4. Create a unique session ID using setsid()
  5. Change the current work directory to a safe place
  6. Close standard file descriptors
  7. Actual jobs of the Daemon

Read Full Post »

unix init — Jun 12, 2010

getty – set terminal type, modes, speed, and line discipline. getty is invoked by init, as the second process in the series, init > getty > login > shell, that ultimately connects a user with the HPUX system.Getty sets the terminal speed and characteristics and prompts for the users’  login information before passing control to the login program.

While the system is running, a user-spawned init directs the actions of the boot init. It accepts a one-character argument and signals the boot init with the kill() system call to perform the appropriate action :::

  • 0~6: Place the system into one of  the run levels 0 through 6
  • a|b|c: Process the inittab entries that have the special “run level” a, b or c, without changing the numeric run level
  • Q|q: Re-example the inittab entries without changing the run level
  • S|s: Enter the single-user mode. When this level change occurs, the logical system console /dev/syscon is changed to the terminal from which the command was executed

When boot init receives a child death signal telling it that a process it spawned has died, it records the fact and the reason it died in the utmps database, /etc/utmp, /var/adm/wtmps.

After boot init has spawned all of the processes specified in the file /etc/inittab, boot init waits for:

  • one of its descendant processes to die
  • a powerfail signal
  • signaled by a user init to change the system’s run level

when one the above conditions happen, boot init re-examine the /etc/inittab. New items can be added to the inittab file at any time.

Read Full Post »

These files, which contains user and accounting information for such commands as last, who, write and login.

  • File utmp contains a record of all users logged onto the system.
  • File wtmp contains a record of all logins and logouts.
  • File btmp contains bad login entries for each invalid logon attempts.

Note that, wtmp and btmp tend to grow without bound, and should be checked regularly. Information that is no longer useful should be deleted periodically to prevent it from being too large. Also note that wtmp and btmp are not created by the program that maintain them. Thus, if these files are removed, record-keeping is turned off.


Read Full Post »

Older Posts »