OS : Ubuntu 10.4
Target : Android Froyo
Creator : hojun baek
참조 : 02. 우분투 10.4 기반 안드로이드 빌드 환경 구축 및 소스 받기, 빌드

1. 안드로이드의 원활한 개발을 위해 Samba, SSH 를 설치 합니다.
sudo apt-get install samba
sudo apt-get install ssh
sudo /etc/init.d/ssh restart

2. 빌드를 위한 필요 패키지 설치

sudo apt-get install flex bison gperf libsdl-dev libesd0-dev libwxgtk2.6-dev build-essential zip curl

sudo apt-get install git-core gnupg gcc-multilib libx11-dev x11proto-core-dev

sudo apt-get install valgrind

저장소를 가져오기 위한 몇가지 패키지 설치
sudo apt-get install git-core gnupg

3. JAVA JDK 설치
* sun-java5-jdk를 찾지 못하였을 경우
sudo apt-get update 를 이용하여 리스트를 최신화시켜줌.

안드로이드 2.2 인 경우에는 반드시 1.5 버젼을 설치하셔야 하고,
안드로이드 2.1 인 경우에는 필요하신 버젼으로 설치하시면 됩니다.

/etc/apt/sources.list 에 다음 내용 추가
cd /
sudo vi /etc/apt/sources.list

deb http://kr.archive.ubuntu.com/ubuntu/ jaunty multiverse
deb http://kr.archive.ubuntu.com/ubuntu/ jaunty-updates multiverse

자바 1.5 : sudo apt-get install sun-java5-jdk
자바 1.6 : sudo apt-get install openjdk-6-jdk

설치가 완료된 후

java -version(버젼 확인)
ls -al /etc/alternatives/java

자바 1.5 : ls -s /usr/lib/jvm/java-1.5.0-sun/jre/bin/java /etc/alternatives/java
자바 1.6 : ls -s /usr/lib/jvm/java-1.6.0-openjdk/jre/bin/java /etc/alternatives/java

4.  환경변수 설정(.bashrc 또는 .profile)에 추가

sudo vi ~/.bashrc

맨 아래에 다음 두줄을 추가
export  JAVA_HOME=/usr/lib/jvm/java-1.5.0-sun  (/usr/lib/jvm  에  설치  된  자바  폴더의  이름을  적어주면 됩니다.)
export ANDROID_JAVA_HOME=$JAVA_HOME

source ~/.bashrc

5. 패키지 업데이트 & 업그레이드
sudo apt-get update
sudo apt-get upgrade

6. JAVA 우선순위 설정(자바 1.5 설치 시 또는 두 버전 모두 설치 시)

자바 1.5 : sudo update-java-alternatives -s java-1.5.0-sun
자바 1.6 : sudo update-java-alternatives -s java-1.6.0-openjdk

자바 버젂 바꾸는데 아래와 같은 에러 메시지가 발생한다면..

update-alternatives: error: no alternatives for firefox-javaplugin.so.
update-alternatives: error: no alternatives for iceape-javaplugin.so.
update-alternatives: error: no alternatives for iceweasel-javaplugin.so.
update-alternatives: error: no alternatives for jhat.
update-alternatives: error: no alternatives for jrunscript.
update-alternatives: error: no alternatives for midbrowser-javaplugin.so.
update-alternatives: error: no alternatives for mozilla-javaplugin.so.
update-alternatives: error: no alternatives for schemagen.
update-alternatives: error: no alternatives for wsgen.
update-alternatives: error: no alternatives for wsimport.
update-alternatives: error: no alternatives for xjc.
update-alternatives: error: no alternatives for xulrunner-1.9-javaplugin.so.
update-alternatives: error: no alternatives for xulrunner-javaplugin.so.
update-alternatives: error: no alternatives for firefox-javaplugin.so.
update-alternatives: error: no alternatives for iceape-javaplugin.so.
update-alternatives: error: no alternatives for iceweasel-javaplugin.so.
update-alternatives: error: no alternatives for midbrowser-javaplugin.so.
update-alternatives: error: no alternatives for mozilla-javaplugin.so.
update-alternatives: error: no alternatives for xulrunner-1.9-javaplugin.so.
update-alternatives: error: no alternatives for xulrunner-javaplugin.so.

sudo apt-get install sun-java5-plugin sun-java6-plugin

이는  자바  빌드와는  크게  상관은  없으나  위의  에러를  잡아주고  어플  실행의  호환성을  위한  플러그인을 설치하는 것입니다.

7. repo 다운로드

cd ~
mkdir bin
sudo gedit ~/.bashrc

마지막 줄에 다음 내용을 추가합니다.
export PATH=/home/사용자명/bin:$PATH;

source ~/.bashrc

cd ~/bin
curl http://android.git.kernel.org/repo > ~/bin/repo
chmod a+x ~/bin/repo

8. 소스 다운로드

cd ~

mkdir 폴더명

cd 폴더명

repo init -u git://android.git.kernel.org/platform/manifest.git -b froyo

이렇게 하면  froyo 소스를 다운 받게 됩니다.

repo init -u git://android.git.kernel.org/platform/manifest.git  만을 입력하는 경우는

가장 최신 소스를 다운 받게 되는 것입니다.
-b 옵션을 이용하여 원하는 소스를 다운 받으면 되는데
froyo 같은 이름을 확인 하시려면

http://android.git.kernel.org/?p=platform/manifest.git;a=summary 로 들어가시면 Heads 에서 확인 가능 합니다.

repo sync(실제로 소스를 다운 받는 명령어) – 약 1~2 시간 소요

9. 소스 빌드

source build/envsetup.sh

다운받은 안드로이드 소스에는 크로스 컴파일 환경까지 갖추어져 있습니다.
컴파일을 위해서는 envsetup.sh 파일이 환경변수에 등록 시켜주어야 하는데,
위의 명령어는 이를 위한 것입니다.
make (실제 빌드) – 약 2 시간 이상 소요~ 최소 2 시간

최초 빌드는 make 로 해주는 것이 제일 좋은 방법이고 안젂한 방법입니다.
그 이유는 먼저 컴파일 된 것을 참조하는 구문이 있을수도 있는데
그런 곳에서 오류가 나서 컴파일이 멈추어 버리는 현상이 나오기 때문입니다.
최초 빌드 이후에는 -j 옵션을 이용하여 스레드를 돌려주면 시갂을 약갂 줄여 빌드를 할 수 있습니다.

'Development > Linux' 카테고리의 다른 글

Ubuntu 10.04 JDK  (0) 2012.09.26
asoundrc asound.conf  (0) 2012.06.17
Gstreamer build  (0) 2011.07.28
NFS in ubuntu  (0) 2009.12.04
Upgrade distribution in ubuntu  (0) 2009.11.27
Posted by 까 치
,

Ubuntu 10.04 JDK

Development/Linux 2012. 9. 26. 21:35

Install sun-java6-jdk on Ubuntu 10.04 (Lucid)

 

Sometimes installing Java can be as if someone stabs you hundreds of pencils in the ass. I  had trouble to install the Sun Java6 JDK after updating to Ubuntu 10.04.

The problem was that the system couldn’t find the package sun-java6-sdk and apt-get gave me a bad message:

Package sun-java6-jdk is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source
E: Package sun-java6-jdk has no installation candidate

Note on current Debian versions:

SunSDK has been completely removed from the partner archives and the user should move to OpenJDK instead. See also the following links:

You should install OpenJDK instead

sudo apt-get install openjdk-6-jdk

If you still want to run the Sun version:

What I did to solve this problem was to add a new source

sudo add-apt-repository "deb http://archive.canonical.com/ lucid partner"

After that a normal

sudo apt-get update
sudo apt-get install sun-java6-jdk

it worked for me.

What you can also do (i did this on Debian Squeeze):

Adding non-free to the

deb http://ftp.debian.org/debian squeeze main contrib non-free

