$ sudo pdftk a.pdf b.pdf cat output a_and_b.pdf
$ sudo pdftk a_and_b.pdf cat 13 42 output pages_13_and_42.pdf
Sunday, September 20, 2015
Tuesday, December 23, 2014
19.1.1 Операторууд (operators)
Хүснэгт 19.2.
С++ хэлний операторууд
Оператор
|
Oперанд
|
Тайлбар
|
Жишээ
|
Нийцэл
|
XA
|
|---|---|---|---|---|---|
::
|
нэг
|
глобал үйлчлэх
хүрээг заана
|
:: name
|
<
|
-
|
::
|
хоёр
|
класс/нэрийн
мужийн үйлчлэх хүрээг заана
|
className::memberName
|
>
|
-
|
->
|
хоёр
|
гишүүн элементийг
заагчаар дамжуулан сонгох
|
ptr->memberName
|
>
|
-
|
.
|
хоёр
|
гишүүн элементийг
обьектоор дамжуулан сонгох
|
obj.memberName
|
>
|
-
|
->
|
нэг
|
ухаалаг заагч
|
obj->member
|
<
|
Г
|
[ ]
|
хоёр
|
индексийг заана
|
ptr[expr]
|
>
|
Г
|
( )
|
дурын [a]
|
функц дуудах
|
function(argList)
|
>
|
-
|
( )
|
дурын
|
анхны
утгыг оноох
|
className(argList)
|
>
|
Г
|
++
|
нэг
|
постфикс нэмэгдүүлэх
|
varName++
|
<
|
+
|
--
|
нэг
|
постфикс хорогдуулах
|
varName--
|
<
|
+
|
typeid
|
нэг
|
төрөл тогтоох
|
typeid(type)
or typeid(expr)
|
<
|
-
|
dynamic_cast
|
хоёр
|
төрлийг
хяналттайгаар динамик
горимд хувиргах
|
dynamic_cast<type>(expr)
|
>
|
-
|
static_cast
|
хоёр
|
төрлийг
хяналттайгаар статик
горимд хувиргах
|
static_cast<type>(expr)
|
>
|
-
|
reinterpret_cast
|
хоёр
|
төрлийг хянахгүй
хувиргах
|
reinterpret_cast<type>(expr)
|
>
|
-
|
const_cast
|
хоёр
|
тогтмолыг хувиргах
|
const_cast<type>(expr)
|
>
|
-
|
sizeof
|
нэг
|
хэмжээг байтаар
илэрхийлэх
|
sizeof expr
or sizeof(type)
|
<
|
-
|
++
|
нэг
|
префикс нэмэгдүүлэх
|
++varName
|
<
|
+
|
--
|
нэг
|
префикс хорогдуулах
|
--varName
|
<
|
+
|
~
|
нэг
|
бит дээрх үгүйсгэл
|
~ expr
|
<
|
+
|
!
|
нэг
|
логик үгүйсгэл
|
! expr
|
<
|
+
|
+, -
|
нэг
|
унарy plus, unary
minus
|
+expr
or -expr
|
<
|
+
|
*
|
нэг
|
заагчийн агуулгыг
сонгох
|
* ptr
|
<
|
+
|
&
|
нэг
|
хаяг тогтоох
|
& lvalue
|
<
|
+
|
new
|
нэг
|
санах ой
хуваарилах
|
new type
or new type(expr-list)
|
<
|
+
|
new [ ]
|
нэг
|
дараалласан санах
ой хуваарилах
|
new type
[ size ]
|
>
|
+
|
delete
|
нэг
|
хуваарилсан
санах ойг чөлөөлөх
|
delete ptr
|
<
|
+
|
delete [ ]
|
нэг
|
дарааллан хуваарилсан
санах ойг чөлөөлөх
|
delete [ ] ptr
|
<
|
Г
|
( )
|
хоёр
|
төрлийг шилжүүлэх
С хэлний хэлбэр
|
( type ) expr
|
<
|
- [b]
|
->*
|
хоёр
|
заагчийн тусламжтайгаар
гишүүн
заагчийг сонгох
|
ptr->*ptrToMember
|
>
|
Г
|
.*
|
хоёр
|
обьектийн тусламжтайгаар
гишүүн
заагчийг сонгох
|
obj.*ptrToMember
|
>
|
-
|
*
|
хоёр
|
үржүүлэх
|
expr1 * expr2
|
>
|
+
|
/
|
хоёр
|
хуваах
|
expr1 / expr2
|
>
|
+
|
%
|
хоёр
|
хуваалтын үлдэгдэл
олох
|
expr1 % expr2
|
>
|
+
|
+
|
хоёр
|
нэмэх
|
expr1 + expr2
|
>
|
+
|
-
|
хоёр
|
хасах
|
expr1 - expr2
|
>
|
+
|
<<
|
хоёр
|
зүүн тийш шилжүүлэх
|
expr << shiftAmt
|
>
|
+
|
>>
|
хоёр
|
баруун тийш шилжүүлэх
|
expr >> shiftAmt
|
>
|
+
|
<
|
хоёр
|
бага
|
expr1 < expr2
|
>
|
+
|
<=
|
хоёр
|
бага буюу
тэнцүү
|
expr1 <= expr2
|
>
|
+
|
>
|
хоёр
|
их
|
expr1 > expr2
|
>
|
+
|
>=
|
хоёр
|
их буюу тэнцүү
|
expr1 >= expr2
|
>
|
+
|
==
|
хоёр
|
тэнцүү [c]
|
expr1 == expr2
|
>
|
+
|
!=
|
хоёр
|
тэнцүү биш
|
expr1 != expr2
|
>
|
+
|
&
|
хоёр
|
бит AND
|
expr1 & expr2
|
>
|
+
|
^
|
хоёр
|
бит XOR
|
expr1 ^ e2
|
>
|
+
|
|
|
хоёр
|
бит OR
|
expr1 | expr2
|
>
|
+
|
&&
|
хоёр
|
логик AND
|
expr1 && expr2
|
>
|
+
|
||
|
хоёр
|
логик OR
|
expr1 || expr2
|
>
|
+
|
=
|
хоёр
|
утга оноох
|
expr1 = expr2
|
<
|
+
|
*=
|
хоёр
|
үржүүлж утга
оноох
|
expr1 *= expr2
|
<
|
+
|
/=
|
хоёр
|
хувааж утга
оноох
|
expr1 /= expr2
|
<
|
+
|
%=
|
хоёр
|
хуваалтын үлдэгдлээр
утга оноох
|
expr1 %= expr2
|
<
|
+
|
+=
|
хоёр
|
нэмж утга
оноох
|
expr1 += expr2
|
<
|
+
|
-=
|
хоёр
|
хасаж утга оноох
|
expr1 -= expr2
|
<
|
+
|
<<=
|
хоёр
|
зүүн шилжүүлж
утга оноох
|
expr1 <<= expr2
|
<
|
+
|
>>=
|
хоёр
|
баруун шилжүүлж
утга оноох
|
expr1 >>= expr2
|
<
|
+
|
&=
|
хоёр
|
AND үйлдлээр утга
оноох
|
expr1 &= expr2
|
<
|
+
|
|=
|
хоёр
|
ОR үйлдлээр утга
оноох
|
expr1 |= expr2
|
<
|
+
|
^=
|
хоёр
|
ХOR үйлдлээр утга оноох
|
expr1 ^= expr2
|
<
|
+
|
? :
|
гурав
|
нөхцөлт илэрхийлэл
|
bool ? expr : expr
|
>
|
-
|
throw
|
нэг
|
Throw exception
|
throw expr
|
<
|
-
|
,
|
хоёр
|
дэс дараалан
гүйцэтгэх
|
expr , expr
|
>
|
+
|
|
[b]
Төрөл хувиргах оператор
нь хэрэглэгчийн тодорхойлсон төрлийг
хувиргахдаа байгуулагч эсвэл
хувиргалтын операторуудыг ашиглаж
болно.
[c]
Энэ операторыг float
эсвэл double
төрлийн операндуудад
хэрэглэж болохгүй.
|
|||||
Эх сурвалж:
Introduction
to Design Patterns in C++ with Qt
Wednesday, December 17, 2014
19.1. Операторууд (operators)
Операторуудыг
хэрэглэгдэх байдлаар нь ангилан ялгавал:
| утга оноох операторууд | =, +=, *=, … |
арифметик операторууд
|
+, -, *, %
|
жиших операторууд
|
<, <=, >, >=, ==,
!=
|
логик операторууд
|
&&, ||, !
|
бит операторууд
|
&, |, ^, ~, <<, >>
|
санах ойн удирдлагын операторууд
|
new, delete, sizeof
|
заагч болон хандалтын
операторууд
|
*, &, ., ->, [], ()
|
үйлчлэх хүрээний оператор
|
:: |
бусад операторууд
|
conditional(?:), comma(,)
|
С++ стандартад
тодорхой түлхүүр үгнүүдийг (keyword)
зарим операторын орлуулгын нэрээр
(alias) оноож өгсөн байдаг.
19.1. Хүснэгт,
операторын орлуулгын нэрс
Оператор
|
Орлуулах нэр
|
| && | and |
| & | bitand |
| &= | and_eq |
| || | or |
| | | bitor |
| |= | or_eq |
| ^ | xor |
| ^= | xor_eq |
| ! | not |
| != | not_eq |
| ~ | compl |
Ихэнх (гэхдээ
бүгд биш) дотоод төрлүүдийн
(built-in type) хувьд операторуудыг
урьдчилан тодорхойлсон байдаг.
Операторын
шинж чанар (operator characteristics)
Операторууд
дараах онцгой шинж чанарыг агуулна:
- эрэмбэ (precedence)
- нийцэл (associativity)
- шаардагдах операндын тоо (number of required operands)
19.2. хүснэгтэд
С++ хэлний бүх операторуудыг эрэмбээр
нь жагсаан (өндөр эрэмбийн
операторууд жагсаалтын дээд хэсэгт),
хэрэглээний дагуу бүлэглэн харуулав.
- Операнд багана тухайн операторт шаардлагатай операндын тоог харуулна.
- Тайлбар багана тухайн операторын дотоод төрөлд зориулсан тодорхойлолтыг агуулна.
- Нийцэл багана хэрэв ижил оператор нэгэн зэрэг олон тоогоор хэрэглэгдвэл хоорондоо хэрхэн нийцэхийг үзүүлнэ. Үүнд:
- „>“ тэмдэглэгээ зүүнээс баруун гэсэн нийцлийг илтгэнэ. Жишээ нь:d = a + b + c; // эхэлж a + b үйлдлийг, дараа нь (a + b) + c үйлдлийг гүйцэтгэнэ.
- „<“ тэмдэглэгээ баруунаас зүүн гэсэн нийцлийг илтгэнэ. Жишээ нь:c = b = a; // а эхэлж b-д, дараа нь с-д оноогдоно.
- Хэт ачаалал (XA) багана тухайн операторыг хэрэглэгчийн төрөлд дахин шинээр тодорхойлох боломжтой эсэхийг харуулна.
- “+” тэмдэглэгээ нь операторыг глобал, эсвэл гишүүн функц хэлбэрээр хэтрүүлэн ачааллах боломжтойг илтгэнэ.
- “Г” тэмдэглэгээ нь операторыг зөвхөн гишүүн функц хэлбэрээр хэтрүүлэн ачааллах боломжтойг илтгэнэ.
- „-“ тэмдэглэгээ нь операторыг хэтрүүлэх ачааллах боломжгүйг илтгэнэ.
Эх сурвалж:
Introduction to Design Patterns in C++ with Qt
Monday, December 15, 2014
19-бүлэг. Төрөл, илэрхийлэл
Энэ бүлэгт
С++ хэл дэх төрлийн систем, түүнчлэн
илэрхийлэл хэрхэн үнэлэгдэж, хувиргагддаг
талаар гүнзгийрүүлэн авч үзэх болно.
Юуны түрүүнд
цаашид хэрэглэгдэх зарим хэллэгүүдийн
товч тодорхойлолтыг өгье.
Оператор
гэдэг нь функцийн тусгай нэгэн төрөл
бөгөөд өгөгдсөн операнд дээр тодорхой
үйлдлийг гүйцэтгэж, үр дүнг нь буцаана.
Операнд
гэдэг нь аль нэг операторын аргумент
юм.
Ерөнхийдөө
оператор нь энгийн функц бөгөөд зарим
тохиолдолд эдгээр функцийг инфикс
үйлдлийн тэмдэгтэйгээр (+, -, *, / зэрэг) дуудаж болно
гэж ойлгох нь зохимжтой. Өөрөөр хэлбэл
функц дуудах урт бичлэгтэй синтаксийн
(sum = operator+(a, b);) оронд
уншихад илүү дөхөм инфикс синтаксыг
(sum = a + b;) ашиглаж
болно.
Илэрхийлэл
нь нэг эсвэл олон тооны операнд болон
фунцкуудээс тогтоно. Илэрхийлэл бүр
тодорхой төрөл, мөн утгатай байна. Уг
утга нь тухайн өгөгдсөн операнд дээр
операторын тодорхойлолтод заасан
үйлдлийг гүйцэтгэснээр гарч ирнэ.
Эх сурвалж:
Introduction to Design Patterns in C++ with Qt
Monday, March 12, 2012
Customizing SELinux policy
Problem: when to upload a file to TFTP server, which runs on Linux host (i.e., Fedora guest), SELinux denies this access and reports it to AVC audit file in "/var/log/audit/audit.log". It happens, because any request of tftp daemon on specified target directory and file are not allowed in the SELinux policy.
Solution: to resolve this issue, a corresponding custom policy module can be created and added to SELinux policy with the "audit2allow" tool.
Case: for example, consider the following AVC audit log, after invoking following command from a remote Windows host:
"tftp -i 192.168.0.120 PUT installed_apps.txt"
----------------------------------------------------------------------
Summary:
SELinux is preventing in.tftpd (tftpd_t) "search" to ./mnt (mnt_t).
Detailed Description:
SELinux denied access requested by in.tftpd. It is not expected that this access
is required by in.tftpd and this access may signal an intrusion attempt. It is
also possible that the specific version or configuration of the application is
causing it to require additional access.
Allowing Access:
Sometimes labeling problems can cause SELinux denials. You could try to restore
the default system file context for ./mnt,
restorecon -v './mnt'
If this does not work, there is currently no automatic way to allow this access.
Instead, you can generate a local policy module to allow this access - see FAQ
(http://fedora.redhat.com/docs/selinux-faq-fc5/#id2961385) Or you can disable
SELinux protection altogether. Disabling SELinux protection is not recommended.
Please file a bug report (http://bugzilla.redhat.com/bugzilla/enter_bug.cgi)
against this package.
Additional Information:
Source Context system_u:system_r:tftpd_t:s0-s0:c0.c1023
Target Context system_u:object_r:mnt_t:s0
Target Objects ./mnt [ dir ]
Source in.tftpd
Source Path /usr/sbin/in.tftpd
Port
Host efe1272.efe
Source RPM Packages tftp-server-0.49-1.fc10
Target RPM Packages filesystem-2.4.19-1.fc10
Policy RPM selinux-policy-3.5.13-74.fc10
Selinux Enabled True
Policy Type targeted
MLS Enabled True
Enforcing Mode Enforcing
Plugin Name catchall_file
Host Name efe1272.efe
Platform Linux efe1272.efe 2.6.27.41-170.2.117.fc10.i686 #1
SMP Thu Dec 10 11:00:29 EST 2009 i686 i686
Alert Count 25
First Seen Mon 12 Mar 2012 09:21:50 AM CET
Last Seen Mon 12 Mar 2012 01:30:02 PM CET
Local ID e48f9047-a5b0-4f62-8510-d57f015c60c1
Line Numbers
Raw Audit Messages
node=efe1272.efe type=AVC msg=audit(1331555402.558:42): avc: denied { search } for pid=12268 comm="in.tftpd" name="mnt" dev=sda3 ino=1036321 scontext=system_u:system_r:tftpd_t:s0-s0:c0.c1023 tcontext=system_u:object_r:mnt_t:s0 tclass=dir
node=efe1272.efe type=SYSCALL msg=audit(1331555402.558:42): arch=40000003 syscall=12 success=no exit=-13 a0=bfe35e81 a1=1 a2=4f5dec4a a3=bfe34734 items=0 ppid=2289 pid=12268 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm="in.tftpd" exe="/usr/sbin/in.tftpd" subj=system_u:system_r:tftpd_t:s0-s0:c0.c1023 key=(null)
By running "audit2allow" on above alert and reviewing the resultant "mntfixlocal.te" policy file will show us (as root):
---------------------------------------------------------------------------
# grep mnt_t /var/log/audit/audit.log | audit2allow -M mntfixlocal
******************** IMPORTANT ***********************
To make this policy package active, execute:
semodule -i mntfixlocal.pp
# cat mntfixlocal.te
module mntfixlocal 1.0;
require {
type tftpd_t;
type mnt_t;
class dir search;
}
#============= tftpd_t ==============
allow tftpd_t mnt_t:dir search;
----------------------------------------------------------
To compile and load this policy module invoke following command (as root):
-----------------------------------------------------------
# semodule -i mntfixlocal.pp
-----------------------------------------------------------
To make sure that the custom policy module is activated, look for any policies regarding "tftpd_t" and "mnt_t" (as user):
-----------------------------------------------------------
$ sesearch -A | grep tftpd_t | grep mnt_t
WARNING: This policy contained disabled aliases; they have been removed.
allow tftpd_t mnt_t : dir search ;
------------------------------------------------------------
Alternatively, we can edit the custom policy module .te file to prevent auditing of such alert whilst still allowing SELinux to continue preventing access. We do this by changing the "allow" line to "dontaudit":
------------------------------------------------------------
#============= tftpd_t ==============
dontaudit tftpd_t mnt_t:dir search;
------------------------------------------------------------
This way we can change any alerts to custom policy modules and add them to SELinux policy.
Finally our custom policy module will be shown as follows (as user):
-----------------------------------------------------------
$ sesearch -A | grep tftpd_t | grep vmblock_t
WARNING: This policy contained disabled aliases; they have been removed.
allow tftpd_t vmblock_t : file { read write create getattr } ;
allow tftpd_t vmblock_t : dir { write add_name search } ;
-------------------------------------------------------------
Source: http://wiki.centos.org/HowTos/SELinux
and also: http://serverfault.com/questions/106007/tftp-uploads-failing
Solution: to resolve this issue, a corresponding custom policy module can be created and added to SELinux policy with the "audit2allow" tool.
Case: for example, consider the following AVC audit log, after invoking following command from a remote Windows host:
"tftp -i 192.168.0.120 PUT installed_apps.txt"
----------------------------------------------------------------------
Summary:
SELinux is preventing in.tftpd (tftpd_t) "search" to ./mnt (mnt_t).
Detailed Description:
SELinux denied access requested by in.tftpd. It is not expected that this access
is required by in.tftpd and this access may signal an intrusion attempt. It is
also possible that the specific version or configuration of the application is
causing it to require additional access.
Allowing Access:
Sometimes labeling problems can cause SELinux denials. You could try to restore
the default system file context for ./mnt,
restorecon -v './mnt'
If this does not work, there is currently no automatic way to allow this access.
Instead, you can generate a local policy module to allow this access - see FAQ
(http://fedora.redhat.com/docs/selinux-faq-fc5/#id2961385) Or you can disable
SELinux protection altogether. Disabling SELinux protection is not recommended.
Please file a bug report (http://bugzilla.redhat.com/bugzilla/enter_bug.cgi)
against this package.
Additional Information:
Source Context system_u:system_r:tftpd_t:s0-s0:c0.c1023
Target Context system_u:object_r:mnt_t:s0
Target Objects ./mnt [ dir ]
Source in.tftpd
Source Path /usr/sbin/in.tftpd
Port
Host efe1272.efe
Source RPM Packages tftp-server-0.49-1.fc10
Target RPM Packages filesystem-2.4.19-1.fc10
Policy RPM selinux-policy-3.5.13-74.fc10
Selinux Enabled True
Policy Type targeted
MLS Enabled True
Enforcing Mode Enforcing
Plugin Name catchall_file
Host Name efe1272.efe
Platform Linux efe1272.efe 2.6.27.41-170.2.117.fc10.i686 #1
SMP Thu Dec 10 11:00:29 EST 2009 i686 i686
Alert Count 25
First Seen Mon 12 Mar 2012 09:21:50 AM CET
Last Seen Mon 12 Mar 2012 01:30:02 PM CET
Local ID e48f9047-a5b0-4f62-8510-d57f015c60c1
Line Numbers
Raw Audit Messages
node=efe1272.efe type=AVC msg=audit(1331555402.558:42): avc: denied { search } for pid=12268 comm="in.tftpd" name="mnt" dev=sda3 ino=1036321 scontext=system_u:system_r:tftpd_t:s0-s0:c0.c1023 tcontext=system_u:object_r:mnt_t:s0 tclass=dir
node=efe1272.efe type=SYSCALL msg=audit(1331555402.558:42): arch=40000003 syscall=12 success=no exit=-13 a0=bfe35e81 a1=1 a2=4f5dec4a a3=bfe34734 items=0 ppid=2289 pid=12268 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm="in.tftpd" exe="/usr/sbin/in.tftpd" subj=system_u:system_r:tftpd_t:s0-s0:c0.c1023 key=(null)
By running "audit2allow" on above alert and reviewing the resultant "mntfixlocal.te" policy file will show us (as root):
---------------------------------------------------------------------------
# grep mnt_t /var/log/audit/audit.log | audit2allow -M mntfixlocal
******************** IMPORTANT ***********************
To make this policy package active, execute:
semodule -i mntfixlocal.pp
# cat mntfixlocal.te
module mntfixlocal 1.0;
require {
type tftpd_t;
type mnt_t;
class dir search;
}
#============= tftpd_t ==============
allow tftpd_t mnt_t:dir search;
----------------------------------------------------------
To compile and load this policy module invoke following command (as root):
-----------------------------------------------------------
# semodule -i mntfixlocal.pp
-----------------------------------------------------------
To make sure that the custom policy module is activated, look for any policies regarding "tftpd_t" and "mnt_t" (as user):
-----------------------------------------------------------
$ sesearch -A | grep tftpd_t | grep mnt_t
WARNING: This policy contained disabled aliases; they have been removed.
allow tftpd_t mnt_t : dir search ;
------------------------------------------------------------
Alternatively, we can edit the custom policy module .te file to prevent auditing of such alert whilst still allowing SELinux to continue preventing access. We do this by changing the "allow" line to "dontaudit":
------------------------------------------------------------
#============= tftpd_t ==============
dontaudit tftpd_t mnt_t:dir search;
------------------------------------------------------------
This way we can change any alerts to custom policy modules and add them to SELinux policy.
Finally our custom policy module will be shown as follows (as user):
-----------------------------------------------------------
$ sesearch -A | grep tftpd_t | grep vmblock_t
WARNING: This policy contained disabled aliases; they have been removed.
allow tftpd_t vmblock_t : file { read write create getattr } ;
allow tftpd_t vmblock_t : dir { write add_name search } ;
-------------------------------------------------------------
Source: http://wiki.centos.org/HowTos/SELinux
and also: http://serverfault.com/questions/106007/tftp-uploads-failing
Tuesday, October 4, 2011
WLAN settings on Nokia N95
To define access point:
Menu -> Tools -> Settings -> Connection -> Access points
- Connection name =
- Data bearer = Wireless LAN
- WLAN network name =
- Network status = Public
- WLAN network mode = Infrastructure
- WLAN security mode = WPA/WPA2 (must be compatible with your WLAN router)
- WLAN security settings
-- WPA/WPA2 = Pre-shared key
-- Pre-shared key = (key phrase used in your WLAN)
-- WPA2 only mode = Off
To activate the access point:
Menu -> Web -> Options -> Settings -> General :
- Access point = Always ask
Menu -> Tools -> Settings -> Connection -> Access points
- Connection name =
- Data bearer = Wireless LAN
- WLAN network name =
- Network status = Public
- WLAN network mode = Infrastructure
- WLAN security mode = WPA/WPA2 (must be compatible with your WLAN router)
- WLAN security settings
-- WPA/WPA2 = Pre-shared key
-- Pre-shared key =
-- WPA2 only mode = Off
To activate the access point:
Menu -> Web -> Options -> Settings -> General :
- Access point = Always ask
Friday, December 3, 2010
Public key usage on Thunderbird (with Enigmail OpenPGP Key Manager)
The Enigmail OpenPGP Key Manager is designed to be simple to use with a clean, powerful interface.
You can access it from within Thunderbird/SeaMonkey via the OpenPGP menu: OpenPGP > Key Management.
You can also run it as a stand alone application by appending -pgpkeyman to the command that runs Thunderbird/SeaMonkey, e.g. on Windows: "C:\Program Files\Mozilla Thunderbird\thunderbird.exe" -pgpkeyman.
For more details refer here.
You can access it from within Thunderbird/SeaMonkey via the OpenPGP menu: OpenPGP > Key Management.
You can also run it as a stand alone application by appending -pgpkeyman to the command that runs Thunderbird/SeaMonkey, e.g. on Windows: "C:\Program Files\Mozilla Thunderbird\thunderbird.exe" -pgpkeyman.
For more details refer here.
Wednesday, March 17, 2010
Enable "Large File Support" in uClibc
Sources:
[1] Blackfin uClinux (http://docs.blackfin.uclinux.org/doku.php?id=faq)
Steps:
1. Jump to a toolchain source folder
2. Delete ".configured" file (it was created once the toolchain built)
3. Enable LFS (Large File Support) in the configuration files
Replace
with
in both files.
4. Return to the top folder and build the toolchain again.
[1] Blackfin uClinux (http://docs.blackfin.uclinux.org/doku.php?id=faq)
Steps:
1. Jump to a toolchain source folder
cd /opt/ifx-lxdb-1-2
2. Delete ".configured" file (it was created once the toolchain built)
rm -f .configured
3. Enable LFS (Large File Support) in the configuration files
cd source/uclibc
chmod 666 ifx-uClibc-def-config.mips
chmod 666 ifx-uClibc-opt-config.mips
Replace
# UCLIBC_HAS_LFS is not set
with
UCLIBC_HAS_LFS=y
in both files.
4. Return to the top folder and build the toolchain again.
cd ../..
./setup.sh all
Strace build on mips with uClibc
Sources:
[1] Building Embedded Linux Systems, pp. 297-298 (how to build strace)
[2] Blackfin uClinux (important tips)
[3] Assabet (compiling strace)
[4] Unable to build strace - busybox forum (same build error and reason of the error)
Steps:
1. Download strace package (strace-4.5.19.tar.bz2, 499,6KB) from sourceforge (http://sourceforge.net/projects/strace/) and save it under "~/debug" folder on a host [1].
2. Jump to the folder and unpack the package
(it will be a folder named "strace-4.5.19" created)
3. Jump to the recently created folder
4. Configure and build it against uClibc [1]
5. First time it will return error messages as shown below:
6. By searching on the Internet [4], the build failure reason results from not supporting large file (Large File Support, LFS) in uClibc. So decided to modify sources that references following functions:
Two files found that contain the functions:
7. All lines that include 64-bit functions were commented in both source files.
8. Clean and build again.
Build passed without any error.
9. Copy strace executable to root filesystem [1]
10. Run minicom, connect a target board (INCAIP2) serially to the host and turn on the target board.
11. After booting Linux on the target, check if strace works:
12. Strace the "voip" application
[1] Building Embedded Linux Systems, pp. 297-298 (how to build strace)
[2] Blackfin uClinux (important tips)
[3] Assabet (compiling strace)
[4] Unable to build strace - busybox forum (same build error and reason of the error)
Steps:
1. Download strace package (strace-4.5.19.tar.bz2, 499,6KB) from sourceforge (http://sourceforge.net/projects/strace/) and save it under "~/debug" folder on a host [1].
2. Jump to the folder and unpack the package
cd ~/debug
tar -xjf strace-4.5.19.tar.bz2
(it will be a folder named "strace-4.5.19" created)
3. Jump to the recently created folder
cd strace-4.5.19
4. Configure and build it against uClibc [1]
CC=mips-linux-gcc ./configure --host=mips-linux
make LDFLAGS="-static"
5. First time it will return error messages as shown below:
file.c: In function `printstatfs64':
file.c:1695: error: storage size of `statbuf' isn't known
file.c:1695: warning: unused variable `statbuf'
file.c: In function `sys_statfs64':
file.c:1729: error: invalid application of `sizeof' to an incomplete type
file.c: In function `sys_fstatfs64':
file.c:1743: error: invalid application of `sizeof' to an incomplete type
make[1]: *** [file.o] Error 1
make[1]: Leaving directory `/home/boldoo/debug/strace-4.5.19'
make: *** [all] Error 2
6. By searching on the Internet [4], the build failure reason results from not supporting large file (Large File Support, LFS) in uClibc. So decided to modify sources that references following functions:
sys_truncate64()
sys_ftruncate64()
sys_getdents64()
sys_statfs64()
sys_fstatfs64()
Two files found that contain the functions:
file.c
linux/mips/syscallent.h
7. All lines that include 64-bit functions were commented in both source files.
8. Clean and build again.
make clean
make LDFLAGS="-static"
Build passed without any error.
9. Copy strace executable to root filesystem [1]
cp strace /opt/rootfs.incaip2/sbin/
10. Run minicom, connect a target board (INCAIP2) serially to the host and turn on the target board.
11. After booting Linux on the target, check if strace works:
# strace ls
execve("/bin/ls", ["ls"], [/* 11 vars */]) = 0
ioctl(0, TIOCNXCL, {B115200 opost isig icanon echo ...}) = 0
ioctl(1, TIOCNXCL, {B115200 opost isig icanon echo ...}) = 0
getuid() = 0
getgid() = 0
setgid(0) = 0
setuid(0) = 0
ioctl(1, 0x40087468, 0x7fff7cc0) = 0
ioctl(1, TIOCNXCL, {B115200 opost isig icanon echo ...}) = 0
lstat(".", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
brk(0) = 0x1000a120
brk(0x1000b120) = 0x1000b120
brk(0x1000c000) = 0x1000c000
stat(".", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
open(".", O_RDONLY) = 3
fcntl(3, F_SETFD, FD_CLOEXEC) = 0
getdents(3, /* 7 entries */, 3933) = 128
lstat("./drv_vmmc", {st_mode=S_IFREG|0755, st_size=345000, ...}) = 0
lstat("./hapi.o", {st_mode=S_IFREG|0664, st_size=10996, ...}) = 0
lstat("./tmp", {st_mode=S_IFLNK|0777, st_size=22, ...}) = 0
lstat("./drv_tapi", {st_mode=S_IFREG|0755, st_size=171132, ...}) = 0
lstat("./startpa.sh", {st_mode=S_IFREG|0755, st_size=246, ...}) = 0
getdents(3, /* 0 entries */, 3933) = 0
close(3) = 0
open("/etc/TZ", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/etc/TZ", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/etc/TZ", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/etc/TZ", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/etc/TZ", O_RDONLY) = -1 ENOENT (No such file or directory)
write(1, "drv_tapi drv_vmmc hapi.o "..., 52drv_tapi drv_vmmc hapi.p
) = 52
exit(0) = ?
12. Strace the "voip" application
# strace voip
execve("/usr/local/bin/voip", ["voip"], [/* 11 vars */]) = 0
old_mmap(NULL, 20, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x0
stat("/etc/ld.so.cache", {st_mode=S_IFREG|0644, st_size=64, ...}) = 0
open("/etc/ld.so.cache", O_RDONLY) = 3
old_mmap(NULL, 64, PROT_READ, MAP_SHARED, 3, 0) = 0x2aaaf000
close(3) = 0
open("/lib/libc.so.0", O_RDONLY) = 3
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0
read(3, "\177ELF\1\2\1\0\0\0\0\0\0\0\0\0\0\3\0\10\0\0\0\1\0\0\265\0\0\0\0004"..6
old_mmap(NULL, 684032, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2aaee000
old_mmap(0x2aaee000, 397556, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 3, 0) 0
old_mmap(0x2ab8f000, 4748, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x610
old_mmap(0x2ab91000, 15800, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANO0
close(3) = 0
munmap(0x2aab0000, 4096) = 0
munmap(0x2aaaf000, 64) = 0
ioctl(0, TIOCNXCL, {B115200 opost isig icanon echo ...}) = 0
ioctl(1, TIOCNXCL, {B115200 opost isig icanon echo ...}) = 0
write(1, "voip application (Mar 12 2010, 1"..., 42voip application (Mar 12 2010)
) = 42
rt_sigaction(SIGINT, {0x14000000, [RT_68], 0x400b80 /* SA_??? */}, {SIG_DFL, [R0
open("/dev/vmmc10", O_RDWR) = 3
open("/dev/vmmc11", O_RDWUnable to handle kernel paging request at virtual addr4
Oops in fault.c::do_page_fault, line 226:
$0 : 00000000 802e0000 fffffffc fffffffc 00000000 83791d4c 20004f11 83791d4c
$8 : 00000000 8027fb38 00000000 00000000 00000007 00000020 836c66b0 00000013
$16: 00000000 ffffffea 83791d4c 806e4f00 00000001 c0080fb0 83707000 836c4000
$24: 00000000 00432050 83790000 83791c80 00000000 802aa1b4
Hi : 00000000
Lo : 00000002
epc : 802ac5c8 Not tainted
Status: 1000fd03
Cause : 00800008
PrId : 00019640
Process voip (pid: 66, stackpage=83790000)
Stack: 806a4a3c 801cf2c4 83a09000 80309178 00000000 802aa1b4 2ab420d0
00000fff 801cf474 839a7550 83e25e80 00000001 83e25e80 00000001 00000000
80118e78 00000000 00001000 00000000 80118ad0 00000000 80118ad0 80103550
810e6c00 c00869cc 83e25e80 80307c00 83e25e80 00000060 83791d40 00000000
00000000 00000000 c00d9cb0 83791dd0 00000000 00000000 c0080fb0 c00b8b90
00000102 ...
Call Trace: [< 801cf2c4 >] [< 802aa1b4 >] [< 801cf474 >] [< 80118e78 >] [< 80118ad0 >]
[< 80118ad0 >] [< 80103550 >] [< c00869cc >] [< c00d9cb0 >] [< c0080fb0 >] [< c00b8b90 >]
[< c0080fb0 >] [< 80134094 >] [< c00d9cb0 >] [< c00d9d20 >] [< c009d610 >] [< c0080f14 >]
[< 80126a98 >] [< 80131438 >] [< 80131438 >] [< c0077540 >] [< 8011e964 >] [< 80126b14 >]
[< 8011ea3c >] [< 8011ea34 >] [< 8010c180 >] [< 8010c004 >] [< c0080710 >] [< c0076e2c >]
[< 8014e0d8 >] [< 80108b4c >] [< 8014de38 >] [< 80109a60 >] [< 80161e4c >]
Code: 00021080 00441021 aca30004 < 8c460000 > 00061a02 00061402 00431021 004
R) = 4
brk(0) = 0x1000013c
brk(0x1000113c) = 0x1000113c
brk(0x10002000) = 0x10002000
ioctl(4, 0x2000710f
+++ killed by SIGSEGV +++
Segmentation fault
Friday, February 12, 2010
A client-server application example (socket programming)
Applications:
- server: streamserver
- client: streamclient
Application sources:
- server: /home/< user>/Desktop/socket_programming/server.c
- client: < home>/source/user/efe/streamclient
Building/running applications:
- server: gcc server.c –o streamserver
- client: refer to “Building an application”, “Installing an application” and “Running/testing an application” sections.
Description/synopsis
On a target (INCA-IP2 board) will be run the “streamclient” client application and on a host computer the “streamserver” server application.
“Streamclient” tries to establish stream socket (TCP) connection with “streamserver”, which runs on the host (whos IP address is 192.168.0.98) and listens to the port 3490. When “streamserver” detects incoming connection from the remote target, it sends “Hello world” text as response. “streamclient” will display on the standard output what it has received.
Preperation
1. Enabling port 3490 in firewall
Allow port 3490 by adding following lines (before COMMIT) to “/etc/sysconfig/iptables”:
# Allow port 3490 for an example application
-A INPUT -m state --state NEW -m tcp -p tcp --dport 3490 -j ACCEPT
-A INPUT -m state --state NEW -m udp -p udp --dport 3490 -j ACCEPT
# End of port 3490 rule
After that restart firewall with “service iptables restart” command.
2. Check if port 3490 opened
After loading “streamserver”, open another terminal window and invoke “netstat –na | grep 3490” to check if the port 3490 is open and listened. If the port is open, the command should return:
tcp 0 0 0.0.0.0:3490 0.0.0.0:* LISTEN
Testing example
First, start “streamserver” on the host computer:
server
When starts, it must display:
server: waiting for connections...
Then start “streamclient” on the target. For starting “streamclient”, an IP address of the host must be given as command line argument:
streamclient 192.168.0.98
When the client starts and receives data from the server, it must display:
client: connecting to 192.168.0.98
client: received 'He'
and the server must display:
server: got connection from 192.168.0.97
Then, terminate the server application with CTRL+C command on the host and start again client connection. This time the client must return:
client: connect: Connection refused
client: failed to connect
It means the socket on port 3490 is closed.
- server: streamserver
- client: streamclient
Application sources:
- server: /home/< user>/Desktop/socket_programming/server.c
- client: < home>/source/user/efe/streamclient
Building/running applications:
- server: gcc server.c –o streamserver
- client: refer to “Building an application”, “Installing an application” and “Running/testing an application” sections.
Description/synopsis
On a target (INCA-IP2 board) will be run the “streamclient” client application and on a host computer the “streamserver” server application.
“Streamclient” tries to establish stream socket (TCP) connection with “streamserver”, which runs on the host (whos IP address is 192.168.0.98) and listens to the port 3490. When “streamserver” detects incoming connection from the remote target, it sends “Hello world” text as response. “streamclient” will display on the standard output what it has received.
Preperation
1. Enabling port 3490 in firewall
Allow port 3490 by adding following lines (before COMMIT) to “/etc/sysconfig/iptables”:
# Allow port 3490 for an example application
-A INPUT -m state --state NEW -m tcp -p tcp --dport 3490 -j ACCEPT
-A INPUT -m state --state NEW -m udp -p udp --dport 3490 -j ACCEPT
# End of port 3490 rule
After that restart firewall with “service iptables restart” command.
2. Check if port 3490 opened
After loading “streamserver”, open another terminal window and invoke “netstat –na | grep 3490” to check if the port 3490 is open and listened. If the port is open, the command should return:
tcp 0 0 0.0.0.0:3490 0.0.0.0:* LISTEN
Testing example
First, start “streamserver” on the host computer:
server
When starts, it must display:
server: waiting for connections...
Then start “streamclient” on the target. For starting “streamclient”, an IP address of the host must be given as command line argument:
streamclient 192.168.0.98
When the client starts and receives data from the server, it must display:
client: connecting to 192.168.0.98
client: received 'He'
and the server must display:
server: got connection from 192.168.0.97
Then, terminate the server application with CTRL+C command on the host and start again client connection. This time the client must return:
client: connect: Connection refused
client: failed to connect
It means the socket on port 3490 is closed.
Wednesday, February 10, 2010
Select - synchronous I/O multiplexing (оролт/гаралтыг синхрон сонгох)
Юникс програмчлалаас:
#include < sys/time.h>
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *errorfds, struct timeval *timeout);
void FD_CLR(int fd, fd_set *fdset);
int FD_ISSET(int fd, fd_set *fdset);
void FD_SET(int fd, fd_set *fdset);
void FD_ZERO(fd_set *fdset);
Энэ select() функц нь өгөгдсөн файл тодорхойлогчуудын (file descriptor) аль нь уншихад бэлэн, эсвэл бичихэд бэлэн, эсвэл алдаатай байгааг заана. Хэрэв өгөгдсөн файл тодорхойлогчуудын хувьд заагдсан нөхцөл хангагдаагүй (FALSE) байвал эдгээр файл тодорхойлогчуудын аль нэг дээр заагдсан нөхцөл биелэх хүртэл заасан хугацааг дуустал саатна.
select() функц нь ердийн файлууд, терминал төхөөрөмжүүд, STREAMS файлууд, FIFO төхөөрөмж, pipe төхөөрөмжүүдтэй ажиллах чадвартай.
nfds аргумент нь шалгагдах/тестлэгдэх файл тодорхойлогчдын хязгаарыг заана. Өөрөөр хэлбэл 0-с nfds-1 хязгаарт багтсан файл тодорхойлогчууд шалгагдана.
Хэрэв readfds аргумент нь тэг заагч (null pointer) биш бол, оролтон дээр уншихад бэлнийг нь шалгах файл тодорхойлогчуудыг, гаралтан дээр уншихад бэлэн болсон файл тодорхойлогчуудыг заана. Эдгээр файл тодорхойлуулагчууд нь fd_set төрлийнх байна.
Хэрэв writefds аргумент нь тэг заагч (null pointer) биш бол, оролтон дээр бичихэд бэлнийг нь шалгах файл тодорхойлогчуудыг, гаралтан дээр бичихэд бэлэн болсон файл тодорхойлогчуудыг заана. Эдгээр файл тодорхойлуулагчууд нь мөн адил fd_set төрлийнх байна.
Хэрэв errorfds аргумент нь тэг заагч (null pointer) биш бол, оролтон дээр алдаатай эсэхийг нь шалгах файл тодорхойлогчуудыг, гаралтан дээр алдаа гараад хүлээгдэж байгаа файл тодорхойлогчуудыг заана. Эдгээр файл тодорхойлуулагчууд нь мөн адил fd_set төрлийнх байна.
select() хэвийн гүйцэтгэгдвэл readfds, writefds, errorfds заагчуудын зааж байгаа обьектууд тус бүр уншихад, бичихэд, эсвэл алдаатай файл тодорхойлогчуудыг зааж өөрчлөгдөнө. Мөн энэ тохиолдолд бас nfds хязгаарт багтсан файл тодорхойлогч бүрийн хувьд харгалзах бит нь 1 болно. Үүний тулд оролтонд уг харгалзах бит 1 гэж тавигдсан, тэгээд шалгалт/тестээр файл тодорхойлогчуудад харгалзах нөхцөлүүдээс (уншихад, бичихэд бэлэн, эсвэл алдаатай) биелсэн байх ёстой.
Хэрэв timeout аргумент нь тэг заагч (null pointer) биш бол, энэ аргумент select() функцыг биелж дуусахыг заасан хугацааны интервалыг агуулсан обьектыг заах ба уг обьектын төрөл нь struct timeval байх ёстой. Хэрэв timeout аргументын зааж байгаа struct timeval төрлийн обьектын гишүүд нь 0 утгатай бол select() ерөөсөө саатахгүй (блоклохгүй). Хэрэв timeout аргумент тэг заагч (null pointer) бол select() функц түүний шалгах ёстой эвэнт (event) үнэн зөв (non-zero) утга автал хүлээж саатна (блоклоно). Хэрэв түүний шалгах ёстой эвэнт болохоос өмнө заагдсан хугацааны интервал дуусвал select() 0 утга буцааж, шалгалтаа дуусгана. select()-д ашиглагдах хугацааны интервал нь бусад alarm(), ualarm(), settimer() зэрэг функцүүдээр тавигдсан таймерийн (timer) ажиллагаанд нөлөөлөхгүй. Функцын амжилттай төгссөн тохиолдолд timeout аргументаар заагдаж байсан обьектын утга өөрчлөгдсөн байх талтай.
Хэрэв readfds, writefds, errorfds аргументууд бүгд тэг заагч, харин timeout аргумент тэг заагч биш бол select() заагдсан хугацааны интервал өнгөртөл саатна эсвэл сигналаар ажиллагаа нь тасалдана. Харин эдгээр бүх аргументууд бүгд тэг заагч бол select()-н ажиллагаа зөвхөн сигналаар тасалдана.
Ердийн файлын файл тодорхойлогч ямар ч тохиолдолд уншихад бэлэн, бичихэд бэлэн, алдаатай гэсэн сонголтыг буцаана.
Хэрэв select() амжилтгүй гүйцэтгэгдвэл readfds, writefds, errorfds аргументуудын зааж буй обьектуудын утга өөрчлөгдөхгүй. Хэрэв заагдсан хугацааны интервал шалгагдах нөхцөл биелэхээс өмнө өнгөрвөл readfds, writefds, errorfds аргументын зааж буй обьектууд 0 утга авна.
Өгөгдсөн файл тодорхойлогчуудыг масклах fd_set төрлийн маскууд нь дараахь командаар тохируулагдах ба шалгагдана: FD_CLR(), FD_SET(), FD_ISSET(), FD_ZERO(). Эдгээр нь функц эсвэл макро гэдэг нь тодорхойгүй.
FD_CLR(fd, &fdset) - fdset дэх fd файл тодорхойлогчид харгалзах битийг тэглэнэ (цэвэрлэнэ).
FD_SET(fd, &fdset) - fdset дэх fd файл тодорхойлогчид харгалзах битийг нэглэнэ (тавина).
FD_ISSET(fd, &fdset) - хэрэв fdset дэх fd файл тодорхойлогчид харгалзах бит тавигдсан (нэглэсэн) бол тэгээс ялгаатай утга, үгүй бол 0 утга буцаана.
FD_ZERO(&fdset) - fdset дэх бүх файл тодорхойлогчид харгалзах битийн утгыг тэглэнэ (цэвэрлэнэ).
Хэрэв fd аргументын утга 0-с бага эсвэл FD_SETSIZE-тай тэнцүү буюу түүнээс их байвал (fd < 0, fd >= FD_SETSIZE) эдгээр командууд заагдсан ёсоор биш, харин тодорхойгүй байдлаар ажиллана.
FD_CLR(), FD_SET(), FD_ZERO() командууд ямар ч утга буцаахгүй, харин FD_ISSET() команд fdset дэх fd-д харгалзах битийн утгаас хамаарч 1 эсвэл 0 гэсэн утгыг буцаана.
Хэрэв select() амжилттай биелэгдсэн тохиолдолд бит маскад тавигдсан (нэглэгдсэн) битийн тоотой тэнцүү утга буцаана. Эсрэг тохиолдолд -1 утгыг буцааж, errno-г нэглэнэ.
Source: http://www.opengroup.org/onlinepubs/007908799/xsh/select.html
#include < sys/time.h>
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *errorfds, struct timeval *timeout);
void FD_CLR(int fd, fd_set *fdset);
int FD_ISSET(int fd, fd_set *fdset);
void FD_SET(int fd, fd_set *fdset);
void FD_ZERO(fd_set *fdset);
Энэ select() функц нь өгөгдсөн файл тодорхойлогчуудын (file descriptor) аль нь уншихад бэлэн, эсвэл бичихэд бэлэн, эсвэл алдаатай байгааг заана. Хэрэв өгөгдсөн файл тодорхойлогчуудын хувьд заагдсан нөхцөл хангагдаагүй (FALSE) байвал эдгээр файл тодорхойлогчуудын аль нэг дээр заагдсан нөхцөл биелэх хүртэл заасан хугацааг дуустал саатна.
select() функц нь ердийн файлууд, терминал төхөөрөмжүүд, STREAMS файлууд, FIFO төхөөрөмж, pipe төхөөрөмжүүдтэй ажиллах чадвартай.
nfds аргумент нь шалгагдах/тестлэгдэх файл тодорхойлогчдын хязгаарыг заана. Өөрөөр хэлбэл 0-с nfds-1 хязгаарт багтсан файл тодорхойлогчууд шалгагдана.
Хэрэв readfds аргумент нь тэг заагч (null pointer) биш бол, оролтон дээр уншихад бэлнийг нь шалгах файл тодорхойлогчуудыг, гаралтан дээр уншихад бэлэн болсон файл тодорхойлогчуудыг заана. Эдгээр файл тодорхойлуулагчууд нь fd_set төрлийнх байна.
Хэрэв writefds аргумент нь тэг заагч (null pointer) биш бол, оролтон дээр бичихэд бэлнийг нь шалгах файл тодорхойлогчуудыг, гаралтан дээр бичихэд бэлэн болсон файл тодорхойлогчуудыг заана. Эдгээр файл тодорхойлуулагчууд нь мөн адил fd_set төрлийнх байна.
Хэрэв errorfds аргумент нь тэг заагч (null pointer) биш бол, оролтон дээр алдаатай эсэхийг нь шалгах файл тодорхойлогчуудыг, гаралтан дээр алдаа гараад хүлээгдэж байгаа файл тодорхойлогчуудыг заана. Эдгээр файл тодорхойлуулагчууд нь мөн адил fd_set төрлийнх байна.
select() хэвийн гүйцэтгэгдвэл readfds, writefds, errorfds заагчуудын зааж байгаа обьектууд тус бүр уншихад, бичихэд, эсвэл алдаатай файл тодорхойлогчуудыг зааж өөрчлөгдөнө. Мөн энэ тохиолдолд бас nfds хязгаарт багтсан файл тодорхойлогч бүрийн хувьд харгалзах бит нь 1 болно. Үүний тулд оролтонд уг харгалзах бит 1 гэж тавигдсан, тэгээд шалгалт/тестээр файл тодорхойлогчуудад харгалзах нөхцөлүүдээс (уншихад, бичихэд бэлэн, эсвэл алдаатай) биелсэн байх ёстой.
Хэрэв timeout аргумент нь тэг заагч (null pointer) биш бол, энэ аргумент select() функцыг биелж дуусахыг заасан хугацааны интервалыг агуулсан обьектыг заах ба уг обьектын төрөл нь struct timeval байх ёстой. Хэрэв timeout аргументын зааж байгаа struct timeval төрлийн обьектын гишүүд нь 0 утгатай бол select() ерөөсөө саатахгүй (блоклохгүй). Хэрэв timeout аргумент тэг заагч (null pointer) бол select() функц түүний шалгах ёстой эвэнт (event) үнэн зөв (non-zero) утга автал хүлээж саатна (блоклоно). Хэрэв түүний шалгах ёстой эвэнт болохоос өмнө заагдсан хугацааны интервал дуусвал select() 0 утга буцааж, шалгалтаа дуусгана. select()-д ашиглагдах хугацааны интервал нь бусад alarm(), ualarm(), settimer() зэрэг функцүүдээр тавигдсан таймерийн (timer) ажиллагаанд нөлөөлөхгүй. Функцын амжилттай төгссөн тохиолдолд timeout аргументаар заагдаж байсан обьектын утга өөрчлөгдсөн байх талтай.
Хэрэв readfds, writefds, errorfds аргументууд бүгд тэг заагч, харин timeout аргумент тэг заагч биш бол select() заагдсан хугацааны интервал өнгөртөл саатна эсвэл сигналаар ажиллагаа нь тасалдана. Харин эдгээр бүх аргументууд бүгд тэг заагч бол select()-н ажиллагаа зөвхөн сигналаар тасалдана.
Ердийн файлын файл тодорхойлогч ямар ч тохиолдолд уншихад бэлэн, бичихэд бэлэн, алдаатай гэсэн сонголтыг буцаана.
Хэрэв select() амжилтгүй гүйцэтгэгдвэл readfds, writefds, errorfds аргументуудын зааж буй обьектуудын утга өөрчлөгдөхгүй. Хэрэв заагдсан хугацааны интервал шалгагдах нөхцөл биелэхээс өмнө өнгөрвөл readfds, writefds, errorfds аргументын зааж буй обьектууд 0 утга авна.
Өгөгдсөн файл тодорхойлогчуудыг масклах fd_set төрлийн маскууд нь дараахь командаар тохируулагдах ба шалгагдана: FD_CLR(), FD_SET(), FD_ISSET(), FD_ZERO(). Эдгээр нь функц эсвэл макро гэдэг нь тодорхойгүй.
FD_CLR(fd, &fdset) - fdset дэх fd файл тодорхойлогчид харгалзах битийг тэглэнэ (цэвэрлэнэ).
FD_SET(fd, &fdset) - fdset дэх fd файл тодорхойлогчид харгалзах битийг нэглэнэ (тавина).
FD_ISSET(fd, &fdset) - хэрэв fdset дэх fd файл тодорхойлогчид харгалзах бит тавигдсан (нэглэсэн) бол тэгээс ялгаатай утга, үгүй бол 0 утга буцаана.
FD_ZERO(&fdset) - fdset дэх бүх файл тодорхойлогчид харгалзах битийн утгыг тэглэнэ (цэвэрлэнэ).
Хэрэв fd аргументын утга 0-с бага эсвэл FD_SETSIZE-тай тэнцүү буюу түүнээс их байвал (fd < 0, fd >= FD_SETSIZE) эдгээр командууд заагдсан ёсоор биш, харин тодорхойгүй байдлаар ажиллана.
FD_CLR(), FD_SET(), FD_ZERO() командууд ямар ч утга буцаахгүй, харин FD_ISSET() команд fdset дэх fd-д харгалзах битийн утгаас хамаарч 1 эсвэл 0 гэсэн утгыг буцаана.
Хэрэв select() амжилттай биелэгдсэн тохиолдолд бит маскад тавигдсан (нэглэгдсэн) битийн тоотой тэнцүү утга буцаана. Эсрэг тохиолдолд -1 утгыг буцааж, errno-г нэглэнэ.
Source: http://www.opengroup.org/onlinepubs/007908799/xsh/select.html
Tuesday, February 9, 2010
Signal handling (Сигнал боловсруулах)
С программчлалаас:
Сигнал гэдэг нь програм ажиллаж явцад үүсч болох онцгой нөхцөлийг (exceptional condition) хэлнэ. Тухайлбал тасалдал (interrupt), программын ажиллах явцад гарах алдаа (run-time error), эсвэл гаднаас үүсэлтэй нөхцөлүүд (program termination/break) байж болно. Сигналтай ажиллах 2 функц, мөн сигналуудын төрлийг "signal.h" гэсэн толгой файлд тодорхойлсон байдаг.
Дараахь сигналын төрлүүд тодорхойлогдсон байдаг:
SIGABRT - Abort буюу програмын хэвийн бус тасралт (abnormal termination). Жишээ нь abort() функцээр үүснэ.
SIGFPE - Floating point exception буюу алдаатай арифметик үйлдлүүд. Жишээ нь тэгд хуваах, эсвэл дүүрэлт г.м.
SIGILL - Illegal instruction буюу програм зөвшөөрөгдөөгүй/танигдахгүй инструкц (процессорын код) агуулсныг мэдээллэнэ.
SIGINT - Interrupt буюу програмын ажиллагааг зогсоох хүсэлтийн гараас буюу терминалаас тавьсныг мэдээллэнэ.
SIGSEGV - Segment violation буюу хадгалах төхөөрөмж (storage) руу хандсан хандалт буруу хийгдсэнийг мэдээллэнэ. Жишээ нь санах ойн хязгаараас давсан хандалт хийх.
SIGTERM - Terminate буюу програмыг зогсоох хүсэлт хийгдсэнийг мэдээллэнэ.
Дээрх стандарт сигналуудаас гадна өөр сигналыг нэмж тодорхойлох боломжтой. Тэр тохиолдолд сигналын нэр заавал SIG гэсэн эхлэлтэй байх ёстой.
#include
void (*signal(int sig, void (*handler)(int)))(int)
signal() фунцк нь sig сигналыг хүлээн авсан үед ямар функцыг (handler()) түүний боловсруулагчаар сонгохыг тохируулна. Уг боловсруулагч функцын аргумент нь тухайн сигнал байж болно. signal() функцын 2 дахь аргументэд SIG_DFL, SIG_IGN гэсэн тусгай утгыг бас оноож өгч болно. Эхнийх нь сигналыг системд урьдчилан зааж өгсөн байдлаар боловсруулах бол дараагийнх нь сигналыг боловсруулахгүйгээр орхино.
signal() функцээр сигнал болон түүнийг боловсруулагч функцын оноолт амжилттай хийгдсэн тохиолдолд боловсруулагч функцын (handler()) өмнөх утга буцна, харин оноолт хийгдэж чадаагүй бол SIG_ERR гэсэн утга буцах ба errno-н утга 1 болно.
Ямар нэгэн сигнал мэдээлэгдвэл, эхлээд програмын ажиллагаа зогсоно. Энэ нь signal(sig, SIG_DFL) гэсэн оноолттой адил шинжтэй. Дараа нь хэрэв тухайн сигналд боловсруулагч функц оноогдсон байвал уг функцыг дуудаж ажиллуулна. Боловсруулагч функц ажиллагаагаа хэвийн дуусгасан тохиолдолд програмын ажиллагаа зогссон цэгээсээ үргэлжлэн ажиллана. Хэрэв сигналын төрөл SIGFPE байсан бол програм үргэлжлэн ажиллахгүй, харин тодорхой байдалд орно. Иймээс SIGFPE сигнал боловсруулах функцууд нь ямагт abort, exit, эсвэл longjump гэсэн функцуудыг агуулсан байх хэрэгтэй.
Програм өөрөө сигналыг мэдээллэх шаардлага заримдаа гардаг. Энэ тохиолдолд raise() функцыг хэрэглэнэ.
#include
int raise (int sig);
Хэрэв raise() функц амжилттай биелэгдвэл 0 утга, үгүй бол тэгээс ялгаатай утга буцаана.
Дараахь жишээ програмд interrupt сигнал хүлээн авсан тохиолдолд програмын ажиллагааг хэрхэн зогсоож байгааг харууллаа.
#include < stdio.h>
#include < stdlib.h>
#include < signal.h>
FILE *temp_file;
void leave(int sig);
main() {
/* сигнал, түүнийг боловсруулагч функцын оноолтыг хийх */
(void) signal(SIGINT,leave);
/* tmp файлыг бичихээр нээх */
temp_file = fopen("tmp","w");
for(;;) {
/* ямар нэг үйлдэл хийх */
printf("Ready...\n");
/* гараас унших */
(void)getchar();
}
/* програм энд хэзээ ч хүрэхгүй ... */
exit(EXIT_SUCCESS);
}
/*
* SIGINT сигналыг хүлээн авмагц, tmp файлыг хаана
* гэхдээ стандарт функцыг (fprintf, fclose) сигнал боловсруулагчаас
* дуудах нь бүх тохиолдолд ажиллах баталгаагүй, энэ нь тухайн системээс
* хамаарна. Тиймээс энэ код ажиллахгүй бол гайхах хэрэггүй.
*/
void
leave(int sig) {
fprintf(temp_file,"\nInterrupted..\n");
fclose(temp_file);
exit(sig);
}
Сигнал гэдэг нь програм ажиллаж явцад үүсч болох онцгой нөхцөлийг (exceptional condition) хэлнэ. Тухайлбал тасалдал (interrupt), программын ажиллах явцад гарах алдаа (run-time error), эсвэл гаднаас үүсэлтэй нөхцөлүүд (program termination/break) байж болно. Сигналтай ажиллах 2 функц, мөн сигналуудын төрлийг "signal.h" гэсэн толгой файлд тодорхойлсон байдаг.
Дараахь сигналын төрлүүд тодорхойлогдсон байдаг:
SIGABRT - Abort буюу програмын хэвийн бус тасралт (abnormal termination). Жишээ нь abort() функцээр үүснэ.
SIGFPE - Floating point exception буюу алдаатай арифметик үйлдлүүд. Жишээ нь тэгд хуваах, эсвэл дүүрэлт г.м.
SIGILL - Illegal instruction буюу програм зөвшөөрөгдөөгүй/танигдахгүй инструкц (процессорын код) агуулсныг мэдээллэнэ.
SIGINT - Interrupt буюу програмын ажиллагааг зогсоох хүсэлтийн гараас буюу терминалаас тавьсныг мэдээллэнэ.
SIGSEGV - Segment violation буюу хадгалах төхөөрөмж (storage) руу хандсан хандалт буруу хийгдсэнийг мэдээллэнэ. Жишээ нь санах ойн хязгаараас давсан хандалт хийх.
SIGTERM - Terminate буюу програмыг зогсоох хүсэлт хийгдсэнийг мэдээллэнэ.
Дээрх стандарт сигналуудаас гадна өөр сигналыг нэмж тодорхойлох боломжтой. Тэр тохиолдолд сигналын нэр заавал SIG гэсэн эхлэлтэй байх ёстой.
#include
void (*signal(int sig, void (*handler)(int)))(int)
signal() фунцк нь sig сигналыг хүлээн авсан үед ямар функцыг (handler()) түүний боловсруулагчаар сонгохыг тохируулна. Уг боловсруулагч функцын аргумент нь тухайн сигнал байж болно. signal() функцын 2 дахь аргументэд SIG_DFL, SIG_IGN гэсэн тусгай утгыг бас оноож өгч болно. Эхнийх нь сигналыг системд урьдчилан зааж өгсөн байдлаар боловсруулах бол дараагийнх нь сигналыг боловсруулахгүйгээр орхино.
signal() функцээр сигнал болон түүнийг боловсруулагч функцын оноолт амжилттай хийгдсэн тохиолдолд боловсруулагч функцын (handler()) өмнөх утга буцна, харин оноолт хийгдэж чадаагүй бол SIG_ERR гэсэн утга буцах ба errno-н утга 1 болно.
Ямар нэгэн сигнал мэдээлэгдвэл, эхлээд програмын ажиллагаа зогсоно. Энэ нь signal(sig, SIG_DFL) гэсэн оноолттой адил шинжтэй. Дараа нь хэрэв тухайн сигналд боловсруулагч функц оноогдсон байвал уг функцыг дуудаж ажиллуулна. Боловсруулагч функц ажиллагаагаа хэвийн дуусгасан тохиолдолд програмын ажиллагаа зогссон цэгээсээ үргэлжлэн ажиллана. Хэрэв сигналын төрөл SIGFPE байсан бол програм үргэлжлэн ажиллахгүй, харин тодорхой байдалд орно. Иймээс SIGFPE сигнал боловсруулах функцууд нь ямагт abort, exit, эсвэл longjump гэсэн функцуудыг агуулсан байх хэрэгтэй.
Програм өөрөө сигналыг мэдээллэх шаардлага заримдаа гардаг. Энэ тохиолдолд raise() функцыг хэрэглэнэ.
#include
int raise (int sig);
Хэрэв raise() функц амжилттай биелэгдвэл 0 утга, үгүй бол тэгээс ялгаатай утга буцаана.
Дараахь жишээ програмд interrupt сигнал хүлээн авсан тохиолдолд програмын ажиллагааг хэрхэн зогсоож байгааг харууллаа.
#include < stdio.h>
#include < stdlib.h>
#include < signal.h>
FILE *temp_file;
void leave(int sig);
main() {
/* сигнал, түүнийг боловсруулагч функцын оноолтыг хийх */
(void) signal(SIGINT,leave);
/* tmp файлыг бичихээр нээх */
temp_file = fopen("tmp","w");
for(;;) {
/* ямар нэг үйлдэл хийх */
printf("Ready...\n");
/* гараас унших */
(void)getchar();
}
/* програм энд хэзээ ч хүрэхгүй ... */
exit(EXIT_SUCCESS);
}
/*
* SIGINT сигналыг хүлээн авмагц, tmp файлыг хаана
* гэхдээ стандарт функцыг (fprintf, fclose) сигнал боловсруулагчаас
* дуудах нь бүх тохиолдолд ажиллах баталгаагүй, энэ нь тухайн системээс
* хамаарна. Тиймээс энэ код ажиллахгүй бол гайхах хэрэггүй.
*/
void
leave(int sig) {
fprintf(temp_file,"\nInterrupted..\n");
fclose(temp_file);
exit(sig);
}
Subscribe to:
Posts (Atom)