示例#1
0
int GetClipText(ClipData *cd) {
    int rc;
    ULONG PostCount;
    char *mem;
    
    rc = DosOpenMutexSem(SEM_PREFIX "CLIPSYN", &hmtxSyn);
    if (rc != 0) return -1;
    rc = DosOpenEventSem(SEM_PREFIX "CLIPGET", &hevGet);
    if (rc != 0) return -1;
/*    rc = DosOpenEventSem(SEM_PREFIX "CLIPPUT", &hevPut);*/
/*    if (rc != 0) return -1;*/
    rc = DosOpenEventSem(SEM_PREFIX "CLIPEND", &hevEnd);
    if (rc != 0) return -1;
    
    DosRequestMutexSem(hmtxSyn, SEM_INDEFINITE_WAIT);
    DosResetEventSem(hevEnd, &PostCount);
    DosPostEventSem(hevGet);
    DosWaitEventSem(hevEnd, SEM_INDEFINITE_WAIT);
    if (0 == DosGetNamedSharedMem((void **)&mem, MEM_PREFIX "CLIPDATA", PAG_READ | PAG_WRITE)) {
        cd->fLen = *(ULONG*)mem;
        cd->fChar = strdup(mem + 4);
        DosFreeMem(mem);
    } else {
        cd->fLen = 0;
        cd->fChar = 0;
    }
    DosPostEventSem(hevGet);
    DosReleaseMutexSem(hmtxSyn);
/*    DosCloseEventSem(hevPut);*/
    DosCloseEventSem(hevGet);
    DosCloseEventSem(hevEnd);
    DosCloseMutexSem(hmtxSyn);
    return 0;
}
示例#2
0
SOM_Scope HMODULE   SOMLINK WPSamFM_clsQueryModuleHandle (M_WPSamF *somSelf)
{
    /* M_WPSamFData *somThis = M_WPSamFGetData (somSelf); */
    M_WPSamFMethodDebug ("M_WPSamF","WPSamFM_clsQueryModuleHandle");


    if(!hevPrfResetLock)
       if(DosOpenEventSem (HEV_PRFRESETLOCK, &hevPrfResetLock))
          if(DosCreateEventSem(HEV_PRFRESETLOCK, // Name
                                 &hevPrfResetLock, // Pointer to sem
                                 0,                // Not used with named sems
                                 TRUE))            // Initial state (TRUE = POSTED)
             hevPrfResetLock = 0;


    if(!pShareInitOS2)
       if (DosGetNamedSharedMem ((PPVOID) &pShareInitOS2,
                                        SHARE_INITOS2,
                                        PAG_READ | PAG_WRITE))
          pShareInitOS2 = 0;

    if(!hevSammy)
       if (DosOpenEventSem (HEV_SAMMY, &hevSammy))
          hevSammy = 0;


    if (hmod == NULLHANDLE)
    {
       zString zsPathName;

       /*
        *   Retrieve registered pathname of our module (DLL) and query the
        *   module handle.
        */
       zsPathName =
          _somLocateClassFile (SOMClassMgrObject, SOM_IdFromString (CLASSNAME),
                            WPSamF_MajorVersion, WPSamF_MinorVersion);

       if (DosQueryModuleHandle (zsPathName, &hmod))
       {
          DebugE (D_SOM, "_clsQueryModuleHandle", "Failed to load module");
          hmod = NULLHANDLE;
       }

    }   /* end if (hmod == NULLHANDLE) */

    DebugULd (D_SOM, "_clsQueryModuleHandle", "hmod", hmod);

    return (hmod);
}
示例#3
0
unsigned long SysCreateEventSem(unsigned char *name,
                           unsigned long numargs,
                           RXSTRING args[],
                           char *queuename,
                           RXSTRING *retstr)
{
    unsigned long rc;

    HEV handle = NULL;           /* mutex handle */

    if (numargs > 1) return INVALID_ROUTINE;

    if (numargs == 1) {

        rc = DosCreateEventSem(args[0].strptr, &handle, DC_SEM_SHARED, 1);

        /* may already be created try to open it */
        if (rc != NO_ERROR) {
            rc = DosOpenEventSem(args[0].strptr, &handle);
        }

    } else {                                /* unnamed semaphore */
        rc = DosCreateEventSem(NULL, &handle, DC_SEM_SHARED, 1);
    }

    if (!handle && rc != NO_ERROR) retstr->strlength = 0;  /* return null string */
    else {                                       /* format the result  */
        retstr->strlength = sprintf(retstr->strptr, "%lu", handle);
    }

    return VALID_ROUTINE;
}
static void WaitForSlip(void) {

    int FirstTime = 1;
    APIRET rc;
    short Seconds = Timeout;
    do {
        rc = DosOpenEventSem("\\sem32\\slip\\monitor", &slip_running);
        if (rc) {
            if (FirstTime) {
                printf("[ Waiting for SLIP - maximum wait = %d seconds ]\n",
                       Timeout);
                FirstTime = 0;
            }
            Seconds--;
            if (Seconds >= 0) {
                if (Debug) {
                    fprintf(stderr, ".");
                    fflush(stderr);
                }
                DosSleep(1000L);
            }
        }
    } while (rc && (Seconds >= 0));
    if (Debug) {
        fprintf(stderr, "\n");
    }
    if (Seconds < 0) {
        printf("The SLIP driver appears not to have started.\n");
        exit(1);
    }
}						// WaitForSlip()
示例#5
0
static APIRET PipeWaitAndResetEventSem(HEV *SemHandle)
{
#define EVENTSEM_TIMEOUT SEM_INDEFINITE_WAIT

	APIRET rc;
	ULONG PostCt;

	rc = DosWaitEventSem(*SemHandle, EVENTSEM_TIMEOUT);
	if (!rc) rc = DosResetEventSem(*SemHandle, &PostCt);

	if (rc == ERROR_INVALID_HANDLE)
	{
		rc = DosOpenEventSem(0, SemHandle);

		if (!rc) 
		{
		    rc = DosWaitEventSem(*SemHandle, EVENTSEM_TIMEOUT);
		    if (!rc) rc = DosResetEventSem(*SemHandle, &PostCt);
		}
	}

        if (rc == ERROR_ALREADY_RESET) rc = 0;

	return rc;
}
static void OpenASem(const char *Name, HEV * Hev) {

    APIRET rc = DosOpenEventSem(BORCAST Name, Hev);
    if (rc != 0) {
        fprintf(stderr, "Error %lu accessing %s - is SLIP up?\n", rc, Name);
        exit(1);
    }
}						// OpenASem()
示例#7
0
int PutClipText(ClipData *cd) {
    int rc;
    ULONG PostCount;
    char *mem;
    
    rc = DosOpenMutexSem(SEM_PREFIX "CLIPSYN", &hmtxSyn);
    if (rc != 0) return -1;
/*    rc = DosOpenEventSem(SEM_PREFIX "CLIPGET", &hevGet);*/
/*    if (rc != 0) return -1;*/
    rc = DosOpenEventSem(SEM_PREFIX "CLIPPUT", &hevPut);
    if (rc != 0) return -1;
    rc = DosOpenEventSem(SEM_PREFIX "CLIPEND", &hevEnd);
    if (rc != 0) return -1;
    
    DosRequestMutexSem(hmtxSyn, SEM_INDEFINITE_WAIT);
    DosResetEventSem(hevEnd, &PostCount);
    if (0 == DosAllocSharedMem((void **)&mem,
                               MEM_PREFIX "CLIPDATA",
                               cd->fLen + 5,
                               PAG_COMMIT | PAG_READ | PAG_WRITE))
    {
        ULONG L = cd->fLen;
        memcpy((void *)mem, (void *)&L, 4);
        strcpy(mem + 4, cd->fChar);
    }
    DosPostEventSem(hevPut);
    DosWaitEventSem(hevEnd, SEM_INDEFINITE_WAIT);
    DosPostEventSem(hevPut);
    DosReleaseMutexSem(hmtxSyn);
    DosCloseEventSem(hevPut);
/*    DosCloseEventSem(hevGet); */
    DosCloseEventSem(hevEnd);
    DosCloseMutexSem(hmtxSyn);
    if (mem)
        DosFreeMem(mem);
    return 0;
    
}
示例#8
0
static APIRET PipeQueryEventSem(HEV *SemHandle, ULONG *ulPostCt)
{
	APIRET rc;

	rc = DosQueryEventSem(*SemHandle, ulPostCt);

	if (rc == ERROR_INVALID_HANDLE)
	{
		rc = DosOpenEventSem(0, SemHandle);

		if (!rc) 
		    rc = DosQueryEventSem(*SemHandle, ulPostCt);
	}

	return rc;
}
示例#9
0
unsigned long SysOpenEventSem(unsigned char *name,
                           unsigned long numargs,
                           RXSTRING args[],
                           char *queuename,
                           RXSTRING *retstr)
{
    unsigned long rc;

    HEV handle = NULL;           /* mutex handle */

    if (numargs != 1) return INVALID_ROUTINE; /* Only one argument accepted */

    if (!string2ulong(args[0].strptr, &handle)) return INVALID_ROUTINE;

                                       /* get a binary handle        */
                                       /* try to open it             */
    rc = DosOpenEventSem(NULL, &handle);

    RETVAL(rc)
}
示例#10
0
static APIRET PipePostEventSem(HEV *SemHandle)
{
	APIRET rc;

	rc = DosPostEventSem(*SemHandle);

	if (rc)
	{
	     if (rc == ERROR_INVALID_HANDLE)
	     {

		rc = DosOpenEventSem(0, SemHandle);

		if (!rc) 
			rc = DosPostEventSem(*SemHandle);
	     }
	     else if (rc == ERROR_ALREADY_POSTED) 
		rc = 0;
	}

	return rc;
}
示例#11
0
Event::Event ( char *tag, char *Name, int OneInstanceOnly ) : Tag(0), DebugFlag(FALSE) {

   if ( tag ) {
      Tag = (char*) malloc ( strlen(tag) + 1 ) ;
      strcpy ( Tag, tag ) ;
   } /* endif */

   #ifdef __OS2__

      char FullName [_MAX_PATH] ;
      strcpy ( FullName, "\\SEM32\\" ) ;
      strcat ( FullName, Name?Name:"" ) ;
      unsigned long Status = 1 ;
      Handle = 0 ;
      if ( Name && !OneInstanceOnly ) 
         Status = DosOpenEventSem ( PSZ(FullName), &Handle ) ;
      if ( Status ) {
         Status = DosCreateEventSem ( PSZ(Name?FullName:0), &Handle, DC_SEM_SHARED, FALSE ) ;
         if ( OneInstanceOnly && ( Status == ERROR_DUPLICATE_NAME ) )
            Log ( "Event(%s): Unable to create semaphore for '%s'.  Already exists.", Tag?Tag:"", Name?Name:"" ) ;
         else if ( Status ) 
            Log ( "Event(%s): Unable to create semaphore for '%s'.  Status %i.", Tag?Tag:"", Name?Name:"", Status ) ;
      } /* endif */

   #else

      Handle = CreateEvent ( 0, TRUE, FALSE, Name ) ;
      if ( Handle && OneInstanceOnly && ( GetLastError() == ERROR_ALREADY_EXISTS ) ) {
         Log ( "Event(%s): Unable to create event semaphore '%s'.  Already exists.", Tag?Tag:"", Name?Name:"" ) ;
         CloseHandle ( Handle ) ;
         Handle = 0 ;
      } else if ( !Handle ) {
         DWORD Status = GetLastError ( ) ;
         Log ( "Event(%s): Unable to create event semaphore '%s'.  Status %i.", Tag?Tag:"", Name?Name:"", Status ) ;
      } /* endif */

   #endif

} /* endmethod */
示例#12
0
/**
 * Returns the spawn2 semaphore lazily creating it or making sure it's
 * available in the given process (the current process if NULL). Will return
 * NULLHANDLE if lazy creation fails. Must be called under global_lock().
 */