This worked for me for example in the newest Debian 6 (Squeeze) version.

Update 1:

Thanks for the comment of Mark Zhao. You can also update the /etc/apt/sources.list file and add/uncomment the following lines:

deb http://archive.canonical.com/ubuntu lucid partner
deb-src http://archive.canonical.com/ubuntu lucid partner
 

Update 2:

Thanks to the comment of Reinier, it seems that the Sun Java Packages have been removed from the canonical-archive.

 

 

Update 3:

Another tip from a comment by user lipin:

sudo add-apt-repository ppa:ferramroberto/java
sudo apt-get update
sudo apt-get install sun-java6-jdk
 
 

'Development > Linux' 카테고리의 다른 글

[Android] 우분트 10.4 기반 빌드/환경구축/소스/빌드[펌]  (0) 2012.09.26
asoundrc asound.conf  (0) 2012.06.17
Gstreamer build  (0) 2011.07.28
NFS in ubuntu  (0) 2009.12.04
Upgrade distribution in ubuntu  (0) 2009.11.27
Posted by 까 치
,

Why asoundrc?

What is it good for, why do I want one?

Neither the .asoundrc nor the asound.conf files are required for ALSA to work properly. Most applications will work without them. They are used to allow extra functionality, such as routing and sample-rate conversion, through the alsa-lib layer.

The .asoundrc file

This file allows the you to have more advanced control over your card/device. The .asoundrc file consists of definitions of the various cards available in your system. It also gives you access to the pcm plugins in alsa-lib. These allow you to do tricky things like combine your cards into one or access multiple i/o's on your mulitchannel card.

Where does asoundrc live?

The asoundrc file is typically installed in a user's home directory

	$HOME/.asoundrc

and is called from

	/usr/share/alsa/alsa.conf

It is also possible to install a system wide configuration file as

	/etc/asound.conf

When an alsa application starts both configuration files are read.

Below is the most basic definition.

The default plugin

Make a file called .asoundrc in your home and/or root directory.

        vi /home/xxx/.asoundrc

copy and paste the following into the file then save it.

        pcm.!default {
type hw
card 0
}

ctl.!default {
type hw
card 0
}

The keyword default is defined in the ALSA lib API and will always access hw:0,0 - the default device on the default soundcard. Specifying the !default name supercedes the one defined in the ALSA lib API.

Now you can test:

	aplay -D default test.wav

The naming of PCM devices

A typical asoundrc starts with a 'PCM hw type'. This gives an ALSA application the ability to start a virtual soundcard (plugin, or slave) by a given name. Without this, the soundcard(s)/devices(s) must be accessed with names like hw:0,0 or default. For example:

	aplay -D hw:0,0 test.wav

or with ecasound

	ecasound -i test.wav -o alsa,hw:0,0

The numbers after hw: stand for the soundcard number and device number. This can get confusing as some sound "cards" are better represented by calling them sound "devices", for example USB sounddevices. However they are still "cards" in the sense that they have a specific driver controlling a specific piece of hardware. They also correspond to the index shown in

	/proc/asound/cards

As with most arrays the first item usually starts at 0 not 1. This is true for the way pcm devices (physical i/o channels) are represented in ALSA. Starting at pcm0c (capture), pcm0p (playback).

We use subdevices mainly for hardware which can mix several streams together. It is impractical to have 32 devices with exactly the same capabilities. The subdevices can be opened without a specific address, so the first free subdevice is opened. Also, we temporarily use subdevices for hardware with alot of streams (I/O connectors) - for example MIDI. There are several limits given by used minor numbers (8 PCM devices per card, 8 MIDI devices per card etc.).

For example, to access the first device on the first soundcard/device, you would use

	hw:0,0

to access the first device on the second soundcard/device, you would use

	hw:1,0

to access the second device on the third soundcard/device, you would use

	hw:2,1

The Control device

The control device for a card is the way that programs modify various "controls" on the card. For many cards this includes the mixer, some cards, for example the rme9652, have no mixer. However, they do still have a number of other controls and some programs like JACK need to be able to access them. Examples include the digital i/o sync indicators, sample clock source switch and so on.

Aliases

With the 'PCM hw type' you are able to define aliases for your devices. The syntax for this definition is:

	pcm.NAME {
type hw # Kernel PCM
card INT/STR # Card name or number
[device] INT # Device number (default 0)
[subdevice] INT # Subdevice number, -1 first available (default -1)
mmap_emulation BOOL # enable mmap emulation for ro/wo devices
}

For example, this gives your first soundcard an alias:

	pcm.primary {
type hw
card 0
device 0
}

Now you can access this card by the alias 'primary'.

	aplay -D primary test.wav

Plugins

To see a full list of plugins visit the alsa-lib documentation which is generated daily from cvs.

Q: What are plugins?

A: In ALSA, PCM plugins extend functionality and features of PCM devices. The plugins deal automagically with jobs like naming devices, sample rate conversions, sample copying among channels, writing to a file, joining sound cards/devices for multiple inputs/outputs (not sample synced), using multi channel sound cards/devices and other possibilities left for you to explore. to make use of them you need to create a virtual slave device.

A very simple slave could be defined as follows:

	pcm_slave.sltest {
pcm
}

This defines a slave without any parameters. It's nothing more than another alias for your sound device. The slightly more complicated thing to understand is that parameters for 'pcm types' must be defined in the slave-definition-block. Let's setup a rate-converter which shows this behaviour.

	pcm_slave.sl2 {
pcm
rate 48000
}

pcm.rate_convert {
type rate
slave sl2
}

Now you can call this newly created virtual device by:

	aplay -D rate_convert test.wav

Which automatically converts your samples to a 44.1 kHz sample rate while playing. It's not very useful because most players and alsa converts samples to the right sample rate which your soundcard is capable of, but you can use it for a conversion to a lower static sample rate for example. A more complex tool for conversion is the pcm type plug. the syntax is:

  	type plug             	# Format adjusted PCM
slave STR # Slave name (see pcm_slave)
# or
slave { # Slave definition
pcm STR # Slave PCM name
# or
pcm { } # Slave PCM definition
[format STR] # Slave format (default nearest) or "unchanged"
[channels INT] # Slave channels (default nearest) or "unchanged"
[rate INT] # Slave rate (default nearest) or "unchanged"
}
route_policy STR # route policy for automatic ttable generation
# STR can be 'default', 'average', 'copy', 'duplicate'
# average: result is average of input channels
# copy: only first channels are copied to destination
# duplicate: duplicate first set of channels
# default: copy policy, except for mono capture - sum
ttable { # Transfer table (bidimensional compound of
# cchannels * schannels numbers)
CCHANNEL {
SCHANNEL REAL # route value (0.0 ... 1.0)
}
}

We can use it as follows:

	pcm_slave.sl3 {
pcm
format S16_LE
channels 1
rate 16000
}

pcm.complex_convert {
type plug
slave sl3
}

By calling it with:

	aplay -vD complex_convert test.wav

You will convert the sample during playing to the sample format: S16_LE, one channel and a sample rate of 16 kHz. As you called aplay with the verbose option -v you see this options as it appears as it comes from the original file. with:

	aplay -v test.wav

You see the original settings of the file.

Software mixing

Software mixing is the ability to play multiple sound files or applications at the same time through the same device. There are many ways to have software mixing in the Linux environment. Usually it requires a server application such as ARTSD, ESD, JACK... The list is large and the apps can often be confusing to use.

dmix

These days we have a native plugin for ALSA called the dmix (direct mixing) plugin. It allows software mixing in an easy to use syntax and without the hassle of installing/understanding a new application first.

A very interesting and potentially extremely useful aspect of this plugin is using it combined with the default plugin name. In theory this means all applications that have native ALSA support will share the sound device. In practice not many applications are able to take advantage of this functionality yet. However if you have time to test and report your findings to the application developers it is worth a try:

    pcm.!default {
type plug
slave.pcm "dmixer"
}


