Re: [Chicken-users] daemonize egg: redirect I/O?
On Wed, Oct 31, 2007 at 07:44:19AM +0100, felix winkelmann wrote: On 10/31/07, Ozzi [EMAIL PROTECTED] wrote: Ok, I think I understand what you're getting it. Unfortunately I can't get it to work. You'll have to excuse the thrown-together quality of the code below, but it demonstrates the problem I have. Perhaps I am just mis-using dynamic-wind, or I have to use something besides (exit) when catching the kill signal, I'm not sure. The exit will not invoke any pending dynamic-wind thunks Why not? Shouldn't it? IMHO it violates POLA not to do so. Peter -- http://sjamaan.ath.cx -- The process of preparing programs for a digital computer is especially attractive, not only because it can be economically and scientifically rewarding, but also because it can be an aesthetic experience much like composing poetry or music. -- Donald Knuth pgp5OzvgVSZaM.pgp Description: PGP signature ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] daemonize egg: redirect I/O?
On 10/31/07, Peter Bex [EMAIL PROTECTED] wrote: The exit will not invoke any pending dynamic-wind thunks Why not? Shouldn't it? IMHO it violates POLA not to do so. Because it might not be desired. It shouldn't. And I don't know who POLA is, nor did I meeet her before. cheers, felix ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] daemonize egg: redirect I/O?
On Wed, Oct 31, 2007 at 10:24:44AM +0100, felix winkelmann wrote: On 10/31/07, Peter Bex [EMAIL PROTECTED] wrote: The exit will not invoke any pending dynamic-wind thunks Why not? Shouldn't it? IMHO it violates POLA not to do so. Because it might not be desired. Why wouldn't it if you use dynamic-wind? The thunk is exited by calling (exit), isn't it? So I would *expect* it to call the 'after' part of the dynamic-wind. Just from reading the standard I would never consider the possibility that a program ever leaves the thunk without calling the 'after' part. People use dynamic-wind because they *want* the 'after' part to be called whenever the thunk is exited. It shouldn't. And I don't know who POLA is, nor did I meeet her before. $ wtf is POLA POLA: principle of least astonishment Peter -- http://sjamaan.ath.cx -- The process of preparing programs for a digital computer is especially attractive, not only because it can be economically and scientifically rewarding, but also because it can be an aesthetic experience much like composing poetry or music. -- Donald Knuth pgpWy7EVmf7uD.pgp Description: PGP signature ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] daemonize egg: redirect I/O?
On 10/31/07, Peter Bex [EMAIL PROTECTED] wrote: On Wed, Oct 31, 2007 at 10:24:44AM +0100, felix winkelmann wrote: On 10/31/07, Peter Bex [EMAIL PROTECTED] wrote: The exit will not invoke any pending dynamic-wind thunks Why not? Shouldn't it? IMHO it violates POLA not to do so. Because it might not be desired. Why wouldn't it if you use dynamic-wind? The thunk is exited by calling (exit), isn't it? So I would *expect* it to call the 'after' part of the dynamic-wind. Just from reading the standard I would never consider the possibility that a program ever leaves the thunk without calling the 'after' part. People use dynamic-wind because they *want* the 'after' part to be called whenever the thunk is exited. I guess we disagree here. cheers, felix ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] daemonize egg: redirect I/O?
On Wed, Oct 31, 2007 at 11:23:59AM +0100, felix winkelmann wrote: Why wouldn't it if you use dynamic-wind? The thunk is exited by calling (exit), isn't it? So I would *expect* it to call the 'after' part of the dynamic-wind. Just from reading the standard I would never consider the possibility that a program ever leaves the thunk without calling the 'after' part. People use dynamic-wind because they *want* the 'after' part to be called whenever the thunk is exited. I guess we disagree here. Well, so be it. I'll add a note to 'extensions to the standard' and the documentation of 'exit' because I'm sure there are more people out there who are not aware of this. Cheers, Peter -- http://sjamaan.ath.cx -- The process of preparing programs for a digital computer is especially attractive, not only because it can be economically and scientifically rewarding, but also because it can be an aesthetic experience much like composing poetry or music. -- Donald Knuth pgpSFLgctP6im.pgp Description: PGP signature ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] daemonize egg: redirect I/O?
On 10/31/07, Peter Bex [EMAIL PROTECTED] wrote: Well, so be it. I'll add a note to 'extensions to the standard' and the documentation of 'exit' because I'm sure there are more people out there who are not aware of this. This has nothing to do with the standard. exit is not a standard procedure. Adding a note to the actual exit documentation is of course fine. Note that this is a highly subjective matter, and just because you think it is natural to do X, it doesn't necessarily have to be so for others. Personally, if I say (exit) I want to exit and not run through whatever handlers have been set up, there is too much hidden state expecting. The exit is explicit, not implicit (by falling off the end). Hooking into the exit procedures is possible via various means, if one wants to perform some cleanup. cheers, felix ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] daemonize egg: redirect I/O?
On Wed, Oct 31, 2007 at 12:09:27PM +0100, felix winkelmann wrote: On 10/31/07, Peter Bex [EMAIL PROTECTED] wrote: Well, so be it. I'll add a note to 'extensions to the standard' and the documentation of 'exit' because I'm sure there are more people out there who are not aware of this. This has nothing to do with the standard. exit is not a standard procedure. I understand that, but as I said before it is possible to read the standard in such a way that there is no possibility to ever execute a thunk without also executing the 'after' part. So the nonstandard 'exit' procedure interacts with the standard dynamic-wind procedure in a way that may or may not be expected depending on how you read the standard. Adding a note to the actual exit documentation is of course fine. Note that this is a highly subjective matter, and just because you think it is natural to do X, it doesn't necessarily have to be so for others. Absolutely. The key word is 'necessarily'. It may or it may not be expected. It is important to make the documentation crystal clear so that there will be no misundertandings. For people who understand it the way you do (as opposed to the way I do), the extra note will just a be a bit of additional clutter they can skip over when reading it. Cheers, Peter -- http://sjamaan.ath.cx -- The process of preparing programs for a digital computer is especially attractive, not only because it can be economically and scientifically rewarding, but also because it can be an aesthetic experience much like composing poetry or music. -- Donald Knuth pgpOPjVKqpz0Z.pgp Description: PGP signature ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] daemonize egg: redirect I/O?
Ozzi wrote: Thomas Christian Chust wrote: I think it would suffice for daemonize to wrap the call to the daemon's main procedure in a dynamic-wind block and call the cleanup function from the exit thunk. Unless the daemon procedure terminates itself with a low-level _exit or by sending itself a kill signal, the cleanup code should then always be executed. Ok, I think I understand what you're getting it. Unfortunately I can't get it to work. You'll have to excuse the thrown-together quality of the code below, but it demonstrates the problem I have. Perhaps I am just mis-using dynamic-wind, or I have to use something besides (exit) when catching the kill signal, I'm not sure. [...] Oops 8-( On my machine this fails as well -- I was apparently mistaken thinking that (exit) would honor dynamic-wind guards. In that case you could still use (on-exit CLEANUP-PROC), though. cu, Thomas ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] daemonize egg: redirect I/O?
Thomas Christian Chust wrote: I think it would suffice for daemonize to wrap the call to the daemon's main procedure in a dynamic-wind block and call the cleanup function from the exit thunk. Unless the daemon procedure terminates itself with a low-level _exit or by sending itself a kill signal, the cleanup code should then always be executed. Ok, I think I understand what you're getting it. Unfortunately I can't get it to work. You'll have to excuse the thrown-together quality of the code below, but it demonstrates the problem I have. Perhaps I am just mis-using dynamic-wind, or I have to use something besides (exit) when catching the kill signal, I'm not sure. (use posix) (define (silly-daemon) (dynamic-wind ;; Before: Create our test pid file. It's empty, that's ok. (lambda () (system touch /tmp/test.pid)) ;; Proc: Sleep a bit. (lambda () ;; Exit cleanly (?) on kill. (set-signal-handler! signal/term (lambda () (exit))) (sleep 5)) ;; After: Delete our test pid file. (lambda () (system rm /tmp/test.pid ;; Start silly-daemon. (let ((pid (process-fork silly-daemon))) ;; Wait long enough for silly-daemon to finish sleeping. (sleep 7) ;; See if it deleted the pid file. (if (file-exists? /tmp/test.pid) (print Failure!) (print Success!))) ;; Success! is printed. ;; Start silly-daemon. (let ((pid (process-fork silly-daemon))) ;; Wait a second, then... (sleep 1) ;; ...kill silly-daemon before it finishes sleeping. (system (format kill ~a pid)) ;; Wait a second before... (sleep 1) ;; ...checking to see if it deleted the pid file. (if (file-exists? /tmp/test.pid) (print Failure!) (print Success!))) ;; Failure! is printed. Thomas Christian Chust wrote: Ozzi wrote: cu, Thomas ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] daemonize egg: redirect I/O?
On 10/31/07, Ozzi [EMAIL PROTECTED] wrote: Ok, I think I understand what you're getting it. Unfortunately I can't get it to work. You'll have to excuse the thrown-together quality of the code below, but it demonstrates the problem I have. Perhaps I am just mis-using dynamic-wind, or I have to use something besides (exit) when catching the kill signal, I'm not sure. The exit will not invoke any pending dynamic-wind thunks, you can use reset instead. To clean up before exiting, you might also check use the on-exit procedure. cheers, felix ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] daemonize egg: redirect I/O?
I think it would suffice for daemonize to wrap the call to the daemon's main procedure in a dynamic-wind block and call the cleanup function from the exit thunk. Unless the daemon procedure terminates itself with a low-level _exit or by sending itself a kill signal, the cleanup code should then always be executed. Wouldn't this also call the exit thunk if the daemon proc itself ever issues a call-with-current-continuation? That sounds like unexpected behavior. -M ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] daemonize egg: redirect I/O?
Mark Fredrickson wrote: I think it would suffice for daemonize to wrap the call to the daemon's main procedure in a dynamic-wind block and call the cleanup function from the exit thunk. Unless the daemon procedure terminates itself with a low-level _exit or by sending itself a kill signal, the cleanup code should then always be executed. Wouldn't this also call the exit thunk if the daemon proc itself ever issues a call-with-current-continuation? That sounds like unexpected behavior. It would do so -- whether that is desired or not is probably a question of taste. cu, Thomas ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] daemonize egg: redirect I/O?
Ozzi wrote: Thomas Christian Chust wrote: I wonder why one would want to pass this cleanup argument to the daemon procedure -- why should the spawned process simply perform cleanup once the daemon procedure returns? The problem with that, as I see it, is that sometimes daemons don't get to return normally, i.e. if they get killed. Of course any proper daemon will implement signal handlers and such so that it will clean up after itself and exit gracefully. [...] I think it would suffice for daemonize to wrap the call to the daemon's main procedure in a dynamic-wind block and call the cleanup function from the exit thunk. Unless the daemon procedure terminates itself with a low-level _exit or by sending itself a kill signal, the cleanup code should then always be executed. cu, Thomas ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] daemonize egg: redirect I/O?
um, why not just use (duplicate-fileno (portfileno port)) ? or if its only stdin/stdout/stderr that youre worried about, calling (current-[input|output|error]-port) with an argument should change the value. the above three procs are parameters (re: the daemon question, i would just use (foreign-lambda int daemon int int) , but thats just me.) -elf On Fri, 26 Oct 2007, Thomas Christian Chust wrote: Ozzi wrote: I am working on for creating unix daemons. Can anyone tell me how to redirect stdout and stderr? I want to redirect them to /dev/null by default. Hello, such an egg would indeed be a useful addition :-) To redirect the standard file descriptors I would suggest to use the same technique as if one wanted to achieve this from C: (require-extension posix) (let ((null-device (file-open /dev/null (bitwise-ior open/read open/write (duplicate-fileno null-device fileno/stdin) (duplicate-fileno null-device fileno/stdout) (duplicate-fileno null-device fileno/stderr) (file-close null-device)) I would also be interested in comments on my plans for the egg in general. Presently, the interface is as follows: daemonize is a function that takes a daemon proc of one argument, that argument being a cleanup proc which the daemon proc should call before it exits. I wonder why one would want to pass this cleanup argument to the daemon procedure -- why should the spawned process simply perform cleanup once the daemon procedure returns? [...] Let me know what you think, and if you have any other ideas or suggestions. Apart from redirecting I/O, don't forget to also place your daemon process into its own process group so it doesn't get terminated when the parent process' group leader dies (see setsid(2) and daemon(3) in your system's manpages). [...] cu, Thomas ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] daemonize egg: redirect I/O?
Elf wrote: um, why not just use (duplicate-fileno (portfileno port)) ? [...] Because not the file descriptor of a given port should be duplicated but rather the file descriptor of a given port should be replaced by a duplicate of another one. Of course one could use (portfileno ...) instead of the fileno/... constants in my example, but it wouldn't make much of a difference, unless the ports were already set to something different from the standard -- but in that case it may not be such a good idea to redirect them. I think it makes much more sense to redirect those descriptors which are, by default, connected to the controlling terminal of the process, because they usually become useless after detaching from the original process group. (re: the daemon question, i would just use (foreign-lambda int daemon int int) , but thats just me.) Isn't daemon(3) a BSD C library function? I don't know whether it is available everywhere -- and besides that, an implementation in Scheme is not a lot of work but could offer a great deal of added flexibility in addition to what deamon(3) can do. [...] cu, Thomas ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] daemonize egg: redirect I/O?
grok that. im trying to get chicken working in visual studio. this does not rate amongst the 'fun' things i have done. yay work requiring ms os. -elf On Fri, 26 Oct 2007, Alex Queiroz wrote: Hallo, On 10/26/07, Elf [EMAIL PROTECTED] wrote: heh, none of these are going to work everywhere. all posix extensions are custom. the only i/o procs in the standard are call-with-[input|output]file, with-[input|output]-to-file, current-[input|output]-port, [input|output]-file?, [open|close]-[input|output]-file, write, display, read, load, eof-object?, newline, and the lovely and never implemented transcript-[on|off]. i know im missing some (character one, prolly), but the point is that the standard basically only says 'you need to be able to interact with the system' in terms of its i/o specification. there has never been a general posix.1003 or posix.2 srfi submitted (or at least there has never been one posted). Yes, that's why a low-level egg is needed that uses POSIX where available and (sigh) the Win32 API in Windows systems. In the ideal world I would use only POSIX OSes, but unfortunately I can't and I'd rather use scheme everywhere. Cheers, ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] daemonize egg: redirect I/O?
Hallo, On 10/26/07, Elf [EMAIL PROTECTED] wrote: heh, none of these are going to work everywhere. all posix extensions are custom. the only i/o procs in the standard are call-with-[input|output]file, with-[input|output]-to-file, current-[input|output]-port, [input|output]-file?, [open|close]-[input|output]-file, write, display, read, load, eof-object?, newline, and the lovely and never implemented transcript-[on|off]. i know im missing some (character one, prolly), but the point is that the standard basically only says 'you need to be able to interact with the system' in terms of its i/o specification. there has never been a general posix.1003 or posix.2 srfi submitted (or at least there has never been one posted). Yes, that's why a low-level egg is needed that uses POSIX where available and (sigh) the Win32 API in Windows systems. In the ideal world I would use only POSIX OSes, but unfortunately I can't and I'd rather use scheme everywhere. Cheers, -- -alex http://www.ventonegro.org/ ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] daemonize egg: redirect I/O?
Hallo, On 10/26/07, Elf [EMAIL PROTECTED] wrote: (re: the daemon question, i would just use (foreign-lambda int daemon int int) , but thats just me.) A very nice solution... If it worked (everywhere). Cheers, -- -alex http://www.ventonegro.org/ ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] daemonize egg: redirect I/O?
On Fri, 26 Oct 2007, Thomas Christian Chust wrote: Elf wrote: um, why not just use (duplicate-fileno (portfileno port)) ? [...] Because not the file descriptor of a given port should be duplicated but rather the file descriptor of a given port should be replaced by a duplicate of another one. Of course one could use (portfileno ...) instead of the fileno/... constants in my example, but it wouldn't make much of a difference, unless the ports were already set to something different from the standard -- but in that case it may not be such a good idea to redirect them. I think it makes much more sense to redirect those descriptors which are, by default, connected to the controlling terminal of the process, because they usually become useless after detaching from the original process group. yes, i understood that. hence the comment regarding the (current-input/output/error-port) procedures being parameters that take an argument for automatic replacement. they need to be replaced WITH something, though, hence the portfileno remark. (re: the daemon question, i would just use (foreign-lambda int daemon int int) , but thats just me.) Isn't daemon(3) a BSD C library function? I don't know whether it is available everywhere -- and besides that, an implementation in Scheme is not a lot of work but could offer a great deal of added flexibility in addition to what deamon(3) can do. [...] daemon() has been standard in libc since around 1995. the only machines that wont have it are windows boxen. the direct chicken code for daemon() (without type or validity checking), and with an explicit continuation since return values mean very little in this context, is: (define (daemon nochdir noclose cnt) (call-with-current-continuation (lambda (k) (process-fork (lambda () (k #t))) (exit 0))) (create-session) (call-with-current-continuation (lambda (k) (process-fork (lambda () (k #t))) (exit 0))) (and (= 0 nochdir) (change-directory /)) (and-let* ((cls (= 0 noclose)) (ipt (open-input-file /dev/null)) (opt (open-output-file /dev/null))) (current-input-port ipt) (current-output-port opt) (current-error-port opt) (cnt))) the call/cc's i believe are necessary because process-fork automatically calls (_exit 0) after evaling the lambda for the child procs. -elf ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] daemonize egg: redirect I/O?
heh, none of these are going to work everywhere. all posix extensions are custom. the only i/o procs in the standard are call-with-[input|output]file, with-[input|output]-to-file, current-[input|output]-port, [input|output]-file?, [open|close]-[input|output]-file, write, display, read, load, eof-object?, newline, and the lovely and never implemented transcript-[on|off]. i know im missing some (character one, prolly), but the point is that the standard basically only says 'you need to be able to interact with the system' in terms of its i/o specification. there has never been a general posix.1003 or posix.2 srfi submitted (or at least there has never been one posted). rant in my experiences amongst the various distributions, this is the area in which the greatest incompatabilities are found. furthermore, unlike 95% or more of the other incompats, its hard/impossible to write wrappers to allow lowlev crosscompat, because everyone has different views on how to schemeify posix, and instead of agreeing on something thats fairly ugly (straight c wrapping or whatnot) that everyone can build their nice extensions with (which could then be wrapped), the implementations are almost entirely divergent. if r6rs had actually been a real attempt at standardisation, it would have tackled posix(ish) constructs, regular expressions, and networking, as its useful to both academic and nonacademic coders, is divergent between the distributions, is a major hook for potential converts, and has the highest visibility for ALL distributions. (go to the page for any given distrib, and some subset of the above will be displayed most prominently under 'features', along with whatever library/module system they use.) /rant sorry. :) -elf On Fri, 26 Oct 2007, Alex Queiroz wrote: Hallo, On 10/26/07, Elf [EMAIL PROTECTED] wrote: (re: the daemon question, i would just use (foreign-lambda int daemon int int) , but thats just me.) A very nice solution... If it worked (everywhere). Cheers, ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] daemonize egg: redirect I/O?
Thomas Christian Chust wrote: I wonder why one would want to pass this cleanup argument to the daemon procedure -- why should the spawned process simply perform cleanup once the daemon procedure returns? The problem with that, as I see it, is that sometimes daemons don't get to return normally, i.e. if they get killed. Of course any proper daemon will implement signal handlers and such so that it will clean up after itself and exit gracefully. With my implementation you can implement that sort of stuff anyway you like, and just call the additional (cleanup) proc to take care of whatever you had daemonize set up for you, i.e. the PID file. Of course, it might be nice to have daemonize take care of everything, including signal handlers and such. I would see that as a further abstraction. (define (super-daemonize proc) (daemonize (lambda (cleanup) (set-signal-handler! ...) ; Call cleanup if we get killed. (proc) (cleanup ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users