home
NEWS       BLOGS       FORUMS       NEWSLETTERS       RESEARCH       EVENTS       DIGITAL LIBRARY       CAREERS  
Network Computing Network Computing Powered by InformationWeek Business Technology Network

IMMERSE YOURSELF:

SOA

  |

Data Center

  |

802.11n

  |

Data Privacy

  |
APO  |

Virtualization

  |

NAC

  |

Security

  |

Network Mgmt

  |

Enterprise Apps

  |

Storage & Servers




Listing Directories and Closing Pipes

Providing a way to list just directories, closing off an unclosed pipe, the history of memory, and more

By Ray Swartz

Nadine Palmer asks for a way to list only the directories in the current directory. I provide a find command to solve her problem. Ricardo Pinninghoff can't figure out why his program hangs. The answer is an unclosed pipe. I also correct another problem he didn't know was there. Andy Young provides a brief history lesson about core memory. Neil Cook updates a previous feedback item about zombie processes. Allan Johnson Jr. corrects an error he found in an October 1993 item on generating random numbers.

Getting a Short List

Question: Is there some way to list just the directories in a directory?

Nadine Palmer / Knoxville, Tenn.

Answer: Listing out directories seems like something that would be handled by one of ls's options. However, there isn't one that lists just directories. The -d option tells this command to list a directory name instead of the files in that directory, if the argument is a directory. However, the command ls -d * lists both directory and non-directory files.

Though ls can't do the trick, the find command can. This command recognizes the -type d logical expression that is true only for directories. Also specify the -prune option to avoid descent into subdirectories. Reader B. G. Sudhakar suggested the ! -name "." construct, which makes sure the current directory does not get pruned. The resulting command line is shown in Listing 1.

The Pipes Are Frozen

Question: I'm writing a C++ class named file. I want it to be able to read the standard output of a command, such as:


open(file, "/bin/ls -l /dev |");

I wrote the code [Listing 2A] to implement this. It almost works. The problem is that it doesn't terminate. Can you help?

Ricardo Pinninghoff / Osorno, Chile

Answer: There are two errors with your program, both of them subtle. The first problem is the result of the fork() system call on line 8. After a fork operation, there are two virtually identical processes, meaning that every file that was opened before the fork is now held open by two processes. In your program, the open file is the pipe created in line 7.

As a result, the pipe is open for writing by two processes. A read() on a pipe (line 9) detects an end of file only if the writing end of the pipe has been closed by all the processes with write access to the pipe.

Thus, even though the child process closes the write end of the pipe when it exits, the parent process never closes fd[1], its write end of the pipe. The parent process doesn't terminate because the read() that controls the while loop in line 9 is waiting for something to read from the pipe whose write end is still open.

To get the parent to terminate, you need to close the write end of the pipe before you start reading from it with the call close(fd[1]) [Listing 2B, line 8a]. Now, only the child process has the pipe's write end open, and when the child exits, the parent will terminate too.

Another small error in this program gives some repeated output. In line 10, strlen(linea) is used to tell read() how many characters from the string linea to print. This step is required because read() doesn't put a \0 at the end of what it reads. Instead, read() returns the number of characters it read.

When the pipe is full of output, read() puts 132 characters (the result of sizeof(linea) in line 9) into linea without terminating linea. The write() call sends at least 132 characters to standard output (file descriptor 1). On my system, this arrangement worked fine; however, it is a bug waiting to hatch.

The error is evident on the last call to read(). The last call reads the tail end of what the child put in pipe. This amount is probably less than 132 characters. The write() command doesn't know this and prints the same number of characters it always has. In most cases, it will repeat some of the previous output. It did on my machine.

The solution is to store the number of characters that read() returns and to use that value to tell write() how many characters to print out of linea. In my version, I stored this number in the variable count [see Listing 2B, line 9].

The changes required to close the pipe's write end in the parent process and to correct the output error are shown in Listing 2B. I've only listed lines 3-11 because the changes are all within that range. The added lines are noted by a lower case ``a'' placed after the line number. Changed lines are marked with an asterisk.

Thanks for the Memory

Andy Young from San Diego had this comment about my September 1993 column on avoiding core files. He writes:

Sorry to ``dump'' on you, Ray, but you obviously weren't around when computers used real core memory. The cores were ferrite, but they went out of favor about the time disks came into wide-spread use. So there was no such thing as dumping core to disks. Alas, it got dumped to the line printer, which meant we had to wait about half an hour for a six-inch stack of paper to come chugging off at 120 lines per minute.