pcm.dmixer {
type dmix
ipc_key 1024
slave {
pcm "hw:1,0"
period_time 0
period_size 1024
buffer_size 4096
rate 44100
}
bindings {
0 0
1 1
}
}

ctl.dmixer {
type hw
card 0
}

(To use it with your own name just change the word !default above)

Now try:

	aplay -f cd -D default test.wav

on multiple consoles.

Some notes:

The dmix PCM name is already defined in the global configuration file /usr/share/alsa/alsa.conf.

- The default sample rate for this device is 48000Hz. If you would like to change it use:

 	aplay -D"plug:'dmix:RATE=44100'" test.wav

- An example command for dmix plugin to use 44100Hz sample-rate and hw:1,0 output device:

 	aplay -Dplug:'dmix:SLAVE="hw:1,0",RATE=44100' test.wav

- The dmix PCM name is already defined in the global configuration file /usr/share/alsa/alsa.conf.

Defaults are:

	SLAVE="hw:0,0",RATE=48000

NB the dmix plugin is not based on client/server architecture, but it writes directly to the soundcard's DMA buffer. There is no limit to the amount of instances that can be run at one time.

dsnoop

While the dmix plugin is for mixing multiple output(playback) streams together, if you want to use multiple input(capture) clients you need to use the dsnoop plugin:

    pcm.mixin {
type dsnoop
ipc_key 5978293 # must be unique for all dmix plugins!!!!
ipc_key_add_uid yes
slave {
pcm "hw:0,0"
channels 2
period_size 1024
buffer_size 4096
rate 44100
periods 0
period_time 0
}
bindings {
0 0
0 1
}
}

JACK plugin

This plugin allows the user to connect applications that support alsa natively to the JACK daemon.

To compile and install jack, you need to move to src/pcm/ext directory, and run "make jack" and "make install-jack". this is intentional.

To use the JACK plugin you will need to add the following to your .asoundrc.

	pcm.jackplug {
type plug
slave { pcm "jack" }
}

pcm.jack {
type jack
playback_ports {
0 alsa_pcm:playback_1
1 alsa_pcm:playback_2
}
capture_ports {
0 alsa_pcm:capture_1
1 alsa_pcm:capture_2
}
}

Now, you can use:

	aplay -Djackplug somefile
arecord -Djackplug somefile

Virtual multi channel devices

If you would like to link two or more ALSA devices together so that you have a virtual multi channel device it is possible. However this will not create the mythical "multi-channel soundcard out of el-cheapo consumer cards". The real devices will drift out of sync over time. It is sometimes helpful to make applications see for example, one 4 channel card to allow for flexible routing if they can't easily be made to talk to multiple cards (making use of JACK being one example).

Copy and paste the following into your asoundrc.

	# create a virtual four-channel device with two sound devices:
# This is in fact two interleaved stereo streams in
# different memory locations, so JACK will complain that it
# cannot get mmap-based access. see below.

pcm.multi {
type multi;
slaves.a.pcm "hw:0,0";
slaves.a.channels 2;
slaves.b.pcm "hw:1,0";
slaves.b.channels 2;
bindings.0.slave a;
bindings.0.channel 0;
bindings.1.slave a;
bindings.1.channel 1;
bindings.2.slave b;
bindings.2.channel 0;
bindings.3.slave b;
bindings.3.channel 1;
}

# JACK will be unhappy if there is no mixer to talk to, so we set
# this to card 0. This could be any device but 0 is easy.

ctl.multi {
type hw;
card 0;
}

# This creates a 4 channel interleaved pcm stream based on
# the multi device. JACK will work with this one.

pcm.ttable {
type route;
slave.pcm "multi";
ttable.0.0 1;
ttable.1.1 1;
ttable.2.2 1;
ttable.3.3 1;
}
# see above.
ctl.ttable {
type hw;
card 0;
}

This will give you xruns, but it's suitable for testing. To test the above setting feed an audio signal to the real sound devices play it back and listen to it with an external mixer:

	arecord -f S16_LE -r 44100 -c 4 -D multi | aplay -f S16_LE -r 44100 -c 4 -D multi

To start JACK with the new device, use

 	jackd [-a] -R [-v] -d alsa -d ttable [-p 1024]

Bindings explained

The above example for a virtual multi channel device uses bindings to make the connections work. The following is a more advanced asoundrc for 2 RME Hammerfalls which is a professional multichannel sound device. Below is a full explanation of how bindings work.

	# This is for two RME Hammerfall cards. They have been split into top row
# and bottom row with channels 0-7+16-25 on rme9652_0 and channels 8-15+26-27 on
# rme9652_1. NB. channels 24-27 are used as two stereo channels while the others are mono.

# eg. card1
# | 0 1 2 3 4 5 6 7 |
# | 8 9 10 11 12 13 14 15 24 25|
# card2
# | 16 17 18 19 20 21 22 23 24 25|




pcm_slave.rme9652_s {
pcm rme9652_0
}
pcm.rme9652_1 {
type hw
card 1
}
ctl.rme9652_1 {
type hw
card 1
}
pcm.rme9652_0 {
type hw
card 0
}
ctl.rme9652_0 {
type hw
card 0
}
ctl.rme9652_48 {
type hw
card 0
}
pcm.rme9652_48 {
type multi;
slaves.a.pcm rme9652_0;
slaves.a.channels 26;
slaves.b.pcm rme9652_1;
slaves.b.channels 26;
bindings.0.slave a;
bindings.0.channel 0;
bindings.1.slave a;
bindings.1.channel 1;
bindings.2.slave a;
bindings.2.channel 2;
bindings.3.slave a;
bindings.3.channel 3;
bindings.4.slave a;
bindings.4.channel 4;
bindings.5.slave a;
bindings.5.channel 5;
bindings.6.slave a;
bindings.6.channel 6;
bindings.7.slave a;
bindings.7.channel 7;
bindings.8.slave a;
bindings.8.channel 16;
bindings.9.slave a;
bindings.9.channel 17;
bindings.10.slave a;
bindings.10.channel 18;
bindings.11.slave a;
bindings.11.channel 19;
bindings.12.slave a;
bindings.12.channel 20;
bindings.13.slave a;
bindings.13.channel 21;
bindings.14.slave a;
bindings.14.channel 22;
bindings.15.slave a;
bindings.15.channel 23;

# Use rme9652_1

bindings.16.slave b;
bindings.16.channel 8;
bindings.17.slave b;
bindings.17.channel 9;
bindings.18.slave b;
bindings.18.channel 10;
bindings.19.slave b;
bindings.19.channel 11;
bindings.20.slave b;
bindings.20.channel 12;
bindings.21.slave b;
bindings.21.channel 13;
bindings.22.slave b;
bindings.22.channel 14;
bindings.23.slave b;
bindings.23.channel 15;

# stereo channels

bindings.24.slave a;
bindings.24.channel 24;
bindings.25.slave a;
bindings.25.channel 25;
bindings.26.slave b;
bindings.26.channel 24;
bindings.27.slave b;
bindings.27.channel 25;
}

What is happening?

There are two sound cards which are linked with a wordclock pipe. That allows them to keep sample sync with each other which is very important for multichannel work. If the sample rates are not in sync then your sounds become out of time with each other.

Each sound card has a number of physical channels 19 + 10. They are represented in /proc/asound/cardx as pcmXc (capture) and pcmXp (playback). Where X equals the number of the physical input/output (i/o) channels starting at 0.

If you look at the lines:

	type multi;
slaves.a.pcm rme9652_0;
slaves.a.channels 26;

You can see that the card has been nicknamed "a" and given a range of 26 channels. You can assign the card any number of channels you want but you can only use as many channels as the card has physically available. The bindings start at the first available pcm device for the card ie. pcm0c pcm0p - and move upwards sequentially from there.

