[<<] [<] Page 1 of 1 [>] [>>] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Subject:
Linux Daemon HOWTO
From: Devin Watson ####@####.#### Date: 18 May 2004 22:56:24 -0000 Message-Id: <1084920957.23696.19.camel@PVR> Everyone - I've written a somewhat short but informative introduction into writing daemons in Linux. I noticed that this isn't really out there right now, and I thought I'd at least try my hand at writing this. The SGML (LinuxDoc) file can be found at: http://www.linuxprofilm.com/articles/linux-daemon-howto.sgml I've also got HTML and PDF versions there: http://www.linuxprofilm.com/articles/linux-daemon-howto.html http://www.linuxprofilm.com/articles/linux-daemon-howto.pdf I'd like any suggestions and feedback on this. -Devin Watson | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Subject:
Re: Linux Daemon HOWTO
From: Charles Curley ####@####.#### Date: 18 May 2004 23:45:40 -0000 Message-Id: <20040518234534.GB20761@charlescurley.com> On Tue, May 18, 2004 at 06:55:57PM -0400, Devin Watson wrote: > Everyone - > > I've written a somewhat short but informative introduction into writing > daemons in Linux. I noticed that this isn't really out there right now, > and I thought I'd at least try my hand at writing this. > > The SGML (LinuxDoc) file can be found at: > > http://www.linuxprofilm.com/articles/linux-daemon-howto.sgml > > I've also got HTML and PDF versions there: > > http://www.linuxprofilm.com/articles/linux-daemon-howto.html > http://www.linuxprofilm.com/articles/linux-daemon-howto.pdf > > I'd like any suggestions and feedback on this. Don't forget to add a copyright statement and license, both for the LDP's protection and for your own. It's been a while since I engaged in daemonology :-), but shouldn't this: /* Open any logs here */ /* Change the current working directory */ if ((chdir("/")) < 0) { exit(EXIT_FAILURE); } be: /* Open any logs here */ /* Change the current working directory */ if ((chdir("/")) < 0) { /* Log failure, then close logs */ exit(EXIT_FAILURE); } You should probably log the failure so that the user knows she doesn't have a necessary directory. In that case, if you are handling your log files yourself, you have to close them gracefully before you exit so that the last few entries are preserved. Also, I doubt you want a daemon to run in /. I'm not sure how you open log files in daemons in Linux, but shouldn't you set umask before you open a log file? These are nit picks. The code you have shows how to do it. As this is an instructional article, the code should not get loaded down with error checking to the point that it obscures your main point. You might suggest ways to tighten up the code at the end. I like it. It's short, sweet and to the point. The user can go from there. Well done. -- Charles Curley /"\ ASCII Ribbon Campaign Looking for fine software \ / Respect for open standards and/or writing? X No HTML/RTF in email http://www.charlescurley.com / \ No M$ Word docs in email Key fingerprint = CE5C 6645 A45A 64E4 94C0 809C FFF6 4C48 4ECD DFDB --> --> |
<type 'exceptions.IOError'> | Python 2.5.2: /usr/bin/python Sat Jul 6 03:36:13 2024 |
A problem occurred in a Python script. Here is the sequence of function calls leading up to the error, in the order they occurred.
/opt/ezmlm-browse-0.20/<string> in |
/opt/ezmlm-browse-0.20/main.py in main() |
424 |
425 if path is not None: |
426 main_path(path) |
427 else: |
428 main_form() |
global main_form = <function main_form at 0x9332c6c> |
/opt/ezmlm-browse-0.20/main.py in main_form() |
378 except ImportError: |
379 die(ctxt, "Invalid command") |
380 module.do(ctxt) |
381 |
382 def main(): |
module = <module 'commands.showthread' from '/opt/ezmlm-browse-0.20/commands/showthread.pyc'>, module.do = <function do at 0x933b844>, global ctxt = {'HTTP_X_FORWARDED_SERVER': 'glitch', 'HTTP_REFE...HTTP_ACCEPT_ENCODING': 'gzip, br, zstd, deflate'} |
/opt/ezmlm-browse-0.20/commands/showthread.py in do(ctxt={'HTTP_X_FORWARDED_SERVER': 'glitch', 'HTTP_REFE...HTTP_ACCEPT_ENCODING': 'gzip, br, zstd, deflate'}) |
9 ctxt.update(ezmlm.thread(ctxt[THREADID])) |
10 header(ctxt, 'Thread: ' + ctxt[SUBJECT], 'showthread') |
11 do_list(ctxt, 'msgs', ctxt[MSGSPERPAGE], ctxt[MESSAGES], |
12 lambda:sub_showmsg(ctxt, ctxt[MSGNUM])) |
13 footer(ctxt) |
global sub_showmsg = <function sub_showmsg at 0x93321ec>, ctxt = {'HTTP_X_FORWARDED_SERVER': 'glitch', 'HTTP_REFE...HTTP_ACCEPT_ENCODING': 'gzip, br, zstd, deflate'}, global MSGNUM = 'msgnum' |
/opt/ezmlm-browse-0.20/globalfns.py in do_list(ctxt={'HTTP_X_FORWARDED_SERVER': 'glitch', 'HTTP_REFE...HTTP_ACCEPT_ENCODING': 'gzip, br, zstd, deflate'}, name='msgs', perpage=10, values=[{'author': u'Devin Watson', 'authorid': 'hpddcdpgimaaaodmebkg', 'date': '18 May 2004 22:56:24 -0000', 'month': 200405, 'msgnum': 7301, 'subject': u'Linux Daemon HOWTO', 'threadid': 'pabfjdhhafocknlohihp', 'timestamp': 1084920984.0}, {'author': u'Charles Curley', 'authorid': 'fbacfjfdkmpbdhgmbbhp', 'date': '18 May 2004 23:45:40 -0000', 'month': 200405, 'msgnum': 7302, 'subject': u'Re: Linux Daemon HOWTO', 'threadid': 'pabfjdhhafocknlohihp', 'timestamp': 1084923940.0}, {'author': u'Colin Watson', 'authorid': 'apcdgkbgafajaibhibkf', 'date': '19 May 2004 16:37:20 -0000', 'month': 200405, 'msgnum': 7306, 'subject': u'Re: Linux Daemon HOWTO', 'threadid': 'pabfjdhhafocknlohihp', 'timestamp': 1084984640.0}, {'author': u'Devin Watson', 'authorid': 'hpddcdpgimaaaodmebkg', 'date': '19 May 2004 22:30:19 -0000', 'month': 200405, 'msgnum': 7307, 'subject': u'Re: Linux Daemon HOWTO', 'threadid': 'pabfjdhhafocknlohihp', 'timestamp': 1085005819.0}, {'author': u'Devin Watson', 'authorid': 'hpddcdpgimaaaodmebkg', 'date': '19 May 2004 23:24:19 -0000', 'month': 200405, 'msgnum': 7308, 'subject': u'Re: Linux Daemon HOWTO', 'threadid': 'pabfjdhhafocknlohihp', 'timestamp': 1085009059.0}], peritem=<function <lambda> at 0x933b9cc>) |
128 write(template % ctxt) |
129 if peritem: |
130 peritem() |
131 ctxt[ROW] += 1 |
132 |
peritem = <function <lambda> at 0x933b9cc> |
/opt/ezmlm-browse-0.20/commands/showthread.py in |
9 ctxt.update(ezmlm.thread(ctxt[THREADID])) |
10 header(ctxt, 'Thread: ' + ctxt[SUBJECT], 'showthread') |
11 do_list(ctxt, 'msgs', ctxt[MSGSPERPAGE], ctxt[MESSAGES], |
12 lambda:sub_showmsg(ctxt, ctxt[MSGNUM])) |
13 footer(ctxt) |
global sub_showmsg = <function sub_showmsg at 0x93321ec>, ctxt = {'HTTP_X_FORWARDED_SERVER': 'glitch', 'HTTP_REFE...HTTP_ACCEPT_ENCODING': 'gzip, br, zstd, deflate'}, global MSGNUM = 'msgnum' |
/opt/ezmlm-browse-0.20/globalfns.py in sub_showmsg(ctxt={'HTTP_X_FORWARDED_SERVER': 'glitch', 'HTTP_REFE...HTTP_ACCEPT_ENCODING': 'gzip, br, zstd, deflate'}, msgnum=7302) |
229 format_timestamp(ctxt, ctxt) |
230 write(html('msg-header') % ctxt) |
231 rec_showpart(ctxt, msg, 0) |
232 write(html('msg-footer') % ctxt) |
233 ctxt.pop() |
global rec_showpart = <function rec_showpart at 0x93321b4>, ctxt = {'HTTP_X_FORWARDED_SERVER': 'glitch', 'HTTP_REFE...HTTP_ACCEPT_ENCODING': 'gzip, br, zstd, deflate'}, msg = <email.message.Message instance at 0x9390ecc> |
/opt/ezmlm-browse-0.20/globalfns.py in rec_showpart(ctxt={'HTTP_X_FORWARDED_SERVER': 'glitch', 'HTTP_REFE...HTTP_ACCEPT_ENCODING': 'gzip, br, zstd, deflate'}, part=<email.message.Message instance at 0x9390ecc>, partnum=1) |
205 else: |
206 for p in part.get_payload(): |
207 partnum = rec_showpart(ctxt, p, partnum+1) |
208 else: |
209 write(html('msg-sep') % ctxt) |
partnum = 1, global rec_showpart = <function rec_showpart at 0x93321b4>, ctxt = {'HTTP_X_FORWARDED_SERVER': 'glitch', 'HTTP_REFE...HTTP_ACCEPT_ENCODING': 'gzip, br, zstd, deflate'}, p = <email.message.Message instance at 0x93970cc> |
/opt/ezmlm-browse-0.20/globalfns.py in rec_showpart(ctxt={'HTTP_X_FORWARDED_SERVER': 'glitch', 'HTTP_REFE...HTTP_ACCEPT_ENCODING': 'gzip, br, zstd, deflate'}, part=<email.message.Message instance at 0x93970cc>, partnum=2) |
208 else: |
209 write(html('msg-sep') % ctxt) |
210 sub_showpart(ctxt, part) |
211 return partnum |
212 |
global sub_showpart = <function sub_showpart at 0x9332144>, ctxt = {'HTTP_X_FORWARDED_SERVER': 'glitch', 'HTTP_REFE...HTTP_ACCEPT_ENCODING': 'gzip, br, zstd, deflate'}, part = <email.message.Message instance at 0x93970cc> |
/opt/ezmlm-browse-0.20/globalfns.py in sub_showpart(ctxt={'HTTP_X_FORWARDED_SERVER': 'glitch', 'HTTP_REFE...HTTP_ACCEPT_ENCODING': 'gzip, br, zstd, deflate'}, part=<email.message.Message instance at 0x93970cc>) |
164 type = ctxt[TYPE] = part.get_content_type() |
165 ctxt[FILENAME] = part.get_filename() |
166 template = html('msg-' + type.replace('/', '-')) |
167 if not template: |
168 template = html('msg-' + type[:type.find('/')]) |
global template = <function template at 0x932ae9c>, global html = <function html at 0x932aed4>, type = 'application/pgp-signature', type.replace = <built-in method replace of str object at 0x9399020> |
/opt/ezmlm-browse-0.20/globalfns.py in html(name='msg-application-pgp-signature') |
40 |
41 def html(name): |
42 return template(name + '.html') |
43 |
44 def xml(name): |
global template = <function template at 0x932ae9c>, name = 'msg-application-pgp-signature' |
/opt/ezmlm-browse-0.20/globalfns.py in template(filename='msg-application-pgp-signature.html') |
31 except IOError: |
32 if not _template_zipfile: |
33 _template_zipfile = zipfile.ZipFile(sys.argv[0]) |
34 try: |
35 f = _template_zipfile.open(n).read() |
global _template_zipfile = None, global zipfile = <module 'zipfile' from '/usr/lib/python2.5/zipfile.pyc'>, zipfile.ZipFile = <class zipfile.ZipFile at 0x92c3a7c>, global sys = <module 'sys' (built-in)>, sys.argv = ['-c', '/opt/ezmlm-browse-0.20'] |
/usr/lib/python2.5/zipfile.py in __init__(self=<zipfile.ZipFile instance at 0x9390e4c>, file='-c', mode='r', compression=0, allowZip64=False) |
337 self.filename = file |
338 modeDict = {'r' : 'rb', 'w': 'wb', 'a' : 'r+b'} |
339 self.fp = open(file, modeDict[mode]) |
340 else: |
341 self._filePassed = 1 |
self = <zipfile.ZipFile instance at 0x9390e4c>, self.fp = None, builtin open = <built-in function open>, file = '-c', modeDict = {'a': 'r+b', 'r': 'rb', 'w': 'wb'}, mode = 'r' |
<type 'exceptions.IOError'>: [Errno 2] No such file or directory: '-c'
args =
(2, 'No such file or directory')
errno =
2
filename =
'-c'
message =
''
strerror =
'No such file or directory'