unsigned long global_spawn2_sem(ProcDesc *proc)
{
  APIRET arc;

  if (!proc)
    proc = find_proc_desc(getpid());

  ASSERT(proc);

  if (gpData->spawn2_sem == NULLHANDLE)
  {
    ASSERT(proc->spawn2_sem == NULLHANDLE);

    arc = DosCreateEventSem(NULL, &gpData->spawn2_sem, DC_SEM_SHARED | DCE_AUTORESET, FALSE);
    if (arc != NO_ERROR)
      return NULLHANDLE;

    ASSERT(gpData->spawn2_sem_refcnt == 0);
    gpData->spawn2_sem_refcnt = 1;

    proc->spawn2_sem = gpData->spawn2_sem;
  }
  else if (proc->spawn2_sem == NULLHANDLE)
  {
    arc = DosOpenEventSem(NULL, &gpData->spawn2_sem);
    ASSERT_MSG(arc == NO_ERROR, "%ld %lx", arc, gpData->spawn2_sem);

    ASSERT(gpData->spawn2_sem_refcnt != 0);
    ++gpData->spawn2_sem_refcnt;

    proc->spawn2_sem = gpData->spawn2_sem;
  }

  TRACE("spawn2_sem %lx (refcnt %d)\n", proc->spawn2_sem, gpData->spawn2_sem_refcnt);

  return proc->spawn2_sem;
}
VOID PostEventSemaphore (ULONG Known_key_number)
{
  // Чтобы сообщить о нажатии клавиши, можно включить событийный семафор,
  // который должен быть создан внешним приложением (например, в одном из
  // потоков Nice). Задаем название семафора.
  CHAR Semaphore_name[256] = "";

  switch (Known_key_number)
  {
    case MMK_POWER:           strcpy (Semaphore_name, MMK_POWER_SEMAPHORE_NAME           ); break;
    case MMK_SLEEP:           strcpy (Semaphore_name, MMK_SLEEP_SEMAPHORE_NAME           ); break;
    case MMK_MAIL_READER:     strcpy (Semaphore_name, MMK_MAIL_READER_SEMAPHORE_NAME     ); break;
    case MMK_MEDIA_PLAYER:    strcpy (Semaphore_name, MMK_MEDIA_PLAYER_SEMAPHORE_NAME    ); break;
    case MMK_PAGE_LEFT:       strcpy (Semaphore_name, MMK_PAGE_LEFT_SEMAPHORE_NAME       ); break;
    case MMK_PAGE_RIGHT:      strcpy (Semaphore_name, MMK_PAGE_RIGHT_SEMAPHORE_NAME      ); break;

    default: return;
  }

  // Включаем семафор.
  if (Semaphore_name[0] != 0)
  {
    HEV Semaphore = NULLHANDLE; ULONG Post_count = 0;

    if (DosOpenEventSem (Semaphore_name, &Semaphore) == NO_ERROR &&
        DosQueryEventSem (Semaphore, &Post_count) == NO_ERROR)
    {
      APIRET RC = DosPostEventSem (Semaphore);
    }

    if (Semaphore != NULLHANDLE) DosClose (Semaphore);
  }

  // Возврат.
  return;
}
示例#14
0
int main (int argc, char *argv[])
   {
   APIRET       rc;
   PCHAR        pcEnv;
   PRFPROFILE   prfProfile;

#ifdef DEBUG
   ulDebugMask = 0xFFFFFFFF;
#endif /* DEBUG */

   hab = WinInitialize(0);
   hmq = WinCreateMsgQueue(hab, 0);
   DebugS (1, "PM Interface initialized");

   /* Shared Memory organisieren */
   if (rc = DosGetNamedSharedMem ((PPVOID) &pShareInitOS2,
                                  SHARE_INITOS2,
                                  PAG_READ | PAG_WRITE))
      {
      if (rc = DosAllocSharedMem( (PPVOID) &pShareInitOS2,    // Pointer to shared mem
                                  SHARE_INITOS2,              // Name
                                  CCHSHARE_INITOS2,           // Size of shared mem
                                  PAG_COMMIT | PAG_READ | PAG_WRITE)) // Flags
         return(1);
      else
         {
         /* Shared Memory initialisieren */

         memset (pShareInitOS2, '\0', CCHSHARE_INITOS2);

         pShareInitOS2->pszRegFile       = (PCHAR) pShareInitOS2 +
                                          sizeof(*pShareInitOS2);
         strcpy (pShareInitOS2->pszRegFile,
                 DosScanEnv (ENV_SYSTEM_INI, &pcEnv) ? "" : pcEnv);
         pShareInitOS2->pszRootUserIni   = pShareInitOS2->pszRegFile +
                                          strlen(pShareInitOS2->pszRegFile) + 1;
         pShareInitOS2->pszRootSystemIni = pShareInitOS2->pszRootUserIni + 1;
         pShareInitOS2->pszUserIni       = pShareInitOS2->pszRootSystemIni + 1;
         pShareInitOS2->pszSystemIni     = pShareInitOS2->pszUserIni   + CCHMAXPATH;
         pShareInitOS2->pszEnvironment   = pShareInitOS2->pszSystemIni + CCHMAXPATH;
         }
      }
   DebugS (1, "Shared Memory initialized");

   /* Semaphoren organisieren */
   rc = DosOpenEventSem (HEV_SAMMY, &hevSammy);

   if( rc )
      rc = DosCreateEventSem( HEV_SAMMY,   // Name
                              &hevSammy,   // Pointer to sem
                              0,           // Not used with named sems
                              FALSE);      // Initial state (FALSE = SET)

   else        /* Sammy ist bereits installiert */
      {
      pShareInitOS2->pszEnvironment[0] = '\0';
      pShareInitOS2->pszEnvironment[1] = '\0';
      pShareInitOS2->pszSystemIni[0]   = '\0';
      pShareInitOS2->pszUserIni[0]     = '\0';
      DosPostEventSem(hevSammy);
      goto Exit;
      }

   if( rc )
      {
      intSammyRetCode = rc;
      goto Exit;
      }

   rc = DosOpenEventSem (HEV_PRFRESETLOCK, &hevPrfResetLock);

   if( rc )
      rc = DosCreateEventSem( HEV_PRFRESETLOCK, // Name
                              &hevPrfResetLock, // Pointer to sem
                              0,                // Not used with named sems
                              TRUE);            // Initial state (TRUE = POSTED)

   if( rc )
      {
      intSammyRetCode = rc;
      goto Exit;
      }
   DebugS (1, "Semaphores initialized");

   ChangeWPS(pShareInitOS2->pszUserIni, pShareInitOS2->pszSystemIni);

   /* Hintergrundloop starten, das Shell mit aktueller Env. startet */

   DosCreateThread (&tid1,
                    (PFNTHREAD) thStartProg,
                    (ULONG) ((argc > 1) ? argv[1] : ""),
                    0,
                    THREADSTACK);
   DebugS (1, "Background loop started");

   /* Hintergrundloop starten, das jeweils nach L�schen einer Semaphore */
   /* einen prfReset initiiert                      */
   DosCreateThread (&tid2,
                    (PFNTHREAD) thSwitch,
                    (ULONG) 0,
                    0,
                    THREADSTACK);

   while (WinGetMsg (hab, &qmsg, 0, 0, 0))
      WinDispatchMsg (hab, &qmsg);

   if (intSammyRetCode)
      {
      DosKillThread (tid1);
      DosKillThread (tid2);

      WinSetObjectData(WinQueryObject("<WP_DESKTOP>"), "WORKAREA=NO");
      WinPostMsg(WinQueryWindow(HWND_DESKTOP, QW_BOTTOM), WM_CLOSE, 0, 0);

      WinAlarm (HWND_DESKTOP, WA_ERROR);

      prfProfile.pszSysName  = (DosScanEnv (ENV_SYSTEM_INI, &pcEnv) ? "" : pcEnv);
      prfProfile.pszUserName = (DosScanEnv (ENV_USER_INI, &pcEnv) ? "" : pcEnv);

      prfProfile.cchUserName = strlen(prfProfile.pszUserName);
      prfProfile.cchSysName  = strlen(prfProfile.pszSysName);

      DosSleep (1000);
      DosKillProcess( DKP_PROCESSTREE, ulShellID );

      if ( !PrfReset(hab, &prfProfile))
         WinSetObjectData(WinQueryObject("<WP_DESKTOP>"), "OPEN=ICON;WORKAREA=YES");
      }
Exit:
   WinDestroyMsgQueue(hmq);
   WinTerminate(hab);

   DebugS (1, "Application terminated");

   return intSammyRetCode;
   }