The first card for this file has 18 physical pcm devices. Nine of them are capture devices ie. pcm0c pcm1c pcm2cpcm8c, each with corresponding playback channels ie. pcm0p pcm1p pcm2p ... pcm8p. The second card has 10 physical pcm devices ie. pcm0c pcm1c pcm2c ... pcm9c. ...

If you look at the lines:

    	bindings.0.slave a;
bindings.0.channel 0;
bindings.1.slave a;
bindings.1.channel 1;

The first binding points to the first available pcm device on the card represented as "a". The second binding points to the second available pcm device on "a" and so on up to the last one available. We then assign a channel number to the binding so that the channels on the new virtual "soundcard" we have created are easy for us to access.

Another way of saying it is:

   	address of.the first channel on my new soundcard.using my real soundcard called "a";
make this address of.the first channel on my new soundcard.be the first pcm device on my new soundcard;
   	address of.the second channel on my new soundcard.using my real soundcard called "a";
make this address of.the second channel on my real soundcard.be the second pcm device on my new soundcard;


Referenced applications

  • aRTsd - the aRTs sound server is the basis of desktop sound for KDE.
  • ESD - the Enlightened Sound Daemon mixes several audio streams for playback by a single audio device.
  • Ecasound - a commandline multitrack recorder and editor with various GUI apps.
  • JACK - Jack Audio Connection Kit. If you don't know this app you don't know JACK.

Notes:

  1. Example: Alternative .asoundrc and modules.conf files
  2. Tricks for getting the most out of the card.


'Development > Linux' 카테고리의 다른 글

[Android] 우분트 10.4 기반 빌드/환경구축/소스/빌드[펌]  (0) 2012.09.26
Ubuntu 10.04 JDK  (0) 2012.09.26
Gstreamer build  (0) 2011.07.28
NFS in ubuntu  (0) 2009.12.04
Upgrade distribution in ubuntu  (0) 2009.11.27
Posted by 까 치
,

Gstreamer build

Development/Linux 2011. 7. 28. 15:48
gnome-media - GNOME media utilities
gstreamer-tools - Tools for use with GStreamer
gstreamer0.10-alsa - GStreamer plugin for ALSA
gstreamer0.10-doc - GStreamer core documentation and manuals
gstreamer0.10-esd - GStreamer plugin for ESD
gstreamer0.10-gnomevfs - GStreamer plugin for GnomeVFS
gstreamer0.10-plugins-base - GStreamer plugins from the "base" set
gstreamer0.10-plugins-base-apps - GStreamer helper programs from the "base" set
gstreamer0.10-plugins-base-dbg - GStreamer plugins from the "base" set
gstreamer0.10-plugins-base-doc - GStreamer documentation for plugins from the "base" set
gstreamer0.10-plugins-good - GStreamer plugins from the "good" set
gstreamer0.10-plugins-good-dbg - GStreamer plugins from the "good" set
gstreamer0.10-plugins-good-doc - GStreamer documentation for plugins from the "good" set
gstreamer0.10-tools - Tools for use with GStreamer
gstreamer0.10-x - GStreamer plugins for X11 and Pango
juk - music organizer and player for KDE
libgstreamer-plugins-base0.10-0 - GStreamer libraries from the "base" set
libgstreamer-plugins-base0.10-dev - GStreamer development files for libraries from the "base" set
libgstreamer-plugins-pulse0.10-0 - PulseAudio plugin for GStreamer
libgstreamer0.10-0 - Core GStreamer libraries and elements
libgstreamer0.10-0-dbg - Core GStreamer libraries and elements
libgstreamer0.10-dev - GStreamer core development files
python-gst0.10 - generic media-playing framework (Python bindings)
python-gst0.10-dbg - generic media-playing framework (Python debug bindings)
serpentine - An application for creating audio CDs
totem-gstreamer - A simple media player for the Gnome desktop based on gstreamer
totem-mozilla - Totem Mozilla plugin
farsight0.1-rtp - plugin providing RTP support for farsight
geekast - GNOME interface to peercast
geekast-binary - GNOME interface to peercast - binaries
goobox - CD player and ripper for GNOME
gstreamer-editor - GStreamer Pipeline Editor and other GUI tools
gstreamer0.10-ffmpeg - FFmpeg plugin for GStreamer
gstreamer0.10-fluendo-mp3 - Fluendo mp3 decoder GStreamer plugin
gstreamer0.10-fluendo-mpegdemux - Fluendo GStreamer plugin for MPEG2 demuxing
gstreamer0.10-gl - GStreamer plugin for OpenGL output
gstreamer0.10-gnonlin - non-linear editing module for GStreamer
gstreamer0.10-gnonlin-dev - development files of the non-linear editing module for GStreamer
gstreamer0.10-pitfdll - GStreamer plugin for using MS Windows binary codecs
gstreamer0.10-plugins-bad - GStreamer plugins from the "bad" set
gstreamer0.10-plugins-bad-dbg - GStreamer plugins from the "bad" set
gstreamer0.10-plugins-bad-doc - GStreamer documentation for plugins from the "bad" set
gstreamer0.10-plugins-farsight - Gstreamer plugins for audio/video conferencing
gstreamer0.10-plugins-ugly - GStreamer plugins from the "ugly" set
gstreamer0.10-plugins-ugly-dbg - GStreamer plugins from the "ugly" set
gstreamer0.10-plugins-ugly-doc - GStreamer documentation for plugins from the "ugly" set
gstreamer0.10-sdl - GStreamer plugin for SDL output
gstreamer0.8-a52dec - ATSC A/52 audio decoder plugin for GStreamer
gstreamer0.8-aa - AA-lib plugin for GStreamer
gstreamer0.8-alsa - ALSA plugin for GStreamer
gstreamer0.8-artsd - aRtsd plugin for GStreamer
gstreamer0.8-audiofile - AudioFile plugin for GStreamer
gstreamer0.8-caca - Colour AsCii Art library plugin for GStreamer
gstreamer0.8-cdio - low-level CD-ROM reading and control plugin for GStreamer
gstreamer0.8-cdparanoia - cdparanoia plugin for GStreamer
gstreamer0.8-doc - GStreamer documentation
gstreamer0.8-dv - DV plugin for GStreamer
gstreamer0.8-dvd - DVD plugin for GStreamer
gstreamer0.8-esd - Enlightened Sound Daemon plugin for GStreamer
gstreamer0.8-festival - Festival speech synthesis plugin for GStreamer
gstreamer0.8-ffmpeg - FFmpeg plugin for GStreamer
gstreamer0.8-flac - FLAC plugin for GStreamer
gstreamer0.8-gnomevfs - Gnome VFS plugin for GStreamer
gstreamer0.8-gsm - GSM plugin for GStreamer
gstreamer0.8-gtk - Gtk/Gdk plugin for GStreamer
gstreamer0.8-hermes - colorspace conversion plugin for GStreamer based on hermes
gstreamer0.8-jpeg - JPEG plugin for GStreamer
gstreamer0.8-mad - MAD MPEG audio decoder plugin for GStreamer
gstreamer0.8-mikmod - MikMod decoder plugin for GStreamer
gstreamer0.8-misc - Collection of various GStreamer plugins
gstreamer0.8-mms - mms plugin for GStreamer
gstreamer0.8-mpeg2dec - MPEG1 and MPEG2 video decoder plugin for GStreamer
gstreamer0.8-musepack - Musepack (MPC) audio decoder plugin for GStreamer
gstreamer0.8-oss - OSS plugin for GStreamer
gstreamer0.8-plugin-apps - Simple GStreamer applications
gstreamer0.8-plugins - All GStreamer plugins
gstreamer0.8-sdl - SDL videosink plugin for GStreamer
gstreamer0.8-sid - C64 SID decoder plugin for GStreamer
gstreamer0.8-speex - Speex plugin for GStreamer
gstreamer0.8-swfdec - SWF (Macromedia Flash) decoder plugin for GStreamer
gstreamer0.8-theora - Theora plugin for GStreamer
gstreamer0.8-tools - Tools for use with GStreamer
gstreamer0.8-vorbis - Vorbis plugin for GStreamer
gstreamer0.8-x - X videosink plugin for GStreamer
libfarsight0.1-1 - audio/video stream library
libfarsight0.1-dbg - audio/video stream library: debugging support
libfarsight0.1-dev - audio/video stream library: development files
libfarsight0.1-doc - audio/video stream library: documentation
libglib-cil - CLI binding for the GLib utility library
libgstreamer-gconf0.8-0 - GConf support for GStreamer
libgstreamer-gconf0.8-dev - Development files for GConf support for GStreamer
libgstreamer-perl - Perl interface to the gstreamer media processing framework
libgstreamer-plugins0.8-0 - Various GStreamer libraries and library plugins
libgstreamer-plugins0.8-dev - Development files for various GStreamer library and library plugins
libgstreamer0.10-ruby1.8 - GStreamer 0.10 bindings for the Ruby language
libgstreamer0.8-0 - Core GStreamer libraries, plugins, and utilities
libgstreamer0.8-dev - GStreamer development libraries and headers
libgstreamer0.8-ruby - GStreamer 0.8 bindings for the Ruby language
libgtksourceview1-ruby - GTKSourceView bindings for the Ruby language
peercast-geekast - GNOME interface to peercast - peercast-servent data files
pitivi - non-linear audio/video editor using GStreamer
python-gst - generic media-playing framework (Python bindings)
soundconverter - convert sound files to other formats
swf-player - Mozilla plugin for SWF files (Macromedia Flash)
tap-plugins - Tom's Audio Processing LADSPA plugins
telepathy-stream-engine - stream handler for the Telepathy framework
thoggen - DVD backup utility based on GStreamer and Gtk+
gstreamer0.10-plugins-bad-multiverse - GStreamer plugins from the "bad" set (Multiverse Variant)
gstreamer0.10-plugins-bad-multiverse-dbg - GStreamer plugins from the "bad" set (Multiverse Variant)
gstreamer0.10-plugins-ugly-multiverse - GStreamer plugins from the "ugly" set (Multiverse Variant)
gstreamer0.10-plugins-ugly-multiverse-dbg - GStreamer plugins from the "ugly" set (Multiverse Variant)
gstreamer0.8-dirac - Dirac decoder plugin for GStreamer
gstreamer0.8-faac - AAC encodingplugin for GStreamer
gstreamer0.8-faad - AAC decoding plugin for GStreamer
gstreamer0.8-lame - LAME encoder plugin for GStreamer
gstreamer0.8-pitfdll - DLL/QTX loader plugin for GStreamer
gstreamer0.8-plugins-multiverse - All Multiverse GStreamer plugins
gstreamer0.8-xvid - XVID encoder plugin for GStreamer
app-install-data - GNOME Application Installer (data files)
gnome-app-install - GNOME Application Installer
openoffice.org - OpenOffice.org Office suite
pulseaudio - PulseAudio sound server

