My way to check if a progam is already running - Linux

This is a discussion on My way to check if a progam is already running - Linux ; Lockfiles are bad, they show up at times as stale, and then prevent your program to run. /* This assumes there is a directory ~/.MyProgram/ struct passwd *userinfo; char temp[4096]; FILE *fptr; int a, b; /* get user info */ ...

+ Reply to Thread
Page 1 of 3 1 2 3 LastLast
Results 1 to 20 of 56

Thread: My way to check if a progam is already running

  1. My way to check if a progam is already running



    Lockfiles are bad, they show up at times as stale,
    and then prevent your program to run.

    /* This assumes there is a directory ~/.MyProgram/

    struct passwd *userinfo;
    char temp[4096];
    FILE *fptr;
    int a, b;

    /* get user info */
    userinfo = getpwuid(getuid() );

    /* get home directory */
    home_dir = strsave(userinfo -> pw_dir);

    /* test if already a MyProgram running */
    sprintf(temp, "pidof MyProgram > %s/.MyProgram/pids", home_dir);
    ftr = popen(temp, "w");
    pclose(ftr);

    sprintf(temp, "%s/.MyProgram/pids", home_dir);
    fptr = fopen(temp, "r");
    if(fptr)
    {
    a = fscanf(fptr, "%d %d", &b, &b);
    fclose(fptr);

    if(a == 2)
    {
    fprintf(stderr, "MyProgram: An other MyProgram is already running, aborting.\n");

    exit(1);
    }
    }
    ---------------------------------------------------------------------------------------------

    What do you think, this good?


  2. Re: My way to check if a progam is already running

    Jan Panteltje writes:

    > Lockfiles are bad, they show up at times as stale,
    > and then prevent your program to run.


    If lockfile exists but application is not running then it was most
    likely improperly closed -- maybe something administrator should look
    at.

    If you are really concerned about stale lockfiles you can save PID in it
    and then, in script starting application, check if such process exists.

    > /* This assumes there is a directory ~/.MyProgram/
    >
    > struct passwd *userinfo;
    > char temp[4096];
    > FILE *fptr;
    > int a, b;
    >
    > /* get user info */
    > userinfo = getpwuid(getuid() );
    >
    > /* get home directory */
    > home_dir = strsave(userinfo -> pw_dir);
    >
    > /* test if already a MyProgram running */
    > sprintf(temp, "pidof MyProgram > %s/.MyProgram/pids", home_dir);
    > ftr = popen(temp, "w");
    > pclose(ftr);
    >
    > sprintf(temp, "%s/.MyProgram/pids", home_dir);
    > fptr = fopen(temp, "r");
    > if(fptr)
    > {
    > a = fscanf(fptr, "%d %d", &b, &b);
    > fclose(fptr);
    >
    > if(a == 2)
    > {
    > fprintf(stderr, "MyProgram: An other MyProgram "
    > "is already running, aborting.\n");
    >
    > exit(1);
    > }
    > }
    >
    > What do you think, this good?


    No. First of all, why are you creating temporary file? Isn't reading
    from a pipe enough? For instance:

    #v+
    FILE *f = popen("pidof MyProgram", "r");
    if (!f) {
    perror("popen");
    exit(1);
    } else {
    int a = fscanf(f, "%*d %*d");
    fclose(f);
    if (a==2) {
    fprintf(stderr, "MyProgram: already running\n");
    exit(1);
    } else if (a!=1) {
    fprintf(stderr, "MyProgram: error reading pidof's output\n");
    exit(1);
    }
    }
    #v+

    But most important is that your code depends on external tool which is
    no needed here (it may be a shock for you but my OS doesn't have
    a pidof). Moreover, there can be more programs named MyProgram.

    --
    Best regards, _ _
    .o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o
    ..o | Computer Science, Michal "mina86" Nazarewicz (o o)
    ooo +-------ooO--(_)--Ooo--

  3. Re: My way to check if a progam is already running

    On a sunny day (Wed, 20 Jun 2007 01:06:32 +0200) it happened Michal Nazarewicz
    wrote in <874pl37ddz.fsf@erwin.mina86.com>:

    >Jan Panteltje writes:
    >
    >> Lockfiles are bad, they show up at times as stale,
    >> and then prevent your program to run.

    >
    >If lockfile exists but application is not running then it was most
    >likely improperly closed -- maybe something administrator should look
    >at.


    Crashed, killed by something...

    >If you are really concerned about stale lockfiles you can save PID in it
    >and then, in script starting application, check if such process exists.


    This is not guaranteed I think, it is possible to have the same pid on
    an other run, even for an other process?


  4. Re: My way to check if a progam is already running

    On Jun 20, 7:37 am, Jan Panteltje wrote:
    > >If lockfile exists but application is not running then it was most
    > >likely improperly closed -- maybe something administrator should look
    > >at.

    >
    > Crashed, killed by something...
    >
    > >If you are really concerned about stale lockfiles you can save PID in it
    > >and then, in script starting application, check if such process exists.

    >
    > This is not guaranteed I think, it is possible to have the same pid on
    > an other run, even for an other process?


    This is one of those great questions where the answer is, "why do you
    need to know?" What happens if two instances of the program run that
    causes a problem? Odds are thinking about that question will very
    quickly give you the right answer.

    As for a generic solution, pile on as many checks as you need until
    you're comfortable a collision is improbable. Write to a file your
    PID, process name, start time, and a random TCP port that you have
    open. If the start time is after the system start time, and there's a
    file with that PID and process name, and that TCP port is in use, that
    should be good enough for anyone.

    If it's not, implement a 'validate' protocol on that TCP port. Write a
    random GUID to the pid file too, and use the TCP port to connect to
    the program and validate the GUID.

    Another way is to actually have the process *lock* its lockfile with
    an advisory lock. If you can lock the lockfile (try in a non-blocking
    way), then remove/ignore it. Only if the process is still running can
    it keep its lockfile locked.

    However, odds are there's a much simpler way to do it. What goes wrong
    if two instances run?

    DS


  5. Re: My way to check if a progam is already running

    On a sunny day (Wed, 20 Jun 2007 11:43:16 -0700) it happened David Schwartz
    wrote in
    <1182364996.772026.50080@q19g2000prn.googlegroups.c om>:

    >However, odds are there's a much simpler way to do it. What goes wrong
    >if two instances run?
    >
    >DS


    My way is the simpler way it seems, seems to work 100% here so far.
    What goes wrong is that if the program writes to files and has cached info.
    If a second instance is started it will at some point write other data.
    Well this is why I added the feature.
    (See my first posting in this thread).


  6. Re: My way to check if a progam is already running

    On Jun 20, 3:30 pm, Jan Panteltje wrote:

    > My way is the simpler way it seems, seems to work 100% here so far.
    > What goes wrong is that if the program writes to files and has cached > info.
    > If a second instance is started it will at some point write other
    > data.
    > Well this is why I added the feature.
    > (See my first posting in this thread).


    Easy fix -- advisory lock the files when you change them.

    DS


  7. Re: My way to check if a progam is already running

    On a sunny day (Wed, 20 Jun 2007 16:10:49 -0700) it happened David Schwartz
    wrote in
    <1182381049.427065.228730@i13g2000prf.googlegroups. com>:

    >On Jun 20, 3:30 pm, Jan Panteltje wrote:
    >
    >> My way is the simpler way it seems, seems to work 100% here so far.
    >> What goes wrong is that if the program writes to files and has cached > info.
    >> If a second instance is started it will at some point write other
    >> data.
    >> Well this is why I added the feature.
    >> (See my first posting in this thread).

    >
    >Easy fix -- advisory lock the files when you change them.
    >
    >DS


    That will prevent _that_ problem, but not the problem that you still have 2
    the same applications running where the user is supposed to use one.
    No way does it solve some practical problem where data is dynamically updated.
    A typical example is this newsreader, if one instance is used and newsgroups are
    read, it updates article numbers and writes these immediately back to a config file.
    If there was an old instance hanging around, and a user starts using that to
    get new articles, it will use its own counter in RAM (set to when it last
    started or did something) and get the same articles again.
    It does not first 'read' all configs before it goes online, it only reads
    those at startup.
    This happened a couple of times (old version was hidden behind some other
    application) that is why I came up with my solution.
    Preventing 2 from running is a better way then a lot of overhead locking
    files and loading everything on every keystroke...
    It is really easy to start a new instance by accident, as it is under a special
    function key.


  8. Re: My way to check if a progam is already running

    On Jun 21, 4:17 am, Jan Panteltje wrote:

    > That will prevent _that_ problem,


    I thought that was 'the problem'.

    > but not the problem that you still have 2
    > the same applications running where the user is supposed to use one.


    Why not?

    > No way does it solve some practical problem where data is dynamically updated.


    Sure it does.

    > A typical example is this newsreader, if one instance is used and newsgroups are
    > read, it updates article numbers and writes these immediately back to a config file.
    > If there was an old instance hanging around, and a user starts using that to
    > get new articles, it will use its own counter in RAM (set to when it last
    > started or did something) and get the same articles again.


    No it won't. If it has a counter in RAM, it also has a lock on the
    file. (Remember, the whole point of the lock was to prevent the file
    from changing when we needed its contents not to change.) The second
    instance would see that the file is locked and abort.

    > It does not first 'read' all configs before it goes online, it only reads
    > those at startup.


    If it needs those configs not to change, it needs to keep them locked.

    > This happened a couple of times (old version was hidden behind some other
    > application) that is why I came up with my solution.
    > Preventing 2 from running is a better way then a lot of overhead locking
    > files and loading everything on every keystroke...
    > It is really easy to start a new instance by accident, as it is under a special
    > function key.


    Hold the lock the whole time the program is running.

    DS


  9. Re: My way to check if a progam is already running

    On a sunny day (Thu, 21 Jun 2007 11:52:13 -0700) it happened David Schwartz
    wrote in
    <1182451933.333284.25880@i13g2000prf.googlegroups.c om>:

    >On Jun 21, 4:17 am, Jan Panteltje wrote:
    >
    >> That will prevent _that_ problem,

    >
    >I thought that was 'the problem'.
    >
    >> but not the problem that you still have 2
    >> the same applications running where the user is supposed to use one.

    >
    >Why not?


    Well, you'd want to be nice and say: "Hey Dummy, you already started WhatEver." :-)


    >> No way does it solve some practical problem where data is dynamically updated.

    >
    >Sure it does.


    Ok I see your point, but all this file locking is it not more complicated
    then the 10 lines of code at the start of main() that I proposed?
    Especially as many files (not just one) are involved?

    /* This assumes there is a directory ~/.MyProgram/

    struct passwd *userinfo;
    char temp[4096];
    FILE *fptr;
    int a, b;

    /* get user info */
    userinfo = getpwuid(getuid() );

    /* get home directory */
    home_dir = strsave(userinfo -> pw_dir);

    /* test if already a MyProgram running */
    sprintf(temp, "pidof MyProgram > %s/.MyProgram/pids", home_dir);
    ftr = popen(temp, "w");
    pclose(ftr);

    sprintf(temp, "%s/.MyProgram/pids", home_dir);
    fptr = fopen(temp, "r");
    if(fptr)
    {
    a = fscanf(fptr, "%d %d", &b, &b);
    fclose(fptr);

    if(a == 2)
    {
    fprintf(stderr, "MyProgram: An other MyProgram is already running, aborting.\n");

    exit(1);
    }
    }



  10. Re: My way to check if a progam is already running

    On Jun 21, 12:00 pm, Jan Panteltje wrote:

    > Ok I see your point, but all this file locking is it not more complicated
    > then the 10 lines of code at the start of main() that I proposed?
    > Especially as many files (not just one) are involved?


    Your solution has several defects.

    1) It breaks if the name of the program is changed or the program is
    accessed under another name.

    2) It breaks if another program is ever added that manipulates the
    same data.

    3) It prohibits multiple operations of the same program, even if they
    are on different data sets.

    Locking the thing that must not change makes more logical sense.

    DS


  11. Re: My way to check if a progam is already running

    On a sunny day (Thu, 21 Jun 2007 12:12:20 -0700) it happened David Schwartz
    wrote in
    <1182453140.552495.60130@o11g2000prd.googlegroups.c om>:

    >On Jun 21, 12:00 pm, Jan Panteltje wrote:
    >
    >> Ok I see your point, but all this file locking is it not more complicated
    >> then the 10 lines of code at the start of main() that I proposed?
    >> Especially as many files (not just one) are involved?

    >
    >Your solution has several defects.
    >
    >1) It breaks if the name of the program is changed or the program is
    >accessed under another name.


    Yes, not a normal user scenario, but could happen.


    >2) It breaks if another program is ever added that manipulates the
    >same data.


    Sure, but that would make little sense, you do not just change postgres
    files either, although you could as root.

    >3) It prohibits multiple operations of the same program, even if they
    >are on different data sets.


    Yes, good point.

    >Locking the thing that must not change makes more logical sense.
    >
    >DS


    OK.

  12. Re: My way to check if a progam is already running

    Jan Panteltje writes:

    > Lockfiles are bad, they show up at times as stale,
    > and then prevent your program to run.
    >
    > /* This assumes there is a directory ~/.MyProgram/
    > struct passwd *userinfo;
    > char temp[4096];
    > FILE *fptr;
    > int a, b;
    >
    > /* get home directory */
    > userinfo = getpwuid(getuid() );
    > home_dir = strsave(userinfo -> pw_dir);
    >
    > /* test if already a MyProgram running */
    > sprintf(temp, "pidof MyProgram > %s/.MyProgram/pids", home_dir);
    > ftr = popen(temp, "w");
    > pclose(ftr);
    >
    > sprintf(temp, "%s/.MyProgram/pids", home_dir);
    > fptr = fopen(temp, "r");
    > if(fptr) {
    > a = fscanf(fptr, "%d %d", &b, &b);
    > fclose(fptr);
    > if(a == 2) {
    > fprintf(stderr, "MyProgram: An other MyProgram "
    > "is already running, aborting.\n");
    > exit(1);
    > }
    > }


    Come to think of it it doesn't work. The first instance of the program
    is run -- it executes pidof and saves it output to pids file (now there
    is only one pid in the file). Then task is switched and another
    instance of the program is being run. It executes pidof and saves it
    output to pids file (now there are two pids in the file).

    What happens next is that both instances read two pids from the file and
    both programs think that another instance is already running even though
    one of them can safely continue to run. That's why you should not use
    temporary file but instead read data from pipe directly.

    Still, however, it won't work as in following scenario: The first
    instance executes pidof and before pidof does anything task is switched
    and another instance executes pidof. Now, there are two instances of
    the program and both pidof tools report two pids and both instances
    exit.

    That's why you should use lock files, ie. you try to lock a file and on
    success you're the only instance. On failure you're another instance.

    --
    Best regards, _ _
    .o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o
    ..o | Computer Science, Michal "mina86" Nazarewicz (o o)
    ooo +-------ooO--(_)--Ooo--

  13. Re: My way to check if a progam is already running

    On a sunny day (Fri, 22 Jun 2007 13:50:11 +0200) it happened Michal Nazarewicz
    wrote in <87y7icryx8.fsf@erwin.mina86.com>:

    >Jan Panteltje writes:
    >
    >> Lockfiles are bad, they show up at times as stale,
    >> and then prevent your program to run.
    >>
    >> /* This assumes there is a directory ~/.MyProgram/
    >> struct passwd *userinfo;
    >> char temp[4096];
    >> FILE *fptr;
    >> int a, b;
    >>
    >> /* get home directory */
    >> userinfo = getpwuid(getuid() );
    >> home_dir = strsave(userinfo -> pw_dir);
    >>
    >> /* test if already a MyProgram running */
    >> sprintf(temp, "pidof MyProgram > %s/.MyProgram/pids", home_dir);
    >> ftr = popen(temp, "w");
    >> pclose(ftr);
    >>
    >> sprintf(temp, "%s/.MyProgram/pids", home_dir);
    >> fptr = fopen(temp, "r");
    >> if(fptr) {
    >> a = fscanf(fptr, "%d %d", &b, &b);
    >> fclose(fptr);
    >> if(a == 2) {
    >> fprintf(stderr, "MyProgram: An other MyProgram "
    >> "is already running, aborting.\n");
    >> exit(1);
    >> }
    >> }

    >
    >Come to think of it it doesn't work.


    I can assure you it works perfectly, I am using it.
    :-)

  14. Re: My way to check if a progam is already running

    Michal Nazarewicz writes:
    > Jan Panteltje writes:
    >> Lockfiles are bad, they show up at times as stale,
    >> and then prevent your program to run.
    >>
    >> /* This assumes there is a directory ~/.MyProgram/
    >> struct passwd *userinfo;
    >> char temp[4096];
    >> FILE *fptr;
    >> int a, b;
    >>
    >> /* get home directory */
    >> userinfo = getpwuid(getuid() );
    >> home_dir = strsave(userinfo -> pw_dir);
    >>
    >> /* test if already a MyProgram running */
    >> sprintf(temp, "pidof MyProgram > %s/.MyProgram/pids", home_dir);
    >> ftr = popen(temp, "w");
    >> pclose(ftr);
    >>
    >> sprintf(temp, "%s/.MyProgram/pids", home_dir);
    >> fptr = fopen(temp, "r");
    >> if(fptr) {
    >> a = fscanf(fptr, "%d %d", &b, &b);
    >> fclose(fptr);
    >> if(a == 2) {
    >> fprintf(stderr, "MyProgram: An other MyProgram "
    >> "is already running, aborting.\n");
    >> exit(1);
    >> }
    >> }

    >
    > Come to think of it it doesn't work. The first instance of the program
    > is run -- it executes pidof and saves it output to pids file (now there
    > is only one pid in the file). Then task is switched and another
    > instance of the program is being run. It executes pidof and saves it
    > output to pids file (now there are two pids in the file).


    Not using this code. Each new instance of the program will overwrite
    the existing pids file with its own pid, due to the '>'-redirection
    used in the pidof command.

    [...]

    > That's why you should use lock files, ie. you try to lock a file and on
    > success you're the only instance.


    A 'lock file' is something different from a 'file lock'.

  15. Re: My way to check if a progam is already running

    Rainer Weikusat writes:
    > Michal Nazarewicz writes:
    >> Jan Panteltje writes:
    >>> Lockfiles are bad, they show up at times as stale,
    >>> and then prevent your program to run.
    >>> /* This assumes there is a directory ~/.MyProgram/
    >>> struct passwd *userinfo;
    >>> char temp[4096];
    >>> FILE *fptr;
    >>> int a, b;
    >>>
    >>> /* get home directory */
    >>> userinfo = getpwuid(getuid() );
    >>> home_dir = strsave(userinfo -> pw_dir);
    >>>
    >>> /* test if already a MyProgram running */
    >>> sprintf(temp, "pidof MyProgram > %s/.MyProgram/pids", home_dir);
    >>> ftr = popen(temp, "w");
    >>> pclose(ftr);
    >>>
    >>> sprintf(temp, "%s/.MyProgram/pids", home_dir);
    >>> fptr = fopen(temp, "r");
    >>> if(fptr) {
    >>> a = fscanf(fptr, "%d %d", &b, &b);
    >>> fclose(fptr);
    >>> if(a == 2) {
    >>> fprintf(stderr, "MyProgram: An other MyProgram "
    >>> "is already running, aborting.\n");
    >>> exit(1);
    >>> }
    >>> }

    >>
    >> Come to think of it it doesn't work. The first instance of the program
    >> is run -- it executes pidof and saves it output to pids file (now there
    >> is only one pid in the file). Then task is switched and another
    >> instance of the program is being run. It executes pidof and saves it
    >> output to pids file (now there are two pids in the file).

    >
    > Not using this code. Each new instance of the program will overwrite
    > the existing pids file with its own pid, due to the '>'-redirection
    > used in the pidof command.


    This is, of course, nonsense, because pidof prints all pids. Michael
    is right.

  16. Re: My way to check if a progam is already running

    On a sunny day (Fri, 22 Jun 2007 15:39:05 +0200) it happened Rainer Weikusat
    wrote in <87abus9khy.fsf@fever.mssgmbh.com>:

    >Rainer Weikusat writes:
    >> Michal Nazarewicz writes:
    >>> Jan Panteltje writes:
    >>>> Lockfiles are bad, they show up at times as stale,
    >>>> and then prevent your program to run.
    >>>> /* This assumes there is a directory ~/.MyProgram/
    >>>> struct passwd *userinfo;
    >>>> char temp[4096];
    >>>> FILE *fptr;
    >>>> int a, b;
    >>>>
    >>>> /* get home directory */
    >>>> userinfo = getpwuid(getuid() );
    >>>> home_dir = strsave(userinfo -> pw_dir);
    >>>>
    >>>> /* test if already a MyProgram running */
    >>>> sprintf(temp, "pidof MyProgram > %s/.MyProgram/pids", home_dir);
    >>>> ftr = popen(temp, "w");
    >>>> pclose(ftr);
    >>>>
    >>>> sprintf(temp, "%s/.MyProgram/pids", home_dir);
    >>>> fptr = fopen(temp, "r");
    >>>> if(fptr) {
    >>>> a = fscanf(fptr, "%d %d", &b, &b);
    >>>> fclose(fptr);
    >>>> if(a == 2) {
    >>>> fprintf(stderr, "MyProgram: An other MyProgram "
    >>>> "is already running, aborting.\n");
    >>>> exit(1);
    >>>> }
    >>>> }
    >>>
    >>> Come to think of it it doesn't work. The first instance of the program
    >>> is run -- it executes pidof and saves it output to pids file (now there
    >>> is only one pid in the file). Then task is switched and another
    >>> instance of the program is being run. It executes pidof and saves it
    >>> output to pids file (now there are two pids in the file).

    >>
    >> Not using this code. Each new instance of the program will overwrite
    >> the existing pids file with its own pid, due to the '>'-redirection
    >> used in the pidof command.

    >
    >This is, of course, nonsense, because pidof prints all pids. Michael
    >is right.


    Does not matter how many PIDs and whatever, if more then one, then there is
    an other instance running. abort.
    The check is made in main() before any threads etc.. are launched.
    it is really simple.
    Works for me, so due to the nature of computers and Turing machines, should
    work for you too.


  17. Re: My way to check if a progam is already running

    Jan Panteltje writes:
    > On a sunny day (Fri, 22 Jun 2007 15:39:05 +0200) it happened Rainer Weikusat
    > wrote in <87abus9khy.fsf@fever.mssgmbh.com>:
    >>Rainer Weikusat writes:
    >>> Michal Nazarewicz writes:
    >>>> Jan Panteltje writes:
    >>>>> Lockfiles are bad, they show up at times as stale,
    >>>>> and then prevent your program to run.
    >>>>> /* This assumes there is a directory ~/.MyProgram/
    >>>>> struct passwd *userinfo;
    >>>>> char temp[4096];
    >>>>> FILE *fptr;
    >>>>> int a, b;
    >>>>>
    >>>>> /* get home directory */
    >>>>> userinfo = getpwuid(getuid() );
    >>>>> home_dir = strsave(userinfo -> pw_dir);
    >>>>>
    >>>>> /* test if already a MyProgram running */
    >>>>> sprintf(temp, "pidof MyProgram > %s/.MyProgram/pids", home_dir);
    >>>>> ftr = popen(temp, "w");
    >>>>> pclose(ftr);
    >>>>>
    >>>>> sprintf(temp, "%s/.MyProgram/pids", home_dir);
    >>>>> fptr = fopen(temp, "r");
    >>>>> if(fptr) {
    >>>>> a = fscanf(fptr, "%d %d", &b, &b);
    >>>>> fclose(fptr);
    >>>>> if(a == 2) {
    >>>>> fprintf(stderr, "MyProgram: An other MyProgram "
    >>>>> "is already running, aborting.\n");
    >>>>> exit(1);
    >>>>> }
    >>>>> }
    >>>>
    >>>> Come to think of it it doesn't work. The first instance of the program
    >>>> is run -- it executes pidof and saves it output to pids file (now there
    >>>> is only one pid in the file). Then task is switched and another
    >>>> instance of the program is being run. It executes pidof and saves it
    >>>> output to pids file (now there are two pids in the file).
    >>>
    >>> Not using this code. Each new instance of the program will overwrite
    >>> the existing pids file with its own pid, due to the '>'-redirection
    >>> used in the pidof command.

    >>
    >>This is, of course, nonsense, because pidof prints all pids. Michael
    >>is right.

    >
    > Does not matter how many PIDs and whatever, if more then one, then there is
    > an other instance running. abort.


    The problem is that two instances of the program which were started at
    about the same time (in computer terms, not human terms) could both
    read two pids from the pids file, because the second instance could
    write the file with the two pids before the first has read the file
    with the one pid.

    An easy way to see this in action should be to insert a
    'raise(SIGTSTP)' after the pclose, to start two instances of the program
    and then continue them both. This isn't very likely to ever happen on
    its own on a single-user system, though.

  18. Re: My way to check if a progam is already running

    Jan Panteltje writes:

    > On Fri, 22 Jun 2007 13:50:11 +0200 it happened Michal Nazarewicz
    > wrote in <87y7icryx8.fsf@erwin.mina86.com>:
    >
    >>Jan Panteltje writes:
    >>
    >>> Lockfiles are bad, they show up at times as stale,
    >>> and then prevent your program to run.
    >>>
    >>> /* This assumes there is a directory ~/.MyProgram/
    >>> struct passwd *userinfo;
    >>> char temp[4096];
    >>> FILE *fptr;
    >>> int a, b;
    >>>
    >>> /* get home directory */
    >>> userinfo = getpwuid(getuid() );
    >>> home_dir = strsave(userinfo -> pw_dir);
    >>>
    >>> /* test if already a MyProgram running */
    >>> sprintf(temp, "pidof MyProgram > %s/.MyProgram/pids", home_dir);
    >>> ftr = popen(temp, "w");
    >>> pclose(ftr);
    >>>
    >>> sprintf(temp, "%s/.MyProgram/pids", home_dir);
    >>> fptr = fopen(temp, "r");
    >>> if(fptr) {
    >>> a = fscanf(fptr, "%d %d", &b, &b);
    >>> fclose(fptr);
    >>> if(a == 2) {
    >>> fprintf(stderr, "MyProgram: An other MyProgram "
    >>> "is already running, aborting.\n");
    >>> exit(1);
    >>> }
    >>> }

    >>
    >>Come to think of it it doesn't work.

    >
    > I can assure you it works perfectly, I am using it.
    > :-)


    Program testing can be used to show the presence of bugs, but never to
    show their absence.
    -- Edsger Wybe Dijkstra (1930-2002)

    The fact that you run this code and it does what you think it does
    doesn't mean that it's correct. I described a situation when you run
    two instances of the program and both abort where one should continue
    running and the other should abort.

    Maybe even something else. Assume there is one instance running and you
    run two new instances (A and B). A runs shell which truncates pids file
    and executes pidof which writes two pids into pids file. Now task is
    switched and B is being executed. It runs shell which truncates pids
    file. Now task is switched and A opens pids file which is *empty*
    (because shell executed by B truncated it) so program thinks it's the
    only instance.

    So as I said before, if you really insist on using this approach you
    should read from pipe directly, like in:

    #v+
    FILE *fp = popen("pidof MyProgram", "r");
    if (!fp) {
    perror("popen");
    exit(1);
    }

    a = fscanf(fp, "%*d %*d");
    pclose(fp);

    if (a==2) {
    fputs("MyProgram: already running\n", stderr);
    exit(1);
    } else if (a==1) {
    fputs("MyProgram: pidof error\n", stderr);
    exit(1);
    }
    #v-

    Still it may fail as described in previous post.

    --
    Best regards, _ _
    .o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o
    ..o | Computer Science, Michal "mina86" Nazarewicz (o o)
    ooo +-------ooO--(_)--Ooo--

  19. Re: My way to check if a progam is already running

    On a sunny day (Fri, 22 Jun 2007 20:03:07 +0200) it happened Rainer Weikusat
    wrote in <87vedf989w.fsf@fever.mssgmbh.com>:

    >Jan Panteltje writes:
    >> On a sunny day (Fri, 22 Jun 2007 15:39:05 +0200) it happened Rainer Weikusat
    >> wrote in <87abus9khy.fsf@fever.mssgmbh.com>:
    >>>Rainer Weikusat writes:
    >>>> Michal Nazarewicz writes:
    >>>>> Jan Panteltje writes:
    >>>>>> Lockfiles are bad, they show up at times as stale,
    >>>>>> and then prevent your program to run.
    >>>>>> /* This assumes there is a directory ~/.MyProgram/
    >>>>>> struct passwd *userinfo;
    >>>>>> char temp[4096];
    >>>>>> FILE *fptr;
    >>>>>> int a, b;
    >>>>>>
    >>>>>> /* get home directory */
    >>>>>> userinfo = getpwuid(getuid() );
    >>>>>> home_dir = strsave(userinfo -> pw_dir);
    >>>>>>
    >>>>>> /* test if already a MyProgram running */
    >>>>>> sprintf(temp, "pidof MyProgram > %s/.MyProgram/pids", home_dir);
    >>>>>> ftr = popen(temp, "w");
    >>>>>> pclose(ftr);
    >>>>>>
    >>>>>> sprintf(temp, "%s/.MyProgram/pids", home_dir);
    >>>>>> fptr = fopen(temp, "r");
    >>>>>> if(fptr) {
    >>>>>> a = fscanf(fptr, "%d %d", &b, &b);
    >>>>>> fclose(fptr);
    >>>>>> if(a == 2) {
    >>>>>> fprintf(stderr, "MyProgram: An other MyProgram "
    >>>>>> "is already running, aborting.\n");
    >>>>>> exit(1);
    >>>>>> }
    >>>>>> }
    >>>>>
    >>>>> Come to think of it it doesn't work. The first instance of the program
    >>>>> is run -- it executes pidof and saves it output to pids file (now there
    >>>>> is only one pid in the file). Then task is switched and another
    >>>>> instance of the program is being run. It executes pidof and saves it
    >>>>> output to pids file (now there are two pids in the file).
    >>>>
    >>>> Not using this code. Each new instance of the program will overwrite
    >>>> the existing pids file with its own pid, due to the '>'-redirection
    >>>> used in the pidof command.
    >>>
    >>>This is, of course, nonsense, because pidof prints all pids. Michael
    >>>is right.

    >>
    >> Does not matter how many PIDs and whatever, if more then one, then there is
    >> an other instance running. abort.

    >
    >The problem is that two instances of the program which were started at
    >about the same time (in computer terms, not human terms) could both
    >read two pids from the pids file, because the second instance could
    >write the file with the two pids before the first has read the file
    >with the one pid.



    Then both would abort? and then user would have to press the button again.


    >An easy way to see this in action should be to insert a
    >'raise(SIGTSTP)' after the pclose, to start two instances of the program
    >and then continue them both. This isn't very likely to ever happen on
    >its own on a single-user system, though.


    Normally, as it is a user pressing a quick key, or a mouse click on an icon,
    I'd say there is too much time involved between actions for this to happen.
    Normal human response is about 200mS IIRC, click a mouse faster then that is
    very difficult I think.
    And even if you did, there is overhead, window manager, xmodmap, xbindkeys.
    X, the whole chain, looking through the path....
    I say not a problem.
    Sure you can write a small C program and try execv or something....
    Let me know if you can get 2 instances up.



  20. Re: My way to check if a progam is already running

    On a sunny day (Fri, 22 Jun 2007 20:36:20 +0200) it happened Michal Nazarewicz
    wrote in <87wsxvvntn.fsf@erwin.mina86.com>:

    >Jan Panteltje writes:
    >
    >> On Fri, 22 Jun 2007 13:50:11 +0200 it happened Michal Nazarewicz
    >> wrote in <87y7icryx8.fsf@erwin.mina86.com>:
    >>
    >>>Jan Panteltje writes:
    >>>
    >>>> Lockfiles are bad, they show up at times as stale,
    >>>> and then prevent your program to run.
    >>>>
    >>>> /* This assumes there is a directory ~/.MyProgram/
    >>>> struct passwd *userinfo;
    >>>> char temp[4096];
    >>>> FILE *fptr;
    >>>> int a, b;
    >>>>
    >>>> /* get home directory */
    >>>> userinfo = getpwuid(getuid() );
    >>>> home_dir = strsave(userinfo -> pw_dir);
    >>>>
    >>>> /* test if already a MyProgram running */
    >>>> sprintf(temp, "pidof MyProgram > %s/.MyProgram/pids", home_dir);
    >>>> ftr = popen(temp, "w");
    >>>> pclose(ftr);
    >>>>
    >>>> sprintf(temp, "%s/.MyProgram/pids", home_dir);
    >>>> fptr = fopen(temp, "r");
    >>>> if(fptr) {
    >>>> a = fscanf(fptr, "%d %d", &b, &b);
    >>>> fclose(fptr);
    >>>> if(a == 2) {
    >>>> fprintf(stderr, "MyProgram: An other MyProgram "
    >>>> "is already running, aborting.\n");
    >>>> exit(1);
    >>>> }
    >>>> }
    >>>
    >>>Come to think of it it doesn't work.

    >>
    >> I can assure you it works perfectly, I am using it.
    >> :-)

    >
    > Program testing can be used to show the presence of bugs, but never to
    >show their absence.
    > -- Edsger Wybe Dijkstra (1930-2002)
    >
    >The fact that you run this code and it does what you think it does
    >doesn't mean that it's correct. I described a situation when you run
    >two instances of the program and both abort where one should continue
    >running and the other should abort.
    >
    >Maybe even something else. Assume there is one instance running and you
    >run two new instances (A and B). A runs shell which truncates pids file
    >and executes pidof which writes two pids into pids file. Now task is
    >switched and B is being executed. It runs shell which truncates pids
    >file. Now task is switched and A opens pids file which is *empty*
    >(because shell executed by B truncated it) so program thinks it's the
    >only instance.
    >
    >So as I said before, if you really insist on using this approach you
    >should read from pipe directly, like in:
    >
    >#v+
    >FILE *fp = popen("pidof MyProgram", "r");
    >if (!fp) {
    > perror("popen");
    > exit(1);
    >}
    >
    >a = fscanf(fp, "%*d %*d");
    >pclose(fp);
    >
    >if (a==2) {
    > fputs("MyProgram: already running\n", stderr);
    > exit(1);
    >} else if (a==1) {
    > fputs("MyProgram: pidof error\n", stderr);
    > exit(1);
    >}
    >#v-
    >


    Yes that is nice, is better.

    >Still it may fail as described in previous post.


    Well I will try to report it here if I ever start 2 instances of my newsreader.


+ Reply to Thread
Page 1 of 3 1 2 3 LastLast