A lot of us learned to do octal arithmetic and annotate those core-dump listings with manual relocation of addresses to figure out what had gone wrong. But, if we only got one run per day, it was worth a couple hours of this drudgery to find the bug.

Rather than recompile the program and wait yet another day to run it, we would use a hand punch to fix the bad instruction. Or, if a hole had to be covered up, we'd cover them up with little red squares of sticky tape. However, the operators didn't like us to do that because the little red squares had a tendency to come off when the cards went through the card reader.

More About Zombies

Neil Cook of Nottingham, England, comments about Jon Hanrath's feedback about zombie processes. Neil writes:

In the July 1993 issue, Jon Hanrath suggests that another way to clear zombie processes is to explicitly ignore the child processes using SIG_IGN, which causes the child processes to die normally when they exit.

This solution only works under System V-flavored Unix, it is not the behavior seen with BSD Unix. The best way to stop zombies in BSD is to use the wait() system call. However, if more information is required on the defunct process, wait3() can be used. The wait3() call [Listing 3] can be used to achieve the same effect as a wait((int *)0). However, wait3() as used here can be used to overcome the unreliability of signals by freeing all children currently in a zombie state.

A Random Correction

Allan Johnson Jr. spotted an error in the October 1993 column about getting the Korn shell to supply random numbers to a program that printed random sayings from a file. He writes:

In your answer, ``A Random Comment,'' you showed how to generate a random number between 1 and 25,000 using the Korn shell's RANDOM variable. Unfortunately, you miscalculated. You show the calculation as let x=$RANDOM%25000. However, this specification delivers a number between 0 and 24,999. To get a number between 1 and 25,000, you have to add one to the number in your statement. The correct assignment is let x=$RANDOM%25000+1.

Note that this same approach will work outside the Korn shell. In the C shell on my system, I ran the command shown [in Listing 4]. It returns a different number after each invocation.

Print This Page


e-mail Send as e-mail





Ready to take that job and shove it?

Function:

Keyword(s):

State:
SPONSOR
RECENT JOB POSTINGS
CAREER NEWS
Go beyond Google and get vertical. These specialized search sites will help you find the business information you need -- fast.

Ari Balogh was named to the post of chief technology officer as the companys for a "realignment" of employees.










InformationWeek U.S. IT Salary Survey 2008
Salaries for business technology professionals are falling. Here's what you need to know in order to make good hiring decisions and personal career choices. Download Today
 
ROLLING RIGHT ALONG
Follow key Network Computing Reviews from conception to completion. This Week: Holistic APM.



Network Computing Reports Emerging Enterprise Podcast Series: Secrets to Success








TechSearch


Microsite of the Week


Powerful Information at Your Fingertips



InformationWeek Business Technology Network
InformationWeekInformationWeek 500InformationWeek 500 ConferenceInformationWeek AnalyticsInformationWeek CIO
InformationWeek EventsInformationWeek ReportsInformationWeek MagazinebMightyByte and SwitchDark Reading
Digital LibraryIntelligent EnterpriseInternet EvolutionNetwork ComputingNo JitterPlug Into The Cloud
space
Techweb Events Network
InteropVoiceConWeb 2.0 ExpoWeb 2.0 SummitEnterprise 2.0 ConferenceMobile Business ExpoSoftware ConferenceCSI - Computer Security Institute
Black HatGTECEnergy CampMashup CampStartup Camp
space
Light Reading Communications Network
Light ReadingLight Reading EuropeUnstrungLight Reading's Cable Digital NewsConstantinopleInternet EvolutionPyramid Research
Heavy ReadingLight Reading Live!Light Reading InsiderEthernet ExpoOptical ExpoTeleco TVTower Technology Summit
space
Financial Technology Network
Advanced TradingBank Systems & TechnologyInsurance & TechnologyWall Street & TechnologyAccelerating Wall StreetBank Systems & Technology Executive SummitBuyside Trading SummitInsurance & Technology Executive Summit
space
Microsoft Technology Network
MSDN MagazineTechNetThe Architecture Journal
space


App Infrastructure   |   Messaging & Collaboration   |   Network & Systems Mgmt   |   Network Infrastructure   |   Security  |   Storage & Servers   |   Wireless   |   Enterprise Apps
About Us  |  Contact Us  |  Site Map  |  Technology Marketing Solutions  |  Advertising Contacts  |   Briefing Centers
Copyright © 2008  United Business Media LLC  |  Privacy Statement  |  Terms of Service  |  Your California Privacy Rights