* 까치님에 의해서 게시물 이동되었습니다 (2007-11-29 11:19)

'Development > Linux' 카테고리의 다른 글

Ubuntu 10.04 JDK  (0) 2012.09.26
asoundrc asound.conf  (0) 2012.06.17
NFS in ubuntu  (0) 2009.12.04
Upgrade distribution in ubuntu  (0) 2009.11.27
Upgrade Ubuntu  (0) 2009.11.27
Posted by 까 치
,

NFS in ubuntu

Development/Linux 2009. 12. 4. 12:20
Refer to this website
http://ubuntuforums.org/showthread.php?t=249889

Why NFS?

I simply wanted to experiment with NFS, and couldn't seem to find the documentation here on the forums. I found using NFS just as easy if not easier than using Samba for sharing between a few of my Unix based systems. In order to share a folder it only required a single line in a configuration file under /etc/exports, and a single line under /etc/fstab on the client to mount the share on each client at boot.

I mostly edited and moved things around from these guides to make a more complete single guide to getting this working using Ubuntu.

http://www.cyberciti.biz/tips/ubuntu...nfs-share.html (for client configuration)
http://www.redhat.com/docs/manuals/l...nfs-mount.html (for mounting using fstab)
http://czarism.com/easy-peasy-ubuntu...s-file-sharing (for server configuration)
http://www.freebsd.org/doc/en_US.ISO...twork-nfs.html (contains more info about NFS)

Install NFS Server Support
at the terminal type

sudo apt-get install nfs-kernel-server nfs-common portmap
When configuring portmap do =not= bind loopback. If you do you can either edit /etc/default/portmap by hand or run:

sudo dpkg-reconfigure portmap
sudo /etc/init.d/portmap restart


Editing /etc/exports
the /etc/exports file is used for creating a share on the NFS server

invoke your favorite text editor or

sudo vi /etc/exports



Here are some quick examples of what you could add to your /etc/exports

For Full Read Write Permissions allowing any computer from 192.168.1.1 through 192.168.1.255
  • /files 192.168.1.1/24(rw,no_root_squash,async)

Or for Read Only from a single machine
  • /files 192.168.1.2 (ro,async)
save this file and then in a terminal type
sudo /etc/init.d/nfs-kernel-server restart



Also aftter making changes to /etc/exports in a terminal you must type
sudo exportfs -a


Install NFS client support
sudo apt-get install portmap nfs-common


Mounting manually
Example to mount server.mydomain.com:/files to /files. In this example server.mydomain.com is the name of the server containing the nfs share, and files is the name of the share on the nfs server

The mount point /files must first exist on the client machine.
cd /
sudo mkdir files

to mount the share from a terminal type

sudo mount server.mydomain.com:/files /files

Note you may need to restart above services:
sudo /etc/init.d/portmap restart
sudo /etc/init.d/nfs-common restart


Mounting at boot using /etc/fstab
Invoke the text editor using your favorite editor, or
gksudo gedit /etc/fstab

In this example my /etc/fstab was like this:
  • server.mydomain.com:/files /files nfs rsize=8192,wsize=8192,timeo=14,intr
You could copy and paste my line, and change “servername.mydomain.com:/files”, and “/files” to match your server name:share name, and the name of the mount point you created.
It is a good idea to test this before a reboot in case a mistake was made.

type
mount /files
in a terminal, and the mount point /files will be mounted from the server.


[example]
mount -t nfs XXX.XXX.XXX.xxx:/scratchbox/users/root/home/root/magpie_xxx /scratchbox/users/root/home/root/views -o nolock,tcp

Posted by 까 치
,
Error occurred "Could not find the release notes"
This case is for 7.10 to 7.04
sudo sed -i 's/feisty/gutsy/' /etc/apt/sources.list
sudo apt-get update
sudo apt-get dist-upgrade

Refer to the distribute release version name on below
http://www.ubuntu.com/getubuntu/upgrading
Posted by 까 치
,

Upgrade Ubuntu

Development/Linux 2009. 11. 27. 13:20

1 Desktop

Go to System > Administration > Software Sources:

Type in your password:

In the Software Sources window, go to the Updates tab and select Normal releases in the Show new distribution releases drop-down menu; then close the Software Sources window:

Now start the Update Manager (System > Administration > Update Manager):

The Update Manager should show that a new distribution release (8.10) is available. Click on the Upgrade button to start the distribution upgrade:

A window with the release notes for 8.10 comes up. Click on Upgrade again:

');

The upgrade is being prepared:

Click on Start Upgrade to finally begin with the upgrade process:

Replace /etc/update-manager/release-upgrades:

At the end of the upgrade process, you should remove obsolete packages:

The system needs to be rebooted to complete the upgrade, therefore click on Restart Now:

