[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

ps_tty_name broken?



Hi,

I believe that ps_tty_name may be broken.  I have included two
examples using libps.  The first is the broken one.  Here we see
that after using ps_tty_name and trying to use a new procset the
program crashes. The second example demostrates what should happen, ie
it doesn't crash.  I used owner_uid as a matter of convience, however,
it works for all of the other fields that I have tried (args, args_len,
env, env_len amoung others).

neal@hurd:~ $ gcc -g test.c -lps
neal@hurd:~ $ gdb a.out
(gdb) run 51
Starting program: /home/neal/a.out 51
[Switching to thread 3249.3]
[Switching to thread 3249.4]
/dev/ttyp0

Program received signal SIGSEGV, Segmentation fault.
0x8048987 in main (argc=2, argv=0x101ac04) at test.c:73
73            assert(proc_stat_pid(proc) == pid);
(gdb) quit
The program is running.  Exit anyway? (y or n) y
neal@hurd:~ $ gcc -g test2.c -lps
neal@hurd:~ $ ./a.out 51
1000
1000
1000
1000
1000
1000
1000
1000
1000
1000

-Neal

-- 
----------------------------------------------------------------------------
Neal Walfield                                              neal@walfield.org
UMass Lowell - Fox 1512                                  Phone: 978-934-5347
                                                           Fax: 603-415-3645
Love is the triumph of imagination over intelligence.
                -- H. L. Mencken
#define _GNU_SOURCE 1

#include <hurd.h>
#include <stdio.h>
#include <ps.h>
#include <assert.h>

/* Verify that PSTAT_FIELD is available in PROC
 */
error_t load_proc_field(struct proc_stat *p, int PSTAT_FIELD)
{
  if (!(p->flags & PSTAT_FIELD)) {
    /* The requested data is not availanle, try to
     * have it loaded
     */
    int err = proc_stat_set_flags(p, PSTAT_FIELD);
    if (err)
      return err;

    /* The call was successful, but according to the interface
     * the data may still not be available.
     */
    if (!(p->flags & PSTAT_FIELD))
      /* XXX - FIXME
       * proc_stat_set_flags succeeded but it did not set the PSTAT_ARGS flag
       * what is the correct error code to return in this situation?
       */
      return EGRATUITOUS;
  }

  return 0;
}

int main(int argc, char **argv)
{
  int pid;
  char *end;
  int i;

  if (argc < 2)
    {
      printf("usage: %s pid\n", argv[0]);
      return -1;
    }

  pid = strtol(argv[1], &end, 0);
  if (*end != '\0')
    {
      printf("usage: %s pid\n", argv[0]);
      return -1;
    }

  for(i = 0; i < 10; i++)
    {
      int err;
      struct ps_context *context;
      struct proc_stat_list *procset;
      struct proc_stat *proc;
      const char *buffer;

      /* Get the process list */
      err = ps_context_create(getproc(), &context);
      if (err)
        return err;

      err = proc_stat_list_create(context, &procset);
      if (err)
        return err;

      err = proc_stat_list_add_pids(procset, &pid, 1, 0);

      proc = procset->proc_stats[0];
      assert(proc_stat_pid(proc) == pid);

      err = load_proc_field(proc, PSTAT_TTY);

      if (err)
        buffer = "??";
      else
        {
          buffer = ps_tty_name(proc->tty);
          if (!buffer)
            buffer = "??";
        }

      printf("%s\n", buffer);

      proc_stat_list_free(procset);
      ps_context_free(context);
    }

  return 0;
}
#define _GNU_SOURCE 1

#include <hurd.h>
#include <stdio.h>
#include <ps.h>
#include <assert.h>

/* Verify that PSTAT_FIELD is available in PROC
 */
error_t load_proc_field(struct proc_stat *p, int PSTAT_FIELD)
{
  if (!(p->flags & PSTAT_FIELD)) {
    /* The requested data is not availanle, try to
     * have it loaded
     */
    int err = proc_stat_set_flags(p, PSTAT_FIELD);
    if (err)
      return err;

    /* The call was successful, but according to the interface
     * the data may still not be available.
     */
    if (!(p->flags & PSTAT_FIELD))
      /* XXX - FIXME
       * proc_stat_set_flags succeeded but it did not set the PSTAT_ARGS flag
       * what is the correct error code to return in this situation?
       */
      return EGRATUITOUS;
  }

  return 0;
}

int main(int argc, char **argv)
{
  int pid;
  char *end;
  int i;

  if (argc < 2)
    {
      printf("usage: %s pid\n", argv[0]);
      return -1;
    }

  pid = strtol(argv[1], &end, 0);
  if (*end != '\0')
    {
      printf("usage: %s pid\n", argv[0]);
      return -1;
    }

  for(i = 0; i < 10; i++)
    {
      int err;
      struct ps_context *context;
      struct proc_stat_list *procset;
      struct proc_stat *proc;
      char *buffer;

      /* Get the process list */
      err = ps_context_create(getproc(), &context);
      if (err)
        return err;

      err = proc_stat_list_create(context, &procset);
      if (err)
        return err;

      err = proc_stat_list_add_pids(procset, &pid, 1, 0);

      proc = procset->proc_stats[0];
      assert(proc_stat_pid(proc) == pid);

      err = load_proc_field(proc, PSTAT_OWNER_UID);

      if (err)
        printf("??\n");
      else
        printf("%d\n", proc_stat_owner_uid(proc));

      proc_stat_list_free(procset);
      ps_context_free(context);
    }

  return 0;
}

Reply to: