Some while ago, Jon Smith wrote:
>
> Has anyone successfully gotten Star Office 5.0 to run multi-user?
>

I have just solved this.  The problem is that StarOffice accesses the
command line arguments (and hence the "/net" flag needed to install
multi-user) using the vile /proc/xxx/cmdline mechanism.  The FreeBSD
implementation of this is a hack that only returns argv[0] and therefore
discards any command line arguments.

The attached patch is still a hack, but is one step closer to the right
answer: it now returns the right answer if the current process reads its
own /proc/xxx/cmdline, but still returns only argv[0] if a process
attempts to read another process' cmdline.  This is enough to solve the
StarOffice problem.

The reason I haven't done the job properly is that I don't know how to
read an address in user-space for a process other than curproc.  From the
implementation of /proc/xxx/mem, this seems difficult to do.


Index: procfs_status.c
===================================================================
RCS file: /repository/src/sys/miscfs/procfs/procfs_status.c,v
retrieving revision 1.12
diff -c -r1.12 procfs_status.c
*** procfs_status.c     1999/01/05 03:53:06     1.12
--- procfs_status.c     1999/05/15 20:36:16
***************
*** 47,52 ****
--- 47,56 ----
  #include <sys/tty.h>
  #include <sys/resourcevar.h>
  #include <miscfs/procfs/procfs.h>
+ #include <vm/vm.h>
+ #include <vm/pmap.h>
+ #include <vm/vm_param.h>
+ #include <sys/exec.h>
  
  int
  procfs_dostatus(curp, p, pfs, uio)
***************
*** 164,178 ****
                return (EOPNOTSUPP);
  
        /*
!        * For now, this is a hack.  To implement this fully would require
!        * groping around in the process address space to follow argv etc.
         */
!       ps = psbuf;
!       bcopy(p->p_comm, ps, MAXCOMLEN);
!       ps[MAXCOMLEN] = '\0';
!       ps += strlen(ps);
! 
!       ps += sprintf(ps, "\n");
  
        xlen = ps - psbuf;
        xlen -= uio->uio_offset;
--- 168,207 ----
                return (EOPNOTSUPP);
  
        /*
!        * This is a hack: the correct behaviour is only implemented for
!        * the case of the current process enquiring about its own argv
!        * (due to the difficulty of accessing other processes' address space).
!        * For other cases, we cop out and just return argv[0] from p->p_comm.
!        * Note that if the argv is no longer available, we deliberately
!        * don't fall back on p->p_comm or return an error: the authentic
!        * Linux behaviour is to return zero-length in this case.
         */
!       if (curproc == p) {
!               struct ps_strings pstr;
!               int i;
!               size_t bytes_left, done;
! 
!               error = copyin((void*)PS_STRINGS, &pstr, sizeof(pstr));
!               if (error) return (error);
!               bytes_left = sizeof(psbuf);
!               ps = psbuf;
!               for (i = 0; bytes_left && (i < pstr.ps_nargvstr); i++) {
!                       error = copyinstr(pstr.ps_argvstr[i], ps,
!                                bytes_left, &done);
!                       /* If too long or malformed, just truncate      */
!                       if (error) {
!                               error = 0;
!                               break;
!                       }
!                       ps += done;
!                       bytes_left -= done;
!               }
!       } else {
!               ps = psbuf;
!               bcopy(p->p_comm, ps, MAXCOMLEN);
!               ps[MAXCOMLEN] = '\0';
!               ps += strlen(ps);
!       }
  
        xlen = ps - psbuf;
        xlen -= uio->uio_offset;

Reply via email to