After the reboot, you can use your new Ubuntu 8.10 desktop:

 

2 Server

First become root:

sudo su

Then run

apt-get update

and install the package update-manager-core:

apt-get install update-manager-core

Open the file /etc/update-manager/release-upgrades...

vi /etc/update-manager/release-upgrades

... and change Prompt=lts to Prompt=normal:

[...]
Prompt=normal

Then run

do-release-upgrade

to start the distribution upgrade.

Confirm that you want to do the upgrade:

Do you want to start the upgrade?


2 packages are going to be removed. 48 new packages are going to be
installed. 376 packages are going to be upgraded.

You have to download a total of 242M. This download will take about 6
minutes with your connection.

Fetching and installing the upgrade can take several hours. Once the
download has finished, the process cannot be cancelled.

 Continue [yN]  Details [d]
 <-- y

At the end of the upgrade process, you should remove obsolete packages:

Remove obsolete packages?


21 packages are going to be removed.

 Continue [yN]  Details [d]
 <-- y

The server needs to be rebooted to complete the upgrade:

System upgrade is complete.

Restart required

To finish the upgrade, a restart is required.
If you select 'y' the system will be restarted.

Continue [yN] <-- y

After the reboot, your server is running Ubuntu 8.10.

Posted by 까 치
,

Error occurred on below ...

W: GPG error: http://dl.google.com testing Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY XXXXXXXXXX

Resolve on below ...

gpg --keyserver keyserver.ubuntu.com --recv XXXXXXXXX

gpg --export --armor XXXXXXXXX | sudo apt-key add -

sudo apt-get update


DONE

Posted by 까 치
,

sigaction

Development/Linux 2009. 8. 1. 15:35

1장. sigaction(2)

차례
1.1. 사용법
1.2. 설명
1.3. 반환값
1.4. 에러
1.5. 예제
1.6. 참고문헌

시그널 처리관련 함수


1.1. 사용법

#include <signal.h>
int sigaction(int signum,  const  struct  sigaction  *act,
	struct sigaction *oldact);
int  sigprocmask(int  how,  const  sigset_t *set, sigset_t *oldset);
int sigpending(sigset_t *set);
int sigsuspend(const sigset_t *mask);
		


1.2. 설명

sigaction() 시스템 호출은 특정 시그널의 수신에 대해서 취할 액션을 설정하거나 변경하기 위해서 사용된다.

signum는 시그널을 명시한다. SIGKILLSIGSTOP를 제외한 모든 시그널이 타당한 시그널이 될 수 있다.

만약 actnull이 아니라면 signum번호를 가지는 시그널에 대해서 act함수가 설치된다. 만약 oldact가 null이 아니라면 이전의 액션은 oldact에 저장된다.

sigaction구조체는 다음과 같이 정의되어 있다.

struct sigaction 
{
    void (*sa_handler)(int);
    void (*sa_sigaction)(int, siginfo_t *, void *);
    sigset_t sa_mask;
    int sa_flags;
    void (*sa_restorer)(void);
}
		

sa_handler

signum번호를 가지는 시그널이 발생했을 때 실행된 함수를 설치한다. 함수외에도 SIG_DFL과 SIG_IGN을 지정할 수 있다. 전자는 시그널에 대한 기본행동을 후자는 시그널을 무시하기 위해서 사용한다.

sa_mask

sa_handler에 등록된 시그널 핸들러 함수가 실행되는 동안 블럭되어야 하는 시그널의 마스크를 제공한다. SA_NOMASK가 적용되어 있지 않다면

sa_flags

시그널 처리 프로세스의 행위를 수정하는 일련의 플래그들을 명시한다. 다음중 하나 이상의 것들에 의해서 만들어 진다.

SA_NOCLDSTOP

만약 signum이 SIGCHLD라면, 자식 프로세스가 SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU등을 받아서 중단되었을 때 이를 통지 받을 수 없게 된다.

SA_ONESHOT, SA_RESETHAND

일단 시그널 처리기가 호출되면, 기본 상태에 대한 시그널 액션을 재 저장한다. 이는 signal(2)호출에 대한 기본 행위이다.

SA_RESTART

일부 시스템 호출들이 시그널을 통해 재시작할 수 있도록 함으로서 BSD 시그널과 호환되도록 한다.

SA_NOMASK, SA_NODEFER

시그널이 자체 시그널 처리기로부터 수신 받지 않도록 한다.

SA_SIGINFO

시그널 처리기가 하나가 아닌 3개의 인자를 취할경우 sa_handler대신 sigaction의 siginfo_t를 이용할 수 있다. siginto_t는 다음과 같이 정의된 구조체이다.

siginfo_t {
    int      si_signo;  /* 시그널 넘버 */
    int      si_errno;  /* errno 값 */
    int      si_code;   /* 시그널 코드 */
    pid_t    si_pid;    /* 프로세스 ID 보내기 */
    uid_t    si_uid;    /* 프로세스를 전송하는 실제 사용자 ID */
    int      si_status; /* Exit 값 또는 시그널 */
    clock_t  si_utime;  /* 소모된 사용자 시간 */
    clock_t  si_stime;  /* 소모된 시스템 시간 */
    sigval_t si_value;  /* 시그널 값 */
    int      si_int;    /* POSIX.1b 시그널 */
    void *   si_ptr;    /* POSIX.1b 시그널 */
    void *   si_addr;   /* 실패를 초래한 메모리 위치 */
    int      si_band;   /* 밴드 이벤트 */
    int      si_fd;     /* 파일 기술자 */
}
						
SIGCHLD 시그널은 si_pid, si_uid, si_status, si_utime, si_stime를 채운다. si_int, si_ptr은 시그널의 송신자에 의해서 명시될 수 있다.

si_code는 왜 시그널이 보내졌는지를 지시한다.

sigprocmask()는 현재 블록된 시그널들을 변경시키기 위해서 사용한다. 호출의 행위는 how 값들에 대해서 의존적이 된다. how는 다음중 하나를 선택할 수 있다.

SIG_BLOCK

set에 설정된 시그널을 블럭 시그널셋에 추가시킨다.

SIG_UNBLOCK

시그널 셋set의 시그널을 현재의 블럭된 시그널에서 삭제한다.

SIG_SETMASK

시그널 셋set의 시그널을 블럭화된 시그널로 지정한다.

oldset이 null이 아니면, 시그널 마스크의 이전 값은 oldset에 저장된다.

sigpending()함수는 전달 시그널들에 대한 검사를 허용한다. 전달 시그널들의 마스크는 set에 저장된다.

sigsuspend()는 프로세스의 시그널 마스크를 일시적으로 mask로 대체하고, 시그널이 수신될때까지 프로세스를 중지시킨다.


1.3. 반환값

성공하면 0을 실패하면 -1을 리턴한다.


1.4. 에러

EINVAL

부적절한 시그널이 지정되거나. 무시할 수 없는 SIGKILL SIGSTOP에 대한 액션을 변경하고자 할 경우

EFAULT

act, oldact, set, oldset 이 타당하지 않은 메모리 영역을 가리킬 경우

EINTR

시스템 호출이 인터럽트 되었다.


1.5. 예제

#include <signal.h> 
#include <unistd.h> 
#include <string.h> 
#include <stdio.h> 

void sig_int(int signo);
void sig_usr(int signo);

int main()
{
    int i = 0;
    struct sigaction intsig, usrsig;

    usrsig.sa_handler = sig_usr;
    sigemptyset(&usrsig.sa_mask);
    usrsig.sa_flags = 0;

    intsig.sa_handler = sig_int;
    sigemptyset(&intsig.sa_mask);
    intsig.sa_flags = 0;

	// SIGINT에 대해서 sig_int를 등록한다. 
    if (sigaction(SIGINT, &intsig, 0) == -1)
    {
        printf ("signal(SIGINT) error");
        return -1;
    }    

	// SIGUSR2에 대해서 usrsig를 등록한다. 
    if (sigaction(SIGUSR2, &usrsig, 0) == -1)
    {
        printf ("signal(SIGUSR2) error");
        return -1;
    }    

    while(1)
    {
        printf("%dn", i);
        i++;
        sleep(1);
    }
}