示例#15
0
int main(int argc, char *argv[]) {

  int do_load,do_unload,do_help,do_path;
  do_load=do_unload=do_help=do_path=0;

  char basepath[CCHMAXPATH];

  if (argc == 1)
    do_help = 1;
  else {
    for (int i=1; i < argc; i++) {
      if (strnicmp(argv[i],"-l", 2) == 0)
        do_load = 1;
      else if (strnicmp(argv[i],"-u", 2) == 0)
        do_unload = 1;
      else if (strnicmp(argv[i],"-h", 2) == 0) 
        do_help = 1;
      else if (strnicmp(argv[i],"-?", 2) == 0)
        do_help = 1;
      else if (strnicmp(argv[i],"-p", 2) == 0) {
        if (argc > i+1) {
          strcpy(basepath, argv[i+1]);
          if (basepath[strlen(basepath)] !='\\') {
            strcat(basepath, "\\");
          }
        do_path = 1;
        } else {
          do_help = 1;
        }
      }
    }
  }


  if (do_help) {
    printf("%s for OS/2 preloader\n"\
           "\n"\
           "Usage: %s [-h] [-l | -u] [-p path]\n"\
           "       -h display this help\n"\
           "       -l load modules\n"\
           "       -u unload modules\n"\
           "       -p specify fully qualified path to directory where EXE is located\n",
           MOZ_APP_DISPLAYNAME, argv[0]);
    return(1);
  }

  if (do_unload) {
    HEV hev = NULLHANDLE;
    if (DosOpenEventSem(SEMNAME, &hev) == NO_ERROR) {
      if (DosPostEventSem(hev) == NO_ERROR) {
        if (DosCloseEventSem(hev) == NO_ERROR) {
          return(0);
        }
      }
    }
    printf("%s for OS/2 preloader is not running\n", MOZ_APP_DISPLAYNAME);
    return(1);
  }

  if (do_path == 0) {
    /* Get the name of this EXE and use its location as the path */
    HMODULE hmodule;
    DosQueryModFromEIP(&hmodule, NULL, 0, NULL, NULL, (ULONG)ForceModuleLoad);
    DosQueryModuleName(hmodule, CCHMAXPATH, basepath);
    char *pchar = strrchr(basepath, '\\');
    pchar++;
    *pchar = '\0';
  }

  if (do_load) {
    ULONG ulCurMaxFH;
    LONG ulReqFH = 40;
    DosSetRelMaxFH(&ulReqFH, &ulCurMaxFH);

    HEV hev;
    if (DosCreateEventSem(SEMNAME, &hev, DC_SEM_SHARED, FALSE) != NO_ERROR) {
      printf("%s for OS/2 preloader is already running\n", MOZ_APP_DISPLAYNAME);
      return(1);
    }

    /* Add directory where EXE is located to LIBPATH */
    DosSetExtLIBPATH(basepath, BEGIN_LIBPATH);

    /* loop through list loading named modules */
    char filepath[CCHMAXPATH];
    HMODULE hmod;

    int i = 0, nummodules = 0;
    while (bindir[i]) {
      strcpy(filepath,basepath);
      strcat(filepath,bindir[i]);
   
      if (DosLoadModule(NULL, 0, filepath, &hmod) == NO_ERROR) {
        ForceModuleLoad(hmod);
        nummodules++;
      }
      i++;
    }

    i = 0;
    while (compdir[i]) {
      strcpy(filepath, basepath);
      strcat(filepath, "COMPONENTS\\");
      strcat(filepath, compdir[i]);

      if (DosLoadModule(NULL, 0, filepath, &hmod) == NO_ERROR) {
        ForceModuleLoad(hmod);
        nummodules++;
      }
      i++;
    }
   
    if (nummodules > 0) {
      if (DosWaitEventSem(hev, SEM_INDEFINITE_WAIT) != NO_ERROR) {
        printf("DosWaitEventSem failed\n");
        return(1);
      }

      if (DosCloseEventSem(hev) != NO_ERROR) {
        printf("DosCloseEventSem failed\n");
        return(1);
      }
    } else {
      printf("No modules available to load\n");
    }
  }

 return(0);
}
示例#16
0
static void *
tf (void *arg)
{
  if (pthread_mutex_lock (&lock))
    {
      puts ("1st locking of lock failed");
	  exit (1);
    }

  struct flock fl =
    {
      .l_type = F_WRLCK,
      .l_start = 0,
      .l_whence = SEEK_SET,
      .l_len = 10
    };
  if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLKW, &fl)) != 0)
    {
      puts ("fourth fcntl failed");
      exit (1);
    }

  pthread_mutex_unlock (&lock);

  pthread_mutex_lock (&lock2);

  return NULL;
}