void sig_int(int signo)
{
    sigset_t sigset, oldset;

	// 핸들러가 수행되는 동안 수신되는 모든 시그널에 대해서
	// 블럭한다.  
    sigfillset(&sigset);
    if (sigprocmask(SIG_BLOCK, &sigset, &oldset) < 0)
    {
        printf("sigprocmask %d error n", signo);
    }
    fprintf(stderr, "SIGINT !!!!n");
    sleep(5);
}

void sig_usr(int signo)
{
    printf("sig_usr2n");
}
		

Posted by 까 치
,

Linux daemon

Development/Linux 2009. 7. 6. 21:19
아래 글은 Nick lib 의 푸우님께서 작성해주신 글입니다.
문제시 삭제 조치하겠습니다.
Ref  http://www.nicklib.com/bbs/board.php?bo_table=bbs_column&wr_id=9


요즘 통 글을 안 올렸네요.
요즘 회사일로 정신이 없네요.
죄송하구요. ^^; 
아무튼 이번에는 UNIX/LINUX의 Deamon 프로세스 만드는 것에 대해 정리해 보도록 하겠습니다.
 
1. Daemon이란?
 
뭐 이글을 관심이 있어서 읽고 계시는 분 중에 Daemon이 뭔지를 모르시는 분은 없겠지만...
그래도 한번 정리해 봅니다.
Daemon의 뜻 자체는 "악마", "악령", "귀신"과 같이 좀 무시무시 합니다.
하지만 Daemon의 어원은 신화에서 신과 인간사이의 초자연적인 영적존재로서의 수호신에서 나왔다고 합니다. 뭐 좋은쪽으로 생각하죠.
컴퓨터 상에서 Daemon은 겉으로는 보이지 않지만 항상 뒤에서 뭔가를 계속해서 수행해 주는 프로그램을 말합니다. 예로 httpd, ftpd, telnetd 등...
이런면에서 왜 Daemon이라는 이름 지었는지 이해가 가네요.
윈도우즈에서는 Daemon이라는 용어가 마음에 들지 않았는지 아니면 뭔가 꼭 튀게 해야한다고 생각했는지 몰라도... UNIX/LINUX의 Daemon과 같은 역할을 하는 프로그램을 Service 라고 합니다.
"데몬"은 이름에 뭔가 철학을 담아 지은것 같은데... "서비스"... 참 단순해서 좋긴 좋네요. ㅋㅋ  ^^;
 
Daemon 프로그램이 되려면 몇가지 특징을 갖추어야 하지만 가장 중요한 것은 "OS가 부팅되면 사용자의 개입없이 실행될 수 있을 것"입니다.
이 말은 다시 말해 누군가가 로그인을 하여 굳이 실행하지 않아도 OS의 init프로세스에 의해 실행될 수 있어야 한다는 이야기 이고 이럴려면 프로그램을 제어하는 터미널(tty)를 갖지 말아야 한다는 것 입니다. 반대로 말하면 누군가 로그인 해서 데몬을 시작시켰다면 로그아웃할 때 해당 데몬은 계속해서 살아 있어야 한다는 말도 됩니다.
 
이제 이러한 특징을 갖는 프로그램을 만드는 방법을 단계별로 알아보도록 하죠.
 
 
2. 로그 아웃시 프로그램 종료되지 않게 하기
 
우선 데몬은 아니더라도 데몬과 비슷하게 수행하면 계속해서 작업을 수행 할 수 있도록 하는 방법에 대해서 알아 보겠습니다.
 
기본 소스는 다음과 같습니다.
 
#include <stdio.h>

int work()
{
        FILE *fp;
        unsigned long count=0;

        fp=fopen("/tmp/daemon.out""wt");
        if(fp==NULL) {
                printf("File Open Errorn");
                return -1;
        }

        while(1){
                sleep(1);
                fprintf(fp, "%lun", count);
                fflush(fp);
                fprintf(stdout, "%lun", count++);
        }
        fclose(fp);

        return 0;
}

int main(int argc, char *argv[])
{
        work();

        return 0;
}
 
 
위의 프로그램은 간단하니깐 보시면 아시겠지만 main()함수가 수행되면 work()라는 함수를 수행하게 됩니다.
work()함수는 무한루프를 돌면서 1초마다 "/tmp/daemon.out"파일에 카운팅을 기록합니다.
또 표준출력으로도 같은 값을 출력하는 프로그램입니다.
위의 소스를 컴파일하여 daemon이라는 실행파일을 생성했다고 하고 다음의 글들을 작성토록 하겠습니다.
 
자 그럼 로그아웃이 될때 어떤 현상이 일어날지에 대해 한번 알아보도록 하죠.
 
로그아웃하거나 해당 터미널이 끊기게 되면 OS 해당 터미널을 제어단말로 사용하던 모든 프로그램에게 특별한 신호를 보내게 됩니다.
이 신호가 SIGHUP, 즉, Hangup 시그널입니다.
일반적인 프로그램은 이 Hangup 시그널을 받으면 정상종료를 하게 됩니다.
뭐 프로세스가 알아서 정상종료 한다기 보다는 이 시그널을 어떻게 처리하라는 루틴을 구현하지 않은 프로세스는 조용히 OS가 죽이는 것이죠.
 
OS에 SIGHUP을 무시하게 해주는 'nohup'이라는 쉘명령어가 있습니다.
일반적인 사용방법은 다음과 같습니다.
 
#nohup daemon&
 
위의 명령어 중 daemon은 데몬 프로그램의 이름이고 마지막 &는 이 글의 주제와는 상관없지만 백그라운드로 실행해서 프롬프트를 다시 얻기 위함입니다.
이렇게 daemon을 실행한 뒤 로그아웃하거나 단말기를 끊고 다시 접속한 다음 "ps -ef | grep daemon" 명령을 통해 보시면 daemon이 살아 있음을 보실 수 있으실 것 입니다.
또한 "tail -f /tmp/daemon.out" 해서 보시면 살아 있을 뿐 더러 원래의 기능도 정상적으로 수행 하고 있음을 알 수 있습니다.
 
그런데 여기서 원래 daemon은 파일 뿐만 아니라 화면에도 카운팅 번호를 출력하도록 되어 있었는데 위의 명령의 수행 후에는 아래와 같은 메시지만 남기고 나타나지 않습니다.
 
appending output to `nohup.out'
 
이는 nohup 명령어가 daemon의 표준 출력을 현재 경로의 'nohup.out'이라는 파일로 리다이렉트 시켰기 때문입니다.
 
어찌되었건 쉘에서 제공하는 명령어를 통해 데몬과 유사한 기능을 하도록 해 보았네요. 
 
자 이번에는 'nohup'과 같은 기능을 시스템 함수로 구현해 보도록 하겠습니다.
 
골자는 프로그램 내에서 SIGHUP시그널을 무시할 수 있도록 코딩하는 것입니다.
 
 위 함수에 #include <signal.h> 를 포함하고 main함수를 다음과 같이 고칩니다.
 
 
int main(int argc, char *argv[])
{
        signal(SIGHUP, SIG_IGN);

        work();

        return 0;
}
 
 
지금 부터는 work()함수의 표준 출력이 귀찮아 지므로 표준 출력으로 내보는 문장은 적절히 삭제하셔도 좋습니다.  
위의 main()함수는 signal()함수를 통해 SIGHUP시그널을 무시하도록 설정 한 뒤 work()함수를 수행한 것입니다.
 
컴파일 후 테스트는 여러분의 몫으로 하구요.
 
SIGHUP을 무시하는 방법은 아니지만 또 다른 방법이 있는데 이는 프로세스 내에서 자신의 그룹아이디를 바꾸는 것입니다.
 
이는 로그 아웃시 현재 터미널을 제어 단말기로 하고 있는 프로세스에 OS가 SIGHUP시그널을 보낼 때 쉘프로세스의 아이디를 그룹아이디로 갖는 모든 프로세스에게 보낸다는 것에 착안한 것입니다.
 
즉, 프로그램은 특정 쉘프로세스에서 수행되기 때문에 일반적으로 프로세스 그룹아이디는 수행 환경이 되었던 쉘프로세스 아이디를 갖게 되는데 이를 프로세스 내에게 바꾸는 것입니다. 
 
int main(int argc, char *argv[])
{
        int newpgid;

        newpgid = setpgrp();

        work();

        return 0;
}
 
위의 소스에 보이는 setpgrp()함수는 자신의 프로세스 그룹을 자신의 프로세스아이디로 바꿔줍니다.
이렇게 하면 로그아웃시 이 프로세스는 아예 SIGHUP시그널을 받지도 않으므로 종료되지 않습니다.
 
자 여기까지는 데몬 프로그램을 만드는 법이라기 보다는 일반적으로 프로세스에서 일어나는 일과 이들을 처리하는 방법, 그리고 간단히 데몬과 유사한 효과 내기라고 생각하시면 될 듯 싶습니다.
 
 
3. fork에 의한 Daemon만들기
 
 
위에서 이야기 한 방법들도 뭐 잘못된 방법들은 아니지만 일반적으로는 이제부터 이야기 하는 방법으로 주로 데몬을 만듭니다.
main()함수를 다음과 같이 바꾸세요.
 
int main(int argc, char *argv[])
{
        int pid;

        pid=fork();
        switch(pid){
        case -1:
                fprintf(stderr, "Fork Errorn");
                break;
        case 0:         // child
                break;
        default:        // parent
                return 0;
        }

        work();

        return 0;
}
 
위의 main()함수는 프로그램이 시작되자 마자 fork()를 수행해서 자식프로세스는 work()함수를 수행하고 부모프로세스는 종료하게 합니다.
그러면 사실 자식프로세스는 아직 살아 있는데 부모프로세스가 터미널과 연결되어 있었는데 사라지게 됩니다. 고로 자식 프로세스는 제어단말기를 가지지 않게 되고 부모가 없으므로 고아프로세스가 되었네요.
이렇게 고아프로세스가 발생하면 OS는 이 고아 프로세스를 init프로세스의 자식으로 만들어 줍니다.
부모,자식,고아를 이야기 했으니 입양이라고 해야 할까요? ㅋㅋㅋ
하지만 원래 init프로세스는 1번 프로세스로서 조상 프로세스에 해당됨으로 입양이라고 하기는 좀 그렇네요.
 
아무튼 위의 프로그램은 아무 문제가 없습니다. 좀비가 발생하지도 않구요.
 
하지만 이런 케이스를 생각해 보죠.
daemon도 프로세스이므로 현재 작업디렉토리를 갖습니다.
그래서 이 daemon이 실행된 후 daemon을 실행 시켰던 디렉토리가 속한 파일시스템을 "umount" 시키려 한다면 OS는 해당 파일시스템이 사용되고 있다고 umount 하지 못한다고 할 것 입니다.
이런 경우 해당 데몬을 내려야 하는데...
더욱 나쁜 경우는 어떤 데몬이 이 파일시스템을 사용하고 있는지를 알기가 힘들다는 것이죠.
그래서 데몬은 데몬이 되기 전에 현재 경로를 "/'와 같이 "umount"될 수 없는 곳으로 옮기는 것이 좋습니다.
 
또 한가지 고려해야 할 것은 현재 daemon은 뭐 파일에 숫자만 적고 있지만 여러분이 만드는 deamon은 어떤 일을 하게 될 지 사실 모릅니다.
예를 들어 daemon이 또 fork를 해서 자식 프로세스들을 갖을 수도 있고 exec()함수나 system()함수에 의해 아예 다른 프로그램을 실행 시킬 수도 있을 것입니다.
이때 새로 생성되는 프로세스를 현재 daemon이 제어 할 수 없다면 이 또한 문제일 수 있겠죠?
그래서 데몬프로세스는 데몬이 된 직 후 자신이 속한 프로세스 그룹의 리더가 아니라면 새로운 프로세스 세션을 만들고 자신이 리더가 된 후 다음 작업들을 하게 됩니다.  이러한 기능을 하는 함수가 바로 setsid()라는 함수 입니다. (참조: http://teamblog.joinc.co.kr/yundream/226)
 아래 소스는 chdir()과 setsid()함수를 호출하여 위에서 이야기한 내용을 반영하고 있습니다.
 
int main(int argc, char *argv[])
{
        int pid;

        pid=fork();
        switch(pid){
        case -1:
                fprintf(stderr, "Fork Errorn");
                break;
        case 0:         // child
                break;
        default:        // parent
                return 0;
        }

        chdir("/");
        setsid();

        work();

        return 0;
}
 
 
자 여기까지 하면 뭐 데몬이 잘 만들어 진 것 입니다.
 
추가로 실제 데몬을 프로그래밍 하실 때 주의하실 점은 시그널에 대한 처리를 꼭 하시라는 것 입니다.
위의 샘플 소스는 뭐 특별하게 시그널 처리를 할께 딱히 없지만 예를 들어 웹서버와 같이 통신 프로그램인 경우 SIG_PIPE와 같은 시그널을 처리해야 합니다.
 
 
4. 오뚜기 같은 Daemon만들기
 
마지막으로 이야기 하는 것은 일반적인 데몬에 대한 이야기는 아니구요 팁같은 거라고 할까요?
데몬은 서비스 제공하는 프로세스이다 보니깐...
시스템이 시작되면 시작되서 끝날때 까지 살아 있어야 하는데...
우리가 짜는 프로그램이 문제가 없다고 장담할 수는 없겠죠? (저만 그런가?)
 
만약 데몬으로 띄운 프로그램이 죽으면 타격이 크죠.
뭐 그 타격은 타격이더라도 세션이나 트랜잭션이 중요한 서비스가 아닌 경우라면 빨리 다시 시작이라도 시켜서 정상화를 시키고 싶은 경우가 있습니다.
 
이런 경우에 다음과 같은 방법으로 할 수 있을 것입니다.
먼저 일반 데몬을 하나 만들기 위해 일반 fork하시구요.
그리고 다시 fork를 해서 자식프로세스는 서비스를 수행하구요 부모프로세스는 자식이 종료되기를 기다립니다.
그런데 자식프로세스는 무한루프일 거니깐...
부모프로세스 입장에서 자식이 종료되었다면 실제로는 뭔가 문제가 생긴 것이겠죠?
이때 다시 fork를 해서 위의 과정을 반복합니다.
 
소스는 다음과 같습니다.  
 
int main(int argc, char *argv[])
{
        int pid;
        int ret;

        if (( pid = fork()) < 0) {
                fprintf(stderr, "Main Fork Errorn");
                return 0;
        } else if(pid > 0) {
                return 0;
        }

        chdir("/");
        setsid();

        while(1) {
                if (( pid = fork()) < 0) {
                        fprintf(stderr, "Sub Fork Errorn");
                        return 0;
                } else if(pid == 0) {
                        break;
                } else if(pid > 0) {
                        wait(&ret);
                }
        }

        work();

        return 0;
}
 
 
만약 자식이 종료될때 상태를 알고자 한다면 wait()함수의 인자인 ret값을 조사하면 됩니다.
 
자 이렇게 해서 UNIX/LINUX에서 Daemon만들기에 대한 이야기를 마치도록 하겠습니다. 
Posted by 까 치
,