static int
do_test (void)
{
  fd = create_temp_file("tst-flock2-", NULL);
  if (fd == -1)
    {
      puts ("create_temp_file failed");
      return 1;
    }

  int i;
  for (i = 0; i < 20; ++i)
    write (fd, "foobar xyzzy", 12);

  pthread_barrier_t *b;
#ifdef __EMX__
  APIRET arc;
  arc = DosAllocSharedMem ((PPVOID) &b, NULL, sizeof (pthread_barrier_t),
                           PAG_READ | PAG_WRITE | PAG_COMMIT | OBJ_GETTABLE);
  if (arc)
    {
      puts ("DosAllocSharedMem failed");
      return 1;
    }
  b->hmtx = NULLHANDLE;
  arc = DosCreateMutexSem (NULL, &b->hmtx, DC_SEM_SHARED, FALSE);
  if (arc)
    {
      puts ("DosCreateMutexSem failed");
      return 1;
    }
  b->hev = NULLHANDLE;
  arc = DosCreateEventSem (NULL, &b->hev, DC_SEM_SHARED | DCE_AUTORESET, FALSE);
  if (arc)
    {
      puts ("DosCreateEventSem failed");
      return 1;
    }
  b->cnt = 0;
  b->cnt_max = 2;
#else
  b = mmap (NULL, sizeof (pthread_barrier_t), PROT_READ | PROT_WRITE,
	    MAP_SHARED, fd, 0);
  if (b == MAP_FAILED)
    {
      puts ("mmap failed");
      return 1;
    }

  pthread_barrierattr_t ba;
  if (pthread_barrierattr_init (&ba) != 0)
    {
      puts ("barrierattr_init failed");
      return 1;
    }

  if (pthread_barrierattr_setpshared (&ba, PTHREAD_PROCESS_SHARED) != 0)
    {
      puts ("barrierattr_setpshared failed");
      return 1;
    }

  if (pthread_barrier_init (b, &ba, 2) != 0)
    {
      puts ("barrier_init failed");
      return 1;
    }

  if (pthread_barrierattr_destroy (&ba) != 0)
    {
      puts ("barrierattr_destroy failed");
      return 1;
    }
#endif

  struct flock fl =
    {
      .l_type = F_WRLCK,
      .l_start = 0,
      .l_whence = SEEK_SET,
      .l_len = 10
    };
  if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLKW, &fl)) != 0)
    {
      puts ("first fcntl failed");
      return 1;
    }

  pid_t pid = fork ();
  if (pid == -1)
    {
      puts ("fork failed");
      return 1;
    }

  if (pid == 0)
    {
#ifdef __EMX__
      arc = DosGetSharedMem (b, PAG_READ | PAG_WRITE);
      if (arc)
        {
          puts ("DosGetSharedMem failed");
          return 1;
        }
      arc = DosOpenMutexSem (NULL, &b->hmtx);
      if (arc)
        {
          puts ("DosOpenMutexSem failed");
          return 1;
        }
      arc = DosOpenEventSem (NULL, &b->hev);
      if (arc)
        {
          puts ("DosOpenEventSem failed");
          return 1;
        }
#endif
      /* Make sure the child does not stay around indefinitely.  */
      alarm (10);

      /* Try to get the lock.  */
      if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLK, &fl)) == 0)
	{
	  puts ("child:  second flock succeeded");
	  return 1;
	}
    }

  pthread_barrier_wait (b);

  if (pid != 0)
    {
      fl.l_type = F_UNLCK;
      if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLKW, &fl)) != 0)
	{
	  puts ("third fcntl failed");
	  return 1;
	}
    }

  pthread_barrier_wait (b);

  pthread_t th;
  if (pid == 0)
    {
      if (pthread_mutex_lock (&lock2) != 0)
	{
	  puts ("1st locking of lock2 failed");
	  return 1;
	}

      if (pthread_create (&th, NULL, tf, NULL) != 0)
	{
	  puts ("pthread_create failed");
	  return 1;
	}

      /* Let the new thread run.  */
      sleep (1);

      if (pthread_mutex_lock (&lock) != 0)
	{
	  puts ("2nd locking of lock failed");
	  return 1;
	}

      puts ("child locked file");
    }

  pthread_barrier_wait (b);

  if (pid != 0)
    {
      fl.l_type = F_WRLCK;
      if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLK, &fl)) == 0)
	{
	  puts ("fifth fcntl succeeded");
	  return 1;
	}

      puts ("file locked by child");
    }

  pthread_barrier_wait (b);

  if (pid == 0)
    {
      if (pthread_mutex_unlock (&lock2) != 0)
	{
	  puts ("unlock of lock2 failed");
	  return 1;
	}

      if (pthread_join (th, NULL) != 0)
	{
	  puts ("join failed");
	  return 1;
	}

      puts ("child's thread terminated");
    }

  pthread_barrier_wait (b);

  if (pid != 0)
    {
      fl.l_type = F_WRLCK;
      if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLK, &fl)) == 0)
	{
	  puts ("fifth fcntl succeeded");
	  return 1;
	}

      puts ("file still locked");
    }

  pthread_barrier_wait (b);

  if (pid == 0)
    {
      _exit (0);
    }

  int status;
  if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid)
    {
      puts ("waitpid failed");
      return 1;
    }
  puts ("child terminated");

  if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLKW, &fl)) != 0)
    {
      puts ("sixth fcntl failed");
      return 1;
    }

  return status;
}